From mboxrd@z Thu Jan 1 00:00:00 1970 Received: by passt.top (Postfix, from userid 1000) id 29B9D5A027B; Thu, 15 Aug 2024 10:36:49 +0200 (CEST) From: Stefano Brivio To: passt-dev@passt.top Subject: [PATCH v2 5/7] netlink, pasta: Fetch link-local address from namespace interface once it's up Date: Thu, 15 Aug 2024 10:36:47 +0200 Message-ID: <20240815083649.4188007-6-sbrivio@redhat.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240815083649.4188007-1-sbrivio@redhat.com> References: <20240815083649.4188007-1-sbrivio@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: E2Q65DBFSWNY4TMJ5T7ILQNARTWXZ3MN X-Message-ID-Hash: E2Q65DBFSWNY4TMJ5T7ILQNARTWXZ3MN X-MailFrom: sbrivio@passt.top 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: David Gibson , Paul Holzinger 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: As soon as we bring up the interface, the Linux kernel will set up a link-local address for it, so we can fetch it and start using right away, if we need a link-local address to communicate to the container before we see any traffic coming from it. Signed-off-by: Stefano Brivio --- netlink.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ netlink.h | 1 + pasta.c | 7 +++++++ 3 files changed, 55 insertions(+) diff --git a/netlink.c b/netlink.c index 59f2fd9..06a3816 100644 --- a/netlink.c +++ b/netlink.c @@ -794,6 +794,53 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af, return status; } +/** + * nl_addr_get_ll() - Get first IPv6 link-local address for a given interface + * @s: Netlink socket + * @ifi: Interface index in outer network namespace + * @addr: Link-local address to fill + * + * Return: 0 on success, negative error code on failure + */ +int nl_addr_get_ll(int s, unsigned int ifi, struct in6_addr *addr) +{ + struct req_t { + struct nlmsghdr nlh; + struct ifaddrmsg ifa; + } req = { + .ifa.ifa_family = AF_INET6, + .ifa.ifa_index = ifi, + }; + struct nlmsghdr *nh; + bool found = false; + char buf[NLBUFSIZ]; + ssize_t status; + uint32_t seq; + + seq = nl_send(s, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); + nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWADDR) { + struct ifaddrmsg *ifa = (struct ifaddrmsg *)NLMSG_DATA(nh); + struct rtattr *rta; + size_t na; + + if (ifa->ifa_index != ifi || ifa->ifa_scope != RT_SCOPE_LINK || + found) + continue; + + for (rta = IFA_RTA(ifa), na = IFA_PAYLOAD(nh); RTA_OK(rta, na); + rta = RTA_NEXT(rta, na)) { + if (rta->rta_type != IFA_ADDRESS) + continue; + + if (!found) { + memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta)); + found = true; + } + } + } + return status; +} + /** * nl_add_set() - Set IP addresses for given interface and address family * @s: Netlink socket diff --git a/netlink.h b/netlink.h index 66a44ad..b51e99c 100644 --- a/netlink.h +++ b/netlink.h @@ -19,6 +19,7 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af, void *addr, int *prefix_len, void *addr_l); int nl_addr_set(int s, unsigned int ifi, sa_family_t af, const void *addr, int prefix_len); +int nl_addr_get_ll(int s, unsigned int ifi, struct in6_addr *addr); int nl_addr_set_ll_nodad(int s, unsigned int ifi); int nl_addr_dup(int s_src, unsigned int ifi_src, int s_dst, unsigned int ifi_dst, sa_family_t af); diff --git a/pasta.c b/pasta.c index 17eed15..e8883bd 100644 --- a/pasta.c +++ b/pasta.c @@ -340,6 +340,13 @@ void pasta_ns_conf(struct ctx *c) } if (c->ifi6) { + rc = nl_addr_get_ll(nl_sock_ns, c->pasta_ifi, + &c->ip6.addr_ll_seen); + if (rc < 0) { + warn("Can't get LL address from namespace: %s", + strerror(-rc)); + } + rc = nl_addr_set_ll_nodad(nl_sock_ns, c->pasta_ifi); if (rc < 0) { warn("Can't set nodad for LL in namespace: %s", -- 2.43.0