Merge branch 'master' into bgpd-ipv4-plus-label-misc3

This commit is contained in:
Daniel Walton 2017-06-21 10:30:29 -04:00 committed by GitHub
commit c1a44e4367
50 changed files with 2471 additions and 2034 deletions

View File

@ -492,7 +492,7 @@ bgp_show_all_instances_nexthops_vty (struct vty *vty)
DEFUN (show_ip_bgp_nexthop, DEFUN (show_ip_bgp_nexthop,
show_ip_bgp_nexthop_cmd, show_ip_bgp_nexthop_cmd,
"show [ip] bgp [<view|vrf> WORD] nexthop [detail]", "show [ip] bgp [<view|vrf> VIEWVRFNAME] nexthop [detail]",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR

View File

@ -3562,10 +3562,6 @@ bgp_cleanup_table(struct bgp_table *table, safi_t safi)
&& (ri->sub_type == BGP_ROUTE_NORMAL || && (ri->sub_type == BGP_ROUTE_NORMAL ||
ri->sub_type == BGP_ROUTE_AGGREGATE)) ri->sub_type == BGP_ROUTE_AGGREGATE))
{ {
#if ENABLE_BGP_VNC
if (table->owner && table->owner->bgp)
vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri);
#endif
bgp_zebra_withdraw (&rn->p, ri, safi); bgp_zebra_withdraw (&rn->p, ri, safi);
bgp_info_reap (rn, ri); bgp_info_reap (rn, ri);
} }
@ -8462,7 +8458,7 @@ bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom,
DEFUN (show_ip_bgp_large_community_list, DEFUN (show_ip_bgp_large_community_list,
show_ip_bgp_large_community_list_cmd, show_ip_bgp_large_community_list_cmd,
"show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] large-community-list <(1-500)|WORD> [json]", "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] large-community-list <(1-500)|WORD> [json]",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -8504,7 +8500,7 @@ DEFUN (show_ip_bgp_large_community_list,
} }
DEFUN (show_ip_bgp_large_community, DEFUN (show_ip_bgp_large_community,
show_ip_bgp_large_community_cmd, show_ip_bgp_large_community_cmd,
"show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] large-community [AA:BB:CC] [json]", "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] large-community [AA:BB:CC] [json]",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -8551,7 +8547,7 @@ static int bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t
/* BGP route print out function. */ /* BGP route print out function. */
DEFUN (show_ip_bgp, DEFUN (show_ip_bgp,
show_ip_bgp_cmd, 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\ cidr-only\
|dampening <flap-statistics|dampened-paths|parameters>\ |dampening <flap-statistics|dampened-paths|parameters>\
@ -8672,7 +8668,7 @@ DEFUN (show_ip_bgp,
DEFUN (show_ip_bgp_route, DEFUN (show_ip_bgp_route,
show_ip_bgp_route_cmd, 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]", "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
SHOW_STR SHOW_STR
IP_STR IP_STR
@ -8741,7 +8737,7 @@ DEFUN (show_ip_bgp_route,
DEFUN (show_ip_bgp_regexp, DEFUN (show_ip_bgp_regexp,
show_ip_bgp_regexp_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -9453,7 +9449,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, DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
show_ip_bgp_instance_neighbor_prefix_counts_cmd, show_ip_bgp_instance_neighbor_prefix_counts_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> prefix-counts [json]", "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
SHOW_STR SHOW_STR
IP_STR IP_STR
@ -9822,7 +9818,7 @@ peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
DEFUN (show_ip_bgp_instance_neighbor_advertised_route, DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
show_ip_bgp_instance_neighbor_advertised_route_cmd, 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]", "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
SHOW_STR SHOW_STR
IP_STR IP_STR
@ -9986,7 +9982,7 @@ bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
DEFUN (show_ip_bgp_neighbor_routes, DEFUN (show_ip_bgp_neighbor_routes,
show_ip_bgp_neighbor_routes_cmd, 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]", "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
SHOW_STR SHOW_STR
IP_STR IP_STR

View File

@ -50,12 +50,6 @@ bgp_table_unlock (struct bgp_table *rt)
route_table_finish (rt->route_table); route_table_finish (rt->route_table);
rt->route_table = NULL; rt->route_table = NULL;
if (rt->owner)
{
peer_unlock (rt->owner);
rt->owner = NULL;
}
XFREE (MTYPE_BGP_TABLE, rt); XFREE (MTYPE_BGP_TABLE, rt);
} }

View File

@ -32,9 +32,6 @@ struct bgp_table
int lock; int lock;
/* The owner of this 'bgp_table' structure. */
struct peer *owner;
struct route_table *route_table; struct route_table *route_table;
uint64_t version; uint64_t version;
}; };

View File

@ -275,11 +275,11 @@ argv_find_and_parse_safi (struct cmd_token **argv, int argc, int *index, safi_t
* that is being parsed. * that is being parsed.
* *
* The show commands are generally of the form: * 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: * Since we use argv_find if the show command in particular doesn't have:
* [ip] * [ip]
* [<view|vrf> WORD] * [<view|vrf> VIEWVRFNAME]
* [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]] * [<ipv4|ipv6> [<unicast|multicast|vpn|labeled-unicast>]]
* The command parsing should still be ok. * The command parsing should still be ok.
* *
@ -862,7 +862,7 @@ DEFUN (no_auto_summary,
/* "router bgp" commands. */ /* "router bgp" commands. */
DEFUN_NOSH (router_bgp, DEFUN_NOSH (router_bgp,
router_bgp_cmd, router_bgp_cmd,
"router bgp [(1-4294967295) [<view|vrf> WORD]]", "router bgp [(1-4294967295) [<view|vrf> VIEWVRFNAME]]",
ROUTER_STR ROUTER_STR
BGP_STR BGP_STR
AS_STR AS_STR
@ -940,7 +940,7 @@ DEFUN_NOSH (router_bgp,
/* "no router bgp" commands. */ /* "no router bgp" commands. */
DEFUN (no_router_bgp, DEFUN (no_router_bgp,
no_router_bgp_cmd, no_router_bgp_cmd,
"no router bgp [(1-4294967295) [<view|vrf> WORD]]", "no router bgp [(1-4294967295) [<view|vrf> VIEWVRFNAME]]",
NO_STR NO_STR
ROUTER_STR ROUTER_STR
BGP_STR BGP_STR
@ -1252,7 +1252,7 @@ DEFUN (bgp_maxmed_admin,
DEFUN (bgp_maxmed_admin_medv, DEFUN (bgp_maxmed_admin_medv,
bgp_maxmed_admin_medv_cmd, bgp_maxmed_admin_medv_cmd,
"bgp max-med administrative (0-4294967294)", "bgp max-med administrative (0-4294967295)",
BGP_STR BGP_STR
"Advertise routes with max-med\n" "Advertise routes with max-med\n"
"Administratively applied, for an indefinite period\n" "Administratively applied, for an indefinite period\n"
@ -1262,7 +1262,7 @@ DEFUN (bgp_maxmed_admin_medv,
int idx_number = 3; int idx_number = 3;
bgp->v_maxmed_admin = 1; 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); bgp_maxmed_update(bgp);
@ -1271,7 +1271,7 @@ DEFUN (bgp_maxmed_admin_medv,
DEFUN (no_bgp_maxmed_admin, DEFUN (no_bgp_maxmed_admin,
no_bgp_maxmed_admin_cmd, no_bgp_maxmed_admin_cmd,
"no bgp max-med administrative [(0-4294967294)]", "no bgp max-med administrative [(0-4294967295)]",
NO_STR NO_STR
BGP_STR BGP_STR
"Advertise routes with max-med\n" "Advertise routes with max-med\n"
@ -1288,24 +1288,7 @@ DEFUN (no_bgp_maxmed_admin,
DEFUN (bgp_maxmed_onstartup, DEFUN (bgp_maxmed_onstartup,
bgp_maxmed_onstartup_cmd, bgp_maxmed_onstartup_cmd,
"bgp max-med on-startup (5-86400)", "bgp max-med on-startup (5-86400) [(0-4294967295)]",
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_STR BGP_STR
"Advertise routes with max-med\n" "Advertise routes with max-med\n"
"Effective on a startup\n" "Effective on a startup\n"
@ -1313,10 +1296,15 @@ DEFUN (bgp_maxmed_onstartup_medv,
"Max MED value to be used\n") "Max MED value to be used\n")
{ {
VTY_DECLVAR_CONTEXT(bgp, bgp); VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_number = 3; int idx = 0;
int idx_number_2 = 4;
VTY_GET_INTEGER ("max-med on-startup period", bgp->v_maxmed_onstartup, argv[idx_number]->arg); argv_find (argv, argc, "(5-86400)", &idx);
VTY_GET_INTEGER ("max-med on-startup med-value", bgp->maxmed_onstartup_value, argv[idx_number_2]->arg); 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); bgp_maxmed_update(bgp);
return CMD_SUCCESS; return CMD_SUCCESS;
@ -1324,7 +1312,7 @@ DEFUN (bgp_maxmed_onstartup_medv,
DEFUN (no_bgp_maxmed_onstartup, DEFUN (no_bgp_maxmed_onstartup,
no_bgp_maxmed_onstartup_cmd, 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 NO_STR
BGP_STR BGP_STR
"Advertise routes with max-med\n" "Advertise routes with max-med\n"
@ -1493,25 +1481,11 @@ DEFUN (no_bgp_wpkt_quanta,
return bgp_wpkt_quanta_config_vty(vty, argv[idx_number]->arg, 0); 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 int
bgp_config_write_coalesce_time (struct vty *vty, struct bgp *bgp) bgp_config_write_coalesce_time (struct vty *vty, struct bgp *bgp)
{ {
if (bgp->coalesce_time != BGP_DEFAULT_SUBGROUP_COALESCE_TIME) 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); bgp->coalesce_time, VTY_NEWLINE);
return 0; return 0;
@ -1524,8 +1498,12 @@ DEFUN (bgp_coalesce_time,
"Subgroup coalesce timer\n" "Subgroup coalesce timer\n"
"Subgroup coalesce timer value (in ms)\n") "Subgroup coalesce timer value (in ms)\n")
{ {
int idx_number = 1; VTY_DECLVAR_CONTEXT(bgp, bgp);
return bgp_coalesce_config_vty(vty, argv[idx_number]->arg, 1);
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, DEFUN (no_bgp_coalesce_time,
@ -1535,8 +1513,10 @@ DEFUN (no_bgp_coalesce_time,
"Subgroup coalesce timer\n" "Subgroup coalesce timer\n"
"Subgroup coalesce timer value (in ms)\n") "Subgroup coalesce timer value (in ms)\n")
{ {
int idx_number = 2; VTY_DECLVAR_CONTEXT(bgp, bgp);
return bgp_coalesce_config_vty(vty, argv[idx_number]->arg, 0);
bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
return CMD_SUCCESS;
} }
/* Maximum-paths configuration */ /* Maximum-paths configuration */
@ -6496,7 +6476,7 @@ bgp_clear_prefix (struct vty *vty, const char *view_name, const char *ip_str,
/* one clear bgp command to rule them all */ /* one clear bgp command to rule them all */
DEFUN (clear_ip_bgp_all, DEFUN (clear_ip_bgp_all,
clear_ip_bgp_all_cmd, clear_ip_bgp_all_cmd,
"clear [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_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_WITH_LABEL_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 CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -6531,8 +6511,8 @@ DEFUN (clear_ip_bgp_all,
/* clear [ip] bgp */ /* clear [ip] bgp */
if (argv_find (argv, argc, "ip", &idx)) if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP; afi = AFI_IP;
/* [<view|vrf> WORD] */ /* [<view|vrf> VIEWVRFNAME] */
if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
{ {
vrf = argv[idx + 1]->arg; vrf = argv[idx + 1]->arg;
@ -6603,7 +6583,7 @@ DEFUN (clear_ip_bgp_all,
DEFUN (clear_ip_bgp_prefix, DEFUN (clear_ip_bgp_prefix,
clear_ip_bgp_prefix_cmd, 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 CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -6616,7 +6596,7 @@ DEFUN (clear_ip_bgp_prefix,
int idx = 0; int idx = 0;
/* [<view|vrf> WORD] */ /* [<view|vrf> VIEWVRFNAME] */
if (argv_find (argv, argc, "WORD", &idx)) if (argv_find (argv, argc, "WORD", &idx))
vrf = argv[idx]->arg; vrf = argv[idx]->arg;
@ -6644,7 +6624,7 @@ DEFUN (clear_bgp_ipv6_safi_prefix,
DEFUN (clear_bgp_instance_ipv6_safi_prefix, DEFUN (clear_bgp_instance_ipv6_safi_prefix,
clear_bgp_instance_ipv6_safi_prefix_cmd, 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 CLEAR_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -7506,7 +7486,7 @@ bgp_show_summary_vty (struct vty *vty, const char *name,
/* `show [ip] bgp summary' commands. */ /* `show [ip] bgp summary' commands. */
DEFUN (show_ip_bgp_summary, DEFUN (show_ip_bgp_summary,
show_ip_bgp_summary_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -7525,7 +7505,7 @@ DEFUN (show_ip_bgp_summary,
/* show [ip] bgp */ /* show [ip] bgp */
if (argv_find (argv, argc, "ip", &idx)) if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP; afi = AFI_IP;
/* [<view|vrf> WORD] */ /* [<view|vrf> VIEWVRFNAME] */
if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
vrf = argv[++idx]->arg; vrf = argv[++idx]->arg;
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */ /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
@ -9462,7 +9442,7 @@ bgp_show_neighbor_vty (struct vty *vty, const char *name,
/* "show [ip] bgp neighbors" commands. */ /* "show [ip] bgp neighbors" commands. */
DEFUN (show_ip_bgp_neighbors, DEFUN (show_ip_bgp_neighbors,
show_ip_bgp_neighbors_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -9642,7 +9622,7 @@ bgp_show_update_groups(struct vty *vty, const char *name,
DEFUN (show_ip_bgp_updgrps, DEFUN (show_ip_bgp_updgrps,
show_ip_bgp_updgrps_cmd, show_ip_bgp_updgrps_cmd,
"show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] update-groups [SUBGROUP-ID]", "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] update-groups [SUBGROUP-ID]",
SHOW_STR SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -9662,7 +9642,7 @@ DEFUN (show_ip_bgp_updgrps,
/* show [ip] bgp */ /* show [ip] bgp */
if (argv_find (argv, argc, "ip", &idx)) if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP; afi = AFI_IP;
/* [<view|vrf> WORD] */ /* [<view|vrf> VIEWVRFNAME] */
if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
vrf = argv[++idx]->arg; vrf = argv[++idx]->arg;
/* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */ /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
@ -9712,7 +9692,7 @@ DEFUN (show_bgp_updgrps_stats,
DEFUN (show_bgp_instance_updgrps_stats, DEFUN (show_bgp_instance_updgrps_stats,
show_bgp_instance_updgrps_stats_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -9772,7 +9752,7 @@ DEFUN (show_ip_bgp_updgrps_adj,
DEFUN (show_ip_bgp_instance_updgrps_adj, DEFUN (show_ip_bgp_instance_updgrps_adj,
show_ip_bgp_instance_updgrps_adj_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -9830,7 +9810,7 @@ DEFUN (show_bgp_updgrps_adj,
DEFUN (show_bgp_instance_updgrps_adj, DEFUN (show_bgp_instance_updgrps_adj,
show_bgp_instance_updgrps_adj_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -9871,7 +9851,7 @@ DEFUN (show_ip_bgp_updgrps_adj_s,
DEFUN (show_ip_bgp_instance_updgrps_adj_s, DEFUN (show_ip_bgp_instance_updgrps_adj_s,
show_ip_bgp_instance_updgrps_adj_s_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -9947,7 +9927,7 @@ DEFUN (show_bgp_updgrps_adj_s,
DEFUN (show_bgp_instance_updgrps_adj_s, DEFUN (show_bgp_instance_updgrps_adj_s,
show_bgp_instance_updgrps_adj_s_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -10134,7 +10114,7 @@ bgp_show_peer_group_vty (struct vty *vty, const char *name,
DEFUN (show_ip_bgp_peer_groups, DEFUN (show_ip_bgp_peer_groups,
show_ip_bgp_peer_groups_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -11025,7 +11005,6 @@ bgp_vty_init (void)
install_element (BGP_NODE, &bgp_maxmed_admin_medv_cmd); install_element (BGP_NODE, &bgp_maxmed_admin_medv_cmd);
install_element (BGP_NODE, &bgp_maxmed_onstartup_cmd); install_element (BGP_NODE, &bgp_maxmed_onstartup_cmd);
install_element (BGP_NODE, &no_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 */ /* bgp disable-ebgp-connected-nh-check */
install_element (BGP_NODE, &bgp_disable_connected_route_check_cmd); install_element (BGP_NODE, &bgp_disable_connected_route_check_cmd);

View File

@ -6809,7 +6809,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 != BGP_DEFAULT_EBGP_ROUTEADV) ||
(peer_group_active (peer) && peer->v_routeadv != g_peer->v_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); addr, peer->v_routeadv, VTY_NEWLINE);
} }
@ -6818,7 +6818,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 != BGP_DEFAULT_KEEPALIVE || peer->holdtime != BGP_DEFAULT_HOLDTIME)) ||
(peer_group_active (peer) && (peer->keepalive != g_peer->keepalive || peer->holdtime != g_peer->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); peer->keepalive, peer->holdtime, VTY_NEWLINE);
} }
@ -6827,7 +6827,7 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
(peer_group_active (peer) && peer->connect != g_peer->connect))) (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); peer->connect, VTY_NEWLINE);
} }
@ -7170,11 +7170,11 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
" neighbor %s maximum-prefix %lu", " neighbor %s maximum-prefix %lu",
addr, peer->pmax[afi][safi]); addr, peer->pmax[afi][safi]);
if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT) 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)) if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
vty_out (vty, " warning-only"); vty_out (vty, " warning-only");
if (peer->pmax_restart[afi][safi]) 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); vty_out (vty, "%s", VTY_NEWLINE);
} }
@ -7237,7 +7237,7 @@ bgp_config_write_peer_af (struct vty *vty, struct bgp *bgp,
if (peer->weight[afi][safi]) if (peer->weight[afi][safi])
{ {
afi_header_vty_out (vty, afi, safi, write, 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); addr, peer->weight[afi][safi], VTY_NEWLINE);
} }
} }
@ -7382,7 +7382,7 @@ bgp_config_write (struct vty *vty)
} }
if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER) 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); VTY_NEWLINE);
/* BGP configuration. */ /* BGP configuration. */
@ -7433,7 +7433,7 @@ bgp_config_write (struct vty *vty)
/* BGP default local-preference. */ /* BGP default local-preference. */
if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF) 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_local_pref, VTY_NEWLINE);
/* BGP default show-hostname */ /* BGP default show-hostname */
@ -7445,7 +7445,7 @@ bgp_config_write (struct vty *vty)
/* BGP default subgroup-pkt-queue-max. */ /* BGP default subgroup-pkt-queue-max. */
if (bgp->default_subgroup_pkt_queue_max != 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->default_subgroup_pkt_queue_max, VTY_NEWLINE);
/* BGP client-to-client reflection. */ /* BGP client-to-client reflection. */
@ -7495,16 +7495,16 @@ bgp_config_write (struct vty *vty)
if (bgp->v_maxmed_onstartup != BGP_MAXMED_ONSTARTUP_UNCONFIGURED) 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) 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); vty_out (vty, "%s", VTY_NEWLINE);
} }
if (bgp->v_maxmed_admin != BGP_MAXMED_ADMIN_UNCONFIGURED) if (bgp->v_maxmed_admin != BGP_MAXMED_ADMIN_UNCONFIGURED)
{ {
vty_out (vty, " bgp max-med administrative"); vty_out (vty, " bgp max-med administrative");
if (bgp->maxmed_admin_value != BGP_MAXMED_VALUE_DEFAULT) 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); vty_out (vty, "%s", VTY_NEWLINE);
} }
@ -7516,10 +7516,10 @@ bgp_config_write (struct vty *vty)
/* BGP graceful-restart. */ /* BGP graceful-restart. */
if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME) 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); bgp->stalepath_time, VTY_NEWLINE);
if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME) 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); bgp->restart_time, VTY_NEWLINE);
if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART)) if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE); vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
@ -7578,7 +7578,7 @@ bgp_config_write (struct vty *vty)
/* BGP timers configuration. */ /* BGP timers configuration. */
if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE
&& bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) && 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); bgp->default_holdtime, VTY_NEWLINE);
/* peer-group */ /* peer-group */
@ -7692,6 +7692,38 @@ bgp_if_finish (struct bgp *bgp)
extern void bgp_snmp_init (void); 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 void
bgp_init (void) bgp_init (void)
{ {
@ -7741,6 +7773,8 @@ bgp_init (void)
/* BFD init */ /* BFD init */
bgp_bfd_init(); bgp_bfd_init();
cmd_variable_handler_register (bgp_viewvrf_var_handlers);
} }
void void

View File

@ -1284,14 +1284,6 @@ AM_CONDITIONAL(OSPFD, test "x$OSPFD" = "xospfd")
if test "${enable_ldpd}" = "no";then if test "${enable_ldpd}" = "no";then
LDPD="" LDPD=""
else 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" LDPD="ldpd"
AC_DEFINE(HAVE_LDPD, 1, ldpd) AC_DEFINE(HAVE_LDPD, 1, ldpd)
fi fi

View File

@ -8,8 +8,7 @@ Add packages:
sudo dnf install git autoconf automake libtool make gawk \ sudo dnf install git autoconf automake libtool make gawk \
readline-devel texinfo net-snmp-devel groff pkgconfig \ readline-devel texinfo net-snmp-devel groff pkgconfig \
json-c-devel pam-devel perl-XML-LibXML c-ares-devel \ json-c-devel pam-devel c-ares-devel python3-devel
python3-devel
Get FRR, compile it and install it (from Git) Get FRR, compile it and install it (from Git)
--------------------------------------------- ---------------------------------------------

View File

@ -18,7 +18,7 @@ Configure Package location:
Add packages: Add packages:
sudo pkg_add git autoconf automake libtool gmake gawk openssl \ 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): Install SSL Root Certificates (for git https access):

View File

@ -12,7 +12,7 @@ Install required packages
------------------------- -------------------------
sudo pkgin install git autoconf automake libtool gmake gawk openssl \ 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): Install SSL Root Certificates (for git https access):

View File

@ -47,12 +47,6 @@ Add libjson to Solaris equivalent of ld.so.conf
crle -l /opt/csw/lib -u crle -l /opt/csw/lib -u
Add Perl packages:
cpan
cpan[1]> install XML::LibXML
cpan[2]> exit
Add pytest: Add pytest:
pip install pytest pip install pytest

View File

@ -11,7 +11,7 @@ Configure PKG_PATH
Add packages: Add packages:
pkg_add git autoconf-2.69p2 automake-1.15p0 libtool bison pkg_add git autoconf-2.69p2 automake-1.15p0 libtool bison
pkg_add gmake gawk dejagnu openssl json-c p5-XML-LibXML py-test pkg_add gmake gawk dejagnu openssl json-c py-test
Select Python2.7 as default (required for pytest) Select Python2.7 as default (required for pytest)

View File

@ -13,7 +13,7 @@ Add packages:
apt-get install git autoconf automake libtool make gawk libreadline-dev \ apt-get install git autoconf automake libtool make gawk libreadline-dev \
texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-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 Install newer bison from 14.04 package source (Ubuntu 12.04 package source
is too old) is too old)
@ -51,11 +51,6 @@ Install newer version of autoconf and automake:
sudo make install sudo make install
cd .. cd ..
Install XML::LibXML
sudo cpan
install XML::LibXML
Install pytest: Install pytest:
pip install pytest pip install pytest

1
ldpd/.gitignore vendored
View File

@ -15,4 +15,3 @@ TAGS
.arch-ids .arch-ids
*~ *~
*.loT *.loT
ldp_vty_cmds.c

View File

@ -3,16 +3,12 @@
AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib AM_CPPFLAGS = -I.. -I$(top_srcdir) -I$(top_srcdir)/lib -I$(top_builddir)/lib
DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\" DEFS = @DEFS@ -DSYSCONFDIR=\"$(sysconfdir)/\"
INSTALL_SDATA=@INSTALL@ -m 600 INSTALL_SDATA=@INSTALL@ -m 600
EXTRA_DIST=
AM_CFLAGS = $(WERROR) AM_CFLAGS = $(WERROR)
noinst_LIBRARIES = libldp.a noinst_LIBRARIES = libldp.a
sbin_PROGRAMS = ldpd sbin_PROGRAMS = ldpd
BUILT_SOURCES = ldp_vty_cmds.c
EXTRA_DIST += ldp_vty.xml
libldp_a_SOURCES = \ libldp_a_SOURCES = \
accept.c address.c adjacency.c control.c hello.c init.c interface.c \ 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 \ keepalive.c l2vpn.c labelmapping.c lde.c lde_lib.c ldpd.c \
@ -23,11 +19,6 @@ libldp_a_SOURCES = \
noinst_HEADERS = \ noinst_HEADERS = \
control.h lde.h ldpd.h ldpe.h ldp.h log.h ldp_debug.h ldp_vty.h 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_SOURCES = ldpd.c
ldpd_LDADD = libldp.a ../lib/libfrr.la @LIBCAP@ ldpd_LDADD = libldp.a ../lib/libfrr.la @LIBCAP@

View File

@ -25,9 +25,9 @@
#include "ldpe.h" #include "ldpe.h"
#include "log.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 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_del(struct ldpd_conf *, struct tnbr *);
static void tnbr_start(struct tnbr *); static void tnbr_start(struct tnbr *);
static void tnbr_stop(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) RB_GENERATE(tnbr_head, tnbr, entry, tnbr_compare)
static __inline int 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)) if (adj_get_af(a) < adj_get_af(b))
return (-1); return (-1);
@ -163,7 +163,7 @@ adj_find(struct in_addr lsr_id, struct hello_source *source)
} }
int int
adj_get_af(struct adj *adj) adj_get_af(const struct adj *adj)
{ {
switch (adj->source.type) { switch (adj->source.type) {
case HELLO_LINK: case HELLO_LINK:
@ -220,7 +220,7 @@ adj_stop_itimer(struct adj *adj)
/* targeted neighbors */ /* targeted neighbors */
static __inline int 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) if (a->af < b->af)
return (-1); return (-1);

View File

@ -26,7 +26,7 @@
#include "sockopt.h" #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_new(struct kaddr *);
static struct if_addr *if_addr_lookup(struct if_addr_head *, struct kaddr *); static struct if_addr *if_addr_lookup(struct if_addr_head *, struct kaddr *);
static int if_start(struct iface *, int); 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) RB_GENERATE(iface_head, iface, entry, iface_compare)
static __inline int 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)); return (strcmp(a->name, b->name));
} }
@ -81,12 +81,12 @@ ldpe_if_init(struct iface *iface)
/* ipv4 */ /* ipv4 */
iface->ipv4.iface = iface; iface->ipv4.iface = iface;
iface->ipv4.state = IF_STA_DOWN; iface->ipv4.state = IF_STA_DOWN;
RB_INIT(&iface->ipv4.adj_tree); RB_INIT(ia_adj_head, &iface->ipv4.adj_tree);
/* ipv6 */ /* ipv6 */
iface->ipv6.iface = iface; iface->ipv6.iface = iface;
iface->ipv6.state = IF_STA_DOWN; iface->ipv6.state = IF_STA_DOWN;
RB_INIT(&iface->ipv6.adj_tree); RB_INIT(ia_adj_head, &iface->ipv6.adj_tree);
} }
void void
@ -305,7 +305,7 @@ if_reset(struct iface *iface, int af)
ia = iface_af_get(iface, af); ia = iface_af_get(iface, af);
if_stop_hello_timer(ia); 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); adj_del(adj, S_SHUTDOWN);
/* try to cleanup */ /* try to cleanup */

View File

@ -27,16 +27,16 @@
#include "log.h" #include "log.h"
static void l2vpn_pw_fec(struct l2vpn_pw *, struct fec *); static void l2vpn_pw_fec(struct l2vpn_pw *, struct fec *);
static __inline int l2vpn_compare(struct l2vpn *, struct l2vpn *); static __inline int l2vpn_compare(const struct l2vpn *, const struct l2vpn *);
static __inline int l2vpn_if_compare(struct l2vpn_if *, struct l2vpn_if *); static __inline int l2vpn_if_compare(const struct l2vpn_if *, const struct l2vpn_if *);
static __inline int l2vpn_pw_compare(struct l2vpn_pw *, struct l2vpn_pw *); 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_head, l2vpn, entry, l2vpn_compare)
RB_GENERATE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare) RB_GENERATE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare)
RB_GENERATE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare) RB_GENERATE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare)
static __inline int 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)); return (strcmp(a->name, b->name));
} }
@ -55,9 +55,9 @@ l2vpn_new(const char *name)
l2vpn->mtu = DEFAULT_L2VPN_MTU; l2vpn->mtu = DEFAULT_L2VPN_MTU;
l2vpn->pw_type = DEFAULT_PW_TYPE; l2vpn->pw_type = DEFAULT_PW_TYPE;
RB_INIT(&l2vpn->if_tree); RB_INIT(l2vpn_if_head, &l2vpn->if_tree);
RB_INIT(&l2vpn->pw_tree); RB_INIT(l2vpn_pw_head, &l2vpn->pw_tree);
RB_INIT(&l2vpn->pw_inactive_tree); RB_INIT(l2vpn_pw_head, &l2vpn->pw_inactive_tree);
return (l2vpn); return (l2vpn);
} }
@ -76,15 +76,16 @@ l2vpn_del(struct l2vpn *l2vpn)
struct l2vpn_if *lif; struct l2vpn_if *lif;
struct l2vpn_pw *pw; 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); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(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); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(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); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw); free(pw);
} }
@ -111,7 +112,7 @@ l2vpn_exit(struct l2vpn *l2vpn)
} }
static __inline int 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)); return (strcmp(a->ifname, b->ifname));
} }
@ -174,7 +175,7 @@ l2vpn_if_update(struct l2vpn_if *lif)
} }
static __inline int 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)); return (strcmp(a->ifname, b->ifname));
} }
@ -512,7 +513,7 @@ l2vpn_binding_ctl(pid_t pid)
fn = (struct fec_node *)f; fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL && if (fn->local_label == NO_LABEL &&
RB_EMPTY(&fn->downstream)) RB_EMPTY(lde_map_head, &fn->downstream))
continue; continue;
memset(&pwctl, 0, sizeof(pwctl)); memset(&pwctl, 0, sizeof(pwctl));

