Merge branch 'master' into evpn-bug-fixes

This commit is contained in:
Mitesh Kanjariya 2018-02-21 00:36:58 -08:00 committed by GitHub
commit f487dcaf74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
83 changed files with 1721 additions and 1114 deletions

View File

@ -166,7 +166,6 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen,
api.type = ZEBRA_ROUTE_BABEL; api.type = ZEBRA_ROUTE_BABEL;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.prefix = quagga_prefix; api.prefix = quagga_prefix;
if(metric >= KERNEL_INFINITY) { if(metric >= KERNEL_INFINITY) {
@ -175,7 +174,7 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen,
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
api.nexthop_num = 1; api.nexthop_num = 1;
api_nh->ifindex = ifindex; api_nh->ifindex = ifindex;
api_nh->vrf_id = VRF_DEFAULT;
switch (family) { switch (family) {
case AF_INET: case AF_INET:
uchar_to_inaddr(&api_nh->gate.ipv4, gate); uchar_to_inaddr(&api_nh->gate.ipv4, gate);

View File

@ -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))) if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)))
snprintf(buf + strlen(buf), size - strlen(buf), snprintf(buf + strlen(buf), size - strlen(buf),
", community %s", community_str(attr->community, ", community %s",
false)); community_str(attr->community, false));
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
snprintf(buf + strlen(buf), size - strlen(buf), snprintf(buf + strlen(buf), size - strlen(buf),

View File

@ -153,9 +153,9 @@ extern int bgp_debug_zebra(struct prefix *p);
extern int bgp_debug_count(void); extern int bgp_debug_count(void);
extern const char *bgp_debug_rdpfxpath2str(afi_t, safi_t, struct prefix_rd *, extern const char *bgp_debug_rdpfxpath2str(afi_t, safi_t, struct prefix_rd *,
union prefixconstptr, union prefixconstptr, mpls_label_t *,
mpls_label_t *, u_int32_t, u_int32_t, int, u_int32_t, char *,
int, u_int32_t, char *, int); int);
const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data, const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data,
size_t datalen); size_t datalen);

View File

@ -3301,6 +3301,18 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf,
for (ri = rn->info; ri; ri = ri->next) { for (ri = rn->info; ri; ri = ri->next) {
if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) && if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) &&
(!ri->extra || !ri->extra->parent)) { (!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, bgp_evpn_advertise_type5_route(bgp_vrf, &rn->p,
ri->attr, ri->attr,
afi, safi); afi, safi);

View File

@ -83,7 +83,7 @@ static void display_vrf_import_rt(struct vty *vty,
case ECOMMUNITY_ENCODE_AS: case ECOMMUNITY_ENCODE_AS:
eas.as = (*pnt++ << 8); eas.as = (*pnt++ << 8);
eas.as |= (*pnt++); 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); 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: case ECOMMUNITY_ENCODE_AS:
eas.as = (*pnt++ << 8); eas.as = (*pnt++ << 8);
eas.as |= (*pnt++); 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); 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, DEFUN (bgp_evpn_advertise_type5,
bgp_evpn_advertise_type5_cmd, 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" "Advertise prefix routes\n"
BGP_AFI_HELP_STR 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 */ struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */
int idx_afi = 0; int idx_afi = 0;
int idx_safi = 0; int idx_safi = 0;
int idx_rmap = 0;
afi_t afi = 0; afi_t afi = 0;
safi_t safi = 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_afi(argv, argc, &idx_afi, &afi);
argv_find_and_parse_safi(argv, argc, &idx_safi, &safi); 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)) { if (!(afi == AFI_IP) || (afi == AFI_IP6)) {
vty_out(vty, vty_out(vty,
@ -2754,24 +2769,44 @@ DEFUN (bgp_evpn_advertise_type5,
/* if we are already advertising ipv4 prefix as type-5 /* if we are already advertising ipv4 prefix as type-5
* nothing to do * nothing to do
*/ */
if (!CHECK_FLAG(bgp_vrf->vrf_flags, if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) { BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
return CMD_WARNING;
SET_FLAG(bgp_vrf->vrf_flags, SET_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV4_IN_EVPN); BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi);
}
} else { } else {
/* if we are already advertising ipv6 prefix as type-5 /* if we are already advertising ipv6 prefix as type-5
* nothing to do * nothing to do
*/ */
if (!CHECK_FLAG(bgp_vrf->vrf_flags, if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) { BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
return CMD_WARNING;
SET_FLAG(bgp_vrf->vrf_flags, SET_FLAG(bgp_vrf->vrf_flags,
BGP_VRF_ADVERTISE_IPV6_IN_EVPN); 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); bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi);
}
}
return CMD_SUCCESS; return CMD_SUCCESS;
} }
@ -2827,6 +2862,15 @@ DEFUN (no_bgp_evpn_advertise_type5,
BGP_VRF_ADVERTISE_IPV6_IN_EVPN); 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; return CMD_SUCCESS;
} }

View File

@ -366,8 +366,8 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
return CMD_WARNING; return CMD_WARNING;
} }
table = bgp->rib[afi][SAFI_MPLS_VPN]; table = bgp->rib[afi][SAFI_MPLS_VPN];
return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, table, prd, type,
table, prd, type, output_arg, use_json); output_arg, use_json);
} }
DEFUN (show_bgp_ip_vpn_all_rd, DEFUN (show_bgp_ip_vpn_all_rd,

View File

@ -24,30 +24,6 @@
#include "bgpd/bgp_route.h" #include "bgpd/bgp_route.h"
#include "bgpd/bgp_rd.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_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION)
#define MPLS_LABEL_IS_NULL(label) \ #define MPLS_LABEL_IS_NULL(label) \
((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL \ ((label) == MPLS_LABEL_IPV4_EXPLICIT_NULL \

View File

@ -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 (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->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
attr->local_pref = BGP_GSHUT_LOCAL_PREF; attr->local_pref = BGP_GSHUT_LOCAL_PREF;
} else { } else {
@ -1966,7 +1967,8 @@ int subgroup_process_announce_selected(struct update_subgroup *subgrp,
: NULL); : NULL);
/* First update is deferred until ORF or ROUTE-REFRESH is received */ /* First update is deferred until ORF or ROUTE-REFRESH is received */
if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi], if (onlypeer
&& CHECK_FLAG(onlypeer->af_sflags[afi][safi],
PEER_STATUS_ORF_WAIT_REFRESH)) PEER_STATUS_ORF_WAIT_REFRESH))
return 0; return 0;
@ -2099,13 +2101,14 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
rn->flags, rn->flags,
BGP_NODE_REGISTERED_FOR_LABEL)) BGP_NODE_REGISTERED_FOR_LABEL))
bgp_unregister_for_label(rn); bgp_unregister_for_label(rn);
label_ntop(MPLS_IMP_NULL_LABEL, 1, label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
&rn->local_label); &rn->local_label);
bgp_set_valid_label(&rn->local_label); bgp_set_valid_label(&rn->local_label);
} else } else
bgp_register_for_label(rn, new_select); 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); bgp_unregister_for_label(rn);
} }
} else if (CHECK_FLAG(rn->flags, BGP_NODE_REGISTERED_FOR_LABEL)) { } 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; 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 */ /* unlocked in bgp_processq_del */
pqnode->bgp = bgp_lock(bgp); 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; return;
/* Add route nodes to an existing work queue item until reaching the /* 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)) { if (work_queue_item_count(wq)) {
struct work_queue_item *item = work_queue_last_item(wq); struct work_queue_item *item = work_queue_last_item(wq);
pqnode = item->data; pqnode = item->data;
if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER) || if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
pqnode->bgp != bgp || pqnode->queued >= ARBITRARY_PROCESS_QLEN) || pqnode->bgp != bgp
|| pqnode->queued >= ARBITRARY_PROCESS_QLEN)
pqnode = bgp_processq_alloc(bgp); pqnode = bgp_processq_alloc(bgp);
else else
pqnode_reuse = 1; 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, 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, struct attr *attr, afi_t afi, safi_t safi, int type,
int sub_type, struct prefix_rd *prd, int sub_type, struct prefix_rd *prd, mpls_label_t *label,
mpls_label_t *label, u_int32_t num_labels, u_int32_t num_labels, int soft_reconfig,
int soft_reconfig, struct bgp_route_evpn *evpn) struct bgp_route_evpn *evpn)
{ {
int ret; int ret;
int aspath_loop_count = 0; 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->change_local_as) {
if (peer->allowas_in[afi][safi]) if (peer->allowas_in[afi][safi])
aspath_loop_count = 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; aspath_loop_count = 1;
if (aspath_loop_check(attr->aspath, peer->change_local_as) 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 (peer->sort == BGP_PEER_EBGP) {
/* If we receive the graceful-shutdown community from an eBGP peer we /* If we receive the graceful-shutdown community from an eBGP
* must lower local-preference */ * peer we must lower local-preference */
if (new_attr.community && if (new_attr.community
community_include(new_attr.community, COMMUNITY_GSHUT)) { && community_include(new_attr.community, COMMUNITY_GSHUT)) {
new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
new_attr.local_pref = BGP_GSHUT_LOCAL_PREF; new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
/* If graceful-shutdown is configured then add the GSHUT community to /* If graceful-shutdown is configured then add the GSHUT
* all paths received from eBGP peers */ * community to all paths received from eBGP peers */
} else if (bgp_flag_check(peer->bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) { } else if (bgp_flag_check(peer->bgp,
BGP_FLAG_GRACEFUL_SHUTDOWN)) {
bgp_attr_add_gshut_community(&new_attr); bgp_attr_add_gshut_community(&new_attr);
} }
} }
/* next hop check. */ /* next hop check. */
if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) && if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
bgp_update_martian_nexthop(bgp, afi, safi, &new_attr)) { && bgp_update_martian_nexthop(bgp, afi, safi, &new_attr)) {
reason = "martian or self next-hop;"; reason = "martian or self next-hop;";
bgp_attr_flush(&new_attr); bgp_attr_flush(&new_attr);
goto filtered; 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)) { && CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) {
if (bgp_debug_update(peer, p, NULL, 1)) { if (bgp_debug_update(peer, p, NULL, 1)) {
bgp_debug_rdpfxpath2str( bgp_debug_rdpfxpath2str(
afi, safi, prd, p, afi, safi, prd, p, label,
label, num_labels, num_labels, addpath_id ? 1 : 0,
addpath_id ? 1 : 0, addpath_id, addpath_id, pfx_buf,
pfx_buf, sizeof(pfx_buf)); sizeof(pfx_buf));
zlog_debug("%s rcvd %s", peer->host, zlog_debug("%s rcvd %s", peer->host,
pfx_buf); pfx_buf);
} }
@ -2865,10 +2873,10 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
} }
bgp_debug_rdpfxpath2str( bgp_debug_rdpfxpath2str(
afi, safi, prd, p, afi, safi, prd, p, label,
label, num_labels, num_labels, addpath_id ? 1 : 0,
addpath_id ? 1 : 0, addpath_id, addpath_id, pfx_buf,
pfx_buf, sizeof(pfx_buf)); sizeof(pfx_buf));
zlog_debug( zlog_debug(
"%s rcvd %s...duplicate ignored", "%s rcvd %s...duplicate ignored",
peer->host, pfx_buf); 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 (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
if (bgp_debug_update(peer, p, NULL, 1)) { if (bgp_debug_update(peer, p, NULL, 1)) {
bgp_debug_rdpfxpath2str( bgp_debug_rdpfxpath2str(
afi, safi, prd, p, afi, safi, prd, p, label, num_labels,
label, num_labels,
addpath_id ? 1 : 0, addpath_id, pfx_buf, addpath_id ? 1 : 0, addpath_id, pfx_buf,
sizeof(pfx_buf)); sizeof(pfx_buf));
zlog_debug( zlog_debug(
@ -2906,10 +2913,10 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
/* Received Logging. */ /* Received Logging. */
if (bgp_debug_update(peer, p, NULL, 1)) { if (bgp_debug_update(peer, p, NULL, 1)) {
bgp_debug_rdpfxpath2str(afi, safi, prd, p, bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
label, num_labels, num_labels, addpath_id ? 1 : 0,
addpath_id ? 1 : 0, addpath_id, addpath_id, pfx_buf,
pfx_buf, sizeof(pfx_buf)); sizeof(pfx_buf));
zlog_debug("%s rcvd %s", peer->host, 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; connected = 0;
if (bgp_find_or_add_nexthop(bgp, afi, ri, NULL, if (bgp_find_or_add_nexthop(bgp, afi, ri, NULL,
connected) || connected)
CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
bgp_info_set_flag(rn, ri, BGP_INFO_VALID); bgp_info_set_flag(rn, ri, BGP_INFO_VALID);
else { else {
if (BGP_DEBUG(nht, NHT)) { 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; peer->rcvd_attr_printed = 1;
} }
bgp_debug_rdpfxpath2str(afi, safi, prd, p, bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
label, num_labels,
addpath_id ? 1 : 0, addpath_id, pfx_buf, addpath_id ? 1 : 0, addpath_id, pfx_buf,
sizeof(pfx_buf)); sizeof(pfx_buf));
zlog_debug("%s rcvd %s", peer->host, 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 */ /* Update MPLS label */
if (has_valid_label) { if (has_valid_label) {
extra = bgp_info_extra_get(new); extra = bgp_info_extra_get(new);
memcpy(&extra->label, label, memcpy(&extra->label, label, num_labels * sizeof(mpls_label_t));
num_labels * sizeof(mpls_label_t));
extra->num_labels = num_labels; extra->num_labels = num_labels;
if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
bgp_set_valid_label(&extra->label[0]); 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 else
connected = 0; connected = 0;
if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, connected) || if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, connected)
CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
bgp_info_set_flag(rn, new, BGP_INFO_VALID); bgp_info_set_flag(rn, new, BGP_INFO_VALID);
else { else {
if (BGP_DEBUG(nht, NHT)) { if (BGP_DEBUG(nht, NHT)) {
@ -3259,8 +3264,7 @@ filtered:
peer->rcvd_attr_printed = 1; peer->rcvd_attr_printed = 1;
} }
bgp_debug_rdpfxpath2str(afi, safi, prd, p, bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
label, num_labels,
addpath_id ? 1 : 0, addpath_id, pfx_buf, addpath_id ? 1 : 0, addpath_id, pfx_buf,
sizeof(pfx_buf)); sizeof(pfx_buf));
zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s", 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, 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, struct attr *attr, afi_t afi, safi_t safi, int type,
int sub_type, struct prefix_rd *prd, int sub_type, struct prefix_rd *prd, mpls_label_t *label,
mpls_label_t *label, u_int32_t num_labels, u_int32_t num_labels, struct bgp_route_evpn *evpn)
struct bgp_route_evpn *evpn)
{ {
struct bgp *bgp; struct bgp *bgp;
char pfx_buf[BGP_PRD_PATH_STRLEN]; 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_adj_in_unset(rn, peer, addpath_id)) {
if (bgp_debug_update(peer, p, NULL, 1)) { if (bgp_debug_update(peer, p, NULL, 1)) {
bgp_debug_rdpfxpath2str( bgp_debug_rdpfxpath2str(
afi, safi, prd, p, afi, safi, prd, p, label, num_labels,
label, num_labels,
addpath_id ? 1 : 0, addpath_id, pfx_buf, addpath_id ? 1 : 0, addpath_id, pfx_buf,
sizeof(pfx_buf)); sizeof(pfx_buf));
zlog_debug( zlog_debug(
@ -3353,8 +3355,7 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
/* Logging. */ /* Logging. */
if (bgp_debug_update(peer, p, NULL, 1)) { if (bgp_debug_update(peer, p, NULL, 1)) {
bgp_debug_rdpfxpath2str(afi, safi, prd, p, bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
label, num_labels,
addpath_id ? 1 : 0, addpath_id, pfx_buf, addpath_id ? 1 : 0, addpath_id, pfx_buf,
sizeof(pfx_buf)); sizeof(pfx_buf));
zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host, 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)) if (ri && !CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
bgp_rib_withdraw(rn, ri, peer, afi, safi, prd); bgp_rib_withdraw(rn, ri, peer, afi, safi, prd);
else if (bgp_debug_update(peer, p, NULL, 1)) { else if (bgp_debug_update(peer, p, NULL, 1)) {
bgp_debug_rdpfxpath2str(afi, safi, prd, p, bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
label, num_labels,
addpath_id ? 1 : 0, addpath_id, pfx_buf, addpath_id ? 1 : 0, addpath_id, pfx_buf,
sizeof(pfx_buf)); sizeof(pfx_buf));
zlog_debug("%s Can't find the route %s", peer->host, 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, ret = bgp_update(peer, &rn->p, ain->addpath_rx_id,
ain->attr, afi, safi, ZEBRA_ROUTE_BGP, ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, prd, BGP_ROUTE_NORMAL, prd, label_pnt,
label_pnt, num_labels, 1, NULL); num_labels, 1, NULL);
if (ret < 0) { if (ret < 0) {
bgp_unlock_node(rn); bgp_unlock_node(rn);
@ -4060,8 +4060,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
else else
ret = bgp_withdraw(peer, &p, addpath_id, attr, afi, ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
safi, ZEBRA_ROUTE_BGP, safi, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, NULL, BGP_ROUTE_NORMAL, NULL, NULL, 0,
NULL, 0, NULL); NULL);
/* Address family configuration mismatch or maximum-prefix count /* Address family configuration mismatch or maximum-prefix count
overflow. */ 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); rn = bgp_node_lookup(bgp->route[afi][safi], &p);
if (!rn) { if (!rn) {
vty_out(vty, vty_out(vty, "%% Can't find static route specified\n");
"%% Can't find static route specified\n");
return CMD_WARNING_CONFIG_FAILED; 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. */ /* Check previous routes are installed into BGP. */
if (bgp_static->valid && if (bgp_static->valid
bgp_static->backdoor != backdoor) && bgp_static->backdoor != backdoor)
need_update = 1; need_update = 1;
bgp_static->backdoor = backdoor; bgp_static->backdoor = backdoor;
@ -5111,11 +5110,10 @@ DEFPY(bgp_network,
} }
} }
return bgp_static_set(vty, no, address_str ? addr_prefix_str:prefix_str, return bgp_static_set(
AFI_IP, bgp_node_safi(vty), vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
map_name, backdoor?1:0, bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
label_index ? label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
(uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
} }
DEFPY(ipv6_bgp_network, DEFPY(ipv6_bgp_network,
@ -5130,10 +5128,9 @@ DEFPY(ipv6_bgp_network,
"Label index to associate with the prefix\n" "Label index to associate with the prefix\n"
"Label index value\n") "Label index value\n")
{ {
return bgp_static_set(vty, no, prefix_str, AFI_IP6, return bgp_static_set(
bgp_node_safi(vty), map_name, 0, vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
label_index ? label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
(uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
} }
/* Aggreagete address: /* Aggreagete address:
@ -5858,8 +5855,7 @@ DEFUN (no_ipv6_aggregate_address,
void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
const union g_addr *nexthop, ifindex_t ifindex, const union g_addr *nexthop, ifindex_t ifindex,
enum nexthop_types_t nhtype, uint32_t metric, enum nexthop_types_t nhtype, uint32_t metric,
u_char type, u_short instance, u_char type, u_short instance, route_tag_t tag)
route_tag_t tag)
{ {
struct bgp_info *new; struct bgp_info *new;
struct bgp_info *bi; struct bgp_info *bi;
@ -6255,13 +6251,13 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
switch (af) { switch (af) {
case AF_INET: case AF_INET:
sprintf(nexthop, "%s", sprintf(nexthop, "%s",
inet_ntop(af, &attr->mp_nexthop_global_in, inet_ntop(af, &attr->mp_nexthop_global_in, buf,
buf, BUFSIZ)); BUFSIZ));
break; break;
case AF_INET6: case AF_INET6:
sprintf(nexthop, "%s", sprintf(nexthop, "%s",
inet_ntop(af, &attr->mp_nexthop_global, inet_ntop(af, &attr->mp_nexthop_global, buf,
buf, BUFSIZ)); BUFSIZ));
break; break;
default: default:
sprintf(nexthop, "?"); sprintf(nexthop, "?");
@ -6271,13 +6267,10 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
if (json_paths) { if (json_paths) {
json_nexthop_global = json_object_new_object(); 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, json_object_string_add(json_nexthop_global,
"afi", (af == AF_INET) ? "ip" : "ipv6",
(af == AF_INET) ?
"ip" : "ipv6");
json_object_string_add(json_nexthop_global,
(af == AF_INET) ?
"ip" : "ipv6",
nexthop); nexthop);
json_object_boolean_true_add(json_nexthop_global, json_object_boolean_true_add(json_nexthop_global,
"used"); "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", json_object_string_add(json_nexthop_global, "ip",
inet_ntoa(attr->nexthop)); inet_ntoa(attr->nexthop));
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global, "afi",
"afi", "ipv4"); "ipv4");
json_object_boolean_true_add(json_nexthop_global, json_object_boolean_true_add(json_nexthop_global,
"used"); "used");
} else } else
vty_out(vty, "%-16s", inet_ntoa(attr->nexthop)); vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
} }
/* IPv4 Next Hop */ /* IPv4 Next Hop */
else if (p->family == AF_INET else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
if (json_paths) { if (json_paths) {
json_nexthop_global = json_object_new_object(); json_nexthop_global = json_object_new_object();
if ((safi == SAFI_MPLS_VPN) if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
|| (safi == SAFI_EVPN)) json_object_string_add(
json_object_string_add(json_nexthop_global, json_nexthop_global, "ip",
"ip",
inet_ntoa(attr->mp_nexthop_global_in)); inet_ntoa(attr->mp_nexthop_global_in));
else else
json_object_string_add(json_nexthop_global, json_object_string_add(
"ip", json_nexthop_global, "ip",
inet_ntoa(attr->nexthop)); inet_ntoa(attr->nexthop));
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global, "afi",
"afi", "ipv4"); "ipv4");
json_object_boolean_true_add(json_nexthop_global, json_object_boolean_true_add(json_nexthop_global,
"used"); "used");
} else { } else {
if ((safi == SAFI_MPLS_VPN) if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
|| (safi == SAFI_EVPN))
vty_out(vty, "%-16s", vty_out(vty, "%-16s",
inet_ntoa( inet_ntoa(attr->mp_nexthop_global_in));
attr->mp_nexthop_global_in));
else else
vty_out(vty, "%-16s", vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
inet_ntoa(attr->nexthop));
} }
} }
/* IPv6 Next Hop */ /* IPv6 Next Hop */
else if (p->family == AF_INET6 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
int len; int len;
char buf[BUFSIZ]; char buf[BUFSIZ];
if (json_paths) { if (json_paths) {
json_nexthop_global = json_object_new_object(); json_nexthop_global = json_object_new_object();
json_object_string_add(json_nexthop_global, "ip", json_object_string_add(
inet_ntop(AF_INET6, json_nexthop_global, "ip",
&attr->mp_nexthop_global, buf, inet_ntop(AF_INET6, &attr->mp_nexthop_global,
BUFSIZ)); buf, BUFSIZ));
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global, "afi",
"afi", "ipv6"); "ipv6");
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global, "scope",
"scope", "global"); "global");
/* We display both LL & GL if both have been /* We display both LL & GL if both have been
* received */ * received */
if ((attr->mp_nexthop_len == 32) if ((attr->mp_nexthop_len == 32)
|| (binfo->peer->conf_if)) { || (binfo->peer->conf_if)) {
json_nexthop_ll = json_nexthop_ll = json_object_new_object();
json_object_new_object();
json_object_string_add( json_object_string_add(
json_nexthop_ll, "ip", json_nexthop_ll, "ip",
inet_ntop( inet_ntop(AF_INET6,
AF_INET6, &attr->mp_nexthop_local, buf,
&attr->mp_nexthop_local, BUFSIZ));
buf, BUFSIZ)); json_object_string_add(json_nexthop_ll, "afi",
json_object_string_add(json_nexthop_ll, "ipv6");
"afi", "ipv6"); json_object_string_add(json_nexthop_ll, "scope",
json_object_string_add(json_nexthop_ll,
"scope",
"link-local"); "link-local");
if ((IPV6_ADDR_CMP( if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
&attr->mp_nexthop_global,
&attr->mp_nexthop_local) &attr->mp_nexthop_local)
!= 0) != 0)
&& !attr->mp_nexthop_prefer_global) && !attr->mp_nexthop_prefer_global)
json_object_boolean_true_add( json_object_boolean_true_add(
json_nexthop_ll, json_nexthop_ll, "used");
"used");
else else
json_object_boolean_true_add( json_object_boolean_true_add(
json_nexthop_global, json_nexthop_global, "used");
"used");
} else } else
json_object_boolean_true_add( json_object_boolean_true_add(
json_nexthop_global, "used"); json_nexthop_global, "used");
@ -6385,8 +6366,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
&& !attr->mp_nexthop_prefer_global) && !attr->mp_nexthop_prefer_global)
|| (binfo->peer->conf_if)) { || (binfo->peer->conf_if)) {
if (binfo->peer->conf_if) { if (binfo->peer->conf_if) {
len = vty_out( len = vty_out(vty, "%s",
vty, "%s",
binfo->peer->conf_if); binfo->peer->conf_if);
len = 16 - len; /* len of IPv6 len = 16 - len; /* len of IPv6
addr + max addr + max
@ -6394,11 +6374,9 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
ifname */ ifname */
if (len < 1) if (len < 1)
vty_out(vty, "\n%*s", vty_out(vty, "\n%*s", 36, " ");
36, " ");
else else
vty_out(vty, "%*s", len, vty_out(vty, "%*s", len, " ");
" ");
} else { } else {
len = vty_out( len = vty_out(
vty, "%s", vty, "%s",
@ -6409,17 +6387,16 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
len = 16 - len; len = 16 - len;
if (len < 1) if (len < 1)
vty_out(vty, "\n%*s", vty_out(vty, "\n%*s", 36, " ");
36, " ");
else else
vty_out(vty, "%*s", len, vty_out(vty, "%*s", len, " ");
" ");
} }
} else { } else {
len = vty_out(vty, "%s", len = vty_out(
vty, "%s",
inet_ntop(AF_INET6, inet_ntop(AF_INET6,
&attr->mp_nexthop_global, &attr->mp_nexthop_global, buf,
buf, BUFSIZ)); BUFSIZ));
len = 16 - len; len = 16 - len;
if (len < 1) if (len < 1)
@ -6433,8 +6410,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
/* MED/Metric */ /* MED/Metric */
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
if (json_paths) if (json_paths)
json_object_int_add(json_path, "med", json_object_int_add(json_path, "med", attr->med);
attr->med);
else else
vty_out(vty, "%10u", attr->med); vty_out(vty, "%10u", attr->med);
else if (!json_paths) 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) { if (json_paths) {
char buf[BUFSIZ]; char buf[BUFSIZ];
json_object_string_add(json_path, "peerId", json_object_string_add(
sockunion2str(&binfo->peer->su, json_path, "peerId",
buf, sockunion2str(&binfo->peer->su, buf, SU_ADDRSTRLEN));
SU_ADDRSTRLEN));
} }
/* Print aspath */ /* Print aspath */
@ -6474,8 +6449,7 @@ void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
/* Print origin */ /* Print origin */
if (json_paths) if (json_paths)
json_object_string_add( json_object_string_add(json_path, "origin",
json_path, "origin",
bgp_origin_long_str[attr->origin]); bgp_origin_long_str[attr->origin]);
else else
vty_out(vty, "%s", bgp_origin_str[attr->origin]); 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 (attr) {
if (((p->family == AF_INET) if (((p->family == AF_INET)
&& ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
|| (safi == SAFI_EVPN || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
|| (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_EVPN) { || 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, bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN,
use_json, json); use_json, json);
else else
vty_out(vty, "%s ", bgp_damp_reuse_time_vty(vty, binfo, timebuf, vty_out(vty, "%s ",
BGP_UPTIME_LEN, bgp_damp_reuse_time_vty(vty, binfo, timebuf,
use_json, json)); BGP_UPTIME_LEN, use_json,
json));
/* Print attribute */ /* Print attribute */
attr = binfo->attr; 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, peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
json); json);
else else
vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf, vty_out(vty, "%s ",
BGP_UPTIME_LEN, 0, NULL)); peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, 0,
NULL));
if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED) if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
&& !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) { && !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'; tag_buf[0] = '\0';
if (binfo->extra && binfo->extra->num_labels) { if (binfo->extra && binfo->extra->num_labels) {
bgp_evpn_label2str(binfo->extra->label, bgp_evpn_label2str(binfo->extra->label,
binfo->extra->num_labels, binfo->extra->num_labels, tag_buf,
tag_buf, sizeof(tag_buf)); sizeof(tag_buf));
vty_out(vty, " VNI %s", tag_buf); vty_out(vty, " VNI %s", tag_buf);
} }
vty_out(vty, "\n"); 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 */ /* Line2 display Next-hop, Neighbor, Router-id */
/* Display the nexthop */ /* Display the nexthop */
if ((p->family == AF_INET || p->family == AF_ETHERNET || if ((p->family == AF_INET || p->family == AF_ETHERNET
p->family == AF_EVPN) || p->family == AF_EVPN)
&& (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_EVPN || safi == SAFI_EVPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { || !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 (attr->community) {
if (json_paths) { if (json_paths) {
if (!attr->community->json) if (!attr->community->json)
community_str(attr->community, community_str(attr->community, true);
true);
json_object_lock(attr->community->json); json_object_lock(attr->community->json);
json_object_object_add(json_path, "community", json_object_object_add(json_path, "community",
attr->community->json); 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])) if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0]))
#endif #endif
{ {
mpls_label_t label = label_pton( mpls_label_t label =
&binfo->extra->label[0]); label_pton(&binfo->extra->label[0]);
if (json_paths) if (json_paths)
json_object_int_add(json_path, "remoteLabel", json_object_int_add(json_path, "remoteLabel",
label); 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, static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
const char *prefix, afi_t afi, safi_t safi, const char *prefix, afi_t afi, safi_t safi,
enum bgp_show_type type); enum bgp_show_type type);
static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
const char *regstr, afi_t afi, afi_t afi, safi_t safi, enum bgp_show_type type);
safi_t safi, enum bgp_show_type type);
static int bgp_show_community(struct vty *vty, struct bgp *bgp, static int bgp_show_community(struct vty *vty, struct bgp *bgp,
const char *comstr, int exact, afi_t afi, const char *comstr, int exact, afi_t afi,
safi_t safi); 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, static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
struct bgp_table *table, enum bgp_show_type type, struct bgp_table *table, enum bgp_show_type type,
void *output_arg, u_char use_json, void *output_arg, u_char use_json, char *rd,
char *rd, int is_last, int is_last, unsigned long *output_cum,
unsigned long *output_cum, unsigned long *total_cum) unsigned long *total_cum,
unsigned long *json_header_depth)
{ {
struct bgp_info *ri; struct bgp_info *ri;
struct bgp_node *rn; 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) if (output_cum && *output_cum != 0)
header = 0; header = 0;
if (use_json && header) { if (use_json && !*json_header_depth) {
vty_out(vty, vty_out(vty,
"{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64 "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
",\n \"routerId\": \"%s\",\n \"routes\": { ", ",\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->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
: bgp->name, : bgp->name,
table->version, inet_ntoa(bgp->router_id)); table->version, inet_ntoa(bgp->router_id));
if (rd) *json_header_depth = 2;
if (rd) {
vty_out(vty, " \"routeDistinguishers\" : {"); vty_out(vty, " \"routeDistinguishers\" : {");
++*json_header_depth;
}
json_paths = json_object_new_object(); 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_flap_neighbor
|| type == bgp_show_type_dampend_paths || type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor) { || type == bgp_show_type_damp_neighbor) {
if (!(ri->extra if (!(ri->extra && ri->extra->damp_info))
&& ri->extra->damp_info))
continue; continue;
} }
if (type == bgp_show_type_regexp) { 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.peer = ri->peer;
binfo.attr = &dummy_attr; binfo.attr = &dummy_attr;
ret = route_map_apply(rmap, &rn->p, ret = route_map_apply(rmap, &rn->p, RMAP_BGP,
RMAP_BGP, &binfo); &binfo);
if (ret == RMAP_DENYMATCH) if (ret == RMAP_DENYMATCH)
continue; continue;
} }
@ -7973,8 +7949,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
if (ri->peer == NULL if (ri->peer == NULL
|| ri->peer->su_remote == NULL || ri->peer->su_remote == NULL
|| !sockunion_same(ri->peer->su_remote, || !sockunion_same(ri->peer->su_remote, su))
su))
continue; continue;
} }
if (type == bgp_show_type_cidr_only) { 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; struct community *com = output_arg;
if (!ri->attr->community if (!ri->attr->community
|| !community_cmp(ri->attr->community, || !community_cmp(ri->attr->community, com))
com))
continue; continue;
} }
if (type == bgp_show_type_community_list) { if (type == bgp_show_type_community_list) {
struct community_list *list = output_arg; struct community_list *list = output_arg;
if (!community_list_match( if (!community_list_match(ri->attr->community,
ri->attr->community, list)) list))
continue; continue;
} }
if (type if (type == bgp_show_type_community_list_exact) {
== bgp_show_type_community_list_exact) {
struct community_list *list = output_arg; struct community_list *list = output_arg;
if (!community_list_exact_match( 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) { if (type == bgp_show_type_lcommunity_list) {
struct community_list *list = output_arg; struct community_list *list = output_arg;
if (!lcommunity_list_match( if (!lcommunity_list_match(ri->attr->lcommunity,
ri->attr->lcommunity, list)) list))
continue; continue;
} }
if (type == bgp_show_type_lcommunity_all) { if (type == bgp_show_type_lcommunity_all) {
@ -8069,8 +8042,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
if (type == bgp_show_type_dampend_paths if (type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor) || type == bgp_show_type_damp_neighbor)
vty_out(vty, BGP_SHOW_DAMP_HEADER); vty_out(vty, BGP_SHOW_DAMP_HEADER);
else if ( else if (type == bgp_show_type_flap_statistics
type == bgp_show_type_flap_statistics
|| type == bgp_show_type_flap_neighbor) || type == bgp_show_type_flap_neighbor)
vty_out(vty, BGP_SHOW_FLAP_HEADER); vty_out(vty, BGP_SHOW_FLAP_HEADER);
else else
@ -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 if (type == bgp_show_type_dampend_paths
|| type == bgp_show_type_damp_neighbor) || type == bgp_show_type_damp_neighbor)
damp_route_vty_out(vty, &rn->p, ri, display, damp_route_vty_out(vty, &rn->p, ri, display,
safi, use_json, safi, use_json, json_paths);
json_paths);
else if (type == bgp_show_type_flap_statistics else if (type == bgp_show_type_flap_statistics
|| type == bgp_show_type_flap_neighbor) || type == bgp_show_type_flap_neighbor)
flap_route_vty_out(vty, &rn->p, ri, display, flap_route_vty_out(vty, &rn->p, ri, display,
safi, use_json, safi, use_json, json_paths);
json_paths);
else else
route_vty_out(vty, &rn->p, ri, display, route_vty_out(vty, &rn->p, ri, display, safi,
safi, json_paths); json_paths);
display++; display++;
} }
@ -8106,8 +8076,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
p = &rn->p; p = &rn->p;
sprintf(buf2, "%s/%d", sprintf(buf2, "%s/%d",
inet_ntop(p->family, &p->u.prefix, inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
buf, BUFSIZ),
p->prefixlen); p->prefixlen);
if (first) if (first)
vty_out(vty, "\"%s\": ", buf2); 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 (use_json) {
if (json_paths) if (json_paths)
json_object_free(json_paths); json_object_free(json_paths);
if (is_last) if (rd) {
vty_out(vty, " } }\n"); vty_out(vty, " }%s ", (is_last ? "" : ","));
else }
vty_out(vty, " }, "); if (is_last) {
unsigned long i;
for (i = 0; i < *json_header_depth; ++i)
vty_out(vty, " } ");
}
} else { } else {
if (is_last) { if (is_last) {
/* No route is displayed */ /* 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; struct bgp_node *rn, *next;
unsigned long output_cum = 0; unsigned long output_cum = 0;
unsigned long total_cum = 0; unsigned long total_cum = 0;
unsigned long json_header_depth = 0;
bool show_msg; bool show_msg;
show_msg = (!use_json && type == bgp_show_type_normal); 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)); memcpy(&prd, &(rn->p), sizeof(struct prefix_rd));
prefix_rd2str(&prd, rd, sizeof(rd)); prefix_rd2str(&prd, rd, sizeof(rd));
bgp_show_table(vty, bgp, safi, rn->info, type, bgp_show_table(vty, bgp, safi, rn->info, type,
output_arg, use_json, output_arg, use_json, rd, next == NULL,
rd, next == NULL, &output_cum, &total_cum,
&output_cum, &total_cum); &json_header_depth);
if (next == NULL) if (next == NULL)
show_msg = false; 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", "\nDisplayed %ld routes and %ld total paths\n",
output_cum, total_cum); output_cum, total_cum);
} }
if (use_json)
vty_out(vty, " } }");
return CMD_SUCCESS; return CMD_SUCCESS;
} }
static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, 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) enum bgp_show_type type, void *output_arg, u_char use_json)
{ {
struct bgp_table *table; struct bgp_table *table;
unsigned long json_header_depth = 0;
if (bgp == NULL) { if (bgp == NULL) {
bgp = bgp_get_default(); 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; safi = SAFI_UNICAST;
return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json, 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, static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
@ -8543,7 +8516,8 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
if (display) if (display)
json_object_object_add(json, "paths", json_paths); json_object_object_add(json, "paths", json_paths);
vty_out(vty, "%s\n", json_object_to_json_string_ext( vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY)); json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
@ -8811,14 +8785,17 @@ DEFUN (show_ip_bgp,
if (argv_find(argv, argc, "community", &idx)) { if (argv_find(argv, argc, "community", &idx)) {
/* show a specific community */ /* show a specific community */
if (argv_find(argv, argc, "local-AS", &idx_community_type) 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, "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)) { || argv_find(argv, argc, "AA:NN", &idx_community_type)) {
if (argv_find(argv, argc, "exact-match", &idx)) if (argv_find(argv, argc, "exact-match", &idx))
exact_match = 1; 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); exact_match, afi, safi);
} }
} }
@ -9036,9 +9013,8 @@ DEFUN (show_ip_bgp_instance_all,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
const char *regstr, afi_t afi, afi_t afi, safi_t safi, enum bgp_show_type type)
safi_t safi, enum bgp_show_type type)
{ {
regex_t *regex; regex_t *regex;
int rc; int rc;
@ -9185,7 +9161,8 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
ip_str); ip_str);
vty_out(vty, "%s\n", vty_out(vty, "%s\n",
json_object_to_json_string_ext( 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); json_object_free(json_no);
} else } else
vty_out(vty, 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", json_object_string_add(json_no, "warning",
"No such neighbor"); "No such neighbor");
vty_out(vty, "%s\n", vty_out(vty, "%s\n",
json_object_to_json_string_ext(json_no, json_object_to_json_string_ext(
JSON_C_TO_STRING_PRETTY)); json_no, JSON_C_TO_STRING_PRETTY));
json_object_free(json_no); json_object_free(json_no);
} else } else
vty_out(vty, "No such neighbor\n"); 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]++; ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
/* announced address space */ /* announced address space */
if (space) if (space)
ts->total_space += pow(2.0, ts->total_space +=
space - rn->p.prefixlen); pow(2.0, space - rn->p.prefixlen);
} else if (prn->info) } else if (prn->info)
ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++; ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
@ -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]; pcounts.table = peer->bgp->rib[afi][safi];
/* in-place call via thread subsystem so as to record execution time /* 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 * stats for the thread-walk (i.e. ensure this can't be blamed on
* * on just vty_read()). * on just vty_read()).
* */ */
thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0); thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
if (use_json) { if (use_json) {
@ -9616,8 +9593,9 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
json, "recommended", json, "recommended",
"Please report this bug, with the above command output"); "Please report this bug, with the above command output");
} }
vty_out(vty, "%s\n", json_object_to_json_string_ext(json, vty_out(vty, "%s\n",
JSON_C_TO_STRING_PRETTY)); json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
@ -9851,7 +9829,8 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
"bgpOriginatingDefaultNetwork", "bgpOriginatingDefaultNetwork",
"0.0.0.0"); "0.0.0.0");
} else { } else {
vty_out(vty, "BGP table version is %" PRIu64 vty_out(vty,
"BGP table version is %" PRIu64
", local router ID is %s\n", ", local router ID is %s\n",
table->version, inet_ntoa(bgp->router_id)); table->version, inet_ntoa(bgp->router_id));
vty_out(vty, BGP_SHOW_SCODE_HEADER); vty_out(vty, BGP_SHOW_SCODE_HEADER);
@ -9963,19 +9942,14 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
} }
if (adj->attr) { if (adj->attr) {
bgp_attr_dup(&attr, bgp_attr_dup(&attr, adj->attr);
adj->attr);
ret = bgp_output_modifier( ret = bgp_output_modifier(
peer, &rn->p, peer, &rn->p, &attr,
&attr, afi, afi, safi, rmap_name);
safi,
rmap_name);
if (ret != RMAP_DENY) { if (ret != RMAP_DENY) {
route_vty_out_tmp( route_vty_out_tmp(
vty, vty, &rn->p,
&rn->p, &attr, safi,
&attr,
safi,
use_json, use_json,
json_ar); json_ar);
output_count++; output_count++;
@ -10000,8 +9974,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
output_count); output_count);
} }
if (use_json) { if (use_json) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(json, vty_out(vty, "%s\n",
JSON_C_TO_STRING_PRETTY)); json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); 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)); prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
if (p->u.prefix_evpn.route_type == 5) { if (p->u.prefix_evpn.route_type == 5) {
char local_buf[PREFIX_STRLEN]; char local_buf[PREFIX_STRLEN];
uint8_t family = IS_EVPN_PREFIX_IPADDR_V4((struct prefix_evpn *)p) uint8_t family = IS_EVPN_PREFIX_IPADDR_V4((
struct prefix_evpn *)p)
? AF_INET ? AF_INET
: AF_INET6; : AF_INET6;
inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr, local_buf, inet_ntop(family, &p->u.prefix_evpn.ip.ip.addr,
PREFIX_STRLEN); local_buf, PREFIX_STRLEN);
sprintf(buf, "%s/%u", local_buf,p->u.prefix_evpn.ip_prefix_length); sprintf(buf, "%s/%u", local_buf,
p->u.prefix_evpn.ip_prefix_length);
} else { } else {
prefix2str(p, buf, sizeof(buf)); prefix2str(p, buf, sizeof(buf));
} }
if (bgp_static->gatewayIp.family == AF_INET || if (bgp_static->gatewayIp.family == AF_INET
bgp_static->gatewayIp.family == AF_INET6) || bgp_static->gatewayIp.family == AF_INET6)
inet_ntop(bgp_static->gatewayIp.family, inet_ntop(bgp_static->gatewayIp.family,
&bgp_static->gatewayIp.u.prefix, buf2, &bgp_static->gatewayIp.u.prefix, buf2,
sizeof(buf2)); sizeof(buf2));

