mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 17:18:56 +00:00
Merge branch 'master' into evpn-bug-fixes
This commit is contained in:
commit
f487dcaf74
@ -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);
|
||||||
|
@ -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),
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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 \
|
||||||
|
459
bgpd/bgp_route.c
459
bgpd/bgp_route.c
@ -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));
|
||||||
|
@ -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);
|
||||||
|
134
bgpd/bgp_vty.c
134
bgpd/bgp_vty.c
@ -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);
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
73
bgpd/bgpd.c
73
bgpd/bgpd.c
@ -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,
|
||||||
|
43
bgpd/bgpd.h
43
bgpd/bgpd.h
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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],
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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));
|
||||||
|
@ -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)+)',
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
22
ldpd/lde.c
22
ldpd/lde.c
@ -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 */
|
||||||
|
@ -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:
|
||||||
|
@ -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),
|
||||||
|
63
lib/mpls.h
63
lib/mpls.h
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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",
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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. */
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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);
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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!");
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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. */
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
20
zebra/rib.h
20
zebra/rib.h
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
|
@ -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)) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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. */
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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. */
|
||||||
|
123
zebra/zserv.c
123
zebra/zserv.c
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user