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
This commit is contained in:
parent
78d7704b7c
commit
b8103ca76d
14
sys/net/if.c
14
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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user