View File

@ -618,8 +618,7 @@ static route_map_result_t route_match_mac_address(void *rule,
p.prefixlen = ETH_ALEN * 8; p.prefixlen = ETH_ALEN * 8;
p.u.prefix_eth = prefix->u.prefix_evpn.mac; p.u.prefix_eth = prefix->u.prefix_evpn.mac;
return (access_list_apply(alist, &p) return (access_list_apply(alist, &p) == FILTER_DENY
== FILTER_DENY
? RMAP_NOMATCH ? RMAP_NOMATCH
: RMAP_MATCH); : 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, "evpn vni", route_match_vni, route_match_vni_compile,
route_match_vni_free}; 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 local-preference LOCAL-PREF' */
/* Match function return 1 if match is success else return zero. */ /* 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) static int bgp_route_map_process_update_cb(char *rmap_name)
@ -3132,6 +3194,36 @@ DEFUN (no_match_mac_address,
RMAP_EVENT_FILTER_DELETED); RMAP_EVENT_FILTER_DELETED);
} }
DEFUN (match_evpn_route_type,
match_evpn_route_type_cmd,
"match evpn route-type <macip | multicast | prefix>",
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 <macip | multicast | prefix>",
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, DEFUN (match_evpn_vni,
match_evpn_vni_cmd, match_evpn_vni_cmd,
"match evpn vni (1-16777215)", "match evpn vni (1-16777215)",
@ -3780,7 +3872,8 @@ DEFUN (set_community,
buffer_putstr(b, "no-export"); buffer_putstr(b, "no-export");
continue; continue;
} }
if (strncmp(argv[i]->arg, "graceful-shutdown", strlen(argv[i]->arg)) if (strncmp(argv[i]->arg, "graceful-shutdown",
strlen(argv[i]->arg))
== 0) { == 0) {
buffer_putstr(b, "graceful-shutdown"); buffer_putstr(b, "graceful-shutdown");
continue; 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_tag_cmd);
route_map_install_match(&route_match_mac_address_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_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_ip_nexthop_cmd);
route_map_install_set(&route_set_local_pref_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, &no_match_mac_address_cmd);
install_element(RMAP_NODE, &match_evpn_vni_cmd); install_element(RMAP_NODE, &match_evpn_vni_cmd);
install_element(RMAP_NODE, &no_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, &match_aspath_cmd);
install_element(RMAP_NODE, &no_match_aspath_cmd); install_element(RMAP_NODE, &no_match_aspath_cmd);

View File

@ -1540,7 +1540,8 @@ DEFUN (no_bgp_maxpaths,
} }
ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd, 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" "Forward packets over multiple paths\n"
"Number of paths\n") "Number of paths\n")
@ -3394,7 +3395,7 @@ DEFUN (no_neighbor_set_peer_group,
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }
ret = peer_group_unbind(bgp, peer, group); ret = peer_delete(peer);
return bgp_vty_return(vty, ret); return bgp_vty_return(vty, ret);
} }
@ -4363,22 +4364,22 @@ DEFUN (neighbor_attr_unchanged,
SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED); SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED);
SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED); SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED);
} else { } else {
if (!CHECK_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED) && if (!CHECK_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED)
peer_af_flag_check(peer, afi, safi, && peer_af_flag_check(peer, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED)) { PEER_FLAG_AS_PATH_UNCHANGED)) {
peer_af_flag_unset_vty(vty, peer_str, afi, safi, peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED); PEER_FLAG_AS_PATH_UNCHANGED);
} }
if (!CHECK_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED) && if (!CHECK_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED)
peer_af_flag_check(peer, afi, safi, && peer_af_flag_check(peer, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED)) { PEER_FLAG_NEXTHOP_UNCHANGED)) {
peer_af_flag_unset_vty(vty, peer_str, afi, safi, peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED); PEER_FLAG_NEXTHOP_UNCHANGED);
} }
if (!CHECK_FLAG(flags, PEER_FLAG_MED_UNCHANGED) && if (!CHECK_FLAG(flags, PEER_FLAG_MED_UNCHANGED)
peer_af_flag_check(peer, afi, safi, && peer_af_flag_check(peer, afi, safi,
PEER_FLAG_MED_UNCHANGED)) { PEER_FLAG_MED_UNCHANGED)) {
peer_af_flag_unset_vty(vty, peer_str, afi, safi, peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_MED_UNCHANGED); PEER_FLAG_MED_UNCHANGED);
@ -6125,8 +6126,8 @@ DEFUN_NOSH (address_family_ipv4_safi,
if (argc == 3) { if (argc == 3) {
VTY_DECLVAR_CONTEXT(bgp, bgp); VTY_DECLVAR_CONTEXT(bgp, bgp);
safi_t safi = bgp_vty_safi_from_str(argv[2]->text); safi_t safi = bgp_vty_safi_from_str(argv[2]->text);
if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT && if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_UNICAST && safi != SAFI_MULTICAST
&& safi != SAFI_EVPN) { && safi != SAFI_EVPN) {
vty_out(vty, vty_out(vty,
"Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n");
@ -6149,8 +6150,8 @@ DEFUN_NOSH (address_family_ipv6_safi,
if (argc == 3) { if (argc == 3) {
VTY_DECLVAR_CONTEXT(bgp, bgp); VTY_DECLVAR_CONTEXT(bgp, bgp);
safi_t safi = bgp_vty_safi_from_str(argv[2]->text); safi_t safi = bgp_vty_safi_from_str(argv[2]->text);
if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT && if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_UNICAST && safi != SAFI_MULTICAST
&& safi != SAFI_EVPN) { && safi != SAFI_EVPN) {
vty_out(vty, vty_out(vty,
"Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n"); "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n");
@ -6537,8 +6538,9 @@ DEFUN (show_bgp_vrfs,
if (uj) { if (uj) {
int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN) ? -1 : int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN)
(int64_t)bgp->vrf_id; ? -1
: (int64_t)bgp->vrf_id;
json_object_string_add(json_vrf, "type", type); json_object_string_add(json_vrf, "type", type);
json_object_int_add(json_vrf, "vrfId", vrf_id_ui); json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
json_object_string_add(json_vrf, "routerId", json_object_string_add(json_vrf, "routerId",
@ -6549,17 +6551,18 @@ DEFUN (show_bgp_vrfs,
peers_estb); peers_estb);
json_object_int_add(json_vrf, "l3vni", bgp->l3vni); json_object_int_add(json_vrf, "l3vni", bgp->l3vni);
json_object_string_add(json_vrf, "rmac", json_object_string_add(
prefix_mac2str(&bgp->rmac, buf, json_vrf, "rmac",
sizeof(buf))); prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
json_object_object_add(json_vrfs, name, json_vrf); json_object_object_add(json_vrfs, name, json_vrf);
} else } else
vty_out(vty, vty_out(vty,
"%4s %-5d %-16s %9u %10u %-37s %-10u %-15s\n", "%4s %-5d %-16s %9u %10u %-37s %-10u %-15s\n",
type, bgp->vrf_id == VRF_UNKNOWN ? type,
-1 : (int)bgp->vrf_id, bgp->vrf_id == VRF_UNKNOWN ? -1
inet_ntoa(bgp->router_id), : (int)bgp->vrf_id,
peers_cfg, peers_estb, name, bgp->l3vni, inet_ntoa(bgp->router_id), peers_cfg,
peers_estb, name, bgp->l3vni,
prefix_mac2str(&bgp->rmac, buf, sizeof(buf))); prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
} }
@ -6568,7 +6571,8 @@ DEFUN (show_bgp_vrfs,
json_object_int_add(json, "totalVrfs", count); json_object_int_add(json, "totalVrfs", count);
vty_out(vty, "%s\n", json_object_to_json_string_ext( vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY)); json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
@ -6718,16 +6722,19 @@ DEFUN (show_bgp_memory,
/* Other attributes */ /* Other attributes */
if ((count = community_count())) if ((count = community_count()))
vty_out(vty, "%ld BGP community entries, using %s of memory\n", vty_out(vty, "%ld BGP community entries, using %s of memory\n",
count, mtype_memstr(memstrbuf, sizeof(memstrbuf), count,
mtype_memstr(memstrbuf, sizeof(memstrbuf),
count * sizeof(struct community))); count * sizeof(struct community)));
if ((count = mtype_stats_alloc(MTYPE_ECOMMUNITY))) if ((count = mtype_stats_alloc(MTYPE_ECOMMUNITY)))
vty_out(vty, "%ld BGP community entries, using %s of memory\n", vty_out(vty, "%ld BGP community entries, using %s of memory\n",
count, mtype_memstr(memstrbuf, sizeof(memstrbuf), count,
mtype_memstr(memstrbuf, sizeof(memstrbuf),
count * sizeof(struct ecommunity))); count * sizeof(struct ecommunity)));
if ((count = mtype_stats_alloc(MTYPE_LCOMMUNITY))) if ((count = mtype_stats_alloc(MTYPE_LCOMMUNITY)))
vty_out(vty, vty_out(vty,
"%ld BGP large-community entries, using %s of memory\n", "%ld BGP large-community entries, using %s of memory\n",
count, mtype_memstr(memstrbuf, sizeof(memstrbuf), count,
mtype_memstr(memstrbuf, sizeof(memstrbuf),
count * sizeof(struct lcommunity))); count * sizeof(struct lcommunity)));
if ((count = mtype_stats_alloc(MTYPE_CLUSTER))) if ((count = mtype_stats_alloc(MTYPE_CLUSTER)))
@ -6757,7 +6764,8 @@ DEFUN (show_bgp_memory,
count * sizeof(struct hash_backet))); count * sizeof(struct hash_backet)));
if ((count = mtype_stats_alloc(MTYPE_BGP_REGEXP))) if ((count = mtype_stats_alloc(MTYPE_BGP_REGEXP)))
vty_out(vty, "%ld compiled regexes, using %s of memory\n", vty_out(vty, "%ld compiled regexes, using %s of memory\n",
count, mtype_memstr(memstrbuf, sizeof(memstrbuf), count,
mtype_memstr(memstrbuf, sizeof(memstrbuf),
count * sizeof(regex_t))); count * sizeof(regex_t)));
return CMD_SUCCESS; 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"); json_object_string_add(bestpath, "asPath", "confed");
if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) { if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
if (bgp_flag_check(bgp, if (bgp_flag_check(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET))
BGP_FLAG_MULTIPATH_RELAX_AS_SET)) json_object_string_add(bestpath, "multiPathRelax",
json_object_string_add(bestpath,
"multiPathRelax",
"as-set"); "as-set");
else else
json_object_string_add(bestpath, json_object_string_add(bestpath, "multiPathRelax",
"multiPathRelax",
"true"); "true");
} else } else
json_object_string_add(bestpath, json_object_string_add(bestpath, "multiPathRelax", "false");
"multiPathRelax",
"false");
if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)) if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID))
json_object_string_add(bestpath, "compareRouterId", "true"); json_object_string_add(bestpath, "compareRouterId", "true");
if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED) if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED)
|| bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) { || bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) {
if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED)) if (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED))
json_object_string_add(bestpath, "med", json_object_string_add(bestpath, "med", "confed");
"confed");
if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST)) if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST))
json_object_string_add(bestpath, "med", json_object_string_add(bestpath, "med",
"missing-as-worst"); "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]; char memstrbuf[MTYPE_MEMSTR_LEN];
int64_t vrf_id_ui; int64_t vrf_id_ui;
vrf_id_ui = vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN)
(bgp->vrf_id == VRF_UNKNOWN) ? -1 : ? -1
(int64_t)bgp->vrf_id; : (int64_t)bgp->vrf_id;
/* Usage summary and header */ /* Usage summary and header */
if (use_json) { 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, vty_out(vty,
"BGP router identifier %s, local AS number %u vrf-id %d", "BGP router identifier %s, local AS number %u vrf-id %d",
inet_ntoa(bgp->router_id), bgp->as, inet_ntoa(bgp->router_id), bgp->as,
bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id == VRF_UNKNOWN
(int)bgp->vrf_id); ? -1
: (int)bgp->vrf_id);
vty_out(vty, "\n"); vty_out(vty, "\n");
} }
@ -7015,7 +7018,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
json, "peerGroupCount", ents); json, "peerGroupCount", ents);
json_object_int_add( json_object_int_add(
json, "peerGroupMemory", json, "peerGroupMemory",
ents * sizeof(struct ents
* sizeof(struct
peer_group)); peer_group));
} }
@ -7039,9 +7043,10 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
vty_out(vty, vty_out(vty,
"RIB entries %ld, using %s of memory\n", "RIB entries %ld, using %s of memory\n",
ents, ents,
mtype_memstr(memstrbuf, mtype_memstr(
sizeof(memstrbuf), memstrbuf, sizeof(memstrbuf),
ents * sizeof(struct ents
* sizeof(struct
bgp_node))); bgp_node)));
/* Peer related usage */ /* Peer related usage */
@ -7059,7 +7064,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
mtype_memstr( mtype_memstr(
memstrbuf, memstrbuf,
sizeof(memstrbuf), sizeof(memstrbuf),
ents * sizeof(struct ents
* sizeof(struct
peer_group))); peer_group)));
if (CHECK_FLAG(bgp->af_flags[afi][safi], if (CHECK_FLAG(bgp->af_flags[afi][safi],
@ -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->status == Established)
if (peer->afc_recv[afi][pfx_rcd_safi]) if (peer->afc_recv[afi][pfx_rcd_safi])
vty_out(vty, " %12ld", vty_out(vty, " %12ld",
peer->pcount[afi][pfx_rcd_safi]); peer->pcount[afi]
[pfx_rcd_safi]);
else else
vty_out(vty, " NoNeg"); vty_out(vty, " NoNeg");
else { else {
@ -7192,7 +7199,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
bgp_show_bestpath_json(bgp, json); bgp_show_bestpath_json(bgp, json);
vty_out(vty, "%s\n", json_object_to_json_string_ext( vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY)); json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
@ -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); paf = peer_af_find(p, afi, safi);
if (paf && PAF_SUBGRP(paf)) { if (paf && PAF_SUBGRP(paf)) {
vty_out(vty, " Update group %" PRIu64 vty_out(vty,
", subgroup %" PRIu64 "\n", " Update group %" PRIu64 ", subgroup %" PRIu64
"\n",
PAF_UPDGRP(paf)->id, PAF_SUBGRP(paf)->id); PAF_UPDGRP(paf)->id, PAF_SUBGRP(paf)->id);
vty_out(vty, " Packet Queue length %d\n", vty_out(vty, " Packet Queue length %d\n",
bpacket_queue_virtual_length(paf)); 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; epoch_tbuf = time(NULL) - uptime;
#if CONFDATE > 20200101 #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 #endif
/* /*
* bgpTimerUp was miliseconds that was accurate * 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", "bgpTimerConfiguredKeepAliveIntervalMsecs",
p->keepalive * 1000); p->keepalive * 1000);
} else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) } 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, json_object_int_add(json_neigh,
"bgpTimerConfiguredHoldTimeMsecs", "bgpTimerConfiguredHoldTimeMsecs",
bgp->default_holdtime); 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", vty_out(vty, ", keepalive interval is %d seconds\n",
p->keepalive); p->keepalive);
} else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) } 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", vty_out(vty, " Configured hold time is %d",
bgp->default_holdtime); bgp->default_holdtime);
vty_out(vty, ", keepalive interval is %d seconds\n", vty_out(vty, ", keepalive interval is %d seconds\n",
@ -9629,7 +9639,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, u_char use_json,
} else } else
vty_out(vty, vty_out(vty,
" Reduce the no. of prefix from %s, will restart in %ld seconds\n", " Reduce the no. of prefix from %s, will restart in %ld seconds\n",
p->host, thread_timer_remain_second( p->host,
thread_timer_remain_second(
p->t_pmax_restart)); p->t_pmax_restart));
} else { } else {
if (use_json) if (use_json)
@ -9874,7 +9885,8 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
} }
if (use_json) { if (use_json) {
vty_out(vty, "%s\n", json_object_to_json_string_ext( vty_out(vty, "%s\n",
json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY)); json, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} else { } else {
@ -9910,7 +9922,8 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
json_object_int_add(json, "vrfId", json_object_int_add(json, "vrfId",
(bgp->vrf_id == VRF_UNKNOWN) (bgp->vrf_id == VRF_UNKNOWN)
? -1 : (int64_t) bgp->vrf_id); ? -1
: (int64_t)bgp->vrf_id);
json_object_string_add( json_object_string_add(
json, "vrfName", json, "vrfName",
(bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
@ -10645,7 +10658,8 @@ DEFUN (show_ip_bgp_peer_groups,
vrf = pg = NULL; vrf = pg = NULL;
int idx = 0; 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; pg = argv_find(argv, argc, "PGNAME", &idx) ? argv[idx]->arg : NULL;
return bgp_show_peer_group_vty(vty, vrf, pg); return bgp_show_peer_group_vty(vty, vrf, pg);

View File

@ -570,8 +570,8 @@ static int zebra_read_route(int command, struct zclient *zclient,
/* Now perform the add/update. */ /* Now perform the add/update. */
bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex, bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex,
nhtype, api.metric, api.type, nhtype, api.metric, api.type, api.instance,
api.instance, api.tag); api.tag);
} else { } else {
bgp_redistribute_delete(bgp, &api.prefix, api.type, bgp_redistribute_delete(bgp, &api.prefix, api.type,
api.instance); api.instance);
@ -1001,7 +1001,6 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr)); memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
api.vrf_id = bgp->vrf_id; api.vrf_id = bgp->vrf_id;
api.nh_vrf_id = bgp->vrf_id;
api.type = ZEBRA_ROUTE_BGP; api.type = ZEBRA_ROUTE_BGP;
api.safi = safi; api.safi = safi;
api.prefix = *p; 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 = &api.nexthops[valid_nh_count];
api_nh->gate.ipv4 = *nexthop; api_nh->gate.ipv4 = *nexthop;
api_nh->vrf_id = bgp->vrf_id;
/* EVPN type-2 routes are /* EVPN type-2 routes are
programmed as onlink on l3-vni SVI 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; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
} }
if (mpinfo->extra && if (mpinfo->extra
bgp_is_valid_label(&mpinfo->extra->label[0]) && bgp_is_valid_label(&mpinfo->extra->label[0])
&& !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) { && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
has_valid_label = 1; has_valid_label = 1;
label = label_pton(&mpinfo->extra->label[0]); 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 this is a evpn route we don't have to include the label */
if (has_valid_label && if (has_valid_label && !(CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)))
!(CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)))
SET_FLAG(api.message, ZAPI_MESSAGE_LABEL); SET_FLAG(api.message, ZAPI_MESSAGE_LABEL);
if (info->sub_type != BGP_ROUTE_AGGREGATE) 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)); sizeof(nh_buf));
label_buf[0] = '\0'; label_buf[0] = '\0';
if (has_valid_label && if (has_valid_label
!CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE))
sprintf(label_buf, "label %u", sprintf(label_buf, "label %u",
api_nh->labels[0]); api_nh->labels[0]);
zlog_debug(" nhop [%d]: %s %s", i + 1, nh_buf, 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)); memset(&api, 0, sizeof(api));
memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr)); memcpy(&api.rmac, &(info->attr->rmac), sizeof(struct ethaddr));
api.vrf_id = peer->bgp->vrf_id; api.vrf_id = peer->bgp->vrf_id;
api.nh_vrf_id = peer->bgp->vrf_id;
api.type = ZEBRA_ROUTE_BGP; api.type = ZEBRA_ROUTE_BGP;
api.safi = safi; api.safi = safi;
api.prefix = *p; 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. /* For default instance, register to learn about VNIs, if appropriate.
*/ */
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled())
&& is_evpn_enabled())
bgp_zebra_advertise_all_vni(bgp, 1); 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. /* For default instance, unregister learning about VNIs, if appropriate.
*/ */
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && is_evpn_enabled())
&& is_evpn_enabled())
bgp_zebra_advertise_all_vni(bgp, 0); bgp_zebra_advertise_all_vni(bgp, 0);
/* Deregister for router-id, interfaces, redistributed routes. */ /* 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)) if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s", zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s",
(cmd == ZEBRA_L3VNI_ADD) ? "add" : "del", (cmd == ZEBRA_L3VNI_ADD) ? "add" : "del",
vrf_id_to_name(vrf_id), vrf_id_to_name(vrf_id), l3vni,
l3vni,
prefix_mac2str(&rmac, buf, sizeof(buf))); prefix_mac2str(&rmac, buf, sizeof(buf)));
if (cmd == ZEBRA_L3VNI_ADD) if (cmd == ZEBRA_L3VNI_ADD)
@ -1784,8 +1778,8 @@ static int bgp_zebra_process_local_vni(int command, struct zclient *zclient,
if (BGP_DEBUG(zebra, ZEBRA)) if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Rx VNI %s VRF %s VNI %u tenant-vrf %s", zlog_debug("Rx VNI %s VRF %s VNI %u tenant-vrf %s",
(command == ZEBRA_VNI_ADD) ? "add" : "del", (command == ZEBRA_VNI_ADD) ? "add" : "del",
vrf_id_to_name(vrf_id), vrf_id_to_name(vrf_id), vni,
vni, vrf_id_to_name(tenant_vrf_id)); vrf_id_to_name(tenant_vrf_id));
if (command == ZEBRA_VNI_ADD) if (command == ZEBRA_VNI_ADD)
return bgp_evpn_local_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); return bgp_evpn_local_macip_del(bgp, vni, &mac, &ip);
} }
static void bgp_zebra_process_local_ip_prefix(int cmd, static void bgp_zebra_process_local_ip_prefix(int cmd, struct zclient *zclient,
struct zclient *zclient,
zebra_size_t length, zebra_size_t length,
vrf_id_t vrf_id) 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 (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) {
if (p.family == AF_INET) if (p.family == AF_INET)
return bgp_evpn_advertise_type5_route(bgp_vrf, &p, return bgp_evpn_advertise_type5_route(
NULL, bgp_vrf, &p, NULL, AFI_IP, SAFI_UNICAST);
AFI_IP,
SAFI_UNICAST);
else else
return bgp_evpn_advertise_type5_route(bgp_vrf, &p, return bgp_evpn_advertise_type5_route(
NULL, bgp_vrf, &p, NULL, AFI_IP6, SAFI_UNICAST);
AFI_IP6,
SAFI_UNICAST);
} else { } else {
if (p.family == AF_INET) if (p.family == AF_INET)
return bgp_evpn_withdraw_type5_route(bgp_vrf, &p, return bgp_evpn_withdraw_type5_route(
AFI_IP, bgp_vrf, &p, AFI_IP, SAFI_UNICAST);
SAFI_UNICAST);
else else
return bgp_evpn_withdraw_type5_route(bgp_vrf, &p, return bgp_evpn_withdraw_type5_route(
AFI_IP6, bgp_vrf, &p, AFI_IP6, SAFI_UNICAST);
SAFI_UNICAST);
} }
} }

View File

@ -1403,16 +1403,12 @@ static void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi,
if (rn->info != NULL) { if (rn->info != NULL) {
/* Special handling for 2-level routing /* Special handling for 2-level routing
* tables. */ * tables. */
if (safi == SAFI_MPLS_VPN if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_ENCAP
|| safi == SAFI_EVPN) { || safi == SAFI_EVPN) {
for (nrn = bgp_table_top(( for (nrn = bgp_table_top(
struct bgp_table (struct bgp_table *)(rn->info));
*)(rn->info)); nrn; nrn = bgp_route_next(nrn))
nrn; bgp_process(bgp, nrn, afi, safi);
nrn = bgp_route_next(nrn))
bgp_process(bgp, nrn,
afi, safi);
} else } else
bgp_process(bgp, rn, afi, safi); 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; peer->afc[afi][safi] = 1;
if (peer->group) if (peer->group)
peer_group2peer_config_copy_af(peer->group, peer, peer_group2peer_config_copy_af(peer->group, peer, afi, safi);
afi, safi);
if (!active && peer_active(peer)) { if (!active && peer_active(peer)) {
bgp_timer_set(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); ret |= peer_activate_af(peer, afi, safi);
} }
/* If this is the first peer to be activated for this afi/labeled-unicast /* If this is the first peer to be activated for this
* recalc bestpaths to trigger label allocation */ * afi/labeled-unicast recalc bestpaths to trigger label allocation */
if (safi == SAFI_LABELED_UNICAST && !bgp->allocate_mpls_labels[afi][SAFI_UNICAST]) { if (safi == SAFI_LABELED_UNICAST
&& !bgp->allocate_mpls_labels[afi][SAFI_UNICAST]) {
if (BGP_DEBUG(zebra, ZEBRA)) 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->allocate_mpls_labels[afi][SAFI_UNICAST] = 1;
bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST); 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; bgp = peer->bgp;
/* If this is the last peer to be deactivated for this afi/labeled-unicast /* If this is the last peer to be deactivated for this
* recalc bestpaths to trigger label deallocation */ * afi/labeled-unicast recalc bestpaths to trigger label deallocation */
if (safi == SAFI_LABELED_UNICAST && if (safi == SAFI_LABELED_UNICAST
bgp->allocate_mpls_labels[afi][SAFI_UNICAST] && && bgp->allocate_mpls_labels[afi][SAFI_UNICAST]
!bgp_afi_safi_peer_exists(bgp, afi, safi)) { && !bgp_afi_safi_peer_exists(bgp, afi, safi)) {
if (BGP_DEBUG(zebra, ZEBRA)) 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->allocate_mpls_labels[afi][SAFI_UNICAST] = 0;
bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST); bgp_recalculate_afi_safi_bestpaths(bgp, afi, SAFI_UNICAST);
@ -2856,8 +2854,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get()); XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get());
bgp->peer = list_new(); bgp->peer = list_new();
bgp->peer->cmp = (int (*)(void *, void *))peer_cmp; bgp->peer->cmp = (int (*)(void *, void *))peer_cmp;
bgp->peerhash = hash_create(peer_hash_key_make, bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same,
peer_hash_same,
"BGP Peer Hash"); "BGP Peer Hash");
bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE; bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE;
@ -3988,7 +3985,8 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi,
} }
/* Track if addpath TX is in use */ /* Track if addpath TX is in use */
if (flag & (PEER_FLAG_ADDPATH_TX_ALL_PATHS if (flag
& (PEER_FLAG_ADDPATH_TX_ALL_PATHS
| PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) { | PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS)) {
bgp = peer->bgp; bgp = peer->bgp;
addpath_tx_used = 0; addpath_tx_used = 0;
@ -6802,7 +6800,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
} else { } else {
if (!peer_af_flag_check(peer, afi, safi, if (!peer_af_flag_check(peer, afi, safi,
PEER_FLAG_SEND_COMMUNITY) PEER_FLAG_SEND_COMMUNITY)
&& (!g_peer || peer_af_flag_check(g_peer, afi, safi, && (!g_peer
|| peer_af_flag_check(g_peer, afi, safi,
PEER_FLAG_SEND_COMMUNITY)) PEER_FLAG_SEND_COMMUNITY))
&& !peer_af_flag_check(peer, afi, safi, && !peer_af_flag_check(peer, afi, safi,
PEER_FLAG_SEND_EXT_COMMUNITY) PEER_FLAG_SEND_EXT_COMMUNITY)
@ -6811,7 +6810,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
PEER_FLAG_SEND_EXT_COMMUNITY)) PEER_FLAG_SEND_EXT_COMMUNITY))
&& !peer_af_flag_check(peer, afi, safi, && !peer_af_flag_check(peer, afi, safi,
PEER_FLAG_SEND_LARGE_COMMUNITY) PEER_FLAG_SEND_LARGE_COMMUNITY)
&& (!g_peer || peer_af_flag_check( && (!g_peer
|| peer_af_flag_check(
g_peer, afi, safi, g_peer, afi, safi,
PEER_FLAG_SEND_LARGE_COMMUNITY))) { PEER_FLAG_SEND_LARGE_COMMUNITY))) {
vty_out(vty, " no neighbor %s send-community all\n", vty_out(vty, " no neighbor %s send-community all\n",
@ -6841,7 +6841,8 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
if (!peer_af_flag_check(peer, afi, safi, if (!peer_af_flag_check(peer, afi, safi,
PEER_FLAG_SEND_COMMUNITY) PEER_FLAG_SEND_COMMUNITY)
&& (!g_peer || peer_af_flag_check( && (!g_peer
|| peer_af_flag_check(
g_peer, afi, safi, g_peer, afi, safi,
PEER_FLAG_SEND_COMMUNITY))) { PEER_FLAG_SEND_COMMUNITY))) {
vty_out(vty, vty_out(vty,
@ -6954,16 +6955,16 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
bgp_config_write_filter(vty, peer, afi, safi); bgp_config_write_filter(vty, peer, afi, safi);
/* atribute-unchanged. */ /* atribute-unchanged. */
if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_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_NEXTHOP_UNCHANGED)
peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) { || peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) {
if (!peer_group_active(peer) || if (!peer_group_active(peer)
peergroup_af_flag_check(peer, afi, safi, || peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED) || PEER_FLAG_AS_PATH_UNCHANGED)
peergroup_af_flag_check(peer, afi, safi, || peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED) || PEER_FLAG_NEXTHOP_UNCHANGED)
peergroup_af_flag_check(peer, afi, safi, || peergroup_af_flag_check(peer, afi, safi,
PEER_FLAG_MED_UNCHANGED)) { PEER_FLAG_MED_UNCHANGED)) {
vty_out(vty, vty_out(vty,

View File

@ -262,9 +262,10 @@ struct bgp {
/* $FRR indent$ */ /* $FRR indent$ */
/* clang-format off */ /* clang-format off */
#define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */ #define BGP_MAXMED_ADMIN_UNCONFIGURED 0 /* Off by default */
u_int32_t u_int32_t maxmed_admin_value; /* Max-med value when administrative in on
maxmed_admin_value; /* Max-med value when administrative in on
*/ */
/* $FRR indent$ */
/* clang-format off */
#define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */ #define BGP_MAXMED_VALUE_DEFAULT 4294967294 /* Maximum by default */
u_char maxmed_active; /* 1/0 if max-med is active or not */ u_char maxmed_active; /* 1/0 if max-med is active or not */
@ -451,6 +452,9 @@ struct bgp {
/* list of corresponding l2vnis (struct bgpevpn) */ /* list of corresponding l2vnis (struct bgpevpn) */
struct list *l2vnis; 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 QOBJ_FIELDS
}; };
DECLARE_QOBJ_TYPE(bgp) DECLARE_QOBJ_TYPE(bgp)
@ -870,20 +874,28 @@ struct peer {
struct work_queue *clear_node_queue; struct work_queue *clear_node_queue;
#define PEER_TOTAL_RX(peer) \ #define PEER_TOTAL_RX(peer) \
atomic_load_explicit(&peer->open_in, memory_order_relaxed) + \ atomic_load_explicit(&peer->open_in, memory_order_relaxed) \
atomic_load_explicit(&peer->update_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->notify_in, memory_order_relaxed) \
atomic_load_explicit(&peer->refresh_in, memory_order_relaxed) + \ + atomic_load_explicit(&peer->refresh_in, \
atomic_load_explicit(&peer->keepalive_in, memory_order_relaxed) + \ memory_order_relaxed) \
atomic_load_explicit(&peer->dynamic_cap_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) \ #define PEER_TOTAL_TX(peer) \
atomic_load_explicit(&peer->open_out, memory_order_relaxed) + \ atomic_load_explicit(&peer->open_out, memory_order_relaxed) \
atomic_load_explicit(&peer->update_out, memory_order_relaxed) + \ + atomic_load_explicit(&peer->update_out, \
atomic_load_explicit(&peer->notify_out, memory_order_relaxed) + \ memory_order_relaxed) \
atomic_load_explicit(&peer->refresh_out, memory_order_relaxed) + \ + atomic_load_explicit(&peer->notify_out, \
atomic_load_explicit(&peer->keepalive_out, memory_order_relaxed) + \ memory_order_relaxed) \
atomic_load_explicit(&peer->dynamic_cap_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 */ /* Statistics field */
_Atomic uint32_t open_in; /* Open message input count */ _Atomic uint32_t open_in; /* Open message input count */
@ -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, extern int bgp_map_afi_safi_iana2int(iana_afi_t pkt_afi, iana_safi_t pkt_safi,
afi_t *afi, safi_t *safi); afi_t *afi, safi_t *safi);
extern int bgp_map_afi_safi_int2iana(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_create(struct peer *, afi_t, safi_t);
extern struct peer_af *peer_af_find(struct peer *, afi_t, safi_t); extern struct peer_af *peer_af_find(struct peer *, afi_t, safi_t);

View File

@ -264,7 +264,8 @@ int bgp_rfapi_is_vnc_configured(struct bgp *bgp)
{ \ { \
switch (bgp_rfapi_is_vnc_configured(bgp)) { \ switch (bgp_rfapi_is_vnc_configured(bgp)) { \
case EPERM: \ case EPERM: \
vty_out(vty, "VNC operations only permitted on default BGP instance.\n"); \ vty_out(vty, \
"VNC operations only permitted on default BGP instance.\n"); \
return CMD_WARNING_CONFIG_FAILED; \ return CMD_WARNING_CONFIG_FAILED; \
break; \ break; \
case ENXIO: \ case ENXIO: \
@ -509,8 +510,7 @@ DEFUN (vnc_defaults_responselifetime,
} else { } else {
rspint = strtoul(argv[1]->arg, NULL, 10); rspint = strtoul(argv[1]->arg, NULL, 10);
if (rspint > INT32_MAX) if (rspint > INT32_MAX)
rspint = rspint = INT32_MAX; /* is really an int, not an unsigned
INT32_MAX; /* is really an int, not an unsigned
int */ int */
} }
@ -554,7 +554,7 @@ rfapi_group_new(struct bgp *bgp, rfapi_group_cfg_type_t type, const char *name)
/* add to tail of list */ /* add to tail of list */
listnode_add(bgp->rfapi_cfg->nve_groups_sequential, rfg); 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); QOBJ_REG(rfg, rfapi_nve_group_cfg);
return rfg; return rfg;
@ -1636,8 +1636,8 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
idx += 2; /* skip afi and keyword */ idx += 2; /* skip afi and keyword */
if (is_bgp) { if (is_bgp) {
if (idx == argc || if (idx == argc
strmatch(argv[idx]->arg, || strmatch(argv[idx]->arg,
rfg->plist_export_bgp_name[afi])) { rfg->plist_export_bgp_name[afi])) {
if (rfg->plist_export_bgp_name[afi]) if (rfg->plist_export_bgp_name[afi])
free(rfg->plist_export_bgp_name[afi]); free(rfg->plist_export_bgp_name[afi]);
@ -1647,8 +1647,8 @@ DEFUN (vnc_nve_group_export_no_prefixlist,
vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi); vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi);
} }
} else { } else {
if (idx == argc || if (idx == argc
strmatch(argv[idx]->arg, || strmatch(argv[idx]->arg,
rfg->plist_export_zebra_name[afi])) { rfg->plist_export_zebra_name[afi])) {
if (rfg->plist_export_zebra_name[afi]) if (rfg->plist_export_zebra_name[afi])
free(rfg->plist_export_zebra_name[afi]); free(rfg->plist_export_zebra_name[afi]);
@ -1768,8 +1768,9 @@ DEFUN (vnc_nve_group_export_no_routemap,
} }
if (is_bgp) { if (is_bgp) {
if (idx == argc || if (idx == argc
strmatch(argv[idx]->arg, rfg->routemap_export_bgp_name)) { || strmatch(argv[idx]->arg,
rfg->routemap_export_bgp_name)) {
if (rfg->routemap_export_bgp_name) if (rfg->routemap_export_bgp_name)
free(rfg->routemap_export_bgp_name); free(rfg->routemap_export_bgp_name);
rfg->routemap_export_bgp_name = NULL; rfg->routemap_export_bgp_name = NULL;
@ -1779,8 +1780,8 @@ DEFUN (vnc_nve_group_export_no_routemap,
vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6);
} }
} else { } else {
if (idx == argc || if (idx == argc
strmatch(argv[idx]->arg, || strmatch(argv[idx]->arg,
rfg->routemap_export_zebra_name)) { rfg->routemap_export_zebra_name)) {
if (rfg->routemap_export_zebra_name) if (rfg->routemap_export_zebra_name)
free(rfg->routemap_export_zebra_name); free(rfg->routemap_export_zebra_name);
@ -2466,8 +2467,7 @@ bgp_rfapi_delete_named_nve_group(struct vty *vty, /* NULL = no output */
if (rfg->rfd) if (rfg->rfd)
clear_vnc_vrf_closer(rfg); clear_vnc_vrf_closer(rfg);
bgp_rfapi_delete_nve_group(vty, bgp, 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, for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential,
node, nnode, rfg)) { node, nnode, rfg)) {
if (rfg->rfd) if (rfg->rfd)
@ -2977,6 +2977,11 @@ DEFUN_NOSH (vnc_vrf_policy,
struct rfapi_nve_group_cfg *rfg; struct rfapi_nve_group_cfg *rfg;
VTY_DECLVAR_CONTEXT(bgp, bgp); 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 */ /* Search for name */
rfg = bgp_rfapi_cfg_match_byname(bgp, argv[1]->arg, rfg = bgp_rfapi_cfg_match_byname(bgp, argv[1]->arg,
RFAPI_GROUP_CFG_VRF); RFAPI_GROUP_CFG_VRF);
@ -3007,6 +3012,10 @@ DEFUN (vnc_no_vrf_policy,
{ {
VTY_DECLVAR_CONTEXT(bgp, bgp); 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, return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[2]->arg,
RFAPI_GROUP_CFG_VRF); RFAPI_GROUP_CFG_VRF);
} }
@ -3063,7 +3072,7 @@ DEFUN (vnc_vrf_policy_no_label,
vnc_redistribute_prechange(bgp); vnc_redistribute_prechange(bgp);
} }
rfg->label = MPLS_LABEL_ILLEGAL; rfg->label = MPLS_LABEL_NONE;
if (bgp->rfapi_cfg->rfg_redist == rfg) { if (bgp->rfapi_cfg->rfg_redist == rfg) {
vnc_redistribute_postchange(bgp); 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]) { if (rfg->plist_export_bgp_name[afi]) {
vty_out(vty, vty_out(vty,
" export %s%s prefix-list %s\n", " export %s%s prefix-list %s\n",
(rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "bgp "), (rfg->type == RFAPI_GROUP_CFG_VRF
? ""
: "bgp "),
afistr, afistr,
rfg->plist_export_bgp_name rfg->plist_export_bgp_name
[afi]); [afi]);
@ -3958,7 +3969,9 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
if (rfg->plist_export_zebra_name[afi]) { if (rfg->plist_export_zebra_name[afi]) {
vty_out(vty, vty_out(vty,
" export %s%s prefix-list %s\n", " export %s%s prefix-list %s\n",
(rfg->type == RFAPI_GROUP_CFG_VRF ? "" : "zebra "), (rfg->type == RFAPI_GROUP_CFG_VRF
? ""
: "zebra "),
afistr, afistr,
rfg->plist_export_zebra_name rfg->plist_export_zebra_name
[afi]); [afi]);
@ -3993,12 +4006,16 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
if (rfg->routemap_export_bgp_name) { if (rfg->routemap_export_bgp_name) {
vty_out(vty, " export %sroute-map %s\n", 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); rfg->routemap_export_bgp_name);
} }
if (rfg->routemap_export_zebra_name) { if (rfg->routemap_export_zebra_name) {
vty_out(vty, " export %sroute-map %s\n", 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); rfg->routemap_export_zebra_name);
} }
if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) { 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 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->default_rt_import_list || hc->default_rt_export_list
|| hc->nve_groups_sequential->count) { || 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, prefix2str(&rfg->vn_prefix, buf,
sizeof(buf)); sizeof(buf));
vty_out(vty, " prefix %s %s\n", vty_out(vty, " prefix %s %s\n", "vn",
"vn", buf); buf);
} }
if (rfg->un_prefix.family && rfg->un_node) { 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, prefix2str(&rfg->un_prefix, buf,
sizeof(buf)); sizeof(buf));
vty_out(vty, " prefix %s %s\n", vty_out(vty, " prefix %s %s\n", "un",
"un", buf); buf);
} }
@ -4215,10 +4233,9 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
value); value);
} else } else
vty_out(vty, vty_out(vty, " rd %s\n",
" rd %s\n", prefix_rd2str(
prefix_rd2str(&rfg->rd, &rfg->rd, buf,
buf,
sizeof(buf))); sizeof(buf)));
} }
if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) { if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) {

View File

@ -396,7 +396,6 @@ static void vnc_zebra_route_msg(struct prefix *p, unsigned int nhp_count,
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_VNC; api.type = ZEBRA_ROUTE_VNC;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.prefix = *p; 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++) { for (i = 0; i < api.nexthop_num; i++) {
api_nh = &api.nexthops[i]; api_nh = &api.nexthops[i];
api_nh->vrf_id = VRF_DEFAULT;
switch (p->family) { switch (p->family) {
case AF_INET: case AF_INET:
memcpy(&api_nh->gate.ipv4, nhp_ary4[i], memcpy(&api_nh->gate.ipv4, nhp_ary4[i],

View File

@ -13,7 +13,7 @@ Package: frr
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends} Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends}
Pre-Depends: adduser Pre-Depends: adduser
Conflicts: zebra, zebra-pj Conflicts: zebra, zebra-pj, quagga
Replaces: zebra, zebra-pj Replaces: zebra, zebra-pj
Suggests: snmpd Suggests: snmpd
Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga

View File

@ -13,7 +13,7 @@ Package: frr
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends} Depends: ${shlibs:Depends}, logrotate (>= 3.2-11), ${misc:Depends}
Pre-Depends: adduser Pre-Depends: adduser
Conflicts: zebra, zebra-pj Conflicts: zebra, zebra-pj, quagga
Replaces: zebra, zebra-pj Replaces: zebra, zebra-pj
Suggests: snmpd Suggests: snmpd
Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga Description: BGP/OSPF/RIP/RIPng/ISIS/PIM/LDP routing daemon forked from Quagga

View File

@ -20,7 +20,7 @@ any packages**
sudo addgroup --system --gid 92 frr sudo addgroup --system --gid 92 frr
sudo addgroup --system --gid 85 frrvty 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 --gecos "FRR suite" --shell /bin/false frr
sudo usermod -a -G frrvty frr sudo usermod -a -G frrvty frr
@ -34,7 +34,7 @@ an example.)
./bootstrap.sh ./bootstrap.sh
./configure \ ./configure \
--enable-exampledir=/usr/share/doc/frr/examples/ \ --enable-exampledir=/usr/share/doc/frr/examples/ \
--localstatedir=/var/run/frr \ --localstatedir=/var/opt/frr \
--sbindir=/usr/lib/frr \ --sbindir=/usr/lib/frr \
--sysconfdir=/etc/frr \ --sysconfdir=/etc/frr \
--enable-vtysh \ --enable-vtysh \
@ -61,6 +61,7 @@ an example.)
### Create empty FRR configuration files ### 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/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 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/zebra.conf
sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf
@ -91,20 +92,6 @@ other settings)
### Troubleshooting ### 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** **Shared library error**
If you try and start any of the frrouting daemons you may see the below error If you try and start any of the frrouting daemons you may see the below error

View File

@ -366,7 +366,6 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors)
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_EIGRP; api.type = ZEBRA_ROUTE_EIGRP;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
memcpy(&api.prefix, p, sizeof(*p)); 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) if (count >= MULTIPATH_NUM)
break; break;
api_nh = &api.nexthops[count]; api_nh = &api.nexthops[count];
api_nh->vrf_id = VRF_DEFAULT;
if (te->adv_router->src.s_addr) { if (te->adv_router->src.s_addr) {
api_nh->gate.ipv4 = te->adv_router->src; api_nh->gate.ipv4 = te->adv_router->src;
api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
@ -408,7 +408,6 @@ void eigrp_zebra_route_delete(struct prefix *p)
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_EIGRP; api.type = ZEBRA_ROUTE_EIGRP;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
memcpy(&api.prefix, p, sizeof(*p)); memcpy(&api.prefix, p, sizeof(*p));

View File

@ -6,7 +6,7 @@ import sys, re, subprocess, os
# find all DEFUNs # find all DEFUNs
defun_re = re.compile( 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) re.M | re.S)
define_re = re.compile( define_re = re.compile(
r'((^#\s*define[^\n]+[^\\]\n)+)', r'((^#\s*define[^\n]+[^\\]\n)+)',

View File

@ -293,6 +293,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
if (ip) { if (ip) {
listnode_delete(circuit->ip_addrs, ip); listnode_delete(circuit->ip_addrs, ip);
prefix_ipv4_free(ip);
if (circuit->area) if (circuit->area)
lsp_regenerate_schedule(circuit->area, lsp_regenerate_schedule(circuit->area,
circuit->is_type, 0); circuit->is_type, 0);
@ -328,6 +329,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
} }
if (ip6) { if (ip6) {
listnode_delete(circuit->ipv6_link, ip6); listnode_delete(circuit->ipv6_link, ip6);
prefix_ipv6_free(ip6);
found = 1; found = 1;
} }
} else { } else {
@ -339,6 +341,7 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
} }
if (ip6) { if (ip6) {
listnode_delete(circuit->ipv6_non_link, ip6); listnode_delete(circuit->ipv6_non_link, ip6);
prefix_ipv6_free(ip6);
found = 1; found = 1;
} }
} }
@ -1165,7 +1168,6 @@ void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
struct isis_area *area = circuit->area; struct isis_area *area = circuit->area;
bool change = circuit->ip_router != ip_router bool change = circuit->ip_router != ip_router
|| circuit->ipv6_router != ipv6_router; || circuit->ipv6_router != ipv6_router;
bool was_enabled = !!circuit->area;
area->ip_circuits += ip_router - circuit->ip_router; area->ip_circuits += ip_router - circuit->ip_router;
area->ipv6_circuits += ipv6_router - circuit->ipv6_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) if (!ip_router && !ipv6_router)
isis_csm_state_change(ISIS_DISABLE, circuit, area); isis_csm_state_change(ISIS_DISABLE, circuit, area);
else if (!was_enabled)
isis_csm_state_change(ISIS_ENABLE, circuit, area);
else else
lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); lsp_regenerate_schedule(circuit->area, circuit->is_type, 0);
} }

View File

@ -261,7 +261,6 @@ static void isis_zebra_route_add_route(struct prefix *prefix,
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_ISIS; api.type = ZEBRA_ROUTE_ISIS;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.prefix = *prefix; api.prefix = *prefix;
@ -281,6 +280,7 @@ static void isis_zebra_route_add_route(struct prefix *prefix,
if (count >= MULTIPATH_NUM) if (count >= MULTIPATH_NUM)
break; break;
api_nh = &api.nexthops[count]; api_nh = &api.nexthops[count];
api_nh->vrf_id = VRF_DEFAULT;
/* FIXME: can it be ? */ /* FIXME: can it be ? */
if (nexthop->ip.s_addr != INADDR_ANY) { if (nexthop->ip.s_addr != INADDR_ANY) {
api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; 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 = &api.nexthops[count];
api_nh->vrf_id = VRF_DEFAULT;
api_nh->gate.ipv6 = nexthop6->ip6; api_nh->gate.ipv6 = nexthop6->ip6;
api_nh->ifindex = nexthop6->ifindex; api_nh->ifindex = nexthop6->ifindex;
api_nh->type = NEXTHOP_TYPE_IPV6_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)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_ISIS; api.type = ZEBRA_ROUTE_ISIS;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.prefix = *prefix; api.prefix = *prefix;

View File

@ -320,9 +320,9 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type)
/* do not accept invalid labels */ /* do not accept invalid labels */
if (label > MPLS_LABEL_MAX || if (label > MPLS_LABEL_MAX ||
(label <= MPLS_LABEL_RESERVED_MAX && (label <= MPLS_LABEL_RESERVED_MAX &&
label != MPLS_LABEL_IPV4NULL && label != MPLS_LABEL_IPV4_EXPLICIT_NULL &&
label != MPLS_LABEL_IPV6NULL && label != MPLS_LABEL_IPV6_EXPLICIT_NULL &&
label != MPLS_LABEL_IMPLNULL)) { label != MPLS_LABEL_IMPLICIT_NULL)) {
session_shutdown(nbr, S_BAD_TLV_VAL, session_shutdown(nbr, S_BAD_TLV_VAL,
msg.id, msg.type); msg.id, msg.type);
goto err; goto err;
@ -396,7 +396,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type)
case MAP_TYPE_PREFIX: case MAP_TYPE_PREFIX:
switch (me->map.fec.prefix.af) { switch (me->map.fec.prefix.af) {
case AF_INET: case AF_INET:
if (label == MPLS_LABEL_IPV6NULL) { if (label == MPLS_LABEL_IPV6_EXPLICIT_NULL) {
session_shutdown(nbr, S_BAD_TLV_VAL, session_shutdown(nbr, S_BAD_TLV_VAL,
msg.id, msg.type); msg.id, msg.type);
goto err; goto err;
@ -405,7 +405,7 @@ recv_labelmessage(struct nbr *nbr, char *buf, uint16_t len, uint16_t type)
goto next; goto next;
break; break;
case AF_INET6: case AF_INET6:
if (label == MPLS_LABEL_IPV4NULL) { if (label == MPLS_LABEL_IPV4_EXPLICIT_NULL) {
session_shutdown(nbr, S_BAD_TLV_VAL, session_shutdown(nbr, S_BAD_TLV_VAL,
msg.id, msg.type); msg.id, msg.type);
goto err; goto err;

View File

@ -702,20 +702,20 @@ lde_update_label(struct fec_node *fn)
switch (fn->fec.type) { switch (fn->fec.type) {
case FEC_TYPE_IPV4: case FEC_TYPE_IPV4:
if (!(ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL)) 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, if (lde_acl_check(ldeconf->ipv4.acl_label_expnull_for,
AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix, AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT) fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
return (MPLS_LABEL_IMPLNULL); return (MPLS_LABEL_IMPLICIT_NULL);
return (MPLS_LABEL_IPV4NULL); return MPLS_LABEL_IPV4_EXPLICIT_NULL;
case FEC_TYPE_IPV6: case FEC_TYPE_IPV6:
if (!(ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL)) 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, if (lde_acl_check(ldeconf->ipv6.acl_label_expnull_for,
AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix, AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT) fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
return (MPLS_LABEL_IMPLNULL); return (MPLS_LABEL_IMPLICIT_NULL);
return (MPLS_LABEL_IPV6NULL); return MPLS_LABEL_IPV6_EXPLICIT_NULL;
default: default:
fatalx("lde_update_label: unexpected fec type"); fatalx("lde_update_label: unexpected fec type");
break; break;
@ -1522,11 +1522,15 @@ lde_change_egress_label(int af)
/* explicitly withdraw all null labels */ /* explicitly withdraw all null labels */
RB_FOREACH(ln, nbr_tree, &lde_nbrs) { 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) 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) 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 */ /* update label of connected routes */

View File

@ -115,11 +115,11 @@ log_label(uint32_t label)
case NO_LABEL: case NO_LABEL:
snprintf(buf, TF_LEN, "-"); snprintf(buf, TF_LEN, "-");
break; break;
case MPLS_LABEL_IMPLNULL: case MPLS_LABEL_IMPLICIT_NULL:
snprintf(buf, TF_LEN, "imp-null"); snprintf(buf, TF_LEN, "imp-null");
break; break;
case MPLS_LABEL_IPV4NULL: case MPLS_LABEL_IPV4_EXPLICIT_NULL:
case MPLS_LABEL_IPV6NULL: case MPLS_LABEL_IPV6_EXPLICIT_NULL:
snprintf(buf, TF_LEN, "exp-null"); snprintf(buf, TF_LEN, "exp-null");
break; break;
default: default:

View File

@ -929,6 +929,7 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_VRF_UNREGISTER), DESC_ENTRY(ZEBRA_VRF_UNREGISTER),
DESC_ENTRY(ZEBRA_VRF_ADD), DESC_ENTRY(ZEBRA_VRF_ADD),
DESC_ENTRY(ZEBRA_VRF_DELETE), DESC_ENTRY(ZEBRA_VRF_DELETE),
DESC_ENTRY(ZEBRA_VRF_LABEL),
DESC_ENTRY(ZEBRA_INTERFACE_VRF_UPDATE), DESC_ENTRY(ZEBRA_INTERFACE_VRF_UPDATE),
DESC_ENTRY(ZEBRA_BFD_CLIENT_REGISTER), DESC_ENTRY(ZEBRA_BFD_CLIENT_REGISTER),
DESC_ENTRY(ZEBRA_INTERFACE_ENABLE_RADV), DESC_ENTRY(ZEBRA_INTERFACE_ENABLE_RADV),

View File

@ -24,21 +24,27 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#ifdef MPLS_LABEL_MAX
#undef MPLS_LABEL_MAX
#endif
/* Well-known MPLS label values (RFC 3032 etc). */ /* Well-known MPLS label values (RFC 3032 etc). */
#define MPLS_V4_EXP_NULL_LABEL 0 #define MPLS_LABEL_IPV4_EXPLICIT_NULL 0 /* [RFC3032] */
#define MPLS_RA_LABEL 1 #define MPLS_LABEL_ROUTER_ALERT 1 /* [RFC3032] */
#define MPLS_V6_EXP_NULL_LABEL 2 #define MPLS_LABEL_IPV6_EXPLICIT_NULL 2 /* [RFC3032] */
#define MPLS_IMP_NULL_LABEL 3 #define MPLS_LABEL_IMPLICIT_NULL 3 /* [RFC3032] */
#define MPLS_ENTROPY_LABEL_INDICATOR 7 #define MPLS_LABEL_ELI 7 /* [RFC6790] */
#define MPLS_GAL_LABEL 13 #define MPLS_LABEL_GAL 13 /* [RFC5586] */
#define MPLS_OAM_ALERT_LABEL 14 #define MPLS_LABEL_OAM_ALERT 14 /* [RFC3429] */
#define MPLS_EXTENSION_LABEL 15 #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 */ /* Minimum and maximum label values */
#define MPLS_MIN_RESERVED_LABEL 0 #define MPLS_LABEL_RESERVED_MIN 0
#define MPLS_MAX_RESERVED_LABEL 15 #define MPLS_LABEL_RESERVED_MAX 15
#define MPLS_MIN_UNRESERVED_LABEL 16 #define MPLS_LABEL_UNRESERVED_MIN 16
#define MPLS_MAX_UNRESERVED_LABEL 1048575 #define MPLS_LABEL_UNRESERVED_MAX 1048575
/* Default min and max SRGB label range */ /* Default min and max SRGB label range */
/* Even if the SRGB allows to manage different Label space between routers, /* Even if the SRGB allows to manage different Label space between routers,
@ -56,11 +62,11 @@
#define MPLS_MAX_LABELS 16 #define MPLS_MAX_LABELS 16
#define IS_MPLS_RESERVED_LABEL(label) \ #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) \ #define IS_MPLS_UNRESERVED_LABEL(label) \
(label >= MPLS_MIN_UNRESERVED_LABEL \ (label >= MPLS_LABEL_UNRESERVED_MIN \
&& label <= MPLS_MAX_UNRESERVED_LABEL) && label <= MPLS_LABEL_UNRESERVED_MAX)
/* Definitions for a MPLS label stack entry (RFC 3032). This encodes the /* Definitions for a MPLS label stack entry (RFC 3032). This encodes the
* label, EXP, BOS and TTL fields. * label, EXP, BOS and TTL fields.
@ -109,7 +115,8 @@ enum lsp_types_t {
ZEBRA_LSP_STATIC = 1, /* Static LSP. */ ZEBRA_LSP_STATIC = 1, /* Static LSP. */
ZEBRA_LSP_LDP = 2, /* LDP LSP. */ ZEBRA_LSP_LDP = 2, /* LDP LSP. */
ZEBRA_LSP_BGP = 3, /* BGP 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. */ /* 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) static inline char *label2str(mpls_label_t label, char *buf, size_t len)
{ {
switch (label) { switch (label) {
case MPLS_V4_EXP_NULL_LABEL: case MPLS_LABEL_IPV4_EXPLICIT_NULL:
strlcpy(buf, "IPv4 Explicit Null", len); strlcpy(buf, "IPv4 Explicit Null", len);
return (buf); return (buf);
case MPLS_RA_LABEL: case MPLS_LABEL_ROUTER_ALERT:
strlcpy(buf, "Router Alert", len); strlcpy(buf, "Router Alert", len);
return (buf); return (buf);
case MPLS_V6_EXP_NULL_LABEL: case MPLS_LABEL_IPV6_EXPLICIT_NULL:
strlcpy(buf, "IPv6 Explict Null", len); strlcpy(buf, "IPv6 Explict Null", len);
return (buf); return (buf);
case MPLS_IMP_NULL_LABEL: case MPLS_LABEL_IMPLICIT_NULL:
strlcpy(buf, "implicit-null", len); strlcpy(buf, "implicit-null", len);
return (buf); return (buf);
case MPLS_ENTROPY_LABEL_INDICATOR: case MPLS_LABEL_ELI:
strlcpy(buf, "Entropy Label Indicator", len); strlcpy(buf, "Entropy Label Indicator", len);
return (buf); return (buf);
case MPLS_GAL_LABEL: case MPLS_LABEL_GAL:
strlcpy(buf, "Generic Associated Channel", len); strlcpy(buf, "Generic Associated Channel", len);
return (buf); return (buf);
case MPLS_OAM_ALERT_LABEL: case MPLS_LABEL_OAM_ALERT:
strlcpy(buf, "OAM Alert", len); strlcpy(buf, "OAM Alert", len);
return (buf); return (buf);
case MPLS_EXTENSION_LABEL: case MPLS_LABEL_EXTENSION:
strlcpy(buf, "Extension", len); strlcpy(buf, "Extension", len);
return (buf); return (buf);
default: 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 #endif

View File

@ -167,6 +167,7 @@ void copy_nexthops(struct nexthop **tnh, struct nexthop *nh,
for (nh1 = nh; nh1; nh1 = nh1->next) { for (nh1 = nh; nh1; nh1 = nh1->next) {
nexthop = nexthop_new(); nexthop = nexthop_new();
nexthop->vrf_id = nh1->vrf_id;
nexthop->ifindex = nh1->ifindex; nexthop->ifindex = nh1->ifindex;
nexthop->type = nh1->type; nexthop->type = nh1->type;
nexthop->flags = nh1->flags; nexthop->flags = nh1->flags;

View File

@ -60,6 +60,11 @@ struct nexthop {
struct nexthop *next; struct nexthop *next;
struct nexthop *prev; struct nexthop *prev;
/*
* What vrf is this nexthop associated with?
*/
vrf_id_t vrf_id;
/* Interface index. */ /* Interface index. */
ifindex_t ifindex; ifindex_t ifindex;
@ -116,18 +121,6 @@ struct nexthop {
(nexthop); \ (nexthop); \
(nexthop) = nexthop_next(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); struct nexthop *nexthop_new(void);
void nexthop_add(struct nexthop **target, struct nexthop *nexthop); void nexthop_add(struct nexthop **target, struct nexthop *nexthop);

View File

@ -363,6 +363,22 @@ static int zebra_hello_send(struct zclient *zclient)
return 0; 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. */ /* 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) 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); 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++) { for (i = 0; i < api->nexthop_num; i++) {
api_nh = &api->nexthops[i]; api_nh = &api->nexthops[i];
stream_putl(s, api_nh->vrf_id);
stream_putc(s, api_nh->type); stream_putc(s, api_nh->type);
switch (api_nh->type) { switch (api_nh->type) {
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
@ -1126,12 +1141,10 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
return -1; return -1;
} }
if (api->nexthop_num)
STREAM_GETL(s, api->nh_vrf_id);
for (i = 0; i < api->nexthop_num; i++) { for (i = 0; i < api->nexthop_num; i++) {
api_nh = &api->nexthops[i]; api_nh = &api->nexthops[i];
STREAM_GETL(s, api_nh->vrf_id);
STREAM_GETC(s, api_nh->type); STREAM_GETC(s, api_nh->type);
switch (api_nh->type) { switch (api_nh->type) {
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
@ -1217,6 +1230,7 @@ struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
struct nexthop *n = nexthop_new(); struct nexthop *n = nexthop_new();
n->type = znh->type; n->type = znh->type;
n->vrf_id = znh->vrf_id;
n->ifindex = znh->ifindex; n->ifindex = znh->ifindex;
n->gate = znh->gate; 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); __func__, *start, *end, keep, response_keep);
} }
/* sanity */ /* sanity */
if (*start > *end || *start < MPLS_MIN_UNRESERVED_LABEL if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
|| *end > MPLS_MAX_UNRESERVED_LABEL) { || *end > MPLS_LABEL_UNRESERVED_MAX) {
zlog_err("%s: Invalid Label chunk: %u - %u", __func__, *start, zlog_err("%s: Invalid Label chunk: %u - %u", __func__, *start,
*end); *end);
return -1; return -1;

View File

@ -93,6 +93,7 @@ typedef enum {
ZEBRA_VRF_UNREGISTER, ZEBRA_VRF_UNREGISTER,
ZEBRA_VRF_ADD, ZEBRA_VRF_ADD,
ZEBRA_VRF_DELETE, ZEBRA_VRF_DELETE,
ZEBRA_VRF_LABEL,
ZEBRA_INTERFACE_VRF_UPDATE, ZEBRA_INTERFACE_VRF_UPDATE,
ZEBRA_BFD_CLIENT_REGISTER, ZEBRA_BFD_CLIENT_REGISTER,
ZEBRA_INTERFACE_ENABLE_RADV, ZEBRA_INTERFACE_ENABLE_RADV,
@ -239,6 +240,7 @@ struct zserv_header {
struct zapi_nexthop { struct zapi_nexthop {
enum nexthop_types_t type; enum nexthop_types_t type;
vrf_id_t vrf_id;
ifindex_t ifindex; ifindex_t ifindex;
union { union {
union g_addr gate; union g_addr gate;
@ -286,7 +288,6 @@ struct zapi_route {
u_int32_t mtu; u_int32_t mtu;
vrf_id_t vrf_id; vrf_id_t vrf_id;
vrf_id_t nh_vrf_id;
struct ethaddr rmac; 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_add_instance(struct redist_proto *, u_short);
extern void redist_del_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_reg_requests(struct zclient *, vrf_id_t);
extern void zclient_send_dereg_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->nexthop_num = 1;
api->nexthops[0].type = NEXTHOP_TYPE_BLACKHOLE; api->nexthops[0].type = NEXTHOP_TYPE_BLACKHOLE;
api->nexthops[0].vrf_id = VRF_DEFAULT;
api->nexthops[0].bh_type = bh_type; api->nexthops[0].bh_type = bh_type;
SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP); SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP);
}; };

View File

@ -96,7 +96,6 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type, const struct prefix
api.type = ZEBRA_ROUTE_NHRP; api.type = ZEBRA_ROUTE_NHRP;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.prefix = *p; api.prefix = *p;
switch (type) { 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); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
api.nexthop_num = 1; api.nexthop_num = 1;
api_nh = &api.nexthops[0]; api_nh = &api.nexthops[0];
api_nh->vrf_id = VRF_DEFAULT;
switch (api.prefix.family) { switch (api.prefix.family) {
case AF_INET: case AF_INET:

View File

@ -99,6 +99,8 @@ struct ospf6_area {
/* Time stamps. */ /* Time stamps. */
struct timeval ts_spf; /* SPF calculation time stamp. */ struct timeval ts_spf; /* SPF calculation time stamp. */
uint32_t full_nbrs; /* Fully adjacent neighbors. */
}; };
#define OSPF6_AREA_ENABLE 0x01 #define OSPF6_AREA_ENABLE 0x01

View File

@ -148,6 +148,32 @@ static void ospf6_as_external_lsa_originate(struct ospf6_route *route)
ospf6_lsa_originate_process(lsa, ospf6); 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) static route_tag_t ospf6_as_external_lsa_get_tag(struct ospf6_lsa *lsa)
{ {
struct ospf6_as_external_lsa *external; struct ospf6_as_external_lsa *external;

View File

@ -192,10 +192,6 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa)
struct timeval now; struct timeval now;
struct ospf6_lsa *old; 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 /* Remove the old instance from all neighbors' Link state
retransmission list (RFC2328 13.2 last paragraph) */ retransmission list (RFC2328 13.2 last paragraph) */
old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id, 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); 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 */ /* actually install */
lsa->installed = now; lsa->installed = now;
ospf6_lsdb_add(lsa, lsa->lsdb); 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 */ /* RFC2740 section 3.5.2. Sending Link State Update packets */
/* RFC2328 section 13.3 Next step in the flooding procedure */ /* 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_lsa *lsa,
struct ospf6_interface *oi) struct ospf6_interface *oi)
{ {
@ -343,16 +346,25 @@ static void ospf6_flood_interface(struct ospf6_neighbor *from,
continue; continue;
} }
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 */ /* (d) add retrans-list, schedule retransmission */
if (is_debug) if (is_debug)
zlog_debug("Add retrans-list of this neighbor"); zlog_debug("Add retrans-list of this neighbor");
ospf6_increment_retrans_count(lsa); ospf6_increment_retrans_count(lsa);
ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list); ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, thread_add_timer(master, ospf6_lsupdate_send_neighbor,
on->ospf6_if->rxmt_interval, on, on->ospf6_if->rxmt_interval,
&on->thread_send_lsupdate); &on->thread_send_lsupdate);
retrans_added++; retrans_added++;
} }
}
/* (2) examin next interface if not added to retrans-list */ /* (2) examin next interface if not added to retrans-list */
if (retrans_added == 0) { if (retrans_added == 0) {
@ -806,6 +818,17 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
zlog_debug("Received is duplicated LSA"); zlog_debug("Received is duplicated LSA");
SET_FLAG(new->flag, OSPF6_LSA_DUPLICATE); 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 */ /* 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"); "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) */ /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
ospf6_lsdb_add(ospf6_lsa_copy(old), ospf6_lsdb_add(ospf6_lsa_copy(old),
from->lsupdate_list); from->lsupdate_list);
thread_add_event(master, ospf6_lsupdate_send_neighbor, thread_add_event(master, ospf6_lsupdate_send_neighbor,
from, 0, &from->thread_send_lsupdate); from, 0, &from->thread_send_lsupdate);
ospf6_lsa_delete(new); ospf6_lsa_delete(new);
return; return;
} }
@ -972,7 +1017,6 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
} }
} }
DEFUN (debug_ospf6_flooding, DEFUN (debug_ospf6_flooding,
debug_ospf6_flooding_cmd, debug_ospf6_flooding_cmd,
"debug ospf6 flooding", "debug ospf6 flooding",

View File

@ -58,5 +58,10 @@ extern void ospf6_install_lsa(struct ospf6_lsa *lsa);
extern int config_write_ospf6_debug_flood(struct vty *vty); extern int config_write_ospf6_debug_flood(struct vty *vty);
extern void install_element_ospf6_debug_flood(void); 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 */ #endif /* OSPF6_FLOOD_H */

View File

@ -301,6 +301,7 @@ void ospf6_interface_disable(struct ospf6_interface *oi)
THREAD_OFF(oi->thread_network_lsa); THREAD_OFF(oi->thread_network_lsa);
THREAD_OFF(oi->thread_link_lsa); THREAD_OFF(oi->thread_link_lsa);
THREAD_OFF(oi->thread_intra_prefix_lsa); THREAD_OFF(oi->thread_intra_prefix_lsa);
THREAD_OFF(oi->thread_as_extern_lsa);
} }
static struct in6_addr * static struct in6_addr *
@ -532,6 +533,7 @@ static void ospf6_interface_state_change(u_char next_state,
OSPF6_NETWORK_LSA_EXECUTE(oi); OSPF6_NETWORK_LSA_EXECUTE(oi);
OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi); OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area); OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oi->area);
OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi);
} else if (prev_state == OSPF6_INTERFACE_DR } else if (prev_state == OSPF6_INTERFACE_DR
|| next_state == OSPF6_INTERFACE_DR) { || next_state == OSPF6_INTERFACE_DR) {
OSPF6_NETWORK_LSA_SCHEDULE(oi); OSPF6_NETWORK_LSA_SCHEDULE(oi);

View File

@ -108,6 +108,7 @@ struct ospf6_interface {
struct thread *thread_network_lsa; struct thread *thread_network_lsa;
struct thread *thread_link_lsa; struct thread *thread_link_lsa;
struct thread *thread_intra_prefix_lsa; struct thread *thread_intra_prefix_lsa;
struct thread *thread_as_extern_lsa;
struct ospf6_route_table *route_connected; struct ospf6_route_table *route_connected;

View File

@ -185,11 +185,21 @@ struct ospf6_intra_prefix_lsa {
0, &(oi)->thread_intra_prefix_lsa); \ 0, &(oi)->thread_intra_prefix_lsa); \
} while (0) } 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) \ #define OSPF6_NETWORK_LSA_EXECUTE(oi) \
do { \ do { \
THREAD_OFF((oi)->thread_network_lsa); \ THREAD_OFF((oi)->thread_network_lsa); \
thread_execute(master, ospf6_network_lsa_originate, oi, 0); \ thread_execute(master, ospf6_network_lsa_originate, oi, 0); \
} while (0) } while (0)
#define OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi) \ #define OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT(oi) \
do { \ do { \
THREAD_OFF((oi)->thread_intra_prefix_lsa); \ THREAD_OFF((oi)->thread_intra_prefix_lsa); \
@ -198,6 +208,11 @@ struct ospf6_intra_prefix_lsa {
0); \ 0); \
} while (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 */ /* Function Prototypes */
extern char *ospf6_router_lsdesc_lookup(u_char type, u_int32_t interface_id, 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 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_add(struct ospf6_lsa *lsa);
extern void ospf6_intra_prefix_lsa_remove(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_route_calculation(struct ospf6_area *oa);
extern void ospf6_intra_brouter_calculation(struct ospf6_area *oa); extern void ospf6_intra_brouter_calculation(struct ospf6_area *oa);

View File

@ -706,6 +706,37 @@ int ospf6_lsa_refresh(struct thread *thread)
return 0; 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. */ /* Fletcher Checksum -- Refer to RFC1008. */

View File

@ -253,5 +253,6 @@ extern void ospf6_lsa_terminate(void);
extern int config_write_ospf6_debug_lsa(struct vty *vty); extern int config_write_ospf6_debug_lsa(struct vty *vty);
extern void install_element_ospf6_debug_lsa(void); extern void install_element_ospf6_debug_lsa(void);
extern void ospf6_lsa_age_set(struct ospf6_lsa *lsa); extern void ospf6_lsa_age_set(struct ospf6_lsa *lsa);
extern void ospf6_flush_self_originated_lsas_now(void);
#endif /* OSPF6_LSA_H */ #endif /* OSPF6_LSA_H */

View File

@ -334,6 +334,7 @@ int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb)
} }
if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)) if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type))
zlog_debug("Remove MaxAge %s", lsa->name); zlog_debug("Remove MaxAge %s", lsa->name);
if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)) { if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)) {
UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED); UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
/* /*

View File

@ -2163,6 +2163,40 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread)
return 0; 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) int ospf6_lsupdate_send_interface(struct thread *thread)
{ {
struct ospf6_interface *oi; struct ospf6_interface *oi;

View File

@ -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_TRANSIT(on->ospf6_if);
} }
OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(on->ospf6_if->area); 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 if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE

View File

@ -315,6 +315,7 @@ void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route,
if (i >= entries) if (i >= entries)
return; return;
nexthops[i].vrf_id = VRF_DEFAULT;
nexthops[i].ifindex = nh->ifindex; nexthops[i].ifindex = nh->ifindex;
if (!IN6_IS_ADDR_UNSPECIFIED(&nh->address)) { if (!IN6_IS_ADDR_UNSPECIFIED(&nh->address)) {
nexthops[i].gate.ipv6 = nh->address; nexthops[i].gate.ipv6 = nh->address;

View File

@ -1029,19 +1029,22 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area,
/* Fill Larger LSA Payload */ /* Fill Larger LSA Payload */
end = ospf6_lsdb_head(lsdb, 2, type, adv_router, &rtr_lsa); end = ospf6_lsdb_head(lsdb, 2, type, adv_router, &rtr_lsa);
if (rtr_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)) { if (!OSPF6_LSA_IS_MAXAGE(rtr_lsa)) {
/* Append first Link State ID LSA */ /* Append first Link State ID LSA */
lsa_header = (struct ospf6_lsa_header *)rtr_lsa->header; lsa_header = (struct ospf6_lsa_header *)rtr_lsa->header;
memcpy(new_header, lsa_header, memcpy(new_header, lsa_header, ntohs(lsa_header->length));
ntohs(lsa_header->length));
/* Assign new lsa length as aggregated length. */ /* Assign new lsa length as aggregated length. */
((struct ospf6_lsa_header *)new_header)->length = ((struct ospf6_lsa_header *)new_header)->length =
htons(total_lsa_length); htons(total_lsa_length);
new_header += ntohs(lsa_header->length); new_header += ntohs(lsa_header->length);
num_lsa--; num_lsa--;
} }
}
/* Print LSA Name */ /* Print LSA Name */
ospf6_lsa_printbuf(lsa, lsa->name, sizeof(lsa->name)); ospf6_lsa_printbuf(lsa, lsa->name, sizeof(lsa->name));

