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.
This commit is contained in:
knakahara 2022-11-25 08:39:32 +00:00
parent 5294306f07
commit 7cb557b6cc
3 changed files with 47 additions and 13 deletions

View File

@ -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"

View File

@ -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_addrinfo *info, const struct rtentry *rt,
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 &&

View File

@ -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, int flags)
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, int flags)
/*
* 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
*/