Page MenuHomeFreeBSD

D4111.id10046.diff
No OneTemporary

D4111.id10046.diff

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/raw_ip.c
===================================================================
--- sys/netinet/raw_ip.c
+++ sys/netinet/raw_ip.c
@@ -89,6 +89,9 @@
#define V_ripcb VNET(ripcb)
#define V_ripcbinfo VNET(ripcbinfo)
+static eventhandler_tag maxsockets_change_eh;
+static eventhandler_tag ifnet_link_event_eh;
+
/*
* Control and data hooks for ipfw, dummynet, divert and so on.
* The data hooks are not used here but it is convenient
@@ -203,6 +206,25 @@
return (0);
}
+static void
+rip_ifnet_link_event(void *arg __unused, struct ifnet *ifp, int linkstate)
+{
+ struct ifaddr *ifa;
+
+ if (linkstate != LINK_STATE_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);
+ }
+ }
+}
+
void
rip_init(void)
{
@@ -210,8 +232,14 @@
in_pcbinfo_init(&V_ripcbinfo, "rip", &V_ripcb, INP_PCBHASH_RAW_SIZE,
1, "ripcb", rip_inpcb_init, NULL, UMA_ZONE_NOFREE,
IPI_HASHFIELDS_NONE);
- EVENTHANDLER_REGISTER(maxsockets_change, rip_zone_change, NULL,
- EVENTHANDLER_PRI_ANY);
+
+ maxsockets_change_eh = EVENTHANDLER_REGISTER(maxsockets_change,
+ rip_zone_change, NULL, EVENTHANDLER_PRI_ANY);
+
+ if (IS_DEFAULT_VNET(curvnet)) {
+ ifnet_link_event_eh = EVENTHANDLER_REGISTER(ifnet_link_event,
+ rip_ifnet_link_event, 0, EVENTHANDLER_PRI_ANY);
+ }
}
#ifdef VIMAGE
@@ -220,6 +248,12 @@
{
in_pcbinfo_destroy(&V_ripcbinfo);
+
+ EVENTHANDLER_DEREGISTER(maxsockets_change, maxsockets_change_eh);
+
+ if (IS_DEFAULT_VNET(curvnet)) {
+ EVENTHANDLER_DEREGISTER(ifnet_link_event, ifnet_link_event_eh);
+ }
}
#endif
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,29 @@
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 (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),
+ ND_NA_FLAG_OVERRIDE, 1, NULL);
+ }
+ }
+}
+
void
nd6_init(void)
{
@@ -211,9 +235,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 +250,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

Mime Type
text/plain
Expires
Wed, Apr 22, 7:02 PM (4 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31994820
Default Alt Text
D4111.id10046.diff (5 KB)

Event Timeline