Merge pull request #4850 from lkrishnamoor/show_cli

bgpd: Adding new bgp evpn cli's for ip-prefix lookup
This commit is contained in:
Russ White 2019-10-18 21:30:37 -04:00 committed by GitHub
commit 12bea6d575
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 289 additions and 147 deletions

View File

@ -4697,59 +4697,60 @@ void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json)
{ {
char buf1[ETHER_ADDR_STRLEN]; char buf1[ETHER_ADDR_STRLEN];
char buf2[PREFIX2STR_BUFFER]; char buf2[PREFIX2STR_BUFFER];
uint8_t family;
uint8_t prefixlen;
if (!json) if (!json)
return; return;
if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) { json_object_int_add(json, "routeType", p->prefix.route_type);
json_object_int_add(json, "routeType", p->prefix.route_type);
switch (p->prefix.route_type) {
case BGP_EVPN_MAC_IP_ROUTE:
json_object_int_add(json, "ethTag", json_object_int_add(json, "ethTag",
p->prefix.imet_addr.eth_tag); p->prefix.macip_addr.eth_tag);
json_object_int_add(json, "ipLen", json_object_int_add(json, "macLen", 8 * ETH_ALEN);
is_evpn_prefix_ipaddr_v4(p) json_object_string_add(json, "mac",
? IPV4_MAX_BITLEN prefix_mac2str(&p->prefix.macip_addr.mac, buf1,
: IPV6_MAX_BITLEN); sizeof(buf1)));
json_object_string_add(json, "ip",
inet_ntoa(p->prefix.imet_addr.ip.ipaddr_v4));
} else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
if (is_evpn_prefix_ipaddr_none(p)) {
json_object_int_add(json, "routeType",
p->prefix.route_type);
json_object_int_add(json, "ethTag",
p->prefix.macip_addr.eth_tag);
json_object_int_add(json, "macLen", 8 * ETH_ALEN);
json_object_string_add(json, "mac",
prefix_mac2str(&p->prefix.macip_addr.mac,
buf1,
sizeof(buf1)));
} else {
uint8_t family;
family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET if (!is_evpn_prefix_ipaddr_none(p)) {
: AF_INET6; family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET :
AF_INET6;
json_object_int_add(json, "routeType", prefixlen = (family == AF_INET) ?
p->prefix.route_type); IPV4_MAX_BITLEN : IPV6_MAX_BITLEN;
json_object_int_add(json, "ethTag", inet_ntop(family, &p->prefix.macip_addr.ip.ip.addr,
p->prefix.macip_addr.eth_tag); buf2, PREFIX2STR_BUFFER);
json_object_int_add(json, "macLen", 8 * ETH_ALEN); json_object_int_add(json, "ipLen", prefixlen);
json_object_string_add(json, "mac", json_object_string_add(json, "ip", buf2);
prefix_mac2str(&p->prefix.macip_addr.mac,
buf1,
sizeof(buf1)));
json_object_int_add(json, "ipLen",
is_evpn_prefix_ipaddr_v4(p)
? IPV4_MAX_BITLEN
: IPV6_MAX_BITLEN);
json_object_string_add(
json, "ip",
inet_ntop(family,
&p->prefix.macip_addr.ip.ip.addr,
buf2,
PREFIX2STR_BUFFER));
} }
} else { break;
/* Currently, this is to cater to other AF_ETHERNET code. */
case BGP_EVPN_IMET_ROUTE:
json_object_int_add(json, "ethTag",
p->prefix.imet_addr.eth_tag);
family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET : AF_INET6;
prefixlen = (family == AF_INET) ? IPV4_MAX_BITLEN :
IPV6_MAX_BITLEN;
inet_ntop(family, &p->prefix.imet_addr.ip.ip.addr, buf2,
PREFIX2STR_BUFFER);
json_object_int_add(json, "ipLen", prefixlen);
json_object_string_add(json, "ip", buf2);
break;
case BGP_EVPN_IP_PREFIX_ROUTE:
json_object_int_add(json, "ethTag",
p->prefix.prefix_addr.eth_tag);
family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET : AF_INET6;
inet_ntop(family, &p->prefix.prefix_addr.ip.ip.addr,
buf2, sizeof(buf2));
json_object_int_add(json, "ipLen",
p->prefix.prefix_addr.ip_prefix_length);
json_object_string_add(json, "ip", buf2);
break;
default:
break;
} }
} }
@ -6008,3 +6009,19 @@ void bgp_evpn_vrf_delete(struct bgp *bgp_vrf)
{ {
bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf); bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
} }
/*
* Get the prefixlen of the ip prefix carried within the type5 evpn route.
*/
int bgp_evpn_get_type5_prefixlen(struct prefix *pfx)
{
struct prefix_evpn *evp = (struct prefix_evpn *)pfx;
if (!pfx || pfx->family != AF_EVPN)
return 0;
if (evp->prefix.route_type != BGP_EVPN_IP_PREFIX_ROUTE)
return 0;
return evp->prefix.prefix_addr.ip_prefix_length;
}