View File

@ -41,15 +41,16 @@
static void lde_shutdown(void); static void lde_shutdown(void);
static int lde_dispatch_imsg(struct thread *); static int lde_dispatch_imsg(struct thread *);
static int lde_dispatch_parent(struct thread *); static int lde_dispatch_parent(struct thread *);
static __inline int lde_nbr_compare(struct lde_nbr *, static __inline int lde_nbr_compare(const struct lde_nbr *,
struct lde_nbr *); const struct lde_nbr *);
static struct lde_nbr *lde_nbr_new(uint32_t, struct lde_nbr *); static struct lde_nbr *lde_nbr_new(uint32_t, struct lde_nbr *);
static void lde_nbr_del(struct lde_nbr *); static void lde_nbr_del(struct lde_nbr *);
static struct lde_nbr *lde_nbr_find(uint32_t); static struct lde_nbr *lde_nbr_find(uint32_t);
static void lde_nbr_clear(void); static void lde_nbr_clear(void);
static void lde_nbr_addr_update(struct lde_nbr *, static void lde_nbr_addr_update(struct lde_nbr *,
struct lde_addr *, int); 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 void lde_map_free(void *);
static int lde_address_add(struct lde_nbr *, struct lde_addr *); static int lde_address_add(struct lde_nbr *, struct lde_addr *);
static int lde_address_del(struct lde_nbr *, struct lde_addr *); static int lde_address_del(struct lde_nbr *, struct lde_addr *);
@ -542,10 +543,10 @@ lde_dispatch_parent(struct thread *thread)
fatal(NULL); fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf)); memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
RB_INIT(&nconf->iface_tree); RB_INIT(iface_head, &nconf->iface_tree);
RB_INIT(&nconf->tnbr_tree); RB_INIT(tnbr_head, &nconf->tnbr_tree);
RB_INIT(&nconf->nbrp_tree); RB_INIT(nbrp_head, &nconf->nbrp_tree);
RB_INIT(&nconf->l2vpn_tree); RB_INIT(l2vpn_head, &nconf->l2vpn_tree);
break; break;
case IMSG_RECONF_IFACE: case IMSG_RECONF_IFACE:
if ((niface = malloc(sizeof(struct iface))) == NULL) if ((niface = malloc(sizeof(struct iface))) == NULL)
@ -573,9 +574,9 @@ lde_dispatch_parent(struct thread *thread)
fatal(NULL); fatal(NULL);
memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn)); memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
RB_INIT(&nl2vpn->if_tree); RB_INIT(l2vpn_if_head, &nl2vpn->if_tree);
RB_INIT(&nl2vpn->pw_tree); RB_INIT(l2vpn_pw_head, &nl2vpn->pw_tree);
RB_INIT(&nl2vpn->pw_inactive_tree); RB_INIT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree);
RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn); RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
break; break;
@ -1189,7 +1190,7 @@ lde_send_notification_eol_pwid(struct lde_nbr *ln, uint16_t pw_type)
} }
static __inline int 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); return (a->peerid - b->peerid);
} }
@ -1314,7 +1315,7 @@ lde_nbr_clear(void)
{ {
struct lde_nbr *ln; struct lde_nbr *ln;
while ((ln = RB_ROOT(&lde_nbrs)) != NULL) while ((ln = RB_ROOT(nbr_tree, &lde_nbrs)) != NULL)
lde_nbr_del(ln); lde_nbr_del(ln);
} }
@ -1360,7 +1361,7 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
} }
static __inline int 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, return (ldp_addrcmp(AF_INET, (union ldpd_addr *)&a->nexthop->id,
(union ldpd_addr *)&b->nexthop->id)); (union ldpd_addr *)&b->nexthop->id));

