]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: reinstate current bgp best route on an inactive neigh del
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Mon, 14 Jan 2019 23:24:43 +0000 (15:24 -0800)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 25 Jan 2019 19:19:26 +0000 (14:19 -0500)
When an inactive-neigh delete is rxed bgp will not have a local path to
remove (and re-run path selection). Instead it simply re-installs the
current best remote path if any.

Ticket: CM-23018
Testing Done: evpn-min

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
bgpd/bgp_evpn.c
bgpd/bgp_evpn.h
bgpd/bgp_vty.c
bgpd/bgp_zebra.c

index 7e2fa9ea76e1e03d285911db3f46d7b797f30e34..c74d7829bd527f620c5289281b3b89e566d7dda4 100644 (file)
@@ -1685,6 +1685,27 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
        return route_change;
 }
 
+static void evpn_zebra_reinstall_best_route(struct bgp *bgp,
+               struct bgpevpn *vpn, struct bgp_node *rn)
+{
+       struct bgp_path_info *tmp_ri;
+       struct bgp_path_info *curr_select = NULL;
+
+       for (tmp_ri = bgp_node_get_bgp_path_info(rn);
+            tmp_ri; tmp_ri = tmp_ri->next) {
+               if (CHECK_FLAG(tmp_ri->flags, BGP_PATH_SELECTED)) {
+                       curr_select = tmp_ri;
+                       break;
+               }
+       }
+
+       if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP
+                       && curr_select->sub_type == BGP_ROUTE_IMPORTED)
+               evpn_zebra_install(bgp, vpn,
+                               (struct prefix_evpn *)&rn->p,
+                               curr_select);
+}
+
 /*
  * If the local route was not selected evict it and tell zebra to re-add
  * the best remote dest.
@@ -1704,8 +1725,6 @@ static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
                                              struct bgp_node *rn,
                                              struct bgp_path_info *local_pi)
 {
-       struct bgp_path_info *tmp_pi;
-       struct bgp_path_info *curr_select = NULL;
        char buf[PREFIX_STRLEN];
 
        /* local path was not picked as the winner; kick it out */
@@ -1717,18 +1736,7 @@ static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
        bgp_path_info_reap(rn, local_pi);
 
        /* tell zebra to re-add the best remote path */
-       for (tmp_pi = bgp_node_get_bgp_path_info(rn);
-            tmp_pi; tmp_pi = tmp_pi->next) {
-               if (CHECK_FLAG(tmp_pi->flags, BGP_PATH_SELECTED)) {
-                       curr_select = tmp_pi;
-                       break;
-               }
-       }
-       if (curr_select &&
-           curr_select->type == ZEBRA_ROUTE_BGP
-           && curr_select->sub_type == BGP_ROUTE_IMPORTED)
-               evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
-                                  curr_select);
+       evpn_zebra_reinstall_best_route(bgp, vpn, rn);
 }
 
 /*
@@ -5304,10 +5312,11 @@ int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
  * Handle del of a local MACIP.
  */
 int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
-                            struct ipaddr *ip)
+                            struct ipaddr *ip, int state)
 {
        struct bgpevpn *vpn;
        struct prefix_evpn p;
+       struct bgp_node *rn;
 
        /* Lookup VNI hash - should exist. */
        vpn = bgp_evpn_lookup_vni(bgp, vni);
@@ -5318,9 +5327,16 @@ int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
                return -1;
        }
 
-       /* Remove EVPN type-2 route and schedule for processing. */
        build_evpn_type2_prefix(&p, mac, ip);
-       delete_evpn_route(bgp, vpn, &p);
+       if (state == ZEBRA_NEIGH_ACTIVE) {
+               /* Remove EVPN type-2 route and schedule for processing. */
+               delete_evpn_route(bgp, vpn, &p);
+       } else {
+               /* Re-instate the current remote best path if any */
+               rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
+               if (rn)
+                       evpn_zebra_reinstall_best_route(bgp, vpn, rn);
+       }
 
        return 0;
 }
index 8728fdcab7633278c0c3c1ff4076f67b72eec03a..5c3d4ce3aa9a1f60a56b1dc99651b43731d9b703 100644 (file)
@@ -129,7 +129,8 @@ extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
                                   struct prefix *p, struct bgp_path_info *ri);
 extern int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp);
 extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
-                                   struct ethaddr *mac, struct ipaddr *ip);
+                                   struct ethaddr *mac, struct ipaddr *ip,
+                                       int state);
 extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
                                    struct ethaddr *mac, struct ipaddr *ip,
                                    uint8_t flags, uint32_t seq);
index c6e48cc16083d97fdfc7061c8ef0e2ed40a01f43..2da19b28db32a3fdf1ce0de5f4d81787f8562dc4 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "command.h"
 #include "lib/json.h"
+#include "lib/zclient.h"
 #include "prefix.h"
 #include "plist.h"
 #include "buffer.h"
@@ -897,7 +898,7 @@ DEFUN_HIDDEN (no_bgp_local_mac,
                return CMD_WARNING;
        }
 
-       rv = bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
+       rv = bgp_evpn_local_macip_del(bgp, vni, &mac, &ip, ZEBRA_NEIGH_ACTIVE);
        if (rv < 0) {
                vty_out(vty, "Internal error\n");
                return CMD_WARNING;
index 3c4b219466ce37d643cb77eb16151b8aa733a39d..17de9433815967d8442711f640a56b8c9de39e8e 100644 (file)
@@ -2480,6 +2480,7 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
        char buf1[INET6_ADDRSTRLEN];
        uint8_t flags = 0;
        uint32_t seqnum = 0;
+       int state = 0;
 
        memset(&ip, 0, sizeof(ip));
        s = zclient->ibuf;
@@ -2503,6 +2504,8 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
        if (command == ZEBRA_MACIP_ADD) {
                flags = stream_getc(s);
                seqnum = stream_getl(s);
+       } else {
+               state = stream_getl(s);
        }
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
@@ -2510,16 +2513,17 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient,
                return 0;
 
        if (BGP_DEBUG(zebra, ZEBRA))
-               zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u seq %u",
+               zlog_debug("%u:Recv MACIP %s flags 0x%x MAC %s IP %s VNI %u seq %u state %d",
                           vrf_id, (command == ZEBRA_MACIP_ADD) ? "Add" : "Del",
                           flags, prefix_mac2str(&mac, buf, sizeof(buf)),
-                          ipaddr2str(&ip, buf1, sizeof(buf1)), vni, seqnum);
+                          ipaddr2str(&ip, buf1, sizeof(buf1)), vni, seqnum,
+                          state);
 
        if (command == ZEBRA_MACIP_ADD)
                return bgp_evpn_local_macip_add(bgp, vni, &mac, &ip,
                                                flags, seqnum);
        else
-               return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
+               return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip, state);
 }
 
 static void bgp_zebra_process_local_ip_prefix(int cmd, struct zclient *zclient,