Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153547849
D4111.id10060.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D4111.id10060.diff
View Options
Index: sys/net/if.h
===================================================================
--- sys/net/if.h
+++ sys/net/if.h
@@ -181,6 +181,7 @@
#define LINK_STATE_UNKNOWN 0 /* link invalid/unknown */
#define LINK_STATE_DOWN 1 /* link is down */
#define LINK_STATE_UP 2 /* link is up */
+#define LINK_STATE_UP_FORCE 3 /* link is up force event */
/*
* Some convenience macros used for setting ifi_baudrate.
Index: sys/net/if.c
===================================================================
--- sys/net/if.c
+++ sys/net/if.c
@@ -2028,6 +2028,9 @@
if (ifp->if_link_state == link_state)
return;
+ if (link_state == LINK_STATE_UP_FORCE)
+ link_state = LINK_STATE_UP;
+
ifp->if_link_state = link_state;
taskqueue_enqueue(taskqueue_swi, &ifp->if_linktask);
Index: sys/net/if_lagg.c
===================================================================
--- sys/net/if_lagg.c
+++ sys/net/if_lagg.c
@@ -1775,7 +1775,12 @@
/* Our link is considered up if at least one of our ports is active */
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
if (lp->lp_ifp->if_link_state == LINK_STATE_UP) {
- new_link = LINK_STATE_UP;
+ /*
+ * Force up to ensure ifnet_link_event is generated
+ * allowing IP protocols to notify other nodes of
+ * potential address move.
+ */
+ new_link = LINK_STATE_UP_FORCE;
break;
}
}
@@ -1818,7 +1823,7 @@
LAGG_WUNLOCK(sc);
}
-struct lagg_port *
+static __noinline struct lagg_port *
lagg_link_active(struct lagg_softc *sc, struct lagg_port *lp)
{
struct lagg_port *lp_next, *rval = NULL;
Index: sys/netinet/if_ether.c
===================================================================
--- sys/netinet/if_ether.c
+++ sys/netinet/if_ether.c
@@ -145,6 +145,7 @@
static void arp_iflladdr(void *arg __unused, struct ifnet *ifp);
static eventhandler_tag iflladdr_tag;
+static eventhandler_tag ifnet_link_event_tag;
static const struct netisr_handler arp_nh = {
.nh_name = "arp",
@@ -1152,30 +1153,43 @@
ifa->ifa_rtrequest = NULL;
}
+static __noinline void
+arp_notify(struct ifnet *ifp)
+{
+ struct ifaddr *ifa;
+
+ if (!(ifp->if_flags & IFF_UP) || (ifp->if_flags & IFF_NOARP))
+ return;
+
+ /*
+ * Send gratuitous ARPs to notify other nodes about potential address
+ * move.
+ */
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr->sa_family == AF_INET)
+ arp_ifinit(ifp, ifa);
+ }
+}
+
/*
- * Sends gratuitous ARPs for each ifaddr to notify other
- * nodes about the address change.
+ * A handler for interface linkstate change events.
*/
-static __noinline void
-arp_handle_ifllchange(struct ifnet *ifp)
+static void
+arp_ifnet_link_event(void *arg __unused, struct ifnet *ifp, int linkstate)
{
- struct ifaddr *ifa;
- TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- if (ifa->ifa_addr->sa_family == AF_INET)
- arp_ifinit(ifp, ifa);
- }
+ if (linkstate == LINK_STATE_UP)
+ arp_notify(ifp);
}
/*
- * A handler for interface link layer address change event.
+ * A handler for interface link layer address change events.
*/
static __noinline void
arp_iflladdr(void *arg __unused, struct ifnet *ifp)
{
- if ((ifp->if_flags & IFF_UP) != 0)
- arp_handle_ifllchange(ifp);
+ arp_notify(ifp);
}
static void
@@ -1183,8 +1197,12 @@
{
netisr_register(&arp_nh);
- if (IS_DEFAULT_VNET(curvnet))
+
+ if (IS_DEFAULT_VNET(curvnet)) {
iflladdr_tag = EVENTHANDLER_REGISTER(iflladdr_event,
arp_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
+ ifnet_link_event_tag = EVENTHANDLER_REGISTER(ifnet_link_event,
+ arp_ifnet_link_event, 0, EVENTHANDLER_PRI_ANY);
+ }
}
SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0);
Index: sys/netinet6/in6.c
===================================================================
--- sys/netinet6/in6.c
+++ sys/netinet6/in6.c
@@ -113,7 +113,7 @@
#define V_icmp6_nodeinfo_oldmcprefix VNET(icmp6_nodeinfo_oldmcprefix)
/*
- * Definitions of some costant IP6 addresses.
+ * Definitions of some constant IP6 addresses.
*/
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
Index: sys/netinet6/nd6.c
===================================================================
--- sys/netinet6/nd6.c
+++ sys/netinet6/nd6.c
@@ -112,6 +112,7 @@
#endif
static eventhandler_tag lle_event_eh;
+static eventhandler_tag ifnet_link_event_eh;
/* for debugging? */
#if 0
@@ -196,6 +197,30 @@
type == RTM_ADD ? RTF_UP: 0), 0, RT_DEFAULT_FIB);
}
+static void
+nd6_ifnet_link_event(void *arg __unused, struct ifnet *ifp, int linkstate)
+{
+ struct ifaddr *ifa;
+ struct in6_addr in6_all;
+
+ if (!(ifp->if_flags & IFF_UP) || linkstate != LINK_STATE_UP)
+ return;
+
+ /*
+ * Send neighbor advertisements to notify other nodes about potential
+ * address move.
+ */
+ in6_all = in6addr_linklocal_allnodes;
+
+ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr->sa_family == AF_INET6) {
+ nd6_na_output(ifp, &in6_all, IFA_IN6(ifa),
+ (((struct in6_ifaddr *)ifa)->ia6_flags &
+ IN6_IFF_ANYCAST) ? 0 : ND_NA_FLAG_OVERRIDE, 1, NULL);
+ }
+ }
+}
+
void
nd6_init(void)
{
@@ -211,9 +236,12 @@
nd6_slowtimo, curvnet);
nd6_dad_init();
- if (IS_DEFAULT_VNET(curvnet))
+ if (IS_DEFAULT_VNET(curvnet)) {
lle_event_eh = EVENTHANDLER_REGISTER(lle_event, nd6_lle_event,
NULL, EVENTHANDLER_PRI_ANY);
+ ifnet_link_event_eh = EVENTHANDLER_REGISTER(ifnet_link_event,
+ nd6_ifnet_link_event, NULL, EVENTHANDLER_PRI_ANY);
+ }
}
#ifdef VIMAGE
@@ -223,8 +251,10 @@
callout_drain(&V_nd6_slowtimo_ch);
callout_drain(&V_nd6_timer_ch);
- if (IS_DEFAULT_VNET(curvnet))
+ if (IS_DEFAULT_VNET(curvnet)) {
EVENTHANDLER_DEREGISTER(lle_event, lle_event_eh);
+ EVENTHANDLER_DEREGISTER(ifnet_link_event, ifnet_link_event_eh);
+ }
}
#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 22, 7:53 PM (2 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31997011
Default Alt Text
D4111.id10060.diff (5 KB)
Attached To
Mode
D4111: Fix lagg failover mode caused by missing node notifications
Attached
Detach File
Event Timeline
Log In to Comment