blob: 0c45efdc2731c1044507cd6b8d20db020da025ee [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present 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;
Jian Lia78cdb22016-04-21 13:03:58 -070043import org.onosproject.openflow.controller.OpenFlowMessageListener;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.openflow.controller.OpenFlowPacketContext;
45import org.onosproject.openflow.controller.OpenFlowSwitch;
46import org.onosproject.openflow.controller.OpenFlowSwitchListener;
47import org.onosproject.openflow.controller.PacketListener;
48import org.onosproject.openflow.controller.RoleState;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070049import org.projectfloodlight.openflow.protocol.OFFactory;
50import org.projectfloodlight.openflow.protocol.OFMessage;
Jordi Ortizaa8de492016-12-01 00:21:36 +010051import org.projectfloodlight.openflow.protocol.OFMeterFeatures;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070052import org.projectfloodlight.openflow.protocol.OFPacketIn;
53import org.projectfloodlight.openflow.protocol.OFPacketInReason;
54import org.projectfloodlight.openflow.protocol.OFPortDesc;
55import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
56import org.projectfloodlight.openflow.types.MacAddress;
57import org.projectfloodlight.openflow.types.OFBufferId;
58import org.projectfloodlight.openflow.types.OFPort;
59
alshabibb452fd72015-04-22 20:46:20 -070060import java.nio.ByteBuffer;
61import java.util.ArrayList;
62import java.util.List;
63import java.util.Set;
Marc De Leenheer8aba62f2017-04-25 14:33:37 -070064import java.util.concurrent.CompletableFuture;
alshabibb452fd72015-04-22 20:46:20 -070065
66import static org.junit.Assert.*;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070067
68
69public class OpenFlowPacketProviderTest {
70
71 private static final int PN1 = 100;
72 private static final int PN2 = 200;
73 private static final int PN3 = 300;
74 private static final short VLANID = (short) 100;
75
76 private static final DeviceId DID = DeviceId.deviceId("of:1");
77 private static final DeviceId DID_MISSING = DeviceId.deviceId("of:2");
78 private static final DeviceId DID_WRONG = DeviceId.deviceId("test:1");
79 private static final PortNumber P1 = PortNumber.portNumber(PN1);
80 private static final PortNumber P2 = PortNumber.portNumber(PN2);
81 private static final PortNumber P3 = PortNumber.portNumber(PN3);
82
83 private static final Instruction INST1 = Instructions.createOutput(P1);
84 private static final Instruction INST2 = Instructions.createOutput(P2);
85 private static final Instruction INST3 = Instructions.createOutput(P3);
86
87 private static final OFPortDesc PD1 = portDesc(PN1);
88 private static final OFPortDesc PD2 = portDesc(PN2);
89
90 private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2);
91 private static final TrafficTreatment TR = treatment(INST1, INST2);
92 private static final TrafficTreatment TR_MISSING = treatment(INST1, INST3);
93
Jian Li68c4fc42016-01-11 16:07:03 -080094 private static final byte[] ANY = new byte[] {0, 0, 0, 0};
Yuta HIGUCHI10681f62014-09-21 17:49:46 -070095
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -070096 private final OpenFlowPacketProvider provider = new OpenFlowPacketProvider();
97 private final TestPacketRegistry registry = new TestPacketRegistry();
98 private final TestController controller = new TestController();
99
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700100 private final TestOpenFlowSwitch sw = new TestOpenFlowSwitch();
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700101
102 @Before
103 public void startUp() {
104 provider.providerRegistry = registry;
105 provider.controller = controller;
106 provider.activate();
107 assertNotNull("listener should be registered", registry.listener);
108 }
109
110 @After
111 public void teardown() {
112 provider.deactivate();
113 assertNull("listeners shouldn't be registered", registry.listener);
114 provider.controller = null;
115 provider.providerRegistry = null;
116 }
117
118 @Test(expected = IllegalArgumentException.class)
Ayaka Koshibe91c9bc72014-09-19 12:52:24 -0700119 public void wrongScheme() {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700120 sw.setRole(RoleState.MASTER);
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700121 OutboundPacket schemeFailPkt = outPacket(DID_WRONG, TR, null);
122 provider.emit(schemeFailPkt);
123 assertEquals("message sent incorrectly", 0, sw.sent.size());
124 }
125
126 @Test
127 public void emit() {
128
129 MacAddress mac1 = MacAddress.of("00:00:00:11:00:01");
130 MacAddress mac2 = MacAddress.of("00:00:00:22:00:02");
131
132 ARP arp = new ARP();
Yuta HIGUCHI10681f62014-09-21 17:49:46 -0700133 arp.setSenderProtocolAddress(ANY)
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700134 .setSenderHardwareAddress(mac1.getBytes())
135 .setTargetHardwareAddress(mac2.getBytes())
Yuta HIGUCHI10681f62014-09-21 17:49:46 -0700136 .setTargetProtocolAddress(ANY)
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700137 .setHardwareType((short) 0)
138 .setProtocolType((short) 0)
139 .setHardwareAddressLength((byte) 6)
140 .setProtocolAddressLength((byte) 4)
141 .setOpCode((byte) 0);
142
143 Ethernet eth = new Ethernet();
144 eth.setVlanID(VLANID)
145 .setEtherType(Ethernet.TYPE_ARP)
146 .setSourceMACAddress("00:00:00:11:00:01")
147 .setDestinationMACAddress("00:00:00:22:00:02")
148 .setPayload(arp);
149
150 //the should-be working setup.
151 OutboundPacket passPkt = outPacket(DID, TR, eth);
152 sw.setRole(RoleState.MASTER);
153 provider.emit(passPkt);
154 assertEquals("invalid switch", sw, controller.current);
155 assertEquals("message not sent", PLIST.size(), sw.sent.size());
156 sw.sent.clear();
157
158 //wrong Role
alshabib6eb438a2014-10-01 16:39:37 -0700159 //sw.setRole(RoleState.SLAVE);
160 //provider.emit(passPkt);
161 //assertEquals("invalid switch", sw, controller.current);
162 //assertEquals("message sent incorrectly", 0, sw.sent.size());
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700163
alshabib6eb438a2014-10-01 16:39:37 -0700164 //sw.setRole(RoleState.MASTER);
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700165
166 //missing switch
167 OutboundPacket swFailPkt = outPacket(DID_MISSING, TR, eth);
168 provider.emit(swFailPkt);
169 assertNull("invalid switch", controller.current);
170 assertEquals("message sent incorrectly", 0, sw.sent.size());
171
172 //to missing port
alshabibb5522ff2014-09-29 19:20:00 -0700173 //OutboundPacket portFailPkt = outPacket(DID, TR_MISSING, eth);
174 //provider.emit(portFailPkt);
175 //assertEquals("extra message sent", 1, sw.sent.size());
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700176
177 }
178
179 @Test
180 public void handlePacket() {
181 OFPacketIn pkt = sw.factory().buildPacketIn()
182 .setBufferId(OFBufferId.NO_BUFFER)
183 .setInPort(OFPort.NO_MASK)
184 .setReason(OFPacketInReason.INVALID_TTL)
185 .build();
186
187 controller.processPacket(null, pkt);
188 assertNotNull("message unprocessed", registry.ctx);
189
190 }
191
192 private static OFPortDesc portDesc(int port) {
193 OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc();
194 builder.setPortNo(OFPort.of(port));
195
196 return builder.build();
197 }
198
199 private static TrafficTreatment treatment(Instruction ... insts) {
tom9a693fd2014-10-03 11:32:19 -0700200 TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700201 for (Instruction i : insts) {
202 builder.add(i);
203 }
204 return builder.build();
205 }
206
207 private static OutboundPacket outPacket(
208 DeviceId d, TrafficTreatment t, Ethernet e) {
209 ByteBuffer buf = null;
210 if (e != null) {
211 buf = ByteBuffer.wrap(e.serialize());
212 }
213 return new DefaultOutboundPacket(d, t, buf);
214 }
215
216 private class TestPacketRegistry implements PacketProviderRegistry {
217
218 PacketProvider listener = null;
219 PacketContext ctx = null;
220
221 @Override
222 public PacketProviderService register(PacketProvider provider) {
223 listener = provider;
224 return new TestPacketProviderService();
225 }
226
227 @Override
228 public void unregister(PacketProvider provider) {
229 listener = null;
230 }
231
232 @Override
233 public Set<ProviderId> getProviders() {
234 return Sets.newHashSet(listener.id());
235 }
236
237 private class TestPacketProviderService implements PacketProviderService {
238
239 @Override
240 public PacketProvider provider() {
241 return null;
242 }
243
244 @Override
245 public void processPacket(PacketContext context) {
246 ctx = context;
247 }
248
249 }
250 }
251
252 private class TestController implements OpenFlowController {
253
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700254 PacketListener pktListener;
255 OpenFlowSwitch current;
256
257 @Override
258 public Iterable<OpenFlowSwitch> getSwitches() {
259 return null;
260 }
261
262 @Override
263 public Iterable<OpenFlowSwitch> getMasterSwitches() {
264 return null;
265 }
266
267 @Override
268 public Iterable<OpenFlowSwitch> getEqualSwitches() {
269 return null;
270 }
271
272 @Override
273 public OpenFlowSwitch getSwitch(Dpid dpid) {
274 if (dpid.equals(Dpid.dpid(DID.uri()))) {
275 current = sw;
276 } else {
277 current = null;
278 }
279 return current;
280 }
281
282 @Override
283 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
284 return null;
285 }
286
287 @Override
288 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
289 return null;
290 }
291
292 @Override
293 public void addListener(OpenFlowSwitchListener listener) {
294 }
295
296 @Override
297 public void removeListener(OpenFlowSwitchListener listener) {
298 }
299
300 @Override
Jian Lia78cdb22016-04-21 13:03:58 -0700301 public void addMessageListener(OpenFlowMessageListener listener) {
302
303 }
304
305 @Override
306 public void removeMessageListener(OpenFlowMessageListener listener) {
307
308 }
309
310 @Override
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700311 public void addPacketListener(int priority, PacketListener listener) {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700312 pktListener = listener;
313 }
314
315 @Override
316 public void removePacketListener(PacketListener listener) {
317 }
318
319 @Override
320 public void addEventListener(OpenFlowEventListener listener) {
321 }
322
323 @Override
324 public void removeEventListener(OpenFlowEventListener listener) {
325 }
326
327 @Override
328 public void write(Dpid dpid, OFMessage msg) {
329 }
330
331 @Override
Marc De Leenheer8aba62f2017-04-25 14:33:37 -0700332 public CompletableFuture<OFMessage> writeResponse(Dpid dpid, OFMessage msg) {
333 return null;
334 }
335
336 @Override
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700337 public void processPacket(Dpid dpid, OFMessage msg) {
338 OpenFlowPacketContext pktCtx =
339 DefaultOpenFlowPacketContext.
340 packetContextFromPacketIn(sw, (OFPacketIn) msg);
341 pktListener.handlePacket(pktCtx);
342 }
343
344 @Override
345 public void setRole(Dpid dpid, RoleState role) {
346 }
347
348 }
349
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700350 private class TestOpenFlowSwitch implements OpenFlowSwitch {
351
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700352 RoleState state;
353 List<OFMessage> sent = new ArrayList<OFMessage>();
354 OFFactory factory = OFFactoryVer10.INSTANCE;
355
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700356 @Override
357 public void sendMsg(OFMessage msg) {
358 sent.add(msg);
359 }
360
361 @Override
362 public void sendMsg(List<OFMessage> msgs) {
363 }
364
365 @Override
366 public void handleMessage(OFMessage fromSwitch) {
367 }
368
369 @Override
370 public void setRole(RoleState role) {
371 state = role;
372 }
373
374 @Override
375 public RoleState getRole() {
376 return state;
377 }
378
379 @Override
380 public List<OFPortDesc> getPorts() {
Ayaka Koshibe0380d4c2014-09-19 16:03:07 -0700381 return PLIST;
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700382 }
383
384 @Override
Jordi Ortizaa8de492016-12-01 00:21:36 +0100385 public OFMeterFeatures getMeterFeatures() {
386 return null;
387 }
388
389 @Override
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700390 public OFFactory factory() {
391 return factory;
392 }
393
394 @Override
395 public String getStringId() {
396 return null;
397 }
398
399 @Override
400 public long getId() {
401 return 0;
402 }
403
404 @Override
Ray Milkeyd3edd032015-01-16 11:38:58 -0800405 public String manufacturerDescription() {
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700406 return null;
407 }
408
409 @Override
410 public String datapathDescription() {
411 return null;
412 }
413
414 @Override
415 public String hardwareDescription() {
416 return null;
417 }
418
419 @Override
420 public String softwareDescription() {
421 return null;
422 }
423
424 @Override
425 public String serialNumber() {
426 return null;
427 }
428
429 @Override
Yuta HIGUCHI69a27352014-10-31 15:48:37 -0700430 public boolean isConnected() {
431 return true;
432 }
433
434 @Override
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700435 public void disconnectSwitch() {
436 }
437
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700438 @Override
Ayaka Koshibe3ef2b0d2014-10-31 13:58:27 -0700439 public void returnRoleReply(RoleState requested, RoleState reponse) {
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700440 }
Marc De Leenheerb9311372015-07-09 11:36:49 -0700441 @Override
442 public Device.Type deviceType() {
443 return Device.Type.SWITCH;
444 }
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700445
Ray Milkeye53f1712015-01-16 09:17:16 -0800446 @Override
447 public String channelId() {
448 return "1.2.3.4:1";
449 }
Ayaka Koshibe96ca09d2014-09-19 12:06:14 -0700450 }
451
452}