View File

@ -25,7 +25,7 @@
#include "mpls.h" #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 *, static int lde_nbr_is_nexthop(struct fec_node *,
struct lde_nbr *); struct lde_nbr *);
static void fec_free(void *); static void fec_free(void *);
@ -43,11 +43,11 @@ struct thread *gc_timer;
void void
fec_init(struct fec_tree *fh) fec_init(struct fec_tree *fh)
{ {
RB_INIT(fh); RB_INIT(fec_tree, fh);
} }
static __inline int 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) if (a->type < b->type)
return (-1); return (-1);
@ -129,7 +129,7 @@ fec_clear(struct fec_tree *fh, void (*free_cb)(void *))
{ {
struct fec *f; struct fec *f;
while ((f = RB_ROOT(fh)) != NULL) { while ((f = RB_ROOT(fec_tree, fh)) != NULL) {
fec_remove(fh, f); fec_remove(fh, f);
free_cb(f); free_cb(f);
} }
@ -159,7 +159,7 @@ rt_dump(pid_t pid)
RB_FOREACH(f, fec_tree, &ft) { RB_FOREACH(f, fec_tree, &ft) {
fn = (struct fec_node *)f; fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL && if (fn->local_label == NO_LABEL &&
RB_EMPTY(&fn->downstream)) RB_EMPTY(lde_map_head, &fn->downstream))
continue; continue;
memset(&rtctl, 0, sizeof(rtctl)); memset(&rtctl, 0, sizeof(rtctl));
@ -179,7 +179,7 @@ rt_dump(pid_t pid)
} }
rtctl.local_label = fn->local_label; rtctl.local_label = fn->local_label;
if (RB_EMPTY(&fn->downstream)) { if (RB_EMPTY(lde_map_head, &fn->downstream)) {
rtctl.in_use = 0; rtctl.in_use = 0;
rtctl.nexthop.s_addr = INADDR_ANY; rtctl.nexthop.s_addr = INADDR_ANY;
rtctl.remote_label = NO_LABEL; rtctl.remote_label = NO_LABEL;
@ -231,10 +231,10 @@ fec_free(void *arg)
while ((fnh = LIST_FIRST(&fn->nexthops))) while ((fnh = LIST_FIRST(&fn->nexthops)))
fec_nh_del(fnh); 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_warnx("%s: fec %s downstream list not empty", __func__,
log_fec(&fn->fec)); 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_warnx("%s: fec %s upstream list not empty", __func__,
log_fec(&fn->fec)); log_fec(&fn->fec));
@ -258,8 +258,8 @@ fec_add(struct fec *fec)
fn->fec = *fec; fn->fec = *fec;
fn->local_label = NO_LABEL; fn->local_label = NO_LABEL;
RB_INIT(&fn->upstream); RB_INIT(lde_map_head, &fn->upstream);
RB_INIT(&fn->downstream); RB_INIT(lde_map_head, &fn->downstream);
LIST_INIT(&fn->nexthops); LIST_INIT(&fn->nexthops);
if (fec_insert(&ft, &fn->fec)) if (fec_insert(&ft, &fn->fec))
@ -396,7 +396,8 @@ lde_kernel_update(struct fec *fec)
lde_gc_start_timer(); lde_gc_start_timer();
} else { } else {
fn->local_label = lde_update_label(fn); 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 */ /* FEC.1: perform lsr label distribution procedure */
RB_FOREACH(ln, nbr_tree, &lde_nbrs) RB_FOREACH(ln, nbr_tree, &lde_nbrs)
lde_send_labelmapping(ln, fn, 1); lde_send_labelmapping(ln, fn, 1);
@ -904,8 +905,8 @@ lde_gc_timer(struct thread *thread)
fn = (struct fec_node *) fec; fn = (struct fec_node *) fec;
if (!LIST_EMPTY(&fn->nexthops) || if (!LIST_EMPTY(&fn->nexthops) ||
!RB_EMPTY(&fn->downstream) || !RB_EMPTY(lde_map_head, &fn->downstream) ||
!RB_EMPTY(&fn->upstream)) !RB_EMPTY(lde_map_head, &fn->upstream))
continue; continue;
fec_remove(&ft, &fn->fec); fec_remove(&ft, &fn->fec);

View File

@ -1,21 +1,20 @@
/* /*
* Copyright (C) 2016 by Open Source Routing. * 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 * This program is distributed in the hope that it will be useful, but
* 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 * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License
* with this program; see the file COPYING; if not, write to the Free Software * along with this program; see the file COPYING; if not, write to the
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/ */
#include <zebra.h> #include <zebra.h>
@ -39,16 +38,10 @@ struct cmd_node ldp_debug_node =
}; };
int 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) { if (strcmp(type_str, "discovery") == 0) {
dir_str = vty_get_arg_value(args, "dir");
if (dir_str == NULL) if (dir_str == NULL)
return (CMD_WARNING); return (CMD_WARNING);
@ -74,8 +67,6 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
else else
DEBUG_ON(event, EVENT); DEBUG_ON(event, EVENT);
} else if (strcmp(type_str, "messages") == 0) { } 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) if (dir_str == NULL)
return (CMD_WARNING); return (CMD_WARNING);
@ -112,7 +103,7 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
} }
int 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); vty_out(vty, "LDP debugging status:%s", VTY_NEWLINE);

