blob: a17a0dbb97da4ef6caf897d4a7bb6084dc951a08 [file] [log] [blame]
yoonseon5a51ef72016-10-26 14:50:09 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
yoonseon5a51ef72016-10-26 14:50:09 -07003 *
4 * 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
7 *
8 * 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.
15 */
16
17package org.onosproject.incubator.net.virtual.impl.provider;
18
19import com.google.common.collect.ImmutableSet;
20import org.junit.After;
21import org.junit.Before;
22import org.junit.Test;
yoonseon5a51ef72016-10-26 14:50:09 -070023import org.onlab.packet.Ethernet;
yoonseon5a51ef72016-10-26 14:50:09 -070024import org.onlab.packet.VlanId;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreServiceAdapter;
27import org.onosproject.core.DefaultApplicationId;
28import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
29import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
30import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
31import org.onosproject.incubator.net.virtual.NetworkId;
Thomas Vachuska52f2cd12018-11-08 21:20:04 -080032import org.onosproject.net.TenantId;
yoonseon5a51ef72016-10-26 14:50:09 -070033import org.onosproject.incubator.net.virtual.VirtualDevice;
yoonseon5a51ef72016-10-26 14:50:09 -070034import org.onosproject.incubator.net.virtual.VirtualNetwork;
Yoonseon Hanffcc32f2017-05-03 14:42:17 -070035import org.onosproject.incubator.net.virtual.VirtualNetworkAdminServiceAdapter;
yoonseon5a51ef72016-10-26 14:50:09 -070036import org.onosproject.incubator.net.virtual.VirtualPort;
yoonseon736a73b2017-01-26 14:27:48 -080037import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
yoonseon5a51ef72016-10-26 14:50:09 -070038import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
39import org.onosproject.incubator.net.virtual.provider.VirtualPacketProviderService;
40import org.onosproject.net.ConnectPoint;
41import org.onosproject.net.DefaultAnnotations;
42import org.onosproject.net.DefaultDevice;
43import org.onosproject.net.DefaultLink;
44import org.onosproject.net.DefaultPort;
45import org.onosproject.net.Device;
46import org.onosproject.net.DeviceId;
yoonseon5a51ef72016-10-26 14:50:09 -070047import org.onosproject.net.Link;
48import org.onosproject.net.Port;
49import org.onosproject.net.PortNumber;
Yoonseon Hanc8089db2017-03-22 20:22:12 +090050import org.onosproject.net.flow.DefaultTrafficSelector;
yoonseon5a51ef72016-10-26 14:50:09 -070051import org.onosproject.net.flow.DefaultTrafficTreatment;
Yoonseon Hanc8089db2017-03-22 20:22:12 +090052import org.onosproject.net.flow.TrafficSelector;
yoonseon5a51ef72016-10-26 14:50:09 -070053import org.onosproject.net.flow.TrafficTreatment;
54import org.onosproject.net.flow.instructions.Instruction;
55import org.onosproject.net.flow.instructions.Instructions;
56import org.onosproject.net.packet.DefaultInboundPacket;
57import org.onosproject.net.packet.DefaultOutboundPacket;
58import org.onosproject.net.packet.DefaultPacketContext;
59import org.onosproject.net.packet.InboundPacket;
60import org.onosproject.net.packet.OutboundPacket;
61import org.onosproject.net.packet.PacketContext;
62import org.onosproject.net.packet.PacketProcessor;
63import org.onosproject.net.packet.PacketServiceAdapter;
64import org.onosproject.net.provider.ProviderId;
65
66import java.nio.ByteBuffer;
67import java.util.LinkedList;
68import java.util.List;
69import java.util.Set;
70
71import static org.junit.Assert.assertEquals;
72
73public class DefaultVirtualPacketProviderTest {
74 private static final String SRC_MAC_ADDR = "00:00:00:00:00:00";
75 private static final String DST_MAC_ADDR = "00:00:00:00:00:01";
76 private static final ProviderId PID = new ProviderId("of", "foo");
77
78 private static final DeviceId DID1 = DeviceId.deviceId("of:001");
79 private static final DeviceId DID2 = DeviceId.deviceId("of:002");
80 private static final PortNumber PORT_NUM1 = PortNumber.portNumber(1);
81 private static final PortNumber PORT_NUM2 = PortNumber.portNumber(2);
82 private static final PortNumber PORT_NUM3 = PortNumber.portNumber(3);
83 private static final PortNumber PORT_NUM4 = PortNumber.portNumber(4);
84
85 private static final DefaultAnnotations ANNOTATIONS =
86 DefaultAnnotations.builder().set("foo", "bar").build();
87
88 private static final Device DEV1 =
89 new DefaultDevice(PID, DID1, Device.Type.SWITCH, "", "", "", "", null);
90 private static final Device DEV2 =
91 new DefaultDevice(PID, DID2, Device.Type.SWITCH, "", "", "", "", null);
92 private static final Port PORT11 =
93 new DefaultPort(DEV1, PORT_NUM1, true, ANNOTATIONS);
94 private static final Port PORT12 =
95 new DefaultPort(DEV1, PORT_NUM2, true, ANNOTATIONS);
96 private static final Port PORT21 =
97 new DefaultPort(DEV2, PORT_NUM3, true, ANNOTATIONS);
98 private static final Port PORT22 =
99 new DefaultPort(DEV2, PORT_NUM4, true, ANNOTATIONS);
100
101 private static final ConnectPoint CP11 = new ConnectPoint(DID1, PORT_NUM1);
102 private static final ConnectPoint CP12 = new ConnectPoint(DID1, PORT_NUM2);
103 private static final ConnectPoint CP21 = new ConnectPoint(DID2, PORT_NUM3);
104 private static final ConnectPoint CP22 = new ConnectPoint(DID2, PORT_NUM4);
105 private static final Link LINK1 = DefaultLink.builder()
106 .src(CP12).dst(CP21).providerId(PID).type(Link.Type.DIRECT).build();
107
108 private static final TenantId TENANT_ID = TenantId.tenantId("1");
109 private static final NetworkId VNET_ID = NetworkId.networkId(1);
110 private static final DeviceId VDID = DeviceId.deviceId("of:100");
111
112 private static final PortNumber VPORT_NUM1 = PortNumber.portNumber(10);
113 private static final PortNumber VPORT_NUM2 = PortNumber.portNumber(11);
114
115 private static final VirtualNetwork VNET = new DefaultVirtualNetwork(
116 VNET_ID, TenantId.tenantId("t1"));
117 private static final VirtualDevice VDEV =
118 new DefaultVirtualDevice(VNET_ID, VDID);
119 private static final VirtualPort VPORT1 =
120 new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM1, CP11);
121 private static final VirtualPort VPORT2 =
122 new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM2, CP22);
123 private static final ConnectPoint VCP11 = new ConnectPoint(VDID, VPORT_NUM1);
124 private static final ConnectPoint VCP12 = new ConnectPoint(VDID, VPORT_NUM2);
125
126 protected DefaultVirtualPacketProvider virtualProvider;
127 protected TestPacketService testPacketService;
yoonseon736a73b2017-01-26 14:27:48 -0800128 protected TestVirtualPacketProviderService providerService;
129
130 private VirtualProviderManager providerManager;
yoonseon5a51ef72016-10-26 14:50:09 -0700131
132 private ApplicationId vAppId;
133
134 @Before
135 public void setUp() {
136 virtualProvider = new DefaultVirtualPacketProvider();
137
138 virtualProvider.coreService = new CoreServiceAdapter();
Yoonseon Hanc8089db2017-03-22 20:22:12 +0900139 virtualProvider.vnaService =
yoonseon5a51ef72016-10-26 14:50:09 -0700140 new TestVirtualNetworkAdminService();
141
yoonseon736a73b2017-01-26 14:27:48 -0800142 providerService = new TestVirtualPacketProviderService();
yoonseon5a51ef72016-10-26 14:50:09 -0700143
144 testPacketService = new TestPacketService();
145 virtualProvider.packetService = testPacketService;
146
yoonseon736a73b2017-01-26 14:27:48 -0800147 providerManager = new VirtualProviderManager();
148 virtualProvider.providerRegistryService = providerManager;
149 providerManager.registerProviderService(VNET_ID, providerService);
150
yoonseon5a51ef72016-10-26 14:50:09 -0700151 virtualProvider.activate();
152 vAppId = new TestApplicationId(0, "Virtual App");
Yoonseon Hanc8089db2017-03-22 20:22:12 +0900153
154 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
155 selector.matchEthType(Ethernet.TYPE_IPV4);
156
Harold Huange86d35f2017-06-14 15:15:18 +0800157 virtualProvider.startPacketHandling();
yoonseon5a51ef72016-10-26 14:50:09 -0700158 }
159
160 @After
161 public void tearDown() {
162 virtualProvider.deactivate();
163 virtualProvider.coreService = null;
Yoonseon Hanc8089db2017-03-22 20:22:12 +0900164 virtualProvider.vnaService = null;
yoonseon5a51ef72016-10-26 14:50:09 -0700165 }
166
167
168 /** Test the virtual outbound packet is delivered to a proper (physical)
169 * device.
170 */
171 @Test
172 public void devirtualizePacket() {
173 TrafficTreatment tr = DefaultTrafficTreatment.builder()
174 .setOutput(VPORT_NUM1).build();
175 ByteBuffer data = ByteBuffer.wrap("abc".getBytes());
176
177 OutboundPacket vOutPacket = new DefaultOutboundPacket(VDID, tr, data);
178
179 virtualProvider.emit(VNET_ID, vOutPacket);
180
181 assertEquals("The count should be 1", 1,
182 testPacketService.getRequestedPacketCount());
183
184 OutboundPacket pOutPacket = testPacketService.getRequestedPacket(0);
185
186 assertEquals("The packet should be requested on DEV1", DID1,
187 pOutPacket.sendThrough());
188
189 PortNumber outPort = pOutPacket.treatment()
190 .allInstructions()
191 .stream()
192 .filter(i -> i.type() == Instruction.Type.OUTPUT)
193 .map(i -> (Instructions.OutputInstruction) i)
194 .map(i -> i.port())
195 .findFirst().get();
196 assertEquals("The packet should be out at PORT1 of DEV1", PORT_NUM1,
197 outPort);
198 }
199
200 /** Test the physical packet context is delivered to a proper (physical)
201 * virtual network and device.
202 */
203 @Test
204 public void virtualizePacket() {
205 Ethernet eth = new Ethernet();
206 eth.setSourceMACAddress(SRC_MAC_ADDR);
207 eth.setDestinationMACAddress(DST_MAC_ADDR);
208 eth.setVlanID((short) 1);
209 eth.setPayload(null);
210
211 InboundPacket pInPacket =
212 new DefaultInboundPacket(CP22, eth,
213 ByteBuffer.wrap(eth.serialize()));
214
215 PacketContext pContext =
216 new TestPacketContext(System.nanoTime(), pInPacket, null, false);
217
218 testPacketService.sendTestPacketContext(pContext);
219
yoonseon5a51ef72016-10-26 14:50:09 -0700220 PacketContext vContext = providerService.getRequestedPacketContext(0);
221 InboundPacket vInPacket = vContext.inPacket();
222
223 assertEquals("the packet should be received from VCP12",
224 VCP12, vInPacket.receivedFrom());
225
226 assertEquals("VLAN tag should be excludede", VlanId.UNTAGGED,
227 vInPacket.parsed().getVlanID());
228 }
229
230 private class TestPacketContext extends DefaultPacketContext {
231
232 /**
233 * Creates a new packet context.
234 *
235 * @param time creation time
236 * @param inPkt inbound packet
237 * @param outPkt outbound packet
238 * @param block whether the context is blocked or not
239 */
240 protected TestPacketContext(long time, InboundPacket inPkt,
241 OutboundPacket outPkt, boolean block) {
242 super(time, inPkt, outPkt, block);
243 }
244
245 @Override
246 public void send() {
247
248 }
249 }
250
251 private static class TestApplicationId extends DefaultApplicationId {
252 public TestApplicationId(int id, String name) {
253 super(id, name);
254 }
255 }
256
257 private static class TestVirtualNetworkAdminService
Yoonseon Hanffcc32f2017-05-03 14:42:17 -0700258 extends VirtualNetworkAdminServiceAdapter {
yoonseon5a51ef72016-10-26 14:50:09 -0700259
260 @Override
261 public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
262 return ImmutableSet.of(VNET);
263 }
264
265 @Override
266 public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
267 return ImmutableSet.of(VDEV);
268 }
269
270 @Override
yoonseon5a51ef72016-10-26 14:50:09 -0700271 public Set<VirtualPort> getVirtualPorts(NetworkId networkId,
272 DeviceId deviceId) {
273 return ImmutableSet.of(VPORT1, VPORT2);
274 }
275
276 @Override
yoonseon5a51ef72016-10-26 14:50:09 -0700277 public Set<TenantId> getTenantIds() {
278 return ImmutableSet.of(TENANT_ID);
279 }
280
yoonseon5a51ef72016-10-26 14:50:09 -0700281 }
282
yoonseon736a73b2017-01-26 14:27:48 -0800283 private static class TestVirtualPacketProviderService
284 extends AbstractVirtualProviderService<VirtualPacketProvider>
yoonseon5a51ef72016-10-26 14:50:09 -0700285 implements VirtualPacketProviderService {
Yoonseon Hanffcc32f2017-05-03 14:42:17 -0700286
yoonseon5a51ef72016-10-26 14:50:09 -0700287 static List<PacketContext> requestedContext = new LinkedList();
288 static List<NetworkId> requestedNetworkId = new LinkedList();
289
290 @Override
291 public VirtualPacketProvider provider() {
292 return null;
293 }
294
Yoonseon Hanffcc32f2017-05-03 14:42:17 -0700295 PacketContext getRequestedPacketContext(int index) {
yoonseon736a73b2017-01-26 14:27:48 -0800296 return requestedContext.get(index);
297 }
298
299 @Override
300 public void processPacket(PacketContext context) {
301 requestedContext.add(context);
yoonseon5a51ef72016-10-26 14:50:09 -0700302 }
303 }
304
305 private static class TestPacketService extends PacketServiceAdapter {
306 static List<OutboundPacket> requestedPacket = new LinkedList();
307 static PacketProcessor processor = null;
308
309 @Override
310 public void addProcessor(PacketProcessor processor, int priority) {
311 this.processor = processor;
312 }
313
314 @Override
315 public void emit(OutboundPacket packet) {
316 requestedPacket.add(packet);
317 }
318
Yoonseon Hanffcc32f2017-05-03 14:42:17 -0700319 OutboundPacket getRequestedPacket(int index) {
yoonseon5a51ef72016-10-26 14:50:09 -0700320 return requestedPacket.get(index);
321 }
322
Yoonseon Hanffcc32f2017-05-03 14:42:17 -0700323 int getRequestedPacketCount() {
yoonseon5a51ef72016-10-26 14:50:09 -0700324 return requestedPacket.size();
325 }
326
Yoonseon Hanffcc32f2017-05-03 14:42:17 -0700327 void sendTestPacketContext(PacketContext context) {
yoonseon5a51ef72016-10-26 14:50:09 -0700328 processor.process(context);
329 }
330 }
331}