diff options
82 files changed, 3740 insertions, 2931 deletions
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 132b754104..e35f9752f1 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -492,7 +492,7 @@ bgp_show_all_instances_nexthops_vty (struct vty *vty) DEFUN (show_ip_bgp_nexthop, show_ip_bgp_nexthop_cmd, - "show [ip] bgp [<view|vrf> WORD] nexthop [detail]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] nexthop [detail]", SHOW_STR IP_STR BGP_STR diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 31c1dd8c10..e7eb7b6d2f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3532,10 +3532,6 @@ bgp_cleanup_table(struct bgp_table *table, safi_t safi) && (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_info_reap (rn, ri); } @@ -8438,7 +8434,7 @@ bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom, DEFUN (show_ip_bgp_large_community_list, show_ip_bgp_large_community_list_cmd, - "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]", SHOW_STR IP_STR BGP_STR @@ -8484,7 +8480,7 @@ DEFUN (show_ip_bgp_large_community_list, } DEFUN (show_ip_bgp_large_community, show_ip_bgp_large_community_cmd, - "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community [AA:BB:CC] [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] large-community [AA:BB:CC] [json]", SHOW_STR IP_STR BGP_STR @@ -8535,7 +8531,7 @@ static int bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t /* BGP route print out function. */ DEFUN (show_ip_bgp, show_ip_bgp_cmd, - "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]\ + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]\ [<\ cidr-only\ |dampening <flap-statistics|dampened-paths|parameters>\ @@ -8656,7 +8652,7 @@ DEFUN (show_ip_bgp, DEFUN (show_ip_bgp_route, show_ip_bgp_route_cmd, - "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]" + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]" "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]", SHOW_STR IP_STR @@ -8725,7 +8721,7 @@ DEFUN (show_ip_bgp_route, DEFUN (show_ip_bgp_regexp, show_ip_bgp_regexp_cmd, - "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] regexp REGEX...", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] regexp REGEX...", SHOW_STR IP_STR BGP_STR @@ -9437,7 +9433,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_c DEFUN (show_ip_bgp_instance_neighbor_prefix_counts, show_ip_bgp_instance_neighbor_prefix_counts_cmd, - "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] " + "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] " "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]", SHOW_STR IP_STR @@ -9810,7 +9806,7 @@ peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, DEFUN (show_ip_bgp_instance_neighbor_advertised_route, show_ip_bgp_instance_neighbor_advertised_route_cmd, - "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] " + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] " "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]", SHOW_STR IP_STR @@ -9974,7 +9970,7 @@ bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi, DEFUN (show_ip_bgp_neighbor_routes, show_ip_bgp_neighbor_routes_cmd, - "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] " + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] " "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]", SHOW_STR IP_STR diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 6c6b622626..3cf0d84684 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -2151,13 +2151,18 @@ route_set_aggregator_as_compile (const char *arg) struct aggregator *aggregator; char as[10]; char address[20]; + int ret; aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator)); sscanf (arg, "%s %s", as, address); aggregator->as = strtoul (as, NULL, 10); - inet_aton (address, &aggregator->address); - + ret = inet_aton (address, &aggregator->address); + if (ret == 0) + { + XFREE (MTYPE_ROUTE_MAP_COMPILED, aggregator); + return NULL; + } return aggregator; } diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c index ff0cfdd658..642807e7ab 100644 --- a/bgpd/bgp_table.c +++ b/bgpd/bgp_table.c @@ -50,12 +50,6 @@ bgp_table_unlock (struct bgp_table *rt) route_table_finish (rt->route_table); rt->route_table = NULL; - if (rt->owner) - { - peer_unlock (rt->owner); - rt->owner = NULL; - } - XFREE (MTYPE_BGP_TABLE, rt); } diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h index cff270ebb9..7b22872628 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h @@ -31,9 +31,6 @@ struct bgp_table int lock; - /* The owner of this 'bgp_table' structure. */ - struct peer *owner; - struct route_table *route_table; uint64_t version; }; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f5f538de95..14e28673bb 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -275,11 +275,11 @@ argv_find_and_parse_safi (struct cmd_token **argv, int argc, int *index, safi_t * that is being parsed. * * The show commands are generally of the form: - * "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] ..." + * "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] ..." * * Since we use argv_find if the show command in particular doesn't have: * [ip] - * [<view|vrf> WORD] + * [<view|vrf> VIEWVRFNAME] * [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] * The command parsing should still be ok. * @@ -859,7 +859,7 @@ DEFUN (no_auto_summary, /* "router bgp" commands. */ DEFUN_NOSH (router_bgp, router_bgp_cmd, - "router bgp [(1-4294967295) [<view|vrf> WORD]]", + "router bgp [(1-4294967295) [<view|vrf> VIEWVRFNAME]]", ROUTER_STR BGP_STR AS_STR @@ -937,7 +937,7 @@ DEFUN_NOSH (router_bgp, /* "no router bgp" commands. */ DEFUN (no_router_bgp, no_router_bgp_cmd, - "no router bgp [(1-4294967295) [<view|vrf> WORD]]", + "no router bgp [(1-4294967295) [<view|vrf> VIEWVRFNAME]]", NO_STR ROUTER_STR BGP_STR @@ -1249,7 +1249,7 @@ DEFUN (bgp_maxmed_admin, DEFUN (bgp_maxmed_admin_medv, bgp_maxmed_admin_medv_cmd, - "bgp max-med administrative (0-4294967294)", + "bgp max-med administrative (0-4294967295)", BGP_STR "Advertise routes with max-med\n" "Administratively applied, for an indefinite period\n" @@ -1259,7 +1259,7 @@ DEFUN (bgp_maxmed_admin_medv, int idx_number = 3; bgp->v_maxmed_admin = 1; - VTY_GET_INTEGER ("max-med admin med-value", bgp->maxmed_admin_value, argv[idx_number]->arg); + bgp->maxmed_admin_value = strtoul (argv[idx_number]->arg, NULL, 10); bgp_maxmed_update(bgp); @@ -1268,7 +1268,7 @@ DEFUN (bgp_maxmed_admin_medv, DEFUN (no_bgp_maxmed_admin, no_bgp_maxmed_admin_cmd, - "no bgp max-med administrative [(0-4294967294)]", + "no bgp max-med administrative [(0-4294967295)]", NO_STR BGP_STR "Advertise routes with max-med\n" @@ -1285,24 +1285,7 @@ DEFUN (no_bgp_maxmed_admin, DEFUN (bgp_maxmed_onstartup, bgp_maxmed_onstartup_cmd, - "bgp max-med on-startup (5-86400)", - BGP_STR - "Advertise routes with max-med\n" - "Effective on a startup\n" - "Time (seconds) period for max-med\n") -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_number = 3; - VTY_GET_INTEGER ("max-med on-startup period", bgp->v_maxmed_onstartup, argv[idx_number]->arg); - bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT; - bgp_maxmed_update(bgp); - - return CMD_SUCCESS; -} - -DEFUN (bgp_maxmed_onstartup_medv, - bgp_maxmed_onstartup_medv_cmd, - "bgp max-med on-startup (5-86400) (0-4294967294)", + "bgp max-med on-startup (5-86400) [(0-4294967295)]", BGP_STR "Advertise routes with max-med\n" "Effective on a startup\n" @@ -1310,10 +1293,15 @@ DEFUN (bgp_maxmed_onstartup_medv, "Max MED value to be used\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - int idx_number = 3; - int idx_number_2 = 4; - VTY_GET_INTEGER ("max-med on-startup period", bgp->v_maxmed_onstartup, argv[idx_number]->arg); - VTY_GET_INTEGER ("max-med on-startup med-value", bgp->maxmed_onstartup_value, argv[idx_number_2]->arg); + int idx = 0; + + argv_find (argv, argc, "(5-86400)", &idx); + bgp->v_maxmed_onstartup = strtoul (argv[idx]->arg, NULL, 10); + if (argv_find (argv, argc, "(0-4294967295)", &idx)) + bgp->maxmed_onstartup_value = strtoul (argv[idx]->arg, NULL, 10); + else + bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT; + bgp_maxmed_update(bgp); return CMD_SUCCESS; @@ -1321,7 +1309,7 @@ DEFUN (bgp_maxmed_onstartup_medv, DEFUN (no_bgp_maxmed_onstartup, no_bgp_maxmed_onstartup_cmd, - "no bgp max-med on-startup [(5-86400) [(0-4294967294)]]", + "no bgp max-med on-startup [(5-86400) [(0-4294967295)]]", NO_STR BGP_STR "Advertise routes with max-med\n" @@ -1490,25 +1478,11 @@ DEFUN (no_bgp_wpkt_quanta, return bgp_wpkt_quanta_config_vty(vty, argv[idx_number]->arg, 0); } -static int -bgp_coalesce_config_vty (struct vty *vty, const char *num, char set) -{ - VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (set) - VTY_GET_INTEGER_RANGE ("coalesce-time", bgp->coalesce_time, num, - 0, 4294967295); - else - bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME; - - return CMD_SUCCESS; -} - int bgp_config_write_coalesce_time (struct vty *vty, struct bgp *bgp) { if (bgp->coalesce_time != BGP_DEFAULT_SUBGROUP_COALESCE_TIME) - vty_out (vty, " coalesce-time %d%s", + vty_out (vty, " coalesce-time %u%s", bgp->coalesce_time, VTY_NEWLINE); return 0; @@ -1521,8 +1495,12 @@ DEFUN (bgp_coalesce_time, "Subgroup coalesce timer\n" "Subgroup coalesce timer value (in ms)\n") { - int idx_number = 1; - return bgp_coalesce_config_vty(vty, argv[idx_number]->arg, 1); + VTY_DECLVAR_CONTEXT(bgp, bgp); + + int idx = 0; + argv_find (argv, argc, "(0-4294967295)", &idx); + bgp->coalesce_time = strtoul (argv[idx]->arg, NULL, 10); + return CMD_SUCCESS; } DEFUN (no_bgp_coalesce_time, @@ -1532,8 +1510,10 @@ DEFUN (no_bgp_coalesce_time, "Subgroup coalesce timer\n" "Subgroup coalesce timer value (in ms)\n") { - int idx_number = 2; - return bgp_coalesce_config_vty(vty, argv[idx_number]->arg, 0); + VTY_DECLVAR_CONTEXT(bgp, bgp); + + bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME; + return CMD_SUCCESS; } /* Maximum-paths configuration */ @@ -6499,7 +6479,7 @@ bgp_clear_prefix (struct vty *vty, const char *view_name, const char *ip_str, /* one clear bgp command to rule them all */ DEFUN (clear_ip_bgp_all, clear_ip_bgp_all_cmd, - "clear [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<soft [<in|out>]|in [prefix-filter]|out>]", + "clear [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<soft [<in|out>]|in [prefix-filter]|out>]", CLEAR_STR IP_STR BGP_STR @@ -6534,7 +6514,7 @@ DEFUN (clear_ip_bgp_all, /* clear [ip] bgp */ if (argv_find (argv, argc, "ip", &idx)) afi = AFI_IP; - /* [<view|vrf> WORD] */ + /* [<view|vrf> VIEWVRFNAME] */ if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) { vrf = argv[idx + 1]->arg; @@ -6604,7 +6584,7 @@ DEFUN (clear_ip_bgp_all, DEFUN (clear_ip_bgp_prefix, clear_ip_bgp_prefix_cmd, - "clear [ip] bgp [<view|vrf> WORD] prefix A.B.C.D/M", + "clear [ip] bgp [<view|vrf> VIEWVRFNAME] prefix A.B.C.D/M", CLEAR_STR IP_STR BGP_STR @@ -6617,7 +6597,7 @@ DEFUN (clear_ip_bgp_prefix, int idx = 0; - /* [<view|vrf> WORD] */ + /* [<view|vrf> VIEWVRFNAME] */ if (argv_find (argv, argc, "WORD", &idx)) vrf = argv[idx]->arg; @@ -6645,7 +6625,7 @@ DEFUN (clear_bgp_ipv6_safi_prefix, DEFUN (clear_bgp_instance_ipv6_safi_prefix, clear_bgp_instance_ipv6_safi_prefix_cmd, - "clear [ip] bgp <view|vrf> WORD ipv6 "BGP_SAFI_CMD_STR" prefix X:X::X:X/M", + "clear [ip] bgp <view|vrf> VIEWVRFNAME ipv6 "BGP_SAFI_CMD_STR" prefix X:X::X:X/M", CLEAR_STR IP_STR BGP_STR @@ -7474,7 +7454,7 @@ bgp_show_summary_vty (struct vty *vty, const char *name, /* `show [ip] bgp summary' commands. */ DEFUN (show_ip_bgp_summary, show_ip_bgp_summary_cmd, - "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] summary [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] summary [json]", SHOW_STR IP_STR BGP_STR @@ -7493,7 +7473,7 @@ DEFUN (show_ip_bgp_summary, /* show [ip] bgp */ if (argv_find (argv, argc, "ip", &idx)) afi = AFI_IP; - /* [<view|vrf> WORD] */ + /* [<view|vrf> VIEWVRFNAME] */ if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) vrf = argv[++idx]->arg; /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */ @@ -9430,7 +9410,7 @@ bgp_show_neighbor_vty (struct vty *vty, const char *name, /* "show [ip] bgp neighbors" commands. */ DEFUN (show_ip_bgp_neighbors, show_ip_bgp_neighbors_cmd, - "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6|vpnv4 <all|rd ASN:nn_or_IP-address:nn>>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|vpnv4 <all|rd ASN:nn_or_IP-address:nn>>] neighbors [<A.B.C.D|X:X::X:X|WORD>] [json]", SHOW_STR IP_STR BGP_STR @@ -9610,7 +9590,7 @@ bgp_show_update_groups(struct vty *vty, const char *name, DEFUN (show_ip_bgp_updgrps, show_ip_bgp_updgrps_cmd, - "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] update-groups [SUBGROUP-ID]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] update-groups [SUBGROUP-ID]", SHOW_STR IP_STR BGP_STR @@ -9630,7 +9610,7 @@ DEFUN (show_ip_bgp_updgrps, /* show [ip] bgp */ if (argv_find (argv, argc, "ip", &idx)) afi = AFI_IP; - /* [<view|vrf> WORD] */ + /* [<view|vrf> VIEWVRFNAME] */ if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) vrf = argv[++idx]->arg; /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */ @@ -9680,7 +9660,7 @@ DEFUN (show_bgp_updgrps_stats, DEFUN (show_bgp_instance_updgrps_stats, show_bgp_instance_updgrps_stats_cmd, - "show [ip] bgp <view|vrf> WORD update-groups statistics", + "show [ip] bgp <view|vrf> VIEWVRFNAME update-groups statistics", SHOW_STR IP_STR BGP_STR @@ -9740,7 +9720,7 @@ DEFUN (show_ip_bgp_updgrps_adj, DEFUN (show_ip_bgp_instance_updgrps_adj, show_ip_bgp_instance_updgrps_adj_cmd, - "show [ip] bgp <view|vrf> WORD update-groups <advertise-queue|advertised-routes|packet-queue>", + "show [ip] bgp <view|vrf> VIEWVRFNAME update-groups <advertise-queue|advertised-routes|packet-queue>", SHOW_STR IP_STR BGP_STR @@ -9798,7 +9778,7 @@ DEFUN (show_bgp_updgrps_adj, DEFUN (show_bgp_instance_updgrps_adj, show_bgp_instance_updgrps_adj_cmd, - "show [ip] bgp <view|vrf> WORD update-groups <advertise-queue|advertised-routes|packet-queue>", + "show [ip] bgp <view|vrf> VIEWVRFNAME update-groups <advertise-queue|advertised-routes|packet-queue>", SHOW_STR IP_STR BGP_STR @@ -9839,7 +9819,7 @@ DEFUN (show_ip_bgp_updgrps_adj_s, DEFUN (show_ip_bgp_instance_updgrps_adj_s, show_ip_bgp_instance_updgrps_adj_s_cmd, - "show [ip] bgp <view|vrf> WORD update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>", + "show [ip] bgp <view|vrf> VIEWVRFNAME update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>", SHOW_STR IP_STR BGP_STR @@ -9915,7 +9895,7 @@ DEFUN (show_bgp_updgrps_adj_s, DEFUN (show_bgp_instance_updgrps_adj_s, show_bgp_instance_updgrps_adj_s_cmd, - "show [ip] bgp <view|vrf> WORD update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>", + "show [ip] bgp <view|vrf> VIEWVRFNAME update-groups SUBGROUP-ID <advertise-queue|advertised-routes|packet-queue>", SHOW_STR IP_STR BGP_STR @@ -10102,7 +10082,7 @@ bgp_show_peer_group_vty (struct vty *vty, const char *name, DEFUN (show_ip_bgp_peer_groups, show_ip_bgp_peer_groups_cmd, - "show [ip] bgp [<view|vrf> WORD] peer-group [PGNAME]", + "show [ip] bgp [<view|vrf> VIEWVRFNAME] peer-group [PGNAME]", SHOW_STR IP_STR BGP_STR @@ -10993,7 +10973,6 @@ bgp_vty_init (void) install_element (BGP_NODE, &bgp_maxmed_admin_medv_cmd); install_element (BGP_NODE, &bgp_maxmed_onstartup_cmd); install_element (BGP_NODE, &no_bgp_maxmed_onstartup_cmd); - install_element (BGP_NODE, &bgp_maxmed_onstartup_medv_cmd); /* bgp disable-ebgp-connected-nh-check */ install_element (BGP_NODE, &bgp_disable_connected_route_check_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 92a0cd6acc..3d0bb8b039 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -6798,7 +6798,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp, ((! peer_group_active (peer) && peer->v_routeadv != BGP_DEFAULT_EBGP_ROUTEADV) || (peer_group_active (peer) && peer->v_routeadv != g_peer->v_routeadv))) { - vty_out (vty, " neighbor %s advertisement-interval %d%s", + vty_out (vty, " neighbor %s advertisement-interval %u%s", addr, peer->v_routeadv, VTY_NEWLINE); } @@ -6807,7 +6807,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp, ((! peer_group_active (peer) && (peer->keepalive != BGP_DEFAULT_KEEPALIVE || peer->holdtime != BGP_DEFAULT_HOLDTIME)) || (peer_group_active (peer) && (peer->keepalive != g_peer->keepalive || peer->holdtime != g_peer->holdtime)))) { - vty_out (vty, " neighbor %s timers %d %d%s", addr, + vty_out (vty, " neighbor %s timers %u %u%s", addr, peer->keepalive, peer->holdtime, VTY_NEWLINE); } @@ -6816,7 +6816,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp, (peer_group_active (peer) && peer->connect != g_peer->connect))) { - vty_out (vty, " neighbor %s timers connect %d%s", addr, + vty_out (vty, " neighbor %s timers connect %u%s", addr, peer->connect, VTY_NEWLINE); } @@ -7096,26 +7096,31 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp, " no neighbor %s send-community all%s", addr, VTY_NEWLINE); } - else if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY) && - (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))) - { - afi_header_vty_out (vty, afi, safi, write, - " no neighbor %s send-community large%s", - addr, VTY_NEWLINE); - } - else if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY) && - (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))) - { - afi_header_vty_out (vty, afi, safi, write, - " no neighbor %s send-community extended%s", - addr, VTY_NEWLINE); - } - else if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) && - (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))) + else { - afi_header_vty_out (vty, afi, safi, write, - " no neighbor %s send-community%s", - addr, VTY_NEWLINE); + if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY) && + (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_LARGE_COMMUNITY))) + { + afi_header_vty_out (vty, afi, safi, write, + " no neighbor %s send-community large%s", + addr, VTY_NEWLINE); + } + + if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY) && + (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))) + { + afi_header_vty_out (vty, afi, safi, write, + " no neighbor %s send-community extended%s", + addr, VTY_NEWLINE); + } + + if (!peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) && + (!g_peer || peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))) + { + afi_header_vty_out (vty, afi, safi, write, + " no neighbor %s send-community%s", + addr, VTY_NEWLINE); + } } } @@ -7154,11 +7159,11 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp, " neighbor %s maximum-prefix %lu", addr, peer->pmax[afi][safi]); if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT) - vty_out (vty, " %d", peer->pmax_threshold[afi][safi]); + vty_out (vty, " %u", peer->pmax_threshold[afi][safi]); if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)) vty_out (vty, " warning-only"); if (peer->pmax_restart[afi][safi]) - vty_out (vty, " restart %d", peer->pmax_restart[afi][safi]); + vty_out (vty, " restart %u", peer->pmax_restart[afi][safi]); vty_out (vty, "%s", VTY_NEWLINE); } @@ -7221,7 +7226,7 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp, if (peer->weight[afi][safi]) { afi_header_vty_out (vty, afi, safi, write, - " neighbor %s weight %d%s", + " neighbor %s weight %lu%s", addr, peer->weight[afi][safi], VTY_NEWLINE); } } @@ -7366,7 +7371,7 @@ bgp_config_write (struct vty *vty) } if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER) - vty_out (vty, "bgp route-map delay-timer %d%s", bm->rmap_update_timer, + vty_out (vty, "bgp route-map delay-timer %u%s", bm->rmap_update_timer, VTY_NEWLINE); /* BGP configuration. */ @@ -7417,7 +7422,7 @@ bgp_config_write (struct vty *vty) /* BGP default local-preference. */ if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF) - vty_out (vty, " bgp default local-preference %d%s", + vty_out (vty, " bgp default local-preference %u%s", bgp->default_local_pref, VTY_NEWLINE); /* BGP default show-hostname */ @@ -7429,7 +7434,7 @@ bgp_config_write (struct vty *vty) /* BGP default subgroup-pkt-queue-max. */ if (bgp->default_subgroup_pkt_queue_max != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX) - vty_out (vty, " bgp default subgroup-pkt-queue-max %d%s", + vty_out (vty, " bgp default subgroup-pkt-queue-max %u%s", bgp->default_subgroup_pkt_queue_max, VTY_NEWLINE); /* BGP client-to-client reflection. */ @@ -7479,16 +7484,16 @@ bgp_config_write (struct vty *vty) if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED) { - vty_out (vty, " bgp max-med on-startup %d", bgp->v_maxmed_onstartup); + vty_out (vty, " bgp max-med on-startup %u", bgp->v_maxmed_onstartup); if (bgp->maxmed_onstartup_value != BGP_MAXMED_VALUE_DEFAULT) - vty_out (vty, " %d", bgp->maxmed_onstartup_value); + vty_out (vty, " %u", bgp->maxmed_onstartup_value); vty_out (vty, "%s", VTY_NEWLINE); } if (bgp->v_maxmed_admin != BGP_MAXMED_ADMIN_UNCONFIGURED) { vty_out (vty, " bgp max-med administrative"); if (bgp->maxmed_admin_value != BGP_MAXMED_VALUE_DEFAULT) - vty_out (vty, " %d", bgp->maxmed_admin_value); + vty_out (vty, " %u", bgp->maxmed_admin_value); vty_out (vty, "%s", VTY_NEWLINE); } @@ -7500,10 +7505,10 @@ bgp_config_write (struct vty *vty) /* BGP graceful-restart. */ if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME) - vty_out (vty, " bgp graceful-restart stalepath-time %d%s", + vty_out (vty, " bgp graceful-restart stalepath-time %u%s", bgp->stalepath_time, VTY_NEWLINE); if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME) - vty_out (vty, " bgp graceful-restart restart-time %d%s", + vty_out (vty, " bgp graceful-restart restart-time %u%s", bgp->restart_time, VTY_NEWLINE); if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART)) vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE); @@ -7562,7 +7567,7 @@ bgp_config_write (struct vty *vty) /* BGP timers configuration. */ if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) - vty_out (vty, " timers bgp %d %d%s", bgp->default_keepalive, + vty_out (vty, " timers bgp %u %u%s", bgp->default_keepalive, bgp->default_holdtime, VTY_NEWLINE); /* peer-group */ @@ -7676,6 +7681,38 @@ bgp_if_finish (struct bgp *bgp) extern void bgp_snmp_init (void); +static void +bgp_viewvrf_autocomplete (vector comps, struct cmd_token *token) +{ + struct vrf *vrf = NULL; + struct listnode *next; + struct bgp *bgp; + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) + { + if (vrf->vrf_id != VRF_DEFAULT) + vector_set (comps, XSTRDUP (MTYPE_COMPLETION, vrf->name)); + } + + for (ALL_LIST_ELEMENTS_RO (bm->bgp, next, bgp)) + { + if (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) + continue; + + vector_set (comps, XSTRDUP (MTYPE_COMPLETION, bgp->name)); + } +} + +static const struct cmd_variable_handler bgp_viewvrf_var_handlers[] = { + { + .tokenname = "VIEWVRFNAME", + .completions = bgp_viewvrf_autocomplete + }, + { + .completions = NULL + }, +}; + void bgp_init (void) { @@ -7725,6 +7762,8 @@ bgp_init (void) /* BFD init */ bgp_bfd_init(); + + cmd_variable_handler_register (bgp_viewvrf_var_handlers); } void diff --git a/configure.ac b/configure.ac index dbc281e471..43e1625b90 100755 --- a/configure.ac +++ b/configure.ac @@ -917,8 +917,7 @@ dnl other functions dnl --------------- AC_CHECK_FUNCS([ \ strlcat strlcpy \ - getgrouplist \ - pledge]) + getgrouplist]) AC_CHECK_HEADER([asm-generic/unistd.h], [AC_CHECK_DECL(__NR_setns, @@ -1285,14 +1284,6 @@ AM_CONDITIONAL(OSPFD, test "x$OSPFD" = "xospfd") if test "${enable_ldpd}" = "no";then LDPD="" else - AX_PROG_PERL_MODULES(XML::LibXML, , [ - if test -f "${srcdir}/ldpd/ldp_vty_cmds.c"; then - AC_MSG_WARN([XML::LibXML perl module not found, using pregenerated ldp_vty_cmds.c]) - else - AC_MSG_ERROR([XML::LibXML perl module not found and pregenerated ldp_vty_cmds.c missing]) - fi - ]) - LDPD="ldpd" AC_DEFINE(HAVE_LDPD, 1, ldpd) fi diff --git a/doc/Building_FRR_on_Fedora24.md b/doc/Building_FRR_on_Fedora24.md index 1f5f12b9cc..bb5b52c62b 100644 --- a/doc/Building_FRR_on_Fedora24.md +++ b/doc/Building_FRR_on_Fedora24.md @@ -8,8 +8,7 @@ Add packages: sudo dnf install git autoconf automake libtool make gawk \ readline-devel texinfo net-snmp-devel groff pkgconfig \ - json-c-devel pam-devel perl-XML-LibXML c-ares-devel \ - python3-devel + json-c-devel pam-devel c-ares-devel python3-devel Get FRR, compile it and install it (from Git) --------------------------------------------- diff --git a/doc/Building_FRR_on_NetBSD6.md b/doc/Building_FRR_on_NetBSD6.md index 542a7f489e..2e453da66c 100644 --- a/doc/Building_FRR_on_NetBSD6.md +++ b/doc/Building_FRR_on_NetBSD6.md @@ -18,7 +18,7 @@ Configure Package location: Add packages: sudo pkg_add git autoconf automake libtool gmake gawk openssl \ - pkg-config json-c p5-XML-LibXML python27 py27-test python35 + pkg-config json-c python27 py27-test python35 Install SSL Root Certificates (for git https access): diff --git a/doc/Building_FRR_on_NetBSD7.md b/doc/Building_FRR_on_NetBSD7.md index 821a6109f2..f5f99d9ba0 100644 --- a/doc/Building_FRR_on_NetBSD7.md +++ b/doc/Building_FRR_on_NetBSD7.md @@ -12,7 +12,7 @@ Install required packages ------------------------- sudo pkgin install git autoconf automake libtool gmake gawk openssl \ - pkg-config json-c p5-XML-LibXML python27 py27-test python35 + pkg-config json-c python27 py27-test python35 Install SSL Root Certificates (for git https access): diff --git a/doc/Building_FRR_on_OmniOS.md b/doc/Building_FRR_on_OmniOS.md index 2e9871467b..7e75bda9e9 100644 --- a/doc/Building_FRR_on_OmniOS.md +++ b/doc/Building_FRR_on_OmniOS.md @@ -47,12 +47,6 @@ Add libjson to Solaris equivalent of ld.so.conf crle -l /opt/csw/lib -u -Add Perl packages: - - cpan - cpan[1]> install XML::LibXML - cpan[2]> exit - Add pytest: pip install pytest diff --git a/doc/Building_FRR_on_OpenBSD6.md b/doc/Building_FRR_on_OpenBSD6.md index c1b583664d..e9e1030515 100644 --- a/doc/Building_FRR_on_OpenBSD6.md +++ b/doc/Building_FRR_on_OpenBSD6.md @@ -10,8 +10,8 @@ Configure PKG_PATH Add packages: - pkg_add git autoconf-2.69p2 automake-1.15p0 libtool - pkg_add gmake gawk dejagnu openssl json-c p5-XML-LibXML py-test + pkg_add git autoconf-2.69p2 automake-1.15p0 libtool bison + pkg_add gmake gawk dejagnu openssl json-c py-test Select Python2.7 as default (required for pytest) @@ -36,6 +36,8 @@ an example) git clone https://github.com/frrouting/frr.git frr cd frr + export AUTOCONF_VERSION="2.69" + export AUTOMAKE_VERSION="1.15" ./bootstrap.sh export LDFLAGS="-L/usr/local/lib" export CPPFLAGS="-I/usr/local/include" @@ -58,29 +60,29 @@ an example) --with-pkg-extra-version=-MyOwnFRRVersion gmake gmake check - sudo gmake install + doas gmake install ### Create empty FRR configuration files - sudo mkdir /var/frr - sudo chown _frr:_frr /var/frr - sudo chmod 755 /var/frr - sudo mkdir /etc/frr - sudo touch /etc/frr/zebra.conf - sudo touch /etc/frr/bgpd.conf - sudo touch /etc/frr/ospfd.conf - sudo touch /etc/frr/ospf6d.conf - sudo touch /etc/frr/isisd.conf - sudo touch /etc/frr/ripd.conf - sudo touch /etc/frr/ripngd.conf - sudo touch /etc/frr/pimd.conf - sudo touch /etc/frr/ldpd.conf - sudo touch /etc/frr/nhrpd.conf - sudo chown -R _frr:_frr /etc/frr - sudo touch /etc/frr/vtysh.conf - sudo chown -R _frr:_frrvty /etc/frr/vtysh.conf - sudo chmod 750 /etc/frr - sudo chmod 640 /etc/frr/*.conf + doas mkdir /var/frr + doas chown _frr:_frr /var/frr + doas chmod 755 /var/frr + doas mkdir /etc/frr + doas touch /etc/frr/zebra.conf + doas touch /etc/frr/bgpd.conf + doas touch /etc/frr/ospfd.conf + doas touch /etc/frr/ospf6d.conf + doas touch /etc/frr/isisd.conf + doas touch /etc/frr/ripd.conf + doas touch /etc/frr/ripngd.conf + doas touch /etc/frr/pimd.conf + doas touch /etc/frr/ldpd.conf + doas touch /etc/frr/nhrpd.conf + doas chown -R _frr:_frr /etc/frr + doas touch /etc/frr/vtysh.conf + doas chown -R _frr:_frrvty /etc/frr/vtysh.conf + doas chmod 750 /etc/frr + doas chmod 640 /etc/frr/*.conf ### Enable IP & IPv6 forwarding @@ -96,7 +98,7 @@ Add the following lines to the end of `/etc/rc.conf`: To enable MPLS forwarding on a given interface, use the following command: - sudo ifconfig em0 mpls + doas ifconfig em0 mpls Alternatively, to make MPLS forwarding persistent across reboots, add the "mpls" keyword in the hostname.* files of the desired interfaces. Example: diff --git a/doc/Building_FRR_on_Ubuntu1204.md b/doc/Building_FRR_on_Ubuntu1204.md index e79614a57e..033e05bcdb 100644 --- a/doc/Building_FRR_on_Ubuntu1204.md +++ b/doc/Building_FRR_on_Ubuntu1204.md @@ -13,7 +13,7 @@ Add packages: apt-get install git autoconf automake libtool make gawk libreadline-dev \ texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-dev \ - libjson0-dev flex python-pip libc-ares-dev python3-dev libxml2 libxml2-dev + libjson0-dev flex python-pip libc-ares-dev python3-dev Install newer bison from 14.04 package source (Ubuntu 12.04 package source is too old) @@ -51,11 +51,6 @@ Install newer version of autoconf and automake: sudo make install cd .. -Install XML::LibXML - - sudo cpan - install XML::LibXML - Install pytest: pip install pytest diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 245b6adce8..675031b754 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -473,7 +473,7 @@ eigrp_topology_update_node_flags(struct eigrp_prefix_entry *dest) for (ALL_LIST_ELEMENTS_RO(dest->entries, node, entry)) { - if ((entry->distance <= (uint64_t)(dest->distance*eigrp->variance)) && + if (((uint64_t)entry->distance <= (uint64_t)(dest->distance*eigrp->variance)) && entry->distance != EIGRP_MAX_METRIC) // is successor { entry->flags |= EIGRP_NEIGHBOR_ENTRY_SUCCESSOR_FLAG; diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 93a69b776b..a0ead05224 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -186,7 +186,7 @@ eigrp_new (const char *AS) eigrp->topology_table = eigrp_topology_new(); eigrp->neighbor_self = eigrp_nbr_new(NULL); - inet_aton("0.0.0.0", &eigrp->neighbor_self->src); + eigrp->neighbor_self->src.s_addr = INADDR_ANY; eigrp->variance = EIGRP_VARIANCE_DEFAULT; eigrp->max_paths = EIGRP_MAX_PATHS_DEFAULT; diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 1869346f89..c6f70c6ca3 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -181,6 +181,7 @@ isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state new_state int old_state; int level; struct isis_circuit *circuit; + bool del; old_state = adj->adj_state; adj->adj_state = new_state; @@ -215,6 +216,7 @@ isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state new_state if (circuit->circ_type == CIRCUIT_T_BROADCAST) { + del = false; for (level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) { if ((adj->level & level) == 0) @@ -238,7 +240,7 @@ isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state new_state list_delete_all_node (circuit->lsp_queue); } isis_event_adjacency_state_change (adj, new_state); - isis_delete_adj (adj); + del = true; } if (circuit->u.bc.lan_neighs[level - 1]) @@ -252,9 +254,15 @@ isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state new_state if (circuit->u.bc.is_dr[level - 1]) lsp_regenerate_schedule_pseudo (circuit, level); } + + if (del) + isis_delete_adj (adj); + + adj = NULL; } else if (circuit->circ_type == CIRCUIT_T_P2P) { + del = false; for (level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) { if ((adj->level & level) == 0) @@ -287,9 +295,14 @@ isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state new_state list_delete_all_node (circuit->lsp_queue); } isis_event_adjacency_state_change (adj, new_state); - isis_delete_adj (adj); + del = true; } } + + if (del) + isis_delete_adj (adj); + + adj = NULL; } return; diff --git a/ldpd/.gitignore b/ldpd/.gitignore index e4ee82587a..35f7740d11 100644 --- a/ldpd/.gitignore +++ b/ldpd/.gitignore @@ -15,4 +15,3 @@ TAGS .arch-ids *~ *.loT -ldp_vty_cmds.c diff --git a/ldpd/Makefile.am b/ldpd/Makefile.am index b760b44573..6074b53a33 100644 --- a/ldpd/Makefile.am +++ b/ldpd/Makefile.am @@ -3,16 +3,12 @@ AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" INSTALL_SDATA=@INSTALL@ -m 600 -EXTRA_DIST= AM_CFLAGS = $(WERROR) noinst_LIBRARIES = libldp.a sbin_PROGRAMS = ldpd -BUILT_SOURCES = ldp_vty_cmds.c -EXTRA_DIST += ldp_vty.xml - libldp_a_SOURCES = \ accept.c address.c adjacency.c control.c hello.c init.c interface.c \ keepalive.c l2vpn.c labelmapping.c lde.c lde_lib.c ldpd.c \ @@ -23,11 +19,6 @@ libldp_a_SOURCES = \ noinst_HEADERS = \ control.h lde.h ldpd.h ldpe.h ldp.h log.h ldp_debug.h ldp_vty.h -ldp_vty_cmds.c: $(srcdir)/ldp_vty.xml $(srcdir)/../tools/xml2cli.pl - @PERL@ $(srcdir)/../tools/xml2cli.pl $(srcdir)/ldp_vty.xml | \ - sed -e 's%DEFUN \((ldp_\(interface_\|mpls_ldp\|address_family\|l2vpn_word\|member_pseudo\)\)%DEFUN_NOSH \1%' \ - > $@ - ldpd_SOURCES = ldpd.c ldpd_LDADD = libldp.a ../lib/libfrr.la @LIBCAP@ diff --git a/ldpd/adjacency.c b/ldpd/adjacency.c index 52e2776654..e73d1b51a2 100644 --- a/ldpd/adjacency.c +++ b/ldpd/adjacency.c @@ -25,9 +25,9 @@ #include "ldpe.h" #include "log.h" -static __inline int adj_compare(struct adj *, struct adj *); +static __inline int adj_compare(const struct adj *, const struct adj *); static int adj_itimer(struct thread *); -static __inline int tnbr_compare(struct tnbr *, struct tnbr *); +static __inline int tnbr_compare(const struct tnbr *, const struct tnbr *); static void tnbr_del(struct ldpd_conf *, struct tnbr *); static void tnbr_start(struct tnbr *); static void tnbr_stop(struct tnbr *); @@ -41,7 +41,7 @@ RB_GENERATE(ia_adj_head, adj, ia_entry, adj_compare) RB_GENERATE(tnbr_head, tnbr, entry, tnbr_compare) static __inline int -adj_compare(struct adj *a, struct adj *b) +adj_compare(const struct adj *a, const struct adj *b) { if (adj_get_af(a) < adj_get_af(b)) return (-1); @@ -163,7 +163,7 @@ adj_find(struct in_addr lsr_id, struct hello_source *source) } int -adj_get_af(struct adj *adj) +adj_get_af(const struct adj *adj) { switch (adj->source.type) { case HELLO_LINK: @@ -220,7 +220,7 @@ adj_stop_itimer(struct adj *adj) /* targeted neighbors */ static __inline int -tnbr_compare(struct tnbr *a, struct tnbr *b) +tnbr_compare(const struct tnbr *a, const struct tnbr *b) { if (a->af < b->af) return (-1); diff --git a/ldpd/interface.c b/ldpd/interface.c index a064a58b2e..ac48520f7b 100644 --- a/ldpd/interface.c +++ b/ldpd/interface.c @@ -26,7 +26,7 @@ #include "sockopt.h" -static __inline int iface_compare(struct iface *, struct iface *); +static __inline int iface_compare(const struct iface *, const struct iface *); static struct if_addr *if_addr_new(struct kaddr *); static struct if_addr *if_addr_lookup(struct if_addr_head *, struct kaddr *); static int if_start(struct iface *, int); @@ -43,7 +43,7 @@ static int if_leave_ipv6_group(struct iface *, struct in6_addr *); RB_GENERATE(iface_head, iface, entry, iface_compare) static __inline int -iface_compare(struct iface *a, struct iface *b) +iface_compare(const struct iface *a, const struct iface *b) { return (strcmp(a->name, b->name)); } @@ -81,12 +81,12 @@ ldpe_if_init(struct iface *iface) /* ipv4 */ iface->ipv4.iface = iface; iface->ipv4.state = IF_STA_DOWN; - RB_INIT(&iface->ipv4.adj_tree); + RB_INIT(ia_adj_head, &iface->ipv4.adj_tree); /* ipv6 */ iface->ipv6.iface = iface; iface->ipv6.state = IF_STA_DOWN; - RB_INIT(&iface->ipv6.adj_tree); + RB_INIT(ia_adj_head, &iface->ipv6.adj_tree); } void @@ -305,7 +305,7 @@ if_reset(struct iface *iface, int af) ia = iface_af_get(iface, af); if_stop_hello_timer(ia); - while ((adj = RB_ROOT(&ia->adj_tree)) != NULL) + while ((adj = RB_ROOT(ia_adj_head, &ia->adj_tree)) != NULL) adj_del(adj, S_SHUTDOWN); /* try to cleanup */ diff --git a/ldpd/l2vpn.c b/ldpd/l2vpn.c index 27948f5a1a..f15461d3d2 100644 --- a/ldpd/l2vpn.c +++ b/ldpd/l2vpn.c @@ -27,16 +27,16 @@ #include "log.h" static void l2vpn_pw_fec(struct l2vpn_pw *, struct fec *); -static __inline int l2vpn_compare(struct l2vpn *, struct l2vpn *); -static __inline int l2vpn_if_compare(struct l2vpn_if *, struct l2vpn_if *); -static __inline int l2vpn_pw_compare(struct l2vpn_pw *, struct l2vpn_pw *); +static __inline int l2vpn_compare(const struct l2vpn *, const struct l2vpn *); +static __inline int l2vpn_if_compare(const struct l2vpn_if *, const struct l2vpn_if *); +static __inline int l2vpn_pw_compare(const struct l2vpn_pw *, const struct l2vpn_pw *); RB_GENERATE(l2vpn_head, l2vpn, entry, l2vpn_compare) RB_GENERATE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare) RB_GENERATE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare) static __inline int -l2vpn_compare(struct l2vpn *a, struct l2vpn *b) +l2vpn_compare(const struct l2vpn *a, const struct l2vpn *b) { return (strcmp(a->name, b->name)); } @@ -55,9 +55,9 @@ l2vpn_new(const char *name) l2vpn->mtu = DEFAULT_L2VPN_MTU; l2vpn->pw_type = DEFAULT_PW_TYPE; - RB_INIT(&l2vpn->if_tree); - RB_INIT(&l2vpn->pw_tree); - RB_INIT(&l2vpn->pw_inactive_tree); + RB_INIT(l2vpn_if_head, &l2vpn->if_tree); + RB_INIT(l2vpn_pw_head, &l2vpn->pw_tree); + RB_INIT(l2vpn_pw_head, &l2vpn->pw_inactive_tree); return (l2vpn); } @@ -76,15 +76,16 @@ l2vpn_del(struct l2vpn *l2vpn) struct l2vpn_if *lif; struct l2vpn_pw *pw; - while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) { + while ((lif = RB_ROOT(l2vpn_if_head, &l2vpn->if_tree)) != NULL) { RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); free(lif); } - while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) { + while ((pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree)) != NULL) { RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); free(pw); } - while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) { + while ((pw = RB_ROOT(l2vpn_pw_head, + &l2vpn->pw_inactive_tree)) != NULL) { RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); free(pw); } @@ -111,7 +112,7 @@ l2vpn_exit(struct l2vpn *l2vpn) } static __inline int -l2vpn_if_compare(struct l2vpn_if *a, struct l2vpn_if *b) +l2vpn_if_compare(const struct l2vpn_if *a, const struct l2vpn_if *b) { return (strcmp(a->ifname, b->ifname)); } @@ -174,7 +175,7 @@ l2vpn_if_update(struct l2vpn_if *lif) } static __inline int -l2vpn_pw_compare(struct l2vpn_pw *a, struct l2vpn_pw *b) +l2vpn_pw_compare(const struct l2vpn_pw *a, const struct l2vpn_pw *b) { return (strcmp(a->ifname, b->ifname)); } @@ -512,7 +513,7 @@ l2vpn_binding_ctl(pid_t pid) fn = (struct fec_node *)f; if (fn->local_label == NO_LABEL && - RB_EMPTY(&fn->downstream)) + RB_EMPTY(lde_map_head, &fn->downstream)) continue; memset(&pwctl, 0, sizeof(pwctl)); diff --git a/ldpd/lde.c b/ldpd/lde.c index 8d2a9dd9dc..0ef46dab3d 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -41,15 +41,16 @@ static void lde_shutdown(void); static int lde_dispatch_imsg(struct thread *); static int lde_dispatch_parent(struct thread *); -static __inline int lde_nbr_compare(struct lde_nbr *, - struct lde_nbr *); +static __inline int lde_nbr_compare(const struct lde_nbr *, + const struct lde_nbr *); static struct lde_nbr *lde_nbr_new(uint32_t, struct lde_nbr *); static void lde_nbr_del(struct lde_nbr *); static struct lde_nbr *lde_nbr_find(uint32_t); static void lde_nbr_clear(void); static void lde_nbr_addr_update(struct lde_nbr *, struct lde_addr *, int); -static __inline int lde_map_compare(struct lde_map *, struct lde_map *); +static __inline int lde_map_compare(const struct lde_map *, + const struct lde_map *); static void lde_map_free(void *); static int lde_address_add(struct lde_nbr *, struct lde_addr *); static int lde_address_del(struct lde_nbr *, struct lde_addr *); @@ -165,11 +166,6 @@ lde_init(struct ldpd_init *init) lde_privs.group = init->group; zprivs_init(&lde_privs); -#ifdef HAVE_PLEDGE - if (pledge("stdio recvfd unix", NULL) == -1) - fatal("pledge"); -#endif - /* start the LIB garbage collector */ lde_gc_start_timer(); @@ -547,10 +543,10 @@ lde_dispatch_parent(struct thread *thread) fatal(NULL); memcpy(nconf, imsg.data, sizeof(struct ldpd_conf)); - RB_INIT(&nconf->iface_tree); - RB_INIT(&nconf->tnbr_tree); - RB_INIT(&nconf->nbrp_tree); - RB_INIT(&nconf->l2vpn_tree); + RB_INIT(iface_head, &nconf->iface_tree); + RB_INIT(tnbr_head, &nconf->tnbr_tree); + RB_INIT(nbrp_head, &nconf->nbrp_tree); + RB_INIT(l2vpn_head, &nconf->l2vpn_tree); break; case IMSG_RECONF_IFACE: if ((niface = malloc(sizeof(struct iface))) == NULL) @@ -578,9 +574,9 @@ lde_dispatch_parent(struct thread *thread) fatal(NULL); memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn)); - RB_INIT(&nl2vpn->if_tree); - RB_INIT(&nl2vpn->pw_tree); - RB_INIT(&nl2vpn->pw_inactive_tree); + RB_INIT(l2vpn_if_head, &nl2vpn->if_tree); + RB_INIT(l2vpn_pw_head, &nl2vpn->pw_tree); + RB_INIT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree); RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn); break; @@ -1194,7 +1190,7 @@ lde_send_notification_eol_pwid(struct lde_nbr *ln, uint16_t pw_type) } static __inline int -lde_nbr_compare(struct lde_nbr *a, struct lde_nbr *b) +lde_nbr_compare(const struct lde_nbr *a, const struct lde_nbr *b) { return (a->peerid - b->peerid); } @@ -1319,7 +1315,7 @@ lde_nbr_clear(void) { struct lde_nbr *ln; - while ((ln = RB_ROOT(&lde_nbrs)) != NULL) + while ((ln = RB_ROOT(nbr_tree, &lde_nbrs)) != NULL) lde_nbr_del(ln); } @@ -1365,7 +1361,7 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed) } static __inline int -lde_map_compare(struct lde_map *a, struct lde_map *b) +lde_map_compare(const struct lde_map *a, const struct lde_map *b) { return (ldp_addrcmp(AF_INET, (union ldpd_addr *)&a->nexthop->id, (union ldpd_addr *)&b->nexthop->id)); diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index 8dc305cac1..edf686537f 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -25,7 +25,7 @@ #include "mpls.h" -static __inline int fec_compare(struct fec *, struct fec *); +static __inline int fec_compare(const struct fec *, const struct fec *); static int lde_nbr_is_nexthop(struct fec_node *, struct lde_nbr *); static void fec_free(void *); @@ -43,11 +43,11 @@ struct thread *gc_timer; void fec_init(struct fec_tree *fh) { - RB_INIT(fh); + RB_INIT(fec_tree, fh); } static __inline int -fec_compare(struct fec *a, struct fec *b) +fec_compare(const struct fec *a, const struct fec *b) { if (a->type < b->type) return (-1); @@ -129,7 +129,7 @@ fec_clear(struct fec_tree *fh, void (*free_cb)(void *)) { struct fec *f; - while ((f = RB_ROOT(fh)) != NULL) { + while ((f = RB_ROOT(fec_tree, fh)) != NULL) { fec_remove(fh, f); free_cb(f); } @@ -159,7 +159,7 @@ rt_dump(pid_t pid) RB_FOREACH(f, fec_tree, &ft) { fn = (struct fec_node *)f; if (fn->local_label == NO_LABEL && - RB_EMPTY(&fn->downstream)) + RB_EMPTY(lde_map_head, &fn->downstream)) continue; memset(&rtctl, 0, sizeof(rtctl)); @@ -179,7 +179,7 @@ rt_dump(pid_t pid) } rtctl.local_label = fn->local_label; - if (RB_EMPTY(&fn->downstream)) { + if (RB_EMPTY(lde_map_head, &fn->downstream)) { rtctl.in_use = 0; rtctl.nexthop.s_addr = INADDR_ANY; rtctl.remote_label = NO_LABEL; @@ -231,10 +231,10 @@ fec_free(void *arg) while ((fnh = LIST_FIRST(&fn->nexthops))) fec_nh_del(fnh); - if (!RB_EMPTY(&fn->downstream)) + if (!RB_EMPTY(lde_map_head, &fn->downstream)) log_warnx("%s: fec %s downstream list not empty", __func__, log_fec(&fn->fec)); - if (!RB_EMPTY(&fn->upstream)) + if (!RB_EMPTY(lde_map_head, &fn->upstream)) log_warnx("%s: fec %s upstream list not empty", __func__, log_fec(&fn->fec)); @@ -258,8 +258,8 @@ fec_add(struct fec *fec) fn->fec = *fec; fn->local_label = NO_LABEL; - RB_INIT(&fn->upstream); - RB_INIT(&fn->downstream); + RB_INIT(lde_map_head, &fn->upstream); + RB_INIT(lde_map_head, &fn->downstream); LIST_INIT(&fn->nexthops); if (fec_insert(&ft, &fn->fec)) @@ -396,7 +396,8 @@ lde_kernel_update(struct fec *fec) lde_gc_start_timer(); } else { fn->local_label = lde_update_label(fn); - if (fn->local_label != NO_LABEL && RB_EMPTY(&fn->upstream)) + if (fn->local_label != NO_LABEL && + RB_EMPTY(lde_map_head, &fn->upstream)) /* FEC.1: perform lsr label distribution procedure */ RB_FOREACH(ln, nbr_tree, &lde_nbrs) lde_send_labelmapping(ln, fn, 1); @@ -904,8 +905,8 @@ lde_gc_timer(struct thread *thread) fn = (struct fec_node *) fec; if (!LIST_EMPTY(&fn->nexthops) || - !RB_EMPTY(&fn->downstream) || - !RB_EMPTY(&fn->upstream)) + !RB_EMPTY(lde_map_head, &fn->downstream) || + !RB_EMPTY(lde_map_head, &fn->upstream)) continue; fec_remove(&ft, &fn->fec); diff --git a/ldpd/ldp_debug.c b/ldpd/ldp_debug.c index 4419f853b4..7915fb709d 100644 --- a/ldpd/ldp_debug.c +++ b/ldpd/ldp_debug.c @@ -1,21 +1,20 @@ /* * Copyright (C) 2016 by Open Source Routing. * - * This file is part of GNU Zebra. + * 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. * - * 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 + * 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <zebra.h> @@ -39,16 +38,10 @@ struct cmd_node ldp_debug_node = }; int -ldp_vty_debug(struct vty *vty, struct vty_arg *args[]) +ldp_vty_debug(struct vty *vty, int disable, const char *type_str, + const char *dir_str, int all) { - const char *type_str, *dir_str; - int disable, all; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - type_str = vty_get_arg_value(args, "type"); - if (strcmp(type_str, "discovery") == 0) { - dir_str = vty_get_arg_value(args, "dir"); if (dir_str == NULL) return (CMD_WARNING); @@ -74,8 +67,6 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[]) else DEBUG_ON(event, EVENT); } else if (strcmp(type_str, "messages") == 0) { - all = (vty_get_arg_value(args, "all")) ? 1 : 0; - dir_str = vty_get_arg_value(args, "dir"); if (dir_str == NULL) return (CMD_WARNING); @@ -112,7 +103,7 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_show_debugging(struct vty *vty, struct vty_arg *args[]) +ldp_vty_show_debugging(struct vty *vty) { vty_out(vty, "LDP debugging status:%s", VTY_NEWLINE); diff --git a/ldpd/ldp_debug.h b/ldpd/ldp_debug.h index 6366d3f6ac..4b91656851 100644 --- a/ldpd/ldp_debug.h +++ b/ldpd/ldp_debug.h @@ -1,21 +1,20 @@ /* * Copyright (C) 2016 by Open Source Routing. * - * This file is part of GNU Zebra. + * 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. * - * 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 + * 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #ifndef _LDP_DEBUG_H_ diff --git a/ldpd/ldp_vty.h b/ldpd/ldp_vty.h index 21a486ff65..93713166f4 100644 --- a/ldpd/ldp_vty.h +++ b/ldpd/ldp_vty.h @@ -1,21 +1,20 @@ /* * Copyright (C) 2016 by Open Source Routing. * - * This file is part of GNU Zebra. + * 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. * - * 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 + * 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #ifndef _LDP_VTY_H_ @@ -37,46 +36,47 @@ int ldp_get_address(const char *, int *, union ldpd_addr *); int ldp_config_write(struct vty *); int ldp_l2vpn_config_write(struct vty *); int ldp_debug_config_write(struct vty *); -int ldp_vty_mpls_ldp (struct vty *, struct vty_arg *[]); -int ldp_vty_address_family (struct vty *, struct vty_arg *[]); -int ldp_vty_disc_holdtime(struct vty *, struct vty_arg *[]); -int ldp_vty_disc_interval(struct vty *, struct vty_arg *[]); -int ldp_vty_targeted_hello_accept(struct vty *, struct vty_arg *[]); -int ldp_vty_session_holdtime(struct vty *, struct vty_arg *[]); -int ldp_vty_interface(struct vty *, struct vty_arg *[]); -int ldp_vty_trans_addr(struct vty *, struct vty_arg *[]); -int ldp_vty_neighbor_targeted(struct vty *, struct vty_arg *[]); -int ldp_vty_label_advertise(struct vty *, struct vty_arg *[]); -int ldp_vty_label_allocate(struct vty *, struct vty_arg *[]); -int ldp_vty_label_expnull(struct vty *, struct vty_arg *[]); -int ldp_vty_label_accept(struct vty *, struct vty_arg *[]); -int ldp_vty_ttl_security(struct vty *, struct vty_arg *[]); -int ldp_vty_router_id(struct vty *, struct vty_arg *[]); -int ldp_vty_ds_cisco_interop(struct vty *, struct vty_arg *[]); -int ldp_vty_trans_pref_ipv4(struct vty *, struct vty_arg *[]); -int ldp_vty_neighbor_password(struct vty *, struct vty_arg *[]); -int ldp_vty_neighbor_ttl_security(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_bridge(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_mtu(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_pwtype(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_interface(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_pseudowire(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_pw_cword(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_pw_nbr_id(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_pw_pwid(struct vty *, struct vty_arg *[]); -int ldp_vty_l2vpn_pw_pwstatus(struct vty *, struct vty_arg *[]); -int ldp_vty_show_binding(struct vty *, struct vty_arg *[]); -int ldp_vty_show_discovery(struct vty *, struct vty_arg *[]); -int ldp_vty_show_interface(struct vty *, struct vty_arg *[]); -int ldp_vty_show_capabilities(struct vty *, struct vty_arg *[]); -int ldp_vty_show_neighbor(struct vty *, struct vty_arg *[]); -int ldp_vty_show_atom_binding(struct vty *, struct vty_arg *[]); -int ldp_vty_show_atom_vc(struct vty *, struct vty_arg *[]); -int ldp_vty_clear_nbr(struct vty *, struct vty_arg *[]); -int ldp_vty_debug(struct vty *, struct vty_arg *[]); -int ldp_vty_show_debugging(struct vty *, struct vty_arg *[]); +int ldp_vty_mpls_ldp (struct vty *, int); +int ldp_vty_address_family (struct vty *, int, const char *); +int ldp_vty_disc_holdtime(struct vty *, int, const char *, const char *); +int ldp_vty_disc_interval(struct vty *, int, const char *, const char *); +int ldp_vty_targeted_hello_accept(struct vty *, int, const char *); +int ldp_vty_nbr_session_holdtime(struct vty *, int, const char *, const char *); +int ldp_vty_af_session_holdtime(struct vty *, int, const char *); +int ldp_vty_interface(struct vty *, int, const char *); +int ldp_vty_trans_addr(struct vty *, int, const char *); +int ldp_vty_neighbor_targeted(struct vty *, int, const char *); +int ldp_vty_label_advertise(struct vty *, int, const char *, const char *); +int ldp_vty_label_allocate(struct vty *, int, int, const char *); +int ldp_vty_label_expnull(struct vty *, int, const char *); +int ldp_vty_label_accept(struct vty *, int, const char *, const char *); +int ldp_vty_ttl_security(struct vty *, int); +int ldp_vty_router_id(struct vty *, int, const char *); +int ldp_vty_ds_cisco_interop(struct vty *, int); +int ldp_vty_trans_pref_ipv4(struct vty *, int); +int ldp_vty_neighbor_password(struct vty *, int, const char *, const char *); +int ldp_vty_neighbor_ttl_security(struct vty *, int, const char *, const char *); +int ldp_vty_l2vpn(struct vty *, int, const char *); +int ldp_vty_l2vpn_bridge(struct vty *, int, const char *); +int ldp_vty_l2vpn_mtu(struct vty *, int, const char *); +int ldp_vty_l2vpn_pwtype(struct vty *, int, const char *); +int ldp_vty_l2vpn_interface(struct vty *, int, const char *); +int ldp_vty_l2vpn_pseudowire(struct vty *, int, const char *); +int ldp_vty_l2vpn_pw_cword(struct vty *, int, const char *); +int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, int, const char *); +int ldp_vty_l2vpn_pw_nbr_id(struct vty *, int, const char *); +int ldp_vty_l2vpn_pw_pwid(struct vty *, int, const char *); +int ldp_vty_l2vpn_pw_pwstatus(struct vty *, int); +int ldp_vty_clear_nbr(struct vty *, const char *); +int ldp_vty_debug(struct vty *, int, const char *, const char *, int); +int ldp_vty_show_binding(struct vty *, const char *, int, int); +int ldp_vty_show_discovery(struct vty *, const char *, int, int); +int ldp_vty_show_interface(struct vty *, const char *, int); +int ldp_vty_show_capabilities(struct vty *, int); +int ldp_vty_show_neighbor(struct vty *, int, int, int); +int ldp_vty_show_atom_binding(struct vty *, int); +int ldp_vty_show_atom_vc(struct vty *, int); +int ldp_vty_show_debugging(struct vty *); void ldp_vty_init(void); diff --git a/ldpd/ldp_vty.xml b/ldpd/ldp_vty.xml deleted file mode 100644 index cd5c92c7b1..0000000000 --- a/ldpd/ldp_vty.xml +++ /dev/null @@ -1,466 +0,0 @@ -<?xml version="1.0"?> -<file init="ldp_vty_init" cmdprefix="ldp" header="ldpd/ldp_vty.h"> - <!-- address-family --> - <options name="address-family"> - <option name="ipv4" help="IPv4 Address Family"/> - <option name="ipv6" help="IPv6 Address Family"/> - </options> - - <!-- ipv4/ipv6 address --> - <options name="addr"> - <option input="ipv4" help="IPv4 address"/> - <option input="ipv6" help="IPv6 address"/> - </options> - - <!-- pseudowire control-word options --> - <options name="cword"> - <option name="exclude" help="Exclude control-word in pseudowire packets"/> - <option name="include" help="Include control-word in pseudowire packets"/> - </options> - - <!-- pseudowire types --> - <options name="pwtype"> - <option name="ethernet" help="Ethernet (type 5)"/> - <option name="ethernet-tagged" help="Ethernet-tagged (type 4)"/> - </options> - - <!-- packet direction --> - <options name="dir"> - <option name="recv" help="Received messages"/> - <option name="sent" help="Sent messages"/> - </options> - - <!-- ACL --> - <options name="acl"> - <option input="acl_range" help="IP access-list number"/> - <option input="acl_expanded_range" help="IP access-list number (expanded range)"/> - <option input="word" help="IP access-list name"/> - </options> - - <!-- shared subtrees --> - <subtree name="label_local_acls"> - <option name="to" help="IP Access-list specifying controls on LDP Peers"> - <select options="acl" arg="to_acl" function="inherited"> - <option name="for" help="IP access-list for destination prefixes"> - <select options="acl" arg="for_acl" function="inherited"/> - </option> - </select> - </option> - <option name="for" help="IP access-list for destination prefixes"> - <select options="acl" arg="for_acl" function="inherited"> - <option name="to" help="IP Access-list specifying controls on LDP Peers"> - <select options="acl" arg="to_acl" function="inherited"/> - </option> - </select> - </option> - </subtree> - - <subtree name="label_remote_acls"> - <option name="from" help="Neighbor from whom to accept label advertisement"> - <select options="acl" arg="from_acl" function="inherited"> - <option name="for" help="IP access-list for destination prefixes"> - <select options="acl" arg="for_acl" function="inherited"/> - </option> - </select> - </option> - <option name="for" help="IP access-list for destination prefixes"> - <select options="acl" arg="for_acl" function="inherited"> - <option name="from" help="Neighbor from whom to accept label advertisement"> - <select options="acl" arg="from_acl" function="inherited"/> - </option> - </select> - </option> - </subtree> - - <subtree name="discovery_link"> - <option name="discovery" help="Configure discovery parameters"> - <option name="hello" arg="hello_type" help="LDP Link Hellos"> - <option name="holdtime" help="Hello holdtime"> - <option input="disc_time" arg="seconds" help="Time (seconds) - 65535 implies infinite" function="ldp_vty_disc_holdtime"/> - </option> - <option name="interval" help="Hello interval"> - <option input="disc_time" arg="seconds" help="Time (seconds)" function="ldp_vty_disc_interval"/> - </option> - </option> - </option> - </subtree> - - <subtree name="discovery_targeted"> - <option name="discovery" help="Configure discovery parameters"> - <option name="targeted-hello" arg="hello_type" help="LDP Targeted Hellos"> - <option name="holdtime" help="Targeted hello holdtime"> - <option input="disc_time" arg="seconds" help="Time (seconds) - 65535 implies infinite" function="ldp_vty_disc_holdtime"/> - </option> - <option name="interval" help="Targeted hello interval"> - <option input="disc_time" arg="seconds" help="Time (seconds)" function="ldp_vty_disc_interval"/> - </option> - </option> - </option> - </subtree> - - <subtree name="session_holdtime"> - <option name="session" help="Configure session parameters"> - <option name="holdtime" help="Configure session holdtime"> - <option input="session_time" arg="seconds" help="Time (seconds)" function="ldp_vty_session_holdtime"/> - </option> - </option> - </subtree> - - <subtree name="af_common"> - <include subtree="discovery_link"/> - <include subtree="discovery_targeted"/> - <option name="discovery" help="Configure discovery parameters"> - <option name="targeted-hello" arg="hello_type" help="LDP Targeted Hellos"> - <option name="accept" help="Accept and respond to targeted hellos" function="ldp_vty_targeted_hello_accept"> - <option name="from" help="Access list to specify acceptable targeted hello source"> - <select options="acl" arg="from_acl" function="inherited"/> - </option> - </option> - </option> - </option> - <option name="label" help="Configure label control and policies"> - <option name="local" help="Configure local label control and policies"> - <option name="advertise" help="Configure outbound label advertisement control" function="ldp_vty_label_advertise"> - <include subtree="label_local_acls"/> - <option name="explicit-null" help="Configure explicit-null advertisement" function="ldp_vty_label_expnull"> - <option name="for" help="IP access-list for destination prefixes"> - <select options="acl" arg="for_acl" function="inherited"/> - </option> - </option> - </option> - <option name="allocate" help="Configure label allocation control"> - <option name="for" help="IP access-list"> - <select options="acl" arg="for_acl" function="ldp_vty_label_allocate"/> - </option> - <option name="host-routes" arg="host-routes" help="allocate local label for host routes only" function="ldp_vty_label_allocate"/> - </option> - </option> - <option name="remote" help="Configure remote/peer label control and policies"> - <option name="accept" help="Configure inbound label acceptance control" function="ldp_vty_label_accept"> - <include subtree="label_remote_acls"/> - </option> - </option> - </option> - <option name="ttl-security" help="LDP ttl security check"> - <option name="disable" help="Disable ttl security" function="ldp_vty_ttl_security"/> - </option> - <include subtree="session_holdtime"/> - <option name="interface" help="Enable LDP on an interface and enter interface submode"> - <option input="ifname" arg="ifname" help="Interface's name" function="ldp_vty_interface"/> - </option> - </subtree> - - <!-- global --> - <subtree name="__global"> - <option name="mpls" help="Global MPLS configuration subcommands"> - <option name="ldp" help="Label Distribution Protocol" function="ldp_vty_mpls_ldp"/> - </option> - <option name="l2vpn" help="Configure l2vpn commands"> - <option input="word" arg="name" help="L2VPN name"> - <option name="type" help="L2VPN type"> - <option name="vpls" help="Virtual Private LAN Service" function="ldp_vty_l2vpn"/> - </option> - </option> - </option> - </subtree> - <tree name="global"> - <include subtree="__global"/> - <option name="no" arg="no" help="Negate a command or set its defaults"> - <include subtree="__global"/> - </option> - </tree> - - <!-- ldp node --> - <subtree name="__ldp_node"> - <option name="address-family" help="Configure Address Family and its parameters"> - <option name="ipv4" arg="address-family" help="IPv4" function="ldp_vty_address_family"/> - <option name="ipv6" arg="address-family" help="IPv6" function="ldp_vty_address_family"/> - </option> - <include subtree="discovery_link"/> - <include subtree="discovery_targeted"/> - <option name="dual-stack" help="Configure dual stack parameters"> - <option name="transport-connection" help="Configure TCP transport parameters"> - <option name="prefer" help="Configure prefered address family for TCP transport connection with neighbor"> - <option name="ipv4" help="IPv4" function="ldp_vty_trans_pref_ipv4"/> - </option> - </option> - <option name="cisco-interop" help="Use Cisco non-compliant format to send and interpret the Dual-Stack capability TLV" function="ldp_vty_ds_cisco_interop"/> - </option> - <option name="neighbor" help="Configure neighbor parameters"> - <option input="ipv4" arg="lsr_id" help="LDP Id of neighbor"> - <option name="password" help="Configure password for MD5 authentication"> - <option input="word" arg="password" help="The password" function="ldp_vty_neighbor_password"/> - </option> - <include subtree="session_holdtime"/> - <option name="ttl-security" help="LDP ttl security check"> - <option name="disable" help="Disable ttl security" function="ldp_vty_neighbor_ttl_security"/> - <option name="hops" help="IP hops"> - <option input="hops" arg="hops" help="maximum number of hops" function="ldp_vty_neighbor_ttl_security"/> - </option> - </option> - </option> - </option> - <option name="router-id" help="Configure router Id"> - <option input="ipv4" arg="addr" help="LSR Id (in form of an IPv4 address)" function="ldp_vty_router_id"/> - </option> - </subtree> - <tree name="ldp_node"> - <include subtree="__ldp_node"/> - <option name="no" arg="no" help="Negate a command or set its defaults"> - <include subtree="__ldp_node"/> - </option> - </tree> - - <!-- address-family ipv4 --> - <subtree name="__ldp_ipv4_node"> - <include subtree="af_common"/> - <option name="discovery" help="Configure discovery parameters"> - <option name="transport-address" help="Specify transport address for TCP connection"> - <option input="ipv4" arg="addr" help="IP address to be used as transport address" function="ldp_vty_trans_addr"/> - </option> - </option> - <option name="neighbor" help="Configure neighbor parameters"> - <option input="ipv4" arg="addr" help="IP address of neighbor"> - <option name="targeted" help="Establish targeted session" function="ldp_vty_neighbor_targeted"/> - </option> - </option> - </subtree> - <tree name="ldp_ipv4_node"> - <include subtree="__ldp_ipv4_node"/> - <option name="no" arg="no" help="Negate a command or set its defaults"> - <include subtree="__ldp_ipv4_node"/> - </option> - </tree> - - <!-- address-family ipv6 --> - <subtree name="__ldp_ipv6_node"> - <include subtree="af_common"/> - <option name="discovery" help="Configure discovery parameters"> - <option name="transport-address" help="Specify transport address for TCP connection"> - <option input="ipv6" arg="addr" help="IPv6 address to be used as transport address" function="ldp_vty_trans_addr"/> - </option> - </option> - <option name="neighbor" help="Configure neighbor parameters"> - <option input="ipv6" arg="addr" help="IPv6 address of neighbor"> - <option name="targeted" help="Establish targeted session" function="ldp_vty_neighbor_targeted"/> - </option> - </option> - </subtree> - <tree name="ldp_ipv6_node"> - <include subtree="__ldp_ipv6_node"/> - <option name="no" arg="no" help="Negate a command or set its defaults"> - <include subtree="__ldp_ipv6_node"/> - </option> - </tree> - - <!-- ldp ipv4 interface node --> - <subtree name="__ldp_ipv4_iface_node"> - <include subtree="discovery_link"/> - </subtree> - <tree name="ldp_ipv4_iface_node"> - <include subtree="__ldp_ipv4_iface_node"/> - <option name="no" arg="no" help="Negate a command or set its defaults"> - <include subtree="__ldp_ipv4_iface_node"/> - </option> - </tree> - - <!-- ldp ipv6 interface node --> - <subtree name="__ldp_ipv6_iface_node"> - <include subtree="discovery_link"/> - </subtree> - <tree name="ldp_ipv6_iface_node"> - <include subtree="__ldp_ipv6_iface_node"/> - <option name="no" arg="no" help="Negate a command or set its defaults"> - <include subtree="__ldp_ipv6_iface_node"/> - </option> - </tree> - - <!-- l2vpn --> - <subtree name="__ldp_l2vpn"> - <option name="bridge" help="Bridge interface"> - <option input="ifname" arg="ifname" help="Interface's name" function="ldp_vty_l2vpn_bridge"/> - </option> - <option name="mtu" help="set Maximum Transmission Unit"> - <option input="mtu" arg="mtu" help="Maximum Transmission Unit value" function="ldp_vty_l2vpn_mtu"/> - </option> - <option name="member" help="L2VPN member configuration"> - <option name="interface" help="Local interface"> - <option input="ifname" arg="ifname" help="Interface's name" function="ldp_vty_l2vpn_interface"/> - </option> - <option name="pseudowire" help="Pseudowire interface"> - <option input="ifname" arg="ifname" help="Interface's name" function="ldp_vty_l2vpn_pseudowire"/> - </option> - </option> - <option name="vc" help="Virtual Circuit options"> - <option name="type" help="Virtual Circuit type to use"> - <select options="pwtype" arg="type" function="ldp_vty_l2vpn_pwtype"/> - </option> - </option> - </subtree> - <tree name="ldp_l2vpn"> - <include subtree="__ldp_l2vpn"/> - <option name="no" arg="no" help="Negate a command or set its defaults"> - <include subtree="__ldp_l2vpn"/> - </option> - </tree> - - <!-- l2vpn pseudowire --> - <subtree name="__ldp_pseudowire"> - <option name="control-word" help="Control-word options"> - <select options="cword" arg="preference" function="ldp_vty_l2vpn_pw_cword"/> - </option> - <option name="neighbor" help="Remote endpoint configuration"> - <option name="address" help="Specify the IPv4 or IPv6 address of the remote endpoint"> - <select options="addr" arg="addr" function="ldp_vty_l2vpn_pw_nbr_addr"/> - </option> - <option name="lsr-id" help="Specify the LSR-ID of the remote endpoint"> - <option input="ipv4" arg="lsr-id" help="IPv4 address" function="ldp_vty_l2vpn_pw_nbr_id"/> - </option> - </option> - <option name="pw-id" help="Set the Virtual Circuit ID"> - <option input="pwid" arg="pwid" help="Virtual Circuit ID value" function="ldp_vty_l2vpn_pw_pwid"/> - </option> - <option name="pw-status" help="Configure PW status"> - <option name="disable" help="Disable PW status" function="ldp_vty_l2vpn_pw_pwstatus"/> - </option> - </subtree> - <tree name="ldp_pseudowire"> - <include subtree="__ldp_pseudowire"/> - <option name="no" arg="no" help="Negate a command or set its defaults"> - <include subtree="__ldp_pseudowire"/> - </option> - </tree> - - <!-- exec mode commands --> - <subtree name="ldp_show_af"> - <option name="binding" help="Label Information Base (LIB) information" function="ldp_vty_show_binding"> - <option name="json" arg="json" help="JavaScript Object Notation" function="ldp_vty_show_binding"/> - <option name="detail" arg="detail" help="Show detailed information"> - <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_binding"/> - </option> - </option> - <option name="discovery" help="Discovery Hello Information" function="ldp_vty_show_discovery"> - <option name="json" arg="json" help="JavaScript Object Notation" function="ldp_vty_show_discovery"/> - <option name="detail" arg="detail" help="Show detailed information"> - <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_discovery"/> - </option> - </option> - <option name="interface" help="interface information"> - <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_interface"/> - </option> - </subtree> - <tree name="ldp_exec"> - <option name="show" help="Show running system information"> - <option name="mpls" help="MPLS information"> - <option name="ldp" help="Label Distribution Protocol"> - <option name="capabilities" help="Display LDP Capabilities information"> - <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_capabilities"/> - </option> - <option name="neighbor" help="Neighbor information" function="ldp_vty_show_neighbor"> - <option name="capabilities" arg="capabilities" help="Display neighbor capability information"> - <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_neighbor"/> - </option> - <option name="json" arg="json" help="JavaScript Object Notation" function="ldp_vty_show_neighbor"/> - <option name="detail" arg="detail" help="Show detailed information"> - <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_neighbor"/> - </option> - </option> - <include subtree="ldp_show_af"/> - <select options="address-family" arg="address-family"> - <include subtree="ldp_show_af"/> - </select> - </option> - </option> - <option name="l2vpn" help="Show information about Layer2 VPN"> - <option name="atom" help="Show Any Transport over MPLS information"> - <option name="binding" help="Show AToM label binding information"> - <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_atom_binding"/> - </option> - <option name="vc" help="Show AToM virtual circuit information"> - <option name="json" arg="json" optional="true" help="JavaScript Object Notation" function="ldp_vty_show_atom_vc"/> - </option> - </option> - </option> - <option name="debugging" help="Debugging functions"> - <option name="mpls" help="MPLS information"> - <option name="ldp" help="Label Distribution Protocol" function="ldp_vty_show_debugging"/> - </option> - </option> - </option> - <option name="clear" help="Reset functions"> - <option name="mpls" help="Reset MPLS statistical information"> - <option name="ldp" help="Clear LDP state"> - <option name="neighbor" help="Clear LDP neighbor sessions" function="ldp_vty_clear_nbr"> - <select options="addr" arg="addr" function="ldp_vty_clear_nbr"/> - </option> - </option> - </option> - </option> - </tree> - - <!-- debug commands --> - <subtree name="__ldp_debug"> - <option name="debug" help="Debugging functions"> - <option name="mpls" help="MPLS information"> - <option name="ldp" help="Label Distribution Protocol"> - <option name="discovery" arg="type" help="Discovery messages"> - <option name="hello" help="Discovery hello message"> - <select options="dir" arg="dir" function="ldp_vty_debug"/> - </option> - </option> - <option name="errors" arg="type" help="Errors" function="ldp_vty_debug"/> - <option name="event" arg="type" help="LDP event information" function="ldp_vty_debug"/> - <option name="messages" arg="type" help="Messages"> - <option name="recv" arg="dir" help="Received messages, excluding periodic Keep Alives" function="ldp_vty_debug"> - <option name="all" arg="all" help="Received messages, including periodic Keep Alives" function="ldp_vty_debug"/> - </option> - <option name="sent" arg="dir" help="Sent messages, excluding periodic Keep Alives" function="ldp_vty_debug"> - <option name="all" arg="all" help="Sent messages, including periodic Keep Alives" function="ldp_vty_debug"/> - </option> - </option> - <option name="zebra" arg="type" help="LDP zebra information" function="ldp_vty_debug"/> - </option> - </option> - </option> - </subtree> - <tree name="ldp_debug"> - <include subtree="__ldp_debug"/> - <option name="no" arg="no" help="Negate a command or set its defaults"> - <include subtree="__ldp_debug"/> - </option> - </tree> - - <!-- nodes --> - <node name="CONFIG"> - <include tree="global"/> - <include tree="ldp_debug"/> - </node> - <node install="1" install_default="1" config_write="ldp_config_write" name="LDP"> - <include tree="ldp_node"/> - </node> - <node install="1" install_default="1" config_write="NULL" name="LDP_IPV4"> - <include tree="ldp_ipv4_node"/> - </node> - <node install="1" install_default="1" config_write="NULL" name="LDP_IPV6"> - <include tree="ldp_ipv6_node"/> - </node> - <node install="1" install_default="1" config_write="NULL" name="LDP_IPV4_IFACE"> - <include tree="ldp_ipv4_iface_node"/> - </node> - <node install="1" install_default="1" config_write="NULL" name="LDP_IPV6_IFACE"> - <include tree="ldp_ipv6_iface_node"/> - </node> - <node install="1" install_default="1" config_write="ldp_l2vpn_config_write" name="LDP_L2VPN"> - <include tree="ldp_l2vpn"/> - </node> - <node install="1" install_default="1" config_write="NULL" name="LDP_PSEUDOWIRE"> - <include tree="ldp_pseudowire"/> - </node> - <node install="1" config_write="ldp_debug_config_write" name="LDP_DEBUG"/> - <node name="ENABLE"> - <include tree="ldp_debug"/> - </node> - <node name="VIEW"> - <include tree="ldp_exec"/> - </node> -</file> diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c new file mode 100644 index 0000000000..d28424cbb7 --- /dev/null +++ b/ldpd/ldp_vty_cmds.c @@ -0,0 +1,1132 @@ +/* + * Copyright (C) 2016 by Open Source Routing. + * + * 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; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "command.h" +#include "vty.h" +#include "ldpd/ldp_vty.h" + +DEFUN_NOSH(ldp_mpls_ldp, + ldp_mpls_ldp_cmd, + "[no] mpls ldp", + "Negate a command or set its defaults\n" + "Global MPLS configuration subcommands\n" + "Label Distribution Protocol\n") +{ + int idx = 0; + int negate = 0; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + + return (ldp_vty_mpls_ldp(vty, negate)); +} + +DEFUN_NOSH(ldp_l2vpn, + ldp_l2vpn_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") +{ + int idx = 0; + int negate = 0; + const char *name; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "WORD", &idx); + name = argv[idx]->arg; + + return (ldp_vty_l2vpn(vty, negate, name)); +} + +DEFUN_NOSH(ldp_address_family, + ldp_address_family_cmd, + "[no] address-family <ipv4|ipv6>", + "Negate a command or set its defaults\n" + "Configure Address Family and its parameters\n" + "IPv4\n" + "IPv6\n") +{ + int idx = 0; + int negate = 0; + const char *af; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "address-family", &idx); + af = argv[idx + 1]->text; + + return (ldp_vty_address_family(vty, negate, af)); +} + +DEFUN (ldp_discovery_holdtime, + ldp_discovery_holdtime_cmd, + "[no] discovery <hello|targeted-hello> holdtime (1-65535)", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "LDP Link Hellos\n" + "LDP Targeted Hellos\n" + "Hello holdtime\n" + "Time (seconds) - 65535 implies infinite\n") +{ + int idx = 0; + int negate = 0; + const char *hello_type; + const char *holdtime; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "discovery", &idx); + hello_type = argv[idx + 1]->text; + argv_find(argv, argc, "(1-65535)", &idx); + holdtime = argv[idx]->arg; + + return (ldp_vty_disc_holdtime(vty, negate, hello_type, holdtime)); +} + +DEFUN (ldp_discovery_interval, + ldp_discovery_interval_cmd, + "[no] discovery <hello|targeted-hello> interval (1-65535)", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "LDP Link Hellos\n" + "LDP Targeted Hellos\n" + "Hello interval\n" + "Time (seconds)\n") +{ + int idx = 0; + int negate = 0; + const char *hello_type; + const char *interval; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "discovery", &idx); + hello_type = argv[idx + 1]->text; + argv_find(argv, argc, "(1-65535)", &idx); + interval = argv[idx]->arg; + + return (ldp_vty_disc_interval(vty, negate, hello_type, interval)); +} + +DEFUN (ldp_dual_stack_transport_connection_prefer_ipv4, + ldp_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") +{ + int idx = 0; + int negate = 0; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + + return (ldp_vty_trans_pref_ipv4(vty, negate)); +} + +DEFUN (ldp_dual_stack_cisco_interop, + ldp_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") +{ + int idx = 0; + int negate = 0; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + + return (ldp_vty_ds_cisco_interop(vty, negate)); +} + +DEFUN (ldp_neighbor_password, + ldp_neighbor_password_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") +{ + int idx = 0; + int negate = 0; + const char *neighbor; + const char *password; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "A.B.C.D", &idx); + neighbor = argv[idx]->arg; + argv_find(argv, argc, "WORD", &idx); + password = argv[idx]->arg; + + return (ldp_vty_neighbor_password(vty, negate, neighbor, password)); +} + +DEFUN (ldp_neighbor_session_holdtime, + ldp_neighbor_session_holdtime_cmd, + "[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") +{ + int idx = 0; + int negate = 0; + const char *neighbor; + const char *holdtime; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "A.B.C.D", &idx); + neighbor = argv[idx]->arg; + argv_find(argv, argc, "(15-65535)", &idx); + holdtime = argv[idx]->arg; + + return (ldp_vty_nbr_session_holdtime(vty, negate, neighbor, holdtime)); +} + +DEFUN (ldp_neighbor_ttl_security, + ldp_neighbor_ttl_security_cmd, + "[no] neighbor A.B.C.D ttl-security <disable|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" + "Disable ttl security\n" + "IP hops\n" + "maximum number of hops\n") +{ + int idx = 0; + int negate = 0; + const char *neighbor; + const char *hops = NULL; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "A.B.C.D", &idx); + neighbor = argv[idx]->arg; + if (argv_find(argv, argc, "(1-254)", &idx)) + hops = argv[idx]->arg; + + return (ldp_vty_neighbor_ttl_security(vty, negate, neighbor, hops)); +} + +DEFUN (ldp_router_id, + ldp_router_id_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") +{ + int idx = 0; + int negate = 0; + const char *address; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "A.B.C.D", &idx); + address = argv[idx]->arg; + + return (ldp_vty_router_id(vty, negate, address)); +} + +DEFUN (ldp_discovery_targeted_hello_accept, + ldp_discovery_targeted_hello_accept_cmd, + "[no] discovery targeted-hello accept [from <(1-199)|(1300-2699)|WORD>]", + "Negate a command or set its defaults\n" + "Configure discovery parameters\n" + "LDP Targeted Hellos\n" + "Accept and respond to targeted hellos\n" + "Access list to specify acceptable targeted hello source\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP access-list name\n") +{ + int idx = 0; + int negate = 0; + const char *from_acl = NULL; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + if (argv_find(argv, argc, "from", &idx)) + from_acl = argv[idx + 1]->arg; + + return (ldp_vty_targeted_hello_accept(vty, negate, from_acl)); +} + +DEFUN (ldp_discovery_transport_address_ipv4, + ldp_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") +{ + int idx = 0; + int negate = 0; + const char *address; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "A.B.C.D", &idx); + address = argv[idx]->arg; + + return (ldp_vty_trans_addr(vty, negate, address)); +} + +DEFUN (ldp_discovery_transport_address_ipv6, + ldp_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") +{ + int idx = 0; + int negate = 0; + const char *address; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "X:X::X:X", &idx); + address = argv[idx]->arg; + + return (ldp_vty_trans_addr(vty, negate, address)); +} + +DEFUN (ldp_label_local_advertise, + ldp_label_local_advertise_cmd, + "[no] label local advertise [{to <(1-199)|(1300-2699)|WORD>|for <(1-199)|(1300-2699)|WORD>}]", + "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" + "IP Access-list specifying controls on LDP Peers\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP access-list name\n" + "IP access-list for destination prefixes\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP access-list name\n") +{ + int idx = 0; + int negate = 0; + const char *to_acl = NULL; + const char *for_acl = NULL; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + + /* arguments within curly braces may be provided in any order */ + if (argv_find(argv, argc, "to", &idx)) + to_acl = argv[idx + 1]->arg; + idx = 0; + if (argv_find(argv, argc, "for", &idx)) + for_acl = argv[idx + 1]->arg; + + return (ldp_vty_label_advertise(vty, negate, to_acl, for_acl)); +} + +DEFUN (ldp_label_local_advertise_explicit_null, + ldp_label_local_advertise_explicit_null_cmd, + "[no] label local advertise explicit-null [for <(1-199)|(1300-2699)|WORD>]", + "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" + "IP access-list for destination prefixes\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP access-list name\n") +{ + int idx = 0; + int negate = 0; + const char *for_acl = NULL; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + if (argv_find(argv, argc, "for", &idx)) + for_acl = argv[idx + 1]->arg; + + return (ldp_vty_label_expnull(vty, negate, for_acl)); +} + +DEFUN (ldp_label_local_allocate, + ldp_label_local_allocate_cmd, + "[no] label local allocate <host-routes|for <(1-199)|(1300-2699)|WORD>>", + "Negate a command or set its defaults\n" + "Configure label control and policies\n" + "Configure local label control and policies\n" + "Configure label allocation control\n" + "allocate local label for host routes only\n" + "IP access-list\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP access-list name\n") +{ + int idx = 0; + int negate = 0; + int host_routes = 0; + const char *for_acl = NULL; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + + /* arguments within curly braces may be provided in any order */ + if (argv_find(argv, argc, "host-routes", &idx)) + host_routes = 1; + idx = 0; + if (argv_find(argv, argc, "for", &idx)) + for_acl = argv[idx + 1]->arg; + + return (ldp_vty_label_allocate(vty, negate, host_routes, for_acl)); +} + +DEFUN (ldp_label_remote_accept, + ldp_label_remote_accept_cmd, + "[no] label remote accept {from <(1-199)|(1300-2699)|WORD>|for <(1-199)|(1300-2699)|WORD>}", + "Negate a command or set its defaults\n" + "Configure label control and policies\n" + "Configure remote/peer label control and policies\n" + "Configure inbound label acceptance control\n" + "Neighbor from whom to accept label advertisement\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP access-list name\n" + "IP access-list for destination prefixes\n" + "IP access-list number\n" + "IP access-list number (expanded range)\n" + "IP access-list name\n") +{ + int idx = 0; + int negate = 0; + const char *from_acl = NULL; + const char *for_acl = NULL; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + + /* arguments within curly braces may be provided in any order */ + if (argv_find(argv, argc, "from", &idx)) + from_acl = argv[idx + 1]->arg; + idx = 0; + if (argv_find(argv, argc, "for", &idx)) + for_acl = argv[idx + 1]->arg; + + return (ldp_vty_label_accept(vty, negate, from_acl, for_acl)); +} + +DEFUN (ldp_ttl_security_disable, + ldp_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") +{ + int idx = 0; + int negate = 0; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + + return (ldp_vty_ttl_security(vty, negate)); +} + +DEFUN (ldp_session_holdtime, + ldp_session_holdtime_cmd, + "[no] session holdtime (15-65535)", + "Negate a command or set its defaults\n" + "Configure session parameters\n" + "Configure session holdtime\n" + "Time (seconds)\n") +{ + int idx = 0; + int negate = 0; + const char *holdtime; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "(15-65535)", &idx); + holdtime = argv[idx]->arg; + + return (ldp_vty_af_session_holdtime(vty, negate, holdtime)); +} + +DEFUN_NOSH(ldp_interface, + ldp_interface_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") +{ + int idx = 0; + int negate = 0; + const char *ifname; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "IFNAME", &idx); + ifname = argv[idx]->arg; + + return (ldp_vty_interface(vty, negate, ifname)); +} + +DEFUN (ldp_neighbor_ipv4_targeted, + ldp_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") +{ + int idx = 0; + int negate = 0; + const char *address; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "A.B.C.D", &idx); + address = argv[idx]->arg; + + return (ldp_vty_neighbor_targeted(vty, negate, address)); +} + +DEFUN (ldp_neighbor_ipv6_targeted, + ldp_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") +{ + int idx = 0; + int negate = 0; + const char *address; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "X:X::X:X", &idx); + address = argv[idx]->arg; + + return (ldp_vty_neighbor_targeted(vty, negate, address)); +} + +DEFUN (ldp_bridge, + ldp_bridge_cmd, + "[no] bridge IFNAME", + "Negate a command or set its defaults\n" + "Bridge interface\n" + "Interface's name\n") +{ + int idx = 0; + int negate = 0; + const char *ifname; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "IFNAME", &idx); + ifname = argv[idx]->arg; + + return (ldp_vty_l2vpn_bridge(vty, negate, ifname)); +} + +DEFUN (ldp_mtu, + ldp_mtu_cmd, + "[no] mtu (1500-9180)", + "Negate a command or set its defaults\n" + "Set Maximum Transmission Unit\n" + "Maximum Transmission Unit value\n") +{ + int idx = 0; + int negate = 0; + const char *mtu; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "(1500-9180)", &idx); + mtu = argv[idx]->arg; + + return (ldp_vty_l2vpn_mtu(vty, negate, mtu)); +} + +DEFUN (ldp_member_interface, + ldp_member_interface_cmd, + "[no] member interface IFNAME", + "Negate a command or set its defaults\n" + "L2VPN member configuration\n" + "Local interface\n" + "Interface's name\n") +{ + int idx = 0; + int negate = 0; + const char *ifname; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "IFNAME", &idx); + ifname = argv[idx]->arg; + + return (ldp_vty_l2vpn_interface(vty, negate, ifname)); +} + +DEFUN_NOSH(ldp_member_pseudowire, + ldp_member_pseudowire_cmd, + "[no] member pseudowire IFNAME", + "Negate a command or set its defaults\n" + "L2VPN member configuration\n" + "Pseudowire interface\n" + "Interface's name\n") +{ + int idx = 0; + int negate = 0; + const char *ifname; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "IFNAME", &idx); + ifname = argv[idx]->arg; + + return (ldp_vty_l2vpn_pseudowire(vty, negate, ifname)); +} + +DEFUN (ldp_vc_type, + ldp_vc_type_cmd, + "[no] vc type <ethernet|ethernet-tagged>", + "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") +{ + int idx = 0; + int negate = 0; + const char *vc_type; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "type", &idx); + vc_type = argv[idx + 1]->text; + + return (ldp_vty_l2vpn_pwtype(vty, negate, vc_type)); +} + +DEFUN (ldp_control_word, + ldp_control_word_cmd, + "[no] control-word <exclude|include>", + "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") +{ + int idx = 0; + int negate = 0; + const char *preference; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "control-word", &idx); + preference = argv[idx + 1]->text; + + return (ldp_vty_l2vpn_pw_cword(vty, negate, preference)); +} + +DEFUN (ldp_neighbor_address, + ldp_neighbor_address_cmd, + "[no] neighbor address <A.B.C.D|X:X::X:X>", + "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") +{ + int idx = 0; + int negate = 0; + const char *address; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "address", &idx); + address = argv[idx + 1]->arg; + + return (ldp_vty_l2vpn_pw_nbr_addr(vty, negate, address)); +} + +DEFUN (ldp_neighbor_lsr_id, + ldp_neighbor_lsr_id_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") +{ + int idx = 0; + int negate = 0; + const char *address; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "A.B.C.D", &idx); + address = argv[idx]->arg; + + return (ldp_vty_l2vpn_pw_nbr_id(vty, negate, address)); +} + +DEFUN (ldp_pw_id, + ldp_pw_id_cmd, + "[no] pw-id (1-4294967295)", + "Negate a command or set its defaults\n" + "Set the Virtual Circuit ID\n" + "Virtual Circuit ID value\n") +{ + int idx = 0; + int negate = 0; + const char *pwid; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "(1-4294967295)", &idx); + pwid = argv[idx]->arg; + + return (ldp_vty_l2vpn_pw_pwid(vty, negate, pwid)); +} + +DEFUN (ldp_pw_status_disable, + ldp_pw_status_disable_cmd, + "[no] pw-status disable", + "Negate a command or set its defaults\n" + "Configure PW status\n" + "Disable PW status\n") +{ + int idx = 0; + int negate = 0; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + + return (ldp_vty_l2vpn_pw_pwstatus(vty, negate)); +} + +DEFUN (ldp_clear_mpls_ldp_neighbor, + ldp_clear_mpls_ldp_neighbor_cmd, + "clear mpls ldp neighbor [<A.B.C.D|X:X::X:X>]", + "Reset functions\n" + "Reset MPLS statistical information\n" + "Clear LDP state\n" + "Clear LDP neighbor sessions\n" + "IPv4 address\n" + "IPv6 address\n") +{ + int idx = 0; + const char *address = NULL; + + if (argv_find(argv, argc, "neighbor", &idx)) + address = argv[idx + 1]->arg; + + return (ldp_vty_clear_nbr(vty, address)); +} + +DEFUN (ldp_debug_mpls_ldp_discovery_hello, + ldp_debug_mpls_ldp_discovery_hello_cmd, + "[no] debug mpls ldp discovery hello <recv|sent>", + "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") +{ + int idx = 0; + int negate = 0; + const char *dir; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "hello", &idx); + dir = argv[idx + 1]->text; + + return (ldp_vty_debug(vty, negate, "discovery", dir, 0)); +} + +DEFUN (ldp_debug_mpls_ldp_type, + ldp_debug_mpls_ldp_type_cmd, + "[no] debug mpls ldp <errors|event|zebra>", + "Negate a command or set its defaults\n" + "Debugging functions\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Errors\n" + "LDP event information\n" + "LDP zebra information\n") +{ + int idx = 0; + int negate = 0; + const char *type; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + argv_find(argv, argc, "ldp", &idx); + type = argv[idx + 1]->text; + + return (ldp_vty_debug(vty, negate, type, NULL, 0)); +} + +DEFUN (ldp_debug_mpls_ldp_messages_recv, + ldp_debug_mpls_ldp_messages_recv_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") +{ + int idx = 0; + int negate = 0; + int all = 0; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + if (argv_find(argv, argc, "all", &idx)) + all = 1; + + return (ldp_vty_debug(vty, negate, "messages", "recv", all)); +} + +DEFUN (ldp_debug_mpls_ldp_messages_sent, + ldp_debug_mpls_ldp_messages_sent_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") +{ + int idx = 0; + int negate = 0; + int all = 0; + + if (argv_find(argv, argc, "no", &idx)) + negate = 1; + if (argv_find(argv, argc, "all", &idx)) + all = 1; + + return (ldp_vty_debug(vty, negate, "messages", "sent", all)); +} + +DEFUN (ldp_show_mpls_ldp_binding, + ldp_show_mpls_ldp_binding_cmd, + "show mpls ldp [<ipv4|ipv6>] binding [detail] [json]", + "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" + "Show detailed information\n" + "JavaScript Object Notation\n") +{ + int idx = 0; + const char *af = NULL; + int detail = 0; + int json = 0; + + if (argv_find(argv, argc, "ipv4", &idx) || + argv_find(argv, argc, "ipv6", &idx)) + af = argv[idx]->text; + if (argv_find(argv, argc, "detail", &idx)) + detail = 1; + if (argv_find(argv, argc, "json", &idx)) + json = 1; + + return (ldp_vty_show_binding(vty, af, detail, json)); +} + +DEFUN (ldp_show_mpls_ldp_discovery, + ldp_show_mpls_ldp_discovery_cmd, + "show mpls ldp [<ipv4|ipv6>] discovery [detail] [json]", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "IPv4 Address Family\n" + "IPv6 Address Family\n" + "Discovery Hello Information\n" + "Show detailed information\n" + "JavaScript Object Notation\n") +{ + int idx = 0; + const char *af = NULL; + int detail = 0; + int json = 0; + + if (argv_find(argv, argc, "ipv4", &idx) || + argv_find(argv, argc, "ipv6", &idx)) + af = argv[idx]->text; + if (argv_find(argv, argc, "detail", &idx)) + detail = 1; + if (argv_find(argv, argc, "json", &idx)) + json = 1; + + return (ldp_vty_show_discovery(vty, af, detail, json)); +} + +DEFUN (ldp_show_mpls_ldp_interface, + ldp_show_mpls_ldp_interface_cmd, + "show mpls ldp [<ipv4|ipv6>] interface [json]", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "IPv4 Address Family\n" + "IPv6 Address Family\n" + "interface information\n" + "JavaScript Object Notation\n") +{ + int idx = 0; + const char *af = NULL; + int json = 0; + + if (argv_find(argv, argc, "ipv4", &idx) || + argv_find(argv, argc, "ipv6", &idx)) + af = argv[idx]->text; + if (argv_find(argv, argc, "json", &idx)) + json = 1; + + return (ldp_vty_show_interface(vty, af, json)); +} + +DEFUN (ldp_show_mpls_ldp_capabilities, + ldp_show_mpls_ldp_capabilities_cmd, + "show mpls ldp capabilities [json]", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Display LDP Capabilities information\n" + "JavaScript Object Notation\n") +{ + int idx = 0; + int json = 0; + + if (argv_find(argv, argc, "json", &idx)) + json = 1; + + return (ldp_vty_show_capabilities(vty, json)); +} + +DEFUN (ldp_show_mpls_ldp_neighbor, + ldp_show_mpls_ldp_neighbor_cmd, + "show mpls ldp neighbor [detail] [json]", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Neighbor information\n" + "Show detailed information\n" + "JavaScript Object Notation\n") +{ + int idx = 0; + int detail = 0; + int json = 0; + + if (argv_find(argv, argc, "detail", &idx)) + detail = 1; + if (argv_find(argv, argc, "json", &idx)) + json = 1; + + return (ldp_vty_show_neighbor(vty, 0, detail, json)); +} + +DEFUN (ldp_show_mpls_ldp_neighbor_capabilities, + ldp_show_mpls_ldp_neighbor_capabilities_cmd, + "show mpls ldp neighbor capabilities [json]", + "Show running system information\n" + "MPLS information\n" + "Label Distribution Protocol\n" + "Neighbor information\n" + "Display neighbor capability information\n" + "JavaScript Object Notation\n") +{ + int idx = 0; + int json = 0; + + if (argv_find(argv, argc, "json", &idx)) + json = 1; + + return (ldp_vty_show_neighbor(vty, 1, 0, json)); +} + +DEFUN (ldp_show_l2vpn_atom_binding, + ldp_show_l2vpn_atom_binding_cmd, + "show l2vpn atom binding [json]", + "Show running system information\n" + "Show information about Layer2 VPN\n" + "Show Any Transport over MPLS information\n" + "Show AToM label binding information\n" + "JavaScript Object Notation\n") +{ + int idx = 0; + int json = 0; + + if (argv_find(argv, argc, "json", &idx)) + json = 1; + + return (ldp_vty_show_atom_binding(vty, json)); +} + +DEFUN (ldp_show_l2vpn_atom_vc, + ldp_show_l2vpn_atom_vc_cmd, + "show l2vpn atom vc [json]", + "Show running system information\n" + "Show information about Layer2 VPN\n" + "Show Any Transport over MPLS information\n" + "Show AToM virtual circuit information\n" + "JavaScript Object Notation\n") +{ + int idx = 0; + int json = 0; + + if (argv_find(argv, argc, "json", &idx)) + json = 1; + + return (ldp_vty_show_atom_vc(vty, json)); +} + +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") +{ + return (ldp_vty_show_debugging(vty)); +} + +void +ldp_vty_init (void) +{ + install_node(&ldp_node, ldp_config_write); + install_node(&ldp_ipv4_node, NULL); + install_node(&ldp_ipv6_node, NULL); + install_node(&ldp_ipv4_iface_node, NULL); + install_node(&ldp_ipv6_iface_node, NULL); + install_node(&ldp_l2vpn_node, ldp_l2vpn_config_write); + install_node(&ldp_pseudowire_node, NULL); + install_node(&ldp_debug_node, ldp_debug_config_write); + install_default(LDP_NODE); + install_default(LDP_IPV4_NODE); + install_default(LDP_IPV6_NODE); + install_default(LDP_IPV4_IFACE_NODE); + install_default(LDP_IPV6_IFACE_NODE); + install_default(LDP_L2VPN_NODE); + install_default(LDP_PSEUDOWIRE_NODE); + + install_element(CONFIG_NODE, &ldp_mpls_ldp_cmd); + install_element(CONFIG_NODE, &ldp_l2vpn_cmd); + install_element(CONFIG_NODE, &ldp_debug_mpls_ldp_discovery_hello_cmd); + install_element(CONFIG_NODE, &ldp_debug_mpls_ldp_type_cmd); + install_element(CONFIG_NODE, &ldp_debug_mpls_ldp_messages_recv_cmd); + install_element(CONFIG_NODE, &ldp_debug_mpls_ldp_messages_sent_cmd); + + install_element(LDP_NODE, &ldp_address_family_cmd); + install_element(LDP_NODE, &ldp_discovery_holdtime_cmd); + install_element(LDP_NODE, &ldp_discovery_interval_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_password_cmd); + install_element(LDP_NODE, &ldp_neighbor_session_holdtime_cmd); + install_element(LDP_NODE, &ldp_neighbor_ttl_security_cmd); + install_element(LDP_NODE, &ldp_router_id_cmd); + + install_element(LDP_IPV4_NODE, &ldp_discovery_holdtime_cmd); + install_element(LDP_IPV4_NODE, &ldp_discovery_interval_cmd); + install_element(LDP_IPV4_NODE, &ldp_discovery_targeted_hello_accept_cmd); + install_element(LDP_IPV4_NODE, &ldp_discovery_transport_address_ipv4_cmd); + install_element(LDP_IPV4_NODE, &ldp_label_local_advertise_cmd); + install_element(LDP_IPV4_NODE, &ldp_label_local_advertise_explicit_null_cmd); + install_element(LDP_IPV4_NODE, &ldp_label_local_allocate_cmd); + install_element(LDP_IPV4_NODE, &ldp_label_remote_accept_cmd); + install_element(LDP_IPV4_NODE, &ldp_ttl_security_disable_cmd); + install_element(LDP_IPV4_NODE, &ldp_interface_cmd); + install_element(LDP_IPV4_NODE, &ldp_session_holdtime_cmd); + install_element(LDP_IPV4_NODE, &ldp_neighbor_ipv4_targeted_cmd); + + install_element(LDP_IPV6_NODE, &ldp_discovery_holdtime_cmd); + install_element(LDP_IPV6_NODE, &ldp_discovery_interval_cmd); + install_element(LDP_IPV6_NODE, &ldp_discovery_targeted_hello_accept_cmd); + install_element(LDP_IPV6_NODE, &ldp_discovery_transport_address_ipv6_cmd); + install_element(LDP_IPV6_NODE, &ldp_label_local_advertise_cmd); + install_element(LDP_IPV6_NODE, &ldp_label_local_advertise_explicit_null_cmd); + install_element(LDP_IPV6_NODE, &ldp_label_local_allocate_cmd); + install_element(LDP_IPV6_NODE, &ldp_label_remote_accept_cmd); + install_element(LDP_IPV6_NODE, &ldp_ttl_security_disable_cmd); + install_element(LDP_IPV6_NODE, &ldp_interface_cmd); + install_element(LDP_IPV6_NODE, &ldp_session_holdtime_cmd); + install_element(LDP_IPV6_NODE, &ldp_neighbor_ipv6_targeted_cmd); + + install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_holdtime_cmd); + install_element(LDP_IPV4_IFACE_NODE, &ldp_discovery_interval_cmd); + + install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_holdtime_cmd); + install_element(LDP_IPV6_IFACE_NODE, &ldp_discovery_interval_cmd); + + install_element(LDP_L2VPN_NODE, &ldp_bridge_cmd); + install_element(LDP_L2VPN_NODE, &ldp_mtu_cmd); + install_element(LDP_L2VPN_NODE, &ldp_member_interface_cmd); + install_element(LDP_L2VPN_NODE, &ldp_member_pseudowire_cmd); + install_element(LDP_L2VPN_NODE, &ldp_vc_type_cmd); + + install_element(LDP_PSEUDOWIRE_NODE, &ldp_control_word_cmd); + install_element(LDP_PSEUDOWIRE_NODE, &ldp_neighbor_address_cmd); + install_element(LDP_PSEUDOWIRE_NODE, &ldp_neighbor_lsr_id_cmd); + install_element(LDP_PSEUDOWIRE_NODE, &ldp_pw_id_cmd); + install_element(LDP_PSEUDOWIRE_NODE, &ldp_pw_status_disable_cmd); + + install_element(ENABLE_NODE, &ldp_clear_mpls_ldp_neighbor_cmd); + install_element(ENABLE_NODE, &ldp_debug_mpls_ldp_discovery_hello_cmd); + install_element(ENABLE_NODE, &ldp_debug_mpls_ldp_type_cmd); + install_element(ENABLE_NODE, &ldp_debug_mpls_ldp_messages_recv_cmd); + install_element(ENABLE_NODE, &ldp_debug_mpls_ldp_messages_sent_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_capabilities_cmd); + install_element(VIEW_NODE, &ldp_show_mpls_ldp_neighbor_cmd); + install_element(VIEW_NODE, &ldp_show_mpls_ldp_neighbor_capabilities_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); +} diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c index 8394907142..532c880afc 100644 --- a/ldpd/ldp_vty_conf.c +++ b/ldpd/ldp_vty_conf.c @@ -1,21 +1,20 @@ /* * Copyright (C) 2016 by Open Source Routing. * - * This file is part of GNU Zebra. + * 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. * - * 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 + * 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <zebra.h> @@ -37,8 +36,6 @@ static void ldp_af_config_write(struct vty *, int, struct ldpd_conf *, static void ldp_l2vpn_pw_config_write(struct vty *, struct l2vpn_pw *); static int ldp_vty_get_af(struct vty *); static int ldp_iface_is_configured(struct ldpd_conf *, const char *); -static int ldp_vty_nbr_session_holdtime(struct vty *, struct vty_arg *[]); -static int ldp_vty_af_session_holdtime(struct vty *, struct vty_arg *[]); struct cmd_node ldp_node = { @@ -418,12 +415,8 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname) } int -ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[]) +ldp_vty_mpls_ldp(struct vty *vty, int disable) { - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - if (disable) vty_conf->flags &= ~F_LDPD_ENABLED; else { @@ -437,15 +430,10 @@ ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_address_family(struct vty *vty, struct vty_arg *args[]) +ldp_vty_address_family(struct vty *vty, int disable, const char *af_str) { struct ldpd_af_conf *af_conf; int af; - const char *af_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - af_str = vty_get_arg_value(args, "address-family"); if (strcmp(af_str, "ipv4") == 0) { af = AF_INET; @@ -480,7 +468,8 @@ ldp_vty_address_family(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[]) +ldp_vty_disc_holdtime(struct vty *vty, int disable, const char *hello_type_str, + const char *seconds_str) { struct ldpd_af_conf *af_conf; struct iface *iface; @@ -489,13 +478,6 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[]) char *ep; long int secs; enum hello_type hello_type; - const char *seconds_str; - const char *hello_type_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - seconds_str = vty_get_arg_value(args, "seconds"); - hello_type_str = vty_get_arg_value(args, "hello_type"); secs = strtol(seconds_str, &ep, 10); if (*ep != '\0' || secs < MIN_HOLDTIME || secs > MAX_HOLDTIME) { @@ -580,7 +562,8 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[]) +ldp_vty_disc_interval(struct vty *vty, int disable, const char *hello_type_str, + const char *seconds_str) { struct ldpd_af_conf *af_conf; struct iface *iface; @@ -589,13 +572,6 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[]) char *ep; long int secs; enum hello_type hello_type; - const char *seconds_str; - const char *hello_type_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - seconds_str = vty_get_arg_value(args, "seconds"); - hello_type_str = vty_get_arg_value(args, "hello_type"); secs = strtol(seconds_str, &ep, 10); if (*ep != '\0' || secs < MIN_HELLO_INTERVAL || @@ -681,15 +657,11 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[]) +ldp_vty_targeted_hello_accept(struct vty *vty, int disable, + const char *acl_from_str) { struct ldpd_af_conf *af_conf; int af; - const char *acl_from_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - acl_from_str = vty_get_arg_value(args, "from_acl"); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -711,20 +683,14 @@ ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[]) return (CMD_SUCCESS); } -static int -ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[]) +int +ldp_vty_nbr_session_holdtime(struct vty *vty, int disable, + const char *lsr_id_str, const char *seconds_str) { char *ep; long int secs; struct in_addr lsr_id; struct nbr_params *nbrp; - const char *seconds_str; - const char *lsr_id_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - seconds_str = vty_get_arg_value(args, "seconds"); - lsr_id_str = vty_get_arg_value(args, "lsr_id"); if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 || bad_addr_v4(lsr_id)) { @@ -763,18 +729,14 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[]) return (CMD_SUCCESS); } -static int -ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[]) +int +ldp_vty_af_session_holdtime(struct vty *vty, int disable, + const char *seconds_str) { struct ldpd_af_conf *af_conf; int af; char *ep; long int secs; - const char *seconds_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - seconds_str = vty_get_arg_value(args, "seconds"); secs = strtol(seconds_str, &ep, 10); if (*ep != '\0' || secs < MIN_KEEPALIVE || secs > MAX_KEEPALIVE) { @@ -796,30 +758,11 @@ ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_session_holdtime(struct vty *vty, struct vty_arg *args[]) -{ - switch (vty->node) { - case LDP_NODE: - return (ldp_vty_nbr_session_holdtime(vty, args)); - case LDP_IPV4_NODE: - case LDP_IPV6_NODE: - return (ldp_vty_af_session_holdtime(vty, args)); - default: - fatalx("ldp_vty_session_holdtime: unexpected node"); - } -} - -int -ldp_vty_interface(struct vty *vty, struct vty_arg *args[]) +ldp_vty_interface(struct vty *vty, int disable, const char *ifname) { int af; struct iface *iface; struct iface_af *ia; - const char *ifname; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - ifname = vty_get_arg_value(args, "ifname"); af = ldp_vty_get_af(vty); iface = if_lookup_name(vty_conf, ifname); @@ -878,15 +821,10 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[]) +ldp_vty_trans_addr(struct vty *vty, int disable, const char *addr_str) { struct ldpd_af_conf *af_conf; int af; - const char *addr_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - addr_str = vty_get_arg_value(args, "addr"); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -907,16 +845,11 @@ ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[]) +ldp_vty_neighbor_targeted(struct vty *vty, int disable, const char *addr_str) { int af; union ldpd_addr addr; struct tnbr *tnbr; - const char *addr_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - addr_str = vty_get_arg_value(args, "addr"); af = ldp_vty_get_af(vty); @@ -959,17 +892,11 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[]) +ldp_vty_label_advertise(struct vty *vty, int disable, const char *acl_to_str, + const char *acl_for_str) { struct ldpd_af_conf *af_conf; int af; - const char *acl_to_str; - const char *acl_for_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - acl_to_str = vty_get_arg_value(args, "to_acl"); - acl_for_str = vty_get_arg_value(args, "for_acl"); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -996,17 +923,11 @@ ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[]) +ldp_vty_label_allocate(struct vty *vty, int disable, int host_routes, + const char *acl_for_str) { struct ldpd_af_conf *af_conf; int af; - const char *acl_for_str; - const char *host_routes_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - acl_for_str = vty_get_arg_value(args, "for_acl"); - host_routes_str = vty_get_arg_value(args, "host-routes"); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -1014,7 +935,7 @@ ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[]) af_conf->flags &= ~F_LDPD_AF_ALLOCHOSTONLY; af_conf->acl_label_allocate_for[0] = '\0'; if (!disable) { - if (host_routes_str) + if (host_routes) af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY; else strlcpy(af_conf->acl_label_allocate_for, acl_for_str, @@ -1027,15 +948,10 @@ ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[]) +ldp_vty_label_expnull(struct vty *vty, int disable, const char *acl_for_str) { struct ldpd_af_conf *af_conf; int af; - const char *acl_for_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - acl_for_str = vty_get_arg_value(args, "for_acl"); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -1058,17 +974,11 @@ ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[]) +ldp_vty_label_accept(struct vty *vty, int disable, const char *acl_from_str, + const char *acl_for_str) { struct ldpd_af_conf *af_conf; int af; - const char *acl_from_str; - const char *acl_for_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - acl_from_str = vty_get_arg_value(args, "from_acl"); - acl_for_str = vty_get_arg_value(args, "for_acl"); af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -1095,13 +1005,10 @@ ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[]) +ldp_vty_ttl_security(struct vty *vty, int disable) { struct ldpd_af_conf *af_conf; int af; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; af = ldp_vty_get_af(vty); af_conf = ldp_af_conf_get(vty_conf, af); @@ -1117,14 +1024,8 @@ ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_router_id(struct vty *vty, struct vty_arg *args[]) +ldp_vty_router_id(struct vty *vty, int disable, const char *addr_str) { - const char *addr_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - addr_str = vty_get_arg_value(args, "addr"); - if (disable) vty_conf->rtr_id.s_addr = INADDR_ANY; else { @@ -1141,12 +1042,8 @@ ldp_vty_router_id(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[]) +ldp_vty_ds_cisco_interop(struct vty *vty, int disable) { - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - if (disable) vty_conf->flags &= ~F_LDPD_DS_CISCO_INTEROP; else @@ -1158,12 +1055,8 @@ ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[]) +ldp_vty_trans_pref_ipv4(struct vty *vty, int disable) { - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - if (disable) vty_conf->trans_pref = DUAL_STACK_LDPOV6; else @@ -1175,18 +1068,12 @@ ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[]) +ldp_vty_neighbor_password(struct vty *vty, int disable, const char *lsr_id_str, + const char *password_str) { struct in_addr lsr_id; size_t password_len; struct nbr_params *nbrp; - const char *lsr_id_str; - const char *password_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - lsr_id_str = vty_get_arg_value(args, "lsr_id"); - password_str = vty_get_arg_value(args, "password"); if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 || bad_addr_v4(lsr_id)) { @@ -1226,19 +1113,13 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[]) +ldp_vty_neighbor_ttl_security(struct vty *vty, int disable, + const char *lsr_id_str, const char *hops_str) { struct in_addr lsr_id; struct nbr_params *nbrp; long int hops = 0; char *ep; - const char *lsr_id_str; - const char *hops_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - lsr_id_str = vty_get_arg_value(args, "lsr_id"); - hops_str = vty_get_arg_value(args, "hops"); if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 || bad_addr_v4(lsr_id)) { @@ -1286,16 +1167,11 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn(struct vty *vty, int disable, const char *name_str) { struct l2vpn *l2vpn; struct l2vpn_if *lif; struct l2vpn_pw *pw; - const char *name_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - name_str = vty_get_arg_value(args, "name"); l2vpn = l2vpn_find(vty_conf, name_str); @@ -1336,14 +1212,9 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_bridge(struct vty *vty, int disable, const char *ifname) { VTY_DECLVAR_CONTEXT(l2vpn, l2vpn); - const char *ifname; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - ifname = vty_get_arg_value(args, "ifname"); if (disable) memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname)); @@ -1356,16 +1227,11 @@ ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_mtu(struct vty *vty, int disable, const char *mtu_str) { VTY_DECLVAR_CONTEXT(l2vpn, l2vpn); char *ep; int mtu; - const char *mtu_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - mtu_str = vty_get_arg_value(args, "mtu"); mtu = strtol(mtu_str, &ep, 10); if (*ep != '\0' || mtu < MIN_L2VPN_MTU || mtu > MAX_L2VPN_MTU) { @@ -1384,15 +1250,10 @@ ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_pwtype(struct vty *vty, int disable, const char *type_str) { VTY_DECLVAR_CONTEXT(l2vpn, l2vpn); int pw_type; - const char *type_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - type_str = vty_get_arg_value(args, "type"); if (strcmp(type_str, "ethernet") == 0) pw_type = PW_TYPE_ETHERNET; @@ -1410,15 +1271,10 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_interface(struct vty *vty, int disable, const char *ifname) { VTY_DECLVAR_CONTEXT(l2vpn, l2vpn); struct l2vpn_if *lif; - const char *ifname; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - ifname = vty_get_arg_value(args, "ifname"); lif = l2vpn_if_find(l2vpn, ifname); @@ -1453,15 +1309,10 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_pseudowire(struct vty *vty, int disable, const char *ifname) { VTY_DECLVAR_CONTEXT(l2vpn, l2vpn); struct l2vpn_pw *pw; - const char *ifname; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - ifname = vty_get_arg_value(args, "ifname"); pw = l2vpn_pw_find(l2vpn, ifname); @@ -1504,14 +1355,9 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_pw_cword(struct vty *vty, int disable, const char *preference_str) { VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw); - const char *preference_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - preference_str = vty_get_arg_value(args, "preference"); if (disable) pw->flags |= F_PW_CWORD_CONF; @@ -1528,16 +1374,11 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, int disable, const char *addr_str) { VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw); int af; union ldpd_addr addr; - const char *addr_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - addr_str = vty_get_arg_value(args, "addr"); if (ldp_get_address(addr_str, &af, &addr) == -1 || bad_addr(af, &addr)) { @@ -1561,15 +1402,10 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, int disable, const char *lsr_id_str) { VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw); struct in_addr lsr_id; - const char *lsr_id_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - lsr_id_str = vty_get_arg_value(args, "lsr-id"); if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 || bad_addr_v4(lsr_id)) { @@ -1588,16 +1424,11 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_pw_pwid(struct vty *vty, int disable, const char *pwid_str) { VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw); char *ep; uint32_t pwid; - const char *pwid_str; - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; - pwid_str = vty_get_arg_value(args, "pwid"); pwid = strtol(pwid_str, &ep, 10); if (*ep != '\0' || pwid < MIN_PWID_ID || pwid > MAX_PWID_ID) { @@ -1616,12 +1447,9 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[]) +ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, int disable) { VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw); - int disable; - - disable = (vty_get_arg_value(args, "no")) ? 1 : 0; if (disable) pw->flags |= F_PW_STATUSTLV_CONF; @@ -1725,17 +1553,18 @@ l2vpn_del_api(struct ldpd_conf *conf, struct l2vpn *l2vpn) struct l2vpn_if *lif; struct l2vpn_pw *pw; - while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) { + while ((lif = RB_ROOT(l2vpn_if_head, &l2vpn->if_tree)) != NULL) { QOBJ_UNREG(lif); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); free(lif); } - while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) { + while ((pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree)) != NULL) { QOBJ_UNREG(pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); free(pw); } - while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) { + while ((pw = RB_ROOT(l2vpn_pw_head, + &l2vpn->pw_inactive_tree)) != NULL) { QOBJ_UNREG(pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); free(pw); diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c index 3463fb6c63..252abd17fd 100644 --- a/ldpd/ldp_vty_exec.c +++ b/ldpd/ldp_vty_exec.c @@ -1,21 +1,20 @@ /* * Copyright (C) 2016 by Open Source Routing. * - * This file is part of GNU Zebra. + * 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. * - * 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 + * 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <zebra.h> @@ -1582,24 +1581,22 @@ ldp_vty_get_af(const char *str, int *af) } int -ldp_vty_show_binding(struct vty *vty, struct vty_arg *args[]) +ldp_vty_show_binding(struct vty *vty, const char *af_str, int detail, int json) { struct imsgbuf ibuf; struct show_params params; - const char *af_str; int af; if (ldp_vty_connect(&ibuf) < 0) return (CMD_WARNING); - af_str = vty_get_arg_value(args, "address-family"); if (ldp_vty_get_af(af_str, &af) < 0) return (CMD_ERR_NO_MATCH); memset(¶ms, 0, sizeof(params)); params.family = af; - params.detail = vty_get_arg_value(args, "detail") ? 1 : 0; - params.json = vty_get_arg_value(args, "json") ? 1 : 0; + params.detail = detail; + params.json = json; if (!params.detail && !params.json) vty_out(vty, "%-4s %-20s %-15s %-11s %-13s %6s%s", "AF", @@ -1611,24 +1608,23 @@ ldp_vty_show_binding(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_show_discovery(struct vty *vty, struct vty_arg *args[]) +ldp_vty_show_discovery(struct vty *vty, const char *af_str, int detail, + int json) { struct imsgbuf ibuf; struct show_params params; - const char *af_str; int af; if (ldp_vty_connect(&ibuf) < 0) return (CMD_WARNING); - af_str = vty_get_arg_value(args, "address-family"); if (ldp_vty_get_af(af_str, &af) < 0) return (CMD_ERR_NO_MATCH); memset(¶ms, 0, sizeof(params)); params.family = af; - params.detail = vty_get_arg_value(args, "detail") ? 1 : 0; - params.json = vty_get_arg_value(args, "json") ? 1 : 0; + params.detail = detail; + params.json = json; if (!params.detail && !params.json) vty_out(vty, "%-4s %-15s %-8s %-15s %9s%s", @@ -1643,24 +1639,22 @@ ldp_vty_show_discovery(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[]) +ldp_vty_show_interface(struct vty *vty, const char *af_str, int json) { struct imsgbuf ibuf; struct show_params params; unsigned int ifidx = 0; - const char *af_str; int af; if (ldp_vty_connect(&ibuf) < 0) return (CMD_WARNING); - af_str = vty_get_arg_value(args, "address-family"); if (ldp_vty_get_af(af_str, &af) < 0) return (CMD_ERR_NO_MATCH); memset(¶ms, 0, sizeof(params)); params.family = af; - params.json = vty_get_arg_value(args, "json") ? 1 : 0; + params.json = json; /* header */ if (!params.json) { @@ -1675,9 +1669,9 @@ ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_show_capabilities(struct vty *vty, struct vty_arg *args[]) +ldp_vty_show_capabilities(struct vty *vty, int json) { - if (vty_get_arg_value(args, "json")) { + if (json) { json_object *json; json_object *json_array; json_object *json_cap; @@ -1727,7 +1721,7 @@ ldp_vty_show_capabilities(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[]) +ldp_vty_show_neighbor(struct vty *vty, int capabilities, int detail, int json) { struct imsgbuf ibuf; struct show_params params; @@ -1736,9 +1730,9 @@ ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); memset(¶ms, 0, sizeof(params)); - params.capabilities = vty_get_arg_value(args, "capabilities") ? 1 : 0; - params.detail = vty_get_arg_value(args, "detail") ? 1 : 0; - params.json = vty_get_arg_value(args, "json") ? 1 : 0; + params.capabilities = capabilities; + params.detail = detail; + params.json = json; if (params.capabilities) params.detail = 1; @@ -1753,7 +1747,7 @@ ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_show_atom_binding(struct vty *vty, struct vty_arg *args[]) +ldp_vty_show_atom_binding(struct vty *vty, int json) { struct imsgbuf ibuf; struct show_params params; @@ -1762,14 +1756,14 @@ ldp_vty_show_atom_binding(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); memset(¶ms, 0, sizeof(params)); - params.json = vty_get_arg_value(args, "json") ? 1 : 0; + params.json = json; imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0); return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, ¶ms)); } int -ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[]) +ldp_vty_show_atom_vc(struct vty *vty, int json) { struct imsgbuf ibuf; struct show_params params; @@ -1778,7 +1772,7 @@ ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[]) return (CMD_WARNING); memset(¶ms, 0, sizeof(params)); - params.json = vty_get_arg_value(args, "json") ? 1 : 0; + params.json = json; if (!params.json) { /* header */ @@ -1795,14 +1789,11 @@ ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[]) } int -ldp_vty_clear_nbr(struct vty *vty, struct vty_arg *args[]) +ldp_vty_clear_nbr(struct vty *vty, const char *addr_str) { struct imsgbuf ibuf; - const char *addr_str; struct ctl_nbr nbr; - addr_str = vty_get_arg_value(args, "addr"); - memset(&nbr, 0, sizeof(nbr)); if (addr_str && (ldp_get_address(addr_str, &nbr.af, &nbr.raddr) == -1 || diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index 1a93f5a86f..79fff01c4c 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -1,21 +1,20 @@ /* * Copyright (C) 2016 by Open Source Routing. * - * This file is part of GNU Zebra. + * 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. * - * 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 + * 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA */ #include <zebra.h> diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 6993ad15cc..abcad79d67 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -1043,13 +1043,13 @@ ldp_config_reset_main(struct ldpd_conf *conf) struct iface *iface; struct nbr_params *nbrp; - while ((iface = RB_ROOT(&conf->iface_tree)) != NULL) { + while ((iface = RB_ROOT(iface_head, &conf->iface_tree)) != NULL) { QOBJ_UNREG(iface); RB_REMOVE(iface_head, &conf->iface_tree, iface); free(iface); } - while ((nbrp = RB_ROOT(&conf->nbrp_tree)) != NULL) { + while ((nbrp = RB_ROOT(nbrp_head, &conf->nbrp_tree)) != NULL) { QOBJ_UNREG(nbrp); RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp); free(nbrp); @@ -1105,18 +1105,20 @@ ldp_config_reset_l2vpns(struct ldpd_conf *conf) struct l2vpn_if *lif; struct l2vpn_pw *pw; - while ((l2vpn = RB_ROOT(&conf->l2vpn_tree)) != NULL) { - while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) { + while ((l2vpn = RB_ROOT(l2vpn_head, &conf->l2vpn_tree)) != NULL) { + while ((lif = RB_ROOT(l2vpn_if_head, + &l2vpn->if_tree)) != NULL) { QOBJ_UNREG(lif); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); free(lif); } - while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) { + while ((pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree)) != NULL) { QOBJ_UNREG(pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); free(pw); } - while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) { + while ((pw = RB_ROOT(l2vpn_pw_head, + &l2vpn->pw_inactive_tree)) != NULL) { QOBJ_UNREG(pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); free(pw); @@ -1135,19 +1137,19 @@ ldp_clear_config(struct ldpd_conf *xconf) struct nbr_params *nbrp; struct l2vpn *l2vpn; - while ((iface = RB_ROOT(&xconf->iface_tree)) != NULL) { + while ((iface = RB_ROOT(iface_head, &xconf->iface_tree)) != NULL) { RB_REMOVE(iface_head, &xconf->iface_tree, iface); free(iface); } - while ((tnbr = RB_ROOT(&xconf->tnbr_tree)) != NULL) { + while ((tnbr = RB_ROOT(tnbr_head, &xconf->tnbr_tree)) != NULL) { RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr); free(tnbr); } - while ((nbrp = RB_ROOT(&xconf->nbrp_tree)) != NULL) { + while ((nbrp = RB_ROOT(nbrp_head, &xconf->nbrp_tree)) != NULL) { RB_REMOVE(nbrp_head, &xconf->nbrp_tree, nbrp); free(nbrp); } - while ((l2vpn = RB_ROOT(&xconf->l2vpn_tree)) != NULL) { + while ((l2vpn = RB_ROOT(l2vpn_head, &xconf->l2vpn_tree)) != NULL) { RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, l2vpn); l2vpn_del(l2vpn); } @@ -1550,9 +1552,9 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf) if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) { COPY(l2vpn, xl); RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn); - RB_INIT(&l2vpn->if_tree); - RB_INIT(&l2vpn->pw_tree); - RB_INIT(&l2vpn->pw_inactive_tree); + RB_INIT(l2vpn_if_head, &l2vpn->if_tree); + RB_INIT(l2vpn_pw_head, &l2vpn->pw_tree); + RB_INIT(l2vpn_pw_head, &l2vpn->pw_inactive_tree); switch (ldpd_process) { case PROC_LDE_ENGINE: @@ -1761,10 +1763,10 @@ config_new_empty(void) if (xconf == NULL) fatal(NULL); - RB_INIT(&xconf->iface_tree); - RB_INIT(&xconf->tnbr_tree); - RB_INIT(&xconf->nbrp_tree); - RB_INIT(&xconf->l2vpn_tree); + RB_INIT(iface_head, &xconf->iface_tree); + RB_INIT(tnbr_head, &xconf->tnbr_tree); + RB_INIT(nbrp_head, &xconf->nbrp_tree); + RB_INIT(l2vpn_head, &xconf->l2vpn_tree); /* set default values */ ldp_config_reset(xconf); diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index ce2441ca2f..ba153dfde2 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -151,13 +151,8 @@ ldpe_init(struct ldpd_init *init) TAILQ_INIT(&ctl_conns); control_listen(); -#ifdef HAVE_PLEDGE - if (pledge("stdio cpath inet mcast recvfd", NULL) == -1) - fatal("pledge"); -#endif - LIST_INIT(&global.addr_list); - RB_INIT(&global.adj_tree); + RB_INIT(global_adj_head, &global.adj_tree); TAILQ_INIT(&global.pending_conns); if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1) fatal("inet_pton"); @@ -221,7 +216,7 @@ ldpe_shutdown(void) LIST_REMOVE(if_addr, entry); free(if_addr); } - while ((adj = RB_ROOT(&global.adj_tree)) != NULL) + while ((adj = RB_ROOT(global_adj_head, &global.adj_tree)) != NULL) adj_del(adj, S_SHUTDOWN); /* clean up */ @@ -461,10 +456,10 @@ ldpe_dispatch_main(struct thread *thread) fatal(NULL); memcpy(nconf, imsg.data, sizeof(struct ldpd_conf)); - RB_INIT(&nconf->iface_tree); - RB_INIT(&nconf->tnbr_tree); - RB_INIT(&nconf->nbrp_tree); - RB_INIT(&nconf->l2vpn_tree); + RB_INIT(iface_head, &nconf->iface_tree); + RB_INIT(tnbr_head, &nconf->tnbr_tree); + RB_INIT(nbrp_head, &nconf->nbrp_tree); + RB_INIT(l2vpn_head, &nconf->l2vpn_tree); break; case IMSG_RECONF_IFACE: if ((niface = malloc(sizeof(struct iface))) == NULL) @@ -492,9 +487,9 @@ ldpe_dispatch_main(struct thread *thread) fatal(NULL); memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn)); - RB_INIT(&nl2vpn->if_tree); - RB_INIT(&nl2vpn->pw_tree); - RB_INIT(&nl2vpn->pw_inactive_tree); + RB_INIT(l2vpn_if_head, &nl2vpn->if_tree); + RB_INIT(l2vpn_pw_head, &nl2vpn->pw_tree); + RB_INIT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree); RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn); break; @@ -881,8 +876,8 @@ ldpe_adj_detail_ctl(struct ctl_conn *c) continue; strlcpy(ictl.name, iface->name, sizeof(ictl.name)); - if (RB_EMPTY(&iface->ipv4.adj_tree) && - RB_EMPTY(&iface->ipv6.adj_tree)) + if (RB_EMPTY(ia_adj_head, &iface->ipv4.adj_tree) && + RB_EMPTY(ia_adj_head, &iface->ipv6.adj_tree)) ictl.no_adj = 1; imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_IFACE, 0, 0, -1, &ictl, sizeof(ictl)); diff --git a/ldpd/ldpe.h b/ldpd/ldpe.h index d34ca4dc24..74f6b852b0 100644 --- a/ldpd/ldpe.h +++ b/ldpd/ldpe.h @@ -237,7 +237,7 @@ struct adj *adj_new(struct in_addr, struct hello_source *, union ldpd_addr *); void adj_del(struct adj *, uint32_t); struct adj *adj_find(struct in_addr, struct hello_source *); -int adj_get_af(struct adj *adj); +int adj_get_af(const struct adj *adj); void adj_start_itimer(struct adj *); void adj_stop_itimer(struct adj *); struct tnbr *tnbr_new(int, union ldpd_addr *); diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c index f867db228d..f8d4b5f5fd 100644 --- a/ldpd/neighbor.c +++ b/ldpd/neighbor.c @@ -26,9 +26,11 @@ #include "lde.h" #include "log.h" -static __inline int nbr_id_compare(struct nbr *, struct nbr *); -static __inline int nbr_addr_compare(struct nbr *, struct nbr *); -static __inline int nbr_pid_compare(struct nbr *, struct nbr *); +static __inline int nbr_id_compare(const struct nbr *, const struct nbr *); +static __inline int nbr_addr_compare(const struct nbr *, + const struct nbr *); +static __inline int nbr_pid_compare(const struct nbr *, + const struct nbr *); static void nbr_update_peerid(struct nbr *); static int nbr_ktimer(struct thread *); static void nbr_start_ktimer(struct nbr *); @@ -39,8 +41,8 @@ static void nbr_start_itimeout(struct nbr *); static int nbr_idtimer(struct thread *); static int nbr_act_session_operational(struct nbr *); static void nbr_send_labelmappings(struct nbr *); -static __inline int nbr_params_compare(struct nbr_params *, - struct nbr_params *); +static __inline int nbr_params_compare(const struct nbr_params *, + const struct nbr_params *); RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare) RB_GENERATE(nbr_addr_head, nbr, addr_tree, nbr_addr_compare) @@ -101,13 +103,13 @@ struct nbr_addr_head nbrs_by_addr = RB_INITIALIZER(&nbrs_by_addr); struct nbr_pid_head nbrs_by_pid = RB_INITIALIZER(&nbrs_by_pid); static __inline int -nbr_id_compare(struct nbr *a, struct nbr *b) +nbr_id_compare(const struct nbr *a, const struct nbr *b) { return (ntohl(a->id.s_addr) - ntohl(b->id.s_addr)); } static __inline int -nbr_addr_compare(struct nbr *a, struct nbr *b) +nbr_addr_compare(const struct nbr *a, const struct nbr *b) { if (a->af < b->af) return (-1); @@ -118,7 +120,7 @@ nbr_addr_compare(struct nbr *a, struct nbr *b) } static __inline int -nbr_pid_compare(struct nbr *a, struct nbr *b) +nbr_pid_compare(const struct nbr *a, const struct nbr *b) { return (a->peerid - b->peerid); } @@ -229,7 +231,7 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr, if ((nbr = calloc(1, sizeof(*nbr))) == NULL) fatal(__func__); - RB_INIT(&nbr->adj_tree); + RB_INIT(nbr_adj_head, &nbr->adj_tree); nbr->state = NBR_STA_PRESENT; nbr->peerid = 0; nbr->af = af; @@ -764,7 +766,7 @@ nbr_send_labelmappings(struct nbr *nbr) } static __inline int -nbr_params_compare(struct nbr_params *a, struct nbr_params *b) +nbr_params_compare(const struct nbr_params *a, const struct nbr_params *b) { return (ntohl(a->lsr_id.s_addr) - ntohl(b->lsr_id.s_addr)); } diff --git a/lib/Makefile.am b/lib/Makefile.am index a1b78d3c4d..079737a696 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -15,7 +15,7 @@ libfrr_la_LDFLAGS = -version-info 0:0:0 libfrr_la_SOURCES = \ network.c pid_output.c getopt.c getopt1.c \ - checksum.c vector.c linklist.c vty.c \ + checksum.c vector.c linklist.c vty.c openbsd-tree.c \ graph.c command_parse.y command_lex.l command_match.c \ command_graph.c \ command.c \ @@ -37,6 +37,7 @@ libfrr_la_SOURCES = \ module.c \ hook.c \ frr_pthread.c \ + termtable.c \ # end BUILT_SOURCES = route_types.h gitversion.h command_parse.h command_lex.h @@ -81,6 +82,7 @@ pkginclude_HEADERS = \ sha256.h \ frr_pthread.h \ vrf_int.h \ + termtable.h \ # end noinst_HEADERS = \ diff --git a/lib/command.c b/lib/command.c index 8a4250bce5..5853710999 100644 --- a/lib/command.c +++ b/lib/command.c @@ -534,7 +534,6 @@ cmd_try_do_shortcut (enum node_type node, char* first_word) { node != AUTH_NODE && node != VIEW_NODE && node != AUTH_ENABLE_NODE && - node != ENABLE_NODE && 0 == strcmp( "do", first_word ) ) return 1; return 0; diff --git a/lib/libfrr.c b/lib/libfrr.c index ff4160a243..132f7d4d2c 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -36,8 +36,8 @@ const char frr_sysconfdir[] = SYSCONFDIR; const char frr_vtydir[] = DAEMON_VTY_DIR; const char frr_moduledir[] = MODULE_PATH; -char frr_protoname[] = "NONE"; -char frr_protonameinst[] = "NONE"; +char frr_protoname[256] = "NONE"; +char frr_protonameinst[256] = "NONE"; char config_default[256]; static char pidfile_default[256]; @@ -39,7 +39,7 @@ DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router") DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name") -static __inline int ns_compare (struct ns *, struct ns *); +static __inline int ns_compare (const struct ns *, const struct ns *); static struct ns *ns_lookup (ns_id_t); RB_GENERATE (ns_head, ns, entry, ns_compare) @@ -108,7 +108,7 @@ static int ns_enable (struct ns *ns); static void ns_disable (struct ns *ns); static __inline int -ns_compare(struct ns *a, struct ns *b) +ns_compare(const struct ns *a, const struct ns *b) { return (a->ns_id - b->ns_id); } @@ -453,7 +453,7 @@ ns_terminate (void) { struct ns *ns; - while ((ns = RB_ROOT (&ns_tree)) != NULL) + while ((ns = RB_ROOT (ns_head, &ns_tree)) != NULL) ns_delete (ns); } diff --git a/lib/openbsd-tree.c b/lib/openbsd-tree.c new file mode 100644 index 0000000000..7e753554c9 --- /dev/null +++ b/lib/openbsd-tree.c @@ -0,0 +1,644 @@ +/* $OpenBSD: subr_tree.c,v 1.9 2017/06/08 03:30:52 dlg Exp $ */ + +/* + * Copyright 2002 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2016 David Gwynne <dlg@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> + +#include <lib/openbsd-tree.h> + +static inline struct rb_entry * +rb_n2e(const struct rb_type *t, void *node) +{ + unsigned long addr = (unsigned long)node; + + return ((struct rb_entry *)(addr + t->t_offset)); +} + +static inline void * +rb_e2n(const struct rb_type *t, struct rb_entry *rbe) +{ + unsigned long addr = (unsigned long)rbe; + + return ((void *)(addr - t->t_offset)); +} + +#define RBE_LEFT(_rbe) (_rbe)->rbt_left +#define RBE_RIGHT(_rbe) (_rbe)->rbt_right +#define RBE_PARENT(_rbe) (_rbe)->rbt_parent +#define RBE_COLOR(_rbe) (_rbe)->rbt_color + +#define RBH_ROOT(_rbt) (_rbt)->rbt_root + +static inline void +rbe_set(struct rb_entry *rbe, struct rb_entry *parent) +{ + RBE_PARENT(rbe) = parent; + RBE_LEFT(rbe) = RBE_RIGHT(rbe) = NULL; + RBE_COLOR(rbe) = RB_RED; +} + +static inline void +rbe_set_blackred(struct rb_entry *black, struct rb_entry *red) +{ + RBE_COLOR(black) = RB_BLACK; + RBE_COLOR(red) = RB_RED; +} + +static inline void +rbe_augment(const struct rb_type *t, struct rb_entry *rbe) +{ + (*t->t_augment)(rb_e2n(t, rbe)); +} + +static inline void +rbe_if_augment(const struct rb_type *t, struct rb_entry *rbe) +{ + if (t->t_augment != NULL) + rbe_augment(t, rbe); +} + +static inline void +rbe_rotate_left(const struct rb_type *t, struct rbt_tree *rbt, + struct rb_entry *rbe) +{ + struct rb_entry *parent; + struct rb_entry *tmp; + + tmp = RBE_RIGHT(rbe); + RBE_RIGHT(rbe) = RBE_LEFT(tmp); + if (RBE_RIGHT(rbe) != NULL) + RBE_PARENT(RBE_LEFT(tmp)) = rbe; + + parent = RBE_PARENT(rbe); + RBE_PARENT(tmp) = parent; + if (parent != NULL) { + if (rbe == RBE_LEFT(parent)) + RBE_LEFT(parent) = tmp; + else + RBE_RIGHT(parent) = tmp; + } else + RBH_ROOT(rbt) = tmp; + + RBE_LEFT(tmp) = rbe; + RBE_PARENT(rbe) = tmp; + + if (t->t_augment != NULL) { + rbe_augment(t, rbe); + rbe_augment(t, tmp); + parent = RBE_PARENT(tmp); + if (parent != NULL) + rbe_augment(t, parent); + } +} + +static inline void +rbe_rotate_right(const struct rb_type *t, struct rbt_tree *rbt, + struct rb_entry *rbe) +{ + struct rb_entry *parent; + struct rb_entry *tmp; + + tmp = RBE_LEFT(rbe); + RBE_LEFT(rbe) = RBE_RIGHT(tmp); + if (RBE_LEFT(rbe) != NULL) + RBE_PARENT(RBE_RIGHT(tmp)) = rbe; + + parent = RBE_PARENT(rbe); + RBE_PARENT(tmp) = parent; + if (parent != NULL) { + if (rbe == RBE_LEFT(parent)) + RBE_LEFT(parent) = tmp; + else + RBE_RIGHT(parent) = tmp; + } else + RBH_ROOT(rbt) = tmp; + + RBE_RIGHT(tmp) = rbe; + RBE_PARENT(rbe) = tmp; + + if (t->t_augment != NULL) { + rbe_augment(t, rbe); + rbe_augment(t, tmp); + parent = RBE_PARENT(tmp); + if (parent != NULL) + rbe_augment(t, parent); + } +} + +static inline void +rbe_insert_color(const struct rb_type *t, struct rbt_tree *rbt, + struct rb_entry *rbe) +{ + struct rb_entry *parent, *gparent, *tmp; + + while ((parent = RBE_PARENT(rbe)) != NULL && + RBE_COLOR(parent) == RB_RED) { + gparent = RBE_PARENT(parent); + + if (parent == RBE_LEFT(gparent)) { + tmp = RBE_RIGHT(gparent); + if (tmp != NULL && RBE_COLOR(tmp) == RB_RED) { + RBE_COLOR(tmp) = RB_BLACK; + rbe_set_blackred(parent, gparent); + rbe = gparent; + continue; + } + + if (RBE_RIGHT(parent) == rbe) { + rbe_rotate_left(t, rbt, parent); + tmp = parent; + parent = rbe; + rbe = tmp; + } + + rbe_set_blackred(parent, gparent); + rbe_rotate_right(t, rbt, gparent); + } else { + tmp = RBE_LEFT(gparent); + if (tmp != NULL && RBE_COLOR(tmp) == RB_RED) { + RBE_COLOR(tmp) = RB_BLACK; + rbe_set_blackred(parent, gparent); + rbe = gparent; + continue; + } + + if (RBE_LEFT(parent) == rbe) { + rbe_rotate_right(t, rbt, parent); + tmp = parent; + parent = rbe; + rbe = tmp; + } + + rbe_set_blackred(parent, gparent); + rbe_rotate_left(t, rbt, gparent); + } + } + + RBE_COLOR(RBH_ROOT(rbt)) = RB_BLACK; +} + +static inline void +rbe_remove_color(const struct rb_type *t, struct rbt_tree *rbt, + struct rb_entry *parent, struct rb_entry *rbe) +{ + struct rb_entry *tmp; + + /* Silence clang possible NULL deference warning. */ + if (parent == NULL) + return; + + while ((rbe == NULL || RBE_COLOR(rbe) == RB_BLACK) && + rbe != RBH_ROOT(rbt)) { + if (RBE_LEFT(parent) == rbe) { + tmp = RBE_RIGHT(parent); + if (RBE_COLOR(tmp) == RB_RED) { + rbe_set_blackred(tmp, parent); + rbe_rotate_left(t, rbt, parent); + tmp = RBE_RIGHT(parent); + } + if ((RBE_LEFT(tmp) == NULL || + RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) && + (RBE_RIGHT(tmp) == NULL || + RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) { + RBE_COLOR(tmp) = RB_RED; + rbe = parent; + parent = RBE_PARENT(rbe); + } else { + if (RBE_RIGHT(tmp) == NULL || + RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK) { + struct rb_entry *oleft; + + oleft = RBE_LEFT(tmp); + if (oleft != NULL) + RBE_COLOR(oleft) = RB_BLACK; + + RBE_COLOR(tmp) = RB_RED; + rbe_rotate_right(t, rbt, tmp); + tmp = RBE_RIGHT(parent); + } + + RBE_COLOR(tmp) = RBE_COLOR(parent); + RBE_COLOR(parent) = RB_BLACK; + if (RBE_RIGHT(tmp)) + RBE_COLOR(RBE_RIGHT(tmp)) = RB_BLACK; + + rbe_rotate_left(t, rbt, parent); + rbe = RBH_ROOT(rbt); + break; + } + } else { + tmp = RBE_LEFT(parent); + if (RBE_COLOR(tmp) == RB_RED) { + rbe_set_blackred(tmp, parent); + rbe_rotate_right(t, rbt, parent); + tmp = RBE_LEFT(parent); + } + + if ((RBE_LEFT(tmp) == NULL || + RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) && + (RBE_RIGHT(tmp) == NULL || + RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) { + RBE_COLOR(tmp) = RB_RED; + rbe = parent; + parent = RBE_PARENT(rbe); + } else { + if (RBE_LEFT(tmp) == NULL || + RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) { + struct rb_entry *oright; + + oright = RBE_RIGHT(tmp); + if (oright != NULL) + RBE_COLOR(oright) = RB_BLACK; + + RBE_COLOR(tmp) = RB_RED; + rbe_rotate_left(t, rbt, tmp); + tmp = RBE_LEFT(parent); + } + + RBE_COLOR(tmp) = RBE_COLOR(parent); + RBE_COLOR(parent) = RB_BLACK; + if (RBE_LEFT(tmp) != NULL) + RBE_COLOR(RBE_LEFT(tmp)) = RB_BLACK; + + rbe_rotate_right(t, rbt, parent); + rbe = RBH_ROOT(rbt); + break; + } + } + } + + if (rbe != NULL) + RBE_COLOR(rbe) = RB_BLACK; +} + +static inline struct rb_entry * +rbe_remove(const struct rb_type *t, struct rbt_tree *rbt, struct rb_entry *rbe) +{ + struct rb_entry *child, *parent, *old = rbe; + unsigned int color; + + if (RBE_LEFT(rbe) == NULL) + child = RBE_RIGHT(rbe); + else if (RBE_RIGHT(rbe) == NULL) + child = RBE_LEFT(rbe); + else { + struct rb_entry *tmp; + + rbe = RBE_RIGHT(rbe); + while ((tmp = RBE_LEFT(rbe)) != NULL) + rbe = tmp; + + child = RBE_RIGHT(rbe); + parent = RBE_PARENT(rbe); + color = RBE_COLOR(rbe); + if (child != NULL) + RBE_PARENT(child) = parent; + if (parent != NULL) { + if (RBE_LEFT(parent) == rbe) + RBE_LEFT(parent) = child; + else + RBE_RIGHT(parent) = child; + + rbe_if_augment(t, parent); + } else + RBH_ROOT(rbt) = child; + if (RBE_PARENT(rbe) == old) + parent = rbe; + *rbe = *old; + + tmp = RBE_PARENT(old); + if (tmp != NULL) { + if (RBE_LEFT(tmp) == old) + RBE_LEFT(tmp) = rbe; + else + RBE_RIGHT(tmp) = rbe; + + rbe_if_augment(t, parent); + } else + RBH_ROOT(rbt) = rbe; + + RBE_PARENT(RBE_LEFT(old)) = rbe; + if (RBE_RIGHT(old)) + RBE_PARENT(RBE_RIGHT(old)) = rbe; + + if (t->t_augment != NULL && parent != NULL) { + tmp = parent; + do { + rbe_augment(t, tmp); + tmp = RBE_PARENT(tmp); + } while (tmp != NULL); + } + + goto color; + } + + parent = RBE_PARENT(rbe); + color = RBE_COLOR(rbe); + + if (child != NULL) + RBE_PARENT(child) = parent; + if (parent != NULL) { + if (RBE_LEFT(parent) == rbe) + RBE_LEFT(parent) = child; + else + RBE_RIGHT(parent) = child; + + rbe_if_augment(t, parent); + } else + RBH_ROOT(rbt) = child; +color: + if (color == RB_BLACK) + rbe_remove_color(t, rbt, parent, child); + + return (old); +} + +void * +_rb_remove(const struct rb_type *t, struct rbt_tree *rbt, void *elm) +{ + struct rb_entry *rbe = rb_n2e(t, elm); + struct rb_entry *old; + + old = rbe_remove(t, rbt, rbe); + + return (old == NULL ? NULL : rb_e2n(t, old)); +} + +void * +_rb_insert(const struct rb_type *t, struct rbt_tree *rbt, void *elm) +{ + struct rb_entry *rbe = rb_n2e(t, elm); + struct rb_entry *tmp; + struct rb_entry *parent = NULL; + void *node; + int comp = 0; + + tmp = RBH_ROOT(rbt); + while (tmp != NULL) { + parent = tmp; + + node = rb_e2n(t, tmp); + comp = (*t->t_compare)(elm, node); + if (comp < 0) + tmp = RBE_LEFT(tmp); + else if (comp > 0) + tmp = RBE_RIGHT(tmp); + else + return (node); + } + + rbe_set(rbe, parent); + + if (parent != NULL) { + if (comp < 0) + RBE_LEFT(parent) = rbe; + else + RBE_RIGHT(parent) = rbe; + + rbe_if_augment(t, parent); + } else + RBH_ROOT(rbt) = rbe; + + rbe_insert_color(t, rbt, rbe); + + return (NULL); +} + +/* Finds the node with the same key as elm */ +void * +_rb_find(const struct rb_type *t, struct rbt_tree *rbt, const void *key) +{ + struct rb_entry *tmp = RBH_ROOT(rbt); + void *node; + int comp; + + while (tmp != NULL) { + node = rb_e2n(t, tmp); + comp = (*t->t_compare)(key, node); + if (comp < 0) + tmp = RBE_LEFT(tmp); + else if (comp > 0) + tmp = RBE_RIGHT(tmp); + else + return (node); + } + + return (NULL); +} + +/* Finds the first node greater than or equal to the search key */ +void * +_rb_nfind(const struct rb_type *t, struct rbt_tree *rbt, const void *key) +{ + struct rb_entry *tmp = RBH_ROOT(rbt); + void *node; + void *res = NULL; + int comp; + + while (tmp != NULL) { + node = rb_e2n(t, tmp); + comp = (*t->t_compare)(key, node); + if (comp < 0) { + res = node; + tmp = RBE_LEFT(tmp); + } else if (comp > 0) + tmp = RBE_RIGHT(tmp); + else + return (node); + } + + return (res); +} + +void * +_rb_next(const struct rb_type *t, void *elm) +{ + struct rb_entry *rbe = rb_n2e(t, elm); + + if (RBE_RIGHT(rbe) != NULL) { + rbe = RBE_RIGHT(rbe); + while (RBE_LEFT(rbe) != NULL) + rbe = RBE_LEFT(rbe); + } else { + if (RBE_PARENT(rbe) && + (rbe == RBE_LEFT(RBE_PARENT(rbe)))) + rbe = RBE_PARENT(rbe); + else { + while (RBE_PARENT(rbe) && + (rbe == RBE_RIGHT(RBE_PARENT(rbe)))) + rbe = RBE_PARENT(rbe); + rbe = RBE_PARENT(rbe); + } + } + + return (rbe == NULL ? NULL : rb_e2n(t, rbe)); +} + +void * +_rb_prev(const struct rb_type *t, void *elm) +{ + struct rb_entry *rbe = rb_n2e(t, elm); + + if (RBE_LEFT(rbe)) { + rbe = RBE_LEFT(rbe); + while (RBE_RIGHT(rbe)) + rbe = RBE_RIGHT(rbe); + } else { + if (RBE_PARENT(rbe) && + (rbe == RBE_RIGHT(RBE_PARENT(rbe)))) + rbe = RBE_PARENT(rbe); + else { + while (RBE_PARENT(rbe) && + (rbe == RBE_LEFT(RBE_PARENT(rbe)))) + rbe = RBE_PARENT(rbe); + rbe = RBE_PARENT(rbe); + } + } + + return (rbe == NULL ? NULL : rb_e2n(t, rbe)); +} + +void * +_rb_root(const struct rb_type *t, struct rbt_tree *rbt) +{ + struct rb_entry *rbe = RBH_ROOT(rbt); + + return (rbe == NULL ? rbe : rb_e2n(t, rbe)); +} + +void * +_rb_min(const struct rb_type *t, struct rbt_tree *rbt) +{ + struct rb_entry *rbe = RBH_ROOT(rbt); + struct rb_entry *parent = NULL; + + while (rbe != NULL) { + parent = rbe; + rbe = RBE_LEFT(rbe); + } + + return (parent == NULL ? NULL : rb_e2n(t, parent)); +} + +void * +_rb_max(const struct rb_type *t, struct rbt_tree *rbt) +{ + struct rb_entry *rbe = RBH_ROOT(rbt); + struct rb_entry *parent = NULL; + + while (rbe != NULL) { + parent = rbe; + rbe = RBE_RIGHT(rbe); + } + + return (parent == NULL ? NULL : rb_e2n(t, parent)); +} + +void * +_rb_left(const struct rb_type *t, void *node) +{ + struct rb_entry *rbe = rb_n2e(t, node); + rbe = RBE_LEFT(rbe); + return (rbe == NULL ? NULL : rb_e2n(t, rbe)); +} + +void * +_rb_right(const struct rb_type *t, void *node) +{ + struct rb_entry *rbe = rb_n2e(t, node); + rbe = RBE_RIGHT(rbe); + return (rbe == NULL ? NULL : rb_e2n(t, rbe)); +} + +void * +_rb_parent(const struct rb_type *t, void *node) +{ + struct rb_entry *rbe = rb_n2e(t, node); + rbe = RBE_PARENT(rbe); + return (rbe == NULL ? NULL : rb_e2n(t, rbe)); +} + +void +_rb_set_left(const struct rb_type *t, void *node, void *left) +{ + struct rb_entry *rbe = rb_n2e(t, node); + struct rb_entry *rbl = (left == NULL) ? NULL : rb_n2e(t, left); + + RBE_LEFT(rbe) = rbl; +} + +void +_rb_set_right(const struct rb_type *t, void *node, void *right) +{ + struct rb_entry *rbe = rb_n2e(t, node); + struct rb_entry *rbr = (right == NULL) ? NULL : rb_n2e(t, right); + + RBE_RIGHT(rbe) = rbr; +} + +void +_rb_set_parent(const struct rb_type *t, void *node, void *parent) +{ + struct rb_entry *rbe = rb_n2e(t, node); + struct rb_entry *rbp = (parent == NULL) ? NULL : rb_n2e(t, parent); + + RBE_PARENT(rbe) = rbp; +} + +void +_rb_poison(const struct rb_type *t, void *node, unsigned long poison) +{ + struct rb_entry *rbe = rb_n2e(t, node); + + RBE_PARENT(rbe) = RBE_LEFT(rbe) = RBE_RIGHT(rbe) = + (struct rb_entry *)poison; +} + +int +_rb_check(const struct rb_type *t, void *node, unsigned long poison) +{ + struct rb_entry *rbe = rb_n2e(t, node); + + return ((unsigned long)RBE_PARENT(rbe) == poison && + (unsigned long)RBE_LEFT(rbe) == poison && + (unsigned long)RBE_RIGHT(rbe) == poison); +} diff --git a/lib/openbsd-tree.h b/lib/openbsd-tree.h index e6502b1e74..22cb9252f5 100644 --- a/lib/openbsd-tree.h +++ b/lib/openbsd-tree.h @@ -287,462 +287,262 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \ (x) != NULL; \ (x) = SPLAY_NEXT(name, head, x)) -/* Macros that define a red-black tree */ -#define RB_HEAD(name, type) \ -struct name { \ - struct type *rbh_root; /* root of the tree */ \ -} - -#define RB_INITIALIZER(root) \ - { NULL } - -#define RB_INIT(root) do { \ - (root)->rbh_root = NULL; \ -} while (0) +/* + * Copyright (c) 2016 David Gwynne <dlg@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ #define RB_BLACK 0 #define RB_RED 1 -#define RB_ENTRY(type) \ -struct { \ - struct type *rbe_left; /* left element */ \ - struct type *rbe_right; /* right element */ \ - struct type *rbe_parent; /* parent element */ \ - int rbe_color; /* node color */ \ -} - -#define RB_LEFT(elm, field) (elm)->field.rbe_left -#define RB_RIGHT(elm, field) (elm)->field.rbe_right -#define RB_PARENT(elm, field) (elm)->field.rbe_parent -#define RB_COLOR(elm, field) (elm)->field.rbe_color -#define RB_ROOT(head) (head)->rbh_root -#define RB_EMPTY(head) (RB_ROOT(head) == NULL) - -#define RB_SET(elm, parent, field) do { \ - RB_PARENT(elm, field) = parent; \ - RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ - RB_COLOR(elm, field) = RB_RED; \ -} while (0) -#define RB_SET_BLACKRED(black, red, field) do { \ - RB_COLOR(black, field) = RB_BLACK; \ - RB_COLOR(red, field) = RB_RED; \ -} while (0) +struct rb_type { + int (*t_compare)(const void *, const void *); + void (*t_augment)(void *); + unsigned int t_offset; /* offset of rb_entry in type */ +}; + +struct rbt_tree { + struct rb_entry *rbt_root; +}; + +struct rb_entry { + struct rb_entry *rbt_parent; + struct rb_entry *rbt_left; + struct rb_entry *rbt_right; + unsigned int rbt_color; +}; + +#define RB_HEAD(_name, _type) \ +struct _name { \ + struct rbt_tree rbh_root; \ +} -#ifndef RB_AUGMENT -#define RB_AUGMENT(x) do {} while (0) -#endif +#define RB_ENTRY(_type) struct rb_entry -#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ - (tmp) = RB_RIGHT(elm, field); \ - if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ - RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_LEFT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ - if ((RB_PARENT(tmp, field))) \ - RB_AUGMENT(RB_PARENT(tmp, field)); \ -} while (0) +static inline void +_rb_init(struct rbt_tree *rbt) +{ + rbt->rbt_root = NULL; +} -#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ - (tmp) = RB_LEFT(elm, field); \ - if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ - RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_RIGHT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ - if ((RB_PARENT(tmp, field))) \ - RB_AUGMENT(RB_PARENT(tmp, field)); \ -} while (0) +static inline int +_rb_empty(struct rbt_tree *rbt) +{ + return (rbt->rbt_root == NULL); +} -/* Generates prototypes and inline functions */ -#define RB_PROTOTYPE(name, type, field, cmp) \ - RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) -#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ - RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) -#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ -attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ -attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ -attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ -attr struct type *name##_RB_INSERT(struct name *, struct type *); \ -attr struct type *name##_RB_FIND(struct name *, struct type *); \ -attr struct type *name##_RB_NFIND(struct name *, struct type *); \ -attr struct type *name##_RB_NEXT(struct type *); \ -attr struct type *name##_RB_PREV(struct type *); \ -attr struct type *name##_RB_MINMAX(struct name *, int); \ +void *_rb_insert(const struct rb_type *, struct rbt_tree *, void *); +void *_rb_remove(const struct rb_type *, struct rbt_tree *, void *); +void *_rb_find(const struct rb_type *, struct rbt_tree *, const void *); +void *_rb_nfind(const struct rb_type *, struct rbt_tree *, const void *); +void *_rb_root(const struct rb_type *, struct rbt_tree *); +void *_rb_min(const struct rb_type *, struct rbt_tree *); +void *_rb_max(const struct rb_type *, struct rbt_tree *); +void *_rb_next(const struct rb_type *, void *); +void *_rb_prev(const struct rb_type *, void *); +void *_rb_left(const struct rb_type *, void *); +void *_rb_right(const struct rb_type *, void *); +void *_rb_parent(const struct rb_type *, void *); +void _rb_set_left(const struct rb_type *, void *, void *); +void _rb_set_right(const struct rb_type *, void *, void *); +void _rb_set_parent(const struct rb_type *, void *, void *); +void _rb_poison(const struct rb_type *, void *, unsigned long); +int _rb_check(const struct rb_type *, void *, unsigned long); + +#define RB_INITIALIZER(_head) { { NULL } } + +#define RB_PROTOTYPE(_name, _type, _field, _cmp) \ +extern const struct rb_type *const _name##_RB_TYPE; \ \ - -/* Main rb operation. - * Moves node close to the key of elm to top - */ -#define RB_GENERATE(name, type, field, cmp) \ - RB_GENERATE_INTERNAL(name, type, field, cmp,) -#define RB_GENERATE_STATIC(name, type, field, cmp) \ - RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) -#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ -attr void \ -name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ +__attribute__((__unused__)) static inline void \ +_name##_RB_INIT(struct _name *head) \ { \ - struct type *parent, *gparent, *tmp; \ - while ((parent = RB_PARENT(elm, field)) && \ - RB_COLOR(parent, field) == RB_RED) { \ - gparent = RB_PARENT(parent, field); \ - if (parent == RB_LEFT(gparent, field)) { \ - tmp = RB_RIGHT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ - elm = gparent; \ - continue; \ - } \ - if (RB_RIGHT(parent, field) == elm) { \ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_RIGHT(head, gparent, tmp, field); \ - } else { \ - tmp = RB_LEFT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ - elm = gparent; \ - continue; \ - } \ - if (RB_LEFT(parent, field) == elm) { \ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_LEFT(head, gparent, tmp, field); \ - } \ - } \ - RB_COLOR(head->rbh_root, field) = RB_BLACK; \ + _rb_init(&head->rbh_root); \ } \ \ -attr void \ -name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_INSERT(struct _name *head, struct _type *elm) \ { \ - struct type *tmp; \ - while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ - elm != RB_ROOT(head)) { \ - if (RB_LEFT(parent, field) == elm) { \ - tmp = RB_RIGHT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - tmp = RB_RIGHT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ - struct type *oleft; \ - if ((oleft = RB_LEFT(tmp, field)))\ - RB_COLOR(oleft, field) = RB_BLACK;\ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_RIGHT(head, tmp, oleft, field);\ - tmp = RB_RIGHT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_RIGHT(tmp, field)) \ - RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - elm = RB_ROOT(head); \ - break; \ - } \ - } else { \ - tmp = RB_LEFT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - tmp = RB_LEFT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ - struct type *oright; \ - if ((oright = RB_RIGHT(tmp, field)))\ - RB_COLOR(oright, field) = RB_BLACK;\ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_LEFT(head, tmp, oright, field);\ - tmp = RB_LEFT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_LEFT(tmp, field)) \ - RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - elm = RB_ROOT(head); \ - break; \ - } \ - } \ - } \ - if (elm) \ - RB_COLOR(elm, field) = RB_BLACK; \ + return _rb_insert(_name##_RB_TYPE, &head->rbh_root, elm); \ } \ \ -attr struct type * \ -name##_RB_REMOVE(struct name *head, struct type *elm) \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_REMOVE(struct _name *head, struct _type *elm) \ { \ - struct type *child, *parent, *old = elm; \ - int color; \ - if (RB_LEFT(elm, field) == NULL) \ - child = RB_RIGHT(elm, field); \ - else if (RB_RIGHT(elm, field) == NULL) \ - child = RB_LEFT(elm, field); \ - else { \ - struct type *left; \ - elm = RB_RIGHT(elm, field); \ - while ((left = RB_LEFT(elm, field))) \ - elm = left; \ - child = RB_RIGHT(elm, field); \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ - if (RB_PARENT(elm, field) == old) \ - parent = elm; \ - (elm)->field = (old)->field; \ - if (RB_PARENT(old, field)) { \ - if (RB_LEFT(RB_PARENT(old, field), field) == old)\ - RB_LEFT(RB_PARENT(old, field), field) = elm;\ - else \ - RB_RIGHT(RB_PARENT(old, field), field) = elm;\ - RB_AUGMENT(RB_PARENT(old, field)); \ - } else \ - RB_ROOT(head) = elm; \ - RB_PARENT(RB_LEFT(old, field), field) = elm; \ - if (RB_RIGHT(old, field)) \ - RB_PARENT(RB_RIGHT(old, field), field) = elm; \ - if (parent) { \ - left = parent; \ - do { \ - RB_AUGMENT(left); \ - } while ((left = RB_PARENT(left, field))); \ - } \ - goto color; \ - } \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ -color: \ - if (color == RB_BLACK) \ - name##_RB_REMOVE_COLOR(head, parent, child); \ - return (old); \ + return _rb_remove(_name##_RB_TYPE, &head->rbh_root, elm); \ } \ \ -/* Inserts a node into the RB tree */ \ -attr struct type * \ -name##_RB_INSERT(struct name *head, struct type *elm) \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_FIND(struct _name *head, const struct _type *key) \ { \ - struct type *tmp; \ - struct type *parent = NULL; \ - int comp = 0; \ - tmp = RB_ROOT(head); \ - while (tmp) { \ - parent = tmp; \ - comp = (cmp)(elm, parent); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - RB_SET(elm, parent, field); \ - if (parent != NULL) { \ - if (comp < 0) \ - RB_LEFT(parent, field) = elm; \ - else \ - RB_RIGHT(parent, field) = elm; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = elm; \ - name##_RB_INSERT_COLOR(head, elm); \ - return (NULL); \ + return _rb_find(_name##_RB_TYPE, &head->rbh_root, key); \ } \ \ -/* Finds the node with the same key as elm */ \ -attr struct type * \ -name##_RB_FIND(struct name *head, struct type *elm) \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_NFIND(struct _name *head, const struct _type *key) \ { \ - struct type *tmp = RB_ROOT(head); \ - int comp; \ - while (tmp) { \ - comp = cmp(elm, tmp); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - return (NULL); \ + return _rb_nfind(_name##_RB_TYPE, &head->rbh_root, key); \ } \ \ -/* Finds the first node greater than or equal to the search key */ \ -attr struct type * \ -name##_RB_NFIND(struct name *head, struct type *elm) \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_ROOT(struct _name *head) \ { \ - struct type *tmp = RB_ROOT(head); \ - struct type *res = NULL; \ - int comp; \ - while (tmp) { \ - comp = cmp(elm, tmp); \ - if (comp < 0) { \ - res = tmp; \ - tmp = RB_LEFT(tmp, field); \ - } \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - return (res); \ + return _rb_root(_name##_RB_TYPE, &head->rbh_root); \ } \ \ -/* ARGSUSED */ \ -attr struct type * \ -name##_RB_NEXT(struct type *elm) \ +__attribute__((__unused__)) static inline int \ +_name##_RB_EMPTY(struct _name *head) \ { \ - if (RB_RIGHT(elm, field)) { \ - elm = RB_RIGHT(elm, field); \ - while (RB_LEFT(elm, field)) \ - elm = RB_LEFT(elm, field); \ - } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ - } \ - } \ - return (elm); \ + return _rb_empty(&head->rbh_root); \ } \ \ -/* ARGSUSED */ \ -attr struct type * \ -name##_RB_PREV(struct type *elm) \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_MIN(struct _name *head) \ { \ - if (RB_LEFT(elm, field)) { \ - elm = RB_LEFT(elm, field); \ - while (RB_RIGHT(elm, field)) \ - elm = RB_RIGHT(elm, field); \ - } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ - } \ - } \ - return (elm); \ + return _rb_min(_name##_RB_TYPE, &head->rbh_root); \ } \ \ -attr struct type * \ -name##_RB_MINMAX(struct name *head, int val) \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_MAX(struct _name *head) \ { \ - struct type *tmp = RB_ROOT(head); \ - struct type *parent = NULL; \ - while (tmp) { \ - parent = tmp; \ - if (val < 0) \ - tmp = RB_LEFT(tmp, field); \ - else \ - tmp = RB_RIGHT(tmp, field); \ - } \ - return (parent); \ + return _rb_max(_name##_RB_TYPE, &head->rbh_root); \ +} \ + \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_NEXT(struct _type *elm) \ +{ \ + return _rb_next(_name##_RB_TYPE, elm); \ +} \ + \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_PREV(struct _type *elm) \ +{ \ + return _rb_prev(_name##_RB_TYPE, elm); \ +} \ + \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_LEFT(struct _type *elm) \ +{ \ + return _rb_left(_name##_RB_TYPE, elm); \ +} \ + \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_RIGHT(struct _type *elm) \ +{ \ + return _rb_right(_name##_RB_TYPE, elm); \ +} \ + \ +__attribute__((__unused__)) static inline struct _type * \ +_name##_RB_PARENT(struct _type *elm) \ +{ \ + return _rb_parent(_name##_RB_TYPE, elm); \ +} \ + \ +__attribute__((__unused__)) static inline void \ +_name##_RB_SET_LEFT(struct _type *elm, struct _type *left) \ +{ \ + return _rb_set_left(_name##_RB_TYPE, elm, left); \ +} \ + \ +__attribute__((__unused__)) static inline void \ +_name##_RB_SET_RIGHT(struct _type *elm, struct _type *right) \ +{ \ + return _rb_set_right(_name##_RB_TYPE, elm, right); \ +} \ + \ +__attribute__((__unused__)) static inline void \ +_name##_RB_SET_PARENT(struct _type *elm, struct _type *parent) \ +{ \ + return _rb_set_parent(_name##_RB_TYPE, elm, parent); \ +} \ + \ +__attribute__((__unused__)) static inline void \ +_name##_RB_POISON(struct _type *elm, unsigned long poison) \ +{ \ + return _rb_poison(_name##_RB_TYPE, elm, poison); \ +} \ + \ +__attribute__((__unused__)) static inline int \ +_name##_RB_CHECK(struct _type *elm, unsigned long poison) \ +{ \ + return _rb_check(_name##_RB_TYPE, elm, poison); \ } -#define RB_NEGINF -1 -#define RB_INF 1 - -#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) -#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) -#define RB_FIND(name, x, y) name##_RB_FIND(x, y) -#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) -#define RB_NEXT(name, x, y) name##_RB_NEXT(y) -#define RB_PREV(name, x, y) name##_RB_PREV(y) -#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) -#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) - -#define RB_FOREACH(x, name, head) \ - for ((x) = RB_MIN(name, head); \ - (x) != NULL; \ - (x) = name##_RB_NEXT(x)) - -#define RB_FOREACH_SAFE(x, name, head, y) \ - for ((x) = RB_MIN(name, head); \ - ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \ - (x) = (y)) - -#define RB_FOREACH_REVERSE(x, name, head) \ - for ((x) = RB_MAX(name, head); \ - (x) != NULL; \ - (x) = name##_RB_PREV(x)) - -#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ - for ((x) = RB_MAX(name, head); \ - ((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \ - (x) = (y)) +#define RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \ +static int \ +_name##_RB_COMPARE(const void *lptr, const void *rptr) \ +{ \ + const struct _type *l = lptr, *r = rptr; \ + return _cmp(l, r); \ +} \ +static const struct rb_type _name##_RB_INFO = { \ + _name##_RB_COMPARE, \ + _aug, \ + offsetof(struct _type, _field), \ +}; \ +const struct rb_type *const _name##_RB_TYPE = &_name##_RB_INFO; + +#define RB_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \ +static void \ +_name##_RB_AUGMENT(void *ptr) \ +{ \ + struct _type *p = ptr; \ + return _aug(p); \ +} \ +RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RB_AUGMENT) + +#define RB_GENERATE(_name, _type, _field, _cmp) \ + RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL) + +#define RB_INIT(_name, _head) _name##_RB_INIT(_head) +#define RB_INSERT(_name, _head, _elm) _name##_RB_INSERT(_head, _elm) +#define RB_REMOVE(_name, _head, _elm) _name##_RB_REMOVE(_head, _elm) +#define RB_FIND(_name, _head, _key) _name##_RB_FIND(_head, _key) +#define RB_NFIND(_name, _head, _key) _name##_RB_NFIND(_head, _key) +#define RB_ROOT(_name, _head) _name##_RB_ROOT(_head) +#define RB_EMPTY(_name, _head) _name##_RB_EMPTY(_head) +#define RB_MIN(_name, _head) _name##_RB_MIN(_head) +#define RB_MAX(_name, _head) _name##_RB_MAX(_head) +#define RB_NEXT(_name, _elm) _name##_RB_NEXT(_elm) +#define RB_PREV(_name, _elm) _name##_RB_PREV(_elm) +#define RB_LEFT(_name, _elm) _name##_RB_LEFT(_elm) +#define RB_RIGHT(_name, _elm) _name##_RB_RIGHT(_elm) +#define RB_PARENT(_name, _elm) _name##_RB_PARENT(_elm) +#define RB_SET_LEFT(_name, _elm, _l) _name##_RB_SET_LEFT(_elm, _l) +#define RB_SET_RIGHT(_name, _elm, _r) _name##_RB_SET_RIGHT(_elm, _r) +#define RB_SET_PARENT(_name, _elm, _p) _name##_RB_SET_PARENT(_elm, _p) +#define RB_POISON(_name, _elm, _p) _name##_RB_POISON(_elm, _p) +#define RB_CHECK(_name, _elm, _p) _name##_RB_CHECK(_elm, _p) + +#define RB_FOREACH(_e, _name, _head) \ + for ((_e) = RB_MIN(_name, (_head)); \ + (_e) != NULL; \ + (_e) = RB_NEXT(_name, (_e))) + +#define RB_FOREACH_SAFE(_e, _name, _head, _n) \ + for ((_e) = RB_MIN(_name, (_head)); \ + (_e) != NULL && ((_n) = RB_NEXT(_name, (_e)), 1); \ + (_e) = (_n)) + +#define RB_FOREACH_REVERSE(_e, _name, _head) \ + for ((_e) = RB_MAX(_name, (_head)); \ + (_e) != NULL; \ + (_e) = RB_PREV(_name, (_e))) + +#define RB_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \ + for ((_e) = RB_MAX(_name, (_head)); \ + (_e) != NULL && ((_n) = RB_PREV(_name, (_e)), 1); \ + (_e) = (_n)) #endif /* _SYS_TREE_H_ */ diff --git a/lib/routemap.c b/lib/routemap.c index ed79beb1e7..fcd3c7a7aa 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -2745,7 +2745,7 @@ DEFUN (no_rmap_continue, } -DEFUN_NOSH (rmap_show_name, +DEFUN (rmap_show_name, rmap_show_name_cmd, "show route-map [WORD]", SHOW_STR diff --git a/lib/termtable.c b/lib/termtable.c new file mode 100644 index 0000000000..283fa173d8 --- /dev/null +++ b/lib/termtable.c @@ -0,0 +1,487 @@ +/* + * ASCII table generator. + * Copyright (C) 2017 Cumulus Networks + * Quentin Young + * + * 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; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> +#include <stdio.h> + +#include "memory.h" +#include "termtable.h" + +DEFINE_MTYPE_STATIC(LIB, TTABLE, "ASCII table") + +/* clang-format off */ +struct ttable_style ttable_styles[] = { + { // default ascii + .corner = '+', + .rownums_on = false, + .indent = 1, + .border.top = '-', + .border.bottom = '-', + .border.left = '|', + .border.right = '|', + .border.top_on = true, + .border.bottom_on = true, + .border.left_on = true, + .border.right_on = true, + .cell.lpad = 1, + .cell.rpad = 1, + .cell.align = LEFT, + .cell.border.bottom = '-', + .cell.border.bottom_on = true, + .cell.border.top = '-', + .cell.border.top_on = false, + .cell.border.right = '|', + .cell.border.right_on = true, + .cell.border.left = '|', + .cell.border.left_on = false, + }, { // blank, suitable for plaintext alignment + .corner = ' ', + .rownums_on = false, + .indent = 1, + .border.top = ' ', + .border.bottom = ' ', + .border.left = ' ', + .border.right = ' ', + .border.top_on = false, + .border.bottom_on = false, + .border.left_on = false, + .border.right_on = false, + .cell.lpad = 0, + .cell.rpad = 3, + .cell.align = LEFT, + .cell.border.bottom = ' ', + .cell.border.bottom_on = false, + .cell.border.top = ' ', + .cell.border.top_on = false, + .cell.border.right = ' ', + .cell.border.right_on = false, + .cell.border.left = ' ', + .cell.border.left_on = false, + } +}; +/* clang-format on */ + +void ttable_del(struct ttable *tt) +{ + for (int i = tt->nrows - 1; i >= 0; i--) + ttable_del_row(tt, i); + + XFREE(MTYPE_TTABLE, tt->table); + XFREE(MTYPE_TTABLE, tt); +} + +struct ttable *ttable_new(struct ttable_style *style) +{ + struct ttable *tt; + + tt = XCALLOC(MTYPE_TTABLE, sizeof(struct ttable)); + tt->style = *style; + tt->nrows = 0; + tt->ncols = 0; + tt->size = 0; + tt->table = NULL; + + return tt; +} + +/** + * Inserts or appends a new row at the specified index. + * + * If the index is -1, the row is added to the end of the table. Otherwise the + * index must be a valid index into tt->table. + * + * If the table already has at least one row (and therefore a determinate + * number of columns), a format string specifying a number of columns not equal + * to tt->ncols will result in a no-op and a return value of NULL. + * + * @param tt table to insert into + * @param i insertion index; inserted row will be (i + 1)'th row + * @param format printf format string as in ttable_[add|insert]_row() + * @param ap pre-initialized variadic list of arguments for format string + * + * @return pointer to the first cell of allocated row + */ +static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i, + const char *format, va_list ap) +{ + assert(i >= -1 && i < tt->nrows); + + char *res, *orig, *section; + struct ttable_cell *row; + int col = 0; + int ncols = 0; + + /* count how many columns we have */ + for (int i = 0; format[i]; i++) + ncols += !!(format[i] == '|'); + ncols++; + + if (tt->ncols == 0) + tt->ncols = ncols; + else if (ncols != tt->ncols) + return NULL; + + /* reallocate chunk if necessary */ + while (tt->size < (tt->nrows + 1) * sizeof(struct ttable_cell *)) { + tt->size = MAX(2 * tt->size, 2 * sizeof(struct ttable_cell *)); + tt->table = XREALLOC(MTYPE_TTABLE, tt->table, tt->size); + } + + /* CALLOC a block of cells */ + row = XCALLOC(MTYPE_TTABLE, tt->ncols * sizeof(struct ttable_cell)); + + res = NULL; + vasprintf(&res, format, ap); + + orig = res; + + while (res) { + section = strsep(&res, "|"); + row[col].text = XSTRDUP(MTYPE_TTABLE, section); + row[col].style = tt->style.cell; + col++; + } + + free(orig); + + /* insert row */ + if (i == -1 || i == tt->nrows) + tt->table[tt->nrows] = row; + else { + memmove(&tt->table[i + 1], &tt->table[i], + (tt->nrows - i) * sizeof(struct ttable_cell *)); + tt->table[i] = row; + } + + tt->nrows++; + + return row; +} + +struct ttable_cell *ttable_insert_row(struct ttable *tt, unsigned int i, + const char *format, ...) +{ + struct ttable_cell *ret; + va_list ap; + + va_start(ap, format); + ret = ttable_insert_row_va(tt, i, format, ap); + va_end(ap); + + return ret; +} + +struct ttable_cell *ttable_add_row(struct ttable *tt, const char *format, ...) +{ + struct ttable_cell *ret; + va_list ap; + + va_start(ap, format); + ret = ttable_insert_row_va(tt, -1, format, ap); + va_end(ap); + + return ret; +} + +void ttable_del_row(struct ttable *tt, unsigned int i) +{ + assert((int)i < tt->nrows); + + for (int j = 0; j < tt->ncols; j++) + XFREE(MTYPE_TTABLE, tt->table[i][j].text); + + XFREE(MTYPE_TTABLE, tt->table[i]); + + memmove(&tt->table[i], &tt->table[i + 1], + (tt->nrows - i - 1) * sizeof(struct ttable_cell *)); + + tt->nrows--; + + if (tt->nrows == 0) + tt->ncols = 0; +} + +void ttable_align(struct ttable *tt, unsigned int row, unsigned int col, + unsigned int nrow, unsigned int ncol, enum ttable_align align) +{ + assert((int)row < tt->nrows); + assert((int)col < tt->ncols); + assert((int)row + (int)nrow <= tt->nrows); + assert((int)col + (int)ncol <= tt->ncols); + + for (unsigned int i = row; i < row + nrow; i++) + for (unsigned int j = col; j < col + ncol; j++) + tt->table[i][j].style.align = align; +} + +static void ttable_cell_pad(struct ttable_cell *cell, enum ttable_align align, + short pad) +{ + if (align == LEFT) + cell->style.lpad = pad; + else + cell->style.rpad = pad; +} + +void ttable_pad(struct ttable *tt, unsigned int row, unsigned int col, + unsigned int nrow, unsigned int ncol, enum ttable_align align, + short pad) +{ + assert((int)row < tt->nrows); + assert((int)col < tt->ncols); + assert((int)row + (int)nrow <= tt->nrows); + assert((int)col + (int)ncol <= tt->ncols); + + for (unsigned int i = row; i < row + nrow; i++) + for (unsigned int j = col; j < col + ncol; j++) + ttable_cell_pad(&tt->table[i][j], align, pad); +} + +void ttable_restyle(struct ttable *tt) +{ + for (int i = 0; i < tt->nrows; i++) + for (int j = 0; j < tt->ncols; j++) + tt->table[i][j].style = tt->style.cell; +} + +void ttable_colseps(struct ttable *tt, unsigned int col, + enum ttable_align align, bool on, char sep) +{ + for (int i = 0; i < tt->nrows; i++) { + if (align == RIGHT) { + tt->table[i][col].style.border.right_on = on; + tt->table[i][col].style.border.right = sep; + } else { + tt->table[i][col].style.border.left_on = on; + tt->table[i][col].style.border.left = sep; + } + } +} + +void ttable_rowseps(struct ttable *tt, unsigned int row, + enum ttable_align align, bool on, char sep) +{ + for (int i = 0; i < tt->ncols; i++) { + if (align == TOP) { + tt->table[row][i].style.border.top_on = on; + tt->table[row][i].style.border.top = sep; + } else { + tt->table[row][i].style.border.bottom_on = on; + tt->table[row][i].style.border.bottom = sep; + } + } +} + +char *ttable_dump(struct ttable *tt, const char *newline) +{ + /* clang-format off */ + char *buf; // print buffer + size_t pos; // position in buffer + size_t nl_len; // strlen(newline) + int cw[tt->ncols]; // calculated column widths + int nlines; // total number of newlines / table lines + size_t width; // length of one line, with newline + int abspad; // calculated whitespace for sprintf + char *left; // left part of line + size_t lsize; // size of above + char *right; // right part of line + size_t rsize; // size of above + struct ttable_cell *cell, *row; // iteration pointers + /* clang-format on */ + + nl_len = strlen(newline); + + /* calculate width of each column */ + memset(cw, 0x00, sizeof(int) * tt->ncols); + + for (int j = 0; j < tt->ncols; j++) + for (int i = 0, cellw = 0; i < tt->nrows; i++) { + cell = &tt->table[i][j]; + cellw = 0; + cellw += (int)strlen(cell->text); + cellw += cell->style.lpad; + cellw += cell->style.rpad; + if (j != 0) + cellw += cell->style.border.left_on ? 1 : 0; + if (j != tt->ncols - 1) + cellw += cell->style.border.right_on ? 1 : 0; + cw[j] = MAX(cw[j], cellw); + } + + /* calculate overall line width, including newline */ + width = 0; + width += tt->style.indent; + width += tt->style.border.left_on ? 1 : 0; + width += tt->style.border.right_on ? 1 : 0; + width += strlen(newline); + for (int i = 0; i < tt->ncols; i++) + width += cw[i]; + + /* calculate number of lines en total */ + nlines = tt->nrows; + nlines += tt->style.border.top_on ? 1 : 0; + nlines += 1; // tt->style.border.bottom_on ? 1 : 1; makes life easier + for (int i = 0; i < tt->nrows; i++) { + /* if leftmost cell has top / bottom border, whole row does */ + nlines += tt->table[i][0].style.border.top_on ? 1 : 0; + nlines += tt->table[i][0].style.border.bottom_on ? 1 : 0; + } + + /* initialize left & right */ + lsize = tt->style.indent + (tt->style.border.left_on ? 1 : 0); + left = XCALLOC(MTYPE_TTABLE, lsize); + rsize = nl_len + (tt->style.border.right_on ? 1 : 0); + right = XCALLOC(MTYPE_TTABLE, rsize); + + memset (left, ' ', lsize); + + if (tt->style.border.left_on) + left[lsize - 1] = tt->style.border.left; + + if (tt->style.border.right_on) { + right[0] = tt->style.border.right; + memcpy(&right[1], newline, nl_len); + } else + memcpy(&right[0], newline, nl_len); + + /* allocate print buffer */ + buf = XCALLOC(MTYPE_TMP, width * (nlines + 1) + 1); + pos = 0; + + if (tt->style.border.top_on) { + memcpy(&buf[pos], left, lsize); + pos += lsize; + + for (size_t i = 0; i < width - lsize - rsize; i++) + buf[pos++] = tt->style.border.top; + + memcpy(&buf[pos], right, rsize); + pos += rsize; + } + + for (int i = 0; i < tt->nrows; i++) { + row = tt->table[i]; + + /* if top border and not first row, print top row border */ + if (row[0].style.border.top_on && i != 0) { + memcpy(&buf[pos], left, lsize); + pos += lsize; + + for (size_t i = 0; i < width - lsize - rsize; i++) + buf[pos++] = row[0].style.border.top; + + pos -= width - lsize - rsize; + for (int k = 0; k < tt->ncols; k++) { + if (k != 0 && row[k].style.border.left_on) + buf[pos] = tt->style.corner; + pos += cw[k]; + if (row[k].style.border.right_on + && k != tt->ncols - 1) + buf[pos - 1] = tt->style.corner; + } + + memcpy(&buf[pos], right, rsize); + pos += rsize; + } + + memcpy(&buf[pos], left, lsize); + pos += lsize; + + for (int j = 0; j < tt->ncols; j++) { + /* if left border && not first col print left border */ + if (row[j].style.border.left_on && j != 0) + buf[pos++] = row[j].style.border.left; + + /* print left padding */ + for (int i = 0; i < row[j].style.lpad; i++) + buf[pos++] = ' '; + + /* calculate padding for sprintf */ + abspad = cw[j]; + abspad -= row[j].style.rpad; + abspad -= row[j].style.lpad; + if (j != 0) + abspad -= row[j].style.border.left_on ? 1 : 0; + if (j != tt->ncols - 1) + abspad -= row[j].style.border.right_on ? 1 : 0; + + /* print text */ + const char *fmt; + if (row[j].style.align == LEFT) + fmt = "%-*s"; + else + fmt = "%*s"; + + pos += sprintf(&buf[pos], fmt, abspad, row[j].text); + + /* print right padding */ + for (int i = 0; i < row[j].style.rpad; i++) + buf[pos++] = ' '; + + /* if right border && not last col print right border */ + if (row[j].style.border.right_on && j != tt->ncols - 1) + buf[pos++] = row[j].style.border.right; + } + + memcpy(&buf[pos], right, rsize); + pos += rsize; + + /* if bottom border and not last row, print bottom border */ + if (row[0].style.border.bottom_on && i != tt->nrows - 1) { + memcpy(&buf[pos], left, lsize); + pos += lsize; + + for (size_t i = 0; i < width - lsize - rsize; i++) + buf[pos++] = row[0].style.border.bottom; + + pos -= width - lsize - rsize; + for (int k = 0; k < tt->ncols; k++) { + if (k != 0 && row[k].style.border.left_on) + buf[pos] = tt->style.corner; + pos += cw[k]; + if (row[k].style.border.right_on + && k != tt->ncols - 1) + buf[pos - 1] = tt->style.corner; + } + + memcpy(&buf[pos], right, rsize); + pos += rsize; + } + + assert(!buf[pos]); /* pos == & of first \0 in buf */ + } + + if (tt->style.border.bottom_on) { + memcpy(&buf[pos], left, lsize); + pos += lsize; + + for (size_t i = 0; i < width - lsize - rsize; i++) + buf[pos++] = tt->style.border.bottom; + + memcpy(&buf[pos], right, rsize); + pos += rsize; + } + + buf[pos] = '\0'; + + XFREE(MTYPE_TTABLE, left); + XFREE(MTYPE_TTABLE, right); + + return buf; +} diff --git a/lib/termtable.h b/lib/termtable.h new file mode 100644 index 0000000000..6953002e90 --- /dev/null +++ b/lib/termtable.h @@ -0,0 +1,293 @@ +/* + * ASCII table generator. + * Copyright (C) 2017 Cumulus Networks + * Quentin Young + * + * 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; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef _TERMTABLE_H_ +#define _TERMTABLE_H_ + +enum ttable_align { + LEFT, + RIGHT, + TOP, + BOTTOM, +}; + +struct ttable_border { + char top; + char bottom; + char left; + char right; + + bool top_on; + bool bottom_on; + bool left_on; + bool right_on; +}; + +/* cell style and cell */ +struct ttable_cellstyle { + short lpad; + short rpad; + enum ttable_align align; + struct ttable_border border; +}; + +struct ttable_cell { + char *text; + struct ttable_cellstyle style; +}; + +/* table style and table */ +struct ttable_style { + char corner; /* intersection */ + int indent; /* left table indent */ + bool rownums_on; /* show row numbers; unimplemented */ + + struct ttable_border border; + struct ttable_cellstyle cell; +}; + +struct ttable { + int nrows; /* number of rows */ + int ncols; /* number of cols */ + struct ttable_cell **table; /* table, row x col */ + size_t size; /* size */ + struct ttable_style style; /* style */ +}; + +/* some predefined styles */ +#define TTSTYLE_ASCII 0 +#define TTSTYLE_BLANK 1 + +extern struct ttable_style ttable_styles[2]; + +/** + * Creates a new table with the default style, which looks like this: + * + * +----------+----------+ + * | column 1 | column 2 | + * +----------+----------+ + * | data... | data!! | + * +----------+----------+ + * | datums | 12345 | + * +----------+----------+ + * + * @return the created table + */ +struct ttable *ttable_new(struct ttable_style *tts); + +/** + * Deletes a table and releases all associated resources. + * + * @param tt the table to destroy + */ +void ttable_del(struct ttable *tt); + +/** + * Deletes an individual cell. + * + * @param cell the cell to destroy + */ +void ttable_cell_del(struct ttable_cell *cell); + +/** + * Inserts a new row at the given index. + * + * The row contents are determined by a format string. The format string has + * the same form as a regular printf format string, except that columns are + * delimited by '|'. For example, to make the first column of the table above, + * the call is: + * + * ttable_insert_row(<tt>, <n>, "%s|%s", "column 1", "column 2"); + * + * All features of printf format strings are permissible here. + * + * Caveats: + * - At present you cannot insert '|' into a cell's contents. + * - If there are N columns, '|' must appear n-1 times or the row will not be + * created + * + * @param tt table to insert row into + * @param row the row number (begins at 0) + * @param format column-separated format string + * @param ... arguments to format string + * + * @return pointer to the first cell in the created row, or NULL if not enough + * columns were specified + */ +struct ttable_cell *ttable_insert_row(struct ttable *tt, unsigned int row, + const char *format, ...); +/** + * Inserts a new row at the end of the table. + * + * The row contents are determined by a format string. The format string has + * the same form as a regular printf format string, except that columns are + * delimited by '|'. For example, to make the first column of the table above, + * the call is: + * + * ttable_add_row(<tt>, "%s|%s", "column 1", "column 2"); + * + * All features of printf format strings are permissible here. + * + * Caveats: + * - At present you cannot insert '|' into a cell's contents. + * - If there are N columns, '|' must appear n-1 times or the row will not be + * created + * + * @param tt table to insert row into + * @param format column-separated format string + * @param ... arguments to format string + * + * @return pointer to the first cell in the created row, or NULL if not enough + * columns were specified + */ +struct ttable_cell *ttable_add_row(struct ttable *tt, const char *format, ...); + +/** + * Removes a row from the table. + * + * @param tt table to delete row from + * @param row the row number (begins at 0) + */ +void ttable_del_row(struct ttable *tt, unsigned int row); + +/** + * Sets alignment for a range of cells. + * + * Available alignments are LEFT and RIGHT. Cell contents will be aligned + * accordingly, while respecting padding (if any). Suppose a cell has: + * + * lpad = 1 + * rpad = 1 + * align = RIGHT + * text = 'datums' + * + * The cell would look like: + * + * +-------------------+ + * | datums | + * +-------------------+ + * + * On the other hand: + * + * lpad = 1 + * rpad = 10 + * align = RIGHT + * text = 'datums' + * + * +-------------------+ + * | datums | + * +-------------------+ + * + * The default alignment is LEFT. + * + * @param tt the table to set alignment on + * @param srow starting row index + * @param scol starting column index + * @param nrow # rows to align + * @param ncol # cols to align + * @param align the alignment to set + */ +void ttable_align(struct ttable *tt, unsigned int srow, unsigned int scol, + unsigned int erow, unsigned int ecol, + enum ttable_align align); + +/** + * Sets padding for a range of cells. + * + * Available padding options are LEFT and RIGHT (the alignment enum is reused). + * Both options may be set. Padding is treated as though it is stuck to the + * walls of the cell. Suppose a cell has: + * + * lpad = 4 + * rpad = 2 + * align = RIGHT + * text = 'datums' + * + * The cell padding, marked by '.', would look like: + * + * +--------------+ + * | .datums. | + * +--------------+ + * + * If the column is wider than the cell, the cell contents are aligned in an + * additional padded field according to the cell alignment. + * + * +--------------------+ + * | Data!!!11!~~~~~:-) | + * +--------------------+ + * | . datums. | + * +--------------------+ + * + * @param tt the table to set padding on + * @param srow starting row index + * @param scol starting column index + * @param nrow # rows to pad + * @param ncol # cols to pad + * @param align LEFT or RIGHT + * @param pad # spaces to pad with + */ +void ttable_pad(struct ttable *tt, unsigned int srow, unsigned int scol, + unsigned int nrow, unsigned int ncol, enum ttable_align align, + short pad); + +/** + * Restyle all cells according to table.cell.style. + * + * @param tt table to restyle + */ +void ttable_restyle(struct ttable *tt); + +/** + * Turn left/right column separators on or off for specified column. + * + * @param tt table + * @param col column index + * @param align left or right separators + * @param on true/false for on/off + * @param sep character to use + */ +void ttable_colseps(struct ttable *tt, unsigned int col, + enum ttable_align align, bool on, char sep); + +/** + * Turn bottom row separators on or off for specified row. + * + * @param tt table + * @param row row index + * @param align left or right separators + * @param on true/false for on/off + * @param sep character to use + */ +void ttable_rowseps(struct ttable *tt, unsigned int row, + enum ttable_align align, bool on, char sep); + +/** + * Dumps a table to a heap-allocated string. + * + * Caller must free this string after use with + * + * XFREE (MTYPE_TMP, str); + * + * @param tt the table to dump + * @param newline the desired newline sequence to use, null terminated. + * @return table in text form + */ +char *ttable_dump(struct ttable *tt, const char *newline); + +#endif /* _TERMTABLE_H */ @@ -35,11 +35,11 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map") DEFINE_QOBJ_TYPE(vrf) -static __inline int vrf_id_compare (struct vrf *, struct vrf *); -static __inline int vrf_name_compare (struct vrf *, struct vrf *); +static __inline int vrf_id_compare (const struct vrf *, const struct vrf *); +static __inline int vrf_name_compare (const struct vrf *, const struct vrf *); -RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare) -RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_compare) +RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare); +RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_compare); struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id); struct vrf_name_head vrfs_by_name = RB_INITIALIZER (&vrfs_by_name); @@ -72,13 +72,13 @@ vrf_lookup_by_name (const char *name) } static __inline int -vrf_id_compare (struct vrf *a, struct vrf *b) +vrf_id_compare (const struct vrf *a, const struct vrf *b) { return (a->vrf_id - b->vrf_id); } static int -vrf_name_compare (struct vrf *a, struct vrf *b) +vrf_name_compare (const struct vrf *a, const struct vrf *b) { return strcmp (a->name, b->name); } @@ -377,6 +377,28 @@ vrf_bitmap_check (vrf_bitmap_t bmap, vrf_id_t vrf_id) VRF_BITMAP_FLAG (offset)) ? 1 : 0; } +static void +vrf_autocomplete (vector comps, struct cmd_token *token) +{ + struct vrf *vrf = NULL; + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) + { + if (vrf->vrf_id != 0) + vector_set (comps, XSTRDUP (MTYPE_COMPLETION, vrf->name)); + } +} + +static const struct cmd_variable_handler vrf_var_handlers[] = { + { + .varname = "vrf", + .completions = vrf_autocomplete, + }, + { + .completions = NULL + }, +}; + /* Initialize VRF module. */ void vrf_init (int (*create)(struct vrf *), @@ -408,6 +430,8 @@ vrf_init (int (*create)(struct vrf *), zlog_err ("vrf_init: failed to enable the default VRF!"); exit (1); } + + cmd_variable_handler_register (vrf_var_handlers); } /* Terminate VRF module. */ @@ -419,9 +443,9 @@ vrf_terminate (void) if (debug_vrf) zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__); - while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL) + while ((vrf = RB_ROOT (vrf_id_head, &vrfs_by_id)) != NULL) vrf_delete (vrf); - while ((vrf = RB_ROOT (&vrfs_by_name)) != NULL) + while ((vrf = RB_ROOT (vrf_name_head, &vrfs_by_name)) != NULL) vrf_delete (vrf); } @@ -3151,29 +3151,3 @@ vty_terminate (void) Vvty_serv_thread = NULL; } } - -/* Utility functions to get arguments from commands generated - by the xml2cli.pl script. */ -const char * -vty_get_arg_value (struct vty_arg *args[], const char *arg) -{ - while (*args) - { - if (strcmp ((*args)->name, arg) == 0) - return (*args)->value; - args++; - } - return NULL; -} - -struct vty_arg * -vty_get_arg (struct vty_arg *args[], const char *arg) -{ - while (*args) - { - if (strcmp ((*args)->name, arg) == 0) - return *args; - args++; - } - return NULL; -} @@ -342,7 +342,4 @@ extern void vty_hello (struct vty *); an async-signal-safe function. */ extern void vty_log_fixed (char *buf, size_t len); -extern const char *vty_get_arg_value (struct vty_arg **, const char *); -extern struct vty_arg *vty_get_arg (struct vty_arg **, const char *); - #endif /* _ZEBRA_VTY_H */ diff --git a/lib/zebra.h b/lib/zebra.h index 0a61c433d9..2cc433a863 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -126,6 +126,8 @@ typedef unsigned char u_int8_t; #define __APPLE_USE_RFC_3542 #endif +#include "lib/openbsd-tree.h" + #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index 5d415a68c6..6acd45b7c1 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -1620,6 +1620,7 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa) zlog_info ("brouter %s disappears via area %s", brouter_name, oa->name); ospf6_route_remove (brouter, oa->ospf6->brouter_table); + brouter = NULL; } else if (CHECK_FLAG (brouter->flag, OSPF6_ROUTE_ADD) || CHECK_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE)) @@ -1643,8 +1644,12 @@ ospf6_intra_brouter_calculation (struct ospf6_area *oa) /* But re-originate summaries */ ospf6_abr_originate_summary (brouter); } - UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD); - UNSET_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE); + + if (brouter) + { + UNSET_FLAG (brouter->flag, OSPF6_ROUTE_ADD); + UNSET_FLAG (brouter->flag, OSPF6_ROUTE_CHANGE); + } } if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID (oa->area_id)) diff --git a/ospfclient/ospf_apiclient.c b/ospfclient/ospf_apiclient.c index 0ebae087e3..3f3b5511a2 100644 --- a/ospfclient/ospf_apiclient.c +++ b/ospfclient/ospf_apiclient.c @@ -183,6 +183,7 @@ ospf_apiclient_connect (char *host, int syncport) fd1 = socket (AF_INET, SOCK_STREAM, 0); if (fd1 < 0) { + close (async_server_sock); fprintf (stderr, "ospf_apiclient_connect: creating sync socket failed\n"); return NULL; @@ -196,6 +197,7 @@ ospf_apiclient_connect (char *host, int syncport) { fprintf (stderr, "ospf_apiclient_connect: SO_REUSEADDR failed\n"); close (fd1); + close (async_server_sock); return NULL; } @@ -206,6 +208,7 @@ ospf_apiclient_connect (char *host, int syncport) { fprintf (stderr, "ospf_apiclient_connect: SO_REUSEPORT failed\n"); close (fd1); + close (async_server_sock); return NULL; } #endif /* SO_REUSEPORT */ @@ -227,6 +230,7 @@ ospf_apiclient_connect (char *host, int syncport) { fprintf (stderr, "ospf_apiclient_connect: bind sync socket failed\n"); close (fd1); + close (async_server_sock); return NULL; } @@ -260,6 +264,7 @@ ospf_apiclient_connect (char *host, int syncport) fprintf (stderr, "ospf_apiclient_connect: accept async failed\n"); close (async_server_sock); close (fd1); + close (fd2); return NULL; } diff --git a/ospfclient/ospfclient.c b/ospfclient/ospfclient.c index 195fd5b5a0..d8d0fe8d47 100644 --- a/ospfclient/ospfclient.c +++ b/ospfclient/ospfclient.c @@ -94,7 +94,12 @@ lsa_delete (struct thread *t) oclient = THREAD_ARG (t); - inet_aton (args[6], &area_id); + rc = inet_aton (args[6], &area_id); + if (rc <= 0) + { + printf("Address Specified: %s is invalid\n", args[6]); + return rc; + } printf ("Deleting LSA... "); rc = ospf_apiclient_lsa_delete (oclient, @@ -123,8 +128,19 @@ lsa_inject (struct thread *t) cl = THREAD_ARG (t); - inet_aton (args[5], &ifaddr); - inet_aton (args[6], &area_id); + rc = inet_aton (args[5], &ifaddr); + if (rc <= 0) + { + printf ("Ifaddr specified %s is invalid\n", args[5]); + return rc; + } + + rc = inet_aton (args[6], &area_id); + if (rc <= 0) + { + printf( "Area ID specified %s is invalid\n", args[6]); + return rc; + } lsa_type = atoi (args[2]); opaque_type = atoi (args[3]); opaque_id = atoi (args[4]); diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c index 4723f4a919..6912bc156f 100644 --- a/ospfd/ospf_ri.c +++ b/ospfd/ospf_ri.c @@ -1192,7 +1192,12 @@ DEFUN (router_info, /* Check and get Area value if present */ if (area) { - inet_aton (area, &OspfRI.area_id); + if (!inet_aton (area, &OspfRI.area_id)) + { + vty_out (vty, "%% specified Area ID %s is invalid%s", + area, VTY_NEWLINE); + return CMD_WARNING; + } scope = OSPF_OPAQUE_AREA_LSA; } else diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index e0fa23f35f..173c4e91da 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -63,33 +63,6 @@ ospf_spf_set_reason (ospf_spf_reason_t reason) spf_reason_flags |= 1 << reason; } -static void -ospf_get_spf_reason_str (char *buf) -{ - if (!buf) - return; - - buf[0] = '\0'; - if (spf_reason_flags) - { - if (spf_reason_flags & SPF_FLAG_ROUTER_LSA_INSTALL) - strcat (buf, "R, "); - if (spf_reason_flags & SPF_FLAG_NETWORK_LSA_INSTALL) - strcat (buf, "N, "); - if (spf_reason_flags & SPF_FLAG_SUMMARY_LSA_INSTALL) - strcat (buf, "S, "); - if (spf_reason_flags & SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL) - strcat (buf, "AS, "); - if (spf_reason_flags & SPF_FLAG_ABR_STATUS_CHANGE) - strcat (buf, "ABR, "); - if (spf_reason_flags & SPF_FLAG_ASBR_STATUS_CHANGE) - strcat (buf, "ASBR, "); - if (spf_reason_flags & SPF_FLAG_MAXAGE) - strcat (buf, "M, "); - buf[strlen(buf)-2] = '\0'; /* skip the last ", " */ - } -} - static void ospf_vertex_free (void *); /* List of allocated vertices, to simplify cleanup of SPF. * Not thread-safe obviously. If it ever needs to be, it'd have to be @@ -1384,7 +1357,30 @@ ospf_spf_calculate_timer (struct thread *thread) total_spf_time = monotime_since(&spf_start_time, &ospf->ts_spf_duration); - ospf_get_spf_reason_str (rbuf); + rbuf[0] = '\0'; + if (spf_reason_flags) + { + if (spf_reason_flags & SPF_FLAG_ROUTER_LSA_INSTALL) + strncat (rbuf, "R, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_NETWORK_LSA_INSTALL) + strncat (rbuf, "N, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_SUMMARY_LSA_INSTALL) + strncat (rbuf, "S, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL) + strncat (rbuf, "AS, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_ABR_STATUS_CHANGE) + strncat (rbuf, "ABR, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_ASBR_STATUS_CHANGE) + strncat (rbuf, "ASBR, ", sizeof(rbuf) - strlen(rbuf) - 1); + if (spf_reason_flags & SPF_FLAG_MAXAGE) + strncat (rbuf, "M, ", sizeof(rbuf) - strlen(rbuf) - 1); + + size_t rbuflen = strlen(rbuf); + if (rbuflen >= 2) + rbuf[rbuflen - 2] = '\0'; /* skip the last ", " */ + else + rbuf[0] = '\0'; + } if (IS_DEBUG_OSPF_EVENT) { diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 59f2c33ceb..1a78e0b570 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -4411,9 +4411,8 @@ DEFUN (interface_no_ip_igmp, IFACE_IGMP_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; + struct pim_interface *pim_ifp = ifp->info; - pim_ifp = ifp->info; if (!pim_ifp) return CMD_SUCCESS; @@ -4663,13 +4662,11 @@ DEFUN (interface_ip_igmp_query_interval, "Query interval in seconds\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; + struct pim_interface *pim_ifp = ifp->info; int query_interval; int query_interval_dsec; int ret; - pim_ifp = ifp->info; - if (!pim_ifp) { ret = pim_cmd_igmp_start(vty, ifp); if (ret != CMD_SUCCESS) @@ -4721,11 +4718,9 @@ DEFUN (interface_no_ip_igmp_query_interval, IFACE_IGMP_QUERY_INTERVAL_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; + struct pim_interface *pim_ifp = ifp->info; int default_query_interval_dsec; - pim_ifp = ifp->info; - if (!pim_ifp) return CMD_SUCCESS; @@ -4753,12 +4748,10 @@ DEFUN (interface_ip_igmp_version, "IGMP version number\n") { VTY_DECLVAR_CONTEXT(interface,ifp); - struct pim_interface *pim_ifp = NULL; + struct pim_interface *pim_ifp = ifp->info; int igmp_version, old_version = 0; int ret; - pim_ifp = ifp->info; - if (!pim_ifp) { ret = pim_cmd_igmp_start(vty, ifp); @@ -4797,9 +4790,7 @@ DEFUN (interface_no_ip_igmp_version, "IGMP version number\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; - - pim_ifp = ifp->info; + struct pim_interface *pim_ifp = ifp->info; if (!pim_ifp) return CMD_SUCCESS; @@ -4821,12 +4812,10 @@ DEFUN (interface_ip_igmp_query_max_response_time, "Query response value in deci-seconds\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; + struct pim_interface *pim_ifp = ifp->info; int query_max_response_time; int ret; - pim_ifp = ifp->info; - if (!pim_ifp) { ret = pim_cmd_igmp_start(vty, ifp); if (ret != CMD_SUCCESS) @@ -4859,9 +4848,7 @@ DEFUN (interface_no_ip_igmp_query_max_response_time, "Time for response in deci-seconds\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; - - pim_ifp = ifp->info; + struct pim_interface *pim_ifp = ifp->info; if (!pim_ifp) return CMD_SUCCESS; @@ -4883,13 +4870,11 @@ DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec, "Query response value in deciseconds\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; + struct pim_interface *pim_ifp = ifp->info; int query_max_response_time_dsec; int default_query_interval_dsec; int ret; - pim_ifp = ifp->info; - if (!pim_ifp) { ret = pim_cmd_igmp_start(vty, ifp); if (ret != CMD_SUCCESS) @@ -4923,9 +4908,7 @@ DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec, IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; - - pim_ifp = ifp->info; + struct pim_interface *pim_ifp = ifp->info; if (!pim_ifp) return CMD_SUCCESS; @@ -4945,11 +4928,9 @@ DEFUN (interface_ip_pim_drprio, { VTY_DECLVAR_CONTEXT(interface, ifp); int idx_number = 3; - struct pim_interface *pim_ifp; + struct pim_interface *pim_ifp = ifp->info; uint32_t old_dr_prio; - pim_ifp = ifp->info; - if (!pim_ifp) { vty_out(vty, "Please enable PIM on interface, first%s", VTY_NEWLINE); return CMD_WARNING; @@ -4977,9 +4958,7 @@ DEFUN (interface_no_ip_pim_drprio, "Old Value of the Priority\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; - - pim_ifp = ifp->info; + struct pim_interface *pim_ifp = ifp->info; if (!pim_ifp) { vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE); @@ -5319,9 +5298,7 @@ DEFUN (interface_ip_pim_hello, VTY_DECLVAR_CONTEXT(interface, ifp); int idx_time = 3; int idx_hold = 4; - struct pim_interface *pim_ifp; - - pim_ifp = ifp->info; + struct pim_interface *pim_ifp = ifp->info; if (!pim_ifp) { @@ -5354,9 +5331,7 @@ DEFUN (interface_no_ip_pim_hello, IFACE_PIM_HELLO_HOLD_STR) { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp; - - pim_ifp = ifp->info; + struct pim_interface *pim_ifp = ifp->info; if (!pim_ifp) { vty_out(vty, "Pim not enabled on this interface%s", VTY_NEWLINE); @@ -5943,12 +5918,9 @@ DEFUN (ip_pim_bfd, "Enables BFD support\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp = NULL; + struct pim_interface *pim_ifp = ifp->info; struct bfd_info *bfd_info = NULL; - if (!ifp) - return CMD_SUCCESS; - pim_ifp = ifp->info; if (!pim_ifp) return CMD_SUCCESS; bfd_info = pim_ifp->bfd_info; @@ -5969,11 +5941,8 @@ DEFUN (no_ip_pim_bfd, "Disables BFD support\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - struct pim_interface *pim_ifp = NULL; - - assert (ifp); + struct pim_interface *pim_ifp = ifp->info; - pim_ifp = ifp->info; if (!pim_ifp) return CMD_SUCCESS; diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 01ba2039fb..4aa6ecd5f3 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -531,8 +531,8 @@ pim_ecmp_nexthop_search (struct pim_nexthop_cache *pnc, curr_route_valid = (nexthop->interface->ifindex == nh_node->ifindex); if (curr_route_valid && - !pim_if_connected_to_source (nexthop->interface, - src->u.prefix4)) + !pim_if_connected_to_source (nexthop->interface, + src->u.prefix4)) { nbr = pim_neighbor_find (nexthop->interface, nexthop->mrib_nexthop_addr.u.prefix4); @@ -678,6 +678,9 @@ pim_parse_nexthop_update (int command, struct zclient *zclient, struct pim_nexthop_cache *pnc = NULL; struct pim_neighbor *nbr = NULL; struct interface *ifp = NULL; + struct interface *ifp1 = NULL; + struct pim_interface *pim_ifp = NULL; + char str[INET_ADDRSTRLEN]; s = zclient->ibuf; memset (&p, 0, sizeof (struct prefix)); @@ -753,7 +756,7 @@ pim_parse_nexthop_update (int command, struct zclient *zclient, case NEXTHOP_TYPE_IPV6_IFINDEX: stream_get (&nexthop->gate.ipv6, s, 16); nexthop->ifindex = stream_getl (s); - struct interface *ifp1 = if_lookup_by_index (nexthop->ifindex, VRF_DEFAULT); + ifp1 = if_lookup_by_index (nexthop->ifindex, VRF_DEFAULT); nbr = pim_neighbor_find_if (ifp1); /* Overwrite with Nbr address as NH addr */ if (nbr) @@ -761,21 +764,20 @@ pim_parse_nexthop_update (int command, struct zclient *zclient, nexthop->gate.ipv4 = nbr->source_addr; if (PIM_DEBUG_TRACE) { - char str[INET_ADDRSTRLEN]; pim_inet4_dump ("<nht_nbr?>", nbr->source_addr, str, sizeof (str)); zlog_debug ("%s: NHT using pim nbr addr %s interface %s as rpf", - __PRETTY_FUNCTION__, str, ifp1->name); + __PRETTY_FUNCTION__, str, ifp1->name); } } else { if (PIM_DEBUG_TRACE) { - struct pim_interface *pim_ifp = ifp1->info; + pim_ifp = ifp1->info; zlog_debug ("%s: NHT pim nbr not found on interface %s nbr count:%d ", - __PRETTY_FUNCTION__, ifp1->name, - pim_ifp->pim_neighbor_list->count); + __PRETTY_FUNCTION__, ifp1->name, + pim_ifp->pim_neighbor_list->count); } //Mark nexthop address to 0 until PIM Nbr is resolved. nexthop->gate.ipv4.s_addr = PIM_NET_INADDR_ANY; diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index f373598bea..11d1ed01f3 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -2969,6 +2969,9 @@ ripng_clean() XFREE (MTYPE_ROUTE_TABLE, ripng->route); XFREE (MTYPE_ROUTE_TABLE, ripng->aggregate); + stream_free (ripng->ibuf); + stream_free (ripng->obuf); + XFREE (MTYPE_RIPNG, ripng); ripng = NULL; } /* if (ripng) */ diff --git a/tests/.gitignore b/tests/.gitignore index bab3385da2..5279016b92 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -43,3 +43,4 @@ __pycache__ /lib/test_table /lib/test_timer_correctness /lib/test_timer_performance +/lib/test_ttable diff --git a/tests/Makefile.am b/tests/Makefile.am index f48abac47a..da96453a9e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -44,6 +44,7 @@ check_PROGRAMS = \ lib/test_table \ lib/test_timer_correctness \ lib/test_timer_performance \ + lib/test_ttable \ lib/cli/test_cli \ lib/cli/test_commands \ $(TESTS_BGPD) @@ -84,6 +85,7 @@ lib_test_timer_correctness_SOURCES = lib/test_timer_correctness.c \ helpers/c/prng.c lib_test_timer_performance_SOURCES = lib/test_timer_performance.c \ helpers/c/prng.c +lib_test_ttable_SOURCES = lib/test_ttable.c lib_cli_test_cli_SOURCES = lib/cli/test_cli.c lib/cli/common_cli.c lib_cli_test_commands_SOURCES = lib/cli/test_commands_defun.c \ lib/cli/test_commands.c \ @@ -112,6 +114,7 @@ lib_test_stream_LDADD = $(ALL_TESTS_LDADD) lib_test_table_LDADD = $(ALL_TESTS_LDADD) -lm lib_test_timer_correctness_LDADD = $(ALL_TESTS_LDADD) lib_test_timer_performance_LDADD = $(ALL_TESTS_LDADD) +lib_test_ttable_LDADD = $(ALL_TESTS_LDADD) lib_cli_test_cli_LDADD = $(ALL_TESTS_LDADD) lib_cli_test_commands_LDADD = $(ALL_TESTS_LDADD) bgpd_test_aspath_LDADD = $(BGP_TEST_LDADD) @@ -140,7 +143,8 @@ EXTRA_DIST = \ lib/test_stream.py \ lib/test_stream.refout \ lib/test_table.py \ - lib/test_timer_correctness.py + lib/test_timer_correctness.py \ + lib/test_ttable.py .PHONY: tests.xml tests.xml: $(check_PROGRAMS) diff --git a/tests/lib/test_ttable.c b/tests/lib/test_ttable.c new file mode 100644 index 0000000000..674179b6ab --- /dev/null +++ b/tests/lib/test_ttable.c @@ -0,0 +1,183 @@ +/* + * ASCII table generator. + * Copyright (C) 2017 Cumulus Networks + * Quentin Young + * + * 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; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> +#include <termtable.h> +#include <memory.h> + +int main(int argc, char **argv) +{ + char *table; + + struct ttable *tt = ttable_new(&ttable_styles[TTSTYLE_ASCII]); + + /* test printf compatibility and dimension counters */ + ttable_add_row(tt, "%s|%s|%s", "Column 1", "Column 2", "Column 3"); + assert(tt->ncols == 3); + assert(tt->nrows == 1); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* add new row with 1 column, assert that it is not added */ + assert(ttable_add_row(tt, "%s", "Garbage") == NULL); + assert(tt->ncols == 3); + assert(tt->nrows == 1); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* add new row, assert that it is added */ + assert(ttable_add_row(tt, "%s|%s|%s", "a", "b", "c")); + assert(tt->ncols == 3); + assert(tt->nrows == 2); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* add empty row, assert that it is added */ + assert(ttable_add_row(tt, "||")); + assert(tt->ncols == 3); + assert(tt->nrows == 3); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* delete 1st row, assert that it is removed */ + ttable_del_row(tt, 0); + assert(tt->ncols == 3); + assert(tt->nrows == 2); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* delete last row, assert that it is removed */ + ttable_del_row(tt, 0); + assert(tt->ncols == 3); + assert(tt->nrows == 1); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* delete the remaining row, check dumping an empty table */ + ttable_del_row(tt, 0); + assert(tt->ncols == 0); + assert(tt->nrows == 0); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* add new row */ + ttable_add_row(tt, "%s|%s||%s|%9d", "slick", "black", "triple", 1337); + assert(tt->ncols == 5); + assert(tt->nrows == 1); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* add bigger row */ + ttable_add_row(tt, "%s|%s||%s|%s", + "nebula dusk session streets twilight " + "pioneer beats yeah", + "prarie dog", "cornmeal", ":O -*_-*"); + assert(tt->ncols == 5); + assert(tt->nrows == 2); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* insert new row at beginning */ + ttable_insert_row(tt, 0, "%s|%s||%d|%lf", "converting", "vegetarians", + 2, 2015.0); + assert(tt->ncols == 5); + assert(tt->nrows == 3); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* insert new row at end */ + ttable_insert_row(tt, tt->nrows - 1, "%s|%s||%d|%ld", "converting", + "vegetarians", 1, 2003L); + assert(tt->ncols == 5); + assert(tt->nrows == 4); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* insert new row at middle */ + ttable_insert_row(tt, 1, "%s|%s||%s|%ld", "she", "pioneer", "aki", 1l); + assert(tt->ncols == 5); + assert(tt->nrows == 5); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* set alignment */ + ttable_align(tt, 0, 1, 2, 2, LEFT); + assert(tt->ncols == 5); + assert(tt->nrows == 5); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + ttable_align(tt, 0, 1, 5, 1, RIGHT); + assert(tt->ncols == 5); + assert(tt->nrows == 5); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* set padding */ + ttable_pad(tt, 0, 1, 1, 1, RIGHT, 2); + assert(tt->ncols == 5); + assert(tt->nrows == 5); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + ttable_pad(tt, 0, 0, 5, 4, LEFT, 2); + assert(tt->ncols == 5); + assert(tt->nrows == 5); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* restyle */ + tt->style.cell.border.bottom_on = false; + tt->style.cell.border.top_on = false; + tt->style.cell.border.right_on = false; + tt->style.cell.border.left_on = false; + ttable_restyle(tt); + + /* top & double bottom border for top row */ + ttable_rowseps(tt, 0, BOTTOM, true, '-'); + ttable_rowseps(tt, 1, TOP, true, '-'); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* column separators for leftmost column */ + ttable_colseps(tt, 0, RIGHT, true, '|'); + table = ttable_dump(tt, "\n"); + fprintf(stdout, "%s\n", table); + XFREE(MTYPE_TMP, table); + + /* delete table */ + ttable_del(tt); +} diff --git a/tests/lib/test_ttable.py b/tests/lib/test_ttable.py new file mode 100644 index 0000000000..1d93932ad2 --- /dev/null +++ b/tests/lib/test_ttable.py @@ -0,0 +1,4 @@ +import frrtest + +class TestTTable(frrtest.TestRefOut): + program = './test_ttable' diff --git a/tests/lib/test_ttable.refout b/tests/lib/test_ttable.refout new file mode 100644 index 0000000000..fb59c0f3e1 --- /dev/null +++ b/tests/lib/test_ttable.refout @@ -0,0 +1,143 @@ + |--------------------------------| + | Column 1 | Column 2 | Column 3 | + |--------------------------------| + + |--------------------------------| + | Column 1 | Column 2 | Column 3 | + |--------------------------------| + + |--------------------------------| + | Column 1 | Column 2 | Column 3 | + |----------+----------+----------| + | a | b | c | + |--------------------------------| + + |--------------------------------| + | Column 1 | Column 2 | Column 3 | + |----------+----------+----------| + | a | b | c | + |----------+----------+----------| + | | | | + |--------------------------------| + + |-----------| + | a | b | c | + |---+---+---| + | | | | + |-----------| + + |--------| + | | | | + |--------| + + || + || + + |---------------------------------------| + | slick | black | | triple | 1337 | + |---------------------------------------| + + |------------------------------------------------------------------------------------------------| + | slick | black | | triple | 1337 | + |---------------------------------------------------------+------------+--+----------+-----------| + | nebula dusk session streets twilight pioneer beats yeah | prarie dog | | cornmeal | :O -*_-* | + |------------------------------------------------------------------------------------------------| + + |---------------------------------------------------------------------------------------------------| + | converting | vegetarians | | 2 | 2015.000000 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | slick | black | | triple | 1337 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | nebula dusk session streets twilight pioneer beats yeah | prarie dog | | cornmeal | :O -*_-* | + |---------------------------------------------------------------------------------------------------| + + |---------------------------------------------------------------------------------------------------| + | converting | vegetarians | | 2 | 2015.000000 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | slick | black | | triple | 1337 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | converting | vegetarians | | 1 | 2003 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | nebula dusk session streets twilight pioneer beats yeah | prarie dog | | cornmeal | :O -*_-* | + |---------------------------------------------------------------------------------------------------| + + |---------------------------------------------------------------------------------------------------| + | converting | vegetarians | | 2 | 2015.000000 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | she | pioneer | | aki | 1 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | slick | black | | triple | 1337 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | converting | vegetarians | | 1 | 2003 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | nebula dusk session streets twilight pioneer beats yeah | prarie dog | | cornmeal | :O -*_-* | + |---------------------------------------------------------------------------------------------------| + + |---------------------------------------------------------------------------------------------------| + | converting | vegetarians | | 2 | 2015.000000 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | she | pioneer | | aki | 1 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | slick | black | | triple | 1337 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | converting | vegetarians | | 1 | 2003 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | nebula dusk session streets twilight pioneer beats yeah | prarie dog | | cornmeal | :O -*_-* | + |---------------------------------------------------------------------------------------------------| + + |---------------------------------------------------------------------------------------------------| + | converting | vegetarians | | 2 | 2015.000000 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | she | pioneer | | aki | 1 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | slick | black | | triple | 1337 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | converting | vegetarians | | 1 | 2003 | + |---------------------------------------------------------+-------------+--+----------+-------------| + | nebula dusk session streets twilight pioneer beats yeah | prarie dog | | cornmeal | :O -*_-* | + |---------------------------------------------------------------------------------------------------| + + |----------------------------------------------------------------------------------------------------| + | converting | vegetarians | | 2 | 2015.000000 | + |---------------------------------------------------------+--------------+--+----------+-------------| + | she | pioneer | | aki | 1 | + |---------------------------------------------------------+--------------+--+----------+-------------| + | slick | black | | triple | 1337 | + |---------------------------------------------------------+--------------+--+----------+-------------| + | converting | vegetarians | | 1 | 2003 | + |---------------------------------------------------------+--------------+--+----------+-------------| + | nebula dusk session streets twilight pioneer beats yeah | prarie dog | | cornmeal | :O -*_-* | + |----------------------------------------------------------------------------------------------------| + + |--------------------------------------------------------------------------------------------------------| + | converting | vegetarians | | 2 | 2015.000000 | + |----------------------------------------------------------+---------------+---+-----------+-------------| + | she | pioneer | | aki | 1 | + |----------------------------------------------------------+---------------+---+-----------+-------------| + | slick | black | | triple | 1337 | + |----------------------------------------------------------+---------------+---+-----------+-------------| + | converting | vegetarians | | 1 | 2003 | + |----------------------------------------------------------+---------------+---+-----------+-------------| + | nebula dusk session streets twilight pioneer beats yeah | prarie dog | | cornmeal | :O -*_-* | + |--------------------------------------------------------------------------------------------------------| + + |-----------------------------------------------------------------------------------------------| + | converting vegetarians 2 2015.000000 | + |-----------------------------------------------------------------------------------------------| + |-----------------------------------------------------------------------------------------------| + | she pioneer aki 1 | + | slick black triple 1337 | + | converting vegetarians 1 2003 | + | nebula dusk session streets twilight pioneer beats yeah prarie dog cornmeal :O -*_-* | + |-----------------------------------------------------------------------------------------------| + + |------------------------------------------------------------------------------------------------| + | converting | vegetarians 2 2015.000000 | + |---------------------------------------------------------+--------------------------------------| + |---------------------------------------------------------+--------------------------------------| + | she | pioneer aki 1 | + | slick | black triple 1337 | + | converting | vegetarians 1 2003 | + | nebula dusk session streets twilight pioneer beats yeah | prarie dog cornmeal :O -*_-* | + |------------------------------------------------------------------------------------------------| + diff --git a/tools/Makefile.am b/tools/Makefile.am index de81919cdd..dd32d0dab0 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -13,6 +13,4 @@ sbin_SCRIPTS = frr-reload.py frr EXTRA_DIST += frr.service frr-reload.py frr -EXTRA_DIST += xml2cli.pl - ssd_SOURCES = start-stop-daemon.c diff --git a/tools/xml2cli.pl b/tools/xml2cli.pl deleted file mode 100755 index 40f905bcde..0000000000 --- a/tools/xml2cli.pl +++ /dev/null @@ -1,446 +0,0 @@ -#!/usr/bin/perl -## -## Parse a XML file containing a tree-like representation of Quagga CLI -## commands and generate a file with: -## -## - a DEFUN function for each command; -## - an initialization function. -## -## -## Copyright (C) 2012 Renato Westphal <renatow@digistar.com.br> -## 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. -## - -use strict; -use warnings; -use Getopt::Std; -use vars qw($opt_d); -use File::Basename qw(fileparse); -use XML::LibXML; - -%::input_strs = ( - "ifname" => "IFNAME", - "word" => "WORD", - "line" => ".LINE", - "ipv4" => "A.B.C.D", - "ipv4m" => "A.B.C.D/M", - "ipv6" => "X:X::X:X", - "ipv6m" => "X:X::X:X/M", - "mtu" => "(1500-9180)", - "acl_range" => "(1-199)", - "acl_expanded_range" => "(1300-2699)", - # BGP specific - "rd" => "ASN:nn_or_IP-address:nn", - "asn" => "(1-4294967295)", - "community" => "AA:NN", - "clist" => "(1-500)", - # LDP specific - "disc_time" => "(1-65535)", - "session_time" => "(15-65535)", - "pwid" => "(1-4294967295)", - "hops" => "(1-254)" - ); - -# parse options node and store the corresponding information -# into a global hash of hashes -sub parse_options { - my $xml_node = $_[0]; - my @cmdstr; - - my $options_name = $xml_node->findvalue('./@name'); - if (not $options_name) { - die('error: "options" node without "name" attribute'); - } - - # initialize hash - $::options{$options_name}{'cmdstr'} = ""; - $::options{$options_name}{'help'} = ""; - - my @children = $xml_node->getChildnodes(); - foreach my $child(@children) { - # skip comments, random text, etc - if ($child->getType() != XML_ELEMENT_NODE) { - next; - } - - # check for error/special conditions - if ($child->getName() ne "option") { - die('error: invalid node type: "' . $child->getName() . '"'); - } - - my $name = $child->findvalue('./@name'); - my $input = $child->findvalue('./@input'); - my $help = $child->findvalue('./@help'); - if ($input) { - $name = $::input_strs{$input}; - } - - push (@cmdstr, $name); - $::options{$options_name}{'help'} .= "\n \"" . $help . "\\n\""; - } - $::options{$options_name}{'cmdstr'} = "<" . join('|', @cmdstr) . ">"; -} - -# given a subtree, replace all the corresponding include nodes by -# this subtree -sub subtree_replace_includes { - my $subtree = $_[0]; - - my $subtree_name = $subtree->findvalue('./@name'); - if (not $subtree_name) { - die("subtree without \"name\" attribute"); - } - - my $query = "//include[\@subtree='$subtree_name']"; - foreach my $include_node($::xml->findnodes($query)) { - my @children = $subtree->getChildnodes(); - foreach my $child(reverse @children) { - my $include_node_parent = $include_node->getParentNode(); - $include_node_parent->insertAfter($child->cloneNode(1), - $include_node); - } - $include_node->unbindNode(); - } - $subtree->unbindNode(); -} - -# generate arguments for a given command -sub generate_arguments { - my @nodes = @_; - my $arguments; - my $no_args = 1; - my $argc = -1; - - $arguments .= " struct vty_arg *args[] =\n"; - $arguments .= " {\n"; - for (my $i = 0; $i < @nodes; $i++) { - my %node = %{$nodes[$i]}; - my $arg_value; - - $argc++; - if (not $node{'arg'}) { - next; - } - $no_args = 0; - - # for input and select nodes, the value of the argument is an - # argv[] element. for the other types of nodes, the value of the - # argument is the name of the node - if ($node{'input'} or $node{'type'} eq "select") { - $arg_value = "argv[" . $argc . "]->arg"; - } elsif ($node{'optional'}) { - $arg_value = "(argc > " . $argc . " ? argv[" . $argc. "]->arg : NULL)"; - } else { - $arg_value = '"' . $node{'name'} . '"'; - } - - if ($node{'input'} and $node{'input'} eq "line") { - # arguments of the type 'line' may have multiple spaces (i.e - # they don't fit into a single argv[] element). to properly - # handle these arguments, we need to provide direct access - # to the argv[] array and the argc variable. - my $argc_str = "argc" . (($argc > 1) ? " - " . ($argc - 1) : ""); - my $argv_str = "argv" . (($argc > 1) ? " + " . ($argc - 1) : ""); - $arguments .= " &(struct vty_arg) { " - . ".name = \"" . $node{'arg'} . "\", " - . ".argc = $argc_str, " - . ".argv = $argv_str },\n"; - } else { - # common case - each argument has a name and a single value - $arguments .= " &(struct vty_arg) { " - . ".name = \"" . $node{'arg'} . "\", " - . ".value = " . $arg_value . " },\n"; - } - } - $arguments .= " NULL\n"; - $arguments .= " };\n"; - - # handle special case - if ($no_args) { - return " struct vty_arg *args[] = { NULL };\n"; - } - - return $arguments; -} - -# generate C code -sub generate_code { - my @nodes = @_; - my $funcname = ''; - my $cmdstr = ''; - my $cmdname = ''; - my $helpstr = ''; - my $function = ''; - - for (my $i = 0; $i < @nodes; $i++) { - my %node = %{$nodes[$i]}; - if ($node{'input'}) { - $funcname .= $node{'input'} . " "; - $cmdstr .= $::input_strs{$node{'input'}} . " "; - $helpstr .= "\n \"" . $node{'help'} . "\\n\""; - } elsif ($node{'type'} eq "select") { - my $options_name = $node{'options'}; - $funcname .= $options_name . " "; - $cmdstr .= $::options{$options_name}{'cmdstr'} . " "; - $helpstr .= $::options{$options_name}{'help'}; - } else { - $funcname .= $node{'name'} . " "; - if ($node{'optional'}) { - $cmdstr .= "[" . $node{'name'} . "] "; - } else { - $cmdstr .= $node{'name'} . " "; - } - $helpstr .= "\n \"" . $node{'help'} . "\\n\""; - } - - # update the command string - if ($node{'function'} ne "inherited" and $node{'function'}) { - $function = $node{'function'}; - } - } - - # rtrim - $funcname =~ s/\s+$//; - $cmdstr =~ s/\s+$//; - # lowercase - $funcname = lc($funcname); - # replace " " by "_" - $funcname =~ tr/ /_/; - # replace "-" by "_" - $funcname =~ tr/-/_/; - # add prefix - $funcname = $::cmdprefix . '_' . $funcname; - - # generate DEFUN - $cmdname = $funcname . "_cmd"; - - # don't generate same command more than once - if ($::commands{$cmdname}) { - return $cmdname; - } - $::commands{$cmdname} = "1"; - - print STDOUT "DEFUN (" . $funcname . ",\n" - . " " . $cmdname . ",\n" - . " \"" . $cmdstr . "\"," - . $helpstr . ")\n" - . "{\n" - . generate_arguments(@nodes) - . " return " . $function . " (vty, args);\n" - . "}\n\n"; - - return $cmdname; -} - -# parse tree node (recursive function) -sub parse_tree { - # get args - my $xml_node = $_[0]; - my @nodes = @{$_[1]}; - my $tree_name = $_[2]; - - # hash containing all the node attributes - my %node; - $node{'type'} = $xml_node->getName(); - - # check for error/special conditions - if ($node{'type'} eq "tree") { - goto end; - } - if ($node{'type'} eq "include") { - die('error: can not include "' - . $xml_node->findvalue('./@subtree') . '"'); - } - if (not $node{'type'} ~~ [qw(option select)]) { - die('error: invalid node type: "' . $node{'type'} . '"'); - } - if ($node{'type'} eq "select") { - my $options_name = $xml_node->findvalue('./@options'); - if (not $options_name) { - die('error: "select" node without "name" attribute'); - } - if (not $::options{$options_name}) { - die('error: can not find options'); - } - $node{'options'} = $options_name; - } - - # get node attributes - $node{'name'} = $xml_node->findvalue('./@name'); - $node{'input'} = $xml_node->findvalue('./@input'); - $node{'arg'} = $xml_node->findvalue('./@arg'); - $node{'help'} = $xml_node->findvalue('./@help'); - $node{'function'} = $xml_node->findvalue('./@function'); - $node{'ifdef'} = $xml_node->findvalue('./@ifdef'); - $node{'optional'} = $xml_node->findvalue('./@optional'); - - # push node to stack - push (@nodes, \%node); - - # generate C code - if ($node{'function'}) { - my $cmdname = generate_code(@nodes); - push (@{$::trees{$tree_name}}, [0, $cmdname, 0]); - } - - if ($node{'ifdef'}) { - push (@{$::trees{$tree_name}}, [$node{'ifdef'}, 0, 0]); - } - -end: - # recursively process child nodes - my @children = $xml_node->getChildnodes(); - foreach my $child(@children) { - # skip comments, random text, etc - if ($child->getType() != XML_ELEMENT_NODE) { - next; - } - parse_tree($child, \@nodes, $tree_name); - } - - if ($node{'ifdef'}) { - push (@{$::trees{$tree_name}}, [0, 0, $node{'ifdef'}]); - } -} - -sub parse_node { - # get args - my $xml_node = $_[0]; - - my $node_name = $xml_node->findvalue('./@name'); - if (not $node_name) { - die('missing the "name" attribute'); - } - - my $install = $xml_node->findvalue('./@install'); - my $config_write = $xml_node->findvalue('./@config_write'); - if ($install and $install eq "1") { - print " install_node (&" .lc( $node_name) . "_node, " . $config_write . ");\n"; - } - - my $install_default = $xml_node->findvalue('./@install_default'); - if ($install_default and $install_default eq "1") { - print " install_default (" . $node_name . "_NODE);\n"; - } - - my @children = $xml_node->getChildnodes(); - foreach my $child(@children) { - # skip comments, random text, etc - if ($child->getType() != XML_ELEMENT_NODE) { - next; - } - - if ($child->getName() ne "include") { - die('error: invalid node type: "' . $child->getName() . '"'); - } - my $tree_name = $child->findvalue('./@tree'); - if (not $tree_name) { - die('missing the "tree" attribute'); - } - - foreach my $entry (@{$::trees{$tree_name}}) { - my ($ifdef, $cmdname, $endif) = @{$entry}; - - if ($ifdef) { - print ("#ifdef " . $ifdef . "\n"); - } - - if ($cmdname) { - print " install_element (" . $node_name . "_NODE, &" . $cmdname . ");\n"; - } - - if ($endif) { - print ("#endif /* " . $endif . " */\n"); - } - } - } -} - -# parse command-line arguments -if (not getopts('d')) { - die("Usage: xml2cli.pl [-d] FILE\n"); -} -my $file = shift; - -# initialize the XML parser -my $parser = new XML::LibXML; -$parser->keep_blanks(0); - -# parse XML file -$::xml = $parser->parse_file($file); -my $xmlroot = $::xml->getDocumentElement(); -if ($xmlroot->getName() ne "file") { - die('XML root element name must be "file"'); -} - -# read file attributes -my $init_function = $xmlroot->findvalue('./@init'); -if (not $init_function) { - die('missing the "init" attribute in the "file" node'); -} -$::cmdprefix = $xmlroot->findvalue('./@cmdprefix'); -if (not $::cmdprefix) { - die('missing the "cmdprefix" attribute in the "file" node'); -} -my $header = $xmlroot->findvalue('./@header'); -if (not $header) { - die('missing the "header" attribute in the "file" node'); -} - -# generate source header -print STDOUT "/* Auto-generated from " . fileparse($file) . ". */\n" - . "/* Do not edit! */\n\n" - . "#include <zebra.h>\n\n" - . "#include \"command.h\"\n" - . "#include \"vty.h\"\n" - . "#include \"$header\"\n\n"; - -# Parse options -foreach my $options($::xml->findnodes("/file/options")) { - parse_options($options); -} - -# replace include nodes by the corresponding subtrees -foreach my $subtree(reverse $::xml->findnodes("/file/subtree")) { - subtree_replace_includes($subtree); -} - -# Parse trees -foreach my $tree($::xml->findnodes("/file/tree")) { - my @nodes = (); - my $tree_name = $tree->findvalue('./@name'); - parse_tree($tree, \@nodes, $tree_name); -} - -# install function header -print STDOUT "void\n" - . $init_function . " (void)\n" - . "{\n"; - -# Parse nodes -foreach my $node($::xml->findnodes("/file/node")) { - parse_node($node); -} - -# closing braces for the install function -print STDOUT "}"; - -# print to stderr the expanded XML file if the debug flag (-d) is given -if ($opt_d) { - print STDERR $::xml->toString(1); -} diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am index 587f72c809..8b66ba2564 100644 --- a/vtysh/Makefile.am +++ b/vtysh/Makefile.am @@ -108,6 +108,10 @@ vtysh_scan += $(top_srcdir)/ripngd/ripng_zebra.c vtysh_scan += $(top_srcdir)/ripngd/ripngd.c endif +if LDPD +vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c +endif + if NHRPD vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c endif @@ -146,22 +150,5 @@ vtysh_cmd_FILES = $(vtysh_scan) \ $(top_srcdir)/watchfrr/watchfrr_vty.c \ $(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC) -# this is slightly iffy... ldp_vty_cmds.c can be located in either -# $srcdir or $builddir depending on whether it's coming pre-built from a -# dist tarball or being built. automake uses VPATH to find it, but that -# doesn't work here... -# so after running "make ldp_vty_cmds.c", the file can be in either of the -# two directories. we need to do some magic to find out which. -vtysh_cmd_DEPS = $(vtysh_cmd_FILES) -if LDPD -$(top_builddir)/ldpd/ldp_vty_cmds.c: - make -C "$(top_builddir)/ldpd" ldp_vty_cmds.c -vtysh_cmd_DEPS += $(top_builddir)/ldpd/ldp_vty_cmds.c -endif - -vtysh_cmd.c: $(vtysh_cmd_DEPS) extract.pl - if test -n "${LDPD}"; then \ - ldpcmds="$(top_srcdir)/ldpd/ldp_vty_cmds.c"; \ - test -f "$(top_builddir)/ldpd/ldp_vty_cmds.c" && ldpcmds="$(top_builddir)/ldpd/ldp_vty_cmds.c"; \ - fi; \ - ./extract.pl $(vtysh_cmd_FILES) $${ldpcmds} > vtysh_cmd.c +vtysh_cmd.c: $(vtysh_cmd_FILES) extract.pl + ./extract.pl $(vtysh_cmd_FILES) > vtysh_cmd.c diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 30168a2d98..ffdfd5d725 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2588,7 +2588,7 @@ int vtysh_write_config_integrated(void) { u_int i; - char line[] = "write terminal\n"; + char line[] = "do write terminal\n"; FILE *fp; int fd; struct passwd *pwentry; @@ -2713,7 +2713,7 @@ DEFUN (vtysh_write_memory, if (vtysh_client[i].flag == VTYSH_WATCHFRR) break; if (i < array_size(vtysh_client) && vtysh_client[i].fd != -1) - ret = vtysh_client_execute (&vtysh_client[i], "write integrated", stdout); + ret = vtysh_client_execute (&vtysh_client[i], "do write integrated", stdout); if (ret != CMD_SUCCESS) { diff --git a/zebra/.gitignore b/zebra/.gitignore index df703b67f8..145df05689 100644 --- a/zebra/.gitignore +++ b/zebra/.gitignore @@ -4,7 +4,6 @@ Makefile.in zebra zebra.conf client -testzebra tags TAGS .deps diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 3e0de3b463..0b66e905c7 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -22,7 +22,6 @@ otherobj = $(ioctl_method) $(ipforward) $(if_method) \ AM_CFLAGS = $(WERROR) sbin_PROGRAMS = zebra -noinst_PROGRAMS = testzebra module_LTLIBRARIES = zebra_SOURCES = \ @@ -36,12 +35,6 @@ zebra_SOURCES = \ label_manager.c \ # end -testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \ - zebra_vty.c zebra_ptm.c zebra_routemap.c zebra_ns.c zebra_vrf.c \ - kernel_null.c redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c \ - zebra_ptm_null.c rtadv_null.c if_null.c zserv_null.c zebra_static.c \ - zebra_memory.c zebra_mpls.c zebra_mpls_vty.c zebra_mpls_null.c - noinst_HEADERS = \ zebra_memory.h \ connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \ @@ -53,8 +46,6 @@ noinst_HEADERS = \ zebra_LDADD = $(otherobj) ../lib/libfrr.la $(LIBCAP) -testzebra_LDADD = ../lib/libfrr.la $(LIBCAP) - zebra_DEPENDENCIES = $(otherobj) if SNMP @@ -88,7 +79,7 @@ EXTRA_DIST = if_ioctl.c if_ioctl_solaris.c if_netlink.c \ rt_socket.c rtread_netlink.c rtread_sysctl.c \ rtread_getmsg.c kernel_socket.c kernel_netlink.c \ ioctl.c ioctl_solaris.c \ - zebra_mpls_netlink.c zebra_mpls_openbsd.c \ + zebra_mpls_netlink.c zebra_mpls_openbsd.c zebra_mpls_null.c \ GNOME-SMI GNOME-PRODUCT-ZEBRA-MIB client : client_main.o ../lib/libfrr.la diff --git a/zebra/client_main.c b/zebra/client_main.c index c9d738bb08..0e77ea4aec 100644 --- a/zebra/client_main.c +++ b/zebra/client_main.c @@ -48,7 +48,12 @@ zebra_test_ipv4 (int command, int type, char *prefix, char *gateway, struct in_addr *gpnt; str2prefix_ipv4 (prefix, &p); - inet_aton (gateway, &gate); + if (!inet_aton (gateway, &gate)) + { + printf("Gateway specified: %s is illegal\n", gateway); + return; + } + gpnt = &gate; api.vrf_id = VRF_DEFAULT; diff --git a/zebra/if_null.c b/zebra/if_null.c deleted file mode 100644 index 7cba0a4ee2..0000000000 --- a/zebra/if_null.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2015 Cumulus Networks, Inc. - * Donald Sharp - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include <vrf.h> -#include <prefix.h> - -#include <rtadv.h> -#include <zebra_ns.h> - -void interface_list (struct zebra_ns *zns) -{ return; } diff --git a/zebra/ioctl_null.c b/zebra/ioctl_null.c deleted file mode 100644 index 9cc2daedbe..0000000000 --- a/zebra/ioctl_null.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2006 Sun Microsystems, Inc. - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include "zebra/rib.h" -#include "zebra/rt.h" -#include "zebra/ioctl.h" - -void ifreq_set_name (struct ifreq *a, struct interface *b) { return; } - -int if_set_prefix (struct interface *a, struct connected *b) -{ - kernel_address_add_ipv4 (a, b); - return 0; -} - -int if_unset_prefix (struct interface *a, struct connected *b) -{ - kernel_address_delete_ipv4 (a, b); - return 0; -} - -int if_prefix_add_ipv6 (struct interface *a, struct connected *b) { return 0; } -int if_prefix_delete_ipv6 (struct interface *a, struct connected *b) { return 0; } - -int if_ioctl (u_long a, caddr_t b) { return 0; } - -int if_set_flags (struct interface *a, uint64_t b) { return 0; } -int if_unset_flags (struct interface *a, uint64_t b) { return 0; } - -void if_get_flags (struct interface *a) { return; } - -#ifdef SOLARIS_IPV6 -#pragma weak if_ioctl_ipv6 = if_ioctl -struct connected *if_lookup_linklocal(struct interface *a) { return 0; } - -#define AF_IOCTL(af, request, buffer) \ - ((af) == AF_INET? if_ioctl(request, buffer) : \ - if_ioctl_ipv6(request, buffer)) -#else /* SOLARIS_IPV6 */ - -#define AF_IOCTL(af, request, buffer) if_ioctl(request, buffer) - -#endif /* SOLARIS_IPV6 */ diff --git a/zebra/kernel_null.c b/zebra/kernel_null.c deleted file mode 100644 index 5f1a054bdc..0000000000 --- a/zebra/kernel_null.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * NULL kernel methods for testing. - * Copyright (C) 2006 Sun Microsystems, Inc. - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> -#include <log.h> - -#include "vty.h" -#include "zebra/zserv.h" -#include "zebra/rt.h" -#include "zebra/redistribute.h" -#include "zebra/connected.h" -#include "zebra/rt_netlink.h" -#include "zebra/rib.h" - -int kernel_route_rib (struct prefix *a, struct prefix *b, - struct route_entry *old, struct route_entry *new) { return 0; } - -int kernel_address_add_ipv4 (struct interface *a, struct connected *b) -{ - zlog_debug ("%s", __func__); - SET_FLAG (b->conf, ZEBRA_IFC_REAL); - connected_add_ipv4 (a, 0, &b->address->u.prefix4, b->address->prefixlen, - (b->destination ? &b->destination->u.prefix4 : NULL), - NULL); - return 0; -} - -int kernel_address_delete_ipv4 (struct interface *a, struct connected *b) -{ - zlog_debug ("%s", __func__); - connected_delete_ipv4 (a, 0, &b->address->u.prefix4, b->address->prefixlen, - (b->destination ? &b->destination->u.prefix4 : NULL)); - return 0; -} - -int kernel_neigh_update (int a, int b, uint32_t c, char *d, int e) -{ - return 0; -} - -void kernel_init (struct zebra_ns *zns) { return; } -void kernel_terminate (struct zebra_ns *zns) { return; } -void route_read (struct zebra_ns *zns) { return; } - -int kernel_get_ipmr_sg_stats (void *m) { return 0; } diff --git a/zebra/misc_null.c b/zebra/misc_null.c deleted file mode 100644 index f58eb628b0..0000000000 --- a/zebra/misc_null.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2006 Sun Microsystems, Inc. - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include "prefix.h" -#include "zebra/rtadv.h" -#include "zebra/irdp.h" -#include "zebra/interface.h" - -#if defined (HAVE_RTADV) -void rtadv_config_write (struct vty *vty, struct interface *ifp) { return; } -#endif -void irdp_config_write (struct vty *vty, struct interface *ifp) { return; } -#ifdef HAVE_PROC_NET_DEV -void ifstat_update_proc (void) { return; } -#endif -#ifdef HAVE_NET_RT_IFLIST -void ifstat_update_sysctl (void) { return; } -#endif diff --git a/zebra/redistribute_null.c b/zebra/redistribute_null.c deleted file mode 100644 index 3b83a6b6ae..0000000000 --- a/zebra/redistribute_null.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2006 Sun Microsystems, Inc. - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> -#include "vty.h" -#include "zebra/rib.h" -#include "zebra/zserv.h" - -#include "zebra/redistribute.h" - -void zebra_redistribute_add (int a, struct zserv *b, int c, - struct zebra_vrf *zvrf) -{ return; } -void zebra_redistribute_delete (int a, struct zserv *b, int c, - struct zebra_vrf *zvrf) -{ return; } -void zebra_redistribute_default_add (int a, struct zserv *b, int c, - struct zebra_vrf *zvrf) -{ return; } -void zebra_redistribute_default_delete (int a, struct zserv *b, int c, - struct zebra_vrf *zvrf) -{ return; } - -void redistribute_update (struct prefix *a, struct prefix *b, - struct route_entry *c, struct route_entry *d) -{ return; } -void redistribute_delete (struct prefix *a, struct prefix *b, struct route_entry *c) -{ return; } - -void zebra_interface_up_update (struct interface *a) -{ return; } -void zebra_interface_down_update (struct interface *a) -{ return; } -void zebra_interface_add_update (struct interface *a) -{ return; } -void zebra_interface_delete_update (struct interface *a) -{ return; } - - -void zebra_interface_address_add_update (struct interface *a, - struct connected *b) -{ return; } -void zebra_interface_address_delete_update (struct interface *a, - struct connected *b) -{ return; } - -/* Interface parameters update */ -void zebra_interface_parameters_update (struct interface *ifp) -{ return; }; - -void zebra_interface_vrf_update_del (struct interface *a, vrf_id_t new_vrf_id) -{ return; } - -void zebra_interface_vrf_update_add (struct interface *a, vrf_id_t old_vrf_id) -{ return; } - -int zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, - const char *rmap_name, int add) -{ return 0; } - -int zebra_add_import_table_entry (struct route_node *rn, struct route_entry *re, const char *rmap_name) -{ return 0; } - -int zebra_del_import_table_entry (struct route_node *rn, struct route_entry *re) -{ return 0; } - -int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id) -{ return 0; } - -int zebra_import_table_config(struct vty *vty) -{ return 0; } - -void zebra_import_table_rm_update() -{ return; } diff --git a/zebra/rtadv_null.c b/zebra/rtadv_null.c deleted file mode 100644 index ccb1a39e02..0000000000 --- a/zebra/rtadv_null.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2015 Cumulus Networks, Inc. - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> -#include <lib/prefix.h> -#include <rtadv.h> -#include <zebra_ns.h> - -void zebra_interface_radv_set (struct zserv *client, int sock, u_short length, - struct zebra_vrf *zvrf, int enable) -{ return; } - -void rtadv_init (struct zebra_ns *zns) -{ return; } - -void rtadv_terminate (struct zebra_ns *zns) -{ return; } diff --git a/zebra/test_main.c b/zebra/test_main.c deleted file mode 100644 index 83c1ebb178..0000000000 --- a/zebra/test_main.c +++ /dev/null @@ -1,339 +0,0 @@ -/* main routine. - * Copyright (C) 1997, 98 Kunihiro Ishiguro - * - * 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 this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include <lib/version.h> -#include "getopt.h" -#include "command.h" -#include "thread.h" -#include "filter.h" -#include "memory.h" -#include "zebra_memory.h" -#include "memory_vty.h" -#include "prefix.h" -#include "log.h" -#include "privs.h" -#include "sigevent.h" -#include "vrf.h" - -#include "zebra/rib.h" -#include "zebra/zebra_ns.h" -#include "zebra/zserv.h" -#include "zebra/zebra_vrf.h" -#include "zebra/debug.h" -#include "zebra/router-id.h" -#include "zebra/interface.h" - -/* Zebra instance */ -struct zebra_t zebrad = -{ - .rtm_table_default = 0, -}; - -/* process id. */ -pid_t pid; - -/* Allow non-quagga entities to delete quagga routes */ -int allow_delete = 0; - -/* zebra_rib's workqueue hold time. Private export for use by test code only */ -extern int rib_process_hold_time; - -/* Pacify zclient.o in libfrr, which expects this variable. */ -struct thread_master *master; - -/* Command line options. */ -struct option longopts[] = -{ - { "batch", no_argument, NULL, 'b'}, - { "daemon", no_argument, NULL, 'd'}, - { "allow_delete", no_argument, NULL, 'a'}, - { "config_file", required_argument, NULL, 'f'}, - { "help", no_argument, NULL, 'h'}, - { "vty_addr", required_argument, NULL, 'A'}, - { "vty_port", required_argument, NULL, 'P'}, - { "version", no_argument, NULL, 'v'}, - { "rib_hold", required_argument, NULL, 'r'}, - { 0 } -}; - -zebra_capabilities_t _caps_p [] = -{ - ZCAP_NET_ADMIN, - ZCAP_SYS_ADMIN, - ZCAP_NET_RAW, -}; - -/* Default configuration file path. */ -char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE; - -/* Process ID saved for use by init system */ -const char *pid_file = "testzebra.pid"; - -/* Help information display. */ -static void -usage (char *progname, int status) -{ - if (status != 0) - fprintf (stderr, "Try `%s --help' for more information.\n", progname); - else - { - printf ("Usage : %s [OPTION...]\n\n"\ - "Daemon which manages kernel routing table management and "\ - "redistribution between different routing protocols.\n\n"\ - "-b, --batch Runs in batch mode\n"\ - "-d, --daemon Runs in daemon mode\n"\ - "-a, --allow_delete Allow other processes to delete zebra routes\n" \ - "-f, --config_file Set configuration file name\n"\ - "-A, --vty_addr Set vty's bind address\n"\ - "-P, --vty_port Set vty's port number\n"\ - "-r, --rib_hold Set rib-queue hold time\n"\ - "-v, --version Print program version\n"\ - "-h, --help Display this help and exit\n"\ - "\n"\ - "Report bugs to %s\n", progname, FRR_BUG_ADDRESS); - } - - exit (status); -} - -static ifindex_t test_ifindex = 0; - -/* testrib commands */ -DEFUN (test_interface_state, - test_interface_state_cmd, - "state <up|down>", - "configure interface\n" - "up\n" - "down\n") -{ - int idx_up_down = 1; - VTY_DECLVAR_CONTEXT (interface, ifp); - - if (ifp->ifindex == IFINDEX_INTERNAL) - { - ifp->ifindex = ++test_ifindex; - ifp->mtu = 1500; - ifp->flags = IFF_BROADCAST|IFF_MULTICAST; - } - - switch (argv[idx_up_down]->arg[0]) - { - case 'u': - SET_FLAG (ifp->flags, IFF_UP); - if_add_update (ifp); - printf ("up\n"); - break; - case 'd': - UNSET_FLAG (ifp->flags, IFF_UP); - if_delete_update (ifp); - printf ("down\n"); - break; - default: - return CMD_WARNING; - } - return CMD_SUCCESS; -} - -static void -test_cmd_init (void) -{ - install_element (INTERFACE_NODE, &test_interface_state_cmd); -} - -/* SIGHUP handler. */ -static void -sighup (void) -{ - zlog_info ("SIGHUP received"); - - /* Reload of config file. */ - ; -} - -/* SIGINT handler. */ -static void -sigint (void) -{ - zlog_notice ("Terminating on signal"); - - exit (0); -} - -/* SIGUSR1 handler. */ -static void -sigusr1 (void) -{ - zlog_rotate(); -} - -struct quagga_signal_t zebra_signals[] = -{ - { - .signal = SIGHUP, - .handler = &sighup, - }, - { - .signal = SIGUSR1, - .handler = &sigusr1, - }, - { - .signal = SIGINT, - .handler = &sigint, - }, - { - .signal = SIGTERM, - .handler = &sigint, - }, -}; -/* Main startup routine. */ -int -main (int argc, char **argv) -{ - char *p; - char *vty_addr = NULL; - int vty_port = 0; - int batch_mode = 0; - int daemon_mode = 0; - char *config_file = NULL; - char *progname; - struct thread thread; - - /* Set umask before anything for security */ - umask (0027); - - /* preserve my name */ - progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); - - openzlog(progname, "ZEBRA", 0, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); - - while (1) - { - int opt; - - opt = getopt_long (argc, argv, "bdaf:hA:P:r:v", longopts, 0); - - if (opt == EOF) - break; - - switch (opt) - { - case 0: - break; - case 'b': - batch_mode = 1; - case 'd': - daemon_mode = 1; - break; - case 'a': - allow_delete =1; - break; - case 'f': - config_file = optarg; - break; - case 'A': - vty_addr = optarg; - break; - case 'P': - /* Deal with atoi() returning 0 on failure, and zebra not - listening on zebra port... */ - if (strcmp(optarg, "0") == 0) - { - vty_port = 0; - break; - } - vty_port = atoi (optarg); - break; - case 'r': - rib_process_hold_time = atoi(optarg); - break; - case 'v': - print_version (progname); - exit (0); - break; - case 'h': - usage (progname, 0); - break; - default: - usage (progname, 1); - break; - } - } - - /* port and conf file mandatory */ - if (!vty_port || !config_file) - { - fprintf (stderr, "Error: --vty_port and --config_file arguments" - " are both required\n"); - usage (progname, 1); - } - - /* Make master thread emulator. */ - zebrad.master = thread_master_create (); - - /* Vty related initialize. */ - signal_init (zebrad.master, array_size(zebra_signals), zebra_signals); - cmd_init (1); - vty_config_lockless (); - vty_init (zebrad.master); - memory_init (); - zebra_debug_init (); - zebra_if_init (); - test_cmd_init (); - - /* Zebra related initialize. */ - rib_init (); - access_list_init (); - - /* Make kernel routing socket. */ - zebra_vrf_init (); - zebra_vty_init(); - - /* Configuration file read*/ - vty_read_config (config_file, config_default); - - /* Clean up rib. */ - rib_weed_tables (); - - /* Exit when zebra is working in batch mode. */ - if (batch_mode) - exit (0); - - /* Daemonize. */ - if (daemon_mode && daemon (0, 0) < 0) - { - perror("daemon start failed"); - exit (1); - } - - /* Needed for BSD routing socket. */ - pid = getpid (); - - /* Make vty server socket. */ - vty_serv_sock (vty_addr, vty_port, "/tmp/test_zebra"); - - /* Print banner. */ - zlog_notice ("Zebra %s starting: vty@%d", FRR_VERSION, vty_port); - - while (thread_fetch (zebrad.master, &thread)) - thread_call (&thread); - - /* Not reached... */ - return 0; -} diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c index bca73898c5..45e4435ee5 100644 --- a/zebra/zebra_mpls_openbsd.c +++ b/zebra/zebra_mpls_openbsd.c @@ -238,7 +238,7 @@ kernel_lsp_cmd (int action, zebra_lsp_t *lsp) { zebra_nhlfe_t *nhlfe; struct nexthop *nexthop = NULL; - int nexthop_num = 0; + unsigned int nexthop_num = 0; for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { @@ -288,28 +288,52 @@ kernel_lsp_cmd (int action, zebra_lsp_t *lsp) int kernel_add_lsp (zebra_lsp_t *lsp) { + int ret; + if (!lsp || !lsp->best_nhlfe) // unexpected return -1; - return kernel_lsp_cmd (RTM_ADD, lsp); + UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); + ret = kernel_lsp_cmd (RTM_ADD, lsp); + if (!ret) + SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); + + return ret; } int kernel_upd_lsp (zebra_lsp_t *lsp) { + int ret; + if (!lsp || !lsp->best_nhlfe) // unexpected return -1; - return kernel_lsp_cmd (RTM_CHANGE, lsp); + UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); + UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); + ret = kernel_lsp_cmd (RTM_CHANGE, lsp); + if (!ret) + SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); + + return ret; } int kernel_del_lsp (zebra_lsp_t *lsp) { + int ret; + if (!lsp) // unexpected return -1; - return kernel_lsp_cmd (RTM_DELETE, lsp); + if (! CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED)) + return -1; + + ret = kernel_lsp_cmd (RTM_DELETE, lsp); + if (!ret) + UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); + + return ret; } #define MAX_RTSOCK_BUF 128 * 1024 diff --git a/zebra/zebra_ptm_null.c b/zebra/zebra_ptm_null.c deleted file mode 100644 index 576ea17327..0000000000 --- a/zebra/zebra_ptm_null.c +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @copyright Copyright (C) 2015 Cumulus Networks, Inc. - * - * 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 this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include <zebra.h> -#include "prefix.h" -#include "if.h" -#include "zebra_ptm_redistribute.h" - -void zebra_interface_bfd_update (struct interface *a, struct prefix *dp, - struct prefix *sp, int status, vrf_id_t vrf_id) -{ return; } - -void zebra_bfd_peer_replay_req (void) -{ return; } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index e9ccac1c92..c2af0a0d22 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2897,7 +2897,7 @@ vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p) vrf = vrf_lookup_by_id (vrf_id); if (vrf) { - vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf); + vrf = RB_NEXT (vrf_id_head, vrf); if (vrf) { *next_id_p = vrf->vrf_id; return 1; diff --git a/zebra/zebra_rnh_null.c b/zebra/zebra_rnh_null.c deleted file mode 100644 index 0a3620bbe8..0000000000 --- a/zebra/zebra_rnh_null.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Zebra next hop tracking code - * Copyright (C) 2013 Cumulus Networks, Inc. - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include <zebra.h> -#include "vty.h" -#include "zebra/rib.h" -#include "zebra/zserv.h" -#include "zebra/zebra_rnh.h" - -int zebra_rnh_ip_default_route = 0; -int zebra_rnh_ipv6_default_route = 0; - -void -zebra_free_rnh (struct rnh *rnh) -{} - -void zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type, - struct prefix *p) -{} - -void zebra_print_rnh_table (vrf_id_t vrfid, int family, struct vty *vty, - rnh_type_t type) -{} - -void zebra_register_rnh_static_nh(vrf_id_t vrfid, struct prefix *p, struct route_node *rn) -{} - -void zebra_deregister_rnh_static_nh(vrf_id_t vrfid, struct prefix *p, struct route_node *rn) -{} - -void zebra_deregister_rnh_static_nexthops (vrf_id_t vrfid, struct nexthop *nexthop, - struct route_node *rn) -{} diff --git a/zebra/zserv.c b/zebra/zserv.c index 9d05a3b9df..ba42c67be3 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2153,6 +2153,15 @@ zebra_client_close (struct zserv *client) if (client->t_suicide) thread_cancel (client->t_suicide); + /* Free bitmaps. */ + for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) + for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) + vrf_bitmap_free (client->redist[afi][i]); + + vrf_bitmap_free (client->redist_default); + vrf_bitmap_free (client->ifinfo); + vrf_bitmap_free (client->ridinfo); + /* Free client structure. */ listnode_delete (zebrad.client_list, client); XFREE (MTYPE_TMP, client); diff --git a/zebra/zserv_null.c b/zebra/zserv_null.c deleted file mode 100644 index 47518f477f..0000000000 --- a/zebra/zserv_null.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2015 Cumulus Networks, Inc. - * Donald Sharp - * - * This file is part of Quagga. - * - * Quagga 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. - * - * Quagga 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; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <zebra.h> - -#include <vrf.h> -#include <vty.h> - -#include <zserv.h> -#include <zebra_ns.h> -#include <zebra_vrf.h> -#include <router-id.h> - -int -zebra_server_send_message(struct zserv *client) -{ return 0; } - -void zserv_create_header (struct stream *s, uint16_t cmd, vrf_id_t vrf_id) -{ return; } - -int zsend_vrf_delete (struct zserv *zserv, struct zebra_vrf *zvrf) -{ return 0; } - -int zsend_vrf_add (struct zserv *zserv, struct zebra_vrf *zvrf) -{ return 0; } - -void router_id_init (struct zebra_vrf *zvrf) -{ return; } |
