blob: c27e0846bcc28c66f0b09b2b865ba417f7bcaf62 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070016package org.onlab.onos.provider.of.packet.impl;
17
18import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.assertNotNull;
20import static org.junit.Assert.assertNull;
21
22import java.nio.ByteBuffer;
23import java.util.ArrayList;
24import java.util.List;
25import java.util.Set;
26
27import org.junit.After;
28import org.junit.Before;
29import org.junit.Test;
30import org.onlab.onos.net.DeviceId;
31import org.onlab.onos.net.PortNumber;
32import org.onlab.onos.net.flow.DefaultTrafficTreatment;
33import org.onlab.onos.net.flow.TrafficTreatment;
34import org.onlab.onos.net.flow.instructions.Instruction;
35import org.onlab.onos.net.flow.instructions.Instructions;
36import org.onlab.onos.net.packet.DefaultOutboundPacket;
37import org.onlab.onos.net.packet.OutboundPacket;
38import org.onlab.onos.net.packet.PacketContext;
39import org.onlab.onos.net.packet.PacketProvider;
40import org.onlab.onos.net.packet.PacketProviderRegistry;
41import org.onlab.onos.net.packet.PacketProviderService;
42import org.onlab.onos.net.provider.ProviderId;
43import org.onlab.onos.openflow.controller.DefaultOpenFlowPacketContext;
44import org.onlab.onos.openflow.controller.Dpid;
45import org.onlab.onos.openflow.controller.OpenFlowController;
46import org.onlab.onos.openflow.controller.OpenFlowEventListener;
47import org.onlab.onos.openflow.controller.OpenFlowPacketContext;
48import org.onlab.onos.openflow.controller.OpenFlowSwitch;
49import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
50import org.onlab.onos.openflow.controller.PacketListener;
51import org.onlab.onos.openflow.controller.RoleState;
52import org.onlab.packet.ARP;
53import org.onlab.packet.Ethernet;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070054import org.projectfloodlight.openflow.protocol.OFFactory;
55import org.projectfloodlight.openflow.protocol.OFMessage;
56import org.projectfloodlight.openflow.protocol.OFPacketIn;
57import org.projectfloodlight.openflow.protocol.OFPacketInReason;
58import org.projectfloodlight.openflow.protocol.OFPortDesc;
59import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
60import org.projectfloodlight.openflow.types.MacAddress;
61import org.projectfloodlight.openflow.types.OFBufferId;
62import org.projectfloodlight.openflow.types.OFPort;
63
64import com.google.common.collect.Lists;
65import com.google.common.collect.Sets;
66
67
68public class OpenFlowPacketProviderTest {
69
70 private static final int PN1 = 100;
71 private static final int PN2 = 200;
72 private static final int PN3 = 300;
73 private static final short VLANID = (short) 100;
74
75 private static final DeviceId DID = DeviceId.deviceId("of:1");
76 private static final DeviceId DID_MISSING = DeviceId.deviceId("of:2");
77 private static final DeviceId DID_WRONG = DeviceId.deviceId("test:1");
78 private static final PortNumber P1 = PortNumber.portNumber(PN1);
79 private static final PortNumber P2 = PortNumber.portNumber(PN2);
80 private static final PortNumber P3 = PortNumber.portNumber(PN3);
81
82 private static final Instruction INST1 = Instructions.createOutput(P1);
83 private static final Instruction INST2 = Instructions.createOutput(P2);
84 private static final Instruction INST3 = Instructions.createOutput(P3);
85
86 private static final OFPortDesc PD1 = portDesc(PN1);
87 private static final OFPortDesc PD2 = portDesc(PN2);
88
89 private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2);
90 private static final TrafficTreatment TR = treatment(INST1, INST2);
91 private static final TrafficTreatment TR_MISSING = treatment(INST1, INST3);
92
Yuta HIGUCHI10681f62014-09-21 17:49:46 -070093 private static final byte[] ANY = new byte [] {0, 0, 0, 0};
94
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070095 private final OpenFlowPacketProvider provider = new OpenFlowPacketProvider();
96 private final TestPacketRegistry registry = new TestPacketRegistry();
97 private final TestController controller = new TestController();
98
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070099 private final TestOpenFlowSwitch sw = new TestOpenFlowSwitch();
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700100
101 @Before
102 public void startUp() {
103 provider.providerRegistry = registry;
104 provider.controller = controller;
105 provider.activate();
106 assertNotNull("listener should be registered", registry.listener);
107 }
108
109 @After
110 public void teardown() {
111 provider.deactivate();
112 assertNull("listeners shouldn't be registered", registry.listener);
113 provider.controller = null;
114 provider.providerRegistry = null;
115 }
116
117 @Test(expected = IllegalArgumentException.class)
Ayaka Koshibe91c9bc72014-09-19 12:52:24 -0700118 public void wrongScheme() {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700119 sw.setRole(RoleState.MASTER);
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700120 OutboundPacket schemeFailPkt = outPacket(DID_WRONG, TR, null);
121 provider.emit(schemeFailPkt);
122 assertEquals("message sent incorrectly", 0, sw.sent.size());
123 }
124
125 @Test
126 public void emit() {
127
128 MacAddress mac1 = MacAddress.of("00:00:00:11:00:01");
129 MacAddress mac2 = MacAddress.of("00:00:00:22:00:02");
130
131 ARP arp = new ARP();
Yuta HIGUCHI10681f62014-09-21 17:49:46 -0700132 arp.setSenderProtocolAddress(ANY)
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700133 .setSenderHardwareAddress(mac1.getBytes())
134 .setTargetHardwareAddress(mac2.getBytes())
Yuta HIGUCHI10681f62014-09-21 17:49:46 -0700135 .setTargetProtocolAddress(ANY)
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700136 .setHardwareType((short) 0)
137 .setProtocolType((short) 0)
138 .setHardwareAddressLength((byte) 6)
139 .setProtocolAddressLength((byte) 4)
140 .setOpCode((byte) 0);
141
142 Ethernet eth = new Ethernet();
143 eth.setVlanID(VLANID)
144 .setEtherType(Ethernet.TYPE_ARP)
145 .setSourceMACAddress("00:00:00:11:00:01")
146 .setDestinationMACAddress("00:00:00:22:00:02")
147 .setPayload(arp);
148
149 //the should-be working setup.
150 OutboundPacket passPkt = outPacket(DID, TR, eth);
151 sw.setRole(RoleState.MASTER);
152 provider.emit(passPkt);
153 assertEquals("invalid switch", sw, controller.current);
154 assertEquals("message not sent", PLIST.size(), sw.sent.size());
155 sw.sent.clear();
156
157 //wrong Role
alshabib6eb438a2014-10-01 16:39:37 -0700158 //sw.setRole(RoleState.SLAVE);
159 //provider.emit(passPkt);
160 //assertEquals("invalid switch", sw, controller.current);
161 //assertEquals("message sent incorrectly", 0, sw.sent.size());
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700162
alshabib6eb438a2014-10-01 16:39:37 -0700163 //sw.setRole(RoleState.MASTER);
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700164
165 //missing switch
166 OutboundPacket swFailPkt = outPacket(DID_MISSING, TR, eth);
167 provider.emit(swFailPkt);
168 assertNull("invalid switch", controller.current);
169 assertEquals("message sent incorrectly", 0, sw.sent.size());
170
171 //to missing port
alshabibb5522ff2014-09-29 19:20:00 -0700172 //OutboundPacket portFailPkt = outPacket(DID, TR_MISSING, eth);
173 //provider.emit(portFailPkt);
174 //assertEquals("extra message sent", 1, sw.sent.size());
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700175
176 }
177
178 @Test
179 public void handlePacket() {
180 OFPacketIn pkt = sw.factory().buildPacketIn()
181 .setBufferId(OFBufferId.NO_BUFFER)
182 .setInPort(OFPort.NO_MASK)
183 .setReason(OFPacketInReason.INVALID_TTL)
184 .build();
185
186 controller.processPacket(null, pkt);
187 assertNotNull("message unprocessed", registry.ctx);
188
189 }
190
191 private static OFPortDesc portDesc(int port) {
192 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
193 builder.setPortNo(OFPort.of(port));
194
195 return builder.build();
196 }
197
198 private static TrafficTreatment treatment(Instruction ... insts) {
tom9a693fd2014-10-03 11:32:19 -0700199 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700200 for (Instruction i : insts) {
201 builder.add(i);
202 }
203 return builder.build();
204 }
205
206 private static OutboundPacket outPacket(
207 DeviceId d, TrafficTreatment t, Ethernet e) {
208 ByteBuffer buf = null;
209 if (e != null) {
210 buf = ByteBuffer.wrap(e.serialize());
211 }
212 return new DefaultOutboundPacket(d, t, buf);
213 }
214
215 private class TestPacketRegistry implements PacketProviderRegistry {
216
217 PacketProvider listener = null;
218 PacketContext ctx = null;
219
220 @Override
221 public PacketProviderService register(PacketProvider provider) {
222 listener = provider;
223 return new TestPacketProviderService();
224 }
225
226 @Override
227 public void unregister(PacketProvider provider) {
228 listener = null;
229 }
230
231 @Override
232 public Set<ProviderId> getProviders() {
233 return Sets.newHashSet(listener.id());
234 }
235
236 private class TestPacketProviderService implements PacketProviderService {
237
238 @Override
239 public PacketProvider provider() {
240 return null;
241 }
242
243 @Override
244 public void processPacket(PacketContext context) {
245 ctx = context;
246 }
247
248 }
249 }
250
251 private class TestController implements OpenFlowController {
252
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700253 PacketListener pktListener;
254 OpenFlowSwitch current;
255
256 @Override
257 public Iterable<OpenFlowSwitch> getSwitches() {
258 return null;
259 }
260
261 @Override
262 public Iterable<OpenFlowSwitch> getMasterSwitches() {
263 return null;
264 }
265
266 @Override
267 public Iterable<OpenFlowSwitch> getEqualSwitches() {
268 return null;
269 }
270
271 @Override
272 public OpenFlowSwitch getSwitch(Dpid dpid) {
273 if (dpid.equals(Dpid.dpid(DID.uri()))) {
274 current = sw;
275 } else {
276 current = null;
277 }
278 return current;
279 }
280
281 @Override
282 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
283 return null;
284 }
285
286 @Override
287 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
288 return null;
289 }
290
291 @Override
292 public void addListener(OpenFlowSwitchListener listener) {
293 }
294
295 @Override
296 public void removeListener(OpenFlowSwitchListener listener) {
297 }
298
299 @Override
300 public void addPacketListener(int priority, PacketListener listener) {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700301 pktListener = listener;
302 }
303
304 @Override
305 public void removePacketListener(PacketListener listener) {
306 }
307
308 @Override
309 public void addEventListener(OpenFlowEventListener listener) {
310 }
311
312 @Override
313 public void removeEventListener(OpenFlowEventListener listener) {
314 }
315
316 @Override
317 public void write(Dpid dpid, OFMessage msg) {
318 }
319
320 @Override
321 public void processPacket(Dpid dpid, OFMessage msg) {
322 OpenFlowPacketContext pktCtx =
323 DefaultOpenFlowPacketContext.
324 packetContextFromPacketIn(sw, (OFPacketIn) msg);
325 pktListener.handlePacket(pktCtx);
326 }
327
328 @Override
329 public void setRole(Dpid dpid, RoleState role) {
330 }
331
332 }
333
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700334 private class TestOpenFlowSwitch implements OpenFlowSwitch {
335
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700336 RoleState state;
337 List<OFMessage> sent = new ArrayList<OFMessage>();
338 OFFactory factory = OFFactoryVer10.INSTANCE;
339
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700340 @Override
341 public void sendMsg(OFMessage msg) {
342 sent.add(msg);
343 }
344
345 @Override
346 public void sendMsg(List<OFMessage> msgs) {
347 }
348
349 @Override
350 public void handleMessage(OFMessage fromSwitch) {
351 }
352
353 @Override
354 public void setRole(RoleState role) {
355 state = role;
356 }
357
358 @Override
359 public RoleState getRole() {
360 return state;
361 }
362
363 @Override
364 public List<OFPortDesc> getPorts() {
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700365 return PLIST;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700366 }
367
368 @Override
369 public OFFactory factory() {
370 return factory;
371 }
372
373 @Override
374 public String getStringId() {
375 return null;
376 }
377
378 @Override
379 public long getId() {
380 return 0;
381 }
382
383 @Override
384 public String manfacturerDescription() {
385 return null;
386 }
387
388 @Override
389 public String datapathDescription() {
390 return null;
391 }
392
393 @Override
394 public String hardwareDescription() {
395 return null;
396 }
397
398 @Override
399 public String softwareDescription() {
400 return null;
401 }
402
403 @Override
404 public String serialNumber() {
405 return null;
406 }
407
408 @Override
Yuta HIGUCHI69a27352014-10-31 15:48:37 -0700409 public boolean isConnected() {
410 return true;
411 }
412
413 @Override
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700414 public void disconnectSwitch() {
415 }
416
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700417 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700418 public boolean isOptical() {
419 return false;
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700420 }
421
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700422 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700423 public void returnRoleReply(RoleState requested, RoleState reponse) {
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700424 }
425
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700426 }
427
428}