diff options
Diffstat (limited to 'bgpd/bgp_zebra.c')
| -rw-r--r-- | bgpd/bgp_zebra.c | 147 |
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, ¬e, + &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; |