View File

@ -190,5 +190,6 @@ extern void bgp_evpn_flood_control_change(struct bgp *bgp);
extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp); extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp);
extern void bgp_evpn_cleanup(struct bgp *bgp); extern void bgp_evpn_cleanup(struct bgp *bgp);
extern void bgp_evpn_init(struct bgp *bgp); extern void bgp_evpn_init(struct bgp *bgp);
extern int bgp_evpn_get_type5_prefixlen(struct prefix *pfx);
#endif /* _QUAGGA_BGP_EVPN_H */ #endif /* _QUAGGA_BGP_EVPN_H */

View File

@ -8227,7 +8227,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
json_nexthop_global = json_object_new_object(); json_nexthop_global = json_object_new_object();
} }
if (!json_paths && path->extra) { if (path->extra) {
char tag_buf[30]; char tag_buf[30];
buf2[0] = '\0'; buf2[0] = '\0';
@ -8238,15 +8238,21 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
sizeof(tag_buf)); sizeof(tag_buf));
} }
if (safi == SAFI_EVPN) { if (safi == SAFI_EVPN) {
bgp_evpn_route2str((struct prefix_evpn *)&bn->p, if (!json_paths) {
buf2, sizeof(buf2)); bgp_evpn_route2str((struct prefix_evpn *)&bn->p,
vty_out(vty, " Route %s", buf2); buf2, sizeof(buf2));
if (tag_buf[0] != '\0') vty_out(vty, " Route %s", buf2);
vty_out(vty, " VNI %s", tag_buf); if (tag_buf[0] != '\0')
vty_out(vty, "\n"); vty_out(vty, " VNI %s", tag_buf);
vty_out(vty, "\n");
} else {
if (tag_buf[0])
json_object_string_add(json_path, "VNI",
tag_buf);
}
} }
if (path->extra && path->extra->parent) { if (path->extra && path->extra->parent && !json_paths) {
struct bgp_path_info *parent_ri; struct bgp_path_info *parent_ri;
struct bgp_node *rn, *prn; struct bgp_node *rn, *prn;
@ -9541,37 +9547,47 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
if (has_valid_label) if (has_valid_label)
label = label_pton(&rn->local_label); label = label_pton(&rn->local_label);
if (json) { if (safi == SAFI_EVPN) {
if (has_valid_label)
json_object_int_add(json, "localLabel", label);
json_object_string_add( if (!json) {
json, "prefix",
prefix2str(p, prefix_str, sizeof(prefix_str)));
} else {
if (safi == SAFI_EVPN)
vty_out(vty, "BGP routing table entry for %s%s%s\n", vty_out(vty, "BGP routing table entry for %s%s%s\n",
prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
: "", : "", prd ? ":" : "",
prd ? ":" : "",
bgp_evpn_route2str((struct prefix_evpn *)p, bgp_evpn_route2str((struct prefix_evpn *)p,
buf3, sizeof(buf3))); buf3, sizeof(buf3)));
else } else {
json_object_string_add(json, "rd",
prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
"");
bgp_evpn_route2json((struct prefix_evpn *)p, json);
}
} else {
if (!json) {
vty_out(vty, "BGP routing table entry for %s%s%s/%d\n", vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
? prefix_rd2str(prd, buf1, ? prefix_rd2str(prd, buf1,
sizeof(buf1)) sizeof(buf1))
: ""), : ""),
safi == SAFI_MPLS_VPN ? ":" : "", safi == SAFI_MPLS_VPN ? ":" : "",
inet_ntop(p->family, &p->u.prefix, buf2, inet_ntop(p->family, &p->u.prefix, buf2,
INET6_ADDRSTRLEN), INET6_ADDRSTRLEN),
p->prefixlen); p->prefixlen);
if (has_valid_label) } else
json_object_string_add(json, "prefix",
prefix2str(p, prefix_str, sizeof(prefix_str)));
}
if (has_valid_label) {
if (json)
json_object_int_add(json, "localLabel", label);
else
vty_out(vty, "Local label: %d\n", label); vty_out(vty, "Local label: %d\n", label);
}
if (!json)
if (bgp_labeled_safi(safi) && safi != SAFI_EVPN) if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
vty_out(vty, "not allocated\n"); vty_out(vty, "not allocated\n");
}
for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) { for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
count++; count++;
@ -9703,6 +9719,58 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
} }
} }
static void bgp_show_path_info(struct prefix_rd *pfx_rd,
struct bgp_node *bgp_node, struct vty *vty,
struct bgp *bgp, afi_t afi,
safi_t safi, json_object *json,
enum bgp_path_type pathtype, int *display)
{
struct bgp_path_info *pi;
int header = 1;
char rdbuf[RD_ADDRSTRLEN];
json_object *json_header = NULL;
json_object *json_paths = NULL;
for (pi = bgp_node_get_bgp_path_info(bgp_node); pi;
pi = pi->next) {
if (json && !json_paths) {
/* Instantiate json_paths only if path is valid */
json_paths = json_object_new_array();
if (pfx_rd) {
prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
json_header = json_object_new_object();
} else
json_header = json;
}
if (header) {
route_vty_out_detail_header(
vty, bgp, bgp_node, pfx_rd,
AFI_IP, safi, json_header);
header = 0;
}
(*display)++;
if (pathtype == BGP_PATH_SHOW_ALL
|| (pathtype == BGP_PATH_SHOW_BESTPATH
&& CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
|| (pathtype == BGP_PATH_SHOW_MULTIPATH
&& (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
|| CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
route_vty_out_detail(vty, bgp, bgp_node,
pi, AFI_IP, safi,
json_paths);
}
if (json && json_paths) {
json_object_object_add(json_header, "paths", json_paths);
if (pfx_rd)
json_object_object_add(json, rdbuf, json_header);
}
}
/* Display specified route of BGP table. */ /* Display specified route of BGP table. */
static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp, static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
struct bgp_table *rib, const char *ip_str, struct bgp_table *rib, const char *ip_str,
@ -9711,12 +9779,10 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
enum bgp_path_type pathtype, bool use_json) enum bgp_path_type pathtype, bool use_json)
{ {
int ret; int ret;
int header;
int display = 0; int display = 0;
struct prefix match; struct prefix match;
struct bgp_node *rn; struct bgp_node *rn;
struct bgp_node *rm; struct bgp_node *rm;
struct bgp_path_info *pi;
struct bgp_table *table; struct bgp_table *table;
json_object *json = NULL; json_object *json = NULL;
json_object *json_paths = NULL; json_object *json_paths = NULL;
@ -9730,12 +9796,10 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
match.family = afi2family(afi); match.family = afi2family(afi);
if (use_json) { if (use_json)
json = json_object_new_object(); json = json_object_new_object();
json_paths = json_object_new_array();
}
if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) { for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0) if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
continue; continue;
@ -9743,8 +9807,6 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
if (!table) if (!table)
continue; continue;
header = 1;
if ((rm = bgp_node_match(table, &match)) == NULL) if ((rm = bgp_node_match(table, &match)) == NULL)
continue; continue;
@ -9754,73 +9816,83 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
continue; continue;
} }
for (pi = bgp_node_get_bgp_path_info(rm); pi; bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
pi = pi->next) { vty, bgp, afi, safi, json,
if (header) { pathtype, &display);
route_vty_out_detail_header(
vty, bgp, rm,
(struct prefix_rd *)&rn->p,
AFI_IP, safi, json);
header = 0;
}
display++;
if (pathtype == BGP_PATH_SHOW_ALL bgp_unlock_node(rm);
|| (pathtype == BGP_PATH_SHOW_BESTPATH }
&& CHECK_FLAG(pi->flags, } else if (safi == SAFI_EVPN) {
BGP_PATH_SELECTED)) struct bgp_node *longest_pfx;
|| (pathtype == BGP_PATH_SHOW_MULTIPATH bool is_exact_pfxlen_match = FALSE;
&& (CHECK_FLAG(pi->flags,
BGP_PATH_MULTIPATH) for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
|| CHECK_FLAG(pi->flags, if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
BGP_PATH_SELECTED)))) continue;
route_vty_out_detail(vty, bgp, rm, table = bgp_node_get_bgp_table_info(rn);
pi, AFI_IP, safi, if (!table)
json_paths); continue;
longest_pfx = NULL;
is_exact_pfxlen_match = FALSE;
/*
* Search through all the prefixes for a match. The
* pfx's are enumerated in ascending order of pfxlens.
* So, the last pfx match is the longest match. Set
* is_exact_pfxlen_match when we get exact pfxlen match
*/
for (rm = bgp_table_top(table); rm;
rm = bgp_route_next(rm)) {
/*
* Get prefixlen of the ip-prefix within type5
* evpn route
*/
if (evpn_type5_prefix_match(&rm->p,
&match) && rm->info) {
longest_pfx = rm;
int type5_pfxlen =
bgp_evpn_get_type5_prefixlen(&rm->p);
if (type5_pfxlen == match.prefixlen) {
is_exact_pfxlen_match = TRUE;
bgp_unlock_node(rm);
break;
}
}
} }
if (!longest_pfx)
continue;
if (prefix_check && !is_exact_pfxlen_match)
continue;
rm = longest_pfx;
bgp_lock_node(rm);
bgp_show_path_info((struct prefix_rd *)&rn->p, rm,
vty, bgp, afi, safi, json,
pathtype, &display);
bgp_unlock_node(rm); bgp_unlock_node(rm);
} }
} else if (safi == SAFI_FLOWSPEC) { } else if (safi == SAFI_FLOWSPEC) {
if (use_json)
json_paths = json_object_new_array();
display = bgp_flowspec_display_match_per_ip(afi, rib, display = bgp_flowspec_display_match_per_ip(afi, rib,
&match, prefix_check, &match, prefix_check,
vty, vty,
use_json, use_json,
json_paths); json_paths);
if (use_json && display)
json_object_object_add(json, "paths", json_paths);
} else { } else {
header = 1;
if ((rn = bgp_node_match(rib, &match)) != NULL) { if ((rn = bgp_node_match(rib, &match)) != NULL) {
if (!prefix_check if (!prefix_check
|| rn->p.prefixlen == match.prefixlen) { || rn->p.prefixlen == match.prefixlen) {
for (pi = bgp_node_get_bgp_path_info(rn); pi; bgp_show_path_info(NULL, rn, vty, bgp, afi,
pi = pi->next) { safi, json,
if (header) { pathtype, &display);
route_vty_out_detail_header(
vty, bgp, rn, NULL, afi,
safi, json);
header = 0;
}
display++;
if (pathtype == BGP_PATH_SHOW_ALL
|| (pathtype
== BGP_PATH_SHOW_BESTPATH
&& CHECK_FLAG(
pi->flags,
BGP_PATH_SELECTED))
|| (pathtype
== BGP_PATH_SHOW_MULTIPATH
&& (CHECK_FLAG(
pi->flags,
BGP_PATH_MULTIPATH)
|| CHECK_FLAG(
pi->flags,
BGP_PATH_SELECTED))))
route_vty_out_detail(
vty, bgp, rn, pi,
afi, safi, json_paths);
}
} }
bgp_unlock_node(rn); bgp_unlock_node(rn);
@ -9828,11 +9900,9 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
} }
if (use_json) { if (use_json) {
if (display)
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_C_TO_STRING_NOSLASHESCAPE));
json_object_free(json); json_object_free(json);
} else { } else {
if (!display) { if (!display) {
@ -11025,32 +11095,37 @@ DEFUN (show_ip_bgp_vpn_all_route_prefix,
} }
#endif /* KEEP_OLD_VPN_COMMANDS */ #endif /* KEEP_OLD_VPN_COMMANDS */
DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix, DEFUN (show_bgp_l2vpn_evpn_route_prefix,
show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd, show_bgp_l2vpn_evpn_route_prefix_cmd,
"show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]", "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
SHOW_STR SHOW_STR
IP_STR
BGP_STR BGP_STR
L2VPN_HELP_STR L2VPN_HELP_STR
EVPN_HELP_STR EVPN_HELP_STR
"Display information about all EVPN NLRIs\n" "Network in the BGP routing table to display\n"
"Network in the BGP routing table to display\n"
"Network in the BGP routing table to display\n" "Network in the BGP routing table to display\n"
"Network in the BGP routing table to display\n" "Network in the BGP routing table to display\n"
JSON_STR) JSON_STR)
{ {
int idx = 0; int idx = 0;
char *network = NULL; char *network = NULL;
int prefix_check = 0;
if (argv_find(argv, argc, "A.B.C.D", &idx)) if (argv_find(argv, argc, "A.B.C.D", &idx) ||
argv_find(argv, argc, "X:X::X:X", &idx))
network = argv[idx]->arg; network = argv[idx]->arg;
else if (argv_find(argv, argc, "A.B.C.D/M", &idx)) else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
argv_find(argv, argc, "A.B.C.D/M", &idx)) {
network = argv[idx]->arg; network = argv[idx]->arg;
else { prefix_check = 1;
} else {
vty_out(vty, "Unable to figure out Network\n"); vty_out(vty, "Unable to figure out Network\n");
return CMD_WARNING; return CMD_WARNING;
} }
return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0, return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
BGP_PATH_SHOW_ALL, use_json(argc, argv)); prefix_check, BGP_PATH_SHOW_ALL,
use_json(argc, argv));
} }
static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
@ -12547,7 +12622,7 @@ void bgp_route_init(void)
#endif /* KEEP_OLD_VPN_COMMANDS */ #endif /* KEEP_OLD_VPN_COMMANDS */
install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd); install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
install_element(VIEW_NODE, install_element(VIEW_NODE,
&show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd); &show_bgp_l2vpn_evpn_route_prefix_cmd);
/* BGP dampening clear commands */ /* BGP dampening clear commands */
install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd); install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);

