On Sun, Dec 14, 2025 at 08:54:41PM -0500, Jon Maloy wrote: > When pasta starts without a template interface (-I), it creates the > tap Template interface is -i not -I. -I is the guest interface name - that should take precedence if specified, regardless of late binding or not. > device with the default name (tap0). Later, when late binding discovers > the actual template interface, we now rename the device to match it. > > This ensures the namespace interface has the expected name, matching > the discovered host interface. > > Key changes: > - Add nl_link_rename() function to rename network interfaces > - When late binding triggers with the default TAP name, bring it > down, rename it to match the discovered interface, then bring it up > > Signed-off-by: Jon Maloy > --- > netlink.c | 37 +++++++++++++++++++++++++++++++++++++ > tap.c | 27 +++++++++++++++++++++++++++ > tap.h | 1 + > 3 files changed, 65 insertions(+) > > diff --git a/netlink.c b/netlink.c > index de04fb7..71089ab 100644 > --- a/netlink.c > +++ b/netlink.c > @@ -44,6 +44,8 @@ > /* Default namespace interface name from conf.c */ > extern const char *pasta_default_ifn; > > +static int nl_link_rename(int s, unsigned int ifi, const char *name); > + > /* Same as RTA_NEXT() but for nexthops: RTNH_NEXT() doesn't take 'attrlen' */ > #define RTNH_NEXT_AND_DEC(rtnh, attrlen) \ > ((attrlen) -= RTNH_ALIGN((rtnh)->rtnh_len), RTNH_NEXT(rtnh)) > @@ -315,6 +317,14 @@ static void nl_linkaddr_host_msg_read(struct ctx *c, const struct nlmsghdr *nh) > } > late_binding = true; > > + /* Rename interface if it is still using default name */ > + if (is_default && strcmp(ifname, pasta_default_ifn)) { > + nl_link_set_flags(nl_sock_ns, c->pasta_ifi, > + 0, IFF_UP); > + nl_link_rename(nl_sock_ns, c->pasta_ifi, ifname); > + debug("Renamed tap: %s -> %s", > + pasta_default_ifn, ifname); > + } > if (is_default) > snprintf(c->pasta_ifn, sizeof(c->pasta_ifn), > "%s", ifname); > @@ -1943,6 +1953,33 @@ int nl_link_set_flags(int s, unsigned int ifi, > return nl_do(s, &req, RTM_NEWLINK, 0, sizeof(req)); > } > > +/** > + * nl_link_rename() - Rename a network interface > + * @s: Netlink socket > + * @ifi: Interface index > + * @name: New interface name > + * > + * Return: 0 on success, negative error code on failure > + */ > +static int nl_link_rename(int s, unsigned int ifi, const char *name) > +{ > + struct req_t { > + struct nlmsghdr nlh; > + struct ifinfomsg ifm; > + struct rtattr rta; > + char name[IFNAMSIZ]; > + } req = { > + .ifm.ifi_family = AF_UNSPEC, > + .ifm.ifi_index = ifi, > + .rta.rta_type = IFLA_IFNAME, > + .rta.rta_len = RTA_LENGTH(IFNAMSIZ), > + }; > + > + snprintf(req.name, IFNAMSIZ, "%s", name); > + > + return nl_do(s, &req, RTM_NEWLINK, 0, sizeof(req)); > +} > + > /** > * nl_neigh_msg_read() - Interpret a neighbour state message from netlink > * @c: Execution context > diff --git a/tap.c b/tap.c > index a2a4459..cd59160 100644 > --- a/tap.c > +++ b/tap.c > @@ -1502,6 +1502,33 @@ static void tap_sock_tun_init(struct ctx *c) > tap_start_connection(c); > } > > +/** > + * tap_backend_init_late() - Create tap device for late binding > + * @c: Execution context > + * > + * Called when late binding discovers the template interface name. > + * Creates the TAP device with the discovered name. > + */ > +void tap_backend_init_late(struct ctx *c) Uh... why would you need a second tap device? Also this function doesn't seem to be called. > +{ > + if (c->mode != MODE_PASTA || c->fd_tap != -1) > + return; > + > + if (!*c->pasta_ifn) { > + warn("%s called with empty pasta_ifn", __func__); > + return; > + } > + > + NS_CALL(tap_ns_tun, c); > + if (c->fd_tap == -1) { > + err("Failed to set up tap device in namespace"); > + return; > + } > + > + tap_start_connection(c); > + info("Created tap device %s for late binding", c->pasta_ifn); > +} > + > /** > * tap_sock_update_pool() - Set the buffer base and size for the pool of packets > * @base: Buffer base > diff --git a/tap.h b/tap.h > index ee22a9d..b41eae9 100644 > --- a/tap.h > +++ b/tap.h > @@ -118,6 +118,7 @@ void tap_handler_passt(struct ctx *c, uint32_t events, > int tap_sock_unix_open(char *sock_path); > void tap_sock_reset(struct ctx *c); > void tap_backend_init(struct ctx *c); > +void tap_backend_init_late(struct ctx *c); > void tap_flush_pools(void); > void tap_handler(struct ctx *c, const struct timespec *now); > void tap_add_packet(struct ctx *c, struct iov_tail *data, > -- > 2.51.1 > -- 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