View File

@ -1,21 +1,20 @@
/* /*
* Copyright (C) 2016 by Open Source Routing. * 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 * This program is distributed in the hope that it will be useful, but
* 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 * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License
* with this program; see the file COPYING; if not, write to the Free Software * along with this program; see the file COPYING; if not, write to the
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/ */
#ifndef _LDP_DEBUG_H_ #ifndef _LDP_DEBUG_H_

View File

@ -1,21 +1,20 @@
/* /*
* Copyright (C) 2016 by Open Source Routing. * 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 * This program is distributed in the hope that it will be useful, but
* 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 * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License
* with this program; see the file COPYING; if not, write to the Free Software * along with this program; see the file COPYING; if not, write to the
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/ */
#ifndef _LDP_VTY_H_ #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_config_write(struct vty *);
int ldp_l2vpn_config_write(struct vty *); int ldp_l2vpn_config_write(struct vty *);
int ldp_debug_config_write(struct vty *); int ldp_debug_config_write(struct vty *);
int ldp_vty_mpls_ldp (struct vty *, struct vty_arg *[]); int ldp_vty_mpls_ldp (struct vty *, int);
int ldp_vty_address_family (struct vty *, struct vty_arg *[]); int ldp_vty_address_family (struct vty *, int, const char *);
int ldp_vty_disc_holdtime(struct vty *, struct vty_arg *[]); int ldp_vty_disc_holdtime(struct vty *, int, const char *, const char *);
int ldp_vty_disc_interval(struct vty *, struct vty_arg *[]); int ldp_vty_disc_interval(struct vty *, int, const char *, const char *);
int ldp_vty_targeted_hello_accept(struct vty *, struct vty_arg *[]); int ldp_vty_targeted_hello_accept(struct vty *, int, const char *);
int ldp_vty_session_holdtime(struct vty *, struct vty_arg *[]); int ldp_vty_nbr_session_holdtime(struct vty *, int, const char *, const char *);
int ldp_vty_interface(struct vty *, struct vty_arg *[]); int ldp_vty_af_session_holdtime(struct vty *, int, const char *);
int ldp_vty_trans_addr(struct vty *, struct vty_arg *[]); int ldp_vty_interface(struct vty *, int, const char *);
int ldp_vty_neighbor_targeted(struct vty *, struct vty_arg *[]); int ldp_vty_trans_addr(struct vty *, int, const char *);
int ldp_vty_label_advertise(struct vty *, struct vty_arg *[]); int ldp_vty_neighbor_targeted(struct vty *, int, const char *);
int ldp_vty_label_allocate(struct vty *, struct vty_arg *[]); int ldp_vty_label_advertise(struct vty *, int, const char *, const char *);
int ldp_vty_label_expnull(struct vty *, struct vty_arg *[]); int ldp_vty_label_allocate(struct vty *, int, int, const char *);
int ldp_vty_label_accept(struct vty *, struct vty_arg *[]); int ldp_vty_label_expnull(struct vty *, int, const char *);
int ldp_vty_ttl_security(struct vty *, struct vty_arg *[]); int ldp_vty_label_accept(struct vty *, int, const char *, const char *);
int ldp_vty_router_id(struct vty *, struct vty_arg *[]); int ldp_vty_ttl_security(struct vty *, int);
int ldp_vty_ds_cisco_interop(struct vty *, struct vty_arg *[]); int ldp_vty_router_id(struct vty *, int, const char *);
int ldp_vty_trans_pref_ipv4(struct vty *, struct vty_arg *[]); int ldp_vty_ds_cisco_interop(struct vty *, int);
int ldp_vty_neighbor_password(struct vty *, struct vty_arg *[]); int ldp_vty_trans_pref_ipv4(struct vty *, int);
int ldp_vty_neighbor_ttl_security(struct vty *, struct vty_arg *[]); int ldp_vty_neighbor_password(struct vty *, int, const char *, const char *);
int ldp_vty_l2vpn(struct vty *, struct vty_arg *[]); int ldp_vty_neighbor_ttl_security(struct vty *, int, const char *, const char *);
int ldp_vty_l2vpn_bridge(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn(struct vty *, int, const char *);
int ldp_vty_l2vpn_mtu(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_bridge(struct vty *, int, const char *);
int ldp_vty_l2vpn_pwtype(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_mtu(struct vty *, int, const char *);
int ldp_vty_l2vpn_interface(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_pwtype(struct vty *, int, const char *);
int ldp_vty_l2vpn_pseudowire(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_interface(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_cword(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_pseudowire(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_pw_cword(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_nbr_id(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_pw_nbr_addr(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_pwid(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_pw_nbr_id(struct vty *, int, const char *);
int ldp_vty_l2vpn_pw_pwstatus(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_pw_pwid(struct vty *, int, const char *);
int ldp_vty_show_binding(struct vty *, struct vty_arg *[]); int ldp_vty_l2vpn_pw_pwstatus(struct vty *, int);
int ldp_vty_show_discovery(struct vty *, struct vty_arg *[]); int ldp_vty_clear_nbr(struct vty *, const char *);
int ldp_vty_show_interface(struct vty *, struct vty_arg *[]); int ldp_vty_debug(struct vty *, int, const char *, const char *, int);
int ldp_vty_show_capabilities(struct vty *, struct vty_arg *[]); int ldp_vty_show_binding(struct vty *, const char *, int, int);
int ldp_vty_show_neighbor(struct vty *, struct vty_arg *[]); int ldp_vty_show_discovery(struct vty *, const char *, int, int);
int ldp_vty_show_atom_binding(struct vty *, struct vty_arg *[]); int ldp_vty_show_interface(struct vty *, const char *, int);
int ldp_vty_show_atom_vc(struct vty *, struct vty_arg *[]); int ldp_vty_show_capabilities(struct vty *, int);
int ldp_vty_clear_nbr(struct vty *, struct vty_arg *[]); int ldp_vty_show_neighbor(struct vty *, int, int, int);
int ldp_vty_debug(struct vty *, struct vty_arg *[]); int ldp_vty_show_atom_binding(struct vty *, int);
int ldp_vty_show_debugging(struct vty *, struct vty_arg *[]); int ldp_vty_show_atom_vc(struct vty *, int);
int ldp_vty_show_debugging(struct vty *);
void ldp_vty_init(void); void ldp_vty_init(void);

View File

@ -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>

1132
ldpd/ldp_vty_cmds.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,20 @@
/* /*
* Copyright (C) 2016 by Open Source Routing. * 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 * This program is distributed in the hope that it will be useful, but
* 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 * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License
* with this program; see the file COPYING; if not, write to the Free Software * along with this program; see the file COPYING; if not, write to the
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/ */
#include <zebra.h> #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 void ldp_l2vpn_pw_config_write(struct vty *, struct l2vpn_pw *);
static int ldp_vty_get_af(struct vty *); static int ldp_vty_get_af(struct vty *);
static int ldp_iface_is_configured(struct ldpd_conf *, const char *); 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 = struct cmd_node ldp_node =
{ {
@ -418,12 +415,8 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname)
} }
int 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) if (disable)
vty_conf->flags &= ~F_LDPD_ENABLED; vty_conf->flags &= ~F_LDPD_ENABLED;
else { else {
@ -437,15 +430,10 @@ ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[])
} }
int 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; struct ldpd_af_conf *af_conf;
int af; 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) { if (strcmp(af_str, "ipv4") == 0) {
af = AF_INET; af = AF_INET;
@ -480,7 +468,8 @@ ldp_vty_address_family(struct vty *vty, struct vty_arg *args[])
} }
int 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 ldpd_af_conf *af_conf;
struct iface *iface; struct iface *iface;
@ -489,13 +478,6 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
char *ep; char *ep;
long int secs; long int secs;
enum hello_type hello_type; 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); secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_HOLDTIME || secs > MAX_HOLDTIME) { 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 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 ldpd_af_conf *af_conf;
struct iface *iface; struct iface *iface;
@ -589,13 +572,6 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
char *ep; char *ep;
long int secs; long int secs;
enum hello_type hello_type; 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); secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_HELLO_INTERVAL || if (*ep != '\0' || secs < MIN_HELLO_INTERVAL ||
@ -681,15 +657,11 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
} }
int 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; struct ldpd_af_conf *af_conf;
int af; 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 = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af); 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); return (CMD_SUCCESS);
} }
static int int
ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[]) ldp_vty_nbr_session_holdtime(struct vty *vty, int disable,
const char *lsr_id_str, const char *seconds_str)
{ {
char *ep; char *ep;
long int secs; long int secs;
struct in_addr lsr_id; struct in_addr lsr_id;
struct nbr_params *nbrp; 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 || if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) { bad_addr_v4(lsr_id)) {
@ -763,18 +729,14 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
return (CMD_SUCCESS); return (CMD_SUCCESS);
} }
static int int
ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[]) ldp_vty_af_session_holdtime(struct vty *vty, int disable,
const char *seconds_str)
{ {
struct ldpd_af_conf *af_conf; struct ldpd_af_conf *af_conf;
int af; int af;
char *ep; char *ep;
long int secs; 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); secs = strtol(seconds_str, &ep, 10);
if (*ep != '\0' || secs < MIN_KEEPALIVE || secs > MAX_KEEPALIVE) { 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 int
ldp_vty_session_holdtime(struct vty *vty, struct vty_arg *args[]) ldp_vty_interface(struct vty *vty, int disable, const char *ifname)
{
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[])
{ {
int af; int af;
struct iface *iface; struct iface *iface;
struct iface_af *ia; 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); af = ldp_vty_get_af(vty);
iface = if_lookup_name(vty_conf, ifname); iface = if_lookup_name(vty_conf, ifname);
@ -878,15 +821,10 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
} }
int 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; struct ldpd_af_conf *af_conf;
int af; 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 = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af); 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 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; int af;
union ldpd_addr addr; union ldpd_addr addr;
struct tnbr *tnbr; 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); af = ldp_vty_get_af(vty);
@ -959,17 +892,11 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
} }
int 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; struct ldpd_af_conf *af_conf;
int af; 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 = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af); 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 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; struct ldpd_af_conf *af_conf;
int af; 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 = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af); 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->flags &= ~F_LDPD_AF_ALLOCHOSTONLY;
af_conf->acl_label_allocate_for[0] = '\0'; af_conf->acl_label_allocate_for[0] = '\0';
if (!disable) { if (!disable) {
if (host_routes_str) if (host_routes)
af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY; af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY;
else else
strlcpy(af_conf->acl_label_allocate_for, acl_for_str, 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 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; struct ldpd_af_conf *af_conf;
int af; 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 = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af); 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 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; struct ldpd_af_conf *af_conf;
int af; 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 = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af); 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 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; struct ldpd_af_conf *af_conf;
int af; int af;
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
af = ldp_vty_get_af(vty); af = ldp_vty_get_af(vty);
af_conf = ldp_af_conf_get(vty_conf, af); 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 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) if (disable)
vty_conf->rtr_id.s_addr = INADDR_ANY; vty_conf->rtr_id.s_addr = INADDR_ANY;
else { else {
@ -1141,12 +1042,8 @@ ldp_vty_router_id(struct vty *vty, struct vty_arg *args[])
} }
int 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) if (disable)
vty_conf->flags &= ~F_LDPD_DS_CISCO_INTEROP; vty_conf->flags &= ~F_LDPD_DS_CISCO_INTEROP;
else else
@ -1158,12 +1055,8 @@ ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[])
} }
int 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) if (disable)
vty_conf->trans_pref = DUAL_STACK_LDPOV6; vty_conf->trans_pref = DUAL_STACK_LDPOV6;
else else
@ -1175,18 +1068,12 @@ ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[])
} }
int 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; struct in_addr lsr_id;
size_t password_len; size_t password_len;
struct nbr_params *nbrp; 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 || if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) { bad_addr_v4(lsr_id)) {
@ -1226,19 +1113,13 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
} }
int 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 in_addr lsr_id;
struct nbr_params *nbrp; struct nbr_params *nbrp;
long int hops = 0; long int hops = 0;
char *ep; 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 || if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) { bad_addr_v4(lsr_id)) {
@ -1286,16 +1167,11 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
} }
int 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 *l2vpn;
struct l2vpn_if *lif; struct l2vpn_if *lif;
struct l2vpn_pw *pw; 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); l2vpn = l2vpn_find(vty_conf, name_str);
@ -1336,14 +1212,9 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
} }
int 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); 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) if (disable)
memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname)); 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 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); VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
char *ep; char *ep;
int mtu; 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); mtu = strtol(mtu_str, &ep, 10);
if (*ep != '\0' || mtu < MIN_L2VPN_MTU || mtu > MAX_L2VPN_MTU) { 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 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); VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
int pw_type; 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) if (strcmp(type_str, "ethernet") == 0)
pw_type = PW_TYPE_ETHERNET; pw_type = PW_TYPE_ETHERNET;
@ -1410,15 +1271,10 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
} }
int 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); VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
struct l2vpn_if *lif; 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); lif = l2vpn_if_find(l2vpn, ifname);
@ -1453,15 +1309,10 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
} }
int 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); VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
struct l2vpn_pw *pw; 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); pw = l2vpn_pw_find(l2vpn, ifname);
@ -1504,14 +1355,9 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
} }
int 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); 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) if (disable)
pw->flags |= F_PW_CWORD_CONF; pw->flags |= F_PW_CWORD_CONF;
@ -1528,16 +1374,11 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
} }
int 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); VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
int af; int af;
union ldpd_addr addr; 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 || if (ldp_get_address(addr_str, &af, &addr) == -1 ||
bad_addr(af, &addr)) { bad_addr(af, &addr)) {
@ -1561,15 +1402,10 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
} }
int 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); VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
struct in_addr lsr_id; 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 || if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
bad_addr_v4(lsr_id)) { bad_addr_v4(lsr_id)) {
@ -1588,16 +1424,11 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
} }
int 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); VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
char *ep; char *ep;
uint32_t pwid; 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); pwid = strtol(pwid_str, &ep, 10);
if (*ep != '\0' || pwid < MIN_PWID_ID || pwid > MAX_PWID_ID) { 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 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); VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
int disable;
disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
if (disable) if (disable)
pw->flags |= F_PW_STATUSTLV_CONF; 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_if *lif;
struct l2vpn_pw *pw; 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); QOBJ_UNREG(lif);
RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(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); QOBJ_UNREG(pw);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(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); QOBJ_UNREG(pw);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw); free(pw);

