diff options
| -rw-r--r-- | bgpd/Makefile.am | 1 | ||||
| -rw-r--r-- | bgpd/bgp_debug.c | 69 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_vty.c | 36 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 20 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 4 | ||||
| -rw-r--r-- | bgpd/bgp_routemap.c | 8 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 2 | ||||
| -rw-r--r-- | bgpd/rfapi/bgp_rfapi_cfg.c | 8 | ||||
| -rw-r--r-- | bgpd/rfapi/rfapi_vty.c | 4 | ||||
| -rw-r--r-- | debian/frr.logrotate | 2 | ||||
| -rw-r--r-- | lib/bfd.c | 2 | ||||
| -rw-r--r-- | lib/command.h | 1 | ||||
| -rw-r--r-- | lib/command_lex.l | 6 | ||||
| -rw-r--r-- | lib/command_match.c | 1 | ||||
| -rw-r--r-- | lib/libfrr.c | 2 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 86 | ||||
| -rw-r--r-- | pimd/pim_iface.c | 3 | ||||
| -rw-r--r-- | pimd/pim_iface.h | 3 | ||||
| -rw-r--r-- | pimd/pim_igmp.c | 24 | ||||
| -rw-r--r-- | pimd/pim_igmpv3.c | 19 | ||||
| -rw-r--r-- | pimd/pim_join.c | 18 | ||||
| -rw-r--r-- | pimd/pim_rp.c | 3 | ||||
| -rw-r--r-- | pimd/pim_util.c | 19 | ||||
| -rw-r--r-- | pimd/pim_util.h | 3 | ||||
| -rw-r--r-- | pimd/pim_vty.c | 9 | ||||
| -rwxr-xr-x | tools/frr-reload.py | 15 | ||||
| -rw-r--r-- | vtysh/vtysh_main.c | 4 | ||||
| -rw-r--r-- | watchfrr/watchfrr_vty.c | 23 | ||||
| -rw-r--r-- | zebra/debug.c | 10 | ||||
| -rw-r--r-- | zebra/rib.h | 2 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 9 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 186 |
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 } @@ -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); |
