@@ -67,7 +67,68 @@ def required_wildcards(parent):
67
67
else :
68
68
return 0
69
69
70
- def simple_tcp_packet (pktlen = 100 ,
70
+ def simple_sctp_packet (pktlen = 100 ,
71
+ eth_dst = '00:01:02:03:04:05' ,
72
+ eth_src = '00:06:07:08:09:0a' ,
73
+ dl_vlan_enable = False ,
74
+ vlan_vid = 0 ,
75
+ vlan_pcp = 0 ,
76
+ dl_vlan_cfi = 0 ,
77
+ ip_src = '192.168.0.1' ,
78
+ ip_dst = '192.168.0.2' ,
79
+ ip_tos = 0 ,
80
+ ip_ttl = 64 ,
81
+ sctp_sport = 1234 ,
82
+ sctp_dport = 80 ,
83
+ ip_ihl = None ,
84
+ ip_options = False
85
+ ):
86
+ """
87
+ Return a simple dataplane SCTP packet
88
+
89
+ Supports a few parameters:
90
+ @param len Length of packet in bytes w/o CRC
91
+ @param eth_dst Destinatino MAC
92
+ @param eth_src Source MAC
93
+ @param dl_vlan_enable True if the packet is with vlan, False otherwise
94
+ @param vlan_vid VLAN ID
95
+ @param vlan_pcp VLAN priority
96
+ @param ip_src IP source
97
+ @param ip_dst IP destination
98
+ @param ip_tos IP ToS
99
+ @param ip_ttl IP TTL
100
+ @param sctp_dport SCTP destination port
101
+ @param sctp_sport SCTP source port
102
+
103
+ Generates a simple SCTP request. Users
104
+ shouldn't assume anything about this packet other than that
105
+ it is a valid ethernet/IP/SCTP frame.
106
+ """
107
+
108
+ if MINSIZE > pktlen :
109
+ pktlen = MINSIZE
110
+
111
+ # Note Dot1Q.id is really CFI
112
+ if (dl_vlan_enable ):
113
+ pkt = scapy .Ether (dst = eth_dst , src = eth_src )/ \
114
+ scapy .Dot1Q (prio = vlan_pcp , id = dl_vlan_cfi , vlan = vlan_vid )/ \
115
+ scapy .IP (src = ip_src , dst = ip_dst , tos = ip_tos , ttl = ip_ttl , ihl = ip_ihl )/ \
116
+ scapy .SCTP (sport = sctp_sport , dport = sctp_dport )
117
+ else :
118
+ if not ip_options :
119
+ pkt = scapy .Ether (dst = eth_dst , src = eth_src )/ \
120
+ scapy .IP (src = ip_src , dst = ip_dst , tos = ip_tos , ttl = ip_ttl , ihl = ip_ihl )/ \
121
+ scapy .SCTP (sport = sctp_sport , dport = sctp_dport )
122
+ else :
123
+ pkt = scapy .Ether (dst = eth_dst , src = eth_src )/ \
124
+ scapy .IP (src = ip_src , dst = ip_dst , tos = ip_tos , ttl = ip_ttl , ihl = ip_ihl , options = ip_options )/ \
125
+ scapy .SCTP (sport = sctp_sport , dport = sctp_dport )
126
+
127
+ pkt = pkt / ("D" * (pktlen - len (pkt )))
128
+
129
+ return pkt
130
+
131
+ def simple_tcp_packet (pktlen = 100 ,
71
132
eth_dst = '00:01:02:03:04:05' ,
72
133
eth_src = '00:06:07:08:09:0a' ,
73
134
dl_vlan_enable = False ,
@@ -100,7 +161,7 @@ def simple_tcp_packet(pktlen=100,
100
161
@param ip_ttl IP TTL
101
162
@param tcp_dport TCP destination port
102
163
@param tcp_sport TCP source port
103
- @param tcp_flags TCP Control flags
164
+ @param tcp_flags TCP Control flags
104
165
105
166
Generates a simple TCP request. Users
106
167
shouldn't assume anything about this packet other than that
@@ -161,7 +222,7 @@ def simple_tcpv6_packet(pktlen=100,
161
222
@param ipv6_fl IPv6 flow label
162
223
@param tcp_dport TCP destination port
163
224
@param tcp_sport TCP source port
164
- @param tcp_flags TCP Control flags
225
+ @param tcp_flags TCP Control flags
165
226
166
227
Generates a simple TCP request. Users shouldn't assume anything about this
167
228
packet other than that it is a valid ethernet/IPv6/TCP frame.
@@ -286,7 +347,7 @@ def simple_udpv6_packet(pktlen=100,
286
347
287
348
return pkt
288
349
289
- def simple_icmp_packet (pktlen = 60 ,
350
+ def simple_icmp_packet (pktlen = 60 ,
290
351
eth_dst = '00:01:02:03:04:05' ,
291
352
eth_src = '00:06:07:08:09:0a' ,
292
353
dl_vlan_enable = False ,
@@ -296,7 +357,7 @@ def simple_icmp_packet(pktlen=60,
296
357
ip_dst = '192.168.0.2' ,
297
358
ip_tos = 0 ,
298
359
ip_ttl = 64 ,
299
- ip_id = 1 ,
360
+ ip_id = 1 ,
300
361
icmp_type = 8 ,
301
362
icmp_code = 0 ,
302
363
icmp_data = '' ):
@@ -452,7 +513,7 @@ def simple_icmpv6_packet(pktlen=100,
452
513
453
514
return pkt
454
515
455
- def simple_arp_packet (pktlen = 68 ,
516
+ def simple_arp_packet (pktlen = 68 ,
456
517
eth_dst = 'ff:ff:ff:ff:ff:ff' ,
457
518
eth_src = '00:06:07:08:09:0a' ,
458
519
vlan_vid = 0 ,
@@ -507,7 +568,7 @@ def simple_eth_packet(pktlen=60,
507
568
508
569
return pkt
509
570
510
- def qinq_tcp_packet (pktlen = 100 ,
571
+ def qinq_tcp_packet (pktlen = 100 ,
511
572
eth_dst = '00:01:02:03:04:05' ,
512
573
eth_src = '00:06:07:08:09:0a' ,
513
574
dl_vlan_outer = 20 ,
@@ -693,7 +754,7 @@ def port_config_get(controller, port_no):
693
754
for port in ports :
694
755
if port .port_no == port_no :
695
756
return (port .hw_addr , port .config , port .advertised )
696
-
757
+
697
758
logging .warn ("Did not find port number for port config" )
698
759
return None , None , None
699
760
@@ -738,7 +799,7 @@ def receive_pkt_check(dp, pkt, yes_ports, no_ports, assert_if):
738
799
logging .debug ("Checking for pkt on port " + str (ofport ))
739
800
(rcv_port , rcv_pkt , pkt_time ) = dp .poll (
740
801
port_number = ofport , exp_pkt = exp_pkt_arg )
741
- assert_if .assertTrue (rcv_pkt is not None ,
802
+ assert_if .assertTrue (rcv_pkt is not None ,
742
803
"Did not receive pkt on " + str (ofport ))
743
804
if not oftest .dataplane .match_exp_pkt (pkt , rcv_pkt ):
744
805
logging .debug ("Expected %s" % format_packet (pkt ))
@@ -752,7 +813,7 @@ def receive_pkt_check(dp, pkt, yes_ports, no_ports, assert_if):
752
813
logging .debug ("Negative check for pkt on port " + str (ofport ))
753
814
(rcv_port , rcv_pkt , pkt_time ) = dp .poll (
754
815
port_number = ofport , timeout = 0 , exp_pkt = exp_pkt_arg )
755
- assert_if .assertTrue (rcv_pkt is None ,
816
+ assert_if .assertTrue (rcv_pkt is None ,
756
817
"Unexpected pkt on port " + str (ofport ))
757
818
758
819
@@ -783,12 +844,12 @@ def receive_pkt_verify(parent, egr_ports, exp_pkt, ing_port):
783
844
port_number = check_port , exp_pkt = exp_pkt_arg )
784
845
785
846
if rcv_pkt is None :
786
- logging .error ("ERROR: No packet received from " +
847
+ logging .error ("ERROR: No packet received from " +
787
848
str (check_port ))
788
849
789
850
parent .assertTrue (rcv_pkt is not None ,
790
851
"Did not receive packet port " + str (check_port ))
791
- logging .debug ("Packet len " + str (len (rcv_pkt )) + " in on " +
852
+ logging .debug ("Packet len " + str (len (rcv_pkt )) + " in on " +
792
853
str (rcv_port ))
793
854
794
855
if str (exp_pkt ) != str (rcv_pkt ):
@@ -826,8 +887,8 @@ def match_verify(parent, req_match, res_match):
826
887
'Match failed: vlan_vid: ' + str (req_match .vlan_vid ) +
827
888
" != " + str (res_match .vlan_vid ))
828
889
parent .assertEqual (req_match .vlan_pcp , res_match .vlan_pcp ,
829
- 'Match failed: vlan_pcp: ' +
830
- str (req_match .vlan_pcp ) + " != " +
890
+ 'Match failed: vlan_pcp: ' +
891
+ str (req_match .vlan_pcp ) + " != " +
831
892
str (res_match .vlan_pcp ))
832
893
parent .assertEqual (req_match .eth_type , res_match .eth_type ,
833
894
'Match failed: eth_type: ' + str (req_match .eth_type ) +
@@ -852,11 +913,11 @@ def match_verify(parent, req_match, res_match):
852
913
and ((req_match .ip_proto == TCP_PROTOCOL )
853
914
or (req_match .ip_proto == UDP_PROTOCOL ))):
854
915
parent .assertEqual (req_match .tcp_src , res_match .tcp_src ,
855
- 'Match failed: tcp_src: ' +
916
+ 'Match failed: tcp_src: ' +
856
917
str (req_match .tcp_src ) +
857
918
" != " + str (res_match .tcp_src ))
858
919
parent .assertEqual (req_match .tcp_dst , res_match .tcp_dst ,
859
- 'Match failed: tcp_dst: ' +
920
+ 'Match failed: tcp_dst: ' +
860
921
str (req_match .tcp_dst ) +
861
922
" != " + str (res_match .tcp_dst ))
862
923
@@ -874,7 +935,7 @@ def flow_msg_create(parent, pkt, ing_port=None, action_list=None, wildcards=None
874
935
"""
875
936
Create a flow message
876
937
877
- Match on packet with given wildcards.
938
+ Match on packet with given wildcards.
878
939
See flow_match_test for other parameter descriptoins
879
940
@param egr_queue if not None, make the output an enqueue action
880
941
@param in_band if True, do not wildcard ingress port
@@ -941,7 +1002,7 @@ def flow_msg_install(parent, request, clear_table_override=None):
941
1002
if (clear_table_override != None ):
942
1003
clear_table = clear_table_override
943
1004
944
- if clear_table :
1005
+ if clear_table :
945
1006
logging .debug ("Clear flow table" )
946
1007
delete_all_flows (parent .controller )
947
1008
@@ -963,21 +1024,21 @@ def flow_match_test_port_pair(parent, ing_port, egr_ports, wildcards=None,
963
1024
964
1025
if wildcards is None :
965
1026
wildcards = required_wildcards (parent )
966
- logging .info ("Pkt match test: " + str (ing_port ) + " to " +
1027
+ logging .info ("Pkt match test: " + str (ing_port ) + " to " +
967
1028
str (egr_ports ))
968
1029
logging .debug (" WC: " + hex (wildcards ) + " vlan: " + str (vlan_vid ))
969
1030
if pkt is None :
970
1031
pkt = simple_tcp_packet (dl_vlan_enable = (vlan_vid >= 0 ), vlan_vid = vlan_vid )
971
1032
if exp_pkt is None :
972
1033
exp_pkt = pkt
973
1034
974
- request = flow_msg_create (parent , pkt , ing_port = ing_port ,
1035
+ request = flow_msg_create (parent , pkt , ing_port = ing_port ,
975
1036
wildcards = wildcards , egr_ports = egr_ports ,
976
1037
action_list = action_list )
977
1038
978
1039
flow_msg_install (parent , request )
979
1040
980
- logging .debug ("Send packet: " + str (ing_port ) + " to " +
1041
+ logging .debug ("Send packet: " + str (ing_port ) + " to " +
981
1042
str (egr_ports ))
982
1043
parent .dataplane .send (ing_port , str (pkt ))
983
1044
@@ -1037,16 +1098,16 @@ def get_egr_list(parent, of_ports, how_many, exclude_list=[]):
1037
1098
1038
1099
count = 0
1039
1100
egr_ports = []
1040
- for egr_idx in range (len (of_ports )):
1101
+ for egr_idx in range (len (of_ports )):
1041
1102
if of_ports [egr_idx ] not in exclude_list :
1042
1103
egr_ports .append (of_ports [egr_idx ])
1043
1104
count += 1
1044
1105
if count >= how_many :
1045
1106
return egr_ports
1046
1107
logging .debug ("Could not generate enough egress ports for test" )
1047
1108
return []
1048
-
1049
- def flow_match_test (parent , port_map , wildcards = None , vlan_vid = - 1 , pkt = None ,
1109
+
1110
+ def flow_match_test (parent , port_map , wildcards = None , vlan_vid = - 1 , pkt = None ,
1050
1111
exp_pkt = None , action_list = None ,
1051
1112
max_test = 0 , egr_count = 1 , ing_port = False ):
1052
1113
"""
@@ -1071,18 +1132,18 @@ def flow_match_test(parent, port_map, wildcards=None, vlan_vid=-1, pkt=None,
1071
1132
1072
1133
if egr_count == - 1 :
1073
1134
egr_count = test_param_get ('egr_count' , default = 2 )
1074
-
1135
+
1075
1136
for ing_idx in range (len (of_ports )):
1076
1137
ingress_port = of_ports [ing_idx ]
1077
- egr_ports = get_egr_list (parent , of_ports , egr_count ,
1138
+ egr_ports = get_egr_list (parent , of_ports , egr_count ,
1078
1139
exclude_list = [ingress_port ])
1079
1140
if ing_port :
1080
1141
egr_ports .append (ofp .OFPP_IN_PORT )
1081
1142
if len (egr_ports ) == 0 :
1082
1143
parent .assertTrue (0 , "Failed to generate egress port list" )
1083
1144
1084
- flow_match_test_port_pair (parent , ingress_port , egr_ports ,
1085
- wildcards = wildcards , vlan_vid = vlan_vid ,
1145
+ flow_match_test_port_pair (parent , ingress_port , egr_ports ,
1146
+ wildcards = wildcards , vlan_vid = vlan_vid ,
1086
1147
pkt = pkt , exp_pkt = exp_pkt ,
1087
1148
action_list = action_list )
1088
1149
test_count += 1
@@ -1114,7 +1175,7 @@ def test_param_get(key, default=None):
1114
1175
on the command line, return val (as interpreted by exec). Otherwise
1115
1176
return default value.
1116
1177
1117
- WARNING: TEST PARAMETERS MUST BE PYTHON IDENTIFIERS;
1178
+ WARNING: TEST PARAMETERS MUST BE PYTHON IDENTIFIERS;
1118
1179
eg egr_count, not egr-count.
1119
1180
"""
1120
1181
try :
@@ -1184,7 +1245,7 @@ def action_generate(parent, field_to_mod, mod_field_vals):
1184
1245
1185
1246
return act
1186
1247
1187
- def pkt_action_setup (parent , start_field_vals = {}, mod_field_vals = {},
1248
+ def pkt_action_setup (parent , start_field_vals = {}, mod_field_vals = {},
1188
1249
mod_fields = [], tp = "tcp" , check_test_params = False ):
1189
1250
"""
1190
1251
Set up the ingress and expected packet and action list for a test
@@ -1324,7 +1385,7 @@ def all_stats_get(parent):
1324
1385
"""
1325
1386
Get the aggregate stats for all flows in the table
1326
1387
@param parent Test instance with controller connection and assert
1327
- @returns dict with keys flows, packets, bytes, active (flows),
1388
+ @returns dict with keys flows, packets, bytes, active (flows),
1328
1389
lookups, matched
1329
1390
"""
1330
1391
stat_req = ofp .message .aggregate_stats_request ()
@@ -1339,14 +1400,14 @@ def all_stats_get(parent):
1339
1400
parent .assertTrue (len (reply .entries ) == 1 , "Did not receive flow stats reply" )
1340
1401
1341
1402
for obj in reply .entries :
1342
- (rv ["flows" ], rv ["packets" ], rv ["bytes" ]) = (obj .flow_count ,
1403
+ (rv ["flows" ], rv ["packets" ], rv ["bytes" ]) = (obj .flow_count ,
1343
1404
obj .packet_count , obj .byte_count )
1344
1405
break
1345
1406
1346
1407
request = ofp .message .table_stats_request ()
1347
1408
(reply , pkt ) = parent .controller .transact (request )
1348
1409
1349
-
1410
+
1350
1411
(rv ["active" ], rv ["lookups" ], rv ["matched" ]) = (0 ,0 ,0 )
1351
1412
for obj in reply .entries :
1352
1413
rv ["active" ] += obj .active_count
@@ -1356,7 +1417,7 @@ def all_stats_get(parent):
1356
1417
return rv
1357
1418
1358
1419
_import_blacklist .add ('FILTER' )
1359
- FILTER = '' .join ([(len (repr (chr (x )))== 3 ) and chr (x ) or '.'
1420
+ FILTER = '' .join ([(len (repr (chr (x )))== 3 ) and chr (x ) or '.'
1360
1421
for x in range (256 )])
1361
1422
1362
1423
def hex_dump_buffer (src , length = 16 ):
@@ -1376,7 +1437,7 @@ def hex_dump_buffer(src, length=16):
1376
1437
return '' .join (result )
1377
1438
1378
1439
def format_packet (pkt ):
1379
- return "Packet length %d \n %s" % (len (str (pkt )),
1440
+ return "Packet length %d \n %s" % (len (str (pkt )),
1380
1441
hex_dump_buffer (str (pkt )))
1381
1442
1382
1443
def inspect_packet (pkt ):
@@ -1857,7 +1918,7 @@ def verify_capability(test, capability):
1857
1918
test .assertIn (capability , ofp .const .ofp_capabilities_map ,
1858
1919
"Capability code %d does not exist." % capability )
1859
1920
capability_str = ofp .const .ofp_capabilities_map [capability ]
1860
-
1921
+
1861
1922
logging .info (("Sending features_request to test if capability "
1862
1923
"%s is supported." ), capability_str )
1863
1924
req = ofp .message .features_request ()
@@ -1867,7 +1928,7 @@ def verify_capability(test, capability):
1867
1928
("Unexpected packet type %d received in response to "
1868
1929
"OFPT_FEATURES_REQUEST" ) % res .type )
1869
1930
logging .info ("Received features_reply." )
1870
-
1931
+
1871
1932
if (res .capabilities & capability ) > 0 :
1872
1933
logging .info ("Switch capabilities bitmask claims to support %s" ,
1873
1934
capability_str )
@@ -1890,7 +1951,7 @@ def verify_configuration_flag(test, flag):
1890
1951
"flag %s does not exist." % flag )
1891
1952
flag_str = ofp .const .ofp_config_flags_map [flag ]
1892
1953
1893
- logging .info ("Sending OFPT_GET_CONFIG_REQUEST." )
1954
+ logging .info ("Sending OFPT_GET_CONFIG_REQUEST." )
1894
1955
req = ofp .message .get_config_request ()
1895
1956
rv = test .controller .message_send (req )
1896
1957
test .assertNotEqual (rv , - 1 , "Not able to send get_config_request." )
0 commit comments