blob: ea82ecc0e383bab95251fbf2ffd99e6c65755c18 [file] [log] [blame]
Dan Talaycoc901f4d2010-03-07 21:55:45 -08001
Dan Talaycod2ca1032010-03-10 14:40:26 -08002import sys
Dan Talayco92c99122010-06-03 13:53:18 -07003import copy
Dan Talaycod2ca1032010-03-10 14:40:26 -08004
5try:
6 import scapy.all as scapy
7except:
8 try:
9 import scapy as scapy
10 except:
11 sys.exit("Need to install scapy for packet parsing")
Dan Talayco41eae8b2010-03-10 13:57:06 -080012
Dan Talaycoc901f4d2010-03-07 21:55:45 -080013import oftest.controller as controller
14import oftest.cstruct as ofp
15import oftest.message as message
16import oftest.dataplane as dataplane
17import oftest.action as action
Dan Talayco41eae8b2010-03-10 13:57:06 -080018import oftest.parse as parse
Dan Talaycoc901f4d2010-03-07 21:55:45 -080019import logging
20
Dan Talayco41eae8b2010-03-10 13:57:06 -080021def delete_all_flows(ctrl, logger):
22 """
23 Delete all flows on the switch
24 @param ctrl The controller object for the test
25 @param logger Logging object
26 """
27
Dan Talaycoc901f4d2010-03-07 21:55:45 -080028 logger.info("Deleting all flows")
29 msg = message.flow_mod()
30 msg.match.wildcards = ofp.OFPFW_ALL
Dan Talayco41eae8b2010-03-10 13:57:06 -080031 msg.out_port = ofp.OFPP_NONE
Dan Talaycoc901f4d2010-03-07 21:55:45 -080032 msg.command = ofp.OFPFC_DELETE
33 msg.buffer_id = 0xffffffff
Dan Talayco41eae8b2010-03-10 13:57:06 -080034 return ctrl.message_send(msg)
35
36def simple_tcp_packet(pktlen=100,
37 dl_dst='00:01:02:03:04:05',
38 dl_src='00:06:07:08:09:0a',
Tatsuya Yabe460321e2010-05-25 17:50:49 -070039 dl_vlan_enable=False,
40 dl_vlan=0,
41 dl_vlan_pcp=0,
Dan Talayco41eae8b2010-03-10 13:57:06 -080042 ip_src='192.168.0.1',
43 ip_dst='192.168.0.2',
Tatsuya Yabe460321e2010-05-25 17:50:49 -070044 ip_tos=0,
Dan Talayco41eae8b2010-03-10 13:57:06 -080045 tcp_sport=1234,
46 tcp_dport=80
47 ):
48 """
49 Return a simple dataplane TCP packet
50
51 Supports a few parameters:
52 @param len Length of packet in bytes w/o CRC
53 @param dl_dst Destinatino MAC
54 @param dl_src Source MAC
Tatsuya Yabe460321e2010-05-25 17:50:49 -070055 @param dl_vlan_enable True if the packet is with vlan, False otherwise
56 @param dl_vlan VLAN ID
57 @param dl_vlan_pcp VLAN priority
Dan Talayco41eae8b2010-03-10 13:57:06 -080058 @param ip_src IP source
59 @param ip_dst IP destination
Tatsuya Yabe460321e2010-05-25 17:50:49 -070060 @param ip_tos IP ToS
Dan Talayco41eae8b2010-03-10 13:57:06 -080061 @param tcp_dport TCP destination port
62 @param ip_sport TCP source port
63
64 Generates a simple TCP request. Users
65 shouldn't assume anything about this packet other than that
66 it is a valid ethernet/IP/TCP frame.
67 """
Tatsuya Yabe460321e2010-05-25 17:50:49 -070068 if (dl_vlan_enable):
69 pkt = scapy.Ether(dst=dl_dst, src=dl_src)/ \
70 scapy.Dot1Q(prio=dl_vlan_pcp, id=0, vlan=dl_vlan)/ \
71 scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos)/ \
72 scapy.TCP(sport=tcp_sport, dport=tcp_dport)
73 else:
74 pkt = scapy.Ether(dst=dl_dst, src=dl_src)/ \
75 scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos)/ \
76 scapy.TCP(sport=tcp_sport, dport=tcp_dport)
77
Dan Talayco41eae8b2010-03-10 13:57:06 -080078 pkt = pkt/("D" * (pktlen - len(pkt)))
79
80 return pkt
81
Tatsuya Yabeb8fb3c32010-06-14 15:48:36 -070082def simple_icmp_packet(pktlen=60,
83 dl_dst='00:01:02:03:04:05',
84 dl_src='00:06:07:08:09:0a',
85 dl_vlan_enable=False,
86 dl_vlan=0,
87 dl_vlan_pcp=0,
88 ip_src='192.168.0.1',
89 ip_dst='192.168.0.2',
90 ip_tos=0,
91 icmp_type=8,
92 icmp_code=0
93 ):
94 """
95 Return a simple ICMP packet
96
97 Supports a few parameters:
98 @param len Length of packet in bytes w/o CRC
99 @param dl_dst Destinatino MAC
100 @param dl_src Source MAC
101 @param dl_vlan_enable True if the packet is with vlan, False otherwise
102 @param dl_vlan VLAN ID
103 @param dl_vlan_pcp VLAN priority
104 @param ip_src IP source
105 @param ip_dst IP destination
106 @param ip_tos IP ToS
107 @param icmp_type ICMP type
108 @param icmp_code ICMP code
109
110 Generates a simple ICMP ECHO REQUEST. Users
111 shouldn't assume anything about this packet other than that
112 it is a valid ethernet/ICMP frame.
113 """
114 if (dl_vlan_enable):
115 pkt = scapy.Ether(dst=dl_dst, src=dl_src)/ \
116 scapy.Dot1Q(prio=dl_vlan_pcp, id=0, vlan=dl_vlan)/ \
117 scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos)/ \
118 scapy.ICMP(type=icmp_type, code=icmp_code)
119 else:
120 pkt = scapy.Ether(dst=dl_dst, src=dl_src)/ \
121 scapy.IP(src=ip_src, dst=ip_dst, tos=ip_tos)/ \
122 scapy.ICMP(type=icmp_type, code=icmp_code)
123
124 pkt = pkt/("0" * (pktlen - len(pkt)))
125
126 return pkt
127
Dan Talayco41eae8b2010-03-10 13:57:06 -0800128def do_barrier(ctrl):
129 b = message.barrier_request()
130 ctrl.transact(b)
Dan Talayco92c99122010-06-03 13:53:18 -0700131
132
133def port_config_get(controller, port_no, logger):
134 """
135 Get a port's configuration
136
137 Gets the switch feature configuration and grabs one port's
138 configuration
139
140 @returns (hwaddr, config, advert) The hwaddress, configuration and
141 advertised values
142 """
143 request = message.features_request()
144 reply, pkt = controller.transact(request, timeout=2)
145 logger.debug(reply.show())
146 if reply is None:
147 logger.warn("Get feature request failed")
148 return None, None, None
149 for idx in range(len(reply.ports)):
150 if reply.ports[idx].port_no == port_no:
151 return (reply.ports[idx].hw_addr, reply.ports[idx].config,
152 reply.ports[idx].advertised)
153
154 logger.warn("Did not find port number for port config")
155 return None, None, None
156
157def port_config_set(controller, port_no, config, mask, logger):
158 """
159 Set the port configuration according the given parameters
160
161 Gets the switch feature configuration and updates one port's
162 configuration value according to config and mask
163 """
164 logger.info("Setting port " + str(port_no) + " to config " + str(config))
165 request = message.features_request()
166 reply, pkt = controller.transact(request, timeout=2)
167 if reply is None:
168 return -1
169 logger.debug(reply.show())
170 for idx in range(len(reply.ports)):
171 if reply.ports[idx].port_no == port_no:
172 break
173 if idx >= len(reply.ports):
174 return -1
175 mod = message.port_mod()
176 mod.port_no = port_no
177 mod.hw_addr = reply.ports[idx].hw_addr
178 mod.config = config
179 mod.mask = mask
180 mod.advertise = reply.ports[idx].advertised
181 rv = controller.message_send(mod)
182 return rv
183
184def receive_pkt_check(dataplane, pkt, yes_ports, no_ports, assert_if, logger):
185 """
186 Check for proper receive packets across all ports
187 @param dataplane The dataplane object
188 @param pkt Expected packet; may be None if yes_ports is empty
189 @param yes_ports Set or list of ports that should recieve packet
190 @param no_ports Set or list of ports that should not receive packet
191 @param assert_if Object that implements assertXXX
192 """
193 for ofport in yes_ports:
194 logger.debug("Checking for pkt on port " + str(ofport))
195 (rcv_port, rcv_pkt, pkt_time) = dataplane.poll(
196 port_number=ofport, timeout=1)
197 assert_if.assertTrue(rcv_pkt is not None,
198 "Did not receive pkt on " + str(ofport))
199 assert_if.assertEqual(str(pkt), str(rcv_pkt),
200 "Response packet does not match send packet " +
201 "on port " + str(ofport))
202
203 for ofport in no_ports:
204 logger.debug("Negative check for pkt on port " + str(ofport))
205 (rcv_port, rcv_pkt, pkt_time) = dataplane.poll(
206 port_number=ofport, timeout=1)
207 assert_if.assertTrue(rcv_pkt is None,
208 "Unexpected pkt on port " + str(ofport))