diff --git a/babeld/kernel.c b/babeld/kernel.c index 6b673c487c..8b1b80665c 100644 --- a/babeld/kernel.c +++ b/babeld/kernel.c @@ -166,7 +166,6 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen, api.type = ZEBRA_ROUTE_BABEL; api.safi = SAFI_UNICAST; api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.prefix = quagga_prefix; if(metric >= KERNEL_INFINITY) { @@ -175,8 +174,8 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen, SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api_nh->ifindex = ifindex; - - switch (family) { + api_nh->vrf_id = VRF_DEFAULT; + switch (family) { case AF_INET: uchar_to_inaddr(&api_nh->gate.ipv4, gate); if (IPV4_ADDR_SAME (&api_nh->gate.ipv4, &quagga_prefix.u.prefix4) && diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index b08522b68b..e89f399e41 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -385,8 +385,8 @@ int bgp_dump_attr(struct attr *attr, char *buf, size_t size) if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) snprintf(buf + strlen(buf), size - strlen(buf), - ", community %s", community_str(attr->community, - false)); + ", community %s", + community_str(attr->community, false)); if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) snprintf(buf + strlen(buf), size - strlen(buf), diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index 7c773cfafb..765e43f5b4 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -153,9 +153,9 @@ extern int bgp_debug_zebra(struct prefix *p); extern int bgp_debug_count(void); extern const char *bgp_debug_rdpfxpath2str(afi_t, safi_t, struct prefix_rd *, - union prefixconstptr, - mpls_label_t *, u_int32_t, - int, u_int32_t, char *, int); + union prefixconstptr, mpls_label_t *, + u_int32_t, int, u_int32_t, char *, + int); const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data, size_t datalen); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 9b1ff8f6a9..fbb2ff101d 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3301,6 +3301,18 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, for (ri = rn->info; ri; ri = ri->next) { if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) && (!ri->extra || !ri->extra->parent)) { + + /* apply the route-map */ + if (bgp_vrf->adv_cmd_rmap[afi][safi].map) { + int ret = 0; + + ret = + route_map_apply( + bgp_vrf->adv_cmd_rmap[afi][safi].map, + &rn->p, RMAP_BGP, ri); + if (ret == RMAP_DENYMATCH) + continue; + } bgp_evpn_advertise_type5_route(bgp_vrf, &rn->p, ri->attr, afi, safi); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index bd42ccdecf..1373afec4e 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -83,7 +83,7 @@ static void display_vrf_import_rt(struct vty *vty, case ECOMMUNITY_ENCODE_AS: eas.as = (*pnt++ << 8); eas.as |= (*pnt++); - pnt = ptr_get_be32(pnt, &eas.val); + ptr_get_be32(pnt, &eas.val); snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); @@ -195,7 +195,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt, case ECOMMUNITY_ENCODE_AS: eas.as = (*pnt++ << 8); eas.as |= (*pnt++); - pnt = ptr_get_be32(pnt, &eas.val); + ptr_get_be32(pnt, &eas.val); snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); @@ -2723,19 +2723,34 @@ DEFUN (no_bgp_evpn_advertise_vni_subnet, DEFUN (bgp_evpn_advertise_type5, bgp_evpn_advertise_type5_cmd, - "advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR, + "advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR " [route-map WORD]", "Advertise prefix routes\n" BGP_AFI_HELP_STR - BGP_SAFI_HELP_STR) + BGP_SAFI_HELP_STR + "route-map for filtering specific routes\n" + "Name of the route map\n") { struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */ int idx_afi = 0; int idx_safi = 0; + int idx_rmap = 0; afi_t afi = 0; safi_t safi = 0; + int ret = 0; + int rmap_changed = 0; argv_find_and_parse_afi(argv, argc, &idx_afi, &afi); argv_find_and_parse_safi(argv, argc, &idx_safi, &safi); + ret = argv_find(argv, argc, "route-map", &idx_rmap); + if (ret) { + if (!bgp_vrf->adv_cmd_rmap[afi][safi].name) + rmap_changed = 1; + else if (strcmp(argv[idx_rmap + 1]->arg, + bgp_vrf->adv_cmd_rmap[afi][safi].name) != 0) + rmap_changed = 1; + } else if (bgp_vrf->adv_cmd_rmap[afi][safi].name) { + rmap_changed = 1; + } if (!(afi == AFI_IP) || (afi == AFI_IP6)) { vty_out(vty, @@ -2754,24 +2769,44 @@ DEFUN (bgp_evpn_advertise_type5, /* if we are already advertising ipv4 prefix as type-5 * nothing to do */ - if (!CHECK_FLAG(bgp_vrf->vrf_flags, - BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) { - SET_FLAG(bgp_vrf->vrf_flags, - BGP_VRF_ADVERTISE_IPV4_IN_EVPN); - bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi); - } + if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags, + BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) + return CMD_WARNING; + SET_FLAG(bgp_vrf->vrf_flags, + BGP_VRF_ADVERTISE_IPV4_IN_EVPN); } else { /* if we are already advertising ipv6 prefix as type-5 * nothing to do */ - if (!CHECK_FLAG(bgp_vrf->vrf_flags, - BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) { - SET_FLAG(bgp_vrf->vrf_flags, - BGP_VRF_ADVERTISE_IPV6_IN_EVPN); - bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi); + if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags, + BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) + return CMD_WARNING; + SET_FLAG(bgp_vrf->vrf_flags, + BGP_VRF_ADVERTISE_IPV6_IN_EVPN); + } + + if (rmap_changed) { + bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi); + if (bgp_vrf->adv_cmd_rmap[afi][safi].name) { + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp_vrf->adv_cmd_rmap[afi][safi].name); + bgp_vrf->adv_cmd_rmap[afi][safi].name = NULL; + bgp_vrf->adv_cmd_rmap[afi][safi].map = NULL; } } + + /* set the route-map for advertise command */ + if (ret && argv[idx_rmap + 1]->arg) { + bgp_vrf->adv_cmd_rmap[afi][safi].name = + XSTRDUP(MTYPE_ROUTE_MAP_NAME, + argv[idx_rmap + 1]->arg); + bgp_vrf->adv_cmd_rmap[afi][safi].map = + route_map_lookup_by_name(argv[idx_rmap + 1]->arg); + } + + /* advertise type-5 routes */ + bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi); return CMD_SUCCESS; } @@ -2827,6 +2862,15 @@ DEFUN (no_bgp_evpn_advertise_type5, BGP_VRF_ADVERTISE_IPV6_IN_EVPN); } } + + /* clear the route-map information for advertise ipv4/ipv6 unicast */ + if (bgp_vrf->adv_cmd_rmap[afi][safi].name) { + XFREE(MTYPE_ROUTE_MAP_NAME, + bgp_vrf->adv_cmd_rmap[afi][safi].name); + bgp_vrf->adv_cmd_rmap[afi][safi].name = NULL; + bgp_vrf->adv_cmd_rmap[afi][safi].map = NULL; + } + return CMD_SUCCESS; } diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 0e2594ba8a..ec4989de8f 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -366,8 +366,8 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd, return CMD_WARNING; } table = bgp->rib[afi][SAFI_MPLS_VPN]; - return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, - table, prd, type, output_arg, use_json); + return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type, + output_arg, use_json); } DEFUN (show_bgp_ip_vpn_all_rd, @@ -389,7 +389,7 @@ DEFUN (show_bgp_ip_vpn_all_rd, if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) { if (argv_find(argv, argc, "rd", &idx)) { - ret = str2prefix_rd(argv[idx+1]->arg, &prd); + ret = str2prefix_rd(argv[idx + 1]->arg, &prd); if (!ret) { vty_out(vty, "%% Malformed Route Distinguisher\n"); diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 3b37aadbf8..5c11f7526c 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -24,30 +24,6 @@ #include "bgpd/bgp_route.h" #include "bgpd/bgp_rd.h" -#ifdef MPLS_LABEL_MAX -#undef MPLS_LABEL_MAX -#endif - -typedef enum { - MPLS_LABEL_IPV4_EXPLICIT_NULL = 0, /* [RFC3032] */ - MPLS_LABEL_ROUTER_ALERT = 1, /* [RFC3032] */ - MPLS_LABEL_IPV6_EXPLICIT_NULL = 2, /* [RFC3032] */ - MPLS_LABEL_IMPLICIT_NULL = 3, /* [RFC3032] */ - MPLS_LABEL_UNASSIGNED4 = 4, - MPLS_LABEL_UNASSIGNED5 = 5, - MPLS_LABEL_UNASSIGNED6 = 6, - MPLS_LABEL_ELI = 7, /* Entropy Indicator [RFC6790] */ - MPLS_LABEL_UNASSIGNED8 = 8, - MPLS_LABEL_UNASSIGNED9 = 9, - MPLS_LABEL_UNASSIGNED10 = 10, - MPLS_LABEL_UNASSIGNED11 = 11, - MPLS_LABEL_GAL = 13, /* [RFC5586] */ - MPLS_LABEL_OAM_ALERT = 14, /* [RFC3429] */ - MPLS_LABEL_EXTENSION = 15, /* [RFC7274] */ - MPLS_LABEL_MAX = 1048575, - MPLS_LABEL_ILLEGAL = 0xFFFFFFFF /* for internal use only */ -} mpls_special_label_t; - #define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION) #define MPLS_LABEL_IS_NULL(label) \ ((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL \ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index fe2c5d11a1..3dfc446b2c 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -771,7 +771,7 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new, /* If one path has a label but the other does not, do not treat * them as equals for multipath */ - if ((new->extra && bgp_is_valid_label(&new->extra->label[0])) + if ((new->extra &&bgp_is_valid_label(&new->extra->label[0])) != (exist->extra && bgp_is_valid_label(&exist->extra->label[0]))) { if (debug) @@ -1286,7 +1286,7 @@ void bgp_attr_add_gshut_community(struct attr *attr) if (old) { merge = community_merge(community_dup(old), gshut); - if (old->refcnt== 0) + if (old->refcnt == 0) community_free(old); new = community_uniq_sort(merge); @@ -1662,7 +1662,8 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri, } if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) { - if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) { + if (peer->sort == BGP_PEER_IBGP + || peer->sort == BGP_PEER_CONFED) { attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); attr->local_pref = BGP_GSHUT_LOCAL_PREF; } else { @@ -1718,8 +1719,8 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri, subgrp)) subgroup_announce_reset_nhop( (peer_cap_enhe(peer, afi, safi) - ? AF_INET6 - : p->family), + ? AF_INET6 + : p->family), attr); } /* If IPv6/MP and nexthop does not have any override and happens @@ -1966,8 +1967,9 @@ int subgroup_process_announce_selected(struct update_subgroup *subgrp, : NULL); /* First update is deferred until ORF or ROUTE-REFRESH is received */ - if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi], - PEER_STATUS_ORF_WAIT_REFRESH)) + if (onlypeer + && CHECK_FLAG(onlypeer->af_sflags[afi][safi], + PEER_STATUS_ORF_WAIT_REFRESH)) return 0; memset(&attr, 0, sizeof(struct attr)); @@ -2043,7 +2045,7 @@ int bgp_zebra_has_route_changed(struct bgp_node *rn, struct bgp_info *selected) struct bgp_process_queue { struct bgp *bgp; - STAILQ_HEAD(, bgp_node)pqueue; + STAILQ_HEAD(, bgp_node) pqueue; #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0) unsigned int flags; unsigned int queued; @@ -2099,13 +2101,14 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) bgp_unregister_for_label(rn); - label_ntop(MPLS_IMP_NULL_LABEL, 1, + label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1, &rn->local_label); bgp_set_valid_label(&rn->local_label); } else bgp_register_for_label(rn, new_select); } - } else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) { + } else if (CHECK_FLAG(rn->flags, + BGP_NODE_REGISTERED_FOR_LABEL)) { bgp_unregister_for_label(rn); } } else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) { @@ -2309,7 +2312,8 @@ static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp) { struct bgp_process_queue *pqnode; - pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE, sizeof(struct bgp_process_queue)); + pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE, + sizeof(struct bgp_process_queue)); /* unlocked in bgp_processq_del */ pqnode->bgp = bgp_lock(bgp); @@ -2333,13 +2337,15 @@ void bgp_process(struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi) return; /* Add route nodes to an existing work queue item until reaching the - limit only if is from the same BGP view and it's not an EOIU marker */ + limit only if is from the same BGP view and it's not an EOIU marker + */ if (work_queue_item_count(wq)) { struct work_queue_item *item = work_queue_last_item(wq); pqnode = item->data; - if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER) || - pqnode->bgp != bgp || pqnode->queued >= ARBITRARY_PROCESS_QLEN) + if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER) + || pqnode->bgp != bgp + || pqnode->queued >= ARBITRARY_PROCESS_QLEN) pqnode = bgp_processq_alloc(bgp); else pqnode_reuse = 1; @@ -2675,9 +2681,9 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, - int sub_type, struct prefix_rd *prd, - mpls_label_t *label, u_int32_t num_labels, - int soft_reconfig, struct bgp_route_evpn *evpn) + int sub_type, struct prefix_rd *prd, mpls_label_t *label, + u_int32_t num_labels, int soft_reconfig, + struct bgp_route_evpn *evpn) { int ret; int aspath_loop_count = 0; @@ -2728,7 +2734,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (peer->change_local_as) { if (peer->allowas_in[afi][safi]) aspath_loop_count = peer->allowas_in[afi][safi]; - else if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) + else if (!CHECK_FLAG(peer->flags, + PEER_FLAG_LOCAL_AS_NO_PREPEND)) aspath_loop_count = 1; if (aspath_loop_check(attr->aspath, peer->change_local_as) @@ -2794,23 +2801,24 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (peer->sort == BGP_PEER_EBGP) { - /* If we receive the graceful-shutdown community from an eBGP peer we - * must lower local-preference */ - if (new_attr.community && - community_include(new_attr.community, COMMUNITY_GSHUT)) { + /* If we receive the graceful-shutdown community from an eBGP + * peer we must lower local-preference */ + if (new_attr.community + && community_include(new_attr.community, COMMUNITY_GSHUT)) { new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); new_attr.local_pref = BGP_GSHUT_LOCAL_PREF; - /* If graceful-shutdown is configured then add the GSHUT community to - * all paths received from eBGP peers */ - } else if (bgp_flag_check(peer->bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) { + /* If graceful-shutdown is configured then add the GSHUT + * community to all paths received from eBGP peers */ + } else if (bgp_flag_check(peer->bgp, + BGP_FLAG_GRACEFUL_SHUTDOWN)) { bgp_attr_add_gshut_community(&new_attr); } } /* next hop check. */ - if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) && - bgp_update_martian_nexthop(bgp, afi, safi, &new_attr)) { + if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) + && bgp_update_martian_nexthop(bgp, afi, safi, &new_attr)) { reason = "martian or self next-hop;"; bgp_attr_flush(&new_attr); goto filtered; @@ -2839,10 +2847,10 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, && CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( - afi, safi, prd, p, - label, num_labels, - addpath_id ? 1 : 0, addpath_id, - pfx_buf, sizeof(pfx_buf)); + afi, safi, prd, p, label, + num_labels, addpath_id ? 1 : 0, + addpath_id, pfx_buf, + sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); } @@ -2865,10 +2873,10 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, } bgp_debug_rdpfxpath2str( - afi, safi, prd, p, - label, num_labels, - addpath_id ? 1 : 0, addpath_id, - pfx_buf, sizeof(pfx_buf)); + afi, safi, prd, p, label, + num_labels, addpath_id ? 1 : 0, + addpath_id, pfx_buf, + sizeof(pfx_buf)); zlog_debug( "%s rcvd %s...duplicate ignored", peer->host, pfx_buf); @@ -2892,8 +2900,7 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( - afi, safi, prd, p, - label, num_labels, + afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug( @@ -2906,10 +2913,10 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Received Logging. */ if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, - addpath_id ? 1 : 0, addpath_id, - pfx_buf, sizeof(pfx_buf)); + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, + num_labels, addpath_id ? 1 : 0, + addpath_id, pfx_buf, + sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); } @@ -3060,8 +3067,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, connected = 0; if (bgp_find_or_add_nexthop(bgp, afi, ri, NULL, - connected) || - CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) + connected) + || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) bgp_info_set_flag(rn, ri, BGP_INFO_VALID); else { if (BGP_DEBUG(nht, NHT)) { @@ -3140,8 +3147,7 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, peer->rcvd_attr_printed = 1; } - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); @@ -3153,8 +3159,7 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { extra = bgp_info_extra_get(new); - memcpy(&extra->label, label, - num_labels * sizeof(mpls_label_t)); + memcpy(&extra->label, label, num_labels * sizeof(mpls_label_t)); extra->num_labels = num_labels; if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) bgp_set_valid_label(&extra->label[0]); @@ -3177,8 +3182,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id, else connected = 0; - if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, connected) || - CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) + if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, connected) + || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) bgp_info_set_flag(rn, new, BGP_INFO_VALID); else { if (BGP_DEBUG(nht, NHT)) { @@ -3259,8 +3264,7 @@ filtered: peer->rcvd_attr_printed = 1; } - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s", @@ -3295,9 +3299,8 @@ filtered: int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, - int sub_type, struct prefix_rd *prd, - mpls_label_t *label, u_int32_t num_labels, - struct bgp_route_evpn *evpn) + int sub_type, struct prefix_rd *prd, mpls_label_t *label, + u_int32_t num_labels, struct bgp_route_evpn *evpn) { struct bgp *bgp; char pfx_buf[BGP_PRD_PATH_STRLEN]; @@ -3332,8 +3335,7 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (!bgp_adj_in_unset(rn, peer, addpath_id)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( - afi, safi, prd, p, - label, num_labels, + afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug( @@ -3353,8 +3355,7 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Logging. */ if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host, @@ -3365,8 +3366,7 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id, if (ri && !CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) bgp_rib_withdraw(rn, ri, peer, afi, safi, prd); else if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_debug_rdpfxpath2str(afi, safi, prd, p, - label, num_labels, + bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, addpath_id, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s Can't find the route %s", peer->host, pfx_buf); @@ -3502,8 +3502,8 @@ static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi, ret = bgp_update(peer, &rn->p, ain->addpath_rx_id, ain->attr, afi, safi, ZEBRA_ROUTE_BGP, - BGP_ROUTE_NORMAL, prd, - label_pnt, num_labels, 1, NULL); + BGP_ROUTE_NORMAL, prd, label_pnt, + num_labels, 1, NULL); if (ret < 0) { bgp_unlock_node(rn); @@ -4018,7 +4018,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, * an error SHOULD * be logged locally, and the prefix SHOULD be * ignored. - */ + */ zlog_err( "%s: IPv4 unicast NLRI is multicast address %s, ignoring", peer->host, inet_ntoa(p.u.prefix4)); @@ -4060,8 +4060,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr, else ret = bgp_withdraw(peer, &p, addpath_id, attr, afi, safi, ZEBRA_ROUTE_BGP, - BGP_ROUTE_NORMAL, NULL, - NULL, 0, NULL); + BGP_ROUTE_NORMAL, NULL, NULL, 0, + NULL); /* Address family configuration mismatch or maximum-prefix count overflow. */ @@ -4557,8 +4557,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, rn = bgp_node_lookup(bgp->route[afi][safi], &p); if (!rn) { - vty_out(vty, - "%% Can't find static route specified\n"); + vty_out(vty, "%% Can't find static route specified\n"); return CMD_WARNING_CONFIG_FAILED; } @@ -4603,8 +4602,8 @@ static int bgp_static_set(struct vty *vty, const char *negate, } /* Check previous routes are installed into BGP. */ - if (bgp_static->valid && - bgp_static->backdoor != backdoor) + if (bgp_static->valid + && bgp_static->backdoor != backdoor) need_update = 1; bgp_static->backdoor = backdoor; @@ -4612,7 +4611,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, if (rmap) { if (bgp_static->rmap.name) XFREE(MTYPE_ROUTE_MAP_NAME, - bgp_static->rmap.name); + bgp_static->rmap.name); bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap); bgp_static->rmap.map = @@ -4620,7 +4619,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, } else { if (bgp_static->rmap.name) XFREE(MTYPE_ROUTE_MAP_NAME, - bgp_static->rmap.name); + bgp_static->rmap.name); bgp_static->rmap.name = NULL; bgp_static->rmap.map = NULL; bgp_static->valid = 0; @@ -4638,7 +4637,7 @@ static int bgp_static_set(struct vty *vty, const char *negate, if (rmap) { if (bgp_static->rmap.name) XFREE(MTYPE_ROUTE_MAP_NAME, - bgp_static->rmap.name); + bgp_static->rmap.name); bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap); bgp_static->rmap.map = @@ -5111,11 +5110,10 @@ DEFPY(bgp_network, } } - return bgp_static_set(vty, no, address_str ? addr_prefix_str:prefix_str, - AFI_IP, bgp_node_safi(vty), - map_name, backdoor?1:0, - label_index ? - (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); + return bgp_static_set( + vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP, + bgp_node_safi(vty), map_name, backdoor ? 1 : 0, + label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); } DEFPY(ipv6_bgp_network, @@ -5130,10 +5128,9 @@ DEFPY(ipv6_bgp_network, "Label index to associate with the prefix\n" "Label index value\n") { - return bgp_static_set(vty, no, prefix_str, AFI_IP6, - bgp_node_safi(vty), map_name, 0, - label_index ? - (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); + return bgp_static_set( + vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0, + label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX); } /* Aggreagete address: @@ -5858,8 +5855,7 @@ DEFUN (no_ipv6_aggregate_address, void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, const union g_addr *nexthop, ifindex_t ifindex, enum nexthop_types_t nhtype, uint32_t metric, - u_char type, u_short instance, - route_tag_t tag) + u_char type, u_short instance, route_tag_t tag) { struct bgp_info *new; struct bgp_info *bi; @@ -5874,7 +5870,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, /* Make default attribute. */ bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); - switch(nhtype) { + switch (nhtype) { case NEXTHOP_TYPE_IFINDEX: break; case NEXTHOP_TYPE_IPV4: @@ -6255,13 +6251,13 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, switch (af) { case AF_INET: sprintf(nexthop, "%s", - inet_ntop(af, &attr->mp_nexthop_global_in, - buf, BUFSIZ)); + inet_ntop(af, &attr->mp_nexthop_global_in, buf, + BUFSIZ)); break; case AF_INET6: sprintf(nexthop, "%s", - inet_ntop(af, &attr->mp_nexthop_global, - buf, BUFSIZ)); + inet_ntop(af, &attr->mp_nexthop_global, buf, + BUFSIZ)); break; default: sprintf(nexthop, "?"); @@ -6271,13 +6267,10 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, if (json_paths) { json_nexthop_global = json_object_new_object(); + json_object_string_add(json_nexthop_global, "afi", + (af == AF_INET) ? "ip" : "ipv6"); json_object_string_add(json_nexthop_global, - "afi", - (af == AF_INET) ? - "ip" : "ipv6"); - json_object_string_add(json_nexthop_global, - (af == AF_INET) ? - "ip" : "ipv6", + (af == AF_INET) ? "ip" : "ipv6", nexthop); json_object_boolean_true_add(json_nexthop_global, "used"); @@ -6289,92 +6282,80 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, json_object_string_add(json_nexthop_global, "ip", inet_ntoa(attr->nexthop)); - json_object_string_add(json_nexthop_global, - "afi", "ipv4"); + json_object_string_add(json_nexthop_global, "afi", + "ipv4"); json_object_boolean_true_add(json_nexthop_global, "used"); } else vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); } /* IPv4 Next Hop */ - else if (p->family == AF_INET - && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { + else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { if (json_paths) { json_nexthop_global = json_object_new_object(); - if ((safi == SAFI_MPLS_VPN) - || (safi == SAFI_EVPN)) - json_object_string_add(json_nexthop_global, - "ip", - inet_ntoa(attr->mp_nexthop_global_in)); + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) + json_object_string_add( + json_nexthop_global, "ip", + inet_ntoa(attr->mp_nexthop_global_in)); else - json_object_string_add(json_nexthop_global, - "ip", - inet_ntoa(attr->nexthop)); + json_object_string_add( + json_nexthop_global, "ip", + inet_ntoa(attr->nexthop)); - json_object_string_add(json_nexthop_global, - "afi", "ipv4"); + json_object_string_add(json_nexthop_global, "afi", + "ipv4"); json_object_boolean_true_add(json_nexthop_global, "used"); } else { - if ((safi == SAFI_MPLS_VPN) - || (safi == SAFI_EVPN)) + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) vty_out(vty, "%-16s", - inet_ntoa( - attr->mp_nexthop_global_in)); + inet_ntoa(attr->mp_nexthop_global_in)); else - vty_out(vty, "%-16s", - inet_ntoa(attr->nexthop)); + vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); } } /* IPv6 Next Hop */ - else if (p->family == AF_INET6 - || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { + else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { int len; char buf[BUFSIZ]; if (json_paths) { json_nexthop_global = json_object_new_object(); - json_object_string_add(json_nexthop_global, "ip", - inet_ntop(AF_INET6, - &attr->mp_nexthop_global, buf, - BUFSIZ)); - json_object_string_add(json_nexthop_global, - "afi", "ipv6"); - json_object_string_add(json_nexthop_global, - "scope", "global"); + json_object_string_add( + json_nexthop_global, "ip", + inet_ntop(AF_INET6, &attr->mp_nexthop_global, + buf, BUFSIZ)); + json_object_string_add(json_nexthop_global, "afi", + "ipv6"); + json_object_string_add(json_nexthop_global, "scope", + "global"); /* We display both LL & GL if both have been * received */ if ((attr->mp_nexthop_len == 32) || (binfo->peer->conf_if)) { - json_nexthop_ll = - json_object_new_object(); + json_nexthop_ll = json_object_new_object(); json_object_string_add( json_nexthop_ll, "ip", - inet_ntop( - AF_INET6, - &attr->mp_nexthop_local, - buf, BUFSIZ)); - json_object_string_add(json_nexthop_ll, - "afi", "ipv6"); - json_object_string_add(json_nexthop_ll, - "scope", + inet_ntop(AF_INET6, + &attr->mp_nexthop_local, buf, + BUFSIZ)); + json_object_string_add(json_nexthop_ll, "afi", + "ipv6"); + json_object_string_add(json_nexthop_ll, "scope", "link-local"); - if ((IPV6_ADDR_CMP( - &attr->mp_nexthop_global, - &attr->mp_nexthop_local) + if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global, + &attr->mp_nexthop_local) != 0) && !attr->mp_nexthop_prefer_global) json_object_boolean_true_add( - json_nexthop_ll, - "used"); + json_nexthop_ll, "used"); else json_object_boolean_true_add( - json_nexthop_global, - "used"); + json_nexthop_global, "used"); } else json_object_boolean_true_add( json_nexthop_global, "used"); @@ -6385,20 +6366,17 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, && !attr->mp_nexthop_prefer_global) || (binfo->peer->conf_if)) { if (binfo->peer->conf_if) { - len = vty_out( - vty, "%s", - binfo->peer->conf_if); + len = vty_out(vty, "%s", + binfo->peer->conf_if); len = 16 - len; /* len of IPv6 addr + max len of def ifname */ if (len < 1) - vty_out(vty, "\n%*s", - 36, " "); + vty_out(vty, "\n%*s", 36, " "); else - vty_out(vty, "%*s", len, - " "); + vty_out(vty, "%*s", len, " "); } else { len = vty_out( vty, "%s", @@ -6409,17 +6387,16 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, len = 16 - len; if (len < 1) - vty_out(vty, "\n%*s", - 36, " "); + vty_out(vty, "\n%*s", 36, " "); else - vty_out(vty, "%*s", len, - " "); + vty_out(vty, "%*s", len, " "); } } else { - len = vty_out(vty, "%s", - inet_ntop(AF_INET6, - &attr->mp_nexthop_global, - buf, BUFSIZ)); + len = vty_out( + vty, "%s", + inet_ntop(AF_INET6, + &attr->mp_nexthop_global, buf, + BUFSIZ)); len = 16 - len; if (len < 1) @@ -6433,8 +6410,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, /* MED/Metric */ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) if (json_paths) - json_object_int_add(json_path, "med", - attr->med); + json_object_int_add(json_path, "med", attr->med); else vty_out(vty, "%10u", attr->med); else if (!json_paths) @@ -6457,10 +6433,9 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, if (json_paths) { char buf[BUFSIZ]; - json_object_string_add(json_path, "peerId", - sockunion2str(&binfo->peer->su, - buf, - SU_ADDRSTRLEN)); + json_object_string_add( + json_path, "peerId", + sockunion2str(&binfo->peer->su, buf, SU_ADDRSTRLEN)); } /* Print aspath */ @@ -6474,9 +6449,8 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo, /* Print origin */ if (json_paths) - json_object_string_add( - json_path, "origin", - bgp_origin_long_str[attr->origin]); + json_object_string_add(json_path, "origin", + bgp_origin_long_str[attr->origin]); else vty_out(vty, "%s", bgp_origin_str[attr->origin]); @@ -6674,8 +6648,7 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p, if (attr) { if (((p->family == AF_INET) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) - || (safi == SAFI_EVPN - && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) + || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { @@ -6869,9 +6842,10 @@ static void damp_route_vty_out(struct vty *vty, struct prefix *p, bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json); else - vty_out(vty, "%s ", bgp_damp_reuse_time_vty(vty, binfo, timebuf, - BGP_UPTIME_LEN, - use_json, json)); + vty_out(vty, "%s ", + bgp_damp_reuse_time_vty(vty, binfo, timebuf, + BGP_UPTIME_LEN, use_json, + json)); /* Print attribute */ attr = binfo->attr; @@ -6950,8 +6924,9 @@ static void flap_route_vty_out(struct vty *vty, struct prefix *p, peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json, json); else - vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf, - BGP_UPTIME_LEN, 0, NULL)); + vty_out(vty, "%s ", + peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0, + NULL)); if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED) && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) { @@ -7092,8 +7067,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, tag_buf[0] = '\0'; if (binfo->extra && binfo->extra->num_labels) { bgp_evpn_label2str(binfo->extra->label, - binfo->extra->num_labels, - tag_buf, sizeof(tag_buf)); + binfo->extra->num_labels, tag_buf, + sizeof(tag_buf)); vty_out(vty, " VNI %s", tag_buf); } vty_out(vty, "\n"); @@ -7203,8 +7178,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, /* Line2 display Next-hop, Neighbor, Router-id */ /* Display the nexthop */ - if ((p->family == AF_INET || p->family == AF_ETHERNET || - p->family == AF_EVPN) + if ((p->family == AF_INET || p->family == AF_ETHERNET + || p->family == AF_EVPN) && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { @@ -7612,8 +7587,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, if (attr->community) { if (json_paths) { if (!attr->community->json) - community_str(attr->community, - true); + community_str(attr->community, true); json_object_lock(attr->community->json); json_object_object_add(json_path, "community", attr->community->json); @@ -7733,8 +7707,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0])) #endif { - mpls_label_t label = label_pton( - &binfo->extra->label[0]); + mpls_label_t label = + label_pton(&binfo->extra->label[0]); if (json_paths) json_object_int_add(json_path, "remoteLabel", label); @@ -7862,9 +7836,8 @@ static int bgp_show_community_list(struct vty *vty, struct bgp *bgp, static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp, const char *prefix, afi_t afi, safi_t safi, enum bgp_show_type type); -static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, - const char *regstr, afi_t afi, - safi_t safi, enum bgp_show_type type); +static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, + afi_t afi, safi_t safi, enum bgp_show_type type); static int bgp_show_community(struct vty *vty, struct bgp *bgp, const char *comstr, int exact, afi_t afi, safi_t safi); @@ -7872,9 +7845,10 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp, static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_table *table, enum bgp_show_type type, - void *output_arg, u_char use_json, - char *rd, int is_last, - unsigned long *output_cum, unsigned long *total_cum) + void *output_arg, u_char use_json, char *rd, + int is_last, unsigned long *output_cum, + unsigned long *total_cum, + unsigned long *json_header_depth) { struct bgp_info *ri; struct bgp_node *rn; @@ -7891,7 +7865,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (output_cum && *output_cum != 0) header = 0; - if (use_json && header) { + if (use_json && !*json_header_depth) { vty_out(vty, "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64 ",\n \"routerId\": \"%s\",\n \"routes\": { ", @@ -7899,8 +7873,11 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name, table->version, inet_ntoa(bgp->router_id)); - if (rd) + *json_header_depth = 2; + if (rd) { vty_out(vty, " \"routeDistinguishers\" : {"); + ++*json_header_depth; + } json_paths = json_object_new_object(); } @@ -7925,8 +7902,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, || type == bgp_show_type_flap_neighbor || type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) { - if (!(ri->extra - && ri->extra->damp_info)) + if (!(ri->extra && ri->extra->damp_info)) continue; } if (type == bgp_show_type_regexp) { @@ -7961,8 +7937,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, binfo.peer = ri->peer; binfo.attr = &dummy_attr; - ret = route_map_apply(rmap, &rn->p, - RMAP_BGP, &binfo); + ret = route_map_apply(rmap, &rn->p, RMAP_BGP, + &binfo); if (ret == RMAP_DENYMATCH) continue; } @@ -7973,8 +7949,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (ri->peer == NULL || ri->peer->su_remote == NULL - || !sockunion_same(ri->peer->su_remote, - su)) + || !sockunion_same(ri->peer->su_remote, su)) continue; } if (type == bgp_show_type_cidr_only) { @@ -8013,19 +7988,17 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct community *com = output_arg; if (!ri->attr->community - || !community_cmp(ri->attr->community, - com)) + || !community_cmp(ri->attr->community, com)) continue; } if (type == bgp_show_type_community_list) { struct community_list *list = output_arg; - if (!community_list_match( - ri->attr->community, list)) + if (!community_list_match(ri->attr->community, + list)) continue; } - if (type - == bgp_show_type_community_list_exact) { + if (type == bgp_show_type_community_list_exact) { struct community_list *list = output_arg; if (!community_list_exact_match( @@ -8043,8 +8016,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (type == bgp_show_type_lcommunity_list) { struct community_list *list = output_arg; - if (!lcommunity_list_match( - ri->attr->lcommunity, list)) + if (!lcommunity_list_match(ri->attr->lcommunity, + list)) continue; } if (type == bgp_show_type_lcommunity_all) { @@ -8069,9 +8042,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) vty_out(vty, BGP_SHOW_DAMP_HEADER); - else if ( - type == bgp_show_type_flap_statistics - || type == bgp_show_type_flap_neighbor) + else if (type == bgp_show_type_flap_statistics + || type == bgp_show_type_flap_neighbor) vty_out(vty, BGP_SHOW_FLAP_HEADER); else vty_out(vty, BGP_SHOW_HEADER); @@ -8086,16 +8058,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) damp_route_vty_out(vty, &rn->p, ri, display, - safi, use_json, - json_paths); + safi, use_json, json_paths); else if (type == bgp_show_type_flap_statistics || type == bgp_show_type_flap_neighbor) flap_route_vty_out(vty, &rn->p, ri, display, - safi, use_json, - json_paths); + safi, use_json, json_paths); else - route_vty_out(vty, &rn->p, ri, display, - safi, json_paths); + route_vty_out(vty, &rn->p, ri, display, safi, + json_paths); display++; } @@ -8106,8 +8076,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, p = &rn->p; sprintf(buf2, "%s/%d", - inet_ntop(p->family, &p->u.prefix, - buf, BUFSIZ), + inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); if (first) vty_out(vty, "\"%s\": ", buf2); @@ -8133,10 +8102,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (use_json) { if (json_paths) json_object_free(json_paths); - if (is_last) - vty_out(vty, " } }\n"); - else - vty_out(vty, " }, "); + if (rd) { + vty_out(vty, " }%s ", (is_last ? "" : ",")); + } + if (is_last) { + unsigned long i; + for (i = 0; i < *json_header_depth; ++i) + vty_out(vty, " } "); + } } else { if (is_last) { /* No route is displayed */ @@ -8163,6 +8136,7 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_node *rn, *next; unsigned long output_cum = 0; unsigned long total_cum = 0; + unsigned long json_header_depth = 0; bool show_msg; show_msg = (!use_json && type == bgp_show_type_normal); @@ -8178,9 +8152,9 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, memcpy(&prd, &(rn->p), sizeof(struct prefix_rd)); prefix_rd2str(&prd, rd, sizeof(rd)); bgp_show_table(vty, bgp, safi, rn->info, type, - output_arg, use_json, - rd, next == NULL, - &output_cum, &total_cum); + output_arg, use_json, rd, next == NULL, + &output_cum, &total_cum, + &json_header_depth); if (next == NULL) show_msg = false; } @@ -8194,14 +8168,13 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, "\nDisplayed %ld routes and %ld total paths\n", output_cum, total_cum); } - if (use_json) - vty_out(vty, " } }"); return CMD_SUCCESS; } static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, enum bgp_show_type type, void *output_arg, u_char use_json) { struct bgp_table *table; + unsigned long json_header_depth = 0; if (bgp == NULL) { bgp = bgp_get_default(); @@ -8226,7 +8199,7 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, safi = SAFI_UNICAST; return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json, - NULL, 1, NULL, NULL); + NULL, 1, NULL, NULL, &json_header_depth); } static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, @@ -8331,8 +8304,8 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, vty_out(vty, "BGP routing table entry for %s%s%s/%d\n", ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) - ? prefix_rd2str(prd, buf1, sizeof(buf1)) - : ""), + ? prefix_rd2str(prd, buf1, sizeof(buf1)) + : ""), ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":" : "", buf2, p->prefixlen); @@ -8543,8 +8516,9 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp, if (display) json_object_object_add(json, "paths", json_paths); - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { if (!display) { @@ -8811,14 +8785,17 @@ DEFUN (show_ip_bgp, if (argv_find(argv, argc, "community", &idx)) { /* show a specific community */ if (argv_find(argv, argc, "local-AS", &idx_community_type) - || argv_find(argv, argc, "no-advertise", &idx_community_type) + || argv_find(argv, argc, "no-advertise", + &idx_community_type) || argv_find(argv, argc, "no-export", &idx_community_type) - || argv_find(argv, argc, "graceful-shutdown", &idx_community_type) + || argv_find(argv, argc, "graceful-shutdown", + &idx_community_type) || argv_find(argv, argc, "AA:NN", &idx_community_type)) { if (argv_find(argv, argc, "exact-match", &idx)) exact_match = 1; - return bgp_show_community(vty, bgp, argv[idx_community_type]->arg, + return bgp_show_community(vty, bgp, + argv[idx_community_type]->arg, exact_match, afi, safi); } } @@ -9036,9 +9013,8 @@ DEFUN (show_ip_bgp_instance_all, return CMD_SUCCESS; } -static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, - const char *regstr, afi_t afi, - safi_t safi, enum bgp_show_type type) +static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr, + afi_t afi, safi_t safi, enum bgp_show_type type) { regex_t *regex; int rc; @@ -9185,7 +9161,8 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, ip_str); vty_out(vty, "%s\n", json_object_to_json_string_ext( - json_no, JSON_C_TO_STRING_PRETTY)); + json_no, + JSON_C_TO_STRING_PRETTY)); json_object_free(json_no); } else vty_out(vty, @@ -9206,8 +9183,8 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, json_object_string_add(json_no, "warning", "No such neighbor"); vty_out(vty, "%s\n", - json_object_to_json_string_ext(json_no, - JSON_C_TO_STRING_PRETTY)); + json_object_to_json_string_ext( + json_no, JSON_C_TO_STRING_PRETTY)); json_object_free(json_no); } else vty_out(vty, "No such neighbor\n"); @@ -9325,8 +9302,8 @@ static int bgp_table_stats_walker(struct thread *t) ts->counts[BGP_STATS_UNAGGREGATEABLE]++; /* announced address space */ if (space) - ts->total_space += pow(2.0, - space - rn->p.prefixlen); + ts->total_space += + pow(2.0, space - rn->p.prefixlen); } else if (prn->info) ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++; @@ -9441,20 +9418,20 @@ static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi, if (afi == AFI_IP6) { vty_out(vty, "%30s: ", "/32 equivalent "); vty_out(vty, "%12g\n", - ts.total_space * pow(2.0, -128+32)); + ts.total_space * pow(2.0, -128 + 32)); vty_out(vty, "%30s: ", "/48 equivalent "); vty_out(vty, "%12g\n", - ts.total_space * pow(2.0, -128+48)); + ts.total_space * pow(2.0, -128 + 48)); } else { vty_out(vty, "%30s: ", "% announced "); vty_out(vty, "%12.2f\n", ts.total_space * 100. * pow(2.0, -32)); vty_out(vty, "%30s: ", "/8 equivalent "); vty_out(vty, "%12.2f\n", - ts.total_space * pow(2.0, -32+8)); + ts.total_space * pow(2.0, -32 + 8)); vty_out(vty, "%30s: ", "/24 equivalent "); vty_out(vty, "%12.2f\n", - ts.total_space * pow(2.0, -32+24)); + ts.total_space * pow(2.0, -32 + 24)); } break; default: @@ -9591,9 +9568,9 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi, pcounts.table = peer->bgp->rib[afi][safi]; /* in-place call via thread subsystem so as to record execution time - * * stats for the thread-walk (i.e. ensure this can't be blamed on - * * on just vty_read()). - * */ + * stats for the thread-walk (i.e. ensure this can't be blamed on + * on just vty_read()). + */ thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0); if (use_json) { @@ -9616,8 +9593,9 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi, json, "recommended", "Please report this bug, with the above command output"); } - vty_out(vty, "%s\n", json_object_to_json_string_ext(json, - JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { @@ -9851,8 +9829,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, "bgpOriginatingDefaultNetwork", "0.0.0.0"); } else { - vty_out(vty, "BGP table version is %" PRIu64 - ", local router ID is %s\n", + vty_out(vty, + "BGP table version is %" PRIu64 + ", local router ID is %s\n", table->version, inet_ntoa(bgp->router_id)); vty_out(vty, BGP_SHOW_SCODE_HEADER); vty_out(vty, BGP_SHOW_OCODE_HEADER); @@ -9963,19 +9942,14 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, } if (adj->attr) { - bgp_attr_dup(&attr, - adj->attr); + bgp_attr_dup(&attr, adj->attr); ret = bgp_output_modifier( - peer, &rn->p, - &attr, afi, - safi, - rmap_name); + peer, &rn->p, &attr, + afi, safi, rmap_name); if (ret != RMAP_DENY) { route_vty_out_tmp( - vty, - &rn->p, - &attr, - safi, + vty, &rn->p, + &attr, safi, use_json, json_ar); output_count++; @@ -10000,8 +9974,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, output_count); } if (use_json) { - vty_out(vty, "%s\n", json_object_to_json_string_ext(json, - JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } } @@ -10938,18 +10913,20 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp, prefix_rd2str(prd, rdbuf, sizeof(rdbuf)); if (p->u.prefix_evpn.route_type == 5) { char local_buf[PREFIX_STRLEN]; - uint8_t family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) - ? AF_INET - : AF_INET6; - inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr, local_buf, - PREFIX_STRLEN); - sprintf(buf, "%s/%u", local_buf,p->u.prefix_evpn.ip_prefix_length); + uint8_t family = IS_EVPN_PREFIX_IPADDR_V4(( + struct prefix_evpn *)p) + ? AF_INET + : AF_INET6; + inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr, + local_buf, PREFIX_STRLEN); + sprintf(buf, "%s/%u", local_buf, + p->u.prefix_evpn.ip_prefix_length); } else { prefix2str(p, buf, sizeof(buf)); } - if (bgp_static->gatewayIp.family == AF_INET || - bgp_static->gatewayIp.family == AF_INET6) + if (bgp_static->gatewayIp.family == AF_INET + || bgp_static->gatewayIp.family == AF_INET6) inet_ntop(bgp_static->gatewayIp.family, &bgp_static->gatewayIp.u.prefix, buf2, sizeof(buf2)); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index de2410e009..4d5624d3b0 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -618,8 +618,7 @@ static route_map_result_t route_match_mac_address(void *rule, p.prefixlen = ETH_ALEN * 8; p.u.prefix_eth = prefix->u.prefix_evpn.mac; - return (access_list_apply(alist, &p) - == FILTER_DENY + return (access_list_apply(alist, &p) == FILTER_DENY ? RMAP_NOMATCH : RMAP_MATCH); } @@ -696,6 +695,56 @@ struct route_map_rule_cmd route_match_evpn_vni_cmd = { "evpn vni", route_match_vni, route_match_vni_compile, route_match_vni_free}; +/* `match evpn route-type' */ + +/* Match function should return 1 if match is success else return + zero. */ +static route_map_result_t route_match_evpn_route_type(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) +{ + u_char route_type = 0; + + if (type == RMAP_BGP) { + route_type = *((u_char *)rule); + + if (route_type == prefix->u.prefix_evpn.route_type) + return RMAP_MATCH; + } + + return RMAP_NOMATCH; +} + +/* Route map `route-type' match statement. */ +static void *route_match_evpn_route_type_compile(const char *arg) +{ + u_char *route_type = NULL; + + route_type = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_char)); + + if (strncmp(arg, "ma", 2) == 0) + *route_type = BGP_EVPN_MAC_IP_ROUTE; + else if (strncmp(arg, "mu", 2) == 0) + *route_type = BGP_EVPN_IMET_ROUTE; + else + *route_type = BGP_EVPN_IP_PREFIX_ROUTE; + + return route_type; +} + +/* Free route map's compiled `route-type' value. */ +static void route_match_evpn_route_type_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Route map commands for evpn route-type matching. */ +struct route_map_rule_cmd route_match_evpn_route_type_cmd = { + "evpn route-type", route_match_evpn_route_type, + route_match_evpn_route_type_compile, + route_match_evpn_route_type_free}; + /* `match local-preference LOCAL-PREF' */ /* Match function return 1 if match is success else return zero. */ @@ -3027,6 +3076,19 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name, } } } + + /* for type5 command route-maps */ + FOREACH_AFI_SAFI (afi, safi) { + if (bgp->adv_cmd_rmap[afi][safi].name && + strcmp(rmap_name, bgp->adv_cmd_rmap[afi][safi].name) == 0) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug( + "Processing route_map %s update on advertise type5 route command", + rmap_name); + bgp_evpn_withdraw_type5_routes(bgp, afi, safi); + bgp_evpn_advertise_type5_routes(bgp, afi, safi); + } + } } static int bgp_route_map_process_update_cb(char *rmap_name) @@ -3132,6 +3194,36 @@ DEFUN (no_match_mac_address, RMAP_EVENT_FILTER_DELETED); } +DEFUN (match_evpn_route_type, + match_evpn_route_type_cmd, + "match evpn route-type ", + MATCH_STR + EVPN_HELP_STR + "Match route-type\n" + "mac-ip route\n" + "IMET route\n" + "prefix route\n") +{ + return bgp_route_match_add(vty, "evpn route-type", argv[3]->arg, + RMAP_EVENT_MATCH_ADDED); +} + +DEFUN (no_match_evpn_route_type, + no_match_evpn_route_type_cmd, + "no match evpn route-type ", + NO_STR + MATCH_STR + EVPN_HELP_STR + "Match route-type\n" + "mac-ip route\n" + "IMET route\n" + "prefix route\n") +{ + return bgp_route_match_delete(vty, "evpn route-type", argv[4]->arg, + RMAP_EVENT_MATCH_DELETED); +} + + DEFUN (match_evpn_vni, match_evpn_vni_cmd, "match evpn vni (1-16777215)", @@ -3519,9 +3611,9 @@ DEFUN (set_ip_nexthop_peer, "Use peer address (for BGP only)\n") { int (*func)(struct vty *, struct route_map_index *, const char *, - const char *) = strmatch(argv[0]->text, "no") - ? generic_set_delete - : generic_set_add; + const char *) = strmatch(argv[0]->text, "no") + ? generic_set_delete + : generic_set_add; return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop", "peer-address"); @@ -3537,9 +3629,9 @@ DEFUN (set_ip_nexthop_unchanged, "Don't modify existing Next hop address\n") { int (*func)(struct vty *, struct route_map_index *, const char *, - const char *) = strmatch(argv[0]->text, "no") - ? generic_set_delete - : generic_set_add; + const char *) = strmatch(argv[0]->text, "no") + ? generic_set_delete + : generic_set_add; return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop", "unchanged"); @@ -3780,7 +3872,8 @@ DEFUN (set_community, buffer_putstr(b, "no-export"); continue; } - if (strncmp(argv[i]->arg, "graceful-shutdown", strlen(argv[i]->arg)) + if (strncmp(argv[i]->arg, "graceful-shutdown", + strlen(argv[i]->arg)) == 0) { buffer_putstr(b, "graceful-shutdown"); continue; @@ -4534,6 +4627,7 @@ void bgp_route_map_init(void) route_map_install_match(&route_match_tag_cmd); route_map_install_match(&route_match_mac_address_cmd); route_map_install_match(&route_match_evpn_vni_cmd); + route_map_install_match(&route_match_evpn_route_type_cmd); route_map_install_set(&route_set_ip_nexthop_cmd); route_map_install_set(&route_set_local_pref_cmd); @@ -4568,6 +4662,8 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &no_match_mac_address_cmd); install_element(RMAP_NODE, &match_evpn_vni_cmd); install_element(RMAP_NODE, &no_match_evpn_vni_cmd); + install_element(RMAP_NODE, &match_evpn_route_type_cmd); + install_element(RMAP_NODE, &no_match_evpn_route_type_cmd); install_element(RMAP_NODE, &match_aspath_cmd); install_element(RMAP_NODE, &no_match_aspath_cmd); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 6c06d72eb4..4dc199b951 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1540,7 +1540,8 @@ DEFUN (no_bgp_maxpaths, } ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd, - "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", NO_STR + "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]", + NO_STR "Forward packets over multiple paths\n" "Number of paths\n") @@ -1868,14 +1869,14 @@ static void bgp_redistribute_redo(struct bgp *bgp) struct listnode *node; struct bgp_redist *red; - for (afi = AFI_IP; afi < AFI_MAX; afi++) { - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - red_list = bgp->redist[afi][i]; - if (!red_list) - continue; + red_list = bgp->redist[afi][i]; + if (!red_list) + continue; - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) { bgp_redistribute_resend(bgp, afi, i, red->instance); } @@ -3394,7 +3395,7 @@ DEFUN (no_neighbor_set_peer_group, return CMD_WARNING_CONFIG_FAILED; } - ret = peer_group_unbind(bgp, peer, group); + ret = peer_delete(peer); return bgp_vty_return(vty, ret); } @@ -4363,23 +4364,23 @@ DEFUN (neighbor_attr_unchanged, SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED); SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED); } else { - if (!CHECK_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED) && - peer_af_flag_check(peer, afi, safi, - PEER_FLAG_AS_PATH_UNCHANGED)) { + if (!CHECK_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED) + && peer_af_flag_check(peer, afi, safi, + PEER_FLAG_AS_PATH_UNCHANGED)) { peer_af_flag_unset_vty(vty, peer_str, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED); } - if (!CHECK_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED) && - peer_af_flag_check(peer, afi, safi, - PEER_FLAG_NEXTHOP_UNCHANGED)) { + if (!CHECK_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED) + && peer_af_flag_check(peer, afi, safi, + PEER_FLAG_NEXTHOP_UNCHANGED)) { peer_af_flag_unset_vty(vty, peer_str, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED); } - if (!CHECK_FLAG(flags, PEER_FLAG_MED_UNCHANGED) && - peer_af_flag_check(peer, afi, safi, - PEER_FLAG_MED_UNCHANGED)) { + if (!CHECK_FLAG(flags, PEER_FLAG_MED_UNCHANGED) + && peer_af_flag_check(peer, afi, safi, + PEER_FLAG_MED_UNCHANGED)) { peer_af_flag_unset_vty(vty, peer_str, afi, safi, PEER_FLAG_MED_UNCHANGED); } @@ -6125,8 +6126,8 @@ DEFUN_NOSH (address_family_ipv4_safi, if (argc == 3) { VTY_DECLVAR_CONTEXT(bgp, bgp); safi_t safi = bgp_vty_safi_from_str(argv[2]->text); - if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT && - safi != SAFI_UNICAST && safi != SAFI_MULTICAST + if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT + && safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN) { vty_out(vty, "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); @@ -6149,8 +6150,8 @@ DEFUN_NOSH (address_family_ipv6_safi, if (argc == 3) { VTY_DECLVAR_CONTEXT(bgp, bgp); safi_t safi = bgp_vty_safi_from_str(argv[2]->text); - if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT && - safi != SAFI_UNICAST && safi != SAFI_MULTICAST + if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT + && safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN) { vty_out(vty, "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); @@ -6511,8 +6512,8 @@ DEFUN (show_bgp_vrfs, if (!uj && count == 1) vty_out(vty, "%4s %-5s %-16s %9s %10s %-37s %-10s %-15s\n", - "Type", "Id", "routerId", "#PeersVfg", - "#PeersEstb", "Name", "L3-VNI", "Rmac"); + "Type", "Id", "routerId", "#PeersVfg", + "#PeersEstb", "Name", "L3-VNI", "Rmac"); peers_cfg = peers_estb = 0; if (uj) @@ -6537,8 +6538,9 @@ DEFUN (show_bgp_vrfs, if (uj) { - int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN) ? -1 : - (int64_t)bgp->vrf_id; + int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN) + ? -1 + : (int64_t)bgp->vrf_id; json_object_string_add(json_vrf, "type", type); json_object_int_add(json_vrf, "vrfId", vrf_id_ui); json_object_string_add(json_vrf, "routerId", @@ -6549,17 +6551,18 @@ DEFUN (show_bgp_vrfs, peers_estb); json_object_int_add(json_vrf, "l3vni", bgp->l3vni); - json_object_string_add(json_vrf, "rmac", - prefix_mac2str(&bgp->rmac, buf, - sizeof(buf))); + json_object_string_add( + json_vrf, "rmac", + prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); json_object_object_add(json_vrfs, name, json_vrf); } else vty_out(vty, "%4s %-5d %-16s %9u %10u %-37s %-10u %-15s\n", - type, bgp->vrf_id == VRF_UNKNOWN ? - -1 : (int)bgp->vrf_id, - inet_ntoa(bgp->router_id), - peers_cfg, peers_estb, name, bgp->l3vni, + type, + bgp->vrf_id == VRF_UNKNOWN ? -1 + : (int)bgp->vrf_id, + inet_ntoa(bgp->router_id), peers_cfg, + peers_estb, name, bgp->l3vni, prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); } @@ -6568,8 +6571,9 @@ DEFUN (show_bgp_vrfs, json_object_int_add(json, "totalVrfs", count); - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { if (count) @@ -6718,17 +6722,20 @@ DEFUN (show_bgp_memory, /* Other attributes */ if ((count = community_count())) vty_out(vty, "%ld BGP community entries, using %s of memory\n", - count, mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(struct community))); + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct community))); if ((count = mtype_stats_alloc(MTYPE_ECOMMUNITY))) vty_out(vty, "%ld BGP community entries, using %s of memory\n", - count, mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(struct ecommunity))); + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct ecommunity))); if ((count = mtype_stats_alloc(MTYPE_LCOMMUNITY))) vty_out(vty, "%ld BGP large-community entries, using %s of memory\n", - count, mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(struct lcommunity))); + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct lcommunity))); if ((count = mtype_stats_alloc(MTYPE_CLUSTER))) vty_out(vty, "%ld Cluster lists, using %s of memory\n", count, @@ -6757,8 +6764,9 @@ DEFUN (show_bgp_memory, count * sizeof(struct hash_backet))); if ((count = mtype_stats_alloc(MTYPE_BGP_REGEXP))) vty_out(vty, "%ld compiled regexes, using %s of memory\n", - count, mtype_memstr(memstrbuf, sizeof(memstrbuf), - count * sizeof(regex_t))); + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(regex_t))); return CMD_SUCCESS; } @@ -6773,27 +6781,21 @@ static void bgp_show_bestpath_json(struct bgp *bgp, json_object *json) json_object_string_add(bestpath, "asPath", "confed"); if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) { - if (bgp_flag_check(bgp, - BGP_FLAG_MULTIPATH_RELAX_AS_SET)) - json_object_string_add(bestpath, - "multiPathRelax", + if (bgp_flag_check(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET)) + json_object_string_add(bestpath, "multiPathRelax", "as-set"); else - json_object_string_add(bestpath, - "multiPathRelax", + json_object_string_add(bestpath, "multiPathRelax", "true"); } else - json_object_string_add(bestpath, - "multiPathRelax", - "false"); + json_object_string_add(bestpath, "multiPathRelax", "false"); if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)) json_object_string_add(bestpath, "compareRouterId", "true"); if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED) || bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) { if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED)) - json_object_string_add(bestpath, "med", - "confed"); + json_object_string_add(bestpath, "med", "confed"); if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) json_object_string_add(bestpath, "med", "missing-as-worst"); @@ -6884,9 +6886,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, char memstrbuf[MTYPE_MEMSTR_LEN]; int64_t vrf_id_ui; - vrf_id_ui = - (bgp->vrf_id == VRF_UNKNOWN) ? -1 : - (int64_t)bgp->vrf_id; + vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN) + ? -1 + : (int64_t)bgp->vrf_id; /* Usage summary and header */ if (use_json) { @@ -6905,8 +6907,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, vty_out(vty, "BGP router identifier %s, local AS number %u vrf-id %d", inet_ntoa(bgp->router_id), bgp->as, - bgp->vrf_id == VRF_UNKNOWN ? -1 : - (int)bgp->vrf_id); + bgp->vrf_id == VRF_UNKNOWN + ? -1 + : (int)bgp->vrf_id); vty_out(vty, "\n"); } @@ -7015,8 +7018,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json, "peerGroupCount", ents); json_object_int_add( json, "peerGroupMemory", - ents * sizeof(struct - peer_group)); + ents + * sizeof(struct + peer_group)); } if (CHECK_FLAG(bgp->af_flags[afi][safi], @@ -7039,10 +7043,11 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, vty_out(vty, "RIB entries %ld, using %s of memory\n", ents, - mtype_memstr(memstrbuf, - sizeof(memstrbuf), - ents * sizeof(struct - bgp_node))); + mtype_memstr( + memstrbuf, sizeof(memstrbuf), + ents + * sizeof(struct + bgp_node))); /* Peer related usage */ ents = listcount(bgp->peer); @@ -7059,8 +7064,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, mtype_memstr( memstrbuf, sizeof(memstrbuf), - ents * sizeof(struct - peer_group))); + ents + * sizeof(struct + peer_group))); if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) @@ -7165,7 +7171,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, if (peer->status == Established) if (peer->afc_recv[afi][pfx_rcd_safi]) vty_out(vty, " %12ld", - peer->pcount[afi][pfx_rcd_safi]); + peer->pcount[afi] + [pfx_rcd_safi]); else vty_out(vty, " NoNeg"); else { @@ -7192,8 +7199,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, bgp_show_bestpath_json(bgp, json); - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { if (count) @@ -7829,8 +7837,9 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, paf = peer_af_find(p, afi, safi); if (paf && PAF_SUBGRP(paf)) { - vty_out(vty, " Update group %" PRIu64 - ", subgroup %" PRIu64 "\n", + vty_out(vty, + " Update group %" PRIu64 ", subgroup %" PRIu64 + "\n", PAF_UPDGRP(paf)->id, PAF_SUBGRP(paf)->id); vty_out(vty, " Packet Queue length %d\n", bpacket_queue_virtual_length(paf)); @@ -8300,7 +8309,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json, epoch_tbuf = time(NULL) - uptime; #if CONFDATE > 20200101 - CPP_NOTICE("bgpTimerUp should be deprecated and can be removed now"); + CPP_NOTICE( + "bgpTimerUp should be deprecated and can be removed now"); #endif /* * bgpTimerUp was miliseconds that was accurate @@ -8376,8 +8386,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json, "bgpTimerConfiguredKeepAliveIntervalMsecs", p->keepalive * 1000); } else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) - || (bgp->default_keepalive != - BGP_DEFAULT_KEEPALIVE)) { + || (bgp->default_keepalive + != BGP_DEFAULT_KEEPALIVE)) { json_object_int_add(json_neigh, "bgpTimerConfiguredHoldTimeMsecs", bgp->default_holdtime); @@ -8437,8 +8447,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json, vty_out(vty, ", keepalive interval is %d seconds\n", p->keepalive); } else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) - || (bgp->default_keepalive != - BGP_DEFAULT_KEEPALIVE)) { + || (bgp->default_keepalive + != BGP_DEFAULT_KEEPALIVE)) { vty_out(vty, " Configured hold time is %d", bgp->default_holdtime); vty_out(vty, ", keepalive interval is %d seconds\n", @@ -9629,8 +9639,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json, } else vty_out(vty, " Reduce the no. of prefix from %s, will restart in %ld seconds\n", - p->host, thread_timer_remain_second( - p->t_pmax_restart)); + p->host, + thread_timer_remain_second( + p->t_pmax_restart)); } else { if (use_json) json_object_boolean_true_add( @@ -9874,8 +9885,9 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, } if (use_json) { - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { vty_out(vty, "\n"); @@ -9910,7 +9922,8 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty, json_object_int_add(json, "vrfId", (bgp->vrf_id == VRF_UNKNOWN) - ? -1 : (int64_t) bgp->vrf_id); + ? -1 + : (int64_t)bgp->vrf_id); json_object_string_add( json, "vrfName", (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) @@ -10645,7 +10658,8 @@ DEFUN (show_ip_bgp_peer_groups, vrf = pg = NULL; int idx = 0; - vrf = argv_find(argv, argc, "VIEWVRFNAME", &idx) ? argv[idx]->arg : NULL; + vrf = argv_find(argv, argc, "VIEWVRFNAME", &idx) ? argv[idx]->arg + : NULL; pg = argv_find(argv, argc, "PGNAME", &idx) ? argv[idx]->arg : NULL; return bgp_show_peer_group_vty(vty, vrf, pg); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index e0bd74a206..1dc08e2b00 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -570,8 +570,8 @@ static int zebra_read_route(int command, struct zclient *zclient, /* Now perform the add/update. */ bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex, - nhtype, api.metric, api.type, - api.instance, api.tag); + nhtype, api.metric, api.type, api.instance, + api.tag); } else { bgp_redistribute_delete(bgp, &api.prefix, api.type, api.instance); @@ -1001,7 +1001,6 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, memset(&api, 0, sizeof(api)); memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr)); api.vrf_id = bgp->vrf_id; - api.nh_vrf_id = bgp->vrf_id; api.type = ZEBRA_ROUTE_BGP; api.safi = safi; api.prefix = *p; @@ -1081,7 +1080,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, api_nh = &api.nexthops[valid_nh_count]; api_nh->gate.ipv4 = *nexthop; - + api_nh->vrf_id = bgp->vrf_id; /* EVPN type-2 routes are programmed as onlink on l3-vni SVI */ @@ -1142,8 +1141,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; } - if (mpinfo->extra && - bgp_is_valid_label(&mpinfo->extra->label[0]) + if (mpinfo->extra + && bgp_is_valid_label(&mpinfo->extra->label[0]) && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) { has_valid_label = 1; label = label_pton(&mpinfo->extra->label[0]); @@ -1155,8 +1154,7 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, } /* if this is a evpn route we don't have to include the label */ - if (has_valid_label && - !(CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE))) + if (has_valid_label && !(CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE))) SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); if (info->sub_type != BGP_ROUTE_AGGREGATE) @@ -1198,8 +1196,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, sizeof(nh_buf)); label_buf[0] = '\0'; - if (has_valid_label && - !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) + if (has_valid_label + && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) sprintf(label_buf, "label %u", api_nh->labels[0]); zlog_debug(" nhop [%d]: %s %s", i + 1, nh_buf, @@ -1255,7 +1253,6 @@ void bgp_zebra_withdraw(struct prefix *p, struct bgp_info *info, safi_t safi) memset(&api, 0, sizeof(api)); memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr)); api.vrf_id = peer->bgp->vrf_id; - api.nh_vrf_id = peer->bgp->vrf_id; api.type = ZEBRA_ROUTE_BGP; api.safi = safi; api.prefix = *p; @@ -1579,8 +1576,7 @@ void bgp_zebra_instance_register(struct bgp *bgp) /* For default instance, register to learn about VNIs, if appropriate. */ - if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT - && is_evpn_enabled()) + if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled()) bgp_zebra_advertise_all_vni(bgp, 1); } @@ -1598,8 +1594,7 @@ void bgp_zebra_instance_deregister(struct bgp *bgp) /* For default instance, unregister learning about VNIs, if appropriate. */ - if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT - && is_evpn_enabled()) + if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled()) bgp_zebra_advertise_all_vni(bgp, 0); /* Deregister for router-id, interfaces, redistributed routes. */ @@ -1749,8 +1744,7 @@ static int bgp_zebra_process_local_l3vni(int cmd, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s", (cmd == ZEBRA_L3VNI_ADD) ? "add" : "del", - vrf_id_to_name(vrf_id), - l3vni, + vrf_id_to_name(vrf_id), l3vni, prefix_mac2str(&rmac, buf, sizeof(buf))); if (cmd == ZEBRA_L3VNI_ADD) @@ -1767,7 +1761,7 @@ static int bgp_zebra_process_local_vni(int command, struct zclient *zclient, struct stream *s; vni_t vni; struct bgp *bgp; - struct in_addr vtep_ip = { INADDR_ANY }; + struct in_addr vtep_ip = {INADDR_ANY}; vrf_id_t tenant_vrf_id = VRF_DEFAULT; s = zclient->ibuf; @@ -1784,8 +1778,8 @@ static int bgp_zebra_process_local_vni(int command, struct zclient *zclient, if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Rx VNI %s VRF %s VNI %u tenant-vrf %s", (command == ZEBRA_VNI_ADD) ? "add" : "del", - vrf_id_to_name(vrf_id), - vni, vrf_id_to_name(tenant_vrf_id)); + vrf_id_to_name(vrf_id), vni, + vrf_id_to_name(tenant_vrf_id)); if (command == ZEBRA_VNI_ADD) return bgp_evpn_local_vni_add( @@ -1844,8 +1838,7 @@ static int bgp_zebra_process_local_macip(int command, struct zclient *zclient, return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip); } -static void bgp_zebra_process_local_ip_prefix(int cmd, - struct zclient *zclient, +static void bgp_zebra_process_local_ip_prefix(int cmd, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { @@ -1871,25 +1864,19 @@ static void bgp_zebra_process_local_ip_prefix(int cmd, if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) { if (p.family == AF_INET) - return bgp_evpn_advertise_type5_route(bgp_vrf, &p, - NULL, - AFI_IP, - SAFI_UNICAST); + return bgp_evpn_advertise_type5_route( + bgp_vrf, &p, NULL, AFI_IP, SAFI_UNICAST); else - return bgp_evpn_advertise_type5_route(bgp_vrf, &p, - NULL, - AFI_IP6, - SAFI_UNICAST); + return bgp_evpn_advertise_type5_route( + bgp_vrf, &p, NULL, AFI_IP6, SAFI_UNICAST); } else { if (p.family == AF_INET) - return bgp_evpn_withdraw_type5_route(bgp_vrf, &p, - AFI_IP, - SAFI_UNICAST); + return bgp_evpn_withdraw_type5_route( + bgp_vrf, &p, AFI_IP, SAFI_UNICAST); else - return bgp_evpn_withdraw_type5_route(bgp_vrf, &p, - AFI_IP6, - SAFI_UNICAST); + return bgp_evpn_withdraw_type5_route( + bgp_vrf, &p, AFI_IP6, SAFI_UNICAST); } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 4ff0ef41e0..78e748fb6c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1403,16 +1403,12 @@ static void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi, if (rn->info != NULL) { /* Special handling for 2-level routing * tables. */ - if (safi == SAFI_MPLS_VPN - || safi == SAFI_ENCAP + if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { - for (nrn = bgp_table_top(( - struct bgp_table - *)(rn->info)); - nrn; - nrn = bgp_route_next(nrn)) - bgp_process(bgp, nrn, - afi, safi); + for (nrn = bgp_table_top( + (struct bgp_table *)(rn->info)); + nrn; nrn = bgp_route_next(nrn)) + bgp_process(bgp, nrn, afi, safi); } else bgp_process(bgp, rn, afi, safi); } @@ -1864,8 +1860,7 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) peer->afc[afi][safi] = 1; if (peer->group) - peer_group2peer_config_copy_af(peer->group, peer, - afi, safi); + peer_group2peer_config_copy_af(peer->group, peer, afi, safi); if (!active && peer_active(peer)) { bgp_timer_set(peer); @@ -1933,12 +1928,14 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi) ret |= peer_activate_af(peer, afi, safi); } - /* If this is the first peer to be activated for this afi/labeled-unicast - * recalc bestpaths to trigger label allocation */ - if (safi == SAFI_LABELED_UNICAST && !bgp->allocate_mpls_labels[afi][SAFI_UNICAST]) { + /* If this is the first peer to be activated for this + * afi/labeled-unicast recalc bestpaths to trigger label allocation */ + if (safi == SAFI_LABELED_UNICAST + && !bgp->allocate_mpls_labels[afi][SAFI_UNICAST]) { if (BGP_DEBUG(zebra, ZEBRA)) - zlog_info("peer(s) are now active for labeled-unicast, allocate MPLS labels"); + zlog_info( + "peer(s) are now active for labeled-unicast, allocate MPLS labels"); bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 1; bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST); @@ -2027,14 +2024,15 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi) bgp = peer->bgp; - /* If this is the last peer to be deactivated for this afi/labeled-unicast - * recalc bestpaths to trigger label deallocation */ - if (safi == SAFI_LABELED_UNICAST && - bgp->allocate_mpls_labels[afi][SAFI_UNICAST] && - !bgp_afi_safi_peer_exists(bgp, afi, safi)) { + /* If this is the last peer to be deactivated for this + * afi/labeled-unicast recalc bestpaths to trigger label deallocation */ + if (safi == SAFI_LABELED_UNICAST + && bgp->allocate_mpls_labels[afi][SAFI_UNICAST] + && !bgp_afi_safi_peer_exists(bgp, afi, safi)) { if (BGP_DEBUG(zebra, ZEBRA)) - zlog_info("peer(s) are no longer active for labeled-unicast, deallocate MPLS labels"); + zlog_info( + "peer(s) are no longer active for labeled-unicast, deallocate MPLS labels"); bgp->allocate_mpls_labels[afi][SAFI_UNICAST] = 0; bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST); @@ -2654,7 +2652,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, } } else if (peer->afc[afi][safi]) peer_deactivate(peer, afi, safi); - } + } if (peer->group) { assert(group && peer->group == group); @@ -2856,8 +2854,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get()); bgp->peer = list_new(); bgp->peer->cmp = (int (*)(void *, void *))peer_cmp; - bgp->peerhash = hash_create(peer_hash_key_make, - peer_hash_same, + bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same, "BGP Peer Hash"); bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE; @@ -3988,8 +3985,9 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi, } /* Track if addpath TX is in use */ - if (flag & (PEER_FLAG_ADDPATH_TX_ALL_PATHS - | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) { + if (flag + & (PEER_FLAG_ADDPATH_TX_ALL_PATHS + | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) { bgp = peer->bgp; addpath_tx_used = 0; @@ -6802,8 +6800,9 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, } else { if (!peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) - && (!g_peer || peer_af_flag_check(g_peer, afi, safi, - PEER_FLAG_SEND_COMMUNITY)) + && (!g_peer + || peer_af_flag_check(g_peer, afi, safi, + PEER_FLAG_SEND_COMMUNITY)) && !peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY) && (!g_peer @@ -6811,9 +6810,10 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, PEER_FLAG_SEND_EXT_COMMUNITY)) && !peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY) - && (!g_peer || peer_af_flag_check( - g_peer, afi, safi, - PEER_FLAG_SEND_LARGE_COMMUNITY))) { + && (!g_peer + || peer_af_flag_check( + g_peer, afi, safi, + PEER_FLAG_SEND_LARGE_COMMUNITY))) { vty_out(vty, " no neighbor %s send-community all\n", addr); } else { @@ -6841,9 +6841,10 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, if (!peer_af_flag_check(peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) - && (!g_peer || peer_af_flag_check( - g_peer, afi, safi, - PEER_FLAG_SEND_COMMUNITY))) { + && (!g_peer + || peer_af_flag_check( + g_peer, afi, safi, + PEER_FLAG_SEND_COMMUNITY))) { vty_out(vty, " no neighbor %s send-community\n", addr); @@ -6954,17 +6955,17 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, bgp_config_write_filter(vty, peer, afi, safi); /* atribute-unchanged. */ - if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) || - peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED) || - peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) { + if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) + || peer_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_UNCHANGED) + || peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) { - if (!peer_group_active(peer) || - peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_AS_PATH_UNCHANGED) || - peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_NEXTHOP_UNCHANGED) || - peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_MED_UNCHANGED)) { + if (!peer_group_active(peer) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_AS_PATH_UNCHANGED) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_NEXTHOP_UNCHANGED) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_MED_UNCHANGED)) { vty_out(vty, " neighbor %s attribute-unchanged%s%s%s\n", diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index c4ac4b0adb..220b6d989e 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -262,13 +262,14 @@ struct bgp { /* $FRR indent$ */ /* clang-format off */ #define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */ - u_int32_t - maxmed_admin_value; /* Max-med value when administrative in on + u_int32_t maxmed_admin_value; /* Max-med value when administrative in on */ + /* $FRR indent$ */ + /* clang-format off */ #define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */ - u_char maxmed_active; /* 1/0 if max-med is active or not */ - u_int32_t maxmed_value; /* Max-med value when its active */ + u_char maxmed_active; /* 1/0 if max-med is active or not */ + u_int32_t maxmed_value; /* Max-med value when its active */ /* BGP update delay on startup */ struct thread *t_update_delay; @@ -451,6 +452,9 @@ struct bgp { /* list of corresponding l2vnis (struct bgpevpn) */ struct list *l2vnis; + /* route map for advertise ipv4/ipv6 unicast (type-5 routes) */ + struct bgp_rmap adv_cmd_rmap[AFI_MAX][SAFI_MAX]; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(bgp) @@ -828,8 +832,8 @@ struct peer { #define PEER_CONFIG_ROUTEADV (1 << 2) /* route advertise */ #define PEER_GROUP_CONFIG_TIMER (1 << 3) /* timers from peer-group */ -#define PEER_OR_GROUP_TIMER_SET(peer) \ - (CHECK_FLAG(peer->config, PEER_CONFIG_TIMER) \ +#define PEER_OR_GROUP_TIMER_SET(peer) \ + (CHECK_FLAG(peer->config, PEER_CONFIG_TIMER) \ || CHECK_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER)) _Atomic uint32_t holdtime; @@ -869,21 +873,29 @@ struct peer { /* workqueues */ struct work_queue *clear_node_queue; -#define PEER_TOTAL_RX(peer) \ - atomic_load_explicit(&peer->open_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->update_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->notify_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->refresh_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->keepalive_in, memory_order_relaxed) + \ - atomic_load_explicit(&peer->dynamic_cap_in, memory_order_relaxed) +#define PEER_TOTAL_RX(peer) \ + atomic_load_explicit(&peer->open_in, memory_order_relaxed) \ + + atomic_load_explicit(&peer->update_in, memory_order_relaxed) \ + + atomic_load_explicit(&peer->notify_in, memory_order_relaxed) \ + + atomic_load_explicit(&peer->refresh_in, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->keepalive_in, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->dynamic_cap_in, \ + memory_order_relaxed) -#define PEER_TOTAL_TX(peer) \ - atomic_load_explicit(&peer->open_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->update_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->notify_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->refresh_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->keepalive_out, memory_order_relaxed) + \ - atomic_load_explicit(&peer->dynamic_cap_out, memory_order_relaxed) +#define PEER_TOTAL_TX(peer) \ + atomic_load_explicit(&peer->open_out, memory_order_relaxed) \ + + atomic_load_explicit(&peer->update_out, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->notify_out, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->refresh_out, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->keepalive_out, \ + memory_order_relaxed) \ + + atomic_load_explicit(&peer->dynamic_cap_out, \ + memory_order_relaxed) /* Statistics field */ _Atomic uint32_t open_in; /* Open message input count */ @@ -898,7 +910,7 @@ struct peer { _Atomic uint32_t refresh_in; /* Route Refresh input count */ _Atomic uint32_t refresh_out; /* Route Refresh output count */ _Atomic uint32_t dynamic_cap_in; /* Dynamic Capability input count. */ - _Atomic uint32_t dynamic_cap_out; /* Dynamic Capability output count. */ + _Atomic uint32_t dynamic_cap_out; /* Dynamic Capability output count. */ /* BGP state count */ u_int32_t established; /* Established */ @@ -1480,7 +1492,8 @@ extern int peer_cmp(struct peer *p1, struct peer *p2); extern int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, iana_safi_t pkt_safi, afi_t *afi, safi_t *safi); extern int bgp_map_afi_safi_int2iana(afi_t afi, safi_t safi, - iana_afi_t *pkt_afi, iana_safi_t *pkt_safi); + iana_afi_t *pkt_afi, + iana_safi_t *pkt_safi); extern struct peer_af *peer_af_create(struct peer *, afi_t, safi_t); extern struct peer_af *peer_af_find(struct peer *, afi_t, safi_t); diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index e3cb739464..f28b8a2ced 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -260,20 +260,21 @@ int bgp_rfapi_is_vnc_configured(struct bgp *bgp) /*********************************************************************** * VNC Configuration/CLI ***********************************************************************/ -#define VNC_VTY_CONFIG_CHECK(bgp) \ - { \ - switch (bgp_rfapi_is_vnc_configured(bgp)) { \ - case EPERM: \ - vty_out(vty, "VNC operations only permitted on default BGP instance.\n"); \ - return CMD_WARNING_CONFIG_FAILED; \ - break; \ - case ENXIO: \ - vty_out(vty, "VNC not configured.\n"); \ - return CMD_WARNING_CONFIG_FAILED; \ - break; \ - default: \ - break; \ - } \ +#define VNC_VTY_CONFIG_CHECK(bgp) \ + { \ + switch (bgp_rfapi_is_vnc_configured(bgp)) { \ + case EPERM: \ + vty_out(vty, \ + "VNC operations only permitted on default BGP instance.\n"); \ + return CMD_WARNING_CONFIG_FAILED; \ + break; \ + case ENXIO: \ + vty_out(vty, "VNC not configured.\n"); \ + return CMD_WARNING_CONFIG_FAILED; \ + break; \ + default: \ + break; \ + } \ } DEFUN (vnc_advertise_un_method, @@ -509,9 +510,8 @@ DEFUN (vnc_defaults_responselifetime, } else { rspint = strtoul(argv[1]->arg, NULL, 10); if (rspint > INT32_MAX) - rspint = - INT32_MAX; /* is really an int, not an unsigned - int */ + rspint = INT32_MAX; /* is really an int, not an unsigned + int */ } bgp->rfapi_cfg->default_response_lifetime = rspint; @@ -554,7 +554,7 @@ rfapi_group_new(struct bgp *bgp, rfapi_group_cfg_type_t type, const char *name) /* add to tail of list */ listnode_add(bgp->rfapi_cfg->nve_groups_sequential, rfg); } - rfg->label = MPLS_LABEL_ILLEGAL; + rfg->label = MPLS_LABEL_NONE; QOBJ_REG(rfg, rfapi_nve_group_cfg); return rfg; @@ -1631,14 +1631,14 @@ DEFUN (vnc_nve_group_export_no_prefixlist, return CMD_WARNING_CONFIG_FAILED; } - if (argv[idx-1]->text[0] == 'z') + if (argv[idx - 1]->text[0] == 'z') is_bgp = 0; - idx += 2; /* skip afi and keyword */ + idx += 2; /* skip afi and keyword */ if (is_bgp) { - if (idx == argc || - strmatch(argv[idx]->arg, - rfg->plist_export_bgp_name[afi])) { + if (idx == argc + || strmatch(argv[idx]->arg, + rfg->plist_export_bgp_name[afi])) { if (rfg->plist_export_bgp_name[afi]) free(rfg->plist_export_bgp_name[afi]); rfg->plist_export_bgp_name[afi] = NULL; @@ -1647,9 +1647,9 @@ DEFUN (vnc_nve_group_export_no_prefixlist, vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi); } } else { - if (idx == argc || - strmatch(argv[idx]->arg, - rfg->plist_export_zebra_name[afi])) { + if (idx == argc + || strmatch(argv[idx]->arg, + rfg->plist_export_zebra_name[afi])) { if (rfg->plist_export_zebra_name[afi]) free(rfg->plist_export_zebra_name[afi]); rfg->plist_export_zebra_name[afi] = NULL; @@ -1700,7 +1700,7 @@ DEFUN (vnc_nve_group_export_prefixlist, return CMD_WARNING_CONFIG_FAILED; } - if (argv[idx-1]->text[0] == 'z') + if (argv[idx - 1]->text[0] == 'z') is_bgp = 0; idx = argc - 1; @@ -1758,18 +1758,19 @@ DEFUN (vnc_nve_group_export_no_routemap, switch (argv[idx]->text[0]) { case 'z': is_bgp = 0; - /* fall thru */ + /* fall thru */ case 'b': idx += 2; break; - default: /* route-map */ + default: /* route-map */ idx++; break; } if (is_bgp) { - if (idx == argc || - strmatch(argv[idx]->arg, rfg->routemap_export_bgp_name)) { + if (idx == argc + || strmatch(argv[idx]->arg, + rfg->routemap_export_bgp_name)) { if (rfg->routemap_export_bgp_name) free(rfg->routemap_export_bgp_name); rfg->routemap_export_bgp_name = NULL; @@ -1779,9 +1780,9 @@ DEFUN (vnc_nve_group_export_no_routemap, vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); } } else { - if (idx == argc || - strmatch(argv[idx]->arg, - rfg->routemap_export_zebra_name)) { + if (idx == argc + || strmatch(argv[idx]->arg, + rfg->routemap_export_zebra_name)) { if (rfg->routemap_export_zebra_name) free(rfg->routemap_export_zebra_name); rfg->routemap_export_zebra_name = NULL; @@ -2466,8 +2467,7 @@ bgp_rfapi_delete_named_nve_group(struct vty *vty, /* NULL = no output */ if (rfg->rfd) clear_vnc_vrf_closer(rfg); bgp_rfapi_delete_nve_group(vty, bgp, rfg); - } - else /* must be delete all */ + } else /* must be delete all */ for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential, node, nnode, rfg)) { if (rfg->rfd) @@ -2977,6 +2977,11 @@ DEFUN_NOSH (vnc_vrf_policy, struct rfapi_nve_group_cfg *rfg; VTY_DECLVAR_CONTEXT(bgp, bgp); + if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) { + vty_out(vty, "Can't configure vrf-policy within a BGP VRF instance\n"); + return CMD_WARNING_CONFIG_FAILED; + } + /* Search for name */ rfg = bgp_rfapi_cfg_match_byname(bgp, argv[1]->arg, RFAPI_GROUP_CFG_VRF); @@ -3007,6 +3012,10 @@ DEFUN (vnc_no_vrf_policy, { VTY_DECLVAR_CONTEXT(bgp, bgp); + /* silently return */ + if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF) + return CMD_SUCCESS; + return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[2]->arg, RFAPI_GROUP_CFG_VRF); } @@ -3063,7 +3072,7 @@ DEFUN (vnc_vrf_policy_no_label, vnc_redistribute_prechange(bgp); } - rfg->label = MPLS_LABEL_ILLEGAL; + rfg->label = MPLS_LABEL_NONE; if (bgp->rfapi_cfg->rfg_redist == rfg) { vnc_redistribute_postchange(bgp); @@ -3950,7 +3959,9 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) if (rfg->plist_export_bgp_name[afi]) { vty_out(vty, " export %s%s prefix-list %s\n", - (rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "bgp "), + (rfg->type == RFAPI_GROUP_CFG_VRF + ? "" + : "bgp "), afistr, rfg->plist_export_bgp_name [afi]); @@ -3958,7 +3969,9 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) if (rfg->plist_export_zebra_name[afi]) { vty_out(vty, " export %s%s prefix-list %s\n", - (rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "zebra "), + (rfg->type == RFAPI_GROUP_CFG_VRF + ? "" + : "zebra "), afistr, rfg->plist_export_zebra_name [afi]); @@ -3993,12 +4006,16 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) if (rfg->routemap_export_bgp_name) { vty_out(vty, " export %sroute-map %s\n", - (rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "bgp "), + (rfg->type == RFAPI_GROUP_CFG_VRF + ? "" + : "bgp "), rfg->routemap_export_bgp_name); } if (rfg->routemap_export_zebra_name) { vty_out(vty, " export %sroute-map %s\n", - (rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "zebra "), + (rfg->type == RFAPI_GROUP_CFG_VRF + ? "" + : "zebra "), rfg->routemap_export_zebra_name); } if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) { @@ -4098,7 +4115,8 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) } if (hc->default_rd.prefixlen - || hc->default_response_lifetime != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT + || hc->default_response_lifetime + != BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT || hc->default_rt_import_list || hc->default_rt_export_list || hc->nve_groups_sequential->count) { @@ -4184,8 +4202,8 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) prefix2str(&rfg->vn_prefix, buf, sizeof(buf)); - vty_out(vty, " prefix %s %s\n", - "vn", buf); + vty_out(vty, " prefix %s %s\n", "vn", + buf); } if (rfg->un_prefix.family && rfg->un_node) { @@ -4193,8 +4211,8 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) prefix2str(&rfg->un_prefix, buf, sizeof(buf)); - vty_out(vty, " prefix %s %s\n", - "un", buf); + vty_out(vty, " prefix %s %s\n", "un", + buf); } @@ -4215,11 +4233,10 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp) value); } else - vty_out(vty, - " rd %s\n", - prefix_rd2str(&rfg->rd, - buf, - sizeof(buf))); + vty_out(vty, " rd %s\n", + prefix_rd2str( + &rfg->rd, buf, + sizeof(buf))); } if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) { vty_out(vty, " response-lifetime "); diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index 92d7e6fc76..6afcd21a10 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -396,7 +396,6 @@ static void vnc_zebra_route_msg(struct prefix *p, unsigned int nhp_count, memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_VNC; api.safi = SAFI_UNICAST; api.prefix = *p; @@ -407,6 +406,7 @@ static void vnc_zebra_route_msg(struct prefix *p, unsigned int nhp_count, for (i = 0; i < api.nexthop_num; i++) { api_nh = &api.nexthops[i]; + api_nh->vrf_id = VRF_DEFAULT; switch (p->family) { case AF_INET: memcpy(&api_nh->gate.ipv4, nhp_ary4[i], diff --git a/debianpkg/backports/ubuntu12.04/debian/control b/debianpkg/backports/ubuntu12.04/debian/control index 17ceeb0381..9bae348840 100644 --- a/debianpkg/backports/ubuntu12.04/debian/control +++ b/debianpkg/backports/ubuntu12.04/debian/control @@ -13,7 +13,7 @@ Package: frr Architecture: any Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends} Pre-Depends: adduser -Conflicts: zebra, zebra-pj +Conflicts: zebra, zebra-pj, quagga Replaces: zebra, zebra-pj Suggests: snmpd Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga diff --git a/debianpkg/backports/ubuntu14.04/debian/control b/debianpkg/backports/ubuntu14.04/debian/control index c22bd3bd58..3f31f18462 100644 --- a/debianpkg/backports/ubuntu14.04/debian/control +++ b/debianpkg/backports/ubuntu14.04/debian/control @@ -13,7 +13,7 @@ Package: frr Architecture: any Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends} Pre-Depends: adduser -Conflicts: zebra, zebra-pj +Conflicts: zebra, zebra-pj, quagga Replaces: zebra, zebra-pj Suggests: snmpd Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga diff --git a/doc/Building_FRR_on_Debian9.md b/doc/Building_FRR_on_Debian9.md index 1536c25932..e2d424a3ea 100644 --- a/doc/Building_FRR_on_Debian9.md +++ b/doc/Building_FRR_on_Debian9.md @@ -20,7 +20,7 @@ any packages** sudo addgroup --system --gid 92 frr sudo addgroup --system --gid 85 frrvty - sudo adduser --system --ingroup frr --home /var/run/frr/ \ + sudo adduser --system --ingroup frr --home /var/opt/frr/ \ --gecos "FRR suite" --shell /bin/false frr sudo usermod -a -G frrvty frr @@ -34,7 +34,7 @@ an example.) ./bootstrap.sh ./configure \ --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ + --localstatedir=/var/opt/frr \ --sbindir=/usr/lib/frr \ --sysconfdir=/etc/frr \ --enable-vtysh \ @@ -61,6 +61,7 @@ an example.) ### Create empty FRR configuration files sudo install -m 755 -o frr -g frr -d /var/log/frr + sudo install -m 755 -o frr -g frr -d /var/opt/frr sudo install -m 775 -o frr -g frrvty -d /etc/frr sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf @@ -91,20 +92,6 @@ other settings) ### Troubleshooting -**Local state directory** - -The local state directory must exist and have the correct permissions applied -for the frrouting daemons to start. In the above ./configure example the -local state directory is set to /var/run/frr (--localstatedir=/var/run/frr) -Debian considers /var/run/frr to be temporary and this is removed after a -reboot. - -When using a different local state directory you need to create the new -directory and change the ownership to the frr user, for example: - - mkdir /var/opt/frr - chown frr /var/opt/frr - **Shared library error** If you try and start any of the frrouting daemons you may see the below error diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index f18d39d575..3759c64148 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -366,7 +366,6 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_EIGRP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); @@ -378,6 +377,7 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors) if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; if (te->adv_router->src.s_addr) { api_nh->gate.ipv4 = te->adv_router->src; api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; @@ -408,7 +408,6 @@ void eigrp_zebra_route_delete(struct prefix *p) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_EIGRP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); diff --git a/indent.py b/indent.py index a2c18e556d..560c13c77d 100644 --- a/indent.py +++ b/indent.py @@ -6,7 +6,7 @@ import sys, re, subprocess, os # find all DEFUNs defun_re = re.compile( - r'^(DEF(UN(_NOSH|_HIDDEN)?|PY)\s*\(.*?)^(?=\s*\{)', + r'^((DEF(UN(_NOSH|_HIDDEN)?|PY)|ALIAS)\s*\(.*?)^(?=\s*\{)', re.M | re.S) define_re = re.compile( r'((^#\s*define[^\n]+[^\\]\n)+)', diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 95e02f8691..20ce0f1fad 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -293,6 +293,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit, if (ip) { listnode_delete(circuit->ip_addrs, ip); + prefix_ipv4_free(ip); if (circuit->area) lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); @@ -328,6 +329,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit, } if (ip6) { listnode_delete(circuit->ipv6_link, ip6); + prefix_ipv6_free(ip6); found = 1; } } else { @@ -339,6 +341,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit, } if (ip6) { listnode_delete(circuit->ipv6_non_link, ip6); + prefix_ipv6_free(ip6); found = 1; } } @@ -1165,7 +1168,6 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router, struct isis_area *area = circuit->area; bool change = circuit->ip_router != ip_router || circuit->ipv6_router != ipv6_router; - bool was_enabled = !!circuit->area; area->ip_circuits += ip_router - circuit->ip_router; area->ipv6_circuits += ipv6_router - circuit->ipv6_router; @@ -1179,8 +1181,6 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router, if (!ip_router && !ipv6_router) isis_csm_state_change(ISIS_DISABLE, circuit, area); - else if (!was_enabled) - isis_csm_state_change(ISIS_ENABLE, circuit, area); else lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); } diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 0512a18a2a..ac640c5e49 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -261,7 +261,6 @@ static void isis_zebra_route_add_route(struct prefix *prefix, memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_ISIS; api.safi = SAFI_UNICAST; api.prefix = *prefix; @@ -281,6 +280,7 @@ static void isis_zebra_route_add_route(struct prefix *prefix, if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; /* FIXME: can it be ? */ if (nexthop->ip.s_addr != INADDR_ANY) { api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; @@ -303,6 +303,7 @@ static void isis_zebra_route_add_route(struct prefix *prefix, } api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; api_nh->gate.ipv6 = nexthop6->ip6; api_nh->ifindex = nexthop6->ifindex; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; @@ -330,7 +331,6 @@ static void isis_zebra_route_del_route(struct prefix *prefix, memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_ISIS; api.safi = SAFI_UNICAST; api.prefix = *prefix; diff --git a/ldpd/labelmapping.c b/ldpd/labelmapping.c index 5662038a58..944f93331f 100644 --- a/ldpd/labelmapping.c +++ b/ldpd/labelmapping.c @@ -320,9 +320,9 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) /* do not accept invalid labels */ if (label > MPLS_LABEL_MAX || (label <= MPLS_LABEL_RESERVED_MAX && - label != MPLS_LABEL_IPV4NULL && - label != MPLS_LABEL_IPV6NULL && - label != MPLS_LABEL_IMPLNULL)) { + label != MPLS_LABEL_IPV4_EXPLICIT_NULL && + label != MPLS_LABEL_IPV6_EXPLICIT_NULL && + label != MPLS_LABEL_IMPLICIT_NULL)) { session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, msg.type); goto err; @@ -396,7 +396,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) case MAP_TYPE_PREFIX: switch (me->map.fec.prefix.af) { case AF_INET: - if (label == MPLS_LABEL_IPV6NULL) { + if (label == MPLS_LABEL_IPV6_EXPLICIT_NULL) { session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, msg.type); goto err; @@ -405,7 +405,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type) goto next; break; case AF_INET6: - if (label == MPLS_LABEL_IPV4NULL) { + if (label == MPLS_LABEL_IPV4_EXPLICIT_NULL) { session_shutdown(nbr, S_BAD_TLV_VAL, msg.id, msg.type); goto err; diff --git a/ldpd/lde.c b/ldpd/lde.c index 63e1e39946..a70b97d06b 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -702,20 +702,20 @@ lde_update_label(struct fec_node *fn) switch (fn->fec.type) { case FEC_TYPE_IPV4: if (!(ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL)) - return (MPLS_LABEL_IMPLNULL); + return (MPLS_LABEL_IMPLICIT_NULL); if (lde_acl_check(ldeconf->ipv4.acl_label_expnull_for, AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix, fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT) - return (MPLS_LABEL_IMPLNULL); - return (MPLS_LABEL_IPV4NULL); + return (MPLS_LABEL_IMPLICIT_NULL); + return MPLS_LABEL_IPV4_EXPLICIT_NULL; case FEC_TYPE_IPV6: if (!(ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL)) - return (MPLS_LABEL_IMPLNULL); + return (MPLS_LABEL_IMPLICIT_NULL); if (lde_acl_check(ldeconf->ipv6.acl_label_expnull_for, AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix, fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT) - return (MPLS_LABEL_IMPLNULL); - return (MPLS_LABEL_IPV6NULL); + return (MPLS_LABEL_IMPLICIT_NULL); + return MPLS_LABEL_IPV6_EXPLICIT_NULL; default: fatalx("lde_update_label: unexpected fec type"); break; @@ -1522,11 +1522,15 @@ lde_change_egress_label(int af) /* explicitly withdraw all null labels */ RB_FOREACH(ln, nbr_tree, &lde_nbrs) { - lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLNULL); + lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLICIT_NULL); if (ln->v4_enabled) - lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV4NULL); + lde_send_labelwithdraw_wcard( + ln, + MPLS_LABEL_IPV4_EXPLICIT_NULL); if (ln->v6_enabled) - lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV6NULL); + lde_send_labelwithdraw_wcard( + ln, + MPLS_LABEL_IPV6_EXPLICIT_NULL); } /* update label of connected routes */ diff --git a/ldpd/logmsg.c b/ldpd/logmsg.c index c819b33b43..a9b066a3da 100644 --- a/ldpd/logmsg.c +++ b/ldpd/logmsg.c @@ -115,11 +115,11 @@ log_label(uint32_t label) case NO_LABEL: snprintf(buf, TF_LEN, "-"); break; - case MPLS_LABEL_IMPLNULL: + case MPLS_LABEL_IMPLICIT_NULL: snprintf(buf, TF_LEN, "imp-null"); break; - case MPLS_LABEL_IPV4NULL: - case MPLS_LABEL_IPV6NULL: + case MPLS_LABEL_IPV4_EXPLICIT_NULL: + case MPLS_LABEL_IPV6_EXPLICIT_NULL: snprintf(buf, TF_LEN, "exp-null"); break; default: diff --git a/lib/log.c b/lib/log.c index 66be533e84..9fc19ff683 100644 --- a/lib/log.c +++ b/lib/log.c @@ -929,6 +929,7 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_VRF_UNREGISTER), DESC_ENTRY(ZEBRA_VRF_ADD), DESC_ENTRY(ZEBRA_VRF_DELETE), + DESC_ENTRY(ZEBRA_VRF_LABEL), DESC_ENTRY(ZEBRA_INTERFACE_VRF_UPDATE), DESC_ENTRY(ZEBRA_BFD_CLIENT_REGISTER), DESC_ENTRY(ZEBRA_INTERFACE_ENABLE_RADV), diff --git a/lib/mpls.h b/lib/mpls.h index 95882c26ec..1a1819c2c0 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -24,21 +24,27 @@ #include +#ifdef MPLS_LABEL_MAX +#undef MPLS_LABEL_MAX +#endif + /* Well-known MPLS label values (RFC 3032 etc). */ -#define MPLS_V4_EXP_NULL_LABEL 0 -#define MPLS_RA_LABEL 1 -#define MPLS_V6_EXP_NULL_LABEL 2 -#define MPLS_IMP_NULL_LABEL 3 -#define MPLS_ENTROPY_LABEL_INDICATOR 7 -#define MPLS_GAL_LABEL 13 -#define MPLS_OAM_ALERT_LABEL 14 -#define MPLS_EXTENSION_LABEL 15 +#define MPLS_LABEL_IPV4_EXPLICIT_NULL 0 /* [RFC3032] */ +#define MPLS_LABEL_ROUTER_ALERT 1 /* [RFC3032] */ +#define MPLS_LABEL_IPV6_EXPLICIT_NULL 2 /* [RFC3032] */ +#define MPLS_LABEL_IMPLICIT_NULL 3 /* [RFC3032] */ +#define MPLS_LABEL_ELI 7 /* [RFC6790] */ +#define MPLS_LABEL_GAL 13 /* [RFC5586] */ +#define MPLS_LABEL_OAM_ALERT 14 /* [RFC3429] */ +#define MPLS_LABEL_EXTENSION 15 /* [RFC7274] */ +#define MPLS_LABEL_MAX 1048575 +#define MPLS_LABEL_NONE 0xFFFFFFFF /* for internal use only */ /* Minimum and maximum label values */ -#define MPLS_MIN_RESERVED_LABEL 0 -#define MPLS_MAX_RESERVED_LABEL 15 -#define MPLS_MIN_UNRESERVED_LABEL 16 -#define MPLS_MAX_UNRESERVED_LABEL 1048575 +#define MPLS_LABEL_RESERVED_MIN 0 +#define MPLS_LABEL_RESERVED_MAX 15 +#define MPLS_LABEL_UNRESERVED_MIN 16 +#define MPLS_LABEL_UNRESERVED_MAX 1048575 /* Default min and max SRGB label range */ /* Even if the SRGB allows to manage different Label space between routers, @@ -56,11 +62,11 @@ #define MPLS_MAX_LABELS 16 #define IS_MPLS_RESERVED_LABEL(label) \ - (label >= MPLS_MIN_RESERVED_LABEL && label <= MPLS_MAX_RESERVED_LABEL) + (label >= MPLS_LABEL_RESERVED_MIN && label <= MPLS_LABEL_RESERVED_MAX) #define IS_MPLS_UNRESERVED_LABEL(label) \ - (label >= MPLS_MIN_UNRESERVED_LABEL \ - && label <= MPLS_MAX_UNRESERVED_LABEL) + (label >= MPLS_LABEL_UNRESERVED_MIN \ + && label <= MPLS_LABEL_UNRESERVED_MAX) /* Definitions for a MPLS label stack entry (RFC 3032). This encodes the * label, EXP, BOS and TTL fields. @@ -109,7 +115,8 @@ enum lsp_types_t { ZEBRA_LSP_STATIC = 1, /* Static LSP. */ ZEBRA_LSP_LDP = 2, /* LDP LSP. */ ZEBRA_LSP_BGP = 3, /* BGP LSP. */ - ZEBRA_LSP_SR = 4 /* Segment Routing LSP. */ + ZEBRA_LSP_SR = 4, /* Segment Routing LSP. */ + ZEBRA_LSP_SHARP = 5, /* Identifier for test protocol */ }; /* Functions for basic label operations. */ @@ -153,28 +160,28 @@ static inline void mpls_lse_decode(mpls_lse_t lse, mpls_label_t *label, static inline char *label2str(mpls_label_t label, char *buf, size_t len) { switch (label) { - case MPLS_V4_EXP_NULL_LABEL: + case MPLS_LABEL_IPV4_EXPLICIT_NULL: strlcpy(buf, "IPv4 Explicit Null", len); return (buf); - case MPLS_RA_LABEL: + case MPLS_LABEL_ROUTER_ALERT: strlcpy(buf, "Router Alert", len); return (buf); - case MPLS_V6_EXP_NULL_LABEL: + case MPLS_LABEL_IPV6_EXPLICIT_NULL: strlcpy(buf, "IPv6 Explict Null", len); return (buf); - case MPLS_IMP_NULL_LABEL: + case MPLS_LABEL_IMPLICIT_NULL: strlcpy(buf, "implicit-null", len); return (buf); - case MPLS_ENTROPY_LABEL_INDICATOR: + case MPLS_LABEL_ELI: strlcpy(buf, "Entropy Label Indicator", len); return (buf); - case MPLS_GAL_LABEL: + case MPLS_LABEL_GAL: strlcpy(buf, "Generic Associated Channel", len); return (buf); - case MPLS_OAM_ALERT_LABEL: + case MPLS_LABEL_OAM_ALERT: strlcpy(buf, "OAM Alert", len); return (buf); - case MPLS_EXTENSION_LABEL: + case MPLS_LABEL_EXTENSION: strlcpy(buf, "Extension", len); return (buf); default: @@ -186,13 +193,5 @@ static inline char *label2str(mpls_label_t label, char *buf, size_t len) } } -/* constants used by ldpd */ -#define MPLS_LABEL_IPV4NULL 0 /* IPv4 Explicit NULL Label */ -#define MPLS_LABEL_RTALERT 1 /* Router Alert Label */ -#define MPLS_LABEL_IPV6NULL 2 /* IPv6 Explicit NULL Label */ -#define MPLS_LABEL_IMPLNULL 3 /* Implicit NULL Label */ - /* MPLS_LABEL_RESERVED 4-15 */ /* Values 4-15 are reserved */ -#define MPLS_LABEL_RESERVED_MAX 15 -#define MPLS_LABEL_MAX ((1 << 20) - 1) #endif diff --git a/lib/nexthop.c b/lib/nexthop.c index f531f27302..a094c0e38d 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -167,6 +167,7 @@ void copy_nexthops(struct nexthop **tnh, struct nexthop *nh, for (nh1 = nh; nh1; nh1 = nh1->next) { nexthop = nexthop_new(); + nexthop->vrf_id = nh1->vrf_id; nexthop->ifindex = nh1->ifindex; nexthop->type = nh1->type; nexthop->flags = nh1->flags; diff --git a/lib/nexthop.h b/lib/nexthop.h index 753e66643d..b502f293bc 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -60,6 +60,11 @@ struct nexthop { struct nexthop *next; struct nexthop *prev; + /* + * What vrf is this nexthop associated with? + */ + vrf_id_t vrf_id; + /* Interface index. */ ifindex_t ifindex; @@ -116,18 +121,6 @@ struct nexthop { (nexthop); \ (nexthop) = nexthop_next(nexthop) -extern int zebra_rnh_ip_default_route; -extern int zebra_rnh_ipv6_default_route; - -static inline int nh_resolve_via_default(int family) -{ - if (((family == AF_INET) && zebra_rnh_ip_default_route) - || ((family == AF_INET6) && zebra_rnh_ipv6_default_route)) - return 1; - else - return 0; -} - struct nexthop *nexthop_new(void); void nexthop_add(struct nexthop **target, struct nexthop *nexthop); diff --git a/lib/zclient.c b/lib/zclient.c index 0c29b523bf..714888a3f3 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -363,6 +363,22 @@ static int zebra_hello_send(struct zclient *zclient) return 0; } +void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi, + mpls_label_t label, enum lsp_types_t ltype) +{ + struct stream *s; + + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id); + stream_putl(s, label); + stream_putc(s, afi); + stream_putc(s, ltype); + stream_putw_at(s, 0, stream_get_endp(s)); + zclient_send_message(zclient); +} + /* Send register requests to zebra daemon for the information in a VRF. */ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id) { @@ -975,12 +991,11 @@ int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api) } stream_putw(s, api->nexthop_num); - if (api->nexthop_num) - stream_putl(s, api->nh_vrf_id); for (i = 0; i < api->nexthop_num; i++) { api_nh = &api->nexthops[i]; + stream_putl(s, api_nh->vrf_id); stream_putc(s, api_nh->type); switch (api_nh->type) { case NEXTHOP_TYPE_BLACKHOLE: @@ -1126,12 +1141,10 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api) return -1; } - if (api->nexthop_num) - STREAM_GETL(s, api->nh_vrf_id); - for (i = 0; i < api->nexthop_num; i++) { api_nh = &api->nexthops[i]; + STREAM_GETL(s, api_nh->vrf_id); STREAM_GETC(s, api_nh->type); switch (api_nh->type) { case NEXTHOP_TYPE_BLACKHOLE: @@ -1217,6 +1230,7 @@ struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh) struct nexthop *n = nexthop_new(); n->type = znh->type; + n->vrf_id = znh->vrf_id; n->ifindex = znh->ifindex; n->gate = znh->gate; @@ -1979,8 +1993,8 @@ int lm_get_label_chunk(struct zclient *zclient, u_char keep, __func__, *start, *end, keep, response_keep); } /* sanity */ - if (*start > *end || *start < MPLS_MIN_UNRESERVED_LABEL - || *end > MPLS_MAX_UNRESERVED_LABEL) { + if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN + || *end > MPLS_LABEL_UNRESERVED_MAX) { zlog_err("%s: Invalid Label chunk: %u - %u", __func__, *start, *end); return -1; diff --git a/lib/zclient.h b/lib/zclient.h index 5c7c5d6d5b..d8a70c6cf3 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -93,6 +93,7 @@ typedef enum { ZEBRA_VRF_UNREGISTER, ZEBRA_VRF_ADD, ZEBRA_VRF_DELETE, + ZEBRA_VRF_LABEL, ZEBRA_INTERFACE_VRF_UPDATE, ZEBRA_BFD_CLIENT_REGISTER, ZEBRA_INTERFACE_ENABLE_RADV, @@ -239,6 +240,7 @@ struct zserv_header { struct zapi_nexthop { enum nexthop_types_t type; + vrf_id_t vrf_id; ifindex_t ifindex; union { union g_addr gate; @@ -286,7 +288,6 @@ struct zapi_route { u_int32_t mtu; vrf_id_t vrf_id; - vrf_id_t nh_vrf_id; struct ethaddr rmac; }; @@ -382,6 +383,23 @@ extern u_short *redist_check_instance(struct redist_proto *, u_short); extern void redist_add_instance(struct redist_proto *, u_short); extern void redist_del_instance(struct redist_proto *, u_short); +/* + * Send to zebra that the specified vrf is using label to resolve + * itself for L3VPN's. Repeated calls of this function with + * different labels will cause an effective update of the + * label for lookup. If you pass in MPLS_LABEL_NONE + * we will cause a delete action and remove this label pop + * operation. + * + * The underlying AF_MPLS doesn't care about afi's + * but we can make the zebra_vrf keep track of what + * we have installed and play some special games + * to get them both installed. + */ +extern void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, + afi_t afi, mpls_label_t label, + enum lsp_types_t ltype); + extern void zclient_send_reg_requests(struct zclient *, vrf_id_t); extern void zclient_send_dereg_requests(struct zclient *, vrf_id_t); @@ -505,6 +523,7 @@ static inline void zapi_route_set_blackhole(struct zapi_route *api, { api->nexthop_num = 1; api->nexthops[0].type = NEXTHOP_TYPE_BLACKHOLE; + api->nexthops[0].vrf_id = VRF_DEFAULT; api->nexthops[0].bh_type = bh_type; SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP); }; diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index 2f084f8422..d43aa4929e 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -96,7 +96,6 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix api.type = ZEBRA_ROUTE_NHRP; api.safi = SAFI_UNICAST; api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.prefix = *p; switch (type) { @@ -120,6 +119,7 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 1; api_nh = &api.nexthops[0]; + api_nh->vrf_id = VRF_DEFAULT; switch (api.prefix.family) { case AF_INET: diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h index b7cd9b4b09..e162d21cd2 100644 --- a/ospf6d/ospf6_area.h +++ b/ospf6d/ospf6_area.h @@ -99,6 +99,8 @@ struct ospf6_area { /* Time stamps. */ struct timeval ts_spf; /* SPF calculation time stamp. */ + + uint32_t full_nbrs; /* Fully adjacent neighbors. */ }; #define OSPF6_AREA_ENABLE 0x01 diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 02f8eb0b09..11f9e7c7b6 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -148,6 +148,32 @@ static void ospf6_as_external_lsa_originate(struct ospf6_route *route) ospf6_lsa_originate_process(lsa, ospf6); } +int ospf6_orig_as_external_lsa(struct thread *thread) +{ + struct ospf6_interface *oi; + struct ospf6_lsa *lsa; + uint32_t type, adv_router; + + oi = (struct ospf6_interface *)THREAD_ARG(thread); + oi->thread_as_extern_lsa = NULL; + + if (oi->state == OSPF6_INTERFACE_DOWN) + return 0; + + type = htons(OSPF6_LSTYPE_AS_EXTERNAL); + adv_router = oi->area->ospf6->router_id; + for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, adv_router, lsa)) { + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug("%s: Send update of AS-External LSA %s seq 0x%x", + __PRETTY_FUNCTION__, lsa->name, + ntohl(lsa->header->seqnum)); + + ospf6_flood_interface(NULL, lsa, oi); + } + + return 0; +} + static route_tag_t ospf6_as_external_lsa_get_tag(struct ospf6_lsa *lsa) { struct ospf6_as_external_lsa *external; diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 42716fbc7f..17733d6099 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -192,10 +192,6 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa) struct timeval now; struct ospf6_lsa *old; - if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type) - || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type)) - zlog_debug("Install LSA: %s", lsa->name); - /* Remove the old instance from all neighbors' Link state retransmission list (RFC2328 13.2 last paragraph) */ old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, @@ -237,6 +233,13 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa) ospf6_lsa_checksum(lsa->header); } + if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type) + || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type)) + zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.", + __PRETTY_FUNCTION__, lsa->name, + ntohs(lsa->header->age), + ntohl(lsa->header->seqnum)); + /* actually install */ lsa->installed = now; ospf6_lsdb_add(lsa, lsa->lsdb); @@ -246,7 +249,7 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa) /* RFC2740 section 3.5.2. Sending Link State Update packets */ /* RFC2328 section 13.3 Next step in the flooding procedure */ -static void ospf6_flood_interface(struct ospf6_neighbor *from, +void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, struct ospf6_interface *oi) { @@ -343,15 +346,24 @@ static void ospf6_flood_interface(struct ospf6_neighbor *from, continue; } - /* (d) add retrans-list, schedule retransmission */ - if (is_debug) - zlog_debug("Add retrans-list of this neighbor"); - ospf6_increment_retrans_count(lsa); - ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); - thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, - on->ospf6_if->rxmt_interval, - &on->thread_send_lsupdate); - retrans_added++; + if (ospf6->inst_shutdown) { + if (is_debug) + zlog_debug("%s: Send LSA %s (age %d) update now", + __PRETTY_FUNCTION__, lsa->name, + ntohs(lsa->header->age)); + ospf6_lsupdate_send_neighbor_now(on, lsa); + continue; + } else { + /* (d) add retrans-list, schedule retransmission */ + if (is_debug) + zlog_debug("Add retrans-list of this neighbor"); + ospf6_increment_retrans_count(lsa); + ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); + thread_add_timer(master, ospf6_lsupdate_send_neighbor, + on, on->ospf6_if->rxmt_interval, + &on->thread_send_lsupdate); + retrans_added++; + } } /* (2) examin next interface if not added to retrans-list */ @@ -806,6 +818,17 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, zlog_debug("Received is duplicated LSA"); SET_FLAG(new->flag, OSPF6_LSA_DUPLICATE); } + if (old->header->adv_router == + from->ospf6_if->area->ospf6->router_id + && OSPF6_LSA_IS_MAXAGE(new)) { + ospf6_acknowledge_lsa(new, ismore_recent, from); + ospf6_lsa_delete(new); + if (is_debug) + zlog_debug("%s: Received is self orig MAXAGE LSA %s, discard (ismore_recent %d)", + __PRETTY_FUNCTION__, old->name, + ismore_recent); + return; + } } /* if no database copy or received is more recent */ @@ -959,12 +982,34 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, "Send back directly and then discard"); } + /* Neighbor router sent recent age for LSA, + * Router could be restarted while current copy is + * MAXAGEd and not removed.*/ + if (OSPF6_LSA_IS_MAXAGE(old) && + !OSPF6_LSA_IS_MAXAGE(new)) { + + if (is_debug) + zlog_debug("%s: Current copy of LSA %s is MAXAGE, but new has recent Age.", + old->name, + __PRETTY_FUNCTION__); + + ospf6_lsa_purge(old); + if (new->header->adv_router + != from->ospf6_if->area-> + ospf6->router_id) + ospf6_flood(from, new); + + ospf6_install_lsa(new); + return; + } + /* XXX, MinLSArrival check !? RFC 2328 13 (8) */ ospf6_lsdb_add(ospf6_lsa_copy(old), from->lsupdate_list); thread_add_event(master, ospf6_lsupdate_send_neighbor, from, 0, &from->thread_send_lsupdate); + ospf6_lsa_delete(new); return; } @@ -972,7 +1017,6 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from, } } - DEFUN (debug_ospf6_flooding, debug_ospf6_flooding_cmd, "debug ospf6 flooding", diff --git a/ospf6d/ospf6_flood.h b/ospf6d/ospf6_flood.h index 610eefc803..f5d33e2843 100644 --- a/ospf6d/ospf6_flood.h +++ b/ospf6d/ospf6_flood.h @@ -58,5 +58,10 @@ extern void ospf6_install_lsa(struct ospf6_lsa *lsa); extern int config_write_ospf6_debug_flood(struct vty *vty); extern void install_element_ospf6_debug_flood(void); +extern void ospf6_flood_interface(struct ospf6_neighbor *from, + struct ospf6_lsa *lsa, + struct ospf6_interface *oi); +extern int ospf6_lsupdate_send_neighbor_now(struct ospf6_neighbor *on, + struct ospf6_lsa *lsa); #endif /* OSPF6_FLOOD_H */ diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index fc6c46c7e7..5eaf617702 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -301,6 +301,7 @@ void ospf6_interface_disable(struct ospf6_interface *oi) THREAD_OFF(oi->thread_network_lsa); THREAD_OFF(oi->thread_link_lsa); THREAD_OFF(oi->thread_intra_prefix_lsa); + THREAD_OFF(oi->thread_as_extern_lsa); } static struct in6_addr * @@ -532,6 +533,7 @@ static void ospf6_interface_state_change(u_char next_state, OSPF6_NETWORK_LSA_EXECUTE(oi); OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi); OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); + OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi); } else if (prev_state == OSPF6_INTERFACE_DR || next_state == OSPF6_INTERFACE_DR) { OSPF6_NETWORK_LSA_SCHEDULE(oi); diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h index b67d9a9f2e..9b9952beb6 100644 --- a/ospf6d/ospf6_interface.h +++ b/ospf6d/ospf6_interface.h @@ -108,6 +108,7 @@ struct ospf6_interface { struct thread *thread_network_lsa; struct thread *thread_link_lsa; struct thread *thread_intra_prefix_lsa; + struct thread *thread_as_extern_lsa; struct ospf6_route_table *route_connected; diff --git a/ospf6d/ospf6_intra.h b/ospf6d/ospf6_intra.h index b511a92005..2ae17f0700 100644 --- a/ospf6d/ospf6_intra.h +++ b/ospf6d/ospf6_intra.h @@ -185,11 +185,21 @@ struct ospf6_intra_prefix_lsa { 0, &(oi)->thread_intra_prefix_lsa); \ } while (0) +#define OSPF6_AS_EXTERN_LSA_SCHEDULE(oi) \ + do { \ + if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ + thread_add_event( \ + master, \ + ospf6_orig_as_external_lsa, oi, \ + 0, &(oi)->thread_as_extern_lsa); \ + } while (0) + #define OSPF6_NETWORK_LSA_EXECUTE(oi) \ do { \ THREAD_OFF((oi)->thread_network_lsa); \ thread_execute(master, ospf6_network_lsa_originate, oi, 0); \ } while (0) + #define OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi) \ do { \ THREAD_OFF((oi)->thread_intra_prefix_lsa); \ @@ -198,6 +208,11 @@ struct ospf6_intra_prefix_lsa { 0); \ } while (0) +#define OSPF6_AS_EXTERN_LSA_EXECUTE(oi) \ + do { \ + THREAD_OFF((oi)->thread_as_extern_lsa); \ + thread_execute(master, ospf6_orig_as_external_lsa, oi, 0); \ + } while (0) /* Function Prototypes */ extern char *ospf6_router_lsdesc_lookup(u_char type, u_int32_t interface_id, @@ -215,7 +230,7 @@ extern int ospf6_intra_prefix_lsa_originate_transit(struct thread *); extern int ospf6_intra_prefix_lsa_originate_stub(struct thread *); extern void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa); extern void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa); - +extern int ospf6_orig_as_external_lsa(struct thread *thread); extern void ospf6_intra_route_calculation(struct ospf6_area *oa); extern void ospf6_intra_brouter_calculation(struct ospf6_area *oa); diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index cca4616c16..4a1ba992e3 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -706,6 +706,37 @@ int ospf6_lsa_refresh(struct thread *thread) return 0; } +void ospf6_flush_self_originated_lsas_now(void) +{ + struct listnode *node; + struct ospf6_area *oa; + struct ospf6_lsa *lsa; + const struct route_node *end = NULL; + uint32_t type, adv_router; + + ospf6->inst_shutdown = 1; + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + end = ospf6_lsdb_head(oa->lsdb_self, 0, 0, + ospf6->router_id, &lsa); + while (lsa) { + /* RFC 2328 (14.1): Set MAXAGE */ + lsa->header->age = htons(OSPF_LSA_MAXAGE); + /* Flood MAXAGE LSA*/ + ospf6_flood(NULL, lsa); + + lsa = ospf6_lsdb_next(end, lsa); + } + } + + type = htons(OSPF6_LSTYPE_AS_EXTERNAL); + adv_router = ospf6->router_id; + for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, adv_router, lsa)) { + /* RFC 2328 (14.1): Set MAXAGE */ + lsa->header->age = htons(OSPF_LSA_MAXAGE); + ospf6_flood(NULL, lsa); + } +} /* Fletcher Checksum -- Refer to RFC1008. */ diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index db446a3287..369b381faa 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -253,5 +253,6 @@ extern void ospf6_lsa_terminate(void); extern int config_write_ospf6_debug_lsa(struct vty *vty); extern void install_element_ospf6_debug_lsa(void); extern void ospf6_lsa_age_set(struct ospf6_lsa *lsa); +extern void ospf6_flush_self_originated_lsas_now(void); #endif /* OSPF6_LSA_H */ diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c index 418f858a32..152702391b 100644 --- a/ospf6d/ospf6_lsdb.c +++ b/ospf6d/ospf6_lsdb.c @@ -334,6 +334,7 @@ int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb) } if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)) zlog_debug("Remove MaxAge %s", lsa->name); + if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)) { UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED); /* diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index d76438ea50..fe74ddc982 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -2163,6 +2163,40 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread) return 0; } +int ospf6_lsupdate_send_neighbor_now(struct ospf6_neighbor *on, + struct ospf6_lsa *lsa) +{ + struct ospf6_header *oh; + struct ospf6_lsupdate *lsupdate; + u_char *p; + int lsa_cnt = 0; + + memset(sendbuf, 0, iobuflen); + oh = (struct ospf6_header *)sendbuf; + lsupdate = (struct ospf6_lsupdate *)((caddr_t)oh + + sizeof(struct ospf6_header)); + + p = (u_char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); + ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); + memcpy(p, lsa->header, OSPF6_LSA_SIZE(lsa->header)); + p += OSPF6_LSA_SIZE(lsa->header); + lsa_cnt++; + + oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE; + oh->length = htons(p - sendbuf); + lsupdate->lsa_number = htonl(lsa_cnt); + + if (IS_OSPF6_DEBUG_FLOODING || + IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE, SEND)) + zlog_debug("%s: Send lsupdate with lsa %s (age %u)", + __PRETTY_FUNCTION__, lsa->name, + ntohs(lsa->header->age)); + + ospf6_send_lsupdate(on, NULL, oh); + + return 0; +} + int ospf6_lsupdate_send_interface(struct thread *thread) { struct ospf6_interface *oi; diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index bde89f54a6..05bc254951 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -189,6 +189,15 @@ static void ospf6_neighbor_state_change(u_char next_state, OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(on->ospf6_if); } OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(on->ospf6_if->area); + + if (prev_state == OSPF6_NEIGHBOR_LOADING && + next_state == OSPF6_NEIGHBOR_FULL) { + OSPF6_AS_EXTERN_LSA_SCHEDULE(on->ospf6_if); + on->ospf6_if->area->full_nbrs++; + } + + if (prev_state == OSPF6_NEIGHBOR_FULL) + on->ospf6_if->area->full_nbrs--; } if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 735b28a693..19eb9a3fe6 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -315,6 +315,7 @@ void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route, if (i >= entries) return; + nexthops[i].vrf_id = VRF_DEFAULT; nexthops[i].ifindex = nh->ifindex; if (!IN6_IS_ADDR_UNSPECIFIED(&nh->address)) { nexthops[i].gate.ipv6 = nh->address; diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 17ce1771e2..29ba1bcec7 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -1029,18 +1029,21 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, /* Fill Larger LSA Payload */ end = ospf6_lsdb_head(lsdb, 2, type, adv_router, &rtr_lsa); - if (rtr_lsa) { - if (!OSPF6_LSA_IS_MAXAGE(rtr_lsa)) { - /* Append first Link State ID LSA */ - lsa_header = (struct ospf6_lsa_header *)rtr_lsa->header; - memcpy(new_header, lsa_header, - ntohs(lsa_header->length)); - /* Assign new lsa length as aggregated length. */ - ((struct ospf6_lsa_header *)new_header)->length = - htons(total_lsa_length); - new_header += ntohs(lsa_header->length); - num_lsa--; - } + + /* + * We assume at this point in time that rtr_lsa is + * a valid pointer. + */ + assert(rtr_lsa); + if (!OSPF6_LSA_IS_MAXAGE(rtr_lsa)) { + /* Append first Link State ID LSA */ + lsa_header = (struct ospf6_lsa_header *)rtr_lsa->header; + memcpy(new_header, lsa_header, ntohs(lsa_header->length)); + /* Assign new lsa length as aggregated length. */ + ((struct ospf6_lsa_header *)new_header)->length = + htons(total_lsa_length); + new_header += ntohs(lsa_header->length); + num_lsa--; } /* Print LSA Name */ diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 749873bcf8..25d968fb68 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -180,6 +180,8 @@ void ospf6_delete(struct ospf6 *o) struct ospf6_area *oa; QOBJ_UNREG(o); + + ospf6_flush_self_originated_lsas_now(); ospf6_disable(ospf6); for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa)) @@ -333,6 +335,8 @@ DEFUN(ospf6_router_id, int ret; const char *router_id_str; u_int32_t router_id; + struct ospf6_area *oa; + struct listnode *node; argv_find(argv, argc, "A.B.C.D", &idx); router_id_str = argv[idx]->arg; @@ -344,8 +348,17 @@ DEFUN(ospf6_router_id, } o->router_id_static = router_id; - if (o->router_id == 0) - o->router_id = router_id; + + for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) { + if (oa->full_nbrs) { + vty_out(vty, + "For this router-id change to take effect," + " save config and restart ospf6d\n"); + return CMD_SUCCESS; + } + } + + o->router_id = router_id; return CMD_SUCCESS; } @@ -358,8 +371,22 @@ DEFUN(no_ospf6_router_id, V4NOTATION_STR) { VTY_DECLVAR_CONTEXT(ospf6, o); + struct ospf6_area *oa; + struct listnode *node; + o->router_id_static = 0; + + for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) { + if (oa->full_nbrs) { + vty_out(vty, + "For this router-id change to take effect," + " save config and restart ospf6d\n"); + return CMD_SUCCESS; + } + } o->router_id = 0; + if (o->router_id_zebra.s_addr) + o->router_id = (uint32_t)o->router_id_zebra.s_addr; return CMD_SUCCESS; } @@ -521,6 +548,10 @@ DEFUN (ospf6_distance_ospf6, VTY_DECLVAR_CONTEXT(ospf6, o); int idx = 0; + o->distance_intra = 0; + o->distance_inter = 0; + o->distance_external = 0; + if (argv_find(argv, argc, "intra-area", &idx)) o->distance_intra = atoi(argv[idx + 1]->arg); idx = 0; diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index b39c25ba84..d7a3766b80 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -32,6 +32,8 @@ struct ospf6 { /* static router id */ u_int32_t router_id_static; + struct in_addr router_id_zebra; + /* start time */ struct timeval starttime; @@ -94,6 +96,10 @@ struct ospf6 { struct route_table *distance_table; + /* Used during ospf instance going down send LSDB + * update to neighbors immediatly */ + uint8_t inst_shutdown; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(ospf6) diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 2a419ddfc6..4fb959b952 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -46,8 +46,6 @@ unsigned char conf_debug_ospf6_zebra = 0; /* information about zebra. */ struct zclient *zclient = NULL; -struct in_addr router_id_zebra; - /* Router-id update message from zebra. */ static int ospf6_router_id_update_zebra(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) @@ -56,13 +54,14 @@ static int ospf6_router_id_update_zebra(int command, struct zclient *zclient, struct ospf6 *o = ospf6; zebra_router_id_update_read(zclient->ibuf, &router_id); - router_id_zebra = router_id.u.prefix4; if (o == NULL) return 0; + o->router_id_zebra = router_id.u.prefix4; + if (o->router_id == 0) - o->router_id = (u_int32_t)router_id_zebra.s_addr; + o->router_id = (uint32_t)o->router_id_zebra.s_addr; return 0; } @@ -337,7 +336,6 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; api.safi = SAFI_UNICAST; api.prefix = *dest; @@ -388,7 +386,6 @@ void ospf6_zebra_add_discard(struct ospf6_route *request) if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; api.safi = SAFI_UNICAST; api.prefix = *dest; @@ -422,7 +419,6 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request) if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_OSPF6; api.safi = SAFI_UNICAST; api.prefix = *dest; diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c index d42476b6d8..d7faf4b0de 100644 --- a/ospfd/ospf_ext.c +++ b/ospfd/ospf_ext.c @@ -175,7 +175,7 @@ void ospf_ext_term(void) { if ((OspfEXT.scope != OSPF_OPAQUE_AREA_LSA) - || (OspfEXT.scope != OSPF_OPAQUE_AS_LSA)) + && (OspfEXT.scope != OSPF_OPAQUE_AS_LSA)) zlog_warn( "EXT: Unable to unregister Extended Prefix " "Opaque LSA functions: Wrong scope!"); diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 36b6d5143d..7ad9cf9f2f 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -563,6 +563,7 @@ int ospf_flood_through_area(struct ospf_area *area, struct ospf_neighbor *inbr, struct ospf_interface *oi; int lsa_ack_flag = 0; + assert(area); /* All other types are specific to a single area (Area A). The eligible interfaces are all those interfaces attaching to the Area A. If Area A is the backbone, this includes all the virtual diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 1c586d252c..009fd997ea 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -75,6 +75,7 @@ static void ospf_opaque_funclist_init(void); static void ospf_opaque_funclist_term(void); static void free_opaque_info_per_type(void *val); static void free_opaque_info_per_id(void *val); +static void free_opaque_info_owner(void *val); static int ospf_opaque_lsa_install_hook(struct ospf_lsa *lsa); static int ospf_opaque_lsa_delete_hook(struct ospf_lsa *lsa); @@ -439,9 +440,11 @@ void ospf_delete_opaque_functab(u_char lsa_type, u_char opaque_type) if (functab->opaque_type == opaque_type) { /* Cleanup internal control information, if it * still remains. */ - if (functab->oipt != NULL) + if (functab->oipt != NULL) { free_opaque_info_per_type( functab->oipt); + free_opaque_info_owner(functab->oipt); + } /* Dequeue listnode entry from the list. */ listnode_delete(funclist, functab); @@ -572,6 +575,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab, top = ospf_lookup_by_vrf_id(new->vrf_id); if (new->area != NULL && (top = new->area->ospf) == NULL) { free_opaque_info_per_type((void *)oipt); + free_opaque_info_owner(oipt); oipt = NULL; goto out; /* This case may not exist. */ } @@ -583,6 +587,7 @@ register_opaque_info_per_type(struct ospf_opaque_functab *functab, "register_opaque_info_per_type: Unexpected LSA-type(%u)", new->data->type); free_opaque_info_per_type((void *)oipt); + free_opaque_info_owner(oipt); oipt = NULL; goto out; /* This case may not exist. */ } @@ -600,6 +605,35 @@ out: return oipt; } +/* Remove "oipt" from its owner's self-originated LSA list. */ +static void free_opaque_info_owner(void *val) +{ + struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val; + + switch (oipt->lsa_type) { + case OSPF_OPAQUE_LINK_LSA: { + struct ospf_interface *oi = + (struct ospf_interface *)(oipt->owner); + listnode_delete(oi->opaque_lsa_self, oipt); + break; + } + case OSPF_OPAQUE_AREA_LSA: { + struct ospf_area *area = (struct ospf_area *)(oipt->owner); + listnode_delete(area->opaque_lsa_self, oipt); + break; + } + case OSPF_OPAQUE_AS_LSA: { + struct ospf *top = (struct ospf *)(oipt->owner); + listnode_delete(top->opaque_lsa_self, oipt); + break; + } + default: + zlog_warn("free_opaque_info_owner: Unexpected LSA-type(%u)", + oipt->lsa_type); + break; /* This case may not exist. */ + } +} + static void free_opaque_info_per_type(void *val) { struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val; diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 8670359610..881226683c 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -3897,6 +3897,10 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi, zlog_debug("listcount = %d, [%s]dst %s", listcount(update), IF_NAME(oi), inet_ntoa(addr)); + /* Check that we have really something to process */ + if (listcount(update) == 0) + return; + op = ospf_ls_upd_packet_new(update, oi); /* Prepare OSPF common header. */ diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index b7a47602d0..f2769c6f38 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -337,6 +337,7 @@ static struct route_map_rule_cmd route_match_tag_cmd = { }; struct ospf_metric { + enum { metric_increment, metric_decrement, metric_absolute } type; bool used; u_int32_t metric; }; @@ -356,8 +357,19 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix, ei = object; /* Set metric out value. */ - if (metric->used) + if (!metric->used) + return RMAP_OKAY; + if (metric->type == metric_increment) + ei->route_map_set.metric += metric->metric; + if (metric->type == metric_decrement) + ei->route_map_set.metric -= metric->metric; + if (metric->type == metric_absolute) ei->route_map_set.metric = metric->metric; + + if ((signed int)ei->route_map_set.metric < 1) + ei->route_map_set.metric = -1; + if (ei->route_map_set.metric > OSPF_LS_INFINITY) + ei->route_map_set.metric = OSPF_LS_INFINITY; } return RMAP_OKAY; } @@ -370,23 +382,28 @@ static void *route_set_metric_compile(const char *arg) metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t)); metric->used = false; - /* OSPF doesn't support the +/- in - set metric <+/-metric> check - Ignore the +/- component */ - if (!all_digit(arg)) { - if ((arg[0] == '+' || arg[0] == '-') && all_digit(arg + 1)) { - zlog_warn("OSPF does not support 'set metric +/-'"); - arg++; - } else { - if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) - zlog_warn( - "OSPF does not support 'set metric +rtt / -rtt'"); + if (all_digit(arg)) + metric->type = metric_absolute; - return metric; - } + if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) { + zlog_warn("OSPF does not support 'set metric +rtt / -rtt'"); + return metric; } + + if ((arg[0] == '+') && all_digit(arg + 1)) { + metric->type = metric_increment; + arg++; + } + + if ((arg[0] == '-') && all_digit(arg + 1)) { + metric->type = metric_decrement; + arg++; + } + metric->metric = strtoul(arg, NULL, 10); - metric->used = true; + + if (metric->metric) + metric->used = true; return metric; } diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 725bf952e5..9827eac71b 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -149,14 +149,6 @@ static struct sr_node *sr_node_new(struct in_addr *rid) new->ext_link->del = del_sr_link; new->ext_prefix->del = del_sr_pref; - /* Check if list are correctly created */ - if (new->ext_link == NULL || new->ext_prefix == NULL) { - list_delete_original(new->ext_link); - list_delete_original(new->ext_prefix); - XFREE(MTYPE_OSPF_SR_PARAMS, new); - return NULL; - } - IPV4_ADDR_COPY(&new->adv_router, rid); new->neighbor = NULL; new->instance = 0; @@ -440,7 +432,7 @@ static struct ospf_path *get_nexthop_by_addr(struct ospf *top, struct route_node *rn; /* Sanity Check */ - if ((top == NULL) && (top->new_table)) + if (top == NULL) return NULL; if (IS_DEBUG_OSPF_SR) @@ -511,8 +503,8 @@ static int compute_link_nhlfe(struct sr_link *srl) srl->nhlfe[1].label_in = index2label(srl->sid[1], srl->srn->srgb); - srl->nhlfe[0].label_out = MPLS_IMP_NULL_LABEL; - srl->nhlfe[1].label_out = MPLS_IMP_NULL_LABEL; + srl->nhlfe[0].label_out = MPLS_LABEL_IMPLICIT_NULL; + srl->nhlfe[1].label_out = MPLS_LABEL_IMPLICIT_NULL; rc = 1; return rc; @@ -599,7 +591,7 @@ static int compute_prefix_nhlfe(struct sr_prefix *srp) */ if ((srp->nexthop == NULL) && (!CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_NPFLG))) - srp->nhlfe.label_out = MPLS_IMP_NULL_LABEL; + srp->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL; else if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_VFLG)) srp->nhlfe.label_out = srp->sid; else @@ -694,7 +686,7 @@ static inline void add_sid_nhlfe(struct sr_nhlfe nhlfe) { if ((nhlfe.label_in != 0) && (nhlfe.label_out != 0)) { ospf_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, nhlfe); - if (nhlfe.label_out != MPLS_IMP_NULL_LABEL) + if (nhlfe.label_out != MPLS_LABEL_IMPLICIT_NULL) ospf_zebra_send_mpls_ftn(ZEBRA_ROUTE_ADD, nhlfe); } } @@ -704,7 +696,7 @@ static inline void del_sid_nhlfe(struct sr_nhlfe nhlfe) { if ((nhlfe.label_in != 0) && (nhlfe.label_out != 0)) { ospf_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, nhlfe); - if (nhlfe.label_out != MPLS_IMP_NULL_LABEL) + if (nhlfe.label_out != MPLS_LABEL_IMPLICIT_NULL) ospf_zebra_send_mpls_ftn(ZEBRA_ROUTE_DELETE, nhlfe); } } @@ -1535,7 +1527,7 @@ void ospf_sr_update_prefix(struct interface *ifp, struct prefix *p) EXT_SUBTLV_PREFIX_SID_NPFLG)) { srp->nhlfe.label_in = index2label(srp->sid, OspfSR.self->srgb); - srp->nhlfe.label_out = MPLS_IMP_NULL_LABEL; + srp->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL; add_sid_nhlfe(srp->nhlfe); } } @@ -1992,7 +1984,7 @@ DEFUN (sr_prefix_sid, if (argv_find(argv, argc, "no-php-flag", &idx)) { SET_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_NPFLG); new->nhlfe.label_in = index2label(new->sid, OspfSR.self->srgb); - new->nhlfe.label_out = MPLS_IMP_NULL_LABEL; + new->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL; } if (IS_DEBUG_OSPF_SR) @@ -2168,7 +2160,7 @@ static void show_vty_sr_node(struct vty *vty, struct sr_node *srn) for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) { strncpy(pref, inet_ntoa(srp->nhlfe.prefv4.prefix), 16); snprintf(sid, 22, "SR Pfx (idx %u)", srp->sid); - if (srp->nhlfe.label_out == MPLS_IMP_NULL_LABEL) + if (srp->nhlfe.label_out == MPLS_LABEL_IMPLICIT_NULL) sprintf(label, "pop"); else sprintf(label, "%u", srp->nhlfe.label_out); @@ -2182,7 +2174,7 @@ static void show_vty_sr_node(struct vty *vty, struct sr_node *srn) for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl)) { strncpy(pref, inet_ntoa(srl->nhlfe[0].prefv4.prefix), 16); snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[0]); - if (srl->nhlfe[0].label_out == MPLS_IMP_NULL_LABEL) + if (srl->nhlfe[0].label_out == MPLS_LABEL_IMPLICIT_NULL) sprintf(label, "pop"); else sprintf(label, "%u", srl->nhlfe[0].label_out); @@ -2192,7 +2184,7 @@ static void show_vty_sr_node(struct vty *vty, struct sr_node *srn) label, sid, itf ? itf->name : "-", inet_ntoa(srl->nhlfe[0].nexthop)); snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]); - if (srl->nhlfe[1].label_out == MPLS_IMP_NULL_LABEL) + if (srl->nhlfe[1].label_out == MPLS_LABEL_IMPLICIT_NULL) sprintf(label, "pop"); else sprintf(label, "%u", srl->nhlfe[0].label_out); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 1276f5477c..09350b45a8 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -8558,6 +8558,10 @@ DEFUN (ospf_distance_ospf, VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); int idx = 0; + ospf->distance_intra = 0; + ospf->distance_inter = 0; + ospf->distance_external = 0; + if (argv_find(argv, argc, "intra-area", &idx)) ospf->distance_intra = atoi(argv[idx + 1]->arg); idx = 0; diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 58e8a921d5..93aa603908 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -389,7 +389,6 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p, memset(&api, 0, sizeof(api)); api.vrf_id = ospf->vrf_id; - api.nh_vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -442,6 +441,7 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p, api_nh->ifindex = path->ifindex; api_nh->type = NEXTHOP_TYPE_IFINDEX; } + api_nh->vrf_id = ospf->vrf_id; count++; if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { @@ -467,7 +467,6 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p, memset(&api, 0, sizeof(api)); api.vrf_id = ospf->vrf_id; - api.nh_vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -489,7 +488,6 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p) memset(&api, 0, sizeof(api)); api.vrf_id = ospf->vrf_id; - api.nh_vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; @@ -509,7 +507,6 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) memset(&api, 0, sizeof(api)); api.vrf_id = ospf->vrf_id; - api.nh_vrf_id = ospf->vrf_id; api.type = ZEBRA_ROUTE_OSPF; api.instance = ospf->instance; api.safi = SAFI_UNICAST; diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index 52a5d93c4f..4f02daed42 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -48,7 +48,6 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIP; api.safi = SAFI_UNICAST; @@ -57,6 +56,7 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd) if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; api_nh->gate = rinfo->nh.gate; api_nh->type = NEXTHOP_TYPE_IPV4; if (cmd == ZEBRA_ROUTE_ADD) diff --git a/ripd/ripd.c b/ripd/ripd.c index b5cbc96bc3..9a13250428 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -2319,13 +2319,15 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, tmp_rinfo)) if (tmp_rinfo->type == ZEBRA_ROUTE_RIP && tmp_rinfo->nh.ifindex - == ifc->ifp->ifindex) - rinfo->metric_out = + == ifc->ifp->ifindex) + tmp_rinfo->metric_out = RIP_METRIC_INFINITY; - if (tmp_rinfo->type == ZEBRA_ROUTE_CONNECT + + if (rinfo->type == ZEBRA_ROUTE_CONNECT && prefix_match((struct prefix *)p, ifc->address)) - rinfo->metric_out = RIP_METRIC_INFINITY; + rinfo->metric_out = + RIP_METRIC_INFINITY; } /* Prepare preamble, auth headers, if needs be */ diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index ea069d877f..6c9d911a6a 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -48,7 +48,6 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIPNG; api.safi = SAFI_UNICAST; api.prefix = rp->p; @@ -58,6 +57,7 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd) if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; + api_nh->vrf_id = VRF_DEFAULT; api_nh->gate.ipv6 = rinfo->nexthop; api_nh->ifindex = rinfo->ifindex; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index a35157faa1..0e7d1f2c29 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -26,6 +26,8 @@ #include "prefix.h" #include "nexthop.h" #include "log.h" +#include "vrf.h" +#include "zclient.h" #include "sharpd/sharp_zebra.h" #include "sharpd/sharp_vty.h" @@ -39,7 +41,8 @@ extern uint32_t removed_routes; DEFPY (install_routes, install_routes_cmd, - "install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes", + "sharp install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes", + "Sharp routing Protocol\n" "install some routes\n" "Routes to install\n" "Address to start /32 generation at\n" @@ -76,9 +79,40 @@ DEFPY (install_routes, return CMD_SUCCESS; } +DEFPY(vrf_label, vrf_label_cmd, + "sharp label vrf NAME$name label (0-100000)$label", + "Sharp Routing Protocol\n" + "Give a vrf a label\n" + "Pop and forward for IPv4\n" + "Pop and forward for IPv6\n" + VRF_CMD_HELP_STR + "The label to use, 0 specifies remove the label installed from previous\n" + "Specified range to use\n") +{ + struct vrf *vrf; + afi_t afi = (ipv4) ? AFI_IP : AFI_IP6; + + if (strcmp(name, "default") == 0) + vrf = vrf_lookup_by_id(VRF_DEFAULT); + else + vrf = vrf_lookup_by_name(name); + + if (!vrf) { + vty_out(vty, "Unable to find vrf you silly head"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (label == 0) + label = MPLS_LABEL_NONE; + + vrf_label_add(vrf->vrf_id, afi, label); + return CMD_SUCCESS; +} + DEFPY (remove_routes, remove_routes_cmd, - "remove routes A.B.C.D$start (1-1000000)$routes", + "sharp remove routes A.B.C.D$start (1-1000000)$routes", + "Sharp Routing Protocol\n" "Remove some routes\n" "Routes to remove\n" "Starting spot\n" @@ -112,5 +146,6 @@ void sharp_vty_init(void) { install_element(ENABLE_NODE, &install_routes_cmd); install_element(ENABLE_NODE, &remove_routes_cmd); + install_element(ENABLE_NODE, &vrf_label_cmd); return; } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 25bb512a8b..78e8cf0adc 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -152,6 +152,11 @@ static void zebra_connected(struct zclient *zclient) zclient_send_reg_requests(zclient, VRF_DEFAULT); } +void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label) +{ + zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP); +} + void route_add(struct prefix *p, struct nexthop *nh) { struct zapi_route api; @@ -159,7 +164,6 @@ void route_add(struct prefix *p, struct nexthop *nh) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_SHARP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); @@ -167,6 +171,7 @@ void route_add(struct prefix *p, struct nexthop *nh) SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); api_nh = &api.nexthops[0]; + api_nh->vrf_id = VRF_DEFAULT; api_nh->gate.ipv4 = nh->gate.ipv4; api_nh->type = nh->type; api_nh->ifindex = nh->ifindex; @@ -181,7 +186,6 @@ void route_delete(struct prefix *p) memset(&api, 0, sizeof(api)); api.vrf_id = VRF_DEFAULT; - api.nh_vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_SHARP; api.safi = SAFI_UNICAST; memcpy(&api.prefix, p, sizeof(*p)); diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index 97100f61a6..0bba443bd4 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -24,6 +24,7 @@ extern void sharp_zebra_init(void); +extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label); extern void route_add(struct prefix *p, struct nexthop *nh); extern void route_delete(struct prefix *p); #endif diff --git a/sharpd/subdir.am b/sharpd/subdir.am index da7d68e0bc..490a2ba787 100644 --- a/sharpd/subdir.am +++ b/sharpd/subdir.am @@ -13,6 +13,11 @@ sharpd_libsharp_a_SOURCES = \ sharpd/sharp_vty.c \ # end +noinst_HEADERS += \ + sharpd/sharp_vty.h \ + sharpd/sharp_zebra.h \ + # end + sharpd/sharp_vty_clippy.c: $(CLIPPY_DEPS) sharpd/sharp_vty.$(OBJEXT): sharpd/sharp_vty_clippy.c diff --git a/zebra/connected.c b/zebra/connected.c index d34fd9021a..e28ec8d09b 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -203,7 +203,9 @@ void connected_up(struct interface *ifp, struct connected *ifc) afi_t afi; struct prefix p; struct nexthop nh = { - .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex, + .type = NEXTHOP_TYPE_IFINDEX, + .ifindex = ifp->ifindex, + .vrf_id = ifp->vrf_id, }; if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) @@ -238,13 +240,11 @@ void connected_up(struct interface *ifp, struct connected *ifc) break; } - rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ifp->vrf_id, - ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); + rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, + NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); - rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ifp->vrf_id, - ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); + rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p, + NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) { char buf[PREFIX_STRLEN]; @@ -362,7 +362,9 @@ void connected_down(struct interface *ifp, struct connected *ifc) afi_t afi; struct prefix p; struct nexthop nh = { - .type = NEXTHOP_TYPE_IFINDEX, .ifindex = ifp->ifindex, + .type = NEXTHOP_TYPE_IFINDEX, + .ifindex = ifp->ifindex, + .vrf_id = ifp->vrf_id, }; if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 2a3b95058e..4d888d8069 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -907,6 +907,8 @@ void rtm_read(struct rt_msghdr *rtm) SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC); memset(&nh, 0, sizeof(nh)); + + nh.vrf_id = VRF_DEFAULT; /* This is a reject or blackhole route */ if (flags & RTF_REJECT) { nh.type = NEXTHOP_TYPE_BLACKHOLE; @@ -1049,7 +1051,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) - rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, + rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, &nh, 0, 0, 0, 0, 0); else @@ -1097,7 +1099,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) - rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, + rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, &nh, 0, 0, 0, 0, 0); else @@ -1195,7 +1197,7 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask, msg.rtm.rtm_flags |= RTF_MPLS; if (mpls->smpls.smpls_label - != htonl(MPLS_IMP_NULL_LABEL << MPLS_LABEL_OFFSET)) + != htonl(MPLS_LABEL_IMPLICIT_NULL << MPLS_LABEL_OFFSET)) msg.rtm.rtm_mpls = MPLS_OP_PUSH; } #endif diff --git a/zebra/label_manager.c b/zebra/label_manager.c index ace13eda71..5bf0fce094 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -283,13 +283,13 @@ struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance, return NULL; if (list_isempty(lbl_mgr.lc_list)) - lmc->start = MPLS_MIN_UNRESERVED_LABEL; + lmc->start = MPLS_LABEL_UNRESERVED_MIN; else lmc->start = ((struct label_manager_chunk *)listgetdata( listtail(lbl_mgr.lc_list))) ->end + 1; - if (lmc->start > MPLS_MAX_UNRESERVED_LABEL - size + 1) { + if (lmc->start > MPLS_LABEL_UNRESERVED_MAX - size + 1) { zlog_err("Reached max labels. Start: %u, size: %u", lmc->start, size); XFREE(MTYPE_LM_CHUNK, lmc); diff --git a/zebra/rib.h b/zebra/rib.h index 664afd01b8..9a5d88ed15 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -59,7 +59,6 @@ struct route_entry { /* VRF identifier. */ vrf_id_t vrf_id; - vrf_id_t nh_vrf_id; /* Which routing table */ uint32_t table; @@ -231,22 +230,27 @@ typedef enum { } rib_update_event_t; extern struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *, - ifindex_t); + ifindex_t, + vrf_id_t nh_vrf_id); extern struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *, enum blackhole_type); extern struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *, struct in_addr *, - struct in_addr *); + struct in_addr *, + vrf_id_t nh_vrf_id); extern struct nexthop * route_entry_nexthop_ipv4_ifindex_add(struct route_entry *, struct in_addr *, - struct in_addr *, ifindex_t); + struct in_addr *, ifindex_t, + vrf_id_t nh_vrf_id); extern void route_entry_nexthop_delete(struct route_entry *re, struct nexthop *nexthop); extern struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *, - struct in6_addr *); + struct in6_addr *, + vrf_id_t nh_vrf_id); extern struct nexthop * route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re, - struct in6_addr *ipv6, ifindex_t ifindex); + struct in6_addr *ipv6, ifindex_t ifindex, + vrf_id_t nh_vrf_id); extern void route_entry_nexthop_add(struct route_entry *re, struct nexthop *nexthop); extern void route_entry_copy_nexthops(struct route_entry *re, @@ -294,8 +298,8 @@ extern void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re); /* NOTE: * All rib_add function will not just add prefix into RIB, but * also implicitly withdraw equal prefix of same type. */ -extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id, - int type, u_short instance, int flags, struct prefix *p, +extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, + u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, u_int32_t mtu, uint8_t distance, route_tag_t tag); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 20cc292e11..a80ab9d834 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -443,10 +443,10 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (ifp) nh_vrf_id = ifp->vrf_id; } + nh.vrf_id = nh_vrf_id; - rib_add(afi, SAFI_UNICAST, vrf_id, nh_vrf_id, proto, - 0, flags, &p, NULL, &nh, table, metric, - mtu, distance, tag); + rib_add(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, + NULL, &nh, table, metric, mtu, distance, tag); } else { /* This is a multipath route */ @@ -463,13 +463,13 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, re->metric = metric; re->mtu = mtu; re->vrf_id = vrf_id; - re->nh_vrf_id = vrf_id; re->table = table; re->nexthop_num = 0; re->uptime = time(NULL); re->tag = tag; for (;;) { + vrf_id_t nh_vrf_id; if (len < (int)sizeof(*rtnh) || rtnh->rtnh_len > len) break; @@ -485,8 +485,17 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, ifp = if_lookup_by_index(index, VRF_UNKNOWN); if (ifp) - re->nh_vrf_id = ifp->vrf_id; - } + nh_vrf_id = ifp->vrf_id; + else { + zlog_warn( + "%s: Unknown interface %u specified, defaulting to VRF_DEFAULT", + __PRETTY_FUNCTION__, + index); + nh_vrf_id = VRF_DEFAULT; + } + } else + nh_vrf_id = vrf_id; + gate = 0; if (rtnh->rtnh_len > sizeof(*rtnh)) { memset(tb, 0, sizeof(tb)); @@ -503,24 +512,27 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (index) route_entry_nexthop_ipv4_ifindex_add( re, gate, - prefsrc, index); + prefsrc, index, + nh_vrf_id); else route_entry_nexthop_ipv4_add( re, gate, - prefsrc); + prefsrc, + nh_vrf_id); } else if (rtm->rtm_family == AF_INET6) { if (index) route_entry_nexthop_ipv6_ifindex_add( - re, gate, - index); + re, gate, index, + nh_vrf_id); else route_entry_nexthop_ipv6_add( - re, gate); + re, gate, + nh_vrf_id); } } else - route_entry_nexthop_ifindex_add(re, - index); + route_entry_nexthop_ifindex_add( + re, index, nh_vrf_id); len -= NLMSG_ALIGN(rtnh->rtnh_len); rtnh = RTNH_NEXT(rtnh); @@ -828,6 +840,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, { struct mpls_label_stack *nh_label; mpls_lse_t out_lse[MPLS_MAX_LABELS]; + int num_labels = 0; char label_buf[256]; /* @@ -837,56 +850,54 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, * you fix this assumption */ label_buf[0] = '\0'; - /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP - * (in the case of LER) - */ - nh_label = nexthop->nh_label; - if (rtmsg->rtm_family == AF_MPLS) { - assert(nh_label); - assert(nh_label->num_labels == 1); - } - if (nh_label && nh_label->num_labels) { - int i, num_labels = 0; - u_int32_t bos; + assert(nexthop); + for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) { char label_buf1[20]; - for (i = 0; i < nh_label->num_labels; i++) { - if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) { - bos = ((i == (nh_label->num_labels - 1)) ? 1 - : 0); - out_lse[i] = mpls_lse_encode(nh_label->label[i], - 0, 0, bos); - if (IS_ZEBRA_DEBUG_KERNEL) { - if (!num_labels) - sprintf(label_buf, "label %u", - nh_label->label[i]); - else { - sprintf(label_buf1, "/%u", - nh_label->label[i]); - strlcat(label_buf, label_buf1, - sizeof(label_buf)); - } - } - num_labels++; - } - } - if (num_labels) { - if (rtmsg->rtm_family == AF_MPLS) - addattr_l(nlmsg, req_size, RTA_NEWDST, &out_lse, - num_labels * sizeof(mpls_lse_t)); - else { - struct rtattr *nest; - u_int16_t encap = LWTUNNEL_ENCAP_MPLS; + nh_label = nh->nh_label; + if (!nh_label || !nh_label->num_labels) + continue; - addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, - &encap, sizeof(u_int16_t)); - nest = addattr_nest(nlmsg, req_size, RTA_ENCAP); - addattr_l(nlmsg, req_size, MPLS_IPTUNNEL_DST, - &out_lse, - num_labels * sizeof(mpls_lse_t)); - addattr_nest_end(nlmsg, nest); + for (int i = 0; i < nh_label->num_labels; i++) { + if (nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL) + continue; + + if (IS_ZEBRA_DEBUG_KERNEL) { + if (!num_labels) + sprintf(label_buf, "label %u", + nh_label->label[i]); + else { + sprintf(label_buf1, "/%u", + nh_label->label[i]); + strlcat(label_buf, label_buf1, + sizeof(label_buf)); + } } + + out_lse[num_labels] = + mpls_lse_encode(nh_label->label[i], 0, 0, 0); + num_labels++; + } + } + + if (num_labels) { + /* Set the BoS bit */ + out_lse[num_labels - 1] |= htonl(1 << MPLS_LS_S_SHIFT); + + if (rtmsg->rtm_family == AF_MPLS) + addattr_l(nlmsg, req_size, RTA_NEWDST, &out_lse, + num_labels * sizeof(mpls_lse_t)); + else { + struct rtattr *nest; + u_int16_t encap = LWTUNNEL_ENCAP_MPLS; + + addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, &encap, + sizeof(u_int16_t)); + nest = addattr_nest(nlmsg, req_size, RTA_ENCAP); + addattr_l(nlmsg, req_size, MPLS_IPTUNNEL_DST, &out_lse, + num_labels * sizeof(mpls_lse_t)); + addattr_nest_end(nlmsg, nest); } } @@ -1033,6 +1044,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen, { struct mpls_label_stack *nh_label; mpls_lse_t out_lse[MPLS_MAX_LABELS]; + int num_labels = 0; char label_buf[256]; rtnh->rtnh_len = sizeof(*rtnh); @@ -1047,63 +1059,60 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen, * you fix this assumption */ label_buf[0] = '\0'; - /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP - * (in the case of LER) - */ - nh_label = nexthop->nh_label; - if (rtmsg->rtm_family == AF_MPLS) { - assert(nh_label); - assert(nh_label->num_labels == 1); - } - if (nh_label && nh_label->num_labels) { - int i, num_labels = 0; - u_int32_t bos; + assert(nexthop); + for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) { char label_buf1[20]; - for (i = 0; i < nh_label->num_labels; i++) { - if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) { - bos = ((i == (nh_label->num_labels - 1)) ? 1 - : 0); - out_lse[i] = mpls_lse_encode(nh_label->label[i], - 0, 0, bos); - if (IS_ZEBRA_DEBUG_KERNEL) { - if (!num_labels) - sprintf(label_buf, "label %u", - nh_label->label[i]); - else { - sprintf(label_buf1, "/%u", - nh_label->label[i]); - strlcat(label_buf, label_buf1, - sizeof(label_buf)); - } - } - num_labels++; - } - } - if (num_labels) { - if (rtmsg->rtm_family == AF_MPLS) { - rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_NEWDST, - &out_lse, - num_labels * sizeof(mpls_lse_t)); - rtnh->rtnh_len += RTA_LENGTH( - num_labels * sizeof(mpls_lse_t)); - } else { - struct rtattr *nest; - u_int16_t encap = LWTUNNEL_ENCAP_MPLS; - int len = rta->rta_len; + nh_label = nh->nh_label; + if (!nh_label || !nh_label->num_labels) + continue; - rta_addattr_l(rta, NL_PKT_BUF_SIZE, - RTA_ENCAP_TYPE, &encap, - sizeof(u_int16_t)); - nest = rta_nest(rta, NL_PKT_BUF_SIZE, - RTA_ENCAP); - rta_addattr_l(rta, NL_PKT_BUF_SIZE, - MPLS_IPTUNNEL_DST, &out_lse, - num_labels * sizeof(mpls_lse_t)); - rta_nest_end(rta, nest); - rtnh->rtnh_len += rta->rta_len - len; + for (int i = 0; i < nh_label->num_labels; i++) { + if (nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL) + continue; + + if (IS_ZEBRA_DEBUG_KERNEL) { + if (!num_labels) + sprintf(label_buf, "label %u", + nh_label->label[i]); + else { + sprintf(label_buf1, "/%u", + nh_label->label[i]); + strlcat(label_buf, label_buf1, + sizeof(label_buf)); + } } + + out_lse[num_labels] = + mpls_lse_encode(nh_label->label[i], 0, 0, 0); + num_labels++; + } + } + + if (num_labels) { + /* Set the BoS bit */ + out_lse[num_labels - 1] |= htonl(1 << MPLS_LS_S_SHIFT); + + if (rtmsg->rtm_family == AF_MPLS) { + rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_NEWDST, + &out_lse, + num_labels * sizeof(mpls_lse_t)); + rtnh->rtnh_len += + RTA_LENGTH(num_labels * sizeof(mpls_lse_t)); + } else { + struct rtattr *nest; + u_int16_t encap = LWTUNNEL_ENCAP_MPLS; + int len = rta->rta_len; + + rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_ENCAP_TYPE, + &encap, sizeof(u_int16_t)); + nest = rta_nest(rta, NL_PKT_BUF_SIZE, RTA_ENCAP); + rta_addattr_l(rta, NL_PKT_BUF_SIZE, MPLS_IPTUNNEL_DST, + &out_lse, + num_labels * sizeof(mpls_lse_t)); + rta_nest_end(rta, nest); + rtnh->rtnh_len += rta->rta_len - len; } } diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index ba45f54ad2..95bc8db1c9 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -94,12 +94,12 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry) prefix.prefixlen = ip_masklen(tmpaddr); memset(&nh, 0, sizeof(nh)); + nh.vrf_id = VRF_DEFAULT; nh.type = NEXTHOP_TYPE_IPV4; nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop; - rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, - ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &prefix, NULL, - &nh, 0, 0, 0, 0, 0); + rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, + zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0, 0); } void route_read(struct zebra_ns *zns) diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 22c81b5784..ec80081a46 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -411,12 +411,13 @@ static int fec_change_update_lsp(struct zebra_vrf *zvrf, zebra_fec_t *fec, afi_t afi; /* Uninstall label forwarding entry, if previously installed. */ - if (old_label != MPLS_INVALID_LABEL && old_label != MPLS_IMP_NULL_LABEL) + if (old_label != MPLS_INVALID_LABEL && + old_label != MPLS_LABEL_IMPLICIT_NULL) lsp_uninstall(zvrf, old_label); /* Install label forwarding entry corr. to new label, if needed. */ if (fec->label == MPLS_INVALID_LABEL - || fec->label == MPLS_IMP_NULL_LABEL) + || fec->label == MPLS_LABEL_IMPLICIT_NULL) return 0; afi = family2afi(PREFIX_FAMILY(&fec->rn->p)); @@ -614,7 +615,7 @@ static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe, struct route_entry *match; struct nexthop *match_nh; - table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT); + table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, nexthop->vrf_id); if (!table) return 0; @@ -663,7 +664,7 @@ static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe, struct route_node *rn; struct route_entry *match; - table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT); + table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, nexthop->vrf_id); if (!table) return 0; @@ -711,6 +712,22 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe) /* Check on nexthop based on type. */ switch (nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + /* + * Lookup if this type is special. The + * NEXTHOP_TYPE_IFINDEX is a pop and + * forward into a different table for + * processing. As such this ifindex + * passed to us may be a VRF device + * which will not be in the default + * VRF. So let's look in all of them + */ + ifp = if_lookup_by_index(nexthop->ifindex, VRF_UNKNOWN); + if (ifp && if_is_operative(ifp)) + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + else + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + break; case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: if (nhlfe_nexthop_active_ipv4(nhlfe, nexthop)) @@ -728,7 +745,8 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe) case NEXTHOP_TYPE_IPV6_IFINDEX: if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { - ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); + ifp = if_lookup_by_index(nexthop->ifindex, + nexthop->vrf_id); if (ifp && if_is_operative(ifp)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else @@ -1052,6 +1070,8 @@ static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size) case NEXTHOP_TYPE_IPV6: inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, size); break; + case NEXTHOP_TYPE_IFINDEX: + snprintf(buf, size, "Ifindex: %u", nexthop->ifindex); default: break; } @@ -1090,6 +1110,9 @@ static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) cmp = !(nhop->ifindex == ifindex); break; + case NEXTHOP_TYPE_IFINDEX: + cmp = !(nhop->ifindex == ifindex); + break; default: break; } @@ -1149,6 +1172,7 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, } nexthop_add_labels(nexthop, lsp_type, 1, &out_label); + nexthop->vrf_id = VRF_DEFAULT; nexthop->type = gtype; switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: @@ -1163,6 +1187,9 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, if (ifindex) nexthop->ifindex = ifindex; break; + case NEXTHOP_TYPE_IFINDEX: + nexthop->ifindex = ifindex; + break; default: nexthop_free(nexthop); XFREE(MTYPE_NHLFE, nhlfe); @@ -1324,9 +1351,9 @@ static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe) inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); if (nexthop->ifindex) - json_object_string_add( - json_nhlfe, "interface", - ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); + json_object_string_add(json_nhlfe, "interface", + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); break; default: break; @@ -1356,7 +1383,8 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty) vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4)); if (nexthop->ifindex) vty_out(vty, " dev %s", - ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -1364,7 +1392,8 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty) inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); if (nexthop->ifindex) vty_out(vty, " dev %s", - ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); break; default: break; @@ -1793,7 +1822,7 @@ int zebra_mpls_lsp_install(struct zebra_vrf *zvrf, struct route_node *rn, /* We cannot install a label forwarding entry if local label is the * implicit-null label. */ - if (fec->label == MPLS_IMP_NULL_LABEL) + if (fec->label == MPLS_LABEL_IMPLICIT_NULL) return 0; if (lsp_install(zvrf, fec->label, rn, re)) @@ -2537,8 +2566,8 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf, int cur_op, new_op; cur_op = (slsp->snhlfe_list->out_label - == MPLS_IMP_NULL_LABEL); - new_op = (out_label == MPLS_IMP_NULL_LABEL); + == MPLS_LABEL_IMPLICIT_NULL); + new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL); if (cur_op != new_op) return 0; } @@ -2764,6 +2793,15 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, nexthop = nhlfe->nexthop; switch (nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + { + struct interface *ifp; + + ifp = if_lookup_by_index( + nexthop->ifindex, VRF_UNKNOWN); + vty_out(vty, "%15s", ifp->name); + break; + } case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: vty_out(vty, "%15s", @@ -2780,8 +2818,16 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, break; } - vty_out(vty, " %8d\n", - nexthop->nh_label->label[0]); + if (nexthop->type != NEXTHOP_TYPE_IFINDEX) + vty_out(vty, " %8s\n", + mpls_label2str( + nexthop->nh_label + ->num_labels, + &nexthop->nh_label + ->label[0], + buf, BUFSIZ, 1)); + else + vty_out(vty, "\n"); } } @@ -2810,11 +2856,11 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) snhlfe2str(snhlfe, buf, sizeof(buf)); switch (snhlfe->out_label) { - case MPLS_V4_EXP_NULL_LABEL: - case MPLS_V6_EXP_NULL_LABEL: + case MPLS_LABEL_IPV4_EXPLICIT_NULL: + case MPLS_LABEL_IPV6_EXPLICIT_NULL: strlcpy(lstr, "explicit-null", sizeof(lstr)); break; - case MPLS_IMP_NULL_LABEL: + case MPLS_LABEL_IMPLICIT_NULL: strlcpy(lstr, "implicit-null", sizeof(lstr)); break; default: diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index 27a4971691..fd14b29ca9 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -428,9 +428,19 @@ static inline u_char lsp_distance(enum lsp_types_t type) return (route_distance(ZEBRA_ROUTE_LDP)); case ZEBRA_LSP_BGP: return (route_distance(ZEBRA_ROUTE_BGP)); - default: + case ZEBRA_LSP_NONE: + case ZEBRA_LSP_SHARP: + case ZEBRA_LSP_SR: return 150; } + + /* + * For some reason certain compilers do not believe + * that all the cases have been handled. And + * WTF does this work differently than when I removed + * the default case???? + */ + return 150; } /* @@ -444,6 +454,8 @@ static inline enum lsp_types_t lsp_type_from_re_type(int re_type) return ZEBRA_LSP_STATIC; case ZEBRA_ROUTE_BGP: return ZEBRA_LSP_BGP; + case ZEBRA_ROUTE_SHARP: + return ZEBRA_LSP_SHARP; default: return ZEBRA_LSP_NONE; } @@ -464,9 +476,18 @@ static inline int re_type_from_lsp_type(enum lsp_types_t lsp_type) case ZEBRA_LSP_SR: return ZEBRA_ROUTE_OSPF; case ZEBRA_LSP_NONE: - default: return ZEBRA_ROUTE_KERNEL; + case ZEBRA_LSP_SHARP: + return ZEBRA_ROUTE_SHARP; } + + /* + * For some reason certain compilers do not believe + * that all the cases have been handled. And + * WTF does this work differently than when I removed + * the default case???? + */ + return ZEBRA_ROUTE_KERNEL; } /* NHLFE type as printable string. */ @@ -481,9 +502,19 @@ static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type) return "BGP"; case ZEBRA_LSP_SR: return "SR"; - default: + case ZEBRA_LSP_SHARP: + return "SHARP"; + case ZEBRA_LSP_NONE: return "Unknown"; } + + /* + * For some reason certain compilers do not believe + * that all the cases have been handled. And + * WTF does this work differently than when I removed + * the default case???? + */ + return "Unknown"; } static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf) diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index 9d100bb7d0..0d922830c7 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -68,7 +68,7 @@ static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd, return CMD_WARNING_CONFIG_FAILED; } - out_label = MPLS_IMP_NULL_LABEL; /* as initialization */ + out_label = MPLS_LABEL_IMPLICIT_NULL; /* as initialization */ label = atoi(inlabel_str); if (!IS_MPLS_UNRESERVED_LABEL(label)) { vty_out(vty, "%% Invalid label\n"); @@ -107,11 +107,11 @@ static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd, if (outlabel_str) { if (outlabel_str[0] == 'i') - out_label = MPLS_IMP_NULL_LABEL; + out_label = MPLS_LABEL_IMPLICIT_NULL; else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV4) - out_label = MPLS_V4_EXP_NULL_LABEL; + out_label = MPLS_LABEL_IPV4_EXPLICIT_NULL; else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV6) - out_label = MPLS_V6_EXP_NULL_LABEL; + out_label = MPLS_LABEL_IPV6_EXPLICIT_NULL; else out_label = atoi(outlabel_str); } @@ -221,12 +221,12 @@ static int zebra_mpls_bind(struct vty *vty, int add_cmd, const char *prefix, } if (!strcmp(label_str, "implicit-null")) - label = MPLS_IMP_NULL_LABEL; + label = MPLS_LABEL_IMPLICIT_NULL; else if (!strcmp(label_str, "explicit-null")) { if (p.family == AF_INET) - label = MPLS_V4_EXP_NULL_LABEL; + label = MPLS_LABEL_IPV4_EXPLICIT_NULL; else - label = MPLS_V6_EXP_NULL_LABEL; + label = MPLS_LABEL_IPV6_EXPLICIT_NULL; } else { label = atoi(label_str); if (!IS_MPLS_UNRESERVED_LABEL(label)) { diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 7f5fd472f1..187c2594ad 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -1007,8 +1007,13 @@ int zebra_ptm_bfd_client_register(struct zserv *client, return 0; stream_failure: - if (out_ctxt) - ptm_lib_cleanup_msg(ptm_hdl, out_ctxt); + /* + * IF we ever add more STREAM_GETXXX functions after the out_ctxt + * is allocated then we need to add this code back in + * + * if (out_ctxt) + * ptm_lib_cleanup_msg(ptm_hdl, out_ctxt); + */ return 0; } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index b7b4a159da..967bc92850 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -86,6 +86,7 @@ static const struct { [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20}, [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20}, [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100}, + [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150}, /* no entry/default: 150 */ }; @@ -212,13 +213,15 @@ void route_entry_nexthop_delete(struct route_entry *re, struct nexthop *nexthop) struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *re, - ifindex_t ifindex) + ifindex_t ifindex, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; nexthop = nexthop_new(); nexthop->type = NEXTHOP_TYPE_IFINDEX; nexthop->ifindex = ifindex; + nexthop->vrf_id = nh_vrf_id; route_entry_nexthop_add(re, nexthop); @@ -227,12 +230,14 @@ struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *re, struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *re, struct in_addr *ipv4, - struct in_addr *src) + struct in_addr *src, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; nexthop = nexthop_new(); nexthop->type = NEXTHOP_TYPE_IPV4; + nexthop->vrf_id = nh_vrf_id; nexthop->gate.ipv4 = *ipv4; if (src) nexthop->src.ipv4 = *src; @@ -245,18 +250,20 @@ struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *re, struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re, struct in_addr *ipv4, struct in_addr *src, - ifindex_t ifindex) + ifindex_t ifindex, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; struct interface *ifp; nexthop = nexthop_new(); + nexthop->vrf_id = nh_vrf_id; nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX; nexthop->gate.ipv4 = *ipv4; if (src) nexthop->src.ipv4 = *src; nexthop->ifindex = ifindex; - ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, nh_vrf_id); /*Pending: need to think if null ifp here is ok during bootup? There was a crash because ifp here was coming to be NULL */ if (ifp) @@ -271,11 +278,13 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re, } struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *re, - struct in6_addr *ipv6) + struct in6_addr *ipv6, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; nexthop = nexthop_new(); + nexthop->vrf_id = nh_vrf_id; nexthop->type = NEXTHOP_TYPE_IPV6; nexthop->gate.ipv6 = *ipv6; @@ -286,11 +295,13 @@ struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *re, struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re, struct in6_addr *ipv6, - ifindex_t ifindex) + ifindex_t ifindex, + vrf_id_t nh_vrf_id) { struct nexthop *nexthop; nexthop = nexthop_new(); + nexthop->vrf_id = nh_vrf_id; nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX; nexthop->gate.ipv6 = *ipv6; nexthop->ifindex = ifindex; @@ -306,6 +317,7 @@ struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re, struct nexthop *nexthop; nexthop = nexthop_new(); + nexthop->vrf_id = VRF_DEFAULT; nexthop->type = NEXTHOP_TYPE_BLACKHOLE; nexthop->bh_type = bh_type; @@ -322,6 +334,7 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop, resolved_hop = nexthop_new(); SET_FLAG(resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); + resolved_hop->vrf_id = nexthop->vrf_id; switch (newhop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: @@ -403,7 +416,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, if (set) { UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - zebra_deregister_rnh_static_nexthops(re->nh_vrf_id, + zebra_deregister_rnh_static_nexthops(nexthop->vrf_id, nexthop->resolved, top); nexthops_free(nexthop->resolved); nexthop->resolved = NULL; @@ -422,7 +435,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, * address in the routing table. */ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) { - ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); if (ifp && connected_is_unnumbered(ifp)) { if (if_is_operative(ifp)) return 1; @@ -450,7 +463,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, break; } /* Lookup table. */ - table = zebra_vrf_table(afi, SAFI_UNICAST, re->nh_vrf_id); + table = zebra_vrf_table(afi, SAFI_UNICAST, nexthop->vrf_id); if (!table) return 0; @@ -472,7 +485,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, /* However, do not resolve over default route unless explicitly * allowed. */ if (is_default_prefix(&rn->p) - && !nh_resolve_via_default(p.family)) + && !rnh_resolve_via_default(p.family)) return 0; dest = rib_dest_from_rnode(rn); @@ -838,7 +851,7 @@ static unsigned nexthop_active_check(struct route_node *rn, family = 0; switch (nexthop->type) { case NEXTHOP_TYPE_IFINDEX: - ifp = if_lookup_by_index(nexthop->ifindex, re->nh_vrf_id); + ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); if (ifp && if_is_operative(ifp)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else @@ -867,7 +880,7 @@ static unsigned nexthop_active_check(struct route_node *rn, family = AFI_IP6; if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { ifp = if_lookup_by_index(nexthop->ifindex, - re->nh_vrf_id); + nexthop->vrf_id); if (ifp && if_is_operative(ifp)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else @@ -910,8 +923,8 @@ static unsigned nexthop_active_check(struct route_node *rn, memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr)); /* It'll get set if required inside */ - ret = zebra_route_map_check(family, re->type, p, nexthop, re->nh_vrf_id, - re->tag); + ret = zebra_route_map_check(family, re->type, p, nexthop, + nexthop->vrf_id, re->tag); if (ret == RMAP_DENYMATCH) { if (IS_ZEBRA_DEBUG_RIB) { srcdest_rnode2str(rn, buf, sizeof(buf)); @@ -919,7 +932,7 @@ static unsigned nexthop_active_check(struct route_node *rn, "%u:%s: Filtering out with NH out %s due to route map", re->vrf_id, buf, ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); } UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); } @@ -2554,10 +2567,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } -int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id, - int type, u_short instance, int flags, struct prefix *p, - struct prefix_ipv6 *src_p, const struct nexthop *nh, - u_int32_t table_id, u_int32_t metric, +int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, + int flags, struct prefix *p, struct prefix_ipv6 *src_p, + const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, u_int32_t mtu, uint8_t distance, route_tag_t tag) { struct route_entry *re; @@ -2573,7 +2585,6 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, vrf_id_t nh_vrf_id, re->mtu = mtu; re->table = table_id; re->vrf_id = vrf_id; - re->nh_vrf_id = nh_vrf_id; re->nexthop_num = 0; re->uptime = time(NULL); re->tag = tag; diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index cea46ffc18..9fc5afff0f 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -659,7 +659,7 @@ static struct route_entry *zebra_rnh_resolve_nexthop_entry(vrf_id_t vrfid, * match route to be exact if so specified */ if (is_default_prefix(&rn->p) && - !nh_resolve_via_default(rn->p.family)) + !rnh_resolve_via_default(rn->p.family)) return NULL; /* Identify appropriate route entry. */ @@ -952,7 +952,6 @@ static void copy_state(struct rnh *rnh, struct route_entry *re, state->distance = re->distance; state->metric = re->metric; state->vrf_id = re->vrf_id; - state->nh_vrf_id = re->vrf_id; route_entry_copy_nexthops(state, re->nexthop); rnh->state = state; diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 7e183684da..bd121ec83c 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -54,6 +54,15 @@ typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t; extern int zebra_rnh_ip_default_route; extern int zebra_rnh_ipv6_default_route; +static inline int rnh_resolve_via_default(int family) +{ + if (((family == AF_INET) && zebra_rnh_ip_default_route) + || ((family == AF_INET6) && zebra_rnh_ipv6_default_route)) + return 1; + else + return 0; +} + extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type); extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 4c619e5782..882a03f844 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1329,7 +1329,7 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto, struct nh_rmap_obj nh_obj; nh_obj.nexthop = nexthop; - nh_obj.vrf_id = re->nh_vrf_id; + nh_obj.vrf_id = nexthop->vrf_id; nh_obj.source_protocol = re->type; nh_obj.metric = re->metric; nh_obj.tag = re->tag; diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 2e8ab11b04..b42bd818af 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -87,7 +87,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, switch (si->type) { case STATIC_IPV4_GATEWAY: nexthop = route_entry_nexthop_ipv4_add( - re, &si->addr.ipv4, NULL); + re, &si->addr.ipv4, NULL, si->nh_vrf_id); nh_p.family = AF_INET; nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.u.prefix4 = si->addr.ipv4; @@ -95,19 +95,20 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, break; case STATIC_IPV4_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv4_ifindex_add( - re, &si->addr.ipv4, NULL, si->ifindex); + re, &si->addr.ipv4, NULL, si->ifindex, + si->nh_vrf_id); break; case STATIC_IFNAME: - nexthop = route_entry_nexthop_ifindex_add(re, - si->ifindex); + nexthop = route_entry_nexthop_ifindex_add( + re, si->ifindex, si->nh_vrf_id); break; case STATIC_BLACKHOLE: nexthop = route_entry_nexthop_blackhole_add( re, bh_type); break; case STATIC_IPV6_GATEWAY: - nexthop = route_entry_nexthop_ipv6_add(re, - &si->addr.ipv6); + nexthop = route_entry_nexthop_ipv6_add( + re, &si->addr.ipv6, si->nh_vrf_id); nh_p.family = AF_INET6; nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.u.prefix6 = si->addr.ipv6; @@ -115,7 +116,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, break; case STATIC_IPV6_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv6_ifindex_add( - re, &si->addr.ipv6, si->ifindex); + re, &si->addr.ipv6, si->ifindex, si->nh_vrf_id); break; } /* Update label(s), if present. */ @@ -155,7 +156,6 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, re->metric = 0; re->mtu = 0; re->vrf_id = si->vrf_id; - re->nh_vrf_id = si->nh_vrf_id; re->table = (si->vrf_id != VRF_DEFAULT) ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id @@ -166,7 +166,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, switch (si->type) { case STATIC_IPV4_GATEWAY: nexthop = route_entry_nexthop_ipv4_add( - re, &si->addr.ipv4, NULL); + re, &si->addr.ipv4, NULL, si->nh_vrf_id); nh_p.family = AF_INET; nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.u.prefix4 = si->addr.ipv4; @@ -174,19 +174,20 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, break; case STATIC_IPV4_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv4_ifindex_add( - re, &si->addr.ipv4, NULL, si->ifindex); + re, &si->addr.ipv4, NULL, si->ifindex, + si->nh_vrf_id); break; case STATIC_IFNAME: - nexthop = route_entry_nexthop_ifindex_add(re, - si->ifindex); + nexthop = route_entry_nexthop_ifindex_add( + re, si->ifindex, si->nh_vrf_id); break; case STATIC_BLACKHOLE: nexthop = route_entry_nexthop_blackhole_add( re, bh_type); break; case STATIC_IPV6_GATEWAY: - nexthop = route_entry_nexthop_ipv6_add(re, - &si->addr.ipv6); + nexthop = route_entry_nexthop_ipv6_add( + re, &si->addr.ipv6, si->nh_vrf_id); nh_p.family = AF_INET6; nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.u.prefix6 = si->addr.ipv6; @@ -194,7 +195,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p, break; case STATIC_IPV6_GATEWAY_IFNAME: nexthop = route_entry_nexthop_ipv6_ifindex_add( - re, &si->addr.ipv6, si->ifindex); + re, &si->addr.ipv6, si->ifindex, si->nh_vrf_id); break; } /* Update label(s), if present. */ diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index fe7e77e8be..d3a5316b9d 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -79,6 +79,9 @@ struct zebra_vrf { */ struct zebra_ns *zns; + /* MPLS Label to handle L3VPN <-> vrf popping */ + mpls_label_t label[AFI_MAX]; + /* MPLS static LSP config table */ struct hash *slsp_table; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index f8c9833854..269244f768 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -165,8 +165,8 @@ static int zebra_static_route_leak(struct vty *vty, case -2: vty_out(vty, "%% Cannot use reserved label(s) (%d-%d)\n", - MPLS_MIN_RESERVED_LABEL, - MPLS_MAX_RESERVED_LABEL); + MPLS_LABEL_RESERVED_MIN, + MPLS_LABEL_RESERVED_MAX); break; case -3: vty_out(vty, @@ -458,6 +458,12 @@ DEFPY(ip_route_blackhole_vrf, VTY_DECLVAR_CONTEXT(vrf, vrf); struct zebra_vrf *zvrf = vrf->info; + /* + * Coverity is complaining that prefix could + * be dereferenced, but we know that prefix will + * valid. Add an assert to make it happy + */ + assert(prefix); return zebra_static_route_leak(vty, zvrf, zvrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, NULL, NULL, NULL, flag, @@ -561,7 +567,11 @@ DEFPY(ip_route_address_interface_vrf, ifname = NULL; } - nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + if (nexthop_vrf) + nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + else + nh_zvrf = zvrf; + if (!nh_zvrf) { vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); @@ -668,7 +678,11 @@ DEFPY(ip_route_vrf, ifname = NULL; } - nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + if (nexthop_vrf) + nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + else + nh_zvrf = zvrf; + if (!nh_zvrf) { vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); @@ -762,8 +776,9 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, inet_ntoa(nexthop->gate.ipv4)); if (nexthop->ifindex) vty_out(vty, ", via %s", - ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -772,13 +787,14 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, buf, sizeof buf)); if (nexthop->ifindex) vty_out(vty, ", via %s", - ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IFINDEX: vty_out(vty, " directly connected, %s", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_BLACKHOLE: vty_out(vty, " unreachable"); @@ -801,9 +817,9 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, break; } - if (re->vrf_id != re->nh_vrf_id) { + if (re->vrf_id != nexthop->vrf_id) { struct vrf *vrf = - vrf_lookup_by_id(re->nh_vrf_id); + vrf_lookup_by_id(nexthop->vrf_id); vty_out(vty, "(vrf %s)", vrf->name); } @@ -946,8 +962,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, nexthop->ifindex); json_object_string_add( json_nexthop, "interfaceName", - ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); } break; case NEXTHOP_TYPE_IPV6: @@ -965,8 +982,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, nexthop->ifindex); json_object_string_add( json_nexthop, "interfaceName", - ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + ifindex2ifname( + nexthop->ifindex, + nexthop->vrf_id)); } break; @@ -979,7 +997,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object_string_add( json_nexthop, "interfaceName", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_BLACKHOLE: json_object_boolean_true_add(json_nexthop, @@ -1006,9 +1024,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, break; } - if (re->nh_vrf_id != re->vrf_id) { + if (nexthop->vrf_id != re->vrf_id) { struct vrf *vrf = - vrf_lookup_by_id(re->nh_vrf_id); + vrf_lookup_by_id(nexthop->vrf_id); json_object_string_add(json_nexthop, "vrf", @@ -1121,7 +1139,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, if (nexthop->ifindex) vty_out(vty, ", %s", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -1131,13 +1149,13 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, if (nexthop->ifindex) vty_out(vty, ", %s", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_IFINDEX: vty_out(vty, " is directly connected, %s", ifindex2ifname(nexthop->ifindex, - re->nh_vrf_id)); + nexthop->vrf_id)); break; case NEXTHOP_TYPE_BLACKHOLE: vty_out(vty, " unreachable"); @@ -1159,9 +1177,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, break; } - if (re->nh_vrf_id != re->vrf_id) { - struct vrf *vrf = - vrf_lookup_by_id(re->nh_vrf_id); + if (nexthop->vrf_id != re->vrf_id) { + struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id); vty_out(vty, "(vrf %s)", vrf->name); } @@ -2003,6 +2020,12 @@ DEFPY(ipv6_route_blackhole_vrf, VTY_DECLVAR_CONTEXT(vrf, vrf); struct zebra_vrf *zvrf = vrf->info; + /* + * Coverity is complaining that prefix could + * be dereferenced, but we know that prefix will + * valid. Add an assert to make it happy + */ + assert(prefix); return zebra_static_route_leak(vty, zvrf, zvrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, from_str, NULL, NULL, flag, @@ -2092,7 +2115,11 @@ DEFPY(ipv6_route_address_interface_vrf, struct zebra_vrf *zvrf = vrf->info; struct zebra_vrf *nh_zvrf; - nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + if (nexthop_vrf) + nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + else + nh_zvrf = zvrf; + if (!nh_zvrf) { vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); @@ -2186,7 +2213,11 @@ DEFPY(ipv6_route_vrf, struct zebra_vrf *zvrf = vrf->info; struct zebra_vrf *nh_zvrf; - nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + if (nexthop_vrf) + nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); + else + nh_zvrf = zvrf; + if (!nh_zvrf) { vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 1a56b14466..24e60f1bdf 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -128,7 +128,6 @@ static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni, zebra_mac_t *zrmac); /* l3-vni related APIs*/ -static int is_vni_l3(vni_t); static zebra_l3vni_t *zl3vni_lookup(vni_t vni); static void *zl3vni_alloc(void *p); static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id); @@ -2663,6 +2662,8 @@ static void zvni_build_hash_table() zns = zebra_ns_lookup(NS_DEFAULT); for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { vni_t vni; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; struct zebra_if *zif; struct zebra_l2info_vxlan *vxl; @@ -2676,21 +2677,14 @@ static void zvni_build_hash_table() vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { - zebra_l3vni_t *zl3vni = NULL; + /* L3-VNI and L2-VNI are handled seperately */ + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u", ifp->name, ifp->ifindex, vni); - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return; - } - /* associate with vxlan_if */ zl3vni->local_vtep_ip = vxl->vtep_ip; zl3vni->vxlan_if = ifp; @@ -2706,8 +2700,6 @@ static void zvni_build_hash_table() zebra_vxlan_process_l3vni_oper_up(zl3vni); } else { - zebra_vni_t *zvni = NULL; - zebra_l3vni_t *zl3vni = NULL; struct interface *vlan_if = NULL; if (IS_ZEBRA_DEBUG_VXLAN) @@ -3459,16 +3451,6 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni) return 0; } -static int is_vni_l3(vni_t vni) -{ - zebra_l3vni_t *zl3vni = NULL; - - zl3vni = zl3vni_lookup(vni); - if (zl3vni) - return 1; - return 0; -} - static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni) { struct zebra_ns *zns = NULL; @@ -3505,6 +3487,9 @@ static struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni) struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */ struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */ + if (!zl3vni) + return NULL; + if (!zl3vni->vxlan_if) return NULL; @@ -3677,6 +3662,9 @@ static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni) static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni) { + if (!zl3vni) + return; + if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("L3-VNI %u is UP - send add to BGP", zl3vni->vni); @@ -3687,6 +3675,9 @@ static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni) static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni) { + if (!zl3vni) + return; + if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("L3-VNI %u is Down - Send del to BGP", zl3vni->vni); @@ -4584,6 +4575,8 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, { json_object *json = NULL; void *args[2]; + zebra_l3vni_t *zl3vni = NULL; + zebra_vni_t *zvni = NULL; if (!is_evpn_enabled()) return; @@ -4593,22 +4586,10 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni, args[0] = vty; args[1] = json; - if (is_vni_l3(vni)) { - zebra_l3vni_t *zl3vni = NULL; - - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - if (use_json) - vty_out(vty, "{}\n"); - else - vty_out(vty, "%% VNI %u does not exist\n", vni); - return; - } - + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { zl3vni_print(zl3vni, (void *)args); } else { - zebra_vni_t *zvni; - zvni = zvni_lookup(vni); if (!zvni) { if (use_json) @@ -6018,6 +5999,8 @@ int zebra_vxlan_if_down(struct interface *ifp) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_l3vni_t *zl3vni = NULL; + zebra_vni_t *zvni; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -6028,30 +6011,16 @@ int zebra_vxlan_if_down(struct interface *ifp) vxl = &zif->l2info.vxl; vni = vxl->vni; - - if (is_vni_l3(vni)) { - + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { /* process-if-down for l3-vni */ - zebra_l3vni_t *zl3vni = NULL; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", ifp->name, ifp->ifindex, vni); - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at DOWN, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return -1; - } - zebra_vxlan_process_l3vni_oper_down(zl3vni); - } else { /* process if-down for l2-vni */ - zebra_vni_t *zvni; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", ifp->name, ifp->ifindex, vni); @@ -6088,6 +6057,8 @@ int zebra_vxlan_if_up(struct interface *ifp) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -6098,23 +6069,13 @@ int zebra_vxlan_if_up(struct interface *ifp) vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { - - /* Handle L3-VNI add */ - zebra_l3vni_t *zl3vni = NULL; + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Intf %s(%u) L3-VNI %u is UP", ifp->name, ifp->ifindex, vni); - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return -1; - } - /* we need to associate with SVI, if any, we can associate with * svi-if only after association with vxlan-intf is complete */ @@ -6124,9 +6085,6 @@ int zebra_vxlan_if_up(struct interface *ifp) zebra_vxlan_process_l3vni_oper_up(zl3vni); } else { /* Handle L2-VNI add */ - - zebra_vni_t *zvni = NULL; - zebra_l3vni_t *zl3vni = NULL; struct interface *vlan_if = NULL; if (IS_ZEBRA_DEBUG_VXLAN) @@ -6172,6 +6130,8 @@ int zebra_vxlan_if_del(struct interface *ifp) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -6182,23 +6142,13 @@ int zebra_vxlan_if_del(struct interface *ifp) vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { - - /* process if-del for l3-vni */ - zebra_l3vni_t *zl3vni = NULL; + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Del L3-VNI %u intf %s(%u)", vni, ifp->name, ifp->ifindex); - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return 0; - } - /* process oper-down for l3-vni */ zebra_vxlan_process_l3vni_oper_down(zl3vni); @@ -6208,9 +6158,6 @@ int zebra_vxlan_if_del(struct interface *ifp) } else { /* process if-del for l2-vni*/ - zebra_vni_t *zvni = NULL; - zebra_l3vni_t *zl3vni = NULL; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug("Del L2-VNI %u intf %s(%u)", vni, ifp->name, ifp->ifindex); @@ -6246,7 +6193,6 @@ int zebra_vxlan_if_del(struct interface *ifp) return -1; } } - return 0; } @@ -6258,6 +6204,8 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -6268,16 +6216,8 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { - zebra_l3vni_t *zl3vni = NULL; - - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to find L3-VNI hash on update, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return -1; - } + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( @@ -6331,7 +6271,6 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) zebra_vxlan_process_l3vni_oper_up(zl3vni); } } else { - zebra_vni_t *zvni = NULL; /* Update VNI hash. */ zvni = zvni_lookup(vni); @@ -6422,6 +6361,8 @@ int zebra_vxlan_if_add(struct interface *ifp) vni_t vni; struct zebra_if *zif = NULL; struct zebra_l2info_vxlan *vxl = NULL; + zebra_vni_t *zvni = NULL; + zebra_l3vni_t *zl3vni = NULL; /* Check if EVPN is enabled. */ if (!is_evpn_enabled()) @@ -6432,11 +6373,10 @@ int zebra_vxlan_if_add(struct interface *ifp) vxl = &zif->l2info.vxl; vni = vxl->vni; - if (is_vni_l3(vni)) { + zl3vni = zl3vni_lookup(vni); + if (zl3vni) { /* process if-add for l3-vni*/ - zebra_l3vni_t *zl3vni = NULL; - if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u", @@ -6444,20 +6384,6 @@ int zebra_vxlan_if_add(struct interface *ifp) vxl->access_vlan, inet_ntoa(vxl->vtep_ip), zif->brslave_info.bridge_ifindex); - /* - * we expect the l3-vni has entry to be present here. - * The only place l3-vni is created in zebra is vrf-vni mapping - * command. This might change when we have the switchd support - * for l3-vxlan interface. - */ - zl3vni = zl3vni_lookup(vni); - if (!zl3vni) { - zlog_err( - "Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u", - ifp->name, ifp->ifindex, vni); - return 0; - } - /* associate with vxlan_if */ zl3vni->local_vtep_ip = vxl->vtep_ip; zl3vni->vxlan_if = ifp; @@ -6471,8 +6397,6 @@ int zebra_vxlan_if_add(struct interface *ifp) } else { /* process if-add for l2-vni */ - zebra_vni_t *zvni = NULL; - zebra_l3vni_t *zl3vni = NULL; struct interface *vlan_if = NULL; /* Create or update VNI hash. */ diff --git a/zebra/zserv.c b/zebra/zserv.c index 71437bab15..b3b1fa79e9 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -592,7 +592,6 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, memset(&api, 0, sizeof(api)); api.vrf_id = re->vrf_id; - api.nh_vrf_id = re->nh_vrf_id; api.type = re->type; api.instance = re->instance; api.flags = re->flags; @@ -614,6 +613,7 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p, continue; api_nh = &api.nexthops[count]; + api_nh->vrf_id = nexthop->vrf_id; api_nh->type = nexthop->type; switch (nexthop->type) { case NEXTHOP_TYPE_BLACKHOLE: @@ -1137,7 +1137,6 @@ static int zread_route_add(struct zserv *client, u_short length, re->flags = api.flags; re->uptime = time(NULL); re->vrf_id = vrf_id; - re->nh_vrf_id = api.nh_vrf_id; re->table = zvrf->table_id; if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { @@ -1148,11 +1147,12 @@ static int zread_route_add(struct zserv *client, u_short length, switch (api_nh->type) { case NEXTHOP_TYPE_IFINDEX: nexthop = route_entry_nexthop_ifindex_add( - re, api_nh->ifindex); + re, api_nh->ifindex, re->vrf_id); break; case NEXTHOP_TYPE_IPV4: nexthop = route_entry_nexthop_ipv4_add( - re, &api_nh->gate.ipv4, NULL); + re, &api_nh->gate.ipv4, NULL, + re->vrf_id); break; case NEXTHOP_TYPE_IPV4_IFINDEX: { @@ -1168,8 +1168,8 @@ static int zread_route_add(struct zserv *client, u_short length, } nexthop = route_entry_nexthop_ipv4_ifindex_add( - re, &api_nh->gate.ipv4, NULL, - ifindex); + re, &api_nh->gate.ipv4, NULL, ifindex, + re->vrf_id); /* if this an EVPN route entry, program the nh as neigh @@ -1192,12 +1192,12 @@ static int zread_route_add(struct zserv *client, u_short length, } case NEXTHOP_TYPE_IPV6: nexthop = route_entry_nexthop_ipv6_add( - re, &api_nh->gate.ipv6); + re, &api_nh->gate.ipv6, re->vrf_id); break; case NEXTHOP_TYPE_IPV6_IFINDEX: nexthop = route_entry_nexthop_ipv6_ifindex_add( - re, &api_nh->gate.ipv6, - api_nh->ifindex); + re, &api_nh->gate.ipv6, api_nh->ifindex, + re->vrf_id); break; case NEXTHOP_TYPE_BLACKHOLE: nexthop = route_entry_nexthop_blackhole_add( @@ -1364,7 +1364,6 @@ static int zread_ipv4_add(struct zserv *client, u_short length, /* VRF ID */ re->vrf_id = zvrf_id(zvrf); - re->nh_vrf_id = zvrf_id(zvrf); /* Nexthop parse. */ if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { @@ -1381,13 +1380,14 @@ static int zread_ipv4_add(struct zserv *client, u_short length, switch (nexthop_type) { case NEXTHOP_TYPE_IFINDEX: STREAM_GETL(s, ifindex); - route_entry_nexthop_ifindex_add(re, ifindex); + route_entry_nexthop_ifindex_add(re, ifindex, + re->vrf_id); break; case NEXTHOP_TYPE_IPV4: STREAM_GET(&nhop_addr.s_addr, s, IPV4_MAX_BYTELEN); nexthop = route_entry_nexthop_ipv4_add( - re, &nhop_addr, NULL); + re, &nhop_addr, NULL, re->vrf_id); /* For labeled-unicast, each nexthop is followed * by label. */ if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) { @@ -1401,7 +1401,8 @@ static int zread_ipv4_add(struct zserv *client, u_short length, IPV4_MAX_BYTELEN); STREAM_GETL(s, ifindex); route_entry_nexthop_ipv4_ifindex_add( - re, &nhop_addr, NULL, ifindex); + re, &nhop_addr, NULL, ifindex, + re->vrf_id); break; case NEXTHOP_TYPE_IPV6: zlog_warn("%s: Please use ZEBRA_ROUTE_ADD if you want to pass v6 nexthops", @@ -1574,7 +1575,6 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, /* VRF ID */ re->vrf_id = zvrf_id(zvrf); - re->nh_vrf_id = zvrf_id(zvrf); /* We need to give nh-addr, nh-ifindex with the same next-hop object * to the re to ensure that IPv6 multipathing works; need to coalesce @@ -1635,10 +1635,11 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, nexthop = route_entry_nexthop_ipv6_ifindex_add( re, &nexthops[i], - ifindices[i]); + ifindices[i], + re->vrf_id); else nexthop = route_entry_nexthop_ipv6_add( - re, &nexthops[i]); + re, &nexthops[i], re->vrf_id); if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) nexthop_add_labels(nexthop, label_type, @@ -1646,7 +1647,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, } else { if ((i < if_count) && ifindices[i]) route_entry_nexthop_ifindex_add( - re, ifindices[i]); + re, ifindices[i], re->vrf_id); } } } @@ -1760,6 +1761,9 @@ static int zread_ipv6_add(struct zserv *client, u_short length, } else src_pp = NULL; + /* VRF ID */ + re->vrf_id = zvrf_id(zvrf); + /* We need to give nh-addr, nh-ifindex with the same next-hop object * to the re to ensure that IPv6 multipathing works; need to coalesce * these. Clients should send the same number of paired set of @@ -1797,7 +1801,7 @@ static int zread_ipv6_add(struct zserv *client, u_short length, STREAM_GET(&nhop_addr, s, 16); STREAM_GETL(s, ifindex); route_entry_nexthop_ipv6_ifindex_add( - re, &nhop_addr, ifindex); + re, &nhop_addr, ifindex, re->vrf_id); break; case NEXTHOP_TYPE_IFINDEX: if (if_count < multipath_num) { @@ -1824,17 +1828,18 @@ static int zread_ipv6_add(struct zserv *client, u_short length, nexthop = route_entry_nexthop_ipv6_ifindex_add( re, &nexthops[i], - ifindices[i]); + ifindices[i], + re->vrf_id); else nexthop = route_entry_nexthop_ipv6_add( - re, &nexthops[i]); + re, &nexthops[i], re->vrf_id); if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) nexthop_add_labels(nexthop, label_type, 1, &labels[i]); } else { if ((i < if_count) && ifindices[i]) route_entry_nexthop_ifindex_add( - re, ifindices[i]); + re, ifindices[i], re->vrf_id); } } } @@ -1858,10 +1863,6 @@ static int zread_ipv6_add(struct zserv *client, u_short length, else re->mtu = 0; - /* VRF ID */ - re->vrf_id = zvrf_id(zvrf); - re->nh_vrf_id = zvrf_id(zvrf); - re->table = zvrf->table_id; ret = rib_add_multipath(AFI_IP6, safi, &p, src_pp, re); @@ -2485,6 +2486,75 @@ stream_failure: return 1; } + +static void zread_vrf_label(struct zserv *client, + struct zebra_vrf *zvrf) +{ + struct interface *ifp; + mpls_label_t nlabel; + afi_t afi; + struct stream *s; + struct zebra_vrf *def_zvrf; + enum lsp_types_t ltype; + + s = client->ibuf; + STREAM_GETL(s, nlabel); + STREAM_GETC(s, afi); + if (nlabel == zvrf->label[afi]) { + /* + * Nothing to do here move along + */ + return; + } + + STREAM_GETC(s, ltype); + + if (zvrf->vrf->vrf_id != VRF_DEFAULT) + ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf->vrf_id); + else + ifp = if_lookup_by_name("lo", VRF_DEFAULT); + + if (!ifp) { + zlog_debug("Unable to find specified Interface for %s", + zvrf->vrf->name); + return; + } + + def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + + if (zvrf->label[afi] != MPLS_LABEL_NONE) { + afi_t scrubber; + bool really_remove; + + really_remove = true; + for (scrubber = AFI_IP; scrubber < AFI_MAX ; scrubber++) { + if (scrubber == afi) + continue; + + if (zvrf->label[scrubber] == MPLS_LABEL_NONE) + continue; + + if (zvrf->label[afi] == zvrf->label[scrubber]) { + really_remove = false; + break; + } + } + + if (really_remove) + mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi], + NEXTHOP_TYPE_IFINDEX, NULL, + ifp->ifindex); + } + + if (nlabel != MPLS_LABEL_NONE) + mpls_lsp_install(def_zvrf, ltype, nlabel, MPLS_LABEL_IMPLICIT_NULL, + NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); + + zvrf->label[afi] = nlabel; +stream_failure: + return; +} + static inline void zserv_handle_commands(struct zserv *client, uint16_t command, uint16_t length, @@ -2569,6 +2639,9 @@ static inline void zserv_handle_commands(struct zserv *client, case ZEBRA_VRF_UNREGISTER: zread_vrf_unregister(client, length, zvrf); break; + case ZEBRA_VRF_LABEL: + zread_vrf_label(client, zvrf); + break; case ZEBRA_BFD_CLIENT_REGISTER: zebra_ptm_bfd_client_register(client, length); break;