View File

@ -1,21 +1,20 @@
/* /*
* Copyright (C) 2016 by Open Source Routing. * 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 * This program is distributed in the hope that it will be useful, but
* 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 * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License
* with this program; see the file COPYING; if not, write to the Free Software * along with this program; see the file COPYING; if not, write to the
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/ */
#include <zebra.h> #include <zebra.h>
@ -1582,24 +1581,22 @@ ldp_vty_get_af(const char *str, int *af)
} }
int 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 imsgbuf ibuf;
struct show_params params; struct show_params params;
const char *af_str;
int af; int af;
if (ldp_vty_connect(&ibuf) < 0) if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING); return (CMD_WARNING);
af_str = vty_get_arg_value(args, "address-family");
if (ldp_vty_get_af(af_str, &af) < 0) if (ldp_vty_get_af(af_str, &af) < 0)
return (CMD_ERR_NO_MATCH); return (CMD_ERR_NO_MATCH);
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.family = af; params.family = af;
params.detail = vty_get_arg_value(args, "detail") ? 1 : 0; params.detail = detail;
params.json = vty_get_arg_value(args, "json") ? 1 : 0; params.json = json;
if (!params.detail && !params.json) if (!params.detail && !params.json)
vty_out(vty, "%-4s %-20s %-15s %-11s %-13s %6s%s", "AF", 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 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 imsgbuf ibuf;
struct show_params params; struct show_params params;
const char *af_str;
int af; int af;
if (ldp_vty_connect(&ibuf) < 0) if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING); return (CMD_WARNING);
af_str = vty_get_arg_value(args, "address-family");
if (ldp_vty_get_af(af_str, &af) < 0) if (ldp_vty_get_af(af_str, &af) < 0)
return (CMD_ERR_NO_MATCH); return (CMD_ERR_NO_MATCH);
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.family = af; params.family = af;
params.detail = vty_get_arg_value(args, "detail") ? 1 : 0; params.detail = detail;
params.json = vty_get_arg_value(args, "json") ? 1 : 0; params.json = json;
if (!params.detail && !params.json) if (!params.detail && !params.json)
vty_out(vty, "%-4s %-15s %-8s %-15s %9s%s", 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 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 imsgbuf ibuf;
struct show_params params; struct show_params params;
unsigned int ifidx = 0; unsigned int ifidx = 0;
const char *af_str;
int af; int af;
if (ldp_vty_connect(&ibuf) < 0) if (ldp_vty_connect(&ibuf) < 0)
return (CMD_WARNING); return (CMD_WARNING);
af_str = vty_get_arg_value(args, "address-family");
if (ldp_vty_get_af(af_str, &af) < 0) if (ldp_vty_get_af(af_str, &af) < 0)
return (CMD_ERR_NO_MATCH); return (CMD_ERR_NO_MATCH);
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.family = af; params.family = af;
params.json = vty_get_arg_value(args, "json") ? 1 : 0; params.json = json;
/* header */ /* header */
if (!params.json) { if (!params.json) {
@ -1675,9 +1669,9 @@ ldp_vty_show_interface(struct vty *vty, struct vty_arg *args[])
} }
int 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;
json_object *json_array; json_object *json_array;
json_object *json_cap; json_object *json_cap;
@ -1727,7 +1721,7 @@ ldp_vty_show_capabilities(struct vty *vty, struct vty_arg *args[])
} }
int 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 imsgbuf ibuf;
struct show_params params; struct show_params params;
@ -1736,9 +1730,9 @@ ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING); return (CMD_WARNING);
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.capabilities = vty_get_arg_value(args, "capabilities") ? 1 : 0; params.capabilities = capabilities;
params.detail = vty_get_arg_value(args, "detail") ? 1 : 0; params.detail = detail;
params.json = vty_get_arg_value(args, "json") ? 1 : 0; params.json = json;
if (params.capabilities) if (params.capabilities)
params.detail = 1; params.detail = 1;
@ -1753,7 +1747,7 @@ ldp_vty_show_neighbor(struct vty *vty, struct vty_arg *args[])
} }
int 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 imsgbuf ibuf;
struct show_params params; struct show_params params;
@ -1762,14 +1756,14 @@ ldp_vty_show_atom_binding(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING); return (CMD_WARNING);
memset(&params, 0, sizeof(params)); memset(&params, 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); imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params)); return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params));
} }
int 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 imsgbuf ibuf;
struct show_params params; struct show_params params;
@ -1778,7 +1772,7 @@ ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[])
return (CMD_WARNING); return (CMD_WARNING);
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
params.json = vty_get_arg_value(args, "json") ? 1 : 0; params.json = json;
if (!params.json) { if (!params.json) {
/* header */ /* header */
@ -1795,14 +1789,11 @@ ldp_vty_show_atom_vc(struct vty *vty, struct vty_arg *args[])
} }
int 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; struct imsgbuf ibuf;
const char *addr_str;
struct ctl_nbr nbr; struct ctl_nbr nbr;
addr_str = vty_get_arg_value(args, "addr");
memset(&nbr, 0, sizeof(nbr)); memset(&nbr, 0, sizeof(nbr));
if (addr_str && if (addr_str &&
(ldp_get_address(addr_str, &nbr.af, &nbr.raddr) == -1 || (ldp_get_address(addr_str, &nbr.af, &nbr.raddr) == -1 ||

View File

@ -1,21 +1,20 @@
/* /*
* Copyright (C) 2016 by Open Source Routing. * 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 * This program is distributed in the hope that it will be useful, but
* 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 * WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License
* with this program; see the file COPYING; if not, write to the Free Software * along with this program; see the file COPYING; if not, write to the
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301 USA
*/ */
#include <zebra.h> #include <zebra.h>

View File

@ -1043,13 +1043,13 @@ ldp_config_reset_main(struct ldpd_conf *conf)
struct iface *iface; struct iface *iface;
struct nbr_params *nbrp; 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); QOBJ_UNREG(iface);
RB_REMOVE(iface_head, &conf->iface_tree, iface); RB_REMOVE(iface_head, &conf->iface_tree, iface);
free(iface); free(iface);
} }
while ((nbrp = RB_ROOT(&conf->nbrp_tree)) != NULL) { while ((nbrp = RB_ROOT(nbrp_head, &conf->nbrp_tree)) != NULL) {
QOBJ_UNREG(nbrp); QOBJ_UNREG(nbrp);
RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp); RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp); free(nbrp);
@ -1105,18 +1105,20 @@ ldp_config_reset_l2vpns(struct ldpd_conf *conf)
struct l2vpn_if *lif; struct l2vpn_if *lif;
struct l2vpn_pw *pw; struct l2vpn_pw *pw;
while ((l2vpn = RB_ROOT(&conf->l2vpn_tree)) != NULL) { while ((l2vpn = RB_ROOT(l2vpn_head, &conf->l2vpn_tree)) != NULL) {
while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) { while ((lif = RB_ROOT(l2vpn_if_head,
&l2vpn->if_tree)) != NULL) {
QOBJ_UNREG(lif); QOBJ_UNREG(lif);
RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(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); QOBJ_UNREG(pw);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(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); QOBJ_UNREG(pw);
RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw); free(pw);
@ -1135,19 +1137,19 @@ ldp_clear_config(struct ldpd_conf *xconf)
struct nbr_params *nbrp; struct nbr_params *nbrp;
struct l2vpn *l2vpn; 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); RB_REMOVE(iface_head, &xconf->iface_tree, iface);
free(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); RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
free(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); RB_REMOVE(nbrp_head, &xconf->nbrp_tree, nbrp);
free(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); RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, l2vpn);
l2vpn_del(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) { if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
COPY(l2vpn, xl); COPY(l2vpn, xl);
RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn); RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn);
RB_INIT(&l2vpn->if_tree); RB_INIT(l2vpn_if_head, &l2vpn->if_tree);
RB_INIT(&l2vpn->pw_tree); RB_INIT(l2vpn_pw_head, &l2vpn->pw_tree);
RB_INIT(&l2vpn->pw_inactive_tree); RB_INIT(l2vpn_pw_head, &l2vpn->pw_inactive_tree);
switch (ldpd_process) { switch (ldpd_process) {
case PROC_LDE_ENGINE: case PROC_LDE_ENGINE:
@ -1761,10 +1763,10 @@ config_new_empty(void)
if (xconf == NULL) if (xconf == NULL)
fatal(NULL); fatal(NULL);
RB_INIT(&xconf->iface_tree); RB_INIT(iface_head, &xconf->iface_tree);
RB_INIT(&xconf->tnbr_tree); RB_INIT(tnbr_head, &xconf->tnbr_tree);
RB_INIT(&xconf->nbrp_tree); RB_INIT(nbrp_head, &xconf->nbrp_tree);
RB_INIT(&xconf->l2vpn_tree); RB_INIT(l2vpn_head, &xconf->l2vpn_tree);
/* set default values */ /* set default values */
ldp_config_reset(xconf); ldp_config_reset(xconf);

View File

@ -152,7 +152,7 @@ ldpe_init(struct ldpd_init *init)
control_listen(); control_listen();
LIST_INIT(&global.addr_list); LIST_INIT(&global.addr_list);
RB_INIT(&global.adj_tree); RB_INIT(global_adj_head, &global.adj_tree);
TAILQ_INIT(&global.pending_conns); TAILQ_INIT(&global.pending_conns);
if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1) if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
fatal("inet_pton"); fatal("inet_pton");
@ -216,7 +216,7 @@ ldpe_shutdown(void)
LIST_REMOVE(if_addr, entry); LIST_REMOVE(if_addr, entry);
free(if_addr); 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); adj_del(adj, S_SHUTDOWN);
/* clean up */ /* clean up */
@ -456,10 +456,10 @@ ldpe_dispatch_main(struct thread *thread)
fatal(NULL); fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf)); memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
RB_INIT(&nconf->iface_tree); RB_INIT(iface_head, &nconf->iface_tree);
RB_INIT(&nconf->tnbr_tree); RB_INIT(tnbr_head, &nconf->tnbr_tree);
RB_INIT(&nconf->nbrp_tree); RB_INIT(nbrp_head, &nconf->nbrp_tree);
RB_INIT(&nconf->l2vpn_tree); RB_INIT(l2vpn_head, &nconf->l2vpn_tree);
break; break;
case IMSG_RECONF_IFACE: case IMSG_RECONF_IFACE:
if ((niface = malloc(sizeof(struct iface))) == NULL) if ((niface = malloc(sizeof(struct iface))) == NULL)
@ -487,9 +487,9 @@ ldpe_dispatch_main(struct thread *thread)
fatal(NULL); fatal(NULL);
memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn)); memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
RB_INIT(&nl2vpn->if_tree); RB_INIT(l2vpn_if_head, &nl2vpn->if_tree);
RB_INIT(&nl2vpn->pw_tree); RB_INIT(l2vpn_pw_head, &nl2vpn->pw_tree);
RB_INIT(&nl2vpn->pw_inactive_tree); RB_INIT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree);
RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn); RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
break; break;
@ -876,8 +876,8 @@ ldpe_adj_detail_ctl(struct ctl_conn *c)
continue; continue;
strlcpy(ictl.name, iface->name, sizeof(ictl.name)); strlcpy(ictl.name, iface->name, sizeof(ictl.name));
if (RB_EMPTY(&iface->ipv4.adj_tree) && if (RB_EMPTY(ia_adj_head, &iface->ipv4.adj_tree) &&
RB_EMPTY(&iface->ipv6.adj_tree)) RB_EMPTY(ia_adj_head, &iface->ipv6.adj_tree))
ictl.no_adj = 1; ictl.no_adj = 1;
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_IFACE, 0, 0, imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_IFACE, 0, 0,
-1, &ictl, sizeof(ictl)); -1, &ictl, sizeof(ictl));

