summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorknakahara <knakahara@NetBSD.org>2022-11-25 08:39:32 +0000
committerknakahara <knakahara@NetBSD.org>2022-11-25 08:39:32 +0000
commitf7423a12d738c31ff3556c05a103f139b638697f (patch)
treef1c3cec4db409c21c37b340c1ca08d2f90b37733 /sys/netinet
parentea2fb4985015c4b8ee9ac2df77160c23e87c01d5 (diff)
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.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 533cd1f4fd3..5b00e80e4b3 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -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
*/