diff options
40 files changed, 863 insertions, 552 deletions
diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c index 28c6cbee26..0dd021d475 100644 --- a/bfdd/bfdd_cli.c +++ b/bfdd/bfdd_cli.c @@ -55,7 +55,7 @@ /* * Functions. */ -DEFPY_NOSH( +DEFPY_YANG_NOSH( bfd_enter, bfd_enter_cmd, "bfd", "Configure BFD peers\n") @@ -70,7 +70,7 @@ DEFPY_NOSH( return ret; } -DEFUN( +DEFUN_YANG( bfd_config_reset, bfd_config_reset_cmd, "no bfd", NO_STR @@ -93,7 +93,7 @@ void bfd_cli_show_header_end(struct vty *vty, vty_out(vty, "!\n"); } -DEFPY_NOSH( +DEFPY_YANG_NOSH( bfd_peer_enter, bfd_peer_enter_cmd, "peer <A.B.C.D|X:X::X:X> [{multihop$multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME$ifname|vrf NAME}]", PEER_STR @@ -150,7 +150,7 @@ DEFPY_NOSH( return ret; } -DEFPY( +DEFPY_YANG( bfd_no_peer, bfd_no_peer_cmd, "no peer <A.B.C.D|X:X::X:X> [{multihop$multihop|local-address <A.B.C.D|X:X::X:X>|interface IFNAME$ifname|vrf NAME}]", NO_STR @@ -244,7 +244,7 @@ void bfd_cli_show_peer_end(struct vty *vty, vty_out(vty, " !\n"); } -DEFPY( +DEFPY_YANG( bfd_peer_shutdown, bfd_peer_shutdown_cmd, "[no] shutdown", NO_STR @@ -265,7 +265,7 @@ void bfd_cli_show_shutdown(struct vty *vty, struct lyd_node *dnode, yang_dnode_get_bool(dnode, NULL) ? "" : "no "); } -DEFPY( +DEFPY_YANG( bfd_peer_mult, bfd_peer_mult_cmd, "detect-multiplier (2-255)$multiplier", "Configure peer detection multiplier\n" @@ -287,7 +287,7 @@ void bfd_cli_show_mult(struct vty *vty, struct lyd_node *dnode, yang_dnode_get_string(dnode, NULL)); } -DEFPY( +DEFPY_YANG( bfd_peer_rx, bfd_peer_rx_cmd, "receive-interval (10-60000)$interval", "Configure peer receive interval\n" @@ -316,7 +316,7 @@ void bfd_cli_show_rx(struct vty *vty, struct lyd_node *dnode, } } -DEFPY( +DEFPY_YANG( bfd_peer_tx, bfd_peer_tx_cmd, "transmit-interval (10-60000)$interval", "Configure peer transmit interval\n" @@ -345,7 +345,7 @@ void bfd_cli_show_tx(struct vty *vty, struct lyd_node *dnode, } } -DEFPY( +DEFPY_YANG( bfd_peer_echo, bfd_peer_echo_cmd, "[no] echo-mode", NO_STR @@ -366,7 +366,7 @@ void bfd_cli_show_echo(struct vty *vty, struct lyd_node *dnode, yang_dnode_get_bool(dnode, NULL) ? "" : "no "); } -DEFPY( +DEFPY_YANG( bfd_peer_echo_interval, bfd_peer_echo_interval_cmd, "echo-interval (10-60000)$interval", "Configure peer echo interval\n" @@ -398,7 +398,7 @@ void bfd_cli_show_echo_interval(struct vty *vty, struct lyd_node *dnode, /* * Profile commands. */ -DEFPY_NOSH(bfd_profile, bfd_profile_cmd, +DEFPY_YANG_NOSH(bfd_profile, bfd_profile_cmd, "profile WORD$name", BFD_PROFILE_STR BFD_PROFILE_NAME_STR) @@ -419,7 +419,7 @@ DEFPY_NOSH(bfd_profile, bfd_profile_cmd, return CMD_SUCCESS; } -DEFPY(no_bfd_profile, no_bfd_profile_cmd, +DEFPY_YANG(no_bfd_profile, no_bfd_profile_cmd, "no profile BFDPROF$name", NO_STR BFD_PROFILE_STR @@ -442,37 +442,37 @@ void bfd_cli_show_profile(struct vty *vty, struct lyd_node *dnode, vty_out(vty, " profile %s\n", yang_dnode_get_string(dnode, "./name")); } -ALIAS(bfd_peer_mult, bfd_profile_mult_cmd, +ALIAS_YANG(bfd_peer_mult, bfd_profile_mult_cmd, "detect-multiplier (2-255)$multiplier", "Configure peer detection multiplier\n" "Configure peer detection multiplier value\n") -ALIAS(bfd_peer_tx, bfd_profile_tx_cmd, +ALIAS_YANG(bfd_peer_tx, bfd_profile_tx_cmd, "transmit-interval (10-60000)$interval", "Configure peer transmit interval\n" "Configure peer transmit interval value in milliseconds\n") -ALIAS(bfd_peer_rx, bfd_profile_rx_cmd, +ALIAS_YANG(bfd_peer_rx, bfd_profile_rx_cmd, "receive-interval (10-60000)$interval", "Configure peer receive interval\n" "Configure peer receive interval value in milliseconds\n") -ALIAS(bfd_peer_shutdown, bfd_profile_shutdown_cmd, +ALIAS_YANG(bfd_peer_shutdown, bfd_profile_shutdown_cmd, "[no] shutdown", NO_STR "Disable BFD peer\n") -ALIAS(bfd_peer_echo, bfd_profile_echo_cmd, +ALIAS_YANG(bfd_peer_echo, bfd_profile_echo_cmd, "[no] echo-mode", NO_STR "Configure echo mode\n") -ALIAS(bfd_peer_echo_interval, bfd_profile_echo_interval_cmd, +ALIAS_YANG(bfd_peer_echo_interval, bfd_profile_echo_interval_cmd, "echo-interval (10-60000)$interval", "Configure peer echo interval\n" "Configure peer echo interval value in milliseconds\n") -DEFPY(bfd_peer_profile, bfd_peer_profile_cmd, +DEFPY_YANG(bfd_peer_profile, bfd_peer_profile_cmd, "[no] profile BFDPROF$pname", NO_STR "Use BFD profile settings\n" diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index aefcaeff3a..a74b5f91ac 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -146,6 +146,11 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, afi = BGP_ATTR_NEXTHOP_AFI_IP6(pi->attr) ? AFI_IP6 : AFI_IP; + /* Validation for the ipv4 mapped ipv6 nexthop. */ + if (IS_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) { + afi = AFI_IP; + } + /* This will return true if the global IPv6 NH is a link local * addr */ if (make_prefix(afi, pi, &p) < 0) @@ -533,6 +538,7 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) : 0; struct bgp_dest *net = pi->net; const struct prefix *p_orig = bgp_dest_get_prefix(net); + struct in_addr ipv4; if (p_orig->family == AF_FLOWSPEC) { if (!pi->peer) @@ -548,8 +554,15 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) p->u.prefix4 = p_orig->u.prefix4; p->prefixlen = p_orig->prefixlen; } else { - p->u.prefix4 = pi->attr->nexthop; - p->prefixlen = IPV4_MAX_BITLEN; + if (IS_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) { + ipv4_mapped_ipv6_to_ipv4( + &pi->attr->mp_nexthop_global, &ipv4); + p->u.prefix4 = ipv4; + p->prefixlen = IPV4_MAX_BITLEN; + } else { + p->u.prefix4 = pi->attr->nexthop; + p->prefixlen = IPV4_MAX_BITLEN; + } } break; case AFI_IP6: diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index fc100422a8..6b2a5f55b7 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -11971,6 +11971,52 @@ DEFUN (show_bgp_l2vpn_evpn_route_prefix, use_json(argc, argv)); } +static void show_adj_route_header(struct vty *vty, struct bgp *bgp, + struct bgp_table *table, int *header1, + int *header2, json_object *json, + json_object *json_scode, + json_object *json_ocode, bool wide) +{ + uint64_t version = table ? table->version : 0; + + if (*header1) { + if (json) { + json_object_int_add(json, "bgpTableVersion", version); + json_object_string_add(json, "bgpLocalRouterId", + inet_ntoa(bgp->router_id)); + json_object_int_add(json, "defaultLocPrf", + bgp->default_local_pref); + json_object_int_add(json, "localAS", bgp->as); + json_object_object_add(json, "bgpStatusCodes", + json_scode); + json_object_object_add(json, "bgpOriginCodes", + json_ocode); + } else { + vty_out(vty, + "BGP table version is %" PRIu64 ", local router ID is %s, vrf id ", + version, inet_ntoa(bgp->router_id)); + if (bgp->vrf_id == VRF_UNKNOWN) + vty_out(vty, "%s", VRFID_NONE_STR); + else + vty_out(vty, "%u", bgp->vrf_id); + vty_out(vty, "\n"); + vty_out(vty, "Default local pref %u, ", + bgp->default_local_pref); + vty_out(vty, "local AS %u\n", bgp->as); + vty_out(vty, BGP_SHOW_SCODE_HEADER); + vty_out(vty, BGP_SHOW_NCODE_HEADER); + vty_out(vty, BGP_SHOW_OCODE_HEADER); + } + *header1 = 0; + } + if (*header2) { + if (!json) + vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE + : BGP_SHOW_HEADER)); + *header2 = 0; + } +} + static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, enum bgp_show_adj_route_type type, const char *rmap_name, bool use_json, @@ -12081,60 +12127,9 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, if (ain->peer != peer) continue; - if (header1) { - if (use_json) { - json_object_int_add( - json, "bgpTableVersion", - 0); - json_object_string_add( - json, - "bgpLocalRouterId", - inet_ntoa( - bgp->router_id)); - json_object_int_add(json, - "defaultLocPrf", - bgp->default_local_pref); - json_object_int_add(json, - "localAS", bgp->as); - json_object_object_add( - json, "bgpStatusCodes", - json_scode); - json_object_object_add( - json, "bgpOriginCodes", - json_ocode); - } else { - vty_out(vty, - "BGP table version is 0, local router ID is %s, vrf id ", - inet_ntoa( - bgp->router_id)); - if (bgp->vrf_id == VRF_UNKNOWN) - vty_out(vty, "%s", - VRFID_NONE_STR); - else - vty_out(vty, "%u", - bgp->vrf_id); - vty_out(vty, "\n"); - vty_out(vty, - "Default local pref %u, ", - bgp->default_local_pref); - vty_out(vty, "local AS %u\n", - bgp->as); - vty_out(vty, - BGP_SHOW_SCODE_HEADER); - vty_out(vty, - BGP_SHOW_NCODE_HEADER); - vty_out(vty, - BGP_SHOW_OCODE_HEADER); - } - header1 = 0; - } - if (header2) { - if (!use_json) - vty_out(vty, - (wide ? BGP_SHOW_HEADER_WIDE - : BGP_SHOW_HEADER)); - header2 = 0; - } + show_adj_route_header( + vty, bgp, table, &header1, &header2, + json, json_scode, json_ocode, wide); attr = *ain->attr; route_filtered = false; @@ -12175,71 +12170,10 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, if (paf->peer != peer || !adj->attr) continue; - if (header1) { - if (use_json) { - json_object_int_add( - json, - "bgpTableVersion", - table->version); - json_object_string_add( - json, - "bgpLocalRouterId", - inet_ntoa( - bgp->router_id)); - json_object_int_add( - json, "defaultLocPrf", - bgp->default_local_pref - ); - json_object_int_add( - json, "localAS", - bgp->as); - json_object_object_add( - json, - "bgpStatusCodes", - json_scode); - json_object_object_add( - json, - "bgpOriginCodes", - json_ocode); - } else { - vty_out(vty, - "BGP table version is %" PRIu64", local router ID is %s, vrf id ", - table->version, - inet_ntoa( - bgp->router_id)); - if (bgp->vrf_id == - VRF_UNKNOWN) - vty_out(vty, - "%s", - VRFID_NONE_STR); - else - vty_out(vty, - "%u", - bgp->vrf_id); - vty_out(vty, "\n"); - vty_out(vty, - "Default local pref %u, ", - bgp->default_local_pref - ); - vty_out(vty, - "local AS %u\n", - bgp->as); - vty_out(vty, - BGP_SHOW_SCODE_HEADER); - vty_out(vty, - BGP_SHOW_NCODE_HEADER); - vty_out(vty, - BGP_SHOW_OCODE_HEADER); - } - header1 = 0; - } - if (header2) { - if (!use_json) - vty_out(vty, - (wide ? BGP_SHOW_HEADER_WIDE - : BGP_SHOW_HEADER)); - header2 = 0; - } + show_adj_route_header( + vty, bgp, table, &header1, + &header2, json, json_scode, + json_ocode, wide); const struct prefix *rn_p = bgp_dest_get_prefix(dest); @@ -12261,6 +12195,27 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, bgp_attr_undup(&attr, adj->attr); } + } else if (type == bgp_show_adj_route_bestpath) { + struct bgp_path_info *pi; + + show_adj_route_header(vty, bgp, table, &header1, + &header2, json, json_scode, + json_ocode, wide); + + for (pi = bgp_dest_get_bgp_path_info(dest); pi; + pi = pi->next) { + if (pi->peer != peer) + continue; + + if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) + continue; + + route_vty_out_tmp(vty, + bgp_dest_get_prefix(dest), + pi->attr, safi, use_json, + json_ar, wide); + output_count++; + } } } @@ -12335,6 +12290,48 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi, return CMD_SUCCESS; } +DEFPY (show_ip_bgp_instance_neighbor_bestpath_route, + show_ip_bgp_instance_neighbor_bestpath_route_cmd, + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> bestpath-routes [json$uj | wide$wide]", + SHOW_STR + IP_STR + BGP_STR + BGP_INSTANCE_HELP_STR + BGP_AFI_HELP_STR + BGP_SAFI_WITH_LABEL_HELP_STR + "Detailed information on TCP and BGP neighbor connections\n" + "Neighbor to display information about\n" + "Neighbor to display information about\n" + "Neighbor on BGP configured interface\n" + "Display the routes selected by best path\n" + JSON_STR + "Increase table width for longer prefixes\n") +{ + afi_t afi = AFI_IP6; + safi_t safi = SAFI_UNICAST; + char *rmap_name = NULL; + char *peerstr = NULL; + struct bgp *bgp = NULL; + struct peer *peer; + enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath; + int idx = 0; + + bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, + &bgp, uj); + + if (!idx) + return CMD_WARNING; + + argv_find(argv, argc, "neighbors", &idx); + peerstr = argv[++idx]->arg; + + peer = peer_lookup_in_view(vty, bgp, peerstr, uj); + if (!peer) + return CMD_WARNING; + + return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, uj, wide); +} + DEFPY (show_ip_bgp_instance_neighbor_advertised_route, show_ip_bgp_instance_neighbor_advertised_route_cmd, "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map WORD] [json$uj | wide$wide]", @@ -13544,6 +13541,8 @@ void bgp_route_init(void) install_element(VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd); + install_element(VIEW_NODE, + &show_ip_bgp_instance_neighbor_bestpath_route_cmd); install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd); install_element(VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 0767d2912f..32c65c8fac 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -62,6 +62,7 @@ enum bgp_show_adj_route_type { bgp_show_adj_route_advertised, bgp_show_adj_route_received, bgp_show_adj_route_filtered, + bgp_show_adj_route_bestpath, }; diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 4de5ec3b04..5df9e3f23f 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -574,6 +574,18 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, gnh_modified = 1; } + if (IN6_IS_ADDR_UNSPECIFIED(mod_v6nhg)) { + if (peer->nexthop.v4.s_addr) { + ipv4_to_ipv4_mapped_ipv6(mod_v6nhg, + peer->nexthop.v4); + } + } + + if (IS_MAPPED_IPV6(&peer->nexthop.v6_global)) { + mod_v6nhg = &peer->nexthop.v6_global; + gnh_modified = 1; + } + if (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL || nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) { stream_get_from(&v6nhlocal, s, offset_nhlocal, diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index d776b32a88..795ca00ecf 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -1393,6 +1393,15 @@ Configuring Peers peer in question. This number is between 0 and 600 seconds, with the default advertisement interval being 0. +Displaying Information about Peers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: show bgp <afi> <safi> neighbors WORD bestpath-routes [json] [wide] +.. clicmd:: show bgp <afi> <safi> neighbors WORD bestpath-routes [json] [wide] + + For the given neighbor, WORD, that is specified list the routes selected + by BGP as having the best path. + .. _bgp-peer-filtering: Peer Filtering @@ -2612,17 +2621,17 @@ daemon project, while :clicmd:`show bgp` command is the new format. The choice has been done to keep old format with IPv4 routing table, while new format displays IPv6 routing table. -.. index:: show ip bgp -.. clicmd:: show ip bgp +.. index:: show ip bgp [wide] +.. clicmd:: show ip bgp [wide] -.. index:: show ip bgp A.B.C.D -.. clicmd:: show ip bgp A.B.C.D +.. index:: show ip bgp A.B.C.D [wide] +.. clicmd:: show ip bgp A.B.C.D [wide] -.. index:: show bgp -.. clicmd:: show bgp +.. index:: show bgp [wide] +.. clicmd:: show bgp [wide] -.. index:: show bgp X:X::X:X -.. clicmd:: show bgp X:X::X:X +.. index:: show bgp X:X::X:X [wide] +.. clicmd:: show bgp X:X::X:X [wide] These commands display BGP routes. When no route is specified, the default is to display all BGP routes. @@ -2638,6 +2647,12 @@ displays IPv6 routing table. Total number of prefixes 1 + If _wide_ option is specified, then the prefix table's width is increased + to fully display the prefix and the nexthop. + + This is especially handy dealing with IPv6 prefixes and + if :clicmd:`[no] bgp default show-nexthop-hostname` is enabled. + Some other commands provide additional options for filtering the output. .. index:: show [ip] bgp regexp LINE diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c index c76e067685..3610b3a869 100644 --- a/eigrpd/eigrp_cli.c +++ b/eigrpd/eigrp_cli.c @@ -37,7 +37,7 @@ /* * XPath: /frr-eigrpd:eigrpd/instance */ -DEFPY_NOSH( +DEFPY_YANG_NOSH( router_eigrp, router_eigrp_cmd, "router eigrp (1-65535)$as [vrf NAME]", @@ -61,7 +61,7 @@ DEFPY_NOSH( return rv; } -DEFPY( +DEFPY_YANG( no_router_eigrp, no_router_eigrp_cmd, "no router eigrp (1-65535)$as [vrf NAME]", @@ -101,7 +101,7 @@ void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode) /* * XPath: /frr-eigrpd:eigrpd/instance/router-id */ -DEFPY( +DEFPY_YANG( eigrp_router_id, eigrp_router_id_cmd, "eigrp router-id A.B.C.D$addr", @@ -113,7 +113,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_router_id, no_eigrp_router_id_cmd, "no eigrp router-id [A.B.C.D]", @@ -137,7 +137,7 @@ void eigrp_cli_show_router_id(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-eigrpd:eigrpd/instance/passive-interface */ -DEFPY( +DEFPY_YANG( eigrp_passive_interface, eigrp_passive_interface_cmd, "[no] passive-interface IFNAME", @@ -166,7 +166,7 @@ void eigrp_cli_show_passive_interface(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-eigrpd:eigrpd/instance/active-time */ -DEFPY( +DEFPY_YANG( eigrp_timers_active, eigrp_timers_active_cmd, "timers active-time <(1-65535)$timer|disabled$disabled>", @@ -184,7 +184,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_timers_active, no_eigrp_timers_active_cmd, "no timers active-time [<(1-65535)|disabled>]", @@ -209,7 +209,7 @@ void eigrp_cli_show_active_time(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-eigrpd:eigrpd/instance/variance */ -DEFPY( +DEFPY_YANG( eigrp_variance, eigrp_variance_cmd, "variance (1-128)$variance", @@ -220,7 +220,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_variance, no_eigrp_variance_cmd, "no variance [(1-128)]", @@ -243,7 +243,7 @@ void eigrp_cli_show_variance(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-eigrpd:eigrpd/instance/maximum-paths */ -DEFPY( +DEFPY_YANG( eigrp_maximum_paths, eigrp_maximum_paths_cmd, "maximum-paths (1-32)$maximum_paths", @@ -255,7 +255,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_maximum_paths, no_eigrp_maximum_paths_cmd, "no maximum-paths [(1-32)]", @@ -283,7 +283,7 @@ void eigrp_cli_show_maximum_paths(struct vty *vty, struct lyd_node *dnode, * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K5 * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K6 */ -DEFPY( +DEFPY_YANG( eigrp_metric_weights, eigrp_metric_weights_cmd, "metric weights (0-255)$k1 (0-255)$k2 (0-255)$k3 (0-255)$k4 (0-255)$k5 [(0-255)$k6]", @@ -308,7 +308,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_metric_weights, no_eigrp_metric_weights_cmd, "no metric weights [(0-255) (0-255) (0-255) (0-255) (0-255) (0-255)]", @@ -359,7 +359,7 @@ void eigrp_cli_show_metrics(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-eigrpd:eigrpd/instance/network */ -DEFPY( +DEFPY_YANG( eigrp_network, eigrp_network_cmd, "[no] network A.B.C.D/M$prefix", @@ -388,7 +388,7 @@ void eigrp_cli_show_network(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-eigrpd:eigrpd/instance/neighbor */ -DEFPY( +DEFPY_YANG( eigrp_neighbor, eigrp_neighbor_cmd, "[no] neighbor A.B.C.D$addr", @@ -423,7 +423,7 @@ void eigrp_cli_show_neighbor(struct vty *vty, struct lyd_node *dnode, * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/load * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu */ -DEFPY( +DEFPY_YANG( eigrp_redistribute_source_metric, eigrp_redistribute_source_metric_cmd, "[no] redistribute " FRR_REDIST_STR_EIGRPD @@ -493,7 +493,7 @@ void eigrp_cli_show_redistribute(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/delay */ -DEFPY( +DEFPY_YANG( eigrp_if_delay, eigrp_if_delay_cmd, "delay (1-16777215)$delay", @@ -505,7 +505,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_if_delay, no_eigrp_if_delay_cmd, "no delay [(1-16777215)]", @@ -529,7 +529,7 @@ void eigrp_cli_show_delay(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth */ -DEFPY( +DEFPY_YANG( eigrp_if_bandwidth, eigrp_if_bandwidth_cmd, "eigrp bandwidth (1-10000000)$bw", @@ -542,7 +542,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_if_bandwidth, no_eigrp_if_bandwidth_cmd, "no eigrp bandwidth [(1-10000000)]", @@ -567,7 +567,7 @@ void eigrp_cli_show_bandwidth(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval */ -DEFPY( +DEFPY_YANG( eigrp_if_ip_hellointerval, eigrp_if_ip_hellointerval_cmd, "ip hello-interval eigrp (1-65535)$hello", @@ -581,7 +581,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_if_ip_hellointerval, no_eigrp_if_ip_hellointerval_cmd, "no ip hello-interval eigrp [(1-65535)]", @@ -608,7 +608,7 @@ void eigrp_cli_show_hello_interval(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time */ -DEFPY( +DEFPY_YANG( eigrp_if_ip_holdinterval, eigrp_if_ip_holdinterval_cmd, "ip hold-time eigrp (1-65535)$hold", @@ -622,7 +622,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_if_ip_holdinterval, no_eigrp_if_ip_holdinterval_cmd, "no ip hold-time eigrp [(1-65535)]", @@ -654,7 +654,7 @@ void eigrp_cli_show_hold_time(struct vty *vty, struct lyd_node *dnode, * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses */ -DEFPY( +DEFPY_YANG( eigrp_ip_summary_address, eigrp_ip_summary_address_cmd, "ip summary-address eigrp (1-65535)$as A.B.C.D/M$prefix", @@ -676,7 +676,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_ip_summary_address, no_eigrp_ip_summary_address_cmd, "no ip summary-address eigrp (1-65535)$as A.B.C.D/M$prefix", @@ -714,7 +714,7 @@ void eigrp_cli_show_summarize_address(struct vty *vty, struct lyd_node *dnode, * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication */ -DEFPY( +DEFPY_YANG( eigrp_authentication_mode, eigrp_authentication_mode_cmd, "ip authentication mode eigrp (1-65535)$as <md5|hmac-sha-256>$crypt", @@ -738,7 +738,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_authentication_mode, no_eigrp_authentication_mode_cmd, "no ip authentication mode eigrp (1-65535)$as [<md5|hmac-sha-256>]", @@ -778,7 +778,7 @@ void eigrp_cli_show_authentication(struct vty *vty, struct lyd_node *dnode, * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain */ -DEFPY( +DEFPY_YANG( eigrp_authentication_keychain, eigrp_authentication_keychain_cmd, "ip authentication key-chain eigrp (1-65535)$as WORD$name", @@ -801,7 +801,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_eigrp_authentication_keychain, no_eigrp_authentication_keychain_cmd, "no ip authentication key-chain eigrp (1-65535)$as [WORD]", diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index d864053b15..cd75116c50 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -46,7 +46,7 @@ /* * XPath: /frr-isisd:isis/instance */ -DEFPY_NOSH(router_isis, router_isis_cmd, "router isis WORD$tag", +DEFPY_YANG_NOSH(router_isis, router_isis_cmd, "router isis WORD$tag", ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag\n") @@ -72,7 +72,7 @@ DEFPY_NOSH(router_isis, router_isis_cmd, "router isis WORD$tag", return ret; } -DEFPY(no_router_isis, no_router_isis_cmd, "no router isis WORD$tag", +DEFPY_YANG(no_router_isis, no_router_isis_cmd, "no router isis WORD$tag", NO_STR ROUTER_STR "ISO IS-IS\n" "ISO Routing area tag\n") @@ -126,7 +126,7 @@ void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode, * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing * XPath: /frr-isisd:isis/instance */ -DEFPY(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag", +DEFPY_YANG(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag", "Interface Internet Protocol config commands\n" "IP router interface commands\n" "IS-IS routing protocol\n" @@ -196,7 +196,7 @@ DEFPY(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag", return nb_cli_apply_changes(vty, NULL); } -DEFPY(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag", +DEFPY_YANG(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag", "Interface Internet Protocol config commands\n" "IP router interface commands\n" "IS-IS routing protocol\n" @@ -266,7 +266,7 @@ DEFPY(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag", return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_ip_router_isis, no_ip_router_isis_cmd, +DEFPY_YANG(no_ip_router_isis, no_ip_router_isis_cmd, "no <ip|ipv6>$ip router isis [WORD]$tag", NO_STR "Interface Internet Protocol config commands\n" @@ -327,7 +327,7 @@ void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring */ -DEFPY(isis_bfd, +DEFPY_YANG(isis_bfd, isis_bfd_cmd, "[no] isis bfd", NO_STR PROTO_HELP @@ -351,7 +351,7 @@ DEFPY(isis_bfd, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring/profile */ -DEFPY(isis_bfd_profile, +DEFPY_YANG(isis_bfd_profile, isis_bfd_profile_cmd, "[no] isis bfd profile WORD", NO_STR PROTO_HELP @@ -394,7 +394,7 @@ void cli_show_ip_isis_bfd_monitoring(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/area-address */ -DEFPY(net, net_cmd, "[no] net WORD", +DEFPY_YANG(net, net_cmd, "[no] net WORD", "Remove an existing Network Entity Title for this process\n" "A Network Entity Title for this process (OSI only)\n" "XX.XXXX. ... .XXX.XX Network entity title (NET)\n") @@ -414,7 +414,7 @@ void cli_show_isis_area_address(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/is-type */ -DEFPY(is_type, is_type_cmd, "is-type <level-1|level-1-2|level-2-only>$level", +DEFPY_YANG(is_type, is_type_cmd, "is-type <level-1|level-1-2|level-2-only>$level", "IS Level for this routing process (OSI only)\n" "Act as a station router only\n" "Act as both a station router and an area router\n" @@ -427,7 +427,7 @@ DEFPY(is_type, is_type_cmd, "is-type <level-1|level-1-2|level-2-only>$level", return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_is_type, no_is_type_cmd, +DEFPY_YANG(no_is_type, no_is_type_cmd, "no is-type [<level-1|level-1-2|level-2-only>]", NO_STR "IS Level for this routing process (OSI only)\n" @@ -461,7 +461,7 @@ void cli_show_isis_is_type(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/dynamic-hostname */ -DEFPY(dynamic_hostname, dynamic_hostname_cmd, "[no] hostname dynamic", +DEFPY_YANG(dynamic_hostname, dynamic_hostname_cmd, "[no] hostname dynamic", NO_STR "Dynamic hostname for IS-IS\n" "Dynamic hostname\n") @@ -484,7 +484,7 @@ void cli_show_isis_dynamic_hostname(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/overload */ -DEFPY(set_overload_bit, set_overload_bit_cmd, "[no] set-overload-bit", +DEFPY_YANG(set_overload_bit, set_overload_bit_cmd, "[no] set-overload-bit", "Reset overload bit to accept transit traffic\n" "Set overload bit to avoid any transit traffic\n") { @@ -505,7 +505,7 @@ void cli_show_isis_overload(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/attached */ -DEFPY(set_attached_bit, set_attached_bit_cmd, "[no] set-attached-bit", +DEFPY_YANG(set_attached_bit, set_attached_bit_cmd, "[no] set-attached-bit", "Reset attached bit\n" "Set attached bit to identify as L1/L2 router for inter-area traffic\n") { @@ -526,7 +526,7 @@ void cli_show_isis_attached(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/metric-style */ -DEFPY(metric_style, metric_style_cmd, +DEFPY_YANG(metric_style, metric_style_cmd, "metric-style <narrow|transition|wide>$style", "Use old-style (ISO 10589) or new-style packet formats\n" "Use old style of TLVs with narrow metric\n" @@ -538,7 +538,7 @@ DEFPY(metric_style, metric_style_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_metric_style, no_metric_style_cmd, +DEFPY_YANG(no_metric_style, no_metric_style_cmd, "no metric-style [narrow|transition|wide]", NO_STR "Use old-style (ISO 10589) or new-style packet formats\n" @@ -572,7 +572,7 @@ void cli_show_isis_metric_style(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/area-password */ -DEFPY(area_passwd, area_passwd_cmd, +DEFPY_YANG(area_passwd, area_passwd_cmd, "area-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]", "Configure the authentication password for an area\n" "Clear-text authentication type\n" @@ -611,7 +611,7 @@ void cli_show_isis_area_pwd(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/domain-password */ -DEFPY(domain_passwd, domain_passwd_cmd, +DEFPY_YANG(domain_passwd, domain_passwd_cmd, "domain-password <clear|md5>$pwd_type WORD$pwd [authenticate snp <send-only|validate>$snp]", "Set the authentication password for a routing domain\n" "Clear-text authentication type\n" @@ -633,7 +633,7 @@ DEFPY(domain_passwd, domain_passwd_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_area_passwd, no_area_passwd_cmd, +DEFPY_YANG(no_area_passwd, no_area_passwd_cmd, "no <area-password|domain-password>$cmd", NO_STR "Configure the authentication password for an area\n" @@ -662,7 +662,7 @@ void cli_show_isis_domain_pwd(struct vty *vty, struct lyd_node *dnode, * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/generation-interval * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/generation-interval */ -DEFPY(lsp_gen_interval, lsp_gen_interval_cmd, +DEFPY_YANG(lsp_gen_interval, lsp_gen_interval_cmd, "lsp-gen-interval [level-1|level-2]$level (1-120)$val", "Minimum interval between regenerating same LSP\n" "Set interval for level 1 only\n" @@ -681,7 +681,7 @@ DEFPY(lsp_gen_interval, lsp_gen_interval_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_lsp_gen_interval, no_lsp_gen_interval_cmd, +DEFPY_YANG(no_lsp_gen_interval, no_lsp_gen_interval_cmd, "no lsp-gen-interval [level-1|level-2]$level [(1-120)]", NO_STR "Minimum interval between regenerating same LSP\n" @@ -705,7 +705,7 @@ DEFPY(no_lsp_gen_interval, no_lsp_gen_interval_cmd, * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/refresh-interval * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/refresh-interval */ -DEFPY(lsp_refresh_interval, lsp_refresh_interval_cmd, +DEFPY_YANG(lsp_refresh_interval, lsp_refresh_interval_cmd, "lsp-refresh-interval [level-1|level-2]$level (1-65235)$val", "LSP refresh interval\n" "LSP refresh interval for Level 1 only\n" @@ -724,7 +724,7 @@ DEFPY(lsp_refresh_interval, lsp_refresh_interval_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_lsp_refresh_interval, no_lsp_refresh_interval_cmd, +DEFPY_YANG(no_lsp_refresh_interval, no_lsp_refresh_interval_cmd, "no lsp-refresh-interval [level-1|level-2]$level [(1-65235)]", NO_STR "LSP refresh interval\n" @@ -749,7 +749,7 @@ DEFPY(no_lsp_refresh_interval, no_lsp_refresh_interval_cmd, * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/maximum-lifetime */ -DEFPY(max_lsp_lifetime, max_lsp_lifetime_cmd, +DEFPY_YANG(max_lsp_lifetime, max_lsp_lifetime_cmd, "max-lsp-lifetime [level-1|level-2]$level (350-65535)$val", "Maximum LSP lifetime\n" "Maximum LSP lifetime for Level 1 only\n" @@ -768,7 +768,7 @@ DEFPY(max_lsp_lifetime, max_lsp_lifetime_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_max_lsp_lifetime, no_max_lsp_lifetime_cmd, +DEFPY_YANG(no_max_lsp_lifetime, no_max_lsp_lifetime_cmd, "no max-lsp-lifetime [level-1|level-2]$level [(350-65535)]", NO_STR "Maximum LSP lifetime\n" @@ -792,7 +792,7 @@ DEFPY(no_max_lsp_lifetime, no_max_lsp_lifetime_cmd, * XPath: /frr-isisd:isis/instance/lsp/timers */ -DEFPY(lsp_timers, lsp_timers_cmd, +DEFPY_YANG(lsp_timers, lsp_timers_cmd, "lsp-timers [level-1|level-2]$level gen-interval (1-120)$gen refresh-interval (1-65235)$refresh max-lifetime (350-65535)$lifetime", "LSP-related timers\n" "LSP-related timers for Level 1 only\n" @@ -830,7 +830,7 @@ DEFPY(lsp_timers, lsp_timers_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_lsp_timers, no_lsp_timers_cmd, +DEFPY_YANG(no_lsp_timers, no_lsp_timers_cmd, "no lsp-timers [level-1|level-2]$level [gen-interval (1-120) refresh-interval (1-65235) max-lifetime (350-65535)]", NO_STR "LSP-related timers\n" @@ -902,7 +902,7 @@ void cli_show_isis_lsp_timers(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/lsp/mtu */ -DEFPY(area_lsp_mtu, area_lsp_mtu_cmd, "lsp-mtu (128-4352)$val", +DEFPY_YANG(area_lsp_mtu, area_lsp_mtu_cmd, "lsp-mtu (128-4352)$val", "Configure the maximum size of generated LSPs\n" "Maximum size of generated LSPs\n") { @@ -911,7 +911,7 @@ DEFPY(area_lsp_mtu, area_lsp_mtu_cmd, "lsp-mtu (128-4352)$val", return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_area_lsp_mtu, no_area_lsp_mtu_cmd, "no lsp-mtu [(128-4352)]", +DEFPY_YANG(no_area_lsp_mtu, no_area_lsp_mtu_cmd, "no lsp-mtu [(128-4352)]", NO_STR "Configure the maximum size of generated LSPs\n" "Maximum size of generated LSPs\n") @@ -930,7 +930,7 @@ void cli_show_isis_lsp_mtu(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/spf/minimum-interval */ -DEFPY(spf_interval, spf_interval_cmd, +DEFPY_YANG(spf_interval, spf_interval_cmd, "spf-interval [level-1|level-2]$level (1-120)$val", "Minimum interval between SPF calculations\n" "Set interval for level 1 only\n" @@ -947,7 +947,7 @@ DEFPY(spf_interval, spf_interval_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_spf_interval, no_spf_interval_cmd, +DEFPY_YANG(no_spf_interval, no_spf_interval_cmd, "no spf-interval [level-1|level-2]$level [(1-120)]", NO_STR "Minimum interval between SPF calculations\n" @@ -982,7 +982,7 @@ void cli_show_isis_spf_min_interval(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay */ -DEFPY(spf_delay_ietf, spf_delay_ietf_cmd, +DEFPY_YANG(spf_delay_ietf, spf_delay_ietf_cmd, "spf-delay-ietf init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)", "IETF SPF delay algorithm\n" "Delay used while in QUIET state\n" @@ -1012,7 +1012,7 @@ DEFPY(spf_delay_ietf, spf_delay_ietf_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_spf_delay_ietf, no_spf_delay_ietf_cmd, +DEFPY_YANG(no_spf_delay_ietf, no_spf_delay_ietf_cmd, "no spf-delay-ietf [init-delay (0-60000) short-delay (0-60000) long-delay (0-60000) holddown (0-60000) time-to-learn (0-60000)]", NO_STR "IETF SPF delay algorithm\n" @@ -1048,7 +1048,7 @@ void cli_show_isis_spf_ietf_backoff(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/purge-originator */ -DEFPY(area_purge_originator, area_purge_originator_cmd, "[no] purge-originator", +DEFPY_YANG(area_purge_originator, area_purge_originator_cmd, "[no] purge-originator", NO_STR "Use the RFC 6232 purge-originator\n") { nb_cli_enqueue_change(vty, "./purge-originator", NB_OP_MODIFY, @@ -1068,7 +1068,7 @@ void cli_show_isis_purge_origin(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/mpls-te */ -DEFPY(isis_mpls_te_on, isis_mpls_te_on_cmd, "mpls-te on", +DEFPY_YANG(isis_mpls_te_on, isis_mpls_te_on_cmd, "mpls-te on", MPLS_TE_STR "Enable the MPLS-TE functionality\n") { nb_cli_enqueue_change(vty, "./mpls-te", NB_OP_CREATE, @@ -1077,7 +1077,7 @@ DEFPY(isis_mpls_te_on, isis_mpls_te_on_cmd, "mpls-te on", return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_mpls_te_on, no_isis_mpls_te_on_cmd, "no mpls-te [on]", +DEFPY_YANG(no_isis_mpls_te_on, no_isis_mpls_te_on_cmd, "no mpls-te [on]", NO_STR "Disable the MPLS-TE functionality\n" "Disable the MPLS-TE functionality\n") @@ -1097,7 +1097,7 @@ void cli_show_isis_mpls_te(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/mpls-te/router-address */ -DEFPY(isis_mpls_te_router_addr, isis_mpls_te_router_addr_cmd, +DEFPY_YANG(isis_mpls_te_router_addr, isis_mpls_te_router_addr_cmd, "mpls-te router-address A.B.C.D", MPLS_TE_STR "Stable IP address of the advertising router\n" @@ -1109,7 +1109,7 @@ DEFPY(isis_mpls_te_router_addr, isis_mpls_te_router_addr_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_mpls_te_router_addr, no_isis_mpls_te_router_addr_cmd, +DEFPY_YANG(no_isis_mpls_te_router_addr, no_isis_mpls_te_router_addr_cmd, "no mpls-te router-address [A.B.C.D]", NO_STR MPLS_TE_STR "Delete IP address of the advertising router\n" @@ -1128,7 +1128,7 @@ void cli_show_isis_mpls_te_router_addr(struct vty *vty, struct lyd_node *dnode, yang_dnode_get_string(dnode, NULL)); } -DEFPY(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd, +DEFPY_YANG(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd, "[no] mpls-te inter-as [level-1|level-1-2|level-2-only]", NO_STR MPLS_TE_STR "Configure MPLS-TE Inter-AS support\n" @@ -1143,7 +1143,7 @@ DEFPY(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd, /* * XPath: /frr-isisd:isis/instance/default-information-originate */ -DEFPY(isis_default_originate, isis_default_originate_cmd, +DEFPY_YANG(isis_default_originate, isis_default_originate_cmd, "[no] default-information originate <ipv4|ipv6>$ip <level-1|level-2>$level [always]$always [{metric (0-16777215)$metric|route-map WORD$rmap}]", NO_STR "Control distribution of default information\n" @@ -1219,7 +1219,7 @@ void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/redistribute */ -DEFPY(isis_redistribute, isis_redistribute_cmd, +DEFPY_YANG(isis_redistribute, isis_redistribute_cmd, "[no] redistribute <ipv4|ipv6>$ip " PROTO_REDIST_STR "$proto <level-1|level-2>$level [{metric (0-16777215)|route-map WORD}]", NO_STR REDIST_STR @@ -1278,7 +1278,7 @@ void cli_show_isis_redistribute_ipv6(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/multi-topology */ -DEFPY(isis_topology, isis_topology_cmd, +DEFPY_YANG(isis_topology, isis_topology_cmd, "[no] topology <ipv4-unicast|ipv4-mgmt|ipv6-unicast|ipv4-multicast|ipv6-multicast|ipv6-mgmt|ipv6-dstsrc>$topology [overload]$overload", NO_STR "Configure IS-IS topologies\n" @@ -1379,7 +1379,7 @@ void cli_show_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/segment-routing/enabled */ -DEFPY (isis_sr_enable, +DEFPY_YANG (isis_sr_enable, isis_sr_enable_cmd, "segment-routing on", SR_STR @@ -1391,7 +1391,7 @@ DEFPY (isis_sr_enable, return nb_cli_apply_changes(vty, NULL); } -DEFPY (no_isis_sr_enable, +DEFPY_YANG (no_isis_sr_enable, no_isis_sr_enable_cmd, "no segment-routing [on]", NO_STR @@ -1416,7 +1416,7 @@ void cli_show_isis_sr_enabled(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/segment-routing/srgb */ -DEFPY (isis_sr_global_block_label_range, +DEFPY_YANG (isis_sr_global_block_label_range, isis_sr_global_block_label_range_cmd, "segment-routing global-block (16-1048575)$lower_bound (16-1048575)$upper_bound", SR_STR @@ -1432,7 +1432,7 @@ DEFPY (isis_sr_global_block_label_range, return nb_cli_apply_changes(vty, NULL); } -DEFPY (no_isis_sr_global_block_label_range, +DEFPY_YANG (no_isis_sr_global_block_label_range, no_isis_sr_global_block_label_range_cmd, "no segment-routing global-block [(16-1048575) (16-1048575)]", NO_STR @@ -1460,7 +1460,7 @@ void cli_show_isis_srgb(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/segment-routing/srlb */ -DEFPY (isis_sr_local_block_label_range, +DEFPY_YANG (isis_sr_local_block_label_range, isis_sr_local_block_label_range_cmd, "segment-routing local-block (16-1048575)$lower_bound (16-1048575)$upper_bound", SR_STR @@ -1476,7 +1476,7 @@ DEFPY (isis_sr_local_block_label_range, return nb_cli_apply_changes(vty, NULL); } -DEFPY (no_isis_sr_local_block_label_range, +DEFPY_YANG (no_isis_sr_local_block_label_range, no_isis_sr_local_block_label_range_cmd, "no segment-routing local-block [(16-1048575) (16-1048575)]", NO_STR @@ -1504,7 +1504,7 @@ void cli_show_isis_srlb(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/segment-routing/msd/node-msd */ -DEFPY (isis_sr_node_msd, +DEFPY_YANG (isis_sr_node_msd, isis_sr_node_msd_cmd, "segment-routing node-msd (1-16)$msd", SR_STR @@ -1517,7 +1517,7 @@ DEFPY (isis_sr_node_msd, return nb_cli_apply_changes(vty, NULL); } -DEFPY (no_isis_sr_node_msd, +DEFPY_YANG (no_isis_sr_node_msd, no_isis_sr_node_msd_cmd, "no segment-routing node-msd [(1-16)]", NO_STR @@ -1541,7 +1541,7 @@ void cli_show_isis_node_msd(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid */ -DEFPY (isis_sr_prefix_sid, +DEFPY_YANG (isis_sr_prefix_sid, isis_sr_prefix_sid_cmd, "segment-routing prefix\ <A.B.C.D/M|X:X::X:X/M>$prefix\ @@ -1580,7 +1580,7 @@ DEFPY (isis_sr_prefix_sid, prefix_str); } -DEFPY (no_isis_sr_prefix_sid, +DEFPY_YANG (no_isis_sr_prefix_sid, no_isis_sr_prefix_sid_cmd, "no segment-routing prefix <A.B.C.D/M|X:X::X:X/M>$prefix\ [<absolute$sid_type (16-1048575)|index (0-65535)> [<no-php-flag|explicit-null>]]", @@ -1632,7 +1632,7 @@ void cli_show_isis_prefix_sid(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive */ -DEFPY(isis_passive, isis_passive_cmd, "[no] isis passive", +DEFPY_YANG(isis_passive, isis_passive_cmd, "[no] isis passive", NO_STR "IS-IS routing protocol\n" "Configure the passive mode for interface\n") @@ -1655,7 +1655,7 @@ void cli_show_ip_isis_passive(struct vty *vty, struct lyd_node *dnode, * XPath: /frr-interface:lib/interface/frr-isisd:isis/password */ -DEFPY(isis_passwd, isis_passwd_cmd, "isis password <md5|clear>$type WORD$pwd", +DEFPY_YANG(isis_passwd, isis_passwd_cmd, "isis password <md5|clear>$type WORD$pwd", "IS-IS routing protocol\n" "Configure the authentication password for a circuit\n" "HMAC-MD5 authentication\n" @@ -1672,7 +1672,7 @@ DEFPY(isis_passwd, isis_passwd_cmd, "isis password <md5|clear>$type WORD$pwd", return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_passwd, no_isis_passwd_cmd, "no isis password [<md5|clear> WORD]", +DEFPY_YANG(no_isis_passwd, no_isis_passwd_cmd, "no isis password [<md5|clear> WORD]", NO_STR "IS-IS routing protocol\n" "Configure the authentication password for a circuit\n" @@ -1697,7 +1697,7 @@ void cli_show_ip_isis_password(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric */ -DEFPY(isis_metric, isis_metric_cmd, +DEFPY_YANG(isis_metric, isis_metric_cmd, "isis metric [level-1|level-2]$level (0-16777215)$met", "IS-IS routing protocol\n" "Set default metric for circuit\n" @@ -1715,7 +1715,7 @@ DEFPY(isis_metric, isis_metric_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_metric, no_isis_metric_cmd, +DEFPY_YANG(no_isis_metric, no_isis_metric_cmd, "no isis metric [level-1|level-2]$level [(0-16777215)]", NO_STR "IS-IS routing protocol\n" @@ -1751,7 +1751,7 @@ void cli_show_ip_isis_metric(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval */ -DEFPY(isis_hello_interval, isis_hello_interval_cmd, +DEFPY_YANG(isis_hello_interval, isis_hello_interval_cmd, "isis hello-interval [level-1|level-2]$level (1-600)$intv", "IS-IS routing protocol\n" "Set Hello interval\n" @@ -1771,7 +1771,7 @@ DEFPY(isis_hello_interval, isis_hello_interval_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_hello_interval, no_isis_hello_interval_cmd, +DEFPY_YANG(no_isis_hello_interval, no_isis_hello_interval_cmd, "no isis hello-interval [level-1|level-2]$level [(1-600)]", NO_STR "IS-IS routing protocol\n" @@ -1809,7 +1809,7 @@ void cli_show_ip_isis_hello_interval(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier */ -DEFPY(isis_hello_multiplier, isis_hello_multiplier_cmd, +DEFPY_YANG(isis_hello_multiplier, isis_hello_multiplier_cmd, "isis hello-multiplier [level-1|level-2]$level (2-100)$mult", "IS-IS routing protocol\n" "Set multiplier for Hello holding time\n" @@ -1829,7 +1829,7 @@ DEFPY(isis_hello_multiplier, isis_hello_multiplier_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_hello_multiplier, no_isis_hello_multiplier_cmd, +DEFPY_YANG(no_isis_hello_multiplier, no_isis_hello_multiplier_cmd, "no isis hello-multiplier [level-1|level-2]$level [(2-100)]", NO_STR "IS-IS routing protocol\n" @@ -1868,7 +1868,7 @@ void cli_show_ip_isis_hello_multi(struct vty *vty, struct lyd_node *dnode, * XPath: * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake */ -DEFPY(isis_threeway_adj, isis_threeway_adj_cmd, "[no] isis three-way-handshake", +DEFPY_YANG(isis_threeway_adj, isis_threeway_adj_cmd, "[no] isis three-way-handshake", NO_STR "IS-IS commands\n" "Enable/Disable three-way handshake\n") @@ -1891,7 +1891,7 @@ void cli_show_ip_isis_threeway_shake(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding */ -DEFPY(isis_hello_padding, isis_hello_padding_cmd, "[no] isis hello padding", +DEFPY_YANG(isis_hello_padding, isis_hello_padding_cmd, "[no] isis hello padding", NO_STR "IS-IS routing protocol\n" "Add padding to IS-IS hello packets\n" @@ -1915,7 +1915,7 @@ void cli_show_ip_isis_hello_padding(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval */ -DEFPY(csnp_interval, csnp_interval_cmd, +DEFPY_YANG(csnp_interval, csnp_interval_cmd, "isis csnp-interval (1-600)$intv [level-1|level-2]$level", "IS-IS routing protocol\n" "Set CSNP interval in seconds\n" @@ -1935,7 +1935,7 @@ DEFPY(csnp_interval, csnp_interval_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_csnp_interval, no_csnp_interval_cmd, +DEFPY_YANG(no_csnp_interval, no_csnp_interval_cmd, "no isis csnp-interval [(1-600)] [level-1|level-2]$level", NO_STR "IS-IS routing protocol\n" @@ -1973,7 +1973,7 @@ void cli_show_ip_isis_csnp_interval(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval */ -DEFPY(psnp_interval, psnp_interval_cmd, +DEFPY_YANG(psnp_interval, psnp_interval_cmd, "isis psnp-interval (1-120)$intv [level-1|level-2]$level", "IS-IS routing protocol\n" "Set PSNP interval in seconds\n" @@ -1993,7 +1993,7 @@ DEFPY(psnp_interval, psnp_interval_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_psnp_interval, no_psnp_interval_cmd, +DEFPY_YANG(no_psnp_interval, no_psnp_interval_cmd, "no isis psnp-interval [(1-120)] [level-1|level-2]$level", NO_STR "IS-IS routing protocol\n" @@ -2031,7 +2031,7 @@ void cli_show_ip_isis_psnp_interval(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology */ -DEFPY(circuit_topology, circuit_topology_cmd, +DEFPY_YANG(circuit_topology, circuit_topology_cmd, "[no] isis topology<ipv4-unicast|ipv4-mgmt|ipv6-unicast|ipv4-multicast|ipv6-multicast|ipv6-mgmt|ipv6-dstsrc>$topology", NO_STR "IS-IS routing protocol\n" @@ -2116,7 +2116,7 @@ void cli_show_ip_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type */ -DEFPY(isis_circuit_type, isis_circuit_type_cmd, +DEFPY_YANG(isis_circuit_type, isis_circuit_type_cmd, "isis circuit-type <level-1|level-1-2|level-2-only>$type", "IS-IS routing protocol\n" "Configure circuit type for interface\n" @@ -2131,7 +2131,7 @@ DEFPY(isis_circuit_type, isis_circuit_type_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_circuit_type, no_isis_circuit_type_cmd, +DEFPY_YANG(no_isis_circuit_type, no_isis_circuit_type_cmd, "no isis circuit-type [level-1|level-1-2|level-2-only]", NO_STR "IS-IS routing protocol\n" @@ -2209,7 +2209,7 @@ void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type */ -DEFPY(isis_network, isis_network_cmd, "[no] isis network point-to-point", +DEFPY_YANG(isis_network, isis_network_cmd, "[no] isis network point-to-point", NO_STR "IS-IS routing protocol\n" "Set network type\n" @@ -2234,7 +2234,7 @@ void cli_show_ip_isis_network_type(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority */ -DEFPY(isis_priority, isis_priority_cmd, +DEFPY_YANG(isis_priority, isis_priority_cmd, "isis priority (0-127)$prio [level-1|level-2]$level", "IS-IS routing protocol\n" "Set priority for Designated Router election\n" @@ -2252,7 +2252,7 @@ DEFPY(isis_priority, isis_priority_cmd, return nb_cli_apply_changes(vty, NULL); } -DEFPY(no_isis_priority, no_isis_priority_cmd, +DEFPY_YANG(no_isis_priority, no_isis_priority_cmd, "no isis priority [(0-127)] [level-1|level-2]$level", NO_STR "IS-IS routing protocol\n" @@ -2288,7 +2288,7 @@ void cli_show_ip_isis_priority(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-isisd:isis/instance/log-adjacency-changes */ -DEFPY(log_adj_changes, log_adj_changes_cmd, "[no] log-adjacency-changes", +DEFPY_YANG(log_adj_changes, log_adj_changes_cmd, "[no] log-adjacency-changes", NO_STR "Log changes in adjacency state\n") { nb_cli_enqueue_change(vty, "./log-adjacency-changes", NB_OP_MODIFY, diff --git a/lib/command.c b/lib/command.c index 80b75d9b23..159ed07b38 100644 --- a/lib/command.c +++ b/lib/command.c @@ -904,6 +904,13 @@ static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter, > vty->candidate_config->version) nb_config_replace(vty->candidate_config, running_config, true); + + /* + * Perform pending commit (if any) before executing + * non-YANG command. + */ + if (matched_element->attr != CMD_ATTR_YANG) + nb_cli_pending_commit_check(vty); } ret = matched_element->func(matched_element, vty, argc, argv); diff --git a/lib/command.h b/lib/command.h index 1acca90665..a7a2eaf868 100644 --- a/lib/command.h +++ b/lib/command.h @@ -257,6 +257,12 @@ struct cmd_node { #define DEFPY_HIDDEN(funcname, cmdname, cmdstr, helpstr) \ DEFPY_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN) +#define DEFPY_YANG(funcname, cmdname, cmdstr, helpstr) \ + DEFPY_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_YANG) + +#define DEFPY_YANG_NOSH(funcname, cmdname, cmdstr, helpstr) \ + DEFPY_YANG(funcname, cmdname, cmdstr, helpstr) + #define DEFUN(funcname, cmdname, cmdstr, helpstr) \ DEFUN_CMD_FUNC_DECL(funcname) \ DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \ @@ -270,10 +276,16 @@ struct cmd_node { #define DEFUN_HIDDEN(funcname, cmdname, cmdstr, helpstr) \ DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN) +#define DEFUN_YANG(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_YANG) + /* DEFUN_NOSH for commands that vtysh should ignore */ #define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr) \ DEFUN(funcname, cmdname, cmdstr, helpstr) +#define DEFUN_YANG_NOSH(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_YANG(funcname, cmdname, cmdstr, helpstr) + /* DEFSH for vtysh. */ #define DEFSH(daemon, cmdname, cmdstr, helpstr) \ DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, 0, daemon) @@ -282,6 +294,9 @@ struct cmd_node { DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, \ daemon) +#define DEFSH_YANG(daemon, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, CMD_ATTR_YANG, daemon) + /* DEFUN + DEFSH */ #define DEFUNSH(daemon, funcname, cmdname, cmdstr, helpstr) \ DEFUN_CMD_FUNC_DECL(funcname) \ @@ -302,6 +317,9 @@ struct cmd_node { DEFUNSH_ATTR(daemon, funcname, cmdname, cmdstr, helpstr, \ CMD_ATTR_DEPRECATED) +#define DEFUNSH_YANG(daemon, funcname, cmdname, cmdstr, helpstr) \ + DEFUNSH_ATTR(daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_YANG) + /* ALIAS macro which define existing command's alias. */ #define ALIAS(funcname, cmdname, cmdstr, helpstr) \ DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) @@ -317,6 +335,9 @@ struct cmd_node { DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, \ CMD_ATTR_DEPRECATED, 0) +#define ALIAS_YANG(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_YANG, 0) + #define ALIAS_SH(daemon, funcname, cmdname, cmdstr, helpstr) \ DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon) diff --git a/lib/command_graph.h b/lib/command_graph.h index 1efe8b1803..179e104a57 100644 --- a/lib/command_graph.h +++ b/lib/command_graph.h @@ -74,6 +74,7 @@ enum cmd_token_type { enum { CMD_ATTR_NORMAL, CMD_ATTR_DEPRECATED, CMD_ATTR_HIDDEN, + CMD_ATTR_YANG, }; /* Comamand token struct. */ diff --git a/lib/defun_lex.l b/lib/defun_lex.l index 19b06f51b8..bc5fbd24d9 100644 --- a/lib/defun_lex.l +++ b/lib/defun_lex.l @@ -140,6 +140,8 @@ SPECIAL [(),] "DEFPY_NOSH" value = strdup(yytext); return DEFUNNY; "DEFPY_ATTR" value = strdup(yytext); return DEFUNNY; "DEFPY_HIDDEN" value = strdup(yytext); return DEFUNNY; +"DEFPY_YANG" value = strdup(yytext); return DEFUNNY; +"DEFPY_YANG_NOSH" value = strdup(yytext); return DEFUNNY; "ALIAS" value = strdup(yytext); return DEFUNNY; "ALIAS_HIDDEN" value = strdup(yytext); return DEFUNNY; "install_element" value = strdup(yytext); return INSTALL; diff --git a/lib/filter_cli.c b/lib/filter_cli.c index 030039b3fe..8c7a515dc5 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -169,7 +169,7 @@ static long acl_get_seq(struct vty *vty, const char *xpath) /* * Cisco (legacy) access lists. */ -DEFPY( +DEFPY_YANG( access_list_std, access_list_std_cmd, "access-list <(1-99)|(1300-1999)>$number [seq (1-4294967295)$seq] <deny|permit>$action <[host] A.B.C.D$host|A.B.C.D$host A.B.C.D$mask|any>", ACCESS_LIST_STR @@ -220,7 +220,7 @@ DEFPY( return nb_cli_apply_changes(vty, xpath_entry); } -DEFPY( +DEFPY_YANG( no_access_list_std, no_access_list_std_cmd, "no access-list <(1-99)|(1300-1999)>$number [seq (1-4294967295)$seq] <deny|permit>$action <[host] A.B.C.D$host|A.B.C.D$host A.B.C.D$mask|any>", NO_STR @@ -280,7 +280,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( access_list_ext, access_list_ext_cmd, "access-list <(100-199)|(2000-2699)>$number [seq (1-4294967295)$seq] <deny|permit>$action ip <A.B.C.D$src A.B.C.D$src_mask|host A.B.C.D$src|any> <A.B.C.D$dst A.B.C.D$dst_mask|host A.B.C.D$dst|any>", ACCESS_LIST_STR @@ -351,7 +351,7 @@ DEFPY( return nb_cli_apply_changes(vty, xpath_entry); } -DEFPY( +DEFPY_YANG( no_access_list_ext, no_access_list_ext_cmd, "no access-list <(100-199)|(2000-2699)>$number [seq (1-4294967295)$seq] <deny|permit>$action ip <A.B.C.D$src A.B.C.D$src_mask|host A.B.C.D$src|any> <A.B.C.D$dst A.B.C.D$dst_mask|host A.B.C.D$dst|any>", NO_STR @@ -436,7 +436,7 @@ DEFPY( /* * Zebra access lists. */ -DEFPY( +DEFPY_YANG( access_list, access_list_cmd, "access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <A.B.C.D/M$prefix [exact-match$exact]|any>", ACCESS_LIST_STR @@ -482,7 +482,7 @@ DEFPY( return nb_cli_apply_changes(vty, xpath_entry); } -DEFPY( +DEFPY_YANG( no_access_list, no_access_list_cmd, "no access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <A.B.C.D/M$prefix [exact-match$exact]|any>", NO_STR @@ -539,7 +539,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_access_list_all, no_access_list_all_cmd, "no access-list WORD$name", NO_STR @@ -555,7 +555,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( access_list_remark, access_list_remark_cmd, "access-list WORD$name remark LINE...", ACCESS_LIST_STR @@ -579,7 +579,7 @@ DEFPY( return rv; } -DEFPY( +DEFPY_YANG( no_access_list_remark, no_access_list_remark_cmd, "no access-list WORD$name remark", NO_STR @@ -606,7 +606,7 @@ ALIAS( ACCESS_LIST_REMARK_STR ACCESS_LIST_REMARK_LINE_STR) -DEFPY( +DEFPY_YANG( ipv6_access_list, ipv6_access_list_cmd, "ipv6 access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X::X:X/M$prefix [exact-match$exact]|any>", IPV6_STR @@ -653,7 +653,7 @@ DEFPY( return nb_cli_apply_changes(vty, xpath_entry); } -DEFPY( +DEFPY_YANG( no_ipv6_access_list, no_ipv6_access_list_cmd, "no ipv6 access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X::X:X/M$prefix [exact-match$exact]|any>", NO_STR @@ -711,7 +711,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_ipv6_access_list_all, no_ipv6_access_list_all_cmd, "no ipv6 access-list WORD$name", NO_STR @@ -728,7 +728,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( ipv6_access_list_remark, ipv6_access_list_remark_cmd, "ipv6 access-list WORD$name remark LINE...", IPV6_STR @@ -753,7 +753,7 @@ DEFPY( return rv; } -DEFPY( +DEFPY_YANG( no_ipv6_access_list_remark, no_ipv6_access_list_remark_cmd, "no ipv6 access-list WORD$name remark", NO_STR @@ -782,7 +782,7 @@ ALIAS( ACCESS_LIST_REMARK_STR ACCESS_LIST_REMARK_LINE_STR) -DEFPY( +DEFPY_YANG( mac_access_list, mac_access_list_cmd, "mac access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$mac|any>", MAC_STR @@ -825,7 +825,7 @@ DEFPY( return nb_cli_apply_changes(vty, xpath_entry); } -DEFPY( +DEFPY_YANG( no_mac_access_list, no_mac_access_list_cmd, "no mac access-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <X:X:X:X:X:X$prefix|any>", NO_STR @@ -882,7 +882,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_mac_access_list_all, no_mac_access_list_all_cmd, "no mac access-list WORD$name", NO_STR @@ -899,7 +899,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( mac_access_list_remark, mac_access_list_remark_cmd, "mac access-list WORD$name remark LINE...", MAC_STR @@ -924,7 +924,7 @@ DEFPY( return rv; } -DEFPY( +DEFPY_YANG( no_mac_access_list_remark, no_mac_access_list_remark_cmd, "no mac access-list WORD$name remark", NO_STR @@ -1182,7 +1182,7 @@ static int plist_remove(struct vty *vty, const char *iptype, const char *name, return rv; } -DEFPY( +DEFPY_YANG( ip_prefix_list, ip_prefix_list_cmd, "ip prefix-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <any|A.B.C.D/M$prefix [{ge (0-32)$ge|le (0-32)$le}]>", IP_STR @@ -1239,7 +1239,7 @@ DEFPY( return nb_cli_apply_changes(vty, xpath_entry); } -DEFPY( +DEFPY_YANG( no_ip_prefix_list, no_ip_prefix_list_cmd, "no ip prefix-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <any|A.B.C.D/M$prefix [{ge (0-32)|le (0-32)}]>", NO_STR @@ -1259,7 +1259,7 @@ DEFPY( (struct prefix *)prefix, ge, le); } -DEFPY( +DEFPY_YANG( no_ip_prefix_list_seq, no_ip_prefix_list_seq_cmd, "no ip prefix-list WORD$name seq (1-4294967295)$seq", NO_STR @@ -1271,7 +1271,7 @@ DEFPY( return plist_remove(vty, "ipv4", name, seq_str, NULL, NULL, 0, 0); } -DEFPY( +DEFPY_YANG( no_ip_prefix_list_all, no_ip_prefix_list_all_cmd, "no ip prefix-list WORD$name", NO_STR @@ -1288,7 +1288,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( ip_prefix_list_remark, ip_prefix_list_remark_cmd, "ip prefix-list WORD$name description LINE...", IP_STR @@ -1313,7 +1313,7 @@ DEFPY( return rv; } -DEFPY( +DEFPY_YANG( no_ip_prefix_list_remark, no_ip_prefix_list_remark_cmd, "no ip prefix-list WORD$name description", NO_STR @@ -1342,7 +1342,7 @@ ALIAS( ACCESS_LIST_REMARK_STR ACCESS_LIST_REMARK_LINE_STR) -DEFPY( +DEFPY_YANG( ipv6_prefix_list, ipv6_prefix_list_cmd, "ipv6 prefix-list WORD$name [seq (1-4294967295)] <deny|permit>$action <any|X:X::X:X/M$prefix [{ge (0-128)$ge|le (0-128)$le}]>", IPV6_STR @@ -1399,7 +1399,7 @@ DEFPY( return nb_cli_apply_changes(vty, xpath_entry); } -DEFPY( +DEFPY_YANG( no_ipv6_prefix_list, no_ipv6_prefix_list_cmd, "no ipv6 prefix-list WORD$name [seq (1-4294967295)$seq] <deny|permit>$action <any|X:X::X:X/M$prefix [{ge (0-128)$ge|le (0-128)$le}]>", NO_STR @@ -1419,7 +1419,7 @@ DEFPY( (struct prefix *)prefix, ge, le); } -DEFPY( +DEFPY_YANG( no_ipv6_prefix_list_seq, no_ipv6_prefix_list_seq_cmd, "no ipv6 prefix-list WORD$name seq (1-4294967295)$seq", NO_STR @@ -1431,7 +1431,7 @@ DEFPY( return plist_remove(vty, "ipv6", name, seq_str, NULL, NULL, 0, 0); } -DEFPY( +DEFPY_YANG( no_ipv6_prefix_list_all, no_ipv6_prefix_list_all_cmd, "no ipv6 prefix-list WORD$name", NO_STR @@ -1448,7 +1448,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( ipv6_prefix_list_remark, ipv6_prefix_list_remark_cmd, "ipv6 prefix-list WORD$name description LINE...", IPV6_STR @@ -1473,7 +1473,7 @@ DEFPY( return rv; } -DEFPY( +DEFPY_YANG( no_ipv6_prefix_list_remark, no_ipv6_prefix_list_remark_cmd, "no ipv6 prefix-list WORD$name description", NO_STR @@ -1321,7 +1321,7 @@ void if_link_params_free(struct interface *ifp) /* * XPath: /frr-interface:lib/interface */ -DEFPY_NOSH (interface, +DEFPY_YANG_NOSH (interface, interface_cmd, "interface IFNAME [vrf NAME$vrf_name]", "Select an interface to configure\n" @@ -1384,6 +1384,7 @@ DEFPY_NOSH (interface, * all interface-level commands are converted to the new * northbound model. */ + nb_cli_pending_commit_check(vty); ifp = if_lookup_by_name(ifname, vrf_id); if (ifp) VTY_PUSH_CONTEXT(INTERFACE_NODE, ifp); @@ -1392,7 +1393,7 @@ DEFPY_NOSH (interface, return ret; } -DEFPY (no_interface, +DEFPY_YANG (no_interface, no_interface_cmd, "no interface IFNAME [vrf NAME$vrf_name]", NO_STR @@ -1427,7 +1428,7 @@ static void cli_show_interface(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/description */ -DEFPY (interface_desc, +DEFPY_YANG (interface_desc, interface_desc_cmd, "description LINE...", "Interface specific description\n" @@ -1444,7 +1445,7 @@ DEFPY (interface_desc, return ret; } -DEFPY (no_interface_desc, +DEFPY_YANG (no_interface_desc, no_interface_desc_cmd, "no description", NO_STR diff --git a/lib/ipaddr.h b/lib/ipaddr.h index a96c9788bc..f2b75c1306 100644 --- a/lib/ipaddr.h +++ b/lib/ipaddr.h @@ -89,6 +89,13 @@ static inline char *ipaddr2str(const struct ipaddr *ip, char *buf, int size) return buf; } +#define IS_MAPPED_IPV6(A) \ + ((A)->s6_addr32[0] == 0x00000000 \ + ? ((A)->s6_addr32[1] == 0x00000000 \ + ? (ntohl((A)->s6_addr32[2]) == 0xFFFF ? 1 : 0) \ + : 0) \ + : 0) + /* * Convert IPv4 address to IPv4-mapped IPv6 address which is of the * form ::FFFF:<IPv4 address> (RFC 4291). This IPv6 address can then diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 105fc83cef..534b5128ee 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -53,6 +53,106 @@ static void vty_show_nb_errors(struct vty *vty, int error, const char *errmsg) vty_out(vty, "Error description: %s\n", errmsg); } +static int nb_cli_classic_commit(struct vty *vty) +{ + struct nb_context context = {}; + char errmsg[BUFSIZ] = {0}; + int ret; + + context.client = NB_CLIENT_CLI; + context.user = vty; + ret = nb_candidate_commit(&context, vty->candidate_config, true, NULL, + NULL, errmsg, sizeof(errmsg)); + if (ret != NB_OK && ret != NB_ERR_NO_CHANGES) { + vty_out(vty, "%% Configuration failed.\n\n"); + vty_show_nb_errors(vty, ret, errmsg); + if (vty->t_pending_commit) + vty_out(vty, + "The following commands were dynamically grouped into the same transaction and rejected:\n%s", + vty->pending_cmds_buf); + + /* Regenerate candidate for consistency. */ + nb_config_replace(vty->candidate_config, running_config, true); + return CMD_WARNING_CONFIG_FAILED; + } + + return CMD_SUCCESS; +} + +static void nb_cli_pending_commit_clear(struct vty *vty) +{ + THREAD_TIMER_OFF(vty->t_pending_commit); + vty->backoff_cmd_count = 0; + XFREE(MTYPE_TMP, vty->pending_cmds_buf); + vty->pending_cmds_buflen = 0; + vty->pending_cmds_bufpos = 0; +} + +static int nb_cli_pending_commit_cb(struct thread *thread) +{ + struct vty *vty = THREAD_ARG(thread); + + (void)nb_cli_classic_commit(vty); + nb_cli_pending_commit_clear(vty); + + return 0; +} + +void nb_cli_pending_commit_check(struct vty *vty) +{ + if (vty->t_pending_commit) { + (void)nb_cli_classic_commit(vty); + nb_cli_pending_commit_clear(vty); + } +} + +static bool nb_cli_backoff_start(struct vty *vty) +{ + struct timeval now, delta; + + /* + * Start the configuration backoff timer only if 100 YANG-modeled + * commands or more were entered within the last second. + */ + monotime(&now); + if (monotime_since(&vty->backoff_start, &delta) >= 1000000) { + vty->backoff_start = now; + vty->backoff_cmd_count = 1; + return false; + } + if (++vty->backoff_cmd_count < 100) + return false; + + return true; +} + +static int nb_cli_schedule_command(struct vty *vty) +{ + /* Append command to dynamically sized buffer of scheduled commands. */ + if (!vty->pending_cmds_buf) { + vty->pending_cmds_buflen = 4096; + vty->pending_cmds_buf = + XCALLOC(MTYPE_TMP, vty->pending_cmds_buflen); + } + if ((strlen(vty->buf) + 3) + > (vty->pending_cmds_buflen - vty->pending_cmds_bufpos)) { + vty->pending_cmds_buflen *= 2; + vty->pending_cmds_buf = + XREALLOC(MTYPE_TMP, vty->pending_cmds_buf, + vty->pending_cmds_buflen); + } + strlcat(vty->pending_cmds_buf, "- ", vty->pending_cmds_buflen); + vty->pending_cmds_bufpos = strlcat(vty->pending_cmds_buf, vty->buf, + vty->pending_cmds_buflen); + + /* Schedule the commit operation. */ + THREAD_TIMER_OFF(vty->t_pending_commit); + thread_add_timer_msec(master, nb_cli_pending_commit_cb, vty, 100, + &vty->t_pending_commit); + + return CMD_SUCCESS; +} + void nb_cli_enqueue_change(struct vty *vty, const char *xpath, enum nb_operation operation, const char *value) { @@ -76,7 +176,6 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) { char xpath_base[XPATH_MAXLEN] = {}; bool error = false; - int ret; VTY_CHECK_XPATH; @@ -95,6 +194,7 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) struct nb_node *nb_node; char xpath[XPATH_MAXLEN]; struct yang_data *data; + int ret; /* Handle relative XPaths. */ memset(xpath, 0, sizeof(xpath)); @@ -158,25 +258,19 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) yang_print_errors(ly_native_ctx, buf, sizeof(buf))); } - /* Do an implicit "commit" when using the classic CLI mode. */ + /* + * Do an implicit commit when using the classic CLI mode. + * + * NOTE: the implicit commit might be scheduled to run later when + * too many commands are being sent at the same time. This is a + * protection mechanism where multiple commands are grouped into the + * same configuration transaction, allowing them to be processed much + * faster. + */ if (frr_get_cli_mode() == FRR_CLI_CLASSIC) { - struct nb_context context = {}; - char errmsg[BUFSIZ] = {0}; - - context.client = NB_CLIENT_CLI; - context.user = vty; - ret = nb_candidate_commit(&context, vty->candidate_config, - false, NULL, NULL, errmsg, - sizeof(errmsg)); - if (ret != NB_OK && ret != NB_ERR_NO_CHANGES) { - vty_out(vty, "%% Configuration failed.\n\n"); - vty_show_nb_errors(vty, ret, errmsg); - - /* Regenerate candidate for consistency. */ - nb_config_replace(vty->candidate_config, running_config, - true); - return CMD_WARNING_CONFIG_FAILED; - } + if (vty->t_pending_commit || nb_cli_backoff_start(vty)) + return nb_cli_schedule_command(vty); + return nb_cli_classic_commit(vty); } return CMD_SUCCESS; diff --git a/lib/northbound_cli.h b/lib/northbound_cli.h index b2d8c8f035..112d62efda 100644 --- a/lib/northbound_cli.h +++ b/lib/northbound_cli.h @@ -108,6 +108,14 @@ extern int nb_cli_rpc(const char *xpath, struct list *input, extern void nb_cli_show_dnode_cmds(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +/* + * Perform pending commit, if any. + * + * vty + * The vty context. + */ +extern void nb_cli_pending_commit_check(struct vty *vty); + /* Prototypes of internal functions. */ extern void nb_cli_show_config_prepare(struct nb_config *config, bool with_defaults); diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index 31bee1310e..014147c3f8 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -39,7 +39,7 @@ #define ROUTE_MAP_SEQUENCE_CMD_STR \ "Sequence to insert to/delete from existing route-map entry\n" -DEFPY_NOSH( +DEFPY_YANG_NOSH( route_map, route_map_cmd, "route-map WORD$name <deny|permit>$action (1-65535)$sequence", ROUTE_MAP_CMD_STR @@ -70,6 +70,7 @@ DEFPY_NOSH( VTY_PUSH_XPATH(RMAP_NODE, xpath_index); /* Add support for non-migrated route map users. */ + nb_cli_pending_commit_check(vty); rm = route_map_get(name); action_type = (action[0] == 'p') ? RMAP_PERMIT : RMAP_DENY; rmi = route_map_index_get(rm, action_type, sequence); @@ -79,7 +80,7 @@ DEFPY_NOSH( return rv; } -DEFPY( +DEFPY_YANG( no_route_map_all, no_route_map_all_cmd, "no route-map WORD$name", NO_STR @@ -94,7 +95,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_route_map, no_route_map_cmd, "no route-map WORD$name <deny|permit>$action (1-65535)$sequence", NO_STR @@ -179,7 +180,7 @@ void route_map_instance_show_end(struct vty *vty, struct lyd_node *dnode) vty_out(vty, "!\n"); } -DEFPY( +DEFPY_YANG( match_interface, match_interface_cmd, "match interface IFNAME", MATCH_STR @@ -196,7 +197,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_interface, no_match_interface_cmd, "no match interface [IFNAME]", NO_STR @@ -211,7 +212,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ip_address, match_ip_address_cmd, "match ip address <(1-199)|(1300-2699)|WORD>$name", MATCH_STR @@ -231,7 +232,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ip_address, no_match_ip_address_cmd, "no match ip address [<(1-199)|(1300-2699)|WORD>]", NO_STR @@ -249,7 +250,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ip_address_prefix_list, match_ip_address_prefix_list_cmd, "match ip address prefix-list WORD$name", @@ -269,7 +270,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ip_address_prefix_list, no_match_ip_address_prefix_list_cmd, "no match ip address prefix-list [WORD]", NO_STR @@ -286,7 +287,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ip_next_hop, match_ip_next_hop_cmd, "match ip next-hop <(1-199)|(1300-2699)|WORD>$name", MATCH_STR @@ -306,7 +307,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ip_next_hop, no_match_ip_next_hop_cmd, "no match ip next-hop [<(1-199)|(1300-2699)|WORD>]", NO_STR @@ -324,7 +325,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ip_next_hop_prefix_list, match_ip_next_hop_prefix_list_cmd, "match ip next-hop prefix-list WORD$name", @@ -345,7 +346,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ip_next_hop_prefix_list, no_match_ip_next_hop_prefix_list_cmd, "no match ip next-hop prefix-list [WORD]", @@ -364,7 +365,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ip_next_hop_type, match_ip_next_hop_type_cmd, "match ip next-hop type <blackhole>$type", MATCH_STR @@ -384,7 +385,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ip_next_hop_type, no_match_ip_next_hop_type_cmd, "no match ip next-hop type [<blackhole>]", NO_STR MATCH_STR IP_STR @@ -399,7 +400,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ipv6_address, match_ipv6_address_cmd, "match ipv6 address WORD$name", MATCH_STR @@ -417,7 +418,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ipv6_address, no_match_ipv6_address_cmd, "no match ipv6 address [WORD]", NO_STR @@ -433,7 +434,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ipv6_address_prefix_list, match_ipv6_address_prefix_list_cmd, "match ipv6 address prefix-list WORD$name", MATCH_STR @@ -452,7 +453,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ipv6_address_prefix_list, no_match_ipv6_address_prefix_list_cmd, "no match ipv6 address prefix-list [WORD]", @@ -470,7 +471,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ipv6_next_hop_type, match_ipv6_next_hop_type_cmd, "match ipv6 next-hop type <blackhole>$type", MATCH_STR IPV6_STR @@ -489,7 +490,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd, "no match ipv6 next-hop type [<blackhole>]", NO_STR MATCH_STR IPV6_STR @@ -504,7 +505,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_metric, match_metric_cmd, "match metric (0-4294967295)$metric", MATCH_STR @@ -521,7 +522,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_metric, no_match_metric_cmd, "no match metric [(0-4294967295)]", NO_STR @@ -536,7 +537,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_tag, match_tag_cmd, "match tag (1-4294967295)$tag", MATCH_STR @@ -553,7 +554,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_tag, no_match_tag_cmd, "no match tag [(1-4294967295)]", NO_STR @@ -646,7 +647,7 @@ void route_map_condition_show(struct vty *vty, struct lyd_node *dnode, } } -DEFPY( +DEFPY_YANG( set_ip_nexthop, set_ip_nexthop_cmd, "set ip next-hop A.B.C.D$addr", SET_STR @@ -664,7 +665,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_set_ip_nexthop, no_set_ip_nexthop_cmd, "no set ip next-hop [A.B.C.D]", NO_STR @@ -680,7 +681,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( set_ipv6_nexthop_local, set_ipv6_nexthop_local_cmd, "set ipv6 next-hop local X:X::X:X$addr", SET_STR @@ -699,7 +700,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_set_ipv6_nexthop_local, no_set_ipv6_nexthop_local_cmd, "no set ipv6 next-hop local [X:X::X:X]", NO_STR @@ -716,7 +717,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( set_metric, set_metric_cmd, "set metric <(0-4294967295)$metric|rtt$rtt|+rtt$artt|-rtt$srtt|+metric$ametric|-metric$smetric>", SET_STR @@ -762,7 +763,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_set_metric, no_set_metric_cmd, "no set metric [(0-4294967295)]", NO_STR @@ -776,7 +777,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( set_tag, set_tag_cmd, "set tag (1-4294967295)$tag", SET_STR @@ -793,7 +794,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_set_tag, no_set_tag_cmd, "no set tag [(1-4294967295)]", NO_STR @@ -853,7 +854,7 @@ void route_map_action_show(struct vty *vty, struct lyd_node *dnode, } } -DEFPY( +DEFPY_YANG( rmap_onmatch_next, rmap_onmatch_next_cmd, "on-match next", "Exit policy on matches\n" @@ -864,7 +865,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_rmap_onmatch_next, no_rmap_onmatch_next_cmd, "no on-match next", @@ -877,7 +878,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( rmap_onmatch_goto, rmap_onmatch_goto_cmd, "on-match goto (1-65535)$rm_num", "Exit policy on matches\n" @@ -890,7 +891,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_rmap_onmatch_goto, no_rmap_onmatch_goto_cmd, "no on-match goto", NO_STR @@ -903,13 +904,13 @@ DEFPY( } /* Cisco/GNU Zebra compatibility aliases */ -ALIAS( +ALIAS_YANG( rmap_onmatch_goto, rmap_continue_cmd, "continue (1-65535)$rm_num", "Continue on a different entry within the route-map\n" "Route-map entry sequence number\n") -ALIAS( +ALIAS_YANG( no_rmap_onmatch_goto, no_rmap_continue_cmd, "no continue [(1-65535)]", NO_STR @@ -935,7 +936,7 @@ void route_map_exit_policy_show(struct vty *vty, struct lyd_node *dnode, } } -DEFPY( +DEFPY_YANG( rmap_call, rmap_call_cmd, "call WORD$name", "Jump to another Route-Map after match+set\n" @@ -946,7 +947,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_rmap_call, no_rmap_call_cmd, "no call", NO_STR @@ -963,7 +964,7 @@ void route_map_call_show(struct vty *vty, struct lyd_node *dnode, vty_out(vty, " call %s\n", yang_dnode_get_string(dnode, NULL)); } -DEFPY( +DEFPY_YANG( rmap_description, rmap_description_cmd, "description LINE...", "Route-map comment\n" @@ -980,7 +981,7 @@ DEFPY( return rv; } -DEFUN (no_rmap_description, +DEFUN_YANG (no_rmap_description, no_rmap_description_cmd, "no description", NO_STR @@ -638,6 +638,7 @@ int vrf_handler_create(struct vty *vty, const char *vrfname, ret = nb_cli_apply_changes(vty, xpath_list); if (ret == CMD_SUCCESS) { VTY_PUSH_XPATH(VRF_NODE, xpath_list); + nb_cli_pending_commit_check(vty); vrfp = vrf_lookup_by_name(vrfname); if (vrfp) VTY_PUSH_CONTEXT(VRF_NODE, vrfp); @@ -731,7 +732,7 @@ DEFUN_NOSH(vrf_exit, return CMD_SUCCESS; } -DEFUN_NOSH (vrf, +DEFUN_YANG_NOSH (vrf, vrf_cmd, "vrf NAME", "Select a VRF to configure\n" @@ -743,7 +744,7 @@ DEFUN_NOSH (vrf, return vrf_handler_create(vty, vrfname, NULL); } -DEFUN (no_vrf, +DEFUN_YANG (no_vrf, no_vrf_cmd, "no vrf NAME", NO_STR @@ -2631,6 +2631,9 @@ int vty_config_node_exit(struct vty *vty) { vty->xpath_index = 0; + /* Perform pending commit if any. */ + nb_cli_pending_commit_check(vty); + /* Check if there's a pending confirmed commit. */ if (vty->t_confirmed_commit_timeout) { vty_out(vty, @@ -134,6 +134,14 @@ struct vty { /* Base candidate configuration. */ struct nb_config *candidate_config_base; + /* Dynamic transaction information. */ + struct timeval backoff_start; + size_t backoff_cmd_count; + struct thread *t_pending_commit; + char *pending_cmds_buf; + size_t pending_cmds_buflen; + size_t pending_cmds_bufpos; + /* Confirmed-commit timeout and rollback configuration. */ struct thread *t_confirmed_commit_timeout; struct nb_config *confirmed_commit_rollback; diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index e4270f09a5..0c5513b892 100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c @@ -198,6 +198,10 @@ int nhrp_route_read(ZAPI_CALLBACK_ARGS) if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) return 0; + /* ignore our routes */ + if (api.type == ZEBRA_ROUTE_NHRP) + return 0; + sockunion_family(&nexthop_addr) = AF_UNSPEC; if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { api_nh = &api.nexthops[0]; diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index 7e2394f473..5e64b7afdb 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -37,7 +37,7 @@ /* * XPath: /frr-ripd:ripd/instance */ -DEFPY_NOSH (router_rip, +DEFPY_YANG_NOSH (router_rip, router_rip_cmd, "router rip [vrf NAME]", "Enable a routing process\n" @@ -62,7 +62,7 @@ DEFPY_NOSH (router_rip, return ret; } -DEFPY (no_router_rip, +DEFPY_YANG (no_router_rip, no_router_rip_cmd, "no router rip [vrf NAME]", NO_STR @@ -100,7 +100,7 @@ void cli_show_router_rip(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/allow-ecmp */ -DEFPY (rip_allow_ecmp, +DEFPY_YANG (rip_allow_ecmp, rip_allow_ecmp_cmd, "[no] allow-ecmp", NO_STR @@ -124,7 +124,7 @@ void cli_show_rip_allow_ecmp(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/default-information-originate */ -DEFPY (rip_default_information_originate, +DEFPY_YANG (rip_default_information_originate, rip_default_information_originate_cmd, "[no] default-information originate", NO_STR @@ -150,7 +150,7 @@ void cli_show_rip_default_information_originate(struct vty *vty, /* * XPath: /frr-ripd:ripd/instance/default-metric */ -DEFPY (rip_default_metric, +DEFPY_YANG (rip_default_metric, rip_default_metric_cmd, "default-metric (1-16)", "Set a metric of redistribute routes\n" @@ -162,7 +162,7 @@ DEFPY (rip_default_metric, return nb_cli_apply_changes(vty, NULL); } -DEFPY (no_rip_default_metric, +DEFPY_YANG (no_rip_default_metric, no_rip_default_metric_cmd, "no default-metric [(1-16)]", NO_STR @@ -184,7 +184,7 @@ void cli_show_rip_default_metric(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/distance/default */ -DEFPY (rip_distance, +DEFPY_YANG (rip_distance, rip_distance_cmd, "distance (1-255)", "Administrative distance\n" @@ -196,7 +196,7 @@ DEFPY (rip_distance, return nb_cli_apply_changes(vty, NULL); } -DEFPY (no_rip_distance, +DEFPY_YANG (no_rip_distance, no_rip_distance_cmd, "no distance [(1-255)]", NO_STR @@ -221,7 +221,7 @@ void cli_show_rip_distance(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/distance/source */ -DEFPY (rip_distance_source, +DEFPY_YANG (rip_distance_source, rip_distance_source_cmd, "[no] distance (1-255) A.B.C.D/M$prefix [WORD$acl]", NO_STR @@ -258,7 +258,7 @@ void cli_show_rip_distance_source(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/explicit-neighbor */ -DEFPY (rip_neighbor, +DEFPY_YANG (rip_neighbor, rip_neighbor_cmd, "[no] neighbor A.B.C.D", NO_STR @@ -280,7 +280,7 @@ void cli_show_rip_neighbor(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/network */ -DEFPY (rip_network_prefix, +DEFPY_YANG (rip_network_prefix, rip_network_prefix_cmd, "[no] network A.B.C.D/M", NO_STR @@ -302,7 +302,7 @@ void cli_show_rip_network_prefix(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/interface */ -DEFPY (rip_network_if, +DEFPY_YANG (rip_network_if, rip_network_if_cmd, "[no] network WORD", NO_STR @@ -324,7 +324,7 @@ void cli_show_rip_network_interface(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/offset-list */ -DEFPY (rip_offset_list, +DEFPY_YANG (rip_offset_list, rip_offset_list_cmd, "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]", NO_STR @@ -367,7 +367,7 @@ void cli_show_rip_offset_list(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/passive-default */ -DEFPY (rip_passive_default, +DEFPY_YANG (rip_passive_default, rip_passive_default_cmd, "[no] passive-interface default", NO_STR @@ -393,7 +393,7 @@ void cli_show_rip_passive_default(struct vty *vty, struct lyd_node *dnode, * XPath: /frr-ripd:ripd/instance/passive-interface * /frr-ripd:ripd/instance/non-passive-interface */ -DEFPY (rip_passive_interface, +DEFPY_YANG (rip_passive_interface, rip_passive_interface_cmd, "[no] passive-interface IFNAME", NO_STR @@ -434,7 +434,7 @@ void cli_show_rip_non_passive_interface(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/redistribute */ -DEFPY (rip_redistribute, +DEFPY_YANG (rip_redistribute, rip_redistribute_cmd, "[no] redistribute " FRR_REDIST_STR_RIPD "$protocol [{metric (0-16)|route-map WORD}]", NO_STR @@ -477,7 +477,7 @@ void cli_show_rip_redistribute(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/static-route */ -DEFPY (rip_route, +DEFPY_YANG (rip_route, rip_route_cmd, "[no] route A.B.C.D/M", NO_STR @@ -499,7 +499,7 @@ void cli_show_rip_route(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/timers */ -DEFPY (rip_timers, +DEFPY_YANG (rip_timers, rip_timers_cmd, "timers basic (5-2147483647)$update (5-2147483647)$timeout (5-2147483647)$garbage", "Adjust routing timers\n" @@ -518,7 +518,7 @@ DEFPY (rip_timers, return nb_cli_apply_changes(vty, "./timers"); } -DEFPY (no_rip_timers, +DEFPY_YANG (no_rip_timers, no_rip_timers_cmd, "no timers basic [(5-2147483647) (5-2147483647) (5-2147483647)]", NO_STR @@ -547,7 +547,7 @@ void cli_show_rip_timers(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripd:ripd/instance/version */ -DEFPY (rip_version, +DEFPY_YANG (rip_version, rip_version_cmd, "version (1-2)", "Set routing protocol version\n" @@ -560,7 +560,7 @@ DEFPY (rip_version, return nb_cli_apply_changes(vty, NULL); } -DEFPY (no_rip_version, +DEFPY_YANG (no_rip_version, no_rip_version_cmd, "no version [(1-2)]", NO_STR @@ -596,7 +596,7 @@ void cli_show_rip_version(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon */ -DEFPY (ip_rip_split_horizon, +DEFPY_YANG (ip_rip_split_horizon, ip_rip_split_horizon_cmd, "[no] ip rip split-horizon [poisoned-reverse$poisoned_reverse]", NO_STR @@ -641,7 +641,7 @@ void cli_show_ip_rip_split_horizon(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast */ -DEFPY (ip_rip_v2_broadcast, +DEFPY_YANG (ip_rip_v2_broadcast, ip_rip_v2_broadcast_cmd, "[no] ip rip v2-broadcast", NO_STR @@ -667,7 +667,7 @@ void cli_show_ip_rip_v2_broadcast(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive */ -DEFPY (ip_rip_receive_version, +DEFPY_YANG (ip_rip_receive_version, ip_rip_receive_version_cmd, "ip rip receive version <{1$v1|2$v2}|none>", IP_STR @@ -694,7 +694,7 @@ DEFPY (ip_rip_receive_version, return nb_cli_apply_changes(vty, "./frr-ripd:rip"); } -DEFPY (no_ip_rip_receive_version, +DEFPY_YANG (no_ip_rip_receive_version, no_ip_rip_receive_version_cmd, "no ip rip receive version [<{1|2}|none>]", NO_STR @@ -736,7 +736,7 @@ void cli_show_ip_rip_receive_version(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send */ -DEFPY (ip_rip_send_version, +DEFPY_YANG (ip_rip_send_version, ip_rip_send_version_cmd, "ip rip send version <{1$v1|2$v2}|none>", IP_STR @@ -763,7 +763,7 @@ DEFPY (ip_rip_send_version, return nb_cli_apply_changes(vty, "./frr-ripd:rip"); } -DEFPY (no_ip_rip_send_version, +DEFPY_YANG (no_ip_rip_send_version, no_ip_rip_send_version_cmd, "no ip rip send version [<{1|2}|none>]", NO_STR @@ -805,7 +805,7 @@ void cli_show_ip_rip_send_version(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme */ -DEFPY (ip_rip_authentication_mode, +DEFPY_YANG (ip_rip_authentication_mode, ip_rip_authentication_mode_cmd, "ip rip authentication mode <md5$mode [auth-length <rfc|old-ripd>$auth_length]|text$mode>", IP_STR @@ -837,7 +837,7 @@ DEFPY (ip_rip_authentication_mode, return nb_cli_apply_changes(vty, "./frr-ripd:rip"); } -DEFPY (no_ip_rip_authentication_mode, +DEFPY_YANG (no_ip_rip_authentication_mode, no_ip_rip_authentication_mode_cmd, "no ip rip authentication mode [<md5 [auth-length <rfc|old-ripd>]|text>]", NO_STR @@ -888,7 +888,7 @@ void cli_show_ip_rip_authentication_scheme(struct vty *vty, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password */ -DEFPY (ip_rip_authentication_string, +DEFPY_YANG (ip_rip_authentication_string, ip_rip_authentication_string_cmd, "ip rip authentication string LINE$password", IP_STR @@ -916,7 +916,7 @@ DEFPY (ip_rip_authentication_string, return nb_cli_apply_changes(vty, "./frr-ripd:rip"); } -DEFPY (no_ip_rip_authentication_string, +DEFPY_YANG (no_ip_rip_authentication_string, no_ip_rip_authentication_string_cmd, "no ip rip authentication string [LINE]", NO_STR @@ -943,7 +943,7 @@ void cli_show_ip_rip_authentication_string(struct vty *vty, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain */ -DEFPY (ip_rip_authentication_key_chain, +DEFPY_YANG (ip_rip_authentication_key_chain, ip_rip_authentication_key_chain_cmd, "ip rip authentication key-chain LINE$keychain", IP_STR @@ -965,7 +965,7 @@ DEFPY (ip_rip_authentication_key_chain, return nb_cli_apply_changes(vty, "./frr-ripd:rip"); } -DEFPY (no_ip_rip_authentication_key_chain, +DEFPY_YANG (no_ip_rip_authentication_key_chain, no_ip_rip_authentication_key_chain_cmd, "no ip rip authentication key-chain [LINE]", NO_STR @@ -992,7 +992,7 @@ void cli_show_ip_rip_authentication_key_chain(struct vty *vty, /* * XPath: /frr-ripd:clear-rip-route */ -DEFPY (clear_ip_rip, +DEFPY_YANG (clear_ip_rip, clear_ip_rip_cmd, "clear ip rip [vrf WORD]", CLEAR_STR diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c index b3d92fb0d9..f66de175fa 100644 --- a/ripngd/ripng_cli.c +++ b/ripngd/ripng_cli.c @@ -37,7 +37,7 @@ /* * XPath: /frr-ripngd:ripngd/instance */ -DEFPY_NOSH (router_ripng, +DEFPY_YANG_NOSH (router_ripng, router_ripng_cmd, "router ripng [vrf NAME]", "Enable a routing process\n" @@ -62,7 +62,7 @@ DEFPY_NOSH (router_ripng, return ret; } -DEFPY (no_router_ripng, +DEFPY_YANG (no_router_ripng, no_router_ripng_cmd, "no router ripng [vrf NAME]", NO_STR @@ -100,7 +100,7 @@ void cli_show_router_ripng(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/allow-ecmp */ -DEFPY (ripng_allow_ecmp, +DEFPY_YANG (ripng_allow_ecmp, ripng_allow_ecmp_cmd, "[no] allow-ecmp", NO_STR @@ -124,7 +124,7 @@ void cli_show_ripng_allow_ecmp(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/default-information-originate */ -DEFPY (ripng_default_information_originate, +DEFPY_YANG (ripng_default_information_originate, ripng_default_information_originate_cmd, "[no] default-information originate", NO_STR @@ -150,7 +150,7 @@ void cli_show_ripng_default_information_originate(struct vty *vty, /* * XPath: /frr-ripngd:ripngd/instance/default-metric */ -DEFPY (ripng_default_metric, +DEFPY_YANG (ripng_default_metric, ripng_default_metric_cmd, "default-metric (1-16)", "Set a metric of redistribute routes\n" @@ -162,7 +162,7 @@ DEFPY (ripng_default_metric, return nb_cli_apply_changes(vty, NULL); } -DEFPY (no_ripng_default_metric, +DEFPY_YANG (no_ripng_default_metric, no_ripng_default_metric_cmd, "no default-metric [(1-16)]", NO_STR @@ -184,7 +184,7 @@ void cli_show_ripng_default_metric(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/network */ -DEFPY (ripng_network_prefix, +DEFPY_YANG (ripng_network_prefix, ripng_network_prefix_cmd, "[no] network X:X::X:X/M", NO_STR @@ -206,7 +206,7 @@ void cli_show_ripng_network_prefix(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/interface */ -DEFPY (ripng_network_if, +DEFPY_YANG (ripng_network_if, ripng_network_if_cmd, "[no] network WORD", NO_STR @@ -228,7 +228,7 @@ void cli_show_ripng_network_interface(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/offset-list */ -DEFPY (ripng_offset_list, +DEFPY_YANG (ripng_offset_list, ripng_offset_list_cmd, "[no] offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]", NO_STR @@ -271,7 +271,7 @@ void cli_show_ripng_offset_list(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/passive-interface */ -DEFPY (ripng_passive_interface, +DEFPY_YANG (ripng_passive_interface, ripng_passive_interface_cmd, "[no] passive-interface IFNAME", NO_STR @@ -294,7 +294,7 @@ void cli_show_ripng_passive_interface(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/redistribute */ -DEFPY (ripng_redistribute, +DEFPY_YANG (ripng_redistribute, ripng_redistribute_cmd, "[no] redistribute " FRR_REDIST_STR_RIPNGD "$protocol [{metric (0-16)|route-map WORD}]", NO_STR @@ -337,7 +337,7 @@ void cli_show_ripng_redistribute(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/static-route */ -DEFPY (ripng_route, +DEFPY_YANG (ripng_route, ripng_route_cmd, "[no] route X:X::X:X/M", NO_STR @@ -359,7 +359,7 @@ void cli_show_ripng_route(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/aggregate-addres */ -DEFPY (ripng_aggregate_address, +DEFPY_YANG (ripng_aggregate_address, ripng_aggregate_address_cmd, "[no] aggregate-address X:X::X:X/M", NO_STR @@ -383,7 +383,7 @@ void cli_show_ripng_aggregate_address(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:ripngd/instance/timers */ -DEFPY (ripng_timers, +DEFPY_YANG (ripng_timers, ripng_timers_cmd, "timers basic (1-65535)$update (1-65535)$timeout (1-65535)$garbage", "RIPng timers setup\n" @@ -402,7 +402,7 @@ DEFPY (ripng_timers, return nb_cli_apply_changes(vty, "./timers"); } -DEFPY (no_ripng_timers, +DEFPY_YANG (no_ripng_timers, no_ripng_timers_cmd, "no timers basic [(1-65535) (1-65535) (1-65535)]", NO_STR @@ -431,7 +431,7 @@ void cli_show_ripng_timers(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon */ -DEFPY (ipv6_ripng_split_horizon, +DEFPY_YANG (ipv6_ripng_split_horizon, ipv6_ripng_split_horizon_cmd, "[no] ipv6 ripng split-horizon [poisoned-reverse$poisoned_reverse]", NO_STR @@ -476,7 +476,7 @@ void cli_show_ipv6_ripng_split_horizon(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-ripngd:clear-ripng-route */ -DEFPY (clear_ipv6_rip, +DEFPY_YANG (clear_ipv6_rip, clear_ipv6_rip_cmd, "clear ipv6 ripng [vrf WORD]", CLEAR_STR diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c index 40b41fd728..ccf34b10dd 100644 --- a/sharpd/sharp_main.c +++ b/sharpd/sharp_main.c @@ -167,9 +167,6 @@ int main(int argc, char **argv, char **envp) nexthop_group_init(NULL, NULL, NULL, NULL); vrf_init(NULL, NULL, NULL, NULL, NULL); - access_list_init(); - route_map_init(); - sharp_zebra_init(); /* Get configuration file. */ diff --git a/staticd/static_main.c b/staticd/static_main.c index 0b5063a083..ac8f8ff029 100644 --- a/staticd/static_main.c +++ b/staticd/static_main.c @@ -155,7 +155,6 @@ int main(int argc, char **argv, char **envp) master = frr_init(); - access_list_init(); static_debug_init(); static_vrf_init(); diff --git a/staticd/static_vty.c b/staticd/static_vty.c index 63b425771a..ac18f6adf4 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -451,7 +451,7 @@ int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi, } /* Static unicast routes for multicast RPF lookup. */ -DEFPY (ip_mroute_dist, +DEFPY_YANG (ip_mroute_dist, ip_mroute_dist_cmd, "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]", NO_STR @@ -468,7 +468,7 @@ DEFPY (ip_mroute_dist, } /* Static route configuration. */ -DEFPY(ip_route_blackhole, +DEFPY_YANG(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> \ @@ -506,7 +506,7 @@ DEFPY(ip_route_blackhole, distance_str, vrf, label, table_str); } -DEFPY(ip_route_blackhole_vrf, +DEFPY_YANG(ip_route_blackhole_vrf, ip_route_blackhole_vrf_cmd, "[no] ip route\ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ @@ -553,7 +553,7 @@ DEFPY(ip_route_blackhole_vrf, false); } -DEFPY(ip_route_address_interface, +DEFPY_YANG(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> \ @@ -607,7 +607,7 @@ DEFPY(ip_route_address_interface, !!onlink); } -DEFPY(ip_route_address_interface_vrf, +DEFPY_YANG(ip_route_address_interface_vrf, ip_route_address_interface_vrf_cmd, "[no] ip route\ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ @@ -666,7 +666,7 @@ DEFPY(ip_route_address_interface_vrf, !!onlink); } -DEFPY(ip_route, +DEFPY_YANG(ip_route, ip_route_cmd, "[no] ip route\ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ @@ -718,7 +718,7 @@ DEFPY(ip_route, false); } -DEFPY(ip_route_vrf, +DEFPY_YANG(ip_route_vrf, ip_route_vrf_cmd, "[no] ip route\ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \ @@ -775,7 +775,7 @@ DEFPY(ip_route_vrf, false); } -DEFPY(ipv6_route_blackhole, +DEFPY_YANG(ipv6_route_blackhole, ipv6_route_blackhole_cmd, "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ <reject|blackhole>$flag \ @@ -813,7 +813,7 @@ DEFPY(ipv6_route_blackhole, distance_str, vrf, label, table_str); } -DEFPY(ipv6_route_blackhole_vrf, +DEFPY_YANG(ipv6_route_blackhole_vrf, ipv6_route_blackhole_vrf_cmd, "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ <reject|blackhole>$flag \ @@ -862,7 +862,7 @@ DEFPY(ipv6_route_blackhole_vrf, false); } -DEFPY(ipv6_route_address_interface, +DEFPY_YANG(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 \ @@ -917,7 +917,7 @@ DEFPY(ipv6_route_address_interface, !!onlink); } -DEFPY(ipv6_route_address_interface_vrf, +DEFPY_YANG(ipv6_route_address_interface_vrf, ipv6_route_address_interface_vrf_cmd, "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ X:X::X:X$gate \ @@ -976,7 +976,7 @@ DEFPY(ipv6_route_address_interface_vrf, table_str, !!onlink); } -DEFPY(ipv6_route, +DEFPY_YANG(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|Null0>$ifname> \ @@ -1027,7 +1027,7 @@ DEFPY(ipv6_route, false); } -DEFPY(ipv6_route_vrf, +DEFPY_YANG(ipv6_route_vrf, ipv6_route_vrf_cmd, "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \ @@ -1082,7 +1082,7 @@ DEFPY(ipv6_route_vrf, ifname, flag, tag_str, distance_str, label, table_str, false); } -DEFPY(debug_staticd, +DEFPY_YANG(debug_staticd, debug_staticd_cmd, "[no] debug static [{events$events}]", NO_STR diff --git a/tests/topotests/all-protocol-startup/r1/show_route_map.ref b/tests/topotests/all-protocol-startup/r1/show_route_map.ref index 25786081d1..f95c48b7d7 100644 --- a/tests/topotests/all-protocol-startup/r1/show_route_map.ref +++ b/tests/topotests/all-protocol-startup/r1/show_route_map.ref @@ -70,4 +70,3 @@ route-map: bgp-map Invoked: 0 Optimization: enabled Action: Exit routemap ISIS: -SHARP: diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index dc7f023e8f..3165ea119a 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -52,7 +52,7 @@ /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group */ -DEFPY(vrrp_vrid, +DEFPY_YANG(vrrp_vrid, vrrp_vrid_cmd, "[no] vrrp (1-255)$vrid [version (2-3)]", NO_STR @@ -89,7 +89,7 @@ void cli_show_vrrp(struct vty *vty, struct lyd_node *dnode, bool show_defaults) /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/shutdown */ -DEFPY(vrrp_shutdown, +DEFPY_YANG(vrrp_shutdown, vrrp_shutdown_cmd, "[no] vrrp (1-255)$vrid shutdown", NO_STR @@ -115,7 +115,7 @@ void cli_show_shutdown(struct vty *vty, struct lyd_node *dnode, /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/priority */ -DEFPY(vrrp_priority, +DEFPY_YANG(vrrp_priority, vrrp_priority_cmd, "vrrp (1-255)$vrid priority (1-254)", VRRP_STR @@ -131,7 +131,7 @@ DEFPY(vrrp_priority, /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/priority */ -DEFPY(no_vrrp_priority, +DEFPY_YANG(no_vrrp_priority, no_vrrp_priority_cmd, "no vrrp (1-255)$vrid priority [(1-254)]", NO_STR @@ -158,7 +158,7 @@ void cli_show_priority(struct vty *vty, struct lyd_node *dnode, * XPath: * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/advertisement-interval */ -DEFPY(vrrp_advertisement_interval, +DEFPY_YANG(vrrp_advertisement_interval, vrrp_advertisement_interval_cmd, "vrrp (1-255)$vrid advertisement-interval (10-40950)", VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR @@ -179,7 +179,7 @@ DEFPY(vrrp_advertisement_interval, * XPath: * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/advertisement-interval */ -DEFPY(no_vrrp_advertisement_interval, +DEFPY_YANG(no_vrrp_advertisement_interval, no_vrrp_advertisement_interval_cmd, "no vrrp (1-255)$vrid advertisement-interval [(10-40950)]", NO_STR VRRP_STR VRRP_VRID_STR VRRP_ADVINT_STR @@ -205,7 +205,7 @@ void cli_show_advertisement_interval(struct vty *vty, struct lyd_node *dnode, * XPath: * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/virtual-address */ -DEFPY(vrrp_ip, +DEFPY_YANG(vrrp_ip, vrrp_ip_cmd, "[no] vrrp (1-255)$vrid ip A.B.C.D", NO_STR @@ -233,7 +233,7 @@ void cli_show_ip(struct vty *vty, struct lyd_node *dnode, bool show_defaults) * XPath: * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/virtual-address */ -DEFPY(vrrp_ip6, +DEFPY_YANG(vrrp_ip6, vrrp_ip6_cmd, "[no] vrrp (1-255)$vrid ipv6 X:X::X:X", NO_STR @@ -260,7 +260,7 @@ void cli_show_ipv6(struct vty *vty, struct lyd_node *dnode, bool show_defaults) /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/preempt */ -DEFPY(vrrp_preempt, +DEFPY_YANG(vrrp_preempt, vrrp_preempt_cmd, "[no] vrrp (1-255)$vrid preempt", NO_STR @@ -284,7 +284,7 @@ void cli_show_preempt(struct vty *vty, struct lyd_node *dnode, } /* XXX: yang conversion */ -DEFPY(vrrp_autoconfigure, +DEFPY_YANG(vrrp_autoconfigure, vrrp_autoconfigure_cmd, "[no] vrrp autoconfigure [version (2-3)]", NO_STR @@ -304,7 +304,7 @@ DEFPY(vrrp_autoconfigure, } /* XXX: yang conversion */ -DEFPY(vrrp_default, +DEFPY_YANG(vrrp_default, vrrp_default_cmd, "[no] vrrp default <advertisement-interval$adv (10-40950)$advint|preempt$p|priority$prio (1-254)$prioval|shutdown$s>", NO_STR @@ -583,7 +583,7 @@ static int vrrp_instance_display_sort_cmp(const void **d1, const void **d2) /* clang-format off */ -DEFPY(vrrp_vrid_show, +DEFPY_YANG(vrrp_vrid_show, vrrp_vrid_show_cmd, "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid] [json$json]", SHOW_STR @@ -624,7 +624,7 @@ DEFPY(vrrp_vrid_show, return CMD_SUCCESS; } -DEFPY(vrrp_vrid_show_summary, +DEFPY_YANG(vrrp_vrid_show_summary, vrrp_vrid_show_summary_cmd, "show vrrp [interface INTERFACE$ifn] [(1-255)$vrid] summary", SHOW_STR @@ -674,7 +674,7 @@ DEFPY(vrrp_vrid_show_summary, } -DEFPY(debug_vrrp, +DEFPY_YANG(debug_vrrp, debug_vrrp_cmd, "[no] debug vrrp [{protocol$proto|autoconfigure$ac|packets$pkt|sockets$sock|ndisc$ndisc|arp$arp|zebra$zebra}]", NO_STR diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index 346061d7ca..60c31bd847 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -48,7 +48,7 @@ sub scan_file { } # ?: makes a group non-capturing - @defun = ($line =~ /((?:DEFUN|DEFUN_HIDDEN|ALIAS|ALIAS_HIDDEN|DEFPY|DEFPY_HIDDEN)\s*\(.+?\));?\s?\s?\n/sg); + @defun = ($line =~ /((?:DEFUN|DEFUN_HIDDEN|DEFUN_YANG|ALIAS|ALIAS_HIDDEN|ALIAS_YANG|DEFPY|DEFPY_HIDDEN|DEFPY_YANG)\s*\(.+?\));?\s?\s?\n/sg); @install = ($line =~ /install_element\s*\(\s*[0-9A-Z_]+,\s*&[^;]*;\s*\n/sg); # DEFUN process @@ -98,7 +98,10 @@ sub scan_file { elsif ($file =~ /lib\/if\.c$/) { $protocol = "VTYSH_INTERFACE"; } - elsif ($file =~ /lib\/(filter|filter_cli|lib_vty)\.c$/) { + elsif ($file =~ /lib\/(filter|filter_cli)\.c$/) { + $protocol = "VTYSH_ACL"; + } + elsif ($file =~ /lib\/lib_vty\.c$/) { $protocol = "VTYSH_ALL"; } elsif ($file =~ /lib\/agentx\.c$/) { diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index d0edbb2710..d2675a81b9 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -52,7 +52,8 @@ DECLARE_MGROUP(MVTYSH) * run on it (logging & co. should stay in a fixed/frozen config, and * things like prefix lists are not even initialised) */ #define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_SHARPD|VTYSH_PBRD|VTYSH_STATICD|VTYSH_BFDD|VTYSH_FABRICD|VTYSH_VRRPD -#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_SHARPD|VTYSH_FABRICD +#define VTYSH_ACL VTYSH_BFDD|VTYSH_BABELD|VTYSH_BGPD|VTYSH_EIGRPD|VTYSH_ISISD|VTYSH_FABRICD|VTYSH_LDPD|VTYSH_NHRPD|VTYSH_OSPF6D|VTYSH_OSPFD|VTYSH_PBRD|VTYSH_PIMD|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_VRRPD|VTYSH_ZEBRA +#define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_FABRICD #define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_ISISD|VTYSH_PIMD|VTYSH_NHRPD|VTYSH_EIGRPD|VTYSH_BABELD|VTYSH_PBRD|VTYSH_FABRICD|VTYSH_VRRPD #define VTYSH_VRF VTYSH_ZEBRA|VTYSH_PIMD|VTYSH_STATICD #define VTYSH_KEYS VTYSH_RIPD|VTYSH_EIGRPD diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 61bcf3b658..85221b8b45 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -35,6 +35,7 @@ DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CONFIG_LINE, "Vtysh configuration line") vector configvec; PREDECL_LIST(config_master); +PREDECL_HASH(config_master_hash); struct config { /* Configuration node name. */ @@ -51,6 +52,7 @@ struct config { /* Node entry for the typed Red-black tree */ struct config_master_item rbt_item; + struct config_master_hash_item hash_item; }; struct list *config_top; @@ -79,29 +81,49 @@ static void config_del(struct config *config) XFREE(MTYPE_VTYSH_CONFIG, config); } +static int config_cmp(const struct config *c1, const struct config *c2) +{ + return strcmp(c1->name, c2->name); +} + +static uint32_t config_hash(const struct config *c) +{ + return string_hash_make(c->name); +} + DECLARE_LIST(config_master, struct config, rbt_item) +DECLARE_HASH(config_master_hash, struct config, hash_item, config_cmp, + config_hash) + +/* + * The config_master_head is a list for order of receipt + * The hash is for quick lookup under this NODE + */ +struct configuration { + struct config_master_head master; + struct config_master_hash_head hash_master; +}; static struct config *config_get(int index, const char *line) { struct config *config, *config_loop; - struct config_master_head *master; + struct configuration *configuration; + struct config lookup; config = config_loop = NULL; - master = vector_lookup_ensure(configvec, index); + configuration = vector_lookup_ensure(configvec, index); - if (!master) { - master = XMALLOC(MTYPE_VTYSH_CONFIG, sizeof(struct config_master_head)); - config_master_init(master); - vector_set_index(configvec, index, master); + if (!configuration) { + configuration = XMALLOC(MTYPE_VTYSH_CONFIG, + sizeof(struct configuration)); + config_master_init(&configuration->master); + config_master_hash_init(&configuration->hash_master); + vector_set_index(configvec, index, configuration); } - frr_each (config_master, master, config_loop) { - if (strcmp(config_loop->name, line) == 0) { - config = config_loop; - break; - } - } + lookup.name = (char *)line; + config = config_master_hash_find(&configuration->hash_master, &lookup); if (!config) { config = config_new(); @@ -110,7 +132,8 @@ static struct config *config_get(int index, const char *line) config->line->cmp = (int (*)(void *, void *))line_cmp; config->name = XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line); config->index = index; - config_master_add_tail(master, config); + config_master_add_tail(&configuration->master, config); + config_master_hash_add(&configuration->hash_master, config); } return config; } @@ -438,7 +461,7 @@ void vtysh_config_dump(void) struct listnode *node, *nnode; struct listnode *mnode, *mnnode; struct config *config; - struct config_master_head *master; + struct configuration *configuration; char *line; unsigned int i; @@ -448,8 +471,11 @@ void vtysh_config_dump(void) vty_out(vty, "!\n"); for (i = 0; i < vector_active(configvec); i++) - if ((master = vector_slot(configvec, i)) != NULL) { - while ((config = config_master_pop(master))) { + if ((configuration = vector_slot(configvec, i)) != NULL) { + while ((config = config_master_pop( + &configuration->master))) { + config_master_hash_del( + &configuration->hash_master, config); /* Don't print empty sections for interface. * Route maps on the * other hand could have a legitimate empty @@ -477,9 +503,10 @@ void vtysh_config_dump(void) } for (i = 0; i < vector_active(configvec); i++) - if ((master = vector_slot(configvec, i)) != NULL) { - config_master_fini(master); - XFREE(MTYPE_VTYSH_CONFIG, master); + if ((configuration = vector_slot(configvec, i)) != NULL) { + config_master_fini(&configuration->master); + config_master_hash_fini(&configuration->hash_master); + XFREE(MTYPE_VTYSH_CONFIG, configuration); vector_slot(configvec, i) = NULL; } list_delete_all_node(config_top); diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index ef208bdc83..c81d451693 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -72,6 +72,7 @@ struct fpm_nl_ctx { int socket; bool disabled; bool connecting; + bool nhg_complete; bool rib_complete; bool rmac_complete; bool use_nhg; @@ -149,8 +150,25 @@ enum fpm_nl_events { FNE_RESET_COUNTERS, /* Toggle next hop group feature. */ FNE_TOGGLE_NHG, + /* Reconnect request by our own code to avoid races. */ + FNE_INTERNAL_RECONNECT, + + /* Next hop groups walk finished. */ + FNE_NHG_FINISHED, + /* RIB walk finished. */ + FNE_RIB_FINISHED, + /* RMAC walk finished. */ + FNE_RMAC_FINISHED, }; +#define FPM_RECONNECT(fnc) \ + thread_add_event((fnc)->fthread->master, fpm_process_event, (fnc), \ + FNE_INTERNAL_RECONNECT, &(fnc)->t_event) + +#define WALK_FINISH(fnc, ev) \ + thread_add_event((fnc)->fthread->master, fpm_process_event, (fnc), \ + (ev), NULL) + /* * Prototypes. */ @@ -428,7 +446,18 @@ static int fpm_connect(struct thread *t); static void fpm_reconnect(struct fpm_nl_ctx *fnc) { - /* Grab the lock to empty the stream and stop the zebra thread. */ + /* Cancel all zebra threads first. */ + thread_cancel_async(zrouter.master, &fnc->t_nhgreset, NULL); + thread_cancel_async(zrouter.master, &fnc->t_nhgwalk, NULL); + thread_cancel_async(zrouter.master, &fnc->t_ribreset, NULL); + thread_cancel_async(zrouter.master, &fnc->t_ribwalk, NULL); + thread_cancel_async(zrouter.master, &fnc->t_rmacreset, NULL); + thread_cancel_async(zrouter.master, &fnc->t_rmacwalk, NULL); + + /* + * Grab the lock to empty the streams (data plane might try to + * enqueue updates while we are closing). + */ frr_mutex_lock_autounlock(&fnc->obuf_mutex); /* Avoid calling close on `-1`. */ @@ -442,13 +471,6 @@ static void fpm_reconnect(struct fpm_nl_ctx *fnc) THREAD_OFF(fnc->t_read); THREAD_OFF(fnc->t_write); - thread_cancel_async(zrouter.master, &fnc->t_nhgreset, NULL); - thread_cancel_async(zrouter.master, &fnc->t_nhgwalk, NULL); - thread_cancel_async(zrouter.master, &fnc->t_ribreset, NULL); - thread_cancel_async(zrouter.master, &fnc->t_ribwalk, NULL); - thread_cancel_async(zrouter.master, &fnc->t_rmacreset, NULL); - thread_cancel_async(zrouter.master, &fnc->t_rmacwalk, NULL); - /* FPM is disabled, don't attempt to connect. */ if (fnc->disabled) return; @@ -465,6 +487,13 @@ static int fpm_read(struct thread *t) /* Let's ignore the input at the moment. */ rv = stream_read_try(fnc->ibuf, fnc->socket, STREAM_WRITEABLE(fnc->ibuf)); + /* We've got an interruption. */ + if (rv == -2) { + /* Schedule next read. */ + thread_add_read(fnc->fthread->master, fpm_read, fnc, + fnc->socket, &fnc->t_read); + return 0; + } if (rv == 0) { atomic_fetch_add_explicit(&fnc->counters.connection_closes, 1, memory_order_relaxed); @@ -472,19 +501,15 @@ static int fpm_read(struct thread *t) if (IS_ZEBRA_DEBUG_FPM) zlog_debug("%s: connection closed", __func__); - fpm_reconnect(fnc); + FPM_RECONNECT(fnc); return 0; } if (rv == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK - || errno == EINTR) - return 0; - atomic_fetch_add_explicit(&fnc->counters.connection_errors, 1, memory_order_relaxed); zlog_warn("%s: connection failure: %s", __func__, strerror(errno)); - fpm_reconnect(fnc); + FPM_RECONNECT(fnc); return 0; } stream_reset(fnc->ibuf); @@ -525,33 +550,15 @@ static int fpm_write(struct thread *t) &fnc->counters.connection_errors, 1, memory_order_relaxed); - fpm_reconnect(fnc); + FPM_RECONNECT(fnc); return 0; } fnc->connecting = false; - /* - * Walk the route tables to send old information before starting - * to send updated information. - * - * NOTE 1: - * RIB table walk is called after the next group table walk - * ends. - * - * NOTE 2: - * Don't attempt to go through next hop group table if we were - * explictly told to not use it. - */ - if (fnc->use_nhg) - thread_add_timer(zrouter.master, fpm_nhg_send, fnc, 0, - &fnc->t_nhgwalk); - else - thread_add_timer(zrouter.master, fpm_rib_send, fnc, 0, - &fnc->t_ribwalk); - - thread_add_timer(zrouter.master, fpm_rmac_send, fnc, 0, - &fnc->t_rmacwalk); + /* Permit receiving messages now. */ + thread_add_read(fnc->fthread->master, fpm_read, fnc, + fnc->socket, &fnc->t_read); } frr_mutex_lock_autounlock(&fnc->obuf_mutex); @@ -589,8 +596,9 @@ static int fpm_write(struct thread *t) memory_order_relaxed); zlog_warn("%s: connection failure: %s", __func__, strerror(errno)); - fpm_reconnect(fnc); - break; + + FPM_RECONNECT(fnc); + return 0; } /* Account all bytes sent. */ @@ -661,18 +669,19 @@ static int fpm_connect(struct thread *t) fnc->connecting = (errno == EINPROGRESS); fnc->socket = sock; - thread_add_read(fnc->fthread->master, fpm_read, fnc, sock, - &fnc->t_read); + if (!fnc->connecting) + thread_add_read(fnc->fthread->master, fpm_read, fnc, sock, + &fnc->t_read); thread_add_write(fnc->fthread->master, fpm_write, fnc, sock, &fnc->t_write); /* Mark all routes as unsent. */ - thread_add_timer(zrouter.master, fpm_nhg_reset, fnc, 0, - &fnc->t_nhgreset); - thread_add_timer(zrouter.master, fpm_rib_reset, fnc, 0, - &fnc->t_ribreset); - thread_add_timer(zrouter.master, fpm_rmac_reset, fnc, 0, - &fnc->t_rmacreset); + if (fnc->use_nhg) + thread_add_timer(zrouter.master, fpm_nhg_reset, fnc, 0, + &fnc->t_nhgreset); + else + thread_add_timer(zrouter.master, fpm_rib_reset, fnc, 0, + &fnc->t_ribreset); return 0; } @@ -904,10 +913,11 @@ static int fpm_nhg_send(struct thread *t) dplane_ctx_fini(&fna.ctx); /* We are done sending next hops, lets install the routes now. */ - if (fna.complete) - thread_add_timer(zrouter.master, fpm_rib_send, fnc, 0, - &fnc->t_ribwalk); - else /* Otherwise reschedule next hop group again. */ + if (fna.complete) { + WALK_FINISH(fnc, FNE_NHG_FINISHED); + thread_add_timer(zrouter.master, fpm_rib_reset, fnc, 0, + &fnc->t_ribreset); + } else /* Otherwise reschedule next hop group again. */ thread_add_timer(zrouter.master, fpm_nhg_send, fnc, 0, &fnc->t_nhgwalk); @@ -963,7 +973,11 @@ static int fpm_rib_send(struct thread *t) dplane_ctx_fini(&ctx); /* All RIB routes sent! */ - fnc->rib_complete = true; + WALK_FINISH(fnc, FNE_RIB_FINISHED); + + /* Schedule next event: RMAC reset. */ + thread_add_event(zrouter.master, fpm_rmac_reset, fnc, 0, + &fnc->t_rmacreset); return 0; } @@ -975,6 +989,7 @@ struct fpm_rmac_arg { struct zebra_dplane_ctx *ctx; struct fpm_nl_ctx *fnc; zebra_l3vni_t *zl3vni; + bool complete; }; static void fpm_enqueue_rmac_table(struct hash_bucket *backet, void *arg) @@ -988,7 +1003,7 @@ static void fpm_enqueue_rmac_table(struct hash_bucket *backet, void *arg) bool sticky; /* Entry already sent. */ - if (CHECK_FLAG(zrmac->flags, ZEBRA_MAC_FPM_SENT)) + if (CHECK_FLAG(zrmac->flags, ZEBRA_MAC_FPM_SENT) || !fra->complete) return; sticky = !!CHECK_FLAG(zrmac->flags, @@ -1004,6 +1019,7 @@ static void fpm_enqueue_rmac_table(struct hash_bucket *backet, void *arg) if (fpm_nl_enqueue(fra->fnc, fra->ctx) == -1) { thread_add_timer(zrouter.master, fpm_rmac_send, fra->fnc, 1, &fra->fnc->t_rmacwalk); + fra->complete = false; } } @@ -1022,9 +1038,14 @@ static int fpm_rmac_send(struct thread *t) fra.fnc = THREAD_ARG(t); fra.ctx = dplane_ctx_alloc(); + fra.complete = true; hash_iterate(zrouter.l3vni_table, fpm_enqueue_l3vni_table, &fra); dplane_ctx_fini(&fra.ctx); + /* RMAC walk completed. */ + if (fra.complete) + WALK_FINISH(fra.fnc, FNE_RMAC_FINISHED); + return 0; } @@ -1041,7 +1062,14 @@ static void fpm_nhg_reset_cb(struct hash_bucket *bucket, void *arg) static int fpm_nhg_reset(struct thread *t) { + struct fpm_nl_ctx *fnc = THREAD_ARG(t); + + fnc->nhg_complete = false; hash_iterate(zrouter.nhgs_id, fpm_nhg_reset_cb, NULL); + + /* Schedule next step: send next hop groups. */ + thread_add_event(zrouter.master, fpm_nhg_send, fnc, 0, &fnc->t_nhgwalk); + return 0; } @@ -1070,6 +1098,9 @@ static int fpm_rib_reset(struct thread *t) } } + /* Schedule next step: send RIB routes. */ + thread_add_event(zrouter.master, fpm_rib_send, fnc, 0, &fnc->t_ribwalk); + return 0; } @@ -1092,8 +1123,15 @@ static void fpm_unset_l3vni_table(struct hash_bucket *backet, void *arg) static int fpm_rmac_reset(struct thread *t) { + struct fpm_nl_ctx *fnc = THREAD_ARG(t); + + fnc->rmac_complete = false; hash_iterate(zrouter.l3vni_table, fpm_unset_l3vni_table, NULL); + /* Schedule next event: send RMAC entries. */ + thread_add_event(zrouter.master, fpm_rmac_send, fnc, 0, + &fnc->t_rmacwalk); + return 0; } @@ -1174,6 +1212,30 @@ static int fpm_process_event(struct thread *t) fpm_reconnect(fnc); break; + case FNE_INTERNAL_RECONNECT: + fpm_reconnect(fnc); + break; + + case FNE_NHG_FINISHED: + if (IS_ZEBRA_DEBUG_FPM) + zlog_debug("%s: next hop groups walk finished", + __func__); + + fnc->nhg_complete = true; + break; + case FNE_RIB_FINISHED: + if (IS_ZEBRA_DEBUG_FPM) + zlog_debug("%s: RIB walk finished", __func__); + + fnc->rib_complete = true; + break; + case FNE_RMAC_FINISHED: + if (IS_ZEBRA_DEBUG_FPM) + zlog_debug("%s: RMAC walk finished", __func__); + + fnc->rmac_complete = true; + break; + default: if (IS_ZEBRA_DEBUG_FPM) zlog_debug("%s: unhandled event %d", __func__, event); diff --git a/zebra/rib.h b/zebra/rib.h index 6ec9241b73..b9f4e56905 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -300,6 +300,7 @@ struct rib_table_info { struct zebra_vrf *zvrf; afi_t afi; safi_t safi; + uint32_t table_id; }; enum rib_tables_iter_state { diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 07e8e37b82..8d38b6defe 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1051,14 +1051,17 @@ static bool _netlink_route_add_gateway_info(uint8_t route_family, bytelen + 2)) return false; } else { - if (gw_family == AF_INET) { - if (!nl_attr_put(nlmsg, req_size, RTA_GATEWAY, - &nexthop->gate.ipv4, bytelen)) - return false; - } else { - if (!nl_attr_put(nlmsg, req_size, RTA_GATEWAY, - &nexthop->gate.ipv6, bytelen)) - return false; + if (!(nexthop->rparent + && IS_MAPPED_IPV6(&nexthop->rparent->gate.ipv6))) { + if (gw_family == AF_INET) { + if (!nl_attr_put(nlmsg, req_size, RTA_GATEWAY, + &nexthop->gate.ipv4, bytelen)) + return false; + } else { + if (!nl_attr_put(nlmsg, req_size, RTA_GATEWAY, + &nexthop->gate.ipv6, bytelen)) + return false; + } } } diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 0cc7139d6b..53956e3aec 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -2490,7 +2490,8 @@ dplane_route_notif_update(struct route_node *rn, enum dplane_op_e op, struct zebra_dplane_ctx *ctx) { - enum zebra_dplane_result ret = ZEBRA_DPLANE_REQUEST_FAILURE; + enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE; + int ret = EINVAL; struct zebra_dplane_ctx *new_ctx = NULL; struct nexthop *nexthop; struct nexthop_group *nhg; @@ -2536,12 +2537,15 @@ dplane_route_notif_update(struct route_node *rn, dplane_ctx_set_notif_provider(new_ctx, dplane_ctx_get_notif_provider(ctx)); - dplane_update_enqueue(new_ctx); - - ret = ZEBRA_DPLANE_REQUEST_QUEUED; + ret = dplane_update_enqueue(new_ctx); done: - return ret; + if (ret == AOK) + result = ZEBRA_DPLANE_REQUEST_QUEUED; + else if (ctx) + dplane_ctx_free(&ctx); + + return result; } /* diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index a18885ddb7..3e11d53b16 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -279,7 +279,6 @@ static int netlink_route_info_fill(struct netlink_route_info *ri, int cmd, rib_dest_t *dest, struct route_entry *re) { struct nexthop *nexthop; - struct zebra_vrf *zvrf; memset(ri, 0, sizeof(*ri)); @@ -287,9 +286,7 @@ static int netlink_route_info_fill(struct netlink_route_info *ri, int cmd, ri->af = rib_dest_af(dest); ri->nlmsg_type = cmd; - zvrf = rib_dest_vrf(dest); - if (zvrf) - ri->rtm_table = zvrf->table_id; + ri->rtm_table = rib_table_info(rib_dest_table(dest))->table_id; ri->rtm_protocol = RTPROT_UNSPEC; /* @@ -364,6 +361,7 @@ static int netlink_route_info_encode(struct netlink_route_info *ri, struct rtattr *nest, *inner_nest; struct rtnexthop *rtnh; struct vxlan_encap_info_t *vxlan; + struct in6_addr ipv6; struct { struct nlmsghdr n; @@ -423,8 +421,15 @@ static int netlink_route_info_encode(struct netlink_route_info *ri, nhi = &ri->nhs[0]; if (nhi->gateway) { - nl_attr_put(&req->n, in_buf_len, RTA_GATEWAY, - nhi->gateway, bytelen); + if (nhi->type == NEXTHOP_TYPE_IPV4_IFINDEX + && ri->af == AF_INET6) { + ipv4_to_ipv4_mapped_ipv6(&ipv6, + nhi->gateway->ipv4); + nl_attr_put(&req->n, in_buf_len, RTA_GATEWAY, + &ipv6, bytelen); + } else + nl_attr_put(&req->n, in_buf_len, RTA_GATEWAY, + nhi->gateway, bytelen); } if (nhi->if_index) { diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index c058090844..43bf745896 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1775,6 +1775,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re, struct interface *ifp; rib_dest_t *dest; struct zebra_vrf *zvrf; + struct in_addr ipv4; if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6) @@ -1835,13 +1836,23 @@ static int nexthop_active(afi_t afi, struct route_entry *re, return 0; } + /* Validation for ipv4 mapped ipv6 nexthop. */ + if (IS_MAPPED_IPV6(&nexthop->gate.ipv6)) { + afi = AFI_IP; + } + /* Make lookup prefix. */ memset(&p, 0, sizeof(struct prefix)); switch (afi) { case AFI_IP: p.family = AF_INET; p.prefixlen = IPV4_MAX_PREFIXLEN; - p.u.prefix4 = nexthop->gate.ipv4; + if (IS_MAPPED_IPV6(&nexthop->gate.ipv6)) { + ipv4_mapped_ipv6_to_ipv4(&nexthop->gate.ipv6, &ipv4); + p.u.prefix4 = ipv4; + } else { + p.u.prefix4 = nexthop->gate.ipv4; + } break; case AFI_IP6: p.family = AF_INET6; diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 9b2a58fd17..8155f9acfe 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -351,7 +351,7 @@ static int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype, return CMD_SUCCESS; } -DEFPY( +DEFPY_YANG( match_ip_address_prefix_len, match_ip_address_prefix_len_cmd, "match ip address prefix-len (0-32)$length", MATCH_STR @@ -371,7 +371,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ip_address_prefix_len, no_match_ip_address_prefix_len_cmd, "no match ip address prefix-len [(0-32)]", NO_STR @@ -388,7 +388,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ipv6_address_prefix_len, match_ipv6_address_prefix_len_cmd, "match ipv6 address prefix-len (0-128)$length", MATCH_STR @@ -408,7 +408,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ipv6_address_prefix_len, no_match_ipv6_address_prefix_len_cmd, "no match ipv6 address prefix-len [(0-128)]", NO_STR @@ -425,7 +425,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_ip_nexthop_prefix_len, match_ip_nexthop_prefix_len_cmd, "match ip next-hop prefix-len (0-32)$length", MATCH_STR @@ -446,7 +446,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_ip_nexthop_prefix_len, no_match_ip_nexthop_prefix_len_cmd, "no match ip next-hop prefix-len [(0-32)]", NO_STR @@ -464,7 +464,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_source_protocol, match_source_protocol_cmd, "match source-protocol " FRR_REDIST_STR_ZEBRA "$proto", MATCH_STR @@ -482,7 +482,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_source_protocol, no_match_source_protocol_cmd, "no match source-protocol [" FRR_REDIST_STR_ZEBRA "]", NO_STR @@ -497,7 +497,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( match_source_instance, match_source_instance_cmd, "match source-instance (0-255)$instance", MATCH_STR @@ -515,7 +515,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_match_source_instance, no_match_source_instance_cmd, "no match source-instance [(0-255)]", NO_STR MATCH_STR @@ -531,7 +531,7 @@ DEFPY( /* set functions */ -DEFPY( +DEFPY_YANG( set_src, set_src_cmd, "set src <A.B.C.D$addrv4|X:X::X:X$addrv6>", SET_STR @@ -558,7 +558,7 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } -DEFPY( +DEFPY_YANG( no_set_src, no_set_src_cmd, "no set src [<A.B.C.D|X:X::X:X>]", NO_STR @@ -605,7 +605,7 @@ DEFUN (no_zebra_route_map_timer, return (CMD_SUCCESS); } -DEFPY (ip_protocol, +DEFPY_YANG (ip_protocol, ip_protocol_cmd, "ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " $proto route-map ROUTE-MAP$rmap", @@ -639,7 +639,7 @@ DEFPY (ip_protocol, return ret; } -DEFPY (no_ip_protocol, +DEFPY_YANG (no_ip_protocol, no_ip_protocol_cmd, "no ip protocol " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " $proto [route-map ROUTE-MAP$rmap]", @@ -673,7 +673,7 @@ DEFPY (no_ip_protocol, return ret; } -DEFPY (show_ip_protocol, +DEFPY_YANG (show_ip_protocol, show_ip_protocol_cmd, "show ip protocol [vrf <NAME$vrf_name|all$vrf_all>]", SHOW_STR @@ -686,7 +686,7 @@ DEFPY (show_ip_protocol, return ret; } -DEFPY (ipv6_protocol, +DEFPY_YANG (ipv6_protocol, ipv6_protocol_cmd, "ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " $proto route-map ROUTE-MAP$rmap", @@ -720,7 +720,7 @@ DEFPY (ipv6_protocol, return ret; } -DEFPY (no_ipv6_protocol, +DEFPY_YANG (no_ipv6_protocol, no_ipv6_protocol_cmd, "no ipv6 protocol " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " $proto [route-map ROUTE-MAP$rmap]", @@ -754,7 +754,7 @@ DEFPY (no_ipv6_protocol, return ret; } -DEFPY (show_ipv6_protocol, +DEFPY_YANG (show_ipv6_protocol, show_ipv6_protocol_cmd, "show ipv6 protocol [vrf <NAME$vrf_name|all$vrf_all>]", SHOW_STR @@ -767,7 +767,7 @@ DEFPY (show_ipv6_protocol, return ret; } -DEFPY (ip_protocol_nht_rmap, +DEFPY_YANG (ip_protocol_nht_rmap, ip_protocol_nht_rmap_cmd, "ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " $proto route-map ROUTE-MAP$rmap", @@ -802,7 +802,7 @@ DEFPY (ip_protocol_nht_rmap, return ret; } -DEFPY (no_ip_protocol_nht_rmap, +DEFPY_YANG (no_ip_protocol_nht_rmap, no_ip_protocol_nht_rmap_cmd, "no ip nht " FRR_IP_PROTOCOL_MAP_STR_ZEBRA " $proto route-map [ROUTE-MAP$rmap]", @@ -836,7 +836,7 @@ DEFPY (no_ip_protocol_nht_rmap, return ret; } -DEFPY (show_ip_protocol_nht, +DEFPY_YANG (show_ip_protocol_nht, show_ip_protocol_nht_cmd, "show ip nht route-map [vrf <NAME$vrf_name|all$vrf_all>]", SHOW_STR @@ -850,7 +850,7 @@ DEFPY (show_ip_protocol_nht, return ret; } -DEFPY (ipv6_protocol_nht_rmap, +DEFPY_YANG (ipv6_protocol_nht_rmap, ipv6_protocol_nht_rmap_cmd, "ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " $proto route-map ROUTE-MAP$rmap", @@ -884,7 +884,7 @@ DEFPY (ipv6_protocol_nht_rmap, return ret; } -DEFPY (no_ipv6_protocol_nht_rmap, +DEFPY_YANG (no_ipv6_protocol_nht_rmap, no_ipv6_protocol_nht_rmap_cmd, "no ipv6 nht " FRR_IP6_PROTOCOL_MAP_STR_ZEBRA " $proto [route-map ROUTE-MAP$rmap]", @@ -918,7 +918,7 @@ DEFPY (no_ipv6_protocol_nht_rmap, return ret; } -DEFPY (show_ipv6_protocol_nht, +DEFPY_YANG (show_ipv6_protocol_nht, show_ipv6_protocol_nht_cmd, "show ipv6 nht route-map [vrf <NAME$vrf_name|all$vrf_all>]", SHOW_STR diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index 61fef8779f..66f2924555 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -133,6 +133,7 @@ struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf, info->zvrf = zvrf; info->afi = afi; info->safi = safi; + info->table_id = tableid; route_table_set_info(zrt->table, info); zrt->table->cleanup = zebra_rtable_node_cleanup; |