View File

@ -237,7 +237,7 @@ struct adj *adj_new(struct in_addr, struct hello_source *,
union ldpd_addr *); union ldpd_addr *);
void adj_del(struct adj *, uint32_t); void adj_del(struct adj *, uint32_t);
struct adj *adj_find(struct in_addr, struct hello_source *); 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_start_itimer(struct adj *);
void adj_stop_itimer(struct adj *); void adj_stop_itimer(struct adj *);
struct tnbr *tnbr_new(int, union ldpd_addr *); struct tnbr *tnbr_new(int, union ldpd_addr *);

View File

@ -26,9 +26,11 @@
#include "lde.h" #include "lde.h"
#include "log.h" #include "log.h"
static __inline int nbr_id_compare(struct nbr *, struct nbr *); static __inline int nbr_id_compare(const struct nbr *, const struct nbr *);
static __inline int nbr_addr_compare(struct nbr *, struct nbr *); static __inline int nbr_addr_compare(const struct nbr *,
static __inline int nbr_pid_compare(struct nbr *, 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 void nbr_update_peerid(struct nbr *);
static int nbr_ktimer(struct thread *); static int nbr_ktimer(struct thread *);
static void nbr_start_ktimer(struct nbr *); 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_idtimer(struct thread *);
static int nbr_act_session_operational(struct nbr *); static int nbr_act_session_operational(struct nbr *);
static void nbr_send_labelmappings(struct nbr *); static void nbr_send_labelmappings(struct nbr *);
static __inline int nbr_params_compare(struct nbr_params *, static __inline int nbr_params_compare(const struct nbr_params *,
struct nbr_params *); const struct nbr_params *);
RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare) RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare)
RB_GENERATE(nbr_addr_head, nbr, addr_tree, nbr_addr_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); struct nbr_pid_head nbrs_by_pid = RB_INITIALIZER(&nbrs_by_pid);
static __inline int 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)); return (ntohl(a->id.s_addr) - ntohl(b->id.s_addr));
} }
static __inline int 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) if (a->af < b->af)
return (-1); return (-1);
@ -118,7 +120,7 @@ nbr_addr_compare(struct nbr *a, struct nbr *b)
} }
static __inline int 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); 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) if ((nbr = calloc(1, sizeof(*nbr))) == NULL)
fatal(__func__); fatal(__func__);
RB_INIT(&nbr->adj_tree); RB_INIT(nbr_adj_head, &nbr->adj_tree);
nbr->state = NBR_STA_PRESENT; nbr->state = NBR_STA_PRESENT;
nbr->peerid = 0; nbr->peerid = 0;
nbr->af = af; nbr->af = af;
@ -764,7 +766,7 @@ nbr_send_labelmappings(struct nbr *nbr)
} }
static __inline int 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)); return (ntohl(a->lsr_id.s_addr) - ntohl(b->lsr_id.s_addr));
} }

