summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bgpd/bgp_evpn.c110
-rw-r--r--bgpd/bgp_evpn.h3
-rw-r--r--bgpd/bgp_vty.c3
-rw-r--r--bgpd/bgp_zebra.c10
4 files changed, 64 insertions, 62 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 7f6d34808..c74d7829b 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -887,17 +887,26 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr)
/* Install EVPN route into zebra. */
static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
- struct prefix_evpn *p,
- struct in_addr remote_vtep_ip, uint8_t flags,
- uint32_t seq)
+ struct prefix_evpn *p, struct bgp_path_info *pi)
{
int ret;
+ uint8_t flags;
- if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
- ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
- 1, flags, seq);
- else
+ if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
+ flags = 0;
+ if (pi->attr->sticky)
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+ if (pi->attr->default_gw)
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+ if (is_evpn_prefix_ipaddr_v6(p) &&
+ pi->attr->router_flag)
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
+ ret = bgp_zebra_send_remote_macip(
+ bgp, vpn, p, pi->attr->nexthop, 1, flags,
+ mac_mobility_seqnum(pi->attr));
+ } else {
ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, 1);
+ }
return ret;
}
@@ -1121,11 +1130,9 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
{
struct bgp_path_info *old_select, *new_select;
struct bgp_path_info_pair old_and_new;
- struct prefix_evpn *evp;
afi_t afi = AFI_L2VPN;
safi_t safi = SAFI_EVPN;
int ret = 0;
- uint8_t flags = 0;
/* Compute the best path. */
bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new,
@@ -1133,7 +1140,6 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
old_select = old_and_new.old;
new_select = old_and_new.new;
- evp = (struct prefix_evpn *)&rn->p;
/* If the best path hasn't changed - see if there is still something to
* update
* to zebra RIB.
@@ -1144,20 +1150,10 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
&& !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
&& !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
&& !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
- if (bgp_zebra_has_route_changed(rn, old_select)) {
- if (old_select->attr->sticky)
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
- if (old_select->attr->default_gw)
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
- if (is_evpn_prefix_ipaddr_v6(evp) &&
- old_select->attr->router_flag)
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
-
+ if (bgp_zebra_has_route_changed(rn, old_select))
ret = evpn_zebra_install(
bgp, vpn, (struct prefix_evpn *)&rn->p,
- old_select->attr->nexthop, flags,
- mac_mobility_seqnum(old_select->attr));
- }
+ old_select);
UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
bgp_zebra_clear_route_change_flags(rn);
return ret;
@@ -1182,18 +1178,9 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
if (new_select && new_select->type == ZEBRA_ROUTE_BGP
&& new_select->sub_type == BGP_ROUTE_IMPORTED) {
- flags = 0;
- if (new_select->attr->sticky)
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
- if (new_select->attr->default_gw)
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
- if (is_evpn_prefix_ipaddr_v6(evp) &&
- new_select->attr->router_flag)
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
-
ret = evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
- new_select->attr->nexthop, flags,
- mac_mobility_seqnum(new_select->attr));
+ new_select);
+
/* If an old best existed and it was a "local" route, the only
* reason
* it would be supplanted is due to MAC mobility procedures. So,
@@ -1698,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.
@@ -1717,9 +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;
- uint8_t flags = 0;
char buf[PREFIX_STRLEN];
/* local path was not picked as the winner; kick it out */
@@ -1731,24 +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) {
- if (curr_select->attr->sticky)
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
- if (curr_select->attr->default_gw)
- SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
- evpn_zebra_install(bgp, vpn, (struct prefix_evpn *)&rn->p,
- curr_select->attr->nexthop, flags,
- mac_mobility_seqnum(curr_select->attr));
- }
+ evpn_zebra_reinstall_best_route(bgp, vpn, rn);
}
/*
@@ -5324,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);
@@ -5338,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;
}
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index 8728fdcab..5c3d4ce3a 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -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);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index c6e48cc16..2da19b28d 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -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;
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 3c4b21946..17de94338 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -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,