View File

@ -180,6 +180,8 @@ void ospf6_delete(struct ospf6 *o)
struct ospf6_area *oa; struct ospf6_area *oa;
QOBJ_UNREG(o); QOBJ_UNREG(o);
ospf6_flush_self_originated_lsas_now();
ospf6_disable(ospf6); ospf6_disable(ospf6);
for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa)) for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
@ -333,6 +335,8 @@ DEFUN(ospf6_router_id,
int ret; int ret;
const char *router_id_str; const char *router_id_str;
u_int32_t router_id; u_int32_t router_id;
struct ospf6_area *oa;
struct listnode *node;
argv_find(argv, argc, "A.B.C.D", &idx); argv_find(argv, argc, "A.B.C.D", &idx);
router_id_str = argv[idx]->arg; router_id_str = argv[idx]->arg;
@ -344,7 +348,16 @@ DEFUN(ospf6_router_id,
} }
o->router_id_static = router_id; o->router_id_static = router_id;
if (o->router_id == 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 = router_id; o->router_id = router_id;
return CMD_SUCCESS; return CMD_SUCCESS;
@ -358,8 +371,22 @@ DEFUN(no_ospf6_router_id,
V4NOTATION_STR) V4NOTATION_STR)
{ {
VTY_DECLVAR_CONTEXT(ospf6, o); VTY_DECLVAR_CONTEXT(ospf6, o);
struct ospf6_area *oa;
struct listnode *node;
o->router_id_static = 0; 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; 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; return CMD_SUCCESS;
} }
@ -521,6 +548,10 @@ DEFUN (ospf6_distance_ospf6,
VTY_DECLVAR_CONTEXT(ospf6, o); VTY_DECLVAR_CONTEXT(ospf6, o);
int idx = 0; int idx = 0;
o->distance_intra = 0;
o->distance_inter = 0;
o->distance_external = 0;
if (argv_find(argv, argc, "intra-area", &idx)) if (argv_find(argv, argc, "intra-area", &idx))
o->distance_intra = atoi(argv[idx + 1]->arg); o->distance_intra = atoi(argv[idx + 1]->arg);
idx = 0; idx = 0;

View File

@ -32,6 +32,8 @@ struct ospf6 {
/* static router id */ /* static router id */
u_int32_t router_id_static; u_int32_t router_id_static;
struct in_addr router_id_zebra;
/* start time */ /* start time */
struct timeval starttime; struct timeval starttime;
@ -94,6 +96,10 @@ struct ospf6 {
struct route_table *distance_table; struct route_table *distance_table;
/* Used during ospf instance going down send LSDB
* update to neighbors immediatly */
uint8_t inst_shutdown;
QOBJ_FIELDS QOBJ_FIELDS
}; };
DECLARE_QOBJ_TYPE(ospf6) DECLARE_QOBJ_TYPE(ospf6)

View File

@ -46,8 +46,6 @@ unsigned char conf_debug_ospf6_zebra = 0;
/* information about zebra. */ /* information about zebra. */
struct zclient *zclient = NULL; struct zclient *zclient = NULL;
struct in_addr router_id_zebra;
/* Router-id update message from zebra. */ /* Router-id update message from zebra. */
static int ospf6_router_id_update_zebra(int command, struct zclient *zclient, static int ospf6_router_id_update_zebra(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id) 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; struct ospf6 *o = ospf6;
zebra_router_id_update_read(zclient->ibuf, &router_id); zebra_router_id_update_read(zclient->ibuf, &router_id);
router_id_zebra = router_id.u.prefix4;
if (o == NULL) if (o == NULL)
return 0; return 0;
o->router_id_zebra = router_id.u.prefix4;
if (o->router_id == 0) 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; return 0;
} }
@ -337,7 +336,6 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request)
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_OSPF6; api.type = ZEBRA_ROUTE_OSPF6;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.prefix = *dest; 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)) { if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_OSPF6; api.type = ZEBRA_ROUTE_OSPF6;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.prefix = *dest; 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)) { if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_OSPF6; api.type = ZEBRA_ROUTE_OSPF6;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.prefix = *dest; api.prefix = *dest;

View File

@ -175,7 +175,7 @@ void ospf_ext_term(void)
{ {
if ((OspfEXT.scope != OSPF_OPAQUE_AREA_LSA) if ((OspfEXT.scope != OSPF_OPAQUE_AREA_LSA)
|| (OspfEXT.scope != OSPF_OPAQUE_AS_LSA)) && (OspfEXT.scope != OSPF_OPAQUE_AS_LSA))
zlog_warn( zlog_warn(
"EXT: Unable to unregister Extended Prefix " "EXT: Unable to unregister Extended Prefix "
"Opaque LSA functions: Wrong scope!"); "Opaque LSA functions: Wrong scope!");

View File

@ -563,6 +563,7 @@ int ospf_flood_through_area(struct ospf_area *area, struct ospf_neighbor *inbr,
struct ospf_interface *oi; struct ospf_interface *oi;
int lsa_ack_flag = 0; int lsa_ack_flag = 0;
assert(area);
/* All other types are specific to a single area (Area A). The /* All other types are specific to a single area (Area A). The
eligible interfaces are all those interfaces attaching to the eligible interfaces are all those interfaces attaching to the
Area A. If Area A is the backbone, this includes all the virtual Area A. If Area A is the backbone, this includes all the virtual

View File

@ -75,6 +75,7 @@ static void ospf_opaque_funclist_init(void);
static void ospf_opaque_funclist_term(void); static void ospf_opaque_funclist_term(void);
static void free_opaque_info_per_type(void *val); static void free_opaque_info_per_type(void *val);
static void free_opaque_info_per_id(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_install_hook(struct ospf_lsa *lsa);
static int ospf_opaque_lsa_delete_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) { if (functab->opaque_type == opaque_type) {
/* Cleanup internal control information, if it /* Cleanup internal control information, if it
* still remains. */ * still remains. */
if (functab->oipt != NULL) if (functab->oipt != NULL) {
free_opaque_info_per_type( free_opaque_info_per_type(
functab->oipt); functab->oipt);
free_opaque_info_owner(functab->oipt);
}
/* Dequeue listnode entry from the list. */ /* Dequeue listnode entry from the list. */
listnode_delete(funclist, functab); 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); top = ospf_lookup_by_vrf_id(new->vrf_id);
if (new->area != NULL && (top = new->area->ospf) == NULL) { if (new->area != NULL && (top = new->area->ospf) == NULL) {
free_opaque_info_per_type((void *)oipt); free_opaque_info_per_type((void *)oipt);
free_opaque_info_owner(oipt);
oipt = NULL; oipt = NULL;
goto out; /* This case may not exist. */ 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)", "register_opaque_info_per_type: Unexpected LSA-type(%u)",
new->data->type); new->data->type);
free_opaque_info_per_type((void *)oipt); free_opaque_info_per_type((void *)oipt);
free_opaque_info_owner(oipt);
oipt = NULL; oipt = NULL;
goto out; /* This case may not exist. */ goto out; /* This case may not exist. */
} }
@ -600,6 +605,35 @@ out:
return oipt; 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) static void free_opaque_info_per_type(void *val)
{ {
struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val; struct opaque_info_per_type *oipt = (struct opaque_info_per_type *)val;

View File

@ -3897,6 +3897,10 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
zlog_debug("listcount = %d, [%s]dst %s", listcount(update), zlog_debug("listcount = %d, [%s]dst %s", listcount(update),
IF_NAME(oi), inet_ntoa(addr)); 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); op = ospf_ls_upd_packet_new(update, oi);
/* Prepare OSPF common header. */ /* Prepare OSPF common header. */

View File

@ -337,6 +337,7 @@ static struct route_map_rule_cmd route_match_tag_cmd = {
}; };
struct ospf_metric { struct ospf_metric {
enum { metric_increment, metric_decrement, metric_absolute } type;
bool used; bool used;
u_int32_t metric; u_int32_t metric;
}; };
@ -356,8 +357,19 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
ei = object; ei = object;
/* Set metric out value. */ /* 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; 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; return RMAP_OKAY;
} }
@ -370,22 +382,27 @@ static void *route_set_metric_compile(const char *arg)
metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t)); metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t));
metric->used = false; metric->used = false;
/* OSPF doesn't support the +/- in if (all_digit(arg))
set metric <+/-metric> check metric->type = metric_absolute;
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 (strmatch(arg, "+rtt") || strmatch(arg, "-rtt")) {
zlog_warn("OSPF does not support 'set metric +rtt / -rtt'");
return metric; 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->metric = strtoul(arg, NULL, 10);
if (metric->metric)
metric->used = true; metric->used = true;
return metric; return metric;

View File

@ -149,14 +149,6 @@ static struct sr_node *sr_node_new(struct in_addr *rid)
new->ext_link->del = del_sr_link; new->ext_link->del = del_sr_link;
new->ext_prefix->del = del_sr_pref; 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); IPV4_ADDR_COPY(&new->adv_router, rid);
new->neighbor = NULL; new->neighbor = NULL;
new->instance = 0; new->instance = 0;
@ -440,7 +432,7 @@ static struct ospf_path *get_nexthop_by_addr(struct ospf *top,
struct route_node *rn; struct route_node *rn;
/* Sanity Check */ /* Sanity Check */
if ((top == NULL) && (top->new_table)) if (top == NULL)
return NULL; return NULL;
if (IS_DEBUG_OSPF_SR) if (IS_DEBUG_OSPF_SR)
@ -511,8 +503,8 @@ static int compute_link_nhlfe(struct sr_link *srl)
srl->nhlfe[1].label_in = srl->nhlfe[1].label_in =
index2label(srl->sid[1], srl->srn->srgb); index2label(srl->sid[1], srl->srn->srgb);
srl->nhlfe[0].label_out = MPLS_IMP_NULL_LABEL; srl->nhlfe[0].label_out = MPLS_LABEL_IMPLICIT_NULL;
srl->nhlfe[1].label_out = MPLS_IMP_NULL_LABEL; srl->nhlfe[1].label_out = MPLS_LABEL_IMPLICIT_NULL;
rc = 1; rc = 1;
return rc; return rc;
@ -599,7 +591,7 @@ static int compute_prefix_nhlfe(struct sr_prefix *srp)
*/ */
if ((srp->nexthop == NULL) if ((srp->nexthop == NULL)
&& (!CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_NPFLG))) && (!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)) else if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_VFLG))
srp->nhlfe.label_out = srp->sid; srp->nhlfe.label_out = srp->sid;
else else
@ -694,7 +686,7 @@ static inline void add_sid_nhlfe(struct sr_nhlfe nhlfe)
{ {
if ((nhlfe.label_in != 0) && (nhlfe.label_out != 0)) { if ((nhlfe.label_in != 0) && (nhlfe.label_out != 0)) {
ospf_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, nhlfe); 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); 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)) { if ((nhlfe.label_in != 0) && (nhlfe.label_out != 0)) {
ospf_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, nhlfe); 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); 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)) { EXT_SUBTLV_PREFIX_SID_NPFLG)) {
srp->nhlfe.label_in = index2label(srp->sid, srp->nhlfe.label_in = index2label(srp->sid,
OspfSR.self->srgb); OspfSR.self->srgb);
srp->nhlfe.label_out = MPLS_IMP_NULL_LABEL; srp->nhlfe.label_out = MPLS_LABEL_IMPLICIT_NULL;
add_sid_nhlfe(srp->nhlfe); add_sid_nhlfe(srp->nhlfe);
} }
} }
@ -1992,7 +1984,7 @@ DEFUN (sr_prefix_sid,
if (argv_find(argv, argc, "no-php-flag", &idx)) { if (argv_find(argv, argc, "no-php-flag", &idx)) {
SET_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_NPFLG); SET_FLAG(new->flags, EXT_SUBTLV_PREFIX_SID_NPFLG);
new->nhlfe.label_in = index2label(new->sid, OspfSR.self->srgb); 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) 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)) { for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) {
strncpy(pref, inet_ntoa(srp->nhlfe.prefv4.prefix), 16); strncpy(pref, inet_ntoa(srp->nhlfe.prefv4.prefix), 16);
snprintf(sid, 22, "SR Pfx (idx %u)", srp->sid); 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"); sprintf(label, "pop");
else else
sprintf(label, "%u", srp->nhlfe.label_out); 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)) { for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl)) {
strncpy(pref, inet_ntoa(srl->nhlfe[0].prefv4.prefix), 16); strncpy(pref, inet_ntoa(srl->nhlfe[0].prefv4.prefix), 16);
snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[0]); 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"); sprintf(label, "pop");
else else
sprintf(label, "%u", srl->nhlfe[0].label_out); 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 : "-", label, sid, itf ? itf->name : "-",
inet_ntoa(srl->nhlfe[0].nexthop)); inet_ntoa(srl->nhlfe[0].nexthop));
snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]); 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"); sprintf(label, "pop");
else else
sprintf(label, "%u", srl->nhlfe[0].label_out); sprintf(label, "%u", srl->nhlfe[0].label_out);

