git: b8103ca76de0 - main - netinet: get interface event notifications directly via EVENTHANDLER(9)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 11 Aug 2022 16:20:10 UTC
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 */