-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathlf_create_wanlink.py
More file actions
executable file
·758 lines (663 loc) · 45.9 KB
/
lf_create_wanlink.py
File metadata and controls
executable file
·758 lines (663 loc) · 45.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
#!/usr/bin/env python3
r"""
NAME: lf_create_wanlink.py
PURPOSE: Create and configure a LANforge WANLink used for network impairment.
NOTES: Underlying port IP addresses must be configured in order for wanlink endpoints
to become active.
EXAMPLE: # Duplicate configuration for both ends of the WANLink
./lf_create_wanlink.py \
--mgr <lanforge ip> \
--mgr_port <lanforge port usually 8080> \
--wl_name wanlink \
--port_A eth1 \
--port_B eth2 \
--speed 1024000 \
--latency 24 \
--max_jitter 50 \
--jitter_freq 6 \
--drop_freq 12 \
--log_level debug
# Mixed configuration, each end of WANLink has specific config
./lf_create_wanlink.py \
--mgr <lanforge ip> \
--mgr_port <lanforge port usually 8080> \
--wl_name wanlink \
--port_A eth1 \
--port_B eth2 \
--speed_A 1024000 \
--speed_B 2048000 \
--latency_A 24 \
--latency_B 32 \
--max_jitter 50 \
--jitter_freq 6 \
--drop_freq 12 \
--log_level debug
"""
import sys
import time
if sys.version_info[0] != 3:
print("This script requires Python3")
exit()
import importlib
import argparse
from pprint import pformat
import os
import logging
sys.path.append(os.path.join(os.path.abspath(__file__ + "../../../")))
lanforge_api = importlib.import_module("lanforge_client.lanforge_api")
LFUtils = importlib.import_module("py-json.LANforge.LFUtils")
from lanforge_client.lanforge_api import LFSession # noqa: 402
from lanforge_client.lanforge_api import LFJsonCommand # noqa: 402
from lanforge_client.lanforge_api import LFJsonQuery # noqa: 402
lf_logger_config = importlib.import_module("py-scripts.lf_logger_config")
logger = logging.getLogger(__name__)
# add_wanpath
# http://www.candelatech.com/lfcli_ug.php#add_wanpath
class lf_create_wanlink():
def __init__(self,
lf_mgr=None,
lf_port=None,
lf_user=None,
lf_passwd=None,
debug=False,
):
self.lf_mgr = lf_mgr
self.lf_port = lf_port
self.lf_user = lf_user
self.lf_passwd = lf_passwd
self.debug = debug
self.session = LFSession(lfclient_url="http://%s:8080" % self.lf_mgr,
debug=debug,
connection_timeout_sec=4.0,
stream_errors=True,
stream_warnings=True,
require_session=True,
exit_on_error=True)
# type hinting
self.command: LFJsonCommand
self.command = self.session.get_command()
self.query: LFJsonQuery
self.query = self.session.get_query()
# The order to creating an wanlink between two ethernet ports
# add_wl_endp
# add_cx
# set_wanlink_info side A
# set_endp_flag side A
# set_wanlink_info side B
# set_endp_flag side B
# verify set_wl_corruption side A - commented out
# verify set_wl_corruption side B - commented out
# nc_show_endpoints
# nc_show_endpoints
# query.get_wl
# query.get_wl_endp
def add_wl_endp(self,
_alias: str = None, # Name of endpoint. [R]
_cpu_id: str = None, # The CPU/thread that this process should run on
# (kernel-mode only).
_description: str = None, # Description for this endpoint, put in single quotes if
# it contains spaces.
_latency: str = None, # The latency (ms) that will be added to each packet
# entering this WanLink.
_max_rate: str = None, # Maximum transmit rate (bps) for this WanLink.
_port: str = None, # Port number. [W]
_resource: int = None, # Resource number. [W]
_shelf: int = 1, # Shelf name/id. [R][D:1]
_wle_flags: str = None, # WanLink Endpoint specific flags, see above.
_debug: bool = False,
_suppress_related_commands: bool = False):
if _alias is None:
logger.error("alias in None alias must be set to end point A or end point B. Exiting")
exit(1)
self.command.post_add_wl_endp(
alias=_alias, # Name of endpoint. [R]
cpu_id=_cpu_id, # The CPU/thread that this process should run on
# (kernel-mode only).
description=_description, # Description for this endpoint, put in single quotes if
# it contains spaces.
latency=_latency, # The latency (ms) that will be added to each packet
# entering this WanLink.
max_rate=_max_rate, # Maximum transmit rate (bps) for this WanLink.
port=_port, # Port number. [W]
resource=_resource, # Resource number. [W]
shelf=_shelf, # Shelf name/id. [R][D:1]
wle_flags=_wle_flags, # WanLink Endpoint specific flags, see above.
debug=self.debug,
suppress_related_commands=_suppress_related_commands)
def set_wanlink_info(self,
_drop_freq: str = None, # How often, out of 1,000,000 packets, should we
# purposefully drop a packet.
_dup_freq: str = None, # How often, out of 1,000,000 packets, should we
# purposefully duplicate a packet.
_extra_buffer: str = None, # The extra amount of bytes to buffer before
# dropping pkts, in units of 1024. Use -1 for AUTO.
_jitter_freq: str = None, # How often, out of 1,000,000 packets, should we
# apply jitter.
_latency: str = None, # The base latency added to all packets, in
# milliseconds (or add 'us' suffix for microseconds
_max_drop_amt: str = None, # Maximum amount of packets to drop in a row.
# Default is 1.
_max_jitter: str = None, # The maximum jitter, in milliseconds (or ad 'us'
# suffix for microseconds)
_max_lateness: str = None, # Maximum amount of un-intentional delay before pkt
# is dropped. Default is AUTO
_max_reorder_amt: str = None, # Maximum amount of packets by which to reorder,
# Default is 10.
_min_drop_amt: str = None, # Minimum amount of packets to drop in a row.
# Default is 1.
_min_reorder_amt: str = None, # Minimum amount of packets by which to reorder,
# Default is 1.
_name: str = None, # The name of the endpoint we are configuring. [R]
_playback_capture_file: str = None, # Name of the WAN capture file to play back.
_reorder_freq: str = None, # How often, out of 1,000,000 packets, should we
# make a packet out of order.
_speed: str = None, # The maximum speed of traffic this endpoint will
# accept (bps).
_debug: bool = False,
_suppress_related_commands: bool = False):
# the LANforge api will handle the None values
self.command.post_set_wanlink_info(
drop_freq=_drop_freq, # How often, out of 1,000,000 packets, should we
# purposefully drop a packet.
dup_freq=_dup_freq, # How often, out of 1,000,000 packets, should we
# purposefully duplicate a packet.
extra_buffer=_extra_buffer, # The extra amount of bytes to buffer before
# dropping pkts, in units of 1024. Use -1 for AUTO.
jitter_freq=_jitter_freq, # How often, out of 1,000,000 packets, should we
# apply jitter.
latency=_latency, # The base latency added to all packets, in
# milliseconds (or add 'us' suffix for microseconds
max_drop_amt=_max_drop_amt, # Maximum amount of packets to drop in a row.
# Default is 1.
max_jitter=_max_jitter, # The maximum jitter, in milliseconds (or ad 'us'
# suffix for microseconds)
max_lateness=_max_lateness, # Maximum amount of un-intentional delay before pkt
# is dropped. Default is AUTO
max_reorder_amt=_max_reorder_amt, # Maximum amount of packets by which to reorder,
# Default is 10.
min_drop_amt=_min_drop_amt, # Minimum amount of packets to drop in a row.
# Default is 1.
min_reorder_amt=_min_reorder_amt, # Minimum amount of packets by which to reorder,
# Default is 1.
name=_name, # The name of the endpoint we are configuring. [R]
playback_capture_file=_playback_capture_file, # Name of the WAN capture file to play back.
reorder_freq=_reorder_freq, # How often, out of 1,000,000 packets, should we
# make a packet out of order.
speed=_speed, # The maximum speed of traffic this endpoint will
# accept (bps).
debug=self.debug,
suppress_related_commands=_suppress_related_commands)
# set_endp_flag
def set_endp_flag(self,
_flag: str = None, # The name of the flag. [R]
_name: str = None, # The name of the endpoint we are configuring. [R]
_val: str = None, # Either 1 (for on), or 0 (for off). [R,0-1]
_suppress_related_commands: bool = False):
self.command.post_set_endp_flag(flag=_flag, # The name of the flag. [R]
name=_name, # The name of the endpoint we are configuring. [R]
val=_val, # Either 1 (for on), or 0 (for off). [R,0-1]
debug=self.debug,
suppress_related_commands=_suppress_related_commands)
def add_cx(self,
_alias=None,
_rx_endp=None, # endp_B
_tx_endp=None, # endp_A
_test_mgr="default_tm"):
self.command.post_add_cx(alias=_alias,
rx_endp=_rx_endp,
tx_endp=_tx_endp,
test_mgr=_test_mgr)
def get_wl(self,
_eid_list: list = None,
_requested_col_names: list = None,
_wait_sec: float = 0.01,
_timeout_sec: float = 5.0,
_errors_warnings: list = None):
result = None
ewarn_list = []
try:
result = self.query.get_wl(eid_list=_eid_list,
requested_col_names=_requested_col_names,
wait_sec=_wait_sec,
timeout_sec=_timeout_sec,
errors_warnings=ewarn_list,
debug=self.debug)
logger.debug(pformat(result))
except BaseException: # noqa: B036
logger.warning(pformat(ewarn_list))
return result
def get_wl_endp(self,
_eid_list: list = None,
_requested_col_names: list = None,
_wait_sec: float = 0.01,
_timeout_sec: float = 5.0,
_errors_warnings: list = None):
result = self.query.get_wl_endp(eid_list=_eid_list,
requested_col_names=_requested_col_names,
wait_sec=_wait_sec,
timeout_sec=_timeout_sec,
errors_warnings=_errors_warnings,
debug=self.debug)
logger.debug(pformat(result))
return result
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- #
# ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- #
def parse_args():
parser = argparse.ArgumentParser(
prog=__file__,
formatter_class=argparse.RawTextHelpFormatter,
description=r'''\
NAME: lf_create_wanlink.py
PURPOSE: Create and configure a LANforge WANLink used for network impairment.
NOTES: Underlying port IP addresses must be configured in order for wanlink endpoints
to become active
EXAMPLE: # Duplicate configuration for both ends of the WANLink
./lf_create_wanlink.py \
--wl_name wanlink \
--port_A eth1 \
--port_B eth2 \
--speed 1024000 \
--latency 24 \
--max_jitter 50 \
--jitter_freq 6 \
--drop_freq 12
# Mixed configuration, each end of WANLink has specific config
./lf_create_wanlink.py \
--wl_name wanlink \
--port_A eth1 \
--port_B eth2 \
--speed_A 1024000 \
--speed_B 2048000 \
--latency_A 24 \
--latency_B 32 \
--max_jitter 50 \
--jitter_freq 6 \
--drop_freq 12
''')
# http://www.candelatech.com/lfcli_ug.php#add_wl_endp
parser.add_argument("--host", "--mgr", dest='mgr', help='specify the GUI to connect to')
parser.add_argument("--mgr_port", help="specify the GUI to connect to, default 8080", default="8080")
parser.add_argument("--lf_user", help="lanforge user name default lanforge", default="lanforge")
parser.add_argument("--lf_passwd", help="lanforge password defualt lanforge ", default="lanforge")
parser.add_argument('--wl_name', '--alias', dest='wl_name', help='(add wl endp) The name of the endpoint we are configuring. [R] ')
parser.add_argument('--cpu_id', help="(add wl endp) The CPU/thread that this process should run on (kernel-mode only). Default = 'NA'", default='NA')
parser.add_argument('--description', help="(add wl endp) Description for this endpoint, put in single quotes if it contains spaces Default = 'NA'", default='NA')
parser.add_argument("--latency", help="(add wl endp) The latency (ms) that will be added to each packet entering this WanLink. Default = 'NA' both ports", default='NA')
parser.add_argument("--latency_A", "--latency_a", dest="latency_A",
help="(add wl endp) The latency (ms) that will be added to each packet entering this WanLink. Default = None port a", default=None)
parser.add_argument("--latency_B", "--latency_b", dest="latency_B",
help="(add wl endp) The latency (ms) that will be added to each packet entering this WanLink. Default = None port b", default=None)
parser.add_argument("--max_rate", help="(add wl endp) Use --speed parameter instead. Maximum transmit rate (bps) for this WanLink. Default = 1024000 ", default='1024000')
parser.add_argument("--max_rate_A", "--max_rate_a", dest="max_rate_A",
help="(add wl endp) Use --speed_A parameter instead. Maximum transmit rate (bps) for this WanLink. Default = None ", default=None)
parser.add_argument("--max_rate_B", "--max_rate_b", dest="max_rate_B",
help="(add wl endp) Use --speed_B parameter instead. Maximum transmit rate (bps) for this WanLink. Default = None ", default=None)
parser.add_argument('--port_A', "--port_a", dest='port_A', help='(add wl endp) Endpoint A', default="eth1")
parser.add_argument('--port_B', "--port_b", dest='port_B', help='(add wl endp) Endpoint B', default="eth2")
parser.add_argument("--resource", help='(add wl endp) LANforge resource Default', default=1)
parser.add_argument("--shelf", help='(add wl endp) LANforge Shelf name/id', default=1)
parser.add_argument("--wle_flags", help='(add wl endp) WanLink Endpoint specific flags, Default = 1, SHOW_WP = 1 .Show WanPaths in wanlink endpoint table in GUI', default=1)
# http://www.candelatech.com/lfcli_ug.php#set_wanlink_info
parser.add_argument('--drop_freq', help='(set wanlink info) How often, out of 1,000,000 packets, should we purposefully drop a packet. Default = 0 Both ports (%%)', default="0")
parser.add_argument('--drop_freq_A', '--drop_freq_a', dest='drop_freq_A',
help='(set wanlink info) How often, out of 1,000,000 packets, should we purposefully drop a packet. Default = None port A (%%)', default=None)
parser.add_argument('--drop_freq_B', '--drop_freq_b', dest='drop_freq_B',
help='(set wanlink info) How often, out of 1,000,000 packets, should we purposefully drop a packet. Default = None port B (%%)', default=None)
parser.add_argument('--dup_freq', help='(set wanlink info) How often, out of 1,000,000 packets, should we purposefully duplicate a packet. Default = 0 Both ports (%%)', default="0")
parser.add_argument('--dup_freq_A', '--dup_freq_a', dest='dup_freq_A',
help='(set wanlink info) How often, out of 1,000,000 packets, should we purposefully duplicate a packet. Default = None port A (%%)', default=None)
parser.add_argument('--dup_freq_B', "--dup_freq_b", dest='dup_freq_B',
help='(set wanlink info) How often, out of 1,000,000 packets, should we purposefully duplicate a packet. Default = None port B (%%)', default=None)
parser.add_argument('--extra_buffer', help='(set wanlink info) The extra amount of bytes to buffer before dropping pkts, in units of 1024. Use -1 for AUTO. Default = -1 Both ports (%%)', default="-1") # noqa E501
parser.add_argument('--extra_buffer_A', '--extra_buffer_a', dest='extra_buffer_A',
help='(set wanlink info) The extra amount of bytes to buffer before dropping pkts, in units of 1024. Use -1 for AUTO. Default = None port A (%%)', default=None) # noqa E501
parser.add_argument('--extra_buffer_B', '--extra_buffer_b', dest='extra_buffer_B',
help='(set wanlink info) The extra amount of bytes to buffer before dropping pkts, in units of 1024. Use -1 for AUTO. Default = None port B (%%)', default=None) # noqa E501
parser.add_argument('--jitter_freq', help='(set wanlink info) How often, out of 1,000,000 packets, should we apply jitter. Default = 0 both ports (%%)', default="0")
parser.add_argument('--jitter_freq_A', '--jitter_freq_a', dest='jitter_freq_A',
help='(set wanlink info) How often, out of 1,000,000 packets, should we apply jitter. Default = None port A (%%)', default=None)
parser.add_argument('--jitter_freq_B', '--jitter_freq_b', dest='jitter_freq_B',
help='(set wanlink info) How often, out of 1,000,000 packets, should we apply jitter. Default = None port B (%%)', default=None)
parser.add_argument('--latency_packet', help="(set wanlink info) The base latency added to all packets, in milliseconds (or add 'us' suffix for microseconds. Default = 20 both ports", default="20") # noqa E501
parser.add_argument('--latency_packet_A', '--latency_packet_a', dest='latency_packet_A',
help="(set wanlink info) The base latency added to all packets, in milliseconds (or add 'us' suffix for microseconds. Default = None port A", default=None) # noqa E501
parser.add_argument('--latency_packet_B', '--latency_packet_b', dest='latency_packet_B',
help="(set wanlink info) The base latency added to all packets, in milliseconds (or add 'us' suffix for microseconds. Default = None port B", default=None) # noqa E501
parser.add_argument('--max_drop_amt', help='(set wanlink info) Maximum amount of packets to drop in a row. Default is 1. both ports', default="1")
parser.add_argument('--max_drop_amt_A', '--max_drop_amt_a', dest='max_drop_amt_A',
help='(set wanlink info) Maximum amount of packets to drop in a row. Default is None. port A', default=None)
parser.add_argument('--max_drop_amt_B', '--max_drop_amt_b', dest='max_drop_amt_B',
help='(set wanlink info) Maximum amount of packets to drop in a row. Default is None. port B', default=None)
parser.add_argument('--max_jitter', help="(set wanlink info) The maximum jitter, in milliseconds (or ad 'us' suffix for microseconds) Default = 10 both ports (ms)", default="10")
parser.add_argument('--max_jitter_A', '--max_jitter_a', dest='max_jitter_A',
help="(set wanlink info) The maximum jitter, in milliseconds (or ad 'us' suffix for microseconds) port A (ms)", default=None)
parser.add_argument('--max_jitter_B', '--max_jitter_b', dest='max_jitter_B',
help="(set wanlink info) The maximum jitter, in milliseconds (or ad 'us' suffix for microseconds) port B (ms)", default=None)
parser.add_argument('--max_lateness', help='(set wanlink info) Maximum amount of un-intentional delay before pkt both ports (ms) is dropped. Default is AUTO both ports', default="AUTO")
parser.add_argument('--max_lateness_A', '--max_lateness_a', dest='max_lateness_A',
help='(set wanlink info) Maximum amount of un-intentional delay before pkt both ports (ms) is dropped. Default is AUTO port A', default=None)
parser.add_argument('--max_lateness_B', '--max_lateness_b', dest='max_lateness_B',
help='(set wanlink info) Maximum amount of un-intentional delay before pkt both ports (ms) is dropped. Default is AUTO port B', default=None)
parser.add_argument('--max_reorder_amt', help='(set wanlink info) Maximum amount of packets by which to reorder, Default is 10. both ports (ms)', default="10")
parser.add_argument('--max_reorder_amt_A', '--max_reorder_amt_a', dest='max_reorder_amt_A',
help='(set wanlink info) Maximum amount of packets by which to reorder, Default is 10. both ports (ms) port A (ms)', default=None)
parser.add_argument('--max_reorder_amt_B', '--max_reorder_amt_b', dest='max_reorder_amt_B',
help='(set wanlink info) Maximum amount of packets by which to reorder, Default is 10. both ports (ms) port B (ms)', default=None)
parser.add_argument('--min_drop_amt', help='(set wanlink info) Minimum amount of packets to drop in a row. Default is 1. both ports (ms)', default="1")
parser.add_argument('--min_drop_amt_A', '--min_drop_amt_a', dest='min_drop_amt_A',
help='(set wanlink info) Minimum amount of packets to drop in a row. Default is 1. both ports (ms) port A (ms)', default=None)
parser.add_argument('--min_drop_amt_B', '--min_drop_amt_b', dest='min_drop_amt_B',
help='(set wanlink info) Minimum amount of packets to drop in a row. Default is 1. both ports (ms) port B (ms)', default=None)
parser.add_argument('--min_reorder_amt', help='(set wanlink info) Minimum amount of packets by which to reorder, Default is 1. both ports ', default="1")
parser.add_argument('--min_reorder_amt_A', '--min_reorder_amt_a', dest='min_reorder_amt_A',
help='(set wanlink info) Minimum amount of packets by which to reorder, Default is 1. port A', default=None)
parser.add_argument('--min_reorder_amt_B', '--min_reorder_amt_b', dest='min_reorder_amt_B',
help='(set wanlink info) Minimum amount of packets by which to reorder, Default is 1. port B', default=None)
parser.add_argument('--playback_capture_file', help='(set wanlink info) Name of the WAN capture file to play back. Default = None', default=None)
parser.add_argument('--reorder_freq', help='(set wanlink info) How often, out of 1,000,000 packets, should we make a packet out of order. both ports Default = None', default=None)
parser.add_argument('--reorder_freq_A', '--reorder_freq_a', dest='reorder_freq_A',
help='(set wanlink info) How often, out of 1,000,000 packets, should we make a packet out of order. port A Default = None', default=None)
parser.add_argument('--reorder_freq_B', '--reorder_freq_b', dest='reorder_freq_B',
help='(set wanlink info) How often, out of 1,000,000 packets, should we make a packet out of order. port B Default = None', default=None)
parser.add_argument('--speed', help='(set wanlink info) Use this instead of max_rate. The maximum speed of traffic this endpoint will accept (bps). both ports', default=1000000)
parser.add_argument('--speed_A', '--speed_a', dest='speed_A',
help='(set wanlink info) Use this instead of max_rate_A. The maximum speed of traffic this endpoint will accept (bps). port A', default=None)
parser.add_argument('--speed_B', '--speed_b', dest='speed_B',
help='(set wanlink info) Use this instead of max_rate_B. The maximum speed of traffic this endpoint will accept (bps). port B', default=None)
parser.add_argument('--drop_nth_pkt', help='(set wanlink info) drop packets at every Nth received packet', default=None)
parser.add_argument('--drop_nth_pkt_A', '--drop_nth_pkt_a', dest='drop_nth_pkt_A',
help='(set wanlink info) drop packets at every Nth received packet, port A', default=None)
parser.add_argument('--drop_nth_pkt_B', '--drop_nth_pkt_b', dest='drop_nth_pkt_B',
help='(set wanlink info) drop packets at every Nth received packet, port B', default=None)
parser.add_argument('--suppress_related_commands', help='(set wanlink info) Used by lanforge_api Default False if set store true', action='store_true')
# Set Endp Flags enable KernelMode
parser.add_argument('--kernel_mode', help='(set endp flag) Select kernel-mode Wanlinks, must be the same for both endpoint sets both ports, Default = False', action='store_true')
parser.add_argument('--pass_through_mode', help='''
(set endp flag) pass-through means disable all impairments and slow-downs, without having to manually zero out all of the impairments. Good way to turn it on/off without stopping traffic.,
Default = False', action='store_true'
''', action='store_true')
# Logging Configuration
parser.add_argument('--log_level', default=None, help='Set logging level: debug | info | warning | error | critical')
parser.add_argument("--lf_logger_config_json", help="--lf_logger_config_json <json file> , json configuration of logger")
parser.add_argument('--debug', help='Legacy debug flag', action='store_true')
# Help Summary
parser.add_argument('--help_summary', default=None, action="store_true", help='Show summary of what this script does')
return parser.parse_args()
def main():
args = parse_args()
help_summary = "This script creates a wanlink using the lanforge api."
if args.help_summary:
print(help_summary)
exit(0)
# set up logger
logger_config = lf_logger_config.lf_logger_config()
# set the logger level to debug
if args.log_level:
logger_config.set_level(level=args.log_level)
# lf_logger_config_json will take presidence to changing debug levels
if args.lf_logger_config_json:
# logger_config.lf_logger_config_json = "lf_logger_config.json"
logger_config.lf_logger_config_json = args.lf_logger_config_json
logger_config.load_lf_logger_config()
if not args.wl_name:
logger.error("--wl_name/--alias required arguments")
exit(1)
# The order to creating an wanlink between two ethernet ports
# add_wl_endp
# add_cx
# set_wanlink_info side A
# set_endp_flag side A
# set_wanlink_info side B
# set_endp_flag side B
wanlink = lf_create_wanlink(lf_mgr=args.mgr,
lf_port=8080,
lf_user=args.lf_user,
lf_passwd=args.lf_passwd,
debug=True)
# parameters for add_wl_endp
# alias
endp_A = args.wl_name + "-A"
endp_B = args.wl_name + "-B"
latency_A = args.latency_A if args.latency_A is not None else args.latency
latency_B = args.latency_B if args.latency_B is not None else args.latency
max_rate_A = args.max_rate_A if args.max_rate_A is not None else args.max_rate
max_rate_B = args.max_rate_B if args.max_rate_B is not None else args.max_rate
# parameters for set_wanlink_info
drop_freq_A = args.drop_freq_A if args.drop_freq_A is not None else args.drop_freq
drop_freq_B = args.drop_freq_B if args.drop_freq_B is not None else args.drop_freq
dup_freq_A = args.dup_freq_A if args.dup_freq_A is not None else args.dup_freq
dup_freq_B = args.dup_freq_B if args.dup_freq_B is not None else args.dup_freq
extra_buffer_A = args.extra_buffer_A if args.extra_buffer_A is not None else args.extra_buffer
extra_buffer_B = args.extra_buffer_B if args.extra_buffer_B is not None else args.extra_buffer
jitter_freq_A = args.jitter_freq_A if args.jitter_freq_A is not None else args.jitter_freq
jitter_freq_B = args.jitter_freq_B if args.jitter_freq_B is not None else args.jitter_freq
latency_packet_A = args.latency_packet_A if args.latency_packet_A is not None else args.latency_packet
latency_packet_B = args.latency_packet_B if args.latency_packet_B is not None else args.latency_packet
max_drop_amt_A = args.max_drop_amt_A if args.max_drop_amt_A is not None else args.max_drop_amt
max_drop_amt_B = args.max_drop_amt_B if args.max_drop_amt_B is not None else args.max_drop_amt
max_jitter_A = args.max_jitter_A if args.max_jitter_A is not None else args.max_jitter
max_jitter_B = args.max_jitter_B if args.max_jitter_B is not None else args.max_jitter
max_lateness_A = args.max_lateness_A if args.max_lateness_A is not None else args.max_lateness
max_lateness_B = args.max_lateness_B if args.max_lateness_B is not None else args.max_lateness
max_reorder_amt_A = args.max_reorder_amt_A if args.max_reorder_amt_A is not None else args.max_reorder_amt
max_reorder_amt_B = args.max_reorder_amt_B if args.max_reorder_amt_B is not None else args.max_reorder_amt
min_drop_amt_A = args.min_drop_amt_A if args.min_drop_amt_A is not None else args.min_drop_amt
min_drop_amt_B = args.min_drop_amt_B if args.min_drop_amt_B is not None else args.min_drop_amt
min_reorder_amt_A = args.min_reorder_amt_A if args.min_reorder_amt_A is not None else args.min_reorder_amt
min_reorder_amt_B = args.min_reorder_amt_B if args.min_reorder_amt_B is not None else args.min_reorder_amt
reorder_freq_A = args.reorder_freq_A if args.reorder_freq_A is not None else args.reorder_freq
reorder_freq_B = args.reorder_freq_B if args.reorder_freq_B is not None else args.reorder_freq
speed_A = args.speed_A if args.speed_A is not None else args.speed
speed_B = args.speed_B if args.speed_B is not None else args.speed
drop_nth_pkt_A = args.drop_nth_pkt_A if args.drop_nth_pkt_A is not None else args.drop_nth_pkt
drop_nth_pkt_B = args.drop_nth_pkt_B if args.drop_nth_pkt_B is not None else args.drop_nth_pkt
# Comment out some parameters like 'max_jitter', 'drop_freq' and 'wanlink'
# in order to view the X-Errors headers
logger.info(
f"drop_freq_A:{drop_freq_A}, drop_freq_B:{drop_freq_B}, min_drop_amt_A:{min_drop_amt_A}, min_drop_amt_B:{min_drop_amt_B},"
f" drop_nth_pkt_A:{drop_nth_pkt_A}, drop_nth_pkt_B:{drop_nth_pkt_B}")
# have to determine if the wanlink exists and is running or not
wl_exists = False
wl_running = False
result = None
ewarns = []
try:
result = wanlink.query.get_wl(eid_list=args.wl_name,
requested_col_names=("name", "eid"),
debug=args.debug,
_errors_warnings=ewarns)
except BaseException: # noqa: B036
logger.warning(ewarns)
wl_exists = (False, True)[result is not None]
if wl_exists:
logger.debug(pformat(result))
wl_running = (False, True)[result["state"] == "Run"]
logger.warning(f"running? {wl_running}")
if wl_running:
wanlink.command.post_set_cx_state(cx_name=args.wl_name,
cx_state='STOPPED',
test_mgr='all',
debug=args.debug)
for _ in range(1, 60):
result = wanlink.query.get_wl(eid_list=args.wl_name,
requested_col_names=("name", "eid", "running"),
debug=False)
if result["state"] == "Stopped":
break
time.sleep(1)
if result["state"] == "Running":
raise ValueError("WANLink is still running, does not respond to set_cx_state STOPPED")
# create side A
wanlink.add_wl_endp(_alias=endp_A, # Name of endpoint. [R]
_cpu_id=args.cpu_id, # The CPU/thread that this process should run on (kernel-mode only).
_description=args.description, # Description for this endpoint, put in single quotes if it contains spaces.
_latency=latency_A, # The latency (ms) that will be added to each packet entering this WanLink.
_max_rate=max_rate_A, # Maximum transmit rate (bps) for this WanLink.
_port=args.port_A, # Port number. [W]
_resource=args.resource, # Resource number. [W]
_shelf=args.shelf, # Shelf name/id. [R][D:1]
_wle_flags=args.wle_flags, # WanLink Endpoint specific flags, see above.
_suppress_related_commands=args.suppress_related_commands)
# endp B
wanlink.add_wl_endp(_alias=endp_B, # Name of endpoint. [R]
_cpu_id=args.cpu_id, # The CPU/thread that this process should run on (kernel-mode only).
_description=args.description, # Description for this endpoint, put in single quotes if it contains spaces.
_latency=latency_B, # The latency (ms) that will be added to each packet entering this WanLink.
_max_rate=max_rate_B, # Maximum transmit rate (bps) for this WanLink.
_port=args.port_B, # Port number. [W]
_resource=args.resource, # Resource number. [W]
_shelf=args.shelf, # Shelf name/id. [R][D:1]
_wle_flags=args.wle_flags, # WanLink Endpoint specific flags, see above.
_suppress_related_commands=args.suppress_related_commands)
# we cannot do an add_cx on top of an existing wanlink
if wl_exists:
print(f"found wanlink {args.wl_name}, so endpoints are updated")
else:
result = wanlink.add_cx(_alias=args.wl_name,
_rx_endp=endp_B,
_tx_endp=endp_A,
_test_mgr="default_tm")
logger.info(f"updated wanlink {args.wl_name}")
logger.debug(pformat(result))
# set_wanlink_info A
if drop_nth_pkt_A:
drop_freq_A = drop_nth_pkt_A
wanlink.set_wanlink_info(_drop_freq=drop_freq_A, # How often, out of 1,000,000 packets, should we
# purposefully drop a packet.
_dup_freq=dup_freq_A, # How often, out of 1,000,000 packets, should we
# purposefully duplicate a packet.
_extra_buffer=extra_buffer_A, # The extra amount of bytes to buffer before
# dropping pkts, in units of 1024. Use -1 for AUTO.
_jitter_freq=jitter_freq_A, # How often, out of 1,000,000 packets, should we
# apply jitter.
_latency=latency_packet_A, # The base latency added to all packets, in
# milliseconds (or add 'us' suffix for microseconds
_max_drop_amt=max_drop_amt_A, # Maximum amount of packets to drop in a row.
# Default is 1.
_max_jitter=max_jitter_A, # The maximum jitter, in milliseconds (or ad 'us'
# suffix for microseconds)
_max_lateness=max_lateness_A, # Maximum amount of un-intentional delay before pkt
# is dropped. Default is AUTO
_max_reorder_amt=max_reorder_amt_A, # Maximum amount of packets by which to reorder,
# Default is 10.
_min_drop_amt=min_drop_amt_A, # Minimum amount of packets to drop in a row.
# Default is 1.
_min_reorder_amt=min_reorder_amt_A, # Minimum amount of packets by which to reorder,
# Default is 1.
_name=endp_A, # The name of the endpoint we are configuring. [R]
_playback_capture_file=args.playback_capture_file, # Name of the WAN capture file to play back.
_reorder_freq=reorder_freq_A, # How often, out of 1,000,000 packets, should we
# make a packet out of order.
_speed=speed_A, # The maximum speed of traffic this endpoint will
# accept (bps).
_debug=args.debug,
_suppress_related_commands=args.suppress_related_commands)
if drop_nth_pkt_A:
wanlink.set_endp_flag(_name=endp_A,
_flag=wanlink.command.SetEndpFlagFlag.DropXthPkt.value,
_val=1,
_suppress_related_commands=args.suppress_related_commands)
if drop_nth_pkt_B:
wanlink.set_endp_flag(_name=endp_B,
_flag=wanlink.command.SetEndpFlagFlag.DropXthPkt.value,
_val=1,
_suppress_related_commands=args.suppress_related_commands)
if args.kernel_mode:
wanlink.set_endp_flag(_name=endp_A,
_flag=wanlink.command.SetEndpFlagFlag.KernelMode.value,
_val=1,
_suppress_related_commands=args.suppress_related_commands)
else:
wanlink.set_endp_flag(_name=endp_A,
_flag=wanlink.command.SetEndpFlagFlag.KernelMode.value,
_val=0,
_suppress_related_commands=args.suppress_related_commands)
if args.pass_through_mode:
wanlink.set_endp_flag(_name=endp_A,
_flag='PassthroughMode',
_val=1,
_suppress_related_commands=args.suppress_related_commands)
else:
wanlink.set_endp_flag(_name=endp_A,
_flag='PassthroughMode',
_val=0,
_suppress_related_commands=args.suppress_related_commands)
# set_wanlink_info B
if drop_nth_pkt_B:
drop_freq_B = drop_nth_pkt_B
wanlink.set_wanlink_info(_drop_freq=drop_freq_B, # How often, out of 1,000,000 packets, should we
# purposefully drop a packet.
_dup_freq=dup_freq_B, # How often, out of 1,000,000 packets, should we
# purposefully duplicate a packet.
_extra_buffer=extra_buffer_B, # The extra amount of bytes to buffer before
# dropping pkts, in units of 1024. Use -1 for AUTO.
_jitter_freq=jitter_freq_B, # How often, out of 1,000,000 packets, should we
# apply jitter.
_latency=latency_packet_B, # The base latency added to all packets, in
# milliseconds (or add 'us' suffix for microseconds
_max_drop_amt=max_drop_amt_B, # Maximum amount of packets to drop in a row.
# Default is 1.
_max_jitter=max_jitter_B, # The maximum jitter, in milliseconds (or ad 'us'
# suffix for microseconds)
_max_lateness=max_lateness_B, # Maximum amount of un-intentional delay before pkt
# is dropped. Default is AUTO
_max_reorder_amt=max_reorder_amt_B, # Maximum amount of packets by which to reorder,
# Default is 10.
_min_drop_amt=min_drop_amt_B, # Minimum amount of packets to drop in a row.
# Default is 1.
_min_reorder_amt=min_reorder_amt_B, # Minimum amount of packets by which to reorder,
# Default is 1.
_name=endp_B, # The name of the endpoint we are configuring. [R]
_playback_capture_file=args.playback_capture_file, # Name of the WAN capture file to play back.
_reorder_freq=reorder_freq_B, # How often, out of 1,000,000 packets, should we
# make a packet out of order.
_speed=speed_B, # The maximum speed of traffic this endpoint will
# accept (bps).
_debug=args.debug,
_suppress_related_commands=args.suppress_related_commands)
if args.kernel_mode:
wanlink.set_endp_flag(_name=endp_B,
_flag=wanlink.command.SetEndpFlagFlag.KernelMode.value,
_val=1,
_suppress_related_commands=args.suppress_related_commands)
else:
wanlink.set_endp_flag(_name=endp_B,
_flag=wanlink.command.SetEndpFlagFlag.KernelMode.value,
_val=0,
_suppress_related_commands=args.suppress_related_commands)
if args.pass_through_mode:
wanlink.set_endp_flag(_name=endp_B,
_flag='PassthroughMode',
_val=1,
_suppress_related_commands=args.suppress_related_commands)
else:
wanlink.set_endp_flag(_name=endp_B,
_flag='PassthroughMode',
_val=0,
_suppress_related_commands=args.suppress_related_commands)
if wl_running:
wanlink.command.post_set_cx_state(cx_name=args.wl_name,
cx_state='RUNNING',
test_mgr='all',
debug=args.debug)
wanlink.command.post_nc_show_endpoints(endpoint=endp_A,
debug=args.debug,
suppress_related_commands=args.suppress_related_commands)
wanlink.command.post_nc_show_endpoints(endpoint=endp_B,
debug=args.debug,
suppress_related_commands=args.suppress_related_commands)
eid_list = [args.wl_name]
ewarn_list = []
result = wanlink.get_wl(_eid_list=eid_list,
_wait_sec=0.2,
_timeout_sec=2.0,
_errors_warnings=ewarn_list)
logger.debug(pformat(result))
eid_list = [endp_A, endp_B]
result = wanlink.get_wl_endp(_eid_list=eid_list,
_wait_sec=0.2,
_timeout_sec=2.0,
_errors_warnings=ewarn_list)
logger.debug(pformat(result))
if __name__ == "__main__":
main()