View File

@ -8558,6 +8558,10 @@ DEFUN (ospf_distance_ospf,
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
int idx = 0; int idx = 0;
ospf->distance_intra = 0;
ospf->distance_inter = 0;
ospf->distance_external = 0;
if (argv_find(argv, argc, "intra-area", &idx)) if (argv_find(argv, argc, "intra-area", &idx))
ospf->distance_intra = atoi(argv[idx + 1]->arg); ospf->distance_intra = atoi(argv[idx + 1]->arg);
idx = 0; idx = 0;

View File

@ -389,7 +389,6 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = ospf->vrf_id; api.vrf_id = ospf->vrf_id;
api.nh_vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF; api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance; api.instance = ospf->instance;
api.safi = SAFI_UNICAST; 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->ifindex = path->ifindex;
api_nh->type = NEXTHOP_TYPE_IFINDEX; api_nh->type = NEXTHOP_TYPE_IFINDEX;
} }
api_nh->vrf_id = ospf->vrf_id;
count++; count++;
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) { 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)); memset(&api, 0, sizeof(api));
api.vrf_id = ospf->vrf_id; api.vrf_id = ospf->vrf_id;
api.nh_vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF; api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance; api.instance = ospf->instance;
api.safi = SAFI_UNICAST; 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)); memset(&api, 0, sizeof(api));
api.vrf_id = ospf->vrf_id; api.vrf_id = ospf->vrf_id;
api.nh_vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF; api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance; api.instance = ospf->instance;
api.safi = SAFI_UNICAST; 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)); memset(&api, 0, sizeof(api));
api.vrf_id = ospf->vrf_id; api.vrf_id = ospf->vrf_id;
api.nh_vrf_id = ospf->vrf_id;
api.type = ZEBRA_ROUTE_OSPF; api.type = ZEBRA_ROUTE_OSPF;
api.instance = ospf->instance; api.instance = ospf->instance;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;

