]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Abstract mac neigh installation into it's own function
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 19 Sep 2018 15:02:42 +0000 (11:02 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 19 Sep 2018 15:25:22 +0000 (11:25 -0400)
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>
zebra/interface.c
zebra/interface.h

index ca90c18cf2c89ef7fe21bfbc6931026de7c4cf89..131b8598b039f91478feabcc6a17b6076efab040 100644 (file)
@@ -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)) {
index 02a05e6146399c5b53412baad44241dcf24d3b5c..b632d25c2a19404b027b4d5d8f8a7625c377be18 100644 (file)
@@ -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);