blob: 16be5304d2031e46d1cd2822e1e5253cced61715 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.of.packet.impl;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070017
alshabibb452fd72015-04-22 20:46:20 -070018import com.google.common.collect.Lists;
19import com.google.common.collect.Sets;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070020import org.junit.After;
21import org.junit.Before;
22import org.junit.Test;
alshabibb452fd72015-04-22 20:46:20 -070023import org.onlab.packet.ARP;
24import org.onlab.packet.Ethernet;
Marc De Leenheerb9311372015-07-09 11:36:49 -070025import org.onosproject.net.Device;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.net.DeviceId;
27import org.onosproject.net.PortNumber;
28import org.onosproject.net.flow.DefaultTrafficTreatment;
29import org.onosproject.net.flow.TrafficTreatment;
30import org.onosproject.net.flow.instructions.Instruction;
31import org.onosproject.net.flow.instructions.Instructions;
32import org.onosproject.net.packet.DefaultOutboundPacket;
33import org.onosproject.net.packet.OutboundPacket;
34import org.onosproject.net.packet.PacketContext;
35import org.onosproject.net.packet.PacketProvider;
36import org.onosproject.net.packet.PacketProviderRegistry;
37import org.onosproject.net.packet.PacketProviderService;
38import org.onosproject.net.provider.ProviderId;
39import org.onosproject.openflow.controller.DefaultOpenFlowPacketContext;
40import org.onosproject.openflow.controller.Dpid;
41import org.onosproject.openflow.controller.OpenFlowController;
42import org.onosproject.openflow.controller.OpenFlowEventListener;
43import org.onosproject.openflow.controller.OpenFlowPacketContext;
44import org.onosproject.openflow.controller.OpenFlowSwitch;
45import org.onosproject.openflow.controller.OpenFlowSwitchListener;
46import org.onosproject.openflow.controller.PacketListener;
47import org.onosproject.openflow.controller.RoleState;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070048import org.projectfloodlight.openflow.protocol.OFFactory;
49import org.projectfloodlight.openflow.protocol.OFMessage;
50import org.projectfloodlight.openflow.protocol.OFPacketIn;
51import org.projectfloodlight.openflow.protocol.OFPacketInReason;
52import org.projectfloodlight.openflow.protocol.OFPortDesc;
53import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
54import org.projectfloodlight.openflow.types.MacAddress;
55import org.projectfloodlight.openflow.types.OFBufferId;
56import org.projectfloodlight.openflow.types.OFPort;
57
alshabibb452fd72015-04-22 20:46:20 -070058import java.nio.ByteBuffer;
59import java.util.ArrayList;
60import java.util.List;
61import java.util.Set;
62
63import static org.junit.Assert.*;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070064
65
66public class OpenFlowPacketProviderTest {
67
68 private static final int PN1 = 100;
69 private static final int PN2 = 200;
70 private static final int PN3 = 300;
71 private static final short VLANID = (short) 100;
72
73 private static final DeviceId DID = DeviceId.deviceId("of:1");
74 private static final DeviceId DID_MISSING = DeviceId.deviceId("of:2");
75 private static final DeviceId DID_WRONG = DeviceId.deviceId("test:1");
76 private static final PortNumber P1 = PortNumber.portNumber(PN1);
77 private static final PortNumber P2 = PortNumber.portNumber(PN2);
78 private static final PortNumber P3 = PortNumber.portNumber(PN3);
79
80 private static final Instruction INST1 = Instructions.createOutput(P1);
81 private static final Instruction INST2 = Instructions.createOutput(P2);
82 private static final Instruction INST3 = Instructions.createOutput(P3);
83
84 private static final OFPortDesc PD1 = portDesc(PN1);
85 private static final OFPortDesc PD2 = portDesc(PN2);
86
87 private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2);
88 private static final TrafficTreatment TR = treatment(INST1, INST2);
89 private static final TrafficTreatment TR_MISSING = treatment(INST1, INST3);
90
Jian Li68c4fc42016-01-11 16:07:03 -080091 private static final byte[] ANY = new byte[] {0, 0, 0, 0};
Yuta HIGUCHI10681f62014-09-21 17:49:46 -070092
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070093 private final OpenFlowPacketProvider provider = new OpenFlowPacketProvider();
94 private final TestPacketRegistry registry = new TestPacketRegistry();
95 private final TestController controller = new TestController();
96
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -070097 private final TestOpenFlowSwitch sw = new TestOpenFlowSwitch();
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070098
99 @Before
100 public void startUp() {
101 provider.providerRegistry = registry;
102 provider.controller = controller;
103 provider.activate();
104 assertNotNull("listener should be registered", registry.listener);
105 }
106
107 @After
108 public void teardown() {
109 provider.deactivate();
110 assertNull("listeners shouldn't be registered", registry.listener);
111 provider.controller = null;
112 provider.providerRegistry = null;
113 }
114
115 @Test(expected = IllegalArgumentException.class)
Ayaka Koshibe91c9bc72014-09-19 12:52:24 -0700116 public void wrongScheme() {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700117 sw.setRole(RoleState.MASTER);
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700118 OutboundPacket schemeFailPkt = outPacket(DID_WRONG, TR, null);
119 provider.emit(schemeFailPkt);
120 assertEquals("message sent incorrectly", 0, sw.sent.size());
121 }
122
123 @Test
124 public void emit() {
125
126 MacAddress mac1 = MacAddress.of("00:00:00:11:00:01");
127 MacAddress mac2 = MacAddress.of("00:00:00:22:00:02");
128
129 ARP arp = new ARP();
Yuta HIGUCHI10681f62014-09-21 17:49:46 -0700130 arp.setSenderProtocolAddress(ANY)
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700131 .setSenderHardwareAddress(mac1.getBytes())
132 .setTargetHardwareAddress(mac2.getBytes())
Yuta HIGUCHI10681f62014-09-21 17:49:46 -0700133 .setTargetProtocolAddress(ANY)
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700134 .setHardwareType((short) 0)
135 .setProtocolType((short) 0)
136 .setHardwareAddressLength((byte) 6)
137 .setProtocolAddressLength((byte) 4)
138 .setOpCode((byte) 0);
139
140 Ethernet eth = new Ethernet();
141 eth.setVlanID(VLANID)
142 .setEtherType(Ethernet.TYPE_ARP)
143 .setSourceMACAddress("00:00:00:11:00:01")
144 .setDestinationMACAddress("00:00:00:22:00:02")
145 .setPayload(arp);
146
147 //the should-be working setup.
148 OutboundPacket passPkt = outPacket(DID, TR, eth);
149 sw.setRole(RoleState.MASTER);
150 provider.emit(passPkt);
151 assertEquals("invalid switch", sw, controller.current);
152 assertEquals("message not sent", PLIST.size(), sw.sent.size());
153 sw.sent.clear();
154
155 //wrong Role
alshabib6eb438a2014-10-01 16:39:37 -0700156 //sw.setRole(RoleState.SLAVE);
157 //provider.emit(passPkt);
158 //assertEquals("invalid switch", sw, controller.current);
159 //assertEquals("message sent incorrectly", 0, sw.sent.size());
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700160
alshabib6eb438a2014-10-01 16:39:37 -0700161 //sw.setRole(RoleState.MASTER);
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700162
163 //missing switch
164 OutboundPacket swFailPkt = outPacket(DID_MISSING, TR, eth);
165 provider.emit(swFailPkt);
166 assertNull("invalid switch", controller.current);
167 assertEquals("message sent incorrectly", 0, sw.sent.size());
168
169 //to missing port
alshabibb5522ff2014-09-29 19:20:00 -0700170 //OutboundPacket portFailPkt = outPacket(DID, TR_MISSING, eth);
171 //provider.emit(portFailPkt);
172 //assertEquals("extra message sent", 1, sw.sent.size());
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700173
174 }
175
176 @Test
177 public void handlePacket() {
178 OFPacketIn pkt = sw.factory().buildPacketIn()
179 .setBufferId(OFBufferId.NO_BUFFER)
180 .setInPort(OFPort.NO_MASK)
181 .setReason(OFPacketInReason.INVALID_TTL)
182 .build();
183
184 controller.processPacket(null, pkt);
185 assertNotNull("message unprocessed", registry.ctx);
186
187 }
188
189 private static OFPortDesc portDesc(int port) {
190 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
191 builder.setPortNo(OFPort.of(port));
192
193 return builder.build();
194 }
195
196 private static TrafficTreatment treatment(Instruction ... insts) {
tom9a693fd2014-10-03 11:32:19 -0700197 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700198 for (Instruction i : insts) {
199 builder.add(i);
200 }
201 return builder.build();
202 }
203
204 private static OutboundPacket outPacket(
205 DeviceId d, TrafficTreatment t, Ethernet e) {
206 ByteBuffer buf = null;
207 if (e != null) {
208 buf = ByteBuffer.wrap(e.serialize());
209 }
210 return new DefaultOutboundPacket(d, t, buf);
211 }
212
213 private class TestPacketRegistry implements PacketProviderRegistry {
214
215 PacketProvider listener = null;
216 PacketContext ctx = null;
217
218 @Override
219 public PacketProviderService register(PacketProvider provider) {
220 listener = provider;
221 return new TestPacketProviderService();
222 }
223
224 @Override
225 public void unregister(PacketProvider provider) {
226 listener = null;
227 }
228
229 @Override
230 public Set<ProviderId> getProviders() {
231 return Sets.newHashSet(listener.id());
232 }
233
234 private class TestPacketProviderService implements PacketProviderService {
235
236 @Override
237 public PacketProvider provider() {
238 return null;
239 }
240
241 @Override
242 public void processPacket(PacketContext context) {
243 ctx = context;
244 }
245
246 }
247 }
248
249 private class TestController implements OpenFlowController {
250
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700251 PacketListener pktListener;
252 OpenFlowSwitch current;
253
254 @Override
255 public Iterable<OpenFlowSwitch> getSwitches() {
256 return null;
257 }
258
259 @Override
260 public Iterable<OpenFlowSwitch> getMasterSwitches() {
261 return null;
262 }
263
264 @Override
265 public Iterable<OpenFlowSwitch> getEqualSwitches() {
266 return null;
267 }
268
269 @Override
270 public OpenFlowSwitch getSwitch(Dpid dpid) {
271 if (dpid.equals(Dpid.dpid(DID.uri()))) {
272 current = sw;
273 } else {
274 current = null;
275 }
276 return current;
277 }
278
279 @Override
280 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
281 return null;
282 }
283
284 @Override
285 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
286 return null;
287 }
288
289 @Override
Jian Li28247b52016-01-07 17:24:15 -0800290 public void monitorAllEvents(boolean monitor) {
291 }
292
293 @Override
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700294 public void addListener(OpenFlowSwitchListener listener) {
295 }
296
297 @Override
298 public void removeListener(OpenFlowSwitchListener listener) {
299 }
300
301 @Override
302 public void addPacketListener(int priority, PacketListener listener) {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700303 pktListener = listener;
304 }
305
306 @Override
307 public void removePacketListener(PacketListener listener) {
308 }
309
310 @Override
311 public void addEventListener(OpenFlowEventListener listener) {
312 }
313
314 @Override
315 public void removeEventListener(OpenFlowEventListener listener) {
316 }
317
318 @Override
319 public void write(Dpid dpid, OFMessage msg) {
320 }
321
322 @Override
323 public void processPacket(Dpid dpid, OFMessage msg) {
324 OpenFlowPacketContext pktCtx =
325 DefaultOpenFlowPacketContext.
326 packetContextFromPacketIn(sw, (OFPacketIn) msg);
327 pktListener.handlePacket(pktCtx);
328 }
329
330 @Override
331 public void setRole(Dpid dpid, RoleState role) {
332 }
333
334 }
335
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700336 private class TestOpenFlowSwitch implements OpenFlowSwitch {
337
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700338 RoleState state;
339 List<OFMessage> sent = new ArrayList<OFMessage>();
340 OFFactory factory = OFFactoryVer10.INSTANCE;
341
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700342 @Override
343 public void sendMsg(OFMessage msg) {
344 sent.add(msg);
345 }
346
347 @Override
348 public void sendMsg(List<OFMessage> msgs) {
349 }
350
351 @Override
352 public void handleMessage(OFMessage fromSwitch) {
353 }
354
355 @Override
356 public void setRole(RoleState role) {
357 state = role;
358 }
359
360 @Override
361 public RoleState getRole() {
362 return state;
363 }
364
365 @Override
366 public List<OFPortDesc> getPorts() {
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700367 return PLIST;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700368 }
369
370 @Override
371 public OFFactory factory() {
372 return factory;
373 }
374
375 @Override
376 public String getStringId() {
377 return null;
378 }
379
380 @Override
381 public long getId() {
382 return 0;
383 }
384
385 @Override
Ray Milkeyd3edd032015-01-16 11:38:58 -0800386 public String manufacturerDescription() {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700387 return null;
388 }
389
390 @Override
391 public String datapathDescription() {
392 return null;
393 }
394
395 @Override
396 public String hardwareDescription() {
397 return null;
398 }
399
400 @Override
401 public String softwareDescription() {
402 return null;
403 }
404
405 @Override
406 public String serialNumber() {
407 return null;
408 }
409
410 @Override
Yuta HIGUCHI69a27352014-10-31 15:48:37 -0700411 public boolean isConnected() {
412 return true;
413 }
414
415 @Override
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700416 public void disconnectSwitch() {
417 }
418
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700419 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700420 public void returnRoleReply(RoleState requested, RoleState reponse) {
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700421 }
Marc De Leenheerb9311372015-07-09 11:36:49 -0700422 @Override
423 public Device.Type deviceType() {
424 return Device.Type.SWITCH;
425 }
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700426
Ray Milkeye53f1712015-01-16 09:17:16 -0800427 @Override
428 public String channelId() {
429 return "1.2.3.4:1";
430 }
431
Jian Li152b8852015-12-07 14:47:25 -0800432 @Override
433 public void addEventListener(OpenFlowEventListener listener) {
434 }
435
436 @Override
437 public void removeEventListener(OpenFlowEventListener listener) {
438 }
439
Saurav Dasfa2fa932015-03-03 11:29:48 -0800440
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700441 }
442
443}