View File

@ -48,7 +48,6 @@ static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd)
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_RIP; api.type = ZEBRA_ROUTE_RIP;
api.safi = SAFI_UNICAST; 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) if (count >= MULTIPATH_NUM)
break; break;
api_nh = &api.nexthops[count]; api_nh = &api.nexthops[count];
api_nh->vrf_id = VRF_DEFAULT;
api_nh->gate = rinfo->nh.gate; api_nh->gate = rinfo->nh.gate;
api_nh->type = NEXTHOP_TYPE_IPV4; api_nh->type = NEXTHOP_TYPE_IPV4;
if (cmd == ZEBRA_ROUTE_ADD) if (cmd == ZEBRA_ROUTE_ADD)

View File

@ -2320,12 +2320,14 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
if (tmp_rinfo->type == ZEBRA_ROUTE_RIP if (tmp_rinfo->type == ZEBRA_ROUTE_RIP
&& tmp_rinfo->nh.ifindex && tmp_rinfo->nh.ifindex
== ifc->ifp->ifindex) == ifc->ifp->ifindex)
rinfo->metric_out = tmp_rinfo->metric_out =
RIP_METRIC_INFINITY; RIP_METRIC_INFINITY;
if (tmp_rinfo->type == ZEBRA_ROUTE_CONNECT
if (rinfo->type == ZEBRA_ROUTE_CONNECT
&& prefix_match((struct prefix *)p, && prefix_match((struct prefix *)p,
ifc->address)) ifc->address))
rinfo->metric_out = RIP_METRIC_INFINITY; rinfo->metric_out =
RIP_METRIC_INFINITY;
} }
/* Prepare preamble, auth headers, if needs be */ /* Prepare preamble, auth headers, if needs be */

