Module Name: src Committed By: knakahara Date: Fri Nov 25 08:39:32 UTC 2022
Modified Files: src/sys/net: if.h route.c src/sys/netinet: in.c Log Message: Support explicit unnumbered interface. Currently, NetBSD supports implicit unnumbered interface by setting the same IP address to two interfaces. However, such interface is not treated as unnumbered when one of the interfaces is being changed and has been changed IP address. That behavior can be harmful for some routing daemons. To generate a diff of this commit: cvs rdiff -u -r1.303 -r1.304 src/sys/net/if.h cvs rdiff -u -r1.234 -r1.235 src/sys/net/route.c cvs rdiff -u -r1.246 -r1.247 src/sys/netinet/in.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if.h diff -u src/sys/net/if.h:1.303 src/sys/net/if.h:1.304 --- src/sys/net/if.h:1.303 Mon Oct 24 08:11:25 2022 +++ src/sys/net/if.h Fri Nov 25 08:39:32 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: if.h,v 1.303 2022/10/24 08:11:25 msaitoh Exp $ */ +/* $NetBSD: if.h,v 1.304 2022/11/25 08:39:32 knakahara Exp $ */ /*- * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -447,7 +447,15 @@ typedef struct ifnet { #define IFF_DEBUG 0x0004 /* turn on debugging */ #define IFF_LOOPBACK 0x0008 /* is a loopback net */ #define IFF_POINTOPOINT 0x0010 /* interface is point-to-point link */ +#if 0 /* 0x0020 was IFF_NOTRAILERS */ +#else +/* + * sys/compat/svr4 is remvoed on 19 Dec 2018. + * And then, IFF_NOTRAILERS itself is removed by if.h:r1.268 on 5 Feb 2019. + */ +#define IFF_UNNUMBERED 0x0020 /* explicit unnumbered */ +#endif #define IFF_RUNNING 0x0040 /* resources allocated */ #define IFF_NOARP 0x0080 /* no address resolution protocol */ #define IFF_PROMISC 0x0100 /* receive all packets */ @@ -599,7 +607,7 @@ if_start_lock(struct ifnet *ifp) #endif /* _KERNEL */ #define IFFBITS \ - "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT" \ + "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6UNNUMBERED" \ "\7RUNNING\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX" \ "\15LINK0\16LINK1\17LINK2\20MULTICAST" Index: src/sys/net/route.c diff -u src/sys/net/route.c:1.234 src/sys/net/route.c:1.235 --- src/sys/net/route.c:1.234 Tue Sep 20 02:23:37 2022 +++ src/sys/net/route.c Fri Nov 25 08:39:32 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: route.c,v 1.234 2022/09/20 02:23:37 knakahara Exp $ */ +/* $NetBSD: route.c,v 1.235 2022/11/25 08:39:32 knakahara Exp $ */ /*- * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. @@ -97,7 +97,7 @@ #endif #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.234 2022/09/20 02:23:37 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.235 2022/11/25 08:39:32 knakahara Exp $"); #include <sys/param.h> #ifdef RTFLUSH_DEBUG @@ -1367,6 +1367,11 @@ rt_update_get_ifa(const struct rt_addrin ifa = ifa_ifwithnet_psref(info->rti_info[RTAX_IFP], psref); if (ifa == NULL) goto next; + if (ifa->ifa_ifp->if_flags & IFF_UNNUMBERED) { + ifa_release(ifa, psref); + ifa = NULL; + goto next; + } *ifp = ifa->ifa_ifp; if_acquire(*ifp, psref_ifp); if (info->rti_info[RTAX_IFA] == NULL && Index: src/sys/netinet/in.c diff -u src/sys/netinet/in.c:1.246 src/sys/netinet/in.c:1.247 --- src/sys/netinet/in.c:1.246 Sat Nov 19 08:00:51 2022 +++ src/sys/netinet/in.c Fri Nov 25 08:39:32 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: in.c,v 1.246 2022/11/19 08:00:51 yamt Exp $ */ +/* $NetBSD: in.c,v 1.247 2022/11/25 08:39:32 knakahara Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.246 2022/11/19 08:00:51 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.247 2022/11/25 08:39:32 knakahara Exp $"); #include "arp.h" @@ -790,6 +790,10 @@ in_ifaddlocal(struct ifaddr *ifa) struct in_ifaddr *ia; ia = (struct in_ifaddr *)ifa; + if ((ia->ia_ifp->if_flags & IFF_UNNUMBERED)) { + rt_addrmsg(RTM_NEWADDR, ifa); + return; + } if (ia->ia_addr.sin_addr.s_addr == INADDR_ANY || (ia->ia_ifp->if_flags & IFF_POINTOPOINT && in_hosteq(ia->ia_dstaddr.sin_addr, ia->ia_addr.sin_addr))) @@ -813,10 +817,17 @@ in_ifremlocal(struct ifaddr *ifa) int bound = curlwp_bind(); ia = (struct in_ifaddr *)ifa; + if ((ia->ia_ifp->if_flags & IFF_UNNUMBERED)) { + rt_addrmsg(RTM_DELADDR, ifa); + goto out; + } /* Delete the entry if exactly one ifaddr matches the * address, ifa->ifa_addr. */ s = pserialize_read_enter(); IN_ADDRLIST_READER_FOREACH(p) { + if ((p->ia_ifp->if_flags & IFF_UNNUMBERED)) + continue; + if (!in_hosteq(p->ia_addr.sin_addr, ia->ia_addr.sin_addr)) continue; if (p->ia_ifp != ia->ia_ifp) @@ -1323,6 +1334,9 @@ in_addprefix(struct in_ifaddr *target, i if (prefix.s_addr != p.s_addr) continue; + if ((ia->ia_ifp->if_flags & IFF_UNNUMBERED)) + continue; + /* * if we got a matching prefix route inserted by other * interface address, we don't need to bother @@ -1339,14 +1353,18 @@ in_addprefix(struct in_ifaddr *target, i /* * noone seem to have prefix route. insert it. */ - error = rtinit(&target->ia_ifa, RTM_ADD, flags); - if (error == 0) - target->ia_flags |= IFA_ROUTE; - else if (error == EEXIST) { - /* - * the fact the route already exists is not an error. - */ + if (target->ia_ifa.ifa_ifp->if_flags & IFF_UNNUMBERED) { error = 0; + } else { + error = rtinit(&target->ia_ifa, RTM_ADD, flags); + if (error == 0) + target->ia_flags |= IFA_ROUTE; + else if (error == EEXIST) { + /* + * the fact the route already exists is not an error. + */ + error = 0; + } } return error; } @@ -1399,6 +1417,9 @@ in_scrubprefix(struct in_ifaddr *target) if (prefix.s_addr != p.s_addr) continue; + if ((ia->ia_ifp->if_flags & IFF_UNNUMBERED)) + continue; + /* * if we got a matching prefix route, move IFA_ROUTE to him */