Use lladdr_event to propagate gratiotus arp.
Differential Revision: https://reviews.freebsd.org/D4019
This commit is contained in:
parent
042c83fdc8
commit
b13c5b5db2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=290603
13
sys/net/if.c
13
sys/net/if.c
@ -2512,7 +2512,8 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
|
|||||||
return (error);
|
return (error);
|
||||||
error = if_setlladdr(ifp,
|
error = if_setlladdr(ifp,
|
||||||
ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len);
|
ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len);
|
||||||
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
|
if (error == 0)
|
||||||
|
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIOCAIFGROUP:
|
case SIOCAIFGROUP:
|
||||||
@ -3375,16 +3376,6 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
|
|||||||
ifr.ifr_flagshigh = ifp->if_flags >> 16;
|
ifr.ifr_flagshigh = ifp->if_flags >> 16;
|
||||||
(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr);
|
(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr);
|
||||||
}
|
}
|
||||||
#ifdef INET
|
|
||||||
/*
|
|
||||||
* Also send gratuitous ARPs to notify other nodes about
|
|
||||||
* the address change.
|
|
||||||
*/
|
|
||||||
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
|
||||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
|
||||||
arp_ifinit(ifp, ifa);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -523,7 +523,7 @@ vlan_iflladdr(void *arg __unused, struct ifnet *ifp)
|
|||||||
#ifndef VLAN_ARRAY
|
#ifndef VLAN_ARRAY
|
||||||
struct ifvlan *next;
|
struct ifvlan *next;
|
||||||
#endif
|
#endif
|
||||||
int i;
|
int error, i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if it's a trunk interface first of all
|
* Check if it's a trunk interface first of all
|
||||||
@ -544,8 +544,11 @@ vlan_iflladdr(void *arg __unused, struct ifnet *ifp)
|
|||||||
LIST_FOREACH_SAFE(ifv, &ifp->if_vlantrunk->hash[i], ifv_list, next) {
|
LIST_FOREACH_SAFE(ifv, &ifp->if_vlantrunk->hash[i], ifv_list, next) {
|
||||||
#endif /* VLAN_ARRAY */
|
#endif /* VLAN_ARRAY */
|
||||||
VLAN_UNLOCK();
|
VLAN_UNLOCK();
|
||||||
if_setlladdr(ifv->ifv_ifp, IF_LLADDR(ifp),
|
error = if_setlladdr(ifv->ifv_ifp, IF_LLADDR(ifp),
|
||||||
ifp->if_addrlen);
|
ifp->if_addrlen);
|
||||||
|
if (error == 0)
|
||||||
|
EVENTHANDLER_INVOKE(iflladdr_event,
|
||||||
|
ifv->ifv_ifp);
|
||||||
VLAN_LOCK();
|
VLAN_LOCK();
|
||||||
}
|
}
|
||||||
VLAN_UNLOCK();
|
VLAN_UNLOCK();
|
||||||
|
@ -489,7 +489,8 @@ ng_eiface_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
|||||||
}
|
}
|
||||||
error = if_setlladdr(priv->ifp,
|
error = if_setlladdr(priv->ifp,
|
||||||
(u_char *)msg->data, ETHER_ADDR_LEN);
|
(u_char *)msg->data, ETHER_ADDR_LEN);
|
||||||
EVENTHANDLER_INVOKE(iflladdr_event, priv->ifp);
|
if (error == 0)
|
||||||
|
EVENTHANDLER_INVOKE(iflladdr_event, priv->ifp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,7 +534,8 @@ ng_ether_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
|||||||
}
|
}
|
||||||
error = if_setlladdr(priv->ifp,
|
error = if_setlladdr(priv->ifp,
|
||||||
(u_char *)msg->data, ETHER_ADDR_LEN);
|
(u_char *)msg->data, ETHER_ADDR_LEN);
|
||||||
EVENTHANDLER_INVOKE(iflladdr_event, priv->ifp);
|
if (error == 0)
|
||||||
|
EVENTHANDLER_INVOKE(iflladdr_event, priv->ifp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NGM_ETHER_GET_PROMISC:
|
case NGM_ETHER_GET_PROMISC:
|
||||||
|
@ -142,7 +142,9 @@ static void in_arpinput(struct mbuf *);
|
|||||||
static void arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr,
|
static void arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr,
|
||||||
struct ifnet *ifp, int bridged, struct llentry *la);
|
struct ifnet *ifp, int bridged, struct llentry *la);
|
||||||
static void arp_mark_lle_reachable(struct llentry *la);
|
static void arp_mark_lle_reachable(struct llentry *la);
|
||||||
|
static void arp_iflladdr(void *arg __unused, struct ifnet *ifp);
|
||||||
|
|
||||||
|
static eventhandler_tag iflladdr_tag;
|
||||||
|
|
||||||
static const struct netisr_handler arp_nh = {
|
static const struct netisr_handler arp_nh = {
|
||||||
.nh_name = "arp",
|
.nh_name = "arp",
|
||||||
@ -1150,10 +1152,39 @@ arp_ifinit2(struct ifnet *ifp, struct ifaddr *ifa, u_char *enaddr)
|
|||||||
ifa->ifa_rtrequest = NULL;
|
ifa->ifa_rtrequest = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sends gratuitous ARPs for each ifaddr to notify other
|
||||||
|
* nodes about the address change.
|
||||||
|
*/
|
||||||
|
static __noinline void
|
||||||
|
arp_handle_ifllchange(struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
struct ifaddr *ifa;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
|
||||||
|
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||||
|
arp_ifinit(ifp, ifa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A handler for interface link layer address change event.
|
||||||
|
*/
|
||||||
|
static __noinline void
|
||||||
|
arp_iflladdr(void *arg __unused, struct ifnet *ifp)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((ifp->if_flags & IFF_UP) != 0)
|
||||||
|
arp_handle_ifllchange(ifp);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
arp_init(void)
|
arp_init(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
netisr_register(&arp_nh);
|
netisr_register(&arp_nh);
|
||||||
|
if (IS_DEFAULT_VNET(curvnet))
|
||||||
|
iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event,
|
||||||
|
arp_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
|
||||||
}
|
}
|
||||||
SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);
|
SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user