View File

@ -48,7 +48,6 @@ static void ripng_zebra_ipv6_send(struct route_node *rp, u_char cmd)
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_RIPNG; api.type = ZEBRA_ROUTE_RIPNG;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
api.prefix = rp->p; 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) if (count >= MULTIPATH_NUM)
break; break;
api_nh = &api.nexthops[count]; api_nh = &api.nexthops[count];
api_nh->vrf_id = VRF_DEFAULT;
api_nh->gate.ipv6 = rinfo->nexthop; api_nh->gate.ipv6 = rinfo->nexthop;
api_nh->ifindex = rinfo->ifindex; api_nh->ifindex = rinfo->ifindex;
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;

View File

@ -26,6 +26,8 @@
#include "prefix.h" #include "prefix.h"
#include "nexthop.h" #include "nexthop.h"
#include "log.h" #include "log.h"
#include "vrf.h"
#include "zclient.h"
#include "sharpd/sharp_zebra.h" #include "sharpd/sharp_zebra.h"
#include "sharpd/sharp_vty.h" #include "sharpd/sharp_vty.h"
@ -39,7 +41,8 @@ extern uint32_t removed_routes;
DEFPY (install_routes, DEFPY (install_routes,
install_routes_cmd, 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" "install some routes\n"
"Routes to install\n" "Routes to install\n"
"Address to start /32 generation at\n" "Address to start /32 generation at\n"
@ -76,9 +79,40 @@ DEFPY (install_routes,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFPY(vrf_label, vrf_label_cmd,
"sharp label <ip$ipv4|ipv6$ipv6> 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, DEFPY (remove_routes,
remove_routes_cmd, 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" "Remove some routes\n"
"Routes to remove\n" "Routes to remove\n"
"Starting spot\n" "Starting spot\n"
@ -112,5 +146,6 @@ void sharp_vty_init(void)
{ {
install_element(ENABLE_NODE, &install_routes_cmd); install_element(ENABLE_NODE, &install_routes_cmd);
install_element(ENABLE_NODE, &remove_routes_cmd); install_element(ENABLE_NODE, &remove_routes_cmd);
install_element(ENABLE_NODE, &vrf_label_cmd);
return; return;
} }

View File

@ -152,6 +152,11 @@ static void zebra_connected(struct zclient *zclient)
zclient_send_reg_requests(zclient, VRF_DEFAULT); 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) void route_add(struct prefix *p, struct nexthop *nh)
{ {
struct zapi_route api; struct zapi_route api;
@ -159,7 +164,6 @@ void route_add(struct prefix *p, struct nexthop *nh)
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_SHARP; api.type = ZEBRA_ROUTE_SHARP;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
memcpy(&api.prefix, p, sizeof(*p)); 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); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
api_nh = &api.nexthops[0]; api_nh = &api.nexthops[0];
api_nh->vrf_id = VRF_DEFAULT;
api_nh->gate.ipv4 = nh->gate.ipv4; api_nh->gate.ipv4 = nh->gate.ipv4;
api_nh->type = nh->type; api_nh->type = nh->type;
api_nh->ifindex = nh->ifindex; api_nh->ifindex = nh->ifindex;
@ -181,7 +186,6 @@ void route_delete(struct prefix *p)
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = VRF_DEFAULT; api.vrf_id = VRF_DEFAULT;
api.nh_vrf_id = VRF_DEFAULT;
api.type = ZEBRA_ROUTE_SHARP; api.type = ZEBRA_ROUTE_SHARP;
api.safi = SAFI_UNICAST; api.safi = SAFI_UNICAST;
memcpy(&api.prefix, p, sizeof(*p)); memcpy(&api.prefix, p, sizeof(*p));

View File

@ -24,6 +24,7 @@
extern void sharp_zebra_init(void); 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_add(struct prefix *p, struct nexthop *nh);
extern void route_delete(struct prefix *p); extern void route_delete(struct prefix *p);
#endif #endif

View File

@ -13,6 +13,11 @@ sharpd_libsharp_a_SOURCES = \
sharpd/sharp_vty.c \ sharpd/sharp_vty.c \
# end # end
noinst_HEADERS += \
sharpd/sharp_vty.h \
sharpd/sharp_zebra.h \
# end
sharpd/sharp_vty_clippy.c: $(CLIPPY_DEPS) sharpd/sharp_vty_clippy.c: $(CLIPPY_DEPS)
sharpd/sharp_vty.$(OBJEXT): sharpd/sharp_vty_clippy.c sharpd/sharp_vty.$(OBJEXT): sharpd/sharp_vty_clippy.c

View File

@ -203,7 +203,9 @@ void connected_up(struct interface *ifp, struct connected *ifc)
afi_t afi; afi_t afi;
struct prefix p; struct prefix p;
struct nexthop nh = { 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)) if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
@ -238,13 +240,11 @@ void connected_up(struct interface *ifp, struct connected *ifc)
break; break;
} }
rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ifp->vrf_id, rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p,
ZEBRA_ROUTE_CONNECT, 0, 0, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
&p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ifp->vrf_id, rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, &p,
ZEBRA_ROUTE_CONNECT, 0, 0, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
&p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
char buf[PREFIX_STRLEN]; char buf[PREFIX_STRLEN];
@ -362,7 +362,9 @@ void connected_down(struct interface *ifp, struct connected *ifc)
afi_t afi; afi_t afi;
struct prefix p; struct prefix p;
struct nexthop nh = { 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)) if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))

View File

@ -907,6 +907,8 @@ void rtm_read(struct rt_msghdr *rtm)
SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC); SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC);
memset(&nh, 0, sizeof(nh)); memset(&nh, 0, sizeof(nh));
nh.vrf_id = VRF_DEFAULT;
/* This is a reject or blackhole route */ /* This is a reject or blackhole route */
if (flags & RTF_REJECT) { if (flags & RTF_REJECT) {
nh.type = NEXTHOP_TYPE_BLACKHOLE; 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 if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE) || 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, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
&nh, 0, 0, 0, 0, 0); &nh, 0, 0, 0, 0, 0);
else else
@ -1097,7 +1099,7 @@ void rtm_read(struct rt_msghdr *rtm)
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|| rtm->rtm_type == RTM_CHANGE) || 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, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
&nh, 0, 0, 0, 0, 0); &nh, 0, 0, 0, 0, 0);
else else
@ -1195,7 +1197,7 @@ int rtm_write(int message, union sockunion *dest, union sockunion *mask,
msg.rtm.rtm_flags |= RTF_MPLS; msg.rtm.rtm_flags |= RTF_MPLS;
if (mpls->smpls.smpls_label 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; msg.rtm.rtm_mpls = MPLS_OP_PUSH;
} }
#endif #endif

View File

@ -283,13 +283,13 @@ struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance,
return NULL; return NULL;
if (list_isempty(lbl_mgr.lc_list)) if (list_isempty(lbl_mgr.lc_list))
lmc->start = MPLS_MIN_UNRESERVED_LABEL; lmc->start = MPLS_LABEL_UNRESERVED_MIN;
else else
lmc->start = ((struct label_manager_chunk *)listgetdata( lmc->start = ((struct label_manager_chunk *)listgetdata(
listtail(lbl_mgr.lc_list))) listtail(lbl_mgr.lc_list)))
->end ->end
+ 1; + 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, zlog_err("Reached max labels. Start: %u, size: %u", lmc->start,
size); size);
XFREE(MTYPE_LM_CHUNK, lmc); XFREE(MTYPE_LM_CHUNK, lmc);

View File

@ -59,7 +59,6 @@ struct route_entry {
/* VRF identifier. */ /* VRF identifier. */
vrf_id_t vrf_id; vrf_id_t vrf_id;
vrf_id_t nh_vrf_id;
/* Which routing table */ /* Which routing table */
uint32_t table; uint32_t table;
@ -231,22 +230,27 @@ typedef enum {
} rib_update_event_t; } rib_update_event_t;
extern struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *, 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 *, extern struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *,
enum blackhole_type); enum blackhole_type);
extern struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *, extern struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *,
struct in_addr *, struct in_addr *,
struct in_addr *); struct in_addr *,
vrf_id_t nh_vrf_id);
extern struct nexthop * extern struct nexthop *
route_entry_nexthop_ipv4_ifindex_add(struct route_entry *, struct in_addr *, 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, extern void route_entry_nexthop_delete(struct route_entry *re,
struct nexthop *nexthop); struct nexthop *nexthop);
extern struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *, 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 * extern struct nexthop *
route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re, 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, extern void route_entry_nexthop_add(struct route_entry *re,
struct nexthop *nexthop); struct nexthop *nexthop);
extern void route_entry_copy_nexthops(struct route_entry *re, 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: /* NOTE:
* All rib_add function will not just add prefix into RIB, but * All rib_add function will not just add prefix into RIB, but
* also implicitly withdraw equal prefix of same type. */ * 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, extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
int type, u_short instance, int flags, struct prefix *p, u_short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh, struct prefix_ipv6 *src_p, const struct nexthop *nh,
u_int32_t table_id, u_int32_t metric, u_int32_t mtu, u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
uint8_t distance, route_tag_t tag); uint8_t distance, route_tag_t tag);

View File

@ -443,10 +443,10 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (ifp) if (ifp)
nh_vrf_id = ifp->vrf_id; nh_vrf_id = ifp->vrf_id;
} }
nh.vrf_id = nh_vrf_id;
rib_add(afi, SAFI_UNICAST, vrf_id, nh_vrf_id, proto, rib_add(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p,
0, flags, &p, NULL, &nh, table, metric, NULL, &nh, table, metric, mtu, distance, tag);
mtu, distance, tag);
} else { } else {
/* This is a multipath route */ /* This is a multipath route */
@ -463,13 +463,13 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
re->metric = metric; re->metric = metric;
re->mtu = mtu; re->mtu = mtu;
re->vrf_id = vrf_id; re->vrf_id = vrf_id;
re->nh_vrf_id = vrf_id;
re->table = table; re->table = table;
re->nexthop_num = 0; re->nexthop_num = 0;
re->uptime = time(NULL); re->uptime = time(NULL);
re->tag = tag; re->tag = tag;
for (;;) { for (;;) {
vrf_id_t nh_vrf_id;
if (len < (int)sizeof(*rtnh) if (len < (int)sizeof(*rtnh)
|| rtnh->rtnh_len > len) || rtnh->rtnh_len > len)
break; break;
@ -485,8 +485,17 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
ifp = if_lookup_by_index(index, ifp = if_lookup_by_index(index,
VRF_UNKNOWN); VRF_UNKNOWN);
if (ifp) 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; gate = 0;
if (rtnh->rtnh_len > sizeof(*rtnh)) { if (rtnh->rtnh_len > sizeof(*rtnh)) {
memset(tb, 0, sizeof(tb)); memset(tb, 0, sizeof(tb));
@ -503,24 +512,27 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (index) if (index)
route_entry_nexthop_ipv4_ifindex_add( route_entry_nexthop_ipv4_ifindex_add(
re, gate, re, gate,
prefsrc, index); prefsrc, index,
nh_vrf_id);
else else
route_entry_nexthop_ipv4_add( route_entry_nexthop_ipv4_add(
re, gate, re, gate,
prefsrc); prefsrc,
nh_vrf_id);
} else if (rtm->rtm_family } else if (rtm->rtm_family
== AF_INET6) { == AF_INET6) {
if (index) if (index)
route_entry_nexthop_ipv6_ifindex_add( route_entry_nexthop_ipv6_ifindex_add(
re, gate, re, gate, index,
index); nh_vrf_id);
else else
route_entry_nexthop_ipv6_add( route_entry_nexthop_ipv6_add(
re, gate); re, gate,
nh_vrf_id);
} }
} else } else
route_entry_nexthop_ifindex_add(re, route_entry_nexthop_ifindex_add(
index); re, index, nh_vrf_id);
len -= NLMSG_ALIGN(rtnh->rtnh_len); len -= NLMSG_ALIGN(rtnh->rtnh_len);
rtnh = RTNH_NEXT(rtnh); 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; struct mpls_label_stack *nh_label;
mpls_lse_t out_lse[MPLS_MAX_LABELS]; mpls_lse_t out_lse[MPLS_MAX_LABELS];
int num_labels = 0;
char label_buf[256]; char label_buf[256];
/* /*
@ -837,26 +850,19 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
* you fix this assumption * you fix this assumption
*/ */
label_buf[0] = '\0'; 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) { assert(nexthop);
int i, num_labels = 0; for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
u_int32_t bos;
char label_buf1[20]; char label_buf1[20];
for (i = 0; i < nh_label->num_labels; i++) { nh_label = nh->nh_label;
if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) { if (!nh_label || !nh_label->num_labels)
bos = ((i == (nh_label->num_labels - 1)) ? 1 continue;
: 0);
out_lse[i] = mpls_lse_encode(nh_label->label[i], for (int i = 0; i < nh_label->num_labels; i++) {
0, 0, bos); if (nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL)
continue;
if (IS_ZEBRA_DEBUG_KERNEL) { if (IS_ZEBRA_DEBUG_KERNEL) {
if (!num_labels) if (!num_labels)
sprintf(label_buf, "label %u", sprintf(label_buf, "label %u",
@ -868,10 +874,17 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
sizeof(label_buf)); sizeof(label_buf));
} }
} }
out_lse[num_labels] =
mpls_lse_encode(nh_label->label[i], 0, 0, 0);
num_labels++; num_labels++;
} }
} }
if (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) if (rtmsg->rtm_family == AF_MPLS)
addattr_l(nlmsg, req_size, RTA_NEWDST, &out_lse, addattr_l(nlmsg, req_size, RTA_NEWDST, &out_lse,
num_labels * sizeof(mpls_lse_t)); num_labels * sizeof(mpls_lse_t));
@ -879,16 +892,14 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen,
struct rtattr *nest; struct rtattr *nest;
u_int16_t encap = LWTUNNEL_ENCAP_MPLS; u_int16_t encap = LWTUNNEL_ENCAP_MPLS;
addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, &encap,
&encap, sizeof(u_int16_t)); sizeof(u_int16_t));
nest = addattr_nest(nlmsg, req_size, RTA_ENCAP); nest = addattr_nest(nlmsg, req_size, RTA_ENCAP);
addattr_l(nlmsg, req_size, MPLS_IPTUNNEL_DST, addattr_l(nlmsg, req_size, MPLS_IPTUNNEL_DST, &out_lse,
&out_lse,
num_labels * sizeof(mpls_lse_t)); num_labels * sizeof(mpls_lse_t));
addattr_nest_end(nlmsg, nest); addattr_nest_end(nlmsg, nest);
} }
} }
}
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
rtmsg->rtm_flags |= RTNH_F_ONLINK; rtmsg->rtm_flags |= RTNH_F_ONLINK;
@ -1033,6 +1044,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
{ {
struct mpls_label_stack *nh_label; struct mpls_label_stack *nh_label;
mpls_lse_t out_lse[MPLS_MAX_LABELS]; mpls_lse_t out_lse[MPLS_MAX_LABELS];
int num_labels = 0;
char label_buf[256]; char label_buf[256];
rtnh->rtnh_len = sizeof(*rtnh); rtnh->rtnh_len = sizeof(*rtnh);
@ -1047,26 +1059,19 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
* you fix this assumption * you fix this assumption
*/ */
label_buf[0] = '\0'; 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) { assert(nexthop);
int i, num_labels = 0; for (struct nexthop *nh = nexthop; nh; nh = nh->rparent) {
u_int32_t bos;
char label_buf1[20]; char label_buf1[20];
for (i = 0; i < nh_label->num_labels; i++) { nh_label = nh->nh_label;
if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) { if (!nh_label || !nh_label->num_labels)
bos = ((i == (nh_label->num_labels - 1)) ? 1 continue;
: 0);
out_lse[i] = mpls_lse_encode(nh_label->label[i], for (int i = 0; i < nh_label->num_labels; i++) {
0, 0, bos); if (nh_label->label[i] == MPLS_LABEL_IMPLICIT_NULL)
continue;
if (IS_ZEBRA_DEBUG_KERNEL) { if (IS_ZEBRA_DEBUG_KERNEL) {
if (!num_labels) if (!num_labels)
sprintf(label_buf, "label %u", sprintf(label_buf, "label %u",
@ -1078,34 +1083,38 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen,
sizeof(label_buf)); sizeof(label_buf));
} }
} }
out_lse[num_labels] =
mpls_lse_encode(nh_label->label[i], 0, 0, 0);
num_labels++; num_labels++;
} }
} }
if (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) { if (rtmsg->rtm_family == AF_MPLS) {
rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_NEWDST, rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_NEWDST,
&out_lse, &out_lse,
num_labels * sizeof(mpls_lse_t)); num_labels * sizeof(mpls_lse_t));
rtnh->rtnh_len += RTA_LENGTH( rtnh->rtnh_len +=
num_labels * sizeof(mpls_lse_t)); RTA_LENGTH(num_labels * sizeof(mpls_lse_t));
} else { } else {
struct rtattr *nest; struct rtattr *nest;
u_int16_t encap = LWTUNNEL_ENCAP_MPLS; u_int16_t encap = LWTUNNEL_ENCAP_MPLS;
int len = rta->rta_len; int len = rta->rta_len;
rta_addattr_l(rta, NL_PKT_BUF_SIZE, rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_ENCAP_TYPE,
RTA_ENCAP_TYPE, &encap, &encap, sizeof(u_int16_t));
sizeof(u_int16_t)); nest = rta_nest(rta, NL_PKT_BUF_SIZE, RTA_ENCAP);
nest = rta_nest(rta, NL_PKT_BUF_SIZE, rta_addattr_l(rta, NL_PKT_BUF_SIZE, MPLS_IPTUNNEL_DST,
RTA_ENCAP); &out_lse,
rta_addattr_l(rta, NL_PKT_BUF_SIZE,
MPLS_IPTUNNEL_DST, &out_lse,
num_labels * sizeof(mpls_lse_t)); num_labels * sizeof(mpls_lse_t));
rta_nest_end(rta, nest); rta_nest_end(rta, nest);
rtnh->rtnh_len += rta->rta_len - len; rtnh->rtnh_len += rta->rta_len - len;
} }
} }
}
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
rtnh->rtnh_flags |= RTNH_F_ONLINK; rtnh->rtnh_flags |= RTNH_F_ONLINK;

