| /* |
| * Copyright 2016-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.onosproject.incubator.net.virtual.impl.provider; |
| |
| import com.google.common.collect.ImmutableSet; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.onlab.osgi.ServiceDirectory; |
| import org.onlab.packet.Ethernet; |
| import org.onlab.packet.IpAddress; |
| import org.onlab.packet.MacAddress; |
| import org.onlab.packet.VlanId; |
| import org.onosproject.core.ApplicationId; |
| import org.onosproject.core.CoreServiceAdapter; |
| import org.onosproject.core.DefaultApplicationId; |
| import org.onosproject.incubator.net.virtual.DefaultVirtualDevice; |
| import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork; |
| import org.onosproject.incubator.net.virtual.DefaultVirtualPort; |
| import org.onosproject.incubator.net.virtual.NetworkId; |
| import org.onosproject.incubator.net.virtual.TenantId; |
| import org.onosproject.incubator.net.virtual.VirtualDevice; |
| import org.onosproject.incubator.net.virtual.VirtualHost; |
| import org.onosproject.incubator.net.virtual.VirtualLink; |
| import org.onosproject.incubator.net.virtual.VirtualNetwork; |
| import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService; |
| import org.onosproject.incubator.net.virtual.VirtualPort; |
| import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService; |
| import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider; |
| import org.onosproject.incubator.net.virtual.provider.VirtualPacketProviderService; |
| import org.onosproject.net.ConnectPoint; |
| import org.onosproject.net.DefaultAnnotations; |
| import org.onosproject.net.DefaultDevice; |
| import org.onosproject.net.DefaultLink; |
| import org.onosproject.net.DefaultPort; |
| import org.onosproject.net.Device; |
| import org.onosproject.net.DeviceId; |
| import org.onosproject.net.HostId; |
| import org.onosproject.net.HostLocation; |
| import org.onosproject.net.Link; |
| import org.onosproject.net.Port; |
| import org.onosproject.net.PortNumber; |
| import org.onosproject.net.flow.DefaultTrafficTreatment; |
| import org.onosproject.net.flow.TrafficTreatment; |
| import org.onosproject.net.flow.instructions.Instruction; |
| import org.onosproject.net.flow.instructions.Instructions; |
| import org.onosproject.net.packet.DefaultInboundPacket; |
| import org.onosproject.net.packet.DefaultOutboundPacket; |
| import org.onosproject.net.packet.DefaultPacketContext; |
| import org.onosproject.net.packet.InboundPacket; |
| import org.onosproject.net.packet.OutboundPacket; |
| import org.onosproject.net.packet.PacketContext; |
| import org.onosproject.net.packet.PacketProcessor; |
| import org.onosproject.net.packet.PacketServiceAdapter; |
| import org.onosproject.net.provider.ProviderId; |
| |
| import java.nio.ByteBuffer; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Set; |
| |
| import static org.junit.Assert.assertEquals; |
| |
| public class DefaultVirtualPacketProviderTest { |
| private static final String SRC_MAC_ADDR = "00:00:00:00:00:00"; |
| private static final String DST_MAC_ADDR = "00:00:00:00:00:01"; |
| private static final ProviderId PID = new ProviderId("of", "foo"); |
| |
| private static final DeviceId DID1 = DeviceId.deviceId("of:001"); |
| private static final DeviceId DID2 = DeviceId.deviceId("of:002"); |
| private static final PortNumber PORT_NUM1 = PortNumber.portNumber(1); |
| private static final PortNumber PORT_NUM2 = PortNumber.portNumber(2); |
| private static final PortNumber PORT_NUM3 = PortNumber.portNumber(3); |
| private static final PortNumber PORT_NUM4 = PortNumber.portNumber(4); |
| |
| private static final DefaultAnnotations ANNOTATIONS = |
| DefaultAnnotations.builder().set("foo", "bar").build(); |
| |
| private static final Device DEV1 = |
| new DefaultDevice(PID, DID1, Device.Type.SWITCH, "", "", "", "", null); |
| private static final Device DEV2 = |
| new DefaultDevice(PID, DID2, Device.Type.SWITCH, "", "", "", "", null); |
| private static final Port PORT11 = |
| new DefaultPort(DEV1, PORT_NUM1, true, ANNOTATIONS); |
| private static final Port PORT12 = |
| new DefaultPort(DEV1, PORT_NUM2, true, ANNOTATIONS); |
| private static final Port PORT21 = |
| new DefaultPort(DEV2, PORT_NUM3, true, ANNOTATIONS); |
| private static final Port PORT22 = |
| new DefaultPort(DEV2, PORT_NUM4, true, ANNOTATIONS); |
| |
| private static final ConnectPoint CP11 = new ConnectPoint(DID1, PORT_NUM1); |
| private static final ConnectPoint CP12 = new ConnectPoint(DID1, PORT_NUM2); |
| private static final ConnectPoint CP21 = new ConnectPoint(DID2, PORT_NUM3); |
| private static final ConnectPoint CP22 = new ConnectPoint(DID2, PORT_NUM4); |
| private static final Link LINK1 = DefaultLink.builder() |
| .src(CP12).dst(CP21).providerId(PID).type(Link.Type.DIRECT).build(); |
| |
| private static final TenantId TENANT_ID = TenantId.tenantId("1"); |
| private static final NetworkId VNET_ID = NetworkId.networkId(1); |
| private static final DeviceId VDID = DeviceId.deviceId("of:100"); |
| |
| private static final PortNumber VPORT_NUM1 = PortNumber.portNumber(10); |
| private static final PortNumber VPORT_NUM2 = PortNumber.portNumber(11); |
| |
| private static final VirtualNetwork VNET = new DefaultVirtualNetwork( |
| VNET_ID, TenantId.tenantId("t1")); |
| private static final VirtualDevice VDEV = |
| new DefaultVirtualDevice(VNET_ID, VDID); |
| private static final VirtualPort VPORT1 = |
| new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM1, CP11); |
| private static final VirtualPort VPORT2 = |
| new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM2, CP22); |
| private static final ConnectPoint VCP11 = new ConnectPoint(VDID, VPORT_NUM1); |
| private static final ConnectPoint VCP12 = new ConnectPoint(VDID, VPORT_NUM2); |
| |
| protected DefaultVirtualPacketProvider virtualProvider; |
| protected TestPacketService testPacketService; |
| protected TestVirtualPacketProviderService providerService; |
| |
| private VirtualProviderManager providerManager; |
| |
| private ApplicationId vAppId; |
| |
| @Before |
| public void setUp() { |
| virtualProvider = new DefaultVirtualPacketProvider(); |
| |
| virtualProvider.coreService = new CoreServiceAdapter(); |
| virtualProvider.virtualNetworkAdminService = |
| new TestVirtualNetworkAdminService(); |
| |
| providerService = new TestVirtualPacketProviderService(); |
| |
| testPacketService = new TestPacketService(); |
| virtualProvider.packetService = testPacketService; |
| |
| providerManager = new VirtualProviderManager(); |
| virtualProvider.providerRegistryService = providerManager; |
| providerManager.registerProviderService(VNET_ID, providerService); |
| |
| virtualProvider.activate(); |
| virtualProvider.startPacketHandling(); |
| vAppId = new TestApplicationId(0, "Virtual App"); |
| } |
| |
| @After |
| public void tearDown() { |
| virtualProvider.deactivate(); |
| virtualProvider.coreService = null; |
| virtualProvider.virtualNetworkAdminService = null; |
| } |
| |
| |
| /** Test the virtual outbound packet is delivered to a proper (physical) |
| * device. |
| */ |
| @Test |
| public void devirtualizePacket() { |
| TrafficTreatment tr = DefaultTrafficTreatment.builder() |
| .setOutput(VPORT_NUM1).build(); |
| ByteBuffer data = ByteBuffer.wrap("abc".getBytes()); |
| |
| OutboundPacket vOutPacket = new DefaultOutboundPacket(VDID, tr, data); |
| |
| virtualProvider.emit(VNET_ID, vOutPacket); |
| |
| assertEquals("The count should be 1", 1, |
| testPacketService.getRequestedPacketCount()); |
| |
| OutboundPacket pOutPacket = testPacketService.getRequestedPacket(0); |
| |
| assertEquals("The packet should be requested on DEV1", DID1, |
| pOutPacket.sendThrough()); |
| |
| PortNumber outPort = pOutPacket.treatment() |
| .allInstructions() |
| .stream() |
| .filter(i -> i.type() == Instruction.Type.OUTPUT) |
| .map(i -> (Instructions.OutputInstruction) i) |
| .map(i -> i.port()) |
| .findFirst().get(); |
| assertEquals("The packet should be out at PORT1 of DEV1", PORT_NUM1, |
| outPort); |
| } |
| |
| /** Test the physical packet context is delivered to a proper (physical) |
| * virtual network and device. |
| */ |
| @Test |
| public void virtualizePacket() { |
| Ethernet eth = new Ethernet(); |
| eth.setSourceMACAddress(SRC_MAC_ADDR); |
| eth.setDestinationMACAddress(DST_MAC_ADDR); |
| eth.setVlanID((short) 1); |
| eth.setPayload(null); |
| |
| InboundPacket pInPacket = |
| new DefaultInboundPacket(CP22, eth, |
| ByteBuffer.wrap(eth.serialize())); |
| |
| PacketContext pContext = |
| new TestPacketContext(System.nanoTime(), pInPacket, null, false); |
| |
| testPacketService.sendTestPacketContext(pContext); |
| |
| PacketContext vContext = providerService.getRequestedPacketContext(0); |
| InboundPacket vInPacket = vContext.inPacket(); |
| |
| assertEquals("the packet should be received from VCP12", |
| VCP12, vInPacket.receivedFrom()); |
| |
| assertEquals("VLAN tag should be excludede", VlanId.UNTAGGED, |
| vInPacket.parsed().getVlanID()); |
| } |
| |
| private class TestPacketContext extends DefaultPacketContext { |
| |
| /** |
| * Creates a new packet context. |
| * |
| * @param time creation time |
| * @param inPkt inbound packet |
| * @param outPkt outbound packet |
| * @param block whether the context is blocked or not |
| */ |
| protected TestPacketContext(long time, InboundPacket inPkt, |
| OutboundPacket outPkt, boolean block) { |
| super(time, inPkt, outPkt, block); |
| } |
| |
| @Override |
| public void send() { |
| |
| } |
| } |
| |
| private static class TestApplicationId extends DefaultApplicationId { |
| public TestApplicationId(int id, String name) { |
| super(id, name); |
| } |
| } |
| |
| private static class TestVirtualNetworkAdminService |
| implements VirtualNetworkAdminService { |
| |
| @Override |
| public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) { |
| return ImmutableSet.of(VNET); |
| } |
| |
| @Override |
| public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) { |
| return ImmutableSet.of(VDEV); |
| } |
| |
| @Override |
| public Set<VirtualHost> getVirtualHosts(NetworkId networkId) { |
| return null; |
| } |
| |
| @Override |
| public Set<VirtualLink> getVirtualLinks(NetworkId networkId) { |
| return null; |
| } |
| |
| @Override |
| public Set<VirtualPort> getVirtualPorts(NetworkId networkId, |
| DeviceId deviceId) { |
| return ImmutableSet.of(VPORT1, VPORT2); |
| } |
| |
| @Override |
| public <T> T get(NetworkId networkId, Class<T> serviceClass) { |
| return null; |
| } |
| |
| @Override |
| public ServiceDirectory getServiceDirectory() { |
| return null; |
| } |
| |
| @Override |
| public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) { |
| return null; |
| } |
| |
| @Override |
| public void registerTenantId(TenantId tenantId) { |
| |
| } |
| |
| @Override |
| public void unregisterTenantId(TenantId tenantId) { |
| |
| } |
| |
| @Override |
| public Set<TenantId> getTenantIds() { |
| return ImmutableSet.of(TENANT_ID); |
| } |
| |
| @Override |
| public VirtualNetwork createVirtualNetwork(TenantId tenantId) { |
| return null; |
| } |
| |
| @Override |
| public void removeVirtualNetwork(NetworkId networkId) { |
| |
| } |
| |
| @Override |
| public VirtualDevice createVirtualDevice(NetworkId networkId, |
| DeviceId deviceId) { |
| return null; |
| } |
| |
| @Override |
| public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) { |
| |
| } |
| |
| @Override |
| public VirtualHost createVirtualHost(NetworkId networkId, HostId hostId, |
| MacAddress mac, VlanId vlan, |
| HostLocation location, |
| Set<IpAddress> ips) { |
| return null; |
| } |
| |
| @Override |
| public void removeVirtualHost(NetworkId networkId, HostId hostId) { |
| |
| } |
| |
| @Override |
| public VirtualLink createVirtualLink(NetworkId networkId, |
| ConnectPoint src, ConnectPoint dst) { |
| return null; |
| } |
| |
| @Override |
| public void removeVirtualLink(NetworkId networkId, |
| ConnectPoint src, ConnectPoint dst) { |
| |
| } |
| |
| @Override |
| public VirtualPort createVirtualPort(NetworkId networkId, |
| DeviceId deviceId, |
| PortNumber portNumber, |
| ConnectPoint realizedBy) { |
| return null; |
| } |
| |
| @Override |
| public void bindVirtualPort(NetworkId networkId, |
| DeviceId deviceId, |
| PortNumber portNumber, |
| ConnectPoint realizedBy) { |
| |
| } |
| |
| @Override |
| public void removeVirtualPort(NetworkId networkId, DeviceId deviceId, |
| PortNumber portNumber) { |
| |
| } |
| } |
| |
| private static class TestVirtualPacketProviderService |
| extends AbstractVirtualProviderService<VirtualPacketProvider> |
| implements VirtualPacketProviderService { |
| static List<PacketContext> requestedContext = new LinkedList(); |
| static List<NetworkId> requestedNetworkId = new LinkedList(); |
| |
| @Override |
| public VirtualPacketProvider provider() { |
| return null; |
| } |
| |
| public NetworkId getRequestedNetworkId(int index) { |
| return requestedNetworkId.get(index); |
| } |
| |
| public PacketContext getRequestedPacketContext(int index) { |
| return requestedContext.get(index); |
| } |
| |
| @Override |
| public void processPacket(PacketContext context) { |
| requestedContext.add(context); |
| } |
| } |
| |
| private static class TestPacketService extends PacketServiceAdapter { |
| static List<OutboundPacket> requestedPacket = new LinkedList(); |
| static PacketProcessor processor = null; |
| |
| @Override |
| public void addProcessor(PacketProcessor processor, int priority) { |
| this.processor = processor; |
| } |
| |
| @Override |
| public void emit(OutboundPacket packet) { |
| requestedPacket.add(packet); |
| } |
| |
| public OutboundPacket getRequestedPacket(int index) { |
| return requestedPacket.get(index); |
| } |
| |
| public int getRequestedPacketCount() { |
| return requestedPacket.size(); |
| } |
| |
| public void sendTestPacketContext(PacketContext context) { |
| processor.process(context); |
| } |
| } |
| } |