aboutgitcodebugslistschat
path: root/netlink.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2024-08-15 00:33:24 +0200
committerStefano Brivio <sbrivio@redhat.com>2024-08-18 01:29:52 +0200
commitd6f022073124edd7a46fb849a8496d6ea6ce136f (patch)
tree42e6c24228fa1de1814002a4b6840bc7d45804f6 /netlink.c
parent74e508cf797e4fdd812fed3b1b1439a6fc00ebfd (diff)
downloadpasst-d6f022073124edd7a46fb849a8496d6ea6ce136f.tar
passt-d6f022073124edd7a46fb849a8496d6ea6ce136f.tar.gz
passt-d6f022073124edd7a46fb849a8496d6ea6ce136f.tar.bz2
passt-d6f022073124edd7a46fb849a8496d6ea6ce136f.tar.lz
passt-d6f022073124edd7a46fb849a8496d6ea6ce136f.tar.xz
passt-d6f022073124edd7a46fb849a8496d6ea6ce136f.tar.zst
passt-d6f022073124edd7a46fb849a8496d6ea6ce136f.zip
netlink, pasta: Fetch link-local address from namespace interface once it's up
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 <sbrivio@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'netlink.c')
-rw-r--r--netlink.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/netlink.c b/netlink.c
index 5a5af14..9592b1b 100644
--- a/netlink.c
+++ b/netlink.c
@@ -797,6 +797,53 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af,
}
/**
+ * 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
* @ifi: Interface index