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;
}
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
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)
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;
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"));
+}
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 */