View File

@ -15,7 +15,7 @@ libfrr_la_LDFLAGS = -version-info 0:0:0
libfrr_la_SOURCES = \ libfrr_la_SOURCES = \
network.c pid_output.c getopt.c getopt1.c \ 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 \ graph.c command_parse.y command_lex.l command_match.c \
command_graph.c \ command_graph.c \
command.c \ command.c \

View File

@ -40,6 +40,10 @@
#define MPLS_MIN_UNRESERVED_LABEL 16 #define MPLS_MIN_UNRESERVED_LABEL 16
#define MPLS_MAX_UNRESERVED_LABEL 1048575 #define MPLS_MAX_UNRESERVED_LABEL 1048575
/* Default min and max SRGB label range */
#define MPLS_DEFAULT_MIN_SRGB_LABEL 16000
#define MPLS_DEFAULT_MAX_SRGB_LABEL 23999
#define IS_MPLS_RESERVED_LABEL(label) \ #define IS_MPLS_RESERVED_LABEL(label) \
(label >= MPLS_MIN_RESERVED_LABEL && label <= MPLS_MAX_RESERVED_LABEL) (label >= MPLS_MIN_RESERVED_LABEL && label <= MPLS_MAX_RESERVED_LABEL)

View File

@ -39,7 +39,7 @@
DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router") DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router")
DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name") 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); static struct ns *ns_lookup (ns_id_t);
RB_GENERATE (ns_head, ns, entry, ns_compare) 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 void ns_disable (struct ns *ns);
static __inline int 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); return (a->ns_id - b->ns_id);
} }
@ -453,7 +453,7 @@ ns_terminate (void)
{ {
struct ns *ns; struct ns *ns;
while ((ns = RB_ROOT (&ns_tree)) != NULL) while ((ns = RB_ROOT (ns_head, &ns_tree)) != NULL)
ns_delete (ns); ns_delete (ns);
} }

644
lib/openbsd-tree.c Normal file
View File

@ -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);
}

View File