View File

@ -94,12 +94,12 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry)
prefix.prefixlen = ip_masklen(tmpaddr); prefix.prefixlen = ip_masklen(tmpaddr);
memset(&nh, 0, sizeof(nh)); memset(&nh, 0, sizeof(nh));
nh.vrf_id = VRF_DEFAULT;
nh.type = NEXTHOP_TYPE_IPV4; nh.type = NEXTHOP_TYPE_IPV4;
nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop; nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop;
rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, VRF_DEFAULT, rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0,
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &prefix, NULL, zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0, 0);
&nh, 0, 0, 0, 0, 0);
} }
void route_read(struct zebra_ns *zns) void route_read(struct zebra_ns *zns)

View File

@ -411,12 +411,13 @@ static int fec_change_update_lsp(struct zebra_vrf *zvrf, zebra_fec_t *fec,
afi_t afi; afi_t afi;
/* Uninstall label forwarding entry, if previously installed. */ /* 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); lsp_uninstall(zvrf, old_label);
/* Install label forwarding entry corr. to new label, if needed. */ /* Install label forwarding entry corr. to new label, if needed. */
if (fec->label == MPLS_INVALID_LABEL if (fec->label == MPLS_INVALID_LABEL
|| fec->label == MPLS_IMP_NULL_LABEL) || fec->label == MPLS_LABEL_IMPLICIT_NULL)
return 0; return 0;
afi = family2afi(PREFIX_FAMILY(&fec->rn->p)); 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 route_entry *match;
struct nexthop *match_nh; 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) if (!table)
return 0; return 0;
@ -663,7 +664,7 @@ static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
struct route_node *rn; struct route_node *rn;
struct route_entry *match; 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) if (!table)
return 0; return 0;
@ -711,6 +712,22 @@ static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)
/* Check on nexthop based on type. */ /* Check on nexthop based on type. */
switch (nexthop->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:
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
if (nhlfe_nexthop_active_ipv4(nhlfe, nexthop)) 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: case NEXTHOP_TYPE_IPV6_IFINDEX:
if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { 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)) if (ifp && if_is_operative(ifp))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else else
@ -1052,6 +1070,8 @@ static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size)
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, size); inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, size);
break; break;
case NEXTHOP_TYPE_IFINDEX:
snprintf(buf, size, "Ifindex: %u", nexthop->ifindex);
default: default:
break; 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) if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
cmp = !(nhop->ifindex == ifindex); cmp = !(nhop->ifindex == ifindex);
break; break;
case NEXTHOP_TYPE_IFINDEX:
cmp = !(nhop->ifindex == ifindex);
break;
default: default:
break; 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_add_labels(nexthop, lsp_type, 1, &out_label);
nexthop->vrf_id = VRF_DEFAULT;
nexthop->type = gtype; nexthop->type = gtype;
switch (nexthop->type) { switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4: 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) if (ifindex)
nexthop->ifindex = ifindex; nexthop->ifindex = ifindex;
break; break;
case NEXTHOP_TYPE_IFINDEX:
nexthop->ifindex = ifindex;
break;
default: default:
nexthop_free(nexthop); nexthop_free(nexthop);
XFREE(MTYPE_NHLFE, nhlfe); 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)); inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
if (nexthop->ifindex) if (nexthop->ifindex)
json_object_string_add( json_object_string_add(json_nhlfe, "interface",
json_nhlfe, "interface", ifindex2ifname(nexthop->ifindex,
ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); nexthop->vrf_id));
break; break;
default: default:
break; 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)); vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
if (nexthop->ifindex) if (nexthop->ifindex)
vty_out(vty, " dev %s", vty_out(vty, " dev %s",
ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); ifindex2ifname(nexthop->ifindex,
nexthop->vrf_id));
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX: 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)); inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
if (nexthop->ifindex) if (nexthop->ifindex)
vty_out(vty, " dev %s", vty_out(vty, " dev %s",
ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); ifindex2ifname(nexthop->ifindex,
nexthop->vrf_id));
break; break;
default: default:
break; 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 /* We cannot install a label forwarding entry if local label is the
* implicit-null label. * implicit-null label.
*/ */
if (fec->label == MPLS_IMP_NULL_LABEL) if (fec->label == MPLS_LABEL_IMPLICIT_NULL)
return 0; return 0;
if (lsp_install(zvrf, fec->label, rn, re)) 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; int cur_op, new_op;
cur_op = (slsp->snhlfe_list->out_label cur_op = (slsp->snhlfe_list->out_label
== MPLS_IMP_NULL_LABEL); == MPLS_LABEL_IMPLICIT_NULL);
new_op = (out_label == MPLS_IMP_NULL_LABEL); new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL);
if (cur_op != new_op) if (cur_op != new_op)
return 0; return 0;
} }
@ -2764,6 +2793,15 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
nexthop = nhlfe->nexthop; nexthop = nhlfe->nexthop;
switch (nexthop->type) { 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:
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
vty_out(vty, "%15s", vty_out(vty, "%15s",
@ -2780,8 +2818,16 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
break; break;
} }
vty_out(vty, " %8d\n", if (nexthop->type != NEXTHOP_TYPE_IFINDEX)
nexthop->nh_label->label[0]); 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)); snhlfe2str(snhlfe, buf, sizeof(buf));
switch (snhlfe->out_label) { switch (snhlfe->out_label) {
case MPLS_V4_EXP_NULL_LABEL: case MPLS_LABEL_IPV4_EXPLICIT_NULL:
case MPLS_V6_EXP_NULL_LABEL: case MPLS_LABEL_IPV6_EXPLICIT_NULL:
strlcpy(lstr, "explicit-null", sizeof(lstr)); strlcpy(lstr, "explicit-null", sizeof(lstr));
break; break;
case MPLS_IMP_NULL_LABEL: case MPLS_LABEL_IMPLICIT_NULL:
strlcpy(lstr, "implicit-null", sizeof(lstr)); strlcpy(lstr, "implicit-null", sizeof(lstr));
break; break;
default: default:

View File

@ -428,9 +428,19 @@ static inline u_char lsp_distance(enum lsp_types_t type)
return (route_distance(ZEBRA_ROUTE_LDP)); return (route_distance(ZEBRA_ROUTE_LDP));
case ZEBRA_LSP_BGP: case ZEBRA_LSP_BGP:
return (route_distance(ZEBRA_ROUTE_BGP)); return (route_distance(ZEBRA_ROUTE_BGP));
default: case ZEBRA_LSP_NONE:
case ZEBRA_LSP_SHARP:
case ZEBRA_LSP_SR:
return 150; 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; return ZEBRA_LSP_STATIC;
case ZEBRA_ROUTE_BGP: case ZEBRA_ROUTE_BGP:
return ZEBRA_LSP_BGP; return ZEBRA_LSP_BGP;
case ZEBRA_ROUTE_SHARP:
return ZEBRA_LSP_SHARP;
default: default:
return ZEBRA_LSP_NONE; 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: case ZEBRA_LSP_SR:
return ZEBRA_ROUTE_OSPF; return ZEBRA_ROUTE_OSPF;
case ZEBRA_LSP_NONE: case ZEBRA_LSP_NONE:
default:
return ZEBRA_ROUTE_KERNEL; 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. */ /* NHLFE type as printable string. */
@ -481,9 +502,19 @@ static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type)
return "BGP"; return "BGP";
case ZEBRA_LSP_SR: case ZEBRA_LSP_SR:
return "SR"; return "SR";
default: case ZEBRA_LSP_SHARP:
return "SHARP";
case ZEBRA_LSP_NONE:
return "Unknown"; 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) static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf)

View File

