blob: 43c10516c285fd4d9920e78dfb80c982531369cb [file] [log] [blame]
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -07001package org.onlab.onos.provider.of.packet.impl;
2
3import static org.junit.Assert.assertEquals;
4import static org.junit.Assert.assertNotNull;
5import static org.junit.Assert.assertNull;
6
7import java.nio.ByteBuffer;
8import java.util.ArrayList;
9import java.util.List;
10import java.util.Set;
11
12import org.junit.After;
13import org.junit.Before;
14import org.junit.Test;
15import org.onlab.onos.net.DeviceId;
16import org.onlab.onos.net.PortNumber;
17import org.onlab.onos.net.flow.DefaultTrafficTreatment;
18import org.onlab.onos.net.flow.TrafficTreatment;
19import org.onlab.onos.net.flow.instructions.Instruction;
20import org.onlab.onos.net.flow.instructions.Instructions;
21import org.onlab.onos.net.packet.DefaultOutboundPacket;
22import org.onlab.onos.net.packet.OutboundPacket;
23import org.onlab.onos.net.packet.PacketContext;
24import org.onlab.onos.net.packet.PacketProvider;
25import org.onlab.onos.net.packet.PacketProviderRegistry;
26import org.onlab.onos.net.packet.PacketProviderService;
27import org.onlab.onos.net.provider.ProviderId;
28import org.onlab.onos.openflow.controller.DefaultOpenFlowPacketContext;
29import org.onlab.onos.openflow.controller.Dpid;
30import org.onlab.onos.openflow.controller.OpenFlowController;
31import org.onlab.onos.openflow.controller.OpenFlowEventListener;
32import org.onlab.onos.openflow.controller.OpenFlowPacketContext;
33import org.onlab.onos.openflow.controller.OpenFlowSwitch;
34import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
35import org.onlab.onos.openflow.controller.PacketListener;
36import org.onlab.onos.openflow.controller.RoleState;
37import org.onlab.packet.ARP;
38import org.onlab.packet.Ethernet;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070039import org.projectfloodlight.openflow.protocol.OFFactory;
40import org.projectfloodlight.openflow.protocol.OFMessage;
41import org.projectfloodlight.openflow.protocol.OFPacketIn;
42import org.projectfloodlight.openflow.protocol.OFPacketInReason;
43import org.projectfloodlight.openflow.protocol.OFPortDesc;
44import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
45import org.projectfloodlight.openflow.types.MacAddress;
46import org.projectfloodlight.openflow.types.OFBufferId;
47import org.projectfloodlight.openflow.types.OFPort;
48
49import com.google.common.collect.Lists;
50import com.google.common.collect.Sets;
51
52
53public class OpenFlowPacketProviderTest {
54
55 private static final int PN1 = 100;
56 private static final int PN2 = 200;
57 private static final int PN3 = 300;
58 private static final short VLANID = (short) 100;
59
60 private static final DeviceId DID = DeviceId.deviceId("of:1");
61 private static final DeviceId DID_MISSING = DeviceId.deviceId("of:2");
62 private static final DeviceId DID_WRONG = DeviceId.deviceId("test:1");
63 private static final PortNumber P1 = PortNumber.portNumber(PN1);
64 private static final PortNumber P2 = PortNumber.portNumber(PN2);
65 private static final PortNumber P3 = PortNumber.portNumber(PN3);
66
67 private static final Instruction INST1 = Instructions.createOutput(P1);
68 private static final Instruction INST2 = Instructions.createOutput(P2);
69 private static final Instruction INST3 = Instructions.createOutput(P3);
70
71 private static final OFPortDesc PD1 = portDesc(PN1);
72 private static final OFPortDesc PD2 = portDesc(PN2);
73
74 private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2);
75 private static final TrafficTreatment TR = treatment(INST1, INST2);
76 private static final TrafficTreatment TR_MISSING = treatment(INST1, INST3);
77
Yuta HIGUCHI10681f62014-09-21 17:49:46 -070078 private static final byte[] ANY = new byte [] {0, 0, 0, 0};
79
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070080 private final OpenFlowPacketProvider provider = new OpenFlowPacketProvider();
81 private final TestPacketRegistry registry = new TestPacketRegistry();
82 private final TestController controller = new TestController();
83
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070084 private final TestOpenFlowSwitch sw = new TestOpenFlowSwitch();
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070085
86 @Before
87 public void startUp() {
88 provider.providerRegistry = registry;
89 provider.controller = controller;
90 provider.activate();
91 assertNotNull("listener should be registered", registry.listener);
92 }
93
94 @After
95 public void teardown() {
96 provider.deactivate();
97 assertNull("listeners shouldn't be registered", registry.listener);
98 provider.controller = null;
99 provider.providerRegistry = null;
100 }
101
102 @Test(expected = IllegalArgumentException.class)
Ayaka Koshibe91c9bc72014-09-19 12:52:24 -0700103 public void wrongScheme() {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700104 sw.setRole(RoleState.MASTER);
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700105 OutboundPacket schemeFailPkt = outPacket(DID_WRONG, TR, null);
106 provider.emit(schemeFailPkt);
107 assertEquals("message sent incorrectly", 0, sw.sent.size());
108 }
109
110 @Test
111 public void emit() {
112
113 MacAddress mac1 = MacAddress.of("00:00:00:11:00:01");
114 MacAddress mac2 = MacAddress.of("00:00:00:22:00:02");
115
116 ARP arp = new ARP();
Yuta HIGUCHI10681f62014-09-21 17:49:46 -0700117 arp.setSenderProtocolAddress(ANY)
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700118 .setSenderHardwareAddress(mac1.getBytes())
119 .setTargetHardwareAddress(mac2.getBytes())
Yuta HIGUCHI10681f62014-09-21 17:49:46 -0700120 .setTargetProtocolAddress(ANY)
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700121 .setHardwareType((short) 0)
122 .setProtocolType((short) 0)
123 .setHardwareAddressLength((byte) 6)
124 .setProtocolAddressLength((byte) 4)
125 .setOpCode((byte) 0);
126
127 Ethernet eth = new Ethernet();
128 eth.setVlanID(VLANID)
129 .setEtherType(Ethernet.TYPE_ARP)
130 .setSourceMACAddress("00:00:00:11:00:01")
131 .setDestinationMACAddress("00:00:00:22:00:02")
132 .setPayload(arp);
133
134 //the should-be working setup.
135 OutboundPacket passPkt = outPacket(DID, TR, eth);
136 sw.setRole(RoleState.MASTER);
137 provider.emit(passPkt);
138 assertEquals("invalid switch", sw, controller.current);
139 assertEquals("message not sent", PLIST.size(), sw.sent.size());
140 sw.sent.clear();
141
142 //wrong Role
alshabib6eb438a2014-10-01 16:39:37 -0700143 //sw.setRole(RoleState.SLAVE);
144 //provider.emit(passPkt);
145 //assertEquals("invalid switch", sw, controller.current);
146 //assertEquals("message sent incorrectly", 0, sw.sent.size());
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700147
alshabib6eb438a2014-10-01 16:39:37 -0700148 //sw.setRole(RoleState.MASTER);
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700149
150 //missing switch
151 OutboundPacket swFailPkt = outPacket(DID_MISSING, TR, eth);
152 provider.emit(swFailPkt);
153 assertNull("invalid switch", controller.current);
154 assertEquals("message sent incorrectly", 0, sw.sent.size());
155
156 //to missing port
alshabibb5522ff2014-09-29 19:20:00 -0700157 //OutboundPacket portFailPkt = outPacket(DID, TR_MISSING, eth);
158 //provider.emit(portFailPkt);
159 //assertEquals("extra message sent", 1, sw.sent.size());
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700160
161 }
162
163 @Test
164 public void handlePacket() {
165 OFPacketIn pkt = sw.factory().buildPacketIn()
166 .setBufferId(OFBufferId.NO_BUFFER)
167 .setInPort(OFPort.NO_MASK)
168 .setReason(OFPacketInReason.INVALID_TTL)
169 .build();
170
171 controller.processPacket(null, pkt);
172 assertNotNull("message unprocessed", registry.ctx);
173
174 }
175
176 private static OFPortDesc portDesc(int port) {
177 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
178 builder.setPortNo(OFPort.of(port));
179
180 return builder.build();
181 }
182
183 private static TrafficTreatment treatment(Instruction ... insts) {
tom9a693fd2014-10-03 11:32:19 -0700184 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700185 for (Instruction i : insts) {
186 builder.add(i);
187 }
188 return builder.build();
189 }
190
191 private static OutboundPacket outPacket(
192 DeviceId d, TrafficTreatment t, Ethernet e) {
193 ByteBuffer buf = null;
194 if (e != null) {
195 buf = ByteBuffer.wrap(e.serialize());
196 }
197 return new DefaultOutboundPacket(d, t, buf);
198 }
199
200 private class TestPacketRegistry implements PacketProviderRegistry {
201
202 PacketProvider listener = null;
203 PacketContext ctx = null;
204
205 @Override
206 public PacketProviderService register(PacketProvider provider) {
207 listener = provider;
208 return new TestPacketProviderService();
209 }
210
211 @Override
212 public void unregister(PacketProvider provider) {
213 listener = null;
214 }
215
216 @Override
217 public Set<ProviderId> getProviders() {
218 return Sets.newHashSet(listener.id());
219 }
220
221 private class TestPacketProviderService implements PacketProviderService {
222
223 @Override
224 public PacketProvider provider() {
225 return null;
226 }
227
228 @Override
229 public void processPacket(PacketContext context) {
230 ctx = context;
231 }
232
233 }
234 }
235
236 private class TestController implements OpenFlowController {
237
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700238 PacketListener pktListener;
239 OpenFlowSwitch current;
240
241 @Override
242 public Iterable<OpenFlowSwitch> getSwitches() {
243 return null;
244 }
245
246 @Override
247 public Iterable<OpenFlowSwitch> getMasterSwitches() {
248 return null;
249 }
250
251 @Override
252 public Iterable<OpenFlowSwitch> getEqualSwitches() {
253 return null;
254 }
255
256 @Override
257 public OpenFlowSwitch getSwitch(Dpid dpid) {
258 if (dpid.equals(Dpid.dpid(DID.uri()))) {
259 current = sw;
260 } else {
261 current = null;
262 }
263 return current;
264 }
265
266 @Override
267 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
268 return null;
269 }
270
271 @Override
272 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
273 return null;
274 }
275
276 @Override
277 public void addListener(OpenFlowSwitchListener listener) {
278 }
279
280 @Override
281 public void removeListener(OpenFlowSwitchListener listener) {
282 }
283
284 @Override
285 public void addPacketListener(int priority, PacketListener listener) {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700286 pktListener = listener;
287 }
288
289 @Override
290 public void removePacketListener(PacketListener listener) {
291 }
292
293 @Override
294 public void addEventListener(OpenFlowEventListener listener) {
295 }
296
297 @Override
298 public void removeEventListener(OpenFlowEventListener listener) {
299 }
300
301 @Override
302 public void write(Dpid dpid, OFMessage msg) {
303 }
304
305 @Override
306 public void processPacket(Dpid dpid, OFMessage msg) {
307 OpenFlowPacketContext pktCtx =
308 DefaultOpenFlowPacketContext.
309 packetContextFromPacketIn(sw, (OFPacketIn) msg);
310 pktListener.handlePacket(pktCtx);
311 }
312
313 @Override
314 public void setRole(Dpid dpid, RoleState role) {
315 }
316
317 }
318
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700319 private class TestOpenFlowSwitch implements OpenFlowSwitch {
320
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700321 RoleState state;
322 List<OFMessage> sent = new ArrayList<OFMessage>();
323 OFFactory factory = OFFactoryVer10.INSTANCE;
324
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700325 @Override
326 public void sendMsg(OFMessage msg) {
327 sent.add(msg);
328 }
329
330 @Override
331 public void sendMsg(List<OFMessage> msgs) {
332 }
333
334 @Override
335 public void handleMessage(OFMessage fromSwitch) {
336 }
337
338 @Override
339 public void setRole(RoleState role) {
340 state = role;
341 }
342
343 @Override
344 public RoleState getRole() {
345 return state;
346 }
347
348 @Override
349 public List<OFPortDesc> getPorts() {
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700350 return PLIST;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700351 }
352
353 @Override
354 public OFFactory factory() {
355 return factory;
356 }
357
358 @Override
359 public String getStringId() {
360 return null;
361 }
362
363 @Override
364 public long getId() {
365 return 0;
366 }
367
368 @Override
369 public String manfacturerDescription() {
370 return null;
371 }
372
373 @Override
374 public String datapathDescription() {
375 return null;
376 }
377
378 @Override
379 public String hardwareDescription() {
380 return null;
381 }
382
383 @Override
384 public String softwareDescription() {
385 return null;
386 }
387
388 @Override
389 public String serialNumber() {
390 return null;
391 }
392
393 @Override
394 public void disconnectSwitch() {
395 }
396
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700397 @Override
398 public void returnRoleAssertFailure(RoleState role) {
399 }
400
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700401 @Override
402 public boolean isOptical() {
403 return false;
404 }
405
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700406 }
407
408}