@ -287,462 +287,262 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \
(x) != NULL; \ (x) != NULL; \
(x) = SPLAY_NEXT(name, head, x)) (x) = SPLAY_NEXT(name, head, x))
/* Macros that define a red-black tree */ /*
#define RB_HEAD(name, type) \ * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
struct name { \ *
struct type *rbh_root; /* root of the tree */ \ * 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.
#define RB_INITIALIZER(root) \ *
{ NULL } * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
#define RB_INIT(root) do { \ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
(root)->rbh_root = NULL; \ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
} while (0) * 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_BLACK 0
#define RB_RED 1 #define RB_RED 1
#define RB_ENTRY(type) \
struct { \ struct rb_type {
struct type *rbe_left; /* left element */ \ int (*t_compare)(const void *, const void *);
struct type *rbe_right; /* right element */ \ void (*t_augment)(void *);
struct type *rbe_parent; /* parent element */ \ unsigned int t_offset; /* offset of rb_entry in type */
int rbe_color; /* node color */ \ };
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; \
} }
#define RB_LEFT(elm, field) (elm)->field.rbe_left #define RB_ENTRY(_type) struct rb_entry
#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 { \ static inline void
RB_PARENT(elm, field) = parent; \ _rb_init(struct rbt_tree *rbt)
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ {
RB_COLOR(elm, field) = RB_RED; \ rbt->rbt_root = NULL;
} while (0)
#define RB_SET_BLACKRED(black, red, field) do { \
RB_COLOR(black, field) = RB_BLACK; \
RB_COLOR(red, field) = RB_RED; \
} while (0)
#ifndef RB_AUGMENT
#define RB_AUGMENT(x) do {} while (0)
#endif
#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)
#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)
/* 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); \
\
/* 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) \
{ \
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; \
} \
\
attr void \
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, 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; \
} \
\
attr 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); \
} \
\
/* Inserts a node into the RB tree */ \
attr struct type * \
name##_RB_INSERT(struct name *head, struct type *elm) \
{ \
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); \
} \
\
/* Finds the node with the same key as elm */ \
attr struct type * \
name##_RB_FIND(struct name *head, struct type *elm) \
{ \
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); \
} \
\
/* Finds the first node greater than or equal to the search key */ \
attr struct type * \
name##_RB_NFIND(struct name *head, struct type *elm) \
{ \
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); \
} \
\
/* ARGSUSED */ \
attr struct type * \
name##_RB_NEXT(struct type *elm) \
{ \
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); \
} \
\
/* ARGSUSED */ \
attr struct type * \
name##_RB_PREV(struct type *elm) \
{ \
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); \
} \
\
attr struct type * \
name##_RB_MINMAX(struct name *head, int val) \
{ \
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); \
} }
#define RB_NEGINF -1 static inline int
#define RB_INF 1 _rb_empty(struct rbt_tree *rbt)
{
return (rbt->rbt_root == NULL);
}
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) void *_rb_insert(const struct rb_type *, struct rbt_tree *, void *);
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) void *_rb_remove(const struct rb_type *, struct rbt_tree *, void *);
#define RB_FIND(name, x, y) name##_RB_FIND(x, y) void *_rb_find(const struct rb_type *, struct rbt_tree *, const void *);
#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) void *_rb_nfind(const struct rb_type *, struct rbt_tree *, const void *);
#define RB_NEXT(name, x, y) name##_RB_NEXT(y) void *_rb_root(const struct rb_type *, struct rbt_tree *);
#define RB_PREV(name, x, y) name##_RB_PREV(y) void *_rb_min(const struct rb_type *, struct rbt_tree *);
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) void *_rb_max(const struct rb_type *, struct rbt_tree *);
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) 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_FOREACH(x, name, head) \ #define RB_INITIALIZER(_head) { { NULL } }
for ((x) = RB_MIN(name, head); \
(x) != NULL; \
(x) = name##_RB_NEXT(x))
#define RB_FOREACH_SAFE(x, name, head, y) \ #define RB_PROTOTYPE(_name, _type, _field, _cmp) \
for ((x) = RB_MIN(name, head); \ extern const struct rb_type *const _name##_RB_TYPE; \
((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \ \
(x) = (y)) __attribute__((__unused__)) static inline void \
_name##_RB_INIT(struct _name *head) \
{ \
_rb_init(&head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_INSERT(struct _name *head, struct _type *elm) \
{ \
return _rb_insert(_name##_RB_TYPE, &head->rbh_root, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_REMOVE(struct _name *head, struct _type *elm) \
{ \
return _rb_remove(_name##_RB_TYPE, &head->rbh_root, elm); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_FIND(struct _name *head, const struct _type *key) \
{ \
return _rb_find(_name##_RB_TYPE, &head->rbh_root, key); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_NFIND(struct _name *head, const struct _type *key) \
{ \
return _rb_nfind(_name##_RB_TYPE, &head->rbh_root, key); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_ROOT(struct _name *head) \
{ \
return _rb_root(_name##_RB_TYPE, &head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline int \
_name##_RB_EMPTY(struct _name *head) \
{ \
return _rb_empty(&head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_MIN(struct _name *head) \
{ \
return _rb_min(_name##_RB_TYPE, &head->rbh_root); \
} \
\
__attribute__((__unused__)) static inline struct _type * \
_name##_RB_MAX(struct _name *head) \
{ \
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_FOREACH_REVERSE(x, name, head) \ #define RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \
for ((x) = RB_MAX(name, head); \ static int \
(x) != NULL; \ _name##_RB_COMPARE(const void *lptr, const void *rptr) \
(x) = name##_RB_PREV(x)) { \
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_FOREACH_REVERSE_SAFE(x, name, head, y) \ #define RB_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \
for ((x) = RB_MAX(name, head); \ static void \
((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \ _name##_RB_AUGMENT(void *ptr) \
(x) = (y)) { \
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_ */ #endif /* _SYS_TREE_H_ */

View File

@ -123,15 +123,13 @@ static struct ttable_cell *ttable_insert_row_va(struct ttable *tt, int i,
assert(i >= -1 && i < tt->nrows); assert(i >= -1 && i < tt->nrows);
char *res, *orig, *section; char *res, *orig, *section;
const char *f;
struct ttable_cell *row; struct ttable_cell *row;
int col = 0; int col = 0;
int ncols = 0; int ncols = 0;
/* count how many columns we have */ /* count how many columns we have */
f = format; for (int i = 0; format[i]; i++)
for (; f[ncols]; f[ncols] == '|' ? ncols++ : *f++) ncols += !!(format[i] == '|');
;
ncols++; ncols++;
if (tt->ncols == 0) if (tt->ncols == 0)
@ -338,7 +336,7 @@ char *ttable_dump(struct ttable *tt, const char *newline)
/* calculate number of lines en total */ /* calculate number of lines en total */
nlines = tt->nrows; nlines = tt->nrows;
nlines += tt->style.border.top_on ? 1 : 0; nlines += tt->style.border.top_on ? 1 : 0;
nlines += tt->style.border.bottom_on ? 1 : 1; // makes life easier nlines += 1; // tt->style.border.bottom_on ? 1 : 1; makes life easier
for (int i = 0; i < tt->nrows; i++) { for (int i = 0; i < tt->nrows; i++) {
/* if leftmost cell has top / bottom border, whole row does */ /* 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.top_on ? 1 : 0;

View File

@ -35,11 +35,11 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
DEFINE_QOBJ_TYPE(vrf) DEFINE_QOBJ_TYPE(vrf)
static __inline int vrf_id_compare (struct vrf *, struct vrf *); static __inline int vrf_id_compare (const struct vrf *, const struct vrf *);
static __inline int vrf_name_compare (struct vrf *, 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_id_head, vrf, id_entry, vrf_id_compare);
RB_GENERATE (vrf_name_head, vrf, name_entry, vrf_name_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_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id);
struct vrf_name_head vrfs_by_name = RB_INITIALIZER (&vrfs_by_name); 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 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); return (a->vrf_id - b->vrf_id);
} }
static int 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); 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; 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. */ /* Initialize VRF module. */
void void
vrf_init (int (*create)(struct vrf *), 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!"); zlog_err ("vrf_init: failed to enable the default VRF!");
exit (1); exit (1);
} }
cmd_variable_handler_register (vrf_var_handlers);
} }
/* Terminate VRF module. */ /* Terminate VRF module. */
@ -419,9 +443,9 @@ vrf_terminate (void)
if (debug_vrf) if (debug_vrf)
zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__); 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); 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); vrf_delete (vrf);
} }

View File

@ -3151,29 +3151,3 @@ vty_terminate (void)
Vvty_serv_thread = NULL; 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;
}

View File

@ -342,7 +342,4 @@ extern void vty_hello (struct vty *);
an async-signal-safe function. */ an async-signal-safe function. */
extern void vty_log_fixed (char *buf, size_t len); 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 */ #endif /* _ZEBRA_VTY_H */

View File

@ -126,6 +126,8 @@ typedef unsigned char u_int8_t;
#define __APPLE_USE_RFC_3542 #define __APPLE_USE_RFC_3542
#endif #endif
#include "lib/openbsd-tree.h"
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#include <netinet/ip.h> #include <netinet/ip.h>

View File

@ -13,6 +13,4 @@ sbin_SCRIPTS = frr-reload.py frr
EXTRA_DIST += frr.service frr-reload.py frr EXTRA_DIST += frr.service frr-reload.py frr
EXTRA_DIST += xml2cli.pl
ssd_SOURCES = start-stop-daemon.c ssd_SOURCES = start-stop-daemon.c

View File

@ -32,3 +32,4 @@ pimd=no
ldpd=no ldpd=no
nhrpd=no nhrpd=no
eigrpd=no eigrpd=no
babeld=no

View File

@ -15,6 +15,7 @@ pimd_options=" --daemon -A 127.0.0.1"
ldpd_options=" --daemon -A 127.0.0.1" ldpd_options=" --daemon -A 127.0.0.1"
nhrpd_options=" --daemon -A 127.0.0.1" nhrpd_options=" --daemon -A 127.0.0.1"
eigrpd_options=" --daemon -A 127.0.0.1" eigrpd_options=" --daemon -A 127.0.0.1"
babeld_options=" --daemon -A 127.0.0.1"
# The list of daemons to watch is automatically generated by the init script. # The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes watchfrr_enable=yes

View File

@ -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);
}

View File

@ -108,6 +108,10 @@ vtysh_scan += $(top_srcdir)/ripngd/ripng_zebra.c
vtysh_scan += $(top_srcdir)/ripngd/ripngd.c vtysh_scan += $(top_srcdir)/ripngd/ripngd.c
endif endif
if LDPD
vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c
endif
if NHRPD if NHRPD
vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c
endif endif
@ -146,22 +150,5 @@ vtysh_cmd_FILES = $(vtysh_scan) \
$(top_srcdir)/watchfrr/watchfrr_vty.c \ $(top_srcdir)/watchfrr/watchfrr_vty.c \
$(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC) $(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC)
# this is slightly iffy... ldp_vty_cmds.c can be located in either vtysh_cmd.c: $(vtysh_cmd_FILES) extract.pl
# $srcdir or $builddir depending on whether it's coming pre-built from a ./extract.pl $(vtysh_cmd_FILES) > vtysh_cmd.c
# 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

View File

@ -2029,17 +2029,19 @@ DEFUNSH (VTYSH_INTERFACE,
DEFUN (vtysh_show_thread, DEFUN (vtysh_show_thread,
vtysh_show_thread_cmd, vtysh_show_thread_cmd,
"show thread cpu [FILTER]", "show thread cpu [FILTER]",
SHOW_STR SHOW_STR
"Thread information\n" "Thread information\n"
"Thread CPU usage\n" "Thread CPU usage\n"
"Display filter (rwtexb)\n") "Display filter (rwtexb)\n")
{ {
int idx_filter = 3;
unsigned int i; unsigned int i;
int idx = 0;
int ret = CMD_SUCCESS; int ret = CMD_SUCCESS;
char line[100]; char line[100];
sprintf(line, "show thread cpu %s\n", (argc == 4) ? argv[idx_filter]->arg : ""); const char *filter = argv_find (argv, argc, "FILTER", &idx) ? argv[idx]->arg : "";
snprintf(line, sizeof(line), "do show thread cpu %s\n", filter);
for (i = 0; i < array_size(vtysh_client); i++) for (i = 0; i < array_size(vtysh_client); i++)
if ( vtysh_client[i].fd >= 0 ) if ( vtysh_client[i].fd >= 0 )
{ {

View File

@ -60,7 +60,7 @@ extern struct zebra_t zebrad;
/* static function declarations */ /* static function declarations */
static void static void
fec_evaluate (struct zebra_vrf *zvrf, int add); fec_evaluate (struct zebra_vrf *zvrf);
static u_int32_t static u_int32_t
fec_derive_label_from_index (struct zebra_vrf *vrf, zebra_fec_t *fec); fec_derive_label_from_index (struct zebra_vrf *vrf, zebra_fec_t *fec);
static int static int
@ -357,7 +357,7 @@ lsp_uninstall (struct zebra_vrf *zvrf, mpls_label_t label)
* their local labels and trigger client updates. * their local labels and trigger client updates.
*/ */
static void static void
fec_evaluate (struct zebra_vrf *zvrf, int add) fec_evaluate (struct zebra_vrf *zvrf)
{ {
struct route_node *rn; struct route_node *rn;
zebra_fec_t *fec; zebra_fec_t *fec;
@ -385,13 +385,8 @@ fec_evaluate (struct zebra_vrf *zvrf, int add)
/* Save old label, determine new label. */ /* Save old label, determine new label. */
old_label = fec->label; old_label = fec->label;
if (add) new_label = zvrf->mpls_srgb.start_label + fec->label_index;
{ if (new_label >= zvrf->mpls_srgb.end_label)
new_label = zvrf->mpls_srgb.start_label + fec->label_index;
if (new_label >= zvrf->mpls_srgb.end_label)
new_label = MPLS_INVALID_LABEL;
}
else
new_label = MPLS_INVALID_LABEL; new_label = MPLS_INVALID_LABEL;
/* If label has changed, update FEC and clients. */ /* If label has changed, update FEC and clients. */
@ -399,8 +394,8 @@ fec_evaluate (struct zebra_vrf *zvrf, int add)
continue; continue;
if (IS_ZEBRA_DEBUG_MPLS) if (IS_ZEBRA_DEBUG_MPLS)
zlog_debug ("Update fec %s new label %u upon label block %s", zlog_debug ("Update fec %s new label %u upon label block",
buf, new_label, add ? "ADD" : "DEL"); buf, new_label);
fec->label = new_label; fec->label = new_label;
fec_update_clients (fec); fec_update_clients (fec);
@ -2937,7 +2932,7 @@ zebra_mpls_label_block_add (struct zebra_vrf *zvrf, u_int32_t start_label,
zvrf->mpls_srgb.end_label = end_label; zvrf->mpls_srgb.end_label = end_label;
/* Evaluate registered FECs to see if any get a label or not. */ /* Evaluate registered FECs to see if any get a label or not. */
fec_evaluate (zvrf, 1); fec_evaluate (zvrf);
return 0; return 0;
} }
@ -2947,11 +2942,11 @@ zebra_mpls_label_block_add (struct zebra_vrf *zvrf, u_int32_t start_label,
int int
zebra_mpls_label_block_del (struct zebra_vrf *zvrf) zebra_mpls_label_block_del (struct zebra_vrf *zvrf)
{ {
zvrf->mpls_srgb.start_label = 0; zvrf->mpls_srgb.start_label = MPLS_DEFAULT_MIN_SRGB_LABEL;
zvrf->mpls_srgb.end_label = 0; zvrf->mpls_srgb.end_label = MPLS_DEFAULT_MAX_SRGB_LABEL;
/* Process registered FECs to clear their local label, if needed. */ /* Process registered FECs to clear their local label, if needed. */
fec_evaluate (zvrf, 0); fec_evaluate (zvrf);
return 0; return 0;
} }
@ -2964,9 +2959,13 @@ zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *zvrf)
if (zvrf->mpls_srgb.start_label == 0) if (zvrf->mpls_srgb.start_label == 0)
return 0; return 0;
vty_out(vty, "mpls label global-block %u %u%s", if ((zvrf->mpls_srgb.start_label != MPLS_DEFAULT_MIN_SRGB_LABEL) ||
zvrf->mpls_srgb.start_label, zvrf->mpls_srgb.end_label, (zvrf->mpls_srgb.end_label != MPLS_DEFAULT_MAX_SRGB_LABEL))
VTY_NEWLINE); {
vty_out(vty, "mpls label global-block %u %u%s",
zvrf->mpls_srgb.start_label, zvrf->mpls_srgb.end_label,
VTY_NEWLINE);
}
return 1; return 1;
} }
@ -3000,8 +2999,8 @@ zebra_mpls_init_tables (struct zebra_vrf *zvrf)
zvrf->fec_table[AFI_IP] = route_table_init(); zvrf->fec_table[AFI_IP] = route_table_init();
zvrf->fec_table[AFI_IP6] = route_table_init(); zvrf->fec_table[AFI_IP6] = route_table_init();
zvrf->mpls_flags = 0; zvrf->mpls_flags = 0;
zvrf->mpls_srgb.start_label = 0; zvrf->mpls_srgb.start_label = MPLS_DEFAULT_MIN_SRGB_LABEL;
zvrf->mpls_srgb.end_label = 0; zvrf->mpls_srgb.end_label = MPLS_DEFAULT_MAX_SRGB_LABEL;
} }
/* /*

View File

@ -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); vrf = vrf_lookup_by_id (vrf_id);
if (vrf) if (vrf)
{ {
vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf); vrf = RB_NEXT (vrf_id_head, vrf);
if (vrf) { if (vrf) {
*next_id_p = vrf->vrf_id; *next_id_p = vrf->vrf_id;
return 1; return 1;