Files
wlan-lanforge-scripts/lf_firemod.pl
Ben Greear 41abc4f5f2 Add tos-plus test script
Update lf_associate comments, firemod defaults, and make tos script
use AutoHelper and multicon 1.
2020-03-31 11:41:38 -07:00

833 lines
27 KiB
Perl
Executable File

#!/usr/bin/perl -w
# This program is used to create, show, and modify existing connections
# and get some basic information from LANforge.
# (C) 2020 Candela Technologies Inc.
#
#
use strict;
use warnings;
use diagnostics;
use Carp;
$SIG{ __DIE__ } = sub { Carp::confess( @_ ) };
$SIG{ __WARN__ } = sub { Carp::confess( @_ ) };
# Un-buffer output
$| = 1;
# use lib prepends to @INC, so put lower priority first
# This is before run-time, so cannot condition this with normal 'if' logic.
use lib '/home/lanforge/scripts';
use lib "./";
use LANforge::Endpoint;
use LANforge::Port;
use LANforge::Utils;
use Net::Telnet ();
use Getopt::Long;
our $NA = 'NA';
our $NL = "\n";
our $shelf_num = 1;
# Default values for ye ole cmd-line args.
our $resource = 1;
our $quiet = "yes";
our $endp_name = "";
our $endp_cmd = "";
our $port_name = "";
our $speed = "-1";
our $action = "";
our $do_cmd = "NA";
our $lfmgr_host = "localhost";
our $lfmgr_port = 4001;
our $endp_vals = undef;
our $ip_port = "-1"; # let lf choose
our $multicon = "0"; #no multicon
# For creating multicast endpoints
our $endp_type = undef; #"mc_udp"; this needs to be explicit
our $mcast_addr = "224.9.9.9";
our $mcast_port = "9999";
our $max_speed = "0";
our $rcv_mcast = "YES";
our $min_pkt_sz = "-1";
our $max_pkt_sz = "0";
our $use_csums = "NO"; # Use LANforge checksums in payload?
our $ttl = 32;
our $report_timer = 5000;
our $tos = "";
our $lat1 = "";
our $lat2 = "";
our $arm_pps = "";
our $arm_cpu_id = "NA";
# For cross connects
our $cx_name = "";
our $cx_endps = "";
our $list_cx_name = "all";
our $test_mgr = "default_tm";
our $list_test_mgr = "all";
our $stats_from_file = "";
our $fail_msg = "";
our $manual_check = 0;
our @known_endp_types = qw(generic lf_tcp lf_tcp6 lf_udp lf_udp6 mc_udp mc_udp6);
our @known_tos = qw(DONT-SET LOWCOST LOWDELAY RELIABILITY THROUGHPUT BK BE VI VO);
########################################################################
# Nothing to configure below here, most likely.
########################################################################
my $endp_type_str = join(' | ', @::known_endp_types);
my $tos_str = join(' | ', @::known_tos);
our $usage = <<"__EndOfUsage__";
$0 [ --action {
create_cx | create_endp | create_arm |
delete_cx | delete_cxe | delete_endp | do_cmd |
list_cx | list_endp | list_ports |
set_endp | show_cx | show_endp | show_port |
start_cx | start_endp | stop_cx | stop_endp
} ]
[--arm_pps {packets per second}]
[--cmd {lf-cli-command text}]
[--cx_name {connection name}]
[--cx_endps {endp1},{endp2}]
[--endp_cmd {generic-endp-command}]
[--endp_name {name}]
[--endp_type { $endp_type_str }]
[--endp_vals {key,key,key,key}]
# show_endp output can be narrowed with key-value arguments
# Examples:
# --action show_endp --endp_vals MinTxRate,DestMAC,Avg-Jitter
# Not available: Latency,Pkt-Gaps, or rows below steps-failed.
# Special Keys:
# --endp_vals tx_bytes (Tx Bytes)
# --endp_vals rx_bytes (Rx Bytes)
[--ip_port {-1 (let LF choose, AUTO) | 0 (let OS choose, ANY) | specific IP port}]
[--max_pkt_sz {maximum payload size in bytes}]
[--max_speed {speed in bps, 0 means same as mininum value}]
[--min_pkt_sz {minimum payload size in bytes}]
[--mcast_addr {multicast address, for example: 224.4.5.6}]
[--mcast_port {multicast port number}]
[--mgr {host-name | IP}]
[--mgr_port {ip port}]
[--multicon {0 (no multi-conn, Normal) | number of connections (TCP only)}]
[--port_name {name}]
[--quiet { yes | no }]
[--rcv_mcast {yes (receiver) | no (transmitter)}]
[--report_timer {miliseconds}]
[--resource {number}]
[--speed {speed in bps}]
[--stats_from_file {file-name}]
# Read 'show-endp' ouput from a file instead of direct query from LANforge.
# This can save a lot of time if we already have the output available.
[--tos { $tos_str },{priority}]
[--use_csums {yes | no, should we checksum the payload}]
[--use_ports {port-A,port-B} # Example: 1.1.eth1,1.2.sta0
# notation is <shelf>.<resource>.<port-name>
# if this option is present, you can skip the create_endp action
[--use_speeds {speed-A,speed-B} # Example: 54000,1000000
# if this option is present, you can skip the create_endp action
[--log_cli {1|filename}]
[--test_mgr {default_tm|all|other-tm-name}]
[--ttl {time-to-live}]
Example:
$0 --action set_endp --endp_name udp1-A --speed 154000
$0 --action normalize_latency --lat1 "latency-buckets info for endpA" --lat2 "latency-buckets-info for endpB"
$0 --action create_endp --endp_name mcast_xmit_1 --speed 154000 \\
--endp_type mc_udp --mcast_addr 224.9.9.8 --mcast_port 9998 \\
--rcv_mcast NO --port_name eth1 \\
--min_pkt_sz 1072 --max_pkt_sz 1472 \\
--use_csums NO --ttl 32 \\
--quiet no --report_timer 1000
$0 --action create_endp --endp_name bc1 --speed 256000 \\
--endp_type lf_tcp --tos THROUGHPUT,100 --port_name rd0#1
$0 --action create_endp --endp_name ping1 --port_name sta0 --endp_cmd \"lfping -p deadbeef000 -I sta0 8.8.4.4\"
--endp_type generic
$0 --action list_cx --test_mgr all --cx_name all
# Unlikely example of creating a CX from differently named endpoints:
$0 --action create_cx --cx_name L301 \\
--cx_endps ep_rd0a,ep_rd1a --report_timer 1000
# Or, skip explicit endpoint creation with the using-ports feature:
$0 --action create_cx --cx_name banana \\
--use_ports sta0,eth1 --use_speeds 15000,10000000 --report_timer 1200
Example of creating an Armageddon connection:
$0 --action create_arm --endp_name arm01-A --port_name eth1 \\
--arm_pps 80000 --min_pkt_sz 1472 --max_pkt_sz 1514 --tos LOWDELAY,100
$0 --mgr jedtest --action create_cx --cx_name arm-01 --cx_endps arm01-A,arm01-B
Example of creating endpoints and joining them:
$0 --mgr localhost --action create_endp --endp_name test1a --speed 10000000 \\
--endp_type lf_tcp --port_name eth5 --ip_port 0 --multicon 10
$0 --mgr localhost --resource 3 --action create_endp --endp_name test1b --speed 0 \\
--endp_type lf_tcp --port_name wlan2 --multicon 1
$0 --mgr localhost --action create_cx --cx_name test1 --cx_endps test1a,test1b
$0 -m vm-48e4 -p 4001 --action create_cx --cx_name testo --endp_type tcp \\
--use_ports r0b,r1b --use_speeds 9600,9600 --report_timer 250
__EndOfUsage__
my $i = 0;
my $cmd;
my $log_cli = "unset"; # use ENV{LOG_CLI} elsewhere
my $show_help = 0;
our $use_ports_str = "NA";
our $use_speeds_str = "NA";
our $use_max_speeds = "NA";
our @use_ports = ();
our @use_speeds = ();
if (@ARGV < 2) {
print $usage;
exit 0;
}
our $debug = 0;
GetOptions
(
'action|a=s' => \$::action,
'arm_pps=i' => \$::arm_pps,
'cmd|c=s' => \$::do_cmd,
'cx_endps=s' => \$::cx_endps,
'cx_name=s' => \$::cx_name,
'debug|d' => \$::debug,
'help|h' => \$show_help,
'ip_port=i' => \$::ip_port,
'endp_cmd=s' => \$::endp_cmd,
'endp_name|e=s' => \$::endp_name,
'endp_type=s' => \$::endp_type,
'endp_vals|o=s' => \$::endp_vals,
'log_cli=s{0,1}' => \$log_cli,
'manager|mgr|m=s' => \$::lfmgr_host,
'max_speed=s' => \$::speed,
'min_pkt_sz=s' => \$::min_pkt_sz,
'max_pkt_sz=s' => \$::max_pkt_sz,
'mcast_addr=s' => \$::mcast_addr,
'mcast_port=s' => \$::mcast_port,
'lfmgr_port|mgr_port|port|p=i' => \$::lfmgr_port,
'multicon=i' => \$::multicon,
'port_name=s' => \$::port_name,
'quiet|q=s' => \$::quiet,
'rcv_mcast=s' => \$::rcv_mcast,
'report_timer=i' => \$::report_timer,
'resource|r=i' => \$::resource,
'speed|s=i' => \$::speed,
'stats_from_file=s' => \$::stats_from_file,
'ttl=i' => \$::ttl,
'use_csums=s' => \$::use_csums,
'use_ports=s' => \$::use_ports_str,
'use_speeds=s' => \$::use_speeds_str,
'use_max_speeds=s' => \$::use_max_speeds,
'test_mgr=s' => \$::test_mgr,
'tos=s' => \$::tos,
'lat1=s' => \$::lat1,
'lat2=s' => \$::lat2,
) || die("$::usage");
if ($show_help) {
print $usage;
exit 0;
}
# Convert some TOS values that the server likely doesn't understand.
if ($tos eq "BK") {
$tos = 64;
}
elsif ($tos eq "BE") {
$tos = 96;
}
elsif ($tos eq "VI") {
$tos = 128;
}
elsif ($tos eq "VO") {
$tos = 192;
}
use Data::Dumper;
if ($::debug) {
$ENV{DEBUG} = 1 if (!(defined $ENV{DEBUG}));
}
if ($::quiet eq "0") {
$::quiet = "no";
}
elsif ($::quiet eq "1") {
$::quiet = "yes";
}
if (defined $log_cli) {
if ($log_cli ne "unset") {
# here is how we reset the variable if it was used as a flag
if ($log_cli eq "") {
$ENV{'LOG_CLI'} = 1;
}
else {
$ENV{'LOG_CLI'} = $log_cli;
}
}
}
if ($::do_cmd ne "NA") {
$::action = "do_cmd";
}
our @valid_actions = qw(
create_arm create_cx create_endp normalize_latency
delete_cx delete_cxe delete_endp do_cmd
list_cx list_endp list_ports
set_endp show_cx show_endp show_port start_endp stop_endp
);
if (($::action eq "") && ((defined $::endp_vals) && ("$::endp_vals" ne ""))) {
$::action = "show_endp";
}
if (! (grep {$_ eq $::action} @::valid_actions )) {
die("Invalid action: $::action\n$::usage\n");
}
our @actions_needing_endp = qw(
create_arm create_endp
delete_endp
set_endp start_endp stop_endp
);
if (grep {$_ eq $::action} @actions_needing_endp) {
if (length($::endp_name) == 0) {
print "ERROR: Must specify endp_name.\n";
die("$::usage");
}
}
if ($::quiet eq "1" ) {
$::quiet = "yes";
}
# Open connection to the LANforge server.
our $utils = new LANforge::Utils();
if (!defined $::stats_from_file || ("" eq $::stats_from_file)) {
$::utils->connect($lfmgr_host, $lfmgr_port);
}
if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm,list_endp,normalize_latency")) {
$::max_speed = $::speed if ($::max_speed eq "-1");
if ($::action eq "normalize_latency") {
my $val = $::utils->normalize_latency($::lat1, $::lat2);
print("Normalized-Latency: $val\n");
}
elsif ($::action eq "list_endp") {
$::utils->cli_rcv_silent(0);
$::quiet = "no";
my @lines = split(/\r?\n/, $::utils->doAsyncCmd("nc_show_endpoints all"));
for my $line (@lines) {
if ($line =~ /^([A-Z]\w+)\s+\[(.*?)\]/) {
print "** $line\n";
}
}
}
elsif ($::action eq "show_endp") {
if ((defined $::endp_vals) && ("$::endp_vals" ne "")) {
my %option_map = ();
my $option = '';
for $option (split(',', $::endp_vals)) {
#print "OPTION[$option]\n";
#next if ($option =~ /\s/);
my $oopt = $option;
$option_map{ $option } = '';
if ($option =~ /rx[_-]pps/ ) { $option = "Rx-Pkts-Per-Sec"; }
if ($option =~ /tx[_-]pps/ ) { $option = "Tx-Pkts-Per-Sec"; }
if ($option =~ /rx[_-]pkts/ ) { $option = "Rx-Pkts-Total"; }
if ($option =~ /tx[_-]pkts/ ) { $option = "Tx-Pkts-Total"; }
if ($option =~ /rx[_-]bps/ ) { $option = "Rx-Bytes-bps"; }
if ($option =~ /tx[_-]bps/ ) { $option = "Tx-Bytes-bps"; }
if ($option =~ /^Rx[ _-]Bytes$/ ) { $option = "Rx-Bytes-Total"; }
if ($option =~ /^Tx[ _-]Bytes$/ ) { $option = "Tx-Bytes-Total"; }
if ($option =~ /^Rx[ _-]Pkts$/ ) { $option = "Rx-Pkts-Total"; }
if ($option =~ /^Tx[ _-]Pkts$/ ) { $option = "Tx-Pkts-Total"; }
if ($option =~ /^EID$/i ) {
$option_map{ "Shelf" } = '';
$option_map{ "Card" } = '';
$option_map{ "Port" } = '';
}
# we don't know if we're armageddon or layer 3
if ($option =~ /tx_bytes/ ) {
$option_map{ "Tx-Bytes-Total" } = '';
$option = "Bytes Transmitted";
}
elsif ($option =~ /rx_b(ps|ytes)/ ) {
$option_map{ "Rx-Bytes-Total" } = '';
$option = "Bytes Rcvd";
}
elsif ($option =~ /tx_packets/) {
$option_map{ "Tx-Pkts-Total" } = '';
$option = "Packets Transmitted";
}
elsif ($option =~ /rx_packets/) {
$option_map{ "Rx-Pkts-Total" } = '';
$option = "Packets Rcvd";
}
if ($oopt ne $option) {
$option_map{ $option } = '';
}
}
# options are reformatted
my $i;
my @lines = ();
if ($stats_from_file ne "") {
@lines = split(/\r?\n/, get_stats_from_file($stats_from_file, $endp_name));
}
else {
@lines = split(/\r?\n/, $::utils->doAsyncCmd("nc_show_endp $endp_name"));
}
my $rh_value_map = $::utils->show_as_hash(\@lines);
if ($debug && ($quiet ne "yes")) {
my @keyz = sort keys(%$rh_value_map);
print Dumper(\@keyz);
}
for my $option (keys %option_map) {
my $val = '-';
if ($option =~ /^EID$/i) {
$val = "1.".$rh_value_map->{"Card"}.".".$rh_value_map->{"Port"};
}
elsif (defined $rh_value_map->{$option}) {
$val = $rh_value_map->{$option};
if ($option =~ /Latency/) {
$val = $rh_value_map->{$option};
$option_map{"Normalized-Hdr"} = $::utils->normalize_bucket_hdr(17);
$option_map{"Latency"} = $val;
}
elsif ($option =~ /Pkt-Gaps/) {
$val = $rh_value_map->{$option};
$option_map{"Normalized-Hdr"} = $::utils->normalize_bucket_hdr(17);
$option_map{"Pkt-Gaps"} = $val;
}
elsif ($option =~ /RX-Silence/) {
$val = $rh_value_map->{$option};
$option_map{"Normalized-Hdr"} = $::utils->normalize_bucket_hdr(17);
$option_map{"RX-Silence"} = $val;
}
}
else {
$val = 'not found';
}
$option_map{ $option } = $val;
}
for $option ( sort keys %option_map ) {
#print("Checking option: $option\n");
print $option.": ".$option_map{ $option }."\n";
}
}
else {
if ($stats_from_file ne "") {
print get_stats_from_file($stats_from_file, $endp_name);
}
else {
print $::utils->doAsyncCmd("nc_show_endp $::endp_name");
}
}
}
elsif ($::action eq "create_arm") {
die("Must choose packets per second: --arm_pps\n$::usage")
if (! defined $::arm_pps || $::arm_pps eq "");
$::min_pkt_sz = "1472" if ($::min_pkt_sz eq "-1");
$::max_pkt_sz = $::min_pkt_sz if ($::max_pkt_sz eq "-1");
my $ip_port = "-1"; # let lf choose
$cmd = $::utils->fmt_cmd("add_arm_endp", $::endp_name, $shelf_num, $::resource,
$::port_name, "arm_udp", $::arm_pps,
$::min_pkt_sz, $::max_pkt_sz, $::arm_cpu_id, $::tos);
$::utils->doCmd($cmd);
$cmd = "set_endp_report_timer $::endp_name $::report_timer";
$::utils->doCmd($cmd);
}
elsif ($::action eq "create_endp") {
create_endp($::endp_name, $::resource, $::port_name, $::endp_type, $::speed, $::max_speed);
}
else {
# Set endp
if ($speed ne "NA") {
# Read the endpoint in...
#my $endp1 = new LANforge::Endpoint();
#$::utils->updateEndpoint($endp1, $endp_name);
# Assume Layer-3 for now
$cmd = $::utils->fmt_cmd("add_endp", $endp_name, $::NA, $::NA, $::NA,
$::NA, $::NA, $::NA, $speed, $max_speed);
#print("cmd: $cmd\n");
$::utils->doCmd($cmd);
}
}
}
elsif ($::action eq "start_endp") {
$cmd = "start_endp $::endp_name";
$::utils->doCmd($cmd);
}
elsif ($::action eq "stop_endp") {
$cmd = "stop_endp $::endp_name";
$::utils->doCmd($cmd);
}
elsif ($::action eq "delete_endp") {
$cmd = "rm_endp $::endp_name";
$::utils->doCmd($cmd);
}
elsif ($::action eq "show_port") {
print $::utils->doAsyncCmd("nc_show_port 1 $::resource $::port_name") . "\n";
}
elsif ($::action eq "do_cmd") {
print $::utils->doAsyncCmd("$::do_cmd") . "\n";
}
elsif ($::action eq "list_ports") {
my @ports = $::utils->getPortListing($::shelf_num, $::resource);
my $i;
for ($i = 0; $i<@ports; $i++) {
my $cur = $ports[$i]->cur_flags();
#print "cur-flags -:$cur:-\n";
print $ports[$i]->dev();
if ($cur =~ /LINK\-UP/) {
print " link=UP";
}
else {
print " link=DOWN";
}
# Guess speed..need better CLI output API for more precise speed.
if ($cur =~ /10G\-FD/) {
print " speed=10G";
}
elsif ($cur =~ /1000\-/) {
print " speed=1G";
}
elsif ($cur =~ /100bt\-/) {
print " speed=100M";
}
elsif ($cur =~ /10bt\-/) {
print " speed=10M";
}
else {
print " speed=UNKNOWN";
}
print "\n";
}
}
elsif ($::action eq "list_cx") {
$::cx_name = $::list_cx_name if ($::cx_name eq "");
$::test_mgr = $::list_test_mgr if ($::test_mgr eq "");
my $cmd = $::utils->fmt_cmd("show_cxe", $::test_mgr, $::cx_name );
my @lines = split(/\r?\n/, $::utils->doAsyncCmd($cmd));
my $out = '';
my $num_ep = 0;
for my $line (@lines) {
#print " |||$line\n";
if ($line =~ /\s*WAN_LINK CX:\s+([^ ]+)\s+id:.*$/ ) {
$out .= "WL $1";
}
if ($line =~ /^WanLink\s+\[([^ ]+)\] .*$/ ) {
$out .= ", wanlink $1";
$num_ep++;
}
if ($line =~ /^\s*(WanLink|LANFORGE.*? CX):\s+([^ ]+) .*$/ ) {
$out .= "CX $2";
}
if ($line =~ /^ARM_.*? CX:\s+([^ ]+) .*$/ ) {
$out .= "CX $1";
}
if ($line =~ /^(Endpoint|ArmEndp) \[([^ \]]+)\].*$/) {
$out .= ", endpoint $2";
$num_ep++;
}
if (($line =~ /^ *$/) && ($num_ep >1)) {
print "$out\n";
$out = '';
$num_ep = 0;
}
}
}
elsif ($::action eq "show_cx") {
# require a cx_name
die("Please specify cx_name\n$::usage") if (length($::cx_name) < 1);
if (length($::test_mgr) <1) {
$::test_mgr = "default_tm";
}
my $cmd = $::utils->fmt_cmd("show_cxe", $::test_mgr, $::cx_name );
#print "$cmd\n";
print $::utils->doAsyncCmd($cmd)."\n";
}
elsif ($::action eq "create_cx") {
# require cx_name, test_mgr, two endpoints
my $end_a = "";
my $end_b = "";
my $port_a = "";
my $port_b = "";
my $speed_a = 0;
my $speed_b = 0;
my $max_speed_a = $::max_speed;
my $max_speed_b = $::max_speed;
if ("NA" ne $::use_ports_str) {
($port_a, $port_b) = split(',', $::use_ports_str);
if (!(defined $port_a) || !(defined $port_b)) {
die("Error with port names. Please format as short EIDs: 1.1.sta0000,1.2.eth1");
}
die("Please name your cross connect: --cx_name\n$::usage")
if ($::cx_name eq "");
$end_a = "${main::cx_name}-A";
$end_b = "${main::cx_name}-B";
$::cx_endps = "$end_a,$end_b";
}
elsif ((defined $::cx_endps) && ("" ne $::cx_endps)) {
($end_a, $end_b) = split(/,/, $::cx_endps);
die("Specify two endpoints like: tcp123-A,tcp123-B \n$::usage")
if ((length($end_a) < 1) || (length($end_b) < 1));
}
else {
die("please use --cx_endps a,b or --use_ports portA,portB");
}
if ("NA" ne $::use_speeds_str) {
($speed_a, $speed_b) = split(',', $::use_speeds_str);
$max_speed_a = $speed_a;
$max_speed_b = $speed_b;
}
if ("NA" ne $::use_max_speeds) {
($max_speed_a, $max_speed_b) = split(',', $::use_speeds_str);
}
# create endpoints
my $resource_a = $::resource;
my $resource_b = $::resource;
my $shelf;
my @hunks;
if ($port_a =~ /1\.\d+\.\S+/) {
@hunks = split(/[.]/, $port_a);
($shelf, $resource_a, $port_a) = @hunks;
}
if ($port_b =~ /1\.\d+\.\S+/) {
@hunks = split(/[.]/, $port_b);
($shelf, $resource_b, $port_b) = @hunks;
}
print ("end_a[$end_a] resource_a[$resource_a] port_a[$port_a], type[$::endp_type] speed[$speed_a] max[$max_speed_a]\n");
print ("end_b[$end_b] resource_b[$resource_b] port_b[$port_b], type[$::endp_type] speed[$speed_b] max[$max_speed_b]\n");
create_endp($end_a, $resource_a, $port_a, $::endp_type, $speed_a, $max_speed_a);
create_endp($end_b, $resource_b, $port_b, $::endp_type, $speed_b, $max_speed_b);
my $cmd = $::utils->fmt_cmd("add_cx", $::cx_name, $::test_mgr, $end_a, $end_b);
$::utils->doCmd($cmd);
my $cxonly = $::NA;
$cmd = $::utils->fmt_cmd("set_cx_report_timer", $::test_mgr, $::cx_name, $::report_timer, $cxonly);
$::utils->doCmd($cmd);
}
elsif ($::action eq "delete_cx") {
# require cx_name
die("Which test manager?: --test_mgr\n$::usage") if ($::test_mgr eq "");
die("Which cross connect? --cx_name\n$::usage") if ($::cx_name eq "");
$::utils->doCmd($::utils->fmt_cmd("rm_cx", $::test_mgr, $::cx_name));
}
elsif ($::action eq "delete_cxe") {
# require cx_name
die("Which test manager?: --test_mgr\n$::usage") if ($::test_mgr eq "");
die("Which cross connect? --cx_name\n$::usage") if ($::cx_name eq "");
$::utils->doCmd($::utils->fmt_cmd("rm_cx", $::test_mgr, $::cx_name));
$::utils->doCmd($::utils->fmt_cmd("rm_endp", "$::cx_name-A"));
$::utils->doCmd($::utils->fmt_cmd("rm_endp", "$::cx_name-B"));
}
else {
die("Unknown action: $::action\n$::usage\n");
}
exit(0);
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
sub create_endp {
my ($my_endp_name, $my_resource, $my_port_name, $my_endp_type, $my_speed, $my_max_speed) = @_;
die("Must choose endpoint protocol type: --endp_type\n$::usage")
if (! defined $::endp_type|| $::endp_type eq "");
if ($my_endp_type eq "tcp") {
$my_endp_type = "lf_tcp";
}
if ($my_endp_type eq "udp") {
$my_endp_type = "lf_udp";
}
if ($my_endp_type ne "NA") {
die("Endpoint protocol type --endp_type must be among "
.join(', ', @::known_endp_types)."\n".$::usage)
if (! grep {$_ eq $my_endp_type } @::known_endp_types);
}
if ($my_endp_type eq "generic") {
if ($::endp_cmd eq "") {
die("Must specify endp_cmd if creating a generic endpoint.\n");
}
$cmd = $::utils->fmt_cmd("add_gen_endp", $my_endp_name, 1, $my_resource,
$my_port_name, "gen_generic");
$::utils->doCmd($cmd);
# Create the dummy
#my $dname = "D_" . $::endp_name;
#$cmd = $::utils->fmt_cmd("add_gen_endp", $dname, shelf_num, $::resource,
# $::port_name, "gen_generic");
#$::utils->doCmd($cmd);
$cmd = "set_gen_cmd " . $my_endp_name . " " . $::endp_cmd;
$::utils->doCmd($cmd);
$cmd = "set_endp_report_timer $my_endp_name $::report_timer";
$::utils->doCmd($cmd);
$::cx_name = "CX_" . $my_endp_name;
$cmd = "add_cx $::cx_name $::test_mgr $my_endp_name";
$::utils->doCmd($cmd);
my $cxonly = $::NA;
$cmd = $::utils->fmt_cmd("set_cx_report_timer", $::test_mgr, $::cx_name, $::report_timer, $cxonly);
$::utils->doCmd($cmd);
}
elsif ($my_endp_type eq "mc_udp") {
# For instance:
# add_endp mcast-xmit-eth1 1 3 eth1 mc_udp 9999 NO 9600 0 NO 1472 1472 INCREASING NO 32 0 0
# set_mc_endp mcast-xmit-eth1 32 224.9.9.9 9999 NO
# Assume Layer-3 for now
$cmd = $::utils->fmt_cmd("add_endp", $my_endp_name, 1, $my_resource,
$my_port_name, $my_endp_type, $::mcast_port, $::NA,
$my_speed, $my_max_speed, $::NA, $::min_pkt_sz,
$::max_pkt_sz, "increasing", $::use_csums, $::ttl, "0", "0");
$::utils->doCmd($cmd);
$cmd = $::utils->fmt_cmd("set_mc_endp", $::endp_name, $::ttl, $::mcast_addr, $::mcast_port, $::rcv_mcast);
$::utils->doCmd($cmd);
$cmd = "set_endp_report_timer $::endp_name $::report_timer";
$::utils->doCmd($cmd);
}
elsif (grep { $_ eq $my_endp_type} split(/,/, "lf_udp,lf_tcp,lf_udp6,lf_tcp6,NA")) {
if ($::use_ports_str ne "NA") {
($::port_name,) = split(',', $::use_ports_str);
}
die("Which port is this? --port_name")
if (!defined $::port_name || $port_name eq "" || $port_name eq "0" );
if ($::use_speeds_str ne "NA") {
($::speed,) = split(',', $::use_speeds_str);
}
die("Please set port speed: --speed")
if ($::speed eq "-1"|| $::speed eq $::NA);
if ($::min_pkt_sz =~ /^\s*auto\s*$/i) {
$::min_pkt_sz = "-1";
}
if ($::max_pkt_sz =~ /^\s*same\s*$/i ) {
$::max_pkt_sz = "0";
}
elsif ($::max_pkt_sz =~ /^\s*auto\s*$/i) {
$::max_pkt_sz = "-1";
}
# Assume Layer-3 for now
my $bursty = $::NA;
my $random_sz = $::NA;
my $payld_pat = "increasing";
$::ttl = $::NA;
my $bad_ppm = "0";
$cmd = $::utils->fmt_cmd("add_endp", $my_endp_name, 1, $my_resource,
$my_port_name, $my_endp_type, $::ip_port, $bursty,
$my_speed, $my_max_speed,
$random_sz, $::min_pkt_sz, $::max_pkt_sz,
$payld_pat, $::use_csums, $::ttl,
$bad_ppm, $::multicon);
$::utils->doCmd($cmd);
$cmd = "set_endp_report_timer $my_endp_name $::report_timer";
$::utils->doCmd($cmd);
if ($::tos ne "") {
my($service, $priority) = split(',', $::tos);
if (!$priority) {
$priority = "NA";
}
$::utils->doCmd("set_endp_tos $my_endp_name $service $priority");
}
}
else {
die( "ERROR: Endpoint type: $::endp_type is not currently supported.");
}
} # ~create_endp()
# ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
sub get_stats_from_file {
my $fname = shift;
my $endp_name = shift;
open(F, "<$fname") or die("Can't open $fname for reading: $!\n");
my $endp_text = "";
my $ep = "";
my @lines = ();
while ( my $line = <F>) {
@lines = (@lines, $line);
}
# Append dummy line to make it easier to terminate the parse logic.
@lines = (@lines, "Endpoint [________] (NOT_RUNNING)\n");
my $i;
for ($i = 0; $i<@lines;$i++) {
my $line = $lines[$i];
chomp($line);
if (($line =~ /Endpoint\s+\[(.*)\]/) ||
($line =~ /WanLink\s+\[(.*)\]/) ||
($line =~ /ArmEndp\s+\[(.*)\]/) ||
# TODO: Layer-4 ?
($line =~ /VoipEndp\s+\[(.*)\]/)) {
my $m1 = $1;
#print "Found starting line: $line name: $m1 endp_name: $endp_name\n";
if ($endp_text ne "") {
# See if existing endp entry matches?
if ($ep eq $endp_name) {
return $endp_text;
}
}
$endp_text = "$line\n";
$ep = $m1;
}
else {
if ($endp_text ne "") {
$endp_text .= "$line\n";
}
}
}
return "";
}