@ -68,7 +68,7 @@ static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd,
return CMD_WARNING_CONFIG_FAILED; 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); label = atoi(inlabel_str);
if (!IS_MPLS_UNRESERVED_LABEL(label)) { if (!IS_MPLS_UNRESERVED_LABEL(label)) {
vty_out(vty, "%% Invalid label\n"); 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) {
if (outlabel_str[0] == 'i') 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) 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) 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 else
out_label = atoi(outlabel_str); 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")) if (!strcmp(label_str, "implicit-null"))
label = MPLS_IMP_NULL_LABEL; label = MPLS_LABEL_IMPLICIT_NULL;
else if (!strcmp(label_str, "explicit-null")) { else if (!strcmp(label_str, "explicit-null")) {
if (p.family == AF_INET) if (p.family == AF_INET)
label = MPLS_V4_EXP_NULL_LABEL; label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
else else
label = MPLS_V6_EXP_NULL_LABEL; label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
} else { } else {
label = atoi(label_str); label = atoi(label_str);
if (!IS_MPLS_UNRESERVED_LABEL(label)) { if (!IS_MPLS_UNRESERVED_LABEL(label)) {

View File

@ -1007,8 +1007,13 @@ int zebra_ptm_bfd_client_register(struct zserv *client,
return 0; return 0;
stream_failure: 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; return 0;
} }

View File

@ -86,6 +86,7 @@ static const struct {
[ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20}, [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20},
[ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20}, [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20},
[ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100}, [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100},
[ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150},
/* no entry/default: 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, 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; struct nexthop *nexthop;
nexthop = nexthop_new(); nexthop = nexthop_new();
nexthop->type = NEXTHOP_TYPE_IFINDEX; nexthop->type = NEXTHOP_TYPE_IFINDEX;
nexthop->ifindex = ifindex; nexthop->ifindex = ifindex;
nexthop->vrf_id = nh_vrf_id;
route_entry_nexthop_add(re, nexthop); 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 nexthop *route_entry_nexthop_ipv4_add(struct route_entry *re,
struct in_addr *ipv4, struct in_addr *ipv4,
struct in_addr *src) struct in_addr *src,
vrf_id_t nh_vrf_id)
{ {
struct nexthop *nexthop; struct nexthop *nexthop;
nexthop = nexthop_new(); nexthop = nexthop_new();
nexthop->type = NEXTHOP_TYPE_IPV4; nexthop->type = NEXTHOP_TYPE_IPV4;
nexthop->vrf_id = nh_vrf_id;
nexthop->gate.ipv4 = *ipv4; nexthop->gate.ipv4 = *ipv4;
if (src) if (src)
nexthop->src.ipv4 = *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 nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
struct in_addr *ipv4, struct in_addr *ipv4,
struct in_addr *src, struct in_addr *src,
ifindex_t ifindex) ifindex_t ifindex,
vrf_id_t nh_vrf_id)
{ {
struct nexthop *nexthop; struct nexthop *nexthop;
struct interface *ifp; struct interface *ifp;
nexthop = nexthop_new(); nexthop = nexthop_new();
nexthop->vrf_id = nh_vrf_id;
nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX; nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
nexthop->gate.ipv4 = *ipv4; nexthop->gate.ipv4 = *ipv4;
if (src) if (src)
nexthop->src.ipv4 = *src; nexthop->src.ipv4 = *src;
nexthop->ifindex = ifindex; 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? /*Pending: need to think if null ifp here is ok during bootup?
There was a crash because ifp here was coming to be NULL */ There was a crash because ifp here was coming to be NULL */
if (ifp) 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 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; struct nexthop *nexthop;
nexthop = nexthop_new(); nexthop = nexthop_new();
nexthop->vrf_id = nh_vrf_id;
nexthop->type = NEXTHOP_TYPE_IPV6; nexthop->type = NEXTHOP_TYPE_IPV6;
nexthop->gate.ipv6 = *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 nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
struct in6_addr *ipv6, struct in6_addr *ipv6,
ifindex_t ifindex) ifindex_t ifindex,
vrf_id_t nh_vrf_id)
{ {
struct nexthop *nexthop; struct nexthop *nexthop;
nexthop = nexthop_new(); nexthop = nexthop_new();
nexthop->vrf_id = nh_vrf_id;
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX; nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
nexthop->gate.ipv6 = *ipv6; nexthop->gate.ipv6 = *ipv6;
nexthop->ifindex = ifindex; nexthop->ifindex = ifindex;
@ -306,6 +317,7 @@ struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *re,
struct nexthop *nexthop; struct nexthop *nexthop;
nexthop = nexthop_new(); nexthop = nexthop_new();
nexthop->vrf_id = VRF_DEFAULT;
nexthop->type = NEXTHOP_TYPE_BLACKHOLE; nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
nexthop->bh_type = bh_type; nexthop->bh_type = bh_type;
@ -322,6 +334,7 @@ static void nexthop_set_resolved(afi_t afi, struct nexthop *newhop,
resolved_hop = nexthop_new(); resolved_hop = nexthop_new();
SET_FLAG(resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); SET_FLAG(resolved_hop->flags, NEXTHOP_FLAG_ACTIVE);
resolved_hop->vrf_id = nexthop->vrf_id;
switch (newhop->type) { switch (newhop->type) {
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX:
@ -403,7 +416,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
if (set) { if (set) {
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE); 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); nexthop->resolved, top);
nexthops_free(nexthop->resolved); nexthops_free(nexthop->resolved);
nexthop->resolved = NULL; nexthop->resolved = NULL;
@ -422,7 +435,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
* address in the routing table. * address in the routing table.
*/ */
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) { 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 (ifp && connected_is_unnumbered(ifp)) {
if (if_is_operative(ifp)) if (if_is_operative(ifp))
return 1; return 1;
@ -450,7 +463,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
break; break;
} }
/* Lookup table. */ /* 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) if (!table)
return 0; 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 /* However, do not resolve over default route unless explicitly
* allowed. */ * allowed. */
if (is_default_prefix(&rn->p) if (is_default_prefix(&rn->p)
&& !nh_resolve_via_default(p.family)) && !rnh_resolve_via_default(p.family))
return 0; return 0;
dest = rib_dest_from_rnode(rn); dest = rib_dest_from_rnode(rn);
@ -838,7 +851,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
family = 0; family = 0;
switch (nexthop->type) { switch (nexthop->type) {
case NEXTHOP_TYPE_IFINDEX: 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)) if (ifp && if_is_operative(ifp))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else else
@ -867,7 +880,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
family = AFI_IP6; family = AFI_IP6;
if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) {
ifp = if_lookup_by_index(nexthop->ifindex, ifp = if_lookup_by_index(nexthop->ifindex,
re->nh_vrf_id); nexthop->vrf_id);
if (ifp && if_is_operative(ifp)) if (ifp && if_is_operative(ifp))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else else
@ -910,8 +923,8 @@ static unsigned nexthop_active_check(struct route_node *rn,
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr)); memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
/* It'll get set if required inside */ /* It'll get set if required inside */
ret = zebra_route_map_check(family, re->type, p, nexthop, re->nh_vrf_id, ret = zebra_route_map_check(family, re->type, p, nexthop,
re->tag); nexthop->vrf_id, re->tag);
if (ret == RMAP_DENYMATCH) { if (ret == RMAP_DENYMATCH) {
if (IS_ZEBRA_DEBUG_RIB) { if (IS_ZEBRA_DEBUG_RIB) {
srcdest_rnode2str(rn, buf, sizeof(buf)); 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", "%u:%s: Filtering out with NH out %s due to route map",
re->vrf_id, buf, re->vrf_id, buf,
ifindex2ifname(nexthop->ifindex, ifindex2ifname(nexthop->ifindex,
re->nh_vrf_id)); nexthop->vrf_id));
} }
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); 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 rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
int type, u_short instance, int flags, struct prefix *p, int flags, struct prefix *p, struct prefix_ipv6 *src_p,
struct prefix_ipv6 *src_p, const struct nexthop *nh, const struct nexthop *nh, u_int32_t table_id, u_int32_t metric,
u_int32_t table_id, u_int32_t metric,
u_int32_t mtu, uint8_t distance, route_tag_t tag) u_int32_t mtu, uint8_t distance, route_tag_t tag)
{ {
struct route_entry *re; 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->mtu = mtu;
re->table = table_id; re->table = table_id;
re->vrf_id = vrf_id; re->vrf_id = vrf_id;
re->nh_vrf_id = nh_vrf_id;
re->nexthop_num = 0; re->nexthop_num = 0;
re->uptime = time(NULL); re->uptime = time(NULL);
re->tag = tag; re->tag = tag;

View File

@ -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 * match route to be exact if so specified
*/ */
if (is_default_prefix(&rn->p) && if (is_default_prefix(&rn->p) &&
!nh_resolve_via_default(rn->p.family)) !rnh_resolve_via_default(rn->p.family))
return NULL; return NULL;
/* Identify appropriate route entry. */ /* Identify appropriate route entry. */
@ -952,7 +952,6 @@ static void copy_state(struct rnh *rnh, struct route_entry *re,
state->distance = re->distance; state->distance = re->distance;
state->metric = re->metric; state->metric = re->metric;
state->vrf_id = re->vrf_id; state->vrf_id = re->vrf_id;
state->nh_vrf_id = re->vrf_id;
route_entry_copy_nexthops(state, re->nexthop); route_entry_copy_nexthops(state, re->nexthop);
rnh->state = state; rnh->state = state;

View File

@ -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_ip_default_route;
extern int zebra_rnh_ipv6_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, extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,
rnh_type_t type); rnh_type_t type);
extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,

View File

@ -1329,7 +1329,7 @@ route_map_result_t zebra_nht_route_map_check(int family, int client_proto,
struct nh_rmap_obj nh_obj; struct nh_rmap_obj nh_obj;
nh_obj.nexthop = nexthop; 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.source_protocol = re->type;
nh_obj.metric = re->metric; nh_obj.metric = re->metric;
nh_obj.tag = re->tag; nh_obj.tag = re->tag;

View File

@ -87,7 +87,7 @@ void static_install_route(afi_t afi, safi_t safi, struct prefix *p,
switch (si->type) { switch (si->type) {
case STATIC_IPV4_GATEWAY: case STATIC_IPV4_GATEWAY:
nexthop = route_entry_nexthop_ipv4_add( 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.family = AF_INET;
nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.prefixlen = IPV4_MAX_BITLEN;
nh_p.u.prefix4 = si->addr.ipv4; 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; break;
case STATIC_IPV4_GATEWAY_IFNAME: case STATIC_IPV4_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv4_ifindex_add( 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; break;
case STATIC_IFNAME: case STATIC_IFNAME:
nexthop = route_entry_nexthop_ifindex_add(re, nexthop = route_entry_nexthop_ifindex_add(
si->ifindex); re, si->ifindex, si->nh_vrf_id);
break; break;
case STATIC_BLACKHOLE: case STATIC_BLACKHOLE:
nexthop = route_entry_nexthop_blackhole_add( nexthop = route_entry_nexthop_blackhole_add(
re, bh_type); re, bh_type);
break; break;
case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY:
nexthop = route_entry_nexthop_ipv6_add(re, nexthop = route_entry_nexthop_ipv6_add(
&si->addr.ipv6); re, &si->addr.ipv6, si->nh_vrf_id);
nh_p.family = AF_INET6; nh_p.family = AF_INET6;
nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = si->addr.ipv6; 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; break;
case STATIC_IPV6_GATEWAY_IFNAME: case STATIC_IPV6_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv6_ifindex_add( nexthop = route_entry_nexthop_ipv6_ifindex_add(
re, &si->addr.ipv6, si->ifindex); re, &si->addr.ipv6, si->ifindex, si->nh_vrf_id);
break; break;
} }
/* Update label(s), if present. */ /* 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->metric = 0;
re->mtu = 0; re->mtu = 0;
re->vrf_id = si->vrf_id; re->vrf_id = si->vrf_id;
re->nh_vrf_id = si->nh_vrf_id;
re->table = re->table =
(si->vrf_id != VRF_DEFAULT) (si->vrf_id != VRF_DEFAULT)
? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id ? (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) { switch (si->type) {
case STATIC_IPV4_GATEWAY: case STATIC_IPV4_GATEWAY:
nexthop = route_entry_nexthop_ipv4_add( 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.family = AF_INET;
nh_p.prefixlen = IPV4_MAX_BITLEN; nh_p.prefixlen = IPV4_MAX_BITLEN;
nh_p.u.prefix4 = si->addr.ipv4; 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; break;
case STATIC_IPV4_GATEWAY_IFNAME: case STATIC_IPV4_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv4_ifindex_add( 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; break;
case STATIC_IFNAME: case STATIC_IFNAME:
nexthop = route_entry_nexthop_ifindex_add(re, nexthop = route_entry_nexthop_ifindex_add(
si->ifindex); re, si->ifindex, si->nh_vrf_id);
break; break;
case STATIC_BLACKHOLE: case STATIC_BLACKHOLE:
nexthop = route_entry_nexthop_blackhole_add( nexthop = route_entry_nexthop_blackhole_add(
re, bh_type); re, bh_type);
break; break;
case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY:
nexthop = route_entry_nexthop_ipv6_add(re, nexthop = route_entry_nexthop_ipv6_add(
&si->addr.ipv6); re, &si->addr.ipv6, si->nh_vrf_id);
nh_p.family = AF_INET6; nh_p.family = AF_INET6;
nh_p.prefixlen = IPV6_MAX_BITLEN; nh_p.prefixlen = IPV6_MAX_BITLEN;
nh_p.u.prefix6 = si->addr.ipv6; 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; break;
case STATIC_IPV6_GATEWAY_IFNAME: case STATIC_IPV6_GATEWAY_IFNAME:
nexthop = route_entry_nexthop_ipv6_ifindex_add( nexthop = route_entry_nexthop_ipv6_ifindex_add(
re, &si->addr.ipv6, si->ifindex); re, &si->addr.ipv6, si->ifindex, si->nh_vrf_id);
break; break;
} }
/* Update label(s), if present. */ /* Update label(s), if present. */

View File

@ -79,6 +79,9 @@ struct zebra_vrf {
*/ */
struct zebra_ns *zns; struct zebra_ns *zns;
/* MPLS Label to handle L3VPN <-> vrf popping */
mpls_label_t label[AFI_MAX];
/* MPLS static LSP config table */ /* MPLS static LSP config table */
struct hash *slsp_table; struct hash *slsp_table;

View File

@ -165,8 +165,8 @@ static int zebra_static_route_leak(struct vty *vty,
case -2: case -2:
vty_out(vty, vty_out(vty,
"%% Cannot use reserved label(s) (%d-%d)\n", "%% Cannot use reserved label(s) (%d-%d)\n",
MPLS_MIN_RESERVED_LABEL, MPLS_LABEL_RESERVED_MIN,
MPLS_MAX_RESERVED_LABEL); MPLS_LABEL_RESERVED_MAX);
break; break;
case -3: case -3:
vty_out(vty, vty_out(vty,
@ -458,6 +458,12 @@ DEFPY(ip_route_blackhole_vrf,
VTY_DECLVAR_CONTEXT(vrf, vrf); VTY_DECLVAR_CONTEXT(vrf, vrf);
struct zebra_vrf *zvrf = vrf->info; 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, return zebra_static_route_leak(vty, zvrf, zvrf,
AFI_IP, SAFI_UNICAST, no, prefix, AFI_IP, SAFI_UNICAST, no, prefix,
mask_str, NULL, NULL, NULL, flag, mask_str, NULL, NULL, NULL, flag,
@ -561,7 +567,11 @@ DEFPY(ip_route_address_interface_vrf,
ifname = NULL; ifname = NULL;
} }
if (nexthop_vrf)
nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
else
nh_zvrf = zvrf;
if (!nh_zvrf) { if (!nh_zvrf) {
vty_out(vty, "%% nexthop vrf %s is not defined\n", vty_out(vty, "%% nexthop vrf %s is not defined\n",
nexthop_vrf); nexthop_vrf);
@ -668,7 +678,11 @@ DEFPY(ip_route_vrf,
ifname = NULL; ifname = NULL;
} }
if (nexthop_vrf)
nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
else
nh_zvrf = zvrf;
if (!nh_zvrf) { if (!nh_zvrf) {
vty_out(vty, "%% nexthop vrf %s is not defined\n", vty_out(vty, "%% nexthop vrf %s is not defined\n",
nexthop_vrf); 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)); inet_ntoa(nexthop->gate.ipv4));
if (nexthop->ifindex) if (nexthop->ifindex)
vty_out(vty, ", via %s", vty_out(vty, ", via %s",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(
re->nh_vrf_id)); nexthop->ifindex,
nexthop->vrf_id));
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX: 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)); buf, sizeof buf));
if (nexthop->ifindex) if (nexthop->ifindex)
vty_out(vty, ", via %s", vty_out(vty, ", via %s",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(
re->nh_vrf_id)); nexthop->ifindex,
nexthop->vrf_id));
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
vty_out(vty, " directly connected, %s", vty_out(vty, " directly connected, %s",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(nexthop->ifindex,
re->nh_vrf_id)); nexthop->vrf_id));
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " unreachable"); vty_out(vty, " unreachable");
@ -801,9 +817,9 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
break; break;
} }
if (re->vrf_id != re->nh_vrf_id) { if (re->vrf_id != nexthop->vrf_id) {
struct vrf *vrf = 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); 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); nexthop->ifindex);
json_object_string_add( json_object_string_add(
json_nexthop, "interfaceName", json_nexthop, "interfaceName",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(
re->nh_vrf_id)); nexthop->ifindex,
nexthop->vrf_id));
} }
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
@ -965,8 +982,9 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
nexthop->ifindex); nexthop->ifindex);
json_object_string_add( json_object_string_add(
json_nexthop, "interfaceName", json_nexthop, "interfaceName",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(
re->nh_vrf_id)); nexthop->ifindex,
nexthop->vrf_id));
} }
break; break;
@ -979,7 +997,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
json_object_string_add( json_object_string_add(
json_nexthop, "interfaceName", json_nexthop, "interfaceName",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(nexthop->ifindex,
re->nh_vrf_id)); nexthop->vrf_id));
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
json_object_boolean_true_add(json_nexthop, 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; break;
} }
if (re->nh_vrf_id != re->vrf_id) { if (nexthop->vrf_id != re->vrf_id) {
struct vrf *vrf = struct vrf *vrf =
vrf_lookup_by_id(re->nh_vrf_id); vrf_lookup_by_id(nexthop->vrf_id);
json_object_string_add(json_nexthop, json_object_string_add(json_nexthop,
"vrf", "vrf",
@ -1121,7 +1139,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
if (nexthop->ifindex) if (nexthop->ifindex)
vty_out(vty, ", %s", vty_out(vty, ", %s",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(nexthop->ifindex,
re->nh_vrf_id)); nexthop->vrf_id));
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX: 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) if (nexthop->ifindex)
vty_out(vty, ", %s", vty_out(vty, ", %s",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(nexthop->ifindex,
re->nh_vrf_id)); nexthop->vrf_id));
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
vty_out(vty, " is directly connected, %s", vty_out(vty, " is directly connected, %s",
ifindex2ifname(nexthop->ifindex, ifindex2ifname(nexthop->ifindex,
re->nh_vrf_id)); nexthop->vrf_id));
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
vty_out(vty, " unreachable"); vty_out(vty, " unreachable");
@ -1159,9 +1177,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
break; break;
} }
if (re->nh_vrf_id != re->vrf_id) { if (nexthop->vrf_id != re->vrf_id) {
struct vrf *vrf = struct vrf *vrf = vrf_lookup_by_id(nexthop->vrf_id);
vrf_lookup_by_id(re->nh_vrf_id);
vty_out(vty, "(vrf %s)", vrf->name); vty_out(vty, "(vrf %s)", vrf->name);
} }
@ -2003,6 +2020,12 @@ DEFPY(ipv6_route_blackhole_vrf,
VTY_DECLVAR_CONTEXT(vrf, vrf); VTY_DECLVAR_CONTEXT(vrf, vrf);
struct zebra_vrf *zvrf = vrf->info; 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, return zebra_static_route_leak(vty, zvrf, zvrf,
AFI_IP6, SAFI_UNICAST, no, prefix_str, AFI_IP6, SAFI_UNICAST, no, prefix_str,
NULL, from_str, NULL, NULL, flag, 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 *zvrf = vrf->info;
struct zebra_vrf *nh_zvrf; struct zebra_vrf *nh_zvrf;
if (nexthop_vrf)
nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
else
nh_zvrf = zvrf;
if (!nh_zvrf) { if (!nh_zvrf) {
vty_out(vty, "%% nexthop vrf %s is not defined\n", vty_out(vty, "%% nexthop vrf %s is not defined\n",
nexthop_vrf); nexthop_vrf);
@ -2186,7 +2213,11 @@ DEFPY(ipv6_route_vrf,
struct zebra_vrf *zvrf = vrf->info; struct zebra_vrf *zvrf = vrf->info;
struct zebra_vrf *nh_zvrf; struct zebra_vrf *nh_zvrf;
if (nexthop_vrf)
nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf); nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
else
nh_zvrf = zvrf;
if (!nh_zvrf) { if (!nh_zvrf) {
vty_out(vty, "%% nexthop vrf %s is not defined\n", vty_out(vty, "%% nexthop vrf %s is not defined\n",
nexthop_vrf); nexthop_vrf);

View File

@ -128,7 +128,6 @@ static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni,
zebra_mac_t *zrmac); zebra_mac_t *zrmac);
/* l3-vni related APIs*/ /* l3-vni related APIs*/
static int is_vni_l3(vni_t);
static zebra_l3vni_t *zl3vni_lookup(vni_t vni); static zebra_l3vni_t *zl3vni_lookup(vni_t vni);
static void *zl3vni_alloc(void *p); static void *zl3vni_alloc(void *p);
static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id); 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); zns = zebra_ns_lookup(NS_DEFAULT);
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
vni_t vni; vni_t vni;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
struct zebra_if *zif; struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl; struct zebra_l2info_vxlan *vxl;
@ -2676,21 +2677,14 @@ static void zvni_build_hash_table()
vxl = &zif->l2info.vxl; vxl = &zif->l2info.vxl;
vni = vxl->vni; vni = vxl->vni;
if (is_vni_l3(vni)) { /* L3-VNI and L2-VNI are handled seperately */
zebra_l3vni_t *zl3vni = NULL; zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u", zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u",
ifp->name, ifp->ifindex, vni); 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 */ /* associate with vxlan_if */
zl3vni->local_vtep_ip = vxl->vtep_ip; zl3vni->local_vtep_ip = vxl->vtep_ip;
zl3vni->vxlan_if = ifp; zl3vni->vxlan_if = ifp;
@ -2706,8 +2700,6 @@ static void zvni_build_hash_table()
zebra_vxlan_process_l3vni_oper_up(zl3vni); zebra_vxlan_process_l3vni_oper_up(zl3vni);
} else { } else {
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
struct interface *vlan_if = NULL; struct interface *vlan_if = NULL;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
@ -3459,16 +3451,6 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni)
return 0; 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) static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
{ {
struct zebra_ns *zns = NULL; 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_if *zif = NULL; /* zebra_if for vxlan_if */
struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */ struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */
if (!zl3vni)
return NULL;
if (!zl3vni->vxlan_if) if (!zl3vni->vxlan_if)
return NULL; 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) static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
{ {
if (!zl3vni)
return;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("L3-VNI %u is UP - send add to BGP", zlog_debug("L3-VNI %u is UP - send add to BGP",
zl3vni->vni); 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) static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni)
{ {
if (!zl3vni)
return;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("L3-VNI %u is Down - Send del to BGP", zlog_debug("L3-VNI %u is Down - Send del to BGP",
zl3vni->vni); 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; json_object *json = NULL;
void *args[2]; void *args[2];
zebra_l3vni_t *zl3vni = NULL;
zebra_vni_t *zvni = NULL;
if (!is_evpn_enabled()) if (!is_evpn_enabled())
return; return;
@ -4593,22 +4586,10 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
args[0] = vty; args[0] = vty;
args[1] = json; args[1] = json;
if (is_vni_l3(vni)) {
zebra_l3vni_t *zl3vni = NULL;
zl3vni = zl3vni_lookup(vni); zl3vni = zl3vni_lookup(vni);
if (!zl3vni) { if (zl3vni) {
if (use_json)
vty_out(vty, "{}\n");
else
vty_out(vty, "%% VNI %u does not exist\n", vni);
return;
}
zl3vni_print(zl3vni, (void *)args); zl3vni_print(zl3vni, (void *)args);
} else { } else {
zebra_vni_t *zvni;
zvni = zvni_lookup(vni); zvni = zvni_lookup(vni);
if (!zvni) { if (!zvni) {
if (use_json) if (use_json)
@ -6018,6 +5999,8 @@ int zebra_vxlan_if_down(struct interface *ifp)
vni_t vni; vni_t vni;
struct zebra_if *zif = NULL; struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL; struct zebra_l2info_vxlan *vxl = NULL;
zebra_l3vni_t *zl3vni = NULL;
zebra_vni_t *zvni;
/* Check if EVPN is enabled. */ /* Check if EVPN is enabled. */
if (!is_evpn_enabled()) if (!is_evpn_enabled())
@ -6028,30 +6011,16 @@ int zebra_vxlan_if_down(struct interface *ifp)
vxl = &zif->l2info.vxl; vxl = &zif->l2info.vxl;
vni = vxl->vni; vni = vxl->vni;
zl3vni = zl3vni_lookup(vni);
if (is_vni_l3(vni)) { if (zl3vni) {
/* process-if-down for l3-vni */ /* process-if-down for l3-vni */
zebra_l3vni_t *zl3vni = NULL;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Intf %s(%u) L3-VNI %u is DOWN", zlog_debug("Intf %s(%u) L3-VNI %u is DOWN",
ifp->name, ifp->ifindex, vni); 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); zebra_vxlan_process_l3vni_oper_down(zl3vni);
} else { } else {
/* process if-down for l2-vni */ /* process if-down for l2-vni */
zebra_vni_t *zvni;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Intf %s(%u) L2-VNI %u is DOWN", zlog_debug("Intf %s(%u) L2-VNI %u is DOWN",
ifp->name, ifp->ifindex, vni); ifp->name, ifp->ifindex, vni);
@ -6088,6 +6057,8 @@ int zebra_vxlan_if_up(struct interface *ifp)
vni_t vni; vni_t vni;
struct zebra_if *zif = NULL; struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL; struct zebra_l2info_vxlan *vxl = NULL;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
/* Check if EVPN is enabled. */ /* Check if EVPN is enabled. */
if (!is_evpn_enabled()) if (!is_evpn_enabled())
@ -6098,23 +6069,13 @@ int zebra_vxlan_if_up(struct interface *ifp)
vxl = &zif->l2info.vxl; vxl = &zif->l2info.vxl;
vni = vxl->vni; vni = vxl->vni;
if (is_vni_l3(vni)) { zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
/* Handle L3-VNI add */
zebra_l3vni_t *zl3vni = NULL;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Intf %s(%u) L3-VNI %u is UP", zlog_debug("Intf %s(%u) L3-VNI %u is UP",
ifp->name, ifp->ifindex, vni); 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 /* we need to associate with SVI, if any, we can associate with
* svi-if only after association with vxlan-intf is complete * 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); zebra_vxlan_process_l3vni_oper_up(zl3vni);
} else { } else {
/* Handle L2-VNI add */ /* Handle L2-VNI add */
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
struct interface *vlan_if = NULL; struct interface *vlan_if = NULL;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
@ -6172,6 +6130,8 @@ int zebra_vxlan_if_del(struct interface *ifp)
vni_t vni; vni_t vni;
struct zebra_if *zif = NULL; struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL; struct zebra_l2info_vxlan *vxl = NULL;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
/* Check if EVPN is enabled. */ /* Check if EVPN is enabled. */
if (!is_evpn_enabled()) if (!is_evpn_enabled())
@ -6182,23 +6142,13 @@ int zebra_vxlan_if_del(struct interface *ifp)
vxl = &zif->l2info.vxl; vxl = &zif->l2info.vxl;
vni = vxl->vni; vni = vxl->vni;
if (is_vni_l3(vni)) { zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
/* process if-del for l3-vni */
zebra_l3vni_t *zl3vni = NULL;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Del L3-VNI %u intf %s(%u)", zlog_debug("Del L3-VNI %u intf %s(%u)",
vni, ifp->name, ifp->ifindex); 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 */ /* process oper-down for l3-vni */
zebra_vxlan_process_l3vni_oper_down(zl3vni); zebra_vxlan_process_l3vni_oper_down(zl3vni);
@ -6208,9 +6158,6 @@ int zebra_vxlan_if_del(struct interface *ifp)
} else { } else {
/* process if-del for l2-vni*/ /* process if-del for l2-vni*/
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Del L2-VNI %u intf %s(%u)", zlog_debug("Del L2-VNI %u intf %s(%u)",
vni, ifp->name, ifp->ifindex); vni, ifp->name, ifp->ifindex);
@ -6246,7 +6193,6 @@ int zebra_vxlan_if_del(struct interface *ifp)
return -1; return -1;
} }
} }
return 0; return 0;
} }
@ -6258,6 +6204,8 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
vni_t vni; vni_t vni;
struct zebra_if *zif = NULL; struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL; struct zebra_l2info_vxlan *vxl = NULL;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
/* Check if EVPN is enabled. */ /* Check if EVPN is enabled. */
if (!is_evpn_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; vxl = &zif->l2info.vxl;
vni = vxl->vni; vni = vxl->vni;
if (is_vni_l3(vni)) {
zebra_l3vni_t *zl3vni = NULL;
zl3vni = zl3vni_lookup(vni); zl3vni = zl3vni_lookup(vni);
if (!zl3vni) { if (zl3vni) {
zlog_err(
"Failed to find L3-VNI hash on update, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return -1;
}
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug( 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); zebra_vxlan_process_l3vni_oper_up(zl3vni);
} }
} else { } else {
zebra_vni_t *zvni = NULL;
/* Update VNI hash. */ /* Update VNI hash. */
zvni = zvni_lookup(vni); zvni = zvni_lookup(vni);
@ -6422,6 +6361,8 @@ int zebra_vxlan_if_add(struct interface *ifp)
vni_t vni; vni_t vni;
struct zebra_if *zif = NULL; struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL; struct zebra_l2info_vxlan *vxl = NULL;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
/* Check if EVPN is enabled. */ /* Check if EVPN is enabled. */
if (!is_evpn_enabled()) if (!is_evpn_enabled())
@ -6432,11 +6373,10 @@ int zebra_vxlan_if_add(struct interface *ifp)
vxl = &zif->l2info.vxl; vxl = &zif->l2info.vxl;
vni = vxl->vni; vni = vxl->vni;
if (is_vni_l3(vni)) { zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
/* process if-add for l3-vni*/ /* process if-add for l3-vni*/
zebra_l3vni_t *zl3vni = NULL;
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug( zlog_debug(
"Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u", "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), vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
zif->brslave_info.bridge_ifindex); 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 */ /* associate with vxlan_if */
zl3vni->local_vtep_ip = vxl->vtep_ip; zl3vni->local_vtep_ip = vxl->vtep_ip;
zl3vni->vxlan_if = ifp; zl3vni->vxlan_if = ifp;
@ -6471,8 +6397,6 @@ int zebra_vxlan_if_add(struct interface *ifp)
} else { } else {
/* process if-add for l2-vni */ /* process if-add for l2-vni */
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
struct interface *vlan_if = NULL; struct interface *vlan_if = NULL;
/* Create or update VNI hash. */ /* Create or update VNI hash. */

View File

@ -592,7 +592,6 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p,
memset(&api, 0, sizeof(api)); memset(&api, 0, sizeof(api));
api.vrf_id = re->vrf_id; api.vrf_id = re->vrf_id;
api.nh_vrf_id = re->nh_vrf_id;
api.type = re->type; api.type = re->type;
api.instance = re->instance; api.instance = re->instance;
api.flags = re->flags; api.flags = re->flags;
@ -614,6 +613,7 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p,
continue; continue;
api_nh = &api.nexthops[count]; api_nh = &api.nexthops[count];
api_nh->vrf_id = nexthop->vrf_id;
api_nh->type = nexthop->type; api_nh->type = nexthop->type;
switch (nexthop->type) { switch (nexthop->type) {
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
@ -1137,7 +1137,6 @@ static int zread_route_add(struct zserv *client, u_short length,
re->flags = api.flags; re->flags = api.flags;
re->uptime = time(NULL); re->uptime = time(NULL);
re->vrf_id = vrf_id; re->vrf_id = vrf_id;
re->nh_vrf_id = api.nh_vrf_id;
re->table = zvrf->table_id; re->table = zvrf->table_id;
if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { 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) { switch (api_nh->type) {
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
nexthop = route_entry_nexthop_ifindex_add( nexthop = route_entry_nexthop_ifindex_add(
re, api_nh->ifindex); re, api_nh->ifindex, re->vrf_id);
break; break;
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
nexthop = route_entry_nexthop_ipv4_add( nexthop = route_entry_nexthop_ipv4_add(
re, &api_nh->gate.ipv4, NULL); re, &api_nh->gate.ipv4, NULL,
re->vrf_id);
break; break;
case NEXTHOP_TYPE_IPV4_IFINDEX: { 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( nexthop = route_entry_nexthop_ipv4_ifindex_add(
re, &api_nh->gate.ipv4, NULL, re, &api_nh->gate.ipv4, NULL, ifindex,
ifindex); re->vrf_id);
/* if this an EVPN route entry, /* if this an EVPN route entry,
program the nh as neigh program the nh as neigh
@ -1192,12 +1192,12 @@ static int zread_route_add(struct zserv *client, u_short length,
} }
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
nexthop = route_entry_nexthop_ipv6_add( nexthop = route_entry_nexthop_ipv6_add(
re, &api_nh->gate.ipv6); re, &api_nh->gate.ipv6, re->vrf_id);
break; break;
case NEXTHOP_TYPE_IPV6_IFINDEX: case NEXTHOP_TYPE_IPV6_IFINDEX:
nexthop = route_entry_nexthop_ipv6_ifindex_add( nexthop = route_entry_nexthop_ipv6_ifindex_add(
re, &api_nh->gate.ipv6, re, &api_nh->gate.ipv6, api_nh->ifindex,
api_nh->ifindex); re->vrf_id);
break; break;
case NEXTHOP_TYPE_BLACKHOLE: case NEXTHOP_TYPE_BLACKHOLE:
nexthop = route_entry_nexthop_blackhole_add( nexthop = route_entry_nexthop_blackhole_add(
@ -1364,7 +1364,6 @@ static int zread_ipv4_add(struct zserv *client, u_short length,
/* VRF ID */ /* VRF ID */
re->vrf_id = zvrf_id(zvrf); re->vrf_id = zvrf_id(zvrf);
re->nh_vrf_id = zvrf_id(zvrf);
/* Nexthop parse. */ /* Nexthop parse. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { 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) { switch (nexthop_type) {
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
STREAM_GETL(s, ifindex); STREAM_GETL(s, ifindex);
route_entry_nexthop_ifindex_add(re, ifindex); route_entry_nexthop_ifindex_add(re, ifindex,
re->vrf_id);
break; break;
case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4:
STREAM_GET(&nhop_addr.s_addr, s, STREAM_GET(&nhop_addr.s_addr, s,
IPV4_MAX_BYTELEN); IPV4_MAX_BYTELEN);
nexthop = route_entry_nexthop_ipv4_add( nexthop = route_entry_nexthop_ipv4_add(
re, &nhop_addr, NULL); re, &nhop_addr, NULL, re->vrf_id);
/* For labeled-unicast, each nexthop is followed /* For labeled-unicast, each nexthop is followed
* by label. */ * by label. */
if (CHECK_FLAG(message, ZAPI_MESSAGE_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); IPV4_MAX_BYTELEN);
STREAM_GETL(s, ifindex); STREAM_GETL(s, ifindex);
route_entry_nexthop_ipv4_ifindex_add( route_entry_nexthop_ipv4_ifindex_add(
re, &nhop_addr, NULL, ifindex); re, &nhop_addr, NULL, ifindex,
re->vrf_id);
break; break;
case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6:
zlog_warn("%s: Please use ZEBRA_ROUTE_ADD if you want to pass v6 nexthops", 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 */ /* VRF ID */
re->vrf_id = zvrf_id(zvrf); 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 /* 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 * 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 = nexthop =
route_entry_nexthop_ipv6_ifindex_add( route_entry_nexthop_ipv6_ifindex_add(
re, &nexthops[i], re, &nexthops[i],
ifindices[i]); ifindices[i],
re->vrf_id);
else else
nexthop = route_entry_nexthop_ipv6_add( nexthop = route_entry_nexthop_ipv6_add(
re, &nexthops[i]); re, &nexthops[i], re->vrf_id);
if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
nexthop_add_labels(nexthop, label_type, nexthop_add_labels(nexthop, label_type,
@ -1646,7 +1647,7 @@ static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client,
} else { } else {
if ((i < if_count) && ifindices[i]) if ((i < if_count) && ifindices[i])
route_entry_nexthop_ifindex_add( 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 } else
src_pp = NULL; 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 /* 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 * to the re to ensure that IPv6 multipathing works; need to coalesce
* these. Clients should send the same number of paired set of * 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_GET(&nhop_addr, s, 16);
STREAM_GETL(s, ifindex); STREAM_GETL(s, ifindex);
route_entry_nexthop_ipv6_ifindex_add( route_entry_nexthop_ipv6_ifindex_add(
re, &nhop_addr, ifindex); re, &nhop_addr, ifindex, re->vrf_id);
break; break;
case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IFINDEX:
if (if_count < multipath_num) { if (if_count < multipath_num) {
@ -1824,17 +1828,18 @@ static int zread_ipv6_add(struct zserv *client, u_short length,
nexthop = nexthop =
route_entry_nexthop_ipv6_ifindex_add( route_entry_nexthop_ipv6_ifindex_add(
re, &nexthops[i], re, &nexthops[i],
ifindices[i]); ifindices[i],
re->vrf_id);
else else
nexthop = route_entry_nexthop_ipv6_add( nexthop = route_entry_nexthop_ipv6_add(
re, &nexthops[i]); re, &nexthops[i], re->vrf_id);
if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL)) if (CHECK_FLAG(message, ZAPI_MESSAGE_LABEL))
nexthop_add_labels(nexthop, label_type, nexthop_add_labels(nexthop, label_type,
1, &labels[i]); 1, &labels[i]);
} else { } else {
if ((i < if_count) && ifindices[i]) if ((i < if_count) && ifindices[i])
route_entry_nexthop_ifindex_add( 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 else
re->mtu = 0; re->mtu = 0;
/* VRF ID */
re->vrf_id = zvrf_id(zvrf);
re->nh_vrf_id = zvrf_id(zvrf);
re->table = zvrf->table_id; re->table = zvrf->table_id;
ret = rib_add_multipath(AFI_IP6, safi, &p, src_pp, re); ret = rib_add_multipath(AFI_IP6, safi, &p, src_pp, re);
@ -2485,6 +2486,75 @@ stream_failure:
return 1; 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, static inline void zserv_handle_commands(struct zserv *client,
uint16_t command, uint16_t command,
uint16_t length, uint16_t length,
@ -2569,6 +2639,9 @@ static inline void zserv_handle_commands(struct zserv *client,
case ZEBRA_VRF_UNREGISTER: case ZEBRA_VRF_UNREGISTER:
zread_vrf_unregister(client, length, zvrf); zread_vrf_unregister(client, length, zvrf);
break; break;
case ZEBRA_VRF_LABEL:
zread_vrf_label(client, zvrf);
break;
case ZEBRA_BFD_CLIENT_REGISTER: case ZEBRA_BFD_CLIENT_REGISTER:
zebra_ptm_bfd_client_register(client, length); zebra_ptm_bfd_client_register(client, length);
break; break;