]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Send ARP requests proactively during OSPF Adjacency formation.
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 00:24:41 +0000 (17:24 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 00:24:41 +0000 (17:24 -0700)
Signed-off-by: Ayan Banerjee <ayan@cumulusnetworks.com>
Reviewed-by: JR Rivers <jrrivers@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
ospfd/ospf_nsm.c
ospfd/ospf_packet.c
ospfd/ospf_packet.h

index 0e6814e22b5aa55fc36f4b92aba95104332d8a26..d3266e83557f429e6850bc80c271ebfc99118c2e 100644 (file)
@@ -170,6 +170,10 @@ nsm_packet_received (struct ospf_neighbor *nbr)
   if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma)
     OSPF_POLL_TIMER_OFF (nbr->nbr_nbma->t_poll);
 
+  /* Send proactive ARP requests */
+  if (nbr->state < NSM_Exchange)
+      ospf_proactively_arp (nbr);
+
   return 0;
 }
 
@@ -184,13 +188,22 @@ nsm_start (struct ospf_neighbor *nbr)
   OSPF_NSM_TIMER_ON (nbr->t_inactivity, ospf_inactivity_timer,
                      nbr->v_inactivity);
 
+  /* Send proactive ARP requests */
+  ospf_proactively_arp (nbr);
+
   return 0;
 }
 
 static int
 nsm_twoway_received (struct ospf_neighbor *nbr)
 {
-  return (nsm_should_adj (nbr) ? NSM_ExStart : NSM_TwoWay);
+  int adj = nsm_should_adj (nbr);
+
+  /* Send proactive ARP requests */
+  if (adj)
+     ospf_proactively_arp (nbr);
+
+  return (adj ? NSM_ExStart : NSM_TwoWay);
 }
 
 int
@@ -273,6 +286,9 @@ nsm_negotiation_done (struct ospf_neighbor *nbr)
   struct ospf_lsa *lsa;
   struct route_node *rn;
 
+  /* Send proactive ARP requests */
+  ospf_proactively_arp (nbr);
+
   LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
     ospf_db_summary_add (nbr, lsa);
   LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
@@ -334,7 +350,12 @@ nsm_adj_ok (struct ospf_neighbor *nbr)
   int adj = nsm_should_adj (nbr);
 
   if (nbr->state == NSM_TwoWay && adj == 1)
-    next_state = NSM_ExStart;
+    {
+      next_state = NSM_ExStart;
+
+      /* Send proactive ARP requests */
+      ospf_proactively_arp (nbr);
+    }
   else if (nbr->state >= NSM_ExStart && adj == 0)
     next_state = NSM_TwoWay;
 
index efdf8263b747984e3c70e7648be88e02ba67ace4..4b4a61a6e8a8855de5bfba6c8fea7a8690195975 100644 (file)
@@ -3960,3 +3960,35 @@ ospf_ls_ack_send_delayed (struct ospf_interface *oi)
   while (listcount (oi->ls_ack))
     ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
 }
+
+/*
+ * On pt-to-pt links, all OSPF control packets are sent to the multicast
+ * address. As a result, the kernel does not need to learn the interface
+ * MAC of the OSPF neighbor. However, in our world, this will delay
+ * convergence. Take the case when due to a link flap, all routes now
+ * want to use an interface which was deemed to be costlier prior to this
+ * event. For routes that will be installed, the missing MAC will have
+ * punt-to-CPU set on them. This may overload the CPU control path that
+ * can be avoided if the MAC was known apriori.
+ */
+#define OSPF_PING_NBR_STR_MAX  (8 + 40 + 20)
+void
+ospf_proactively_arp (struct ospf_neighbor *nbr)
+{
+    char ping_nbr[OSPF_PING_NBR_STR_MAX];
+    char *str_ptr;
+    int  ret;
+
+    if (!nbr || !nbr->oi || !nbr->oi->ifp || !nbr->oi->ifp->name)
+       return;
+
+    str_ptr = strcpy (ping_nbr, "ping -c 1 -I ");
+    str_ptr = strcat (str_ptr, nbr->oi->ifp->name);
+    str_ptr = strcat (str_ptr, " ");
+    str_ptr = strcat (str_ptr, inet_ntoa (nbr->address.u.prefix4));
+    str_ptr = strcat (str_ptr, " > /dev/null 2>&1 &");
+    ret = system (ping_nbr);
+    if (IS_DEBUG_OSPF_EVENT)
+       zlog_debug ("Executed %s %s", ping_nbr,
+                   ((ret == 0) ? "successfully" : "but failed"));
+}
index 337686ad886923649af932286ff501db5f01ad5e..60761322df875e2b101f66e7345343eefa39bef7 100644 (file)
@@ -174,4 +174,6 @@ extern int ospf_hello_reply_timer (struct thread *);
 extern const struct message ospf_packet_type_str[];
 extern const size_t ospf_packet_type_str_max;
 
+extern void ospf_proactively_arp (struct ospf_neighbor *);
+
 #endif /* _ZEBRA_OSPF_PACKET_H */