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 A76A45A004F for ; Fri, 05 Jul 2024 04:07:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202312; t=1720145251; bh=OIdQ6IbbkzulUc57s2g6dk9lY2z108Axdxe6PZ1Z6A8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NhB55Q+CCJvZ29QBAIrhfoaARB2ZZDv12a0+WFkoGw0Z4nXAlEuwyH/A5JSoFuqLA 7hoE5gAW2bl5WxJCbuB+vtq1ZNMtpXWpltXLQeTfx+pqtmBJkEWURuYWWDKV95s8Fg 9lPN1CvKwFHMgRJoqUHdhXeH7hek2aCG/E/g+faco2sp5ehWAGNw1pYjUhEZCdvEkF hqC0fktggfQ2Tmseyah/h7eqR1iHcQPZ0GWKNCTocZSFj7kb/nbauXuYt1CxnwCOKZ yBKdYXK1rhx8abSFvA9SVNTiQ2+HhKH+KUAr9KBFr5T2wwG3wU1bTgbFeK4gAhvwM8 hIjQtd7O8Hf5w== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4WFcNM1DMmz4xPc; Fri, 5 Jul 2024 12:07:31 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Subject: [PATCH v7 16/27] icmp: Manage outbound socket address via flow table Date: Fri, 5 Jul 2024 12:07:13 +1000 Message-ID: <20240705020724.3447719-17-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240705020724.3447719-1-david@gibson.dropbear.id.au> References: <20240705020724.3447719-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: PPIJZ7J6577BR7JE3BPOPEBSNJZNJ5NZ X-Message-ID-Hash: PPIJZ7J6577BR7JE3BPOPEBSNJZNJ5NZ 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: jmaloy@redhat.com, David Gibson 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: For now when we forward a ping to the host we leave the host side forwarding address and port blank since we don't necessarily know what source address and id will be used by the kernel. When the outbound address option is active, though, we do know the address at least, so we can record it in the flowside. Having done that, use it as the primary source of truth, binding the outgoing socket based on the information in there. This allows the possibility of more complex rules for what outbound address and/or id we use in future. To implement this we create a new helper which sets up a new socket based on information in a flowside, which will also have future uses. It behaves slightly differently from the existing ICMP code, in that it doesn't bind to a specific interface if given a loopback address. This is logically correct - the loopback address means we need to operate through the host's loopback interface, not ifname_out. We didn't need it in ICMP because ICMP will never generate a loopback address at this point, however we intend to change that in future. Signed-off-by: David Gibson --- flow.c | 1 - icmp.c | 23 ++++++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/flow.c b/flow.c index 2d0a8a32..cf952a32 100644 --- a/flow.c +++ b/flow.c @@ -194,7 +194,6 @@ static int flowside_sock_splice(void *arg) * Return: socket fd of protocol @proto bound to the forwarding address and port * from @tgt (if specified). */ -/* cppcheck-suppress unusedFunction */ int flowside_sock_l4(const struct ctx *c, enum epoll_type type, uint8_t pif, const struct flowside *tgt, uint32_t data) { diff --git a/icmp.c b/icmp.c index e2e697e7..29a66e6f 100644 --- a/icmp.c +++ b/icmp.c @@ -157,30 +157,27 @@ static struct icmp_ping_flow *icmp_ping_new(const struct ctx *c, union epoll_ref ref = { .type = EPOLL_TYPE_PING }; union flow *flow = flow_alloc(); struct icmp_ping_flow *pingf; + const struct flowside *tgt; const void *bind_addr; - const char *bind_if; if (!flow) return NULL; flow_initiate_af(flow, PIF_TAP, af, saddr, id, daddr, id); - /* FIXME: Record outbound source address when known */ - flow_target_af(flow, PIF_HOST, af, NULL, 0, daddr, 0); - pingf = FLOW_SET_TYPE(flow, flowtype, ping); - - pingf->seq = -1; - if (af == AF_INET) { + if (af == AF_INET) bind_addr = &c->ip4.addr_out; - bind_if = c->ip4.ifname_out; - } else { + else if (af == AF_INET6) bind_addr = &c->ip6.addr_out; - bind_if = c->ip6.ifname_out; - } + + tgt = flow_target_af(flow, PIF_HOST, af, bind_addr, 0, daddr, 0); + pingf = FLOW_SET_TYPE(flow, flowtype, ping); + + pingf->seq = -1; ref.flowside = FLOW_SIDX(flow, TGTSIDE); - pingf->sock = sock_l4(c, af, EPOLL_TYPE_PING, bind_addr, bind_if, - 0, ref.data); + pingf->sock = flowside_sock_l4(c, EPOLL_TYPE_PING, PIF_HOST, + tgt, ref.data); if (pingf->sock < 0) { warn("Cannot open \"ping\" socket. You might need to:"); -- 2.45.2