Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F133236830
D4111.id10059.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D4111.id10059.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
@@ -143,6 +143,7 @@
struct ifnet *ifp, int bridged, struct llentry *la);
static void arp_mark_lle_reachable(struct llentry *la);
+static eventhandler_tag ifnet_link_event_eh;
static const struct netisr_handler arp_nh = {
.nh_name = "arp",
@@ -1151,9 +1152,40 @@
}
static 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);
+ }
+}
+
+static void
+arp_ifnet_link_event(void *arg __unused, struct ifnet *ifp, int linkstate)
+{
+
+ if (linkstate == LINK_STATE_UP)
+ arp_notify(ifp);
+}
+
+static void
arp_init(void)
{
netisr_register(&arp_nh);
+
+ if (IS_DEFAULT_VNET(curvnet)) {
+ ifnet_link_event_eh = 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
Sat, Oct 25, 5:25 AM (16 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24162240
Default Alt Text
D4111.id10059.diff (4 KB)
Attached To
Mode
D4111: Fix lagg failover mode caused by missing node notifications
Attached
Detach File
Event Timeline
Log In to Comment