From: Quentin Young Date: Mon, 17 Oct 2016 23:36:21 +0000 (+0000) Subject: Merge branch 'cmaster-next' into vtysh-grammar X-Git-Tag: frr-3.0-branchpoint~129^2~76 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=e52702f29d003585dcfbb4914b2a52d77a177739;p=mirror%2Ffrr.git Merge branch 'cmaster-next' into vtysh-grammar Signed-off-by: Quentin Young Conflicts: bgpd/bgp_route.c bgpd/bgp_routemap.c bgpd/bgp_vty.c isisd/isis_redist.c isisd/isis_routemap.c isisd/isis_vty.c isisd/isisd.c lib/command.c lib/distribute.c lib/if.c lib/keychain.c lib/routemap.c lib/routemap.h ospf6d/ospf6_asbr.c ospf6d/ospf6_interface.c ospf6d/ospf6_neighbor.c ospf6d/ospf6_top.c ospf6d/ospf6_zebra.c ospf6d/ospf6d.c ospfd/ospf_routemap.c ospfd/ospf_vty.c ripd/rip_routemap.c ripngd/ripng_routemap.c vtysh/extract.pl.in vtysh/vtysh.c zebra/interface.c zebra/irdp_interface.c zebra/rt_netlink.c zebra/rtadv.c zebra/test_main.c zebra/zebra_routemap.c zebra/zebra_vty.c --- e52702f29d003585dcfbb4914b2a52d77a177739 diff --cc bgpd/bgp_mplsvpn.c index 48baedcea5,86e8788351..c050e6ddd8 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@@ -217,12 -270,25 +270,25 @@@ bgp_nlri_parse_vpn (struct peer *peer, psize - VPN_PREFIXLEN_MIN_BYTES); if (attr) + { - bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0); + bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0); + #if ENABLE_BGP_VNC + rfapiProcessUpdate(peer, NULL, &p, &prd, attr, packet->afi, + SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, + &label); + #endif + } else + { + #if ENABLE_BGP_VNC + rfapiProcessWithdraw(peer, NULL, &p, &prd, attr, packet->afi, + SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, 0); + #endif - bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt); - } + bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN, + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt); + } + } /* Packet length consistency check. */ if (pnt != lim) return -1; diff --cc bgpd/bgp_route.c index 9f3c9baae5,764bb6c438..db73d379d4 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@@ -60,7 -60,14 +60,13 @@@ Software Foundation, Inc., 59 Temple Pl #include "bgpd/bgp_mpath.h" #include "bgpd/bgp_nht.h" #include "bgpd/bgp_updgrp.h" -#include "bgpd/bgp_vty.h" + #if ENABLE_BGP_VNC + #include "bgpd/rfapi/rfapi_backend.h" + #include "bgpd/rfapi/vnc_import_bgp.h" + #include "bgpd/rfapi/vnc_export_bgp.h" + #endif + /* Extern from bgp_dump.c */ extern const char *bgp_origin_str[]; extern const char *bgp_origin_long_str[]; @@@ -1868,8 -1924,13 +1923,13 @@@ bgp_process_main (struct work_queue *wq !bgp->addpath_tx_used[afi][safi]) { if (bgp_zebra_has_route_changed (rn, old_select)) + { + #if ENABLE_BGP_VNC + vnc_import_bgp_add_route(bgp, p, old_select); + vnc_import_bgp_exterior_add_route(bgp, p, old_select); + #endif - bgp_zebra_announce (p, old_select, bgp, afi, safi); + bgp_zebra_announce (p, old_select, bgp, afi, safi); - + } UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG); bgp_zebra_clear_route_change_flags (rn); UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED); @@@ -2150,7 -2226,33 +2225,33 @@@ bgp_rib_withdraw (struct bgp_node *rn, bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi); return; } - + + #if ENABLE_BGP_VNC + if (safi == SAFI_MPLS_VPN) { + struct bgp_node *prn = NULL; + struct bgp_table *table = NULL; + + prn = bgp_node_get(peer->bgp->rib[afi][safi], (struct prefix *) prd); + if (prn->info) { + table = (struct bgp_table *)(prn->info); + + vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( + peer->bgp, + prd, + table, + &rn->p, + ri); + } + bgp_unlock_node(prn); + } + if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) { + if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) { + + vnc_import_bgp_del_route(peer->bgp, &rn->p, ri); + vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p, ri); + } + } + #endif bgp_rib_remove (rn, ri, peer, afi, safi); } @@@ -3116,9 -3317,15 +3316,15 @@@ bgp_cleanup_table(struct bgp_table *tab && ri->type == ZEBRA_ROUTE_BGP && (ri->sub_type == BGP_ROUTE_NORMAL || ri->sub_type == BGP_ROUTE_AGGREGATE)) + { + #if ENABLE_BGP_VNC + if (table->owner && table->owner->bgp) + vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri); + #endif - bgp_zebra_withdraw (&rn->p, ri, safi); - } + bgp_zebra_withdraw (&rn->p, ri, safi); } } ++} /* Delete all kernel routes. */ void @@@ -5958,7 -6374,14 +6225,14 @@@ route_vty_out (struct vty *vty, struct json_object_array_add(json_paths, json_path); } else + { - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, "%s", VTY_NEWLINE); + #if ENABLE_BGP_VNC + /* prints an additional line, indented, with VNC info, if present */ + if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_UNICAST)) + rfapi_vty_out_vncinfo(vty, p, binfo, safi); + #endif + } } /* called from terminal list command */ @@@ -7191,7 -7618,16 +7467,8 @@@ bgp_show_table (struct vty *vty, struc for (ri = rn->info; ri; ri = ri->next) { + total_count++; if (type == bgp_show_type_flap_statistics - || type == bgp_show_type_flap_address - || type == bgp_show_type_flap_prefix - || type == bgp_show_type_flap_cidr_only - || type == bgp_show_type_flap_regexp - || type == bgp_show_type_flap_filter_list - || type == bgp_show_type_flap_prefix_list - || type == bgp_show_type_flap_prefix_longer - || type == bgp_show_type_flap_route_map || type == bgp_show_type_flap_neighbor || type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) @@@ -10244,31 -14846,137 +10524,30 @@@ bgp_route_init (void install_element (BGP_IPV4M_NODE, &aggregate_address_mask_as_set_cmd); install_element (BGP_IPV4M_NODE, &aggregate_address_as_set_summary_cmd); install_element (BGP_IPV4M_NODE, &aggregate_address_mask_as_set_summary_cmd); - install_element (BGP_IPV4M_NODE, &aggregate_address_summary_as_set_cmd); - install_element (BGP_IPV4M_NODE, &aggregate_address_mask_summary_as_set_cmd); install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd); - install_element (BGP_IPV4M_NODE, &no_aggregate_address_summary_only_cmd); - install_element (BGP_IPV4M_NODE, &no_aggregate_address_as_set_cmd); - install_element (BGP_IPV4M_NODE, &no_aggregate_address_as_set_summary_cmd); - install_element (BGP_IPV4M_NODE, &no_aggregate_address_summary_as_set_cmd); install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd); - install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_summary_only_cmd); - install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_as_set_cmd); - install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_as_set_summary_cmd); - install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_summary_as_set_cmd); - install_element (VIEW_NODE, &show_ip_bgp_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_cmd); install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd); - install_element (VIEW_NODE, &show_bgp_ipv4_safi_cmd); install_element (VIEW_NODE, &show_ip_bgp_route_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_route_cmd); - install_element (VIEW_NODE, &show_ip_bgp_route_pathtype_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_route_pathtype_cmd); - install_element (VIEW_NODE, &show_bgp_ipv4_safi_route_pathtype_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_cmd); - install_element (VIEW_NODE, &show_bgp_ipv4_safi_route_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_route_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_route_cmd); - install_element (VIEW_NODE, &show_ip_bgp_prefix_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_pathtype_cmd); - install_element (VIEW_NODE, &show_bgp_ipv4_safi_prefix_pathtype_cmd); - install_element (VIEW_NODE, &show_bgp_ipv4_safi_prefix_cmd); - install_element (VIEW_NODE, &show_ip_bgp_prefix_pathtype_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_pathtype_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd); - - install_element (VIEW_NODE, &show_ip_bgp_regexp_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_regexp_cmd); - install_element (VIEW_NODE, &show_ip_bgp_prefix_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_filter_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_filter_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_filter_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_route_map_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_route_map_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_map_cmd); - install_element (VIEW_NODE, &show_ip_bgp_cidr_only_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_cidr_only_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community_all_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_all_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community2_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community3_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community4_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_cmd); - install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community_all_cmd); - install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community_cmd); - install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community2_cmd); - install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community3_cmd); - install_element (VIEW_NODE, &show_bgp_instance_afi_safi_community4_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community2_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community3_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community4_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_community_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_community_list_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_community_list_exact_cmd); - install_element (VIEW_NODE, &show_ip_bgp_prefix_longer_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_prefix_longer_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_longer_cmd); - install_element (VIEW_NODE, &show_ip_bgp_neighbor_advertised_route_cmd); + + install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd); + install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd); + install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd); + install_element (VIEW_NODE, &show_ip_bgp_dampening_params_cmd); + install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd); + + /* Restricted node: VIEW_NODE - (set of dangerous commands) */ - install_element (RESTRICTED_NODE, &show_ip_bgp_route_cmd); + - install_element (ENABLE_NODE, &show_ip_bgp_instance_all_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_route_cmd); ++ install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd); ++ install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd); ++ install_element (VIEW_NODE, &show_ip_bgp_route_cmd); + - install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_neighbor_routes_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_dampening_params_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd); + install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd); - install_element (VIEW_NODE, &show_ip_bgp_neighbor_advertised_route_rmap_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_rmap_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_rmap_cmd); - install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_received_routes_cmd); - install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_rmap_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_received_routes_rmap_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_rmap_cmd); - install_element (VIEW_NODE, &show_bgp_instance_afi_safi_neighbor_adv_recd_routes_cmd); + install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_routes_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd); + install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd); + install_element (VIEW_NODE, &show_ip_bgp_dampening_params_cmd); + install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_parameters_cmd); - install_element (VIEW_NODE, &show_ip_bgp_dampened_paths_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_dampd_paths_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_dampening_flap_stats_cmd); - install_element (VIEW_NODE, &show_ip_bgp_damp_dampened_paths_cmd); - install_element (VIEW_NODE, &show_ip_bgp_flap_statistics_cmd); - install_element (VIEW_NODE, &show_ip_bgp_damp_flap_statistics_cmd); - install_element (VIEW_NODE, &show_ip_bgp_flap_address_cmd); - install_element (VIEW_NODE, &show_ip_bgp_damp_flap_address_cmd); - install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_cmd); - install_element (VIEW_NODE, &show_ip_bgp_flap_cidr_only_cmd); - install_element (VIEW_NODE, &show_ip_bgp_damp_flap_cidr_only_cmd); - install_element (VIEW_NODE, &show_ip_bgp_flap_regexp_cmd); - install_element (VIEW_NODE, &show_ip_bgp_flap_filter_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_damp_flap_filter_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_damp_flap_prefix_list_cmd); - install_element (VIEW_NODE, &show_ip_bgp_flap_prefix_longer_cmd); - install_element (VIEW_NODE, &show_ip_bgp_damp_flap_prefix_longer_cmd); - install_element (VIEW_NODE, &show_ip_bgp_flap_route_map_cmd); - install_element (VIEW_NODE, &show_ip_bgp_damp_flap_route_map_cmd); - install_element (VIEW_NODE, &show_ip_bgp_neighbor_flap_cmd); - install_element (VIEW_NODE, &show_ip_bgp_neighbor_damp_cmd); - - install_element (VIEW_NODE, &show_bgp_ipv4_prefix_cmd); - install_element (VIEW_NODE, &show_bgp_ipv4_vpn_rd_route_cmd); - install_element (VIEW_NODE, &show_bgp_ipv4_vpn_route_cmd); - - install_element (VIEW_NODE, &show_bgp_ipv6_vpn_rd_route_cmd); - install_element (VIEW_NODE, &show_bgp_ipv6_vpn_route_cmd); /* BGP dampening clear commands */ install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd); diff --cc bgpd/bgp_routemap.c index 33a29e8f4c,acb7449a09..028158e520 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@@ -108,7 -110,7 +111,7 @@@ o Local extension set ipv6 next-hop local : Done set as-path exclude : Done --*/ ++*/ /* generic value manipulation to be shared in multiple rules */ @@@ -330,7 -332,7 +333,7 @@@ struct route_map_rule_cmd route_match_p /* Match function should return 1 if match is success else return zero. */ static route_map_result_t --route_match_ip_address (void *rule, struct prefix *prefix, ++route_match_ip_address (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct access_list *alist; @@@ -341,7 -343,7 +344,7 @@@ alist = access_list_lookup (AFI_IP, (char *) rule); if (alist == NULL) return RMAP_NOMATCH; -- ++ return (access_list_apply (alist, prefix) == FILTER_DENY ? RMAP_NOMATCH : RMAP_MATCH); } @@@ -376,7 -378,7 +379,7 @@@ struct route_map_rule_cmd route_match_i /* Match function return 1 if match is success else return zero. */ static route_map_result_t --route_match_ip_next_hop (void *rule, struct prefix *prefix, ++route_match_ip_next_hop (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct access_list *alist; @@@ -428,7 -430,7 +431,7 @@@ struct route_map_rule_cmd route_match_i /* Match function return 1 if match is success else return zero. */ static route_map_result_t --route_match_ip_route_source (void *rule, struct prefix *prefix, ++route_match_ip_route_source (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct access_list *alist; @@@ -485,7 -487,7 +488,7 @@@ struct route_map_rule_cmd route_match_i /* `match ip address prefix-list PREFIX_LIST' */ static route_map_result_t --route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, ++route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct prefix_list *plist; @@@ -495,7 -497,7 +498,7 @@@ plist = prefix_list_lookup (AFI_IP, (char *) rule); if (plist == NULL) return RMAP_NOMATCH; -- ++ return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH : RMAP_MATCH); } @@@ -692,7 -694,7 +695,7 @@@ struct route_map_rule_cmd route_match_l /* Match function return 1 if match is success else return zero. */ static route_map_result_t --route_match_metric (void *rule, struct prefix *prefix, ++route_match_metric (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct rmap_value *rv; @@@ -720,10 -722,10 +723,10 @@@ struct route_map_rule_cmd route_match_m /* Match function for as-path match. I assume given object is */ static route_map_result_t --route_match_aspath (void *rule, struct prefix *prefix, ++route_match_aspath (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { -- ++ struct as_list *as_list; struct bgp_info *bgp_info; @@@ -756,7 -758,7 +759,7 @@@ route_match_aspath_free (void *rule } /* Route map commands for aspath matching. */ --struct route_map_rule_cmd route_match_aspath_cmd = ++struct route_map_rule_cmd route_match_aspath_cmd = { "as-path", route_match_aspath, @@@ -773,14 -775,14 +776,14 @@@ struct rmap_communit /* Match function for community match. */ static route_map_result_t --route_match_community (void *rule, struct prefix *prefix, ++route_match_community (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct community_list *list; struct bgp_info *bgp_info; struct rmap_community *rcom; -- if (type == RMAP_BGP) ++ if (type == RMAP_BGP) { bgp_info = object; rcom = rule; @@@ -835,12 -837,12 +838,12 @@@ route_match_community_free (void *rule { struct rmap_community *rcom = rule; -- XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); ++ XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom); } /* Route map commands for community matching. */ --struct route_map_rule_cmd route_match_community_cmd = ++struct route_map_rule_cmd route_match_community_cmd = { "community", route_match_community, @@@ -850,19 -852,19 +853,19 @@@ /* Match function for extcommunity match. */ static route_map_result_t --route_match_ecommunity (void *rule, struct prefix *prefix, ++route_match_ecommunity (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct community_list *list; struct bgp_info *bgp_info; -- if (type == RMAP_BGP) ++ if (type == RMAP_BGP) { bgp_info = object; -- ++ if (!bgp_info->attr->extra) return RMAP_NOMATCH; -- ++ list = community_list_lookup (bgp_clist, (char *) rule, EXTCOMMUNITY_LIST_MASTER); if (! list) @@@ -889,7 -891,7 +892,7 @@@ route_match_ecommunity_free (void *rule } /* Route map commands for community matching. */ --struct route_map_rule_cmd route_match_ecommunity_cmd = ++struct route_map_rule_cmd route_match_ecommunity_cmd = { "extcommunity", route_match_ecommunity, @@@ -902,7 -904,7 +905,7 @@@ /* `match origin' */ static route_map_result_t --route_match_origin (void *rule, struct prefix *prefix, ++route_match_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { u_char *origin; @@@ -912,7 -914,7 +915,7 @@@ { origin = rule; bgp_info = object; -- ++ if (bgp_info->attr->origin == *origin) return RMAP_MATCH; } @@@ -1159,7 -1128,7 +1129,7 @@@ route_set_ip_nexthop (void *rule, struc { if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) || CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT)) -- && peer->su_remote ++ && peer->su_remote && sockunion_family (peer->su_remote) == AF_INET) { bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote); @@@ -1233,7 -1202,7 +1203,7 @@@ route_set_ip_nexthop_free (void *rule if (rins->address) XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address); -- ++ XFREE (MTYPE_ROUTE_MAP_COMPILED, rins); } @@@ -1262,8 -1231,8 +1232,8 @@@ route_set_local_pref (void *rule, struc /* Fetch routemap's rule information. */ rv = rule; bgp_info = object; -- -- /* Set local preference value. */ ++ ++ /* Set local preference value. */ if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) locpref = bgp_info->attr->local_pref; @@@ -1275,7 -1244,7 +1245,7 @@@ } /* Set local preference rule structure. */ --struct route_map_rule_cmd route_set_local_pref_cmd = ++struct route_map_rule_cmd route_set_local_pref_cmd = { "local-preference", route_set_local_pref, @@@ -1299,8 -1268,8 +1269,8 @@@ route_set_weight (void *rule, struct pr /* Fetch routemap's rule information. */ rv = rule; bgp_info = object; -- -- /* Set weight value. */ ++ ++ /* Set weight value. */ weight = route_value_adjust(rv, 0, bgp_info->peer); if (weight) (bgp_attr_extra_get (bgp_info->attr))->weight = weight; @@@ -1312,7 -1281,7 +1282,7 @@@ } /* Set local preference rule structure. */ --struct route_map_rule_cmd route_set_weight_cmd = ++struct route_map_rule_cmd route_set_weight_cmd = { "weight", route_set_weight, @@@ -1324,7 -1293,7 +1294,7 @@@ /* Set metric to attribute. */ static route_map_result_t --route_set_metric (void *rule, struct prefix *prefix, ++route_set_metric (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct rmap_value *rv; @@@ -1347,7 -1316,7 +1317,7 @@@ } /* Set metric rule structure. */ --struct route_map_rule_cmd route_set_metric_cmd = ++struct route_map_rule_cmd route_set_metric_cmd = { "metric", route_set_metric, @@@ -1368,7 -1337,7 +1338,7 @@@ route_set_aspath_prepend (void *rule, s if (type == RMAP_BGP) { binfo = object; -- ++ if (binfo->attr->aspath->refcnt) new = aspath_dup (binfo->attr->aspath); else @@@ -1412,7 -1381,7 +1382,7 @@@ route_set_aspath_prepend_free (void *ru /* Set as-path prepend rule structure. */ --struct route_map_rule_cmd route_set_aspath_prepend_cmd = ++struct route_map_rule_cmd route_set_aspath_prepend_cmd = { "as-path prepend", route_set_aspath_prepend, @@@ -1446,7 -1415,7 +1416,7 @@@ route_set_aspath_exclude (void *rule, s } /* Set ASn exlude rule structure. */ --struct route_map_rule_cmd route_set_aspath_exclude_cmd = ++struct route_map_rule_cmd route_set_aspath_exclude_cmd = { "as-path exclude", route_set_aspath_exclude, @@@ -1473,7 -1442,7 +1443,7 @@@ route_set_community (void *rule, struc struct community *new = NULL; struct community *old; struct community *merge; -- ++ if (type == RMAP_BGP) { rcs = rule; @@@ -1496,8 -1465,8 +1466,8 @@@ if (rcs->additive && old) { merge = community_merge (community_dup (old), rcs->com); -- -- /* HACK: if the old community is not intern'd, ++ ++ /* HACK: if the old community is not intern'd, * we should free it here, or all reference to it may be lost. * Really need to cleanup attribute caching sometime. */ @@@ -1508,7 -1477,7 +1478,7 @@@ } else new = community_dup (rcs->com); -- ++ /* will be interned by caller if required */ attr->community = new; @@@ -1527,7 -1496,7 +1497,7 @@@ route_set_community_compile (const cha char *sp; int additive = 0; int none = 0; -- ++ if (strcmp (arg, "none") == 0) none = 1; else @@@ -1549,12 -1518,12 +1519,12 @@@ if (! com) return NULL; } -- ++ rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set)); rcs->com = com; rcs->additive = additive; rcs->none = none; -- ++ return rcs; } @@@ -1570,7 -1539,7 +1540,7 @@@ route_set_community_free (void *rule } /* Set community rule structure. */ --struct route_map_rule_cmd route_set_community_cmd = ++struct route_map_rule_cmd route_set_community_cmd = { "community", route_set_community, @@@ -1683,10 -1652,10 +1653,10 @@@ route_set_ecommunity (void *rule, struc { ecom = rule; bgp_info = object; -- ++ if (! ecom) return RMAP_OKAY; -- ++ /* We assume additive for Extended Community. */ old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity; @@@ -1731,7 -1700,7 +1701,7 @@@ route_set_ecommunity_free (void *rule } /* Set community rule structure. */ --struct route_map_rule_cmd route_set_ecommunity_rt_cmd = ++struct route_map_rule_cmd route_set_ecommunity_rt_cmd = { "extcommunity rt", route_set_ecommunity, @@@ -1750,12 -1719,12 +1720,12 @@@ route_set_ecommunity_soo_compile (cons ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0); if (! ecom) return NULL; -- ++ return ecommunity_intern (ecom); } /* Set community rule structure. */ --struct route_map_rule_cmd route_set_ecommunity_soo_cmd = ++struct route_map_rule_cmd route_set_ecommunity_soo_cmd = { "extcommunity soo", route_set_ecommunity, @@@ -1776,7 -1745,7 +1746,7 @@@ route_set_origin (void *rule, struct pr { origin = rule; bgp_info = object; -- ++ bgp_info->attr->origin = *origin; } @@@ -1809,7 -1778,7 +1779,7 @@@ route_set_origin_free (void *rule } /* Set origin rule structure. */ --struct route_map_rule_cmd route_set_origin_cmd = ++struct route_map_rule_cmd route_set_origin_cmd = { "origin", route_set_origin, @@@ -1850,7 -1819,7 +1820,7 @@@ route_set_atomic_aggregate_free (void * } /* Set atomic aggregate rule structure. */ --struct route_map_rule_cmd route_set_atomic_aggregate_cmd = ++struct route_map_rule_cmd route_set_atomic_aggregate_cmd = { "atomic-aggregate", route_set_atomic_aggregate, @@@ -1866,7 -1835,7 +1836,7 @@@ struct aggregato }; static route_map_result_t --route_set_aggregator_as (void *rule, struct prefix *prefix, ++route_set_aggregator_as (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct bgp_info *bgp_info; @@@ -1878,7 -1847,7 +1848,7 @@@ bgp_info = object; aggregator = rule; ae = bgp_attr_extra_get (bgp_info->attr); -- ++ ae->aggregator_as = aggregator->as; ae->aggregator_addr = aggregator->address; bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR); @@@ -1909,7 -1878,7 +1879,7 @@@ route_set_aggregator_as_free (void *rul XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); } --struct route_map_rule_cmd route_set_aggregator_as_cmd = ++struct route_map_rule_cmd route_set_aggregator_as_cmd = { "aggregator as", route_set_aggregator_as, @@@ -1988,7 -1923,7 +1924,7 @@@ static struct route_map_rule_cmd route_ /* `match ipv6 address IP_ACCESS_LIST' */ static route_map_result_t --route_match_ipv6_address (void *rule, struct prefix *prefix, ++route_match_ipv6_address (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct access_list *alist; @@@ -1998,7 -1933,7 +1934,7 @@@ alist = access_list_lookup (AFI_IP6, (char *) rule); if (alist == NULL) return RMAP_NOMATCH; -- ++ return (access_list_apply (alist, prefix) == FILTER_DENY ? RMAP_NOMATCH : RMAP_MATCH); } @@@ -2029,7 -1964,7 +1965,7 @@@ struct route_map_rule_cmd route_match_i /* `match ipv6 next-hop IP_ADDRESS' */ static route_map_result_t --route_match_ipv6_next_hop (void *rule, struct prefix *prefix, ++route_match_ipv6_next_hop (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct in6_addr *addr = rule; @@@ -2038,10 -1973,10 +1974,10 @@@ if (type == RMAP_BGP) { bgp_info = object; -- ++ if (!bgp_info->attr->extra) return RMAP_NOMATCH; -- ++ if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr)) return RMAP_MATCH; @@@ -2090,7 -2025,7 +2026,7 @@@ struct route_map_rule_cmd route_match_i /* `match ipv6 address prefix-list PREFIX_LIST' */ static route_map_result_t --route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix, ++route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct prefix_list *plist; @@@ -2100,7 -2035,7 +2036,7 @@@ plist = prefix_list_lookup (AFI_IP6, (char *) rule); if (plist == NULL) return RMAP_NOMATCH; -- ++ return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH : RMAP_MATCH); } @@@ -2131,7 -2066,7 +2067,7 @@@ struct route_map_rule_cmd route_match_i /* Set nexthop to object. ojbect must be pointer to struct attr. */ static route_map_result_t --route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix, ++route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct in6_addr *address; @@@ -2142,8 -2077,8 +2078,8 @@@ /* Fetch routemap's rule information. */ address = rule; bgp_info = object; -- -- /* Set next hop value. */ ++ ++ /* Set next hop value. */ (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address; /* Set nexthop length. */ @@@ -2259,7 -2194,7 +2195,7 @@@ struct route_map_rule_cmd route_set_ipv /* Set nexthop to object. ojbect must be pointer to struct attr. */ static route_map_result_t --route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, ++route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct in6_addr *address; @@@ -2270,10 -2205,10 +2206,10 @@@ /* Fetch routemap's rule information. */ address = rule; bgp_info = object; -- -- /* Set next hop value. */ ++ ++ /* Set next hop value. */ (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address; -- ++ /* Set nexthop length. */ if (bgp_info->attr->extra->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) bgp_info->attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL; @@@ -2418,7 -2353,7 +2354,7 @@@ struct route_map_rule_cmd route_set_ipv /* `set vpnv4 nexthop A.B.C.D' */ static route_map_result_t --route_set_vpnv4_nexthop (void *rule, struct prefix *prefix, ++route_set_vpnv4_nexthop (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { struct in_addr *address; @@@ -2429,8 -2364,8 +2365,8 @@@ /* Fetch routemap's rule information. */ address = rule; bgp_info = object; -- -- /* Set next hop value. */ ++ ++ /* Set next hop value. */ (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address; (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4; } @@@ -2481,11 -2416,11 +2417,11 @@@ route_set_originator_id (void *rule, st struct in_addr *address; struct bgp_info *bgp_info; -- if (type == RMAP_BGP) ++ if (type == RMAP_BGP) { address = rule; bgp_info = object; -- ++ bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID); (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address; } @@@ -2521,7 -2456,7 +2457,7 @@@ route_set_originator_id_free (void *rul } /* Set originator-id rule structure. */ --struct route_map_rule_cmd route_set_originator_id_cmd = ++struct route_map_rule_cmd route_set_originator_id_cmd = { "originator-id", route_set_originator_id, @@@ -3718,8 -4180,8 +3662,8 @@@ DEFUN (set_aggregator_as int ret; struct in_addr address; char *argstr; -- - ret = inet_aton (argv[1], &address); ++ + ret = inet_aton (argv[idx_ipv4]->arg, &address); if (ret == 0) { vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE); @@@ -3755,10 -4212,10 +3699,10 @@@ DEFUN (no_set_aggregator_as struct in_addr address; char *argstr; - if (argv == 0) - return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL); - - ret = inet_aton (argv[1], &address); + if (argc <= idx_asn) + return generic_set_delete (vty, vty->index, "aggregator as", NULL); - ++ + ret = inet_aton (argv[idx_ip]->arg, &address); if (ret == 0) { vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE); @@@ -3777,9 -4234,75 +3721,8 @@@ return ret; } -ALIAS (no_set_aggregator_as, - no_set_aggregator_as_val_cmd, - "no set aggregator as " CMD_AS_RANGE " A.B.C.D", - NO_STR - SET_STR - "BGP aggregator attribute\n" - "AS number of aggregator\n" - "AS number\n" - "IP address of aggregator\n") - -DEFUN (set_tag, - set_tag_cmd, - "set tag <1-4294967295>", - SET_STR - "Tag value for routing protocol\n" - "Tag value\n") -{ - return bgp_route_set_add (vty, vty->index, "tag", argv[0]); -} - -DEFUN (no_set_tag, - no_set_tag_cmd, - "no set tag", - NO_STR - SET_STR - "Tag value for routing protocol\n") -{ - if (argc == 0) - bgp_route_set_delete(vty, vty->index, "tag", NULL); - - return bgp_route_set_delete (vty, vty->index, "tag", argv[0]); -} - -ALIAS (no_set_tag, - no_set_tag_val_cmd, - "no set tag <1-4294967295>", - NO_STR - SET_STR - "Tag value for routing protocol\n" - "Tag value\n") - -- #ifdef HAVE_IPV6 -DEFUN (match_ipv6_address, - match_ipv6_address_cmd, - "match ipv6 address WORD", - MATCH_STR - IPV6_STR - "Match IPv6 address of route\n" - "IPv6 access-list name\n") -{ - return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0], - RMAP_EVENT_FILTER_ADDED); -} - -DEFUN (no_match_ipv6_address, - no_match_ipv6_address_cmd, - "no match ipv6 address WORD", - NO_STR - MATCH_STR - IPV6_STR - "Match IPv6 address of route\n" - "IPv6 access-list name\n") -{ - return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0], - RMAP_EVENT_FILTER_DELETED); -} - -DEFUN (match_ipv6_next_hop, +DEFUN (match_ipv6_next_hop, match_ipv6_next_hop_cmd, "match ipv6 next-hop X:X::X:X", MATCH_STR diff --cc bgpd/bgp_vty.c index b5e2d9e36f,258a709837..0f8d0c76dd --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@@ -695,16 -696,15 +695,16 @@@ DEFUN (router_bgp // "router bgp X" else { - VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX); + VTY_GET_INTEGER_RANGE ("AS", as, argv[idx_asn]->arg, 1, BGP_AS4_MAX); inst_type = BGP_INSTANCE_TYPE_DEFAULT; - if (argc == 3) + if (argc > 3) { - name = argv[2]; - if (!strcmp(argv[1], "vrf")) + name = argv[idx_vrf]->arg; + - if (!strcmp(argv[idx_view_vrf]->text, "vrf")) ++ if (!strcmp(argv[idx_view_vrf]->text, "vrf")) inst_type = BGP_INSTANCE_TYPE_VRF; - else if (!strcmp(argv[idx_view_vrf]->text, "view")) - else if (!strcmp(argv[1], "view")) ++ else if (!strcmp(argv[idx_view_vrf]->text, "view")) inst_type = BGP_INSTANCE_TYPE_VIEW; } @@@ -1997,12 -2144,11 +1997,12 @@@ DEFUN (bgp_bestpath_med "Compare MED among confederation paths\n" "Treat missing MED as the least preferred one\n") { + int idx_med_knob = 3; struct bgp *bgp; -- ++ bgp = vty->index; - if (strncmp (argv[0], "confed", 1) == 0) + if (strncmp (argv[idx_med_knob]->arg, "confed", 1) == 0) bgp_flag_set (bgp, BGP_FLAG_MED_CONFED); else bgp_flag_set (bgp, BGP_FLAG_MED_MISSING_AS_WORST); @@@ -2019,12 -2165,10 +2019,12 @@@ DEFUN (bgp_bestpath_med2 "Change the default bestpath selection\n" "MED attribute\n" "Compare MED among confederation paths\n" - "Treat missing MED as the least preferred one\n") + "Treat missing MED as the least preferred one\n" + "Treat missing MED as the least preferred one\n" + "Compare MED among confederation paths\n") { struct bgp *bgp; -- ++ bgp = vty->index; bgp_flag_set (bgp, BGP_FLAG_MED_CONFED); bgp_flag_set (bgp, BGP_FLAG_MED_MISSING_AS_WORST); @@@ -2048,8 -2199,8 +2048,8 @@@ DEFUN (no_bgp_bestpath_med struct bgp *bgp; bgp = vty->index; -- - if (strncmp (argv[0], "confed", 1) == 0) ++ + if (strncmp (argv[idx_med_knob]->arg, "confed", 1) == 0) bgp_flag_unset (bgp, BGP_FLAG_MED_CONFED); else bgp_flag_unset (bgp, BGP_FLAG_MED_MISSING_AS_WORST); @@@ -2070,7 -2221,7 +2070,7 @@@ DEFUN (no_bgp_bestpath_med2 "Treat missing MED as the least preferred one\n") { struct bgp *bgp; -- ++ bgp = vty->index; bgp_flag_unset (bgp, BGP_FLAG_MED_CONFED); bgp_flag_unset (bgp, BGP_FLAG_MED_MISSING_AS_WORST); @@@ -2571,7 -2746,7 +2571,7 @@@ DEFUN (no_bgp_disable_connected_route_c static int --peer_remote_as_vty (struct vty *vty, const char *peer_str, ++peer_remote_as_vty (struct vty *vty, const char *peer_str, const char *as_str, afi_t afi, safi_t safi) { int ret; @@@ -3318,7 -3559,7 +3318,7 @@@ DEFUN (no_neighbor_set_peer_group } static int --peer_flag_modify_vty (struct vty *vty, const char *ip_str, ++peer_flag_modify_vty (struct vty *vty, const char *ip_str, u_int16_t flag, int set) { int ret; @@@ -4098,10 -4288,39 +4098,10 @@@ DEFUN (neighbor_attr_unchanged4 bgp_node_safi (vty), flags); } -ALIAS (neighbor_attr_unchanged, - neighbor_attr_unchanged5_cmd, - NEIGHBOR_CMD2 "attribute-unchanged as-path next-hop med", - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "BGP attribute is propagated unchanged to this neighbor\n" - "As-path attribute\n" - "Nexthop attribute\n" - "Med attribute\n") - -ALIAS (neighbor_attr_unchanged, - neighbor_attr_unchanged6_cmd, - NEIGHBOR_CMD2 "attribute-unchanged as-path med next-hop", - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "BGP attribute is propagated unchanged to this neighbor\n" - "As-path attribute\n" - "Med attribute\n" - "Nexthop attribute\n") - -ALIAS (neighbor_attr_unchanged, - neighbor_attr_unchanged7_cmd, - NEIGHBOR_CMD2 "attribute-unchanged next-hop med as-path", - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "BGP attribute is propagated unchanged to this neighbor\n" - "Nexthop attribute\n" - "Med attribute\n" - "As-path attribute\n") - -ALIAS (neighbor_attr_unchanged, - neighbor_attr_unchanged8_cmd, - NEIGHBOR_CMD2 "attribute-unchanged next-hop as-path med", +DEFUN (no_neighbor_attr_unchanged, + no_neighbor_attr_unchanged_cmd, + "no neighbor attribute-unchanged [as-path] [next-hop] [med]", - NO_STR ++ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "BGP attribute is propagated unchanged to this neighbor\n" @@@ -4223,7 -4511,17 +4223,7 @@@ DEFUN (no_neighbor_attr_unchanged4 /* EBGP multihop configuration. */ static int --peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str, ++peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str, const char *ttl_str) { struct peer *peer; @@@ -4245,7 -4543,7 +4245,7 @@@ } static int --peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str) ++peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str) { struct peer *peer; @@@ -4371,7 -4684,15 +4371,7 @@@ DEFUN (no_neighbor_description /* Neighbor update-source. */ static int --peer_update_source_vty (struct vty *vty, const char *peer_str, ++peer_update_source_vty (struct vty *vty, const char *peer_str, const char *source_str) { struct peer *peer; @@@ -4431,8 -4752,8 +4431,8 @@@ DEFUN (no_neighbor_update_source } static int --peer_default_originate_set_vty (struct vty *vty, const char *peer_str, -- afi_t afi, safi_t safi, ++peer_default_originate_set_vty (struct vty *vty, const char *peer_str, ++ afi_t afi, safi_t safi, const char *rmap, int set) { int ret; @@@ -4496,7 -4811,16 +4496,7 @@@ DEFUN (no_neighbor_default_originate /* Set neighbor's BGP port. */ static int --peer_port_vty (struct vty *vty, const char *ip_str, int afi, ++peer_port_vty (struct vty *vty, const char *ip_str, int afi, const char *port_str) { struct peer *peer; @@@ -4508,7 -4832,7 +4508,7 @@@ return CMD_WARNING; if (! port_str) -- { ++ { sp = getservbyname ("bgp", "tcp"); port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port); } @@@ -4552,7 -4872,16 +4552,8 @@@ DEFUN (no_neighbor_port /* neighbor weight. */ static int --peer_weight_set_vty (struct vty *vty, const char *ip_str, ++peer_weight_set_vty (struct vty *vty, const char *ip_str, + afi_t afi, safi_t safi, const char *weight_str) { int ret; @@@ -4591,9 -4921,7 +4593,13 @@@ DEFUN (neighbor_weight "Set default weight for routes from this neighbor\n" "default weight\n") { - return peer_weight_set_vty (vty, argv[0], bgp_node_afi (vty), bgp_node_safi (vty), argv[1]); + int idx_peer = 1; + int idx_number = 3; - return peer_weight_set_vty (vty, argv[idx_peer]->arg, argv[idx_number]->arg); ++ return peer_weight_set_vty (vty, ++ argv[idx_peer]->arg, ++ bgp_node_afi (vty), ++ bgp_node_safi (vty), ++ argv[idx_number]->arg); } DEFUN (no_neighbor_weight, @@@ -4602,13 -4930,19 +4608,13 @@@ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 - "Set default weight for routes from this neighbor\n") + "Set default weight for routes from this neighbor\n" + "default weight\n") { - return peer_weight_unset_vty (vty, argv[0], bgp_node_afi (vty), bgp_node_safi (vty)); + int idx_peer = 2; - return peer_weight_unset_vty (vty, argv[idx_peer]->arg); ++ return peer_weight_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty), bgp_node_safi (vty)); } -ALIAS (no_neighbor_weight, - no_neighbor_weight_val_cmd, - NO_NEIGHBOR_CMD2 "weight <0-65535>", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Set default weight for routes from this neighbor\n" - "default weight\n") /* Override capability negotiation. */ DEFUN (neighbor_override_capability, @@@ -4658,7 -4988,7 +4664,7 @@@ DEFUN (no_neighbor_strict_capability } static int --peer_timers_set_vty (struct vty *vty, const char *ip_str, ++peer_timers_set_vty (struct vty *vty, const char *ip_str, const char *keep_str, const char *hold_str) { int ret; @@@ -4717,14 -5055,9 +4723,14 @@@ DEFUN (no_neighbor_timers "BGP per neighbor timers\n" "Keepalive interval\n" "Holdtime\n") +{ + int idx_peer = 2; + return peer_timers_unset_vty (vty, argv[idx_peer]->arg); +} + static int --peer_timers_connect_set_vty (struct vty *vty, const char *ip_str, ++peer_timers_connect_set_vty (struct vty *vty, const char *ip_str, const char *time_str) { int ret; @@@ -4778,17 -5109,24 +4784,17 @@@ DEFUN (no_neighbor_timers_connect NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "BGP per neighbor timers\n" - "BGP connect timer\n") + "BGP connect timer\n" + "Connect timer\n") { - return peer_timers_connect_unset_vty (vty, argv[0]); + int idx_peer = 2; + return peer_timers_connect_unset_vty (vty, argv[idx_peer]->arg); } -ALIAS (no_neighbor_timers_connect, - no_neighbor_timers_connect_val_cmd, - NO_NEIGHBOR_CMD2 "timers connect <1-65535>", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "BGP per neighbor timers\n" - "BGP connect timer\n" - "Connect timer\n") static int --peer_advertise_interval_vty (struct vty *vty, const char *ip_str, -- const char *time_str, int set) ++peer_advertise_interval_vty (struct vty *vty, const char *ip_str, ++ const char *time_str, int set) { int ret; struct peer *peer; @@@ -4928,7 -5275,7 +4934,7 @@@ DEFUN (no_neighbor_interface /* Set distribute list to the peer. */ static int --peer_distribute_set_vty (struct vty *vty, const char *ip_str, ++peer_distribute_set_vty (struct vty *vty, const char *ip_str, afi_t afi, safi_t safi, const char *name_str, const char *direct_str) { @@@ -5015,7 -5357,7 +5021,7 @@@ DEFUN (no_neighbor_distribute_list /* Set prefix list to the peer. */ static int peer_prefix_list_set_vty (struct vty *vty, const char *ip_str, afi_t afi, -- safi_t safi, const char *name_str, ++ safi_t safi, const char *name_str, const char *direct_str) { int ret; @@@ -5048,7 -5390,7 +5054,7 @@@ peer_prefix_list_unset_vty (struct vty peer = peer_and_group_lookup_vty (vty, ip_str); if (! peer) return CMD_WARNING; -- ++ /* Check filter direction. */ if (strncmp (direct_str, "i", 1) == 0) direct = FILTER_IN; @@@ -5095,7 -5432,7 +5101,7 @@@ DEFUN (no_neighbor_prefix_list } static int --peer_aslist_set_vty (struct vty *vty, const char *ip_str, ++peer_aslist_set_vty (struct vty *vty, const char *ip_str, afi_t afi, safi_t safi, const char *name_str, const char *direct_str) { @@@ -5119,7 -5456,7 +5125,7 @@@ } static int --peer_aslist_unset_vty (struct vty *vty, const char *ip_str, ++peer_aslist_unset_vty (struct vty *vty, const char *ip_str, afi_t afi, safi_t safi, const char *direct_str) { @@@ -5178,7 -5510,7 +5184,7 @@@ DEFUN (no_neighbor_filter_list /* Set route-map to the peer. */ static int --peer_route_map_set_vty (struct vty *vty, const char *ip_str, ++peer_route_map_set_vty (struct vty *vty, const char *ip_str, afi_t afi, safi_t safi, const char *name_str, const char *direct_str) { @@@ -5322,7 -5646,7 +5328,7 @@@ DEFUN (no_neighbor_unsuppress_map static int peer_maximum_prefix_set_vty (struct vty *vty, const char *ip_str, afi_t afi, -- safi_t safi, const char *num_str, ++ safi_t safi, const char *num_str, const char *threshold_str, int warning, const char *restart_str) { @@@ -5478,30 -5785,83 +5484,30 @@@ DEFUN (no_neighbor_maximum_prefix NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 - "Maximum number of prefix accept from this peer\n") + "Maximum number of prefix accept from this peer\n" + "maximum no. of prefix limit\n" + "Threshold value (%) at which to generate a warning msg\n" + "Restart bgp connection after limit is exceeded\n" + "Restart interval in minutes" + "Only give warning message when limit is exceeded\n") { - return peer_maximum_prefix_unset_vty (vty, argv[0], bgp_node_afi (vty), + int idx_peer = 2; + return peer_maximum_prefix_unset_vty (vty, argv[idx_peer]->arg, bgp_node_afi (vty), bgp_node_safi (vty)); } -- -ALIAS (no_neighbor_maximum_prefix, - no_neighbor_maximum_prefix_val_cmd, - NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295>", - NO_STR ++ + +/* "neighbor allowas-in" */ +DEFUN (neighbor_allowas_in, + neighbor_allowas_in_cmd, + "neighbor allowas-in [(1-10)]", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 - "Maximum number of prefix accept from this peer\n" - "maximum no. of prefix limit\n") - -ALIAS (no_neighbor_maximum_prefix, - no_neighbor_maximum_prefix_threshold_cmd, - NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100>", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Maximum number of prefix accept from this peer\n" - "maximum no. of prefix limit\n" - "Threshold value (%) at which to generate a warning msg\n") - -ALIAS (no_neighbor_maximum_prefix, - no_neighbor_maximum_prefix_warning_cmd, - NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> warning-only", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Maximum number of prefix accept from this peer\n" - "maximum no. of prefix limit\n" - "Only give warning message when limit is exceeded\n") - -ALIAS (no_neighbor_maximum_prefix, - no_neighbor_maximum_prefix_threshold_warning_cmd, - NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> warning-only", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Maximum number of prefix accept from this peer\n" - "maximum no. of prefix limit\n" - "Threshold value (%) at which to generate a warning msg\n" - "Only give warning message when limit is exceeded\n") - -ALIAS (no_neighbor_maximum_prefix, - no_neighbor_maximum_prefix_restart_cmd, - NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> restart <1-65535>", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Maximum number of prefix accept from this peer\n" - "maximum no. of prefix limit\n" - "Restart bgp connection after limit is exceeded\n" - "Restart interval in minutes") - -ALIAS (no_neighbor_maximum_prefix, - no_neighbor_maximum_prefix_threshold_restart_cmd, - NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> restart <1-65535>", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Maximum number of prefix accept from this peer\n" - "maximum no. of prefix limit\n" - "Threshold value (%) at which to generate a warning msg\n" - "Restart bgp connection after limit is exceeded\n" - "Restart interval in minutes") - -/* "neighbor allowas-in" */ -DEFUN (neighbor_allowas_in, - neighbor_allowas_in_cmd, - NEIGHBOR_CMD2 "allowas-in", - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Accept as-path with my AS present in it\n") + "Accept as-path with my AS present in it\n" + "Number of occurances of AS number\n") { + int idx_peer = 1; + int idx_number = 3; int ret; struct peer *peer; unsigned int allow_num; @@@ -5556,11 -5928,11 +5562,11 @@@ DEFUN (neighbor_ttl_security struct peer *peer; int gtsm_hops; - peer = peer_and_group_lookup_vty (vty, argv[0]); + peer = peer_and_group_lookup_vty (vty, argv[idx_peer]->arg); if (! peer) return CMD_WARNING; -- - VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[1], 1, 254); ++ + VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[idx_number]->arg, 1, 254); /* * If 'neighbor swpX', then this is for directly connected peers, @@@ -6170,7 -10009,7 +6176,7 @@@ DEFUN (show_bgp_views vty_out (vty, "BGP Multiple Instance is not enabled%s", VTY_NEWLINE); return CMD_WARNING; } -- ++ vty_out (vty, "Defined BGP views:%s", VTY_NEWLINE); for (ALL_LIST_ELEMENTS_RO(inst, node, bgp)) { @@@ -6181,7 -10020,7 +6187,7 @@@ bgp->name ? bgp->name : "(null)", bgp->as, VTY_NEWLINE); } -- ++ return CMD_SUCCESS; } @@@ -6302,14 -10141,14 +6308,14 @@@ DEFUN (show_bgp_memory { char memstrbuf[MTYPE_MEMSTR_LEN]; unsigned long count; -- ++ /* RIB related usage stats */ count = mtype_stats_alloc (MTYPE_BGP_NODE); vty_out (vty, "%ld RIB nodes, using %s of memory%s", count, mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct bgp_node)), VTY_NEWLINE); -- ++ count = mtype_stats_alloc (MTYPE_BGP_ROUTE); vty_out (vty, "%ld BGP routes, using %s of memory%s", count, mtype_memstr (memstrbuf, sizeof (memstrbuf), @@@ -6320,7 -10159,7 +6326,7 @@@ mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct bgp_info_extra)), VTY_NEWLINE); -- ++ if ((count = mtype_stats_alloc (MTYPE_BGP_STATIC))) vty_out (vty, "%ld Static routes, using %s of memory%s", count, mtype_memstr (memstrbuf, sizeof (memstrbuf), @@@ -6332,7 -10171,7 +6338,7 @@@ mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct bpacket)), VTY_NEWLINE); -- ++ /* Adj-In/Out */ if ((count = mtype_stats_alloc (MTYPE_BGP_ADJ_IN))) vty_out (vty, "%ld Adj-In entries, using %s of memory%s", count, @@@ -6344,7 -10183,7 +6350,7 @@@ mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct bgp_adj_out)), VTY_NEWLINE); -- ++ if ((count = mtype_stats_alloc (MTYPE_BGP_NEXTHOP_CACHE))) vty_out (vty, "%ld Nexthop cache entries, using %s of memory%s", count, mtype_memstr (memstrbuf, sizeof (memstrbuf), @@@ -6359,32 -10198,32 +6365,32 @@@ /* Attributes */ count = attr_count(); -- vty_out (vty, "%ld BGP attributes, using %s of memory%s", count, -- mtype_memstr (memstrbuf, sizeof (memstrbuf), -- count * sizeof(struct attr)), ++ vty_out (vty, "%ld BGP attributes, using %s of memory%s", count, ++ mtype_memstr (memstrbuf, sizeof (memstrbuf), ++ count * sizeof(struct attr)), VTY_NEWLINE); if ((count = mtype_stats_alloc (MTYPE_ATTR_EXTRA))) -- vty_out (vty, "%ld BGP extra attributes, using %s of memory%s", count, -- mtype_memstr (memstrbuf, sizeof (memstrbuf), -- count * sizeof(struct attr_extra)), ++ vty_out (vty, "%ld BGP extra attributes, using %s of memory%s", count, ++ mtype_memstr (memstrbuf, sizeof (memstrbuf), ++ count * sizeof(struct attr_extra)), VTY_NEWLINE); -- ++ if ((count = attr_unknown_count())) vty_out (vty, "%ld unknown attributes%s", count, VTY_NEWLINE); -- ++ /* AS_PATH attributes */ count = aspath_count (); vty_out (vty, "%ld BGP AS-PATH entries, using %s of memory%s", count, mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct aspath)), VTY_NEWLINE); -- ++ count = mtype_stats_alloc (MTYPE_AS_SEG); vty_out (vty, "%ld BGP AS-PATH segments, using %s of memory%s", count, mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct assegment)), VTY_NEWLINE); -- ++ /* Other attributes */ if ((count = community_count ())) vty_out (vty, "%ld BGP community entries, using %s of memory%s", count, @@@ -6396,26 -10235,26 +6402,26 @@@ mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct ecommunity)), VTY_NEWLINE); -- ++ if ((count = mtype_stats_alloc (MTYPE_CLUSTER))) vty_out (vty, "%ld Cluster lists, using %s of memory%s", count, mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct cluster_list)), VTY_NEWLINE); -- ++ /* Peer related usage */ count = mtype_stats_alloc (MTYPE_BGP_PEER); vty_out (vty, "%ld peers, using %s of memory%s", count, mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct peer)), VTY_NEWLINE); -- ++ if ((count = mtype_stats_alloc (MTYPE_PEER_GROUP))) vty_out (vty, "%ld peer groups, using %s of memory%s", count, mtype_memstr (memstrbuf, sizeof (memstrbuf), count * sizeof (struct peer_group)), VTY_NEWLINE); -- ++ /* Other */ if ((count = mtype_stats_alloc (MTYPE_HASH))) vty_out (vty, "%ld hash tables, using %s of memory%s", count, @@@ -6614,7 -10453,7 +6620,7 @@@ bgp_show_summary (struct vty *vty, stru vty_out (vty, "%s%s", header, VTY_NEWLINE); } } -- ++ count++; if (use_json) @@@ -7633,7 -11729,7 +7641,7 @@@ bgp_show_peer (struct vty *vty, struct if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION) && bgp_confederation_peers_check (bgp, p->as)) vty_out (vty, " Neighbor under common administration%s", VTY_NEWLINE); -- ++ /* Status. */ vty_out (vty, " BGP state = %s", LOOKUP (bgp_status_msg, p->status)); @@@ -7665,7 -11761,7 +7673,7 @@@ } } /* Capability. */ -- if (p->status == Established) ++ if (p->status == Established) { if (p->cap || p->afc_adv[AFI_IP][SAFI_UNICAST] @@@ -7880,7 -11979,10 +7891,10 @@@ } } if (! restart_af_count) + { - json_object_string_add(json_cap, "addressFamiliesByPeer", "none"); + json_object_string_add(json_cap, "addressFamiliesByPeer", "none"); + json_object_free(json_restart); + } else json_object_object_add(json_cap, "addressFamiliesByPeer", json_restart); } @@@ -8154,7 -12256,7 +8168,7 @@@ if (p->t_gr_restart) vty_out (vty, " The remaining time of restart timer is %ld%s", thread_timer_remain_second (p->t_gr_restart), VTY_NEWLINE); -- ++ if (p->t_gr_stale) vty_out (vty, " The remaining time of stalepath timer is %ld%s", thread_timer_remain_second (p->t_gr_stale), VTY_NEWLINE); @@@ -8414,7 -12507,7 +8419,7 @@@ ntohs (p->su_local->sin.sin_port), VTY_NEWLINE); } -- ++ /* Remote address. */ if (p->su_remote) { @@@ -8647,71 -12793,93 +8652,71 @@@ bgp_show_all_instances_neighbors_vty (s vty_out (vty, "}%s", VTY_NEWLINE); } -/* "show ip bgp neighbors" commands. */ -DEFUN (show_ip_bgp_neighbors, - show_ip_bgp_neighbors_cmd, - "show ip bgp neighbors {json}", - SHOW_STR - IP_STR - BGP_STR - "Detailed information on TCP and BGP neighbor connections\n" - "JavaScript Object Notation\n") +static int +bgp_show_neighbor_vty (struct vty *vty, const char *name, + enum show_type type, const char *ip_str, u_char use_json) { - u_char uj = use_json(argc, argv); - - return bgp_show_neighbor_vty (vty, NULL, show_all, NULL, uj, NULL); -} - -ALIAS (show_ip_bgp_neighbors, - show_ip_bgp_ipv4_neighbors_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors {json}", - SHOW_STR - IP_STR - BGP_STR - "Address family\n" - "Address Family modifier\n" - "Address Family modifier\n" - "Detailed information on TCP and BGP neighbor connections\n" - "JavaScript Object Notation\n") - -ALIAS (show_ip_bgp_neighbors, - show_ip_bgp_vpnv4_all_neighbors_cmd, - "show ip bgp vpnv4 all neighbors {json}", - SHOW_STR - IP_STR - BGP_STR - "Display VPNv4 NLRI specific information\n" - "Display information about all VPNv4 NLRIs\n" - "Detailed information on TCP and BGP neighbor connections\n" - "JavaScript Object Notation\n") + int ret; + struct bgp *bgp; + union sockunion su; + json_object *json = NULL; -ALIAS (show_ip_bgp_neighbors, - show_ip_bgp_vpnv4_rd_neighbors_cmd, - "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors {json}", - SHOW_STR - IP_STR - BGP_STR - "Display VPNv4 NLRI specific information\n" - "Display information for a route distinguisher\n" - "VPN Route Distinguisher\n" - "Detailed information on TCP and BGP neighbor connections\n" - "JavaScript Object Notation\n") + if (use_json) + json = json_object_new_object(); -ALIAS (show_ip_bgp_neighbors, - show_bgp_neighbors_cmd, - "show bgp neighbors {json}", - SHOW_STR - BGP_STR - "Detailed information on TCP and BGP neighbor connections\n" - "JavaScript Object Notation\n") + if (name) + { + if (strmatch(name, "all")) + { + bgp_show_all_instances_neighbors_vty (vty, use_json); + return CMD_SUCCESS; + } + else + { + bgp = bgp_lookup_by_name (name); + if (! bgp) + { + if (use_json) + { + json_object_boolean_true_add(json, "bgpNoSuchInstance"); - vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); ++ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); + json_object_free(json); + } + else + vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE); -ALIAS (show_ip_bgp_neighbors, - show_bgp_ipv6_neighbors_cmd, - "show bgp ipv6 neighbors {json}", - SHOW_STR - BGP_STR - "Address family\n" - "Detailed information on TCP and BGP neighbor connections\n" - "JavaScript Object Notation\n") + return CMD_WARNING; + } + } + } + else + { + bgp = bgp_get_default (); + } -DEFUN (show_ip_bgp_neighbors_peer, - show_ip_bgp_neighbors_peer_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) {json}", - SHOW_STR - IP_STR - BGP_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" - "JavaScript Object Notation\n") -{ - u_char uj = use_json(argc, argv); + if (bgp) + { + if (ip_str) + { + ret = str2sockunion (ip_str, &su); + if (ret < 0) + bgp_show_neighbor (vty, bgp, type, NULL, ip_str, use_json, json); + else + bgp_show_neighbor (vty, bgp, type, &su, NULL, use_json, json); + } + else + { + bgp_show_neighbor (vty, bgp, type, NULL, NULL, use_json, json); + } + } - return bgp_show_neighbor_vty (vty, NULL, show_peer, argv[argc - 2], uj, NULL); + return CMD_SUCCESS; } -ALIAS (show_ip_bgp_neighbors_peer, - show_ip_bgp_ipv4_neighbors_peer_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) {json}", +/* "show ip bgp neighbors" commands. */ +DEFUN (show_ip_bgp_neighbors, + show_ip_bgp_neighbors_cmd, + "show [ip] bgp [ WORD] [] neighbors [] [json]", SHOW_STR IP_STR BGP_STR @@@ -8817,7 -13088,7 +8822,7 @@@ DEFUN (show_ip_bgp_community_info { vty_out (vty, "Address Refcnt Community%s", VTY_NEWLINE); -- hash_iterate (community_hash (), ++ hash_iterate (community_hash (), (void (*) (struct hash_backet *, void *)) community_show_all_iterator, vty); @@@ -10062,7 -14478,7 +10067,7 @@@ bgp_vty_init (void install_default (BGP_VPNV6_NODE); install_default (BGP_ENCAP_NODE); install_default (BGP_ENCAPV6_NODE); -- ++ /* "bgp multiple-instance" commands. */ install_element (CONFIG_NODE, &bgp_multiple_instance_cmd); install_element (CONFIG_NODE, &no_bgp_multiple_instance_cmd); @@@ -10155,7 -14597,7 +10160,7 @@@ /* "bgp always-compare-med" commands */ install_element (BGP_NODE, &bgp_always_compare_med_cmd); install_element (BGP_NODE, &no_bgp_always_compare_med_cmd); -- ++ /* "bgp deterministic-med" commands */ install_element (BGP_NODE, &bgp_deterministic_med_cmd); install_element (BGP_NODE, &no_bgp_deterministic_med_cmd); @@@ -10165,9 -14607,11 +10170,9 @@@ install_element (BGP_NODE, &no_bgp_graceful_restart_cmd); install_element (BGP_NODE, &bgp_graceful_restart_stalepath_time_cmd); install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_cmd); - install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_val_cmd); install_element (BGP_NODE, &bgp_graceful_restart_restart_time_cmd); install_element (BGP_NODE, &no_bgp_graceful_restart_restart_time_cmd); - install_element (BGP_NODE, &no_bgp_graceful_restart_restart_time_val_cmd); -- ++ /* "bgp fast-external-failover" commands */ install_element (BGP_NODE, &bgp_fast_external_failover_cmd); install_element (BGP_NODE, &no_bgp_fast_external_failover_cmd); @@@ -10205,7 -14651,7 +10210,7 @@@ /* "no bgp default ipv4-unicast" commands. */ install_element (BGP_NODE, &no_bgp_default_ipv4_unicast_cmd); install_element (BGP_NODE, &bgp_default_ipv4_unicast_cmd); -- ++ /* "bgp network import-check" commands. */ install_element (BGP_NODE, &bgp_network_import_check_cmd); install_element (BGP_NODE, &bgp_network_import_check_exact_cmd); @@@ -10311,7 -14772,7 +10316,7 @@@ install_element (BGP_VPNV6_NODE, &no_neighbor_set_peer_group_cmd); install_element (BGP_ENCAP_NODE, &no_neighbor_set_peer_group_cmd); install_element (BGP_ENCAPV6_NODE, &no_neighbor_set_peer_group_cmd); -- ++ /* "neighbor softreconfiguration inbound" commands.*/ install_element (BGP_NODE, &neighbor_soft_reconfiguration_cmd); install_element (BGP_NODE, &no_neighbor_soft_reconfiguration_cmd); @@@ -10728,7 -15307,32 +10733,24 @@@ /* "neighbor weight" commands. */ install_element (BGP_NODE, &neighbor_weight_cmd); install_element (BGP_NODE, &no_neighbor_weight_cmd); - install_element (BGP_NODE, &no_neighbor_weight_val_cmd); + + install_element (BGP_IPV4_NODE, &neighbor_weight_cmd); + install_element (BGP_IPV4_NODE, &no_neighbor_weight_cmd); - install_element (BGP_IPV4_NODE, &no_neighbor_weight_val_cmd); + install_element (BGP_IPV4M_NODE, &neighbor_weight_cmd); + install_element (BGP_IPV4M_NODE, &no_neighbor_weight_cmd); - install_element (BGP_IPV4M_NODE, &no_neighbor_weight_val_cmd); + install_element (BGP_IPV6_NODE, &neighbor_weight_cmd); + install_element (BGP_IPV6_NODE, &no_neighbor_weight_cmd); - install_element (BGP_IPV6_NODE, &no_neighbor_weight_val_cmd); + install_element (BGP_IPV6M_NODE, &neighbor_weight_cmd); + install_element (BGP_IPV6M_NODE, &no_neighbor_weight_cmd); - install_element (BGP_IPV6M_NODE, &no_neighbor_weight_val_cmd); + install_element (BGP_VPNV4_NODE, &neighbor_weight_cmd); + install_element (BGP_VPNV4_NODE, &no_neighbor_weight_cmd); - install_element (BGP_VPNV4_NODE, &no_neighbor_weight_val_cmd); + install_element (BGP_VPNV6_NODE, &neighbor_weight_cmd); + install_element (BGP_VPNV6_NODE, &no_neighbor_weight_cmd); - install_element (BGP_VPNV6_NODE, &no_neighbor_weight_val_cmd); + install_element (BGP_ENCAP_NODE, &neighbor_weight_cmd); + install_element (BGP_ENCAP_NODE, &no_neighbor_weight_cmd); - install_element (BGP_ENCAP_NODE, &no_neighbor_weight_val_cmd); + install_element (BGP_ENCAPV6_NODE, &neighbor_weight_cmd); + install_element (BGP_ENCAPV6_NODE, &no_neighbor_weight_cmd); - install_element (BGP_ENCAPV6_NODE, &no_neighbor_weight_val_cmd); + /* "neighbor override-capability" commands. */ install_element (BGP_NODE, &neighbor_override_capability_cmd); install_element (BGP_NODE, &no_neighbor_override_capability_cmd); @@@ -10988,36 -15965,55 +11010,22 @@@ install_element (VIEW_NODE, &show_bgp_updgrps_adj_s_cmd); install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_s_cmd); install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_s_cmd); - install_element (RESTRICTED_NODE, &show_ip_bgp_summary_cmd); - install_element (RESTRICTED_NODE, &show_ip_bgp_updgrps_cmd); - install_element (RESTRICTED_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd); - install_element (RESTRICTED_NODE, &show_ip_bgp_updgrps_adj_cmd); - install_element (RESTRICTED_NODE, &show_ip_bgp_instance_updgrps_adj_cmd); - install_element (RESTRICTED_NODE, &show_bgp_updgrps_adj_cmd); - install_element (RESTRICTED_NODE, &show_bgp_instance_updgrps_adj_cmd); - install_element (RESTRICTED_NODE, &show_bgp_updgrps_afi_adj_cmd); - install_element (RESTRICTED_NODE, &show_ip_bgp_updgrps_adj_s_cmd); - install_element (RESTRICTED_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd); - install_element (RESTRICTED_NODE, &show_bgp_updgrps_adj_s_cmd); - install_element (RESTRICTED_NODE, &show_bgp_instance_updgrps_adj_s_cmd); - install_element (RESTRICTED_NODE, &show_bgp_updgrps_afi_adj_s_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_summary_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_updgrps_cmd); - install_element (ENABLE_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_updgrps_adj_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_instance_updgrps_adj_cmd); - install_element (ENABLE_NODE, &show_bgp_updgrps_adj_cmd); - install_element (ENABLE_NODE, &show_bgp_instance_updgrps_adj_cmd); - install_element (ENABLE_NODE, &show_bgp_updgrps_afi_adj_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_updgrps_adj_s_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd); - install_element (ENABLE_NODE, &show_bgp_updgrps_adj_s_cmd); - install_element (ENABLE_NODE, &show_bgp_instance_updgrps_adj_s_cmd); - install_element (ENABLE_NODE, &show_bgp_updgrps_afi_adj_s_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_summary_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_all_summary_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_summary_cmd); - install_element (VIEW_NODE, &show_bgp_ipv4_safi_summary_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_summary_cmd); - install_element (VIEW_NODE, &show_bgp_instance_ipv4_safi_summary_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_summary_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd); -#ifdef HAVE_IPV6 - install_element (VIEW_NODE, &show_bgp_summary_cmd); - install_element (VIEW_NODE, &show_bgp_instance_summary_cmd); - install_element (VIEW_NODE, &show_bgp_instance_all_summary_cmd); - install_element (VIEW_NODE, &show_bgp_ipv6_summary_cmd); - install_element (VIEW_NODE, &show_bgp_ipv6_safi_summary_cmd); - install_element (VIEW_NODE, &show_bgp_instance_ipv6_summary_cmd); - install_element (VIEW_NODE, &show_bgp_instance_ipv6_safi_summary_cmd); -#endif /* HAVE_IPV6 */ - - install_element (VIEW_NODE, &show_bgp_ipv4_vpn_summary_cmd); - - install_element (VIEW_NODE, &show_bgp_ipv6_vpn_summary_cmd); ++ install_element (VIEW_NODE, &show_ip_bgp_summary_cmd); ++ install_element (VIEW_NODE, &show_ip_bgp_updgrps_cmd); ++ install_element (VIEW_NODE, &show_bgp_instance_all_ipv6_updgrps_cmd); ++ install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_cmd); ++ install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_cmd); ++ install_element (VIEW_NODE, &show_bgp_updgrps_adj_cmd); ++ install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_cmd); ++ install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_cmd); ++ install_element (VIEW_NODE, &show_ip_bgp_updgrps_adj_s_cmd); ++ install_element (VIEW_NODE, &show_ip_bgp_instance_updgrps_adj_s_cmd); ++ install_element (VIEW_NODE, &show_bgp_updgrps_adj_s_cmd); ++ install_element (VIEW_NODE, &show_bgp_instance_updgrps_adj_s_cmd); ++ install_element (VIEW_NODE, &show_bgp_updgrps_afi_adj_s_cmd); /* "show ip bgp neighbors" commands. */ install_element (VIEW_NODE, &show_ip_bgp_neighbors_cmd); - install_element (ENABLE_NODE, &show_ip_bgp_neighbors_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbors_cmd); - install_element (VIEW_NODE, &show_ip_bgp_neighbors_peer_cmd); - install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbors_peer_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbors_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbors_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_neighbors_peer_cmd); - install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_neighbors_peer_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_neighbors_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_all_neighbors_cmd); - install_element (VIEW_NODE, &show_ip_bgp_instance_neighbors_peer_cmd); - -#ifdef HAVE_IPV6 - install_element (VIEW_NODE, &show_bgp_neighbors_cmd); - install_element (VIEW_NODE, &show_bgp_ipv6_neighbors_cmd); - install_element (VIEW_NODE, &show_bgp_neighbors_peer_cmd); - install_element (VIEW_NODE, &show_bgp_ipv6_neighbors_peer_cmd); - install_element (VIEW_NODE, &show_bgp_instance_neighbors_cmd); - install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbors_cmd); - install_element (VIEW_NODE, &show_bgp_instance_neighbors_peer_cmd); - install_element (VIEW_NODE, &show_bgp_instance_ipv6_neighbors_peer_cmd); - - /* Old commands. */ - install_element (VIEW_NODE, &show_ipv6_bgp_summary_cmd); - install_element (VIEW_NODE, &show_ipv6_mbgp_summary_cmd); -#endif /* HAVE_IPV6 */ /* "show ip bgp peer-group" commands. */ install_element (VIEW_NODE, &show_ip_bgp_peer_groups_cmd); @@@ -11083,19 -16091,13 +11083,13 @@@ /* "show bgp memory" commands. */ install_element (VIEW_NODE, &show_bgp_memory_cmd); - install_element (RESTRICTED_NODE, &show_bgp_memory_cmd); - install_element (ENABLE_NODE, &show_bgp_memory_cmd); -- ++ /* "show bgp views" commands. */ install_element (VIEW_NODE, &show_bgp_views_cmd); - install_element (RESTRICTED_NODE, &show_bgp_views_cmd); - install_element (ENABLE_NODE, &show_bgp_views_cmd); -- ++ /* "show bgp vrfs" commands. */ install_element (VIEW_NODE, &show_bgp_vrfs_cmd); - install_element (RESTRICTED_NODE, &show_bgp_vrfs_cmd); - install_element (ENABLE_NODE, &show_bgp_vrfs_cmd); -- ++ /* Community-list. */ community_list_vty (); } @@@ -11219,7 -16209,7 +11213,7 @@@ community_list_unset_vty (struct vty *v if (argc > 1) { - // Check the list direct. - /* Check the list direct. */ ++ // Check the list direct. if (strncmp (argv[1], "p", 1) == 0) direct = COMMUNITY_PERMIT; else if (strncmp (argv[1], "d", 1) == 0) @@@ -11396,10 -16529,9 +11390,10 @@@ DEFUN (show_ip_community_list_arg } static int - extcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv, -extcommunity_list_set_vty (struct vty *vty, int argc, const char **argv, - int style, int reject_all_digit_name) ++extcommunity_list_set_vty (struct vty *vty, int argc, struct cmd_token **argv, + int style) { + /* CHECK ME dwalton finish this int ret; int direct; char *str; @@@ -11416,7 -16548,7 +11410,7 @@@ return CMD_WARNING; } - // All digit name check. - /* All digit name check. */ ++ // All digit name check. if (reject_all_digit_name && all_digit (argv[0])) { vty_out (vty, "%% Community name cannot have all digits%s", VTY_NEWLINE); @@@ -11431,7 -16563,8 +11425,7 @@@ ret = extcommunity_list_set (bgp_clist, argv[0], str, direct, style); - // Free temporary community list string allocated by argv_concat(). - /* Free temporary community list string allocated by - argv_concat(). */ ++ // Free temporary community list string allocated by argv_concat(). if (str) XFREE (MTYPE_TMP, str); @@@ -11722,20 -16994,41 +11716,16 @@@ community_list_vty (void /* Community-list. */ install_element (CONFIG_NODE, &ip_community_list_standard_cmd); - install_element (CONFIG_NODE, &ip_community_list_standard2_cmd); - install_element (CONFIG_NODE, &ip_community_list_expanded_cmd); - install_element (CONFIG_NODE, &ip_community_list_name_standard_cmd); - install_element (CONFIG_NODE, &ip_community_list_name_standard2_cmd); - install_element (CONFIG_NODE, &ip_community_list_name_expanded_cmd); install_element (CONFIG_NODE, &no_ip_community_list_standard_all_cmd); - install_element (CONFIG_NODE, &no_ip_community_list_standard_direction_cmd); install_element (CONFIG_NODE, &no_ip_community_list_expanded_all_cmd); - install_element (CONFIG_NODE, &no_ip_community_list_name_standard_all_cmd); - install_element (CONFIG_NODE, &no_ip_community_list_name_expanded_all_cmd); - install_element (CONFIG_NODE, &no_ip_community_list_standard_cmd); - install_element (CONFIG_NODE, &no_ip_community_list_expanded_cmd); - install_element (CONFIG_NODE, &no_ip_community_list_name_standard_cmd); - install_element (CONFIG_NODE, &no_ip_community_list_name_standard_brief_cmd); - install_element (CONFIG_NODE, &no_ip_community_list_name_expanded_cmd); install_element (VIEW_NODE, &show_ip_community_list_cmd); install_element (VIEW_NODE, &show_ip_community_list_arg_cmd); - install_element (ENABLE_NODE, &show_ip_community_list_cmd); - install_element (ENABLE_NODE, &show_ip_community_list_arg_cmd); /* Extcommunity-list. */ install_element (CONFIG_NODE, &ip_extcommunity_list_standard_cmd); - install_element (CONFIG_NODE, &ip_extcommunity_list_standard2_cmd); - install_element (CONFIG_NODE, &ip_extcommunity_list_expanded_cmd); - install_element (CONFIG_NODE, &ip_extcommunity_list_name_standard_cmd); - install_element (CONFIG_NODE, &ip_extcommunity_list_name_standard2_cmd); install_element (CONFIG_NODE, &ip_extcommunity_list_name_expanded_cmd); install_element (CONFIG_NODE, &no_ip_extcommunity_list_standard_all_cmd); - install_element (CONFIG_NODE, &no_ip_extcommunity_list_standard_direction_cmd); install_element (CONFIG_NODE, &no_ip_extcommunity_list_expanded_all_cmd); - install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_standard_all_cmd); - install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_expanded_all_cmd); - install_element (CONFIG_NODE, &no_ip_extcommunity_list_standard_cmd); - install_element (CONFIG_NODE, &no_ip_extcommunity_list_expanded_cmd); - install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_standard_cmd); - install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_standard_brief_cmd); - install_element (CONFIG_NODE, &no_ip_extcommunity_list_name_expanded_cmd); install_element (VIEW_NODE, &show_ip_extcommunity_list_cmd); install_element (VIEW_NODE, &show_ip_extcommunity_list_arg_cmd); - install_element (ENABLE_NODE, &show_ip_extcommunity_list_cmd); - install_element (ENABLE_NODE, &show_ip_extcommunity_list_arg_cmd); } diff --cc bgpd/bgpd.c index 9a7b297fb3,9ad68fbc67..eb8a50b267 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@@ -4515,9 -4562,14 +4562,14 @@@ peer_weight_set (struct peer *peer, afi group = peer->group; for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) { - peer->weight = group->conf->weight; + if (peer->weight[afi][safi] != weight) + { + peer->weight[afi][safi] = weight; + SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT); + peer_on_policy_change (peer, afi, safi, 0); - } ++ } } - return 1; + return 0; } int @@@ -4526,24 -4578,55 +4578,55 @@@ peer_weight_unset (struct peer *peer, a struct peer_group *group; struct listnode *node, *nnode; - /* Set default weight. */ + /* not the peer-group itself but a peer in a peer-group */ - if (peer_group_active(peer)) + if (peer_group_active (peer)) - peer->weight = peer->group->conf->weight; - else - peer->weight = 0; + { + group = peer->group; - UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT); + /* inherit weight from the peer-group */ + if (CHECK_FLAG (group->conf->af_flags[afi][safi], PEER_FLAG_WEIGHT)) + { + peer->weight[afi][safi] = group->conf->weight[afi][safi]; + peer_af_flag_set (peer, afi, safi, PEER_FLAG_WEIGHT); + peer_on_policy_change (peer, afi, safi, 0); + } + else + { + if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT)) + { + peer->weight[afi][safi] = 0; + peer_af_flag_unset (peer, afi, safi, PEER_FLAG_WEIGHT); + peer_on_policy_change (peer, afi, safi, 0); + } + } + } - if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) - return 0; + else + { + if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT)) + { + peer->weight[afi][safi] = 0; + peer_af_flag_unset (peer, afi, safi, PEER_FLAG_WEIGHT); + peer_on_policy_change (peer, afi, safi, 0); + } - /* peer-group member updates. */ - group = peer->group; + /* peer-group member updates. */ + group = peer->group; + + if (group) + { - for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) - { + for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) + { - peer->weight = 0; + if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_WEIGHT)) + { + peer->weight[afi][safi] = 0; + peer_af_flag_unset (peer, afi, safi, PEER_FLAG_WEIGHT); + peer_on_policy_change (peer, afi, safi, 0); + } + } - } ++ } } - return 1; + return 0; } int diff --cc bgpd/rfapi/rfapi_vty.c index 0000000000,1978bec280..e519ed4803 mode 000000,100644..100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@@ -1,0 -1,5016 +1,5016 @@@ + /* + * + * Copyright 2009-2016, LabN Consulting, L.L.C. + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + + #include + + #include "lib/zebra.h" + #include "lib/prefix.h" + #include "lib/table.h" + #include "lib/vty.h" + #include "lib/memory.h" + #include "lib/routemap.h" + #include "lib/log.h" + #include "lib/linklist.h" + #include "lib/command.h" + + #include "bgpd/bgpd.h" + #include "bgpd/bgp_ecommunity.h" + #include "bgpd/bgp_attr.h" + #include "bgpd/bgp_mplsvpn.h" + + #include "bgpd/rfapi/bgp_rfapi_cfg.h" + #include "bgpd/rfapi/rfapi.h" + #include "bgpd/rfapi/rfapi_backend.h" + + #include "bgpd/bgp_route.h" + #include "bgpd/bgp_aspath.h" + #include "bgpd/bgp_community.h" + #include "bgpd/bgp_vnc_types.h" + + #include "bgpd/rfapi/rfapi_import.h" + #include "bgpd/rfapi/rfapi_private.h" + #include "bgpd/rfapi/rfapi_monitor.h" + #include "bgpd/rfapi/rfapi_rib.h" + #include "bgpd/rfapi/rfapi_vty.h" + #include "bgpd/rfapi/rfapi_ap.h" + #include "bgpd/rfapi/rfapi_encap_tlv.h" + #include "bgpd/rfapi/vnc_debug.h" + + #define DEBUG_L2_EXTRA 0 + + #define VNC_SHOW_STR "VNC information\n" + + /* format related utilies */ + + + #define FMT_MIN 60 /* seconds */ + #define FMT_HOUR (60 * FMT_MIN) + #define FMT_DAY (24 * FMT_HOUR) + #define FMT_YEAR (365 * FMT_DAY) + + char * + rfapiFormatSeconds (uint32_t seconds, char *buf, size_t len) + { + int year, day, hour, min; + + if (seconds >= FMT_YEAR) + { + year = seconds / FMT_YEAR; + seconds -= year * FMT_YEAR; + } + else + year = 0; + + if (seconds >= FMT_DAY) + { + day = seconds / FMT_DAY; + seconds -= day * FMT_DAY; + } + else + day = 0; + + if (seconds >= FMT_HOUR) + { + hour = seconds / FMT_HOUR; + seconds -= hour * FMT_HOUR; + } + else + hour = 0; + + if (seconds >= FMT_MIN) + { + min = seconds / FMT_MIN; + seconds -= min * FMT_MIN; + } + else + min = 0; + + if (year > 0) + { + snprintf (buf, len, "%dy%dd%dh", year, day, hour); + } + else if (day > 0) + { + snprintf (buf, len, "%dd%dh%dm", day, hour, min); + } + else + { + snprintf (buf, len, "%02d:%02d:%02d", hour, min, seconds); + } + + return buf; + } + + char * + rfapiFormatAge (time_t age, char *buf, size_t len) + { + time_t now, age_adjusted; + + now = rfapi_time (NULL); + age_adjusted = now - age; + + return rfapiFormatSeconds (age_adjusted, buf, len); + } + + + /* + * Reimplementation of quagga/lib/prefix.c function, but + * for RFAPI-style prefixes + */ + void + rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix) + { + uint8_t *pnt; + int index; + int offset; + + static uint8_t maskbit[] = + { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; + + switch (rprefix->prefix.addr_family) + { + case AF_INET: + index = rprefix->length / 8; + if (index < 4) + { + pnt = (uint8_t *) & rprefix->prefix.addr.v4; + offset = rprefix->length % 8; + pnt[index] &= maskbit[offset]; + index++; + while (index < 4) + pnt[index++] = 0; + } + break; + + case AF_INET6: + index = rprefix->length / 8; + if (index < 16) + { + pnt = (uint8_t *) & rprefix->prefix.addr.v6; + offset = rprefix->length % 8; + pnt[index] &= maskbit[offset]; + index++; + while (index < 16) + pnt[index++] = 0; + } + break; + + default: + assert (0); + } + } + + /* + * translate a quagga prefix into a rfapi IP address. The + * prefix is REQUIRED to be 32 bits for IPv4 and 128 bits for IPv6 + * + * RETURNS: + * + * 0 Success + * <0 Error + */ + int + rfapiQprefix2Raddr (struct prefix *qprefix, struct rfapi_ip_addr *raddr) + { + memset (raddr, 0, sizeof (struct rfapi_ip_addr)); + raddr->addr_family = qprefix->family; + switch (qprefix->family) + { + case AF_INET: + if (qprefix->prefixlen != 32) + return -1; + raddr->addr.v4 = qprefix->u.prefix4; + break; + case AF_INET6: + if (qprefix->prefixlen != 128) + return -1; + raddr->addr.v6 = qprefix->u.prefix6; + break; + default: + return -1; + } + return 0; + } + + /* + * Translate Quagga prefix to RFAPI prefix + */ + /* rprefix->cost set to 0 */ + void + rfapiQprefix2Rprefix (struct prefix *qprefix, struct rfapi_ip_prefix *rprefix) + { + memset (rprefix, 0, sizeof (struct rfapi_ip_prefix)); + rprefix->length = qprefix->prefixlen; + rprefix->prefix.addr_family = qprefix->family; + switch (qprefix->family) + { + case AF_INET: + rprefix->prefix.addr.v4 = qprefix->u.prefix4; + break; + case AF_INET6: + rprefix->prefix.addr.v6 = qprefix->u.prefix6; + break; + default: + assert (0); + } + } + + int + rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix, struct prefix *qprefix) + { + memset (qprefix, 0, sizeof (struct prefix)); + qprefix->prefixlen = rprefix->length; + qprefix->family = rprefix->prefix.addr_family; + + switch (rprefix->prefix.addr_family) + { + case AF_INET: + qprefix->u.prefix4 = rprefix->prefix.addr.v4; + break; + case AF_INET6: + qprefix->u.prefix6 = rprefix->prefix.addr.v6; + break; + default: + return EAFNOSUPPORT; + } + return 0; + } + + /* + * returns 1 if prefixes have same addr family, prefix len, and address + * Note that host bits matter in this comparison! + * + * For paralellism with quagga/lib/prefix.c. if we need a comparison + * where host bits are ignored, call that function rfapiRprefixCmp. + */ + int + rfapiRprefixSame (struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2) + { + if (hp1->prefix.addr_family != hp2->prefix.addr_family) + return 0; + if (hp1->length != hp2->length) + return 0; + if (hp1->prefix.addr_family == AF_INET) + if (IPV4_ADDR_SAME (&hp1->prefix.addr.v4, &hp2->prefix.addr.v4)) + return 1; + if (hp1->prefix.addr_family == AF_INET6) + if (IPV6_ADDR_SAME (&hp1->prefix.addr.v6, &hp2->prefix.addr.v6)) + return 1; + return 0; + } + + int + rfapiRaddr2Qprefix (struct rfapi_ip_addr *hia, struct prefix *pfx) + { + memset (pfx, 0, sizeof (struct prefix)); + pfx->family = hia->addr_family; + + switch (hia->addr_family) + { + case AF_INET: + pfx->prefixlen = 32; + pfx->u.prefix4 = hia->addr.v4; + break; + case AF_INET6: + pfx->prefixlen = 128; + pfx->u.prefix6 = hia->addr.v6; + break; + default: + return EAFNOSUPPORT; + } + return 0; + } + + void + rfapiL2o2Qprefix (struct rfapi_l2address_option *l2o, struct prefix *pfx) + { + memset (pfx, 0, sizeof (struct prefix)); + pfx->family = AF_ETHERNET; + pfx->prefixlen = 48; + pfx->u.prefix_eth = l2o->macaddr; + } + + char * + rfapiEthAddr2Str (const struct ethaddr *ea, char *buf, int bufsize) + { + int i; + char *p = buf; + + assert (bufsize > (3 * ETHER_ADDR_LEN)); + + for (i = 0; i <= ETHER_ADDR_LEN; ++i) + { + sprintf (p, "%02x", ea->octet[i]); + if (i < (ETHER_ADDR_LEN - 1)) + *(p + 2) = ':'; + p += 3; + } + return buf; + } + + int + rfapiStr2EthAddr (const char *str, struct ethaddr *ea) + { + unsigned int a[6]; + int i; + + if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x", + a + 0, a + 1, a + 2, a + 3, a + 4, a + 5) != 6) + { + + return EINVAL; + } + + for (i = 0; i < 6; ++i) + ea->octet[i] = a[i] & 0xff; + + return 0; + } + + const char * + rfapi_ntop (int af, const void *src, char *buf, socklen_t size) + { + if (af == AF_ETHERNET) + { + return rfapiEthAddr2Str ((const struct ethaddr *) src, buf, size); + } + + return inet_ntop (af, src, buf, size); + } + + int + rfapiDebugPrintf (void *dummy, const char *format, ...) + { + va_list args; + va_start (args, format); + vzlog (NULL, LOG_DEBUG, format, args); + va_end (args); + return 0; + } + + static int + rfapiStdioPrintf (void *stream, const char *format, ...) + { + FILE *file = NULL; + + va_list args; + va_start (args, format); + + switch ((uintptr_t) stream) + { + case 1: + file = stdout; + break; + case 2: + file = stderr; + break; + default: + assert (0); + } + + vfprintf (file, format, args); + va_end (args); + return 0; + } + + /* Fake out for debug logging */ + static struct vty vty_dummy_zlog; + static struct vty vty_dummy_stdio; + #define HVTY_NEWLINE ((vty == &vty_dummy_zlog)? "": VTY_NEWLINE) + + static const char * + str_vty_newline (struct vty *vty) + { + if (vty == &vty_dummy_zlog) + return ""; + return VTY_NEWLINE; + } + + int + rfapiStream2Vty ( + void *stream, /* input */ + int (**fp) (void *, const char *, ...), /* output */ + struct vty **vty, /* output */ + void **outstream, /* output */ + const char **vty_newline) /* output */ + { + + if (!stream) + { + vty_dummy_zlog.type = VTY_SHELL; /* for VTY_NEWLINE */ + *vty = &vty_dummy_zlog; + *fp = (int (*)(void *, const char *,...)) rfapiDebugPrintf; + *outstream = NULL; + *vty_newline = str_vty_newline (*vty); + return (vzlog_test (NULL, LOG_DEBUG)); + } + + if (((uintptr_t) stream == (uintptr_t) 1) || + ((uintptr_t) stream == (uintptr_t) 2)) + { + + vty_dummy_stdio.type = VTY_SHELL; /* for VTY_NEWLINE */ + *vty = &vty_dummy_stdio; + *fp = (int (*)(void *, const char *,...)) rfapiStdioPrintf; + *outstream = stream; + *vty_newline = str_vty_newline (*vty); + return 1; + } + + if (stream) + { + *vty = stream; /* VTY_NEWLINE requires vty to be legit */ + *fp = (int (*)(void *, const char *,...)) vty_out; + *outstream = stream; + *vty_newline = str_vty_newline (*vty); + return 1; + } + + return 0; + } + + /* called from bgpd/bgp_vty.c'route_vty_out() */ + void + rfapi_vty_out_vncinfo ( + struct vty *vty, + struct prefix *p, + struct bgp_info *bi, + safi_t safi) + { + char *s; + uint32_t lifetime; + + /* + * Print, on an indented line: + * UN address [if VPN route and VNC UN addr subtlv] + * EC list + * VNC lifetime + */ + vty_out (vty, " "); + + if (safi == SAFI_MPLS_VPN) + { + struct prefix pfx_un; + + if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un)) + { + char buf[BUFSIZ]; + vty_out (vty, "UN=%s", inet_ntop (pfx_un.family, + pfx_un.u.val, buf, BUFSIZ)); + } + } + + if (bi->attr && bi->attr->extra && bi->attr->extra->ecommunity) + { + s = ecommunity_ecom2str (bi->attr->extra->ecommunity, + ECOMMUNITY_FORMAT_ROUTE_MAP); + vty_out (vty, " EC{%s}", s); + XFREE (MTYPE_ECOMMUNITY_STR, s); + } + + if (bi->extra != NULL) + vty_out (vty, " label=%u", decode_label (bi->extra->tag)); + + if (rfapiGetVncLifetime (bi->attr, &lifetime)) + { + if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) + { + vty_out (vty, " life=none"); + } + } + else + { + vty_out (vty, " life=%d", lifetime); + } + + vty_out (vty, " type=%s, subtype=%d", + zebra_route_string (bi->type), bi->sub_type); + + vty_out (vty, "%s", HVTY_NEWLINE); + } + + void + rfapiPrintAttrPtrs (void *stream, struct attr *attr) + { + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + struct attr_extra *ae; + char buf[BUFSIZ]; + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + fp (out, "Attr[%p]:%s", attr, HVTY_NEWLINE); + if (!attr) + return; + + /* IPv4 Nexthop */ + inet_ntop (AF_INET, &attr->nexthop, buf, BUFSIZ); + fp (out, " nexthop=%s%s", buf, HVTY_NEWLINE); + + fp (out, " aspath=%p, refcnt=%d%s", attr->aspath, + (attr->aspath ? attr->aspath->refcnt : 0), HVTY_NEWLINE); + fp (out, " community=%p, refcnt=%d%s", attr->community, + (attr->community ? attr->community->refcnt : 0), HVTY_NEWLINE); + + if ((ae = attr->extra)) + { + fp (out, " ecommunity=%p, refcnt=%d%s", ae->ecommunity, + (ae->ecommunity ? ae->ecommunity->refcnt : 0), HVTY_NEWLINE); + fp (out, " cluster=%p, refcnt=%d%s", ae->cluster, + (ae->cluster ? ae->cluster->refcnt : 0), HVTY_NEWLINE); + fp (out, " transit=%p, refcnt=%d%s", ae->transit, + (ae->transit ? ae->transit->refcnt : 0), HVTY_NEWLINE); + } + } + + /* + * Print BI in an Import Table + */ + void + rfapiPrintBi (void *stream, struct bgp_info *bi) + { + char buf[BUFSIZ]; + char *s; + + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + char line[BUFSIZ]; + char *p = line; + int r; + int has_macaddr = 0; + struct ethaddr macaddr; + struct rfapi_l2address_option l2o_buf; + uint8_t l2hid=0; /* valid if has_macaddr */ + + #define REMAIN (BUFSIZ - (p-line)) + #define INCP {p += (r > REMAIN)? REMAIN: r;} + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + if (!bi) + return; + + if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && bi->extra + && bi->extra->vnc.import.timer) + { + struct thread *t = (struct thread *) bi->extra->vnc.import.timer; + r = snprintf (p, REMAIN, " [%4lu] ", thread_timer_remain_second (t)); + INCP; + + } + else + { + r = snprintf (p, REMAIN, " "); + INCP; + } + + if (bi->extra) + { + /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */ + if (decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH) + { + has_macaddr = 1; + memcpy (macaddr.octet, bi->extra->vnc.import.rd.val + 2, 6); + l2hid = bi->extra->vnc.import.rd.val[1]; + } + } + + /* + * Print these items: + * type/subtype + * nexthop address + * lifetime + * RFP option sizes (they are opaque values) + * extended communities (RTs) + */ + if (bi->attr && bi->attr->extra) + { + uint32_t lifetime; + int printed_1st_gol = 0; + struct bgp_attr_encap_subtlv *pEncap; + struct prefix pfx_un; + int af = BGP_MP_NEXTHOP_FAMILY (bi->attr->extra->mp_nexthop_len); + + /* Nexthop */ + if (af == AF_INET) + { + r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET, + &bi->attr->extra->mp_nexthop_global_in, + buf, BUFSIZ)); + INCP; + } + else if (af == AF_INET6) + { + r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET6, + &bi->attr->extra->mp_nexthop_global, + buf, BUFSIZ)); + INCP; + } + else + { + r = snprintf (p, REMAIN, "?"); + INCP; + } + + /* + * VNC tunnel subtlv, if present, contains UN address + */ + if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un)) + { + r = snprintf (p, REMAIN, " un=%s", inet_ntop (pfx_un.family, + pfx_un.u.val, buf, + BUFSIZ)); + INCP; + + } + + /* Lifetime */ + if (rfapiGetVncLifetime (bi->attr, &lifetime)) + { + r = snprintf (p, REMAIN, " nolife"); + INCP; + } + else + { + if (lifetime == 0xffffffff) + r = snprintf (p, REMAIN, " %6s", "infini"); + else + r = snprintf (p, REMAIN, " %6u", lifetime); + INCP; + } + + /* RFP option lengths */ + for (pEncap = bi->attr->extra->vnc_subtlvs; pEncap; + pEncap = pEncap->next) + { + + if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) + { + if (printed_1st_gol) + { + r = snprintf (p, REMAIN, ","); + INCP; + } + else + { + r = snprintf (p, REMAIN, " "); /* leading space */ + INCP; + } + r = snprintf (p, REMAIN, "%d", pEncap->length); + INCP; + printed_1st_gol = 1; + } + } + + /* RT list */ + if (bi->attr->extra->ecommunity) + { + s = ecommunity_ecom2str (bi->attr->extra->ecommunity, + ECOMMUNITY_FORMAT_ROUTE_MAP); + r = snprintf (p, REMAIN, " %s", s); + INCP; + XFREE (MTYPE_ECOMMUNITY_STR, s); + } + + } + + r = snprintf (p, REMAIN, " bi@%p", bi); + INCP; + + r = snprintf (p, REMAIN, " p@%p", bi->peer); + INCP; + + if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) + { + r = snprintf (p, REMAIN, " HD=yes"); + INCP; + } + else + { + r = snprintf (p, REMAIN, " HD=no"); + INCP; + } + + if (bi->attr) + { + + if (bi->attr->extra) + { + r = snprintf (p, REMAIN, " W=%d", bi->attr->extra->weight); + INCP; + } + + if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) + { + r = snprintf (p, REMAIN, " LP=%d", bi->attr->local_pref); + INCP; + } + else + { + r = snprintf (p, REMAIN, " LP=unset"); + INCP; + } + } + + r = + snprintf (p, REMAIN, " %c:%u", zebra_route_char (bi->type), bi->sub_type); + INCP; + + fp (out, "%s%s", line, HVTY_NEWLINE); + + if (has_macaddr) + { + fp (out, " RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s", + l2hid, + macaddr.octet[0], + macaddr.octet[1], + macaddr.octet[2], + macaddr.octet[3], macaddr.octet[4], macaddr.octet[5], HVTY_NEWLINE); + } + + if (!rfapiGetL2o (bi->attr, &l2o_buf)) + { + fp (out, + " L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s", + l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1], + l2o_buf.macaddr.octet[2], l2o_buf.macaddr.octet[3], + l2o_buf.macaddr.octet[4], l2o_buf.macaddr.octet[5], l2o_buf.label, + l2o_buf.logical_net_id, l2o_buf.local_nve_id, HVTY_NEWLINE); + } + if (bi->extra && bi->extra->vnc.import.aux_prefix.family) + { + char buf[BUFSIZ]; + const char *sp; + + sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family, + &bi->extra->vnc.import.aux_prefix.u.prefix, + buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + if (sp) + { + fp (out, " IP: %s%s", sp, HVTY_NEWLINE); + } + } + { + struct rfapi_un_option *uo = rfapi_encap_tlv_to_un_option (bi->attr); + if (uo) + { + rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel); + rfapi_un_options_free (uo); + } + } + } + + char * + rfapiMonitorVpn2Str (struct rfapi_monitor_vpn *m, char *buf, int size) + { + char buf_pfx[BUFSIZ]; + char buf_vn[BUFSIZ]; + char buf_un[BUFSIZ]; + int rc; + + rfapiRfapiIpAddr2Str (&m->rfd->un_addr, buf_vn, BUFSIZ); + rfapiRfapiIpAddr2Str (&m->rfd->vn_addr, buf_un, BUFSIZ); + + rc = snprintf (buf, size, + "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", + m, m->next, m->rfd, buf_vn, buf_un, + inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ), + m->p.prefixlen, m->node); + buf[size - 1] = 0; + if (rc >= size) + return NULL; + return buf; + } + + static void + rfapiDebugPrintMonitorVpn (void *stream, struct rfapi_monitor_vpn *m) + { + char buf[BUFSIZ]; + + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + rfapiMonitorVpn2Str (m, buf, BUFSIZ); + fp (out, " Mon %s%s", buf, HVTY_NEWLINE); + } + + static void + rfapiDebugPrintMonitorEncap (void *stream, struct rfapi_monitor_encap *m) + { + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out = NULL; + const char *vty_newline; + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + fp (out, " Mon m=%p, next=%p, node=%p, bi=%p%s", + m, m->next, m->node, m->bi, HVTY_NEWLINE); + } + + void + rfapiShowItNode (void *stream, struct route_node *rn) + { + struct bgp_info *bi; + char buf[BUFSIZ]; + + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + fp (out, "%s/%d @%p #%d%s", + rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), + rn->p.prefixlen, rn, rn->lock, HVTY_NEWLINE); + + for (bi = rn->info; bi; bi = bi->next) + { + rfapiPrintBi (stream, bi); + } + + /* doesn't show montors */ + } + + void + rfapiShowImportTable ( + void *stream, + const char *label, + struct route_table *rt, + int isvpn) + { + struct route_node *rn; + char buf[BUFSIZ]; + + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + fp (out, "Import Table [%s]%s", label, HVTY_NEWLINE); + + for (rn = route_top (rt); rn; rn = route_next (rn)) + { + struct bgp_info *bi; + + if (rn->p.family == AF_ETHERNET) + { + rfapiEthAddr2Str (&rn->p.u.prefix_eth, buf, BUFSIZ); + } + else + { + inet_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ); + } + + fp (out, "%s/%d @%p #%d%s", buf, rn->p.prefixlen, rn, rn->lock - 1, /* account for loop iterator locking */ + HVTY_NEWLINE); + + for (bi = rn->info; bi; bi = bi->next) + { + rfapiPrintBi (stream, bi); + } + + if (isvpn) + { + struct rfapi_monitor_vpn *m; + for (m = RFAPI_MONITOR_VPN (rn); m; m = m->next) + { + rfapiDebugPrintMonitorVpn (stream, m); + } + } + else + { + struct rfapi_monitor_encap *m; + for (m = RFAPI_MONITOR_ENCAP (rn); m; m = m->next) + { + rfapiDebugPrintMonitorEncap (stream, m); + } + } + } + } + + int + rfapiShowVncQueries (void *stream, struct prefix *pfx_match) + { + struct bgp *bgp; + struct rfapi *h; + struct listnode *node; + struct rfapi_descriptor *rfd; + + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + int printedheader = 0; + + int nves_total = 0; + int nves_with_queries = 0; + int nves_displayed = 0; + + int queries_total = 0; + int queries_displayed = 0; + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return CMD_WARNING; + + bgp = bgp_get_default (); /* assume 1 instance for now */ + if (!bgp) + { + vty_out (vty, "No BGP instance%s", VTY_NEWLINE); + return CMD_WARNING; + } + + h = bgp->rfapi; + if (!h) + { + vty_out (vty, "No RFAPI instance%s", VTY_NEWLINE); + return CMD_WARNING; + } + + for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) + { + + struct route_node *rn; + int printedquerier = 0; + + + ++nves_total; + + if (rfd->mon || (rfd->mon_eth && skiplist_count (rfd->mon_eth))) + { + ++nves_with_queries; + } + else + { + continue; + } + + /* + * IP Queries + */ + if (rfd->mon) + { + for (rn = route_top (rfd->mon); rn; rn = route_next (rn)) + { + struct rfapi_monitor_vpn *m; + char buf_remain[BUFSIZ]; + char buf_pfx[BUFSIZ]; + + if (!rn->info) + continue; + + m = rn->info; + + ++queries_total; + + if (pfx_match && !prefix_match (pfx_match, &rn->p) && + !prefix_match (&rn->p, pfx_match)) + continue; + + ++queries_displayed; + + if (!printedheader) + { + ++printedheader; + fp (out, "%s", VTY_NEWLINE); + fp (out, "%-15s %-15s %-15s %-10s%s", + "VN Address", "UN Address", + "Target", "Remaining", VTY_NEWLINE); + } + + if (!printedquerier) + { + char buf_vn[BUFSIZ]; + char buf_un[BUFSIZ]; + + rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ); + rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ); + + fp (out, "%-15s %-15s", buf_vn, buf_un); + printedquerier = 1; + + ++nves_displayed; + } + else + fp (out, "%-15s %-15s", "", ""); + buf_remain[0] = 0; + if (m->timer) + { + rfapiFormatSeconds (thread_timer_remain_second (m->timer), + buf_remain, BUFSIZ); + } + fp (out, " %-15s %-10s%s", + inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ), + buf_remain, VTY_NEWLINE); + } + } + + /* + * Ethernet Queries + */ + if (rfd->mon_eth && skiplist_count (rfd->mon_eth)) + { + + int rc; + void *cursor; + struct rfapi_monitor_eth *mon_eth; + + for (cursor = NULL, + rc = + skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, + &cursor); rc == 0; + rc = + skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, + &cursor)) + { + + char buf_remain[BUFSIZ]; + char buf_pfx[BUFSIZ]; + struct prefix pfx_mac; + + ++queries_total; + + zlog_debug ("%s: checking rfd=%p mon_eth=%p", __func__, rfd, + mon_eth); + + memset ((void *) &pfx_mac, 0, sizeof (struct prefix)); + pfx_mac.family = AF_ETHERNET; + pfx_mac.prefixlen = 48; + pfx_mac.u.prefix_eth = mon_eth->macaddr; + + if (pfx_match && !prefix_match (pfx_match, &pfx_mac) && + !prefix_match (&pfx_mac, pfx_match)) + continue; + + ++queries_displayed; + + if (!printedheader) + { + ++printedheader; + fp (out, "%s", VTY_NEWLINE); + fp (out, "%-15s %-15s %-17s %10s %-10s%s", + "VN Address", "UN Address", + "Target", "LNI", "Remaining", VTY_NEWLINE); + } + + if (!printedquerier) + { + char buf_vn[BUFSIZ]; + char buf_un[BUFSIZ]; + + rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ); + rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ); + + fp (out, "%-15s %-15s", buf_vn, buf_un); + printedquerier = 1; + + ++nves_displayed; + } + else + fp (out, "%-15s %-15s", "", ""); + buf_remain[0] = 0; + if (mon_eth->timer) + { + rfapiFormatSeconds (thread_timer_remain_second + (mon_eth->timer), buf_remain, BUFSIZ); + } + fp (out, " %-17s %10d %-10s%s", + rfapi_ntop (pfx_mac.family, &pfx_mac.u.prefix, buf_pfx, + BUFSIZ), mon_eth->logical_net_id, buf_remain, + VTY_NEWLINE); + } + } + } + + if (queries_total) + { + fp (out, "%s", VTY_NEWLINE); + fp (out, "Displayed %d out of %d total queries%s", + queries_displayed, queries_total, VTY_NEWLINE); + } + return CMD_SUCCESS; + } + + static int + rfapiPrintRemoteRegBi ( + struct bgp *bgp, + void *stream, + struct route_node *rn, + struct bgp_info *bi) + { + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + struct prefix pfx_un; + struct prefix pfx_vn; + uint8_t cost; + uint32_t lifetime; + bgp_encap_types tun_type; + + char buf_pfx[BUFSIZ]; + char buf_ntop[BUFSIZ]; + char buf_un[BUFSIZ]; + char buf_vn[BUFSIZ]; + char buf_lifetime[BUFSIZ]; + int nlines = 0; + + if (!stream) + return 0; /* for debug log, print into buf & call output once */ + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return 0; + + /* + * Prefix + */ + buf_pfx[0] = 0; + snprintf (buf_pfx, BUFSIZ, "%s/%d", + rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf_ntop, BUFSIZ), + rn->p.prefixlen); + buf_pfx[BUFSIZ - 1] = 0; + nlines++; + + /* + * UN addr + */ + buf_un[0] = 0; + if (!rfapiGetUnAddrOfVpnBi (bi, &pfx_un)) + { + snprintf (buf_un, BUFSIZ, "%s", + inet_ntop (pfx_un.family, &pfx_un.u.prefix, buf_ntop, + BUFSIZ)); + } + buf_un[BUFSIZ - 1] = 0; + + rfapiGetTunnelType(bi->attr,&tun_type); + /* + * VN addr + */ + buf_vn[0] = 0; + if (tun_type == BGP_ENCAP_TYPE_MPLS) + { + /* MPLS carries un in nrli next hop (same as vn for IP tunnels) */ + if (bi->extra) + { + u_int32_t l = decode_label (bi->extra->tag); + snprintf (buf_vn, BUFSIZ, "Label: %d", l); + } + else /* should never happen */ + { + snprintf (buf_vn, BUFSIZ, "Label: N/A"); + } + } + else + { + rfapiNexthop2Prefix (bi->attr, &pfx_vn); + snprintf (buf_vn, BUFSIZ, "%s", + inet_ntop (pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); + } + buf_vn[BUFSIZ - 1] = 0; + + + /* + * Cost is encoded in local_pref as (255-cost) + * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion + * back to cost. + */ + if (bi->attr) + { + uint32_t local_pref; + if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) + local_pref = bi->attr->local_pref; + else + local_pref = 0; + cost = (local_pref > 255) ? 0 : 255 - local_pref; + } + else + { + cost = 0; + } + + fp (out, "%-20s ", buf_pfx); + fp (out, "%-15s ", buf_vn); + fp (out, "%-15s ", buf_un); + fp (out, "%-4d ", cost); + + /* Lifetime */ + /* NB rfapiGetVncLifetime sets infinite value when returning !0 */ + if (rfapiGetVncLifetime (bi->attr, &lifetime) || + (lifetime == RFAPI_INFINITE_LIFETIME)) + { + + fp (out, "%-10s ", "infinite"); + } + else + { + time_t t_lifetime = lifetime; + rfapiFormatSeconds (t_lifetime, buf_lifetime, BUFSIZ); + fp (out, "%-10s ", buf_lifetime); + } + + if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && + bi->extra && bi->extra->vnc.import.timer) + { + + uint32_t remaining; + time_t age; + char buf_age[BUFSIZ]; + + struct thread *t = (struct thread *) bi->extra->vnc.import.timer; + remaining = thread_timer_remain_second (t); + + #if RFAPI_REGISTRATIONS_REPORT_AGE + /* + * Calculate when the timer started. Doing so here saves + * us a timestamp field in "struct bgp_info". + * + * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the + * original calculation. + */ + age = rfapiGetHolddownFromLifetime (lifetime, factor) - remaining; + #else /* report remaining time */ + age = remaining; + #endif + rfapiFormatSeconds (age, buf_age, BUFSIZ); + + fp (out, "%-10s ", buf_age); + + } + else if (RFAPI_LOCAL_BI (bi)) + { + + char buf_age[BUFSIZ]; + + if (bi && bi->extra && bi->extra->vnc.import.create_time) + { + rfapiFormatAge (bi->extra->vnc.import.create_time, buf_age, BUFSIZ); + } + else + { + buf_age[0] = '?'; + buf_age[1] = 0; + } + fp (out, "%-10s ", buf_age); + } + fp (out, "%s", HVTY_NEWLINE); + + if (rn->p.family == AF_ETHERNET) + { + /* + * If there is a corresponding IP address && != VN address, + * print that on the next line + */ + + if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) + { + const char *sp; + + sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family, + &bi->extra->vnc.import.aux_prefix.u.prefix, + buf_ntop, BUFSIZ); + buf_ntop[BUFSIZ - 1] = 0; + + if (sp && strcmp (buf_vn, sp) != 0) + { + fp (out, " IP: %s", sp); + if (nlines == 1) + nlines++; + } + } + } + if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra) + { + u_int32_t l = decode_label (bi->extra->tag); + if (!MPLS_LABEL_IS_NULL (l)) + { + fp (out, " Label: %d", l); + if (nlines == 1) + nlines++; + } + } + if (nlines > 1) + fp (out, "%s", HVTY_NEWLINE); + + return 1; + } + + static int + rfapiShowRemoteRegistrationsIt ( + struct bgp *bgp, + void *stream, + struct rfapi_import_table *it, + struct prefix *prefix_only, + int show_expiring, /* either/or */ + int show_local, + int show_remote, + int show_imported, /* either/or */ + uint32_t *pLni) /* AFI_ETHER only */ + { + afi_t afi; + int printed_rtlist_hdr = 0; + + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + int total = 0; + int printed = 0; + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return printed; + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) + { + + struct route_node *rn; + + if (!it->imported_vpn[afi]) + continue; + + for (rn = route_top (it->imported_vpn[afi]); rn; rn = route_next (rn)) + { + + struct bgp_info *bi; + int count_only; + + /* allow for wider or more narrow mask from user */ + if (prefix_only && + !prefix_match (prefix_only, &rn->p) && + !prefix_match (&rn->p, prefix_only)) + count_only = 1; + else + count_only = 0; + + for (bi = rn->info; bi; bi = bi->next) + { + + if (!show_local && RFAPI_LOCAL_BI (bi)) + { + + /* local route from RFP */ + continue; + } + + if (!show_remote && !RFAPI_LOCAL_BI (bi)) + { + + /* remote route */ + continue; + } + + if (show_expiring && !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) + continue; + + if (!show_expiring && CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) + continue; + + if (bi->type == ZEBRA_ROUTE_BGP_DIRECT || + bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) + { + if (!show_imported) + continue; + } + else + { + if (show_imported) + continue; + } + + total++; + if (count_only == 1) + continue; + if (!printed_rtlist_hdr) + { + const char *agetype = ""; + char *s; + const char *type = ""; + if (show_imported) + { + type = "Imported"; + } + else + { + if (show_expiring) + { + type = "Holddown"; + } + else + { + if (RFAPI_LOCAL_BI (bi)) + { + type = "Local"; + } + else + { + type = "Remote"; + } + } + } + + s = ecommunity_ecom2str (it->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP); + + if (pLni) + { + fp (out, "%s[%s] L2VPN Network 0x%x (%u) RT={%s}%s", + HVTY_NEWLINE, type, *pLni, (*pLni & 0xfff), s, + HVTY_NEWLINE); + } + else + { + fp (out, "%s[%s] Prefix RT={%s}%s", + HVTY_NEWLINE, type, s, HVTY_NEWLINE); + } + XFREE (MTYPE_ECOMMUNITY_STR, s); + + if (show_expiring) + { + #if RFAPI_REGISTRATIONS_REPORT_AGE + agetype = "Age"; + #else + agetype = "Remaining"; + #endif + } + else if (show_local) + { + agetype = "Age"; + } + + printed_rtlist_hdr = 1; + + fp (out, "%-20s %-15s %-15s %4s %-10s %-10s%s", + (pLni ? "L2 Address/IP" : "Prefix"), + "VN Address", "UN Address", "Cost", + "Lifetime", agetype, HVTY_NEWLINE); + } + printed += rfapiPrintRemoteRegBi (bgp, stream, rn, bi); + } + } + } + + if (printed > 0) + { + + const char *type = "prefixes"; + + if (show_imported) + { + type = "imported prefixes"; + } + else + { + if (show_expiring) + { + type = "prefixes in holddown"; + } + else + { + if (show_local && !show_remote) + { + type = "locally registered prefixes"; + } + else if (!show_local && show_remote) + { + type = "remotely registered prefixes"; + } + } + } + + fp (out, "Displayed %d out of %d %s%s", + printed, total, type, HVTY_NEWLINE); + } + return printed; + } + + + + /* + * rfapiShowRemoteRegistrations + * + * Similar to rfapiShowImportTable() above. This function + * is mean to produce the "remote" portion of the output + * of "show vnc registrations". + */ + int + rfapiShowRemoteRegistrations ( + void *stream, + struct prefix *prefix_only, + int show_expiring, + int show_local, + int show_remote, + int show_imported) + { + struct bgp *bgp; + struct rfapi *h; + struct rfapi_import_table *it; + int printed = 0; + + bgp = bgp_get_default (); + if (!bgp) + { + return printed; + } + + h = bgp->rfapi; + if (!h) + { + return printed; + } + + for (it = h->imports; it; it = it->next) + { + printed += + rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only, + show_expiring, show_local, + show_remote, show_imported, NULL); + } + + if (h->import_mac) + { + void *cursor = NULL; + int rc; + uintptr_t lni_as_ptr; + uint32_t lni; + uint32_t *pLni; + + for (rc = + skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, + &cursor); !rc; + rc = + skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, + &cursor)) + { + pLni = NULL; + if ((lni_as_ptr & 0xffffffff) == lni_as_ptr) + { + lni = (uint32_t) (lni_as_ptr & 0xffffffff); + pLni = &lni; + } + + printed += + rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only, + show_expiring, show_local, + show_remote, show_imported, pLni); + } + } + + return printed; + } + + /*------------------------------------------ + * rfapiRfapiIpAddr2Str + * + * UI helper: generate string from rfapi_ip_addr + * + * input: + * a IP v4/v6 address + * + * output + * buf put string here + * bufsize max space to write + * + * return value: + * NULL conversion failed + * non-NULL pointer to buf + --------------------------------------------*/ + const char * + rfapiRfapiIpAddr2Str (struct rfapi_ip_addr *a, char *buf, int bufsize) + { + const char *rc = NULL; + + switch (a->addr_family) + { + case AF_INET: + rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize); + break; + case AF_INET6: + rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize); + break; + } + return rc; + } + + void + rfapiPrintRfapiIpAddr (void *stream, struct rfapi_ip_addr *a) + { + char buf[BUFSIZ]; + const char *rc = NULL; + + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out = NULL; + const char *vty_newline; + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + rc = rfapiRfapiIpAddr2Str (a, buf, BUFSIZ); + + if (rc) + fp (out, "%s", buf); + } + + const char * + rfapiRfapiIpPrefix2Str (struct rfapi_ip_prefix *p, char *buf, int bufsize) + { + struct rfapi_ip_addr *a = &p->prefix; + const char *rc = NULL; + + switch (a->addr_family) + { + case AF_INET: + rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize); + break; + case AF_INET6: + rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize); + break; + } + + if (rc) + { + int alen = strlen (buf); + int remaining = bufsize - alen - 1; + int slen; + + if (remaining > 0) + { + slen = snprintf (buf + alen, remaining, "/%u", p->length); + if (slen < remaining) /* see man page for snprintf(3) */ + return rc; + } + } + + return NULL; + } + + void + rfapiPrintRfapiIpPrefix (void *stream, struct rfapi_ip_prefix *p) + { + char buf[BUFSIZ]; + const char *rc; + + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out = NULL; + const char *vty_newline; + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + rc = rfapiRfapiIpPrefix2Str (p, buf, BUFSIZ); + + if (rc) + fp (out, "%s:%u", buf, p->cost); + else + fp (out, "?/?:?"); + } + + void + rfapiPrintRd (struct vty *vty, struct prefix_rd *prd) + { + char buf[BUFSIZ]; + + buf[0] = 0; + prefix_rd2str (prd, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; + vty_out (vty, "%s", buf); + } + + void + rfapiPrintAdvertisedInfo ( + struct vty *vty, + struct rfapi_descriptor *rfd, + safi_t safi, + struct prefix *p) + { + afi_t afi; /* of the VN address */ + struct bgp_node *bn; + struct bgp_info *bi; + uint8_t type = ZEBRA_ROUTE_BGP; + struct bgp *bgp; + int printed = 0; + struct prefix_rd prd0; + struct prefix_rd *prd; + + /* + * Find the bgp_info in the RIB corresponding to this + * prefix and rfd + */ + + afi = family2afi (p->family); + assert (afi == AFI_IP || afi == AFI_IP6); + + bgp = bgp_get_default (); /* assume 1 instance for now */ + assert (bgp); + + if (safi == SAFI_ENCAP) + { + memset (&prd0, 0, sizeof (prd0)); + prd0.family = AF_UNSPEC; + prd0.prefixlen = 64; + prd = &prd0; + } + else + { + prd = &rfd->rd; + } + bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); + + vty_out (vty, " bn=%p%s", bn, HVTY_NEWLINE); + + for (bi = bn->info; bi; bi = bi->next) + { + if (bi->peer == rfd->peer && + bi->type == type && + bi->sub_type == BGP_ROUTE_RFP && + bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd) + { + + rfapiPrintBi (vty, bi); + printed = 1; + } + } + + if (!printed) + { + vty_out (vty, " --?--%s", HVTY_NEWLINE); + return; + } + + } + + void + rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd) + { + /* pHD un-addr vn-addr pCB cookie rd lifetime */ + /* RT export list */ + /* RT import list */ + /* list of advertised prefixes */ + /* dump import table */ + + char *s; + void *cursor; + int rc; + afi_t afi; + struct rfapi_adb *adb; + char buf[BUFSIZ]; + + vty_out (vty, "%-10p ", rfd); + rfapiPrintRfapiIpAddr (vty, &rfd->un_addr); + vty_out (vty, " "); + rfapiPrintRfapiIpAddr (vty, &rfd->vn_addr); + vty_out (vty, " %p %p ", rfd->response_cb, rfd->cookie); + rfapiPrintRd (vty, &rfd->rd); + vty_out (vty, " %d", rfd->response_lifetime); + vty_out (vty, " %s", (rfd->rfg ? rfd->rfg->name : "")); + vty_out (vty, "%s", HVTY_NEWLINE); + + vty_out (vty, " Peer %p #%d%s", rfd->peer, rfd->peer->lock, HVTY_NEWLINE); + + /* export RT list */ + if (rfd->rt_export_list) + { + s = + ecommunity_ecom2str (rfd->rt_export_list, + ECOMMUNITY_FORMAT_ROUTE_MAP); + vty_out (vty, " Export %s%s", s, HVTY_NEWLINE); + XFREE (MTYPE_ECOMMUNITY_STR, s); + } + else + { + vty_out (vty, " Export (nil)%s", HVTY_NEWLINE); + } + + /* import RT list */ + if (rfd->import_table) + { + s = ecommunity_ecom2str (rfd->import_table->rt_import_list, + ECOMMUNITY_FORMAT_ROUTE_MAP); + vty_out (vty, " Import %s%s", s, HVTY_NEWLINE); + XFREE (MTYPE_ECOMMUNITY_STR, s); + } + else + { + vty_out (vty, " Import (nil)%s", HVTY_NEWLINE); + } + + for (afi = AFI_IP; afi < AFI_MAX; ++afi) + { + u_char family; + + family = afi2family (afi); + if (!family) + continue; + + cursor = NULL; + for (rc = + skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb, + &cursor); rc == 0; + rc = + skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb, + &cursor)) + { + + /* group like family prefixes together in output */ + if (family != adb->prefix_ip.family) + continue; + + prefix2str (&adb->prefix_ip, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + + vty_out (vty, " Adv Pfx: %s%s", buf, HVTY_NEWLINE); + rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->prefix_ip); + } + } + for (rc = + skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb, + &cursor); rc == 0; + rc = + skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb, + &cursor)) + { + + prefix2str (&adb->prefix_eth, buf, BUFSIZ); + buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + + vty_out (vty, " Adv Pfx: %s%s", buf, HVTY_NEWLINE); + + /* TBD update the following function to print ethernet info */ + /* Also need to pass/use rd */ + rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->prefix_ip); + } + vty_out (vty, "%s", HVTY_NEWLINE); + } + + /* + * test scripts rely on first line for each nve starting in 1st column, + * leading whitespace for additional detail of that nve + */ + void + rfapiPrintMatchingDescriptors (struct vty *vty, + struct prefix *vn_prefix, + struct prefix *un_prefix) + { + struct bgp *bgp; + struct rfapi *h; + struct listnode *ln; + struct rfapi_descriptor *rfd; + int printed = 0; + + bgp = bgp_get_default (); /* assume 1 instance for now */ + if (!bgp) + return; + + h = bgp->rfapi; + assert (h); + + for (ln = listhead (&h->descriptors); ln; ln = listnextnode (ln)) + { + rfd = listgetdata (ln); + + struct prefix pfx; + + if (vn_prefix) + { + assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx)); + if (!prefix_match (vn_prefix, &pfx)) + continue; + } + + if (un_prefix) + { + assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx)); + if (!prefix_match (un_prefix, &pfx)) + continue; + } + + if (!printed) + { + /* print column header */ + vty_out (vty, + "%s %s %s %s %s %s %s %s%s", + "descriptor", "un-addr", "vn-addr", "callback", "cookie", + "RD", "lifetime", "group", HVTY_NEWLINE); + } + rfapiPrintDescriptor (vty, rfd); + printed = 1; + } + } + + + /* + * Parse an address and put into a struct prefix + */ + int + rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p) + { + if (!str2prefix (str, p)) + { + vty_out (vty, "Malformed address \"%s\"%s", str, HVTY_NEWLINE); + return CMD_WARNING; + } + switch (p->family) + { + case AF_INET: + if (p->prefixlen != 32) + { + vty_out (vty, "Not a host address: \"%s\"%s", str, HVTY_NEWLINE); + return CMD_WARNING; + } + break; + case AF_INET6: + if (p->prefixlen != 128) + { + vty_out (vty, "Not a host address: \"%s\"%s", str, HVTY_NEWLINE); + return CMD_WARNING; + } + break; + default: + vty_out (vty, "Invalid address \"%s\"%s", str, HVTY_NEWLINE); + return CMD_WARNING; + } + return 0; + } + + int + rfapiCliGetRfapiIpAddr ( + struct vty *vty, + const char *str, + struct rfapi_ip_addr *hai) + { + struct prefix pfx; + int rc; + + rc = rfapiCliGetPrefixAddr (vty, str, &pfx); + if (rc) + return rc; + + hai->addr_family = pfx.family; + if (pfx.family == AF_INET) + hai->addr.v4 = pfx.u.prefix4; + else + hai->addr.v6 = pfx.u.prefix6; + + return 0; + } + + /* + * Note: this function does not flush vty output, so if it is called + * with a stream pointing to a vty, the user will have to type something + * before the callback output shows up + */ + void + rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops) + { + struct rfapi_next_hop_entry *nh; + int count; + + int (*fp) (void *, const char *, ...); + struct vty *vty; + void *out; + const char *vty_newline; + + #define REMAIN (BUFSIZ - (p-line)) + #define INCP {p += (r > REMAIN)? REMAIN: r;} + + + if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) + return; + + for (nh = next_hops, count = 1; nh; nh = nh->next, ++count) + { + + char line[BUFSIZ]; + char *p = line; + int r; + + r = snprintf (p, REMAIN, "%3d pfx=", count); + INCP; + + if (rfapiRfapiIpPrefix2Str (&nh->prefix, p, REMAIN)) + { + /* it fit, so count length */ + r = strlen (p); + } + else + { + /* didn't fit */ + goto truncate; + } + INCP; + + r = snprintf (p, REMAIN, ", un="); + INCP; + + if (rfapiRfapiIpAddr2Str (&nh->un_address, p, REMAIN)) + { + /* it fit, so count length */ + r = strlen (p); + } + else + { + /* didn't fit */ + goto truncate; + } + INCP; + + r = snprintf (p, REMAIN, ", vn="); + INCP; + + if (rfapiRfapiIpAddr2Str (&nh->vn_address, p, REMAIN)) + { + /* it fit, so count length */ + r = strlen (p); + } + else + { + /* didn't fit */ + goto truncate; + } + INCP; + + truncate: + line[BUFSIZ - 1] = 0; + fp (out, "%s%s", line, HVTY_NEWLINE); + + /* + * options + */ + if (nh->vn_options) + { + struct rfapi_vn_option *vo; + char offset[] = " "; + + for (vo = nh->vn_options; vo; vo = vo->next) + { + char pbuf[100]; + + switch (vo->type) + { + case RFAPI_VN_OPTION_TYPE_L2ADDR: + rfapiEthAddr2Str (&vo->v.l2addr.macaddr, pbuf, + sizeof (pbuf)); + fp (out, "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s", + offset, pbuf, (vo->v.l2addr.label & 0x00ffffff), + (vo->v.l2addr.logical_net_id & 0x00ffffff), + vo->v.l2addr.local_nve_id, HVTY_NEWLINE); + break; + + case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP: + prefix2str (&vo->v.local_nexthop.addr, pbuf, sizeof (pbuf)); + fp (out, "%sLNH %s cost=%d%s", + offset, pbuf, vo->v.local_nexthop.cost, HVTY_NEWLINE); + break; + + default: + fp (out, "%svn option type %d (unknown)%s", + offset, vo->type, HVTY_NEWLINE); + break; + } + } + } + if (nh->un_options) + { + struct rfapi_un_option *uo; + char offset[] = " "; + + for (uo = nh->un_options; uo; uo = uo->next) + { + switch (uo->type) + { + case RFAPI_UN_OPTION_TYPE_TUNNELTYPE: + rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel); + break; + default: + fp (out, "%sUN Option type %d%s", + offset, uo->type, vty_newline); + break; + } + + } + } + } + } + + /*********************************************************************** + * STATIC ROUTES + ***********************************************************************/ + + /* + * Add another nexthop to the NHL + */ + static void + rfapiAddDeleteLocalRfpPrefix ( + struct rfapi_ip_addr *un_addr, + struct rfapi_ip_addr *vn_addr, + struct rfapi_ip_prefix *rprefix, + int is_add, + uint32_t lifetime, /* add only */ + struct rfapi_vn_option *vn_options, + struct rfapi_next_hop_entry **head, + struct rfapi_next_hop_entry **tail) + { + struct rfapi_next_hop_entry *new; + + /* + * construct NHL + */ + + new = XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_next_hop_entry)); + new->prefix = *rprefix; + new->un_address = *un_addr; + new->vn_address = *vn_addr; + + new->vn_options = vn_options; + if (is_add) + { + new->lifetime = lifetime; + } + else + { + new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; + } + + if (*tail) + (*tail)->next = new; + *tail = new; + if (!*head) + { + *head = new; + } + } + + + static int + register_add ( + struct vty *vty, + const char *arg_prefix, + const char *arg_vn, + const char *arg_un, + const char *arg_cost, /* optional */ + const char *arg_lifetime, /* optional */ + const char *arg_macaddr, /* optional */ + const char *arg_vni, /* mac present=>mandatory Virtual Network ID */ + int argc, + const char **argv) + { + struct rfapi_ip_addr vn_address; + struct rfapi_ip_addr un_address; + struct prefix pfx; + struct rfapi_ip_prefix rpfx; + uint32_t cost; + uint32_t lnh_cost; + uint32_t lifetime; + rfapi_handle rfd; + struct rfapi_vn_option optary[10]; /* XXX must be big enough */ + struct rfapi_vn_option *opt = NULL; + int opt_next = 0; + + int rc = CMD_WARNING; + char *endptr; + struct bgp *bgp; + struct rfapi *h; + struct rfapi_cfg *rfapi_cfg; + + const char *arg_lnh = NULL; + const char *arg_lnh_cost = NULL; + + bgp = bgp_get_default (); /* assume 1 instance for now */ + if (!bgp) + { + if (vty) + vty_out (vty, "BGP not configured%s", VTY_NEWLINE); + return CMD_WARNING; + } + + h = bgp->rfapi; + rfapi_cfg = bgp->rfapi_cfg; + if (!h || !rfapi_cfg) + { + if (vty) + vty_out (vty, "RFAPI not configured%s", VTY_NEWLINE); + return CMD_WARNING; + } + + for (; argc; --argc, ++argv) + { + if (!strcmp (*argv, "local-next-hop")) + { + if (arg_lnh) + { + vty_out (vty, "local-next-hop specified more than once%s", + VTY_NEWLINE); + return CMD_WARNING; + } + if (argc <= 1) + { + vty_out (vty, "Missing parameter for local-next-hop%s", + VTY_NEWLINE); + return CMD_WARNING; + } + ++argv, --argc; + arg_lnh = *argv; + } + if (!strcmp (*argv, "local-cost")) + { + if (arg_lnh_cost) + { + vty_out (vty, "local-cost specified more than once%s", + VTY_NEWLINE); + return CMD_WARNING; + } + if (argc <= 1) + { + vty_out (vty, "Missing parameter for local-cost%s", + VTY_NEWLINE); + return CMD_WARNING; + } + ++argv, --argc; + arg_lnh_cost = *argv; + } + } + + if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &vn_address))) + goto fail; + if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &un_address))) + goto fail; + + /* arg_prefix is optional if mac address is given */ + if (arg_macaddr && !arg_prefix) + { + /* + * fake up a 0/32 or 0/128 prefix + */ + switch (vn_address.addr_family) + { + case AF_INET: + arg_prefix = "0.0.0.0/32"; + break; + case AF_INET6: + arg_prefix = "0::0/128"; + break; + default: + vty_out (vty, "Internal error, unknown VN address family%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + } + + if (!str2prefix (arg_prefix, &pfx)) + { + vty_out (vty, "Malformed prefix \"%s\"%s", arg_prefix, + VTY_NEWLINE); + goto fail; + } + if (pfx.family != AF_INET + && pfx.family != AF_INET6) + { + vty_out (vty, "prefix \"%s\" has invalid address family%s", + arg_prefix, VTY_NEWLINE); + goto fail; + } + + + memset (optary, 0, sizeof (optary)); + + if (arg_cost) + { + endptr = NULL; + cost = strtoul (arg_cost, &endptr, 10); + if (*endptr != '\0' || cost > 255) + { + vty_out (vty, "%% Invalid %s value%s", "cost", VTY_NEWLINE); + goto fail; + } + } + else + { + cost = 255; + } + + if (arg_lifetime) + { + if (!strcmp (arg_lifetime, "infinite")) + { + lifetime = RFAPI_INFINITE_LIFETIME; + } + else + { + endptr = NULL; + lifetime = strtoul (arg_lifetime, &endptr, 10); + if (*endptr != '\0') + { + vty_out (vty, "%% Invalid %s value%s", "lifetime", + VTY_NEWLINE); + goto fail; + } + } + } + else + { + lifetime = RFAPI_INFINITE_LIFETIME; /* default infinite */ + } + + if (arg_lnh_cost) + { + if (!arg_lnh) + { + vty_out (vty, + "%% %s may only be specified with local-next-hop%s", + "local-cost", VTY_NEWLINE); + goto fail; + } + endptr = NULL; + lnh_cost = strtoul (arg_lnh_cost, &endptr, 10); + if (*endptr != '\0' || lnh_cost > 255) + { + vty_out (vty, "%% Invalid %s value%s", "local-cost", + VTY_NEWLINE); + goto fail; + } + } + else + { + lnh_cost = 255; + } + + if (arg_lnh) + { + if (!arg_prefix) + { + vty_out (vty, "%% %s may only be specified with prefix%s", + "local-next-hop", VTY_NEWLINE); + goto fail; + } + if ((rc = rfapiCliGetPrefixAddr (vty, arg_lnh, + &optary[opt_next].v. + local_nexthop.addr))) + { + + goto fail; + } + + optary[opt_next].v.local_nexthop.cost = lnh_cost; + optary[opt_next].type = RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP; + + if (opt_next) + { + optary[opt_next - 1].next = optary + opt_next; + } + else + { + opt = optary; + } + ++opt_next; + } + + if (arg_vni && !arg_macaddr) + { + vty_out (vty, "%% %s may only be specified with mac address%s", + "virtual-network-identifier", VTY_NEWLINE); + goto fail; + } + + if (arg_macaddr) + { + if (!arg_vni) + { + vty_out (vty, + "Missing \"vni\" parameter (mandatory with mac)%s", + VTY_NEWLINE); + return CMD_WARNING; + } + VTY_GET_INTEGER ("Logical Network ID", + optary[opt_next].v.l2addr.logical_net_id, + arg_vni); + + if ((rc = rfapiStr2EthAddr (arg_macaddr, + &optary[opt_next].v.l2addr.macaddr))) + { + vty_out (vty, "Invalid %s value%s", "mac address", + VTY_NEWLINE); + goto fail; + } + /* TBD label, NVE ID */ + + optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR; + + if (opt_next) + { + optary[opt_next - 1].next = optary + opt_next; + } + else + { + opt = optary; + } + ++opt_next; + } + + zlog_debug + ("%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s", + __func__, arg_vn, arg_un, arg_prefix, + (arg_cost ? arg_cost : "NULL"), + (arg_lifetime ? arg_lifetime : "NULL"), + (arg_lnh ? arg_lnh : "NULL")); + + rfapiQprefix2Rprefix (&pfx, &rpfx); + + rpfx.cost = cost & 255; + + /* look up rf descriptor, call open if it doesn't exist */ + rc = + rfapi_find_rfd (bgp, &vn_address, &un_address, + (struct rfapi_descriptor **) &rfd); + if (rc) + { + if (ENOENT == rc) + { + struct rfapi_un_option uo; + + /* + * flag descriptor as provisionally opened for static route + * registration so that we can fix up the other parameters + * when the real open comes along + */ + memset (&uo, 0, sizeof (uo)); + uo.type = RFAPI_UN_OPTION_TYPE_PROVISIONAL; + + rc = rfapi_open (rfapi_get_rfp_start_val_by_bgp (bgp), &vn_address, &un_address, &uo, /* flags */ + NULL, NULL, /* no userdata */ + &rfd); + if (rc) + { + vty_out (vty, "Can't open session for this NVE: %s%s", + rfapi_error_str (rc), VTY_NEWLINE); + rc = CMD_WARNING; + goto fail; + } + } + else + { + vty_out (vty, "Can't find session for this NVE: %s%s", + rfapi_error_str (rc), VTY_NEWLINE); + goto fail; + } + } + + rc = + rfapi_register (rfd, &rpfx, lifetime, NULL, opt, RFAPI_REGISTER_ADD); + if (!rc) + { + struct rfapi_next_hop_entry *head = NULL; + struct rfapi_next_hop_entry *tail = NULL; + struct rfapi_vn_option *vn_opt_new; + + zlog_debug ("%s: rfapi_register succeeded, returning 0", __func__); + + if (h->rfp_methods.local_cb) + { + struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfd; + vn_opt_new = rfapi_vn_options_dup (opt); + + rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx, + 1, lifetime, vn_opt_new, &head, + &tail); + if (head) + { + h->flags |= RFAPI_INCALLBACK; + (*h->rfp_methods.local_cb) (head, r->cookie); + h->flags &= ~RFAPI_INCALLBACK; + } + head = tail = NULL; + } + return 0; + } + + zlog_debug ("%s: rfapi_register failed", __func__); + vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, "Registration failed.%s", VTY_NEWLINE); + vty_out (vty, + "Confirm that either the VN or UN address matches a configured NVE group.%s", + VTY_NEWLINE); + return CMD_WARNING; + + fail: + zlog_debug ("%s: fail, rc=%d", __func__, rc); + return rc; + } + + /************************************************************************ + * Add prefix With .LNH_OPTIONS + ************************************************************************/ + DEFUN (add_vnc_prefix_cost_life_lnh, + add_vnc_prefix_cost_life_lnh_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> lifetime <1-4294967295> .LNH_OPTIONS", ++ "add vnc prefix vn un cost (0-255) lifetime (1-4294967295) .LNH_OPTIONS", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Administrative cost [default: 255]\n" + "Administrative cost\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], argv[3], argv[4], + /* mac vni */ + NULL, NULL, argc, argv); + } + + DEFUN (add_vnc_prefix_life_cost_lnh, + add_vnc_prefix_life_cost_lnh_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295> cost <0-255> .LNH_OPTIONS", ++ "add vnc prefix vn un lifetime (1-4294967295) cost (0-255) .LNH_OPTIONS", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n" + "Administrative cost [default: 255]\n" + "Administrative cost\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], argv[4], argv[3], + /* mac vni */ + NULL, NULL, argc, argv); + } + + DEFUN (add_vnc_prefix_cost_lnh, + add_vnc_prefix_cost_lnh_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> .LNH_OPTIONS", ++ "add vnc prefix vn un cost (0-255) .LNH_OPTIONS", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Administrative cost [default: 255]\n" + "Administrative cost\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], argv[3], NULL, + /* mac vni */ + NULL, NULL, argc, argv); + } + + DEFUN (add_vnc_prefix_life_lnh, + add_vnc_prefix_life_lnh_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295> .LNH_OPTIONS", ++ "add vnc prefix vn un lifetime (1-4294967295) .LNH_OPTIONS", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], NULL, argv[3], + /* mac vni */ + NULL, NULL, argc, argv); + } + + DEFUN (add_vnc_prefix_lnh, + add_vnc_prefix_lnh_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) .LNH_OPTIONS", ++ "add vnc prefix vn un .LNH_OPTIONS", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], NULL, NULL, + /* mac vni */ + NULL, NULL, argc, argv); + } + + /************************************************************************ + * Add prefix Without .LNH_OPTIONS + ************************************************************************/ + DEFUN (add_vnc_prefix_cost_life, + add_vnc_prefix_cost_life_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> lifetime <1-4294967295>", ++ "add vnc prefix vn un cost (0-255) lifetime (1-4294967295)", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Administrative cost [default: 255]\n" + "Administrative cost\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], argv[3], argv[4], + /* mac vni */ + NULL, NULL, 0, NULL); + } + + DEFUN (add_vnc_prefix_life_cost, + add_vnc_prefix_life_cost_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295> cost <0-255>", ++ "add vnc prefix vn un lifetime (1-4294967295) cost (0-255)", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n" + "Administrative cost [default: 255]\n" + "Administrative cost\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], argv[4], argv[3], + /* mac vni */ + NULL, NULL, 0, NULL); + } + + DEFUN (add_vnc_prefix_cost, + add_vnc_prefix_cost_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255>", ++ "add vnc prefix vn un cost (0-255)", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Administrative cost [default: 255]\n" + "Administrative cost\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], argv[3], NULL, + /* mac vni */ + NULL, NULL, 0, NULL); + } + + DEFUN (add_vnc_prefix_life, + add_vnc_prefix_life_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295>", ++ "add vnc prefix vn un lifetime (1-4294967295)", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], NULL, argv[3], + /* mac vni */ + NULL, NULL, 0, NULL); + } + + DEFUN (add_vnc_prefix, + add_vnc_prefix_cmd, - "add vnc prefix (A.B.C.D/M|X:X::X:X/M) vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X)", ++ "add vnc prefix vn un ", + "Add registration\n" + "VNC Information\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[0], argv[1], argv[2], NULL, NULL, + /* mac vni */ + NULL, NULL, 0, NULL); + } + + /************************************************************************ + * Mac address registrations + ************************************************************************/ + DEFUN (add_vnc_mac_vni_prefix_cost_life, + add_vnc_mac_vni_prefix_cost_life_cmd, - "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) cost <0-255> lifetime <1-4294967295>", ++ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn un prefix cost (0-255) lifetime (1-4294967295)", + "Add registration\n" + "VNC Information\n" + "Add/modify mac address infomation\n" + "MAC address\n" + "Virtual Network Identifier follows\n" + "Virtual Network Identifier\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "Administrative cost [default: 255]\n" + "Administrative cost\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[4], argv[2], argv[3], argv[5], argv[6], + /* mac vni */ + argv[0], argv[1], 0, NULL); + } + + + DEFUN (add_vnc_mac_vni_prefix_life, + add_vnc_mac_vni_prefix_life_cmd, - "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) lifetime <1-4294967295>", ++ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn un prefix lifetime (1-4294967295)", + "Add registration\n" + "VNC Information\n" + "Add/modify mac address infomation\n" + "MAC address\n" + "Virtual Network Identifier follows\n" + "Virtual Network Identifier\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[4], argv[2], argv[3], NULL, argv[5], + /* mac vni */ + argv[0], argv[1], 0, NULL); + } + + DEFUN (add_vnc_mac_vni_prefix_cost, + add_vnc_mac_vni_prefix_cost_cmd, - "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M) cost <0-255>", ++ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn un prefix cost (0-255)", + "Add registration\n" + "VNC Information\n" + "Add/modify mac address infomation\n" + "MAC address\n" + "Virtual Network Identifier follows\n" + "Virtual Network Identifier\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "Administrative cost [default: 255]\n" "Administrative cost\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[4], argv[2], argv[3], argv[5], NULL, + /* mac vni */ + argv[0], argv[1], 0, NULL); + } + + DEFUN (add_vnc_mac_vni_prefix, + add_vnc_mac_vni_prefix_cmd, - "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) prefix (A.B.C.D/M|X:X::X:X/M)", ++ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn un prefix ", + "Add registration\n" + "VNC Information\n" + "Add/modify mac address infomation\n" + "MAC address\n" + "Virtual Network Identifier follows\n" + "Virtual Network Identifier\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Add/modify prefix related infomation\n" + "IPv4 prefix\n" "IPv6 prefix\n") + { + /* pfx vn un cost life */ + return register_add (vty, argv[4], argv[2], argv[3], NULL, NULL, + /* mac vni */ + argv[0], argv[1], 0, NULL); + } + + DEFUN (add_vnc_mac_vni_cost_life, + add_vnc_mac_vni_cost_life_cmd, - "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255> lifetime <1-4294967295>", ++ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn un cost (0-255) lifetime (1-4294967295)", + "Add registration\n" + "VNC Information\n" + "Add/modify mac address infomation\n" + "MAC address\n" + "Virtual Network Identifier follows\n" + "Virtual Network Identifier\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Administrative cost [default: 255]\n" + "Administrative cost\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n") + { + /* pfx vn un cost life */ + return register_add (vty, NULL, argv[2], argv[3], argv[4], argv[5], + /* mac vni */ + argv[0], argv[1], 0, NULL); + } + + + DEFUN (add_vnc_mac_vni_cost, + add_vnc_mac_vni_cost_cmd, - "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) cost <0-255>", ++ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn un cost (0-255)", + "Add registration\n" + "VNC Information\n" + "Add/modify mac address infomation\n" + "MAC address\n" + "Virtual Network Identifier follows\n" + "Virtual Network Identifier\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Administrative cost [default: 255]\n" "Administrative cost\n") + { + /* pfx vn un cost life */ + return register_add (vty, NULL, argv[2], argv[3], argv[4], NULL, + /* mac vni */ + argv[0], argv[1], 0, NULL); + } + + + DEFUN (add_vnc_mac_vni_life, + add_vnc_mac_vni_life_cmd, - "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X) lifetime <1-4294967295>", ++ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn un lifetime (1-4294967295)", + "Add registration\n" + "VNC Information\n" + "Add/modify mac address infomation\n" + "MAC address\n" + "Virtual Network Identifier follows\n" + "Virtual Network Identifier\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Registration lifetime [default: infinite]\n" + "Lifetime value in seconds\n") + { + /* pfx vn un cost life */ + return register_add (vty, NULL, argv[2], argv[3], NULL, argv[4], + /* mac vni */ + argv[0], argv[1], 0, NULL); + } + + + DEFUN (add_vnc_mac_vni, + add_vnc_mac_vni_cmd, - "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier <1-4294967295> vn (A.B.C.D|X:X::X:X) un (A.B.C.D|X:X::X:X)", ++ "add vnc mac YY:YY:YY:YY:YY:YY virtual-network-identifier (1-4294967295) vn un ", + "Add registration\n" + "VNC Information\n" + "Add/modify mac address infomation\n" + "MAC address\n" + "Virtual Network Identifier follows\n" + "Virtual Network Identifier\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" "UN IPv6 interface address\n") + { + /* pfx vn un cost life */ + return register_add (vty, NULL, argv[2], argv[3], NULL, NULL, + /* mac vni */ + argv[0], argv[1], 0, NULL); + } + + /************************************************************************ + * Delete prefix + ************************************************************************/ + + struct rfapi_local_reg_delete_arg + { + /* + * match parameters + */ + struct rfapi_ip_addr un_address; /* AF==0: wildcard */ + struct rfapi_ip_addr vn_address; /* AF==0: wildcard */ + struct prefix prefix; /* AF==0: wildcard */ + + struct rfapi_l2address_option_match l2o; + + /* + * result parameters + */ + struct vty *vty; + uint32_t reg_count; + uint32_t pfx_count; + uint32_t query_count; + + uint32_t failed_pfx_count; + + uint32_t nve_count; + struct skiplist *nves; + + uint32_t remote_active_nve_count; + uint32_t remote_active_pfx_count; + uint32_t remote_holddown_nve_count; + uint32_t remote_holddown_pfx_count; + }; + + struct nve_addr + { + struct rfapi_ip_addr vn; + struct rfapi_ip_addr un; + struct rfapi_descriptor *rfd; + struct rfapi_local_reg_delete_arg *cda; + }; + + static void + nve_addr_free (void *hap) + { + ((struct nve_addr *) hap)->cda->nve_count += 1; + XFREE (MTYPE_RFAPI_NVE_ADDR, hap); + } + + static int + nve_addr_cmp (void *k1, void *k2) + { + struct nve_addr *a = (struct nve_addr *) k1; + struct nve_addr *b = (struct nve_addr *) k2; + int ret = 0; + + if (!a || !b) + { + return (a - b); + } + if (a->un.addr_family != b->un.addr_family) + { + return (a->un.addr_family - b->un.addr_family); + } + if (a->vn.addr_family != b->vn.addr_family) + { + return (a->vn.addr_family - b->vn.addr_family); + } + if (a->un.addr_family == AF_INET) + { + ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4); + if (ret != 0) + { + return ret; + } + } + else if (a->un.addr_family == AF_INET6) + { + ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6); + if (ret != 0) + { + return ret; + } + } + else + { + assert (0); + } + if (a->vn.addr_family == AF_INET) + { + ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4); + if (ret != 0) + return ret; + } + else if (a->vn.addr_family == AF_INET6) + { + ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6); + if (ret == 0) + { + return ret; + } + } + else + { + assert (0); + } + return 0; + } + + static int + parse_deleter_args ( + struct vty *vty, + const char *arg_prefix, + const char *arg_vn, + const char *arg_un, + const char *arg_l2addr, + const char *arg_vni, + struct rfapi_local_reg_delete_arg *rcdarg) + { + int rc = CMD_WARNING; + + memset (rcdarg, 0, sizeof (struct rfapi_local_reg_delete_arg)); + + if (arg_vn && strcmp (arg_vn, "*")) + { + if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &rcdarg->vn_address))) + return rc; + } + if (arg_un && strcmp (arg_un, "*")) + { + if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &rcdarg->un_address))) + return rc; + } + if (arg_prefix && strcmp (arg_prefix, "*")) + { + + if (!str2prefix (arg_prefix, &rcdarg->prefix)) + { + vty_out (vty, "Malformed prefix \"%s\"%s", arg_prefix, VTY_NEWLINE); + return rc; + } + } + + if (arg_l2addr) + { + if (!arg_vni) + { + vty_out (vty, "Missing VNI%s", VTY_NEWLINE); + return rc; + } + if (strcmp (arg_l2addr, "*")) + { + if ((rc = rfapiStr2EthAddr (arg_l2addr, &rcdarg->l2o.o.macaddr))) + { + vty_out (vty, "Malformed L2 Address \"%s\"%s", + arg_l2addr, VTY_NEWLINE); + return rc; + } + rcdarg->l2o.flags |= RFAPI_L2O_MACADDR; + } + if (strcmp (arg_vni, "*")) + { + VTY_GET_INTEGER ("Logical Network ID", + rcdarg->l2o.o.logical_net_id, arg_vni); + rcdarg->l2o.flags |= RFAPI_L2O_LNI; + } + } + return 0; + } + + static void + record_nve_in_cda_list ( + struct rfapi_local_reg_delete_arg *cda, + struct rfapi_ip_addr *un_address, + struct rfapi_ip_addr *vn_address, + struct rfapi_descriptor *rfd) + { + struct nve_addr ha; + struct nve_addr *hap; + + memset (&ha, 0, sizeof (ha)); + ha.un = *un_address; + ha.vn = *vn_address; + ha.rfd = rfd; + + if (!cda->nves) + cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free); + + if (skiplist_search (cda->nves, &ha, (void *) &hap)) + { + hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr)); + assert (hap); + ha.cda = cda; + * hap = ha; + skiplist_insert (cda->nves, hap, hap); + } + } + + static void + clear_vnc_responses (struct rfapi_local_reg_delete_arg *cda) + { + struct rfapi *h; + struct rfapi_descriptor *rfd; + int query_count = 0; + struct listnode *node; + struct bgp *bgp_default = bgp_get_default (); + + if (cda->vn_address.addr_family && cda->un_address.addr_family) + { + /* + * Single nve case + */ + if (rfapi_find_rfd + (bgp_default, &cda->vn_address, &cda->un_address, &rfd)) + return; + + rfapiRibClear (rfd); + rfapi_query_done_all (rfd, &query_count); + cda->query_count += query_count; + + /* + * Track unique nves seen + */ + record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd); + return; + } + + /* + * wildcard case + */ + + if (!bgp_default) + return; /* ENXIO */ + + h = bgp_default->rfapi; + + if (!h) + return; /* ENXIO */ + + for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) + { + /* + * match un, vn addresses of NVEs + */ + if (cda->un_address.addr_family && + rfapi_ip_addr_cmp (&cda->un_address, &rfd->un_addr)) + { + continue; + } + if (cda->vn_address.addr_family && + rfapi_ip_addr_cmp (&cda->vn_address, &rfd->vn_addr)) + { + continue; + } + + rfapiRibClear (rfd); + + rfapi_query_done_all (rfd, &query_count); + cda->query_count += query_count; + + /* + * Track unique nves seen + */ + record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd); + } + } + + /* + * TBD need to count deleted prefixes and nves? + * + * ENXIO BGP or VNC not configured + */ + static int + rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda) + { + struct rfapi_ip_addr *pUn; /* NULL = wildcard */ + struct rfapi_ip_addr *pVn; /* NULL = wildcard */ + struct prefix *pPrefix; /* NULL = wildcard */ + + struct rfapi *h; + struct listnode *node; + struct rfapi_descriptor *rfd; + struct rfapi_ip_prefix rprefix; + struct bgp *bgp_default = bgp_get_default (); + struct rfapi_next_hop_entry *head = NULL; + struct rfapi_next_hop_entry *tail = NULL; + struct rfapi_cfg *rfapi_cfg; + + #if DEBUG_L2_EXTRA + zlog_debug ("%s: entry", __func__); + #endif + + if (!bgp_default) + return ENXIO; + + pUn = (cda->un_address.addr_family ? &cda->un_address : NULL); + pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL); + pPrefix = (cda->prefix.family ? &cda->prefix : NULL); + + h = bgp_default->rfapi; + rfapi_cfg = bgp_default->rfapi_cfg; + + if (!h || !rfapi_cfg) + return ENXIO; + + if (pPrefix) + { + rfapiQprefix2Rprefix (pPrefix, &rprefix); + } + + #if DEBUG_L2_EXTRA + zlog_debug ("%s: starting descriptor loop", __func__); + #endif + + for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) + { + struct rfapi_adb *adb; + int rc; + int deleted_from_this_nve; + struct nve_addr ha; + struct nve_addr *hap; + + #if DEBUG_L2_EXTRA + zlog_debug ("%s: rfd=%p", __func__, rfd); + #endif + + /* + * match un, vn addresses of NVEs + */ + if (pUn && (rfapi_ip_addr_cmp (pUn, &rfd->un_addr))) + continue; + if (pVn && (rfapi_ip_addr_cmp (pVn, &rfd->vn_addr))) + continue; + + #if DEBUG_L2_EXTRA + zlog_debug ("%s: un, vn match", __func__); + #endif + + /* + * match prefix + */ + + deleted_from_this_nve = 0; + + { + struct skiplist *sl; + struct rfapi_ip_prefix rp; + void *cursor; + struct list *adb_delete_list; + + /* + * The advertisements are stored in a skiplist. Withdrawing + * the registration deletes the advertisement from the + * skiplist, which we can't do while iterating over that + * same skiplist using the current skiplist API. + * + * Strategy: iterate over the skiplist and build another + * list containing only the matching ADBs. Then delete + * _everything_ in that second list (which can be done + * using either skiplists or quagga linklists). + */ + adb_delete_list = list_new (); + + /* + * Advertised IP prefixes (not 0/32 or 0/128) + */ + sl = rfd->advertised.ipN_by_prefix; + + for (cursor = NULL, + rc = skiplist_next (sl, NULL, (void **) &adb, &cursor); + !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor)) + { + + if (pPrefix) + { + if (!prefix_same (pPrefix, &adb->prefix_ip)) + { + #if DEBUG_L2_EXTRA + zlog_debug ("%s: adb=%p, prefix doesn't match, skipping", + __func__, adb); + #endif + continue; + } + } + if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR)) + { + if (memcmp + (cda->l2o.o.macaddr.octet, + adb->prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN)) + { + #if DEBUG_L2_EXTRA + zlog_debug ("%s: adb=%p, macaddr doesn't match, skipping", + __func__, adb); + #endif + continue; + } + } + + if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI)) + { + if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id) + { + #if DEBUG_L2_EXTRA + zlog_debug ("%s: adb=%p, LNI doesn't match, skipping", + __func__, adb); + #endif + continue; + } + } + + #if DEBUG_L2_EXTRA + zlog_debug ("%s: ipN adding adb %p to delete list", __func__, + adb); + #endif + + listnode_add (adb_delete_list, adb); + } + + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb)) + { + + struct rfapi_vn_option vn1; + struct rfapi_vn_option vn2; + struct rfapi_vn_option *pVn; + int this_advertisement_prefix_count; + + this_advertisement_prefix_count = 1; + + rfapiQprefix2Rprefix (&adb->prefix_ip, &rp); + + /* if mac addr present in advert, make l2o vn option */ + if (adb->prefix_eth.family == AF_ETHERNET) + { + + memset (&vn1, 0, sizeof (vn1)); + memset (&vn2, 0, sizeof (vn2)); + + vn1.type = RFAPI_VN_OPTION_TYPE_L2ADDR; + vn1.v.l2addr.macaddr = adb->prefix_eth.u.prefix_eth; + + /* + * use saved RD value instead of trying to invert + * complex L2-style RD computation in rfapi_register() + */ + vn2.type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; + vn2.v.internal_rd = adb->prd; + + vn1.next = &vn2; + + pVn = &vn1; + ++this_advertisement_prefix_count; + } + else + { + pVn = NULL; + } + + #if DEBUG_L2_EXTRA + zlog_debug ("%s: ipN killing reg from adb %p ", __func__, adb); + #endif + + rc = rfapi_register (rfd, &rp, 0, NULL, pVn, RFAPI_REGISTER_KILL); + if (!rc) + { + cda->pfx_count += this_advertisement_prefix_count; + cda->reg_count += 1; + deleted_from_this_nve = 1; + } + if (h->rfp_methods.local_cb) + { + rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr, &rfd->vn_addr, + &rp, 0, 0, NULL, &head, &tail); + } + } + list_delete_all_node (adb_delete_list); + + if (!(pPrefix && !RFAPI_0_PREFIX (pPrefix))) + { + void *cursor; + + /* + * Caller didn't specify a prefix, or specified (0/32 or 0/128) + */ + + /* + * Advertised 0/32 and 0/128 (indexed by ethernet address) + */ + sl = rfd->advertised.ip0_by_ether; + + for (cursor = NULL, + rc = skiplist_next (sl, NULL, (void **) &adb, &cursor); + !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor)) + { + + if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR)) + { + if (memcmp (cda->l2o.o.macaddr.octet, + adb->prefix_eth.u.prefix_eth.octet, + ETHER_ADDR_LEN)) + { + + continue; + } + } + if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI)) + { + if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id) + { + continue; + } + } + #if DEBUG_L2_EXTRA + zlog_debug ("%s: ip0 adding adb %p to delete list", + __func__, adb); + #endif + listnode_add (adb_delete_list, adb); + } + + + for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb)) + { + + struct rfapi_vn_option vn; + + rfapiQprefix2Rprefix (&adb->prefix_ip, &rp); + + memset (&vn, 0, sizeof (vn)); + vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR; + vn.v.l2addr = adb->l2o; + + #if DEBUG_L2_EXTRA + zlog_debug ("%s: ip0 killing reg from adb %p ", + __func__, adb); + #endif + + rc = rfapi_register (rfd, &rp, 0, NULL, &vn, + RFAPI_REGISTER_KILL); + if (!rc) + { + cda->pfx_count += 1; + cda->reg_count += 1; + deleted_from_this_nve = 1; + } + if (h->rfp_methods.local_cb) + { + struct rfapi_vn_option *vn_opt_new; + + vn_opt_new = rfapi_vn_options_dup (&vn); + rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr, + &rfd->vn_addr, &rp, 0, 0, + vn_opt_new, &head, &tail); + } + } + list_delete_all_node (adb_delete_list); + } + list_delete (adb_delete_list); + } + + + if (head) + { /* should not be set if (NULL == rfapi_cfg->local_cb) */ + h->flags |= RFAPI_INCALLBACK; + (*h->rfp_methods.local_cb) (head, rfd->cookie); + h->flags &= ~RFAPI_INCALLBACK; + head = tail = NULL; + } + + if (deleted_from_this_nve) + { + /* + * track unique NVEs seen + */ + memset (&ha, 0, sizeof (ha)); + ha.un = rfd->un_addr; + ha.vn = rfd->vn_addr; + + if (!cda->nves) + cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free); + if (skiplist_search (cda->nves, &ha, (void **) &hap)) + { + hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr)); + assert (hap); + ha.cda = cda; + *hap = ha; + skiplist_insert (cda->nves, hap, hap); + } + } + } + + return 0; + } + + /* + * clear_vnc_prefix + * + * Deletes local and remote prefixes that match + */ + static void + clear_vnc_prefix (struct rfapi_local_reg_delete_arg *cda) + { + struct prefix pfx_un; + struct prefix pfx_vn; + + struct prefix *pUN = NULL; + struct prefix *pVN = NULL; + struct prefix *pPrefix = NULL; + + /* + * Delete matching remote prefixes in holddown + */ + if (cda->vn_address.addr_family) + { + if (!rfapiRaddr2Qprefix (&cda->vn_address, &pfx_vn)) + pVN = &pfx_vn; + } + if (cda->un_address.addr_family) + { + if (!rfapiRaddr2Qprefix (&cda->un_address, &pfx_un)) + pUN = &pfx_un; + } + if (cda->prefix.family) + { + pPrefix = &cda->prefix; + } + rfapiDeleteRemotePrefixes (pUN, pVN, pPrefix, + 0, 1, &cda->remote_active_pfx_count, + &cda->remote_active_nve_count, + &cda->remote_holddown_pfx_count, + &cda->remote_holddown_nve_count); + + /* + * Now do local prefixes + */ + rfapiDeleteLocalPrefixes (cda); + } + + static void + print_cleared_stats (struct rfapi_local_reg_delete_arg *cda) + { + struct vty *vty = cda->vty; /* for benefit of VTY_NEWLINE */ + + /* Our special element-deleting function counts nves */ + if (cda->nves) + { + skiplist_free (cda->nves); + cda->nves = NULL; + } + if (cda->failed_pfx_count) + vty_out (vty, "Failed to delete %d prefixes%s", + cda->failed_pfx_count, VTY_NEWLINE); + + /* left as "prefixes" even in single case for ease of machine parsing */ + vty_out (vty, + "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs%s", + cda->reg_count, cda->pfx_count, cda->query_count, cda->nve_count, + VTY_NEWLINE); + + /* + * We don't currently allow deletion of active remote prefixes from + * the command line + */ + + vty_out (vty, "[Holddown] Cleared %u prefixes from %u NVEs%s", + cda->remote_holddown_pfx_count, cda->remote_holddown_nve_count, + VTY_NEWLINE); + } + + /* + * Caller has already deleted registrations and queries for this/these + * NVEs. Now we just have to close their descriptors. + */ + static void + clear_vnc_nve_closer (struct rfapi_local_reg_delete_arg *cda) + { + struct skiplist *sl = cda->nves; /* contains affected NVEs */ + struct nve_addr *pKey; + struct nve_addr *pValue; + void *cursor = NULL; + int rc; + + if (!sl) + return; + + for (rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor); + !rc; + rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor)) + { + + if (pValue->rfd) + { + ((struct rfapi_descriptor *) pValue->rfd)->flags |= + RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY; + rfapi_close (pValue->rfd); + } + } + } + + DEFUN (clear_vnc_nve_all, + clear_vnc_nve_all_cmd, + "clear vnc nve *", + "clear\n" + "VNC Information\n" "Clear per NVE information\n" "For all NVEs\n") + { + + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = parse_deleter_args (vty, NULL, NULL, NULL, NULL, NULL, &cda))) + return rc; + + cda.vty = vty; + + clear_vnc_responses (&cda); + clear_vnc_prefix (&cda); + clear_vnc_nve_closer (&cda); + + print_cleared_stats (&cda); + + return 0; + } + + DEFUN (clear_vnc_nve_vn_un, + clear_vnc_nve_vn_un_cmd, - "clear vnc nve vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X)", ++ "clear vnc nve vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear prefix registration infomation\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" "UN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = + parse_deleter_args (vty, NULL, argv[0], argv[1], NULL, NULL, &cda))) + return rc; + + cda.vty = vty; + + clear_vnc_responses (&cda); + clear_vnc_prefix (&cda); + clear_vnc_nve_closer (&cda); + + print_cleared_stats (&cda); + + return 0; + } + + DEFUN (clear_vnc_nve_un_vn, + clear_vnc_nve_un_vn_cmd, - "clear vnc nve un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X)", ++ "clear vnc nve un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear prefix registration infomation\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" "VN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = + parse_deleter_args (vty, NULL, argv[1], argv[0], NULL, NULL, &cda))) + return rc; + + cda.vty = vty; + + clear_vnc_responses (&cda); + clear_vnc_prefix (&cda); + clear_vnc_nve_closer (&cda); + + print_cleared_stats (&cda); + + return 0; + } + + DEFUN (clear_vnc_nve_vn, + clear_vnc_nve_vn_cmd, - "clear vnc nve vn (*|A.B.C.D|X:X::X:X)", ++ "clear vnc nve vn <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear prefix registration infomation\n" + "VN address of NVE\n" + "VN IPv4 interface address\n" "VN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = parse_deleter_args (vty, NULL, argv[0], NULL, NULL, NULL, &cda))) + return rc; + + cda.vty = vty; + + clear_vnc_responses (&cda); + clear_vnc_prefix (&cda); + clear_vnc_nve_closer (&cda); + + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_nve_un, + clear_vnc_nve_un_cmd, - "clear vnc nve un (*|A.B.C.D|X:X::X:X)", ++ "clear vnc nve un <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear prefix registration infomation\n" + "UN address of NVE\n" + "UN IPv4 interface address\n" "UN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = parse_deleter_args (vty, NULL, NULL, argv[0], NULL, NULL, &cda))) + return rc; + + cda.vty = vty; + + clear_vnc_responses (&cda); + clear_vnc_prefix (&cda); + clear_vnc_nve_closer (&cda); + + print_cleared_stats (&cda); + return 0; + } + + /*------------------------------------------------- + * Clear VNC Prefix + *-------------------------------------------------*/ + + /* + * This function is defined in this file (rather than in rfp_registration.c) + * because here we have access to all the task handles. + */ + DEFUN (clear_vnc_prefix_vn_un, + clear_vnc_prefix_vn_un_cmd, - "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X)", ++ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear prefix registration infomation\n" + "All prefixes\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "VN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "All UN addresses\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = + parse_deleter_args (vty, argv[0], argv[1], argv[2], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_prefix_un_vn, + clear_vnc_prefix_un_vn_cmd, - "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X)", ++ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear prefix registration infomation\n" + "All prefixes\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "UN address of NVE\n" + "All UN addresses\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "VN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = + parse_deleter_args (vty, argv[0], argv[2], argv[1], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_prefix_un, + clear_vnc_prefix_un_cmd, - "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) un (*|A.B.C.D|X:X::X:X)", ++ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> un <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear prefix registration infomation\n" + "All prefixes\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "UN address of NVE\n" + "All UN addresses\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = + parse_deleter_args (vty, argv[0], NULL, argv[1], NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_prefix_vn, + clear_vnc_prefix_vn_cmd, - "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) vn (*|A.B.C.D|X:X::X:X)", ++ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> vn <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear prefix registration infomation\n" + "All prefixes\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "UN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = + parse_deleter_args (vty, argv[0], argv[1], NULL, NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_prefix_all, + clear_vnc_prefix_all_cmd, - "clear vnc prefix (*|A.B.C.D/M|X:X::X:X/M) *", ++ "clear vnc prefix <*|A.B.C.D/M|X:X::X:X/M> *", + "clear\n" + "VNC Information\n" + "Clear prefix registration infomation\n" + "All prefixes\n" + "IPv4 prefix\n" + "IPv6 prefix\n" + "From any NVE\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + if ((rc = parse_deleter_args (vty, argv[0], NULL, NULL, NULL, NULL, &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + /*------------------------------------------------- + * Clear VNC MAC + *-------------------------------------------------*/ + + /* + * This function is defined in this file (rather than in rfp_registration.c) + * because here we have access to all the task handles. + */ + DEFUN (clear_vnc_mac_vn_un, + clear_vnc_mac_vn_un_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X)", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "Virtual network identifier\n" + "VN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "All UN addresses\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, NULL, argv[2], argv[3], argv[0], argv[1], + &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_mac_un_vn, + clear_vnc_mac_un_vn_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X)", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "UN address of NVE\n" + "All UN addresses\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "VN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, NULL, argv[3], argv[2], argv[0], argv[1], + &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_mac_un, + clear_vnc_mac_un_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X)", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "UN address of NVE\n" + "All UN addresses\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, NULL, NULL, argv[2], argv[0], argv[1], &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_mac_vn, + clear_vnc_mac_vn_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X)", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X>", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "UN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, NULL, argv[2], NULL, argv[0], argv[1], &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_mac_all, + clear_vnc_mac_all_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) *", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> *", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "From any NVE\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, NULL, NULL, NULL, argv[0], argv[1], &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + /*------------------------------------------------- + * Clear VNC MAC PREFIX + *-------------------------------------------------*/ + + DEFUN (clear_vnc_mac_vn_un_prefix, + clear_vnc_mac_vn_un_prefix_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X) un (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M)", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "Virtual network identifier\n" + "VN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n" + "UN address of NVE\n" + "All UN addresses\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "Clear prefix registration infomation\n" + "All prefixes\n" + "IPv4 prefix\n" + "IPv6 prefix\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, argv[4], argv[2], argv[3], argv[0], argv[1], + &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_mac_un_vn_prefix, + clear_vnc_mac_un_vn_prefix_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X) vn (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M) prefix (*|A.B.C.D/M|X:X::X:X/M)", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M> prefix <*|A.B.C.D/M|X:X::X:X/M>", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "UN address of NVE\n" + "All UN addresses\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n" + "VN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, argv[4], argv[3], argv[2], argv[0], argv[1], + &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_mac_un_prefix, + clear_vnc_mac_un_prefix_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) un (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M)", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> un <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "UN address of NVE\n" + "All UN addresses\n" + "UN IPv4 interface address\n" + "UN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, argv[3], NULL, argv[2], argv[0], argv[1], + &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_mac_vn_prefix, + clear_vnc_mac_vn_prefix_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) vn (*|A.B.C.D|X:X::X:X) prefix (*|A.B.C.D/M|X:X::X:X/M)", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> vn <*|A.B.C.D|X:X::X:X> prefix <*|A.B.C.D/M|X:X::X:X/M>", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "UN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, argv[3], argv[2], NULL, argv[0], argv[1], + &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + DEFUN (clear_vnc_mac_all_prefix, + clear_vnc_mac_all_prefix_cmd, - "clear vnc mac (*|YY:YY:YY:YY:YY:YY) virtual-network-identifier (*|<1-4294967295>) prefix (*|A.B.C.D/M|X:X::X:X/M)", ++ "clear vnc mac <*|YY:YY:YY:YY:YY:YY> virtual-network-identifier <*|(1-4294967295)> prefix <*|A.B.C.D/M|X:X::X:X/M>", + "clear\n" + "VNC Information\n" + "Clear mac registration infomation\n" + "All macs\n" + "MAC address\n" + "VNI keyword\n" + "Any virtual network identifier\n" + "Virtual network identifier\n" + "UN address of NVE\n" + "All VN addresses\n" + "VN IPv4 interface address\n" + "VN IPv6 interface address\n") + { + struct rfapi_local_reg_delete_arg cda; + int rc; + + /* pfx vn un L2 VNI */ + if ((rc = + parse_deleter_args (vty, argv[2], NULL, NULL, argv[0], argv[1], &cda))) + return rc; + cda.vty = vty; + clear_vnc_prefix (&cda); + print_cleared_stats (&cda); + return 0; + } + + /************************************************************************ + * Show commands + ************************************************************************/ + + + /* copied from rfp_vty.c */ + static int + check_and_display_is_vnc_running (struct vty *vty) + { + if (!bgp_rfapi_is_vnc_configured (NULL)) + return 1; /* is running */ + + if (vty) + { + vty_out (vty, + "VNC is not configured. (There are no configured BGP VPN SAFI peers.)%s", + VTY_NEWLINE); + } + return 0; /* not running */ + } + + static int + rfapi_vty_show_nve_summary (struct vty *vty, show_nve_summary_t show_type) + { + struct bgp *bgp_default = bgp_get_default (); + struct rfapi *h; + int is_vnc_running = !bgp_rfapi_is_vnc_configured (bgp_default); + + int active_local_routes; + int active_remote_routes; + int holddown_remote_routes; + int imported_remote_routes; + + if (!bgp_default) + goto notcfg; + + h = bgp_default->rfapi; + + if (!h) + goto notcfg; + + /* don't show local info if not running RFP */ + if (is_vnc_running || show_type == SHOW_NVE_SUMMARY_REGISTERED) + { + + switch (show_type) + { + + case SHOW_NVE_SUMMARY_ACTIVE_NVES: + vty_out (vty, "%-24s ", "NVEs:"); + vty_out (vty, "%-8s %-8u ", "Active:", h->descriptors.count); + vty_out (vty, "%-8s %-8u ", "Maximum:", h->stat.max_descriptors); + vty_out (vty, "%-8s %-8u", "Unknown:", h->stat.count_unknown_nves); + break; + + case SHOW_NVE_SUMMARY_REGISTERED: + /* + * NB: With the introduction of L2 route support, we no + * longer have a one-to-one correspondence between + * locally-originated route advertisements and routes in + * the import tables that have local origin. This + * discrepancy arises because a single advertisement + * may contain both an IP prefix and a MAC address. + * Such an advertisement results in two import table + * entries: one indexed by IP prefix, the other indexed + * by MAC address. + * + * TBD: update computation and display of registration + * statistics to reflect the underlying semantics. + */ + if (is_vnc_running) + { + vty_out (vty, "%-24s ", "Registrations:"); + vty_out (vty, "%-8s %-8u ", "Active:", + rfapiApCountAll (bgp_default)); + vty_out (vty, "%-8s %-8u ", "Failed:", + h->stat.count_registrations_failed); + vty_out (vty, "%-8s %-8u", "Total:", + h->stat.count_registrations); + vty_out (vty, "%s", VTY_NEWLINE); + } + vty_out (vty, "%-24s ", "Prefixes registered:"); + vty_out (vty, "%s", VTY_NEWLINE); + + rfapiCountAllItRoutes (&active_local_routes, + &active_remote_routes, + &holddown_remote_routes, + &imported_remote_routes); + + /* local */ + if (is_vnc_running) + { + vty_out (vty, " %-20s ", "Locally:"); + vty_out (vty, "%-8s %-8u ", "Active:", active_local_routes); + vty_out (vty, "%s", VTY_NEWLINE); + } + + + vty_out (vty, " %-20s ", "Remotely:"); + vty_out (vty, "%-8s %-8u", "Active:", active_remote_routes); + vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, " %-20s ", "In Holddown:"); + vty_out (vty, "%-8s %-8u", "Active:", holddown_remote_routes); + vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, " %-20s ", "Imported:"); + vty_out (vty, "%-8s %-8u", "Active:", imported_remote_routes); + break; + + case SHOW_NVE_SUMMARY_QUERIES: + vty_out (vty, "%-24s ", "Queries:"); + vty_out (vty, "%-8s %-8u ", "Active:", rfapi_monitor_count (NULL)); + vty_out (vty, "%-8s %-8u ", "Failed:", + h->stat.count_queries_failed); + vty_out (vty, "%-8s %-8u", "Total:", h->stat.count_queries); + break; + + case SHOW_NVE_SUMMARY_RESPONSES: + rfapiRibShowResponsesSummary (vty); + + default: + break; + } + vty_out (vty, "%s", VTY_NEWLINE); + } + return 0; + + notcfg: + vty_out (vty, "VNC is not configured.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + static int + rfapi_show_nves ( + struct vty *vty, + struct prefix *vn_prefix, + struct prefix *un_prefix) + { + //struct hash *rfds; + //struct rfp_rfapi_descriptor_param param; + + struct bgp *bgp_default = bgp_get_default (); + struct rfapi *h; + struct listnode *node; + struct rfapi_descriptor *rfd; + + int total = 0; + int printed = 0; + int rc; + + if (!bgp_default) + goto notcfg; + + h = bgp_default->rfapi; + + if (!h) + goto notcfg; + + rc = rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); + if (rc) + return rc; + + for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) + { + struct prefix pfx; + char vn_addr_buf[INET6_ADDRSTRLEN] = + { + 0,}; + char un_addr_buf[INET6_ADDRSTRLEN] = + { + 0,}; + char age[10]; + + ++total; + + if (vn_prefix) + { + assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx)); + if (!prefix_match (vn_prefix, &pfx)) + continue; + } + + if (un_prefix) + { + assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx)); + if (!prefix_match (un_prefix, &pfx)) + continue; + } + + rfapiRfapiIpAddr2Str (&rfd->vn_addr, vn_addr_buf, INET6_ADDRSTRLEN); + rfapiRfapiIpAddr2Str (&rfd->un_addr, un_addr_buf, INET6_ADDRSTRLEN); + + if (!printed) + { + /* print out a header */ + vty_out (vty, " " + "Active Next Hops%s", VTY_NEWLINE); + vty_out (vty, "%-15s %-15s %-5s %-5s %-6s %-6s %s%s", + "VN Address", + "UN Address", + "Regis", "Resps", "Reach", "Remove", "Age", VTY_NEWLINE); + } + + ++printed; + + vty_out (vty, "%-15s %-15s %-5u %-5u %-6u %-6u %s%s", + vn_addr_buf, + un_addr_buf, + rfapiApCount (rfd), + rfapi_monitor_count (rfd), + rfd->stat_count_nh_reachable, + rfd->stat_count_nh_removal, + rfapiFormatAge (rfd->open_time, age, 10), VTY_NEWLINE); + } + + if (printed > 0 || vn_prefix || un_prefix) + vty_out (vty, "Displayed %d out of %d active NVEs%s", + printed, total, VTY_NEWLINE); + + return 0; + + notcfg: + vty_out (vty, "VNC is not configured.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + + DEFUN (vnc_show_summary, + vnc_show_summary_cmd, + "show vnc summary", + SHOW_STR + VNC_SHOW_STR + "Display VNC status summary\n") + { + if (!check_and_display_is_vnc_running (vty)) + return CMD_SUCCESS; + bgp_rfapi_show_summary (bgp_get_default (), vty); + vty_out (vty, "%s", VTY_NEWLINE); + rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); + rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); + rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_RESPONSES); + rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED); + return CMD_SUCCESS; + } + + DEFUN (vnc_show_nves, + vnc_show_nves_cmd, + "show vnc nves", + SHOW_STR + VNC_SHOW_STR + "List known NVEs\n") + { + rfapi_show_nves (vty, NULL, NULL); + return CMD_SUCCESS; + } + + DEFUN (vnc_show_nves_ptct, + vnc_show_nves_ptct_cmd, - "show vnc nves (vn|un) (A.B.C.D|X:X::X:X)", ++ "show vnc nves ", + SHOW_STR + VNC_SHOW_STR + "List known NVEs\n" + "VN address of NVE\n" + "UN address of NVE\n" + "IPv4 interface address\n" + "IPv6 interface address\n") + { + struct prefix pfx; + + if (!check_and_display_is_vnc_running (vty)) + return CMD_SUCCESS; + + if (!str2prefix (argv[1], &pfx)) + { + vty_out (vty, "Malformed address \"%s\"%s", argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + if (pfx.family != AF_INET && pfx.family != AF_INET6) + { + vty_out (vty, "Invalid address \"%s\"%s", argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + + if (*(argv[0]) == 'u') + { + rfapi_show_nves (vty, NULL, &pfx); + } + else + { + rfapi_show_nves (vty, &pfx, NULL); + } + + return CMD_SUCCESS; + } + + /* adapted from rfp_registration_cache_log() */ + static void + rfapi_show_registrations ( + struct vty *vty, + struct prefix *restrict_to, + int show_local, + int show_remote, + int show_holddown, + int show_imported) + { + int printed = 0; + + if (!vty) + return; + + rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED); + + if (show_local) + { + /* non-expiring, local */ + printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 1, 0, 0); + } + if (show_remote) + { + /* non-expiring, non-local */ + printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 0); + } + if (show_holddown) + { + /* expiring, including local */ + printed += rfapiShowRemoteRegistrations (vty, restrict_to, 1, 1, 1, 0); + } + if (show_imported) + { + /* non-expiring, non-local */ + printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 1); + } + if (!printed) + { + vty_out (vty, "%s", VTY_NEWLINE); + } + } + + DEFUN (vnc_show_registrations_pfx, + vnc_show_registrations_pfx_cmd, - "show vnc registrations ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])", ++ "show vnc registrations <[A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY]>", + SHOW_STR + VNC_SHOW_STR + "List active prefix registrations\n" + "Limit output to a particular prefix or address\n" + "Limit output to a particular prefix or address\n") + { + struct prefix p; + struct prefix *p_addr = NULL; + + if (argc == 1) + { + if (!str2prefix (argv[0], &p)) + { + vty_out (vty, "Invalid prefix: %s%s", argv[0], VTY_NEWLINE); + return CMD_SUCCESS; + } + else + { + p_addr = &p; + } + } + + rfapi_show_registrations (vty, p_addr, 1, 1, 1, 1); + return CMD_SUCCESS; + } + + ALIAS (vnc_show_registrations_pfx, + vnc_show_registrations_cmd, + "show vnc registrations", + SHOW_STR + VNC_SHOW_STR + "List active prefix registrations\n") + DEFUN (vnc_show_registrations_some_pfx, + vnc_show_registrations_some_pfx_cmd, + "show vnc registrations (all|holddown|imported|local|remote) ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])", + SHOW_STR + VNC_SHOW_STR + "List active prefix registrations\n" + "show all registrations\n" + "show only registrations in holddown\n" + "show only imported prefixes\n" + "show only local registrations\n" + "show only remote registrations\n" + "Limit output to a particular prefix or address\n" + "Limit output to a particular prefix or address\n") + { + struct prefix p; + struct prefix *p_addr = NULL; + + int show_local = 0; + int show_remote = 0; + int show_holddown = 0; + int show_imported = 0; + + if (argc == 2) + { + if (!str2prefix (argv[1], &p)) + { + vty_out (vty, "Invalid prefix: %s%s", argv[1], VTY_NEWLINE); + return CMD_SUCCESS; + } + else + { + p_addr = &p; + } + } + switch (*argv[0]) + { + case 'a': + show_local = 1; + show_remote = 1; + show_holddown = 1; + show_imported = 1; + break; + + case 'h': + show_holddown = 1; + break; + + case 'i': + show_imported = 1; + break; + + case 'l': + show_local = 1; + break; + + case 'r': + show_remote = 1; + break; + } + + rfapi_show_registrations (vty, p_addr, + show_local, show_remote, show_holddown, + show_imported); + return CMD_SUCCESS; + } + + ALIAS (vnc_show_registrations_some_pfx, + vnc_show_registrations_some_cmd, + "show vnc registrations (all|holddown|imported|local|remote)", + SHOW_STR + VNC_SHOW_STR + "List active prefix registrations\n" + "show all registrations\n" + "show only registrations in holddown\n" + "show only imported prefixes\n" + "show only local registrations\n" + "show only remote registrations\n") + + DEFUN (vnc_show_responses_pfx, - vnc_show_responses_pfx_cmd, - "show vnc responses ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])", ++ vnc_show_responses_pfx_cmd, ++ "show vnc responses <[A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY]>", + SHOW_STR + VNC_SHOW_STR + "List recent query responses\n" + "Limit output to a particular prefix or address\n" + "Limit output to a particular prefix or address\n") + { + struct prefix p; + struct prefix *p_addr = NULL; + + if (argc == 1) + { + if (!str2prefix (argv[0], &p)) + { + vty_out (vty, "Invalid prefix: %s%s", argv[0], VTY_NEWLINE); + return CMD_SUCCESS; + } + else + { + p_addr = &p; + } + } + rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); + + rfapiRibShowResponsesSummary (vty); + + rfapiRibShowResponses (vty, p_addr, 0); + rfapiRibShowResponses (vty, p_addr, 1); + + return CMD_SUCCESS; + } + + ALIAS (vnc_show_responses_pfx, + vnc_show_responses_cmd, + "show vnc responses", + SHOW_STR + VNC_SHOW_STR + "List recent query responses\n") + + DEFUN (vnc_show_responses_some_pfx, - vnc_show_responses_some_pfx_cmd, - "show vnc responses (active|removed) ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])", ++ vnc_show_responses_some_pfx_cmd, ++ "show vnc responses <[A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY]>", + SHOW_STR + VNC_SHOW_STR + "List recent query responses\n" + "show only active query responses\n" + "show only removed query responses\n" + "Limit output to a particular prefix or address\n" + "Limit output to a particular prefix or address\n") + { + struct prefix p; + struct prefix *p_addr = NULL; + + int show_active = 0; + int show_removed = 0; + + if (!check_and_display_is_vnc_running (vty)) + return CMD_SUCCESS; + + if (argc == 2) + { + if (!str2prefix (argv[1], &p)) + { + vty_out (vty, "Invalid prefix: %s%s", argv[1], VTY_NEWLINE); + return CMD_SUCCESS; + } + else + { + p_addr = &p; + } + } + + switch (*argv[0]) + { + case 'a': + show_active = 1; + break; + + case 'r': + show_removed = 1; + break; + } + + rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); + + rfapiRibShowResponsesSummary (vty); + + if (show_active) + rfapiRibShowResponses (vty, p_addr, 0); + if (show_removed) + rfapiRibShowResponses (vty, p_addr, 1); + + return CMD_SUCCESS; + } + + ALIAS (vnc_show_responses_some_pfx, + vnc_show_responses_some_cmd, + "show vnc responses (active|removed)", + SHOW_STR + VNC_SHOW_STR + "List recent query responses\n" + "show only active query responses\n" + "show only removed query responses\n") + + DEFUN (show_vnc_queries_pfx, + show_vnc_queries_pfx_cmd, - "show vnc queries ([A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY])", ++ "show vnc queries <[A.B.C.D/M]|[X:X::X:X/M]|[YY:YY:YY:YY:YY:YY]>", + SHOW_STR + VNC_SHOW_STR + "List active queries\n" + "Limit output to a particular IPv4 prefix or address\n" + "Limit output to a particular IPv6 prefix or address\n") + { + struct prefix pfx; + struct prefix *p = NULL; + + if (argc == 1) + { + if (!str2prefix (argv[0], &pfx)) + { + vty_out (vty, "Invalid prefix: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + p = &pfx; + } + + rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); + + return rfapiShowVncQueries (vty, p); + } + + ALIAS (show_vnc_queries_pfx, + show_vnc_queries_cmd, + "show vnc queries", + SHOW_STR + VNC_SHOW_STR + "List active queries\n") + + DEFUN (vnc_clear_counters, + vnc_clear_counters_cmd, + "clear vnc counters", + CLEAR_STR + VNC_SHOW_STR + "Reset VNC counters\n") + { + struct bgp *bgp_default = bgp_get_default (); + struct rfapi *h; + struct listnode *node; + struct rfapi_descriptor *rfd; + + if (!bgp_default) + goto notcfg; + + h = bgp_default->rfapi; + + if (!h) + goto notcfg; + + /* per-rfd */ + for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) + { + rfd->stat_count_nh_reachable = 0; + rfd->stat_count_nh_removal = 0; + } + + /* global */ + memset (&h->stat, 0, sizeof (h->stat)); + + /* + * 151122 per bug 103, set count_registrations = number active. + * Do same for queries + */ + h->stat.count_registrations = rfapiApCountAll (bgp_default); + h->stat.count_queries = rfapi_monitor_count (NULL); + + rfapiRibShowResponsesSummaryClear (); + + return CMD_SUCCESS; + + notcfg: + vty_out (vty, "VNC is not configured.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + void rfapi_vty_init () + { + install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd); + install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd); + install_element (ENABLE_NODE, &add_vnc_prefix_cost_lnh_cmd); + install_element (ENABLE_NODE, &add_vnc_prefix_life_lnh_cmd); + install_element (ENABLE_NODE, &add_vnc_prefix_lnh_cmd); + + install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_cmd); + install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_cmd); + install_element (ENABLE_NODE, &add_vnc_prefix_cost_cmd); + install_element (ENABLE_NODE, &add_vnc_prefix_life_cmd); + install_element (ENABLE_NODE, &add_vnc_prefix_cmd); + + install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_life_cmd); + install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_life_cmd); + install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_cmd); + install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cmd); + install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_life_cmd); + install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_cmd); + install_element (ENABLE_NODE, &add_vnc_mac_vni_life_cmd); + install_element (ENABLE_NODE, &add_vnc_mac_vni_cmd); + + install_element (ENABLE_NODE, &clear_vnc_nve_all_cmd); + install_element (ENABLE_NODE, &clear_vnc_nve_vn_un_cmd); + install_element (ENABLE_NODE, &clear_vnc_nve_un_vn_cmd); + install_element (ENABLE_NODE, &clear_vnc_nve_vn_cmd); + install_element (ENABLE_NODE, &clear_vnc_nve_un_cmd); + + install_element (ENABLE_NODE, &clear_vnc_prefix_vn_un_cmd); + install_element (ENABLE_NODE, &clear_vnc_prefix_un_vn_cmd); + install_element (ENABLE_NODE, &clear_vnc_prefix_un_cmd); + install_element (ENABLE_NODE, &clear_vnc_prefix_vn_cmd); + install_element (ENABLE_NODE, &clear_vnc_prefix_all_cmd); + + install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_cmd); + install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_cmd); + install_element (ENABLE_NODE, &clear_vnc_mac_un_cmd); + install_element (ENABLE_NODE, &clear_vnc_mac_vn_cmd); + install_element (ENABLE_NODE, &clear_vnc_mac_all_cmd); + + install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_prefix_cmd); + install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_prefix_cmd); + install_element (ENABLE_NODE, &clear_vnc_mac_un_prefix_cmd); + install_element (ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd); + install_element (ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd); + + install_element (ENABLE_NODE, &vnc_clear_counters_cmd); + + install_element (VIEW_NODE, &vnc_show_summary_cmd); + install_element (ENABLE_NODE, &vnc_show_summary_cmd); + install_element (VIEW_NODE, &vnc_show_nves_cmd); + install_element (ENABLE_NODE, &vnc_show_nves_cmd); + install_element (VIEW_NODE, &vnc_show_nves_ptct_cmd); + install_element (ENABLE_NODE, &vnc_show_nves_ptct_cmd); + + install_element (VIEW_NODE, &vnc_show_registrations_cmd); + install_element (ENABLE_NODE, &vnc_show_registrations_cmd); + install_element (VIEW_NODE, &vnc_show_registrations_pfx_cmd); + install_element (ENABLE_NODE, &vnc_show_registrations_pfx_cmd); + + install_element (VIEW_NODE, &vnc_show_registrations_some_cmd); + install_element (ENABLE_NODE, &vnc_show_registrations_some_cmd); + install_element (VIEW_NODE, &vnc_show_registrations_some_pfx_cmd); + install_element (ENABLE_NODE, &vnc_show_registrations_some_pfx_cmd); + + install_element (VIEW_NODE, &vnc_show_responses_cmd); + install_element (ENABLE_NODE, &vnc_show_responses_cmd); + install_element (VIEW_NODE, &vnc_show_responses_pfx_cmd); + install_element (ENABLE_NODE, &vnc_show_responses_pfx_cmd); + + install_element (VIEW_NODE, &vnc_show_responses_some_cmd); + install_element (ENABLE_NODE, &vnc_show_responses_some_cmd); + install_element (VIEW_NODE, &vnc_show_responses_some_pfx_cmd); + install_element (ENABLE_NODE, &vnc_show_responses_some_pfx_cmd); + + install_element (ENABLE_NODE, &show_vnc_queries_cmd); + install_element (VIEW_NODE, &show_vnc_queries_cmd); + install_element (ENABLE_NODE, &show_vnc_queries_pfx_cmd); + install_element (VIEW_NODE, &show_vnc_queries_pfx_cmd); + } diff --cc bgpd/rfapi/vnc_debug.c index 0000000000,eaa8c56ee9..5db6f558b8 mode 000000,100644..100644 --- a/bgpd/rfapi/vnc_debug.c +++ b/bgpd/rfapi/vnc_debug.c @@@ -1,0 -1,230 +1,230 @@@ + /* + * + * Copyright 2016, LabN Consulting, L.L.C. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + + #include "lib/zebra.h" + + #include + #include "lib/prefix.h" + #include "lib/linklist.h" + #include "lib/stream.h" + #include "lib/command.h" + #include "lib/str.h" + #include "lib/log.h" + #include "bgpd/rfapi/vnc_debug.h" + + /* + * debug state storage + */ + unsigned long conf_vnc_debug; + unsigned long term_vnc_debug; + + struct vnc_debug { + unsigned long bit; + const char *name; + }; + + struct vnc_debug vncdebug[] = + { + {VNC_DEBUG_RFAPI_QUERY, "rfapi-query"}, + {VNC_DEBUG_IMPORT_BI_ATTACH, "import-bi-attach"}, + {VNC_DEBUG_IMPORT_DEL_REMOTE, "import-del-remote"}, + {VNC_DEBUG_EXPORT_BGP_GETCE, "export-bgp-getce"}, + {VNC_DEBUG_EXPORT_BGP_DIRECT_ADD, "export-bgp-direct-add"}, + {VNC_DEBUG_IMPORT_BGP_ADD_ROUTE, "import-bgp-add-route"}, + }; + + #define VNC_STR "VNC information\n" + + /*********************************************************************** + * debug bgp vnc + ***********************************************************************/ + DEFUN (debug_bgp_vnc, + debug_bgp_vnc_cmd, - "debug bgp vnc (rfapi-query|import-bi-attach|import-del-remote)", ++ "debug bgp vnc ", + DEBUG_STR + BGP_STR + VNC_STR + "rfapi query handling\n" + "import BI atachment\n" + "import delete remote routes\n") + { + size_t i; + + for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) + { + if (!strcmp(argv[0], vncdebug[i].name)) + { + if (vty->node == CONFIG_NODE) + { + conf_vnc_debug |= vncdebug[i].bit; + term_vnc_debug |= vncdebug[i].bit; + } + else + { + term_vnc_debug |= vncdebug[i].bit; + vty_out (vty, "BGP vnc %s debugging is on%s", + vncdebug[i].name, VTY_NEWLINE); + } + return CMD_SUCCESS; + } + } + vty_out (vty, "Unknown debug flag: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + DEFUN (no_debug_bgp_vnc, + no_debug_bgp_vnc_cmd, - "no debug bgp vnc (rfapi-query|import-bi-attach|import-del-remote)", ++ "no debug bgp vnc ", + NO_STR + DEBUG_STR + BGP_STR + VNC_STR + "rfapi query handling\n" + "import BI atachment\n" + "import delete remote routes\n") + { + size_t i; + + for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) + { + if (!strcmp(argv[0], vncdebug[i].name)) + { + if (vty->node == CONFIG_NODE) + { + conf_vnc_debug &= ~vncdebug[i].bit; + term_vnc_debug &= ~vncdebug[i].bit; + } + else + { + term_vnc_debug &= ~vncdebug[i].bit; + vty_out (vty, "BGP vnc %s debugging is off%s", + vncdebug[i].name, VTY_NEWLINE); + } + return CMD_SUCCESS; + } + } + vty_out (vty, "Unknown debug flag: %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + ALIAS (no_debug_bgp_vnc, + undebug_bgp_vnc_cmd, + "undebug bgp vnc (rfapi-query|import-bi-attach|import-del-remote)", + UNDEBUG_STR + BGP_STR + VNC_STR + "rfapi query handling\n" + "import BI atachment\n" + "import delete remote routes\n") + + + /*********************************************************************** + * no debug bgp vnc all + ***********************************************************************/ + + DEFUN (no_debug_bgp_vnc_all, + no_debug_bgp_vnc_all_cmd, + "no debug all bgp vnc", + NO_STR + DEBUG_STR + "Disable all VNC debugging\n" + BGP_STR + VNC_STR) + { + term_vnc_debug = 0; + vty_out (vty, "All possible VNC debugging has been turned off%s", VTY_NEWLINE); + + return CMD_SUCCESS; + } + + ALIAS (no_debug_bgp_vnc_all, + undebug_bgp_vnc_all_cmd, + "undebug all bgp vnc", + UNDEBUG_STR + "Disable all VNC debugging\n" + BGP_STR + VNC_STR) + + /*********************************************************************** + * show/save + ***********************************************************************/ + + DEFUN (show_debugging_bgp_vnc, + show_debugging_bgp_vnc_cmd, + "show debugging bgp vnc", + SHOW_STR + DEBUG_STR + BGP_STR + VNC_STR) + { + size_t i; + + vty_out (vty, "BGP VNC debugging status:%s", VTY_NEWLINE); + + for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) + { + if (term_vnc_debug & vncdebug[i].bit) + { + vty_out (vty, " BGP VNC %s debugging is on%s", + vncdebug[i].name, VTY_NEWLINE); + } + } + vty_out (vty, "%s", VTY_NEWLINE); + return CMD_SUCCESS; + } + + static int + bgp_vnc_config_write_debug (struct vty *vty) + { + int write = 0; + size_t i; + + for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) + { + if (conf_vnc_debug & vncdebug[i].bit) + { + vty_out (vty, "debug bgp vnc %s%s", vncdebug[i].name, VTY_NEWLINE); + write++; + } + } + return write; + } + + static struct cmd_node debug_node = + { + DEBUG_VNC_NODE, + "", + 1 + }; + + void + vnc_debug_init (void) + { + install_node (&debug_node, bgp_vnc_config_write_debug); + install_element (ENABLE_NODE, &show_debugging_bgp_vnc_cmd); + + install_element (ENABLE_NODE, &debug_bgp_vnc_cmd); + install_element (CONFIG_NODE, &debug_bgp_vnc_cmd); + install_element (ENABLE_NODE, &no_debug_bgp_vnc_cmd); + install_element (ENABLE_NODE, &undebug_bgp_vnc_cmd); + + install_element (ENABLE_NODE, &no_debug_bgp_vnc_all_cmd); + install_element (ENABLE_NODE, &undebug_bgp_vnc_all_cmd); + } diff --cc isisd/isis_redist.c index 384eb3572b,21daaa7794..045c7daa32 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@@ -551,11 -553,7 +552,11 @@@ DEFUN (isis_redistribute "Route map reference\n" "Pointer to route-map entries\n") { + int idx_afi = 1; + int idx_protocol = 2; + int idx_level = 3; + int idx_metric_rmap = 4; - struct isis_area *area = vty->index; + VTY_DECLVAR_CONTEXT (isis_area, area); int family; int afi; int type; @@@ -618,10 -619,7 +619,10 @@@ DEFUN (no_isis_redistribute "Redistribute into level-1\n" "Redistribute into level-2\n") { + int idx_afi = 2; + int idx_protocol = 3; + int idx_level = 4; - struct isis_area *area = vty->index; + VTY_DECLVAR_CONTEXT (isis_area, area); int type; int level; int family; @@@ -660,17 -667,17 +661,17 @@@ DEFUN (isis_default_originate "Route map reference\n" "Pointer to route-map entries\n") { + int idx_afi = 2; + int idx_level = 3; + int idx_metric_rmap = 4; - struct isis_area *area = vty->index; + VTY_DECLVAR_CONTEXT (isis_area, area); int family; - int originate_type; + int originate_type = DEFAULT_ORIGINATE; int level; - unsigned long metric; - const char *routemap; - - if (argc < 5) - return CMD_WARNING; + unsigned long metric = 0xffffffff; + const char *routemap = NULL; - family = str2family(argv[0]); + family = str2family(argv[idx_afi]->text); if (family < 0) return CMD_WARNING; @@@ -713,10 -734,7 +714,9 @@@ DEFUN (no_isis_default_originate "Distribute default route into level-1\n" "Distribute default route into level-2\n") { + int idx_afi = 3; + int idx_level = 4; - struct isis_area *area = vty->index; - + VTY_DECLVAR_CONTEXT (isis_area, area); int family; int level; diff --cc isisd/isis_vty.c index 7fe65e6ca7,12ef682c17..492572bddf --- a/isisd/isis_vty.c +++ b/isisd/isis_vty.c @@@ -61,17 -60,12 +60,14 @@@ DEFUN (ip_router_isis "IS-IS Routing for IP\n" "Routing process tag\n") { + int idx_afi = 0; + int idx_word = 3; - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); struct isis_circuit *circuit; struct isis_area *area; - const char *af = argv[0]; - const char *area_tag = argv[1]; + const char *af = argv[idx_afi]->arg; + const char *area_tag = argv[idx_word]->arg; - ifp = (struct interface *) vty->index; - assert (ifp); - /* Prevent more than one area per circuit */ circuit = circuit_scan_by_ifp (ifp); if (circuit && circuit->area) @@@ -128,21 -111,12 +124,14 @@@ DEFUN (no_ip_router_isis "IS-IS Routing for IP\n" "Routing process tag\n") { + int idx_afi = 1; + int idx_word = 4; - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); struct isis_area *area; struct isis_circuit *circuit; - const char *af = argv[0]; - const char *area_tag = argv[1]; + const char *af = argv[idx_afi]->arg; + const char *area_tag = argv[idx_word]->arg; - ifp = (struct interface *) vty->index; - if (!ifp) - { - vty_out (vty, "Invalid interface %s", VTY_NEWLINE); - return CMD_ERR_NO_MATCH; - } - area = isis_area_lookup (area_tag); if (!area) { @@@ -1326,13 -1393,10 +1315,11 @@@ DEFUN (metric_style "Send and accept both styles of TLVs during transition\n" "Use new style of TLVs to carry wider metric\n") { + int idx_metric_style = 1; - struct isis_area *area = vty->index; + VTY_DECLVAR_CONTEXT (isis_area, area); int ret; - assert(area); - - if (strncmp (argv[0], "w", 1) == 0) + if (strncmp (argv[idx_metric_style]->arg, "w", 1) == 0) { isis_area_metricstyle_set(area, false, true); return CMD_SUCCESS; @@@ -1510,19 -1564,10 +1484,11 @@@ DEFUN (is_type "Act as both a station router and an area router\n" "Act as an area router only\n") { + int idx_level = 1; - struct isis_area *area; + VTY_DECLVAR_CONTEXT (isis_area, area); int type; - area = vty->index; - - if (!area) - { - vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE); - return CMD_ERR_NO_MATCH; - } - - type = string2circuit_t (argv[0]); + type = string2circuit_t (argv[idx_level]->arg); if (!type) { vty_out (vty, "Unknown IS level %s", VTY_NEWLINE); @@@ -1600,25 -1642,22 +1563,24 @@@ DEFUN (lsp_gen_interval "Minimum interval between regenerating same LSP\n" "Minimum interval in seconds\n") { + int idx_number = 1; - struct isis_area *area; + VTY_DECLVAR_CONTEXT (isis_area, area); uint16_t interval; int level; - area = vty->index; - interval = atoi (argv[0]); + interval = atoi (argv[idx_number]->arg); level = IS_LEVEL_1 | IS_LEVEL_2; return set_lsp_gen_interval (vty, area, interval, level); } DEFUN (no_lsp_gen_interval, no_lsp_gen_interval_cmd, - "no lsp-gen-interval", + "no lsp-gen-interval [(1-120)]", NO_STR - "Minimum interval between regenerating same LSP\n") + "Minimum interval between regenerating same LSP\n" + "Minimum interval in seconds\n") { - struct isis_area *area; + VTY_DECLVAR_CONTEXT (isis_area, area); uint16_t interval; int level; @@@ -1636,13 -1680,11 +1597,12 @@@ DEFUN (lsp_gen_interval_l1 "Set interval for level 1 only\n" "Minimum interval in seconds\n") { + int idx_number = 2; - struct isis_area *area; + VTY_DECLVAR_CONTEXT (isis_area, area); uint16_t interval; int level; - area = vty->index; - interval = atoi (argv[0]); + interval = atoi (argv[idx_number]->arg); level = IS_LEVEL_1; return set_lsp_gen_interval (vty, area, interval, level); } @@@ -1672,26 -1720,23 +1631,25 @@@ DEFUN (lsp_gen_interval_l2 "Set interval for level 2 only\n" "Minimum interval in seconds\n") { + VTY_DECLVAR_CONTEXT (isis_area, area); + int idx_number = 2; - struct isis_area *area; uint16_t interval; int level; - area = vty->index; - interval = atoi (argv[0]); + interval = atoi (argv[idx_number]->arg); level = IS_LEVEL_2; return set_lsp_gen_interval (vty, area, interval, level); } DEFUN (no_lsp_gen_interval_l2, no_lsp_gen_interval_l2_cmd, - "no lsp-gen-interval level-2", + "no lsp-gen-interval level-2 [(1-120)]", NO_STR "Minimum interval between regenerating same LSP\n" - "Set interval for level 2 only\n") + "Set interval for level 2 only\n" + "Minimum interval in seconds\n") { - struct isis_area *area; + VTY_DECLVAR_CONTEXT (isis_area, area); uint16_t interval; int level; @@@ -1708,31 -1759,23 +1665,28 @@@ DEFUN (spf_interval "Minimum interval between SPF calculations\n" "Minimum interval between consecutive SPFs in seconds\n") { + int idx_number = 1; - struct isis_area *area; + VTY_DECLVAR_CONTEXT (isis_area, area); u_int16_t interval; - area = vty->index; - interval = atoi (argv[0]); + interval = atoi (argv[idx_number]->arg); area->min_spf_interval[0] = interval; area->min_spf_interval[1] = interval; return CMD_SUCCESS; } + DEFUN (no_spf_interval, no_spf_interval_cmd, - "no spf-interval", + "no spf-interval [[] (1-120)]", NO_STR - "Minimum interval between SPF calculations\n") + "Minimum interval between SPF calculations\n" + "Set interval for level 1 only\n" + "Set interval for level 2 only\n" + "Minimum interval between consecutive SPFs in seconds\n") { - struct isis_area *area; - - area = vty->index; + VTY_DECLVAR_CONTEXT (isis_area, area); area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; @@@ -1748,12 -1797,10 +1702,11 @@@ DEFUN (spf_interval_l1 "Set interval for level 1 only\n" "Minimum interval between consecutive SPFs in seconds\n") { + int idx_number = 2; - struct isis_area *area; + VTY_DECLVAR_CONTEXT (isis_area, area); u_int16_t interval; - area = vty->index; - interval = atoi (argv[0]); + interval = atoi (argv[idx_number]->arg); area->min_spf_interval[0] = interval; return CMD_SUCCESS; @@@ -1783,12 -1835,10 +1734,11 @@@ DEFUN (spf_interval_l2 "Set interval for level 2 only\n" "Minimum interval between consecutive SPFs in seconds\n") { + int idx_number = 2; - struct isis_area *area; + VTY_DECLVAR_CONTEXT (isis_area, area); u_int16_t interval; - area = vty->index; - interval = atoi (argv[0]); + interval = atoi (argv[idx_number]->arg); area->min_spf_interval[1] = interval; return CMD_SUCCESS; @@@ -2157,15 -2197,8 +2087,9 @@@ DEFUN (no_area_passwd "Configure the authentication password for an area\n" "Set the authentication password for a routing domain\n") { + int idx_password = 1; + int level = strmatch (argv[idx_password]->text, "domain-password") ? IS_LEVEL_2 : IS_LEVEL_1; - struct isis_area *area = vty->index; - - if (!area) - { - vty_out (vty, "Can't find IS-IS instance%s", VTY_NEWLINE); - return CMD_ERR_NO_MATCH; - } + VTY_DECLVAR_CONTEXT (isis_area, area); - int level = (argv[0][0] == 'd') ? IS_LEVEL_2 : IS_LEVEL_1; return isis_area_passwd_unset (area, level); } diff --cc isisd/isisd.c index ffe17b3643,d6ce627b93..143e380016 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@@ -1976,15 -1963,11 +1972,12 @@@ DEFUN (topology_baseis "A Network IS Base for this topology\n" "XXXX.XXXX.XXXX Network entity title (NET)\n") { + int idx_word = 2; - struct isis_area *area; u_char buff[ISIS_SYS_ID_LEN]; - - area = vty->index; - assert (area); + VTY_DECLVAR_CONTEXT (isis_area, area); - if (sysid2buff (buff, argv[0])) - sysid2buff (area->topology_baseis, argv[0]); + if (sysid2buff (buff, argv[idx_word]->arg)) + sysid2buff (area->topology_baseis, argv[idx_word]->arg); return CMD_SUCCESS; } @@@ -2014,14 -2000,10 +2004,11 @@@ DEFUN (topology_basedynh "Dynamic hostname base for this topology\n" "Dynamic hostname base\n") { + int idx_word = 2; - struct isis_area *area; - - area = vty->index; - assert (area); + VTY_DECLVAR_CONTEXT (isis_area, area); /* I hope that it's enough. */ - area->topology_basedynh = strndup (argv[0], 16); + area->topology_basedynh = strndup (argv[idx_word]->arg, 16); return CMD_SUCCESS; } @@@ -2424,7 -2388,7 +2393,6 @@@ isis_init ( install_element (ISIS_NODE, &topology_baseis_cmd); install_element (ISIS_NODE, &topology_basedynh_cmd); install_element (ISIS_NODE, &no_topology_baseis_cmd); - install_element (ISIS_NODE, &no_topology_baseis_noid_cmd); install_element (VIEW_NODE, &show_isis_generated_topology_cmd); - install_element (ENABLE_NODE, &show_isis_generated_topology_cmd); #endif /* TOPOLOGY_GENERATE */ } diff --cc ldpd/ldp_vty_cmds.c index 0000000000,b55c7fc8a9..64715999f2 mode 000000,100644..100644 --- a/ldpd/ldp_vty_cmds.c +++ b/ldpd/ldp_vty_cmds.c @@@ -1,0 -1,1726 +1,1726 @@@ + /* Auto-generated from ldp_vty.xml. */ + /* Do not edit! */ + + #include + + #include "command.h" + #include "vty.h" + #include "ldp_vty.h" + + DEFUN (ldp_mpls_ldp, + ldp_mpls_ldp_cmd, + "mpls ldp", + "Global MPLS configuration subcommands\n" + "Label Distribution Protocol\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_mpls_ldp (vty, args); + } + + DEFUN (ldp_l2vpn_word_type_vpls, + ldp_l2vpn_word_type_vpls_cmd, + "l2vpn WORD type vpls", + "Configure l2vpn commands\n" + "L2VPN name\n" + "L2VPN type\n" + "Virtual Private LAN Service\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "name", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn (vty, args); + } + + DEFUN (ldp_no_mpls_ldp, + ldp_no_mpls_ldp_cmd, + "no mpls ldp", + "Negate a command or set its defaults\n" + "Global MPLS configuration subcommands\n" + "Label Distribution Protocol\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + NULL + }; + return ldp_vty_mpls_ldp (vty, args); + } + + DEFUN (ldp_no_l2vpn_word_type_vpls, + ldp_no_l2vpn_word_type_vpls_cmd, + "no l2vpn WORD type vpls", + "Negate a command or set its defaults\n" + "Configure l2vpn commands\n" + "L2VPN name\n" + "L2VPN type\n" + "Virtual Private LAN Service\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "name", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn (vty, args); + } + + DEFUN (ldp_address_family_ipv4, + ldp_address_family_ipv4_cmd, + "address-family ipv4", + "Configure Address Family and its parameters\n" + "IPv4\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "address-family", .value = "ipv4" }, + NULL + }; + return ldp_vty_address_family (vty, args); + } + + DEFUN (ldp_address_family_ipv6, + ldp_address_family_ipv6_cmd, + "address-family ipv6", + "Configure Address Family and its parameters\n" + "IPv6\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "address-family", .value = "ipv6" }, + NULL + }; + return ldp_vty_address_family (vty, args); + } + + DEFUN (ldp_discovery_hello_holdtime_disc_time, + ldp_discovery_hello_holdtime_disc_time_cmd, - "discovery hello holdtime <1-65535>", ++ "discovery hello holdtime (1-65535)", + "Configure discovery parameters\n" + "LDP Link Hellos\n" + "Hello holdtime\n" + "Time (seconds) - 65535 implies infinite\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "hello_type", .value = "hello" }, + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_disc_holdtime (vty, args); + } + + DEFUN (ldp_discovery_hello_interval_disc_time, + ldp_discovery_hello_interval_disc_time_cmd, - "discovery hello interval <1-65535>", ++ "discovery hello interval (1-65535)", + "Configure discovery parameters\n" + "LDP Link Hellos\n" + "Hello interval\n" + "Time (seconds)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "hello_type", .value = "hello" }, + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_disc_interval (vty, args); + } + + DEFUN (ldp_discovery_targeted_hello_holdtime_disc_time, + ldp_discovery_targeted_hello_holdtime_disc_time_cmd, - "discovery targeted-hello holdtime <1-65535>", ++ "discovery targeted-hello holdtime (1-65535)", + "Configure discovery parameters\n" + "LDP Targeted Hellos\n" + "Targeted hello holdtime\n" + "Time (seconds) - 65535 implies infinite\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" }, + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_disc_holdtime (vty, args); + } + + DEFUN (ldp_discovery_targeted_hello_interval_disc_time, + ldp_discovery_targeted_hello_interval_disc_time_cmd, - "discovery targeted-hello interval <1-65535>", ++ "discovery targeted-hello interval (1-65535)", + "Configure discovery parameters\n" + "LDP Targeted Hellos\n" + "Targeted hello interval\n" + "Time (seconds)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" }, + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_disc_interval (vty, args); + } + + DEFUN (ldp_dual_stack_transport_connection_prefer_ipv4, + ldp_dual_stack_transport_connection_prefer_ipv4_cmd, + "dual-stack transport-connection prefer ipv4", + "Configure dual stack parameters\n" + "Configure TCP transport parameters\n" + "Configure prefered address family for TCP transport connection with neighbor\n" + "IPv4\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_trans_pref_ipv4 (vty, args); + } + + DEFUN (ldp_dual_stack_cisco_interop, + ldp_dual_stack_cisco_interop_cmd, + "dual-stack cisco-interop", + "Configure dual stack parameters\n" + "Use Cisco non-compliant format to send and interpret the Dual-Stack capability TLV\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_ds_cisco_interop (vty, args); + } + + DEFUN (ldp_neighbor_ipv4_password_word, + ldp_neighbor_ipv4_password_word_cmd, + "neighbor A.B.C.D password WORD", + "Configure neighbor parameters\n" + "LDP Id of neighbor\n" + "Configure password for MD5 authentication\n" + "The password\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "lsr_id", .value = argv[0] }, + &(struct vty_arg) { .name = "password", .value = argv[1] }, + NULL + }; + return ldp_vty_neighbor_password (vty, args); + } + + DEFUN (ldp_neighbor_ipv4_session_holdtime_session_time, + ldp_neighbor_ipv4_session_holdtime_session_time_cmd, - "neighbor A.B.C.D session holdtime <15-65535>", ++ "neighbor A.B.C.D session holdtime (15-65535)", + "Configure neighbor parameters\n" + "LDP Id of neighbor\n" + "Configure session parameters\n" + "Configure session holdtime\n" + "Time (seconds)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "lsr_id", .value = argv[0] }, + &(struct vty_arg) { .name = "seconds", .value = argv[1] }, + NULL + }; + return ldp_vty_session_holdtime (vty, args); + } + + DEFUN (ldp_neighbor_ipv4_ttl_security_disable, + ldp_neighbor_ipv4_ttl_security_disable_cmd, + "neighbor A.B.C.D ttl-security disable", + "Configure neighbor parameters\n" + "LDP Id of neighbor\n" + "LDP ttl security check\n" + "Disable ttl security\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "lsr_id", .value = argv[0] }, + NULL + }; + return ldp_vty_neighbor_ttl_security (vty, args); + } + + DEFUN (ldp_neighbor_ipv4_ttl_security_hops_hops, + ldp_neighbor_ipv4_ttl_security_hops_hops_cmd, - "neighbor A.B.C.D ttl-security hops <1-254>", ++ "neighbor A.B.C.D ttl-security hops (1-254)", + "Configure neighbor parameters\n" + "LDP Id of neighbor\n" + "LDP ttl security check\n" + "IP hops\n" + "maximum number of hops\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "lsr_id", .value = argv[0] }, + &(struct vty_arg) { .name = "hops", .value = argv[1] }, + NULL + }; + return ldp_vty_neighbor_ttl_security (vty, args); + } + + DEFUN (ldp_router_id_ipv4, + ldp_router_id_ipv4_cmd, + "router-id A.B.C.D", + "Configure router Id\n" + "LSR Id (in form of an IPv4 address)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_router_id (vty, args); + } + + DEFUN (ldp_no_address_family_ipv4, + ldp_no_address_family_ipv4_cmd, + "no address-family ipv4", + "Negate a command or set its defaults\n" + "Configure Address Family and its parameters\n" + "IPv4\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "address-family", .value = "ipv4" }, + NULL + }; + return ldp_vty_address_family (vty, args); + } + + DEFUN (ldp_no_address_family_ipv6, + ldp_no_address_family_ipv6_cmd, + "no address-family ipv6", + "Negate a command or set its defaults\n" + "Configure Address Family and its parameters\n" + "IPv6\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "address-family", .value = "ipv6" }, + NULL + }; + return ldp_vty_address_family (vty, args); + } + + DEFUN (ldp_no_discovery_hello_holdtime_disc_time, + ldp_no_discovery_hello_holdtime_disc_time_cmd, - "no discovery hello holdtime <1-65535>", ++ "no discovery hello holdtime (1-65535)", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "LDP Link Hellos\n" + "Hello holdtime\n" + "Time (seconds) - 65535 implies infinite\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "hello_type", .value = "hello" }, + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_disc_holdtime (vty, args); + } + + DEFUN (ldp_no_discovery_hello_interval_disc_time, + ldp_no_discovery_hello_interval_disc_time_cmd, - "no discovery hello interval <1-65535>", ++ "no discovery hello interval (1-65535)", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "LDP Link Hellos\n" + "Hello interval\n" + "Time (seconds)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "hello_type", .value = "hello" }, + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_disc_interval (vty, args); + } + + DEFUN (ldp_no_discovery_targeted_hello_holdtime_disc_time, + ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd, - "no discovery targeted-hello holdtime <1-65535>", ++ "no discovery targeted-hello holdtime (1-65535)", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "LDP Targeted Hellos\n" + "Targeted hello holdtime\n" + "Time (seconds) - 65535 implies infinite\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" }, + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_disc_holdtime (vty, args); + } + + DEFUN (ldp_no_discovery_targeted_hello_interval_disc_time, + ldp_no_discovery_targeted_hello_interval_disc_time_cmd, - "no discovery targeted-hello interval <1-65535>", ++ "no discovery targeted-hello interval (1-65535)", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "LDP Targeted Hellos\n" + "Targeted hello interval\n" + "Time (seconds)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" }, + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_disc_interval (vty, args); + } + + DEFUN (ldp_no_dual_stack_transport_connection_prefer_ipv4, + ldp_no_dual_stack_transport_connection_prefer_ipv4_cmd, + "no dual-stack transport-connection prefer ipv4", + "Negate a command or set its defaults\n" + "Configure dual stack parameters\n" + "Configure TCP transport parameters\n" + "Configure prefered address family for TCP transport connection with neighbor\n" + "IPv4\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + NULL + }; + return ldp_vty_trans_pref_ipv4 (vty, args); + } + + DEFUN (ldp_no_dual_stack_cisco_interop, + ldp_no_dual_stack_cisco_interop_cmd, + "no dual-stack cisco-interop", + "Negate a command or set its defaults\n" + "Configure dual stack parameters\n" + "Use Cisco non-compliant format to send and interpret the Dual-Stack capability TLV\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + NULL + }; + return ldp_vty_ds_cisco_interop (vty, args); + } + + DEFUN (ldp_no_neighbor_ipv4_password_word, + ldp_no_neighbor_ipv4_password_word_cmd, + "no neighbor A.B.C.D password WORD", + "Negate a command or set its defaults\n" + "Configure neighbor parameters\n" + "LDP Id of neighbor\n" + "Configure password for MD5 authentication\n" + "The password\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "lsr_id", .value = argv[0] }, + &(struct vty_arg) { .name = "password", .value = argv[1] }, + NULL + }; + return ldp_vty_neighbor_password (vty, args); + } + + DEFUN (ldp_no_neighbor_ipv4_session_holdtime_session_time, + ldp_no_neighbor_ipv4_session_holdtime_session_time_cmd, - "no neighbor A.B.C.D session holdtime <15-65535>", ++ "no neighbor A.B.C.D session holdtime (15-65535)", + "Negate a command or set its defaults\n" + "Configure neighbor parameters\n" + "LDP Id of neighbor\n" + "Configure session parameters\n" + "Configure session holdtime\n" + "Time (seconds)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "lsr_id", .value = argv[0] }, + &(struct vty_arg) { .name = "seconds", .value = argv[1] }, + NULL + }; + return ldp_vty_session_holdtime (vty, args); + } + + DEFUN (ldp_no_neighbor_ipv4_ttl_security_disable, + ldp_no_neighbor_ipv4_ttl_security_disable_cmd, + "no neighbor A.B.C.D ttl-security disable", + "Negate a command or set its defaults\n" + "Configure neighbor parameters\n" + "LDP Id of neighbor\n" + "LDP ttl security check\n" + "Disable ttl security\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "lsr_id", .value = argv[0] }, + NULL + }; + return ldp_vty_neighbor_ttl_security (vty, args); + } + + DEFUN (ldp_no_neighbor_ipv4_ttl_security_hops_hops, + ldp_no_neighbor_ipv4_ttl_security_hops_hops_cmd, - "no neighbor A.B.C.D ttl-security hops <1-254>", ++ "no neighbor A.B.C.D ttl-security hops (1-254)", + "Negate a command or set its defaults\n" + "Configure neighbor parameters\n" + "LDP Id of neighbor\n" + "LDP ttl security check\n" + "IP hops\n" + "maximum number of hops\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "lsr_id", .value = argv[0] }, + &(struct vty_arg) { .name = "hops", .value = argv[1] }, + NULL + }; + return ldp_vty_neighbor_ttl_security (vty, args); + } + + DEFUN (ldp_no_router_id_ipv4, + ldp_no_router_id_ipv4_cmd, + "no router-id A.B.C.D", + "Negate a command or set its defaults\n" + "Configure router Id\n" + "LSR Id (in form of an IPv4 address)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_router_id (vty, args); + } + + DEFUN (ldp_discovery_targeted_hello_accept, + ldp_discovery_targeted_hello_accept_cmd, + "discovery targeted-hello accept", + "Configure discovery parameters\n" + "LDP Targeted Hellos\n" + "Accept and respond to targeted hellos\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" }, + NULL + }; + return ldp_vty_targeted_hello_accept (vty, args); + } + + DEFUN (ldp_label_local_advertise_explicit_null, + ldp_label_local_advertise_explicit_null_cmd, + "label local advertise explicit-null", + "Configure label control and policies\n" + "Configure local label control and policies\n" + "Configure outbound label advertisement control\n" + "Configure explicit-null advertisement\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_explicit_null (vty, args); + } + + DEFUN (ldp_ttl_security_disable, + ldp_ttl_security_disable_cmd, + "ttl-security disable", + "LDP ttl security check\n" + "Disable ttl security\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_ttl_security (vty, args); + } + + DEFUN (ldp_session_holdtime_session_time, + ldp_session_holdtime_session_time_cmd, - "session holdtime <15-65535>", ++ "session holdtime (15-65535)", + "Configure session parameters\n" + "Configure session holdtime\n" + "Time (seconds)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_session_holdtime (vty, args); + } + + DEFUN (ldp_interface_ifname, + ldp_interface_ifname_cmd, + "interface IFNAME", + "Enable LDP on an interface and enter interface submode\n" + "Interface's name\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "ifname", .value = argv[0] }, + NULL + }; + return ldp_vty_interface (vty, args); + } + + DEFUN (ldp_discovery_transport_address_ipv4, + ldp_discovery_transport_address_ipv4_cmd, + "discovery transport-address A.B.C.D", + "Configure discovery parameters\n" + "Specify transport address for TCP connection\n" + "IP address to be used as transport address\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_trans_addr (vty, args); + } + + DEFUN (ldp_neighbor_ipv4_targeted, + ldp_neighbor_ipv4_targeted_cmd, + "neighbor A.B.C.D targeted", + "Configure neighbor parameters\n" + "IP address of neighbor\n" + "Establish targeted session\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_neighbor_targeted (vty, args); + } + + DEFUN (ldp_no_discovery_targeted_hello_accept, + ldp_no_discovery_targeted_hello_accept_cmd, + "no discovery targeted-hello accept", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "LDP Targeted Hellos\n" + "Accept and respond to targeted hellos\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "hello_type", .value = "targeted-hello" }, + NULL + }; + return ldp_vty_targeted_hello_accept (vty, args); + } + + DEFUN (ldp_no_label_local_advertise_explicit_null, + ldp_no_label_local_advertise_explicit_null_cmd, + "no label local advertise explicit-null", + "Negate a command or set its defaults\n" + "Configure label control and policies\n" + "Configure local label control and policies\n" + "Configure outbound label advertisement control\n" + "Configure explicit-null advertisement\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + NULL + }; + return ldp_vty_explicit_null (vty, args); + } + + DEFUN (ldp_no_ttl_security_disable, + ldp_no_ttl_security_disable_cmd, + "no ttl-security disable", + "Negate a command or set its defaults\n" + "LDP ttl security check\n" + "Disable ttl security\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + NULL + }; + return ldp_vty_ttl_security (vty, args); + } + + DEFUN (ldp_no_session_holdtime_session_time, + ldp_no_session_holdtime_session_time_cmd, - "no session holdtime <15-65535>", ++ "no session holdtime (15-65535)", + "Negate a command or set its defaults\n" + "Configure session parameters\n" + "Configure session holdtime\n" + "Time (seconds)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "seconds", .value = argv[0] }, + NULL + }; + return ldp_vty_session_holdtime (vty, args); + } + + DEFUN (ldp_no_interface_ifname, + ldp_no_interface_ifname_cmd, + "no interface IFNAME", + "Negate a command or set its defaults\n" + "Enable LDP on an interface and enter interface submode\n" + "Interface's name\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "ifname", .value = argv[0] }, + NULL + }; + return ldp_vty_interface (vty, args); + } + + DEFUN (ldp_no_discovery_transport_address_ipv4, + ldp_no_discovery_transport_address_ipv4_cmd, + "no discovery transport-address A.B.C.D", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "Specify transport address for TCP connection\n" + "IP address to be used as transport address\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_trans_addr (vty, args); + } + + DEFUN (ldp_no_neighbor_ipv4_targeted, + ldp_no_neighbor_ipv4_targeted_cmd, + "no neighbor A.B.C.D targeted", + "Negate a command or set its defaults\n" + "Configure neighbor parameters\n" + "IP address of neighbor\n" + "Establish targeted session\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_neighbor_targeted (vty, args); + } + + DEFUN (ldp_discovery_transport_address_ipv6, + ldp_discovery_transport_address_ipv6_cmd, + "discovery transport-address X:X::X:X", + "Configure discovery parameters\n" + "Specify transport address for TCP connection\n" + "IPv6 address to be used as transport address\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_trans_addr (vty, args); + } + + DEFUN (ldp_neighbor_ipv6_targeted, + ldp_neighbor_ipv6_targeted_cmd, + "neighbor X:X::X:X targeted", + "Configure neighbor parameters\n" + "IPv6 address of neighbor\n" + "Establish targeted session\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_neighbor_targeted (vty, args); + } + + DEFUN (ldp_no_discovery_transport_address_ipv6, + ldp_no_discovery_transport_address_ipv6_cmd, + "no discovery transport-address X:X::X:X", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "Specify transport address for TCP connection\n" + "IPv6 address to be used as transport address\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_trans_addr (vty, args); + } + + DEFUN (ldp_no_neighbor_ipv6_targeted, + ldp_no_neighbor_ipv6_targeted_cmd, + "no neighbor X:X::X:X targeted", + "Negate a command or set its defaults\n" + "Configure neighbor parameters\n" + "IPv6 address of neighbor\n" + "Establish targeted session\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_neighbor_targeted (vty, args); + } + + DEFUN (ldp_bridge_ifname, + ldp_bridge_ifname_cmd, + "bridge IFNAME", + "Bridge interface\n" + "Interface's name\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "ifname", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_bridge (vty, args); + } + + DEFUN (ldp_mtu_mtu, + ldp_mtu_mtu_cmd, - "mtu <1500-9180>", ++ "mtu (1500-9180)", + "set Maximum Transmission Unit\n" + "Maximum Transmission Unit value\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "mtu", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_mtu (vty, args); + } + + DEFUN (ldp_member_interface_ifname, + ldp_member_interface_ifname_cmd, + "member interface IFNAME", + "L2VPN member configuration\n" + "Local interface\n" + "Interface's name\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "ifname", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_interface (vty, args); + } + + DEFUN (ldp_member_pseudowire_ifname, + ldp_member_pseudowire_ifname_cmd, + "member pseudowire IFNAME", + "L2VPN member configuration\n" + "Pseudowire interface\n" + "Interface's name\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "ifname", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pseudowire (vty, args); + } + + DEFUN (ldp_vc_type_pwtype, + ldp_vc_type_pwtype_cmd, - "vc type (ethernet|ethernet-tagged)", ++ "vc type ", + "Virtual Circuit options\n" + "Virtual Circuit type to use\n" + "Ethernet (type 5)\n" + "Ethernet-tagged (type 4)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "type", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pwtype (vty, args); + } + + DEFUN (ldp_no_bridge_ifname, + ldp_no_bridge_ifname_cmd, + "no bridge IFNAME", + "Negate a command or set its defaults\n" + "Bridge interface\n" + "Interface's name\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "ifname", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_bridge (vty, args); + } + + DEFUN (ldp_no_mtu_mtu, + ldp_no_mtu_mtu_cmd, - "no mtu <1500-9180>", ++ "no mtu (1500-9180)", + "Negate a command or set its defaults\n" + "set Maximum Transmission Unit\n" + "Maximum Transmission Unit value\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "mtu", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_mtu (vty, args); + } + + DEFUN (ldp_no_member_interface_ifname, + ldp_no_member_interface_ifname_cmd, + "no member interface IFNAME", + "Negate a command or set its defaults\n" + "L2VPN member configuration\n" + "Local interface\n" + "Interface's name\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "ifname", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_interface (vty, args); + } + + DEFUN (ldp_no_member_pseudowire_ifname, + ldp_no_member_pseudowire_ifname_cmd, + "no member pseudowire IFNAME", + "Negate a command or set its defaults\n" + "L2VPN member configuration\n" + "Pseudowire interface\n" + "Interface's name\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "ifname", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pseudowire (vty, args); + } + + DEFUN (ldp_no_vc_type_pwtype, + ldp_no_vc_type_pwtype_cmd, - "no vc type (ethernet|ethernet-tagged)", ++ "no vc type ", + "Negate a command or set its defaults\n" + "Virtual Circuit options\n" + "Virtual Circuit type to use\n" + "Ethernet (type 5)\n" + "Ethernet-tagged (type 4)\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "type", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pwtype (vty, args); + } + + DEFUN (ldp_control_word_cword, + ldp_control_word_cword_cmd, - "control-word (exclude|include)", ++ "control-word ", + "Control-word options\n" + "Exclude control-word in pseudowire packets\n" + "Include control-word in pseudowire packets\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "preference", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pw_cword (vty, args); + } + + DEFUN (ldp_neighbor_address_addr, + ldp_neighbor_address_addr_cmd, - "neighbor address (A.B.C.D|X:X::X:X)", ++ "neighbor address ", + "Remote endpoint configuration\n" + "Specify the IPv4 or IPv6 address of the remote endpoint\n" + "IPv4 address\n" + "IPv6 address\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pw_nbr_addr (vty, args); + } + + DEFUN (ldp_neighbor_lsr_id_ipv4, + ldp_neighbor_lsr_id_ipv4_cmd, + "neighbor lsr-id A.B.C.D", + "Remote endpoint configuration\n" + "Specify the LSR-ID of the remote endpoint\n" + "IPv4 address\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "lsr-id", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pw_nbr_id (vty, args); + } + + DEFUN (ldp_pw_id_pwid, + ldp_pw_id_pwid_cmd, - "pw-id <1-4294967295>", ++ "pw-id (1-4294967295)", + "Set the Virtual Circuit ID\n" + "Virtual Circuit ID value\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "pwid", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pw_pwid (vty, args); + } + + DEFUN (ldp_pw_status_disable, + ldp_pw_status_disable_cmd, + "pw-status disable", + "Configure PW status\n" + "Disable PW status\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_l2vpn_pw_pwstatus (vty, args); + } + + DEFUN (ldp_no_control_word_cword, + ldp_no_control_word_cword_cmd, - "no control-word (exclude|include)", ++ "no control-word ", + "Negate a command or set its defaults\n" + "Control-word options\n" + "Exclude control-word in pseudowire packets\n" + "Include control-word in pseudowire packets\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "preference", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pw_cword (vty, args); + } + + DEFUN (ldp_no_neighbor_address_addr, + ldp_no_neighbor_address_addr_cmd, - "no neighbor address (A.B.C.D|X:X::X:X)", ++ "no neighbor address ", + "Negate a command or set its defaults\n" + "Remote endpoint configuration\n" + "Specify the IPv4 or IPv6 address of the remote endpoint\n" + "IPv4 address\n" + "IPv6 address\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pw_nbr_addr (vty, args); + } + + DEFUN (ldp_no_neighbor_lsr_id_ipv4, + ldp_no_neighbor_lsr_id_ipv4_cmd, + "no neighbor lsr-id A.B.C.D", + "Negate a command or set its defaults\n" + "Remote endpoint configuration\n" + "Specify the LSR-ID of the remote endpoint\n" + "IPv4 address\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "lsr-id", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pw_nbr_id (vty, args); + } + + DEFUN (ldp_no_pw_id_pwid, + ldp_no_pw_id_pwid_cmd, - "no pw-id <1-4294967295>", ++ "no pw-id (1-4294967295)", + "Negate a command or set its defaults\n" + "Set the Virtual Circuit ID\n" + "Virtual Circuit ID value\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "pwid", .value = argv[0] }, + NULL + }; + return ldp_vty_l2vpn_pw_pwid (vty, args); + } + + DEFUN (ldp_no_pw_status_disable, + ldp_no_pw_status_disable_cmd, + "no pw-status disable", + "Negate a command or set its defaults\n" + "Configure PW status\n" + "Disable PW status\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + NULL + }; + return ldp_vty_l2vpn_pw_pwstatus (vty, args); + } + + DEFUN (ldp_show_mpls_ldp_neighbor, + ldp_show_mpls_ldp_neighbor_cmd, + "show mpls ldp neighbor", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Neighbor information\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_show_neighbor (vty, args); + } + + DEFUN (ldp_show_mpls_ldp_binding, + ldp_show_mpls_ldp_binding_cmd, + "show mpls ldp binding", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Label Information Base (LIB) information\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_show_binding (vty, args); + } + + DEFUN (ldp_show_mpls_ldp_discovery, + ldp_show_mpls_ldp_discovery_cmd, + "show mpls ldp discovery", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Discovery Hello Information\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_show_discovery (vty, args); + } + + DEFUN (ldp_show_mpls_ldp_interface, + ldp_show_mpls_ldp_interface_cmd, + "show mpls ldp interface", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "interface information\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_show_interface (vty, args); + } + + DEFUN (ldp_show_mpls_ldp_address_family_binding, + ldp_show_mpls_ldp_address_family_binding_cmd, - "show mpls ldp (ipv4|ipv6) binding", ++ "show mpls ldp binding", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "IPv4 Address Family\n" + "IPv6 Address Family\n" + "Label Information Base (LIB) information\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "address-family", .value = argv[0] }, + NULL + }; + return ldp_vty_show_binding (vty, args); + } + + DEFUN (ldp_show_mpls_ldp_address_family_discovery, + ldp_show_mpls_ldp_address_family_discovery_cmd, - "show mpls ldp (ipv4|ipv6) discovery", ++ "show mpls ldp discovery", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "IPv4 Address Family\n" + "IPv6 Address Family\n" + "Discovery Hello Information\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "address-family", .value = argv[0] }, + NULL + }; + return ldp_vty_show_discovery (vty, args); + } + + DEFUN (ldp_show_mpls_ldp_address_family_interface, + ldp_show_mpls_ldp_address_family_interface_cmd, - "show mpls ldp (ipv4|ipv6) interface", ++ "show mpls ldp interface", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "IPv4 Address Family\n" + "IPv6 Address Family\n" + "interface information\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "address-family", .value = argv[0] }, + NULL + }; + return ldp_vty_show_interface (vty, args); + } + + DEFUN (ldp_show_l2vpn_atom_binding, + ldp_show_l2vpn_atom_binding_cmd, + "show l2vpn atom binding", + "Show running system information\n" + "Show information about Layer2 VPN\n" + "Show Any Transport over MPLS information\n" + "Show AToM label binding information\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_show_atom_binding (vty, args); + } + + DEFUN (ldp_show_l2vpn_atom_vc, + ldp_show_l2vpn_atom_vc_cmd, + "show l2vpn atom vc", + "Show running system information\n" + "Show information about Layer2 VPN\n" + "Show Any Transport over MPLS information\n" + "Show AToM virtual circuit information\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_show_atom_vc (vty, args); + } + + DEFUN (ldp_show_debugging_mpls_ldp, + ldp_show_debugging_mpls_ldp_cmd, + "show debugging mpls ldp", + "Show running system information\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_show_debugging (vty, args); + } + + DEFUN (ldp_clear_mpls_ldp_neighbor, + ldp_clear_mpls_ldp_neighbor_cmd, + "clear mpls ldp neighbor", + "Reset functions\n" + "Reset MPLS statistical information\n" + "Clear LDP state\n" + "Clear LDP neighbor sessions\n") + { + struct vty_arg *args[] = { NULL }; + return ldp_vty_clear_nbr (vty, args); + } + + DEFUN (ldp_clear_mpls_ldp_neighbor_addr, + ldp_clear_mpls_ldp_neighbor_addr_cmd, - "clear mpls ldp neighbor (A.B.C.D|X:X::X:X)", ++ "clear mpls ldp neighbor ", + "Reset functions\n" + "Reset MPLS statistical information\n" + "Clear LDP state\n" + "Clear LDP neighbor sessions\n" + "IPv4 address\n" + "IPv6 address\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "addr", .value = argv[0] }, + NULL + }; + return ldp_vty_clear_nbr (vty, args); + } + + DEFUN (ldp_debug_mpls_ldp_discovery_hello_dir, + ldp_debug_mpls_ldp_discovery_hello_dir_cmd, - "debug mpls ldp discovery hello (recv|sent)", ++ "debug mpls ldp discovery hello ", + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Discovery messages\n" + "Discovery hello message\n" + "Received messages\n" + "Sent messages\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "type", .value = "discovery" }, + &(struct vty_arg) { .name = "dir", .value = argv[0] }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_debug_mpls_ldp_errors, + ldp_debug_mpls_ldp_errors_cmd, + "debug mpls ldp errors", + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Errors\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "type", .value = "errors" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_debug_mpls_ldp_event, + ldp_debug_mpls_ldp_event_cmd, + "debug mpls ldp event", + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "LDP event information\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "type", .value = "event" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_debug_mpls_ldp_messages_recv, + ldp_debug_mpls_ldp_messages_recv_cmd, + "debug mpls ldp messages recv", + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Messages\n" + "Received messages, excluding periodic Keep Alives\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "type", .value = "messages" }, + &(struct vty_arg) { .name = "dir", .value = "recv" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_debug_mpls_ldp_messages_recv_all, + ldp_debug_mpls_ldp_messages_recv_all_cmd, + "debug mpls ldp messages recv all", + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Messages\n" + "Received messages, excluding periodic Keep Alives\n" + "Received messages, including periodic Keep Alives\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "type", .value = "messages" }, + &(struct vty_arg) { .name = "dir", .value = "recv" }, + &(struct vty_arg) { .name = "all", .value = "all" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_debug_mpls_ldp_messages_sent, + ldp_debug_mpls_ldp_messages_sent_cmd, + "debug mpls ldp messages sent", + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Messages\n" + "Sent messages, excluding periodic Keep Alives\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "type", .value = "messages" }, + &(struct vty_arg) { .name = "dir", .value = "sent" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_debug_mpls_ldp_messages_sent_all, + ldp_debug_mpls_ldp_messages_sent_all_cmd, + "debug mpls ldp messages sent all", + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Messages\n" + "Sent messages, excluding periodic Keep Alives\n" + "Sent messages, including periodic Keep Alives\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "type", .value = "messages" }, + &(struct vty_arg) { .name = "dir", .value = "sent" }, + &(struct vty_arg) { .name = "all", .value = "all" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_debug_mpls_ldp_zebra, + ldp_debug_mpls_ldp_zebra_cmd, + "debug mpls ldp zebra", + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "LDP zebra information\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "type", .value = "zebra" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_no_debug_mpls_ldp_discovery_hello_dir, + ldp_no_debug_mpls_ldp_discovery_hello_dir_cmd, - "no debug mpls ldp discovery hello (recv|sent)", ++ "no debug mpls ldp discovery hello ", + "Negate a command or set its defaults\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Discovery messages\n" + "Discovery hello message\n" + "Received messages\n" + "Sent messages\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "type", .value = "discovery" }, + &(struct vty_arg) { .name = "dir", .value = argv[0] }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_no_debug_mpls_ldp_errors, + ldp_no_debug_mpls_ldp_errors_cmd, + "no debug mpls ldp errors", + "Negate a command or set its defaults\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Errors\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "type", .value = "errors" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_no_debug_mpls_ldp_event, + ldp_no_debug_mpls_ldp_event_cmd, + "no debug mpls ldp event", + "Negate a command or set its defaults\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "LDP event information\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "type", .value = "event" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_no_debug_mpls_ldp_messages_recv, + ldp_no_debug_mpls_ldp_messages_recv_cmd, + "no debug mpls ldp messages recv", + "Negate a command or set its defaults\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Messages\n" + "Received messages, excluding periodic Keep Alives\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "type", .value = "messages" }, + &(struct vty_arg) { .name = "dir", .value = "recv" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_no_debug_mpls_ldp_messages_recv_all, + ldp_no_debug_mpls_ldp_messages_recv_all_cmd, + "no debug mpls ldp messages recv all", + "Negate a command or set its defaults\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Messages\n" + "Received messages, excluding periodic Keep Alives\n" + "Received messages, including periodic Keep Alives\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "type", .value = "messages" }, + &(struct vty_arg) { .name = "dir", .value = "recv" }, + &(struct vty_arg) { .name = "all", .value = "all" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_no_debug_mpls_ldp_messages_sent, + ldp_no_debug_mpls_ldp_messages_sent_cmd, + "no debug mpls ldp messages sent", + "Negate a command or set its defaults\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Messages\n" + "Sent messages, excluding periodic Keep Alives\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "type", .value = "messages" }, + &(struct vty_arg) { .name = "dir", .value = "sent" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_no_debug_mpls_ldp_messages_sent_all, + ldp_no_debug_mpls_ldp_messages_sent_all_cmd, + "no debug mpls ldp messages sent all", + "Negate a command or set its defaults\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Messages\n" + "Sent messages, excluding periodic Keep Alives\n" + "Sent messages, including periodic Keep Alives\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "type", .value = "messages" }, + &(struct vty_arg) { .name = "dir", .value = "sent" }, + &(struct vty_arg) { .name = "all", .value = "all" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + DEFUN (ldp_no_debug_mpls_ldp_zebra, + ldp_no_debug_mpls_ldp_zebra_cmd, + "no debug mpls ldp zebra", + "Negate a command or set its defaults\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "LDP zebra information\n") + { + struct vty_arg *args[] = + { + &(struct vty_arg) { .name = "no", .value = "no" }, + &(struct vty_arg) { .name = "type", .value = "zebra" }, + NULL + }; + return ldp_vty_debug (vty, args); + } + + void + ldp_vty_init (void) + { + install_element (CONFIG_NODE, &ldp_mpls_ldp_cmd); + install_element (CONFIG_NODE, &ldp_l2vpn_word_type_vpls_cmd); + install_element (CONFIG_NODE, &ldp_no_mpls_ldp_cmd); + install_element (CONFIG_NODE, &ldp_no_l2vpn_word_type_vpls_cmd); + install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_discovery_hello_dir_cmd); + install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_errors_cmd); + install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_event_cmd); + install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_recv_cmd); + install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_recv_all_cmd); + install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_sent_cmd); + install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_messages_sent_all_cmd); + install_element (CONFIG_NODE, &ldp_debug_mpls_ldp_zebra_cmd); + install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_discovery_hello_dir_cmd); + install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_errors_cmd); + install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_event_cmd); + install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_recv_cmd); + install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_recv_all_cmd); + install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_sent_cmd); + install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_messages_sent_all_cmd); + install_element (CONFIG_NODE, &ldp_no_debug_mpls_ldp_zebra_cmd); + install_node (&ldp_node, ldp_config_write); + install_default (LDP_NODE); + install_element (LDP_NODE, &ldp_address_family_ipv4_cmd); + install_element (LDP_NODE, &ldp_address_family_ipv6_cmd); + install_element (LDP_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_NODE, &ldp_discovery_hello_interval_disc_time_cmd); + install_element (LDP_NODE, &ldp_discovery_targeted_hello_holdtime_disc_time_cmd); + install_element (LDP_NODE, &ldp_discovery_targeted_hello_interval_disc_time_cmd); + install_element (LDP_NODE, &ldp_dual_stack_transport_connection_prefer_ipv4_cmd); + install_element (LDP_NODE, &ldp_dual_stack_cisco_interop_cmd); + install_element (LDP_NODE, &ldp_neighbor_ipv4_password_word_cmd); + install_element (LDP_NODE, &ldp_neighbor_ipv4_session_holdtime_session_time_cmd); + install_element (LDP_NODE, &ldp_neighbor_ipv4_ttl_security_disable_cmd); + install_element (LDP_NODE, &ldp_neighbor_ipv4_ttl_security_hops_hops_cmd); + install_element (LDP_NODE, &ldp_router_id_ipv4_cmd); + install_element (LDP_NODE, &ldp_no_address_family_ipv4_cmd); + install_element (LDP_NODE, &ldp_no_address_family_ipv6_cmd); + install_element (LDP_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd); + install_element (LDP_NODE, &ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd); + install_element (LDP_NODE, &ldp_no_discovery_targeted_hello_interval_disc_time_cmd); + install_element (LDP_NODE, &ldp_no_dual_stack_transport_connection_prefer_ipv4_cmd); + install_element (LDP_NODE, &ldp_no_dual_stack_cisco_interop_cmd); + install_element (LDP_NODE, &ldp_no_neighbor_ipv4_password_word_cmd); + install_element (LDP_NODE, &ldp_no_neighbor_ipv4_session_holdtime_session_time_cmd); + install_element (LDP_NODE, &ldp_no_neighbor_ipv4_ttl_security_disable_cmd); + install_element (LDP_NODE, &ldp_no_neighbor_ipv4_ttl_security_hops_hops_cmd); + install_element (LDP_NODE, &ldp_no_router_id_ipv4_cmd); + install_node (&ldp_ipv4_node, NULL); + install_default (LDP_IPV4_NODE); + install_element (LDP_IPV4_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_discovery_hello_interval_disc_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_discovery_targeted_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_discovery_targeted_hello_interval_disc_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_discovery_targeted_hello_accept_cmd); + install_element (LDP_IPV4_NODE, &ldp_label_local_advertise_explicit_null_cmd); + install_element (LDP_IPV4_NODE, &ldp_ttl_security_disable_cmd); + install_element (LDP_IPV4_NODE, &ldp_session_holdtime_session_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_interface_ifname_cmd); + install_element (LDP_IPV4_NODE, &ldp_discovery_transport_address_ipv4_cmd); + install_element (LDP_IPV4_NODE, &ldp_neighbor_ipv4_targeted_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_discovery_targeted_hello_interval_disc_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_discovery_targeted_hello_accept_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_label_local_advertise_explicit_null_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_ttl_security_disable_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_session_holdtime_session_time_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_interface_ifname_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_discovery_transport_address_ipv4_cmd); + install_element (LDP_IPV4_NODE, &ldp_no_neighbor_ipv4_targeted_cmd); + install_node (&ldp_ipv6_node, NULL); + install_default (LDP_IPV6_NODE); + install_element (LDP_IPV6_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_discovery_hello_interval_disc_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_discovery_targeted_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_discovery_targeted_hello_interval_disc_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_discovery_targeted_hello_accept_cmd); + install_element (LDP_IPV6_NODE, &ldp_label_local_advertise_explicit_null_cmd); + install_element (LDP_IPV6_NODE, &ldp_ttl_security_disable_cmd); + install_element (LDP_IPV6_NODE, &ldp_session_holdtime_session_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_interface_ifname_cmd); + install_element (LDP_IPV6_NODE, &ldp_discovery_transport_address_ipv6_cmd); + install_element (LDP_IPV6_NODE, &ldp_neighbor_ipv6_targeted_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_discovery_targeted_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_discovery_targeted_hello_interval_disc_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_discovery_targeted_hello_accept_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_label_local_advertise_explicit_null_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_ttl_security_disable_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_session_holdtime_session_time_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_interface_ifname_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_discovery_transport_address_ipv6_cmd); + install_element (LDP_IPV6_NODE, &ldp_no_neighbor_ipv6_targeted_cmd); + install_node (&ldp_ipv4_iface_node, NULL); + install_default (LDP_IPV4_IFACE_NODE); + install_element (LDP_IPV4_IFACE_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV4_IFACE_NODE, &ldp_discovery_hello_interval_disc_time_cmd); + install_element (LDP_IPV4_IFACE_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV4_IFACE_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd); + install_node (&ldp_ipv6_iface_node, NULL); + install_default (LDP_IPV6_IFACE_NODE); + install_element (LDP_IPV6_IFACE_NODE, &ldp_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV6_IFACE_NODE, &ldp_discovery_hello_interval_disc_time_cmd); + install_element (LDP_IPV6_IFACE_NODE, &ldp_no_discovery_hello_holdtime_disc_time_cmd); + install_element (LDP_IPV6_IFACE_NODE, &ldp_no_discovery_hello_interval_disc_time_cmd); + install_node (&ldp_l2vpn_node, ldp_l2vpn_config_write); + install_default (LDP_L2VPN_NODE); + install_element (LDP_L2VPN_NODE, &ldp_bridge_ifname_cmd); + install_element (LDP_L2VPN_NODE, &ldp_mtu_mtu_cmd); + install_element (LDP_L2VPN_NODE, &ldp_member_interface_ifname_cmd); + install_element (LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd); + install_element (LDP_L2VPN_NODE, &ldp_vc_type_pwtype_cmd); + install_element (LDP_L2VPN_NODE, &ldp_no_bridge_ifname_cmd); + install_element (LDP_L2VPN_NODE, &ldp_no_mtu_mtu_cmd); + install_element (LDP_L2VPN_NODE, &ldp_no_member_interface_ifname_cmd); + install_element (LDP_L2VPN_NODE, &ldp_no_member_pseudowire_ifname_cmd); + install_element (LDP_L2VPN_NODE, &ldp_no_vc_type_pwtype_cmd); + install_node (&ldp_pseudowire_node, NULL); + install_default (LDP_PSEUDOWIRE_NODE); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_control_word_cword_cmd); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_neighbor_address_addr_cmd); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_neighbor_lsr_id_ipv4_cmd); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_pw_id_pwid_cmd); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_pw_status_disable_cmd); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_control_word_cword_cmd); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_neighbor_address_addr_cmd); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_neighbor_lsr_id_ipv4_cmd); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_pw_id_pwid_cmd); + install_element (LDP_PSEUDOWIRE_NODE, &ldp_no_pw_status_disable_cmd); + install_node (&ldp_debug_node, ldp_debug_config_write); + install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_discovery_hello_dir_cmd); + install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_errors_cmd); + install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_event_cmd); + install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_recv_cmd); + install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_recv_all_cmd); + install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_sent_cmd); + install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_messages_sent_all_cmd); + install_element (ENABLE_NODE, &ldp_debug_mpls_ldp_zebra_cmd); + install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_discovery_hello_dir_cmd); + install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_errors_cmd); + install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_event_cmd); + install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_recv_cmd); + install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_recv_all_cmd); + install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_sent_cmd); + install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_messages_sent_all_cmd); + install_element (ENABLE_NODE, &ldp_no_debug_mpls_ldp_zebra_cmd); + install_element (VIEW_NODE, &ldp_show_mpls_ldp_neighbor_cmd); + install_element (VIEW_NODE, &ldp_show_mpls_ldp_binding_cmd); + install_element (VIEW_NODE, &ldp_show_mpls_ldp_discovery_cmd); + install_element (VIEW_NODE, &ldp_show_mpls_ldp_interface_cmd); + install_element (VIEW_NODE, &ldp_show_mpls_ldp_address_family_binding_cmd); + install_element (VIEW_NODE, &ldp_show_mpls_ldp_address_family_discovery_cmd); + install_element (VIEW_NODE, &ldp_show_mpls_ldp_address_family_interface_cmd); + install_element (VIEW_NODE, &ldp_show_l2vpn_atom_binding_cmd); + install_element (VIEW_NODE, &ldp_show_l2vpn_atom_vc_cmd); + install_element (VIEW_NODE, &ldp_show_debugging_mpls_ldp_cmd); + install_element (VIEW_NODE, &ldp_clear_mpls_ldp_neighbor_cmd); + install_element (VIEW_NODE, &ldp_clear_mpls_ldp_neighbor_addr_cmd); + } diff --cc lib/Makefile.am index acaf7e6744,e95e6f34b7..dbf1a82be2 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@@ -1,9 -1,9 +1,10 @@@ ## Process this file with automake to produce Makefile.in. - AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib + AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib \ + -DVTY_DEPRECATE_INDEX AM_CFLAGS = $(WERROR) DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" +AM_YFLAGS = -d lib_LTLIBRARIES = libzebra.la libzebra_la_LDFLAGS = -version-info 0:0:0 @@@ -17,9 -15,11 +18,11 @@@ libzebra_la_SOURCES = filter.c routemap.c distribute.c stream.c str.c log.c plist.c \ zclient.c sockopt.c smux.c agentx.c snmp.c md5.c if_rmap.c keychain.c privs.c \ sigevent.c pqueue.c jhash.c workqueue.c nexthop.c json.c \ - ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c memory.c memory_vty.c + ptm_lib.c csv.c bfd.c vrf.c systemd.c ns.c memory.c memory_vty.c \ + imsg-buffer.c imsg.c skiplist.c \ + qobj.c -BUILT_SOURCES = route_types.h gitversion.h +BUILT_SOURCES = route_types.h gitversion.h command_parse.h libzebra_la_DEPENDENCIES = @LIB_REGEX@ diff --cc lib/command.c index 2f83a7fa5e,fd4b2e2427..63cfc695dc --- a/lib/command.c +++ b/lib/command.c @@@ -38,8 -33,7 +38,9 @@@ #include "command.h" #include "workqueue.h" #include "vrf.h" +#include "command_match.h" +#include "command_parse.h" + #include "qobj.h" DEFINE_MTYPE( LIB, HOST, "Host config") DEFINE_MTYPE( LIB, STRVEC, "String vector") @@@ -318,30 -705,22 +313,33 @@@ install_element (enum node_type ntype, /* cmd_init hasn't been called */ if (!cmdvec) return; - + cnode = vector_slot (cmdvec, ntype); - if (cnode == NULL) + if (cnode == NULL) { fprintf (stderr, "Command node %d doesn't exist, please check it\n", - ntype); - exit (1); + ntype); + exit (EXIT_FAILURE); + } + + // add node to command graph and command vector + // idiotic O(n) deduplication logic, should just use a merkle tree + for (unsigned int i = 0; i < vector_active (cnode->cmd_vector); i++) + { + struct cmd_element *existing = vector_slot (cnode->cmd_vector, i); + if (strmatch (existing->string, cmd->string)) + { + zlog_warn ("Duplicate command: %s\n", cmd->string); + return; } + } + command_parse_format (cnode->cmdgraph, cmd); vector_set (cnode->cmd_vector, cmd); - if (cmd->tokens == NULL) - cmd->tokens = cmd_parse_format(cmd->string, cmd->doc); + + if (ntype == VIEW_NODE) + install_element (ENABLE_NODE, cmd); } static const unsigned char itoa64[] = @@@ -465,217 -844,1678 +463,216 @@@ config_write_host (struct vty *vty return 1; } -/* Utility function for getting command vector. */ -static vector -cmd_node_vector (vector v, enum node_type ntype) +/* Utility function for getting command graph. */ +static struct graph * +cmd_node_graph (vector v, enum node_type ntype) { struct cmd_node *cnode = vector_slot (v, ntype); - return cnode->cmd_vector; + return cnode->cmdgraph; +} + +static int +cmd_try_do_shortcut (enum node_type node, char* first_word) { + if ( first_word != NULL && + node != AUTH_NODE && + node != VIEW_NODE && + node != AUTH_ENABLE_NODE && + node != ENABLE_NODE && - node != RESTRICTED_NODE && + 0 == strcmp( "do", first_word ) ) + return 1; + return 0; } -/* Completion match types. */ -enum match_type +/** + * Compare function for cmd_token. + * Used with qsort to sort command completions. + */ +static int +compare_completions (const void *fst, const void *snd) { - no_match, - extend_match, - ipv4_prefix_match, - ipv4_match, - ipv6_prefix_match, - ipv6_match, - range_match, - vararg_match, - partly_match, - exact_match -}; + struct cmd_token *first = *(struct cmd_token **) fst, + *secnd = *(struct cmd_token **) snd; + return strcmp (first->text, secnd->text); +} -static enum match_type -cmd_ipv4_match (const char *str) +/** + * Takes a list of completions returned by command_complete, + * dedeuplicates them based on both text and description, + * sorts them, and returns them as a vector. + * + * @param completions linked list of cmd_token + * @return deduplicated and sorted vector with + */ +static vector +completions_to_vec (struct list *completions) { - const char *sp; - int dots = 0, nums = 0; - char buf[4]; + vector comps = vector_init (VECTOR_MIN_SIZE); - if (str == NULL) - return partly_match; + struct listnode *ln; + struct cmd_token *token, *cr = NULL; + unsigned int i, exists; + for (ALL_LIST_ELEMENTS_RO(completions,ln,token)) + { + if (token->type == END_TKN && (cr = token)) + continue; - for (;;) + // linear search for token in completions vector + exists = 0; + for (i = 0; i < vector_active (comps) && !exists; i++) { - memset (buf, 0, sizeof (buf)); - sp = str; - while (*str != '\0') - { - if (*str == '.') - { - if (dots >= 3) - return no_match; - - if (*(str + 1) == '.') - return no_match; - - if (*(str + 1) == '\0') - return partly_match; - - dots++; - break; - } - if (!isdigit ((int) *str)) - return no_match; - - str++; - } - - if (str - sp > 3) - return no_match; - - strncpy (buf, sp, str - sp); - if (atoi (buf) > 255) - return no_match; - - nums++; + struct cmd_token *curr = vector_slot (comps, i); + exists = !strcmp (curr->text, token->text) && + !strcmp (curr->desc, token->desc); + } - if (*str == '\0') - break; + if (!exists) + vector_set (comps, copy_cmd_token (token)); + } - str++; - } + // sort completions + qsort (comps->index, + vector_active (comps), + sizeof (void *), + &compare_completions); - if (nums < 4) - return partly_match; + if (cr) + { + vector_set_index (comps, vector_active (comps), NULL); + memmove (comps->index + 1, comps->index, (comps->alloced - 1) * sizeof (void *)); + vector_set_index (comps, 0, copy_cmd_token (cr)); + } - return exact_match; + return comps; } - -static enum match_type -cmd_ipv4_prefix_match (const char *str) +/** + * Generates a vector of cmd_token representing possible completions + * on the current input. + * + * @param vline the vectorized input line + * @param vty the vty with the node to match on + * @param status pointer to matcher status code + */ +static vector +cmd_complete_command_real (vector vline, struct vty *vty, int *status) { - const char *sp; - int dots = 0; - char buf[4]; + struct list *completions; + struct graph *cmdgraph = cmd_node_graph (cmdvec, vty->node); - if (str == NULL) - return partly_match; + enum matcher_rv rv = command_complete (cmdgraph, vline, &completions); - for (;;) + if (MATCHER_ERROR(rv)) + { + switch (rv) { - memset (buf, 0, sizeof (buf)); - sp = str; - while (*str != '\0' && *str != '/') - { - if (*str == '.') - { - if (dots == 3) - return no_match; - - if (*(str + 1) == '.' || *(str + 1) == '/') - return no_match; - - if (*(str + 1) == '\0') - return partly_match; - - dots++; - break; - } - - if (!isdigit ((int) *str)) - return no_match; - - str++; - } - - if (str - sp > 3) - return no_match; - - strncpy (buf, sp, str - sp); - if (atoi (buf) > 255) - return no_match; - - if (dots == 3) - { - if (*str == '/') - { - if (*(str + 1) == '\0') - return partly_match; - - str++; - break; - } - else if (*str == '\0') - return partly_match; - } - - if (*str == '\0') - return partly_match; - - str++; + case MATCHER_AMBIGUOUS: + *status = CMD_ERR_AMBIGUOUS; + default: + *status = CMD_ERR_NO_MATCH; } + return NULL; + } - sp = str; - while (*str != '\0') - { - if (!isdigit ((int) *str)) - return no_match; - - str++; - } + vector comps = completions_to_vec (completions); + list_delete (completions); - if (atoi (sp) > 32) - return no_match; + // set status code appropriately + switch (vector_active (comps)) + { + case 0: + *status = CMD_ERR_NO_MATCH; + break; + case 1: + *status = CMD_COMPLETE_FULL_MATCH; + break; + default: + *status = CMD_COMPLETE_LIST_MATCH; + } - return exact_match; + return comps; } -#define IPV6_ADDR_STR "0123456789abcdefABCDEF:." -#define IPV6_PREFIX_STR "0123456789abcdefABCDEF:./" +vector +cmd_describe_command (vector vline, struct vty *vty, int *status) +{ + vector ret; -#ifdef HAVE_IPV6 + if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) ) + { + enum node_type onode; + vector shifted_vline; + unsigned int index; -static enum match_type -cmd_ipv6_match (const char *str) -{ - struct sockaddr_in6 sin6_dummy; - int ret; + onode = vty->node; + vty->node = ENABLE_NODE; + /* We can try it on enable node, cos' the vty is authenticated */ - if (str == NULL) - return partly_match; + shifted_vline = vector_init (vector_count(vline)); + /* use memcpy? */ + for (index = 1; index < vector_active (vline); index++) + { + vector_set_index (shifted_vline, index-1, vector_lookup(vline, index)); + } - if (strspn (str, IPV6_ADDR_STR) != strlen (str)) - return no_match; + ret = cmd_complete_command_real (shifted_vline, vty, status); - /* use inet_pton that has a better support, - * for example inet_pton can support the automatic addresses: - * ::1.2.3.4 - */ - ret = inet_pton(AF_INET6, str, &sin6_dummy.sin6_addr); - - if (ret == 1) - return exact_match; + vector_free(shifted_vline); + vty->node = onode; + return ret; + } - return no_match; + return cmd_complete_command_real (vline, vty, status); } -static enum match_type -cmd_ipv6_prefix_match (const char *str) +char ** +cmd_complete_command_lib (vector vline, struct vty *vty, int *status, int islib) { - struct sockaddr_in6 sin6_dummy; - const char *delim = "/\0"; - char *dupe, *prefix, *mask, *context, *endptr; - int nmask = -1; - - if (str == NULL) - return partly_match; + char **ret = NULL; + int original_node = vty->node; + vector input_line = vector_init (vector_count (vline)); - if (strspn (str, IPV6_PREFIX_STR) != strlen (str)) - return no_match; + // if the first token is 'do' we'll want to execute the command in the enable node + int do_shortcut = cmd_try_do_shortcut (vty->node, vector_slot (vline, 0)); + vty->node = do_shortcut ? ENABLE_NODE : original_node; - /* tokenize to address + mask */ - dupe = XMALLOC(MTYPE_TMP, strlen(str)+1); - strncpy(dupe, str, strlen(str)+1); - prefix = strtok_r(dupe, delim, &context); - mask = strtok_r(NULL, delim, &context); + // construct the input line we'll be matching on + unsigned int offset = (do_shortcut) ? 1 : 0; + for (unsigned index = 0; index + offset < vector_active (vline); index++) + vector_set_index (input_line, index + offset, vector_lookup (vline, index)); - if (!mask) - return partly_match; + // get token completions -- this is a copying operation + vector comps = cmd_complete_command_real (input_line, vty, status); + if (!MATCHER_ERROR (*status)) + { + // copy completions text into an array of char* + ret = XMALLOC (MTYPE_TMP, vector_active (comps) * sizeof (char *) + 1); + unsigned int i; + for (i = 0; i < vector_active (comps); i++) + { + struct cmd_token *token = vector_slot (comps, i); + ret[i] = XSTRDUP (MTYPE_TMP, token->text); + vector_unset (comps, i); + del_cmd_token (token); + } + // set the last element to NULL, which vty/vtysh uses as a sentinel value + ret[i] = NULL; + vector_free (comps); + comps = NULL; + } - /* validate prefix */ - if (inet_pton(AF_INET6, prefix, &sin6_dummy.sin6_addr) != 1) - return no_match; + // comps should always be null here + assert (!comps); - /* validate mask */ - nmask = strtol (mask, &endptr, 10); - if (*endptr != '\0' || nmask < 0 || nmask > 128) - return no_match; + // free the adjusted input line + vector_free (input_line); - XFREE(MTYPE_TMP, dupe); + // reset vty->node to its original value + vty->node = original_node; - return exact_match; + return ret; } -#endif /* HAVE_IPV6 */ - -#define DECIMAL_STRLEN_MAX 20 - -static int -cmd_range_match (const char *range, const char *str) -{ - char *p; - char buf[DECIMAL_STRLEN_MAX + 1]; - char *endptr = NULL; - signed long long min, max, val; - - if (str == NULL) - return 1; - - val = strtoll (str, &endptr, 10); - if (*endptr != '\0') - return 0; - val = llabs(val); - - range++; - p = strchr (range, '-'); - if (p == NULL) - return 0; - if (p - range > DECIMAL_STRLEN_MAX) - return 0; - strncpy (buf, range, p - range); - buf[p - range] = '\0'; - min = strtoll (buf, &endptr, 10); - if (*endptr != '\0') - return 0; - - range = p + 1; - p = strchr (range, '>'); - if (p == NULL) - return 0; - if (p - range > DECIMAL_STRLEN_MAX) - return 0; - strncpy (buf, range, p - range); - buf[p - range] = '\0'; - max = strtoll (buf, &endptr, 10); - if (*endptr != '\0') - return 0; - - if (val < min || val > max) - return 0; - - return 1; -} - -static enum match_type -cmd_word_match(struct cmd_token *token, - enum filter_type filter, - const char *word) -{ - const char *str; - enum match_type match_type; - - str = token->cmd; - - if (filter == FILTER_RELAXED) - if (!word || !strlen(word)) - return partly_match; - - if (!word) - return no_match; - - switch (token->terminal) - { - case TERMINAL_VARARG: - return vararg_match; - - case TERMINAL_RANGE: - if (cmd_range_match(str, word)) - return range_match; - break; - - case TERMINAL_IPV6: - match_type = cmd_ipv6_match(word); - if ((filter == FILTER_RELAXED && match_type != no_match) - || (filter == FILTER_STRICT && match_type == exact_match)) - return ipv6_match; - break; - - case TERMINAL_IPV6_PREFIX: - match_type = cmd_ipv6_prefix_match(word); - if ((filter == FILTER_RELAXED && match_type != no_match) - || (filter == FILTER_STRICT && match_type == exact_match)) - return ipv6_prefix_match; - break; - - case TERMINAL_IPV4: - match_type = cmd_ipv4_match(word); - if ((filter == FILTER_RELAXED && match_type != no_match) - || (filter == FILTER_STRICT && match_type == exact_match)) - return ipv4_match; - break; - - case TERMINAL_IPV4_PREFIX: - match_type = cmd_ipv4_prefix_match(word); - if ((filter == FILTER_RELAXED && match_type != no_match) - || (filter == FILTER_STRICT && match_type == exact_match)) - return ipv4_prefix_match; - break; - - case TERMINAL_OPTION: - case TERMINAL_VARIABLE: - return extend_match; - - case TERMINAL_LITERAL: - if (filter == FILTER_RELAXED && !strncmp(str, word, strlen(word))) - { - if (!strcmp(str, word)) - return exact_match; - return partly_match; - } - if (filter == FILTER_STRICT && !strcmp(str, word)) - return exact_match; - break; - - default: - assert (0); - } - - return no_match; -} - -struct cmd_matcher -{ - struct cmd_element *cmd; /* The command element the matcher is using */ - enum filter_type filter; /* Whether to use strict or relaxed matching */ - vector vline; /* The tokenized commandline which is to be matched */ - unsigned int index; /* The index up to which matching should be done */ - - /* If set, construct a list of matches at the position given by index */ - enum match_type *match_type; - vector *match; - - unsigned int word_index; /* iterating over vline */ -}; - -static int -push_argument(int *argc, const char **argv, const char *arg) -{ - if (!arg || !strlen(arg)) - arg = NULL; - - if (!argc || !argv) - return 0; - - if (*argc >= CMD_ARGC_MAX) - return -1; - - argv[(*argc)++] = arg; - return 0; -} - -static void -cmd_matcher_record_match(struct cmd_matcher *matcher, - enum match_type match_type, - struct cmd_token *token) -{ - if (matcher->word_index != matcher->index) - return; - - if (matcher->match) - { - if (!*matcher->match) - *matcher->match = vector_init(VECTOR_MIN_SIZE); - vector_set(*matcher->match, token); - } - - if (matcher->match_type) - { - if (match_type > *matcher->match_type) - *matcher->match_type = match_type; - } -} - -static int -cmd_matcher_words_left(struct cmd_matcher *matcher) -{ - return matcher->word_index < vector_active(matcher->vline); -} - -static const char* -cmd_matcher_get_word(struct cmd_matcher *matcher) -{ - assert(cmd_matcher_words_left(matcher)); - - return vector_slot(matcher->vline, matcher->word_index); -} - -static enum matcher_rv -cmd_matcher_match_terminal(struct cmd_matcher *matcher, - struct cmd_token *token, - int *argc, const char **argv) -{ - const char *word; - enum match_type word_match; - - assert(token->type == TOKEN_TERMINAL); - - if (!cmd_matcher_words_left(matcher)) - { - if (token->terminal == TERMINAL_OPTION) - return MATCHER_OK; /* missing optional args are NOT pushed as NULL */ - else - return MATCHER_INCOMPLETE; - } - - word = cmd_matcher_get_word(matcher); - word_match = cmd_word_match(token, matcher->filter, word); - if (word_match == no_match) - return MATCHER_NO_MATCH; - - /* We have to record the input word as argument if it matched - * against a variable. */ - if (TERMINAL_RECORD (token->terminal)) - { - if (push_argument(argc, argv, word)) - return MATCHER_EXCEED_ARGC_MAX; - } - - cmd_matcher_record_match(matcher, word_match, token); - - matcher->word_index++; - - /* A vararg token should consume all left over words as arguments */ - if (token->terminal == TERMINAL_VARARG) - while (cmd_matcher_words_left(matcher)) - { - word = cmd_matcher_get_word(matcher); - if (word && strlen(word)) - push_argument(argc, argv, word); - matcher->word_index++; - } - - return MATCHER_OK; -} - -static enum matcher_rv -cmd_matcher_match_multiple(struct cmd_matcher *matcher, - struct cmd_token *token, - int *argc, const char **argv) -{ - enum match_type multiple_match; - unsigned int multiple_index; - const char *word; - const char *arg = NULL; - struct cmd_token *word_token; - enum match_type word_match; - - assert(token->type == TOKEN_MULTIPLE); - - multiple_match = no_match; - - if (!cmd_matcher_words_left(matcher)) - return MATCHER_INCOMPLETE; - - word = cmd_matcher_get_word(matcher); - for (multiple_index = 0; - multiple_index < vector_active(token->multiple); - multiple_index++) - { - word_token = vector_slot(token->multiple, multiple_index); - - word_match = cmd_word_match(word_token, matcher->filter, word); - if (word_match == no_match) - continue; - - cmd_matcher_record_match(matcher, word_match, word_token); - - if (word_match > multiple_match) - { - multiple_match = word_match; - arg = word; - } - /* To mimic the behavior of the old command implementation, we - * tolerate any ambiguities here :/ */ - } - - matcher->word_index++; - - if (multiple_match == no_match) - return MATCHER_NO_MATCH; - - if (push_argument(argc, argv, arg)) - return MATCHER_EXCEED_ARGC_MAX; - - return MATCHER_OK; -} - -static enum matcher_rv -cmd_matcher_read_keywords(struct cmd_matcher *matcher, - struct cmd_token *token, - vector args_vector) -{ - unsigned int i; - unsigned long keyword_mask; - unsigned int keyword_found; - enum match_type keyword_match; - enum match_type word_match; - vector keyword_vector; - struct cmd_token *word_token; - const char *word; - int keyword_argc; - const char **keyword_argv; - enum matcher_rv rv = MATCHER_OK; - - keyword_mask = 0; - while (1) - { - if (!cmd_matcher_words_left(matcher)) - return MATCHER_OK; - - word = cmd_matcher_get_word(matcher); - - keyword_found = -1; - keyword_match = no_match; - for (i = 0; i < vector_active(token->keyword); i++) - { - if (keyword_mask & (1 << i)) - continue; - - keyword_vector = vector_slot(token->keyword, i); - word_token = vector_slot(keyword_vector, 0); - - word_match = cmd_word_match(word_token, matcher->filter, word); - if (word_match == no_match) - continue; - - cmd_matcher_record_match(matcher, word_match, word_token); - - if (word_match > keyword_match) - { - keyword_match = word_match; - keyword_found = i; - } - else if (word_match == keyword_match) - { - if (matcher->word_index != matcher->index || args_vector) - return MATCHER_AMBIGUOUS; - } - } - - if (keyword_found == (unsigned int)-1) - return MATCHER_NO_MATCH; - - matcher->word_index++; - - if (matcher->word_index > matcher->index) - return MATCHER_OK; - - keyword_mask |= (1 << keyword_found); - - if (args_vector) - { - keyword_argc = 0; - keyword_argv = XMALLOC(MTYPE_TMP, (CMD_ARGC_MAX + 1) * sizeof(char*)); - /* We use -1 as a marker for unused fields as NULL might be a valid value */ - for (i = 0; i < CMD_ARGC_MAX + 1; i++) - keyword_argv[i] = (void*)-1; - vector_set_index(args_vector, keyword_found, keyword_argv); - } - else - { - keyword_argv = NULL; - } - - keyword_vector = vector_slot(token->keyword, keyword_found); - /* the keyword itself is at 0. We are only interested in the arguments, - * so start counting at 1. */ - for (i = 1; i < vector_active(keyword_vector); i++) - { - word_token = vector_slot(keyword_vector, i); - - switch (word_token->type) - { - case TOKEN_TERMINAL: - rv = cmd_matcher_match_terminal(matcher, word_token, - &keyword_argc, keyword_argv); - break; - case TOKEN_MULTIPLE: - rv = cmd_matcher_match_multiple(matcher, word_token, - &keyword_argc, keyword_argv); - break; - case TOKEN_KEYWORD: - assert(!"Keywords should never be nested."); - break; - } - - if (MATCHER_ERROR(rv)) - return rv; - - if (matcher->word_index > matcher->index) - return MATCHER_OK; - } - } - /* not reached */ -} - -static enum matcher_rv -cmd_matcher_build_keyword_args(struct cmd_matcher *matcher, - struct cmd_token *token, - int *argc, const char **argv, - vector keyword_args_vector) -{ - unsigned int i, j; - const char **keyword_args; - vector keyword_vector; - struct cmd_token *word_token; - const char *arg; - enum matcher_rv rv; - - rv = MATCHER_OK; - - if (keyword_args_vector == NULL) - return rv; - - for (i = 0; i < vector_active(token->keyword); i++) - { - keyword_vector = vector_slot(token->keyword, i); - keyword_args = vector_lookup(keyword_args_vector, i); - - if (vector_active(keyword_vector) == 1) - { - /* this is a keyword without arguments */ - if (keyword_args) - { - word_token = vector_slot(keyword_vector, 0); - arg = word_token->cmd; - XFREE (MTYPE_TMP, keyword_args); - } - else - { - arg = NULL; - } - - if (push_argument(argc, argv, arg)) - rv = MATCHER_EXCEED_ARGC_MAX; - } - else - { - /* this is a keyword with arguments */ - if (keyword_args) - { - /* the keyword was present, so just fill in the arguments */ - for (j = 0; keyword_args[j] != (void*)-1; j++) - if (push_argument(argc, argv, keyword_args[j])) - rv = MATCHER_EXCEED_ARGC_MAX; - XFREE(MTYPE_TMP, keyword_args); - } - else - { - /* the keyword was not present, insert NULL for the arguments - * the keyword would have taken. */ - for (j = 1; j < vector_active(keyword_vector); j++) - { - word_token = vector_slot(keyword_vector, j); - if ((word_token->type == TOKEN_TERMINAL - && TERMINAL_RECORD (word_token->terminal)) - || word_token->type == TOKEN_MULTIPLE) - { - if (push_argument(argc, argv, NULL)) - rv = MATCHER_EXCEED_ARGC_MAX; - } - } - } - } - } - vector_free(keyword_args_vector); - return rv; -} - -static enum matcher_rv -cmd_matcher_match_keyword(struct cmd_matcher *matcher, - struct cmd_token *token, - int *argc, const char **argv) -{ - vector keyword_args_vector; - enum matcher_rv reader_rv; - enum matcher_rv builder_rv; - - assert(token->type == TOKEN_KEYWORD); - - if (argc && argv) - keyword_args_vector = vector_init(VECTOR_MIN_SIZE); - else - keyword_args_vector = NULL; - - reader_rv = cmd_matcher_read_keywords(matcher, token, keyword_args_vector); - builder_rv = cmd_matcher_build_keyword_args(matcher, token, argc, - argv, keyword_args_vector); - /* keyword_args_vector is consumed by cmd_matcher_build_keyword_args */ - - if (!MATCHER_ERROR(reader_rv) && MATCHER_ERROR(builder_rv)) - return builder_rv; - - return reader_rv; -} - -static void -cmd_matcher_init(struct cmd_matcher *matcher, - struct cmd_element *cmd, - enum filter_type filter, - vector vline, - unsigned int index, - enum match_type *match_type, - vector *match) -{ - memset(matcher, 0, sizeof(*matcher)); - - matcher->cmd = cmd; - matcher->filter = filter; - matcher->vline = vline; - matcher->index = index; - - matcher->match_type = match_type; - if (matcher->match_type) - *matcher->match_type = no_match; - matcher->match = match; - - matcher->word_index = 0; -} - -static enum matcher_rv -cmd_element_match(struct cmd_element *cmd_element, - enum filter_type filter, - vector vline, - unsigned int index, - enum match_type *match_type, - vector *match, - int *argc, - const char **argv) -{ - struct cmd_matcher matcher; - unsigned int token_index; - enum matcher_rv rv = MATCHER_OK; - - cmd_matcher_init(&matcher, cmd_element, filter, - vline, index, match_type, match); - - if (argc != NULL) - *argc = 0; - - for (token_index = 0; - token_index < vector_active(cmd_element->tokens); - token_index++) - { - struct cmd_token *token = vector_slot(cmd_element->tokens, token_index); - - switch (token->type) - { - case TOKEN_TERMINAL: - rv = cmd_matcher_match_terminal(&matcher, token, argc, argv); - break; - case TOKEN_MULTIPLE: - rv = cmd_matcher_match_multiple(&matcher, token, argc, argv); - break; - case TOKEN_KEYWORD: - rv = cmd_matcher_match_keyword(&matcher, token, argc, argv); - } - - if (MATCHER_ERROR(rv)) - return rv; - - if (matcher.word_index > index) - return MATCHER_OK; - } - - /* return MATCHER_COMPLETE if all words were consumed */ - if (matcher.word_index >= vector_active(vline)) - return MATCHER_COMPLETE; - - /* return MATCHER_COMPLETE also if only an empty word is left. */ - if (matcher.word_index == vector_active(vline) - 1 - && (!vector_slot(vline, matcher.word_index) - || !strlen((char*)vector_slot(vline, matcher.word_index)))) - return MATCHER_COMPLETE; - - return MATCHER_NO_MATCH; /* command is too long to match */ -} - -/** - * Filter a given vector of commands against a given commandline and - * calculate possible completions. - * - * @param commands A vector of struct cmd_element*. Commands that don't - * match against the given command line will be overwritten - * with NULL in that vector. - * @param filter Either FILTER_RELAXED or FILTER_STRICT. This basically - * determines how incomplete commands are handled, compare with - * cmd_word_match for details. - * @param vline A vector of char* containing the tokenized commandline. - * @param index Only match up to the given token of the commandline. - * @param match_type Record the type of the best match here. - * @param matches Record the matches here. For each cmd_element in the commands - * vector, a match vector will be created in the matches vector. - * That vector will contain all struct command_token* of the - * cmd_element which matched against the given vline at the given - * index. - * @return A code specifying if an error occured. If all went right, it's - * CMD_SUCCESS. - */ -static int -cmd_vector_filter(vector commands, - enum filter_type filter, - vector vline, - unsigned int index, - enum match_type *match_type, - vector *matches) -{ - unsigned int i; - struct cmd_element *cmd_element; - enum match_type best_match; - enum match_type element_match; - enum matcher_rv matcher_rv; - - best_match = no_match; - *matches = vector_init(VECTOR_MIN_SIZE); - - for (i = 0; i < vector_active (commands); i++) - if ((cmd_element = vector_slot (commands, i)) != NULL) - { - vector_set_index(*matches, i, NULL); - matcher_rv = cmd_element_match(cmd_element, filter, - vline, index, - &element_match, - (vector*)&vector_slot(*matches, i), - NULL, NULL); - if (MATCHER_ERROR(matcher_rv)) - { - vector_slot(commands, i) = NULL; - if (matcher_rv == MATCHER_AMBIGUOUS) - return CMD_ERR_AMBIGUOUS; - if (matcher_rv == MATCHER_EXCEED_ARGC_MAX) - return CMD_ERR_EXEED_ARGC_MAX; - } - else if (element_match > best_match) - { - best_match = element_match; - } - } - *match_type = best_match; - return CMD_SUCCESS; -} - -/** - * Check whether a given commandline is complete if used for a specific - * cmd_element. - * - * @param cmd_element A cmd_element against which the commandline should be - * checked. - * @param vline The tokenized commandline. - * @return 1 if the given commandline is complete, 0 otherwise. - */ -static int -cmd_is_complete(struct cmd_element *cmd_element, - vector vline) -{ - enum matcher_rv rv; - - rv = cmd_element_match(cmd_element, - FILTER_RELAXED, - vline, -1, - NULL, NULL, - NULL, NULL); - return (rv == MATCHER_COMPLETE); -} - -/** - * Parse a given commandline and construct a list of arguments for the - * given command_element. - * - * @param cmd_element The cmd_element for which we want to construct arguments. - * @param vline The tokenized commandline. - * @param argc Where to store the argument count. - * @param argv Where to store the argument list. Should be at least - * CMD_ARGC_MAX elements long. - * @return CMD_SUCCESS if everything went alright, an error otherwise. - */ -static int -cmd_parse(struct cmd_element *cmd_element, - vector vline, - int *argc, const char **argv) -{ - enum matcher_rv rv = cmd_element_match(cmd_element, - FILTER_RELAXED, - vline, -1, - NULL, NULL, - argc, argv); - switch (rv) - { - case MATCHER_COMPLETE: - return CMD_SUCCESS; - - case MATCHER_NO_MATCH: - return CMD_ERR_NO_MATCH; - - case MATCHER_AMBIGUOUS: - return CMD_ERR_AMBIGUOUS; - - case MATCHER_EXCEED_ARGC_MAX: - return CMD_ERR_EXEED_ARGC_MAX; - - default: - return CMD_ERR_INCOMPLETE; - } -} - -/* Check ambiguous match */ -static int -is_cmd_ambiguous (vector cmd_vector, - const char *command, - vector matches, - enum match_type type) -{ - unsigned int i; - unsigned int j; - const char *str = NULL; - const char *matched = NULL; - vector match_vector; - struct cmd_token *cmd_token; - - if (command == NULL) - command = ""; - - for (i = 0; i < vector_active (matches); i++) - if ((match_vector = vector_slot (matches, i)) != NULL) - { - int match = 0; - - for (j = 0; j < vector_active (match_vector); j++) - if ((cmd_token = vector_slot (match_vector, j)) != NULL) - { - enum match_type ret; - - assert(cmd_token->type == TOKEN_TERMINAL); - if (cmd_token->type != TOKEN_TERMINAL) - continue; - - str = cmd_token->cmd; - - switch (type) - { - case exact_match: - if (!TERMINAL_RECORD (cmd_token->terminal) - && strcmp (command, str) == 0) - match++; - break; - case partly_match: - if (!TERMINAL_RECORD (cmd_token->terminal) - && strncmp (command, str, strlen (command)) == 0) - { - if (matched && strcmp (matched, str) != 0) - return 1; /* There is ambiguous match. */ - else - matched = str; - match++; - } - break; - case range_match: - if (cmd_range_match (str, command)) - { - if (matched && strcmp (matched, str) != 0) - return 1; - else - matched = str; - match++; - } - break; -#ifdef HAVE_IPV6 - case ipv6_match: - if (cmd_token->terminal == TERMINAL_IPV6) - match++; - break; - case ipv6_prefix_match: - if ((ret = cmd_ipv6_prefix_match (command)) != no_match) - { - if (ret == partly_match) - return 2; /* There is incomplete match. */ - - match++; - } - break; -#endif /* HAVE_IPV6 */ - case ipv4_match: - if (cmd_token->terminal == TERMINAL_IPV4) - match++; - break; - case ipv4_prefix_match: - if ((ret = cmd_ipv4_prefix_match (command)) != no_match) - { - if (ret == partly_match) - return 2; /* There is incomplete match. */ - - match++; - } - break; - case extend_match: - if (TERMINAL_RECORD (cmd_token->terminal)) - match++; - break; - case no_match: - default: - break; - } - } - if (!match) - vector_slot (cmd_vector, i) = NULL; - } - return 0; -} - -/* If src matches dst return dst string, otherwise return NULL */ -static const char * -cmd_entry_function (const char *src, struct cmd_token *token) -{ - const char *dst = token->cmd; - - /* Skip variable arguments. */ - if (TERMINAL_RECORD (token->terminal)) - return NULL; - - /* In case of 'command \t', given src is NULL string. */ - if (src == NULL) - return dst; - - /* Matched with input string. */ - if (strncmp (src, dst, strlen (src)) == 0) - return dst; - - return NULL; -} - -/* If src matches dst return dst string, otherwise return NULL */ -/* This version will return the dst string always if it is - CMD_VARIABLE for '?' key processing */ -static const char * -cmd_entry_function_desc (const char *src, struct cmd_token *token) -{ - const char *dst = token->cmd; - - switch (token->terminal) - { - case TERMINAL_VARARG: - return dst; - - case TERMINAL_RANGE: - if (cmd_range_match (dst, src)) - return dst; - else - return NULL; - - case TERMINAL_IPV6: - if (cmd_ipv6_match (src)) - return dst; - else - return NULL; - - case TERMINAL_IPV6_PREFIX: - if (cmd_ipv6_prefix_match (src)) - return dst; - else - return NULL; - - case TERMINAL_IPV4: - if (cmd_ipv4_match (src)) - return dst; - else - return NULL; - - case TERMINAL_IPV4_PREFIX: - if (cmd_ipv4_prefix_match (src)) - return dst; - else - return NULL; - - /* Optional or variable commands always match on '?' */ - case TERMINAL_OPTION: - case TERMINAL_VARIABLE: - return dst; - - case TERMINAL_LITERAL: - /* In case of 'command \t', given src is NULL string. */ - if (src == NULL) - return dst; - - if (strncmp (src, dst, strlen (src)) == 0) - return dst; - else - return NULL; - - default: - assert(0); - return NULL; - } -} - -/** - * Check whether a string is already present in a vector of strings. - * @param v A vector of char*. - * @param str A char*. - * @return 0 if str is already present in the vector, 1 otherwise. - */ -static int -cmd_unique_string (vector v, const char *str) -{ - unsigned int i; - char *match; - - for (i = 0; i < vector_active (v); i++) - if ((match = vector_slot (v, i)) != NULL) - if (strcmp (match, str) == 0) - return 0; - return 1; -} - -/** - * Check whether a struct cmd_token matching a given string is already - * present in a vector of struct cmd_token. - * @param v A vector of struct cmd_token*. - * @param str A char* which should be searched for. - * @return 0 if there is a struct cmd_token* with its cmd matching str, - * 1 otherwise. - */ -static int -desc_unique_string (vector v, const char *str) -{ - unsigned int i; - struct cmd_token *token; - - for (i = 0; i < vector_active (v); i++) - if ((token = vector_slot (v, i)) != NULL) - if (strcmp (token->cmd, str) == 0) - return 0; - return 1; -} - -static int -cmd_try_do_shortcut (enum node_type node, char* first_word) { - if ( first_word != NULL && - node != AUTH_NODE && - node != VIEW_NODE && - node != AUTH_ENABLE_NODE && - node != ENABLE_NODE && - 0 == strcmp( "do", first_word ) ) - return 1; - return 0; -} - -static void -cmd_matches_free(vector *matches) -{ - unsigned int i; - vector cmd_matches; - - for (i = 0; i < vector_active(*matches); i++) - if ((cmd_matches = vector_slot(*matches, i)) != NULL) - vector_free(cmd_matches); - vector_free(*matches); - *matches = NULL; -} - -static int -cmd_describe_cmp(const void *a, const void *b) -{ - const struct cmd_token *first = *(struct cmd_token * const *)a; - const struct cmd_token *second = *(struct cmd_token * const *)b; - - return strcmp(first->cmd, second->cmd); -} - -static void -cmd_describe_sort(vector matchvec) -{ - qsort(matchvec->index, vector_active(matchvec), - sizeof(void*), cmd_describe_cmp); -} - -/* '?' describe command support. */ -static vector -cmd_describe_command_real (vector vline, struct vty *vty, int *status) -{ - unsigned int i; - vector cmd_vector; -#define INIT_MATCHVEC_SIZE 10 - vector matchvec; - struct cmd_element *cmd_element; - unsigned int index; - int ret; - enum match_type match; - char *command; - vector matches = NULL; - vector match_vector; - uint32_t command_found = 0; - const char *last_word; - - /* Set index. */ - if (vector_active (vline) == 0) - { - *status = CMD_ERR_NO_MATCH; - return NULL; - } - - index = vector_active (vline) - 1; - - /* Make copy vector of current node's command vector. */ - cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node)); - - /* Prepare match vector */ - matchvec = vector_init (INIT_MATCHVEC_SIZE); - - /* Filter commands and build a list how they could possibly continue. */ - for (i = 0; i <= index; i++) - { - command = vector_slot (vline, i); - - if (matches) - cmd_matches_free(&matches); - - ret = cmd_vector_filter(cmd_vector, - FILTER_RELAXED, - vline, i, - &match, - &matches); - - if (ret != CMD_SUCCESS) - { - vector_free (cmd_vector); - vector_free (matchvec); - cmd_matches_free(&matches); - *status = ret; - return NULL; - } - - /* The last match may well be ambigious, so break here */ - if (i == index) - break; - - if (match == vararg_match) - { - /* We found a vararg match - so we can throw out the current matches here - * and don't need to continue checking the command input */ - unsigned int j, k; - - for (j = 0; j < vector_active (matches); j++) - if ((match_vector = vector_slot (matches, j)) != NULL) - for (k = 0; k < vector_active (match_vector); k++) - { - struct cmd_token *token = vector_slot (match_vector, k); - vector_set (matchvec, token); - } - - *status = CMD_SUCCESS; - vector_set(matchvec, &token_cr); - vector_free (cmd_vector); - cmd_matches_free(&matches); - cmd_describe_sort(matchvec); - return matchvec; - } - - ret = is_cmd_ambiguous(cmd_vector, command, matches, match); - if (ret == 1) - { - vector_free (cmd_vector); - vector_free (matchvec); - cmd_matches_free(&matches); - *status = CMD_ERR_AMBIGUOUS; - return NULL; - } - else if (ret == 2) - { - vector_free (cmd_vector); - vector_free (matchvec); - cmd_matches_free(&matches); - *status = CMD_ERR_NO_MATCH; - return NULL; - } - } - - /* Make description vector. */ - for (i = 0; i < vector_active (matches); i++) { - if ((cmd_element = vector_slot (cmd_vector, i)) != NULL && - !(cmd_element->attr == CMD_ATTR_DEPRECATED || - cmd_element->attr == CMD_ATTR_HIDDEN)) - { - unsigned int j; - vector vline_trimmed; - - command_found++; - last_word = vector_slot(vline, vector_active(vline) - 1); - if (last_word == NULL || !strlen(last_word)) - { - vline_trimmed = vector_copy(vline); - vector_unset(vline_trimmed, vector_active(vline_trimmed) - 1); - - if (cmd_is_complete(cmd_element, vline_trimmed) - && desc_unique_string(matchvec, command_cr)) - { - if (match != vararg_match) - vector_set(matchvec, &token_cr); - } - - vector_free(vline_trimmed); - } - - match_vector = vector_slot (matches, i); - if (match_vector) - for (j = 0; j < vector_active(match_vector); j++) - { - struct cmd_token *token = vector_slot(match_vector, j); - const char *string; - - string = cmd_entry_function_desc(command, token); - if (string && desc_unique_string(matchvec, string)) - vector_set(matchvec, token); - } - } - } - - /* - * We can get into this situation when the command is complete - * but the last part of the command is an optional piece of - * cli. - */ - last_word = vector_slot(vline, vector_active(vline) - 1); - if (command_found == 0 && (last_word == NULL || !strlen(last_word))) { - vector_set(matchvec, &token_cr); - } - - vector_free (cmd_vector); - cmd_matches_free(&matches); - - if (vector_slot (matchvec, 0) == NULL) - { - vector_free (matchvec); - *status = CMD_ERR_NO_MATCH; - return NULL; - } - - *status = CMD_SUCCESS; - cmd_describe_sort(matchvec); - return matchvec; -} - -vector -cmd_describe_command (vector vline, struct vty *vty, int *status) -{ - vector ret; - - if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) ) - { - enum node_type onode; - vector shifted_vline; - unsigned int index; - - onode = vty->node; - vty->node = ENABLE_NODE; - /* We can try it on enable node, cos' the vty is authenticated */ - - shifted_vline = vector_init (vector_count(vline)); - /* use memcpy? */ - for (index = 1; index < vector_active (vline); index++) - { - vector_set_index (shifted_vline, index-1, vector_lookup(vline, index)); - } - - ret = cmd_describe_command_real (shifted_vline, vty, status); - - vector_free(shifted_vline); - vty->node = onode; - return ret; - } - - - return cmd_describe_command_real (vline, vty, status); -} - - -/* Check LCD of matched command. */ -static int -cmd_lcd (char **matched) -{ - int i; - int j; - int lcd = -1; - char *s1, *s2; - char c1, c2; - - if (matched[0] == NULL || matched[1] == NULL) - return 0; - - for (i = 1; matched[i] != NULL; i++) - { - s1 = matched[i - 1]; - s2 = matched[i]; - - for (j = 0; (c1 = s1[j]) && (c2 = s2[j]); j++) - if (c1 != c2) - break; - - if (lcd < 0) - lcd = j; - else - { - if (lcd > j) - lcd = j; - } - } - return lcd; -} - -static int -cmd_complete_cmp(const void *a, const void *b) -{ - const char *first = *(char * const *)a; - const char *second = *(char * const *)b; - - if (!first) - { - if (!second) - return 0; - return 1; - } - if (!second) - return -1; - - return strcmp(first, second); -} - -static void -cmd_complete_sort(vector matchvec) -{ - qsort(matchvec->index, vector_active(matchvec), - sizeof(void*), cmd_complete_cmp); -} - -/* Command line completion support. */ -static char ** -cmd_complete_command_real (vector vline, struct vty *vty, int *status, int islib) -{ - unsigned int i; - vector cmd_vector = vector_copy (cmd_node_vector (cmdvec, vty->node)); -#define INIT_MATCHVEC_SIZE 10 - vector matchvec; - unsigned int index; - char **match_str; - struct cmd_token *token; - char *command; - int lcd; - vector matches = NULL; - vector match_vector; - - if (vector_active (vline) == 0) - { - vector_free (cmd_vector); - *status = CMD_ERR_NO_MATCH; - return NULL; - } - else - index = vector_active (vline) - 1; - - /* First, filter by command string */ - for (i = 0; i <= index; i++) - { - command = vector_slot (vline, i); - enum match_type match; - int ret; - - if (matches) - cmd_matches_free(&matches); - - /* First try completion match, if there is exactly match return 1 */ - ret = cmd_vector_filter(cmd_vector, - FILTER_RELAXED, - vline, i, - &match, - &matches); - - if (ret != CMD_SUCCESS) - { - vector_free(cmd_vector); - cmd_matches_free(&matches); - *status = ret; - return NULL; - } - - /* Break here - the completion mustn't be checked to be non-ambiguous */ - if (i == index) - break; - - /* If there is exact match then filter ambiguous match else check - ambiguousness. */ - ret = is_cmd_ambiguous (cmd_vector, command, matches, match); - if (ret == 1) - { - vector_free (cmd_vector); - cmd_matches_free(&matches); - *status = CMD_ERR_AMBIGUOUS; - return NULL; - } - } - - /* Prepare match vector. */ - matchvec = vector_init (INIT_MATCHVEC_SIZE); - - /* Build the possible list of continuations into a list of completions */ - for (i = 0; i < vector_active (matches); i++) - if ((match_vector = vector_slot (matches, i))) - { - const char *string; - unsigned int j; - - for (j = 0; j < vector_active (match_vector); j++) - if ((token = vector_slot (match_vector, j))) - { - string = cmd_entry_function (vector_slot (vline, index), - token); - if (string && cmd_unique_string (matchvec, string)) - vector_set (matchvec, (islib != 0 ? - XSTRDUP (MTYPE_TMP, string) : - strdup (string) /* rl freed */)); - } - } - - /* We don't need cmd_vector any more. */ - vector_free (cmd_vector); - cmd_matches_free(&matches); - - /* No matched command */ - if (vector_slot (matchvec, 0) == NULL) - { - vector_free (matchvec); - - /* In case of 'command \t' pattern. Do you need '?' command at - the end of the line. */ - if (vector_slot (vline, index) == '\0') - *status = CMD_ERR_NOTHING_TODO; - else - *status = CMD_ERR_NO_MATCH; - return NULL; - } - - /* Only one matched */ - if (vector_slot (matchvec, 1) == NULL) - { - size_t index_size = matchvec->alloced * sizeof (void *); - match_str = XMALLOC (MTYPE_TMP, index_size); - memcpy (match_str, matchvec->index, index_size); - vector_free (matchvec); - - *status = CMD_COMPLETE_FULL_MATCH; - return match_str; - } - /* Make it sure last element is NULL. */ - vector_set (matchvec, NULL); - - /* Check LCD of matched strings. */ - if (vector_slot (vline, index) != NULL) - { - lcd = cmd_lcd ((char **) matchvec->index); - - if (lcd) - { - int len = strlen (vector_slot (vline, index)); - - if (len < lcd) - { - char *lcdstr; - - lcdstr = (islib != 0 ? - XMALLOC (MTYPE_TMP, lcd + 1) : - malloc(lcd + 1)); - memcpy (lcdstr, matchvec->index[0], lcd); - lcdstr[lcd] = '\0'; - - /* Free matchvec. */ - for (i = 0; i < vector_active (matchvec); i++) - { - if (vector_slot (matchvec, i)) - { - if (islib != 0) - XFREE (MTYPE_TMP, vector_slot (matchvec, i)); - else - free (vector_slot (matchvec, i)); - } - } - vector_free (matchvec); - - /* Make new matchvec. */ - matchvec = vector_init (INIT_MATCHVEC_SIZE); - vector_set (matchvec, lcdstr); - - size_t index_size = matchvec->alloced * sizeof (void *); - match_str = XMALLOC (MTYPE_TMP, index_size); - memcpy (match_str, matchvec->index, index_size); - vector_free (matchvec); - - *status = CMD_COMPLETE_MATCH; - return match_str; - } - } - } - - match_str = (char **) matchvec->index; - cmd_complete_sort(matchvec); - vector_only_wrapper_free (matchvec); - *status = CMD_COMPLETE_LIST_MATCH; - return match_str; -} - -char ** -cmd_complete_command_lib (vector vline, struct vty *vty, int *status, int islib) -{ - char **ret; - - if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) ) - { - enum node_type onode; - vector shifted_vline; - unsigned int index; - - onode = vty->node; - vty->node = ENABLE_NODE; - /* We can try it on enable node, cos' the vty is authenticated */ - - shifted_vline = vector_init (vector_count(vline)); - /* use memcpy? */ - for (index = 1; index < vector_active (vline); index++) - { - vector_set_index (shifted_vline, index-1, vector_lookup(vline, index)); - } - - ret = cmd_complete_command_real (shifted_vline, vty, status, islib); - - vector_free(shifted_vline); - vty->node = onode; - return ret; - } - - return cmd_complete_command_real (vline, vty, status, islib); -} - -char ** -cmd_complete_command (vector vline, struct vty *vty, int *status) +char ** +cmd_complete_command (vector vline, struct vty *vty, int *status) { return cmd_complete_command_lib (vline, vty, status, 0); } @@@ -695,6 -2535,9 +692,9 @@@ node_parent ( enum node_type node case BGP_VPNV6_NODE: case BGP_ENCAP_NODE: case BGP_ENCAPV6_NODE: + case BGP_VNC_DEFAULTS_NODE: - case BGP_VNC_NVE_GROUP_NODE: - case BGP_VNC_L2_GROUP_NODE: ++ case BGP_VNC_NVE_GROUP_NODE: ++ case BGP_VNC_L2_GROUP_NODE: case BGP_IPV4_NODE: case BGP_IPV4M_NODE: case BGP_IPV6_NODE: @@@ -999,11 -2914,10 +1012,10 @@@ DEFUN (config_exit { case VIEW_NODE: case ENABLE_NODE: - case RESTRICTED_NODE: if (vty_shell (vty)) - exit (0); + exit (0); else - vty->status = VTY_CLOSE; + vty->status = VTY_CLOSE; break; case CONFIG_NODE: vty->node = ENABLE_NODE; @@@ -1719,12 -3628,13 +1758,13 @@@ DEFUN (config_logmsg int level; char *message; - if ((level = level_match(argv[0])) == ZLOG_DISABLED) + if ((level = level_match(argv[idx_log_level]->arg)) == ZLOG_DISABLED) return CMD_ERR_NO_MATCH; - zlog(NULL, level, "%s", ((message = argv_concat(argv, argc, 1)) ? message : "")); + zlog(NULL, level, "%s", ((message = argv_concat(argv, argc, idx_message)) ? message : "")); if (message) XFREE(MTYPE_TMP, message); + return CMD_SUCCESS; } @@@ -2195,6 -4174,14 +2235,8 @@@ install_default (enum node_type node void cmd_init (int terminal) { + qobj_init (); + - command_cr = XSTRDUP(MTYPE_CMD_TOKENS, ""); - token_cr.type = TOKEN_TERMINAL; - token_cr.terminal = TERMINAL_LITERAL; - token_cr.cmd = command_cr; - token_cr.desc = XSTRDUP(MTYPE_CMD_TOKENS, ""); - /* Allocate initial top vector of commands. */ cmdvec = vector_init (VECTOR_MIN_SIZE); @@@ -2243,26 -4220,24 +2275,21 @@@ if (terminal) { - install_default (ENABLE_NODE); + install_element (ENABLE_NODE, &config_end_cmd); install_element (ENABLE_NODE, &config_disable_cmd); install_element (ENABLE_NODE, &config_terminal_cmd); - install_element (ENABLE_NODE, ©_runningconfig_startupconfig_cmd); - install_element (ENABLE_NODE, &config_write_terminal_cmd); - install_element (ENABLE_NODE, &config_write_file_cmd); - install_element (ENABLE_NODE, &config_write_memory_cmd); + install_element (ENABLE_NODE, ©_runningconf_startupconf_cmd); + install_element (ENABLE_NODE, &config_write_cmd); + install_element (ENABLE_NODE, &show_running_config_cmd); } install_element (ENABLE_NODE, &show_startup_config_cmd); - install_element (ENABLE_NODE, &show_version_cmd); - install_element (ENABLE_NODE, &show_commandtree_cmd); if (terminal) { - install_element (ENABLE_NODE, &config_terminal_length_cmd); - install_element (ENABLE_NODE, &config_terminal_no_length_cmd); - install_element (ENABLE_NODE, &show_logging_cmd); - install_element (ENABLE_NODE, &echo_cmd); install_element (ENABLE_NODE, &config_logmsg_cmd); - install_default (CONFIG_NODE); } - + install_element (CONFIG_NODE, &hostname_cmd); install_element (CONFIG_NODE, &no_hostname_cmd); @@@ -2297,12 -4281,9 +2324,9 @@@ install_element (CONFIG_NODE, &no_service_terminal_length_cmd); install_element (VIEW_NODE, &show_thread_cpu_cmd); - install_element (ENABLE_NODE, &show_thread_cpu_cmd); - install_element (RESTRICTED_NODE, &show_thread_cpu_cmd); - + install_element (ENABLE_NODE, &clear_thread_cpu_cmd); install_element (VIEW_NODE, &show_work_queues_cmd); - install_element (ENABLE_NODE, &show_work_queues_cmd); vrf_install_commands (); } diff --cc lib/command.h index e411e9c18c,fd0918f118..3c1008d4eb --- a/lib/command.h +++ b/lib/command.h @@@ -67,56 -66,68 +67,68 @@@ struct hos }; /* There are some command levels which called from command node. */ -enum node_type +enum node_type { - AUTH_NODE, /* Authentication mode of vty interface. */ - VIEW_NODE, /* View node. Default mode of vty interface. */ - AUTH_ENABLE_NODE, /* Authentication mode for change enable. */ - ENABLE_NODE, /* Enable node. */ - CONFIG_NODE, /* Config node. Default mode of config file. */ - SERVICE_NODE, /* Service node. */ - DEBUG_NODE, /* Debug node. */ + AUTH_NODE, /* Authentication mode of vty interface. */ - RESTRICTED_NODE, /* Restricted view mode */ + VIEW_NODE, /* View node. Default mode of vty interface. */ + AUTH_ENABLE_NODE, /* Authentication mode for change enable. */ + ENABLE_NODE, /* Enable node. */ + CONFIG_NODE, /* Config node. Default mode of config file. */ + SERVICE_NODE, /* Service node. */ + DEBUG_NODE, /* Debug node. */ VRF_DEBUG_NODE, /* Vrf Debug node. */ + DEBUG_VNC_NODE, /* Debug VNC node. */ - AAA_NODE, /* AAA node. */ - KEYCHAIN_NODE, /* Key-chain node. */ - KEYCHAIN_KEY_NODE, /* Key-chain key node. */ - NS_NODE, /* Logical-Router node. */ - VRF_NODE, /* VRF mode node. */ - INTERFACE_NODE, /* Interface mode node. */ - ZEBRA_NODE, /* zebra connection node. */ - TABLE_NODE, /* rtm_table selection node. */ - RIP_NODE, /* RIP protocol mode node. */ - RIPNG_NODE, /* RIPng protocol mode node. */ - BGP_NODE, /* BGP protocol mode which includes BGP4+ */ - BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */ - BGP_VPNV6_NODE, /* BGP MPLS-VPN PE exchange. */ - BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */ - BGP_IPV4M_NODE, /* BGP IPv4 multicast address family. */ - BGP_IPV6_NODE, /* BGP IPv6 address family */ - BGP_IPV6M_NODE, /* BGP IPv6 multicast address family. */ - BGP_ENCAP_NODE, /* BGP ENCAP SAFI */ - BGP_ENCAPV6_NODE, /* BGP ENCAP SAFI */ + AAA_NODE, /* AAA node. */ + KEYCHAIN_NODE, /* Key-chain node. */ + KEYCHAIN_KEY_NODE, /* Key-chain key node. */ + NS_NODE, /* Logical-Router node. */ + VRF_NODE, /* VRF mode node. */ + INTERFACE_NODE, /* Interface mode node. */ + ZEBRA_NODE, /* zebra connection node. */ + TABLE_NODE, /* rtm_table selection node. */ + RIP_NODE, /* RIP protocol mode node. */ + RIPNG_NODE, /* RIPng protocol mode node. */ + BGP_NODE, /* BGP protocol mode which includes BGP4+ */ + BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */ + BGP_VPNV6_NODE, /* BGP MPLS-VPN PE exchange. */ + BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */ + BGP_IPV4M_NODE, /* BGP IPv4 multicast address family. */ + BGP_IPV6_NODE, /* BGP IPv6 address family */ + BGP_IPV6M_NODE, /* BGP IPv6 multicast address family. */ + BGP_ENCAP_NODE, /* BGP ENCAP SAFI */ + BGP_ENCAPV6_NODE, /* BGP ENCAP SAFI */ + BGP_VNC_DEFAULTS_NODE, /* BGP VNC nve defaults */ + BGP_VNC_NVE_GROUP_NODE, /* BGP VNC nve group */ + BGP_VNC_L2_GROUP_NODE, /* BGP VNC L2 group */ + RFP_DEFAULTS_NODE, /* RFP defaults node */ - OSPF_NODE, /* OSPF protocol mode */ - OSPF6_NODE, /* OSPF protocol for IPv6 mode */ + OSPF_NODE, /* OSPF protocol mode */ + OSPF6_NODE, /* OSPF protocol for IPv6 mode */ + LDP_NODE, /* LDP protocol mode */ + LDP_IPV4_NODE, /* LDP IPv4 address family */ + LDP_IPV6_NODE, /* LDP IPv6 address family */ + LDP_IPV4_IFACE_NODE, /* LDP IPv4 Interface */ + LDP_IPV6_IFACE_NODE, /* LDP IPv6 Interface */ + LDP_L2VPN_NODE, /* LDP L2VPN node */ + LDP_PSEUDOWIRE_NODE, /* LDP Pseudowire node */ - ISIS_NODE, /* ISIS protocol mode */ - PIM_NODE, /* PIM protocol mode */ - MASC_NODE, /* MASC for multicast. */ - IRDP_NODE, /* ICMP Router Discovery Protocol mode. */ - IP_NODE, /* Static ip route node. */ - ACCESS_NODE, /* Access list node. */ - PREFIX_NODE, /* Prefix list node. */ - ACCESS_IPV6_NODE, /* Access list node. */ - PREFIX_IPV6_NODE, /* Prefix list node. */ - AS_LIST_NODE, /* AS list node. */ - COMMUNITY_LIST_NODE, /* Community list node. */ - RMAP_NODE, /* Route map node. */ - SMUX_NODE, /* SNMP configuration node. */ - DUMP_NODE, /* Packet dump node. */ - FORWARDING_NODE, /* IP forwarding node. */ + ISIS_NODE, /* ISIS protocol mode */ + PIM_NODE, /* PIM protocol mode */ + MASC_NODE, /* MASC for multicast. */ + IRDP_NODE, /* ICMP Router Discovery Protocol mode. */ + IP_NODE, /* Static ip route node. */ + ACCESS_NODE, /* Access list node. */ + PREFIX_NODE, /* Prefix list node. */ + ACCESS_IPV6_NODE, /* Access list node. */ + PREFIX_IPV6_NODE, /* Prefix list node. */ + AS_LIST_NODE, /* AS list node. */ + COMMUNITY_LIST_NODE, /* Community list node. */ + RMAP_NODE, /* Route map node. */ + SMUX_NODE, /* SNMP configuration node. */ + DUMP_NODE, /* Packet dump node. */ + FORWARDING_NODE, /* IP forwarding node. */ PROTOCOL_NODE, /* protocol filtering node */ + MPLS_NODE, /* MPLS config node */ - VTY_NODE, /* Vty node. */ - LINK_PARAMS_NODE, /* Link-parameters node */ + VTY_NODE, /* Vty node. */ + LINK_PARAMS_NODE, /* Link-parameters node */ }; /* Node which has some commands and prompt string and configuration diff --cc lib/distribute.c index 8a00833915,498410c22d..8726e993c5 --- a/lib/distribute.c +++ b/lib/distribute.c @@@ -185,27 -191,13 +189,13 @@@ distribute_list_unset (const char *ifna if (!dist) return 0; - if (type == DISTRIBUTE_IN) - { - if (!dist->list[DISTRIBUTE_IN]) + if (!dist->list[type]) - return 0; + return 0; - if (strcmp (dist->list[DISTRIBUTE_IN], alist_name) != 0) + if (strcmp (dist->list[type], alist_name) != 0) - return 0; + return 0; - XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_IN]); - dist->list[DISTRIBUTE_IN] = NULL; - } - - if (type == DISTRIBUTE_OUT) - { - if (!dist->list[DISTRIBUTE_OUT]) - return 0; - if (strcmp (dist->list[DISTRIBUTE_OUT], alist_name) != 0) - return 0; - - XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[DISTRIBUTE_OUT]); - dist->list[DISTRIBUTE_OUT] = NULL; - } + XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]); + dist->list[type] = NULL; /* Apply this distribute-list to the interface. */ (*distribute_delete_hook) (dist); @@@ -261,27 -238,13 +234,13 @@@ distribute_list_prefix_unset (const cha if (!dist) return 0; - if (type == DISTRIBUTE_IN) - { - if (!dist->prefix[DISTRIBUTE_IN]) - return 0; - if (strcmp (dist->prefix[DISTRIBUTE_IN], plist_name) != 0) - return 0; - - XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_IN]); - dist->prefix[DISTRIBUTE_IN] = NULL; - } - - if (type == DISTRIBUTE_OUT) - { - if (!dist->prefix[DISTRIBUTE_OUT]) + if (!dist->prefix[type]) - return 0; + return 0; - if (strcmp (dist->prefix[DISTRIBUTE_OUT], plist_name) != 0) + if (strcmp (dist->prefix[type], plist_name) != 0) - return 0; + return 0; - XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[DISTRIBUTE_OUT]); - dist->prefix[DISTRIBUTE_OUT] = NULL; - } + XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]); + dist->prefix[type] = NULL; /* Apply this distribute-list to the interface. */ (*distribute_delete_hook) (dist); @@@ -308,30 -402,64 +259,61 @@@ DEFUN (distribute_list "Filter outgoing routing updates\n" "Interface name\n") { - enum distribute_type type; + int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0; /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V4_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V4_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE); - return CMD_WARNING; - } + enum distribute_type type = argv[2 + prefix]->arg[0] == 'i' ? - DISTRIBUTE_IN : DISTRIBUTE_OUT; ++ DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT; + + /* Set appropriate function call */ + void (*distfn)(const char *, enum distribute_type, const char *) = prefix ? + &distribute_list_prefix_set : &distribute_list_set; + + /* if interface is present, get name */ + const char *ifname = NULL; + if (argv[argc - 1]->type == VARIABLE_TKN) + ifname = argv[argc - 1]->arg; /* Get interface name corresponding distribute list. */ - distribute_list_set (argv[2], type, argv[0]); + distfn (ifname, type, argv[1 + prefix]->arg); return CMD_SUCCESS; } + DEFUN (ipv6_distribute_list, + ipv6_distribute_list_cmd, - "ipv6 distribute-list WORD (in|out) WORD", ++ "ipv6 distribute-list [prefix] WORD [WORD]", ++ "IPv6\n" + "Filter networks in routing updates\n" + "Access-list name\n" + "Filter incoming routing updates\n" + "Filter outgoing routing updates\n" + "Interface name\n") + { - enum distribute_type type; ++ int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0; + + /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V6_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V6_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE); - return CMD_WARNING; - } ++ enum distribute_type type = argv[3 + prefix]->arg[0] == 'i' ? ++ DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT; ++ ++ /* Set appropriate function call */ ++ void (*distfn)(const char *, enum distribute_type, const char *) = prefix ? ++ &distribute_list_prefix_set : &distribute_list_set; ++ ++ /* if interface is present, get name */ ++ const char *ifname = NULL; ++ if (argv[argc - 1]->type == VARIABLE_TKN) ++ ifname = argv[argc - 1]->arg; + + /* Get interface name corresponding distribute list. */ - distribute_list_set (argv[2], type, argv[0]); ++ distfn (ifname, type, argv[1 + prefix]->arg); + + return CMD_SUCCESS; + } - -ALIAS (ipv6_distribute_list, - ipv6_as_v4_distribute_list_cmd, - "distribute-list WORD (in|out) WORD", - "Filter networks in routing updates\n" - "Access-list name\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") - -DEFUN (no_distribute_list, no_distribute_list_cmd, - "no distribute-list WORD (in|out) WORD", ++ +DEFUN (no_distribute_list, + no_distribute_list_cmd, - "no distribute-list [prefix] WORD [WORD]", ++ "no [ipv6] distribute-list [prefix] WORD [WORD]", NO_STR "Filter networks in routing updates\n" "Access-list name\n" @@@ -339,24 -467,312 +321,29 @@@ "Filter outgoing routing updates\n" "Interface name\n") { - int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0; - int ret; - enum distribute_type type; - - /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V4_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V4_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE); - return CMD_WARNING; - } - - ret = distribute_list_unset (argv[2], type, argv[0]); - if (! ret) - { - vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE); - return CMD_WARNING; - } - return CMD_SUCCESS; -} ++ int ipv6 = strmatch(argv[1]->text, "ipv6"); ++ int prefix = (argv[2 + ipv6]->type == WORD_TKN) ? 1 : 0; + -DEFUN (no_ipv6_distribute_list, - no_ipv6_distribute_list_cmd, - "no ipv6 distribute-list WORD (in|out) WORD", - NO_STR - "Filter networks in routing updates\n" - "Access-list name\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") -{ - int ret; - enum distribute_type type; ++ int idx_alname = 2 + ipv6 + prefix; ++ int idx_disttype = idx_alname + 1; /* Check of distribute list type. */ - enum distribute_type type = argv[3 + prefix]->arg[0] == 'i' ? - DISTRIBUTE_IN : DISTRIBUTE_OUT; - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V6_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V6_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", VTY_NEWLINE); - return CMD_WARNING; - } ++ enum distribute_type distin = (ipv6) ? DISTRIBUTE_V6_IN : DISTRIBUTE_V4_IN; ++ enum distribute_type distout = (ipv6) ? DISTRIBUTE_V6_OUT : DISTRIBUTE_V4_OUT; + - ret = distribute_list_unset (argv[2], type, argv[0]); - if (! ret) - { - vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE); - return CMD_WARNING; - } - return CMD_SUCCESS; -} - -ALIAS (no_ipv6_distribute_list, - no_ipv6_as_v4_distribute_list_cmd, - "no distribute-list WORD (in|out) WORD", - NO_STR - "Filter networks in routing updates\n" - "Access-list name\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") - -DEFUN (distribute_list_prefix_all, - distribute_list_prefix_all_cmd, - "distribute-list prefix WORD (in|out)", - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n") -{ - enum distribute_type type; - - /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V4_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V4_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - /* Get interface name corresponding distribute list. */ - distribute_list_prefix_set (NULL, type, argv[0]); - - return CMD_SUCCESS; -} - -DEFUN (ipv6_distribute_list_prefix_all, - ipv6_distribute_list_prefix_all_cmd, - "ipv6 distribute-list prefix WORD (in|out)", - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n") -{ - enum distribute_type type; - - /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V6_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V6_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - /* Get interface name corresponding distribute list. */ - distribute_list_prefix_set (NULL, type, argv[0]); - - return CMD_SUCCESS; -} - -ALIAS (ipv6_distribute_list_prefix_all, - ipv6_as_v4_distribute_list_prefix_all_cmd, - "distribute-list prefix WORD (in|out)", - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n") - -DEFUN (no_distribute_list_prefix_all, - no_distribute_list_prefix_all_cmd, - "no distribute-list prefix WORD (in|out)", - NO_STR - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n") -{ - int ret; - enum distribute_type type; - - /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V4_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V4_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - ret = distribute_list_prefix_unset (NULL, type, argv[0]); - if (! ret) - { - vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE); - return CMD_WARNING; - } - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_distribute_list_prefix_all, - no_ipv6_distribute_list_prefix_all_cmd, - "no ipv6 distribute-list prefix WORD (in|out)", - NO_STR - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n") -{ - int ret; - enum distribute_type type; - - /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V6_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V6_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - ret = distribute_list_prefix_unset (NULL, type, argv[0]); - if (! ret) - { - vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE); - return CMD_WARNING; - } - return CMD_SUCCESS; -} - -ALIAS (no_ipv6_distribute_list_prefix_all, - no_ipv6_as_v4_distribute_list_prefix_all_cmd, - "no distribute-list prefix WORD (in|out)", - NO_STR - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n") - -DEFUN (distribute_list_prefix, distribute_list_prefix_cmd, - "distribute-list prefix WORD (in|out) WORD", - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") -{ - enum distribute_type type; - - /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V4_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V4_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - /* Get interface name corresponding distribute list. */ - distribute_list_prefix_set (argv[2], type, argv[0]); - - return CMD_SUCCESS; -} - -DEFUN (ipv6_distribute_list_prefix, - ipv6_distribute_list_prefix_cmd, - "ipv6 distribute-list prefix WORD (in|out) WORD", - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") -{ - enum distribute_type type; - - /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V6_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V6_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", - VTY_NEWLINE); - return CMD_WARNING; - } ++ enum distribute_type type = argv[idx_disttype]->arg[0] == 'i' ? distin : distout; + /* Set appropriate function call */ + int (*distfn)(const char *, enum distribute_type, const char *) = prefix ? + &distribute_list_prefix_unset : &distribute_list_unset; + + /* if interface is present, get name */ + const char *ifname = NULL; + if (argv[argc - 1]->type == VARIABLE_TKN) + ifname = argv[argc - 1]->arg; - /* Get interface name corresponding distribute list. */ - distribute_list_prefix_set (argv[2], type, argv[0]); - - return CMD_SUCCESS; -} - -ALIAS (ipv6_distribute_list_prefix, - ipv6_as_v4_distribute_list_prefix_cmd, - "distribute-list prefix WORD (in|out) WORD", - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") - -DEFUN (no_distribute_list_prefix, no_distribute_list_prefix_cmd, - "no distribute-list prefix WORD (in|out) WORD", - NO_STR - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") -{ - int ret; - enum distribute_type type; + int ret = distfn (ifname, type, argv[2 + prefix]->arg); - /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V4_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V4_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - ret = distribute_list_prefix_unset (argv[2], type, argv[0]); if (! ret) { vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE); @@@ -365,6 -781,66 +352,20 @@@ return CMD_SUCCESS; } -DEFUN (no_ipv6_distribute_list_prefix, - no_ipv6_distribute_list_prefix_cmd, - "no ipv6 distribute-list prefix WORD (in|out) WORD", - NO_STR - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") -{ - int ret; - enum distribute_type type; - - /* Check of distribute list type. */ - if (strncmp (argv[1], "i", 1) == 0) - type = DISTRIBUTE_V6_IN; - else if (strncmp (argv[1], "o", 1) == 0) - type = DISTRIBUTE_V6_OUT; - else - { - vty_out (vty, "distribute list direction must be [in|out]%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - ret = distribute_list_prefix_unset (argv[2], type, argv[0]); - if (! ret) - { - vty_out (vty, "distribute list doesn't exist%s", VTY_NEWLINE); - return CMD_WARNING; - } - return CMD_SUCCESS; -} - -ALIAS (no_ipv6_distribute_list_prefix, - no_ipv6_as_v4_distribute_list_prefix_cmd, - "no distribute-list prefix WORD (in|out) WORD", - NO_STR - "Filter networks in routing updates\n" - "Filter prefixes in routing updates\n" - "Name of an IP prefix-list\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") - + static int + distribute_print (struct vty *vty, char *tab[], int is_prefix, + enum distribute_type type, int has_print) + { + if (tab[type]) { + vty_out (vty, "%s %s%s", + has_print ? "," : "", + is_prefix ? "(prefix-list) " : "", + tab[type]); + return 1; + } + return has_print; + } + int config_show_distribute (struct vty *vty) { @@@ -374,71 -851,89 +376,89 @@@ /* Output filter configuration. */ dist = distribute_lookup (NULL); - if (dist && (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT])) - { - vty_out(vty, " Outgoing update filter list for all interface is"); + vty_out (vty, " Outgoing update filter list for all interface is"); - if (dist->list[DISTRIBUTE_OUT]) - vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]); - if (dist->prefix[DISTRIBUTE_OUT]) - vty_out (vty, "%s (prefix-list) %s", - dist->list[DISTRIBUTE_OUT] ? "," : "", - dist->prefix[DISTRIBUTE_OUT]); - vty_out (vty, "%s", VTY_NEWLINE); + has_print = 0; + if (dist) + { + has_print = distribute_print(vty, dist->list, 0, + DISTRIBUTE_V4_OUT, has_print); + has_print = distribute_print(vty, dist->prefix, 1, + DISTRIBUTE_V4_OUT, has_print); + has_print = distribute_print(vty, dist->list, 0, + DISTRIBUTE_V6_OUT, has_print); + has_print = distribute_print(vty, dist->prefix, 1, + DISTRIBUTE_V6_OUT, has_print); } + if (has_print) + vty_out (vty, "%s", VTY_NEWLINE); else - vty_out (vty, " Outgoing update filter list for all interface is not set%s", VTY_NEWLINE); + vty_out (vty, " not set%s", VTY_NEWLINE); for (i = 0; i < disthash->size; i++) for (mp = disthash->index[i]; mp; mp = mp->next) { dist = mp->data; if (dist->ifname) - if (dist->list[DISTRIBUTE_OUT] || dist->prefix[DISTRIBUTE_OUT]) - { - vty_out (vty, " %s filtered by", dist->ifname); + { + vty_out (vty, " %s filtered by", dist->ifname); - if (dist->list[DISTRIBUTE_OUT]) - vty_out (vty, " %s", dist->list[DISTRIBUTE_OUT]); - if (dist->prefix[DISTRIBUTE_OUT]) - vty_out (vty, "%s (prefix-list) %s", - dist->list[DISTRIBUTE_OUT] ? "," : "", - dist->prefix[DISTRIBUTE_OUT]); + has_print = 0; + has_print = distribute_print(vty, dist->list, 0, + DISTRIBUTE_V4_OUT, has_print); + has_print = distribute_print(vty, dist->prefix, 1, + DISTRIBUTE_V4_OUT, has_print); + has_print = distribute_print(vty, dist->list, 0, + DISTRIBUTE_V6_OUT, has_print); + has_print = distribute_print(vty, dist->prefix, 1, + DISTRIBUTE_V6_OUT, has_print); + if (has_print) - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, "%s", VTY_NEWLINE); + else + vty_out(vty, " nothing%s", VTY_NEWLINE); - } + } } /* Input filter configuration. */ dist = distribute_lookup (NULL); - if (dist && (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN])) - { - vty_out(vty, " Incoming update filter list for all interface is"); + vty_out (vty, " Incoming update filter list for all interface is"); - if (dist->list[DISTRIBUTE_IN]) - vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]); - if (dist->prefix[DISTRIBUTE_IN]) - vty_out (vty, "%s (prefix-list) %s", - dist->list[DISTRIBUTE_IN] ? "," : "", - dist->prefix[DISTRIBUTE_IN]); - vty_out (vty, "%s", VTY_NEWLINE); + has_print = 0; + if (dist) + { + has_print = distribute_print(vty, dist->list, 0, + DISTRIBUTE_V4_IN, has_print); + has_print = distribute_print(vty, dist->prefix, 1, + DISTRIBUTE_V4_IN, has_print); + has_print = distribute_print(vty, dist->list, 0, + DISTRIBUTE_V6_IN, has_print); + has_print = distribute_print(vty, dist->prefix, 1, + DISTRIBUTE_V6_IN, has_print); } + if (has_print) + vty_out (vty, "%s", VTY_NEWLINE); else - vty_out (vty, " Incoming update filter list for all interface is not set%s", VTY_NEWLINE); + vty_out (vty, " not set%s", VTY_NEWLINE); for (i = 0; i < disthash->size; i++) for (mp = disthash->index[i]; mp; mp = mp->next) { dist = mp->data; - if (dist->ifname) - { - vty_out (vty, " %s filtered by", dist->ifname); + if (dist->ifname) - if (dist->list[DISTRIBUTE_IN] || dist->prefix[DISTRIBUTE_IN]) + { + vty_out (vty, " %s filtered by", dist->ifname); - if (dist->list[DISTRIBUTE_IN]) - vty_out (vty, " %s", dist->list[DISTRIBUTE_IN]); - if (dist->prefix[DISTRIBUTE_IN]) - vty_out (vty, "%s (prefix-list) %s", - dist->list[DISTRIBUTE_IN] ? "," : "", - dist->prefix[DISTRIBUTE_IN]); + has_print = 0; + has_print = distribute_print(vty, dist->list, 0, + DISTRIBUTE_V4_IN, has_print); + has_print = distribute_print(vty, dist->prefix, 1, + DISTRIBUTE_V4_IN, has_print); + has_print = distribute_print(vty, dist->list, 0, + DISTRIBUTE_V6_IN, has_print); + has_print = distribute_print(vty, dist->prefix, 1, + DISTRIBUTE_V6_IN, has_print); + if (has_print) - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, "%s", VTY_NEWLINE); + else + vty_out(vty, " nothing%s", VTY_NEWLINE); - } + } } return 0; } @@@ -511,7 -997,39 +522,24 @@@ distribute_list_init (int node { disthash = hash_create (distribute_hash_make, (int (*) (const void *, const void *)) distribute_cmp); - /* install v4 */ - if (node == RIP_NODE) { - install_element (node, &distribute_list_all_cmd); - install_element (node, &no_distribute_list_all_cmd); - install_element (node, &distribute_list_cmd); - install_element (node, &no_distribute_list_cmd); - install_element (node, &distribute_list_prefix_all_cmd); - install_element (node, &no_distribute_list_prefix_all_cmd); - install_element (node, &distribute_list_prefix_cmd); - install_element (node, &no_distribute_list_prefix_cmd); - } + + install_element (node, &distribute_list_cmd); + install_element (node, &no_distribute_list_cmd); + + /* install v6 */ + if (node == RIPNG_NODE) { - install_element (node, &ipv6_distribute_list_all_cmd); - install_element (node, &no_ipv6_distribute_list_all_cmd); + install_element (node, &ipv6_distribute_list_cmd); - install_element (node, &no_ipv6_distribute_list_cmd); - install_element (node, &ipv6_distribute_list_prefix_all_cmd); - install_element (node, &no_ipv6_distribute_list_prefix_all_cmd); - install_element (node, &ipv6_distribute_list_prefix_cmd); - install_element (node, &no_ipv6_distribute_list_prefix_cmd); + } + - /* install v4 syntax command for v6 only protocols. */ - if (node == RIPNG_NODE) { - install_element (node, &ipv6_as_v4_distribute_list_all_cmd); - install_element (node, &no_ipv6_as_v4_distribute_list_all_cmd); - install_element (node, &ipv6_as_v4_distribute_list_cmd); - install_element (node, &no_ipv6_as_v4_distribute_list_cmd); - install_element (node, &ipv6_as_v4_distribute_list_prefix_all_cmd); - install_element (node, &no_ipv6_as_v4_distribute_list_prefix_all_cmd); - install_element (node, &ipv6_as_v4_distribute_list_prefix_cmd); - install_element (node, &no_ipv6_as_v4_distribute_list_prefix_cmd); - } ++ /* TODO: install v4 syntax command for v6 only protocols. */ ++ /* if (node == RIPNG_NODE) { ++ * install_element (node, &ipv6_as_v4_distribute_list_all_cmd); ++ * install_element (node, &no_ipv6_as_v4_distribute_list_all_cmd); ++ * install_element (node, &ipv6_as_v4_distribute_list_cmd); ++ * install_element (node, &no_ipv6_as_v4_distribute_list_cmd); ++ * install_element (node, &ipv6_as_v4_distribute_list_prefix_all_cmd); ++ * install_element (node, &no_ipv6_as_v4_distribute_list_prefix_all_cmd); ++ * install_element (node, &ipv6_as_v4_distribute_list_prefix_cmd); ++ * install_element (node, &no_ipv6_as_v4_distribute_list_prefix_cmd); ++ }*/ } diff --cc lib/if.c index dd8922ee91,6ae8500291..6235884e5d --- a/lib/if.c +++ b/lib/if.c @@@ -677,13 -683,14 +683,12 @@@ DEFUN (interface_desc "Interface specific description\n" "Characters describing this interface\n") { + int idx_line = 1; - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); - ifp = vty->index; - if (argc == 0) - return CMD_SUCCESS; - if (ifp->desc) XFREE (MTYPE_TMP, ifp->desc); - ifp->desc = argv_concat(argv, argc, 0); + ifp->desc = argv_concat(argv, argc, idx_line); return CMD_SUCCESS; } @@@ -783,11 -783,10 +787,10 @@@ DEFUN (interface if (!ifp) { - vty_out (vty, "%% interface %s not in %s%s", argv[0], argv[1], VTY_NEWLINE); + vty_out (vty, "%% interface %s not in %s%s", ifname, vrfname, VTY_NEWLINE); return CMD_WARNING; } - vty->index = ifp; - vty->node = INTERFACE_NODE; + VTY_PUSH_CONTEXT_COMPAT (INTERFACE_NODE, ifp); return CMD_SUCCESS; } @@@ -850,10 -857,9 +853,9 @@@ DEFUN (vrf return CMD_WARNING; } - vrfp = vrf_get (VRF_UNKNOWN, argv[0]); + vrfp = vrf_get (VRF_UNKNOWN, vrfname); - vty->index = vrfp; - vty->node = VRF_NODE; + VTY_PUSH_CONTEXT_COMPAT (VRF_NODE, vrfp); return CMD_SUCCESS; } diff --cc lib/json.h index 3fcfe340e9,c8d7fae1cd..e3d73d9d88 --- a/lib/json.h +++ b/lib/json.h @@@ -26,9 -26,15 +26,15 @@@ #include #else #include + + /* + * json_object_to_json_string_ext is only available for json-c + * so let's just turn it back to the original usage. + */ + #define json_object_to_json_string_ext(A, B) json_object_to_json_string (A) #endif -extern int use_json(const int argc, const char *argv[]); +extern int use_json(const int argc, struct cmd_token *argv[]); extern void json_object_string_add(struct json_object* obj, const char *key, const char *s); extern void json_object_int_add(struct json_object* obj, const char *key, diff --cc lib/keychain.c index c2d6e45714,c090956487..f8a3ffc012 --- a/lib/keychain.c +++ b/lib/keychain.c @@@ -237,12 -247,10 +247,11 @@@ DEFUN (key_chain "Key-chain management\n" "Key-chain name\n") { + int idx_word = 2; struct keychain *keychain; - keychain = keychain_get (argv[0]); + keychain = keychain_get (argv[idx_word]->arg); - vty->index = keychain; - vty->node = KEYCHAIN_NODE; + VTY_PUSH_CONTEXT_COMPAT (KEYCHAIN_NODE, keychain); return CMD_SUCCESS; } @@@ -277,18 -284,14 +286,15 @@@ DEFUN (key "Configure a key\n" "Key identifier number\n") { + int idx_number = 1; - struct keychain *keychain; + VTY_DECLVAR_CONTEXT (keychain, keychain); struct key *key; u_int32_t index; - keychain = vty->index; - - VTY_GET_INTEGER ("key identifier", index, argv[0]); + VTY_GET_INTEGER ("key identifier", index, argv[idx_number]->arg); key = key_get (keychain, index); - vty->index_sub = key; - vty->node = KEYCHAIN_KEY_NODE; + VTY_PUSH_CONTEXT_SUB (KEYCHAIN_KEY_NODE, key); - + return CMD_SUCCESS; } @@@ -299,14 -302,11 +305,12 @@@ DEFUN (no_key "Delete a key\n" "Key identifier number\n") { + int idx_number = 2; - struct keychain *keychain; + VTY_DECLVAR_CONTEXT (keychain, keychain); struct key *key; u_int32_t index; - - VTY_GET_INTEGER ("key identifier", index, argv[0]); + - keychain = vty->index; - + VTY_GET_INTEGER ("key identifier", index, argv[idx_number]->arg); key = key_lookup (keychain, index); if (! key) { @@@ -327,10 -327,7 +331,8 @@@ DEFUN (key_string "Set key string\n" "The key\n") { + int idx_line = 1; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); if (key->string) XFREE(MTYPE_KEY, key->string); @@@ -557,20 -552,10 +557,18 @@@ DEFUN (accept_lifetime_day_month_day_mo "Month of the year to expire\n" "Year to expire\n") { + int idx_hhmmss = 1; + int idx_number = 2; + int idx_month = 3; + int idx_number_2 = 4; + int idx_hhmmss_2 = 5; + int idx_number_3 = 6; + int idx_month_2 = 7; + int idx_number_4 = 8; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], argv[6], argv[7]); + return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, + argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg); } DEFUN (accept_lifetime_day_month_month_day, @@@ -586,20 -571,10 +584,18 @@@ "Day of th month to expire\n" "Year to expire\n") { + int idx_hhmmss = 1; + int idx_number = 2; + int idx_month = 3; + int idx_number_2 = 4; + int idx_hhmmss_2 = 5; + int idx_month_2 = 6; + int idx_number_3 = 7; + int idx_number_4 = 8; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_set (vty, &key->accept, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[6], argv[5], argv[7]); + return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, + argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg); } DEFUN (accept_lifetime_month_day_day_month, @@@ -615,20 -590,10 +611,18 @@@ "Month of the year to expire\n" "Year to expire\n") { + int idx_hhmmss = 1; + int idx_month = 2; + int idx_number = 3; + int idx_number_2 = 4; + int idx_hhmmss_2 = 5; + int idx_number_3 = 6; + int idx_month_2 = 7; + int idx_number_4 = 8; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1], - argv[3], argv[4], argv[5], argv[6], argv[7]); + return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, + argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg); } DEFUN (accept_lifetime_month_day_month_day, @@@ -644,20 -609,10 +638,18 @@@ "Day of th month to expire\n" "Year to expire\n") { + int idx_hhmmss = 1; + int idx_month = 2; + int idx_number = 3; + int idx_number_2 = 4; + int idx_hhmmss_2 = 5; + int idx_month_2 = 6; + int idx_number_3 = 7; + int idx_number_4 = 8; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_set (vty, &key->accept, argv[0], argv[2], argv[1], - argv[3], argv[4], argv[6], argv[5], argv[7]); + return key_lifetime_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, + argv[idx_number_2]->arg, argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg); } DEFUN (accept_lifetime_infinite_day_month, @@@ -670,16 -625,10 +662,14 @@@ "Year to start\n" "Never expires") { + int idx_hhmmss = 1; + int idx_number = 2; + int idx_month = 3; + int idx_number_2 = 4; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[1], - argv[2], argv[3]); + return key_lifetime_infinite_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, + argv[idx_month]->arg, argv[idx_number_2]->arg); } DEFUN (accept_lifetime_infinite_month_day, @@@ -692,16 -641,10 +682,14 @@@ "Year to start\n" "Never expires") { + int idx_hhmmss = 1; + int idx_month = 2; + int idx_number = 3; + int idx_number_2 = 4; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_infinite_set (vty, &key->accept, argv[0], argv[2], - argv[1], argv[3]); + return key_lifetime_infinite_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, + argv[idx_month]->arg, argv[idx_number_2]->arg); } DEFUN (accept_lifetime_duration_day_month, @@@ -715,17 -658,10 +703,15 @@@ "Duration of the key\n" "Duration seconds\n") { + int idx_hhmmss = 1; + int idx_number = 2; + int idx_month = 3; + int idx_number_2 = 4; + int idx_number_3 = 6; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[1], - argv[2], argv[3], argv[4]); + return key_lifetime_duration_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, + argv[idx_month]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg); } DEFUN (accept_lifetime_duration_month_day, @@@ -739,17 -675,10 +725,15 @@@ "Duration of the key\n" "Duration seconds\n") { + int idx_hhmmss = 1; + int idx_month = 2; + int idx_number = 3; + int idx_number_2 = 4; + int idx_number_3 = 6; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_duration_set (vty, &key->accept, argv[0], argv[2], - argv[1], argv[3], argv[4]); + return key_lifetime_duration_set (vty, &key->accept, argv[idx_hhmmss]->arg, argv[idx_number]->arg, + argv[idx_month]->arg, argv[idx_number_2]->arg, argv[idx_number_3]->arg); } DEFUN (send_lifetime_day_month_day_month, @@@ -765,20 -694,10 +749,18 @@@ "Month of the year to expire\n" "Year to expire\n") { + int idx_hhmmss = 1; + int idx_number = 2; + int idx_month = 3; + int idx_number_2 = 4; + int idx_hhmmss_2 = 5; + int idx_number_3 = 6; + int idx_month_2 = 7; + int idx_number_4 = 8; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3], - argv[4], argv[5], argv[6], argv[7]); + return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg, + argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg); } DEFUN (send_lifetime_day_month_month_day, @@@ -794,20 -713,10 +776,18 @@@ "Day of th month to expire\n" "Year to expire\n") { + int idx_hhmmss = 1; + int idx_number = 2; + int idx_month = 3; + int idx_number_2 = 4; + int idx_hhmmss_2 = 5; + int idx_month_2 = 6; + int idx_number_3 = 7; + int idx_number_4 = 8; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_set (vty, &key->send, argv[0], argv[1], argv[2], argv[3], - argv[4], argv[6], argv[5], argv[7]); + return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg, + argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg); } DEFUN (send_lifetime_month_day_day_month, @@@ -823,20 -732,10 +803,18 @@@ "Month of the year to expire\n" "Year to expire\n") { + int idx_hhmmss = 1; + int idx_month = 2; + int idx_number = 3; + int idx_number_2 = 4; + int idx_hhmmss_2 = 5; + int idx_number_3 = 6; + int idx_month_2 = 7; + int idx_number_4 = 8; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3], - argv[4], argv[5], argv[6], argv[7]); + return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg, + argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg); } DEFUN (send_lifetime_month_day_month_day, @@@ -852,20 -751,10 +830,18 @@@ "Day of th month to expire\n" "Year to expire\n") { + int idx_hhmmss = 1; + int idx_month = 2; + int idx_number = 3; + int idx_number_2 = 4; + int idx_hhmmss_2 = 5; + int idx_month_2 = 6; + int idx_number_3 = 7; + int idx_number_4 = 8; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_set (vty, &key->send, argv[0], argv[2], argv[1], argv[3], - argv[4], argv[6], argv[5], argv[7]); + return key_lifetime_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, argv[idx_number_2]->arg, + argv[idx_hhmmss_2]->arg, argv[idx_number_3]->arg, argv[idx_month_2]->arg, argv[idx_number_4]->arg); } DEFUN (send_lifetime_infinite_day_month, @@@ -878,16 -767,10 +854,14 @@@ "Year to start\n" "Never expires") { + int idx_hhmmss = 1; + int idx_number = 2; + int idx_month = 3; + int idx_number_2 = 4; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[1], argv[2], - argv[3]); + return key_lifetime_infinite_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, + argv[idx_number_2]->arg); } DEFUN (send_lifetime_infinite_month_day, @@@ -900,16 -783,10 +874,14 @@@ "Year to start\n" "Never expires") { + int idx_hhmmss = 1; + int idx_month = 2; + int idx_number = 3; + int idx_number_2 = 4; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_infinite_set (vty, &key->send, argv[0], argv[2], argv[1], - argv[3]); + return key_lifetime_infinite_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, + argv[idx_number_2]->arg); } DEFUN (send_lifetime_duration_day_month, @@@ -923,17 -800,10 +895,15 @@@ "Duration of the key\n" "Duration seconds\n") { + int idx_hhmmss = 1; + int idx_number = 2; + int idx_month = 3; + int idx_number_2 = 4; + int idx_number_3 = 6; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_duration_set (vty, &key->send, argv[0], argv[1], argv[2], - argv[3], argv[4]); + return key_lifetime_duration_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, + argv[idx_number_2]->arg, argv[idx_number_3]->arg); } DEFUN (send_lifetime_duration_month_day, @@@ -947,17 -817,10 +917,15 @@@ "Duration of the key\n" "Duration seconds\n") { + int idx_hhmmss = 1; + int idx_month = 2; + int idx_number = 3; + int idx_number_2 = 4; + int idx_number_3 = 6; - struct key *key; - - key = vty->index_sub; + VTY_DECLVAR_CONTEXT_SUB (key, key); - return key_lifetime_duration_set (vty, &key->send, argv[0], argv[2], argv[1], - argv[3], argv[4]); + return key_lifetime_duration_set (vty, &key->send, argv[idx_hhmmss]->arg, argv[idx_number]->arg, argv[idx_month]->arg, + argv[idx_number_2]->arg, argv[idx_number_3]->arg); } static struct cmd_node keychain_node = diff --cc lib/routemap.c index a68b6210b3,6f93087ae9..fc2e6b7e52 --- a/lib/routemap.c +++ b/lib/routemap.c @@@ -1984,540 -1405,52 +1993,581 @@@ route_map_notify_dependencies (const ch XFREE (MTYPE_ROUTE_MAP_NAME, name); } + /* VTY related functions. */ -DEFUN (route_map, - route_map_cmd, - "route-map WORD (deny|permit) <1-65535>", - "Create route-map or enter route-map command mode\n" - "Route map tag\n" - "Route map denies set operations\n" - "Route map permits set operations\n" - "Sequence to insert to/delete from existing route-map entry\n") +DEFUN (match_interface, + match_interface_cmd, + "match interface WORD", + MATCH_STR + "match first hop interface of route\n" + "Interface name\n") +{ + int idx_word = 2; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); + + if (rmap_match_set_hook.match_interface) - return rmap_match_set_hook.match_interface (vty, vty->index, "interface", argv[idx_word]->arg, RMAP_EVENT_MATCH_ADDED); ++ return rmap_match_set_hook.match_interface (vty, index, "interface", argv[idx_word]->arg, RMAP_EVENT_MATCH_ADDED); + return CMD_SUCCESS; +} + +DEFUN (no_match_interface, + no_match_interface_cmd, + "no match interface [INTERFACE]", + NO_STR + MATCH_STR + "Match first hop interface of route\n" + "Interface name\n") { - int permit; - unsigned long pref; - struct route_map *map; - struct route_map_index *index; - char *endptr = NULL; + char *iface = (argc == 4) ? argv[3]->arg : NULL; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); - /* Permit check. */ - if (strncmp (argv[1], "permit", strlen (argv[1])) == 0) - permit = RMAP_PERMIT; - else if (strncmp (argv[1], "deny", strlen (argv[1])) == 0) - permit = RMAP_DENY; - else + if (rmap_match_set_hook.no_match_interface) - return rmap_match_set_hook.no_match_interface (vty, vty->index, "interface", iface, RMAP_EVENT_MATCH_DELETED); ++ return rmap_match_set_hook.no_match_interface (vty, index, "interface", iface, RMAP_EVENT_MATCH_DELETED); + return CMD_SUCCESS; +} + + +DEFUN (match_ip_address, + match_ip_address_cmd, + "match ip address <(1-199)|(1300-2699)|WORD>", + MATCH_STR + IP_STR + "Match address of route\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP Access-list name\n") +{ + int idx_acl = 3; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); + + if (rmap_match_set_hook.match_ip_address) - return rmap_match_set_hook.match_ip_address (vty, vty->index, "ip address", argv[idx_acl]->arg, ++ return rmap_match_set_hook.match_ip_address (vty, index, "ip address", argv[idx_acl]->arg, + RMAP_EVENT_FILTER_ADDED); + return CMD_SUCCESS; +} + + +DEFUN (no_match_ip_address, + no_match_ip_address_cmd, + "no match ip address [<(1-199)|(1300-2699)|WORD>]", + NO_STR + MATCH_STR + IP_STR + "Match address of route\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP Access-list name\n") +{ + int idx_word = 4; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); + + if (rmap_match_set_hook.no_match_ip_address) { - vty_out (vty, "the third field must be [permit|deny]%s", VTY_NEWLINE); + if (argc <= idx_word) - return rmap_match_set_hook.no_match_ip_address (vty, vty->index, "ip address", NULL, ++ return rmap_match_set_hook.no_match_ip_address (vty, index, "ip address", NULL, + RMAP_EVENT_FILTER_DELETED); - return rmap_match_set_hook.no_match_ip_address (vty, vty->index, "ip address", argv[idx_word]->arg, ++ return rmap_match_set_hook.no_match_ip_address (vty, index, "ip address", argv[idx_word]->arg, + RMAP_EVENT_FILTER_DELETED); + } + return CMD_SUCCESS; +} + + +DEFUN (match_ip_address_prefix_list, + match_ip_address_prefix_list_cmd, + "match ip address prefix-list WORD", + MATCH_STR + IP_STR + "Match address of route\n" + "Match entries of prefix-lists\n" + "IP prefix-list name\n") +{ + int idx_word = 4; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.match_ip_address_prefix_list) - return rmap_match_set_hook.match_ip_address_prefix_list (vty, vty->index, "ip address prefix-list", ++ return rmap_match_set_hook.match_ip_address_prefix_list (vty, index, "ip address prefix-list", + argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED); + return CMD_SUCCESS; +} + + +DEFUN (no_match_ip_address_prefix_list, + no_match_ip_address_prefix_list_cmd, + "no match ip address prefix-list [WORD]", + NO_STR + MATCH_STR + IP_STR + "Match address of route\n" + "Match entries of prefix-lists\n" + "IP prefix-list name\n") +{ + int idx_word = 5; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); + + if (rmap_match_set_hook.no_match_ip_address_prefix_list) + { + if (argc <= idx_word) - return rmap_match_set_hook.no_match_ip_address_prefix_list (vty, vty->index, "ip address prefix-list", ++ return rmap_match_set_hook.no_match_ip_address_prefix_list (vty, index, "ip address prefix-list", + NULL, RMAP_EVENT_PLIST_DELETED); - return rmap_match_set_hook.no_match_ip_address_prefix_list(vty, vty->index, "ip address prefix-list", ++ return rmap_match_set_hook.no_match_ip_address_prefix_list(vty, index, "ip address prefix-list", + argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED); + } + return CMD_SUCCESS; +} + + +DEFUN (match_ip_next_hop, + match_ip_next_hop_cmd, + "match ip next-hop <(1-199)|(1300-2699)|WORD>", + MATCH_STR + IP_STR + "Match next-hop address of route\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP Access-list name\n") +{ + int idx_acl = 3; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.match_ip_next_hop) - return rmap_match_set_hook.match_ip_next_hop (vty, vty->index, "ip next-hop", argv[idx_acl]->arg, ++ return rmap_match_set_hook.match_ip_next_hop (vty, index, "ip next-hop", argv[idx_acl]->arg, + RMAP_EVENT_FILTER_ADDED); + return CMD_SUCCESS; +} + + +DEFUN (no_match_ip_next_hop, + no_match_ip_next_hop_cmd, + "no match ip next-hop [<(1-199)|(1300-2699)|WORD>]", + NO_STR + MATCH_STR + IP_STR + "Match next-hop address of route\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP Access-list name\n") +{ - int idx_word = 4; ++ int idx_word = 4; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); + + if (rmap_match_set_hook.no_match_ip_next_hop) + { + if (argc <= idx_word) - return rmap_match_set_hook.no_match_ip_next_hop (vty, vty->index, "ip next-hop", NULL, ++ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop", NULL, + RMAP_EVENT_FILTER_DELETED); - return rmap_match_set_hook.no_match_ip_next_hop (vty, vty->index, "ip next-hop", argv[idx_word]->arg, ++ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop", argv[idx_word]->arg, + RMAP_EVENT_FILTER_DELETED); + } + return CMD_SUCCESS; +} + + +DEFUN (match_ip_next_hop_prefix_list, + match_ip_next_hop_prefix_list_cmd, + "match ip next-hop prefix-list WORD", + MATCH_STR + IP_STR + "Match next-hop address of route\n" + "Match entries of prefix-lists\n" + "IP prefix-list name\n") +{ + int idx_word = 4; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.match_ip_next_hop_prefix_list) - return rmap_match_set_hook.match_ip_next_hop_prefix_list (vty, vty->index, "ip next-hop prefix-list", ++ return rmap_match_set_hook.match_ip_next_hop_prefix_list (vty, index, "ip next-hop prefix-list", + argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED); + return CMD_SUCCESS; +} + +DEFUN (no_match_ip_next_hop_prefix_list, + no_match_ip_next_hop_prefix_list_cmd, + "no match ip next-hop prefix-list [WORD]", + NO_STR + MATCH_STR + IP_STR + "Match next-hop address of route\n" + "Match entries of prefix-lists\n" + "IP prefix-list name\n") +{ + int idx_word = 5; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); + + if (rmap_match_set_hook.no_match_ip_next_hop) + { + if (argc <= idx_word) - return rmap_match_set_hook.no_match_ip_next_hop (vty, vty->index, "ip next-hop prefix-list", ++ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop prefix-list", + NULL, RMAP_EVENT_PLIST_DELETED); - return rmap_match_set_hook.no_match_ip_next_hop (vty, vty->index, "ip next-hop prefix-list", ++ return rmap_match_set_hook.no_match_ip_next_hop (vty, index, "ip next-hop prefix-list", + argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED); + } + return CMD_SUCCESS; +} + + +DEFUN (match_ipv6_address, + match_ipv6_address_cmd, + "match ipv6 address WORD", + MATCH_STR + IPV6_STR + "Match IPv6 address of route\n" + "IPv6 access-list name\n") +{ + int idx_word = 3; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.match_ipv6_address) - return rmap_match_set_hook.match_ipv6_address (vty, vty->index, "ipv6 address", argv[idx_word]->arg, ++ return rmap_match_set_hook.match_ipv6_address (vty, index, "ipv6 address", argv[idx_word]->arg, + RMAP_EVENT_FILTER_ADDED); + return CMD_SUCCESS; +} + +DEFUN (no_match_ipv6_address, + no_match_ipv6_address_cmd, + "no match ipv6 address WORD", + NO_STR + MATCH_STR + IPV6_STR + "Match IPv6 address of route\n" + "IPv6 access-list name\n") +{ + int idx_word = 4; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.no_match_ipv6_address) - return rmap_match_set_hook.no_match_ipv6_address (vty, vty->index, "ipv6 address", argv[idx_word]->arg, ++ return rmap_match_set_hook.no_match_ipv6_address (vty, index, "ipv6 address", argv[idx_word]->arg, + RMAP_EVENT_FILTER_DELETED); + return CMD_SUCCESS; +} + + +DEFUN (match_ipv6_address_prefix_list, + match_ipv6_address_prefix_list_cmd, + "match ipv6 address prefix-list WORD", + MATCH_STR + IPV6_STR + "Match address of route\n" + "Match entries of prefix-lists\n" + "IP prefix-list name\n") +{ + int idx_word = 4; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.match_ipv6_address_prefix_list) - return rmap_match_set_hook.match_ipv6_address_prefix_list (vty, vty->index, "ipv6 address prefix-list", ++ return rmap_match_set_hook.match_ipv6_address_prefix_list (vty, index, "ipv6 address prefix-list", + argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED); + return CMD_SUCCESS; +} + +DEFUN (no_match_ipv6_address_prefix_list, + no_match_ipv6_address_prefix_list_cmd, + "no match ipv6 address prefix-list WORD", + NO_STR + MATCH_STR + IPV6_STR + "Match address of route\n" + "Match entries of prefix-lists\n" + "IP prefix-list name\n") +{ + int idx_word = 5; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.no_match_ipv6_address_prefix_list) - return rmap_match_set_hook.no_match_ipv6_address_prefix_list(vty, vty->index, "ipv6 address prefix-list", ++ return rmap_match_set_hook.no_match_ipv6_address_prefix_list(vty, index, "ipv6 address prefix-list", + argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED); + return CMD_SUCCESS; +} + + +DEFUN (match_metric, + match_metric_cmd, + "match metric (0-4294967295)", + MATCH_STR + "Match metric of route\n" + "Metric value\n") +{ + int idx_number = 2; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.match_metric) - return rmap_match_set_hook.match_metric(vty, vty->index, "metric", argv[idx_number]->arg, ++ return rmap_match_set_hook.match_metric(vty, index, "metric", argv[idx_number]->arg, + RMAP_EVENT_MATCH_ADDED); + return CMD_SUCCESS; +} + + +DEFUN (no_match_metric, + no_match_metric_cmd, + "no match metric [(0-4294967295)]", + NO_STR + MATCH_STR + "Match metric of route\n" + "Metric value\n") +{ + int idx_number = 3; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.no_match_metric) + { + if (argc <= idx_number) - return rmap_match_set_hook.no_match_metric (vty, vty->index, "metric", ++ return rmap_match_set_hook.no_match_metric (vty, index, "metric", + NULL, RMAP_EVENT_MATCH_DELETED); - return rmap_match_set_hook.no_match_metric(vty, vty->index, "metric", ++ return rmap_match_set_hook.no_match_metric(vty, index, "metric", + argv[idx_number]->arg, + RMAP_EVENT_MATCH_DELETED); + } + return CMD_SUCCESS; +} + + +DEFUN (match_tag, + match_tag_cmd, - "match tag (1-65535)", ++ "match tag (1-4294967295)", + MATCH_STR + "Match tag of route\n" + "Tag value\n") +{ + int idx_number = 2; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.match_tag) - return rmap_match_set_hook.match_tag(vty, vty->index, "tag", argv[idx_number]->arg, ++ return rmap_match_set_hook.match_tag(vty, index, "tag", argv[idx_number]->arg, + RMAP_EVENT_MATCH_ADDED); + return CMD_SUCCESS; +} + + +DEFUN (no_match_tag, + no_match_tag_cmd, - "no match tag [(1-65535)]", ++ "no match tag [(1-4294967295)]", + NO_STR + MATCH_STR + "Match tag of route\n" + "Tag value\n") +{ ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.no_match_tag) - return rmap_match_set_hook.no_match_tag (vty, vty->index, "tag", argv[3]->arg, ++ return rmap_match_set_hook.no_match_tag (vty, index, "tag", argv[3]->arg, + RMAP_EVENT_MATCH_DELETED); + return CMD_SUCCESS; +} + + +DEFUN (set_ip_nexthop, + set_ip_nexthop_cmd, + "set ip next-hop A.B.C.D", + SET_STR + IP_STR + "Next hop address\n" + "IP address of next hop\n") +{ + int idx_ipv4 = 3; + union sockunion su; + int ret; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); + + ret = str2sockunion (argv[idx_ipv4]->arg, &su); + if (ret < 0) + { + vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (su.sin.sin_addr.s_addr == 0 || + IPV4_CLASS_DE(su.sin.sin_addr.s_addr)) + { + vty_out (vty, "%% nexthop address cannot be 0.0.0.0, multicast " + "or reserved%s", VTY_NEWLINE); return CMD_WARNING; } - /* Preference check. */ - pref = strtoul (argv[2], &endptr, 10); - if (pref == ULONG_MAX || *endptr != '\0') + if (rmap_match_set_hook.set_ip_nexthop) - return rmap_match_set_hook.set_ip_nexthop(vty, vty->index, "ip next-hop", argv[idx_ipv4]->arg); ++ return rmap_match_set_hook.set_ip_nexthop(vty, index, "ip next-hop", argv[idx_ipv4]->arg); + return CMD_SUCCESS; +} + + +DEFUN (no_set_ip_nexthop, + no_set_ip_nexthop_cmd, + "no set ip next-hop []", + NO_STR + SET_STR + "Next hop address\n" + "Use peer address (for BGP only)\n" + "IP address of next hop\n") +{ + int idx_peer = 4; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); + + if (rmap_match_set_hook.no_set_ip_nexthop) { - vty_out (vty, "the fourth field must be positive integer%s", - VTY_NEWLINE); + if (argc <= idx_peer) - return rmap_match_set_hook.no_set_ip_nexthop (vty, vty->index, "ip next-hop", NULL); - return rmap_match_set_hook.no_set_ip_nexthop (vty, vty->index, "ip next-hop", argv[idx_peer]->arg); ++ return rmap_match_set_hook.no_set_ip_nexthop (vty, index, "ip next-hop", NULL); ++ return rmap_match_set_hook.no_set_ip_nexthop (vty, index, "ip next-hop", argv[idx_peer]->arg); + } + return CMD_SUCCESS; +} + + +DEFUN (set_ipv6_nexthop_local, + set_ipv6_nexthop_local_cmd, + "set ipv6 next-hop local X:X::X:X", + SET_STR + IPV6_STR + "IPv6 next-hop address\n" + "IPv6 local address\n" + "IPv6 address of next hop\n") +{ + int idx_ipv6 = 4; + struct in6_addr addr; + int ret; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); + + ret = inet_pton (AF_INET6, argv[idx_ipv6]->arg, &addr); + if (!ret) + { + vty_out (vty, "%% Malformed nexthop address%s", VTY_NEWLINE); return CMD_WARNING; } - if (pref == 0 || pref > 65535) + if (!IN6_IS_ADDR_LINKLOCAL(&addr)) { - vty_out (vty, "the fourth field must be <1-65535>%s", VTY_NEWLINE); + vty_out (vty, "%% Invalid link-local nexthop address%s", VTY_NEWLINE); return CMD_WARNING; } + if (rmap_match_set_hook.set_ipv6_nexthop_local) - return rmap_match_set_hook.set_ipv6_nexthop_local (vty, vty->index, "ipv6 next-hop local", argv[idx_ipv6]->arg); ++ return rmap_match_set_hook.set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", argv[idx_ipv6]->arg); + return CMD_SUCCESS; +} + + +DEFUN (no_set_ipv6_nexthop_local, + no_set_ipv6_nexthop_local_cmd, + "no set ipv6 next-hop local [X:X::X:X]", + NO_STR + SET_STR + IPV6_STR + "IPv6 next-hop address\n" + "IPv6 local address\n" + "IPv6 address of next hop\n") +{ + int idx_ipv6 = 5; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.no_set_ipv6_nexthop_local) + { + if (argc <= idx_ipv6) - return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, vty->index, "ipv6 next-hop local", NULL); - return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, vty->index, "ipv6 next-hop local", argv[5]->arg); ++ return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", NULL); ++ return rmap_match_set_hook.no_set_ipv6_nexthop_local (vty, index, "ipv6 next-hop local", argv[5]->arg); + } + return CMD_SUCCESS; +} + +DEFUN (set_metric, + set_metric_cmd, + "set metric <(0-4294967295)|rtt|+rtt|-rtt|+metric|-metric>", + SET_STR + "Metric value for destination routing protocol\n" + "Metric value\n" + "Assign round trip time\n" + "Add round trip time\n" + "Subtract round trip time\n" + "Add metric\n" + "Subtract metric\n") +{ + int idx_number = 2; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.set_metric) - return rmap_match_set_hook.set_metric (vty, vty->index, "metric", argv[idx_number]->arg); ++ return rmap_match_set_hook.set_metric (vty, index, "metric", argv[idx_number]->arg); + return CMD_SUCCESS; +} + + +DEFUN (no_set_metric, + no_set_metric_cmd, + "no set metric [(0-4294967295)]", + NO_STR + SET_STR + "Metric value for destination routing protocol\n" + "Metric value\n") +{ + int idx_number = 3; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + if (rmap_match_set_hook.no_set_metric) + { + if (argc <= idx_number) - return rmap_match_set_hook.no_set_metric (vty, vty->index, "metric", NULL); - return rmap_match_set_hook.no_set_metric (vty, vty->index, "metric", argv[idx_number]->arg); ++ return rmap_match_set_hook.no_set_metric (vty, index, "metric", NULL); ++ return rmap_match_set_hook.no_set_metric (vty, index, "metric", argv[idx_number]->arg); + } + return CMD_SUCCESS; +} + + +DEFUN (set_tag, + set_tag_cmd, - "set tag (1-65535)", ++ "set tag (1-4294967295)", + SET_STR + "Tag value for routing protocol\n" + "Tag value\n") +{ ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + int idx_number = 2; + if (rmap_match_set_hook.set_tag) - return rmap_match_set_hook.set_tag (vty, vty->index, "tag", argv[idx_number]->arg); ++ return rmap_match_set_hook.set_tag (vty, index, "tag", argv[idx_number]->arg); + return CMD_SUCCESS; +} + + +DEFUN (no_set_tag, + no_set_tag_cmd, - "no set tag [(1-65535)]", ++ "no set tag [(1-4294967295)]", + NO_STR + SET_STR + "Tag value for routing protocol\n" + "Tag value\n") +{ ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ + int idx_number = 3; + if (rmap_match_set_hook.no_set_tag) + { + if (argc <= idx_number) - return rmap_match_set_hook.no_set_tag (vty, vty->index, "tag", NULL); - return rmap_match_set_hook.no_set_tag (vty, vty->index, "tag", argv[idx_number]->arg); ++ return rmap_match_set_hook.no_set_tag (vty, index, "tag", NULL); ++ return rmap_match_set_hook.no_set_tag (vty, index, "tag", argv[idx_number]->arg); + } + return CMD_SUCCESS; +} + + + +DEFUN (route_map, + route_map_cmd, + "route-map WORD (1-65535)", + "Create route-map or enter route-map command mode\n" + "Route map tag\n" + "Route map denies set operations\n" + "Route map permits set operations\n" + "Sequence to insert to/delete from existing route-map entry\n") +{ + int idx_word = 1; + int idx_permit_deny = 2; + int idx_number = 3; + struct route_map *map; + struct route_map_index *index; + char *endptr = NULL; + int permit = argv[idx_permit_deny]->arg[0] == 'p' ? RMAP_PERMIT : RMAP_DENY; + unsigned long pref = strtoul (argv[idx_number]->arg, &endptr, 10); + const char *mapname = argv[idx_word]->arg; + /* Get route map. */ - map = route_map_get (argv[0]); + map = route_map_get (mapname); index = route_map_index_get (map, permit, pref); - vty->index = index; - vty->node = RMAP_NODE; + VTY_PUSH_CONTEXT_COMPAT (RMAP_NODE, index); return CMD_SUCCESS; } @@@ -2623,10 -1574,8 +2671,8 @@@ DEFUN (no_rmap_onmatch_next "Exit policy on matches\n" "Next clause\n") { - struct route_map_index *index; - - index = vty->index; + struct route_map_index *index = VTY_GET_CONTEXT (route_map_index); - + if (index) index->exitpolicy = RMAP_EXIT; @@@ -2640,11 -1589,7 +2686,12 @@@ DEFUN (rmap_onmatch_goto "Goto Clause number\n" "Number\n") { + int idx_number = 2; + char *num = NULL; + num = argv[idx_number]->arg; - - struct route_map_index *index = vty->index; ++ ++ + struct route_map_index *index = VTY_GET_CONTEXT (route_map_index); int d = 0; if (index) @@@ -2735,11 -1689,8 +2780,10 @@@ DEFUN (rmap_call "Jump to another Route-Map after match+set\n" "Target route-map name\n") { + int idx_word = 1; - struct route_map_index *index; + struct route_map_index *index = VTY_GET_CONTEXT (route_map_index); + const char *rmap = argv[idx_word]->arg; - index = vty->index; if (index) { if (index->nextrm) @@@ -2787,10 -1736,8 +2829,9 @@@ DEFUN (rmap_description "Route-map comment\n" "Comment describing this route-map rule\n") { + int idx_line = 1; - struct route_map_index *index; + struct route_map_index *index = VTY_GET_CONTEXT (route_map_index); - index = vty->index; if (index) { if (index->description) diff --cc lib/routemap.h index a6d3123335,0f888897b2..86d72ce474 --- a/lib/routemap.h +++ b/lib/routemap.h @@@ -228,169 -235,7 +235,173 @@@ extern void route_map_upd8_dependency ( extern void route_map_notify_dependencies (const char *affected_name, route_map_event_t event); +extern int generic_match_add (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type); + +extern int generic_match_delete (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type); +extern int generic_set_add (struct vty *vty, struct route_map_index *index, + const char *command, const char *arg); +extern int generic_set_delete (struct vty *vty, struct route_map_index *index, + const char *command, const char *arg); + + +/* match interface */ +extern void route_map_match_interface_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* no match interface */ +extern void route_map_no_match_interface_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* match ip address */ +extern void route_map_match_ip_address_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* no match ip address */ +extern void route_map_no_match_ip_address_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* match ip address prefix list */ +extern void route_map_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* no match ip address prefix list */ +extern void route_map_no_match_ip_address_prefix_list_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* match ip next hop */ +extern void route_map_match_ip_next_hop_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* no match ip next hop */ +extern void route_map_no_match_ip_next_hop_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* match ip next hop prefix list */ +extern void route_map_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* no match ip next hop prefix list */ +extern void route_map_no_match_ip_next_hop_prefix_list_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* match ipv6 address */ +extern void route_map_match_ipv6_address_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* no match ipv6 address */ +extern void route_map_no_match_ipv6_address_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* match ipv6 address prefix list */ +extern void route_map_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* no match ipv6 address prefix list */ +extern void route_map_no_match_ipv6_address_prefix_list_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* match metric */ +extern void route_map_match_metric_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* no match metric */ +extern void route_map_no_match_metric_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* match tag */ +extern void route_map_match_tag_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* no match tag */ +extern void route_map_no_match_tag_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg, + route_map_event_t type)); +/* set ip nexthop */ +extern void route_map_set_ip_nexthop_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)); +/* no set ip nexthop */ +extern void route_map_no_set_ip_nexthop_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)); +/* set ipv6 nexthop local */ +extern void route_map_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)); +/* no set ipv6 nexthop local */ +extern void route_map_no_set_ipv6_nexthop_local_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)); +/* set metric */ +extern void route_map_set_metric_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)); +/* no set metric */ +extern void route_map_no_set_metric_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)); +/* set tag */ +extern void route_map_set_tag_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)); +/* no set tag */ +extern void route_map_no_set_tag_hook (int (*func) (struct vty *vty, + struct route_map_index *index, + const char *command, + const char *arg)); ++ + extern void *route_map_rule_tag_compile (const char *arg); + extern void route_map_rule_tag_free (void *rule); + #endif /* _ZEBRA_ROUTEMAP_H */ diff --cc lib/vty.c index ee7ea579a7,171aca1739..78bf0e720d --- a/lib/vty.c +++ b/lib/vty.c @@@ -383,20 -380,20 +380,20 @@@ vty_auth (struct vty *vty, char *buf { vty->fail++; if (vty->fail >= 3) - { - if (vty->node == AUTH_NODE) - { - vty_out (vty, "%% Bad passwords, too many failures!%s", VTY_NEWLINE); - vty->status = VTY_CLOSE; - } - else - { - /* AUTH_ENABLE_NODE */ - vty->fail = 0; - vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE); + { + if (vty->node == AUTH_NODE) + { + vty_out (vty, "%% Bad passwords, too many failures!%s", VTY_NEWLINE); + vty->status = VTY_CLOSE; + } + else + { + /* AUTH_ENABLE_NODE */ + vty->fail = 0; + vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE); - vty->node = restricted_mode ? RESTRICTED_NODE : VIEW_NODE; + vty->status = VTY_CLOSE; - } - } + } + } } } @@@ -1697,12 -1711,10 +1709,10 @@@ vty_create (int vty_sock, union sockuni strcpy (vty->address, buf); if (no_password_check) { - if (restricted_mode) - vty->node = RESTRICTED_NODE; - else if (host.advanced) + if (host.advanced) - vty->node = ENABLE_NODE; + vty->node = ENABLE_NODE; else - vty->node = VIEW_NODE; + vty->node = VIEW_NODE; } if (host.lines >= 0) vty->lines = host.lines; @@@ -3017,17 -3000,9 +3017,9 @@@ vty_config_write (struct vty *vty if (no_password_check) vty_out (vty, " no login%s", VTY_NEWLINE); - if (restricted_mode != restricted_mode_default) - { - if (restricted_mode_default) - vty_out (vty, " no anonymous restricted%s", VTY_NEWLINE); - else - vty_out (vty, " anonymous restricted%s", VTY_NEWLINE); - } - if (do_log_commands) vty_out (vty, "log commands%s", VTY_NEWLINE); - + vty_out (vty, "!%s", VTY_NEWLINE); return CMD_SUCCESS; diff --cc ospf6d/ospf6_area.c index 3449ec3ff7,685be58324..de395e8b57 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@@ -1053,12 -1089,14 +1053,8 @@@ ospf6_area_init (void install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_tree_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd); - install_element (OSPF6_NODE, &area_range_cmd); - install_element (OSPF6_NODE, &area_range_advertise_cmd); - install_element (OSPF6_NODE, &area_range_cost_cmd); - install_element (OSPF6_NODE, &area_range_advertise_cost_cmd); install_element (OSPF6_NODE, &no_area_range_cmd); - install_element (OSPF6_NODE, &no_area_range_advertise_cmd); - install_element (OSPF6_NODE, &no_area_range_cost_cmd); - install_element (OSPF6_NODE, &no_area_range_advertise_cost_cmd); install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd); install_element (OSPF6_NODE, &ospf6_area_stub_cmd); install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd); diff --cc ospf6d/ospf6_asbr.c index 07ddb9cc88,e3626c25d8..3ade69c30f --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@@ -93,7 -93,10 +93,10 @@@ ospf6_as_external_lsa_originate (struc UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F); /* external route tag */ + if (info->tag) + SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T); + else - UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T); + UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T); /* Set metric */ OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost); @@@ -642,10 -686,10 +686,9 @@@ ospf6_asbr_redistribute_remove (int typ DEFUN (ospf6_redistribute, ospf6_redistribute_cmd, - "redistribute " QUAGGA_REDIST_STR_OSPF6D, + "redistribute ", "Redistribute\n" -- QUAGGA_REDIST_HELP_STR_OSPF6D -- ) ++ QUAGGA_REDIST_HELP_STR_OSPF6D) { int type; @@@ -664,14 -708,12 +707,13 @@@ DEFUN (ospf6_redistribute_routemap "Redistribute\n" QUAGGA_REDIST_HELP_STR_OSPF6D "Route map reference\n" -- "Route map name\n" -- ) ++ "Route map name\n") { + int idx_protocol = 1; + int idx_word = 3; int type; - type = proto_redistnum(AFI_IP6, argv[0]); + type = proto_redistnum(AFI_IP6, argv[idx_protocol]->arg); if (type < 0 || type == ZEBRA_ROUTE_OSPF6) return CMD_WARNING; @@@ -1052,21 -1145,47 +1142,21 @@@ DEFUN (ospf6_routemap_match_interface /* "no match interface WORD" */ DEFUN (ospf6_routemap_no_match_interface, ospf6_routemap_no_match_interface_cmd, - "no match interface", - NO_STR - MATCH_STR - "Match first hop interface of route\n") -{ - int ret = route_map_delete_match ((struct route_map_index *) vty->index, - "interface", (argc == 0) ? NULL : argv[0]); - return route_map_command_status (vty, ret); -} - -ALIAS (ospf6_routemap_no_match_interface, - ospf6_routemap_no_match_interface_val_cmd, - "no match interface WORD", + "no match interface [WORD]", - MATCH_STR NO_STR + MATCH_STR "Match first hop interface of route\n" "Interface name\n") - -/* add "match tag" */ -DEFUN (ospf6_routemap_match_tag, - ospf6_routemap_match_tag_cmd, - "match tag <1-4294967295>", - MATCH_STR - "Tag value for routing protocol\n" - "Tag value\n") { - int ret = route_map_add_match ((struct route_map_index *) vty->index, - "tag", argv[0]); - return route_map_command_status (vty, ret); -} + int idx_word = 3; + int ret; -/* delete "match tag" */ -DEFUN (ospf6_routemap_no_match_tag, - ospf6_routemap_no_match_tag_cmd, - "no match tag", - NO_STR - MATCH_STR - "Tag value for routing protocol\n") -{ - int ret = route_map_delete_match ((struct route_map_index *) vty->index, - "tag", argc ? argv[0] : NULL); + if (argc == 4) + ret = route_map_delete_match ((struct route_map_index *) vty->index, + "interface", argv[idx_word]->arg); + else + ret = route_map_delete_match ((struct route_map_index *) vty->index, + "interface", NULL); return route_map_command_status (vty, ret); } @@@ -1130,6 -1293,40 +1220,34 @@@ DEFUN (ospf6_routemap_no_set_forwarding return route_map_command_status (vty, ret); } + /* add "set tag" */ + DEFUN (ospf6_routemap_set_tag, + ospf6_routemap_set_tag_cmd, - "set tag <1-4294967295>", ++ "set tag (1-4294967295)", + "Set value\n" + "Tag value for routing protocol\n" + "Tag value\n") + { + int ret = route_map_add_set ((struct route_map_index *) vty->index, - "tag", argv[0]); ++ "tag", argv[2]->arg); + return route_map_command_status (vty, ret); + } + + /* delete "set tag" */ + DEFUN (ospf6_routemap_no_set_tag, + ospf6_routemap_no_set_tag_cmd, - "no set tag", ++ "no set tag [(1-4294967295)]", + NO_STR + "Set value\n" - "Tag value for routing protocol\n") ++ "Tag value for routing protocol\n" ++ "Tag value\n") + { - int ret = route_map_delete_set ((struct route_map_index *) vty->index, - "tag", argc ? argv[0] : NULL); ++ char *tag = (argc == 4) ? argv[3]->arg : NULL; ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ int ret = route_map_delete_set (index, "tag", tag); + return route_map_command_status (vty, ret); + } + -ALIAS (ospf6_routemap_no_set_tag, - ospf6_routemap_no_set_tag_val_cmd, - "no set tag <1-4294967295>", - NO_STR - "Set value\n" - "Tag value for routing protocol\n" - "Tag value\n") - static void ospf6_routemap_init (void) { @@@ -1138,11 -1335,9 +1256,12 @@@ route_map_add_hook (ospf6_asbr_routemap_update); route_map_delete_hook (ospf6_asbr_routemap_update); + route_map_set_metric_hook (generic_set_add); + route_map_no_set_metric_hook (generic_set_delete); + route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd); route_map_install_match (&ospf6_routemap_rule_match_interface_cmd); + route_map_install_match (&ospf6_routemap_rule_match_tag_cmd); route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd); route_map_install_set (&ospf6_routemap_rule_set_metric_cmd); @@@ -1161,8 -1363,18 +1281,12 @@@ install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd); /* ASE Metric */ - install_element (RMAP_NODE, &set_metric_cmd); - install_element (RMAP_NODE, &no_set_metric_cmd); - install_element (RMAP_NODE, &no_set_metric_val_cmd); - - /* Forwarding address */ install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd); install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd); + + /* Tag */ + install_element (RMAP_NODE, &ospf6_routemap_set_tag_cmd); + install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_cmd); - install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_val_cmd); } diff --cc ospf6d/ospf6_interface.c index 17c701f10f,cd3b171a61..45977c616e --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@@ -1847,12 -1899,14 +1847,9 @@@ ospf6_interface_init (void /* Install interface node. */ install_node (&interface_node, config_write_ospf6_interface); - install_element (VIEW_NODE, &show_ipv6_ospf6_interface_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd); install_element (CONFIG_NODE, &interface_cmd); install_default (INTERFACE_NODE); diff --cc ospf6d/ospf6_neighbor.c index 91c7f7c62c,bb265274f5..385232f7f8 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@@ -913,7 -920,7 +913,6 @@@ voi ospf6_neighbor_init (void) { install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd); } DEFUN (debug_ospf6_neighbor, diff --cc ospf6d/ospf6_top.c index 48b6cb949a,5def2acf69..31cdbd3c5d --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@@ -929,13 -1007,13 +928,9 @@@ ospf6_top_init (void install_element (CONFIG_NODE, &no_router_ospf6_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_route_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_route_detail_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_detail_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_route_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_detail_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_route_type_detail_cmd); install_default (OSPF6_NODE); install_element (OSPF6_NODE, &ospf6_router_id_cmd); diff --cc ospf6d/ospf6_zebra.c index fd87c5a56f,4d658ed1b8..c3b8739532 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@@ -670,7 -700,9 +676,6 @@@ ospf6_zebra_init (struct thread_master /* Install command element for zebra node. */ install_element (VIEW_NODE, &show_zebra_cmd); - install_element (ENABLE_NODE, &show_zebra_cmd); - install_element (CONFIG_NODE, &router_zebra_cmd); - install_element (CONFIG_NODE, &no_router_zebra_cmd); - install_default (ZEBRA_NODE); install_element (ZEBRA_NODE, &redistribute_ospf6_cmd); install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd); diff --cc ospf6d/ospf6d.c index 8042c73225,5ae7e60e8b..349dae5c76 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@@ -1235,49 -1799,92 +1235,30 @@@ ospf6_init (void install_element_ospf6_clear_interface (); install_element (VIEW_NODE, &show_version_ospf6_cmd); - install_element (ENABLE_NODE, &show_version_ospf6_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_border_routers_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_border_routers_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_border_routers_detail_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_router_cmd); - install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_network_cmd); install_element (VIEW_NODE, &show_ipv6_ospf6_linkstate_detail_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_linkstate_cmd); - install_element (ENABLE_NODE, &show_ipv6_ospf6_linkstate_detail_cmd); #define INSTALL(n,c) \ install_element (n ## _NODE, &show_ipv6_ospf6_ ## c) INSTALL (VIEW, database_cmd); - INSTALL (VIEW, database_detail_cmd); INSTALL (VIEW, database_type_cmd); - INSTALL (VIEW, database_type_detail_cmd); INSTALL (VIEW, database_id_cmd); - INSTALL (VIEW, database_id_detail_cmd); - INSTALL (VIEW, database_linkstate_id_cmd); - INSTALL (VIEW, database_linkstate_id_detail_cmd); INSTALL (VIEW, database_router_cmd); - INSTALL (VIEW, database_router_detail_cmd); - INSTALL (VIEW, database_adv_router_cmd); - INSTALL (VIEW, database_adv_router_detail_cmd); INSTALL (VIEW, database_type_id_cmd); - INSTALL (VIEW, database_type_id_detail_cmd); - INSTALL (VIEW, database_type_linkstate_id_cmd); - INSTALL (VIEW, database_type_linkstate_id_detail_cmd); INSTALL (VIEW, database_type_router_cmd); - INSTALL (VIEW, database_type_router_detail_cmd); - INSTALL (VIEW, database_type_adv_router_cmd); - INSTALL (VIEW, database_type_adv_router_detail_cmd); INSTALL (VIEW, database_adv_router_linkstate_id_cmd); - INSTALL (VIEW, database_adv_router_linkstate_id_detail_cmd); INSTALL (VIEW, database_id_router_cmd); - INSTALL (VIEW, database_id_router_detail_cmd); INSTALL (VIEW, database_type_id_router_cmd); - INSTALL (VIEW, database_type_id_router_detail_cmd); INSTALL (VIEW, database_type_adv_router_linkstate_id_cmd); - INSTALL (VIEW, database_type_adv_router_linkstate_id_detail_cmd); INSTALL (VIEW, database_self_originated_cmd); - INSTALL (VIEW, database_self_originated_detail_cmd); INSTALL (VIEW, database_type_self_originated_cmd); - INSTALL (VIEW, database_type_self_originated_detail_cmd); INSTALL (VIEW, database_type_id_self_originated_cmd); - INSTALL (VIEW, database_type_id_self_originated_detail_cmd); INSTALL (VIEW, database_type_self_originated_linkstate_id_cmd); - INSTALL (VIEW, database_type_self_originated_linkstate_id_detail_cmd); - - INSTALL (ENABLE, database_cmd); - INSTALL (ENABLE, database_detail_cmd); - INSTALL (ENABLE, database_type_cmd); - INSTALL (ENABLE, database_type_detail_cmd); - INSTALL (ENABLE, database_id_cmd); - INSTALL (ENABLE, database_id_detail_cmd); - INSTALL (ENABLE, database_linkstate_id_cmd); - INSTALL (ENABLE, database_linkstate_id_detail_cmd); - INSTALL (ENABLE, database_router_cmd); - INSTALL (ENABLE, database_router_detail_cmd); - INSTALL (ENABLE, database_adv_router_cmd); - INSTALL (ENABLE, database_adv_router_detail_cmd); - INSTALL (ENABLE, database_type_id_cmd); - INSTALL (ENABLE, database_type_id_detail_cmd); - INSTALL (ENABLE, database_type_linkstate_id_cmd); - INSTALL (ENABLE, database_type_linkstate_id_detail_cmd); - INSTALL (ENABLE, database_type_router_cmd); - INSTALL (ENABLE, database_type_router_detail_cmd); - INSTALL (ENABLE, database_type_adv_router_cmd); - INSTALL (ENABLE, database_type_adv_router_detail_cmd); - INSTALL (ENABLE, database_adv_router_linkstate_id_cmd); - INSTALL (ENABLE, database_adv_router_linkstate_id_detail_cmd); - INSTALL (ENABLE, database_id_router_cmd); - INSTALL (ENABLE, database_id_router_detail_cmd); - INSTALL (ENABLE, database_type_id_router_cmd); - INSTALL (ENABLE, database_type_id_router_detail_cmd); - INSTALL (ENABLE, database_type_adv_router_linkstate_id_cmd); - INSTALL (ENABLE, database_type_adv_router_linkstate_id_detail_cmd); - INSTALL (ENABLE, database_self_originated_cmd); - INSTALL (ENABLE, database_self_originated_detail_cmd); - INSTALL (ENABLE, database_type_self_originated_cmd); - INSTALL (ENABLE, database_type_self_originated_detail_cmd); - INSTALL (ENABLE, database_type_id_self_originated_cmd); - INSTALL (ENABLE, database_type_id_self_originated_detail_cmd); - INSTALL (ENABLE, database_type_self_originated_linkstate_id_cmd); - INSTALL (ENABLE, database_type_self_originated_linkstate_id_detail_cmd); - INSTALL (ENABLE, database_cmd); - INSTALL (ENABLE, database_type_cmd); - INSTALL (ENABLE, database_id_cmd); - INSTALL (ENABLE, database_router_cmd); - INSTALL (ENABLE, database_type_id_cmd); - INSTALL (ENABLE, database_type_router_cmd); - INSTALL (ENABLE, database_adv_router_linkstate_id_cmd); - INSTALL (ENABLE, database_id_router_cmd); - INSTALL (ENABLE, database_type_id_router_cmd); - INSTALL (ENABLE, database_type_adv_router_linkstate_id_cmd); - INSTALL (ENABLE, database_self_originated_cmd); - INSTALL (ENABLE, database_type_self_originated_cmd); - INSTALL (ENABLE, database_type_id_self_originated_cmd); - INSTALL (ENABLE, database_type_self_originated_linkstate_id_cmd); - /* Make ospf protocol socket. */ ospf6_serv_sock (); thread_add_read (master, ospf6_receive, NULL, ospf6_sock); diff --cc ospfd/ospf_ri.c index bcb1cd8e20,be06cc0a88..b3d20dca75 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@@ -1621,10 -1621,9 +1621,8 @@@ ospf_router_info_register_vty (void { install_element (VIEW_NODE, &show_ip_ospf_router_info_cmd); install_element (VIEW_NODE, &show_ip_ospf_router_info_pce_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_router_info_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_router_info_pce_cmd); install_element (OSPF_NODE, &router_info_area_cmd); - install_element (OSPF_NODE, &router_info_as_cmd); install_element (OSPF_NODE, &no_router_info_cmd); install_element (OSPF_NODE, &pce_address_cmd); install_element (OSPF_NODE, &pce_path_scope_cmd); diff --cc ospfd/ospf_routemap.c index ebe426cee0,6bd853bf89..6e88515d3e --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@@ -668,15 -662,219 +603,14 @@@ DEFUN (no_match_ip_nexthop "IP access-list number\n" "IP access-list number (expanded range)\n" "IP access-list name\n") - -DEFUN (match_ip_next_hop_prefix_list, - match_ip_next_hop_prefix_list_cmd, - "match ip next-hop prefix-list WORD", - MATCH_STR - IP_STR - "Match next-hop address of route\n" - "Match entries of prefix-lists\n" - "IP prefix-list name\n") { - return ospf_route_match_add (vty, vty->index, "ip next-hop prefix-list", - argv[0]); + char *al = (argc == 5) ? argv[4]->arg : NULL; + return ospf_route_match_delete (vty, vty->index, "ip next-hop", al); } -DEFUN (no_match_ip_next_hop_prefix_list, - no_match_ip_next_hop_prefix_list_cmd, - "no match ip next-hop prefix-list", - NO_STR - MATCH_STR - IP_STR - "Match next-hop address of route\n" - "Match entries of prefix-lists\n") -{ - if (argc == 0) - return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list", - NULL); - return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list", - argv[0]); -} - -ALIAS (no_match_ip_next_hop_prefix_list, - no_match_ip_next_hop_prefix_list_val_cmd, - "no match ip next-hop prefix-list WORD", - NO_STR - MATCH_STR - IP_STR - "Match next-hop address of route\n" - "Match entries of prefix-lists\n" - "IP prefix-list name\n") - -DEFUN (match_ip_address, - match_ip_address_cmd, - "match ip address (<1-199>|<1300-2699>|WORD)", - MATCH_STR - IP_STR - "Match address of route\n" - "IP access-list number\n" - "IP access-list number (expanded range)\n" - "IP access-list name\n") -{ - return ospf_route_match_add (vty, vty->index, "ip address", argv[0]); -} - -DEFUN (no_match_ip_address, - no_match_ip_address_cmd, - "no match ip address", - NO_STR - MATCH_STR - IP_STR - "Match address of route\n") -{ - if (argc == 0) - return ospf_route_match_delete (vty, vty->index, "ip address", NULL); - - return ospf_route_match_delete (vty, vty->index, "ip address", argv[0]); -} - -ALIAS (no_match_ip_address, - no_match_ip_address_val_cmd, - "no match ip address (<1-199>|<1300-2699>|WORD)", - NO_STR - MATCH_STR - IP_STR - "Match address of route\n" - "IP access-list number\n" - "IP access-list number (expanded range)\n" - "IP access-list name\n") - -DEFUN (match_ip_address_prefix_list, - match_ip_address_prefix_list_cmd, - "match ip address prefix-list WORD", - MATCH_STR - IP_STR - "Match address of route\n" - "Match entries of prefix-lists\n" - "IP prefix-list name\n") -{ - return ospf_route_match_add (vty, vty->index, "ip address prefix-list", - argv[0]); -} - -DEFUN (no_match_ip_address_prefix_list, - no_match_ip_address_prefix_list_cmd, - "no match ip address prefix-list", - NO_STR - MATCH_STR - IP_STR - "Match address of route\n" - "Match entries of prefix-lists\n") -{ - if (argc == 0) - return ospf_route_match_delete (vty, vty->index, "ip address prefix-list", - NULL); - return ospf_route_match_delete (vty, vty->index, "ip address prefix-list", - argv[0]); -} - -ALIAS (no_match_ip_address_prefix_list, - no_match_ip_address_prefix_list_val_cmd, - "no match ip address prefix-list WORD", - NO_STR - MATCH_STR - IP_STR - "Match address of route\n" - "Match entries of prefix-lists\n" - "IP prefix-list name\n") - -DEFUN (match_interface, - match_interface_cmd, - "match interface WORD", - MATCH_STR - "Match first hop interface of route\n" - "Interface name\n") -{ - return ospf_route_match_add (vty, vty->index, "interface", argv[0]); -} - -DEFUN (no_match_interface, - no_match_interface_cmd, - "no match interface", - NO_STR - MATCH_STR - "Match first hop interface of route\n") -{ - if (argc == 0) - return ospf_route_match_delete (vty, vty->index, "interface", NULL); - - return ospf_route_match_delete (vty, vty->index, "interface", argv[0]); -} - -ALIAS (no_match_interface, - no_match_interface_val_cmd, - "no match interface WORD", - NO_STR - MATCH_STR - "Match first hop interface of route\n" - "Interface name\n") - -DEFUN (match_tag, - match_tag_cmd, - "match tag <1-4294967295>", - MATCH_STR - "Match tag of route\n" - "Tag value\n") -{ - return ospf_route_match_add (vty, vty->index, "tag", argv[0]); -} - -DEFUN (no_match_tag, - no_match_tag_cmd, - "no match tag", - NO_STR - MATCH_STR - "Match tag of route\n") -{ - if (argc == 0) - return ospf_route_match_delete (vty, vty->index, "tag", NULL); - - return ospf_route_match_delete (vty, vty->index, "tag", argv[0]); -} - -ALIAS (no_match_tag, - no_match_tag_val_cmd, - "no match tag <1-4294967295>", - NO_STR - MATCH_STR - "Match tag of route\n" - "Tag value\n") - -DEFUN (set_metric, - set_metric_cmd, - "set metric <0-4294967295>", - SET_STR - "Metric value for destination routing protocol\n" - "Metric value\n") -{ - return ospf_route_set_add (vty, vty->index, "metric", argv[0]); -} - -DEFUN (no_set_metric, - no_set_metric_cmd, - "no set metric", - NO_STR - SET_STR - "Metric value for destination routing protocol\n") -{ - if (argc == 0) - return ospf_route_set_delete (vty, vty->index, "metric", NULL); - - return ospf_route_set_delete (vty, vty->index, "metric", argv[0]); -} - -ALIAS (no_set_metric, - no_set_metric_val_cmd, - "no set metric <0-4294967295>", - NO_STR - SET_STR - "Metric value for destination routing protocol\n" - "Metric value\n") -- DEFUN (set_metric_type, set_metric_type_cmd, - "set metric-type (type-1|type-2)", + "set metric-type ", SET_STR "Type of metric for destination routing protocol\n" "OSPF[6] external type 1 metric\n" diff --cc ospfd/ospf_vty.c index 359189b345,9da36f6a6c..8261a96a20 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@@ -9969,25 -9976,25 +9969,17 @@@ ospf_vty_show_init (void { /* "show ip ospf" commands. */ install_element (VIEW_NODE, &show_ip_ospf_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_cmd); install_element (VIEW_NODE, &show_ip_ospf_instance_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_instance_cmd); /* "show ip ospf database" commands. */ - install_element (VIEW_NODE, &show_ip_ospf_database_type_cmd); - install_element (VIEW_NODE, &show_ip_ospf_database_type_id_cmd); - install_element (VIEW_NODE, &show_ip_ospf_database_type_id_adv_router_cmd); install_element (VIEW_NODE, &show_ip_ospf_database_type_adv_router_cmd); - install_element (VIEW_NODE, &show_ip_ospf_database_type_id_self_cmd); - install_element (VIEW_NODE, &show_ip_ospf_database_type_self_cmd); install_element (VIEW_NODE, &show_ip_ospf_database_cmd); + install_element (VIEW_NODE, &show_ip_ospf_database_max_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_database_type_adv_router_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_database_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_database_max_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_adv_router_cmd); install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_self_cmd); - install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_self_cmd); install_element (VIEW_NODE, &show_ip_ospf_instance_database_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_database_max_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_instance_database_cmd); - install_element (ENABLE_NODE, &show_ip_ospf_instance_database_max_cmd); /* "show ip ospf interface" commands. */ install_element (VIEW_NODE, &show_ip_ospf_interface_cmd); diff --cc ripd/rip_interface.c index 6df219628c,359549ed80..8c5092d787 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@@ -119,19 -121,9 +121,9 @@@ rip_interface_new (void struct rip_interface *ri; ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface)); - + - /* Default authentication type is simple password for Cisco - compatibility. */ - ri->auth_type = RIP_NO_AUTH; - ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE; - - /* Set default split-horizon behavior. If the interface is Frame - Relay or SMDS is enabled, the default value for split-horizon is - off. But currently Zebra does detect Frame Relay or SMDS - interface. So all interface is set to split horizon. */ - ri->split_horizon_default = RIP_SPLIT_HORIZON; - ri->split_horizon = ri->split_horizon_default; + rip_interface_reset (ri); - + return ri; } @@@ -503,81 -495,82 +495,82 @@@ rip_interface_delete (int command, stru return 0; } - void - rip_interface_clean (void) - { - struct listnode *node; - struct interface *ifp; - struct rip_interface *ri; - - for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) + static void + rip_interface_clean (struct rip_interface *ri) -{ - ri->enable_network = 0; - ri->enable_interface = 0; - ri->running = 0; - - if (ri->t_wakeup) { - ri = ifp->info; - - thread_cancel (ri->t_wakeup); - ri->t_wakeup = NULL; + ri->enable_network = 0; + ri->enable_interface = 0; + ri->running = 0; + + if (ri->t_wakeup) + { + thread_cancel (ri->t_wakeup); + ri->t_wakeup = NULL; + } } --} void - rip_interface_reset (void) + rip_interfaces_clean (void) { struct listnode *node; struct interface *ifp; - struct rip_interface *ri; for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) + rip_interface_clean (ifp->info); + } + + static void + rip_interface_reset (struct rip_interface *ri) -{ + { - ri = ifp->info; + /* Default authentication type is simple password for Cisco + compatibility. */ + ri->auth_type = RIP_NO_AUTH; + ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE; - ri->enable_network = 0; - ri->enable_interface = 0; - ri->running = 0; + /* Set default split-horizon behavior. If the interface is Frame + Relay or SMDS is enabled, the default value for split-horizon is + off. But currently Zebra does detect Frame Relay or SMDS + interface. So all interface is set to split horizon. */ + ri->split_horizon_default = RIP_SPLIT_HORIZON; + ri->split_horizon = ri->split_horizon_default; - ri->ri_send = RI_RIP_UNSPEC; - ri->ri_receive = RI_RIP_UNSPEC; - - if (ri->auth_str) - { - free (ri->auth_str); - ri->auth_str = NULL; - } - if (ri->key_chain) - { - free (ri->key_chain); - ri->key_chain = NULL; - } + ri->ri_send = RI_RIP_UNSPEC; + ri->ri_receive = RI_RIP_UNSPEC; - ri->auth_type = RIP_NO_AUTH; - - ri->list[RIP_FILTER_IN] = NULL; - ri->list[RIP_FILTER_OUT] = NULL; + if (ri->auth_str) + { + free (ri->auth_str); + ri->auth_str = NULL; + } + if (ri->key_chain) + { + free (ri->key_chain); + ri->key_chain = NULL; + } - ri->split_horizon = RIP_NO_SPLIT_HORIZON; - ri->split_horizon_default = RIP_NO_SPLIT_HORIZON; - - ri->prefix[RIP_FILTER_IN] = NULL; - ri->prefix[RIP_FILTER_OUT] = NULL; - - ri->recv_badpackets = 0; - ri->recv_badroutes = 0; - ri->sent_updates = 0; + ri->list[RIP_FILTER_IN] = NULL; + ri->list[RIP_FILTER_OUT] = NULL; - ri->passive = 0; + ri->prefix[RIP_FILTER_IN] = NULL; + ri->prefix[RIP_FILTER_OUT] = NULL; + - if (ri->t_wakeup) - { - thread_cancel (ri->t_wakeup); - ri->t_wakeup = NULL; - } - + ri->recv_badpackets = 0; + ri->recv_badroutes = 0; + ri->sent_updates = 0; + + ri->passive = 0; + + rip_interface_clean (ri); -} + } + + void + rip_interfaces_reset (void) + { + struct listnode *node; + struct interface *ifp; + + for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) + rip_interface_reset (ifp->info); } int diff --cc ripd/ripd.c index c5d928ba6d,ab81996640..7b04368496 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@@ -329,84 -332,14 +332,14 @@@ rip_filter (int rip_distribute, struct (struct prefix *) p) == FILTER_DENY) { if (IS_RIP_DEBUG_PACKET) - zlog_debug ("%s/%d filtered by distribute in", - inet_ntoa (p->prefix), p->prefixlen); - return -1; - } - } - if (ri->prefix[RIP_FILTER_IN]) - { - if (prefix_list_apply (ri->prefix[RIP_FILTER_IN], - (struct prefix *) p) == PREFIX_DENY) - { - if (IS_RIP_DEBUG_PACKET) - zlog_debug ("%s/%d filtered by prefix-list in", - inet_ntoa (p->prefix), p->prefixlen); - return -1; - } - } - - /* All interface filter check. */ - dist = distribute_lookup (NULL); - if (dist) - { - if (dist->list[DISTRIBUTE_IN]) - { - alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]); - - if (alist) - { - if (access_list_apply (alist, - (struct prefix *) p) == FILTER_DENY) - { - if (IS_RIP_DEBUG_PACKET) - zlog_debug ("%s/%d filtered by distribute in", - inet_ntoa (p->prefix), p->prefixlen); + zlog_debug ("%s/%d filtered by distribute %s", + inet_ntoa (p->prefix), p->prefixlen, inout); - return -1; - } - } + return -1; + } + } - } - if (dist->prefix[DISTRIBUTE_IN]) - { - plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]); - - if (plist) - { - if (prefix_list_apply (plist, - (struct prefix *) p) == PREFIX_DENY) - { - if (IS_RIP_DEBUG_PACKET) - zlog_debug ("%s/%d filtered by prefix-list in", - inet_ntoa (p->prefix), p->prefixlen); - return -1; - } - } - } - } - return 0; - } - - static int - rip_outgoing_filter (struct prefix_ipv4 *p, struct rip_interface *ri) + if (ri->prefix[rip_distribute]) - { +{ - struct distribute *dist; - struct access_list *alist; - struct prefix_list *plist; - - if (ri->list[RIP_FILTER_OUT]) - { - if (access_list_apply (ri->list[RIP_FILTER_OUT], - (struct prefix *) p) == FILTER_DENY) - { - if (IS_RIP_DEBUG_PACKET) - zlog_debug ("%s/%d is filtered by distribute out", - inet_ntoa (p->prefix), p->prefixlen); - return -1; - } - } - if (ri->prefix[RIP_FILTER_OUT]) - { - if (prefix_list_apply (ri->prefix[RIP_FILTER_OUT], + if (prefix_list_apply (ri->prefix[rip_distribute], (struct prefix *) p) == PREFIX_DENY) { if (IS_RIP_DEBUG_PACKET) @@@ -420,26 -353,25 +353,25 @@@ dist = distribute_lookup (NULL); if (dist) { - if (dist->list[DISTRIBUTE_OUT]) + if (dist->list[distribute]) { - alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]); + alist = access_list_lookup (AFI_IP, dist->list[distribute]); - + if (alist) { - if (access_list_apply (alist, - (struct prefix *) p) == FILTER_DENY) + if (access_list_apply (alist, (struct prefix *) p) == FILTER_DENY) { if (IS_RIP_DEBUG_PACKET) - zlog_debug ("%s/%d filtered by distribute out", - inet_ntoa (p->prefix), p->prefixlen); + zlog_debug ("%s/%d filtered by distribute %s", + inet_ntoa (p->prefix), p->prefixlen, inout); return -1; } } } - if (dist->prefix[DISTRIBUTE_OUT]) + if (dist->prefix[distribute]) { - plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]); + plist = prefix_list_lookup (AFI_IP, dist->prefix[distribute]); - + if (plist) { if (prefix_list_apply (plist, diff --cc ripngd/ripngd.c index c896922bc0,2a32b934f2..e7db971208 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@@ -623,84 -627,14 +627,14 @@@ ripng_filter (int ripng_distribute, str (struct prefix *) p) == FILTER_DENY) { if (IS_RIPNG_DEBUG_PACKET) - zlog_debug ("%s/%d filtered by distribute in", - inet6_ntoa (p->prefix), p->prefixlen); - return -1; - } - } - if (ri->prefix[RIPNG_FILTER_IN]) - { - if (prefix_list_apply (ri->prefix[RIPNG_FILTER_IN], - (struct prefix *) p) == PREFIX_DENY) - { - if (IS_RIPNG_DEBUG_PACKET) - zlog_debug ("%s/%d filtered by prefix-list in", - inet6_ntoa (p->prefix), p->prefixlen); - return -1; - } - } - - /* All interface filter check. */ - dist = distribute_lookup (NULL); - if (dist) - { - if (dist->list[DISTRIBUTE_IN]) - { - alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_IN]); - - if (alist) - { - if (access_list_apply (alist, - (struct prefix *) p) == FILTER_DENY) - { - if (IS_RIPNG_DEBUG_PACKET) - zlog_debug ("%s/%d filtered by distribute in", - inet6_ntoa (p->prefix), p->prefixlen); - return -1; - } - } - } - if (dist->prefix[DISTRIBUTE_IN]) - { - plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_IN]); - - if (plist) - { - if (prefix_list_apply (plist, - (struct prefix *) p) == PREFIX_DENY) - { - if (IS_RIPNG_DEBUG_PACKET) - zlog_debug ("%s/%d filtered by prefix-list in", - inet6_ntoa (p->prefix), p->prefixlen); + zlog_debug ("%s/%d filtered by distribute %s", + inet6_ntoa (p->prefix), p->prefixlen, inout); - return -1; - } - } + return -1; + } + } - } - } - return 0; - } - - static int - ripng_outgoing_filter (struct prefix_ipv6 *p, struct ripng_interface *ri) + if (ri->prefix[ripng_distribute]) - { +{ - struct distribute *dist; - struct access_list *alist; - struct prefix_list *plist; - - if (ri->list[RIPNG_FILTER_OUT]) - { - if (access_list_apply (ri->list[RIPNG_FILTER_OUT], - (struct prefix *) p) == FILTER_DENY) - { - if (IS_RIPNG_DEBUG_PACKET) - zlog_debug ("%s/%d is filtered by distribute out", - inet6_ntoa (p->prefix), p->prefixlen); - return -1; - } - } - if (ri->prefix[RIPNG_FILTER_OUT]) - { - if (prefix_list_apply (ri->prefix[RIPNG_FILTER_OUT], + if (prefix_list_apply (ri->prefix[ripng_distribute], (struct prefix *) p) == PREFIX_DENY) { if (IS_RIPNG_DEBUG_PACKET) @@@ -714,10 -648,10 +648,10 @@@ dist = distribute_lookup (NULL); if (dist) { - if (dist->list[DISTRIBUTE_OUT]) + if (dist->list[distribute]) { - alist = access_list_lookup (AFI_IP6, dist->list[DISTRIBUTE_OUT]); + alist = access_list_lookup (AFI_IP6, dist->list[distribute]); - + if (alist) { if (access_list_apply (alist, @@@ -730,10 -664,10 +664,10 @@@ } } } - if (dist->prefix[DISTRIBUTE_OUT]) + if (dist->prefix[distribute]) { - plist = prefix_list_lookup (AFI_IP6, dist->prefix[DISTRIBUTE_OUT]); + plist = prefix_list_lookup (AFI_IP6, dist->prefix[distribute]); - + if (plist) { if (prefix_list_apply (plist, diff --cc vtysh/extract.pl.in index 2b0f50cb2f,7c5dec9a54..0c06aee4f4 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@@ -42,12 -42,14 +42,15 @@@ $ignore{'"ip vrf NAME"'} = "ignore" $ignore{'"router rip"'} = "ignore"; $ignore{'"router ripng"'} = "ignore"; $ignore{'"router ospf"'} = "ignore"; -$ignore{'"router ospf <1-65535>"'} = "ignore"; +$ignore{'"router ospf (1-65535)"'} = "ignore"; $ignore{'"router ospf6"'} = "ignore"; + $ignore{'"mpls ldp"'} = "ignore"; + $ignore{'"l2vpn WORD type vpls"'} = "ignore"; + $ignore{'"member pseudowire IFNAME"'} = "ignore"; $ignore{'"router bgp"'} = "ignore"; -$ignore{'"router bgp " "<1-4294967295>"'} = "ignore"; -$ignore{'"router bgp " "<1-4294967295>" " (view|vrf) WORD"'} = "ignore"; +$ignore{'"router bgp " "(1-4294967295)"'} = "ignore"; +$ignore{'"router bgp " "(1-4294967295)" " WORD"'} = "ignore"; +$ignore{'"router bgp [(1-4294967295) [ WORD]]"'} = "ignore"; $ignore{'"router isis WORD"'} = "ignore"; $ignore{'"router zebra"'} = "ignore"; $ignore{'"address-family ipv4"'} = "ignore"; @@@ -63,9 -65,12 +66,12 @@@ $ignore{'"address-family encapv6"'} = " $ignore{'"address-family vpnv6"'} = "ignore"; $ignore{'"address-family vpnv6 unicast"'} = "ignore"; $ignore{'"exit-address-family"'} = "ignore"; + $ignore{'"vnc defaults"'} = "ignore"; + $ignore{'"vnc nve-group NAME"'} = "ignore"; + $ignore{'"exit-vnc"'} = "ignore"; $ignore{'"key chain WORD"'} = "ignore"; -$ignore{'"key <0-2147483647>"'} = "ignore"; -$ignore{'"route-map WORD (deny|permit) <1-65535>"'} = "ignore"; +$ignore{'"key (0-2147483647)"'} = "ignore"; +$ignore{'"route-map WORD (1-65535)"'} = "ignore"; $ignore{'"show route-map"'} = "ignore"; $ignore{'"line vty"'} = "ignore"; $ignore{'"who"'} = "ignore"; @@@ -158,7 -162,10 +164,10 @@@ foreach (@ARGV) elsif ($file =~ /lib\/vty\.c$/) { $protocol = "VTYSH_ALL"; } + elsif ($file =~ /librfp\/.*\.c$/ || $file =~ /rfapi\/.*\.c$/) { + $protocol = "VTYSH_BGPD"; + } - else { + else { ($protocol) = ($file =~ /^.*\/([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/); $protocol = "VTYSH_" . uc $protocol; } @@@ -221,10 -233,15 +230,9 @@@ # If extract.pl fails with a error message and you've been # modifying the cli, then go back and fix your code to # not have cli command function collisions. -# -# If you've removed a cli overwrite, you can safely subtract -# one from $bad_cli_stomps. If you've added to the problem # please fix your code before submittal -if ($cli_stomp != $bad_cli_stomps) { - warn "Expected $bad_cli_stomps command line stomps, but got $cli_stomp instead\n"; - if ($cli_stomp > $bad_cli_stomps) { - exit $cli_stomp; - } +if ($cli_stomp) { + warn "There are $cli_stomp command line stomps\n"; - exit $cli_stomp; } # Check finaly alive $cmd; diff --cc vtysh/vtysh.c index 70b0d7832e,39ad8d81d6..2d040fd5d3 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@@ -1566,15 -1779,25 +1778,29 @@@ DEFUNSH (VTYSH_OSPF6D return vtysh_exit (vty); } -ALIAS (vtysh_exit_ospf6d, - vtysh_quit_ospf6d_cmd, - "quit", - "Exit current mode and down to previous mode\n") +DEFUNSH (VTYSH_OSPF6D, + vtysh_quit_ospf6d, + vtysh_quit_ospf6d_cmd, + "quit", + "Exit current mode and down to previous mode\n") +{ + return vtysh_exit_ospf6d (self, vty, argc, argv); +} + DEFUNSH (VTYSH_LDPD, + vtysh_exit_ldpd, + vtysh_exit_ldpd_cmd, + "exit", + "Exit current mode and down to previous mode\n") + { + return vtysh_exit (vty); + } + + ALIAS (vtysh_exit_ldpd, + vtysh_quit_ldpd_cmd, + "quit", + "Exit current mode and down to previous mode\n") + DEFUNSH (VTYSH_ISISD, vtysh_exit_isisd, vtysh_exit_isisd_cmd, @@@ -1623,8 -1837,16 +1849,8 @@@ DEFUNSH (VTYSH_INTERFACE return CMD_SUCCESS; } -ALIAS_SH (VTYSH_ZEBRA, - vtysh_interface, - vtysh_interface_vrf_cmd, - "interface IFNAME " VRF_CMD_STR, - "Select an interface to configure\n" - "Interface's name\n" - VRF_CMD_HELP_STR) - /* TODO Implement "no interface command in isisd. */ - DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D, + DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD, vtysh_no_interface_cmd, "no interface IFNAME", NO_STR @@@ -1708,9 -1922,9 +1934,9 @@@ DEFUNSH (VTYSH_VRF /* TODO Implement interface description commands in ripngd, ospf6d * and isisd. */ - DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD, + DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_LDPD, interface_desc_cmd, - "description .LINE", + "description LINE...", "Interface specific description\n" "Characters describing this interface\n") @@@ -2158,17 -2396,9 +2384,18 @@@ DEFUNSH (VTYSH_ALL DEFUN (vtysh_write_terminal, vtysh_write_terminal_cmd, - "write terminal []", - "write terminal", ++ "write terminal []", "Write running configuration to memory, network, or terminal\n" - "Write to terminal\n") + "Write to terminal\n" + "For the zebra daemon\n" + "For the rip daemon\n" + "For the ripng daemon\n" + "For the ospf daemon\n" + "For the ospfv6 daemon\n" ++ "For the ldpd daemon" + "For the bgp daemon\n" + "For the isis daemon\n" + "For the pim daemon\n") { u_int i; char line[] = "write terminal\n"; @@@ -2215,11 -2445,12 +2442,11 @@@ return CMD_SUCCESS; } -DEFUN (vtysh_write_terminal_daemon, - vtysh_write_terminal_daemon_cmd, - "write terminal (zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd)", - "Write running configuration to memory, network, or terminal\n" - "Write to terminal\n" +DEFUN (vtysh_show_running_config, + vtysh_show_running_config_cmd, - "show running-config []", ++ "show running-config []", + SHOW_STR + "Current operating configuration\n" "For the zebra daemon\n" "For the rip daemon\n" "For the ripng daemon\n" @@@ -2329,12 -2572,29 +2557,30 @@@ write_config_integrated(void return CMD_SUCCESS; } + static bool vtysh_writeconfig_integrated(void) + { + struct stat s; + + switch (vtysh_write_integrated) + { + case WRITE_INTEGRATED_UNSPECIFIED: + if (stat(integrate_default, &s) && errno == ENOENT) + return false; + return true; + case WRITE_INTEGRATED_NO: + return false; + case WRITE_INTEGRATED_YES: + return true; + } + return true; + } + DEFUN (vtysh_write_memory, vtysh_write_memory_cmd, - "write memory", + "write []", "Write running configuration to memory, network, or terminal\n" - "Write configuration to the file (same as write file)\n") + "Write configuration to the file (same as write file)\n" + "Write configuration to the file (same as write memory)\n") { int ret = CMD_SUCCESS; char line[] = "write memory\n"; @@@ -2384,14 -2644,42 +2630,13 @@@ DEFUN (vtysh_copy_running_config "Copy from one file to another\n" "Copy from current system configuration\n" "Copy to startup configuration\n") - -ALIAS (vtysh_write_memory, - vtysh_write_file_cmd, - "write file", - "Write running configuration to memory, network, or terminal\n" - "Write configuration to the file (same as write memory)\n") - -ALIAS (vtysh_write_memory, - vtysh_write_cmd, - "write", - "Write running configuration to memory, network, or terminal\n") - -ALIAS (vtysh_write_terminal, - vtysh_show_running_config_cmd, - "show running-config", - SHOW_STR - "Current operating configuration\n") - -ALIAS (vtysh_write_terminal, - vtysh_show_running_config_daemon_cmd, - "show running-config (zebra|ripd|ripngd|ospfd|ospf6d|ldpd|bgpd|isisd|pimd)", - SHOW_STR - "Current operating configuration\n" - "For the zebra daemon\n" - "For the rip daemon\n" - "For the ripng daemon\n" - "For the ospf daemon\n" - "For the ospfv6 daemon\n" - "For the ldp daemon\n" - "For the bgp daemon\n" - "For the isis daemon\n" - "For the pim daemon\n") +{ + return vtysh_write_memory (self, vty, argc, argv); +} - DEFUN (vtysh_terminal_length, vtysh_terminal_length_cmd, - "terminal length <0-512>", + "terminal length (0-512)", "Set terminal line parameters\n" "Set number of lines on a screen\n" "Number of lines on screen (0 for no pausing)\n") @@@ -2920,10 -3230,9 +3188,8 @@@ vtysh_init_vty (void /* "exit" command. */ install_element (VIEW_NODE, &vtysh_exit_all_cmd); - install_element (VIEW_NODE, &vtysh_quit_all_cmd); install_element (CONFIG_NODE, &vtysh_exit_all_cmd); /* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */ - install_element (ENABLE_NODE, &vtysh_exit_all_cmd); - install_element (ENABLE_NODE, &vtysh_quit_all_cmd); install_element (RIP_NODE, &vtysh_exit_ripd_cmd); install_element (RIP_NODE, &vtysh_quit_ripd_cmd); install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd); @@@ -3007,8 -3346,18 +3303,15 @@@ #ifdef HAVE_IPV6 install_element (CONFIG_NODE, &router_ospf6_cmd); #endif + install_element (CONFIG_NODE, &ldp_mpls_ldp_cmd); + install_element (LDP_NODE, &ldp_address_family_ipv4_cmd); + install_element (LDP_NODE, &ldp_address_family_ipv6_cmd); + install_element (LDP_IPV4_NODE, &ldp_interface_ifname_cmd); + install_element (LDP_IPV6_NODE, &ldp_interface_ifname_cmd); + install_element (CONFIG_NODE, &ldp_l2vpn_word_type_vpls_cmd); + install_element (LDP_L2VPN_NODE, &ldp_member_pseudowire_ifname_cmd); install_element (CONFIG_NODE, &router_isis_cmd); install_element (CONFIG_NODE, &router_bgp_cmd); - install_element (CONFIG_NODE, &router_bgp_asn_cmd); - install_element (CONFIG_NODE, &router_bgp_view_cmd); install_element (BGP_NODE, &address_family_vpnv4_cmd); install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd); install_element (BGP_NODE, &address_family_vpnv6_cmd); diff --cc zebra/debug.c index 6acf32b43d,92354070ef..65ae3fd174 --- a/zebra/debug.c +++ b/zebra/debug.c @@@ -422,9 -449,10 +454,9 @@@ zebra_debug_init (void install_element (VIEW_NODE, &show_debugging_zebra_cmd); -- install_element (ENABLE_NODE, &show_debugging_zebra_cmd); install_element (ENABLE_NODE, &debug_zebra_events_cmd); install_element (ENABLE_NODE, &debug_zebra_nht_cmd); + install_element (ENABLE_NODE, &debug_zebra_mpls_cmd); install_element (ENABLE_NODE, &debug_zebra_packet_cmd); install_element (ENABLE_NODE, &debug_zebra_packet_direct_cmd); install_element (ENABLE_NODE, &debug_zebra_packet_detail_cmd); diff --cc zebra/interface.c index 62340a460a,0f4d2ee9e4..bbe19fbaf4 --- a/zebra/interface.c +++ b/zebra/interface.c @@@ -1233,8 -1233,7 +1233,7 @@@ DEFUN_NOSH (zebra_interface "Interface's name\n") { int ret; - struct interface *ifp; - + /* Call lib interface() */ if ((ret = interface_cmd.func (self, vty, argc, argv)) != CMD_SUCCESS) return ret; @@@ -1553,10 -1567,9 +1549,9 @@@ DEFUN (linkdetect "link-detect", "Enable link detection on interface\n") { - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); int if_was_operative; - + - ifp = (struct interface *) vty->index; if_was_operative = if_is_no_ptm_operative(ifp); SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); @@@ -1657,12 -1666,10 +1648,11 @@@ DEFUN (bandwidth_if "Set bandwidth informational parameter\n" "Bandwidth in megabits\n") { + int idx_number = 1; - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); unsigned int bandwidth; - - bandwidth = strtol(argv[0], NULL, 10); + - ifp = (struct interface *) vty->index; + bandwidth = strtol(argv[idx_number]->arg, NULL, 10); /* bandwidth range is <1-100000> */ if (bandwidth < 1 || bandwidth > 100000) @@@ -1682,14 -1689,11 +1672,12 @@@ DEFUN (no_bandwidth_if, no_bandwidth_if_cmd, - "no bandwidth", + "no bandwidth [(1-100000)]", NO_STR - "Set bandwidth informational parameter\n") + "Set bandwidth informational parameter\n" + "Bandwidth in megabits\n") { - struct interface *ifp; - - ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); ifp->bandwidth = 0; @@@ -1817,8 -1828,7 +1806,8 @@@ DEFUN (link_params_metric "Link metric for MPLS-TE purpose\n" "Metric value in decimal\n") { + int idx_number = 1; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); u_int32_t metric; @@@ -1850,8 -1860,7 +1839,8 @@@ DEFUN (link_params_maxbw "Maximum bandwidth that can be used\n" "Bytes/second (IEEE floating point format)\n") { + int idx_bandwidth = 1; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); float bw; @@@ -1895,8 -1904,7 +1884,8 @@@ DEFUN (link_params_max_rsv_bw "Maximum bandwidth that may be reserved\n" "Bytes/second (IEEE floating point format)\n") { + int idx_bandwidth = 1; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); float bw; @@@ -1929,9 -1937,7 +1918,9 @@@ DEFUN (link_params_unrsv_bw "Priority\n" "Bytes/second (IEEE floating point format)\n") { + int idx_number = 1; + int idx_bandwidth = 2; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); int priority; float bw; @@@ -1972,8 -1978,7 +1961,8 @@@ DEFUN (link_params_admin_grp "Administrative group membership\n" "32-bit Hexadecimal value (e.g. 0xa1)\n") { + int idx_bitpattern = 1; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); unsigned long value; @@@ -2013,10 -2018,7 +2002,10 @@@ DEFUN (link_params_inter_as "Remote AS number\n" "AS number in the range <1-4294967295>\n") { + int idx_ipv4 = 1; + int idx_number = 3; + - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); struct in_addr addr; u_int32_t as; @@@ -2071,77 -2072,78 +2059,77 @@@ DEFUN (no_link_params_inter_as /* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */ DEFUN (link_params_delay, link_params_delay_cmd, - "delay <0-16777215>", + "delay (0-16777215) [min (0-16777215) max (0-16777215)]", "Unidirectional Average Link Delay\n" - "Average delay in micro-second as decimal (0...16777215)\n") + "Average delay in micro-second as decimal (0...16777215)\n" + "Minimum delay\n" + "Minimum delay in micro-second as decimal (0...16777215)\n" + "Maximum delay\n" + "Maximum delay in micro-second as decimal (0...16777215)\n") { + /* Get and Check new delay values */ + u_int32_t delay = 0, low = 0, high = 0; + VTY_GET_ULONG("delay", delay, argv[1]->arg); + if (argc == 6) + { + VTY_GET_ULONG("minimum delay", low, argv[3]->arg); + VTY_GET_ULONG("maximum delay", high, argv[5]->arg); + } + - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); - u_int32_t delay = 0, low = 0, high = 0; u_int8_t update = 0; - /* Get and Check new delay values */ - VTY_GET_ULONG("delay", delay, argv[0]); - switch (argc) - { - case 1: - /* Check new delay value against old Min and Max delays if set */ - if (IS_PARAM_SET(iflp, LP_MM_DELAY) - && (delay <= iflp->min_delay || delay >= iflp->max_delay)) - { - vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s", - iflp->min_delay, iflp->max_delay, VTY_NEWLINE); - return CMD_WARNING; - } - /* Update delay if value is not set or change */ - if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay) - { - iflp->av_delay = delay; - SET_PARAM(iflp, LP_DELAY); - update = 1; - } - /* Unset Min and Max delays if already set */ - if (IS_PARAM_SET(iflp, LP_MM_DELAY)) - { - iflp->min_delay = 0; - iflp->max_delay = 0; - UNSET_PARAM(iflp, LP_MM_DELAY); - update = 1; - } - break; - case 2: - vty_out (vty, "You should specify both Minimum and Maximum delay with Average delay%s", - VTY_NEWLINE); - return CMD_WARNING; - break; - case 3: - VTY_GET_ULONG("minimum delay", low, argv[1]); - VTY_GET_ULONG("maximum delay", high, argv[2]); - /* Check new delays value coherency */ - if (delay <= low || delay >= high) - { - vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s", - low, high, VTY_NEWLINE); - return CMD_WARNING; - } - /* Update Delays if needed */ - if (IS_PARAM_UNSET(iflp, LP_DELAY) - || IS_PARAM_UNSET(iflp, LP_MM_DELAY) - || iflp->av_delay != delay - || iflp->min_delay != low - || iflp->max_delay != high) - { - iflp->av_delay = delay; - SET_PARAM(iflp, LP_DELAY); - iflp->min_delay = low; - iflp->max_delay = high; - SET_PARAM(iflp, LP_MM_DELAY); - update = 1; - } - break; - default: - return CMD_WARNING; - break; - } + if (argc == 2) + { + /* Check new delay value against old Min and Max delays if set */ + if (IS_PARAM_SET(iflp, LP_MM_DELAY) + && (delay <= iflp->min_delay || delay >= iflp->max_delay)) + { + vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s", + iflp->min_delay, iflp->max_delay, VTY_NEWLINE); + return CMD_WARNING; + } + /* Update delay if value is not set or change */ + if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay) + { + iflp->av_delay = delay; + SET_PARAM(iflp, LP_DELAY); + update = 1; + } + /* Unset Min and Max delays if already set */ + if (IS_PARAM_SET(iflp, LP_MM_DELAY)) + { + iflp->min_delay = 0; + iflp->max_delay = 0; + UNSET_PARAM(iflp, LP_MM_DELAY); + update = 1; + } + } + else + { + /* Check new delays value coherency */ + if (delay <= low || delay >= high) + { + vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s", + low, high, VTY_NEWLINE); + return CMD_WARNING; + } + /* Update Delays if needed */ + if (IS_PARAM_UNSET(iflp, LP_DELAY) + || IS_PARAM_UNSET(iflp, LP_MM_DELAY) + || iflp->av_delay != delay + || iflp->min_delay != low + || iflp->max_delay != high) + { + iflp->av_delay = delay; + SET_PARAM(iflp, LP_DELAY); + iflp->min_delay = low; + iflp->max_delay = high; + SET_PARAM(iflp, LP_MM_DELAY); + update = 1; + } + } /* force protocols to update LINK STATE due to parameters change */ if (update == 1 && if_is_operative (ifp)) @@@ -2179,8 -2191,7 +2167,8 @@@ DEFUN (link_params_delay_var "Unidirectional Link Delay Variation\n" "delay variation in micro-second as decimal (0...16777215)\n") { + int idx_number = 1; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); u_int32_t value; @@@ -2212,8 -2223,7 +2200,8 @@@ DEFUN (link_params_pkt_loss "Unidirectional Link Packet Loss\n" "percentage of total traffic by 0.000003% step and less than 50.331642%\n") { + int idx_percentage = 1; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); float fval; @@@ -2253,8 -2263,7 +2241,8 @@@ DEFUN (link_params_res_bw "Unidirectional Residual Bandwidth\n" "Bytes/second (IEEE floating point format)\n") { + int idx_bandwidth = 1; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); float bw; @@@ -2300,8 -2309,7 +2288,8 @@@ DEFUN (link_params_ava_bw "Unidirectional Available Bandwidth\n" "Bytes/second (IEEE floating point format)\n") { + int idx_bandwidth = 1; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); float bw; @@@ -2347,8 -2355,7 +2335,8 @@@ DEFUN (link_params_use_bw "Unidirectional Utilised Bandwidth\n" "Bytes/second (IEEE floating point format)\n") { + int idx_bandwidth = 1; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct if_link_params *iflp = if_link_params_get (ifp); float bw; @@@ -2536,8 -2543,8 +2524,9 @@@ DEFUN (ip_address "Set the IP address of an interface\n" "IP address (e.g. 10.0.0.1/8)\n") { + int idx_ipv4_prefixlen = 2; - return ip_address_install (vty, vty->index, argv[idx_ipv4_prefixlen]->arg, NULL, NULL); + VTY_DECLVAR_CONTEXT (interface, ifp); - return ip_address_install (vty, ifp, argv[0], NULL, NULL); ++ return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL); } DEFUN (no_ip_address, @@@ -2548,8 -2555,8 +2537,9 @@@ "Set the IP address of an interface\n" "IP Address (e.g. 10.0.0.1/8)") { + int idx_ipv4_prefixlen = 3; - return ip_address_uninstall (vty, vty->index, argv[idx_ipv4_prefixlen]->arg, NULL, NULL); + VTY_DECLVAR_CONTEXT (interface, ifp); - return ip_address_uninstall (vty, ifp, argv[0], NULL, NULL); ++ return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL); } @@@ -2563,9 -2570,8 +2553,10 @@@ DEFUN (ip_address_label "Label of this address\n" "Label\n") { + int idx_ipv4_prefixlen = 2; + int idx_line = 4; - return ip_address_install (vty, vty->index, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg); + VTY_DECLVAR_CONTEXT (interface, ifp); - return ip_address_install (vty, ifp, argv[0], NULL, argv[1]); ++ return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg); } DEFUN (no_ip_address_label, @@@ -2578,9 -2584,8 +2569,10 @@@ "Label of this address\n" "Label\n") { + int idx_ipv4_prefixlen = 3; + int idx_line = 5; - return ip_address_uninstall (vty, vty->index, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg); + VTY_DECLVAR_CONTEXT (interface, ifp); - return ip_address_uninstall (vty, ifp, argv[0], NULL, argv[1]); ++ return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg); } #endif /* HAVE_NETLINK */ @@@ -2743,8 -2748,8 +2735,9 @@@ DEFUN (ipv6_address "Set the IP address of an interface\n" "IPv6 address (e.g. 3ffe:506::1/48)\n") { + int idx_ipv6_prefixlen = 2; - return ipv6_address_install (vty, vty->index, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0); + VTY_DECLVAR_CONTEXT (interface, ifp); - return ipv6_address_install (vty, ifp, argv[0], NULL, NULL, 0); ++ return ipv6_address_install (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0); } DEFUN (no_ipv6_address, @@@ -2755,8 -2760,8 +2748,9 @@@ "Set the IP address of an interface\n" "IPv6 address (e.g. 3ffe:506::1/48)\n") { + int idx_ipv6_prefixlen = 3; - return ipv6_address_uninstall (vty, vty->index, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0); + VTY_DECLVAR_CONTEXT (interface, ifp); - return ipv6_address_uninstall (vty, ifp, argv[0], NULL, NULL, 0); ++ return ipv6_address_uninstall (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0); } #endif /* HAVE_IPV6 */ @@@ -2930,17 -2935,18 +2924,14 @@@ zebra_if_init (void install_node (&vrf_node, vrf_config_write); install_element (VIEW_NODE, &show_interface_cmd); - install_element (VIEW_NODE, &show_interface_vrf_cmd); install_element (VIEW_NODE, &show_interface_vrf_all_cmd); - install_element (VIEW_NODE, &show_interface_name_cmd); install_element (VIEW_NODE, &show_interface_name_vrf_cmd); install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd); - install_element (ENABLE_NODE, &show_interface_cmd); - install_element (ENABLE_NODE, &show_interface_vrf_all_cmd); - install_element (ENABLE_NODE, &show_interface_name_vrf_cmd); - install_element (ENABLE_NODE, &show_interface_name_vrf_all_cmd); ++ install_element (ENABLE_NODE, &show_interface_desc_cmd); - install_element (ENABLE_NODE, &show_interface_desc_vrf_cmd); install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd); install_element (CONFIG_NODE, &zebra_interface_cmd); - install_element (CONFIG_NODE, &zebra_interface_vrf_cmd); install_element (CONFIG_NODE, &no_interface_cmd); - install_element (CONFIG_NODE, &no_interface_vrf_cmd); install_default (INTERFACE_NODE); install_element (INTERFACE_NODE, &interface_desc_cmd); install_element (INTERFACE_NODE, &no_interface_desc_cmd); diff --cc zebra/irdp_interface.c index 2f741380f5,9d8c2e67bf..3e244f5af3 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@@ -18,17 -18,17 +18,17 @@@ * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -- * 02111-1307, USA. ++ * 02111-1307, USA. */ --/* ++/* * This work includes work with the following copywrite: * * Copyright (C) 1997, 2000 Kunihiro Ishiguro * */ --/* ++/* * Thanks to Jens Låås at Swedish University of Agricultural Sciences * for reviewing and tests. */ @@@ -36,7 -36,7 +36,7 @@@ #include --#ifdef HAVE_IRDP ++#ifdef HAVE_IRDP #include "if.h" #include "vty.h" @@@ -81,7 -81,7 +81,7 @@@ irdp_get_prefix(struct interface *ifp { struct listnode *node; struct connected *ifc; -- ++ if (ifp->connected) for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) return ifc->address; @@@ -91,9 -91,9 +91,9 @@@ /* Join to the add/leave multicast group. */ static int --if_group (struct interface *ifp, -- int sock, -- u_int32_t group, ++if_group (struct interface *ifp, ++ int sock, ++ u_int32_t group, int add_leave) { struct ip_mreq m; @@@ -116,7 -116,7 +116,7 @@@ (char *) &m, sizeof (struct ip_mreq)); if (ret < 0) zlog_warn ("IRDP: %s can't setsockopt %s: %s", -- add_leave == IP_ADD_MEMBERSHIP? "join group":"leave group", ++ add_leave == IP_ADD_MEMBERSHIP? "join group":"leave group", inet_2a(group, b1), safe_strerror (errno)); @@@ -137,7 -137,7 +137,7 @@@ if_add_group (struct interface *ifp } if(irdp->flags & IF_DEBUG_MISC ) -- zlog_debug("IRDP: Adding group %s for %s", ++ zlog_debug("IRDP: Adding group %s for %s", inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1), ifp->name); return 0; @@@ -156,7 -156,7 +156,7 @@@ if_drop_group (struct interface *ifp return ret; if(irdp->flags & IF_DEBUG_MISC) -- zlog_debug("IRDP: Leaving group %s for %s", ++ zlog_debug("IRDP: Leaving group %s for %s", inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1), ifp->name); return 0; @@@ -206,7 -206,7 +206,7 @@@ irdp_if_start(struct interface *ifp, in } irdp->flags |= IF_ACTIVE; -- if(!multicast) ++ if(!multicast) irdp->flags |= IF_BROADCAST; if_add_update(ifp); @@@ -219,13 -219,13 +219,13 @@@ if( multicast) { if_add_group(ifp); -- ++ if (! (ifp->flags & (IFF_MULTICAST|IFF_ALLMULTI))) { zlog_warn("IRDP: Interface not multicast enabled %s", ifp->name); } } -- if(set_defaults) ++ if(set_defaults) if_set_defaults(ifp); irdp->irdp_sent = 0; @@@ -239,9 -239,9 +239,9 @@@ seed = ifc->address->u.prefix4.s_addr; break; } -- ++ srandom(seed); -- timer = (random () % IRDP_DEFAULT_INTERVAL) + 1; ++ timer = (random () % IRDP_DEFAULT_INTERVAL) + 1; irdp->AdvPrefList = list_new(); irdp->AdvPrefList->del = (void (*)(void *)) Adv_free; /* Destructor */ @@@ -250,18 -250,18 +250,18 @@@ /* And this for startup. Speed limit from 1991 :-). But it's OK*/ if(irdp->irdp_sent < MAX_INITIAL_ADVERTISEMENTS && -- timer > MAX_INITIAL_ADVERT_INTERVAL ) ++ timer > MAX_INITIAL_ADVERT_INTERVAL ) timer= MAX_INITIAL_ADVERT_INTERVAL; -- ++ if(irdp->flags & IF_DEBUG_MISC) -- zlog_debug("IRDP: Init timer for %s set to %u", -- ifp->name, ++ zlog_debug("IRDP: Init timer for %s set to %u", ++ ifp->name, timer); -- irdp->t_advertise = thread_add_timer(zebrad.master, -- irdp_send_thread, -- ifp, ++ irdp->t_advertise = thread_add_timer(zebrad.master, ++ irdp_send_thread, ++ ifp, timer); } @@@ -270,7 -270,7 +270,7 @@@ irdp_if_stop(struct interface *ifp { struct zebra_if *zi=ifp->info; struct irdp_interface *irdp=&zi->irdp; -- ++ if (irdp == NULL) { zlog_warn ("Interface %s structure is NULL", ifp->name); return; @@@ -281,7 -281,7 +281,7 @@@ return; } -- if(! (irdp->flags & IF_BROADCAST)) ++ if(! (irdp->flags & IF_BROADCAST)) if_drop_group(ifp); irdp_advert_off(ifp); @@@ -307,9 -307,9 +307,9 @@@ irdp_if_shutdown(struct interface *ifp irdp->flags |= IF_SHUTDOWN; irdp->flags &= ~IF_ACTIVE; -- if(! (irdp->flags & IF_BROADCAST)) ++ if(! (irdp->flags & IF_BROADCAST)) if_drop_group(ifp); -- ++ /* Tell the hosts we are out of service */ irdp_advert_off(ifp); } @@@ -327,7 -327,7 +327,7 @@@ irdp_if_no_shutdown(struct interface *i irdp->flags &= ~IF_SHUTDOWN; -- irdp_if_start(ifp, irdp->flags & IF_BROADCAST? FALSE : TRUE, FALSE); ++ irdp_if_start(ifp, irdp->flags & IF_BROADCAST? FALSE : TRUE, FALSE); } @@@ -344,30 -344,30 +344,30 @@@ void irdp_config_write (struct vty *vty if(irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) { -- if( irdp->flags & IF_SHUTDOWN) ++ if( irdp->flags & IF_SHUTDOWN) vty_out (vty, " ip irdp shutdown %s", VTY_NEWLINE); -- if( irdp->flags & IF_BROADCAST) ++ if( irdp->flags & IF_BROADCAST) vty_out (vty, " ip irdp broadcast%s", VTY_NEWLINE); -- else ++ else vty_out (vty, " ip irdp multicast%s", VTY_NEWLINE); -- vty_out (vty, " ip irdp preference %ld%s", ++ vty_out (vty, " ip irdp preference %ld%s", irdp->Preference, VTY_NEWLINE); for (ALL_LIST_ELEMENTS_RO (irdp->AdvPrefList, node, adv)) vty_out (vty, " ip irdp address %s preference %d%s", inet_2a(adv->ip.s_addr, b1), -- adv->pref, ++ adv->pref, VTY_NEWLINE); -- vty_out (vty, " ip irdp holdtime %d%s", ++ vty_out (vty, " ip irdp holdtime %d%s", irdp->Lifetime, VTY_NEWLINE); -- vty_out (vty, " ip irdp minadvertinterval %ld%s", ++ vty_out (vty, " ip irdp minadvertinterval %ld%s", irdp->MinAdvertInterval, VTY_NEWLINE); -- vty_out (vty, " ip irdp maxadvertinterval %ld%s", ++ vty_out (vty, " ip irdp maxadvertinterval %ld%s", irdp->MaxAdvertInterval, VTY_NEWLINE); } @@@ -469,14 -444,9 +444,10 @@@ DEFUN (ip_irdp_holdtime "Set holdtime value\n" "Holdtime value in seconds. Default is 1800 seconds\n") { + int idx_number = 3; - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); struct zebra_if *zi; struct irdp_interface *irdp; - ifp = (struct interface *) vty->index; - if(!ifp) { - return CMD_WARNING; - } zi=ifp->info; irdp=&zi->irdp; @@@ -493,14 -463,9 +464,10 @@@ DEFUN (ip_irdp_minadvertinterval "Set minimum time between advertisement\n" "Minimum advertisement interval in seconds\n") { + int idx_number = 3; - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); struct zebra_if *zi; struct irdp_interface *irdp; - ifp = (struct interface *) vty->index; - if(!ifp) { - return CMD_WARNING; - } zi=ifp->info; irdp=&zi->irdp; @@@ -511,10 -476,10 +478,10 @@@ return CMD_SUCCESS; } -- vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s", ++ vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s", VTY_NEWLINE); -- vty_out (vty, "Please correct!%s", ++ vty_out (vty, "Please correct!%s", VTY_NEWLINE); return CMD_WARNING; } @@@ -527,14 -492,9 +494,10 @@@ DEFUN (ip_irdp_maxadvertinterval "Set maximum time between advertisement\n" "Maximum advertisement interval in seconds\n") { + int idx_number = 3; - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); struct zebra_if *zi; struct irdp_interface *irdp; - ifp = (struct interface *) vty->index; - if(!ifp) { - return CMD_WARNING; - } zi=ifp->info; irdp=&zi->irdp; @@@ -546,10 -506,10 +509,10 @@@ return CMD_SUCCESS; } -- vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s", ++ vty_out (vty, "ICMP warning maxadvertinterval is greater or equal than minadvertinterval%s", VTY_NEWLINE); -- vty_out (vty, "Please correct!%s", ++ vty_out (vty, "Please correct!%s", VTY_NEWLINE); return CMD_WARNING; } @@@ -567,14 -527,9 +530,10 @@@ DEFUN (ip_irdp_preference "Set default preference level for this interface\n" "Preference level\n") { + int idx_number = 3; - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); struct zebra_if *zi; struct irdp_interface *irdp; - ifp = (struct interface *) vty->index; - if(!ifp) { - return CMD_WARNING; - } zi=ifp->info; irdp=&zi->irdp; @@@ -592,13 -547,11 +551,13 @@@ DEFUN (ip_irdp_address_preference "Set IRDP address for advertise\n" "Preference level\n") { + int idx_ipv4 = 3; + int idx_number = 5; + VTY_DECLVAR_CONTEXT (interface, ifp); struct listnode *node; -- struct in_addr ip; ++ struct in_addr ip; int pref; int ret; - struct interface *ifp; struct zebra_if *zi; struct irdp_interface *irdp; struct Adv *adv; @@@ -606,18 -559,13 +565,13 @@@ zi=ifp->info; irdp=&zi->irdp; - ret = inet_aton(argv[0], &ip); + ret = inet_aton(argv[idx_ipv4]->arg, &ip); if(!ret) return CMD_WARNING; - pref = atoi(argv[1]); + pref = atoi(argv[idx_number]->arg); for (ALL_LIST_ELEMENTS_RO (irdp->AdvPrefList, node, adv)) -- if(adv->ip.s_addr == ip.s_addr) ++ if(adv->ip.s_addr == ip.s_addr) return CMD_SUCCESS; adv = Adv_new(); @@@ -639,11 -587,10 +593,11 @@@ DEFUN (no_ip_irdp_address_preference "Select IRDP address\n" "Old preference level\n") { + int idx_ipv4 = 4; + VTY_DECLVAR_CONTEXT (interface, ifp); struct listnode *node, *nnode; -- struct in_addr ip; ++ struct in_addr ip; int ret; - struct interface *ifp; struct zebra_if *zi; struct irdp_interface *irdp; struct Adv *adv; @@@ -651,13 -598,8 +605,8 @@@ zi=ifp->info; irdp=&zi->irdp; - ret = inet_aton(argv[0], &ip); - if (!ret) + ret = inet_aton(argv[idx_ipv4]->arg, &ip); - if (!ret) ++ if (!ret) return CMD_WARNING; for (ALL_LIST_ELEMENTS (irdp->AdvPrefList, node, nnode, adv)) @@@ -668,7 -610,7 +617,7 @@@ break; } } -- ++ return CMD_SUCCESS; } diff --cc zebra/rt_netlink.c index a5f62dfa03,19f453b150..afcd5f0235 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@@ -16,7 -16,7 +16,7 @@@ * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -- * 02111-1307, USA. ++ * 02111-1307, USA. */ #include @@@ -40,7 -40,7 +40,8 @@@ #include "privs.h" #include "nexthop.h" #include "vrf.h" +#include "vty.h" + #include "mpls.h" #include "zebra/zserv.h" #include "zebra/zebra_ns.h" @@@ -94,7 -142,7 +143,7 @@@ set_ifindex(struct interface *ifp, ifin ifi_index, oifp->name, ifp->name); if (if_is_up(oifp)) zlog_err("interface rename detected on up interface: index %d " -- "was renamed from %s to %s, results are uncertain!", ++ "was renamed from %s to %s, results are uncertain!", ifi_index, oifp->name, ifp->name); if_delete_update(oifp); } @@@ -243,7 -291,7 +292,7 @@@ netlink_request (int family, int type, req.nlh.nlmsg_seq = ++nl->seq; req.g.rtgen_family = family; -- /* linux appears to check capabilities on every message ++ /* linux appears to check capabilities on every message * have to raise caps for every message sent */ if (zserv_privs.change (ZPRIVS_RAISE)) @@@ -707,7 -755,7 +756,7 @@@ netlink_interface (struct sockaddr_nl * /* Looking up interface name. */ memset (tb, 0, sizeof tb); netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len); -- ++ #ifdef IFLA_WIRELESS /* check for wireless messages to ignore */ if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0)) @@@ -834,7 -882,7 +883,7 @@@ netlink_interface_addr (struct sockaddr buf, BUFSIZ), ifa->ifa_prefixlen); if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL]))) zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb[IFA_LABEL])); -- ++ if (tb[IFA_CACHEINFO]) { struct ifa_cacheinfo *ci = RTA_DATA (tb[IFA_CACHEINFO]); @@@ -842,13 -890,13 +891,13 @@@ ci->ifa_prefered, ci->ifa_valid); } } -- ++ /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */ if (tb[IFA_LOCAL] == NULL) tb[IFA_LOCAL] = tb[IFA_ADDRESS]; if (tb[IFA_ADDRESS] == NULL) tb[IFA_ADDRESS] = tb[IFA_LOCAL]; -- ++ /* local interface address */ addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL); @@@ -1124,7 -1177,7 +1178,7 @@@ netlink_route_change (struct sockaddr_n struct rtattr *tb[RTA_MAX + 1]; u_char zebra_flags = 0; struct prefix p; -- ++ char anyaddr[16] = { 0 }; int index; @@@ -1400,7 -1458,7 +1459,7 @@@ netlink_link_change (struct sockaddr_n return 0; } #endif /* IFLA_WIRELESS */ -- ++ if (tb[IFLA_IFNAME] == NULL) return -1; name = (char *) RTA_DATA (tb[IFLA_IFNAME]); @@@ -1638,7 -1696,7 +1697,7 @@@ netlink_route_read (struct zebra_ns *zn return 0; } --/* Utility function comes from iproute2. ++/* Utility function comes from iproute2. Authors: Alexey Kuznetsov, */ int addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type, void *data, int alen) @@@ -1680,7 -1739,7 +1740,7 @@@ rta_addattr_l (struct rtattr *rta, unsi return 0; } --/* Utility function comes from iproute2. ++/* Utility function comes from iproute2. Authors: Alexey Kuznetsov, */ int addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data) @@@ -1765,8 -1843,8 +1844,8 @@@ netlink_talk (struct nlmsghdr *n, struc } -- /* -- * Get reply from netlink socket. ++ /* ++ * Get reply from netlink socket. * The reply should either be an acknowlegement or an error. */ return netlink_parse_info (netlink_talk_filter, nl, zns, 0); @@@ -1820,6 -1955,59 +1956,59 @@@ _netlink_route_build_singlepath return; } + label_buf[0] = '\0'; + /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP + * (in the case of LER) + */ + nh_label = nexthop->nh_label; + if (rtmsg->rtm_family == AF_MPLS) + { + assert (nh_label); + assert (nh_label->num_labels == 1); + } + + if (nh_label && nh_label->num_labels) + { + int i, num_labels = 0; + u_int32_t bos; + char label_buf1[20]; - ++ + for (i = 0; i < nh_label->num_labels; i++) + { + if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) + { + bos = ((i == (nh_label->num_labels - 1)) ? 1 : 0); + out_lse[i] = mpls_lse_encode (nh_label->label[i], 0, 0, bos); + if (!num_labels) + sprintf (label_buf, "label %d", nh_label->label[i]); + else + { + sprintf (label_buf1, "/%d", nh_label->label[i]); + strcat (label_buf, label_buf1); + } + num_labels++; + } + } + if (num_labels) + { + if (rtmsg->rtm_family == AF_MPLS) + addattr_l (nlmsg, req_size, RTA_NEWDST, + &out_lse, num_labels * sizeof(mpls_lse_t)); + else + { + struct rtattr *nest; + u_int16_t encap = LWTUNNEL_ENCAP_MPLS; + + addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, + &encap, sizeof (u_int16_t)); + nest = addattr_nest(nlmsg, req_size, RTA_ENCAP); + addattr_l (nlmsg, req_size, MPLS_IPTUNNEL_DST, + &out_lse, num_labels * sizeof(mpls_lse_t)); + addattr_nest_end(nlmsg, nest); + } + } + } + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) rtmsg->rtm_flags |= RTNH_F_ONLINK; @@@ -2063,9 -2347,20 +2348,20 @@@ _netlink_route_debug zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s", routedesc, lookup (nlmsg_str, cmd), - prefix2str (p, buf, sizeof(buf)), - zvrf->vrf_id, nexthop_type_to_str (nexthop->type)); + prefix2str (p, buf, sizeof(buf)), zvrf->vrf_id, + (nexthop) ? nexthop_type_to_str (nexthop->type) : "UNK"); } -} ++ } + + static void + _netlink_mpls_debug( + int cmd, + u_int32_t label, + const char *routedesc) + { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug ("netlink_mpls_multipath() (%s): %s %u/20", + routedesc, lookup (nlmsg_str, cmd), label); } static int diff --cc zebra/rtadv.c index 7edba55953,3e0a198702..dcf31ff450 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@@ -924,9 -917,8 +918,9 @@@ DEFUN (ipv6_nd_ra_interval_msec "Router Advertisement interval\n" "Router Advertisement interval in milliseconds\n") { + int idx_number = 4; + VTY_DECLVAR_CONTEXT (interface, ifp); unsigned interval; - struct interface *ifp = (struct interface *) vty->index; struct zebra_if *zif = ifp->info; struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); struct zebra_ns *zns; @@@ -960,9 -952,8 +954,9 @@@ DEFUN (ipv6_nd_ra_interval "Router Advertisement interval\n" "Router Advertisement interval in seconds\n") { + int idx_number = 3; + VTY_DECLVAR_CONTEXT (interface, ifp); unsigned interval; - struct interface *ifp = (struct interface *) vty->index; struct zebra_if *zif = ifp->info; struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); struct zebra_ns *zns; @@@ -994,13 -985,10 +988,13 @@@ DEFUN (no_ipv6_nd_ra_interval NO_STR "Interface IPv6 config commands\n" "Neighbor discovery\n" - "Router Advertisement interval\n") + "Router Advertisement interval\n" + "Router Advertisement interval in seconds\n" + "Specify millisecond router advertisement interval\n" + "Router Advertisement interval in milliseconds\n") { - struct interface *ifp; - struct zebra_if *zif; + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zif = ifp->info; struct zebra_vrf *zvrf; struct zebra_ns *zns; @@@ -1027,15 -1030,11 +1019,12 @@@ DEFUN (ipv6_nd_ra_lifetime "Router lifetime\n" "Router lifetime in seconds (0 stands for a non-default gw)\n") { + int idx_number = 3; + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zif = ifp->info; int lifetime; - struct interface *ifp; - struct zebra_if *zif; - - ifp = (struct interface *) vty->index; - zif = ifp->info; - VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000); + VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[idx_number]->arg, 0, 9000); /* The value to be placed in the Router Lifetime field * of Router Advertisements sent from the interface, @@@ -1058,14 -1057,10 +1047,11 @@@ DEFUN (no_ipv6_nd_ra_lifetime NO_STR "Interface IPv6 config commands\n" "Neighbor discovery\n" - "Router lifetime\n") + "Router lifetime\n" + "Router lifetime in seconds (0 stands for a non-default gw)\n") { - struct interface *ifp; - struct zebra_if *zif; - - ifp = (struct interface *) vty->index; - zif = ifp->info; + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zif = ifp->info; zif->rtadv.AdvDefaultLifetime = -1; @@@ -1080,10 -1084,9 +1066,10 @@@ DEFUN (ipv6_nd_reachable_time "Reachable time\n" "Reachable time in milliseconds\n") { + int idx_number = 3; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct zebra_if *zif = ifp->info; - VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME); + VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[idx_number]->arg, 1, RTADV_MAX_REACHABLE_TIME); return CMD_SUCCESS; } @@@ -1093,14 -1096,10 +1079,11 @@@ DEFUN (no_ipv6_nd_reachable_time NO_STR "Interface IPv6 config commands\n" "Neighbor discovery\n" - "Reachable time\n") + "Reachable time\n" + "Reachable time in milliseconds\n") { - struct interface *ifp; - struct zebra_if *zif; - - ifp = (struct interface *) vty->index; - zif = ifp->info; + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zif = ifp->info; zif->rtadv.AdvReachableTime = 0; @@@ -1115,10 -1123,9 +1098,10 @@@ DEFUN (ipv6_nd_homeagent_preference "Home Agent preference\n" "preference value (default is 0, least preferred)\n") { + int idx_number = 3; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct zebra_if *zif = ifp->info; - VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535); + VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[idx_number]->arg, 0, 65535); return CMD_SUCCESS; } @@@ -1128,14 -1135,10 +1111,11 @@@ DEFUN (no_ipv6_nd_homeagent_preference NO_STR "Interface IPv6 config commands\n" "Neighbor discovery\n" - "Home Agent preference\n") + "Home Agent preference\n" + "preference value (default is 0, least preferred)\n") { - struct interface *ifp; - struct zebra_if *zif; - - ifp = (struct interface *) vty->index; - zif = ifp->info; + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zif = ifp->info; zif->rtadv.HomeAgentPreference = 0; @@@ -1150,10 -1162,9 +1130,10 @@@ DEFUN (ipv6_nd_homeagent_lifetime "Home Agent lifetime\n" "Home Agent lifetime in seconds (0 to track ra-lifetime)\n") { + int idx_number = 3; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct zebra_if *zif = ifp->info; - VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME); + VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[idx_number]->arg, 0, RTADV_MAX_HALIFETIME); return CMD_SUCCESS; } @@@ -1163,14 -1174,10 +1143,11 @@@ DEFUN (no_ipv6_nd_homeagent_lifetime NO_STR "Interface IPv6 config commands\n" "Neighbor discovery\n" - "Home Agent lifetime\n") + "Home Agent lifetime\n" + "Home Agent lifetime in seconds (0 to track ra-lifetime)\n") { - struct interface *ifp; - struct zebra_if *zif; - - ifp = (struct interface *) vty->index; - zif = ifp->info; + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zif = ifp->info; zif->rtadv.HomeAgentLifetime = -1; @@@ -1336,46 -1329,18 +1289,43 @@@ DEFUN (ipv6_nd_prefix "Infinite valid lifetime\n" "Preferred lifetime in seconds\n" "Infinite preferred lifetime\n" + "Set Router Address flag\n" "Do not use prefix for onlink determination\n" "Do not use prefix for autoconfiguration\n" - "Set Router Address flag\n") + "Do not use prefix for autoconfiguration\n" + "Do not use prefix for onlink determination\n") { + /* prelude */ + char *prefix = argv[3]->arg; + int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN || strmatch (argv[4]->text, "infinite")); + int routeropts = lifetimes ? argc > 6 : argc > 4; + + int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0; + + char *lifetime = NULL, *preflifetime = NULL; + int routeraddr = 0, offlink = 0, noautoconf = 0; + if (lifetimes) + { + lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg : argv[4]->text; + preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg : argv[5]->text; + } + if (routeropts) + { + routeraddr = strmatch (argv[idx_routeropts]->text, "router-address"); + if (!routeraddr) + { + offlink = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "off-link")); + noautoconf = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "no-autoconfig")); + } + } + + /* business */ + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zebra_if = ifp->info; - int i; int ret; - struct interface *ifp; - struct zebra_if *zebra_if; - int cursor = 1; struct rtadv_prefix rp; - ifp = (struct interface *) vty->index; - zebra_if = ifp->info; - - ret = str2prefix_ipv6 (argv[0], &rp.prefix); + ret = str2prefix_ipv6 (prefix, &rp.prefix); if (!ret) { vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); @@@ -1416,23 -1408,165 +1366,19 @@@ DEFUN (no_ipv6_nd_prefix "Infinite valid lifetime\n" "Preferred lifetime in seconds\n" "Infinite preferred lifetime\n" + "Set Router Address flag\n" "Do not use prefix for onlink determination\n" - "Do not use prefix for autoconfiguration\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_val_rev_cmd, - "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) " - "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n" - "Preferred lifetime in seconds\n" - "Infinite preferred lifetime\n" "Do not use prefix for autoconfiguration\n" - "Do not use prefix for onlink determination\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_val_rev_rtaddr_cmd, - "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) " - "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n" - "Preferred lifetime in seconds\n" - "Infinite preferred lifetime\n" "Do not use prefix for autoconfiguration\n" - "Do not use prefix for onlink determination\n" - "Set Router Address flag\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_val_noauto_cmd, - "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) " - "(<0-4294967295>|infinite) (no-autoconfig|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n" - "Preferred lifetime in seconds\n" - "Infinite preferred lifetime\n" - "Do not use prefix for autoconfiguration") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_val_offlink_cmd, - "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) " - "(<0-4294967295>|infinite) (off-link|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n" - "Preferred lifetime in seconds\n" - "Infinite preferred lifetime\n" "Do not use prefix for onlink determination\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_val_rtaddr_cmd, - "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) " - "(<0-4294967295>|infinite) (router-address|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n" - "Preferred lifetime in seconds\n" - "Infinite preferred lifetime\n" - "Set Router Address flag\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_val_cmd, - "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) " - "(<0-4294967295>|infinite)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Valid lifetime in seconds\n" - "Infinite valid lifetime\n" - "Preferred lifetime in seconds\n" - "Infinite preferred lifetime\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_noval_cmd, - "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Do not use prefix for autoconfiguration\n" - "Do not use prefix for onlink determination\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_noval_rev_cmd, - "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Do not use prefix for onlink determination\n" - "Do not use prefix for autoconfiguration\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_noval_noauto_cmd, - "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Do not use prefix for autoconfiguration\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_noval_offlink_cmd, - "ipv6 nd prefix X:X::X:X/M (off-link|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Do not use prefix for onlink determination\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_noval_rtaddr_cmd, - "ipv6 nd prefix X:X::X:X/M (router-address|)", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n" - "Set Router Address flag\n") - -ALIAS (ipv6_nd_prefix, - ipv6_nd_prefix_prefix_cmd, - "ipv6 nd prefix X:X::X:X/M", - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n") - -DEFUN (no_ipv6_nd_prefix, - no_ipv6_nd_prefix_cmd, - "no ipv6 nd prefix IPV6PREFIX", - NO_STR - "Interface IPv6 config commands\n" - "Neighbor discovery\n" - "Prefix information\n" - "IPv6 prefix\n") { + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zebra_if = ifp->info; int ret; - struct interface *ifp; - struct zebra_if *zebra_if; struct rtadv_prefix rp; - + char *prefix = argv[4]->arg; - ifp = (struct interface *) vty->index; - zebra_if = ifp->info; - - ret = str2prefix_ipv6 (argv[0], &rp.prefix); + ret = str2prefix_ipv6 (prefix, &rp.prefix); if (!ret) { vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); @@@ -1460,17 -1748,13 +1406,14 @@@ DEFUN (ipv6_nd_router_preference "Low default router preference\n" "Medium default router preference (default)\n") { + int idx_high_medium_low = 3; - struct interface *ifp; - struct zebra_if *zif; + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zif = ifp->info; int i = 0; - ifp = (struct interface *) vty->index; - zif = ifp->info; - while (0 != rtadv_pref_strs[i]) { - if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0) + if (strncmp (argv[idx_high_medium_low]->arg, rtadv_pref_strs[i], 1) == 0) { zif->rtadv.DefaultPreference = i; return CMD_SUCCESS; @@@ -1487,16 -1771,10 +1430,13 @@@ DEFUN (no_ipv6_nd_router_preference NO_STR "Interface IPv6 config commands\n" "Neighbor discovery\n" - "Default router preference\n") + "Default router preference\n" + "High default router preference\n" + "Medium default router preference (default)\n" + "Low default router preference\n") { - struct interface *ifp; - struct zebra_if *zif; - - ifp = (struct interface *) vty->index; - zif = ifp->info; + VTY_DECLVAR_CONTEXT (interface, ifp); + struct zebra_if *zif = ifp->info; zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */ @@@ -1511,10 -1800,9 +1451,10 @@@ DEFUN (ipv6_nd_mtu "Advertised MTU\n" "MTU in bytes\n") { + int idx_number = 3; - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct zebra_if *zif = ifp->info; - VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535); + VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[idx_number]->arg, 1, 65535); return CMD_SUCCESS; } @@@ -1524,10 -1812,9 +1464,10 @@@ DEFUN (no_ipv6_nd_mtu NO_STR "Interface IPv6 config commands\n" "Neighbor discovery\n" - "Advertised MTU\n") + "Advertised MTU\n" + "MTU in bytes\n") { - struct interface *ifp = (struct interface *) vty->index; + VTY_DECLVAR_CONTEXT (interface, ifp); struct zebra_if *zif = ifp->info; zif->rtadv.AdvLinkMTU = 0; return CMD_SUCCESS; diff --cc zebra/test_main.c index d3813d7356,828b61af91..2829328546 --- a/zebra/test_main.c +++ b/zebra/test_main.c @@@ -124,10 -124,10 +124,9 @@@ DEFUN (test_interface_state "up\n" "down\n") { + int idx_up_down = 1; - struct interface *ifp; + VTY_DECLVAR_CONTEXT (interface, ifp); - if (argc < 1) - return CMD_WARNING; - + - ifp = vty->index; if (ifp->ifindex == IFINDEX_INTERNAL) { ifp->ifindex = ++test_ifindex; diff --cc zebra/zebra_fpm.c index 220fddaf67,a5a953c51f..b2026c1e0c --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@@ -1520,6 -1561,134 +1561,134 @@@ DEFUN (clear_zebra_fpm_stats return CMD_SUCCESS; } + /* + * update fpm connection information + */ -DEFUN ( fpm_remote_ip, - fpm_remote_ip_cmd, - "fpm connection ip A.B.C.D port <1-65535>", ++DEFUN ( fpm_remote_ip, ++ fpm_remote_ip_cmd, ++ "fpm connection ip A.B.C.D port (1-65535)", + "fpm connection remote ip and port\n" + "Remote fpm server ip A.B.C.D\n" + "Enter ip ") + { + + in_addr_t fpm_server; + uint32_t port_no; + - fpm_server = inet_addr (argv[0]); ++ fpm_server = inet_addr (argv[3]->arg); + if (fpm_server == INADDR_NONE) + return CMD_ERR_INCOMPLETE; + - port_no = atoi (argv[1]); ++ port_no = atoi (argv[5]->arg); + if (port_no < TCP_MIN_PORT || port_no > TCP_MAX_PORT) + return CMD_ERR_INCOMPLETE; + + zfpm_g->fpm_server = fpm_server; + zfpm_g->fpm_port = port_no; + + + return CMD_SUCCESS; + } + -DEFUN ( no_fpm_remote_ip, - no_fpm_remote_ip_cmd, - "no fpm connection ip A.B.C.D port <1-65535>", ++DEFUN ( no_fpm_remote_ip, ++ no_fpm_remote_ip_cmd, ++ "no fpm connection ip A.B.C.D port (1-65535)", + "fpm connection remote ip and port\n" + "Connection\n" + "Remote fpm server ip A.B.C.D\n" + "Enter ip ") + { - if (zfpm_g->fpm_server != inet_addr (argv[0]) || - zfpm_g->fpm_port != atoi (argv[1])) ++ if (zfpm_g->fpm_server != inet_addr (argv[4]->arg) || ++ zfpm_g->fpm_port != atoi (argv[6]->arg)) + return CMD_ERR_NO_MATCH; + + zfpm_g->fpm_server = FPM_DEFAULT_IP; + zfpm_g->fpm_port = FPM_DEFAULT_PORT; + + return CMD_SUCCESS; + } + + + /* + * zfpm_init_message_format + */ + static inline void + zfpm_init_message_format (const char *format) + { + int have_netlink, have_protobuf; + + have_netlink = have_protobuf = 0; + + #ifdef HAVE_NETLINK + have_netlink = 1; + #endif + + #ifdef HAVE_PROTOBUF + have_protobuf = 1; + #endif + + zfpm_g->message_format = ZFPM_MSG_FORMAT_NONE; + + if (!format) + { + if (have_netlink) + { + zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK; + } + else if (have_protobuf) + { + zfpm_g->message_format = ZFPM_MSG_FORMAT_PROTOBUF; + } + return; + } + + if (!strcmp ("netlink", format)) + { + if (!have_netlink) + { + zlog_err ("FPM netlink message format is not available"); + return; + } + zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK; + return; + } + + if (!strcmp ("protobuf", format)) + { + if (!have_protobuf) + { + zlog_err ("FPM protobuf message format is not available"); + return; + } + zfpm_g->message_format = ZFPM_MSG_FORMAT_PROTOBUF; + return; + } + + zlog_warn ("Unknown fpm format '%s'", format); + } + + /** + * fpm_remote_srv_write + * + * Module to write remote fpm connection + * + * Returns ZERO on success. + */ + + int fpm_remote_srv_write (struct vty *vty ) + { + struct in_addr in; + + in.s_addr = zfpm_g->fpm_server; + + if (zfpm_g->fpm_server != FPM_DEFAULT_IP || + zfpm_g->fpm_port != FPM_DEFAULT_PORT) + vty_out (vty,"fpm connection ip %s port %d%s", inet_ntoa (in),zfpm_g->fpm_port,VTY_NEWLINE); + + return 0; + } + + /** * zfpm_init * diff --cc zebra/zebra_mpls_vty.c index 0000000000,6136e92cdd..061bb244b2 mode 000000,100644..100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@@ -1,0 -1,881 +1,878 @@@ + /* Zebra MPLS VTY functions + * Copyright (C) 2002 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + #include + + #include "memory.h" + #include "if.h" + #include "prefix.h" + #include "command.h" + #include "table.h" + #include "rib.h" + #include "nexthop.h" + #include "vrf.h" + #include "mpls.h" + #include "lib/json.h" + + #include "zebra/zserv.h" + #include "zebra/zebra_vrf.h" + #include "zebra/zebra_mpls.h" + #include "zebra/zebra_rnh.h" + #include "zebra/redistribute.h" + #include "zebra/zebra_routemap.h" + #include "zebra/zebra_static.h" + + static int + zebra_mpls_transit_lsp (struct vty *vty, int add_cmd, const char *inlabel_str, + const char *gate_str, const char *outlabel_str, + const char *flag_str) + { + struct zebra_vrf *zvrf; + int ret; + enum nexthop_types_t gtype; + union g_addr gate; + mpls_label_t label; + mpls_label_t in_label, out_label; + + zvrf = vrf_info_lookup(VRF_DEFAULT); + if (!zvrf) + { + vty_out (vty, "%% Default VRF does not exist%s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (!inlabel_str) + { + vty_out (vty, "%% No Label Information%s", VTY_NEWLINE); + return CMD_WARNING; + } + + out_label = MPLS_IMP_NULL_LABEL; /* as initialization */ + label = atoi(inlabel_str); + if (!IS_MPLS_UNRESERVED_LABEL(label)) + { + vty_out (vty, "%% Invalid label%s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (add_cmd) + { + if (!gate_str) + { + vty_out (vty, "%% No Nexthop Information%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (!outlabel_str) + { + vty_out (vty, "%% No Outgoing label Information%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + + in_label = label; + gtype = NEXTHOP_TYPE_BLACKHOLE; /* as initialization */ + + if (gate_str) + { + /* Gateway is a IPv4 or IPv6 nexthop. */ + ret = inet_pton (AF_INET6, gate_str, &gate.ipv6); + if (ret) + gtype = NEXTHOP_TYPE_IPV6; + else + { + ret = inet_pton (AF_INET, gate_str, &gate.ipv4); + if (ret) + gtype = NEXTHOP_TYPE_IPV4; + else + { + vty_out (vty, "%% Invalid nexthop%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + } + + if (outlabel_str) + { + if (outlabel_str[0] == 'i') + out_label = MPLS_IMP_NULL_LABEL; + else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV4) + out_label = MPLS_V4_EXP_NULL_LABEL; + else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV6) + out_label = MPLS_V6_EXP_NULL_LABEL; + else + out_label = atoi(outlabel_str); + } + + if (add_cmd) + { + #if defined(HAVE_CUMULUS) + /* Check that label value is consistent. */ + if (!zebra_mpls_lsp_label_consistent (zvrf, in_label, out_label, gtype, + &gate, NULL, 0)) + { + vty_out (vty, "%% Label value not consistent%s", + VTY_NEWLINE); + return CMD_WARNING; + } + #endif /* HAVE_CUMULUS */ + + ret = zebra_mpls_static_lsp_add (zvrf, in_label, out_label, gtype, + &gate, NULL, 0); + } + else + ret = zebra_mpls_static_lsp_del (zvrf, in_label, gtype, &gate, NULL, 0); + + if (ret) + { + vty_out (vty, "%% LSP cannot be %s%s", + add_cmd ? "added" : "deleted", VTY_NEWLINE); + return CMD_WARNING; + } + + return CMD_SUCCESS; + } + + DEFUN (mpls_transit_lsp, + mpls_transit_lsp_cmd, - "mpls lsp <16-1048575> (A.B.C.D|X:X::X:X) (<16-1048575>|explicit-null|implicit-null)", ++ "mpls lsp (16-1048575) <(16-1048575)|explicit-null|implicit-null>", + MPLS_STR + "Establish label switched path\n" + "Incoming MPLS label\n" + "IPv4 gateway address\n" + "IPv6 gateway address\n" + "Outgoing MPLS label\n" + "Use Explicit-Null label\n" + "Use Implicit-Null label\n") + { - return zebra_mpls_transit_lsp (vty, 1, argv[0], argv[1], argv[2], NULL); ++ return zebra_mpls_transit_lsp (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL); + } + + DEFUN (no_mpls_transit_lsp, + no_mpls_transit_lsp_cmd, - "no mpls lsp <16-1048575> (A.B.C.D|X:X::X:X)", ++ "no mpls lsp (16-1048575) ", + NO_STR + MPLS_STR + "Establish label switched path\n" + "Incoming MPLS label\n" + "IPv4 gateway address\n" + "IPv6 gateway address\n") + { - return zebra_mpls_transit_lsp (vty, 0, argv[0], argv[1], NULL, NULL); ++ return zebra_mpls_transit_lsp (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL); + } + + ALIAS (no_mpls_transit_lsp, + no_mpls_transit_lsp_out_label_cmd, - "no mpls lsp <16-1048575> (A.B.C.D|X:X::X:X) (<16-1048575>|explicit-null|implicit-null)", ++ "no mpls lsp (16-1048575) <(16-1048575)|explicit-null|implicit-null>", + NO_STR + MPLS_STR + "Establish label switched path\n" + "Incoming MPLS label\n" + "IPv4 gateway address\n" + "IPv6 gateway address\n" + "Outgoing MPLS label\n" + "Use Explicit-Null label\n" + "Use Implicit-Null label\n") + + DEFUN (no_mpls_transit_lsp_all, + no_mpls_transit_lsp_all_cmd, - "no mpls lsp <16-1048575>", ++ "no mpls lsp (16-1048575)", + NO_STR + MPLS_STR + "Establish label switched path\n" + "Incoming MPLS label\n") + { - return zebra_mpls_transit_lsp (vty, 0, argv[0], NULL, NULL, NULL); ++ return zebra_mpls_transit_lsp (vty, 0, argv[3]->arg, NULL, NULL, NULL); + } + + /* Static route configuration. */ + DEFUN (ip_route_label, + ip_route_label_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) label WORD", ++ "ip route A.B.C.D/M label WORD", + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL, - NULL, NULL, argv[2]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, ++ NULL, NULL, argv[5]->arg); + } + + DEFUN (ip_route_tag_label, + ip_route_tag_label_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD", ++ "ip route A.B.C.D/M tag (1-4294967295) label WORD", + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Set tag for this route\n" + "Tag value\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2], - NULL, NULL, argv[3]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg, ++ NULL, NULL, argv[7]->arg); + } + + /* Mask as A.B.C.D format. */ + DEFUN (ip_route_mask_label, + ip_route_mask_label_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) label WORD", ++ "ip route A.B.C.D A.B.C.D label WORD", + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL, - NULL, NULL, argv[3]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, ++ NULL, NULL, argv[6]->arg); + } + + DEFUN (ip_route_mask_tag_label, + ip_route_mask_tag_label_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD", ++ "ip route A.B.C.D A.B.C.D tag (1-4294967295) label WORD", + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Set tag for this route\n" + "Tag value\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3], - NULL, NULL, argv[4]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, ++ NULL, NULL, argv[8]->arg); + } + + /* Distance option value. */ + DEFUN (ip_route_distance_label, + ip_route_distance_label_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> label WORD", ++ "ip route A.B.C.D/M (1-255) label WORD", + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Distance value for this route\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL, - argv[2], NULL, argv[3]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, ++ argv[4]->arg, NULL, argv[6]->arg); + } + + DEFUN (ip_route_tag_distance_label, + ip_route_tag_distance_label_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD", ++ "ip route A.B.C.D/M tag (1-4294967295) (1-255) label WORD", + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this route\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2], - argv[3], NULL, argv[4]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg, ++ argv[6]->arg, NULL, argv[8]->arg); + } + + DEFUN (ip_route_mask_distance_label, + ip_route_mask_distance_label_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> label WORD", ++ "ip route A.B.C.D A.B.C.D (1-255) label WORD", + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Distance value for this route\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL, - argv[3], NULL, argv[4]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, ++ argv[5]->arg, NULL, argv[7]->arg); + } + + DEFUN (ip_route_mask_tag_distance_label, + ip_route_mask_tag_distance_label_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD", ++ "ip route A.B.C.D A.B.C.D tag (1-4294967295) (1-255) label WORD", + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this route\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3], - argv[4], NULL, argv[5]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, ++ argv[7]->arg, NULL, argv[9]->arg); + } + + DEFUN (no_ip_route_label, + no_ip_route_label_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) label WORD", ++ "no ip route A.B.C.D/M label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL, - NULL, NULL, argv[2]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, ++ NULL, NULL, argv[6]->arg); + } + + DEFUN (no_ip_route_tag_label, + no_ip_route_tag_label_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD", ++ "no ip route A.B.C.D/M tag (1-4294967295) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Tag of this route\n" + "Tag value\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2], - NULL, NULL, argv[3]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg, ++ NULL, NULL, argv[8]->arg); + } + + DEFUN (no_ip_route_mask_label, + no_ip_route_mask_label_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) label WORD", ++ "no ip route A.B.C.D A.B.C.D label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL, - NULL, NULL, argv[3]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, ++ NULL, NULL, argv[7]->arg); + } + + DEFUN (no_ip_route_mask_tag_label, + no_ip_route_mask_tag_label_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> label WORD", ++ "no ip route A.B.C.D A.B.C.D tag (1-4294967295) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Tag of this route\n" + "Tag value\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3], - NULL, NULL, argv[4]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, ++ NULL, NULL, argv[9]->arg); + } + + DEFUN (no_ip_route_distance_label, + no_ip_route_distance_label_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> label WORD", ++ "no ip route A.B.C.D/M (1-255) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Distance value for this route\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL, - argv[2], NULL, argv[3]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, ++ argv[5]->arg, NULL, argv[7]->arg); + } + + DEFUN (no_ip_route_tag_distance_label, + no_ip_route_tag_distance_label_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD", ++ "no ip route A.B.C.D/M tag (1-4294967295) (1-255) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Tag of this route\n" + "Tag value\n" + "Distance value for this route\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2], - argv[3], NULL, argv[4]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg, ++ argv[7]->arg, NULL, argv[9]->arg); + } + + DEFUN (no_ip_route_mask_distance_label, + no_ip_route_mask_distance_label_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>", ++ "no ip route A.B.C.D A.B.C.D (1-255)", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Distance value for this route\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL, - argv[3], NULL, argv[5]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, ++ argv[6]->arg, NULL, NULL); + } + + DEFUN (no_ip_route_mask_tag_distance_label, + no_ip_route_mask_tag_distance_label_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> label WORD", ++ "no ip route A.B.C.D A.B.C.D tag (1-4294967295) (1-255) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Null interface\n" + "Tag of this route\n" + "Tag value\n" + "Distance value for this route\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3], - argv[4], NULL, argv[5]); ++ return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, ++ argv[8]->arg, NULL, argv[10]->arg); + } + + DEFUN (ipv6_route_label, + ipv6_route_label_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) label WORD", ++ "ipv6 route X:X::X:X/M label WORD", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, argv[2]); ++ return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, NULL, NULL, NULL, argv[5]->arg); + } + + DEFUN (ipv6_route_tag_label, + ipv6_route_tag_label_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> label WORD", ++ "ipv6 route X:X::X:X/M tag (1-4294967295) label WORD", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Set tag for this route\n" + "Tag value\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, argv[3]); ++ return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, argv[5]->arg, NULL, NULL, argv[7]->arg); + } + + DEFUN (ipv6_route_ifname_label, + ipv6_route_ifname_label_cmd, + "ipv6 route X:X::X:X/M X:X::X:X INTERFACE label WORD", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, argv[3]); ++ return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, argv[6]->arg); + } + DEFUN (ipv6_route_ifname_tag_label, + ipv6_route_ifname_tag_label_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> label WORD", ++ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) label WORD", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Set tag for this route\n" + "Tag value\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, argv[4]); ++ return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg); + } + + DEFUN (ipv6_route_pref_label, + ipv6_route_pref_label_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> label WORD", ++ "ipv6 route X:X::X:X/M (1-255) label WORD", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Distance value for this prefix\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, argv[3]); ++ return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, NULL, argv[4]->arg, NULL, argv[6]->arg); + } + + DEFUN (ipv6_route_pref_tag_label, + ipv6_route_pref_tag_label_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> label WORD", ++ "ipv6 route X:X::X:X/M tag (1-4294967295) (1-255) label WORD", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this prefix\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, argv[4]); ++ return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, NULL, NULL, argv[5]->arg, argv[6]->arg, NULL, argv[8]->arg); + } + + DEFUN (ipv6_route_ifname_pref_label, + ipv6_route_ifname_pref_label_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> label WORD", ++ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (1-255) label WORD", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Distance value for this prefix\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, argv[4]); ++ return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg); + } + + DEFUN (ipv6_route_ifname_pref_tag_label, + ipv6_route_ifname_pref_tag_label_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> label WORD", ++ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) (1-255) label WORD", + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this prefix\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, argv[5]); ++ return static_ipv6_func (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg); + } + + DEFUN (no_ipv6_route_label, + no_ipv6_route_label_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) label WORD", ++ "no ipv6 route X:X::X:X/M label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, argv[2]); ++ return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, NULL, argv[6]->arg); + } + + DEFUN (no_ipv6_route_tag_label, + no_ipv6_route_tag_label_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> label WORD", ++ "no ipv6 route X:X::X:X/M tag (1-4294967295) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Set tag for this route\n" + "Tag value\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, argv[3]); ++ return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg); + } + + DEFUN (no_ipv6_route_ifname_label, + no_ipv6_route_ifname_label_cmd, + "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, argv[3]); ++ return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, NULL, NULL, argv[7]->arg); + } + + DEFUN (no_ipv6_route_ifname_tag_label, + no_ipv6_route_ifname_tag_label_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> label WORD", ++ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Set tag for this route\n" + "Tag value\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, argv[4]); ++ return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, NULL, NULL, argv[9]->arg); + } + + DEFUN (no_ipv6_route_pref_label, + no_ipv6_route_pref_label_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> label WORD", ++ "no ipv6 route X:X::X:X/M (1-255) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Distance value for this prefix\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, argv[3]); ++ return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg); + } + + DEFUN (no_ipv6_route_pref_tag_label, + no_ipv6_route_pref_tag_label_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> label WORD", ++ "no ipv6 route X:X::X:X/M tag (1-4294967295) (1-255) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this prefix\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, argv[4]); ++ return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg); + } + + DEFUN (no_ipv6_route_ifname_pref_label, + no_ipv6_route_ifname_pref_label_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> label WORD", ++ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (1-255) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Distance value for this prefix\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, argv[4]); ++ return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, argv[6]->arg, NULL, argv[8]->arg); + } + + DEFUN (no_ipv6_route_ifname_pref_tag_label, + no_ipv6_route_ifname_pref_tag_label_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> label WORD", ++ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag (1-4294967295) (1-255) label WORD", + NO_STR + IP_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this prefix\n" + "Specify label(s) for this route\n" + "One or more labels separated by '/'\n") + { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, argv[5]); ++ return static_ipv6_func (vty, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, argv[8]->arg, NULL, argv[10]->arg); + } + + /* MPLS LSP configuration write function. */ + static int + zebra_mpls_config (struct vty *vty) + { + int write = 0; + struct zebra_vrf *zvrf; + + zvrf = vrf_info_lookup(VRF_DEFAULT); + if (!zvrf) + return 0; + + write += zebra_mpls_write_lsp_config(vty, zvrf); + return write; + } + + DEFUN (show_mpls_table, + show_mpls_table_cmd, - "show mpls table {json}", ++ "show mpls table [json]", + SHOW_STR + MPLS_STR + "MPLS table\n" + "JavaScript Object Notation\n") + { + struct zebra_vrf *zvrf; - u_char use_json = (argv[0] != NULL); ++ u_char use_json = (argv[3]->arg != NULL); + + zvrf = vrf_info_lookup(VRF_DEFAULT); + zebra_mpls_print_lsp_table(vty, zvrf, use_json); + return CMD_SUCCESS; + } + + DEFUN (show_mpls_table_lsp, + show_mpls_table_lsp_cmd, - "show mpls table <16-1048575> {json}", ++ "show mpls table (16-1048575) [json]", + SHOW_STR + MPLS_STR + "MPLS table\n" + "LSP to display information about\n" + "JavaScript Object Notation\n") + { + u_int32_t label; + struct zebra_vrf *zvrf; - u_char use_json = (argv[1] != NULL); ++ u_char use_json = (argv[4]->arg != NULL); + + zvrf = vrf_info_lookup(VRF_DEFAULT); - label = atoi(argv[0]); ++ label = atoi(argv[3]->arg); + zebra_mpls_print_lsp (vty, zvrf, label, use_json); + return CMD_SUCCESS; + } + + DEFUN (show_mpls_status, + show_mpls_status_cmd, + "show mpls status", + SHOW_STR + "MPLS information\n" + "MPLS status\n") + { + vty_out (vty, "MPLS support enabled: %s%s", (mpls_enabled) ? "yes" : + "no (mpls kernel extensions not detected)", VTY_NEWLINE); + return CMD_SUCCESS; + } + + /* MPLS node for MPLS LSP. */ + static struct cmd_node mpls_node = { MPLS_NODE, "", 1 }; + + /* MPLS VTY. */ + void + zebra_mpls_vty_init (void) + { + install_element (VIEW_NODE, &show_mpls_status_cmd); - install_element (ENABLE_NODE, &show_mpls_status_cmd); + + if (! mpls_enabled) + return; + + install_node (&mpls_node, zebra_mpls_config); + + install_element (CONFIG_NODE, &ip_route_label_cmd); + install_element (CONFIG_NODE, &ip_route_tag_label_cmd); + install_element (CONFIG_NODE, &ip_route_mask_label_cmd); + install_element (CONFIG_NODE, &ip_route_mask_tag_label_cmd); + install_element (CONFIG_NODE, &no_ip_route_label_cmd); + install_element (CONFIG_NODE, &no_ip_route_tag_label_cmd); + install_element (CONFIG_NODE, &no_ip_route_mask_label_cmd); + install_element (CONFIG_NODE, &no_ip_route_mask_tag_label_cmd); + install_element (CONFIG_NODE, &ip_route_distance_label_cmd); + install_element (CONFIG_NODE, &ip_route_tag_distance_label_cmd); + install_element (CONFIG_NODE, &ip_route_mask_distance_label_cmd); + install_element (CONFIG_NODE, &ip_route_mask_tag_distance_label_cmd); + install_element (CONFIG_NODE, &no_ip_route_distance_label_cmd); + install_element (CONFIG_NODE, &no_ip_route_tag_distance_label_cmd); + install_element (CONFIG_NODE, &no_ip_route_mask_distance_label_cmd); + install_element (CONFIG_NODE, &no_ip_route_mask_tag_distance_label_cmd); + + install_element (CONFIG_NODE, &ipv6_route_label_cmd); + install_element (CONFIG_NODE, &ipv6_route_ifname_label_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_label_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_ifname_label_cmd); + install_element (CONFIG_NODE, &ipv6_route_pref_label_cmd); + install_element (CONFIG_NODE, &ipv6_route_ifname_pref_label_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_pref_label_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_label_cmd); + install_element (CONFIG_NODE, &ipv6_route_tag_label_cmd); + install_element (CONFIG_NODE, &ipv6_route_ifname_tag_label_cmd); + install_element (CONFIG_NODE, &ipv6_route_pref_tag_label_cmd); + install_element (CONFIG_NODE, &ipv6_route_ifname_pref_tag_label_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_tag_label_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_ifname_tag_label_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_pref_tag_label_cmd); + install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_tag_label_cmd); + + install_element (CONFIG_NODE, &mpls_transit_lsp_cmd); + install_element (CONFIG_NODE, &no_mpls_transit_lsp_cmd); + install_element (CONFIG_NODE, &no_mpls_transit_lsp_out_label_cmd); + install_element (CONFIG_NODE, &no_mpls_transit_lsp_all_cmd); + + install_element (VIEW_NODE, &show_mpls_table_cmd); - install_element (ENABLE_NODE, &show_mpls_table_cmd); + install_element (VIEW_NODE, &show_mpls_table_lsp_cmd); - install_element (ENABLE_NODE, &show_mpls_table_lsp_cmd); + } diff --cc zebra/zebra_routemap.c index fddc4fd7b1,9cfae6e705..9b407ed392 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@@ -57,11 -56,9 +57,11 @@@ struct nh_rmap_ob static void zebra_route_map_set_delay_timer(u_int32_t value); + + /* Add zebra route map rule */ static int - zebra_route_match_add(struct vty *vty, struct route_map_index *index, + zebra_route_match_add(struct vty *vty, const char *command, const char *arg, route_map_event_t type) { @@@ -160,45 -207,13 +162,13 @@@ route_match_tag (void *rule, struct pre return RMAP_NOMATCH; } - /* Route map 'match tag' match statement. 'arg' is TAG value */ - static void * - route_match_tag_compile (const char *arg) - { - u_short *tag; - u_short tmp; - - /* tag value shoud be integer. */ - if (! all_digit (arg)) - return NULL; - - tmp = atoi(arg); - if (tmp < 1) - return NULL; - - tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short)); - - if (!tag) - return tag; - - *tag = tmp; - - return tag; - } - - /* Free route map's compiled 'match tag' value. */ - static void - route_match_tag_free (void *rule) - { - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); - } - /* Route map commands for tag matching */ - struct route_map_rule_cmd route_match_tag_cmd = + static struct route_map_rule_cmd route_match_tag_cmd = { - "tag", - route_match_tag, + "tag", + route_match_tag, - route_match_tag_compile, - route_match_tag_free + route_map_rule_tag_compile, + route_map_rule_tag_free, }; @@@ -260,8 -506,8 +230,8 @@@ DEFUN (match_ip_address_prefix_len "Match prefix length of ip address\n" "Prefix length\n") { - return zebra_route_match_add (vty, vty->index, "ip address prefix-len", + return zebra_route_match_add (vty, "ip address prefix-len", - argv[0], RMAP_EVENT_MATCH_ADDED); + argv[4]->arg, RMAP_EVENT_MATCH_ADDED); } DEFUN (no_match_ip_address_prefix_len, @@@ -271,11 -517,15 +241,11 @@@ MATCH_STR IP_STR "Match prefixlen of ip address of route\n" - "prefix length of ip address\n") + "Prefix length\n") { - if (argc == 0) - return zebra_route_match_delete (vty, - "ip address prefix-len", NULL, - RMAP_EVENT_MATCH_DELETED); - + char *plen = (argc == 6) ? argv[5]->arg : NULL; - return zebra_route_match_delete (vty, vty->index, + return zebra_route_match_delete (vty, - "ip address prefix-len", argv[0], + "ip address prefix-len", plen, RMAP_EVENT_MATCH_DELETED); } @@@ -289,8 -547,8 +259,8 @@@ DEFUN (match_ip_nexthop_prefix_len "Match prefixlen of given nexthop\n" "Prefix length\n") { - return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-len", + return zebra_route_match_add (vty, "ip next-hop prefix-len", - argv[0], RMAP_EVENT_MATCH_ADDED); + argv[4]->arg, RMAP_EVENT_MATCH_ADDED); } DEFUN (no_match_ip_nexthop_prefix_len, @@@ -300,12 -558,15 +270,12 @@@ MATCH_STR IP_STR "Match prefixlen of nexthop ip address\n" - "Match prefix length of nexthop\n") + "Match prefix length of nexthop\n" + "Prefix length\n") { - if (argc == 0) - return zebra_route_match_delete (vty, - "ip next-hop prefix-len", NULL, - RMAP_EVENT_MATCH_DELETED); - + char *plen = (argc == 6) ? argv[5]->arg : NULL; - return zebra_route_match_delete (vty, vty->index, + return zebra_route_match_delete (vty, - "ip next-hop prefix-len", argv[0], + "ip next-hop prefix-len", plen, RMAP_EVENT_MATCH_DELETED); } @@@ -316,28 -583,41 +286,28 @@@ DEFUN (match_source_protocol MATCH_STR "Match protocol via which the route was learnt\n") { + char *proto = argv[2]->text; int i; - i = proto_name2num(argv[0]); + i = proto_name2num(proto); if (i < 0) { - vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "", - VTY_NEWLINE); + vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); return CMD_WARNING; } - return zebra_route_match_add (vty, vty->index, "source-protocol", proto, RMAP_EVENT_MATCH_ADDED); - return zebra_route_match_add (vty, "source-protocol", - argv[0], RMAP_EVENT_MATCH_ADDED); ++ return zebra_route_match_add (vty, "source-protocol", proto, RMAP_EVENT_MATCH_ADDED); } DEFUN (no_match_source_protocol, no_match_source_protocol_cmd, - "no match source-protocol (bgp|ospf|rip|ripng|isis|ospf6|connected|system|kernel|static)", + "no match source-protocol []", NO_STR MATCH_STR - "No match protocol via which the route was learnt\n") + "No match protocol via which the route was learnt\n" + ) { - int i; - - if (argc >= 1) - { - i = proto_name2num(argv[0]); - if (i < 0) - { - vty_out (vty, "invalid protocol name \"%s\"%s", argv[0] ? argv[0] : "", - VTY_NEWLINE); - return CMD_WARNING; - } - } - return zebra_route_match_delete (vty, - "source-protocol", argv[0] ? argv[0] : NULL, - RMAP_EVENT_MATCH_DELETED); + char *proto = (argc == 4) ? argv[3]->text : NULL; - return zebra_route_match_delete (vty, vty->index, "source-protocol", proto, RMAP_EVENT_MATCH_DELETED); ++ return zebra_route_match_delete (vty, "source-protocol", proto, RMAP_EVENT_MATCH_DELETED); } /* set functions */ @@@ -399,7 -678,7 +369,9 @@@ DEFUN (set_src vty_out (vty, "%% not a local address%s", VTY_NEWLINE); return CMD_WARNING; } - return generic_set_add (vty, vty->index, "src", argv[idx_ip]->arg); - return zebra_route_set_add (vty, "src", argv[0]); ++ ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ return generic_set_add (vty, index, "src", argv[idx_ip]->arg); } DEFUN (no_set_src, @@@ -409,8 -688,10 +381,9 @@@ SET_STR "Source address for route\n") { - if (argc == 0) - return zebra_route_set_delete (vty, "src", NULL); - - return zebra_route_set_delete (vty, "src", argv[0]); + char *ip = (argc == 4) ? argv[3]->arg : NULL; - return generic_set_delete (vty, vty->index, "src", ip); ++ VTY_DECLVAR_CONTEXT (route_map_index, index); ++ return generic_set_delete (vty, index, "src", ip); } DEFUN (zebra_route_map_timer, @@@ -1489,22 -1788,27 +1462,18 @@@ zebra_route_map_init ( { install_element (CONFIG_NODE, &ip_protocol_cmd); install_element (CONFIG_NODE, &no_ip_protocol_cmd); - install_element (CONFIG_NODE, &no_ip_protocol_val_cmd); install_element (VIEW_NODE, &show_ip_protocol_cmd); -- install_element (ENABLE_NODE, &show_ip_protocol_cmd); install_element (CONFIG_NODE, &ipv6_protocol_cmd); install_element (CONFIG_NODE, &no_ipv6_protocol_cmd); - install_element (CONFIG_NODE, &no_ipv6_protocol_val_cmd); install_element (VIEW_NODE, &show_ipv6_protocol_cmd); -- install_element (ENABLE_NODE, &show_ipv6_protocol_cmd); install_element (CONFIG_NODE, &ip_protocol_nht_rmap_cmd); install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd); - install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_val_cmd); install_element (VIEW_NODE, &show_ip_protocol_nht_cmd); -- install_element (ENABLE_NODE, &show_ip_protocol_nht_cmd); install_element (CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd); install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_cmd); - install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_val_cmd); install_element (VIEW_NODE, &show_ipv6_protocol_nht_cmd); -- install_element (ENABLE_NODE, &show_ipv6_protocol_nht_cmd); install_element (CONFIG_NODE, &zebra_route_map_timer_cmd); install_element (CONFIG_NODE, &no_zebra_route_map_timer_cmd); - install_element (CONFIG_NODE, &no_zebra_route_map_timer_val_cmd); route_map_init (); route_map_init_vty (); diff --cc zebra/zebra_static.c index d05b6e13ac,a691048b2c..d336b81520 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@@ -203,8 -238,13 +239,13 @@@ static_nexthop_same (struct nexthop *ne && si->type == STATIC_IPV6_GATEWAY_IFINDEX && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6) && nexthop->ifindex == si->ifindex) - return 1; + gw_match = 1; + + if (!gw_match) - return 0; + return 0; + + /* Check match on label(s), if any */ + return static_nexthop_label_same (nexthop, &si->snh_label); } /* Uninstall static route from RIB. */ @@@ -280,13 -320,21 +321,21 @@@ static_uninstall_route (afi_t afi, safi /* If there are other active nexthops, do an update. */ if (rib->nexthop_active_num > 1) { + /* Update route in kernel if it's in fib */ + if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) - rib_install_kernel (rn, rib, 1); + rib_install_kernel (rn, rib, 1); + /* Update redistribution if it's selected */ + if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) - redistribute_update (&rn->p, rib, NULL); + redistribute_update (&rn->p, rib, NULL); } else { + /* Remove from redistribute if selected route becomes inactive */ + if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) - redistribute_delete (&rn->p, rib); + redistribute_delete (&rn->p, rib); + /* Remove from kernel if fib route becomes inactive */ + if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) - rib_uninstall_kernel (rn, rib); + rib_uninstall_kernel (rn, rib); } } diff --cc zebra/zebra_vty.c index b3164839fa,12084968b7..03ff5b8763 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@@ -14,9 -14,9 +14,9 @@@ * General Public License for more details. * * You should have received a copy of the GNU General Public License -- * along with GNU Zebra; see the file COPYING. If not, write to the -- * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- * Boston, MA 02111-1307, USA. ++ * along with GNU Zebra; see the file COPYING. If not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 02111-1307, USA. */ #include @@@ -152,7 -171,7 +171,7 @@@ zebra_static_ipv4 (struct vty *vty, saf return CMD_SUCCESS; } -- ++ /* When gateway is A.B.C.D format, gate is treated as nexthop address other case gate is treated as interface name. */ ret = inet_aton (gate_str, &gate); @@@ -191,12 -214,18 +214,12 @@@ DEFUN (ip_mroute_dist "Nexthop interface name\n" "Distance\n") { - return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, argv[0], NULL, argv[1], - NULL, NULL, argc > 2 ? argv[2] : NULL, NULL, NULL); -} + char *destprefix = argv[2]->arg; + char *nexthop = argv[3]->arg; + char *distance = (argc == 5) ? argv[4]->arg : NULL; - return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL); -ALIAS (ip_mroute_dist, - ip_mroute_cmd, - "ip mroute A.B.C.D/M (A.B.C.D|INTERFACE)", - IP_STR - "Configure static unicast route into MRIB for multicast RPF lookup\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Nexthop address\n" - "Nexthop interface name\n") ++ return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL); +} DEFUN (no_ip_mroute_dist, no_ip_mroute_dist_cmd, @@@ -208,12 -237,19 +231,12 @@@ "Nexthop interface name\n" "Distance\n") { - return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, argv[0], NULL, argv[1], - NULL, NULL, argc > 2 ? argv[2] : NULL, NULL, NULL); -} + char *destprefix = argv[3]->arg; + char *nexthop = argv[4]->arg; + char *distance = (argc == 6) ? argv[5]->arg : NULL; - return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL); -ALIAS (no_ip_mroute_dist, - no_ip_mroute_cmd, - "no ip mroute A.B.C.D/M (A.B.C.D|INTERFACE)", - NO_STR - IP_STR - "Configure static unicast route into MRIB for multicast RPF lookup\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Nexthop address\n" - "Nexthop interface name\n") ++ return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL); +} DEFUN (ip_multicast_mode, ip_multicast_mode_cmd, @@@ -307,39 -348,24 +330,47 @@@ DEFUN (show_ip_rpf_addr return CMD_SUCCESS; } -/* Static route configuration. */ -DEFUN (ip_route, - ip_route_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)", - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n") +static void +zebra_vty_ip_route_tdv_helper (int argc, struct cmd_token *argv[], + int idx_curr, char **tag, - char **distance, char **vrf) ++ char **distance, char **vrf, char **labels) { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL, - NULL, NULL, NULL); + *distance = NULL; + while (idx_curr < argc) + { + if (strmatch (argv[idx_curr]->text, "tag")) + { - *tag = argv[idx_curr+1]->arg; ++ if (tag) ++ *tag = argv[idx_curr+1]->arg; + idx_curr += 2; + } + else if (strmatch (argv[idx_curr]->text, "vrf")) + { - *vrf = argv[idx_curr+1]->arg; ++ if (vrf) ++ *vrf = argv[idx_curr+1]->arg; ++ idx_curr += 2; ++ } ++ else if (strmatch (argv[idx_curr]->text, "label")) ++ { ++ if (labels) ++ *labels = argv[idx_curr+1]->arg; + idx_curr += 2; + } + else + { - *distance = argv[idx_curr]->arg; ++ if (distance) ++ *distance = argv[idx_curr]->arg; + idx_curr++; + } + } + + return; } - -DEFUN (ip_route_tag, - ip_route_tag_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295>", +/* Static route configuration. */ +DEFUN (ip_route, + ip_route_cmd, - "ip route A.B.C.D/M [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "ip route A.B.C.D/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IP destination prefix (e.g. 10.0.0.0/8)\n" @@@ -347,29 -373,30 +378,29 @@@ "IP gateway interface name\n" "Null interface\n" "Set tag for this route\n" - "One or more labels separated by '/'\n") + "Tag value\n" + "Distance value for this route\n" + VRF_CMD_HELP_STR) { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2], - NULL, NULL, NULL); + int idx_ipv4_prefixlen = 2; + int idx_ipv4_ifname_null = 3; + int idx_curr = 4; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, + argv[idx_ipv4_prefixlen]->arg, + NULL, + argv[idx_ipv4_ifname_null]->arg, + NULL, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } DEFUN (ip_route_flags, ip_route_flags_cmd, - "ip route A.B.C.D/M [tag (1-65535)] [(1-255)] [vrf NAME]", - "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)", - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL, - NULL, NULL, NULL); -} - -DEFUN (ip_route_flags_tag, - ip_route_flags_tag_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>", ++ "ip route A.B.C.D/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IP destination prefix (e.g. 10.0.0.0/8)\n" @@@ -378,60 -405,61 +409,64 @@@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n" "Set tag for this route\n" - "Tag value\n") - + "Tag value\n" + "Distance value for this route\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3], - NULL, NULL, NULL); + int idx_ipv4_prefixlen = 2; + int idx_ipv4_ifname = 3; + int idx_reject_blackhole = 4; + int idx_curr = 5; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, + argv[idx_ipv4_prefixlen]->arg, + NULL, + argv[idx_ipv4_ifname]->arg, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } DEFUN (ip_route_flags2, ip_route_flags2_cmd, - "ip route A.B.C.D/M [tag (1-65535)] [(1-255)] [vrf NAME]", - "ip route A.B.C.D/M (reject|blackhole)", - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL, - NULL, NULL, NULL); -} - -DEFUN (ip_route_flags2_tag, - ip_route_flags2_tag_cmd, - "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295>", ++ "ip route A.B.C.D/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IP destination prefix (e.g. 10.0.0.0/8)\n" "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n" "Set tag for this route\n" - "Tag value\n") - + "Tag value\n" + "Distance value for this route\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2], - NULL, NULL, NULL); + int idx_ipv4_prefixlen = 2; + int idx_reject_blackhole = 3; + int idx_curr = 4; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, + argv[idx_ipv4_prefixlen]->arg, + NULL, + NULL, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } /* Mask as A.B.C.D format. */ DEFUN (ip_route_mask, ip_route_mask_cmd, - "ip route A.B.C.D A.B.C.D [tag (1-65535)] [(1-255)] [vrf NAME]", - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)", - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL, - NULL, NULL, NULL); -} - -DEFUN (ip_route_mask_tag, - ip_route_mask_tag_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295>", ++ "ip route A.B.C.D A.B.C.D [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IP destination prefix\n" @@@ -440,29 -468,32 +475,31 @@@ "IP gateway interface name\n" "Null interface\n" "Set tag for this route\n" - "Tag value\n") - + "Tag value\n" + "Distance value for this route\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3], - NULL, NULL, NULL); + int idx_ipv4 = 2; + int idx_ipv4_2 = 3; + int idx_ipv4_ifname_null = 4; + int idx_curr = 5; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, + argv[idx_ipv4]->arg, + argv[idx_ipv4_2]->arg, + argv[idx_ipv4_ifname_null]->arg, - NULL, tag, distance, vrf); ++ NULL, tag, distance, vrf, NULL); } DEFUN (ip_route_mask_flags, ip_route_mask_flags_cmd, - "ip route A.B.C.D A.B.C.D [tag (1-65535)] [(1-255)] [vrf NAME]", - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)", - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL, - NULL, NULL, NULL); -} - -DEFUN (ip_route_mask_flags_tag, - ip_route_mask_flags_tag_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>", ++ "ip route A.B.C.D A.B.C.D [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IP destination prefix\n" @@@ -472,32 -503,30 +509,34 @@@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n" "Set tag for this route\n" - "Tag value\n") - + "Tag value\n" + "Distance value for this route\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4], - NULL, NULL, NULL); + int idx_ipv4 = 2; + int idx_ipv4_2 = 3; + int idx_ipv4_ifname = 4; + int idx_reject_blackhole = 5; + int idx_curr = 6; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, + argv[idx_ipv4]->arg, + argv[idx_ipv4_2]->arg, + argv[idx_ipv4_ifname]->arg, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } + DEFUN (ip_route_mask_flags2, ip_route_mask_flags2_cmd, - "ip route A.B.C.D A.B.C.D [tag (1-65535)] [(1-255)] [vrf NAME]", - "ip route A.B.C.D A.B.C.D (reject|blackhole)", - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL, - NULL, NULL, NULL); -} - -DEFUN (ip_route_mask_flags2_tag, - ip_route_mask_flags2_tag_cmd, - "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295>", ++ "ip route A.B.C.D A.B.C.D [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IP destination prefix\n" @@@ -505,89 -534,129 +544,95 @@@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n" "Set tag for this route\n" - "Tag value\n") + "Tag value\n" + "Distance value for this route\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3], - NULL, NULL, NULL); -} + int idx_ipv4 = 2; + int idx_ipv4_2 = 3; + int idx_reject_blackhole = 4; + int idx_curr = 5; + char *tag, *distance, *vrf; -/* Distance option value. */ -DEFUN (ip_route_distance, - ip_route_distance_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>", - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, NULL, - argv[2], NULL, NULL); + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, + argv[idx_ipv4]->arg, + argv[idx_ipv4_2]->arg, + NULL, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (ip_route_tag_distance, - ip_route_tag_distance_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>", +DEFUN (no_ip_route, + no_ip_route_cmd, - "no ip route A.B.C.D/M [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ip route A.B.C.D/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", + NO_STR IP_STR "Establish static routes\n" "IP destination prefix (e.g. 10.0.0.0/8)\n" "IP gateway address\n" "IP gateway interface name\n" "Null interface\n" - "Set tag for this route\n" + "Tag of this route\n" "Tag value\n" - "Distance value for this route\n") - -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2], - argv[3], NULL, NULL); -} - -DEFUN (ip_route_flags_distance, - ip_route_flags_distance_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>", - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n") + "Distance value for this route\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], NULL, - argv[3], NULL, NULL); -} + int idx_ipv4_prefixlen = 3; + int idx_ipv4_ifname_null = 4; + int idx_curr = 5; + char *tag, *distance, *vrf; -DEFUN (ip_route_flags_tag_distance, - ip_route_flags_tag_distance_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>", - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], argv[2], argv[3], - argv[4], NULL, NULL); -} + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); -DEFUN (ip_route_flags_distance2, - ip_route_flags_distance2_cmd, - "ip route A.B.C.D/M (reject|blackhole) <1-255>", - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], NULL, - argv[2], NULL, NULL); + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, + argv[idx_ipv4_prefixlen]->arg, + NULL, + argv[idx_ipv4_ifname_null]->arg, + NULL, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (ip_route_flags_tag_distance2, - ip_route_flags_tag_distance2_cmd, - "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255>", +DEFUN (no_ip_route_flags2, + no_ip_route_flags2_cmd, - "no ip route A.B.C.D/M [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ip route A.B.C.D/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", + NO_STR IP_STR "Establish static routes\n" "IP destination prefix (e.g. 10.0.0.0/8)\n" "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n" - "Set tag for this route\n" + "Tag of this route\n" "Tag value\n" - "Distance value for this route\n") + "Distance value for this route\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], argv[2], - argv[3], NULL, NULL); -} + int idx_ipv4_prefixlen = 3; + int idx_curr = 5; + char *tag, *distance, *vrf; -DEFUN (ip_route_mask_distance, - ip_route_mask_distance_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>", - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, NULL, - argv[3], NULL, NULL); + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, + argv[idx_ipv4_prefixlen]->arg, + NULL, NULL, NULL, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (ip_route_mask_tag_distance, - ip_route_mask_tag_distance_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>", +DEFUN (no_ip_route_mask, + no_ip_route_mask_cmd, - "no ip route A.B.C.D A.B.C.D [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ip route A.B.C.D A.B.C.D [tag (1-4294967295)] [(1-255)] [vrf NAME]", + NO_STR IP_STR "Establish static routes\n" "IP destination prefix\n" @@@ -595,633 -664,2598 +640,640 @@@ "IP gateway address\n" "IP gateway interface name\n" "Null interface\n" - "Set tag for this route\n" + "Tag of this route\n" "Tag value\n" - "Distance value for this route\n") + "Distance value for this route\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3], - argv[4], NULL, NULL); + int idx_ipv4 = 3; + int idx_ipv4_2 = 4; + int idx_ipv4_ifname_null = 5; + int idx_curr = 6; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, + argv[idx_ipv4]->arg, + argv[idx_ipv4_2]->arg, + argv[idx_ipv4_ifname_null]->arg, + NULL, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (ip_route_mask_flags_tag_distance, - ip_route_mask_flags_tag_distance_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>", +DEFUN (no_ip_route_mask_flags2, + no_ip_route_mask_flags2_cmd, - "no ip route A.B.C.D A.B.C.D [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ip route A.B.C.D A.B.C.D [tag (1-4294967295)] [(1-255)] [vrf NAME]", + NO_STR IP_STR "Establish static routes\n" "IP destination prefix\n" "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Set tag for this route\n" + "Emit an ICMP unreachable when matched\n" + "Silently discard pkts when matched\n" + "Tag of this route\n" "Tag value\n" "Distance value for this route\n" - VRF_CMD_HELP_STR) - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], argv[4], - argv[5], NULL, NULL); -} + int idx_ipv4 = 3; + int idx_ipv4_2 = 4; + int idx_curr = 6; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, + argv[idx_ipv4]->arg, + argv[idx_ipv4_2]->arg, + NULL, NULL, - tag, distance, vrf); ++ tag, distance, vrf, NULL); +} -DEFUN (ip_route_mask_flags_distance, - ip_route_mask_flags_distance_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>", +DEFUN (no_ip_route_flags, + no_ip_route_flags_cmd, - "no ip route A.B.C.D/M [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ip route A.B.C.D/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", + NO_STR IP_STR "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" "IP gateway address\n" "IP gateway interface name\n" "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n" - "Distance value for this route\n") + "Tag of this route\n" + "Tag value\n" + "Distance value for this route\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], argv[3], NULL, - argv[4], NULL, NULL); + int idx_ipv4_prefixlen = 3; + int idx_ipv4_ifname = 4; + int idx_reject_blackhole = 5; + int idx_curr = 6; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, + argv[idx_ipv4_prefixlen]->arg, + NULL, + argv[idx_ipv4_ifname]->arg, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (ip_route_mask_flags_distance2, - ip_route_mask_flags_distance2_cmd, - "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>", +DEFUN (no_ip_route_mask_flags, + no_ip_route_mask_flags_cmd, - "no ip route A.B.C.D A.B.C.D [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ip route A.B.C.D A.B.C.D [tag (1-4294967295)] [(1-255)] [vrf NAME]", + NO_STR IP_STR "Establish static routes\n" "IP destination prefix\n" "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], NULL, - argv[3], NULL, NULL); -} - -DEFUN (ip_route_mask_flags_tag_distance2, - ip_route_mask_flags_tag_distance2_cmd, - "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255>", - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Set tag for this route\n" + "Tag of this route\n" "Tag value\n" "Distance value for this route\n" - VRF_CMD_HELP_STR) - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, argv[2], argv[3], - argv[4], NULL, NULL); -} + int idx_ipv4 = 3; + int idx_ipv4_2 = 4; + int idx_ipv4_ifname = 5; + int idx_reject_blackhole = 6; + int idx_curr = 7; + char *tag, *distance, *vrf; -DEFUN (no_ip_route, - no_ip_route_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0)", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL, - NULL, NULL, NULL); + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, + argv[idx_ipv4]->arg, + argv[idx_ipv4_2]->arg, + argv[idx_ipv4_ifname]->arg, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (no_ip_route_tag, - no_ip_route_tag_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Tag of this route\n" - "Tag value\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2], - NULL, NULL, NULL); -} - -ALIAS (no_ip_route, - no_ip_route_flags_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole)", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") - -ALIAS (no_ip_route_tag, - no_ip_route_flags_tag_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n") - -DEFUN (no_ip_route_flags2, - no_ip_route_flags2_cmd, - "no ip route A.B.C.D/M (reject|blackhole)", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, NULL, NULL, - NULL, NULL, NULL); -} - -DEFUN (no_ip_route_flags2_tag, - no_ip_route_flags2_tag_cmd, - "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, NULL, argv[1], - NULL, NULL, NULL); -} - -DEFUN (no_ip_route_mask, - no_ip_route_mask_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0)", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL, - NULL, NULL, NULL); -} - -DEFUN (no_ip_route_mask_tag, - no_ip_route_mask_tag_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Tag of this route\n" - "Tag value\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3], - NULL, NULL, NULL); -} - -ALIAS (no_ip_route_mask, - no_ip_route_mask_flags_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole)", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") - -ALIAS (no_ip_route_mask_tag, - no_ip_route_mask_flags_tag_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n") - -DEFUN (no_ip_route_mask_flags2, - no_ip_route_mask_flags2_cmd, - "no ip route A.B.C.D A.B.C.D (reject|blackhole)", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, NULL, NULL, - NULL, NULL, NULL); -} - -DEFUN (no_ip_route_mask_flags2_tag, - no_ip_route_mask_flags2_tag_cmd, - "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, NULL, argv[2], - NULL, NULL, NULL); -} - -DEFUN (no_ip_route_distance, - no_ip_route_distance_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, NULL, - argv[2], NULL, NULL); -} - -DEFUN (no_ip_route_tag_distance, - no_ip_route_tag_distance_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, argv[2], - argv[3], NULL, NULL); -} - -DEFUN (no_ip_route_flags_distance, - no_ip_route_flags_distance_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], NULL, - argv[3], NULL, NULL); -} - -DEFUN (no_ip_route_flags_tag_distance, - no_ip_route_flags_tag_distance_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], argv[2], argv[3], - argv[4], NULL, NULL); -} - -DEFUN (no_ip_route_flags_distance2, - no_ip_route_flags_distance2_cmd, - "no ip route A.B.C.D/M (reject|blackhole) <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], NULL, - argv[2], NULL, NULL); -} - -DEFUN (no_ip_route_flags_tag_distance2, - no_ip_route_flags_tag_distance2_cmd, - "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], argv[2], - argv[3], NULL, NULL); -} - -DEFUN (no_ip_route_mask_distance, - no_ip_route_mask_distance_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, NULL, - argv[3], NULL, NULL); -} - -DEFUN (no_ip_route_mask_tag_distance, - no_ip_route_mask_tag_distance_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], NULL, argv[3], - argv[4], NULL, NULL); -} - -DEFUN (no_ip_route_mask_flags_distance, - no_ip_route_mask_flags_distance_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], NULL, - argv[4], NULL, NULL); -} - -DEFUN (no_ip_route_mask_flags_tag_distance, - no_ip_route_mask_flags_tag_distance_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], argv[3], argv[4], - argv[5], NULL, NULL); -} - -DEFUN (no_ip_route_mask_flags_distance2, - no_ip_route_mask_flags_distance2_cmd, - "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], NULL, - argv[3], NULL, NULL); -} - -DEFUN (no_ip_route_mask_flags_tag_distance2, - no_ip_route_mask_flags_tag_distance2_cmd, - "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n") -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, argv[2], argv[3], - argv[4], NULL, NULL); -} - -/* Static route configuration. */ -DEFUN (ip_route_vrf, - ip_route_vrf_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, - NULL, NULL, argv[2], NULL); -} - -DEFUN (ip_route_tag_vrf, - ip_route_tag_vrf_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, - argv[2], NULL, argv[3], NULL); -} - -DEFUN (ip_route_flags_vrf, - ip_route_flags_vrf_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], - argv[2], NULL, NULL, argv[3], NULL); -} - -DEFUN (ip_route_flags_tag_vrf, - ip_route_flags_tag_vrf_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) - -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], - argv[2], argv[3], NULL, argv[4], NULL); -} - -DEFUN (ip_route_flags2_vrf, - ip_route_flags2_vrf_cmd, - "ip route A.B.C.D/M (reject|blackhole) " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], - NULL, NULL, argv[2], NULL); -} - -DEFUN (ip_route_flags2_tag_vrf, - ip_route_flags2_tag_vrf_cmd, - "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) - -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], - argv[2], NULL, argv[3], NULL); -} - -/* Mask as A.B.C.D format. */ -DEFUN (ip_route_mask_vrf, - ip_route_mask_vrf_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], - NULL, NULL, NULL, argv[3], NULL); -} - -DEFUN (ip_route_mask_tag_vrf, - ip_route_mask_tag_vrf_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) - -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], - NULL, argv[3], NULL, argv[4], NULL); -} - -DEFUN (ip_route_mask_flags_vrf, - ip_route_mask_flags_vrf_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], - argv[3], NULL, NULL, argv[4], NULL); -} - -DEFUN (ip_route_mask_flags_tag_vrf, - ip_route_mask_flags_tag_vrf_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) - -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], - argv[3], argv[4], NULL, argv[5], NULL); -} - -DEFUN (ip_route_mask_flags2_vrf, - ip_route_mask_flags2_vrf_cmd, - "ip route A.B.C.D A.B.C.D (reject|blackhole) " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, - argv[2], NULL, NULL, argv[3], NULL); -} - -DEFUN (ip_route_mask_flags2_tag_vrf, - ip_route_mask_flags2_tag_vrf_cmd, - "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, - argv[2], argv[3], NULL, argv[4], NULL); -} - -/* Distance option value. */ -DEFUN (ip_route_distance_vrf, - ip_route_distance_vrf_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, - NULL, argv[2], argv[3], NULL); -} - -DEFUN (ip_route_tag_distance_vrf, - ip_route_tag_distance_vrf_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) - -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, - argv[2], argv[3], argv[4], NULL); -} - -DEFUN (ip_route_flags_distance_vrf, - ip_route_flags_distance_vrf_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], - argv[2], NULL, argv[3], argv[4], NULL); -} - -DEFUN (ip_route_flags_tag_distance_vrf, - ip_route_flags_tag_distance_vrf_cmd, - "ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], - argv[2], argv[3], argv[4],argv[5], NULL); -} - -DEFUN (ip_route_flags_distance2_vrf, - ip_route_flags_distance2_vrf_cmd, - "ip route A.B.C.D/M (reject|blackhole) <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], - NULL, argv[2], argv[3], NULL); -} - -DEFUN (ip_route_flags_tag_distance2_vrf, - ip_route_flags_tag_distance2_vrf_cmd, - "ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], NULL, NULL, argv[1], - argv[2], argv[3], argv[4], NULL); -} - -DEFUN (ip_route_mask_distance_vrf, - ip_route_mask_distance_vrf_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], - NULL, NULL, argv[3], argv[4], NULL); -} - -DEFUN (ip_route_mask_tag_distance_vrf, - ip_route_mask_tag_distance_vrf_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], - NULL, argv[3], argv[4], argv[5], NULL); -} - -DEFUN (ip_route_mask_flags_tag_distance_vrf, - ip_route_mask_flags_tag_distance_vrf_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], argv[6], NULL); -} - - -DEFUN (ip_route_mask_flags_distance_vrf, - ip_route_mask_flags_distance_vrf_cmd, - "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], - argv[3], NULL, argv[4], argv[5], NULL); -} - -DEFUN (ip_route_mask_flags_distance2_vrf, - ip_route_mask_flags_distance2_vrf_cmd, - "ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, - argv[2], NULL, argv[3], argv[4], NULL); -} - -DEFUN (ip_route_mask_flags_tag_distance2_vrf, - ip_route_mask_flags_tag_distance2_vrf_cmd, - "ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this route\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[0], argv[1], NULL, - argv[2], argv[3], argv[4], argv[5], NULL); -} - -DEFUN (no_ip_route_vrf, - no_ip_route_vrf_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, - NULL, NULL, argv[2], NULL); -} - -DEFUN (no_ip_route_flags_vrf, - no_ip_route_flags_vrf_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], - argv[2], NULL, NULL, argv[3], NULL); -} - -DEFUN (no_ip_route_tag_vrf, - no_ip_route_tag_vrf_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Tag of this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, - argv[2], NULL, argv[3], NULL); -} - -DEFUN (no_ip_route_flags_tag_vrf, - no_ip_route_flags_tag_vrf_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], - argv[2], argv[3], NULL, argv[4], NULL); -} - -DEFUN (no_ip_route_flags2_vrf, - no_ip_route_flags2_vrf_cmd, - "no ip route A.B.C.D/M (reject|blackhole) " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], - NULL, NULL, argv[2], NULL); -} - -DEFUN (no_ip_route_flags2_tag_vrf, - no_ip_route_flags2_tag_vrf_cmd, - "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], - argv[2], NULL, argv[3], NULL); -} - -DEFUN (no_ip_route_mask_vrf, - no_ip_route_mask_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], - NULL, NULL, NULL, argv[3], NULL); -} - -DEFUN (no_ip_route_mask_flags_vrf, - no_ip_route_mask_flags_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], - argv[3], NULL, NULL, argv[4], NULL); -} - -DEFUN (no_ip_route_mask_tag_vrf, - no_ip_route_mask_tag_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Tag of this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], - NULL, argv[3], NULL, argv[4], NULL); -} - -DEFUN (no_ip_route_mask_flags_tag_vrf, - no_ip_route_mask_flags_tag_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], - argv[3], argv[4], NULL, argv[5], NULL); -} - -DEFUN (no_ip_route_mask_flags2_vrf, - no_ip_route_mask_flags2_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (reject|blackhole) " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, - argv[2], NULL, NULL, argv[3], NULL); -} - -DEFUN (no_ip_route_mask_flags2_tag_vrf, - no_ip_route_mask_flags2_tag_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, - argv[2], argv[3], NULL, argv[4], NULL); -} - - -DEFUN (no_ip_route_distance_vrf, - no_ip_route_distance_vrf_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, - NULL, argv[2], argv[3], NULL); -} - -DEFUN (no_ip_route_tag_distance_vrf, - no_ip_route_tag_distance_vrf_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], NULL, - argv[2], argv[3], argv[4], NULL); -} - -DEFUN (no_ip_route_flags_distance_vrf, - no_ip_route_flags_distance_vrf_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], - argv[2], NULL, argv[3], argv[4], NULL); -} - -DEFUN (no_ip_route_flags_tag_distance_vrf, - no_ip_route_flags_tag_distance_vrf_cmd, - "no ip route A.B.C.D/M (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, argv[1], - argv[2], argv[3], argv[4],argv[5], NULL); -} - -DEFUN (no_ip_route_flags_distance2_vrf, - no_ip_route_flags_distance2_vrf_cmd, - "no ip route A.B.C.D/M (reject|blackhole) <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], - NULL, argv[2], argv[3], NULL); -} - -DEFUN (no_ip_route_flags_tag_distance2_vrf, - no_ip_route_flags_tag_distance2_vrf_cmd, - "no ip route A.B.C.D/M (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix (e.g. 10.0.0.0/8)\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], NULL, NULL, argv[1], - argv[2] , argv[3], argv[4], NULL); -} - -DEFUN (no_ip_route_mask_distance_vrf, - no_ip_route_mask_distance_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], - NULL, NULL, argv[3], argv[4], NULL); -} - -DEFUN (no_ip_route_mask_tag_distance_vrf, - no_ip_route_mask_tag_distance_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE|null0) tag <1-4294967295> <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Null interface\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], - NULL, argv[3], argv[4], argv[5], NULL); -} - -DEFUN (no_ip_route_mask_flags_distance_vrf, - no_ip_route_mask_flags_distance_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], - argv[3], NULL, argv[4], argv[5], NULL); -} - -DEFUN (no_ip_route_mask_flags_tag_distance_vrf, - no_ip_route_mask_flags_tag_distance_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "IP gateway address\n" - "IP gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], argv[2], - argv[3], argv[4], argv[5], argv[6], NULL); -} - -DEFUN (no_ip_route_mask_flags_distance2_vrf, - no_ip_route_mask_flags_distance2_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (reject|blackhole) <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, - argv[2], NULL, argv[3], argv[4], NULL); -} - -DEFUN (no_ip_route_mask_flags_tag_distance2_vrf, - no_ip_route_mask_flags_tag_distance2_vrf_cmd, - "no ip route A.B.C.D A.B.C.D (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IP destination prefix\n" - "IP destination prefix mask\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Tag of this route\n" - "Tag value\n" - "Distance value for this route\n" - VRF_CMD_HELP_STR) -{ - return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[0], argv[1], NULL, - argv[2], argv[3], argv[4], argv[5], NULL); -} - -/* New RIB. Detailed information for IPv4 route. */ -static void -vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast) -{ - struct rib *rib; - struct nexthop *nexthop, *tnexthop; - int recursing; - char buf[PREFIX_STRLEN]; - struct zebra_vrf *zvrf; - - RNODE_FOREACH_RIB (rn, rib) - { - const char *mcast_info = ""; - if (mcast) - { - rib_table_info_t *info = rn->table->info; - mcast_info = (info->safi == SAFI_MULTICAST) - ? " using Multicast RIB" - : " using Unicast RIB"; - } - - vty_out (vty, "Routing entry for %s%s%s", - prefix2str (&rn->p, buf, sizeof(buf)), mcast_info, - VTY_NEWLINE); - vty_out (vty, " Known via \"%s", zebra_route_string (rib->type)); - if (rib->instance) - vty_out (vty, "[%d]", rib->instance); - vty_out (vty, "\""); - vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric); - if (rib->tag) - vty_out (vty, ", tag %"ROUTE_TAG_PRI, rib->tag); - if (rib->mtu) - vty_out (vty, ", mtu %u", rib->mtu); - if (rib->vrf_id != VRF_DEFAULT) - { - zvrf = vrf_info_lookup(rib->vrf_id); - vty_out (vty, ", vrf %s", zvrf->name); - } - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) - vty_out (vty, ", best"); - else if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) - vty_out (vty, ", fib"); - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE)) - vty_out (vty, ", fib-override"); - if (rib->refcnt) - vty_out (vty, ", refcnt %ld", rib->refcnt); - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) - vty_out (vty, ", blackhole"); - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) - vty_out (vty, ", reject"); - vty_out (vty, "%s", VTY_NEWLINE); - - if (rib->type == ZEBRA_ROUTE_RIP - || rib->type == ZEBRA_ROUTE_OSPF - || rib->type == ZEBRA_ROUTE_ISIS - || rib->type == ZEBRA_ROUTE_TABLE - || rib->type == ZEBRA_ROUTE_BGP) - { - time_t uptime; - struct tm *tm; - - uptime = time (NULL); - uptime -= rib->uptime; - tm = gmtime (&uptime); - - vty_out (vty, " Last update "); - - if (uptime < ONE_DAY_SECOND) - vty_out (vty, "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); - else if (uptime < ONE_WEEK_SECOND) - vty_out (vty, "%dd%02dh%02dm", - tm->tm_yday, tm->tm_hour, tm->tm_min); - else - vty_out (vty, "%02dw%dd%02dh", - tm->tm_yday/7, - tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); - vty_out (vty, " ago%s", VTY_NEWLINE); - } - - for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) - { - char addrstr[32]; - - vty_out (vty, " %c%s", - CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ', - recursing ? " " : ""); - - switch (nexthop->type) - { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4)); - if (nexthop->ifindex) - vty_out (vty, ", via %s", - ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - vty_out (vty, " %s", - inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); - if (nexthop->ifindex) - vty_out (vty, ", via %s", - ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); - break; - case NEXTHOP_TYPE_IFINDEX: - vty_out (vty, " directly connected, %s", - ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); - break; - case NEXTHOP_TYPE_BLACKHOLE: - vty_out (vty, " directly connected, Null0"); - break; - default: - break; - } - if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - vty_out (vty, " inactive"); - - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) - vty_out (vty, " onlink"); - - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) - vty_out (vty, " (recursive)"); - - switch (nexthop->type) - { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->src.ipv4.s_addr) - { - if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr, - sizeof addrstr)) - vty_out (vty, ", src %s", addrstr); - } - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) - { - if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr, - sizeof addrstr)) - vty_out (vty, ", src %s", addrstr); - } - break; - default: - break; - } - - /* Label information */ - if (nexthop->nh_label && nexthop->nh_label->num_labels) - { - vty_out (vty, " label %s", - mpls_label2str (nexthop->nh_label->num_labels, - nexthop->nh_label->label, buf, BUFSIZ)); - } - - vty_out (vty, "%s", VTY_NEWLINE); - } - vty_out (vty, "%s", VTY_NEWLINE); - } -} - -static void -vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib, - json_object *json) -{ - struct nexthop *nexthop, *tnexthop; - int recursing; - int len = 0; - char buf[BUFSIZ]; - json_object *json_nexthops = NULL; - json_object *json_nexthop = NULL; - json_object *json_route = NULL; - - if (json) - { - json_route = json_object_new_object(); - json_nexthops = json_object_new_array(); - - json_object_string_add(json_route, "prefix", prefix2str (&rn->p, buf, sizeof buf)); - json_object_string_add(json_route, "protocol", zebra_route_string(rib->type)); - - if (rib->instance) - json_object_int_add(json_route, "instance", rib->instance); - - if (rib->vrf_id) - json_object_int_add(json_route, "vrfId", rib->vrf_id); - - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) - json_object_boolean_true_add(json_route, "selected"); - - if (rib->type != ZEBRA_ROUTE_CONNECT && rib->type != ZEBRA_ROUTE_KERNEL) - { - json_object_int_add(json_route, "distance", rib->distance); - json_object_int_add(json_route, "metric", rib->metric); - } - - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) - json_object_boolean_true_add(json_route, "blackhole"); - - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) - json_object_boolean_true_add(json_route, "reject"); - - if (rib->type == ZEBRA_ROUTE_RIP - || rib->type == ZEBRA_ROUTE_OSPF - || rib->type == ZEBRA_ROUTE_ISIS - || rib->type == ZEBRA_ROUTE_TABLE - || rib->type == ZEBRA_ROUTE_BGP) - { - time_t uptime; - struct tm *tm; - - uptime = time (NULL); - uptime -= rib->uptime; - tm = gmtime (&uptime); - - if (uptime < ONE_DAY_SECOND) - sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); - else if (uptime < ONE_WEEK_SECOND) - sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min); - else - sprintf(buf, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); - - json_object_string_add(json_route, "uptime", buf); - } - - for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) - { - json_nexthop = json_object_new_object(); - - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) - json_object_boolean_true_add(json_nexthop, "fib"); - - switch (nexthop->type) - { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - json_object_string_add(json_nexthop, "ip", inet_ntoa (nexthop->gate.ipv4)); - json_object_string_add(json_nexthop, "afi", "ipv4"); - - if (nexthop->ifindex) - { - json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); - json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); - } - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - json_object_string_add(json_nexthop, "ip", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); - json_object_string_add(json_nexthop, "afi", "ipv6"); - - if (nexthop->ifindex) - { - json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); - json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); - } - break; - - case NEXTHOP_TYPE_IFINDEX: - json_object_boolean_true_add(json_nexthop, "directlyConnected"); - json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); - json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); - break; - case NEXTHOP_TYPE_BLACKHOLE: - json_object_boolean_true_add(json_nexthop, "blackhole"); - break; - default: - break; - } - - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - json_object_boolean_true_add(json_nexthop, "active"); - - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) - json_object_boolean_true_add(json_nexthop, "onLink"); - - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) - json_object_boolean_true_add(json_nexthop, "recursive"); - - switch (nexthop->type) - { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->src.ipv4.s_addr) - { - if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf)) - json_object_string_add(json_nexthop, "source", buf); - } - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) - { - if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf)) - json_object_string_add(json_nexthop, "source", buf); - } - break; - default: - break; - } - - json_object_array_add(json_nexthops, json_nexthop); - } - - json_object_object_add(json_route, "nexthops", json_nexthops); - json_object_array_add(json, json_route); - return; - } - - /* Nexthop information. */ - for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) - { - if (nexthop == rib->nexthop) - { - /* Prefix information. */ - len = vty_out (vty, "%c", zebra_route_char (rib->type)); - if (rib->instance) - len += vty_out (vty, "[%d]", rib->instance); - len += vty_out (vty, "%c%c %s", - CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) - ? '>' : CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB) - ? '!' : ' ', - CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) - ? '*' : ' ', - prefix2str (&rn->p, buf, sizeof buf)); - - /* Distance and metric display. */ - if (rib->type != ZEBRA_ROUTE_CONNECT - && rib->type != ZEBRA_ROUTE_KERNEL) - len += vty_out (vty, " [%d/%d]", rib->distance, - rib->metric); - } - else - vty_out (vty, " %c%*c", - CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) - ? '*' : ' ', - len - 3 + (2 * recursing), ' '); - - switch (nexthop->type) - { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4)); - if (nexthop->ifindex) - vty_out (vty, ", %s", - ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - vty_out (vty, " via %s", - inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); - if (nexthop->ifindex) - vty_out (vty, ", %s", - ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); - break; - - case NEXTHOP_TYPE_IFINDEX: - vty_out (vty, " is directly connected, %s", - ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); - break; - case NEXTHOP_TYPE_BLACKHOLE: - vty_out (vty, " is directly connected, Null0"); - break; - default: - break; - } - if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - vty_out (vty, " inactive"); - - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) - vty_out (vty, " onlink"); - - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) - vty_out (vty, " (recursive)"); - - switch (nexthop->type) - { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->src.ipv4.s_addr) - { - if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf)) - vty_out (vty, ", src %s", buf); - } - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) - { - if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf)) - vty_out (vty, ", src %s", buf); - } - break; - default: - break; - } - - /* Label information */ - if (nexthop->nh_label && nexthop->nh_label->num_labels) - { - vty_out (vty, " label %s", - mpls_label2str (nexthop->nh_label->num_labels, - nexthop->nh_label->label, buf, BUFSIZ)); - } - - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) - vty_out (vty, ", bh"); - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) - vty_out (vty, ", rej"); - - if (rib->type == ZEBRA_ROUTE_RIP - || rib->type == ZEBRA_ROUTE_OSPF - || rib->type == ZEBRA_ROUTE_ISIS - || rib->type == ZEBRA_ROUTE_TABLE - || rib->type == ZEBRA_ROUTE_BGP) - { - time_t uptime; - struct tm *tm; - - uptime = time (NULL); - uptime -= rib->uptime; - tm = gmtime (&uptime); - - if (uptime < ONE_DAY_SECOND) - vty_out (vty, ", %02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); - else if (uptime < ONE_WEEK_SECOND) - vty_out (vty, ", %dd%02dh%02dm", - tm->tm_yday, tm->tm_hour, tm->tm_min); - else - vty_out (vty, ", %02dw%dd%02dh", - tm->tm_yday/7, - tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); - } - vty_out (vty, "%s", VTY_NEWLINE); - } -} - -DEFUN (show_ip_route, - show_ip_route_cmd, - "show ip route {json}", - SHOW_STR - IP_STR - "IP routing table\n") -{ - return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST, use_json(argc, argv)); -} - -static int -do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi, - u_char use_json) -{ - struct route_table *table; - struct route_node *rn; - struct rib *rib; - int first = 1; - struct zebra_vrf *zvrf = NULL; - char buf[BUFSIZ]; - json_object *json = NULL; - json_object *json_prefix = NULL; - - if (!(zvrf = zebra_vrf_list_lookup_by_name (vrf_name))) - { - if (use_json) - vty_out (vty, "{}%s", VTY_NEWLINE); - else - vty_out (vty, "vrf %s not defined%s", vrf_name, VTY_NEWLINE); - return CMD_SUCCESS; - } - - if (zvrf->vrf_id == VRF_UNKNOWN) - { - if (use_json) - vty_out (vty, "{}%s", VTY_NEWLINE); - else - vty_out (vty, "vrf %s inactive%s", vrf_name, VTY_NEWLINE); - return CMD_SUCCESS; - } - - table = zebra_vrf_table (AFI_IP, safi, zvrf->vrf_id); - if (! table) - { - if (use_json) - vty_out (vty, "{}%s", VTY_NEWLINE); - return CMD_SUCCESS; - } - - if (use_json) - { - json = json_object_new_object(); - - /* Show all IPv4 routes. */ - for (rn = route_top (table); rn; rn = route_next (rn)) - { - RNODE_FOREACH_RIB (rn, rib) - { - if (!json_prefix) - json_prefix = json_object_new_array(); - vty_show_ip_route (vty, rn, rib, json_prefix); - } - - if (json_prefix) - { - prefix2str (&rn->p, buf, sizeof buf); - json_object_object_add(json, buf, json_prefix); - json_prefix = NULL; - } - } - - vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); - json_object_free(json); - } - else - { - /* Show all IPv4 routes. */ - for (rn = route_top (table); rn; rn = route_next (rn)) - { - RNODE_FOREACH_RIB (rn, rib) - { - if (first) - { - vty_out (vty, SHOW_ROUTE_V4_HEADER); - first = 0; - } - vty_show_ip_route (vty, rn, rib, NULL); - } - } - } - - return CMD_SUCCESS; -} - -DEFUN (show_ip_route_vrf, - show_ip_route_vrf_cmd, - "show ip route " VRF_CMD_STR " {json}", - SHOW_STR - IP_STR - "IP routing table\n" - VRF_CMD_HELP_STR) -{ - u_char uj = use_json(argc, argv); - - if (argc == 1 && uj) - return do_show_ip_route (vty, NULL, SAFI_UNICAST, uj); - else - return do_show_ip_route (vty, argv[0], SAFI_UNICAST, uj); -} - -DEFUN (show_ip_nht, - show_ip_nht_cmd, - "show ip nht", - SHOW_STR - IP_STR - "IP nexthop tracking table\n") -{ - vrf_id_t vrf_id = VRF_DEFAULT; - - if (argc) - VRF_GET_ID (vrf_id, argv[0]); - - zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); - return CMD_SUCCESS; -} - -ALIAS (show_ip_nht, - show_ip_nht_vrf_cmd, - "show ip nht " VRF_CMD_STR, - SHOW_STR - IP_STR - "IP nexthop tracking table\n" - VRF_CMD_HELP_STR) - -DEFUN (show_ip_nht_vrf_all, - show_ip_nht_vrf_all_cmd, - "show ip nht " VRF_ALL_CMD_STR, - SHOW_STR - IP_STR - "IP nexthop tracking table\n" - VRF_ALL_CMD_HELP_STR) -{ - struct zebra_vrf *zvrf; - vrf_iter_t iter; - - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) - { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); - zebra_print_rnh_table(zvrf->vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); - } - - return CMD_SUCCESS; -} - -DEFUN (show_ipv6_nht, - show_ipv6_nht_cmd, - "show ipv6 nht", - SHOW_STR - IPV6_STR - "IPv6 nexthop tracking table\n") -{ - vrf_id_t vrf_id = VRF_DEFAULT; - - if (argc) - VRF_GET_ID (vrf_id, argv[0]); - - zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); - return CMD_SUCCESS; -} - -ALIAS (show_ipv6_nht, - show_ipv6_nht_vrf_cmd, - "show ipv6 nht " VRF_CMD_STR, - SHOW_STR - IPV6_STR - "IPv6 nexthop tracking table\n" - VRF_CMD_HELP_STR) - -DEFUN (show_ipv6_nht_vrf_all, - show_ipv6_nht_vrf_all_cmd, - "show ipv6 nht " VRF_ALL_CMD_STR, - SHOW_STR - IP_STR - "IPv6 nexthop tracking table\n" - VRF_ALL_CMD_HELP_STR) -{ - struct zebra_vrf *zvrf; - vrf_iter_t iter; - - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) - if ((zvrf = vrf_iter2info (iter)) != NULL) - { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); - zebra_print_rnh_table(zvrf->vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); - } - - return CMD_SUCCESS; -} - -DEFUN (ip_nht_default_route, - ip_nht_default_route_cmd, - "ip nht resolve-via-default", - IP_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - if (zebra_rnh_ip_default_route) - return CMD_SUCCESS; - - zebra_rnh_ip_default_route = 1; - zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); - return CMD_SUCCESS; -} - -DEFUN (no_ip_nht_default_route, - no_ip_nht_default_route_cmd, - "no ip nht resolve-via-default", - NO_STR - IP_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - if (!zebra_rnh_ip_default_route) - return CMD_SUCCESS; - - zebra_rnh_ip_default_route = 0; - zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); - return CMD_SUCCESS; -} - -DEFUN (ipv6_nht_default_route, - ipv6_nht_default_route_cmd, - "ipv6 nht resolve-via-default", - IP6_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - if (zebra_rnh_ipv6_default_route) - return CMD_SUCCESS; - - zebra_rnh_ipv6_default_route = 1; - zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nht_default_route, - no_ipv6_nht_default_route_cmd, - "no ipv6 nht resolve-via-default", - NO_STR - IP6_STR - "Filter Next Hop tracking route resolution\n" - "Resolve via default route\n") -{ - if (!zebra_rnh_ipv6_default_route) - return CMD_SUCCESS; - - zebra_rnh_ipv6_default_route = 0; - zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); - return CMD_SUCCESS; -} - -DEFUN (show_ip_route_tag, - show_ip_route_tag_cmd, - "show ip route tag <1-4294967295>", - SHOW_STR - IP_STR - "IP routing table\n" - "Show only routes with tag\n" - "Tag value\n") -{ - struct route_table *table; - struct route_node *rn; - struct rib *rib; - int first = 1; - route_tag_t tag = 0; - vrf_id_t vrf_id = VRF_DEFAULT; - - if (argc > 1) - { - tag = atol(argv[1]); - VRF_GET_ID (vrf_id, argv[0]); - } - else - tag = atol(argv[0]); - - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); - if (! table) - return CMD_SUCCESS; - - /* Show all IPv4 routes with matching tag value. */ - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, rib) - { - if (rib->tag != tag) - continue; - - if (first) - { - vty_out (vty, SHOW_ROUTE_V4_HEADER); - first = 0; - } - vty_show_ip_route (vty, rn, rib, NULL); - } - return CMD_SUCCESS; -} - -ALIAS (show_ip_route_tag, - show_ip_route_vrf_tag_cmd, - "show ip route " VRF_CMD_STR " tag <1-4294967295>", - SHOW_STR - IP_STR - "IP routing table\n" - VRF_CMD_HELP_STR - "Show only routes with tag\n" - "Tag value\n") -- -DEFUN (show_ip_route_prefix_longer, - show_ip_route_prefix_longer_cmd, - "show ip route A.B.C.D/M longer-prefixes", - SHOW_STR - IP_STR - "IP routing table\n" - "IP prefix /, e.g., 35.0.0.0/8\n" - "Show route matching the specified Network/Mask pair only\n") +/* New RIB. Detailed information for IPv4 route. */ +static void +vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast) { - struct route_table *table; - struct route_node *rn; struct rib *rib; - struct prefix p; - int ret; - int first = 1; - vrf_id_t vrf_id = VRF_DEFAULT; - - if (argc > 1) - { - ret = str2prefix (argv[1], &p); - VRF_GET_ID (vrf_id, argv[0]); - } - else - ret = str2prefix (argv[0], &p); + struct nexthop *nexthop, *tnexthop; + int recursing; + char buf[PREFIX_STRLEN]; + struct zebra_vrf *zvrf; - if (! ret) + RNODE_FOREACH_RIB (rn, rib) { - vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); - return CMD_WARNING; - } - - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); - if (! table) - return CMD_SUCCESS; - - /* Show matched type IPv4 routes. */ - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, rib) - if (prefix_match (&p, &rn->p)) - { - if (first) - { - vty_out (vty, SHOW_ROUTE_V4_HEADER); - first = 0; - } - vty_show_ip_route (vty, rn, rib, NULL); - } - return CMD_SUCCESS; -} - -ALIAS (show_ip_route_prefix_longer, - show_ip_route_vrf_prefix_longer_cmd, - "show ip route " VRF_CMD_STR " A.B.C.D/M longer-prefixes", - SHOW_STR - IP_STR - "IP routing table\n" - VRF_CMD_HELP_STR - "IP prefix /, e.g., 35.0.0.0/8\n" - "Show route matching the specified Network/Mask pair only\n") - -DEFUN (show_ip_route_supernets, - show_ip_route_supernets_cmd, - "show ip route supernets-only", - SHOW_STR - IP_STR - "IP routing table\n" - "Show supernet entries only\n") -{ - struct route_table *table; - struct route_node *rn; - struct rib *rib; - u_int32_t addr; - int first = 1; - vrf_id_t vrf_id = VRF_DEFAULT; - - if (argc > 0) - VRF_GET_ID (vrf_id, argv[0]); - - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); - if (! table) - return CMD_SUCCESS; - - /* Show matched type IPv4 routes. */ - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, rib) - { - addr = ntohl (rn->p.u.prefix4.s_addr); - - if ((IN_CLASSC (addr) && rn->p.prefixlen < 24) - || (IN_CLASSB (addr) && rn->p.prefixlen < 16) - || (IN_CLASSA (addr) && rn->p.prefixlen < 8)) - { - if (first) - { - vty_out (vty, SHOW_ROUTE_V4_HEADER); - first = 0; - } - vty_show_ip_route (vty, rn, rib, NULL); - } - } - return CMD_SUCCESS; -} + const char *mcast_info = ""; + if (mcast) + { + rib_table_info_t *info = rn->table->info; + mcast_info = (info->safi == SAFI_MULTICAST) + ? " using Multicast RIB" + : " using Unicast RIB"; + } - + -ALIAS (show_ip_route_supernets, - show_ip_route_vrf_supernets_cmd, - "show ip route " VRF_CMD_STR " supernets-only", - SHOW_STR - IP_STR - "IP routing table\n" - VRF_CMD_HELP_STR - "Show supernet entries only\n") + vty_out (vty, "Routing entry for %s%s%s", + prefix2str (&rn->p, buf, sizeof(buf)), mcast_info, + VTY_NEWLINE); + vty_out (vty, " Known via \"%s", zebra_route_string (rib->type)); + if (rib->instance) + vty_out (vty, "[%d]", rib->instance); + vty_out (vty, "\""); + vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric); + if (rib->tag) + vty_out (vty, ", tag %d", rib->tag); + if (rib->mtu) + vty_out (vty, ", mtu %u", rib->mtu); + if (rib->vrf_id != VRF_DEFAULT) + { + zvrf = vrf_info_lookup(rib->vrf_id); + vty_out (vty, ", vrf %s", zvrf->name); + } + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) + vty_out (vty, ", best"); + if (rib->refcnt) + vty_out (vty, ", refcnt %ld", rib->refcnt); + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) + vty_out (vty, ", blackhole"); + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) + vty_out (vty, ", reject"); + vty_out (vty, "%s", VTY_NEWLINE); -DEFUN (show_ip_route_protocol, - show_ip_route_protocol_cmd, - "show ip route " QUAGGA_IP_REDIST_STR_ZEBRA, - SHOW_STR - IP_STR - "IP routing table\n" - QUAGGA_IP_REDIST_HELP_STR_ZEBRA) -{ - int type; - struct route_table *table; - struct route_node *rn; - struct rib *rib; - int first = 1; - vrf_id_t vrf_id = VRF_DEFAULT; + if (rib->type == ZEBRA_ROUTE_RIP + || rib->type == ZEBRA_ROUTE_OSPF + || rib->type == ZEBRA_ROUTE_ISIS + || rib->type == ZEBRA_ROUTE_TABLE + || rib->type == ZEBRA_ROUTE_BGP) + { + time_t uptime; + struct tm *tm; - if (argc > 1) - { - type = proto_redistnum (AFI_IP, argv[1]); - VRF_GET_ID (vrf_id, argv[0]); - } - else - type = proto_redistnum (AFI_IP, argv[0]); + uptime = time (NULL); + uptime -= rib->uptime; + tm = gmtime (&uptime); - if (type < 0) - { - vty_out (vty, "Unknown route type%s", VTY_NEWLINE); - return CMD_WARNING; - } + vty_out (vty, " Last update "); - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); - if (! table) - return CMD_SUCCESS; + if (uptime < ONE_DAY_SECOND) - vty_out (vty, "%02d:%02d:%02d", ++ vty_out (vty, "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) - vty_out (vty, "%dd%02dh%02dm", ++ vty_out (vty, "%dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); + else - vty_out (vty, "%02dw%dd%02dh", ++ vty_out (vty, "%02dw%dd%02dh", + tm->tm_yday/7, + tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + vty_out (vty, " ago%s", VTY_NEWLINE); + } - /* Show matched type IPv4 routes. */ - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, rib) - if (rib->type == type) + for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) { - if (first) - { - vty_out (vty, SHOW_ROUTE_V4_HEADER); - first = 0; - } - vty_show_ip_route (vty, rn, rib, NULL); - } - return CMD_SUCCESS; -} + char addrstr[32]; -ALIAS (show_ip_route_protocol, - show_ip_route_vrf_protocol_cmd, - "show ip route " VRF_CMD_STR " " QUAGGA_IP_REDIST_STR_ZEBRA, - SHOW_STR - IP_STR - "IP routing table\n" - VRF_CMD_HELP_STR - QUAGGA_IP_REDIST_HELP_STR_ZEBRA) + vty_out (vty, " %c%s", + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ', + recursing ? " " : ""); -DEFUN (show_ip_route_ospf_instance, - show_ip_route_ospf_instance_cmd, - "show ip route ospf <1-65535>", - SHOW_STR - IP_STR - "IP routing table\n" - "Open Shortest Path First (OSPFv2)\n" - "Instance ID\n") -{ - struct route_table *table; - struct route_node *rn; - struct rib *rib; - int first = 1; - u_short instance = 0; + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4)); + if (nexthop->ifindex) + vty_out (vty, ", via %s", + ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + vty_out (vty, " %s", + inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); + if (nexthop->ifindex) + vty_out (vty, ", via %s", + ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); + break; + case NEXTHOP_TYPE_IFINDEX: + vty_out (vty, " directly connected, %s", + ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + vty_out (vty, " directly connected, Null0"); + break; + default: + break; + } + if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + vty_out (vty, " inactive"); - VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) + vty_out (vty, " onlink"); - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); - if (! table) - return CMD_SUCCESS; + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + vty_out (vty, " (recursive)"); - /* Show matched type IPv4 routes. */ - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, rib) - if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance) - { - if (first) - { - vty_out (vty, SHOW_ROUTE_V4_HEADER); - first = 0; - } - vty_show_ip_route (vty, rn, rib, NULL); + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + if (nexthop->src.ipv4.s_addr) + { + if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr, + sizeof addrstr)) + vty_out (vty, ", src %s", addrstr); + } + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + { + if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr, + sizeof addrstr)) + vty_out (vty, ", src %s", addrstr); + } + break; + default: + break; + } + vty_out (vty, "%s", VTY_NEWLINE); } - return CMD_SUCCESS; + vty_out (vty, "%s", VTY_NEWLINE); + } } -DEFUN (show_ip_route_addr, - show_ip_route_addr_cmd, - "show ip route A.B.C.D", - SHOW_STR - IP_STR - "IP routing table\n" - "Network in the IP routing table to display\n") +static void +vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib, + json_object *json) { - int ret; - struct prefix_ipv4 p; - struct route_table *table; - struct route_node *rn; - vrf_id_t vrf_id = VRF_DEFAULT; - - if (argc > 1) - { - VRF_GET_ID (vrf_id, argv[0]); - ret = str2prefix_ipv4 (argv[1], &p); - } - else - ret = str2prefix_ipv4 (argv[0], &p); + struct nexthop *nexthop, *tnexthop; + int recursing; + int len = 0; + char buf[BUFSIZ]; + json_object *json_nexthops = NULL; + json_object *json_nexthop = NULL; + json_object *json_route = NULL; - if (ret <= 0) + if (json) { - vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); - return CMD_WARNING; - } - - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); - if (! table) - return CMD_SUCCESS; + json_route = json_object_new_object(); + json_nexthops = json_object_new_array(); - rn = route_node_match (table, (struct prefix *) &p); - if (! rn) - { - vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); - return CMD_WARNING; - } + json_object_string_add(json_route, "prefix", prefix2str (&rn->p, buf, sizeof buf)); + json_object_string_add(json_route, "protocol", zebra_route_string(rib->type)); - vty_show_ip_route_detail (vty, rn, 0); + if (rib->instance) + json_object_int_add(json_route, "instance", rib->instance); - route_unlock_node (rn); + if (rib->vrf_id) + json_object_int_add(json_route, "vrfId", rib->vrf_id); - return CMD_SUCCESS; -} + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) + json_object_boolean_true_add(json_route, "selected"); -ALIAS (show_ip_route_addr, - show_ip_route_vrf_addr_cmd, - "show ip route " VRF_CMD_STR " A.B.C.D", - SHOW_STR - IP_STR - "IP routing table\n" - VRF_CMD_HELP_STR - "Network in the IP routing table to display\n") + if (rib->type != ZEBRA_ROUTE_CONNECT && rib->type != ZEBRA_ROUTE_KERNEL) + { + json_object_int_add(json_route, "distance", rib->distance); + json_object_int_add(json_route, "metric", rib->metric); + } -DEFUN (show_ip_route_prefix, - show_ip_route_prefix_cmd, - "show ip route A.B.C.D/M", - SHOW_STR - IP_STR - "IP routing table\n" - "IP prefix /, e.g., 35.0.0.0/8\n") -{ - int ret; - struct prefix_ipv4 p; - struct route_table *table; - struct route_node *rn; - vrf_id_t vrf_id = VRF_DEFAULT; + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) + json_object_boolean_true_add(json_route, "blackhole"); - if (argc > 1) - { - VRF_GET_ID (vrf_id, argv[0]); - ret = str2prefix_ipv4 (argv[1], &p); - } - else - ret = str2prefix_ipv4 (argv[0], &p); + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) + json_object_boolean_true_add(json_route, "reject"); - if (ret <= 0) - { - vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); - return CMD_WARNING; - } + if (rib->type == ZEBRA_ROUTE_RIP + || rib->type == ZEBRA_ROUTE_OSPF + || rib->type == ZEBRA_ROUTE_ISIS + || rib->type == ZEBRA_ROUTE_TABLE + || rib->type == ZEBRA_ROUTE_BGP) + { + time_t uptime; + struct tm *tm; - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); - if (! table) - return CMD_SUCCESS; + uptime = time (NULL); + uptime -= rib->uptime; + tm = gmtime (&uptime); - rn = route_node_match (table, (struct prefix *) &p); - if (! rn || rn->p.prefixlen != p.prefixlen) - { - vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); - return CMD_WARNING; - } + if (uptime < ONE_DAY_SECOND) + sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) + sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min); + else + sprintf(buf, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); - vty_show_ip_route_detail (vty, rn, 0); + json_object_string_add(json_route, "uptime", buf); + } - route_unlock_node (rn); + for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) + { + json_nexthop = json_object_new_object(); - return CMD_SUCCESS; -} + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) + json_object_boolean_true_add(json_nexthop, "fib"); -ALIAS (show_ip_route_prefix, - show_ip_route_vrf_prefix_cmd, - "show ip route " VRF_CMD_STR " A.B.C.D/M", - SHOW_STR - IP_STR - "IP routing table\n" - VRF_CMD_HELP_STR - "IP prefix /, e.g., 35.0.0.0/8\n") + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + json_object_string_add(json_nexthop, "ip", inet_ntoa (nexthop->gate.ipv4)); + json_object_string_add(json_nexthop, "afi", "ipv4"); -static void -vty_show_ip_route_summary (struct vty *vty, struct route_table *table) -{ - struct route_node *rn; - struct rib *rib; -#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX -#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1) - u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1]; - u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1]; - u_int32_t i; - u_int32_t is_ibgp; + if (nexthop->ifindex) + { + json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); + json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); + } + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + json_object_string_add(json_nexthop, "ip", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); + json_object_string_add(json_nexthop, "afi", "ipv6"); - memset (&rib_cnt, 0, sizeof(rib_cnt)); - memset (&fib_cnt, 0, sizeof(fib_cnt)); - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, rib) - { - is_ibgp = (rib->type == ZEBRA_ROUTE_BGP && - CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)); + if (nexthop->ifindex) + { + json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); + json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); + } + break; - rib_cnt[ZEBRA_ROUTE_TOTAL]++; - if (is_ibgp) - rib_cnt[ZEBRA_ROUTE_IBGP]++; - else - rib_cnt[rib->type]++; + case NEXTHOP_TYPE_IFINDEX: + json_object_boolean_true_add(json_nexthop, "directlyConnected"); + json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); + json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + json_object_boolean_true_add(json_nexthop, "blackhole"); + break; + default: + break; + } - if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) - { - fib_cnt[ZEBRA_ROUTE_TOTAL]++; + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + json_object_boolean_true_add(json_nexthop, "active"); - if (is_ibgp) - fib_cnt[ZEBRA_ROUTE_IBGP]++; - else - fib_cnt[rib->type]++; - } - } + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) + json_object_boolean_true_add(json_nexthop, "onLink"); - vty_out (vty, "%-20s %-20s %s (vrf %s)%s", - "Route Source", "Routes", "FIB", - ((rib_table_info_t *)table->info)->zvrf->name, - VTY_NEWLINE); + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + json_object_boolean_true_add(json_nexthop, "recursive"); - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - { - if ((rib_cnt[i] > 0) || - (i == ZEBRA_ROUTE_BGP && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) - { - if (i == ZEBRA_ROUTE_BGP) + switch (nexthop->type) { - vty_out (vty, "%-20s %-20d %-20d %s", "ebgp", - rib_cnt[ZEBRA_ROUTE_BGP], fib_cnt[ZEBRA_ROUTE_BGP], - VTY_NEWLINE); - vty_out (vty, "%-20s %-20d %-20d %s", "ibgp", - rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP], - VTY_NEWLINE); + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + if (nexthop->src.ipv4.s_addr) + { + if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf)) + json_object_string_add(json_nexthop, "source", buf); + } + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + { + if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf)) + json_object_string_add(json_nexthop, "source", buf); + } + break; + default: + break; } - else - vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i), - rib_cnt[i], fib_cnt[i], VTY_NEWLINE); + + json_object_array_add(json_nexthops, json_nexthop); } + + json_object_object_add(json_route, "nexthops", json_nexthops); + json_object_array_add(json, json_route); + return; } - vty_out (vty, "------%s", VTY_NEWLINE); - vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL], - fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE); - vty_out (vty, "%s", VTY_NEWLINE); -} + /* Nexthop information. */ + for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) + { + if (nexthop == rib->nexthop) + { + /* Prefix information. */ + len = vty_out (vty, "%c", zebra_route_char (rib->type)); + if (rib->instance) + len += vty_out (vty, "[%d]", rib->instance); + len += vty_out (vty, "%c%c %s", + CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) + ? '>' : ' ', + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) + ? '*' : ' ', + prefix2str (&rn->p, buf, sizeof buf)); -/* - * Implementation of the ip route summary prefix command. - * - * This command prints the primary prefixes that have been installed by various - * protocols on the box. - * - */ -static void -vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table) -{ - struct route_node *rn; - struct rib *rib; - struct nexthop *nexthop; -#define ZEBRA_ROUTE_IBGP ZEBRA_ROUTE_MAX -#define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1) - u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1]; - u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1]; - u_int32_t i; - int cnt; + /* Distance and metric display. */ - if (rib->type != ZEBRA_ROUTE_CONNECT ++ if (rib->type != ZEBRA_ROUTE_CONNECT + && rib->type != ZEBRA_ROUTE_KERNEL) + len += vty_out (vty, " [%d/%d]", rib->distance, + rib->metric); + } + else + vty_out (vty, " %c%*c", + CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) + ? '*' : ' ', + len - 3 + (2 * recursing), ' '); + + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4)); + if (nexthop->ifindex) + vty_out (vty, ", %s", + ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + vty_out (vty, " via %s", + inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); + if (nexthop->ifindex) + vty_out (vty, ", %s", + ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); + break; + + case NEXTHOP_TYPE_IFINDEX: + vty_out (vty, " is directly connected, %s", + ifindex2ifname_vrf (nexthop->ifindex, rib->vrf_id)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + vty_out (vty, " is directly connected, Null0"); + break; + default: + break; + } + if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + vty_out (vty, " inactive"); + + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) + vty_out (vty, " onlink"); + + if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + vty_out (vty, " (recursive)"); + + switch (nexthop->type) + { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + if (nexthop->src.ipv4.s_addr) + { + if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf)) + vty_out (vty, ", src %s", buf); + } + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + { + if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf)) + vty_out (vty, ", src %s", buf); + } + break; + default: + break; + } - memset (&rib_cnt, 0, sizeof(rib_cnt)); - memset (&fib_cnt, 0, sizeof(fib_cnt)); - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, rib) - { + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) + vty_out (vty, ", bh"); + if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) + vty_out (vty, ", rej"); - /* - * In case of ECMP, count only once. - */ - cnt = 0; - for (nexthop = rib->nexthop; (!cnt && nexthop); nexthop = nexthop->next) - { - cnt++; - rib_cnt[ZEBRA_ROUTE_TOTAL]++; - rib_cnt[rib->type]++; - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) - { - fib_cnt[ZEBRA_ROUTE_TOTAL]++; - fib_cnt[rib->type]++; - } - if (rib->type == ZEBRA_ROUTE_BGP && - CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)) - { - rib_cnt[ZEBRA_ROUTE_IBGP]++; - if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) - fib_cnt[ZEBRA_ROUTE_IBGP]++; - } - } - } + if (rib->type == ZEBRA_ROUTE_RIP + || rib->type == ZEBRA_ROUTE_OSPF + || rib->type == ZEBRA_ROUTE_ISIS + || rib->type == ZEBRA_ROUTE_TABLE + || rib->type == ZEBRA_ROUTE_BGP) + { + time_t uptime; + struct tm *tm; - vty_out (vty, "%-20s %-20s %s (vrf %s)%s", - "Route Source", "Prefix Routes", "FIB", - ((rib_table_info_t *)table->info)->zvrf->name, - VTY_NEWLINE); + uptime = time (NULL); + uptime -= rib->uptime; + tm = gmtime (&uptime); - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) - { - if (rib_cnt[i] > 0) - { - if (i == ZEBRA_ROUTE_BGP) - { - vty_out (vty, "%-20s %-20d %-20d %s", "ebgp", - rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP], - fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP], - VTY_NEWLINE); - vty_out (vty, "%-20s %-20d %-20d %s", "ibgp", - rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP], - VTY_NEWLINE); - } + if (uptime < ONE_DAY_SECOND) - vty_out (vty, ", %02d:%02d:%02d", ++ vty_out (vty, ", %02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) - vty_out (vty, ", %dd%02dh%02dm", ++ vty_out (vty, ", %dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); else - vty_out (vty, ", %02dw%dd%02dh", - vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i), - rib_cnt[i], fib_cnt[i], VTY_NEWLINE); ++ vty_out (vty, ", %02dw%dd%02dh", + tm->tm_yday/7, + tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); } + vty_out (vty, "%s", VTY_NEWLINE); } - - vty_out (vty, "------%s", VTY_NEWLINE); - vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL], - fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE); - vty_out (vty, "%s", VTY_NEWLINE); } -/* Show route summary. */ -DEFUN (show_ip_route_summary, - show_ip_route_summary_cmd, - "show ip route summary", +DEFUN (show_ip_route, + show_ip_route_cmd, + "show ip route [json]", SHOW_STR IP_STR - "IP routing table\n" - "Summary of all routes\n") + "IP routing table\n") { - struct route_table *table; - vrf_id_t vrf_id = VRF_DEFAULT; - - if (argc > 0) - VRF_GET_ID (vrf_id, argv[0]); - - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); - if (! table) - return CMD_SUCCESS; - - vty_show_ip_route_summary (vty, table); - - return CMD_SUCCESS; + return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST, use_json(argc, argv)); } -ALIAS (show_ip_route_summary, - show_ip_route_vrf_summary_cmd, - "show ip route " VRF_CMD_STR " summary", - SHOW_STR - IP_STR - "IP routing table\n" - VRF_CMD_HELP_STR - "Summary of all routes\n") - -/* Show route summary prefix. */ -DEFUN (show_ip_route_summary_prefix, - show_ip_route_summary_prefix_cmd, - "show ip route summary prefix", - SHOW_STR - IP_STR - "IP routing table\n" - "Summary of all routes\n" - "Prefix routes\n") +static int +do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi, + u_char use_json) { struct route_table *table; - vrf_id_t vrf_id = VRF_DEFAULT; + struct route_node *rn; + struct rib *rib; + int first = 1; + struct zebra_vrf *zvrf = NULL; + char buf[BUFSIZ]; + json_object *json = NULL; + json_object *json_prefix = NULL; + + if (!(zvrf = zebra_vrf_list_lookup_by_name (vrf_name))) + { + if (use_json) + vty_out (vty, "{}%s", VTY_NEWLINE); + else + vty_out (vty, "vrf %s not defined%s", vrf_name, VTY_NEWLINE); + return CMD_SUCCESS; + } - if (argc > 0) - VRF_GET_ID (vrf_id, argv[0]); + if (zvrf->vrf_id == VRF_UNKNOWN) + { + if (use_json) + vty_out (vty, "{}%s", VTY_NEWLINE); + else + vty_out (vty, "vrf %s inactive%s", vrf_name, VTY_NEWLINE); + return CMD_SUCCESS; + } - table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); + table = zebra_vrf_table (AFI_IP, safi, zvrf->vrf_id); if (! table) - return CMD_SUCCESS; + { + if (use_json) + vty_out (vty, "{}%s", VTY_NEWLINE); + return CMD_SUCCESS; + } - vty_show_ip_route_summary_prefix (vty, table); + if (use_json) + { + json = json_object_new_object(); + + /* Show all IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + { + RNODE_FOREACH_RIB (rn, rib) + { + if (!json_prefix) + json_prefix = json_object_new_array(); + vty_show_ip_route (vty, rn, rib, json_prefix); + } + + if (json_prefix) + { + prefix2str (&rn->p, buf, sizeof buf); + json_object_object_add(json, buf, json_prefix); + json_prefix = NULL; + } + } + - vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); ++ vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); + json_object_free(json); + } + else + { + /* Show all IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + { + RNODE_FOREACH_RIB (rn, rib) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER); + first = 0; + } + vty_show_ip_route (vty, rn, rib, NULL); + } + } + } return CMD_SUCCESS; } @@@ -1382,9 -3479,9 +1434,9 @@@ DEFUN (no_ipv6_nht_default_route return CMD_SUCCESS; } -DEFUN (show_ip_route_vrf_all_protocol, - show_ip_route_vrf_all_protocol_cmd, - "show ip route " VRF_ALL_CMD_STR " " QUAGGA_IP_REDIST_STR_ZEBRA, +DEFUN (show_ip_route_tag, + show_ip_route_tag_cmd, - "show ip route [vrf NAME] tag (1-65535)", ++ "show ip route [vrf NAME] tag (1-4294967295)", SHOW_STR IP_STR "IP routing table\n" @@@ -1398,45 -3492,51 +1450,45 @@@ struct route_table *table; struct route_node *rn; struct rib *rib; - struct zebra_vrf *zvrf; - vrf_iter_t iter; int first = 1; - u_short tag = 0; - int vrf_header = 1; ++ route_tag_t tag = 0; + vrf_id_t vrf_id = VRF_DEFAULT; - + - type = proto_redistnum (AFI_IP, argv[0]); - if (type < 0) + if (strmatch(argv[idx_vrf]->text, "vrf")) { - vty_out (vty, "Unknown route type%s", VTY_NEWLINE); - return CMD_WARNING; + VRF_GET_ID (vrf_id, argv[idx_name]->arg); - tag = atoi(argv[idx_tag]->arg); ++ tag = atol(argv[idx_tag]->arg); } - - for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + else { - if ((zvrf = vrf_iter2info (iter)) == NULL || - (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) - continue; + idx_tag -= 2; - tag = atoi(argv[idx_tag]->arg); ++ tag = atol(argv[idx_tag]->arg); + } - /* Show matched type IPv4 routes. */ - for (rn = route_top (table); rn; rn = route_next (rn)) - RNODE_FOREACH_RIB (rn, rib) - if (rib->type == type) - { - if (first) - { - vty_out (vty, SHOW_ROUTE_V4_HEADER); - first = 0; - } + table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); + if (! table) + return CMD_SUCCESS; - if (vrf_header) - { - vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); - vrf_header = 0; - } - vty_show_ip_route (vty, rn, rib, NULL); - } - vrf_header = 1; - } + /* Show all IPv4 routes with matching tag value. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + RNODE_FOREACH_RIB (rn, rib) + { + if (rib->tag != tag) + continue; + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER); + first = 0; + } + vty_show_ip_route (vty, rn, rib, NULL); + } return CMD_SUCCESS; } - -DEFUN (show_ip_route_vrf_all_addr, - show_ip_route_vrf_all_addr_cmd, - "show ip route " VRF_ALL_CMD_STR " A.B.C.D", + +DEFUN (show_ip_route_prefix_longer, + show_ip_route_prefix_longer_cmd, + "show ip route [vrf NAME] A.B.C.D/M longer-prefixes", SHOW_STR IP_STR "IP routing table\n" @@@ -1862,642 -3853,826 +1914,657 @@@ vty_show_ip_route_summary_prefix (struc } } - if (add_cmd) - static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, - ifindex, ifname, flag, tag, distance, zvrf, &snh_label); - else - static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, - ifindex, tag, distance, zvrf, &snh_label); - - return CMD_SUCCESS; -} - -DEFUN (ipv6_route, - ipv6_route_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, NULL); -} - -DEFUN (ipv6_route_tag, - ipv6_route_tag_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, NULL); + vty_out (vty, "------%s", VTY_NEWLINE); + vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL], + fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE); + vty_out (vty, "%s", VTY_NEWLINE); } -DEFUN (ipv6_route_flags, - ipv6_route_flags_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)", +/* Show route summary. */ +DEFUN (show_ip_route_summary, + show_ip_route_summary_cmd, + "show ip route [vrf NAME] summary", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") + "IP routing table\n" + VRF_CMD_HELP_STR + "Summary of all routes\n") { - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL, NULL, NULL); -} + struct route_table *table; + vrf_id_t vrf_id = VRF_DEFAULT; -DEFUN (ipv6_route_flags_tag, - ipv6_route_flags_tag_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL, NULL, NULL); -} + if (strmatch(argv[3]->text, "vrf")) + VRF_GET_ID (vrf_id, argv[4]->arg); -DEFUN (ipv6_route_ifname, - ipv6_route_ifname_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, NULL); -} -DEFUN (ipv6_route_ifname_tag, - ipv6_route_ifname_tag_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, NULL); -} + table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); + if (! table) + return CMD_SUCCESS; -DEFUN (ipv6_route_ifname_flags, - ipv6_route_ifname_flags_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL, NULL, NULL); -} + vty_show_ip_route_summary (vty, table); -DEFUN (ipv6_route_ifname_flags_tag, - ipv6_route_ifname_flags_tag_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, NULL, NULL); + return CMD_SUCCESS; } -DEFUN (ipv6_route_pref, - ipv6_route_pref_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, NULL); -} -DEFUN (ipv6_route_pref_tag, - ipv6_route_pref_tag_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255>", +/* Show route summary prefix. */ +DEFUN (show_ip_route_summary_prefix, + show_ip_route_summary_prefix_cmd, + "show ip route [vrf NAME] summary prefix", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n") + "IP routing table\n" + VRF_CMD_HELP_STR + "Summary of all routes\n" + "Prefix routes\n") { - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, NULL); -} + struct route_table *table; + vrf_id_t vrf_id = VRF_DEFAULT; -DEFUN (ipv6_route_flags_pref, - ipv6_route_flags_pref_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, argv[3], NULL, NULL); -} + if (strmatch(argv[3]->text, "vrf")) + VRF_GET_ID (vrf_id, argv[4]->arg); -DEFUN (ipv6_route_flags_pref_tag, - ipv6_route_flags_pref_tag_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], NULL, NULL); -} + table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); + if (! table) + return CMD_SUCCESS; -DEFUN (ipv6_route_ifname_pref, - ipv6_route_ifname_pref_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, NULL); -} + vty_show_ip_route_summary_prefix (vty, table); -DEFUN (ipv6_route_ifname_pref_tag, - ipv6_route_ifname_pref_tag_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, NULL); + return CMD_SUCCESS; } -DEFUN (ipv6_route_ifname_flags_pref, - ipv6_route_ifname_flags_pref_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>", - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], NULL, NULL); -} -DEFUN (ipv6_route_ifname_flags_pref_tag, - ipv6_route_ifname_flags_pref_tag_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255>", +DEFUN (show_ip_route_vrf_all, + show_ip_route_vrf_all_cmd, + "show ip route vrf all", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n") + "IP routing table\n" + VRF_ALL_CMD_HELP_STR) { - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], NULL, NULL); -} + struct route_table *table; + struct route_node *rn; + struct rib *rib; + struct zebra_vrf *zvrf; + vrf_iter_t iter; + int first = 1; + int vrf_header = 1; -DEFUN (no_ipv6_route, - no_ipv6_route_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, NULL, NULL); -} + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + { + if ((zvrf = vrf_iter2info (iter)) == NULL || + (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) + continue; -DEFUN (no_ipv6_route_tag, - no_ipv6_route_tag_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295>", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, NULL, NULL); -} + /* Show all IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + RNODE_FOREACH_RIB (rn, rib) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER); + first = 0; + } -DEFUN (no_ipv6_route_flags, - no_ipv6_route_flags_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole)", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, NULL, NULL, NULL); + if (vrf_header) + { + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vrf_header = 0; + } + vty_show_ip_route (vty, rn, rib, NULL); + } + vrf_header = 1; + } + + return CMD_SUCCESS; } -DEFUN (no_ipv6_route_flags_tag, - no_ipv6_route_flags_tag_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295>", - NO_STR +DEFUN (show_ip_route_vrf_all_tag, + show_ip_route_vrf_all_tag_cmd, - "show ip route vrf all tag (1-65535)", ++ "show ip route vrf all tag (1-4294967295)", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" + "IP routing table\n" + VRF_ALL_CMD_HELP_STR + "Show only routes with tag\n" "Tag value\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], NULL, NULL, NULL); -} + int idx_number = 6; + struct route_table *table; + struct route_node *rn; + struct rib *rib; + struct zebra_vrf *zvrf; + vrf_iter_t iter; + int first = 1; + int vrf_header = 1; - u_short tag = 0; ++ route_tag_t tag = 0; -DEFUN (no_ipv6_route_ifname, - no_ipv6_route_ifname_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, NULL, NULL); -} + if (argv[idx_number]->arg) - tag = atoi(argv[idx_number]->arg); ++ tag = atol(argv[idx_number]->arg); -DEFUN (no_ipv6_route_ifname_tag, - no_ipv6_route_ifname_tag_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295>", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, NULL, NULL); -} + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + { + if ((zvrf = vrf_iter2info (iter)) == NULL || + (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) + continue; -DEFUN (no_ipv6_route_ifname_flags, - no_ipv6_route_ifname_flags_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole)", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, NULL, NULL, NULL); -} + /* Show all IPv4 routes with matching tag value. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + RNODE_FOREACH_RIB (rn, rib) + { + if (rib->tag != tag) + continue; -DEFUN (no_ipv6_route_ifname_flags_tag, - no_ipv6_route_ifname_flags_tag_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295>", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, NULL, NULL); -} + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER); + first = 0; + } -DEFUN (no_ipv6_route_pref, - no_ipv6_route_pref_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, argv[2], NULL, NULL); + if (vrf_header) + { + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vrf_header = 0; + } + vty_show_ip_route (vty, rn, rib, NULL); + } + vrf_header = 1; + } + return CMD_SUCCESS; } -DEFUN (no_ipv6_route_pref_tag, - no_ipv6_route_pref_tag_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255>", - NO_STR +DEFUN (show_ip_route_vrf_all_prefix_longer, + show_ip_route_vrf_all_prefix_longer_cmd, + "show ip route vrf all A.B.C.D/M longer-prefixes", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n") + "IP routing table\n" + VRF_ALL_CMD_HELP_STR + "IP prefix /, e.g., 35.0.0.0/8\n" + "Show route matching the specified Network/Mask pair only\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], argv[3], NULL, NULL); -} + int idx_ipv4_prefixlen = 5; + struct route_table *table; + struct route_node *rn; + struct rib *rib; + struct prefix p; + struct zebra_vrf *zvrf; + vrf_iter_t iter; + int ret; + int first = 1; + int vrf_header = 1; -DEFUN (no_ipv6_route_flags_pref, - no_ipv6_route_flags_pref_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this prefix\n") -{ - /* We do not care about argv[2] */ - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, argv[3], NULL, NULL); -} + ret = str2prefix (argv[idx_ipv4_prefixlen]->arg, &p); + if (! ret) + { + vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); + return CMD_WARNING; + } -DEFUN (no_ipv6_route_flags_pref_tag, - no_ipv6_route_flags_pref_tag_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n") -{ - /* We do not care about argv[2] */ - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], NULL, NULL); -} + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + { + if ((zvrf = vrf_iter2info (iter)) == NULL || + (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) + continue; -DEFUN (no_ipv6_route_ifname_pref, - no_ipv6_route_ifname_pref_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], NULL, NULL); -} + /* Show matched type IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + RNODE_FOREACH_RIB (rn, rib) + if (prefix_match (&p, &rn->p)) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER); + first = 0; + } -DEFUN (no_ipv6_route_ifname_pref_tag, - no_ipv6_route_ifname_pref_tag_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], NULL, NULL); -} + if (vrf_header) + { + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vrf_header = 0; + } + vty_show_ip_route (vty, rn, rib, NULL); + } + vrf_header = 1; + } -DEFUN (no_ipv6_route_ifname_flags_pref, - no_ipv6_route_ifname_flags_pref_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255>", - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this prefix\n") -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], NULL, NULL); + return CMD_SUCCESS; } -DEFUN (no_ipv6_route_ifname_flags_pref_tag, - no_ipv6_route_ifname_flags_pref_tag_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255>", - NO_STR +DEFUN (show_ip_route_vrf_all_supernets, + show_ip_route_vrf_all_supernets_cmd, + "show ip route vrf all supernets-only", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n") + "IP routing table\n" + VRF_ALL_CMD_HELP_STR + "Show supernet entries only\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], NULL, NULL); -} + struct route_table *table; + struct route_node *rn; + struct rib *rib; + struct zebra_vrf *zvrf; + vrf_iter_t iter; + u_int32_t addr; + int first = 1; + int vrf_header = 1; + + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + { + if ((zvrf = vrf_iter2info (iter)) == NULL || + (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) + continue; + + /* Show matched type IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + RNODE_FOREACH_RIB (rn, rib) + { + addr = ntohl (rn->p.u.prefix4.s_addr); + + if ((IN_CLASSC (addr) && rn->p.prefixlen < 24) + || (IN_CLASSB (addr) && rn->p.prefixlen < 16) + || (IN_CLASSA (addr) && rn->p.prefixlen < 8)) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER); + first = 0; + } - + if (vrf_header) + { + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vrf_header = 0; + } + vty_show_ip_route (vty, rn, rib, NULL); + } + } + vrf_header = 1; + } -DEFUN (ipv6_route_vrf, - ipv6_route_vrf_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, NULL, argv[2], NULL); + return CMD_SUCCESS; } -DEFUN (ipv6_route_tag_vrf, - ipv6_route_tag_vrf_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> " VRF_CMD_STR, +DEFUN (show_ip_route_vrf_all_protocol, + show_ip_route_vrf_all_protocol_cmd, + "show ip route vrf all ", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) + "IP routing table\n" + VRF_ALL_CMD_HELP_STR + QUAGGA_IP_REDIST_HELP_STR_ZEBRA"\n") { - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], NULL, argv[3], NULL); -} + int type; + struct route_table *table; + struct route_node *rn; + struct rib *rib; + struct zebra_vrf *zvrf; + vrf_iter_t iter; + int first = 1; + int vrf_header = 1; -DEFUN (ipv6_route_flags_vrf, - ipv6_route_flags_vrf_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL, argv[3], NULL); -} + type = proto_redistnum (AFI_IP, argv[6]->arg); + if (type < 0) + { + vty_out (vty, "Unknown route type%s", VTY_NEWLINE); + return CMD_WARNING; + } -DEFUN (ipv6_route_flags_tag_vrf, - ipv6_route_flags_tag_vrf_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL, argv[4], NULL); -} + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + { + if ((zvrf = vrf_iter2info (iter)) == NULL || + (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) + continue; -DEFUN (ipv6_route_ifname_vrf, - ipv6_route_ifname_vrf_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3], NULL); -} -DEFUN (ipv6_route_ifname_tag_vrf, - ipv6_route_ifname_tag_vrf_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4], NULL); -} + /* Show matched type IPv4 routes. */ + for (rn = route_top (table); rn; rn = route_next (rn)) + RNODE_FOREACH_RIB (rn, rib) + if (rib->type == type) + { + if (first) + { + vty_out (vty, SHOW_ROUTE_V4_HEADER); + first = 0; + } -DEFUN (ipv6_route_ifname_flags_vrf, - ipv6_route_ifname_flags_vrf_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL, argv[4], NULL); -} + if (vrf_header) + { + vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf->name, VTY_NEWLINE); + vrf_header = 0; + } + vty_show_ip_route (vty, rn, rib, NULL); + } + vrf_header = 1; + } -DEFUN (ipv6_route_ifname_flags_tag_vrf, - ipv6_route_ifname_flags_tag_vrf_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, argv[5], NULL); + return CMD_SUCCESS; } -DEFUN (ipv6_route_pref_vrf, - ipv6_route_pref_vrf_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> " VRF_CMD_STR, +DEFUN (show_ip_route_vrf_all_addr, + show_ip_route_vrf_all_addr_cmd, + "show ip route vrf all A.B.C.D", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR) + "IP routing table\n" + VRF_ALL_CMD_HELP_STR + "Network in the IP routing table to display\n") { - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL, argv[2], argv[3], NULL); -} + int idx_ipv4 = 5; + int ret; + struct prefix_ipv4 p; + struct route_table *table; + struct route_node *rn; + struct zebra_vrf *zvrf; + vrf_iter_t iter; -DEFUN (ipv6_route_pref_tag_vrf, - ipv6_route_pref_tag_vrf_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2], argv[3], argv[4], NULL); -} + ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p); + if (ret <= 0) + { + vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); + return CMD_WARNING; + } -DEFUN (ipv6_route_flags_pref_vrf, - ipv6_route_flags_pref_vrf_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4], NULL); -} + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + { + if ((zvrf = vrf_iter2info (iter)) == NULL || + (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) + continue; -DEFUN (ipv6_route_flags_pref_tag_vrf, - ipv6_route_flags_pref_tag_vrf_cmd, - "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5], NULL); -} + rn = route_node_match (table, (struct prefix *) &p); + if (! rn) + continue; -DEFUN (ipv6_route_ifname_pref_vrf, - ipv6_route_ifname_pref_vrf_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4], NULL); + vty_show_ip_route_detail (vty, rn, 0); + + route_unlock_node (rn); + } + + return CMD_SUCCESS; } -DEFUN (ipv6_route_ifname_pref_tag_vrf, - ipv6_route_ifname_pref_tag_vrf_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> " VRF_CMD_STR, +DEFUN (show_ip_route_vrf_all_prefix, + show_ip_route_vrf_all_prefix_cmd, + "show ip route vrf all A.B.C.D/M", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR) + "IP routing table\n" + VRF_ALL_CMD_HELP_STR + "IP prefix /, e.g., 35.0.0.0/8\n") { - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5], NULL); -} + int idx_ipv4_prefixlen = 5; + int ret; + struct prefix_ipv4 p; + struct route_table *table; + struct route_node *rn; + struct zebra_vrf *zvrf; + vrf_iter_t iter; + + ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p); + if (ret <= 0) + { + vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); + return CMD_WARNING; + } + + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + { + if ((zvrf = vrf_iter2info (iter)) == NULL || + (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) + continue; + + rn = route_node_match (table, (struct prefix *) &p); + if (! rn) + continue; + if (rn->p.prefixlen != p.prefixlen) + { + route_unlock_node (rn); + continue; + } + + vty_show_ip_route_detail (vty, rn, 0); + + route_unlock_node (rn); + } -DEFUN (ipv6_route_ifname_flags_pref_vrf, - ipv6_route_ifname_flags_pref_vrf_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255> " VRF_CMD_STR, - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5], NULL); + return CMD_SUCCESS; } -DEFUN (ipv6_route_ifname_flags_pref_tag_vrf, - ipv6_route_ifname_flags_pref_tag_vrf_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, +DEFUN (show_ip_route_vrf_all_summary, + show_ip_route_vrf_all_summary_cmd, + "show ip route vrf all summary ", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR) + "IP routing table\n" + VRF_ALL_CMD_HELP_STR + "Summary of all routes\n") { - return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL); -} + struct zebra_vrf *zvrf; + vrf_iter_t iter; -DEFUN (no_ipv6_route_vrf, - no_ipv6_route_vrf_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL, argv[2], NULL); + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + if ((zvrf = vrf_iter2info (iter)) != NULL) + vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); + + return CMD_SUCCESS; } -DEFUN (no_ipv6_route_tag_vrf, - no_ipv6_route_tag_vrf_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> " VRF_CMD_STR, - NO_STR +DEFUN (show_ip_route_vrf_all_summary_prefix, + show_ip_route_vrf_all_summary_prefix_cmd, + "show ip route vrf all summary prefix", + SHOW_STR IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) + "IP routing table\n" + VRF_ALL_CMD_HELP_STR + "Summary of all routes\n" + "Prefix routes\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], NULL, argv[3], NULL); + struct zebra_vrf *zvrf; + vrf_iter_t iter; + + for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) + if ((zvrf = vrf_iter2info (iter)) != NULL) + vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); + + return CMD_SUCCESS; } -DEFUN (no_ipv6_route_flags_vrf, - no_ipv6_route_flags_vrf_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) +/* Write IPv4 static route configuration. */ +static int +static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, NULL, argv[3], NULL); + struct route_node *rn; + struct static_route *si; + struct route_table *stable; + struct zebra_vrf *zvrf; + char buf[PREFIX_STRLEN]; + int write =0; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO (zvrf_list, node, zvrf)) + { + if ((stable = zvrf->stable[AFI_IP][safi]) == NULL) + continue; + + for (rn = route_top (stable); rn; rn = route_next (rn)) + for (si = rn->info; si; si = si->next) + { + vty_out (vty, "%s %s", cmd, prefix2str (&rn->p, buf, sizeof buf)); + + switch (si->type) + { + case STATIC_IPV4_GATEWAY: + vty_out (vty, " %s", inet_ntoa (si->addr.ipv4)); + break; + case STATIC_IFINDEX: + vty_out (vty, " %s", si->ifname); + break; + case STATIC_IPV4_BLACKHOLE: + vty_out (vty, " Null0"); + break; + } + + /* flags are incompatible with STATIC_IPV4_BLACKHOLE */ + if (si->type != STATIC_IPV4_BLACKHOLE) + { + if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT)) + vty_out (vty, " %s", "reject"); + + if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE)) + vty_out (vty, " %s", "blackhole"); + } + + if (si->tag) + vty_out (vty, " tag %d", si->tag); + + if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT) + vty_out (vty, " %d", si->distance); + + if (si->vrf_id != VRF_DEFAULT) + vty_out (vty, " vrf %s", zvrf ? zvrf->name : ""); + + vty_out (vty, "%s", VTY_NEWLINE); + + write = 1; + } + } + return write; } -DEFUN (no_ipv6_route_flags_tag_vrf, - no_ipv6_route_flags_tag_vrf_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Set tag for this route\n" - "Tag value\n" - VRF_CMD_HELP_STR) +/* General fucntion for IPv6 static route. */ - static int ++int +static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, - const char *gate_str, const char *ifname, - const char *flag_str, const char *tag_str, - const char *distance_str, const char *vrf_id_str) ++ const char *gate_str, const char *ifname, ++ const char *flag_str, const char *tag_str, ++ const char *distance_str, const char *vrf_id_str, ++ const char *label_str) { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], NULL, argv[4], NULL); -} + int ret; + u_char distance; + struct prefix p; + struct in6_addr *gate = NULL; + struct in6_addr gate_addr; + u_char type = 0; + u_char flag = 0; - u_short tag = 0; ++ route_tag_t tag = 0; + unsigned int ifindex = 0; + struct interface *ifp = NULL; + struct zebra_vrf *zvrf; - ++ struct static_nh_label snh_label; ++ + ret = str2prefix (dest_str, &p); + if (ret <= 0) + { + vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); + return CMD_WARNING; + } + + /* Apply mask for given prefix. */ + apply_mask (&p); + + /* Route flags */ + if (flag_str) { + switch(flag_str[0]) { + case 'r': + case 'R': /* XXX */ + SET_FLAG (flag, ZEBRA_FLAG_REJECT); + break; + case 'b': + case 'B': /* XXX */ + SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE); + break; + default: + vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE); + return CMD_WARNING; + } + } + + /* Administrative distance. */ + if (distance_str) + distance = atoi (distance_str); + else + distance = ZEBRA_STATIC_DISTANCE_DEFAULT; + + /* tag */ + if (tag_str) - tag = atoi(tag_str); ++ tag = atol(tag_str); + + /* When gateway is valid IPv6 addrees, then gate is treated as + nexthop address other case gate is treated as interface name. */ + ret = inet_pton (AF_INET6, gate_str, &gate_addr); + + /* VRF id */ + zvrf = zebra_vrf_list_lookup_by_name (vrf_id_str); + + if (!zvrf) + { + vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE); + return CMD_WARNING; + } + ++ /* Labels */ ++ memset (&snh_label, 0, sizeof (struct static_nh_label)); ++ if (label_str) ++ { ++ if (mpls_str2label (label_str, &snh_label.num_labels, ++ snh_label.label)) ++ { ++ vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE); ++ return CMD_WARNING; ++ } ++ } ++ + if (ifname) + { + /* When ifname is specified. It must be come with gateway + address. */ + if (ret != 1) - { - vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); - return CMD_WARNING; - } ++ { ++ vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); ++ return CMD_WARNING; ++ } + type = STATIC_IPV6_GATEWAY_IFINDEX; + gate = &gate_addr; + ifp = if_lookup_by_name_vrf (ifname, zvrf->vrf_id); + if (!ifp) - { - vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE); - return CMD_WARNING; - } ++ { ++ vty_out (vty, "%% Malformed Interface name %s%s", ifname, VTY_NEWLINE); ++ return CMD_WARNING; ++ } + ifindex = ifp->ifindex; + } + else + { + if (ret == 1) - { - type = STATIC_IPV6_GATEWAY; - gate = &gate_addr; - } ++ { ++ type = STATIC_IPV6_GATEWAY; ++ gate = &gate_addr; ++ } + else - { - type = STATIC_IFINDEX; - ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id); - if (!ifp) - { - vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE); ++ { ++ type = STATIC_IFINDEX; ++ ifp = if_lookup_by_name_vrf (gate_str, zvrf->vrf_id); ++ if (!ifp) ++ { ++ vty_out (vty, "%% Malformed Interface name %s%s", gate_str, VTY_NEWLINE); + ifindex = IFINDEX_DELETED; - } ++ } + else - ifindex = ifp->ifindex; - ifname = gate_str; - } ++ ifindex = ifp->ifindex; ++ ifname = gate_str; ++ } + } + + if (add_cmd) - static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, ifindex, ifname, flag, tag, distance, zvrf); ++ static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, ++ ifindex, ifname, flag, tag, distance, zvrf, &snh_label); + else - static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, ifindex, tag, distance, zvrf); ++ static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, (union g_addr *)gate, ++ ifindex, tag, distance, zvrf, &snh_label); -DEFUN (no_ipv6_route_ifname_vrf, - no_ipv6_route_ifname_vrf_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL, argv[3], NULL); + return CMD_SUCCESS; } -DEFUN (no_ipv6_route_ifname_tag_vrf, - no_ipv6_route_ifname_tag_vrf_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> " VRF_CMD_STR, - NO_STR +DEFUN (ipv6_route, + ipv6_route_cmd, - "ipv6 route X:X::X:X/M [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "ipv6 route X:X::X:X/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" @@@ -2505,28 -4680,31 +2572,29 @@@ "IPv6 gateway interface name\n" "Set tag for this route\n" "Tag value\n" - VRF_CMD_HELP_STR) + "Distance value for this prefix\n" - VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4], NULL); -} + int idx_ipv6_prefixlen = 2; + int idx_ipv6_ifname = 3; + int idx_curr = 4; + char *tag, *distance, *vrf; -DEFUN (no_ipv6_route_ifname_flags_vrf, - no_ipv6_route_ifname_flags_vrf_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, NULL, argv[4], NULL); + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return static_ipv6_func (vty, 1, + argv[idx_ipv6_prefixlen]->arg, + argv[idx_ipv6_ifname]->arg, + NULL, NULL, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } - -DEFUN (no_ipv6_route_ifname_flags_tag_vrf, - no_ipv6_route_ifname_flags_tag_vrf_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> " VRF_CMD_STR, - NO_STR +DEFUN (ipv6_route_flags, + ipv6_route_flags_cmd, - "ipv6 route X:X::X:X/M [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "ipv6 route X:X::X:X/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" @@@ -2534,32 -4712,32 +2602,34 @@@ "IPv6 gateway interface name\n" "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n" + "Silently discard pkts when matched\n" "Set tag for this route\n" "Tag value\n" - VRF_CMD_HELP_STR) -{ - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], NULL, argv[5], NULL); -} - -DEFUN (no_ipv6_route_pref_vrf, - no_ipv6_route_pref_vrf_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" "Distance value for this prefix\n" -- VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL, argv[2], argv[3], NULL); + int idx_ipv6_prefixlen = 2; + int idx_ipv6_ifname = 3; + int idx_reject_blackhole = 4; + int idx_curr = 5; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return static_ipv6_func (vty, 1, + argv[idx_ipv6_prefixlen]->arg, + argv[idx_ipv6_ifname]->arg, + NULL, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (no_ipv6_route_pref_tag_vrf, - no_ipv6_route_pref_tag_vrf_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) tag <1-4294967295> <1-255> " VRF_CMD_STR, - NO_STR +DEFUN (ipv6_route_ifname, + ipv6_route_ifname_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" @@@ -2568,28 -4746,33 +2638,30 @@@ "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" -- VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2], argv[3], argv[4], NULL); -} + int idx_ipv6_prefixlen = 2; + int idx_ipv6 = 3; + int idx_interface = 4; + int idx_curr = 5; + char *tag, *distance, *vrf; -DEFUN (no_ipv6_route_flags_pref_vrf, - no_ipv6_route_flags_pref_vrf_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) <1-255> " VRF_CMD_STR, - NO_STR - IP_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR) -{ - /* We do not care about argv[2] */ - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], NULL, argv[3], argv[4], NULL); + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return static_ipv6_func (vty, 1, + argv[idx_ipv6_prefixlen]->arg, + argv[idx_ipv6]->arg, + argv[idx_interface]->arg, + NULL, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (no_ipv6_route_flags_pref_tag_vrf, - no_ipv6_route_flags_pref_tag_vrf_cmd, - "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, - NO_STR +DEFUN (ipv6_route_ifname_flags, + ipv6_route_ifname_flags_cmd, - "ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]", IP_STR "Establish static routes\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" @@@ -2600,58 -4783,30 +2672,62 @@@ "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" -- VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - /* We do not care about argv[2] */ - return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], argv[4], argv[5], NULL); + int idx_ipv6_prefixlen = 2; + int idx_ipv6 = 3; + int idx_interface = 4; + int idx_reject_blackhole = 5; + int idx_curr = 6; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return static_ipv6_func (vty, 1, + argv[idx_ipv6_prefixlen]->arg, + argv[idx_ipv6]->arg, + argv[idx_interface]->arg, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (no_ipv6_route_ifname_pref_vrf, - no_ipv6_route_ifname_pref_vrf_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> " VRF_CMD_STR, +DEFUN (no_ipv6_route, + no_ipv6_route_cmd, - "no ipv6 route X:X::X:X/M [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ipv6 route X:X::X:X/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", NO_STR IP_STR "Establish static routes\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 gateway address\n" "IPv6 gateway interface name\n" + "Set tag for this route\n" + "Tag value\n" "Distance value for this prefix\n" -- VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, argv[3], argv[4], NULL); + int idx_ipv6_prefixlen = 3; + int idx_ipv6_ifname = 4; + int idx_curr = 5; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return static_ipv6_func (vty, 0, + argv[idx_ipv6_prefixlen]->arg, + argv[idx_ipv6_ifname]->arg, + NULL, NULL, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (no_ipv6_route_ifname_pref_tag_vrf, - no_ipv6_route_ifname_pref_tag_vrf_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE tag <1-4294967295> <1-255> " VRF_CMD_STR, +DEFUN (no_ipv6_route_flags, + no_ipv6_route_flags_cmd, - "no ipv6 route X:X::X:X/M [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ipv6 route X:X::X:X/M [tag (1-4294967295)] [(1-255)] [vrf NAME]", NO_STR IP_STR "Establish static routes\n" @@@ -2663,59 -4816,31 +2739,63 @@@ "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" -- VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], argv[4], argv[5], NULL); + int idx_ipv6_prefixlen = 3; + int idx_ipv6_ifname = 4; + int idx_reject_blackhole = 5; + int idx_curr = 5; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return static_ipv6_func (vty, 0, + argv[idx_ipv6_prefixlen]->arg, + argv[idx_ipv6_ifname]->arg, + NULL, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (no_ipv6_route_ifname_flags_pref_vrf, - no_ipv6_route_ifname_flags_pref_vrf_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) <1-255> " VRF_CMD_STR, +DEFUN (no_ipv6_route_ifname, + no_ipv6_route_ifname_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]", NO_STR IP_STR "Establish static routes\n" "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" "IPv6 gateway address\n" "IPv6 gateway interface name\n" - "Emit an ICMP unreachable when matched\n" - "Silently discard pkts when matched\n" + "Set tag for this route\n" + "Tag value\n" "Distance value for this prefix\n" -- VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], NULL, argv[4], argv[5], NULL); + int idx_ipv6_prefixlen = 3; + int idx_ipv6 = 4; + int idx_interface = 5; + int idx_curr = 6; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return static_ipv6_func (vty, 0, + argv[idx_ipv6_prefixlen]->arg, + argv[idx_ipv6]->arg, + argv[idx_interface]->arg, + NULL, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } -DEFUN (no_ipv6_route_ifname_flags_pref_tag_vrf, - no_ipv6_route_ifname_flags_pref_tag_vrf_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE (reject|blackhole) tag <1-4294967295> <1-255> " VRF_CMD_STR, +DEFUN (no_ipv6_route_ifname_flags, + no_ipv6_route_ifname_flags_cmd, - "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-65535)] [(1-255)] [vrf NAME]", ++ "no ipv6 route X:X::X:X/M X:X::X:X INTERFACE [tag (1-4294967295)] [(1-255)] [vrf NAME]", NO_STR IP_STR "Establish static routes\n" @@@ -2727,24 -4852,9 +2807,26 @@@ "Set tag for this route\n" "Tag value\n" "Distance value for this prefix\n" -- VRF_CMD_HELP_STR) ++ VRF_CMD_HELP_STR ++ "Specify labels for this route\n" ++ "One or more labels separated by '/'\n") { - return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL); + int idx_ipv6_prefixlen = 3; + int idx_ipv6 = 4; + int idx_interface = 5; + int idx_reject_blackhole = 6; + int idx_curr = 7; + char *tag, *distance, *vrf; + + tag = distance = vrf = NULL; - zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf); ++ zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); + + return static_ipv6_func (vty, 0, + argv[idx_ipv6_prefixlen]->arg, + argv[idx_ipv6]->arg, + argv[idx_interface]->arg, + argv[idx_reject_blackhole]->arg, - tag, distance, vrf); ++ tag, distance, vrf, NULL); } DEFUN (show_ipv6_route, @@@ -2846,9 -4951,17 +2928,9 @@@ return CMD_SUCCESS; } -ALIAS (show_ipv6_route, - show_ipv6_route_vrf_cmd, - "show ipv6 route " VRF_CMD_STR " {json}", - SHOW_STR - IP_STR - "IPv6 routing table\n" - VRF_CMD_HELP_STR) - DEFUN (show_ipv6_route_tag, show_ipv6_route_tag_cmd, - "show ipv6 route [vrf NAME] tag (1-65535)", - "show ipv6 route tag <1-4294967295>", ++ "show ipv6 route [vrf NAME] tag (1-4294967295)", SHOW_STR IP_STR "IPv6 routing table\n" @@@ -2863,19 -4972,16 +2945,19 @@@ struct route_node *rn; struct rib *rib; int first = 1; - u_short tag = 0; + route_tag_t tag = 0; vrf_id_t vrf_id = VRF_DEFAULT; - if (argc > 1) + if (strmatch(argv[idx_vrf]->text, "vrf")) { - VRF_GET_ID (vrf_id, argv[0]); - tag = atol(argv[1]); + VRF_GET_ID (vrf_id, argv[idx_name]->arg); - tag = atoi(argv[idx_tag]->arg); ++ tag = atol(argv[idx_tag]->arg); } else - tag = atol(argv[0]); + { + idx_tag -= 2; - tag = atoi(argv[idx_tag]->arg); ++ tag = atol(argv[idx_tag]->arg); + } table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); if (! table) @@@ -3240,7 -5403,7 +3322,7 @@@ DEFUN (show_ipv6_route_vrf_all DEFUN (show_ipv6_route_vrf_all_tag, show_ipv6_route_vrf_all_tag_cmd, - "show ipv6 route vrf all tag (1-65535)", - "show ipv6 route " VRF_ALL_CMD_STR " tag <1-4294967295>", ++ "show ipv6 route vrf all tag (1-4294967295)", SHOW_STR IP_STR "IPv6 routing table\n" @@@ -3256,10 -5418,10 +3338,10 @@@ vrf_iter_t iter; int first = 1; int vrf_header = 1; - u_short tag = 0; + route_tag_t tag = 0; - if (argv[0]) - tag = atol(argv[0]); + if (argv[idx_number]->arg) - tag = atoi(argv[idx_number]->arg); ++ tag = atol(argv[idx_number]->arg); for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter)) { @@@ -3857,12 -6122,64 +3929,11 @@@ zebra_vty_init (void /* Commands for VRF */ - install_element (CONFIG_NODE, &ip_route_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_tag_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_flags_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_flags_tag_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_flags2_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_flags2_tag_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_tag_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_flags_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_flags_tag_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_flags2_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_flags2_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_flags_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_flags_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_flags2_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_flags2_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_flags_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_flags2_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_flags2_tag_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_distance_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_tag_distance_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_flags_distance_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_flags_tag_distance_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_flags_distance2_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_flags_tag_distance2_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_distance_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_tag_distance_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_flags_distance_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_flags_tag_distance_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_flags_distance2_vrf_cmd); - install_element (CONFIG_NODE, &ip_route_mask_flags_tag_distance2_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_distance_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_tag_distance_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_flags_distance_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_flags_tag_distance_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_flags_distance2_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_flags_tag_distance2_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_distance_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_tag_distance_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_vrf_cmd); - install_element (CONFIG_NODE, &no_ip_route_mask_flags_tag_distance2_vrf_cmd); + install_element (CONFIG_NODE, &no_ip_route_flags_cmd); + install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd); install_element (VIEW_NODE, &show_ip_route_vrf_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_cmd); - install_element (VIEW_NODE, &show_ip_route_vrf_addr_cmd); - install_element (VIEW_NODE, &show_ip_route_vrf_tag_cmd); - install_element (VIEW_NODE, &show_ip_route_vrf_prefix_cmd); - install_element (VIEW_NODE, &show_ip_route_vrf_prefix_longer_cmd); - install_element (VIEW_NODE, &show_ip_route_vrf_protocol_cmd); - install_element (VIEW_NODE, &show_ip_route_vrf_supernets_cmd); - install_element (VIEW_NODE, &show_ip_route_vrf_summary_cmd); - install_element (VIEW_NODE, &show_ip_route_vrf_summary_prefix_cmd); ++ install_element (VIEW_NODE, &show_ip_route_vrf_cmd); install_element (VIEW_NODE, &show_ip_route_vrf_all_cmd); install_element (VIEW_NODE, &show_ip_route_vrf_all_tag_cmd); @@@ -3873,16 -6190,8 +3944,7 @@@ install_element (VIEW_NODE, &show_ip_route_vrf_all_supernets_cmd); install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_cmd); install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_all_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_all_tag_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_all_addr_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_all_prefix_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_all_prefix_longer_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_all_protocol_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_all_supernets_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_all_summary_cmd); - install_element (ENABLE_NODE, &show_ip_route_vrf_all_summary_prefix_cmd); -#ifdef HAVE_IPV6 install_element (CONFIG_NODE, &ipv6_route_cmd); install_element (CONFIG_NODE, &ipv6_route_flags_cmd); install_element (CONFIG_NODE, &ipv6_route_ifname_cmd); @@@ -3903,19 -6236,54 +3965,10 @@@ install_element (VIEW_NODE, &show_ipv6_route_addr_cmd); install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd); install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_tag_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_protocol_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_addr_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_prefix_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_prefix_longer_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_summary_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_summary_prefix_cmd); install_element (VIEW_NODE, &show_ipv6_mroute_cmd); - install_element (ENABLE_NODE, &show_ipv6_mroute_cmd); /* Commands for VRF */ - - install_element (CONFIG_NODE, &ipv6_route_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_flags_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_ifname_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_ifname_flags_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_flags_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_ifname_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_pref_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_flags_pref_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_ifname_pref_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_pref_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_tag_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_flags_tag_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_ifname_tag_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_ifname_flags_tag_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_pref_tag_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_flags_pref_tag_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_ifname_pref_tag_vrf_cmd); - install_element (CONFIG_NODE, &ipv6_route_ifname_flags_pref_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_flags_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_ifname_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_pref_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_flags_pref_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_tag_vrf_cmd); - install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_pref_tag_vrf_cmd); - - - install_element (VIEW_NODE, &show_ipv6_route_vrf_cmd); - install_element (VIEW_NODE, &show_ipv6_route_vrf_tag_cmd); - install_element (VIEW_NODE, &show_ipv6_route_vrf_summary_cmd); - install_element (VIEW_NODE, &show_ipv6_route_vrf_summary_prefix_cmd); - install_element (VIEW_NODE, &show_ipv6_route_vrf_protocol_cmd); - install_element (VIEW_NODE, &show_ipv6_route_vrf_addr_cmd); - install_element (VIEW_NODE, &show_ipv6_route_vrf_prefix_cmd); - install_element (VIEW_NODE, &show_ipv6_route_vrf_prefix_longer_cmd); - install_element (VIEW_NODE, &show_ipv6_route_vrf_all_cmd); install_element (VIEW_NODE, &show_ipv6_route_vrf_all_tag_cmd); install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd); @@@ -3924,15 -6292,9 +3977,6 @@@ install_element (VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd); install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd); install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_longer_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_tag_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_protocol_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_addr_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_prefix_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_prefix_longer_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_summary_cmd); - install_element (ENABLE_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd); - install_element (VIEW_NODE, &show_ipv6_mroute_vrf_cmd); - install_element (VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd); - install_element (ENABLE_NODE, &show_ipv6_mroute_vrf_all_cmd); -#endif /* HAVE_IPV6 */ } diff --cc zebra/zserv.c index 98908fb67e,da52f93a28..a0f46aadc9 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@@ -713,27 -714,30 +714,30 @@@ zsend_redistribute_route (int cmd, stru stream_putc (s, 1); stream_putl (s, nexthop->ifindex); + /* ldpd needs all nexthops */ + if (client->proto != ZEBRA_ROUTE_LDP) - break; + break; } } - /* Metric */ - if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD || cmd == ZEBRA_REDISTRIBUTE_IPV6_ADD) - { + /* Distance */ - SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE); - stream_putc (s, rib->distance); + SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE); + stream_putc (s, rib->distance); + + /* Metric */ - SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC); - stream_putl (s, rib->metric); + SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC); + stream_putl (s, rib->metric); - /* tag */ + /* Tag */ - if (rib->tag) - { - SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG); + if (rib->tag) + { + SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG); - stream_putw(s, rib->tag); + stream_putl(s, rib->tag); - } + } + + /* MTU */ - SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU); - stream_putl (s, rib->mtu); + SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU); + stream_putl (s, rib->mtu); - } /* write real message flags value */ stream_putc_at (s, messmark, zapi_flags);