Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Aug 2022 16:20:10 GMT
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: b8103ca76de0 - main - netinet: get interface event notifications directly via EVENTHANDLER(9)
Message-ID:  <202208111620.27BGKAJW045171@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=b8103ca76de09414775aa2eaca7b0e1bca59136c

commit b8103ca76de09414775aa2eaca7b0e1bca59136c
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-08-11 16:19:36 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-08-11 16:19:36 +0000

    netinet: get interface event notifications directly via EVENTHANDLER(9)
    
    The old mechanism of getting them via domains/protocols control input
    is a relict from the previous century, when nothing like EVENTHANDLER(9)
    existed yet.  Retire PRC_IFDOWN/PRC_IFUP as netinet was the only one
    to use them.
    
    Reviewed by:            melifaro
    Differential revision:  https://reviews.freebsd.org/D36116
---
 sys/net/if.c         | 14 -------------
 sys/netinet/in.c     | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/netinet/in_var.h |  1 -
 sys/netinet/raw_ip.c | 53 ------------------------------------------------
 sys/sys/protosw.h    |  2 --
 5 files changed, 56 insertions(+), 71 deletions(-)

diff --git a/sys/net/if.c b/sys/net/if.c
index 24a97329d232..906f2256dd54 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -2132,18 +2132,11 @@ link_init_sdl(struct ifnet *ifp, struct sockaddr *paddr, u_char iftype)
 static void
 if_unroute(struct ifnet *ifp, int flag, int fam)
 {
-	struct ifaddr *ifa;
-	struct epoch_tracker et;
 
 	KASSERT(flag == IFF_UP, ("if_unroute: flag != IFF_UP"));
 
 	ifp->if_flags &= ~flag;
 	getmicrotime(&ifp->if_lastchange);
-	NET_EPOCH_ENTER(et);
-	CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
-		if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))
-			pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
-	NET_EPOCH_EXIT(et);
 	ifp->if_qflush(ifp);
 
 	if (ifp->if_carp)
