summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2018-09-19 11:02:42 -0400
committerDonald Sharp <sharpd@cumulusnetworks.com>2018-09-19 11:25:22 -0400
commitee98d1f11c940d5dc62509bc2cb9ca0f6ae4117d (patch)
tree0b6c57955f379d2a60b038a68655998fbe91bf80
parent19f2b5e8751ef6aca63896ac73900b5edc31fc62 (diff)
zebra: Abstract mac neigh installation into it's own function
Abstract the mac neigh installation for 169.254.0.1 into it's own function that we can pass the mac address into. This will allow a future commit to use this functionality when we have the appropriate mac address from reading optional attributes of a RA packet. Signed-off-by: Donald Sharp <sharpd@cumuusnetworks.com>
-rw-r--r--zebra/interface.c45
-rw-r--r--zebra/interface.h5
2 files changed, 43 insertions, 7 deletions
diff --git a/zebra/interface.c b/zebra/interface.c
index ca90c18cf2..131b8598b0 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -136,6 +136,8 @@ static int if_zebra_new_hook(struct interface *ifp)
}
#endif /* HAVE_RTADV */
+ memset(&zebra_if->neigh_mac[0], 0, 6);
+
/* Initialize installed address chains tree. */
zebra_if->ipv4_subnets =
route_table_init_with_delegate(&zebra_if_table_delegate);
@@ -802,19 +804,32 @@ static void ipv6_ll_address_to_mac(struct in6_addr *address, uint8_t *mac)
mac[5] = address->s6_addr[15];
}
-void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
- struct in6_addr *address, int add)
+static bool mac_is_same(char *mac1, char *mac2)
+{
+ if (mac1[0] == mac2[0] &&
+ mac1[1] == mac2[1] &&
+ mac1[2] == mac2[2] &&
+ mac1[3] == mac2[3] &&
+ mac1[4] == mac2[4] &&
+ mac1[5] == mac2[5])
+ return true;
+ else
+ return false;
+}
+
+void if_nbr_mac_to_ipv4ll_neigh_update(struct interface *ifp,
+ char mac[6],
+ struct in6_addr *address,
+ int add)
{
struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id);
struct zebra_if *zif = ifp->info;
char buf[16] = "169.254.0.1";
struct in_addr ipv4_ll;
- char mac[6];
ns_id_t ns_id;
inet_pton(AF_INET, buf, &ipv4_ll);
- ipv6_ll_address_to_mac(address, (uint8_t *)mac);
ns_id = zvrf->zns->ns_id;
/*
@@ -823,10 +838,16 @@ void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
*
* supported message types are RTM_NEWNEIGH and RTM_DELNEIGH
*/
- kernel_neigh_update(0, ifp->ifindex, ipv4_ll.s_addr, mac, 6, ns_id);
+ if (!mac_is_same(zif->neigh_mac, mac)) {
+ kernel_neigh_update(0, ifp->ifindex, ipv4_ll.s_addr,
+ mac, 6, ns_id);
+
+ /* Add arp record */
+ kernel_neigh_update(add, ifp->ifindex, ipv4_ll.s_addr,
+ mac, 6, ns_id);
+ }
- /* Add arp record */
- kernel_neigh_update(add, ifp->ifindex, ipv4_ll.s_addr, mac, 6, ns_id);
+ memcpy(&zif->neigh_mac[0], &mac[0], 6);
/*
* We need to note whether or not we originated a v6
@@ -840,6 +861,16 @@ void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
zvrf->neigh_updates++;
}
+void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
+ struct in6_addr *address, int add)
+{
+
+ char mac[6];
+
+ ipv6_ll_address_to_mac(address, (uint8_t *)mac);
+ if_nbr_mac_to_ipv4ll_neigh_update(ifp, mac, address, add);
+}
+
static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface *ifp)
{
if (listhead(ifp->nbr_connected)) {
diff --git a/zebra/interface.h b/zebra/interface.h
index 02a05e6146..b632d25c2a 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -279,6 +279,7 @@ struct zebra_if {
* for bgp unnumbered?
*/
bool v6_2_v4_ll_neigh_entry;
+ char neigh_mac[6];
struct in6_addr v6_2_v4_ll_addr6;
};
@@ -332,6 +333,10 @@ extern struct interface *if_link_per_ns(struct zebra_ns *, struct interface *);
extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int);
extern void if_unlink_per_ns(struct interface *);
+extern void if_nbr_mac_to_ipv4ll_neigh_update(struct interface *fip,
+ char mac[6],
+ struct in6_addr *address,
+ int add);
extern void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp,
struct in6_addr *address,
int add);