forked from openvswitch/ovs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathofproto-dpif.at
11690 lines (9939 loc) · 564 KB
/
ofproto-dpif.at
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
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
AT_BANNER([ofproto-dpif])
m4_divert_push([PREPARE_TESTS])
# Helper function to check the spread of dp_hash flows over buckets in the datapath
check_dpflow_stats () {
min_flows=$1
min_buckets=$2
dpflows=`cat`
if [[ $# -eq 3 ]]; then
echo "$dpflows" | grep "actions:hash"
n_flows=`echo "$dpflows" | grep -c dp_hash`
n_buckets=`echo "$dpflows" | grep dp_hash | grep -o "actions:[[0-9]]*" | sort | uniq -c | wc -l`
else
n_flows=`echo "$dpflows" | wc -l`
n_buckets=`echo "$dpflows" | grep -o "actions:[[0-9]]*" | sort | uniq -c | wc -l`
fi
if [[ $n_flows -ge $min_flows ]]; then flows=ok; else flows=nok; fi
if [[ $n_buckets -ge $min_buckets ]]; then buckets=ok; else buckets=nok; fi
echo "n_flows=$flows n_buckets=$buckets"
}
m4_divert_pop([PREPARE_TESTS])
AT_SETUP([ofproto-dpif - revalidator/wait])
OVS_VSWITCHD_START
AT_CHECK([ovs-appctl revalidator/wait])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - lldp revalidator event(REV_RECONFIGURE)])
OVS_VSWITCHD_START(
[add-port br0 p1 -- set interface p1 ofport_request=1 type=dummy]
)
dnl first revalidation triggered by add interface
AT_CHECK([ovs-appctl coverage/read-counter rev_reconfigure], [0], [dnl
1
])
dnl enable lldp
AT_CHECK([ovs-vsctl set interface p1 lldp:enable=true])
AT_CHECK([ovs-appctl revalidator/wait])
AT_CHECK([ovs-appctl coverage/read-counter rev_reconfigure], [0], [dnl
2
])
dnl disable lldp
AT_CHECK([ovs-vsctl set interface p1 lldp:enable=false])
AT_CHECK([ovs-appctl revalidator/wait])
AT_CHECK([ovs-appctl coverage/read-counter rev_reconfigure], [0], [dnl
3
])
dnl remove lldp, no revalidation as lldp was disabled
AT_CHECK([ovs-vsctl remove interface p1 lldp enable])
AT_CHECK([ovs-appctl revalidator/wait])
AT_CHECK([ovs-appctl coverage/read-counter rev_reconfigure], [0], [dnl
3
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - active-backup bonding (with primary)])
dnl Create br0 with members p1, p2 and p7, creating bond0 with p1 and
dnl p2 (p1 as primary) and br1 with members p3, p4 and p8.
dnl toggle p1,p2 of bond0 up and down to test bonding in active-backup mode.
dnl With p1 down and p2 up/active, bring p1 back up. Since p1 is the primary,
dnl it should become active.
OVS_VSWITCHD_START(
[add-bond br0 bond0 p1 p2 bond_mode=active-backup \
other_config:bond-primary=p1 -- \
set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 -- \
add-port br0 p7 -- set interface p7 ofport_request=7 type=dummy -- \
add-br br1 -- \
set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
fail-mode=secure -- \
add-port br1 p3 -- set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=3 -- \
add-port br1 p4 -- set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 -- \
add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --])
AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
WAIT_FOR_DUMMY_PORTS([p3], [p4])
OVS_WAIT_UNTIL([test -n "`ovs-appctl bond/show | grep 'active-backup primary: p1'`"])
AT_CHECK([ovs-ofctl add-flow br0 action=normal])
AT_CHECK([ovs-ofctl add-flow br1 action=normal])
ovs-appctl netdev-dummy/set-admin-state up
ovs-appctl time/warp 100
ovs-appctl netdev-dummy/set-admin-state p2 down
ovs-appctl time/stop
ovs-appctl time/warp 100
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
ovs-appctl time/warp 100
ovs-appctl netdev-dummy/set-admin-state p2 up
ovs-appctl netdev-dummy/set-admin-state p1 down
ovs-appctl time/warp 100
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0d),eth_type(0x0800),ipv4(src=10.0.0.5,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0e),eth_type(0x0800),ipv4(src=10.0.0.6,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
ovs-appctl time/warp 2000 100
AT_CHECK([ovs-appctl dpctl/dump-flows | grep 'in_port([[348]])' | strip_xout], [0], [dnl
recirc_id(0),in_port(3),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(3),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0d),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0e),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8035), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8035), packets:0, bytes:0, used:never, actions: <del>
])
ovs-appctl netdev-dummy/set-admin-state p1 up
ovs-appctl time/warp 100
OVS_WAIT_UNTIL_EQUAL([ovs-appctl bond/show | STRIP_RECIRC_ID | STRIP_ACTIVE_MEMBER_MAC], [dnl
---- bond0 ----
bond_mode: active-backup
bond may use recirculation: no, <del>
bond-hash-basis: 0
lb_output action: disabled, bond-id: -1
updelay: 0 ms
downdelay: 0 ms
lacp_status: off
lacp_fallback_ab: false
active-backup primary: p1
<active member mac del>
member p1: enabled
active member
may_enable: true
member p2: enabled
may_enable: true
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - active-backup bonding (primary validation)])
dnl Make a switch with 3 ports in a bond, so that when we delete one of
dnl the ports from the bond, there are still 2 ports left and the bond
dnl remains functional.
OVS_VSWITCHD_START(
[add-bond br0 bond0 p1 p2 p3 bond_mode=active-backup \
other_config:bond-primary=p1 -- \
set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 -- \
set interface p3 type=dummy options:pstream=punix:$OVS_RUNDIR/p3.sock ofport_request=3 -- \
add-port br0 p7 -- set interface p7 ofport_request=7 type=dummy --])
AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
dnl Make sure the initial primary member is set
OVS_WAIT_UNTIL([test -n "`ovs-appctl bond/show | grep 'active-backup primary: p1'`"])
dnl Down the primary member and verify that we switched. Then
dnl bring the primary back and verify that we switched back to the
dnl primary.
ovs-appctl netdev-dummy/set-admin-state p1 down
ovs-appctl time/warp 100
OVS_WAIT_UNTIL([test -n "`ovs-appctl bond/show | fgrep 'member p1: disabled'`"])
ovs-appctl netdev-dummy/set-admin-state p1 up
ovs-appctl time/warp 100
OVS_WAIT_UNTIL_EQUAL([ovs-appctl bond/show | STRIP_RECIRC_ID | STRIP_ACTIVE_MEMBER_MAC], [dnl
---- bond0 ----
bond_mode: active-backup
bond may use recirculation: no, <del>
bond-hash-basis: 0
lb_output action: disabled, bond-id: -1
updelay: 0 ms
downdelay: 0 ms
lacp_status: off
lacp_fallback_ab: false
active-backup primary: p1
<active member mac del>
member p1: enabled
active member
may_enable: true
member p2: enabled
may_enable: true
member p3: enabled
may_enable: true
])
dnl Now delete the primary and verify that the output shows that the
dnl primary is no longer an member
ovs-vsctl --id=@p1 get Interface p1 -- remove Port bond0 interfaces @p1
ovs-appctl time/warp 100
OVS_WAIT_UNTIL([test -n "`ovs-appctl bond/show | fgrep 'active-backup primary: p1 (no such member)'`"])
dnl Now re-add the primary and verify that the output shows that the
dnl primary is available again.
dnl
dnl First, get the UUIDs of the members that exist on bond0.
dnl Strip the trailing ] so that we can add a new UUID to the end.
uuids=`ovs-vsctl get Port bond0 interfaces | sed -e 's/]//'`
dnl Create a new port "p1" and add its UUID to the set of members
dnl on bond0.
ovs-vsctl \
--id=@p1 create Interface name=p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
set Port bond0 interfaces="$uuids, @p1]"
ovs-appctl time/warp 100
OVS_WAIT_UNTIL_EQUAL([ovs-appctl bond/show | STRIP_RECIRC_ID | STRIP_ACTIVE_MEMBER_MAC], [dnl
---- bond0 ----
bond_mode: active-backup
bond may use recirculation: no, <del>
bond-hash-basis: 0
lb_output action: disabled, bond-id: -1
updelay: 0 ms
downdelay: 0 ms
lacp_status: off
lacp_fallback_ab: false
active-backup primary: p1
<active member mac del>
member p1: enabled
active member
may_enable: true
member p2: enabled
may_enable: true
member p3: enabled
may_enable: true
])
dnl Switch to another primary
ovs-vsctl set port bond0 other_config:bond-primary=p2
ovs-appctl time/warp 100
OVS_WAIT_UNTIL_EQUAL([ovs-appctl bond/show | STRIP_RECIRC_ID | STRIP_ACTIVE_MEMBER_MAC], [dnl
---- bond0 ----
bond_mode: active-backup
bond may use recirculation: no, <del>
bond-hash-basis: 0
lb_output action: disabled, bond-id: -1
updelay: 0 ms
downdelay: 0 ms
lacp_status: off
lacp_fallback_ab: false
active-backup primary: p2
<active member mac del>
member p1: enabled
may_enable: true
member p2: enabled
active member
may_enable: true
member p3: enabled
may_enable: true
])
dnl Remove the "bond-primary" config directive from the bond.
AT_CHECK([ovs-vsctl remove Port bond0 other_config bond-primary])
ovs-appctl time/warp 100
OVS_WAIT_UNTIL_EQUAL([ovs-appctl bond/show | STRIP_RECIRC_ID | STRIP_ACTIVE_MEMBER_MAC], [dnl
---- bond0 ----
bond_mode: active-backup
bond may use recirculation: no, <del>
bond-hash-basis: 0
lb_output action: disabled, bond-id: -1
updelay: 0 ms
downdelay: 0 ms
lacp_status: off
lacp_fallback_ab: false
active-backup primary: <none>
<active member mac del>
member p1: enabled
may_enable: true
member p2: enabled
active member
may_enable: true
member p3: enabled
may_enable: true
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - active-backup bonding (without primary)])
dnl Create br0 with members p1, p2 and p7, creating bond0 with p1 and p2
dnl and br1 with members p3, p4 and p8.
dnl toggle p1,p2 of bond0 up and down to test bonding in active-backup mode.
OVS_VSWITCHD_START(
[add-bond br0 bond0 p1 p2 bond_mode=active-backup --\
set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 -- \
add-port br0 p7 -- set interface p7 ofport_request=7 type=dummy -- \
add-br br1 -- \
set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
fail-mode=secure -- \
add-port br1 p3 -- set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=3 -- \
add-port br1 p4 -- set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 -- \
add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --])
AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
WAIT_FOR_DUMMY_PORTS([p3], [p4])
OVS_WAIT_UNTIL([test -n "`ovs-appctl bond/show | grep 'active-backup primary: <none>'`"])
AT_CHECK([ovs-ofctl add-flow br0 action=normal])
AT_CHECK([ovs-ofctl add-flow br1 action=normal])
ovs-appctl netdev-dummy/set-admin-state up
ovs-appctl time/warp 100
ovs-appctl netdev-dummy/set-admin-state p2 down
ovs-appctl time/stop
ovs-appctl time/warp 100
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
ovs-appctl time/warp 100
ovs-appctl netdev-dummy/set-admin-state p2 up
ovs-appctl netdev-dummy/set-admin-state p1 down
ovs-appctl time/warp 100
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0d),eth_type(0x0800),ipv4(src=10.0.0.5,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0e),eth_type(0x0800),ipv4(src=10.0.0.6,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
ovs-appctl time/warp 2000 100
AT_CHECK([ovs-appctl dpctl/dump-flows | grep 'in_port([[348]])' | strip_xout], [0], [dnl
recirc_id(0),in_port(3),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(3),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0d),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0e),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8035), packets:0, bytes:0, used:never, actions: <del>
recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8035), packets:0, bytes:0, used:never, actions: <del>
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - balance-slb bonding])
# Create br0 with members bond0(p1, p2, p3) and p7,
# and br1 with members p4, p5, p6 and p8.
# p1 <-> p4, p2 <-> p5, p3 <-> p6
# Send some traffic, make sure the traffic are spread based on source mac.
OVS_VSWITCHD_START(
[add-bond br0 bond0 p1 p2 p3 bond_mode=balance-slb --\
set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 -- \
set interface p3 type=dummy options:pstream=punix:$OVS_RUNDIR/p3.sock ofport_request=3 -- \
add-port br0 p7 -- set interface p7 ofport_request=7 type=dummy -- \
add-br br1 -- \
set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
fail-mode=secure -- \
add-port br1 p4 -- set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=4 -- \
add-port br1 p5 -- set interface p5 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=5 -- \
add-port br1 p6 -- set interface p6 type=dummy options:stream=unix:$OVS_RUNDIR/p3.sock ofport_request=6 -- \
add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --])
WAIT_FOR_DUMMY_PORTS([p4], [p5], [p6])
AT_CHECK([ovs-ofctl add-flow br0 action=normal])
AT_CHECK([ovs-ofctl add-flow br1 action=normal])
AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK
])
ovs-appctl time/stop
ovs-appctl time/warp 100
(
for i in `seq 0 100 |xargs printf '%02x\n'`;
do
pkt="in_port(7),eth(src=50:54:00:00:00:$i,dst=50:54:00:00:01:00),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)"
AT_CHECK([ovs-appctl netdev-dummy/receive p7 $pkt])
done
)
ovs-appctl time/warp 100
AT_CHECK([ovs-appctl dpif/dump-flows br1 > br1_flows.txt])
# Make sure there is resonable distribution to all three ports.
# We don't want to make this check precise, in case hash function changes.
AT_CHECK([test `egrep 'in_port\(4\)' br1_flows.txt |wc -l` -gt 3])
AT_CHECK([test `egrep 'in_port\(5\)' br1_flows.txt |wc -l` -gt 3])
AT_CHECK([test `egrep 'in_port\(6\)' br1_flows.txt |wc -l` -gt 3])
OVS_VSWITCHD_STOP
AT_CLEANUP
# SEND_TCP_BOND_PKTS([p_name], [p_ofport], [packet_len])
#
# Sends 256 packets to port 'p_name' with different TCP destination ports.
m4_define([SEND_TCP_BOND_PKTS],
[
len_cmd=""
if test -n "$3"; then
len_cmd=" --len $3"
fi
for i in `seq 0 255`; do
pkt="in_port($2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:01:00),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=$i),tcp_flags(ack)"
ovs-appctl netdev-dummy/receive $1 $pkt$len_cmd
done
]
)
AT_SETUP([ofproto-dpif - balance-tcp bonding])
# Create br0 with members bond0(p1, p2, p3) and p7,
# and br1 with members bond1(p4, p5, p6) and p8.
# bond0 <-> bond1
# Send some traffic, make sure the traffic are spread based on L4 headers.
OVS_VSWITCHD_START(
[add-bond br0 bond0 p1 p2 p3 bond_mode=balance-tcp lacp=active \
other-config:lacp-time=fast other-config:bond-rebalance-interval=0 --\
set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 -- \
set interface p3 type=dummy options:pstream=punix:$OVS_RUNDIR/p3.sock ofport_request=3 -- \
add-port br0 p7 -- set interface p7 ofport_request=7 type=dummy -- \
add-br br1 -- \
set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
fail-mode=secure -- \
add-bond br1 bond1 p4 p5 p6 bond_mode=balance-tcp lacp=active \
other-config:lacp-time=fast other-config:bond-rebalance-interval=0 --\
set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=4 -- \
set interface p5 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=5 -- \
set interface p6 type=dummy options:stream=unix:$OVS_RUNDIR/p3.sock ofport_request=6 -- \
add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --])
AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK
])
AT_CHECK([ovs-ofctl add-flow br0 action=normal])
AT_CHECK([ovs-ofctl add-flow br1 action=normal])
AT_CHECK([ovs-appctl upcall/disable-megaflows], [0], [megaflows disabled
], [])
OVS_WAIT_WHILE([ovs-appctl bond/show | grep "may_enable: false"])
ovs-appctl time/stop
ovs-appctl time/warp 100
ovs-appctl lacp/show > lacp.txt
ovs-appctl bond/show > bond.txt
# Check that lb_output is not enabled by default.
AT_CHECK([grep -q '^lb_output action: disabled' bond.txt])
AT_CHECK([SEND_TCP_BOND_PKTS([p7], [7])])
ovs-appctl time/warp 300 100
AT_CHECK([ovs-appctl dpif/dump-flows br0 |grep tcp > br0_flows.txt])
AT_CHECK([ovs-appctl dpif/dump-flows br1 |grep tcp > br1_flows.txt])
# Make sure there is resonable distribution to all three ports.
# We don't want to make this check precise, in case hash function changes.
AT_CHECK([test $(grep -c in_port.4 br1_flows.txt) -gt 24])
AT_CHECK([test $(grep -c in_port.5 br1_flows.txt) -gt 24])
AT_CHECK([test $(grep -c in_port.6 br1_flows.txt) -gt 24])
# Check that bonding is doing dp_hash.
AT_CHECK([grep -q dp_hash br0_flows.txt])
# Enabling lb_output.
AT_CHECK([ovs-vsctl set Port bond0 other_config:lb-output-action=true])
OVS_WAIT_UNTIL([ovs-appctl bond/show | grep -q '^lb_output action: enabled'])
ovs-appctl time/warp 10000 500
ovs-appctl revalidator/wait
OVS_WAIT_WHILE([ovs-appctl dpif/dump-flows br1 | grep -q tcp])
AT_CHECK([SEND_TCP_BOND_PKTS([p7], [7])])
ovs-appctl time/warp 300 100
AT_CHECK([ovs-appctl dpif/dump-flows br0 | grep tcp > br0_flows.txt])
AT_CHECK([ovs-appctl dpif/dump-flows br1 | grep tcp > br1_flows.txt])
# Make sure there is resonable distribution to all three ports, again.
AT_CHECK([test $(grep -c in_port.4 br1_flows.txt) -gt 24])
AT_CHECK([test $(grep -c in_port.5 br1_flows.txt) -gt 24])
AT_CHECK([test $(grep -c in_port.6 br1_flows.txt) -gt 24])
AT_CHECK([grep -q lb_output br0_flows.txt])
AT_CHECK([test $(ovs-appctl dpif-netdev/bond-show | grep -c bucket) -eq 256])
AT_CHECK([ovs-vsctl set Port bond0 other_config:lb-output-action=false])
OVS_WAIT_UNTIL([test -z "$(ovs-appctl dpif-netdev/bond-show)"])
OVS_VSWITCHD_STOP()
AT_CLEANUP
# Make sure that rebalancing works after link state changes.
AT_SETUP([ofproto-dpif - balance-tcp bonding rebalance after link state changes])
# Create br0 with interfaces bond0(p1, p2) and p5,
# and br1 with interfaces bond1(p3, p4) and p6.
# bond0 <-> bond1
# Send some traffic, set link state down and up for p2,
# send big amount of traffic to trigger rebalancing and
# make sure that some hashes rebalanced.
OVS_VSWITCHD_START(
[add-bond br0 bond0 p1 p2 bond_mode=balance-tcp lacp=active \
other-config:lacp-time=fast other-config:bond-rebalance-interval=1000 --\
set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 mtu_request=65535 -- \
set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 mtu_request=65535 -- \
add-port br0 p5 -- set interface p5 ofport_request=5 type=dummy mtu_request=65535 -- \
add-br br1 -- \
set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
fail-mode=secure -- \
add-bond br1 bond1 p3 p4 bond_mode=balance-tcp lacp=active \
other-config:lacp-time=fast other-config:bond-rebalance-interval=1000 --\
set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=3 mtu_request=65535 -- \
set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 mtu_request=65535 -- \
add-port br1 p6 -- set interface p6 ofport_request=6 type=dummy mtu_request=65535 --])
AT_CHECK([ovs-appctl vlog/set bond:dbg])
AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK
])
AT_CHECK([ovs-ofctl add-flow br0 action=normal])
AT_CHECK([ovs-ofctl add-flow br1 action=normal])
AT_CHECK([ovs-appctl upcall/disable-megaflows], [0], [megaflows disabled
], [])
OVS_WAIT_WHILE([ovs-appctl bond/show | grep "may_enable: false"])
ovs-appctl time/stop
ovs-appctl time/warp 2000 200
# Send some traffic to distribute all the hashes between ports.
AT_CHECK([SEND_TCP_BOND_PKTS([p5], [5], [65500])])
# Wait for rebalancing for per-hash stats accounting.
ovs-appctl time/warp 1000 100
# Check that p2 handles some hashes.
ovs-appctl bond/show > bond1.txt
AT_CHECK([sed -n '/member p2/,/^$/p' bond1.txt | grep 'hash'], [0], [ignore])
# Move p2 down to force all hashes move to p1
AT_CHECK([ovs-appctl netdev-dummy/set-admin-state p2 down], 0, [OK
])
ovs-appctl time/warp 200 100
# Check that all hashes moved form p2
ovs-appctl bond/show > bond2.txt
AT_CHECK([sed -n '/member p2/,/^$/p' bond2.txt | grep 'hash'], [1], [ignore])
# Move p2 up
AT_CHECK([ovs-appctl netdev-dummy/set-admin-state p2 up], 0, [OK
])
# Send some packets to trigger rebalancing.
AT_CHECK([SEND_TCP_BOND_PKTS([p5], [5], [65500])])
# Wait for rebalancing
ovs-appctl time/warp 1000 100
# Check that some hashes was shifted to p2
ovs-appctl bond/show > bond3.txt
AT_CHECK([sed -n '/member p2/,/^$/p' bond3.txt | grep 'hash'], [0], [ignore])
OVS_VSWITCHD_STOP()
AT_CLEANUP
# Makes sure recirculation does not change the way packet is handled.
AT_SETUP([ofproto-dpif - balance-tcp bonding, different recirc flow ])
OVS_VSWITCHD_START(
[add-bond br0 bond0 p1 p2 bond_mode=balance-tcp lacp=active \
other-config:lacp-time=fast other-config:bond-rebalance-interval=0 -- \
set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
set interface p2 type=dummy options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 -- \
add-br br1 -- \
set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
fail-mode=standalone -- \
add-bond br1 bond1 p3 p4 bond_mode=balance-tcp lacp=active \
other-config:lacp-time=fast other-config:bond-rebalance-interval=0 -- \
set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=3 -- \
set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 -- \
add-port br1 br1- -- set interface br1- type=patch options:peer=br1+ ofport_request=100 -- \
add-br br-int -- \
set bridge br-int other-config:hwaddr=aa:77:aa:77:00:00 -- \
set bridge br-int datapath-type=dummy other-config:datapath-id=1235 \
fail-mode=secure -- \
add-port br-int br1+ -- set interface br1+ type=patch options:peer=br1- ofport_request=101 -- \
add-port br-int p5 -- set interface p5 ofport_request=5 type=dummy
])
AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK
])
# Waits for all ifaces enabled.
OVS_WAIT_UNTIL([test `ovs-appctl bond/show | grep -- "may_enable: true" | wc -l` -ge 4])
# The dl_vlan flow should not be ever matched,
# since recirculation should not change the flow handling.
AT_DATA([flows.txt], [dnl
table=0 priority=1 in_port=5 actions=mod_vlan_vid:1,output(101)
table=0 priority=2 in_port=5 dl_vlan=1 actions=drop
])
AT_CHECK([ovs-ofctl add-flows br-int flows.txt])
# Sends a packet to trigger recirculation.
AT_CHECK([ovs-appctl netdev-dummy/receive p5 "in_port(5),eth(src=50:54:00:00:00:05,dst=50:54:00:00:01:00),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1)"])
# Collects flow stats.
AT_CHECK([ovs-appctl revalidator/purge], [0])
# Checks the flow stats in br1, should only be one flow with non-zero
# 'n_packets' from internal table.
AT_CHECK([ovs-appctl bridge/dump-flows br1 | ofctl_strip | grep -- "n_packets" | grep -- "table_id" | sed -e 's/output:[[0-9]][[0-9]]*/output/'] , [0], [dnl
table_id=254, n_packets=1, n_bytes=38, priority=20,recirc_id=0x0,dp_hash=0x0/0xff,actions=output
])
# Checks the flow stats in br-int, should be only one match.
AT_CHECK([ovs-ofctl dump-flows br-int | ofctl_strip | sort], [0], [dnl
n_packets=1, n_bytes=34, priority=1,in_port=5 actions=mod_vlan_vid:1,output:101
priority=2,in_port=5,dl_vlan=1 actions=drop
NXST_FLOW reply:
])
OVS_VSWITCHD_STOP()
AT_CLEANUP
AT_SETUP([ofproto-dpif - resubmit])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11 12 13 14 15 16 17 18 19 20 21
AT_DATA([flows.txt], [dnl
table=0 in_port=1 priority=1000 icmp actions=output(10),resubmit(2),output(19),resubmit(3),output(21)
table=0 in_port=2 priority=1500 icmp actions=output(11),resubmit(,1),output(16),resubmit(2,1),output(18)
table=0 in_port=3 priority=2000 icmp actions=output(20)
table=1 in_port=1 priority=1000 icmp actions=output(12),resubmit(4,1),output(13),resubmit(3),output(15)
table=1 in_port=2 priority=1500 icmp actions=output(17),resubmit(,2)
table=1 in_port=3 priority=1500 icmp actions=output(14),resubmit(,2)
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=p1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: 10,11,12,13,14,15,16,17,18,19,20,21
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - goto table])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11
echo "table=0 in_port=1 actions=output(10),goto_table(1)" > flows.txt
for i in `seq 1 63`; do echo "table=$i actions=goto_table($(($i+1)))"; done >> flows.txt
echo "table=64 actions=output(11)" >> flows.txt
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: 10,11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - write actions])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11 12 13
AT_DATA([flows.txt], [dnl
table=0 in_port=1,ip actions=output(10),write_actions(set_field:192.168.3.90->ip_src,output(12)),goto_table(1)
table=1 ip actions=write_actions(output(13)),goto_table(2)
table=2 ip actions=set_field:192.168.3.91->ip_src,output(11)
])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
Datapath actions: 10,set(ipv4(src=192.168.3.91)),11,set(ipv4(src=192.168.3.90)),13
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - modify IPv6 Neighbor Solitication (ND)])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11 12 13
AT_DATA([flows.txt], [dnl
table=0 in_port=1,icmp6,icmpv6_type=135 actions=output(10),write_actions(set_field:fe80::3->nd_target,set_field:aa:aa:aa:aa:aa:aa->nd_sll,output(12)),goto_table(1)
table=1 icmp6 actions=write_actions(output(13)),goto_table(2)
table=2 in_port=1,icmp6,icmpv6_type=135 actions=set_field:fe80::4->nd_target,set_field:cc:cc:cc:cc:cc:cc->nd_sll,output(11)
])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,icmp6,ipv6_src=fe80::1,ipv6_dst=fe80::2,nw_tos=0,nw_ttl=128,icmpv6_type=135,nd_target=fe80::2020,nd_sll=66:55:44:33:22:11'], [0], [stdout])
AT_CHECK([tail -4 stdout], [0],
[Megaflow: recirc_id=0,eth,icmp6,in_port=1,nw_frag=no,icmp_type=0x87/0xff,icmp_code=0x0/0xff,nd_target=fe80::2020,nd_sll=66:55:44:33:22:11
Datapath actions: 10,set(nd(target=fe80::4,sll=cc:cc:cc:cc:cc:cc)),11,set(nd(target=fe80::3,sll=aa:aa:aa:aa:aa:aa)),13
This flow is handled by the userspace slow path because it:
- Uses action(s) not supported by datapath.
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - clear actions])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11 12
AT_DATA([flows.txt], [dnl
table=0 in_port=1,ip actions=output(10),write_actions(set_field:192.168.3.90->ip_src,output(12)),goto_table(1)
table=1 tcp actions=set_field:91->tp_src,output(11),clear_actions
])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,nw_tos=0,nw_ttl=128,tp_src=8,tp_dst=9'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,tcp,in_port=1,nw_frag=no,tp_src=8
Datapath actions: 10,set(tcp(src=91)),11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - group chaining])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=all,bucket=set_field:192.168.3.90->ip_src,group:123,bucket=output:11'])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=123,type=all,bucket=output:10'])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=group:1234'])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - all group in action list])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=all,bucket=output:10,set_field:192.168.3.90->ip_src,bucket=output:11'])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=group:1234'])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
# Must match on the source address to be able to restore it's value for
# the second bucket
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
Datapath actions: set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - indirect group in action list])
OVS_VSWITCHD_START
add_of_ports br0 1 10
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 group_id=1234,type=indirect,bucket=output:10])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=group:1234'])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: 10
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - group actions have no effect afterwards])
OVS_VSWITCHD_START
add_of_ports br0 1 10
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=select,bucket=set_field:192.168.3.90->ip_src,output:10'])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=group:1234,output:10'])
for d in 0 1 2 3; do
pkt="in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:1),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.1.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
AT_CHECK([ovs-appctl netdev-dummy/receive p1 $pkt])
done
AT_CHECK([ovs-appctl dpctl/dump-flows | sed 's/dp_hash(.*\/0xf)/dp_hash(0xXXXX\/0xf)/' | sed 's/packets.*actions:/actions:/' | strip_ufid | strip_used | sort], [0], [dnl
flow-dump from the main thread:
recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), actions:hash(sym_l4(0)),recirc(0x1)
recirc_id(0x1),dp_hash(0xXXXX/0xf),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(src=192.168.0.1,frag=no), actions:set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),10
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - all group in action set])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=all,bucket=output:10,set_field:192.168.3.90->ip_src,bucket=output:11'])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=write_actions(group:1234)'])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
# Must match on the source address to be able to restore it's value for
# the third bucket
AT_CHECK([tail -2 stdout], [0],
[Megaflow: recirc_id=0,eth,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
Datapath actions: set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - indirect group in action set])
OVS_VSWITCHD_START
add_of_ports br0 1 10
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 group_id=1234,type=indirect,bucket=output:10])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=write_actions(group:1234)'])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: 10
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - patch port with action set])
OVS_VSWITCHD_START([ \
add-br br1 -- \
set bridge br1 datapath-type=dummy fail-mode=secure -- \
add-port br0 patch10 -- \
set interface patch10 type=patch options:peer=patch20 ofport_request=10 -- \
add-port br1 patch20 -- \
set interface patch20 type=patch options:peer=patch10 ofport_request=20
])
add_of_ports br0 1
add_of_ports br1 2
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br1 'ip actions=write_actions(pop_vlan,output:2)'])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=output:10'])
AT_CHECK([ovs-appctl ofproto/trace br1 'in_port=20,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_vlan=100,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: pop_vlan,2
])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_vlan=100,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: pop_vlan,2
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - select group])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11
ovs-appctl vlog/set ofproto_dpif:file:dbg
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=select,bucket=output:10,bucket=output:11'])
AT_CHECK([grep -A6 "Constructing select group 1234" ovs-vswitchd.log | sed 's/^.*ofproto_dpif/ofproto_dpif/'], [0], [dnl
ofproto_dpif|DBG|Constructing select group 1234
ofproto_dpif|DBG|No selection method specified. Trying dp_hash.
ofproto_dpif|DBG| Minimum weight: 1, total weight: 2
ofproto_dpif|DBG| Using 16 hash values:
ofproto_dpif|DBG| Bucket 0: weight=1, target=8.00 hits=8
ofproto_dpif|DBG| Bucket 1: weight=1, target=8.00 hits=8
ofproto_dpif|DBG|Use dp_hash with 16 hash values using algorithm 1.
])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=write_actions(group:1234)'])
# Try a bunch of different flows and make sure that they get distributed
# # at least somewhat.
for d in 0 1 2 3; do
for s in 1 2 3 4 ; do
pkt="in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:1),eth_type(0x0800),ipv4(src=192.168.0.$s,dst=192.168.1.$d,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
AT_CHECK([ovs-appctl netdev-dummy/receive p1 $pkt])
done
done
AT_CHECK([ovs-appctl dpctl/dump-flows | sort | strip_ufid | strip_used | check_dpflow_stats 5 2 dp_hash], [0], [dnl
recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), packets:15, bytes:1590, used:0.0s, actions:hash(sym_l4(0)),recirc(0x1)
n_flows=ok n_buckets=ok
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - select group with watch port])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11
AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=select,bucket=watch_port:10,output:10,bucket=output:11'])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=write_actions(group:1234)'])
for d in 0 1 2 3; do
pkt="in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:1),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
AT_CHECK([ovs-appctl netdev-dummy/receive p1 $pkt])
done
AT_CHECK([ovs-appctl dpctl/dump-flows | sort| sed 's/dp_hash(.*\/0xf)/dp_hash(0xXXXX\/0xf)/' | strip_ufid | strip_used], [0], [dnl
flow-dump from the main thread:
recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), packets:3, bytes:318, used:0.0s, actions:hash(sym_l4(0)),recirc(0x1)
recirc_id(0x1),dp_hash(0xXXXX/0xf),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), packets:3, bytes:318, used:0.0s, actions:11
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - select group with weights])
# Helper function to check the accuracy of distribution of packets over buckets
check_group_stats () {
buckets=`grep -o 'packet_count=[[0-9]]*' | cut -d'=' -f2 | tail -n +2`
i=0
for bucket in $buckets; do
min=$1
shift
if [[ $bucket -ge $min ]]; then
echo "bucket$i >= $min"
else
echo "bucket$i < $min"
fi
i=`expr $i + 1`
if [[ $i -ge 4 ]]; then break; fi
done
}
OVS_VSWITCHD_START
add_of_ports br0 1 10 11 12 13 14
ovs-appctl vlog/set ofproto_dpif:file:dbg
AT_CHECK([ovs-ofctl -O OpenFlow13 add-group br0 'group_id=1234,type=select,bucket=weight:5,output:10,bucket=weight:10,output:11,bucket=weight:25,output:12,bucket=weight:60,output:13,bucket=weight:0,output:14'])
AT_CHECK([grep -A9 "Constructing select group 1234" ovs-vswitchd.log | sed 's/^.*ofproto_dpif/ofproto_dpif/'], [0], [dnl
ofproto_dpif|DBG|Constructing select group 1234
ofproto_dpif|DBG|No selection method specified. Trying dp_hash.
ofproto_dpif|DBG| Minimum weight: 5, total weight: 100
ofproto_dpif|DBG| Using 32 hash values:
ofproto_dpif|DBG| Bucket 0: weight=5, target=1.60 hits=2
ofproto_dpif|DBG| Bucket 1: weight=10, target=3.20 hits=3
ofproto_dpif|DBG| Bucket 2: weight=25, target=8.00 hits=8
ofproto_dpif|DBG| Bucket 3: weight=60, target=19.20 hits=19
ofproto_dpif|DBG| Bucket 4: weight=0, target=0.00 hits=0
ofproto_dpif|DBG|Use dp_hash with 32 hash values using algorithm 1.
])
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=write_actions(group:1234)'])
# Try 1000 different flows and make sure that they get distributed according to weights
for d1 in 0 1 2 3 4 5 6 7 8 9 ; do
for d2 in 0 1 2 3 4 5 6 7 8 9 ; do
for s in 0 1 2 3 4 5 6 7 8 9 ; do
pkt="in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:1),eth_type(0x0800),ipv4(src=192.168.1.$s,dst=192.168.$d1.$d2,proto=6,tos=0,ttl=128,frag=no),tcp(src=1000$s,dst=1000)"
AT_CHECK([ovs-appctl netdev-dummy/receive p1 $pkt])
done
done
done
# Check balanced distribution over 32 dp_hash values
AT_CHECK([ovs-appctl dpctl/dump-flows | sort | strip_ufid | strip_used | check_dpflow_stats 32 4 dp_hash], [0], [dnl
recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), packets:999, bytes:117882, used:0.0s, actions:hash(sym_l4(0)),recirc(0x1)
n_flows=ok n_buckets=ok
])
# Check that actual distribution over the buckets is reasonably accurate:
ideal weights dp_hash values
# bucket0: 5%*1000 = 50 2/32*1000 = 63
# bucket1: 10%*1000 = 100 3/32*1000 = 94
# bucket2: 25%*1000 = 250 8/32*1000 = 250
# bucket3: 60%*1000 = 600 19/32*1000 = 594
# bucket4: 0 0
ovs-appctl time/warp 1000
AT_CHECK([ovs-ofctl -O OpenFlow13 dump-group-stats br0 | sed 's/duration=[[0-9]]\.[[0-9]]*s,//' | check_group_stats 40 80 200 500],
[0], [dnl
bucket0 >= 40
bucket1 >= 80
bucket2 >= 200
bucket3 >= 500
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - select group with explicit dp_hash selection method])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11
ovs-appctl vlog/set ofproto_dpif:file:dbg
AT_CHECK([ovs-ofctl -O OpenFlow15 add-group br0 'group_id=1234,type=select,selection_method=dp_hash,bucket=output:10,bucket=output:11'])
AT_CHECK([grep -A6 "Constructing select group 1234" ovs-vswitchd.log | sed 's/^.*ofproto_dpif/ofproto_dpif/'], [0], [dnl
ofproto_dpif|DBG|Constructing select group 1234
ofproto_dpif|DBG|Selection method specified: dp_hash.
ofproto_dpif|DBG| Minimum weight: 1, total weight: 2
ofproto_dpif|DBG| Using 16 hash values:
ofproto_dpif|DBG| Bucket 0: weight=1, target=8.00 hits=8
ofproto_dpif|DBG| Bucket 1: weight=1, target=8.00 hits=8
ofproto_dpif|DBG|Use dp_hash with 16 hash values using algorithm 0.
])
# Fall back to legacy hash with zero buckets
AT_CHECK([ovs-ofctl -O OpenFlow15 add-group br0 'group_id=1235,type=select,selection_method=dp_hash'])
AT_CHECK([grep -A3 "Constructing select group 1235" ovs-vswitchd.log | sed 's/^.*ofproto_dpif/ofproto_dpif/'], [0], [dnl
ofproto_dpif|DBG|Constructing select group 1235
ofproto_dpif|DBG|Selection method specified: dp_hash.
ofproto_dpif|DBG| Don't apply dp_hash method without buckets.
ofproto_dpif|DBG|Falling back to default hash method.
])
# Fall back to legacy hash with zero buckets
AT_CHECK([ovs-ofctl -O OpenFlow15 add-group br0 'group_id=1236,type=select,selection_method=dp_hash,bucket=weight=1,output:10,bucket=weight=1000,output:11'])
AT_CHECK([grep -A4 "Constructing select group 1236" ovs-vswitchd.log | sed 's/^.*ofproto_dpif/ofproto_dpif/'], [0], [dnl
ofproto_dpif|DBG|Constructing select group 1236
ofproto_dpif|DBG|Selection method specified: dp_hash.
ofproto_dpif|DBG| Minimum weight: 1, total weight: 1001
ofproto_dpif|DBG| Too many hash values required: 1024
ofproto_dpif|DBG|Falling back to default hash method.
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - select group with legacy hash selection method])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11
ovs-appctl vlog/set ofproto_dpif:file:dbg
AT_CHECK([ovs-ofctl -O OpenFlow15 add-group br0 'group_id=1234,type=select,selection_method=hash,bucket=output:10,bucket=output:11'])
AT_CHECK([grep -A2 "Constructing select group 1234" ovs-vswitchd.log | sed 's/^.*ofproto_dpif/ofproto_dpif/'], [0], [dnl
ofproto_dpif|DBG|Constructing select group 1234
ofproto_dpif|DBG|Selection method specified: hash.
ofproto_dpif|DBG|No hash fields. Falling back to default hash method.
])
AT_CHECK([ovs-ofctl -O OpenFlow15 add-flow br0 'ip actions=write_actions(group:1234)'])
# Try 16 flows with differing default hash values.
for d in 0 1 2 3; do
for s in 1 2 3 4 ; do
pkt="in_port(1),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:1),eth_type(0x0800),ipv4(src=192.168.0.$s,dst=192.168.1.$d,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
AT_CHECK([ovs-appctl netdev-dummy/receive p1 $pkt])
done
done
# Check that the packets installed 16 data path flows and each of the two
# buckets is hit at least once.
AT_CHECK([ovs-appctl dpctl/dump-flows | strip_ufid | strip_used | sort | check_dpflow_stats 16 2], [0], [dnl
n_flows=ok n_buckets=ok
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - select group with custom hash selection method])
OVS_VSWITCHD_START
add_of_ports br0 1 10 11
# Check that parse failures after 'fields' parsing work
AT_CHECK([ovs-ofctl -O OpenFlow10 add-group br0 'group_id=1,type=select,fields(eth_dst),bukket=output:10'], [1], ,[dnl
ovs-ofctl: unknown keyword bukket
])