@@ -2158,18 +2151,11 @@ if_unroute(struct ifnet *ifp, int flag, int fam)
 static void
 if_route(struct ifnet *ifp, int flag, int fam)
 {
-	struct ifaddr *ifa;
-	struct epoch_tracker et;
 
 	KASSERT(flag == IFF_UP, ("if_route: flag != IFF_UP"));
 
 	ifp->if_flags |= flag;
 	getmicrotime(&ifp->if_lastchange);
-	NET_EPOCH_ENTER(et);
-	CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
-		if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))
-			pfctlinput(PRC_IFUP, ifa->ifa_addr);
-	NET_EPOCH_EXIT(et);
 	if (ifp->if_carp)
 		(*carp_linkstate_p)(ifp);
 	rt_ifmsg(ifp);
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 1c44623bdec1..e394af68ac23 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -954,7 +954,7 @@ ia_getrtprefix(const struct in_ifaddr *ia, struct in_addr *prefix, struct in_add
  * Adds or delete interface "prefix" route corresponding to @ifa.
  *  Returns 0 on success or errno.
  */
-int
+static int
 in_handle_ifaddr_route(int cmd, struct in_ifaddr *ia)
 {
 	struct ifaddr *ifa = &ia->ia_ifa;
@@ -1303,6 +1303,61 @@ in_ifdetach(struct ifnet *ifp)
 	inm_release_wait(NULL);
 }
 
+static void
+in_ifnet_event(void *arg __unused, struct ifnet *ifp, int event)
+{
+	struct epoch_tracker et;
+	struct ifaddr *ifa;
+	struct in_ifaddr *ia;
+	int error;
+
+	NET_EPOCH_ENTER(et);
+	switch (event) {
+	case IFNET_EVENT_DOWN:
+		CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+			if (ifa->ifa_addr->sa_family != AF_INET)
+				continue;
+			ia = (struct in_ifaddr *)ifa;
+			if ((ia->ia_flags & IFA_ROUTE) == 0)
+				continue;
+			ifa_ref(ifa);
+			/*
+			 * in_scrubprefix() kills the interface route.
+			 */
+			in_scrubprefix(ia, 0);
+			/*
+			 * in_ifadown gets rid of all the rest of the
+			 * routes.  This is not quite the right thing
+			 * to do, but at least if we are running a
+			 * routing process they will come back.
+			 */
+			in_ifadown(ifa, 0);
+			ifa_free(ifa);
+		}
+		break;
+
+	case IFNET_EVENT_UP:
+		CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+			if (ifa->ifa_addr->sa_family != AF_INET)
+				continue;
+			ia = (struct in_ifaddr *)ifa;
+			if (ia->ia_flags & IFA_ROUTE)
+				continue;
+			ifa_ref(ifa);
+			error = ifa_del_loopback_route(ifa, ifa->ifa_addr);
+			rt_addrmsg(RTM_ADD, ifa, ifa->ifa_ifp->if_fib);
+			error = in_handle_ifaddr_route(RTM_ADD, ia);
+			if (error == 0)
+				ia->ia_flags |= IFA_ROUTE;
+			error = ifa_add_loopback_route(ifa, ifa->ifa_addr);
+			ifa_free(ifa);
+		}
+		break;
+	}
+	NET_EPOCH_EXIT(et);
+}
+EVENTHANDLER_DEFINE(ifnet_event, in_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
+
 /*
  * Delete all IPv4 multicast address records, and associated link-layer
  * multicast address records, associated with ifp.
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index a6902159e739..c3f936b444dc 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -449,7 +449,6 @@ int	in_control(struct socket *, u_long, caddr_t, struct ifnet *,
 int	in_addprefix(struct in_ifaddr *);
 int	in_scrubprefix(struct in_ifaddr *, u_int);
 void	in_ifscrub_all(void);
-int	in_handle_ifaddr_route(int, struct in_ifaddr *);
 void	ip_input(struct mbuf *);
 void	ip_direct_input(struct mbuf *);
 void	in_ifadown(struct ifaddr *ifa, int);
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 1f631e108a49..0bd874c717e6 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -769,64 +769,11 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
 	return (error);
 }
 
-/*
- * This function exists solely to receive the PRC_IFDOWN messages which are
- * sent by if_down().  It looks for an ifaddr whose ifa_addr is sa, and calls
- * in_ifadown() to remove all routes corresponding to that address.  It also
- * receives the PRC_IFUP messages from if_up() and reinstalls the interface
- * routes.
- */
 void
 rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 {
-	struct in_ifaddr *ia;
-	int err;
-
-	NET_EPOCH_ASSERT();
 
 	switch (cmd) {
-	case PRC_IFDOWN:
-		CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
-			if (ia->ia_ifa.ifa_addr == sa
-			    && (ia->ia_flags & IFA_ROUTE)) {
-				ifa_ref(&ia->ia_ifa);
-				/*
-				 * in_scrubprefix() kills the interface route.
-				 */
-				in_scrubprefix(ia, 0);
-				/*
-				 * in_ifadown gets rid of all the rest of the
-				 * routes.  This is not quite the right thing
-				 * to do, but at least if we are running a
-				 * routing process they will come back.
-				 */
-				in_ifadown(&ia->ia_ifa, 0);
-				ifa_free(&ia->ia_ifa);
-				break;
-			}
-		}
-		break;
-
-	case PRC_IFUP:
-		CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
-			if (ia->ia_ifa.ifa_addr == sa)
-				break;
-		}
-		if (ia == NULL || (ia->ia_flags & IFA_ROUTE))
-			return;
-		ifa_ref(&ia->ia_ifa);
-
-		err = ifa_del_loopback_route((struct ifaddr *)ia, sa);
-
-		rt_addrmsg(RTM_ADD, &ia->ia_ifa, ia->ia_ifp->if_fib);
-		err = in_handle_ifaddr_route(RTM_ADD, ia);
-		if (err == 0)
-			ia->ia_flags |= IFA_ROUTE;
-
-		err = ifa_add_loopback_route((struct ifaddr *)ia, sa);
-
-		ifa_free(&ia->ia_ifa);
-		break;
 #if defined(IPSEC) || defined(IPSEC_SUPPORT)
 	case PRC_MSGSIZE:
 		if (IPSEC_ENABLED(ipv4))
diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h
index 26cd1bc3fc16..85761583c30a 100644
--- a/sys/sys/protosw.h
+++ b/sys/sys/protosw.h
@@ -282,9 +282,7 @@ int	pru_sopoll_notsupp(struct socket *so, int events, struct ucred *cred,
  * where cmd is one of the commands below, sa is a pointer to a sockaddr,
  * and arg is a `void *' argument used within a protocol family.
  */
-#define	PRC_IFDOWN		0	/* interface transition */
 #define	PRC_ROUTEDEAD		1	/* select new route if possible ??? */
-#define	PRC_IFUP		2	/* interface has come back up */
 /* was	PRC_QUENCH2		3	DEC congestion bit says slow down */
 /* was	PRC_QUENCH		4	Deprecated by RFC 6633 */
 #define	PRC_MSGSIZE		5	/* message size forced drop */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202208111620.27BGKAJW045171>