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.
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 */
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);
}
/*
* 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);
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;
}
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);
char buf1[INET6_ADDRSTRLEN];
uint8_t flags = 0;
uint32_t seqnum = 0;
+ int state = 0;
memset(&ip, 0, sizeof(ip));
s = zclient->ibuf;
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);
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,