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