summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/Makefile.am1
-rw-r--r--bgpd/bgp_debug.c69
-rw-r--r--bgpd/bgp_evpn_vty.c36
-rw-r--r--bgpd/bgp_mplsvpn.c20
-rw-r--r--bgpd/bgp_route.c4
-rw-r--r--bgpd/bgp_routemap.c8
-rw-r--r--bgpd/bgp_vty.c2
-rw-r--r--bgpd/rfapi/bgp_rfapi_cfg.c8
-rw-r--r--bgpd/rfapi/rfapi_vty.c4
-rw-r--r--debian/frr.logrotate2
-rw-r--r--lib/bfd.c2
-rw-r--r--lib/command.h1
-rw-r--r--lib/command_lex.l6
-rw-r--r--lib/command_match.c1
-rw-r--r--lib/libfrr.c2
-rw-r--r--pimd/pim_cmd.c86
-rw-r--r--pimd/pim_iface.c3
-rw-r--r--pimd/pim_iface.h3
-rw-r--r--pimd/pim_igmp.c24
-rw-r--r--pimd/pim_igmpv3.c19
-rw-r--r--pimd/pim_join.c18
-rw-r--r--pimd/pim_rp.c3
-rw-r--r--pimd/pim_util.c19
-rw-r--r--pimd/pim_util.h3
-rw-r--r--pimd/pim_vty.c9
-rwxr-xr-xtools/frr-reload.py15
-rw-r--r--vtysh/vtysh_main.c4
-rw-r--r--watchfrr/watchfrr_vty.c23
-rw-r--r--zebra/debug.c10
-rw-r--r--zebra/rib.h2
-rw-r--r--zebra/zebra_rib.c9
-rw-r--r--zebra/zebra_vty.c186
32 files changed, 425 insertions, 177 deletions
diff --git a/bgpd/Makefile.am b/bgpd/Makefile.am
index 0ec5a778bb..1f2602c059 100644
--- a/bgpd/Makefile.am
+++ b/bgpd/Makefile.am
@@ -119,7 +119,6 @@ dist_examples_DATA = bgpd.conf.sample bgpd.conf.sample2 \
bgpd.conf.vnc.sample
bgp_vty.o: bgp_vty_clippy.c
-bgp_debug.o: bgp_debug_clippy.c
EXTRA_DIST = BGP4-MIB.txt
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index c1c4f2b39c..6de9ba3cc6 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -865,39 +865,42 @@ DEFUN (no_debug_bgp_keepalive_peer,
return CMD_SUCCESS;
}
-#ifndef VTYSH_EXTRACT_PL
-#include "bgp_debug_clippy.c"
-#endif
-
/* debug bgp bestpath */
-DEFPY (debug_bgp_bestpath_prefix,
+DEFUN (debug_bgp_bestpath_prefix,
debug_bgp_bestpath_prefix_cmd,
- "debug bgp bestpath <A.B.C.D/M|X:X::X:X/M>$bestpath",
+ "debug bgp bestpath <A.B.C.D/M|X:X::X:X/M>",
DEBUG_STR
BGP_STR
"BGP bestpath\n"
"IPv4 prefix\n"
"IPv6 prefix\n")
{
+ struct prefix *argv_p;
+ int idx_ipv4_ipv6_prefixlen = 3;
+
+ argv_p = prefix_new();
+ (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
+ apply_mask(argv_p);
+
if (!bgp_debug_bestpath_prefixes)
bgp_debug_bestpath_prefixes = list_new();
if (bgp_debug_list_has_entry(bgp_debug_bestpath_prefixes, NULL,
- bestpath)) {
+ argv_p)) {
vty_out(vty,
"BGP bestpath debugging is already enabled for %s\n",
- bestpath_str);
+ argv[idx_ipv4_ipv6_prefixlen]->arg);
return CMD_SUCCESS;
}
- bgp_debug_list_add_entry(bgp_debug_bestpath_prefixes, NULL, bestpath);
+ bgp_debug_list_add_entry(bgp_debug_bestpath_prefixes, NULL, argv_p);
if (vty->node == CONFIG_NODE) {
DEBUG_ON(bestpath, BESTPATH);
} else {
TERM_DEBUG_ON(bestpath, BESTPATH);
vty_out(vty, "BGP bestpath debugging is on for %s\n",
- bestpath_str);
+ argv[idx_ipv4_ipv6_prefixlen]->arg);
}
return CMD_SUCCESS;
@@ -916,15 +919,10 @@ DEFUN (no_debug_bgp_bestpath_prefix,
int idx_ipv4_ipv6_prefixlen = 4;
struct prefix *argv_p;
int found_prefix = 0;
- int ret;
argv_p = prefix_new();
- ret = str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
- if (!ret) {
- prefix_free(argv_p);
- vty_out(vty, "%% Malformed Prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
+ apply_mask(argv_p);
if (bgp_debug_bestpath_prefixes
&& !list_isempty(bgp_debug_bestpath_prefixes)) {
@@ -1267,16 +1265,10 @@ DEFUN (debug_bgp_update_prefix,
{
int idx_ipv4_ipv6_prefixlen = 4;
struct prefix *argv_p;
- int ret;
argv_p = prefix_new();
- ret = str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
- if (!ret) {
- prefix_free(argv_p);
- vty_out(vty, "%% Malformed Prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
+ (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
+ apply_mask(argv_p);
if (!bgp_debug_update_prefixes)
bgp_debug_update_prefixes = list_new();
@@ -1315,15 +1307,10 @@ DEFUN (no_debug_bgp_update_prefix,
int idx_ipv4_ipv6_prefixlen = 5;
struct prefix *argv_p;
int found_prefix = 0;
- int ret;
argv_p = prefix_new();
- ret = str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
- if (!ret) {
- prefix_free(argv_p);
- vty_out(vty, "%% Malformed Prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
+ apply_mask(argv_p);
if (bgp_debug_update_prefixes
&& !list_isempty(bgp_debug_update_prefixes)) {
@@ -1411,15 +1398,10 @@ DEFUN (debug_bgp_zebra_prefix,
{
int idx_ipv4_ipv6_prefixlen = 4;
struct prefix *argv_p;
- int ret;
argv_p = prefix_new();
- ret = str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
- if (!ret) {
- prefix_free(argv_p);
- vty_out(vty, "%% Malformed Prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
+ apply_mask(argv_p);
if (!bgp_debug_zebra_prefixes)
bgp_debug_zebra_prefixes = list_new();
@@ -1476,15 +1458,10 @@ DEFUN (no_debug_bgp_zebra_prefix,
int idx_ipv4_ipv6_prefixlen = 5;
struct prefix *argv_p;
int found_prefix = 0;
- int ret;
argv_p = prefix_new();
- ret = str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
- if (!ret) {
- prefix_free(argv_p);
- vty_out(vty, "%% Malformed Prefix\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ (void)str2prefix(argv[idx_ipv4_ipv6_prefixlen]->arg, argv_p);
+ apply_mask(argv_p);
if (bgp_debug_zebra_prefixes
&& !list_isempty(bgp_debug_zebra_prefixes)) {
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 7ae77aede5..7454aec892 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -723,7 +723,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn,
DEFUN(show_ip_bgp_l2vpn_evpn_rd,
show_ip_bgp_l2vpn_evpn_rd_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn [json]",
+ "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -736,7 +736,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd,
int ret;
struct prefix_rd prd;
- argv_find(argv, argc, "ASN:nn_or_IP-address:nn", &idx_ext_community);
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
@@ -764,7 +764,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_tags,
DEFUN(show_ip_bgp_l2vpn_evpn_rd_tags,
show_ip_bgp_l2vpn_evpn_rd_tags_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn tags",
+ "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN tags",
SHOW_STR
IP_STR
BGP_STR
@@ -777,7 +777,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_tags,
int ret;
struct prefix_rd prd;
- argv_find(argv, argc, "ASN:nn_or_IP-address:nn", &idx_ext_community);
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
@@ -847,7 +847,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_routes,
DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes,
show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
+ "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -867,7 +867,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes,
struct prefix_rd prd;
u_char uj = use_json(argc, argv);
- argv_find(argv, argc, "ASN:nn_or_IP-address:nn", &idx_ext_community);
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
argv_find(argv, argc, "A.B.C.D", &idx_ipv4);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
@@ -978,7 +978,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes,
DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
+ "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -998,7 +998,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
union sockunion su;
u_char uj = use_json(argc, argv);
- argv_find(argv, argc, "ASN:nn_or_IP-address:nn", &idx_ext_community);
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
argv_find(argv, argc, "A.B.C.D", &idx_ipv4);
ret = str2sockunion(argv[idx_ipv4]->arg, &su);
@@ -1068,7 +1068,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_overlay,
DEFUN(show_ip_bgp_evpn_rd_overlay,
show_ip_bgp_evpn_rd_overlay_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn overlay",
+ "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN overlay",
SHOW_STR
IP_STR
BGP_STR
@@ -1082,7 +1082,7 @@ DEFUN(show_ip_bgp_evpn_rd_overlay,
int ret;
struct prefix_rd prd;
- argv_find(argv, argc, "ASN:nn_or_IP-address:nn", &idx_ext_community);
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
@@ -1097,7 +1097,7 @@ DEFUN(show_ip_bgp_evpn_rd_overlay,
/* For testing purpose, static route of MPLS-VPN. */
DEFUN(evpnrt5_network,
evpnrt5_network_cmd,
- "network <A.B.C.D/M|X:X::X:X/M> rd ASN:nn_or_IP-address:nn ethtag WORD label WORD esi WORD gwip <A.B.C.D|X:X::X:X> routermac WORD [route-map WORD]",
+ "network <A.B.C.D/M|X:X::X:X/M> rd ASN:NN_OR_IP-ADDRESS:NN ethtag WORD label WORD esi WORD gwip <A.B.C.D|X:X::X:X> routermac WORD [route-map WORD]",
"Specify a network to announce via BGP\n"
"IP prefix\n"
"IPv6 prefix\n"
@@ -1137,7 +1137,7 @@ DEFUN(evpnrt5_network,
/* For testing purpose, static route of MPLS-VPN. */
DEFUN(no_evpnrt5_network,
no_evpnrt5_network_cmd,
- "no network <A.B.C.D/M|X:X::X:X/M> rd ASN:nn_or_IP-address:nn ethtag WORD label WORD esi WORD gwip <A.B.C.D|X:X::X:X>",
+ "no network <A.B.C.D/M|X:X::X:X/M> rd ASN:NN_OR_IP-ADDRESS:NN ethtag WORD label WORD esi WORD gwip <A.B.C.D|X:X::X:X>",
NO_STR
"Specify a network to announce via BGP\n"
"IP prefix\n"
@@ -2388,7 +2388,7 @@ DEFUN(show_bgp_l2vpn_evpn_route,
*/
DEFUN(show_bgp_l2vpn_evpn_route_rd,
show_bgp_l2vpn_evpn_route_rd_cmd,
- "show bgp l2vpn evpn route rd ASN:nn_or_IP-address:nn [type <macip|multicast>] [json]",
+ "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|multicast>] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -2456,7 +2456,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
*/
DEFUN(show_bgp_l2vpn_evpn_route_rd_macip,
show_bgp_l2vpn_evpn_route_rd_macip_cmd,
- "show bgp l2vpn evpn route rd ASN:nn_or_IP-address:nn mac WORD [ip WORD] [json]",
+ "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -2841,7 +2841,7 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route, show_bgp_evpn_route_cmd,
ALIAS_HIDDEN(
show_bgp_l2vpn_evpn_route_rd, show_bgp_evpn_route_rd_cmd,
- "show bgp evpn route rd ASN:nn_or_IP-address:nn [type <macip|multicast>]",
+ "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|multicast>]",
SHOW_STR BGP_STR EVPN_HELP_STR
"EVPN route information\n"
"Route Distinguisher\n"
@@ -2852,7 +2852,7 @@ ALIAS_HIDDEN(
ALIAS_HIDDEN(
show_bgp_l2vpn_evpn_route_rd_macip, show_bgp_evpn_route_rd_macip_cmd,
- "show bgp evpn route rd ASN:nn_or_IP-address:nn mac WORD [ip WORD]",
+ "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD]",
SHOW_STR BGP_STR EVPN_HELP_STR
"EVPN route information\n"
"Route Distinguisher\n"
@@ -2980,7 +2980,7 @@ DEFUN_NOSH (exit_vni,
DEFUN (bgp_evpn_vni_rd,
bgp_evpn_vni_rd_cmd,
- "rd ASN:nn_or_IP-address:nn",
+ "rd ASN:NN_OR_IP-ADDRESS:NN",
"Route Distinguisher\n"
"ASN:XX or A.B.C.D:XX\n")
{
@@ -3009,7 +3009,7 @@ DEFUN (bgp_evpn_vni_rd,
DEFUN (no_bgp_evpn_vni_rd,
no_bgp_evpn_vni_rd_cmd,
- "no rd ASN:nn_or_IP-address:nn",
+ "no rd ASN:NN_OR_IP-ADDRESS:NN",
NO_STR
"Route Distinguisher\n"
"ASN:XX or A.B.C.D:XX\n")
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index baf081c815..694cb14790 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -236,7 +236,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
/* For testing purpose, static route of MPLS-VPN. */
DEFUN (vpnv4_network,
vpnv4_network_cmd,
- "network A.B.C.D/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575)",
+ "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
"Specify a network to announce via BGP\n"
"IPv4 prefix\n"
"Specify Route Distinguisher\n"
@@ -256,7 +256,7 @@ DEFUN (vpnv4_network,
DEFUN (vpnv4_network_route_map,
vpnv4_network_route_map_cmd,
- "network A.B.C.D/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575) route-map WORD",
+ "network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) route-map WORD",
"Specify a network to announce via BGP\n"
"IPv4 prefix\n"
"Specify Route Distinguisher\n"
@@ -280,7 +280,7 @@ DEFUN (vpnv4_network_route_map,
/* For testing purpose, static route of MPLS-VPN. */
DEFUN (no_vpnv4_network,
no_vpnv4_network_cmd,
- "no network A.B.C.D/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575)",
+ "no network A.B.C.D/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
NO_STR
"Specify a network to announce via BGP\n"
"IPv4 prefix\n"
@@ -301,7 +301,7 @@ DEFUN (no_vpnv4_network,
DEFUN (vpnv6_network,
vpnv6_network_cmd,
- "network X:X::X:X/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575) [route-map WORD]",
+ "network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575) [route-map WORD]",
"Specify a network to announce via BGP\n"
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
"Specify Route Distinguisher\n"
@@ -331,7 +331,7 @@ DEFUN (vpnv6_network,
/* For testing purpose, static route of MPLS-VPN. */
DEFUN (no_vpnv6_network,
no_vpnv6_network_cmd,
- "no network X:X::X:X/M rd ASN:nn_or_IP-address:nn <tag|label> (0-1048575)",
+ "no network X:X::X:X/M rd ASN:NN_OR_IP-ADDRESS:NN <tag|label> (0-1048575)",
NO_STR
"Specify a network to announce via BGP\n"
"IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
@@ -632,7 +632,7 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
DEFUN (show_bgp_ip_vpn_all_rd,
show_bgp_ip_vpn_all_rd_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:nn_or_IP-address:nn] [json]",
+ "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -670,7 +670,7 @@ DEFUN (show_bgp_ip_vpn_all_rd,
DEFUN (show_ip_bgp_vpn_rd,
show_ip_bgp_vpn_rd_cmd,
- "show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn",
+ "show [ip] bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
SHOW_STR
IP_STR
BGP_STR
@@ -736,7 +736,7 @@ DEFUN (show_ip_bgp_vpn_all_tags,
DEFUN (show_ip_bgp_vpn_rd_tags,
show_ip_bgp_vpn_rd_tags_cmd,
- "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn tags",
+ "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
SHOW_STR
IP_STR
BGP_STR
@@ -826,7 +826,7 @@ DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
show_ip_bgp_vpn_rd_neighbor_routes_cmd,
- "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]",
+ "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -966,7 +966,7 @@ DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
- "show [ip] bgp <vpnv4|vpnv6> rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]",
+ "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
SHOW_STR
IP_STR
BGP_STR
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 44b3c5c348..b9f23a387e 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -7841,7 +7841,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
"bestpathFromAs", first_as);
} else {
if (first_as)
- vty_out(vty, ", bestpath-from-AS %d",
+ vty_out(vty, ", bestpath-from-AS %u",
first_as);
else
vty_out(vty,
@@ -10480,7 +10480,7 @@ struct bgp_distance {
DEFUN (show_bgp_afi_vpn_rd_route,
show_bgp_afi_vpn_rd_route_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn <A.B.C.D/M|X:X::X:X/M> [json]",
+ "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN <A.B.C.D/M|X:X::X:X/M> [json]",
SHOW_STR
BGP_STR
BGP_AFI_HELP_STR
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index f5663e9262..bb3def2fbe 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -3972,7 +3972,7 @@ DEFUN (no_set_lcommunity_delete,
DEFUN (set_ecommunity_rt,
set_ecommunity_rt_cmd,
- "set extcommunity rt ASN:nn_or_IP-address:nn...",
+ "set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
SET_STR
"BGP extended community attribute\n"
"Route Target extended community\n"
@@ -3992,7 +3992,7 @@ DEFUN (set_ecommunity_rt,
DEFUN (no_set_ecommunity_rt,
no_set_ecommunity_rt_cmd,
- "no set extcommunity rt ASN:nn_or_IP-address:nn...",
+ "no set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
NO_STR
SET_STR
"BGP extended community attribute\n"
@@ -4006,7 +4006,7 @@ DEFUN (no_set_ecommunity_rt,
DEFUN (set_ecommunity_soo,
set_ecommunity_soo_cmd,
- "set extcommunity soo ASN:nn_or_IP-address:nn...",
+ "set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
SET_STR
"BGP extended community attribute\n"
"Site-of-Origin extended community\n"
@@ -4026,7 +4026,7 @@ DEFUN (set_ecommunity_soo,
DEFUN (no_set_ecommunity_soo,
no_set_ecommunity_soo_cmd,
- "no set extcommunity soo ASN:nn_or_IP-address:nn...",
+ "no set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
NO_STR
SET_STR
"BGP extended community attribute\n"
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index f9105bfaf7..4ddb499821 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -9868,7 +9868,7 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
/* "show [ip] bgp neighbors" commands. */
DEFUN (show_ip_bgp_neighbors,
show_ip_bgp_neighbors_cmd,
- "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|vpnv4 <all|rd ASN:nn_or_IP-address:nn>>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]",
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|vpnv4 <all|rd ASN:NN_OR_IP-ADDRESS:NN>>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]",
SHOW_STR
IP_STR
BGP_STR
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c
index 91a3744315..3dffb59d11 100644
--- a/bgpd/rfapi/bgp_rfapi_cfg.c
+++ b/bgpd/rfapi/bgp_rfapi_cfg.c
@@ -385,7 +385,7 @@ DEFUN (vnc_defaults_rt_both,
DEFUN (vnc_defaults_rd,
vnc_defaults_rd_cmd,
- "rd ASN:nn_or_IP-address:nn",
+ "rd ASN:NN_OR_IP-ADDRESS:NN",
"Specify default route distinguisher\n"
"Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
{
@@ -2841,7 +2841,7 @@ DEFUN (vnc_nve_group_no_l2rd,
DEFUN (vnc_nve_group_rd,
vnc_nve_group_rd_cmd,
- "rd ASN:nn_or_IP-address:nn",
+ "rd ASN:NN_OR_IP-ADDRESS:NN",
"Specify route distinguisher\n"
"Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")
{
@@ -3295,7 +3295,7 @@ DEFUN (vnc_vrf_policy_rt_both,
DEFUN (vnc_vrf_policy_rd,
vnc_vrf_policy_rd_cmd,
- "rd ASN:nn_or_IP-address:nn",
+ "rd ASN:NN_OR_IP-ADDRESS:NN",
"Specify default VRF route distinguisher\n"
"Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:nh:<number> )\n")
{
@@ -3562,7 +3562,7 @@ DEFUN (vnc_l2_group_no_labels,
DEFUN (vnc_l2_group_rt,
vnc_l2_group_rt_cmd,
- "rt <both|export|import> ASN:nn_or_IP-address:nn",
+ "rt <both|export|import> ASN:NN_OR_IP-ADDRESS:NN",
"Specify route targets\n"
"Export+import filters\n"
"Export filters\n"
diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c
index 8d1b2b974e..c6958237a3 100644
--- a/bgpd/rfapi/rfapi_vty.c
+++ b/bgpd/rfapi/rfapi_vty.c
@@ -4791,7 +4791,7 @@ static int vnc_add_vrf_prefix(struct vty *vty, const char *arg_vrf,
DEFUN (add_vrf_prefix_rd_label_pref,
add_vrf_prefix_rd_label_pref_cmd,
- "add vrf NAME prefix <A.B.C.D/M|X:X::X:X/M> [{rd ASN:nn_or_IP-address|label (0-1048575)|preference (0-4294967295)}]",
+ "add vrf NAME prefix <A.B.C.D/M|X:X::X:X/M> [{rd ASN:NN_OR_IP-ADDRESS|label (0-1048575)|preference (0-4294967295)}]",
"Add\n"
"To a VRF\n"
"VRF name\n"
@@ -4914,7 +4914,7 @@ static int vnc_clear_vrf(struct vty *vty, struct bgp *bgp, const char *arg_vrf,
DEFUN (clear_vrf_prefix_rd,
clear_vrf_prefix_rd_cmd,
- "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:nn_or_IP-address]",
+ "clear vrf NAME [prefix <A.B.C.D/M|X:X::X:X/M>] [rd ASN:NN_OR_IP-ADDRESS]",
"Clear stored data\n"
"From a VRF\n"
"VRF name\n"
diff --git a/debian/frr.logrotate b/debian/frr.logrotate
index 9a1fa2149b..2b4acd89c7 100644
--- a/debian/frr.logrotate
+++ b/debian/frr.logrotate
@@ -22,6 +22,6 @@
pids="$pids $(cat /var/run/frr/$i.pid)"
fi
done
- [ -n "$pids" ] && kill -USR1 $pids
+ [ -n "$pids" ] && kill -USR1 $pids || true
endscript
}
diff --git a/lib/bfd.c b/lib/bfd.c
index e8df42a1bd..d51b9f1e63 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -367,7 +367,7 @@ void bfd_show_param(struct vty *vty, struct bfd_info *bfd_info, int bfd_tag,
json_bfd);
} else {
vty_out(vty,
- " %s%sDetect Mul: %d, Min Rx interval: %d,"
+ " %s%sDetect Multiplier: %d, Min Rx interval: %d,"
" Min Tx interval: %d\n",
(extra_space) ? " " : "", (bfd_tag) ? "BFD: " : " ",
bfd_info->detect_mult, bfd_info->required_min_rx,
diff --git a/lib/command.h b/lib/command.h
index 1c6938523c..8cccb62de3 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -357,6 +357,7 @@ struct cmd_node {
#define OSPF_RI_STR "OSPF Router Information specific commands\n"
#define PCE_STR "PCE Router Information specific commands\n"
#define MPLS_STR "MPLS information\n"
+#define WATCHFRR_STR "watchfrr information\n"
#define CONF_BACKUP_EXT ".sav"
diff --git a/lib/command_lex.l b/lib/command_lex.l
index 59d0d840a8..436f3a241d 100644
--- a/lib/command_lex.l
+++ b/lib/command_lex.l
@@ -35,14 +35,14 @@
} } while(0)
%}
-WORD (\-|\+)?[a-z0-9\*][-+_a-zA-Z0-9\*]*
IPV4 A\.B\.C\.D
IPV4_PREFIX A\.B\.C\.D\/M
IPV6 X:X::X:X
IPV6_PREFIX X:X::X:X\/M
MAC M:A:C
MAC_PREFIX M:A:C\/M
-VARIABLE [A-Z][-_a-zA-Z:0-9]+
+VARIABLE [A-Z][-_A-Z:0-9]+
+WORD (\-|\+)?[a-zA-Z0-9\*][-+_a-zA-Z0-9\*]*
NUMBER (\-|\+)?[0-9]{1,20}
RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
@@ -64,7 +64,6 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
%}
[ \t]+ LOC_STEP /* ignore whitespace */;
-{WORD} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return WORD;}
{IPV4} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV4;}
{IPV4_PREFIX} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV4_PREFIX;}
{IPV6} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return IPV6;}
@@ -72,6 +71,7 @@ RANGE \({NUMBER}[ ]?\-[ ]?{NUMBER}\)
{MAC} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return MAC;}
{MAC_PREFIX} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return MAC_PREFIX;}
{VARIABLE} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return VARIABLE;}
+{WORD} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return WORD;}
{RANGE} {yylval->string = XSTRDUP(MTYPE_LEX, yytext); return RANGE;}
. {return yytext[0];}
%%
diff --git a/lib/command_match.c b/lib/command_match.c
index 62e7c63068..6384abe5ce 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -214,6 +214,7 @@ static enum matcher_rv command_match_r(struct graph_node *start, vector vline,
fprintf(stdout, "\"%-20s\" matches \"%-30s\" ? ", input_token,
token->text);
enum match_type mt = match_token(token, input_token);
+ fprintf(stdout, "type: %d ", token->type);
fprintf(stdout, "min: %d - ", minmatch);
switch (mt) {
case trivial_match:
diff --git a/lib/libfrr.c b/lib/libfrr.c
index d5078f98aa..2859f062c1 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -534,7 +534,7 @@ struct thread_master *frr_init(void)
snprintf(p_pathspace, sizeof(p_pathspace), "/%s",
di->pathspace);
- snprintf(config_default, sizeof(config_default), "%s%s/%s%s.conf",
+ snprintf(config_default, sizeof(config_default), "%s%s%s%s.conf",
frr_sysconfdir, p_pathspace, di->name, p_instance);
snprintf(pidfile_default, sizeof(pidfile_default), "%s%s/%s%s.pid",
frr_vtydir, p_pathspace, di->name, p_instance);
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 396b949e4f..144785a5cd 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -4451,7 +4451,8 @@ DEFUN (show_ip_multicast_vrf_all,
return CMD_SUCCESS;
}
-static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj)
+static void show_mroute(struct pim_instance *pim, struct vty *vty,
+ bool fill, u_char uj)
{
struct listnode *node;
struct channel_oil *c_oil;
@@ -4704,11 +4705,9 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj)
continue;
ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index);
- pim_time_uptime(
- oif_uptime, sizeof(oif_uptime),
- now
- - s_route->c_oil
- .oif_creation[oif_vif_index]);
+ pim_time_uptime(oif_uptime, sizeof(oif_uptime),
+ now -
+ s_route->c_oil.oif_creation[oif_vif_index]);
found_oif = 1;
if (ifp_out)
@@ -4751,7 +4750,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj)
src_str, grp_str, proto, in_ifname,
out_ifname, ttl, oif_uptime,
pim->vrf->name);
- if (first) {
+ if (first && !fill) {
src_str[0] = '\0';
grp_str[0] = '\0';
in_ifname[0] = '\0';
@@ -4777,36 +4776,47 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, u_char uj)
DEFUN (show_ip_mroute,
show_ip_mroute_cmd,
- "show ip mroute [vrf NAME] [json]",
+ "show ip mroute [vrf NAME] [fill] [json]",
SHOW_STR
IP_STR
MROUTE_STR
VRF_CMD_HELP_STR
+ "Fill in Assumed data\n"
JSON_STR)
{
u_char uj = use_json(argc, argv);
+ bool fill = false;
int idx = 2;
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
if (!vrf)
return CMD_WARNING;
- show_mroute(vrf->info, vty, uj);
+ if (argv_find(argv, argc, "fill", &idx))
+ fill = true;
+
+ show_mroute(vrf->info, vty, fill, uj);
return CMD_SUCCESS;
}
DEFUN (show_ip_mroute_vrf_all,
show_ip_mroute_vrf_all_cmd,
- "show ip mroute vrf all [json]",
+ "show ip mroute vrf all [fill] [json]",
SHOW_STR
IP_STR
MROUTE_STR
VRF_CMD_HELP_STR
+ "Fill in Assumed data\n"
JSON_STR)
{
u_char uj = use_json(argc, argv);
+ int idx = 4;
struct vrf *vrf;
bool first = true;
+ bool fill = false;
+
+ if (argv_find(argv, argc, "fill", &idx))
+ fill = true;
if (uj)
vty_out(vty, "{ ");
@@ -4818,7 +4828,7 @@ DEFUN (show_ip_mroute_vrf_all,
first = false;
} else
vty_out(vty, "VRF: %s\n", vrf->name);
- show_mroute(vrf->info, vty, uj);
+ show_mroute(vrf->info, vty, fill, uj);
}
if (uj)
vty_out(vty, "}\n");
@@ -6462,6 +6472,58 @@ DEFUN (interface_no_ip_pim_sm,
return CMD_SUCCESS;
}
+/* boundaries */
+DEFUN(interface_ip_pim_boundary_oil,
+ interface_ip_pim_boundary_oil_cmd,
+ "ip multicast boundary oil WORD",
+ IP_STR
+ "Generic multicast configuration options\n"
+ "Define multicast boundary\n"
+ "Filter OIL by group using prefix list\n"
+ "Prefix list to filter OIL with")
+{
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ struct pim_interface *pim_ifp;
+ int idx = 0;
+
+ argv_find(argv, argc, "WORD", &idx);
+
+ PIM_GET_PIM_INTERFACE(pim_ifp, iif);
+
+ if (pim_ifp->boundary_oil_plist)
+ XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
+
+ pim_ifp->boundary_oil_plist =
+ XSTRDUP(MTYPE_PIM_INTERFACE, argv[idx]->arg);
+
+ /* Interface will be pruned from OIL on next Join */
+ return CMD_SUCCESS;
+}
+
+DEFUN(interface_no_ip_pim_boundary_oil,
+ interface_no_ip_pim_boundary_oil_cmd,
+ "no ip multicast boundary oil [WORD]",
+ NO_STR
+ IP_STR
+ "Generic multicast configuration options\n"
+ "Define multicast boundary\n"
+ "Filter OIL by group using prefix list\n"
+ "Prefix list to filter OIL with")
+{
+ VTY_DECLVAR_CONTEXT(interface, iif);
+ struct pim_interface *pim_ifp;
+ int idx;
+
+ argv_find(argv, argc, "WORD", &idx);
+
+ PIM_GET_PIM_INTERFACE(pim_ifp, iif);
+
+ if (pim_ifp->boundary_oil_plist)
+ XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (interface_ip_mroute,
interface_ip_mroute_cmd,
"ip mroute INTERFACE A.B.C.D",
@@ -8564,6 +8626,8 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE, &interface_no_ip_pim_drprio_cmd);
install_element(INTERFACE_NODE, &interface_ip_pim_hello_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_pim_hello_cmd);
+ install_element(INTERFACE_NODE, &interface_ip_pim_boundary_oil_cmd);
+ install_element(INTERFACE_NODE, &interface_no_ip_pim_boundary_oil_cmd);
// Static mroutes NEB
install_element(INTERFACE_NODE, &interface_ip_mroute_cmd);
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index d98e5f1f66..b8cbed7f93 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -246,6 +246,9 @@ void pim_if_delete(struct interface *ifp)
list_delete(pim_ifp->upstream_switch_list);
list_delete(pim_ifp->sec_addr_list);
+ if (pim_ifp->boundary_oil_plist)
+ XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
+
while ((ch = RB_ROOT(pim_ifchannel_rb,
&pim_ifp->ifchannel_rb)) != NULL)
pim_ifchannel_delete(ch);
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index 2f27a14010..09bd2b06e4 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -122,6 +122,9 @@ struct pim_interface {
uint32_t pim_dr_priority; /* config */
int pim_dr_num_nondrpri_neighbors; /* neighbors without dr_pri */
+ /* boundary prefix-list */
+ char *boundary_oil_plist;
+
int64_t pim_ifstat_start; /* start timestamp for stats */
uint32_t pim_ifstat_hello_sent;
uint32_t pim_ifstat_hello_sendfail;
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 3a870374c0..f6c8db7acb 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -299,22 +299,19 @@ static int igmp_recv_query(struct igmp_sock *igmp, int query_version,
return -1;
}
- /* RFC 3376 defines some guidelines on operating in backwards
- * compatibility
- * with older versions of IGMP but there are some gaps in the logic:
+ /*
+ * RFC 3376 defines some guidelines on operating in backwards
+ * compatibility with older versions of IGMP but there are some gaps in
+ * the logic:
*
* - once we drop from say version 3 to version 2 we will never go back
- * to
- * version 3 even if the node that TXed an IGMP v2 query upgrades to
- * v3
+ * to version 3 even if the node that TXed an IGMP v2 query upgrades
+ * to v3
*
* - The node with the lowest IP is the querier so we will only know to
- * drop
- * from v3 to v2 if the node that is the querier is also the one that
- * is
- * running igmp v2. If a non-querier only supports igmp v2 we will
- * have
- * no way of knowing.
+ * drop from v3 to v2 if the node that is the querier is also the one
+ * that is running igmp v2. If a non-querier only supports igmp v2
+ * we will have no way of knowing.
*
* For now we will simplify things and inform the user that they need to
* configure all PIM routers to use the same version of IGMP.
@@ -403,6 +400,9 @@ static int igmp_v1_recv_report(struct igmp_sock *igmp, struct in_addr from,
memcpy(&group_addr, igmp_msg + 4, sizeof(struct in_addr));
+ if (pim_is_group_filtered(ifp->info, &group_addr))
+ return -1;
+
/* non-existant group is created as INCLUDE {empty} */
group = igmp_add_group_by_addr(igmp, group_addr);
if (!group) {
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index 1fc7517e05..ecde546c06 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -671,6 +671,9 @@ void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from,
on_trace(__PRETTY_FUNCTION__, ifp, from, group_addr, num_sources,
sources);
+ if (pim_is_group_filtered(ifp->info, &group_addr))
+ return;
+
/* non-existant group is created as INCLUDE {empty} */
group = igmp_add_group_by_addr(igmp, group_addr);
if (!group) {
@@ -1869,6 +1872,9 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
struct interface *ifp = igmp->interface;
int i;
int local_ncb = 0;
+ struct pim_interface *pim_ifp;
+
+ pim_ifp = igmp->interface->info;
if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) {
zlog_warn(
@@ -1920,6 +1926,7 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
int j;
struct prefix lncb;
struct prefix g;
+ bool filtered = false;
if ((group_record + IGMP_V3_GROUP_RECORD_MIN_SIZE)
> report_pastend) {
@@ -1983,6 +1990,16 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
g.family = AF_INET;
g.u.prefix4 = rec_group;
g.prefixlen = 32;
+
+ /* determine filtering status for group */
+ filtered = pim_is_group_filtered(ifp->info, &rec_group);
+
+ if (PIM_DEBUG_IGMP_PACKETS && filtered)
+ zlog_debug(
+ "Filtering IGMPv3 group record %s from %s on %s per prefix-list %s",
+ inet_ntoa(rec_group), from_str, ifp->name,
+ pim_ifp->boundary_oil_plist);
+
/*
* If we receive a igmp report with the group in 224.0.0.0/24
* then we should ignore it
@@ -1990,7 +2007,7 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
if (prefix_match(&lncb, &g))
local_ncb = 1;
- if (!local_ncb)
+ if (!local_ncb && !filtered)
switch (rec_type) {
case IGMP_GRP_REC_TYPE_MODE_IS_INCLUDE:
igmpv3_report_isin(igmp, from, rec_group,
diff --git a/pimd/pim_join.c b/pimd/pim_join.c
index 4f5e534010..ae5032be73 100644
--- a/pimd/pim_join.c
+++ b/pimd/pim_join.c
@@ -38,6 +38,7 @@
#include "pim_rpf.h"
#include "pim_rp.h"
#include "pim_jp_agg.h"
+#include "pim_util.h"
static void on_trace(const char *label, struct interface *ifp,
struct in_addr src)
@@ -153,6 +154,7 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
int tlv_buf_size)
{
struct prefix msg_upstream_addr;
+ struct pim_interface *pim_ifp;
uint8_t msg_num_groups;
uint16_t msg_holdtime;
int addr_offset;
@@ -163,6 +165,7 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
buf = tlv_buf;
pastend = tlv_buf + tlv_buf_size;
+ pim_ifp = ifp->info;
/*
Parse ucast addr
@@ -231,6 +234,7 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
uint16_t msg_num_pruned_sources;
int source;
struct pim_ifchannel *starg_ch = NULL, *sg_ch = NULL;
+ bool filtered = false;
memset(&sg, 0, sizeof(struct prefix_sg));
addr_offset = pim_parse_addr_group(&sg, buf, pastend - buf);
@@ -273,6 +277,9 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
src_str, ifp->name);
}
+ /* boundary check */
+ filtered = pim_is_group_filtered(pim_ifp, &sg.grp);
+
/* Scan joined sources */
for (source = 0; source < msg_num_joined_sources; ++source) {
addr_offset = pim_parse_addr_source(
@@ -283,6 +290,10 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
buf += addr_offset;
+ /* if we are filtering this group, skip the join */
+ if (filtered)
+ continue;
+
recv_join(ifp, neigh, msg_holdtime,
msg_upstream_addr.u.prefix4, &sg,
msg_source_flags);
@@ -304,6 +315,11 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
}
buf += addr_offset;
+
+ /* if we are filtering this group, skip the prune */
+ if (filtered)
+ continue;
+
recv_prune(ifp, neigh, msg_holdtime,
msg_upstream_addr.u.prefix4, &sg,
msg_source_flags);
@@ -335,7 +351,7 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
}
}
}
- if (starg_ch)
+ if (starg_ch && !filtered)
pim_ifchannel_set_star_g_join_state(starg_ch, 1, 0);
starg_ch = NULL;
} /* scan groups */
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 54d0d2b7d7..5c7561f586 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -229,6 +229,7 @@ static struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
struct prefix *p, *bp;
struct route_node *rn;
+ bp = NULL;
for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
if (rp_info->plist) {
plist = prefix_list_lookup(AFI_IP, rp_info->plist);
@@ -242,7 +243,7 @@ static struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
continue;
}
- if (bp->prefixlen < p->prefixlen) {
+ if (bp && bp->prefixlen < p->prefixlen) {
best = rp_info;
bp = p;
}
diff --git a/pimd/pim_util.c b/pimd/pim_util.c
index 820117a03a..15bde256da 100644
--- a/pimd/pim_util.c
+++ b/pimd/pim_util.c
@@ -21,6 +21,7 @@
#include "log.h"
#include "prefix.h"
+#include "plist.h"
#include "pim_util.h"
@@ -114,7 +115,7 @@ int pim_is_group_224_0_0_0_24(struct in_addr group_addr)
group.family = AF_INET;
group.u.prefix4 = group_addr;
- group.prefixlen = 32;
+ group.prefixlen = IPV4_MAX_PREFIXLEN;
return prefix_match(&group_224, &group);
}
@@ -137,3 +138,19 @@ int pim_is_group_224_4(struct in_addr group_addr)
return prefix_match(&group_all, &group);
}
+
+bool pim_is_group_filtered(struct pim_interface *pim_ifp, struct in_addr *grp)
+{
+ struct prefix grp_pfx;
+ struct prefix_list *pl;
+
+ if (!pim_ifp->boundary_oil_plist)
+ return false;
+
+ grp_pfx.family = AF_INET;
+ grp_pfx.prefixlen = 32;
+ grp_pfx.u.prefix4 = *grp;
+
+ pl = prefix_list_lookup(AFI_IP, pim_ifp->boundary_oil_plist);
+ return pl ? prefix_list_apply(pl, &grp_pfx) == PREFIX_DENY : false;
+}
diff --git a/pimd/pim_util.h b/pimd/pim_util.h
index 1b319cfe4c..c66dd7b660 100644
--- a/pimd/pim_util.h
+++ b/pimd/pim_util.h
@@ -25,6 +25,8 @@
#include <zebra.h>
#include "checksum.h"
+#include "pimd.h"
+#include "pim_iface.h"
uint8_t igmp_msg_encode16to8(uint16_t value);
uint16_t igmp_msg_decode8to16(uint8_t code);
@@ -33,4 +35,5 @@ void pim_pkt_dump(const char *label, const uint8_t *buf, int size);
int pim_is_group_224_0_0_0_24(struct in_addr group_addr);
int pim_is_group_224_4(struct in_addr group_addr);
+bool pim_is_group_filtered(struct pim_interface *pim_ifp, struct in_addr *grp);
#endif /* PIM_UTIL_H */
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index 3da092541d..c1adbcc915 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -285,6 +285,7 @@ int pim_interface_config_write(struct vty *vty)
vty_out(vty, " %d",
pim_ifp->pim_default_holdtime);
vty_out(vty, "\n");
+ ++writes;
}
/* update source */
@@ -358,6 +359,14 @@ int pim_interface_config_write(struct vty *vty)
}
}
+ /* boundary */
+ if (pim_ifp->boundary_oil_plist) {
+ vty_out(vty,
+ " ip pim boundary oil %s\n",
+ pim_ifp->boundary_oil_plist);
+ ++writes;
+ }
+
writes +=
pim_static_write_mroute(pim, vty, ifp);
pim_bfd_write_config(vty, ifp);
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index 8f34b4cb3f..afe66b6eaf 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -557,7 +557,15 @@ def line_for_vtysh_file(ctx_keys, line, delete):
for ctx_key in ctx_keys:
cmd.append(ctx_key)
- return '\n' + '\n'.join(cmd)
+ cmd = '\n' + '\n'.join(cmd)
+
+ # There are some commands that are on by default so their "no" form will be
+ # displayed in the config. "no bgp default ipv4-unicast" is one of these.
+ # If we need to remove this line we do so by adding "bgp default ipv4-unicast",
+ # not by doing a "no no bgp default ipv4-unicast"
+ cmd = cmd.replace('no no ', '')
+
+ return cmd
def get_normalized_ipv6_line(line):
@@ -931,6 +939,7 @@ def compare_context_objects(newconf, running):
return (lines_to_add, lines_to_del)
+
if __name__ == '__main__':
# Command line options
parser = argparse.ArgumentParser(description='Dynamically apply diff in frr configs')
@@ -1143,7 +1152,7 @@ if __name__ == '__main__':
while True:
try:
- _ = subprocess.check_output(cmd)
+ _ = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
@@ -1188,7 +1197,7 @@ if __name__ == '__main__':
fh.write(line + '\n')
try:
- subprocess.check_output(['/usr/bin/vtysh', '-f', filename])
+ subprocess.check_output(['/usr/bin/vtysh', '-f', filename], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
log.warning("frr-reload.py failed due to\n%s" % e.output)
reload_ok = False
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index 003853571f..99c05ef79b 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -404,9 +404,9 @@ int main(int argc, char **argv, char **env)
"NOT SUPPORTED since its\nresults are inconsistent!\n");
}
- snprintf(vtysh_config, sizeof(vtysh_config), "%s%s/%s", sysconfdir,
+ snprintf(vtysh_config, sizeof(vtysh_config), "%s%s%s", sysconfdir,
pathspace, VTYSH_CONFIG_NAME);
- snprintf(frr_config, sizeof(frr_config), "%s%s/%s", sysconfdir,
+ snprintf(frr_config, sizeof(frr_config), "%s%s%s", sysconfdir,
pathspace, FRR_CONFIG_NAME);
strlcat(vtydir, pathspace, sizeof(vtydir));
diff --git a/watchfrr/watchfrr_vty.c b/watchfrr/watchfrr_vty.c
index fd9c017512..1f872c91ff 100644
--- a/watchfrr/watchfrr_vty.c
+++ b/watchfrr/watchfrr_vty.c
@@ -31,16 +31,6 @@
pid_t integrated_write_pid;
static int integrated_result_fd;
-DEFUN_NOSH(show_watchfrr_debugging,
- show_watchfrr_debugging_cmd,
- "show debugging [watchfrr]",
- SHOW_STR
- DEBUG_STR
- "WatchFRR\n")
-{
- return CMD_SUCCESS;
-}
-
DEFUN(config_write_integrated,
config_write_integrated_cmd,
"write integrated",
@@ -111,6 +101,16 @@ DEFUN(config_write_integrated,
exit(1);
}
+DEFUN_NOSH (show_debugging_watchfrr,
+ show_debugging_watchfrr_cmd,
+ "show debugging [watchfrr]",
+ SHOW_STR
+ DEBUG_STR
+ WATCHFRR_STR)
+{
+ return CMD_SUCCESS;
+}
+
void integrated_write_sigchld(int status)
{
uint8_t reply[4] = {0, 0, 0, CMD_WARNING};
@@ -144,5 +144,6 @@ void watchfrr_vty_init(void)
{
integrated_write_pid = -1;
install_element(ENABLE_NODE, &config_write_integrated_cmd);
- install_element(ENABLE_NODE, &show_watchfrr_debugging_cmd);
+ install_element(ENABLE_NODE, &show_debugging_watchfrr_cmd);
+ install_element(CONFIG_NODE, &show_debugging_watchfrr_cmd);
}
diff --git a/zebra/debug.c b/zebra/debug.c
index 4ba8585f3e..ac96051abd 100644
--- a/zebra/debug.c
+++ b/zebra/debug.c
@@ -99,7 +99,7 @@ DEFUN (debug_zebra_events,
"Debug option set for zebra events\n")
{
zebra_debug_event = ZEBRA_DEBUG_EVENT;
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_nht,
@@ -110,7 +110,7 @@ DEFUN (debug_zebra_nht,
"Debug option set for zebra next hop tracking\n")
{
zebra_debug_nht = ZEBRA_DEBUG_NHT;
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_mpls,
@@ -121,7 +121,7 @@ DEFUN (debug_zebra_mpls,
"Debug option set for zebra MPLS LSPs\n")
{
zebra_debug_mpls = ZEBRA_DEBUG_MPLS;
- return CMD_WARNING_CONFIG_FAILED;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_vxlan,
@@ -132,7 +132,7 @@ DEFUN (debug_zebra_vxlan,
"Debug option set for zebra VxLAN (EVPN)\n")
{
zebra_debug_vxlan = ZEBRA_DEBUG_VXLAN;
- return CMD_WARNING;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_pw,
@@ -147,7 +147,7 @@ DEFUN (debug_zebra_pw,
UNSET_FLAG(zebra_debug_pw, ZEBRA_DEBUG_PW);
else
SET_FLAG(zebra_debug_pw, ZEBRA_DEBUG_PW);
- return CMD_WARNING;
+ return CMD_SUCCESS;
}
DEFUN (debug_zebra_packet,
diff --git a/zebra/rib.h b/zebra/rib.h
index e361321247..e3ed6210ca 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -135,6 +135,8 @@ typedef struct rib_dest_t_ {
} rib_dest_t;
#define RIB_ROUTE_QUEUED(x) (1 << (x))
+// If MQ_SIZE is modified this value needs to be updated.
+#define RIB_ROUTE_ANY_QUEUED 0x1F
/*
* The maximum qindex that can be used.
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 61a18e2df7..fab8c3c932 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -2500,6 +2500,15 @@ static void rib_update_table(struct route_table *table,
* the trigger event.
*/
for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
+ /*
+ * If we are looking at a route node and the node
+ * has already been queued we don't
+ * need to queue it up again
+ */
+ if (rn->info
+ && CHECK_FLAG(rib_dest_from_rnode(rn)->flags,
+ RIB_ROUTE_ANY_QUEUED))
+ continue;
switch (event) {
case RIB_UPDATE_IF_CHANGE:
/* Examine all routes that won't get processed by the
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index df1eef119a..04cd17cedb 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -166,10 +166,13 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
}
/* Null0 static route. */
- if ((ifname != NULL)
- && (strncasecmp(ifname, "Null0", strlen(ifname)) == 0)) {
- bh_type = STATIC_BLACKHOLE_NULL;
- ifname = NULL;
+ if (ifname != NULL) {
+ if (strncasecmp(ifname, "Null0", strlen(ifname)) == 0 ||
+ strncasecmp(ifname, "reject", strlen(ifname)) == 0 ||
+ strncasecmp(ifname, "blackhole", strlen(ifname)) == 0) {
+ vty_out(vty, "%% Nexthop interface cannot be Null0, reject or blackhole\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
}
/* Route flags */
@@ -181,6 +184,9 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
case 'b':
bh_type = STATIC_BLACKHOLE_DROP;
break;
+ case 'N':
+ bh_type = STATIC_BLACKHOLE_NULL;
+ break;
default:
vty_out(vty, "%% Malformed flag %s \n", flag_str);
return CMD_WARNING_CONFIG_FAILED;
@@ -333,27 +339,22 @@ DEFUN (show_ip_rpf_addr,
}
/* Static route configuration. */
-DEFPY(ip_route, ip_route_cmd,
+DEFPY(ip_route_blackhole,
+ ip_route_blackhole_cmd,
"[no] ip route\
- <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>\
- <\
- {A.B.C.D$gate|INTERFACE$ifname}\
- |null0$ifname\
- |<reject|blackhole>$flag\
- >\
- [{\
- tag (1-4294967295)\
- |(1-255)$distance\
- |vrf NAME\
- |label WORD\
+ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
+ <Null0|reject|blackhole>$flag \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |vrf NAME \
+ |label WORD \
}]",
NO_STR IP_STR
"Establish static routes\n"
"IP destination prefix (e.g. 10.0.0.0/8)\n"
"IP destination prefix\n"
"IP destination prefix mask\n"
- "IP gateway address\n"
- "IP gateway interface name\n"
"Null interface\n"
"Emit an ICMP unreachable when matched\n"
"Silently discard pkts when matched\n"
@@ -364,9 +365,67 @@ DEFPY(ip_route, ip_route_cmd,
MPLS_LABEL_HELPSTR)
{
return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
- mask_str, NULL, gate_str, ifname, flag,
+ mask_str, NULL, NULL, NULL, flag,
+ tag_str, distance_str, vrf, label);
+}
+
+DEFPY(ip_route_address_interface,
+ ip_route_address_interface_cmd,
+ "[no] ip route\
+ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
+ A.B.C.D$gate \
+ INTERFACE$ifname \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |vrf NAME \
+ |label WORD \
+ }]",
+ NO_STR IP_STR
+ "Establish static routes\n"
+ "IP destination prefix (e.g. 10.0.0.0/8)\n"
+ "IP destination prefix\n"
+ "IP destination prefix mask\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this route\n"
+ VRF_CMD_HELP_STR
+ MPLS_LABEL_HELPSTR)
+{
+ return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
+ mask_str, NULL, gate_str, ifname, NULL,
+ tag_str, distance_str, vrf, label);
+}
+
+DEFPY(ip_route,
+ ip_route_cmd,
+ "[no] ip route\
+ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
+ <A.B.C.D$gate|INTERFACE$ifname> \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |vrf NAME \
+ |label WORD \
+ }]",
+ NO_STR IP_STR
+ "Establish static routes\n"
+ "IP destination prefix (e.g. 10.0.0.0/8)\n"
+ "IP destination prefix\n"
+ "IP destination prefix mask\n"
+ "IP gateway address\n"
+ "IP gateway interface name\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this route\n"
+ VRF_CMD_HELP_STR
+ MPLS_LABEL_HELPSTR)
+{
+ return zebra_static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
+ mask_str, NULL, gate_str, ifname, NULL,
tag_str, distance_str, vrf, label);
- return 0;
}
/* New RIB. Detailed information for IPv4 route. */
@@ -1752,19 +1811,75 @@ static int static_config(struct vty *vty, afi_t afi, safi_t safi,
return write;
}
+DEFPY(ipv6_route_blackhole,
+ ipv6_route_blackhole_cmd,
+ "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+ <Null0|reject|blackhole>$flag \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |vrf NAME \
+ |label WORD \
+ }]",
+ NO_STR
+ IPV6_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
+ "Null interface\n"
+ "Emit an ICMP unreachable when matched\n"
+ "Silently discard pkts when matched\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this prefix\n"
+ VRF_CMD_HELP_STR
+ MPLS_LABEL_HELPSTR)
+{
+ return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
+ NULL, from_str, NULL, NULL, flag,
+ tag_str, distance_str, vrf, label);
+}
+
+DEFPY(ipv6_route_address_interface,
+ ipv6_route_address_interface_cmd,
+ "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+ X:X::X:X$gate \
+ INTERFACE$ifname \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |vrf NAME \
+ |label WORD \
+ }]",
+ NO_STR
+ IPV6_STR
+ "Establish static routes\n"
+ "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+ "IPv6 source-dest route\n"
+ "IPv6 source prefix\n"
+ "IPv6 gateway address\n"
+ "IPv6 gateway interface name\n"
+ "Set tag for this route\n"
+ "Tag value\n"
+ "Distance value for this prefix\n"
+ VRF_CMD_HELP_STR
+ MPLS_LABEL_HELPSTR)
+{
+ return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
+ NULL, from_str, gate_str, ifname, NULL,
+ tag_str, distance_str, vrf, label);
+}
+
DEFPY(ipv6_route,
ipv6_route_cmd,
- "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M]\
- <\
- {X:X::X:X$gate|INTERFACE$ifname}\
- |null0$ifname\
- |<reject|blackhole>$flag\
- >\
- [{\
- tag (1-4294967295)\
- |(1-255)$distance\
- |vrf NAME\
- |label WORD\
+ "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
+ <X:X::X:X$gate|INTERFACE$ifname> \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |vrf NAME \
+ |label WORD \
}]",
NO_STR
IPV6_STR
@@ -1774,9 +1889,6 @@ DEFPY(ipv6_route,
"IPv6 source prefix\n"
"IPv6 gateway address\n"
"IPv6 gateway interface name\n"
- "Null interface\n"
- "Emit an ICMP unreachable when matched\n"
- "Silently discard pkts when matched\n"
"Set tag for this route\n"
"Tag value\n"
"Distance value for this prefix\n"
@@ -1784,7 +1896,7 @@ DEFPY(ipv6_route,
MPLS_LABEL_HELPSTR)
{
return zebra_static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
- NULL, from_str, gate_str, ifname, flag,
+ NULL, from_str, gate_str, ifname, NULL,
tag_str, distance_str, vrf, label);
}
@@ -2664,6 +2776,8 @@ void zebra_vty_init(void)
install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
install_element(CONFIG_NODE, &ip_multicast_mode_cmd);
install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd);
+ install_element(CONFIG_NODE, &ip_route_blackhole_cmd);
+ install_element(CONFIG_NODE, &ip_route_address_interface_cmd);
install_element(CONFIG_NODE, &ip_route_cmd);
install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd);
install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd);
@@ -2687,6 +2801,8 @@ void zebra_vty_init(void)
install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_cmd);
install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd);
+ install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd);
+ install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd);
install_element(CONFIG_NODE, &ipv6_route_cmd);
install_element(CONFIG_NODE, &ip_nht_default_route_cmd);
install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd);