From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id E84915A031A for ; Wed, 26 Jun 2024 02:34:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1719362053; bh=xkHXRsrfGShixBj35QymHpzLWQyBAER1N92b2iUYakY=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=Qsrq6fkj3r5l8L/5i4vTPzK28YynKTJgkc3xpDLCQpKqx7z7CygtVc+lojW42cO9D aEHrnxdHmYBl8TEpufqExak/c7k0eDzL5Dpxv93nHf5dxyx1/rNzMQu9Qj+kV+vz4l oJiYK0gUH4sfXOc7U00kmiNnUVk7GNHb663aF0ICIvxFrvMsEwJcq1uDoWSewfIYJV V7dIlItHoTMiI6+CXYwHS1IVp9r4tRwVycdsudzPP91pt4VBeAFxDNY3heSaGGXPLm 8h9i4b+vwa7U61qVAyooXpJ5Urg7HBDsbw2stJtwh5wCZ4XSQeDprh3TQlOQm1vX8R drC2PBLxuKN/w== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4W82ks2H2Rz4wc3; Wed, 26 Jun 2024 10:34:13 +1000 (AEST) Date: Wed, 26 Jun 2024 10:25:24 +1000 From: David Gibson To: Stefano Brivio Subject: Re: [PATCH v6 02/26] flow: Common address information for target side Message-ID: References: <20240614061348.3814736-1-david@gibson.dropbear.id.au> <20240614061348.3814736-3-david@gibson.dropbear.id.au> <20240626002359.1614c80e@elisabeth> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="nS2V0oKksI+8bPuA" Content-Disposition: inline In-Reply-To: <20240626002359.1614c80e@elisabeth> Message-ID-Hash: ADVHDDY3FV5YSJ7XE22HE5TD3KZRD2KT X-Message-ID-Hash: ADVHDDY3FV5YSJ7XE22HE5TD3KZRD2KT X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top, jmaloy@redhat.com X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --nS2V0oKksI+8bPuA Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Jun 26, 2024 at 12:23:59AM +0200, Stefano Brivio wrote: > On Fri, 14 Jun 2024 16:13:24 +1000 > David Gibson wrote: >=20 > > Require the address and port information for the target (non > > initiating) side to be populated when a flow enters TGT state. > > Implement that for TCP and ICMP. For now this leaves some information > > redundantly recorded in both generic and type specific fields. We'll > > fix that in later patches. > >=20 > > For TCP we now use the information from the flow to construct the > > destination socket address in both tcp_conn_from_tap() and > > tcp_splice_connect(). > >=20 > > Signed-off-by: David Gibson > > --- > > flow.c | 38 ++++++++++++++++++------ > > flow_table.h | 5 +++- > > icmp.c | 3 +- > > inany.h | 30 ++++++++++++++++++- > > tcp.c | 83 ++++++++++++++++++++++++++++------------------------ > > tcp_splice.c | 45 +++++++++++----------------- > > 6 files changed, 126 insertions(+), 78 deletions(-) > >=20 > > diff --git a/flow.c b/flow.c > > index 1819111d..39e046bf 100644 > > --- a/flow.c > > +++ b/flow.c > > @@ -165,8 +165,10 @@ void flow_log_(const struct flow_common *f, int pr= i, const char *fmt, ...) > > */ > > static void flow_set_state(struct flow_common *f, enum flow_state stat= e) > > { > > - char estr[INANY_ADDRSTRLEN], fstr[INANY_ADDRSTRLEN]; > > + char estr0[INANY_ADDRSTRLEN], fstr0[INANY_ADDRSTRLEN]; > > + char estr1[INANY_ADDRSTRLEN], fstr1[INANY_ADDRSTRLEN]; > > const struct flowside *ini =3D &f->side[INISIDE]; > > + const struct flowside *tgt =3D &f->side[TGTSIDE]; > > uint8_t oldstate =3D f->state; > > =20 > > ASSERT(state < FLOW_NUM_STATES); > > @@ -177,19 +179,24 @@ static void flow_set_state(struct flow_common *f,= enum flow_state state) > > FLOW_STATE(f)); > > =20 > > if (MAX(state, oldstate) >=3D FLOW_STATE_TGT) > > - flow_log_(f, LOG_DEBUG, "%s [%s]:%hu -> [%s]:%hu =3D> %s", > > + flow_log_(f, LOG_DEBUG, > > + "%s [%s]:%hu -> [%s]:%hu =3D> %s [%s]:%hu -> [%s]:%hu", > > pif_name(f->pif[INISIDE]), > > - inany_ntop(&ini->eaddr, estr, sizeof(estr)), > > + inany_ntop(&ini->eaddr, estr0, sizeof(estr0)), > > ini->eport, > > - inany_ntop(&ini->faddr, fstr, sizeof(fstr)), > > + inany_ntop(&ini->faddr, fstr0, sizeof(fstr0)), > > ini->fport, > > - pif_name(f->pif[TGTSIDE])); > > + pif_name(f->pif[TGTSIDE]), > > + inany_ntop(&tgt->faddr, fstr1, sizeof(fstr1)), > > + tgt->fport, > > + inany_ntop(&tgt->eaddr, estr1, sizeof(estr1)), > > + tgt->eport); > > else if (MAX(state, oldstate) >=3D FLOW_STATE_INI) > > flow_log_(f, LOG_DEBUG, "%s [%s]:%hu -> [%s]:%hu =3D> ?", > > pif_name(f->pif[INISIDE]), > > - inany_ntop(&ini->eaddr, estr, sizeof(estr)), > > + inany_ntop(&ini->eaddr, estr0, sizeof(estr0)), > > ini->eport, > > - inany_ntop(&ini->faddr, fstr, sizeof(fstr)), > > + inany_ntop(&ini->faddr, fstr0, sizeof(fstr0)), > > ini->fport); > > } > > =20 > > @@ -261,21 +268,34 @@ const struct flowside *flow_initiate_sa(union flo= w *flow, uint8_t pif, > > } > > =20 > > /** > > - * flow_target() - Move flow to TGT, setting TGTSIDE details > > + * flow_target_af() - Move flow to TGT, setting TGTSIDE details > > * @flow: Flow to change state > > * @pif: pif of the target side > > + * @af: Address family for @eaddr and @faddr > > + * @saddr: Source address (pointer to in_addr or in6_addr) > > + * @sport: Endpoint port > > + * @daddr: Destination address (pointer to in_addr or in6_addr) > > + * @dport: Destination port > > + * > > + * Return: pointer to the target flowside information > > */ > > -void flow_target(union flow *flow, uint8_t pif) > > +const struct flowside *flow_target_af(union flow *flow, uint8_t pif, > > + sa_family_t af, > > + const void *saddr, in_port_t sport, > > + const void *daddr, in_port_t dport) > > { > > struct flow_common *f =3D &flow->f; > > + struct flowside *tgt =3D &f->side[TGTSIDE]; > > =20 > > ASSERT(pif !=3D PIF_NONE); > > ASSERT(flow_new_entry =3D=3D flow && f->state =3D=3D FLOW_STATE_INI); > > ASSERT(f->type =3D=3D FLOW_TYPE_NONE); > > ASSERT(f->pif[INISIDE] !=3D PIF_NONE && f->pif[TGTSIDE] =3D=3D PIF_NO= NE); > > =20 > > + flowside_from_af(tgt, af, daddr, dport, saddr, sport); > > f->pif[TGTSIDE] =3D pif; > > flow_set_state(f, FLOW_STATE_TGT); > > + return tgt; > > } > > =20 > > /** > > diff --git a/flow_table.h b/flow_table.h > > index 2e912532..7af32c6a 100644 > > --- a/flow_table.h > > +++ b/flow_table.h > > @@ -114,7 +114,10 @@ const struct flowside *flow_initiate_af(union flow= *flow, uint8_t pif, > > const struct flowside *flow_initiate_sa(union flow *flow, uint8_t pif, > > const union sockaddr_inany *ssa, > > in_port_t dport); > > -void flow_target(union flow *flow, uint8_t pif); > > +const struct flowside *flow_target_af(union flow *flow, uint8_t pif, > > + sa_family_t af, > > + const void *saddr, in_port_t sport, > > + const void *daddr, in_port_t dport); > > =20 > > union flow *flow_set_type(union flow *flow, enum flow_type type); > > #define FLOW_SET_TYPE(flow_, t_, var_) (&flow_set_type((flow_), (t_))-= >var_) > > diff --git a/icmp.c b/icmp.c > > index 38d1deeb..c86c54c3 100644 > > --- a/icmp.c > > +++ b/icmp.c > > @@ -167,7 +167,8 @@ static struct icmp_ping_flow *icmp_ping_new(const s= truct ctx *c, > > return NULL; > > =20 > > flow_initiate_af(flow, PIF_TAP, af, saddr, id, daddr, id); > > - flow_target(flow, PIF_HOST); > > + /* FIXME: Record outbound source address when known */ > > + flow_target_af(flow, PIF_HOST, af, NULL, 0, daddr, 0); > > pingf =3D FLOW_SET_TYPE(flow, flowtype, ping); > > =20 > > pingf->seq =3D -1; > > diff --git a/inany.h b/inany.h > > index 47b66fa9..2bf3becf 100644 > > --- a/inany.h > > +++ b/inany.h > > @@ -187,7 +187,6 @@ static inline bool inany_is_unspecified(const union= inany_addr *a) > > * > > * Return: true if @a is in fe80::/10 (IPv6 link local unicast) > > */ > > -/* cppcheck-suppress unusedFunction */ > > static inline bool inany_is_linklocal6(const union inany_addr *a) > > { > > return IN6_IS_ADDR_LINKLOCAL(&a->a6); > > @@ -273,4 +272,33 @@ static inline void inany_siphash_feed(struct sipha= sh_state *state, > > =20 > > const char *inany_ntop(const union inany_addr *src, char *dst, socklen= _t size); > > =20 > > +/** sockaddr_from_inany() - Construct a sockaddr from an inany > > + * @sa: Pointer to sockaddr to fill in > > + * @sl: Updated to relevant of length of initialised @sa > > + * @addr: IPv[46] address > > + * @port: Port (host byte order) > > + * @scope: Scope ID (ignored for IPv4 addresses) >=20 > Perhaps worth specifying that it's the interface index for IPv6 > link-local addresses only (even if it's not the case as of this patch, > more below): >=20 > * @scope: Scope ID for link-local IPv6 addresses only: interface index Right.. as it happens, I'm reworking this in a way that will obsolete this parameter anyway. > > + */ > > +static inline void sockaddr_from_inany(union sockaddr_inany *sa, sockl= en_t *sl, > > + const union inany_addr *addr, > > + in_port_t port, uint32_t scope) > > +{ > > + const struct in_addr *v4 =3D inany_v4(addr); > > + > > + if (v4) { > > + sa->sa_family =3D AF_INET; > > + sa->sa4.sin_addr =3D *v4; > > + sa->sa4.sin_port =3D htons(port); > > + memset(&sa->sa4.sin_zero, 0, sizeof(sa->sa4.sin_zero)); > > + *sl =3D sizeof(sa->sa4); > > + } else { > > + sa->sa_family =3D AF_INET6; > > + sa->sa6.sin6_addr =3D addr->a6; > > + sa->sa6.sin6_port =3D htons(port); > > + sa->sa6.sin6_scope_id =3D scope; > > + sa->sa6.sin6_flowinfo =3D 0; > > + *sl =3D sizeof(sa->sa6); > > + } > > +} > > + > > #endif /* INANY_H */ > > diff --git a/tcp.c b/tcp.c > > index 07a2eb1c..c6cd0c72 100644 > > --- a/tcp.c > > +++ b/tcp.c > > @@ -1610,18 +1610,10 @@ static void tcp_conn_from_tap(struct ctx *c, sa= _family_t af, > > { > > in_port_t srcport =3D ntohs(th->source); > > in_port_t dstport =3D ntohs(th->dest); > > - struct sockaddr_in addr4 =3D { > > - .sin_family =3D AF_INET, > > - .sin_port =3D htons(dstport), > > - .sin_addr =3D *(struct in_addr *)daddr, > > - }; > > - struct sockaddr_in6 addr6 =3D { > > - .sin6_family =3D AF_INET6, > > - .sin6_port =3D htons(dstport), > > - .sin6_addr =3D *(struct in6_addr *)daddr, > > - }; > > - const struct sockaddr *sa; > > + const struct flowside *ini, *tgt; > > struct tcp_tap_conn *conn; > > + union inany_addr dstaddr; /* FIXME: Avoid bulky temporary */ > > + union sockaddr_inany sa; > > union flow *flow; > > int s =3D -1, mss; > > socklen_t sl; > > @@ -1629,7 +1621,8 @@ static void tcp_conn_from_tap(struct ctx *c, sa_f= amily_t af, > > if (!(flow =3D flow_alloc())) > > return; > > =20 > > - flow_initiate_af(flow, PIF_TAP, af, saddr, srcport, daddr, dstport); > > + ini =3D flow_initiate_af(flow, PIF_TAP, > > + af, saddr, srcport, daddr, dstport); > > =20 > > if (af =3D=3D AF_INET) { > > if (IN4_IS_ADDR_UNSPECIFIED(saddr) || > > @@ -1661,19 +1654,28 @@ static void tcp_conn_from_tap(struct ctx *c, sa= _family_t af, > > dstport); > > goto cancel; > > } > > + } else { > > + ASSERT(0); > > } > > =20 > > if ((s =3D tcp_conn_sock(c, af)) < 0) > > goto cancel; > > =20 > > + dstaddr =3D ini->faddr; > > + > > if (!c->no_map_gw) { > > - if (af =3D=3D AF_INET && IN4_ARE_ADDR_EQUAL(daddr, &c->ip4.gw)) > > - addr4.sin_addr.s_addr =3D htonl(INADDR_LOOPBACK); > > - if (af =3D=3D AF_INET6 && IN6_ARE_ADDR_EQUAL(daddr, &c->ip6.gw)) > > - addr6.sin6_addr =3D in6addr_loopback; > > + if (inany_equals4(&dstaddr, &c->ip4.gw)) > > + dstaddr =3D inany_loopback4; > > + else if (inany_equals6(&dstaddr, &c->ip6.gw)) > > + dstaddr =3D inany_loopback6; > > } > > =20 > > - if (af =3D=3D AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr)) { > > + /* FIXME: Record outbound source address when known */ > > + tgt =3D flow_target_af(flow, PIF_HOST, AF_INET6, > > + NULL, 0, /* Kernel decides source address */ > > + &dstaddr, dstport); > > + > > + if (inany_is_linklocal6(&tgt->eaddr)) { > > struct sockaddr_in6 addr6_ll =3D { > > .sin6_family =3D AF_INET6, > > .sin6_addr =3D c->ip6.addr_ll, > > @@ -1681,9 +1683,10 @@ static void tcp_conn_from_tap(struct ctx *c, sa_= family_t af, > > }; > > if (bind(s, (struct sockaddr *)&addr6_ll, sizeof(addr6_ll))) > > goto cancel; > > + } else if (!inany_is_loopback(&tgt->eaddr)) { > > + tcp_bind_outbound(c, s, af); > > } > > =20 > > - flow_target(flow, PIF_HOST); > > conn =3D FLOW_SET_TYPE(flow, FLOW_TCP, tcp); > > conn->sock =3D s; > > conn->timer =3D -1; > > @@ -1706,14 +1709,6 @@ static void tcp_conn_from_tap(struct ctx *c, sa_= family_t af, > > =20 > > inany_from_af(&conn->faddr, af, daddr); > > =20 > > - if (af =3D=3D AF_INET) { > > - sa =3D (struct sockaddr *)&addr4; > > - sl =3D sizeof(addr4); > > - } else { > > - sa =3D (struct sockaddr *)&addr6; > > - sl =3D sizeof(addr6); > > - } > > - > > conn->fport =3D dstport; > > conn->eport =3D srcport; > > =20 > > @@ -1726,19 +1721,16 @@ static void tcp_conn_from_tap(struct ctx *c, sa= _family_t af, > > =20 > > tcp_hash_insert(c, conn); > > =20 > > - if (!bind(s, sa, sl)) { > > + sockaddr_from_inany(&sa, &sl, &tgt->eaddr, tgt->eport, c->ifi6); >=20 > ...so, I never tried to use a non-zero scope identifier for, say, > global unicast IPv6 addresses. Perhaps it's harmless. But I still think > that, logically, we should pass it as zero in that case. Right, that will be changed by the rework I have in mind anyway. > > + > > + if (!bind(s, &sa.sa, sl)) { > > tcp_rst(c, conn); /* Nobody is listening then */ > > goto cancel; > > } > > if (errno !=3D EADDRNOTAVAIL && errno !=3D EACCES) > > conn_flag(c, conn, LOCAL); >=20 > This will have a semi-trivial conflict with 54a9d3801b95 ("tcp: Don't > rely on bind() to fail to decide that connection target is valid"). Yeah, I already did that rebase, it was surprisingly fiddly. >=20 > > =20 > > - if ((af =3D=3D AF_INET && !IN4_IS_ADDR_LOOPBACK(&addr4.sin_addr)) || > > - (af =3D=3D AF_INET6 && !IN6_IS_ADDR_LOOPBACK(&addr6.sin6_addr) && > > - !IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr))) > > - tcp_bind_outbound(c, s, af); > > - > > - if (connect(s, sa, sl)) { > > + if (connect(s, &sa.sa, sl)) { > > if (errno !=3D EINPROGRESS) { > > tcp_rst(c, conn); > > goto cancel; > > @@ -2236,9 +2228,25 @@ static void tcp_tap_conn_from_sock(struct ctx *c= , in_port_t dstport, > > const union sockaddr_inany *sa, > > const struct timespec *now) > > { > > + union inany_addr saddr, daddr; /* FIXME: avoid bulky temporaries */ > > struct tcp_tap_conn *conn; > > + in_port_t srcport; > > + > > + inany_from_sockaddr(&saddr, &srcport, sa); > > + tcp_snat_inbound(c, &saddr); > > =20 > > - flow_target(flow, PIF_TAP); > > + if (inany_v4(&saddr)) { > > + daddr =3D inany_from_v4(c->ip4.addr_seen); > > + } else { > > + if (inany_is_linklocal6(&saddr)) > > + daddr.a6 =3D c->ip6.addr_ll_seen; > > + else > > + daddr.a6 =3D c->ip6.addr_seen; > > + } > > + dstport +=3D c->tcp.fwd_in.delta[dstport]; > > + > > + flow_target_af(flow, PIF_TAP, AF_INET6, > > + &saddr, srcport, &daddr, dstport); > > conn =3D FLOW_SET_TYPE(flow, FLOW_TCP, tcp); > > =20 > > conn->sock =3D s; > > @@ -2246,10 +2254,9 @@ static void tcp_tap_conn_from_sock(struct ctx *c= , in_port_t dstport, > > conn->ws_to_tap =3D conn->ws_from_tap =3D 0; > > conn_event(c, conn, SOCK_ACCEPTED); > > =20 > > - inany_from_sockaddr(&conn->faddr, &conn->fport, sa); > > - conn->eport =3D dstport + c->tcp.fwd_in.delta[dstport]; > > - > > - tcp_snat_inbound(c, &conn->faddr); > > + conn->faddr =3D saddr; > > + conn->fport =3D srcport; > > + conn->eport =3D dstport; > > =20 > > tcp_seq_init(c, conn, now); > > tcp_hash_insert(c, conn); > > diff --git a/tcp_splice.c b/tcp_splice.c > > index 5a406c63..bcb42c97 100644 > > --- a/tcp_splice.c > > +++ b/tcp_splice.c > > @@ -320,31 +320,20 @@ static int tcp_splice_connect_finish(const struct= ctx *c, > > * tcp_splice_connect() - Create and connect socket for new spliced co= nnection > > * @c: Execution context > > * @conn: Connection pointer > > - * @af: Address family > > - * @pif: pif on which to create socket > > - * @port: Destination port, host order > > * > > * Return: 0 for connect() succeeded or in progress, negative value on= error > > */ > > -static int tcp_splice_connect(const struct ctx *c, struct tcp_splice_c= onn *conn, > > - sa_family_t af, uint8_t pif, in_port_t port) > > +static int tcp_splice_connect(const struct ctx *c, struct tcp_splice_c= onn *conn) > > { > > - struct sockaddr_in6 addr6 =3D { > > - .sin6_family =3D AF_INET6, > > - .sin6_port =3D htons(port), > > - .sin6_addr =3D IN6ADDR_LOOPBACK_INIT, > > - }; > > - struct sockaddr_in addr4 =3D { > > - .sin_family =3D AF_INET, > > - .sin_port =3D htons(port), > > - .sin_addr =3D IN4ADDR_LOOPBACK_INIT, > > - }; > > - const struct sockaddr *sa; > > + const struct flowside *tgt =3D &conn->f.side[TGTSIDE]; > > + sa_family_t af =3D inany_v4(&tgt->eaddr) ? AF_INET : AF_INET6; > > + uint8_t tgtpif =3D conn->f.pif[TGTSIDE]; > > + union sockaddr_inany sa; > > socklen_t sl; > > =20 > > - if (pif =3D=3D PIF_HOST) > > + if (tgtpif =3D=3D PIF_HOST) > > conn->s[1] =3D tcp_conn_sock(c, af); > > - else if (pif =3D=3D PIF_SPLICE) > > + else if (tgtpif =3D=3D PIF_SPLICE) > > conn->s[1] =3D tcp_conn_sock_ns(c, af); > > else > > ASSERT(0); > > @@ -358,15 +347,9 @@ static int tcp_splice_connect(const struct ctx *c,= struct tcp_splice_conn *conn, > > conn->s[1]); > > } > > =20 > > - if (CONN_V6(conn)) { > > - sa =3D (struct sockaddr *)&addr6; > > - sl =3D sizeof(addr6); > > - } else { > > - sa =3D (struct sockaddr *)&addr4; > > - sl =3D sizeof(addr4); > > - } > > + sockaddr_from_inany(&sa, &sl, &tgt->eaddr, tgt->eport, 0); > > =20 > > - if (connect(conn->s[1], sa, sl)) { > > + if (connect(conn->s[1], &sa.sa, sl)) { > > if (errno !=3D EINPROGRESS) { > > flow_trace(conn, "Couldn't connect socket for splice: %s", > > strerror(errno)); > > @@ -471,7 +454,13 @@ bool tcp_splice_conn_from_sock(const struct ctx *c, > > return false; > > } > > =20 > > - flow_target(flow, tgtpif); > > + /* FIXME: Record outbound source address when known */ > > + if (af =3D=3D AF_INET) > > + flow_target_af(flow, tgtpif, AF_INET, > > + NULL, 0, &in4addr_loopback, dstport); > > + else > > + flow_target_af(flow, tgtpif, AF_INET6, > > + NULL, 0, &in6addr_loopback, dstport); > > conn =3D FLOW_SET_TYPE(flow, FLOW_TCP_SPLICE, tcp_splice); > > =20 > > conn->flags =3D af =3D=3D AF_INET ? 0 : SPLICE_V6; > > @@ -483,7 +472,7 @@ bool tcp_splice_conn_from_sock(const struct ctx *c, > > if (setsockopt(s0, SOL_TCP, TCP_QUICKACK, &((int){ 1 }), sizeof(int))) > > flow_trace(conn, "failed to set TCP_QUICKACK on %i", s0); > > =20 > > - if (tcp_splice_connect(c, conn, af, tgtpif, dstport)) > > + if (tcp_splice_connect(c, conn)) > > conn_flag(c, conn, CLOSING); > > =20 > > FLOW_ACTIVATE(conn); >=20 --=20 David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson --nS2V0oKksI+8bPuA Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmZ7X/MACgkQzQJF27ox 2GfURg/9HkFp+fQeZbJRvqlt/tiKjxjlus5qnrD1mPRGA3RilRbIqkHIeGjE4GKd O0A+Ti7syaxuPIuGvtQqrHeMXw33r9M5dX/DqluLWwgEVcy84Au9g2wHMfTGdhi2 cpKb4FWmP27rdYClvzgWalPKkXSCfxCOi5ZLB6GOjZUeIJ4DigCyjOB+mfCRyXS3 pLwnTkS6tG/JePinS7Hy2UOMN61a0GpRBJrmdlJFdkpCrH3mlHEax+EB9aRnUfYs tSCr6KlIXTG2E2AnQWgw/V8Vm+zxnOMIwCvjd3/5BuKZvN25JYnVAKAGEd2ZCP/S x2VhrZiVopnVBYHrB0toajFMza9CusN5czC5nlqxRAlpbPISLxHCfPRA2mXmOxtV PU+rE/EWblHeRegnuOJJue2VTSfmP7GA9t+n3zhTJpbe7Ian03LyXjsGoXUFdSJA zPfrTpiC5rBn5rw/4qRgboA9xWllrEV0aWAAc5z9NoUb16dQZfnPOCbLAAhIDWXB 210vVwABhnua4XO/9Bnu2dRU96UUYPTs1x04h2VVCr2DxZr356+f88K58SFIBIJu ADaxXfNIEEfj2Fcazk4vj/Vctljb3zGjw9wmpUEraKiiw1915vo6vJ/uJGP0Vpvp GIi0wB3SxynXGj+tK82Bo35KFzmlMaQ8/zq2oa8e10IhPDMI7CY= =1zb3 -----END PGP SIGNATURE----- --nS2V0oKksI+8bPuA--