summaryrefslogtreecommitdiff
path: root/bgpd/bgp_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_zebra.c')
-rw-r--r--bgpd/bgp_zebra.c147
1 files changed, 129 insertions, 18 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 00213b4239..12bc2e41bc 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -531,9 +531,9 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS)
api.instance, &api.prefix, buf, nhtype, ifindex,
api.metric, api.tag);
} else {
- zlog_debug("Rx route DEL VRF %u %s[%d] %s", vrf_id,
+ zlog_debug("Rx route DEL VRF %u %s[%d] %pFX", vrf_id,
zebra_route_string(api.type), api.instance,
- buf);
+ &api.prefix);
}
}
@@ -918,7 +918,7 @@ static bool bgp_table_map_apply(struct route_map *map, const struct prefix *p,
{
route_map_result_t ret;
- ret = route_map_apply(map, p, RMAP_BGP, path);
+ ret = route_map_apply(map, p, path);
bgp_attr_flush(path->attr);
if (ret != RMAP_DENYMATCH)
@@ -1179,6 +1179,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
int nh_updated;
bool do_wt_ecmp;
uint64_t cum_bw = 0;
+ uint32_t nhg_id = 0;
+ bool is_add;
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
@@ -1257,7 +1259,17 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
if (do_wt_ecmp)
cum_bw = bgp_path_info_mpath_cumbw(info);
- for (mpinfo = info; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
+ /* EVPN MAC-IP routes are installed with a L3 NHG id */
+ if (bgp_evpn_path_es_use_nhg(bgp, info, &nhg_id)) {
+ mpinfo = NULL;
+ api.nhgid = nhg_id;
+ if (nhg_id)
+ SET_FLAG(api.message, ZAPI_MESSAGE_NHG);
+ } else {
+ mpinfo = info;
+ }
+
+ for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
uint32_t nh_weight;
if (valid_nh_count >= multipath_num)
@@ -1395,6 +1407,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
valid_nh_count++;
}
+ is_add = (valid_nh_count || nhg_id) ? true : false;
+
/*
* When we create an aggregate route we must also
* install a Null0 route in the RIB, so overwrite
@@ -1428,9 +1442,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
zlog_debug(
"Tx route %s VRF %u %pFX metric %u tag %" ROUTE_TAG_PRI
- " count %d",
+ " count %d nhg %d",
valid_nh_count ? "add" : "delete", bgp->vrf_id,
- &api.prefix, api.metric, api.tag, api.nexthop_num);
+ &api.prefix, api.metric, api.tag, api.nexthop_num,
+ nhg_id);
for (i = 0; i < api.nexthop_num; i++) {
api_nh = &api.nexthops[i];
@@ -1487,8 +1502,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
__func__, buf_prefix,
(recursion_flag ? "" : "NOT "));
}
- zclient_route_send(valid_nh_count ? ZEBRA_ROUTE_ADD
- : ZEBRA_ROUTE_DELETE,
+ zclient_route_send(is_add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
zclient, &api);
}
@@ -1820,7 +1834,6 @@ int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type,
vrf_bitmap_unset(zclient->redist[afi][type], bgp->vrf_id);
}
-
if (bgp_install_info_to_zebra(bgp)) {
/* Send distribute delete message to zebra. */
if (BGP_DEBUG(zebra, ZEBRA))
@@ -2380,6 +2393,99 @@ static int iptable_notify_owner(ZAPI_CALLBACK_ARGS)
return 0;
}
+/* Process route notification messages from RIB */
+static int bgp_zebra_route_notify_owner(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct prefix p;
+ enum zapi_route_notify_owner note;
+ uint32_t table_id;
+ char buf[PREFIX_STRLEN];
+ afi_t afi;
+ safi_t safi;
+ struct bgp_dest *dest;
+ struct bgp *bgp;
+ struct bgp_path_info *pi, *new_select;
+
+ if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, &note,
+ &afi, &safi)) {
+ zlog_err("%s : error in msg decode", __PRETTY_FUNCTION__);
+ return -1;
+ }
+
+ /* Get the bgp instance */
+ bgp = bgp_lookup_by_vrf_id(vrf_id);
+ if (!bgp) {
+ flog_err(EC_BGP_INVALID_BGP_INSTANCE,
+ "%s : bgp instance not found vrf %d",
+ __PRETTY_FUNCTION__, vrf_id);
+ return -1;
+ }
+
+ if (BGP_DEBUG(zebra, ZEBRA))
+ prefix2str(&p, buf, sizeof(buf));
+
+ /* Find the bgp route node */
+ dest = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi, &p,
+ &bgp->vrf_prd);
+ if (!dest)
+ return -1;
+
+ bgp_dest_unlock_node(dest);
+
+ switch (note) {
+ case ZAPI_ROUTE_INSTALLED:
+ new_select = NULL;
+ /* Clear the flags so that route can be processed */
+ if (CHECK_FLAG(dest->flags,
+ BGP_NODE_FIB_INSTALL_PENDING)) {
+ UNSET_FLAG(dest->flags,
+ BGP_NODE_FIB_INSTALL_PENDING);
+ SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
+ if (BGP_DEBUG(zebra, ZEBRA))
+ zlog_debug("route %s : INSTALLED", buf);
+ /* Find the best route */
+ for (pi = dest->info; pi; pi = pi->next) {
+ /* Process aggregate route */
+ bgp_aggregate_increment(bgp, &p, pi,
+ afi, safi);
+ if (CHECK_FLAG(pi->flags,
+ BGP_PATH_SELECTED))
+ new_select = pi;
+ }
+ /* Advertise the route */
+ if (new_select)
+ group_announce_route(bgp, afi, safi,
+ dest, new_select);
+ else {
+ flog_err(EC_BGP_INVALID_ROUTE,
+ "selected route %s not found",
+ buf);
+ return -1;
+ }
+ }
+ break;
+ case ZAPI_ROUTE_REMOVED:
+ /* Route deleted from dataplane, reset the installed flag
+ * so that route can be reinstalled when client sends
+ * route add later
+ */
+ UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED);
+ break;
+ case ZAPI_ROUTE_FAIL_INSTALL:
+ /* Error will be logged by zebra module */
+ break;
+ case ZAPI_ROUTE_BETTER_ADMIN_WON:
+ /* No action required */
+ break;
+ case ZAPI_ROUTE_REMOVE_FAIL:
+ zlog_warn("%s: Route %s failure to remove",
+ __func__, buf);
+ break;
+ }
+ return 0;
+}
+
/* this function is used to forge ip rule,
* - either for iptable/ipset using fwmark id
* - or for sample ip rule cmd
@@ -2390,6 +2496,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
{
struct prefix pfx;
uint8_t fam = AF_INET;
+ char ifname[INTERFACE_NAMSIZ];
if (pbra->nh.type == NEXTHOP_TYPE_IPV6)
fam = AF_INET6;
@@ -2431,7 +2538,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
stream_put(s, &pfx.u.prefix, prefix_blen(&pfx));
stream_putw(s, 0); /* dst port */
-
+ stream_putc(s, 0); /* dsfield */
/* if pbr present, fwmark is not used */
if (pbr)
stream_putl(s, 0);
@@ -2440,7 +2547,8 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
stream_putl(s, pbra->table_id);
- stream_putl(s, 0); /* ifindex unused */
+ memset(ifname, 0, sizeof(ifname));
+ stream_put(s, ifname, INTERFACE_NAMSIZ); /* ifname unused */
}
static void bgp_encode_pbr_ipset_match(struct stream *s,
@@ -2745,6 +2853,7 @@ static int bgp_zebra_process_local_macip(ZAPI_CALLBACK_ARGS)
stream_get(&esi, s, sizeof(esi_t));
} else {
state = stream_getl(s);
+ memset(&esi, 0, sizeof(esi_t));
}
bgp = bgp_lookup_by_vrf_id(vrf_id);
@@ -2908,6 +3017,7 @@ void bgp_zebra_init(struct thread_master *master, unsigned short instance)
zclient->ipset_notify_owner = ipset_notify_owner;
zclient->ipset_entry_notify_owner = ipset_entry_notify_owner;
zclient->iptable_notify_owner = iptable_notify_owner;
+ zclient->route_notify_owner = bgp_zebra_route_notify_owner;
zclient->instance = instance;
}
@@ -2954,7 +3064,8 @@ void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra,
bgp_encode_pbr_rule_action(s, pbra, pbr);
stream_putw_at(s, 0, stream_get_endp(s));
- if (!zclient_send_message(zclient) && install) {
+ if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE)
+ && install) {
if (!pbr)
pbra->install_in_progress = true;
else
@@ -2985,7 +3096,7 @@ void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install)
bgp_encode_pbr_ipset_match(s, pbrim);
stream_putw_at(s, 0, stream_get_endp(s));
- if (!zclient_send_message(zclient) && install)
+ if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
pbrim->install_in_progress = true;
}
@@ -3013,7 +3124,7 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
bgp_encode_pbr_ipset_entry_match(s, pbrime);
stream_putw_at(s, 0, stream_get_endp(s));
- if (!zclient_send_message(zclient) && install)
+ if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
pbrime->install_in_progress = true;
}
@@ -3088,7 +3199,7 @@ void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
stream_putw_at(s, 0, stream_get_endp(s));
ret = zclient_send_message(zclient);
if (install) {
- if (ret)
+ if (ret != ZCLIENT_SEND_FAILURE)
pba->refcnt++;
else
pbm->install_iptable_in_progress = true;
@@ -3222,7 +3333,7 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable)
}
if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
- < 0) {
+ == ZCLIENT_SEND_FAILURE) {
zlog_err("error sending capability");
ret = BGP_GR_FAILURE;
} else {
@@ -3264,7 +3375,7 @@ int bgp_zebra_update(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type)
api.cap = type;
if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
- < 0) {
+ == ZCLIENT_SEND_FAILURE) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("error sending capability");
return BGP_GR_FAILURE;
@@ -3296,7 +3407,7 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp)
api.stale_removal_time = bgp->rib_stale_time;
api.vrf_id = bgp->vrf_id;
if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
- < 0) {
+ == ZCLIENT_SEND_FAILURE) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("error sending capability");
return BGP_GR_FAILURE;