View File

@ -601,6 +601,53 @@ int prefix_match(const struct prefix *n, const struct prefix *p)
if (np[offset] != pp[offset]) if (np[offset] != pp[offset])
return 0; return 0;
return 1; return 1;
}
/*
* n is a type5 evpn prefix. This function tries to see if there is an
* ip-prefix within n which matches prefix p
* If n includes p prefix then return 1 else return 0.
*/
int evpn_type5_prefix_match(const struct prefix *n, const struct prefix *p)
{
int offset;
int shift;
int prefixlen;
const uint8_t *np, *pp;
struct prefix_evpn *evp;
if (n->family != AF_EVPN)
return 0;
evp = (struct prefix_evpn *)n;
pp = p->u.val;
if ((evp->prefix.route_type != 5) ||
(p->family == AF_INET6 && !is_evpn_prefix_ipaddr_v6(evp)) ||
(p->family == AF_INET && !is_evpn_prefix_ipaddr_v4(evp)) ||
(is_evpn_prefix_ipaddr_none(evp)))
return 0;
prefixlen = evp->prefix.prefix_addr.ip_prefix_length;
np = &evp->prefix.prefix_addr.ip.ip.addr;
/* If n's prefix is longer than p's one return 0. */
if (prefixlen > p->prefixlen)
return 0;
offset = prefixlen / PNBBY;
shift = prefixlen % PNBBY;
if (shift)
if (maskbit[shift] & (np[offset] ^ pp[offset]))
return 0;
while (offset--)
if (np[offset] != pp[offset])
return 0;
return 1;
} }
/* If n includes p then return 1 else return 0. Prefix mask is not considered */ /* If n includes p then return 1 else return 0. Prefix mask is not considered */

View File

@ -407,6 +407,8 @@ extern void prefix_mcast_inet4_dump(const char *onfail, struct in_addr addr,
char *buf, int buf_size); char *buf, int buf_size);
extern const char *prefix_sg2str(const struct prefix_sg *sg, char *str); extern const char *prefix_sg2str(const struct prefix_sg *sg, char *str);
extern const char *prefix2str(union prefixconstptr, char *, int); extern const char *prefix2str(union prefixconstptr, char *, int);
extern int evpn_type5_prefix_match(const struct prefix *evpn_pfx,
const struct prefix *match_pfx);
extern int prefix_match(const struct prefix *, const struct prefix *); extern int prefix_match(const struct prefix *, const struct prefix *);
extern int prefix_match_network_statement(const struct prefix *, extern int prefix_match_network_statement(const struct prefix *,
const struct prefix *); const struct prefix *);