/*
* Copyright (c) 2013 Big Switch Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
*
* 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.sdnplatform.netvirt.virtualrouting.internal;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.openflow.protocol.OFMatch;
import org.openflow.protocol.OFPacketIn;
import org.openflow.protocol.OFPacketIn.OFPacketInReason;
import org.openflow.protocol.OFPacketOut;
import org.openflow.protocol.OFPhysicalPort;
import org.openflow.protocol.OFType;
import org.openflow.protocol.factory.BasicFactory;
import org.openflow.util.HexString;
import org.sdnplatform.addressspace.BetterEntityClass;
import org.sdnplatform.core.ListenerContext;
import org.sdnplatform.core.IControllerService;
import org.sdnplatform.core.IOFSwitch;
import org.sdnplatform.core.IListener.Command;
import org.sdnplatform.core.module.ModuleContext;
import org.sdnplatform.core.test.MockThreadPoolService;
import org.sdnplatform.core.util.MutableInteger;
import org.sdnplatform.devicemanager.IDevice;
import org.sdnplatform.devicemanager.IDeviceService;
import org.sdnplatform.devicemanager.IEntityClassifierService;
import org.sdnplatform.devicemanager.SwitchPort;
import org.sdnplatform.devicemanager.IDeviceService.DeviceField;
import org.sdnplatform.devicemanager.internal.BetterDeviceManagerImpl;
import org.sdnplatform.devicemanager.internal.DefaultEntityClassifier;
import org.sdnplatform.devicemanager.internal.Entity;
import org.sdnplatform.devicemanager.test.MockDeviceManager;
import org.sdnplatform.flowcache.FlowCacheObj;
import org.sdnplatform.flowcache.IFlowCacheService;
import org.sdnplatform.flowcache.IFlowReconcileService;
import org.sdnplatform.flowcache.OFMatchReconcile;
import org.sdnplatform.flowcache.OFMatchReconcile.ReconcileAction;
import org.sdnplatform.forwarding.IForwardingService;
import org.sdnplatform.forwarding.IRewriteService;
import org.sdnplatform.forwarding.RewriteServiceImpl;
import org.sdnplatform.linkdiscovery.ILinkDiscoveryService;
import org.sdnplatform.netvirt.core.VNS;
import org.sdnplatform.netvirt.core.VNSInterface;
import org.sdnplatform.netvirt.core.VNS.BroadcastMode;
import org.sdnplatform.netvirt.manager.INetVirtManagerService;
import org.sdnplatform.netvirt.virtualrouting.IVirtualRoutingService;
import org.sdnplatform.netvirt.virtualrouting.VirtualMACExhaustedException;
import org.sdnplatform.netvirt.virtualrouting.IARPListener.ARPCommand;
import org.sdnplatform.netvirt.virtualrouting.IICMPListener.ICMPCommand;
import org.sdnplatform.netvirt.virtualrouting.internal.VirtualRouterManager;
import org.sdnplatform.netvirt.virtualrouting.internal.VirtualRouting;
import org.sdnplatform.packet.ARP;
import org.sdnplatform.packet.Data;
import org.sdnplatform.packet.Ethernet;
import org.sdnplatform.packet.ICMP;
import org.sdnplatform.packet.IPacket;
import org.sdnplatform.packet.IPv4;
import org.sdnplatform.packet.LLDP;
import org.sdnplatform.packet.LLDPTLV;
import org.sdnplatform.packet.UDP;
import org.sdnplatform.restserver.IRestApiService;
import org.sdnplatform.restserver.RestApiServer;
import org.sdnplatform.routing.IRoutingDecision;
import org.sdnplatform.routing.IRoutingService;
import org.sdnplatform.routing.Route;
import org.sdnplatform.routing.IRoutingDecision.RoutingAction;
import org.sdnplatform.storage.IStorageSourceService;
import org.sdnplatform.storage.memory.MemoryStorageSource;
import org.sdnplatform.tagmanager.ITagManagerService;
import org.sdnplatform.test.PlatformTestCase;
import org.sdnplatform.threadpool.IThreadPoolService;
import org.sdnplatform.topology.ITopologyService;
import org.sdnplatform.topology.NodePortTuple;
import org.sdnplatform.tunnelmanager.ITunnelManagerService;
@SuppressWarnings("unchecked")
public class VirtualRoutingTest extends PlatformTestCase {
private INetVirtManagerService netVirtManager;
private MockDeviceManager mockDeviceManager;
private ITunnelManagerService tunnelManager;
private MemoryStorageSource storageSource;
private VirtualRouting virtualRouting;
private BetterDeviceManagerImpl tagManager;
private ModuleContext fmc;
protected IFlowReconcileService flowReconcileMgr;
protected ITopologyService topology;
private IRoutingService routingEngine;
private IForwardingService forwarding;
private RewriteServiceImpl rewriteService;
private IFlowCacheService betterFlowCacheMgr;
private ILinkDiscoveryService linkDiscovery;
private IOFSwitch mockSwitch;
protected IPacket testPacket;
protected byte[] testPacketSerialized;
protected IPacket testPacketUnknownDest;
protected byte[] testPacketUnknownDestSerialized;
protected IPacket broadcastPacket;
protected byte[] broadcastPacketSerialized;
protected IPacket multicastPacket;
protected byte[] multicastPacketSerialized;
protected IPacket lldpPacket;
protected byte[] lldpPacketSerialized;
long dev1m, dev2m;
protected IDevice dev1, dev2;
private VNS netVirt[];
private final int nNetVirtes = 100;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
storageSource = new MemoryStorageSource();
mockDeviceManager = new MockDeviceManager();
tunnelManager = createMock(ITunnelManagerService.class);
virtualRouting = new VirtualRouting();
tagManager = new BetterDeviceManagerImpl();
netVirtManager = createNiceMock(INetVirtManagerService.class);
topology = createMock(ITopologyService.class);
routingEngine = createNiceMock(IRoutingService.class);
flowReconcileMgr = createNiceMock(IFlowReconcileService.class);
RestApiServer ras = new RestApiServer();
MockThreadPoolService tp = new MockThreadPoolService();
DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
forwarding = createMock(IForwardingService.class);
rewriteService = new RewriteServiceImpl();
betterFlowCacheMgr = createNiceMock(IFlowCacheService.class);
linkDiscovery = createMock(ILinkDiscoveryService.class);
fmc = new ModuleContext();
fmc.addService(IControllerService.class, mockControllerProvider);
fmc.addService(IStorageSourceService.class, storageSource);
fmc.addService(IDeviceService.class, mockDeviceManager);
fmc.addService(ITagManagerService.class, tagManager);
fmc.addService(IVirtualRoutingService.class, virtualRouting);
fmc.addService(INetVirtManagerService.class, netVirtManager);
fmc.addService(IRestApiService.class, ras);
fmc.addService(IThreadPoolService.class, tp);
fmc.addService(ITopologyService.class, topology);
fmc.addService(IRoutingService.class, routingEngine);
fmc.addService(IFlowReconcileService.class, flowReconcileMgr);
fmc.addService(IEntityClassifierService.class, entityClassifier);
fmc.addService(IForwardingService.class, forwarding);
fmc.addService(IRewriteService.class, rewriteService);
fmc.addService(IFlowCacheService.class, betterFlowCacheMgr);
fmc.addService(ILinkDiscoveryService.class, linkDiscovery);
fmc.addService(ITunnelManagerService.class, tunnelManager);
storageSource.init(fmc);
mockDeviceManager.init(fmc);
tagManager.init(fmc);
virtualRouting.init(fmc);
ras.init(fmc);
mockControllerProvider.init(fmc);
tp.init(fmc);
entityClassifier.init(fmc);
rewriteService.init(fmc);
storageSource.startUp(fmc);
mockDeviceManager.startUp(fmc);
tagManager.startUp(fmc);
virtualRouting.startUp(fmc);
ras.startUp(fmc);
mockControllerProvider.startUp(fmc);
tp.startUp(fmc);
entityClassifier.startUp(fmc);
rewriteService.startUp(fmc);
// Build our test packet
this.testPacket = new Ethernet()
.setDestinationMACAddress("00:11:22:33:44:55")
.setSourceMACAddress("00:44:33:22:11:00")
.setVlanID((short) 42)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.1.2")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.testPacketSerialized = testPacket.serialize();
this.testPacketUnknownDest = new Ethernet()
.setDestinationMACAddress("00:11:22:33:44:66")
.setSourceMACAddress("00:44:33:22:11:00")
.setVlanID((short) 42)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.1.3")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.testPacketUnknownDestSerialized = testPacketUnknownDest.serialize();
// Build a broadcast packet
this.broadcastPacket = new Ethernet()
.setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
.setSourceMACAddress("00:44:33:22:11:00")
.setVlanID((short) 42)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.255.255")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.broadcastPacketSerialized = broadcastPacket.serialize();
// Build a broadcast packet
this.multicastPacket = new Ethernet()
.setDestinationMACAddress("01:00:5e:01:02:03")
.setSourceMACAddress("00:44:33:22:11:00")
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 1)
.setProtocol(IPv4.PROTOCOL_UDP)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("224.1.2.3")
.setPayload(new UDP()
.setSourcePort((short) 4567)
.setDestinationPort((short) 4567)
.setPayload(new Data(new byte[] {0x74, 0x65, 0x73, 0x74, 0x0a}))));
this.multicastPacketSerialized = multicastPacket.serialize();
// Build a broadcast packet
this.lldpPacket = new Ethernet()
.setDestinationMACAddress("01:80:c2:00:00:0e")
.setSourceMACAddress("00:44:33:22:11:00")
.setEtherType(Ethernet.TYPE_LLDP)
.setPayload(
new LLDP()
.setChassisId(new LLDPTLV()
.setType((byte) 1)
.setLength((byte) 7)
.setValue(new byte[] {0x4, 0x0, 0x0, 0x0, 0x73, 0x28, 0x3}))
.setPortId(new LLDPTLV()
.setType((byte) 2)
.setLength((byte) 3)
.setValue(new byte[] {0x2, 0x0, 0x18}))
.setTtl(new LLDPTLV()
.setType((byte) 3)
.setLength((byte) 2)
.setValue(new byte[] {0x0, 0x78}))
);
this.lldpPacketSerialized = lldpPacket.serialize();
expect(topology.isAttachmentPointPort(EasyMock.anyLong(), EasyMock.anyShort())).andReturn(true).anyTimes();
expect(topology.getL2DomainId(1)).andReturn(1L).anyTimes();
replay(topology);
dev1m = Ethernet.toLong(((Ethernet)testPacket).
getSourceMACAddress());
dev2m = Ethernet.toLong(((Ethernet)testPacket).
getDestinationMACAddress());
dev1 = mockDeviceManager.learnEntity(dev1m, null, null, 1L, 1);
dev2 = mockDeviceManager.learnEntity(dev2m, null, null, 1L, 2);
netVirt = new VNS[nNetVirtes];
for (int n = 0; n < nNetVirtes; n++) {
netVirt[n] = new VNS("tt1|NetVirt" + n);
netVirt[n].setPriority(n);
}
mockSwitch = createMock(IOFSwitch.class);
expect(mockSwitch.getId()).andReturn(1L).anyTimes();
HashMap<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
switches.put(1L, mockSwitch);
mockControllerProvider.setSwitches(switches);
expect(tunnelManager.isTunnelEndpoint(anyObject(IDevice.class)))
.andReturn(false).anyTimes();
replay(tunnelManager);
}
protected VirtualRouting getVirtualRouting() {
return virtualRouting;
}
/**
* Common mockup environment for unicast tests
*/
private void testUnicastInternal(ListenerContext cntx,
RoutingAction action) throws Exception {
OFPacketIn pi;
VirtualRouting routing = getVirtualRouting();
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
// build out input packet
pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short) 1)
.setPacketData(testPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) testPacketSerialized.length);
// Start recording the replay on the mocks
replay(mockSwitch);
// Trigger the packet in
routing.receive(mockSwitch, pi, parseAndAnnotate(cntx, pi, dev1, dev2));
// Get the annotation output for verification
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
// Verify the replay matched our expectations
verify(mockSwitch);
assertTrue(d.getRoutingAction() == action);
assertTrue(d.getSourcePort().getSwitchDPID() == 1L);
assertTrue(d.getSourcePort().getPort() == pi.getInPort());
assertEquals(d.getSourceDevice(), dev1);
if (dev2 != null)
assertEquals(true, d.getDestinationDevices().contains(dev2));
}
private void verifyContext(ListenerContext cntx, VNS srcNetVirt, VNS dstNetVirt) {
List<VNSInterface> srcIfaces, dstIfaces;
srcIfaces = INetVirtManagerService.bcStore.get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
dstIfaces = INetVirtManagerService.bcStore.get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
if (srcNetVirt == null) {
assertTrue(srcIfaces == null || srcIfaces.size() == 0);
assertTrue(dstIfaces == null || dstIfaces.size() == 0);
} else {
assertTrue(srcIfaces.size() == 1);
assertTrue(srcIfaces.get(0).getParentVNS() == srcNetVirt);
if (dstIfaces != null) {
assertTrue(dstIfaces.size() == 1);
assertTrue(dstIfaces.get(0).getParentVNS() == dstNetVirt);
}
}
}
private void verifyContext(ListenerContext cntx, VNS netVirt) {
verifyContext(cntx, netVirt, netVirt);
}
/**
* No annotation, should drop
*/
@Test
public void testUnicastNoAnnotation() throws Exception {
ListenerContext cntx = new ListenerContext();
testUnicastInternal(cntx, RoutingAction.DROP);
verifyContext(cntx, null);
}
/**
* Same source and destination NetVirt, should forward
*/
@Test
public void testUnicastPass() throws Exception {
ListenerContext cntx = new ListenerContext();
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface2", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_DST_IFACES, dstIfaces);
testUnicastInternal(cntx, RoutingAction.FORWARD);
verifyContext(cntx, netVirt[0]);
}
/**
* Devices in the same NetVirt
* @throws Exception
*/
@Test
public void testChooseNetVirtSameNetVirt() throws Exception {
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
expect(netVirtManager.getInterfaces(dev1)).andReturn(srcIfaces).times(1);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface2", netVirt[0], null, null));
expect(netVirtManager.getInterfaces(dev2)).andReturn(dstIfaces).times(1);
replay(netVirtManager);
boolean ret = virtualRouting.connected(dev1, 0, dev2, 0);
verify(netVirtManager);
assertTrue(ret);
}
/**
* Devices in the same NetVirt
* @throws Exception
*/
@Test
public void testChooseNetVirtDifferentNetVirt() throws Exception {
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
expect(netVirtManager.getInterfaces(dev1)).andReturn(srcIfaces).times(1);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface2", netVirt[1], null, null));
expect(netVirtManager.getInterfaces(dev2)).andReturn(dstIfaces).times(1);
replay(netVirtManager);
boolean ret = virtualRouting.connected(dev1, 0, dev2, 0);
verify(netVirtManager);
assertFalse(ret);
}
/**
* Difference source and destination NetVirt, should drop
*/
@Test
public void testUnicastDrop() throws Exception {
ListenerContext cntx = new ListenerContext();
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[1], null, null));
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface2", netVirt[2], null, null));
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_DST_IFACES, dstIfaces);
testUnicastInternal(cntx, RoutingAction.DROP);
verifyContext(cntx, null);
}
/**
* Multiple source and destination NetVirtes with one overlap,
* should forward.
*/
@Test
public void testUnicastPassMulti() throws Exception {
int nChosen = 50;
ListenerContext cntx = new ListenerContext();
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 10; n++) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null, null));
}
srcIfaces.add(new VNSInterface("testSrcIface1x" + nChosen, netVirt[nChosen], null, null));
for (int n = 21; n < 40; n++) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null, null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
for (int n = 70; n < 80; n++) {
dstIfaces.add(new VNSInterface("testSrcIface2x" + n, netVirt[n], null, null));
}
dstIfaces.add(new VNSInterface("testSrcIface2x" + nChosen, netVirt[nChosen], null, null));
for (int n = 81; n < 95; n++) {
dstIfaces.add(new VNSInterface("testSrcIface2x" + n, netVirt[n], null, null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_DST_IFACES, dstIfaces);
testUnicastInternal(cntx, RoutingAction.FORWARD);
verifyContext(cntx, netVirt[nChosen]);
}
/**
* Multiple source and destination NetVirtes with one pair connected by virtual
* routing. Should forward.
*/
@Test
public void testVRUnicastPassMulti() throws Exception {
int srcChosen = 5;
int dstChosen = 75;
ListenerContext cntx = new ListenerContext();
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[srcChosen].getName(), null);
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[dstChosen].getName(), null);
Map<String, Object> rr1 = h.createRoutingRule(r1, "tt1", null, null,
null, "tt1", null, null,
null, null, null,
"permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2);
h.addRoutingRule(rr1);
h.writeToStorage(storageSource);
Thread.sleep(1000);
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 10; n++) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null,
null));
}
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
for (int n = 70; n < 80; n++) {
dstIfaces.add(new VNSInterface("testSrcIface2x" + n, netVirt[n], null,
null));
}
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
/* NetVirt5 and NetVirt75 are connected via a router so we should see FORWARD */
testUnicastInternal(cntx, RoutingAction.FORWARD);
verifyContext(cntx, netVirt[srcChosen], netVirt[dstChosen]);
}
@Test
public void testVRUnicastPassMultiL3() throws Exception {
int srcChosen = 5;
int dstChosen = 75;
ListenerContext cntx = new ListenerContext();
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[srcChosen].getName(), null);
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[dstChosen].getName(), null);
Map<String, Object> rr1 =
h.createRoutingRule(r1, "tt1", null, null, null, "tt1", null,
null, null, null, null, "permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2);
h.addRoutingRule(rr1);
h.writeToStorage(storageSource);
Thread.sleep(1000);
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 10; n++) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null,
null));
}
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
for (int n = 70; n < 80; n++) {
dstIfaces.add(new VNSInterface("testSrcIface2x" + n, netVirt[n], null, null));
}
/* Do not set CONTEXT_DST_IFACES in the cntx. This will be queried */
long mac = HexString.toLong("00:11:22:33:44:55");
int ip = IPv4.toIPv4Address("192.168.1.2");
IDevice dst = mockDeviceManager.learnEntity(mac, null, ip, 1L, 2);
dev2 = dst;
expect(netVirtManager.getInterfaces(dst)).andReturn(dstIfaces).anyTimes();
replay(netVirtManager);
this.testPacket = new Ethernet()
.setDestinationMACAddress(Ethernet.toByteArray(VirtualRouterManager.VIRTUAL_ROUTING_MAC))
.setSourceMACAddress("00:44:33:22:11:00")
.setVlanID((short) 42)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.1.2")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.testPacketSerialized = testPacket.serialize();
testUnicastInternal(cntx, RoutingAction.FORWARD);
/* Check that the dest Ip is also matched in the flowmod */
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
int dstIpWildcard = d.getWildcards() & OFMatch.OFPFW_NW_DST_MASK;
assertEquals(dstIpWildcard, 0);
verifyContext(cntx, netVirt[srcChosen], netVirt[dstChosen]);
/* Check that source and dest MAC and TTL are modified */
assertEquals(new Long(VirtualRouterManager.VIRTUAL_ROUTING_MAC),
rewriteService.getOrigIngressDstMac(cntx));
assertEquals(new Long(mac), rewriteService.getFinalIngressDstMac(cntx));
assertEquals(1, rewriteService.getTtlDecrement(cntx).intValue());
verify(netVirtManager);
}
@Test
public void testUnicastSameNetVirtDifferentSubnet() throws Exception {
ListenerContext cntx = new ListenerContext();
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[0].getName(), null);
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1);
h.writeToStorage(storageSource);
Thread.sleep(1000);
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1x0", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface2x0", netVirt[0], null, null));
/* Do not set CONTEXT_DST_IFACES in the cntx. This will be queried */
long mac = HexString.toLong("00:11:22:33:44:55");
int ip = IPv4.toIPv4Address("192.168.1.2");
IDevice dst = mockDeviceManager.learnEntity(mac, null, ip, 1L, 2);
dev2 = dst;
expect(netVirtManager.getInterfaces(dst)).andReturn(dstIfaces).anyTimes();
replay(netVirtManager);
this.testPacket = new Ethernet()
.setDestinationMACAddress(Ethernet.toByteArray(VirtualRouterManager.VIRTUAL_ROUTING_MAC))
.setSourceMACAddress("00:44:33:22:11:00")
.setVlanID((short) 42)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.1.2")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.testPacketSerialized = testPacket.serialize();
testUnicastInternal(cntx, RoutingAction.FORWARD);
/* Check that the dest Ip is also matched in the flowmod */
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
int dstIpWildcard = d.getWildcards() & OFMatch.OFPFW_NW_DST_MASK;
assertEquals(dstIpWildcard, 0);
verifyContext(cntx, netVirt[0], netVirt[0]);
/* Check that source and dest MAC and TTL are modified */
assertEquals(new Long(VirtualRouterManager.VIRTUAL_ROUTING_MAC),
rewriteService.getOrigIngressDstMac(cntx));
assertEquals(new Long(mac), rewriteService.getFinalIngressDstMac(cntx));
assertEquals(1, rewriteService.getTtlDecrement(cntx).intValue());
verify(netVirtManager);
}
@Test
public void testVRUnicastTTLDrop() throws Exception {
ListenerContext cntx = new ListenerContext();
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[0].getName(), null);
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[1].getName(), null);
Map<String, Object> rr1 =
h.createRoutingRule(r1, "tt1", null, null, null, "tt1", null,
null, null, null, null, "permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2);
h.addRoutingRule(rr1);
h.writeToStorage(storageSource);
Thread.sleep(1000);
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1x0", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface2x1", netVirt[1], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
// Set the TTL to 1
this.testPacket = new Ethernet()
.setDestinationMACAddress(Ethernet.toByteArray(VirtualRouterManager.VIRTUAL_ROUTING_MAC))
.setSourceMACAddress("00:44:33:22:11:00")
.setVlanID((short) 42)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 1)
.setSourceAddress("192.168.1.1")
.setDestinationAddress("192.168.1.2")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.testPacketSerialized = testPacket.serialize();
VirtualRouting routing = getVirtualRouting();
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
// build out input packet
OFPacketIn pi;
pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short) 1)
.setPacketData(testPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) testPacketSerialized.length);
// Start recording the replay on the mocks
replay(mockSwitch);
// Trigger the packet in
Command ret = routing.receive(mockSwitch, pi,
parseAndAnnotate(cntx, pi, dev1, dev2));
assertEquals(Command.STOP, ret);
}
@Test
public void testVRUnicastPassStaticARP() throws Exception {
ListenerContext cntx = new ListenerContext();
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[0].getName(), null);
Map<String, Object> ip1 = h.createIfaceIp(if1, "10.1.1.1",
"0.0.0.255");
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[1].getName(), null);
Map<String, Object> if3 = h.createIface(r1, "if3", true,
netVirt[2].getName(), null);
Map<String, Object> ip3 = h.createIfaceIp(if3, "10.1.3.1",
"0.0.0.255");
String srcMacStr = new String("00:11:33:44:55:66");
String destMacStr = new String("00:11:22:33:44:55");
String nextHopMacStr = new String("55:44:33:22:11:00");
String nextHopIpStr = new String("10.1.3.10");
String srcIpStr = new String("10.1.1.2");
String destIpStr = new String("10.1.3.2");
Map<String, Object> rr1 =
h.createRoutingRule(r1, "tt1", null, null, null, null, null,
"0.0.0.0", "255.255.255.255", null,
nextHopIpStr, "permit");
Map<String, Object> arp1 = h.createStaticArp(destIpStr, destMacStr);
Map<String, Object> arp2 = h.createStaticArp(nextHopIpStr,
nextHopMacStr);
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2, if3);
h.addIfaceIpAddr(ip1, ip3);
h.addRoutingRule(rr1);
h.addStaticArp(arp1, arp2);
h.writeToStorage(storageSource);
Thread.sleep(1000);
/* NetVirt0 and NetVirt1 are in the source. NetVirt2 is in the dest. All 3 are
* connected via a router
*/
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 2; n++) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null,
null));
}
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface2x2", netVirt[2], null, null));
/* We need to assign dev1 and dev2 to a proper address space */
String addressSpaceName = "MyAddressSpace";
Short vlan = 0;
BetterEntityClass addressSpace = new BetterEntityClass(addressSpaceName, vlan);
IEntityClassifierService ecs =
createMock(IEntityClassifierService.class);
expect(ecs.classifyEntity(anyObject(Entity.class)))
.andReturn(addressSpace).anyTimes();
expect(ecs.getKeyFields())
.andReturn(EnumSet.of(DeviceField.VLAN, DeviceField.MAC))
.anyTimes();
ecs.addListener(mockDeviceManager);
expectLastCall().anyTimes();
replay(ecs);
mockDeviceManager.setEntityClassifier(ecs);
dev1m = Ethernet.toLong(((Ethernet)testPacket).
getSourceMACAddress());
dev1 = mockDeviceManager.learnEntity(HexString.toLong(srcMacStr), null,
null, 1L, 1);
/* The destination device in this case is unknown to virtual routing */
dev2 = null;
/* Tell device manager of the next hop device */
long mac = HexString.toLong(nextHopMacStr);
int ip = IPv4.toIPv4Address(nextHopIpStr);
IDevice dst = mockDeviceManager.learnEntity(mac, null, ip, 1L, 2);
expect(netVirtManager.getInterfaces(dst)).andReturn(dstIfaces).anyTimes();
expect(netVirtManager.getVNS(netVirt[2].getName())).andReturn(netVirt[2]).times(2);
replay(netVirtManager);
this.testPacket = new Ethernet()
.setDestinationMACAddress(Ethernet.toByteArray(VirtualRouting.MIN_VIRTUAL_MAC))
.setSourceMACAddress(srcMacStr)
.setVlanID((short) 42)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress(srcIpStr)
.setDestinationAddress(destIpStr)
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.testPacketSerialized = testPacket.serialize();
testUnicastInternal(cntx, RoutingAction.FORWARD);
/* Check that the dest Ip is also matched in the flowmod */
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
int dstIpWildcard = d.getWildcards() & OFMatch.OFPFW_NW_DST_MASK;
assertEquals(dstIpWildcard, 0);
verifyContext(cntx, netVirt[1], netVirt[2]);
/* Check that source and dest MAC and TTL are modified */
assertEquals(new Long(VirtualRouting.MIN_VIRTUAL_MAC),
rewriteService.getOrigIngressDstMac(cntx));
assertEquals(new Long(mac), rewriteService.getFinalIngressDstMac(cntx));
assertEquals(new Long(VirtualRouterManager.VIRTUAL_ROUTING_MAC),
rewriteService.getFinalEgressSrcMac(cntx));
verify(netVirtManager, ecs);
}
@Test
public void testVRUnicastPassGatewayPool() throws Exception {
ListenerContext cntx = new ListenerContext();
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[0].getName(), null);
Map<String, Object> ip1 = h.createIfaceIp(if1, "10.1.1.1",
"0.0.0.255");
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[1].getName(), null);
Map<String, Object> if3 = h.createIface(r1, "if3", true,
netVirt[2].getName(), null);
Map<String, Object> ip3 = h.createIfaceIp(if3, "10.1.3.1",
"0.0.0.255");
Map<String, Object> gwPool = h.createGatewayPool(r1, "gw-pool");
Map<String, Object> gwNode1 = h.createGatewayNode(gwPool, "10.1.3.10");
Map<String, Object> gwNode2 = h.createGatewayNode(gwPool, "10.1.3.11");
String srcMacStr = new String("00:11:33:44:55:66");
String destMacStr = new String("00:11:22:33:44:55");
String gwNode1MacStr = new String("55:44:33:22:11:00");
String gwNode1IpStr = new String("10.1.3.10");
String gwNode2MacStr = new String("55:44:33:22:11:01");
String gwNode2IpStr = new String("10.1.3.11");
String srcIpStr = new String("10.1.1.2");
String destIpStr = new String("10.1.3.2");
Map<String, Object> rr1 =
h.createRoutingRule(r1, "tt1", null, null, null, null, null,
"0.0.0.0", "255.255.255.255", null,
null, "permit", "tt1|r1|gw-pool");
Map<String, Object> arp1 = h.createStaticArp(destIpStr, destMacStr);
Map<String, Object> arp2 = h.createStaticArp(gwNode1IpStr,
gwNode1MacStr);
Map<String, Object> arp3 = h.createStaticArp(gwNode2IpStr,
gwNode2MacStr);
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2, if3);
h.addIfaceIpAddr(ip1, ip3);
h.addRoutingRule(rr1);
h.addStaticArp(arp1, arp2, arp3);
h.addVirtRtrGatewayPool(gwPool);
h.addGatewayNode(gwNode1);
h.addGatewayNode(gwNode2);
h.writeToStorage(storageSource);
Thread.sleep(1000);
/* NetVirt0 and NetVirt1 are in the source. NetVirt2 is in the dest. All 3 are
* connected via a router
*/
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 2; n++) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null,
null));
}
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface2x2", netVirt[2], null, null));
/* We need to assign dev1 and dev2 to a proper address space */
String addressSpaceName = "MyAddressSpace";
Short vlan = 0;
BetterEntityClass addressSpace = new BetterEntityClass(addressSpaceName, vlan);
IEntityClassifierService ecs =
createMock(IEntityClassifierService.class);
expect(ecs.classifyEntity(anyObject(Entity.class)))
.andReturn(addressSpace).anyTimes();
expect(ecs.getKeyFields())
.andReturn(EnumSet.of(DeviceField.VLAN, DeviceField.MAC))
.anyTimes();
ecs.addListener(mockDeviceManager);
expectLastCall().anyTimes();
replay(ecs);
mockDeviceManager.setEntityClassifier(ecs);
dev1m = Ethernet.toLong(((Ethernet)testPacket).
getSourceMACAddress());
dev1 = mockDeviceManager.learnEntity(HexString.toLong(srcMacStr), null,
null, 1L, 1);
/* The destination device in this case is unknown to virtual routing */
dev2 = null;
/* Tell device manager of gwNode1 device */
long gwNode1Mac = HexString.toLong(gwNode1MacStr);
int gwNode1Ip = IPv4.toIPv4Address(gwNode1IpStr);
IDevice gwNode1Dev = mockDeviceManager.learnEntity(gwNode1Mac, null, gwNode1Ip, 1L, 2);
expect(netVirtManager.getInterfaces(gwNode1Dev)).andReturn(dstIfaces).anyTimes();
expect(netVirtManager.getVNS(netVirt[2].getName())).andReturn(netVirt[2]).times(2);
/* Tell device manager of gwNode2 device */
long gwNode2Mac = HexString.toLong(gwNode2MacStr);
int gwNode2Ip = IPv4.toIPv4Address(gwNode2IpStr);
IDevice gwNode2Dev = mockDeviceManager.learnEntity(gwNode2Mac, null, gwNode2Ip, 2L, 2);
replay(netVirtManager);
/*
* Setup the mock routes
*/
Route routeD1ToGN1 = new Route(dev1.getMACAddress(),
gwNode1Dev.getMACAddress());
routeD1ToGN1.getPath().add(new NodePortTuple(1L, (short)1));
routeD1ToGN1.getPath().add(new NodePortTuple(1L, (short)2));
Route routeD1ToGN2 = new Route(dev1.getMACAddress(),
gwNode2Dev.getMACAddress());
routeD1ToGN2.getPath().add(new NodePortTuple(1L, (short)1));
routeD1ToGN2.getPath().add(new NodePortTuple(1L, (short)3));
routeD1ToGN2.getPath().add(new NodePortTuple(2L, (short)1));
routeD1ToGN2.getPath().add(new NodePortTuple(2L, (short)2));
/*
* ReMock up topology to return the L2DomainId
*/
reset(topology);
expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
expect(topology.getL2DomainId(2L)).andReturn(1L).anyTimes();
expect(topology.isAttachmentPointPort(EasyMock.anyLong(),
EasyMock.anyShort()))
.andReturn(true).anyTimes();
/*
* Mock up routingEngine to return the appropriate mock route
*/
expect(routingEngine.getRoute(1L, (short)1, 1L, (short)2, 0)).
andReturn(routeD1ToGN1).times(1);
expect(routingEngine.getRoute(1L, (short)1, 2L, (short)2, 0)).
andReturn(routeD1ToGN2).times(1);
replay(topology, routingEngine);
this.testPacket = new Ethernet()
.setDestinationMACAddress(Ethernet.toByteArray(VirtualRouting.MIN_VIRTUAL_MAC))
.setSourceMACAddress(srcMacStr)
.setVlanID((short) 42)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress(srcIpStr)
.setDestinationAddress(destIpStr)
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
this.testPacketSerialized = testPacket.serialize();
testUnicastInternal(cntx, RoutingAction.FORWARD);
/* Check that the dest Ip is also matched in the flowmod */
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
int dstIpWildcard = d.getWildcards() & OFMatch.OFPFW_NW_DST_MASK;
assertEquals(dstIpWildcard, 0);
verifyContext(cntx, netVirt[1], netVirt[2]);
/* Check that source and dest MAC and TTL are modified */
assertEquals(new Long(VirtualRouting.MIN_VIRTUAL_MAC),
rewriteService.getOrigIngressDstMac(cntx));
assertEquals(new Long(gwNode1Mac), rewriteService.getFinalIngressDstMac(cntx));
assertEquals(new Long(VirtualRouterManager.VIRTUAL_ROUTING_MAC),
rewriteService.getFinalEgressSrcMac(cntx));
verify(netVirtManager, ecs, topology, routingEngine);
}
/**
* Multiple source and destination NetVirtes with no overlap,
* should drop.
*/
@Test
public void testUnicastDropMulti() throws Exception {
final int nNetVirtes = 100;
ListenerContext cntx = new ListenerContext();
VNS[] netVirt = new VNS[nNetVirtes];
for (int n = 0; n < nNetVirtes; n++) {
netVirt[n] = new VNS("testNetVirt" + n);
netVirt[n].setPriority(n);
}
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 30; n++) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null, null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
for (int n = 70; n < nNetVirtes; n++) {
dstIfaces.add(new VNSInterface("testSrcIface2x" + n, netVirt[n], null, null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_DST_IFACES, dstIfaces);
testUnicastInternal(cntx, RoutingAction.DROP);
verifyContext(cntx, null);
}
/**
* Multiple source and destination NetVirtes with multiple,
* overlap and different priority. Should pick the one
* with the highest priority.
*/
@Test
public void testUnicastPassPriority() throws Exception {
final int nNetVirtes = 100;
ListenerContext cntx = new ListenerContext();
VNS[] netVirt = new VNS[nNetVirtes];
for (int n = 0; n < nNetVirtes; n++) {
netVirt[n] = new VNS("testNetVirt" + n);
netVirt[n].setPriority(n);
}
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 70; n >0; n--) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null, null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
for (int n = 30; n < nNetVirtes; n++) {
dstIfaces.add(new VNSInterface("testSrcIface2x" + n, netVirt[n], null, null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_DST_IFACES, dstIfaces);
testUnicastInternal(cntx, RoutingAction.FORWARD);
verifyContext(cntx, netVirt[70]);
}
/**
* Multiple source and destination NetVirtes with multiple pairs connected by
* virtual routing. Should forward.
*/
@Test
public void testVRUnicastPassPriority() throws Exception {
ListenerContext cntx = new ListenerContext();
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[5].getName(), null);
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[6].getName(), null);
Map<String, Object> if3 = h.createIface(r1, "if3", true,
netVirt[7].getName(), null);
Map<String, Object> if4 = h.createIface(r1, "if4", true,
netVirt[8].getName(), null);
Map<String, Object> if5 = h.createIface(r1, "if5", true,
netVirt[9].getName(), null);
Map<String, Object> if6 = h.createIface(r1, "if6", true,
netVirt[10].getName(), null);
Map<String, Object> rr1 = h.createRoutingRule(r1, "tt1", null, null,
null, "tt1", null, null,
null, null, null,
"permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2, if3, if4, if5, if6);
h.addRoutingRule(rr1);
h.writeToStorage(storageSource);
Thread.sleep(1000);
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 7; n++) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null, null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
for (int n = 7; n < 15; n++) {
dstIfaces.add(new VNSInterface("testSrcIface2x" + n, netVirt[n], null, null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_DST_IFACES, dstIfaces);
testUnicastInternal(cntx, RoutingAction.FORWARD);
verifyContext(cntx, netVirt[6], netVirt[10]);
}
/**
* Multiple source and destination NetVirtes with multiple pairs connected by
* virtual routing. Should forward.
*/
@Test
public void testVRUnicastPassPriority2() throws Exception {
ListenerContext cntx = new ListenerContext();
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[5].getName(), null);
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[6].getName(), null);
Map<String, Object> if3 = h.createIface(r1, "if3", true,
netVirt[7].getName(), null);
Map<String, Object> if4 = h.createIface(r1, "if4", true,
netVirt[8].getName(), null);
Map<String, Object> if5 = h.createIface(r1, "if5", true,
netVirt[9].getName(), null);
Map<String, Object> if6 = h.createIface(r1, "if6", true,
netVirt[10].getName(), null);
Map<String, Object> rr1 = h.createRoutingRule(r1, "tt1", null, null,
null, "tt1", null, null,
null, null, null,
"permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2, if3, if4, if5, if6);
h.addRoutingRule(rr1);
h.writeToStorage(storageSource);
Thread.sleep(1000);
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 6; n++) {
srcIfaces.add(new VNSInterface("testSrcIface1x" + n, netVirt[n], null,
null));
}
srcIfaces.add(new VNSInterface("testSrcIface2x20", netVirt[20], null,
null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
for (int n = 7; n < 15; n++) {
dstIfaces.add(new VNSInterface("testSrcIface2x" + n, netVirt[n], null,
null));
}
/* When a higher priority common interface is added, that is selected */
dstIfaces.add(new VNSInterface("testSrcIface2x20", netVirt[20], null,
null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
testUnicastInternal(cntx, RoutingAction.FORWARD);
verifyContext(cntx, netVirt[20]);
}
/**
* Common function for sending a Broadcast/Multicast packet
*/
private void testXcastInternal(OFPacketIn pi, ListenerContext cntx, RoutingAction action, int ndev, int nifaces)
throws Exception {
VirtualRouting routing = getVirtualRouting();
IControllerService mockControllerProvider = createMock(IControllerService.class);
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
// Start recording the replay on the mocks
replay(mockSwitch);
// Trigger the packet in
Command ret = routing.receive(mockSwitch, pi, parseAndAnnotate(cntx, pi, dev1, dev2));
// Get the annotation output for verification
IRoutingDecision d = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
// Verify the replay matched our expectations
// Don't veryfiy netVirtManager if the RoutingAction is drop, then NetVirt Manager function
// wouldn't hav been invoked.
verify(mockSwitch);
if (action == RoutingAction.DROP) {
assertTrue(ret == Command.STOP);
} else if (action == RoutingAction.FORWARD_OR_FLOOD){
assertTrue(d.getRoutingAction() == action);
assertTrue(d.getSourcePort().getSwitchDPID() == 1L);
assertTrue(d.getSourcePort().getPort() == pi.getInPort());
assertEquals(d.getSourceDevice(), dev1);
assertTrue(d.getDestinationDevices().size() == ndev);
assertTrue(d.getMulticastInterfaces().size() == 0);
}
}
/*
* Wrapper for testing Broadcast
*/
private void testBroadcastInternal(ListenerContext cntx, RoutingAction action, int ndev, int nifaces)
throws Exception {
OFPacketIn pi;
// build out input packet
pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short) 1)
.setPacketData(broadcastPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) broadcastPacketSerialized.length);
testXcastInternal(pi, cntx, action, ndev, nifaces);
}
/**
* Broadcast packet, should drop since a src NetVirt asked for it
*/
@Test
public void testBroadcastDrop() throws Exception {
ListenerContext cntx = new ListenerContext();
VNS netVirt = new VNS("testNetVirt");
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface", netVirt, null, null));
netVirt.setBroadcastMode(BroadcastMode.DROP);
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
testBroadcastInternal(cntx, RoutingAction.DROP, 0, 0);
}
/**
* Broadcast packet, should flood by default
*/
@Test
public void testBroadcastFlood() throws Exception {
ListenerContext cntx = new ListenerContext();
VNS[] netVirt = new VNS[3];
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 3; n++) {
netVirt[n] = new VNS("testNetVirt" + n);
srcIfaces.add(new VNSInterface("testSrcIface" + n, netVirt[n], null, null));
}
netVirt[1].setBroadcastMode(BroadcastMode.ALWAYS_FLOOD);
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
testBroadcastInternal(cntx, RoutingAction.FORWARD_OR_FLOOD, 0, 0);
}
/**
* Broadcast packet, should send to known destination devices and
* explicitly configured broadcast switch interfaces.
* FORWARD_TO_KNOWN is the default behavior for NetVirt broadcast.
*/
@Test
public void testBroadcastForward() throws Exception {
ListenerContext cntx = new ListenerContext();
VNS[] netVirt = new VNS[3];
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
mockDeviceManager.startUp(fmc);
for (int n = 0; n < 3; n++) {
netVirt[n] = new VNS("testNetVirt" + n);
IDevice d = mockDeviceManager.learnEntity(n, null, null, null, null);
netVirt[n].addDevice(d);
srcIfaces.add(new VNSInterface("testSrcIface" + n, netVirt[n], null, null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
testBroadcastInternal(cntx, RoutingAction.MULTICAST, 2, 0);
}
/*
* Wrapper for testing Broadcast
*/
private void testMulticastInternal(ListenerContext cntx, RoutingAction action, int ndev, int nifaces)
throws Exception {
OFPacketIn pi;
// build out input packet
pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short) 1)
.setPacketData(multicastPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) multicastPacketSerialized.length);
testXcastInternal(pi, cntx, action, ndev, nifaces);
}
/**
* Multicast packet, should drop since a src NetVirt asked for it
*/
@Test
public void testMulticastDrop() throws Exception {
ListenerContext cntx = new ListenerContext();
VNS netVirt = new VNS("testNetVirt");
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface", netVirt, null, null));
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
netVirt.setBroadcastMode(BroadcastMode.DROP);
testMulticastInternal(cntx, RoutingAction.DROP, 0, 0);
}
/**
* Multicast packet, floods when the mode is set to ALWAYS_FLOOD
*/
@Test
public void testMulticastFlood() throws Exception {
ListenerContext cntx = new ListenerContext();
VNS[] netVirt = new VNS[3];
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 3; n++) {
netVirt[n] = new VNS("testNetVirt" + n);
srcIfaces.add(new VNSInterface("testSrcIface" + n, netVirt[n], null, null));
}
netVirt[1].setBroadcastMode(BroadcastMode.ALWAYS_FLOOD);
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
testMulticastInternal(cntx, RoutingAction.FORWARD_OR_FLOOD, 0, 0);
}
/**
* Multicast packet: Packet is multicast only to known devices/interfaces
* FORWARD_TO_KNOWN is the default behavior for NetVirt multicast.
*/
@Test
public void testMulticastForward() throws Exception {
ListenerContext cntx = new ListenerContext();
VNS[] netVirt = new VNS[3];
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
mockDeviceManager.startUp(fmc);
for (int n = 0; n < 3; n++) {
netVirt[n] = new VNS("testNetVirt" + n);
IDevice d = mockDeviceManager.learnEntity(n, null, null, null, null);
netVirt[n].addDevice(d);
srcIfaces.add(new VNSInterface("testSrcIface" + n, netVirt[n], null, null));
}
// FORWARD_TO_KNOWN is the default behavior.
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES, srcIfaces);
/*
* Add a couple of switch ports to the broadcast interface on the netVirtmanager.
*/
testMulticastInternal(cntx, RoutingAction.MULTICAST, 2, 0);
}
/**
* Tests a host talking to another IP address we don't know about.
*/
@Test
public void testUnknownDest() throws Exception {
OFPacketIn pi;
ListenerContext cntx = new ListenerContext();
VirtualRouting routing = getVirtualRouting();
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
reset(topology);
expect(topology.isAttachmentPointPort(EasyMock.anyLong(), EasyMock.anyShort())).andReturn(true).anyTimes();
expect(topology.getL2DomainId(EasyMock.anyLong())).andReturn(1L).anyTimes();
dev1 = mockDeviceManager.learnEntity(dev1m, null, null, 1L, 1);
// build out input packet
pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short) 1)
.setPacketData(testPacketUnknownDestSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) testPacketUnknownDestSerialized.length);
// Start recording the replay on the mocks
replay(mockSwitch);
// Trigger the packet in
routing.receive(mockSwitch, pi, parseAndAnnotate(cntx, pi, dev1, null));
// Get the annotation output for verification
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
// Verify the replay matched our expectations
verify(mockSwitch);
// Make sure we are re-injecting an ARP
assertTrue(d.getRoutingAction() == RoutingAction.FORWARD);
}
@Test
public void testBroadcastForwardWithInterfaces(){
// Set the Listener Context.
ListenerContext cntx = new ListenerContext();
VNS[] netVirt = new VNS[3];
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 3; n++) {
netVirt[n] = new VNS("testNetVirt" + n);
IDevice d = mockDeviceManager.learnEntity(n, null, null, null, null);
netVirt[n].addDevice(d);
srcIfaces.add(new VNSInterface("testSrcIface" + n, netVirt[n], null, null));
}
// Default broadcast behavior is FORWARD_TO_KNOWN
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
// Set the packet in.
OFPacketIn pi;
pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short) 1)
.setPacketData(broadcastPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) broadcastPacketSerialized.length);
// Set the routing action.
RoutingAction action = RoutingAction.MULTICAST;
VirtualRouting routing = getVirtualRouting();
INetVirtManagerService mockNetVirtManager = createMock(INetVirtManagerService.class);
routing.setNetVirtManager(mockNetVirtManager);
// Create some mock switches for creating the switch port tuple.
IOFSwitch mockSwitch2 = createNiceMock(IOFSwitch.class);
expect(mockSwitch2.getId()).andReturn(2L).anyTimes();
List<SwitchPort> lspt = new ArrayList<SwitchPort>();
lspt.add(new SwitchPort(1L, 101));
lspt.add(new SwitchPort(2L, 102));
HashMap<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
switches.put(1L, mockSwitch);
switches.put(2L, mockSwitch2);
mockControllerProvider.setSwitches(switches);
expect(mockNetVirtManager.getBroadcastSwitchPorts()).
andReturn(lspt).anyTimes();
// Start recording the replay on the mocks
replay(mockNetVirtManager);
replay(mockSwitch);
replay(mockSwitch2);
// Trigger the packet in
Command ret = routing.receive(mockSwitch, pi,
parseAndAnnotate(cntx, pi, dev1, null));
// Get the annotation output for verification
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
// Verify the replay matched our expectations
// Don't verify netVirtManager if the RoutingAction is drop, then NetVirt
// Manager function wouldn't have been invoked.
verify(mockNetVirtManager);
if (action == RoutingAction.DROP) {
assertEquals(Command.STOP, ret);
} else if (action == RoutingAction.FORWARD_OR_FLOOD){
assertEquals(action, d.getRoutingAction());
assertEquals(1L, d.getSourcePort().getSwitchDPID());
assertEquals(pi.getInPort(), d.getSourcePort().getPort());
assertEquals(dev1, d.getSourceDevice());
assertEquals(2, d.getDestinationDevices().size());
assertEquals(2, d.getMulticastInterfaces().size());
}
}
@Test
public void testMulticastForwardWithInterfaces(){
// Set the Listener Context.
ListenerContext cntx = new ListenerContext();
VNS[] netVirt = new VNS[3];
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 3; n++) {
netVirt[n] = new VNS("testNetVirt" + n);
IDevice d = mockDeviceManager.learnEntity(n, null, null, null, null);
netVirt[n].addDevice(d);
srcIfaces.add(new VNSInterface("testSrcIface" + n, netVirt[n], null, null));
}
// Default mutlicast behavior is FORWARD_TO_KNOWN
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
// Set the packet in.
OFPacketIn pi;
// build out multicast input packet
pi = ((OFPacketIn) new BasicFactory().getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short) 1)
.setPacketData(multicastPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) multicastPacketSerialized.length);
// Set the routing action.
RoutingAction action = RoutingAction.MULTICAST;
VirtualRouting routing = getVirtualRouting();
INetVirtManagerService mockNetVirtManager =
createMock(INetVirtManagerService.class);
routing.setNetVirtManager(mockNetVirtManager);
// Create some mock switches for creating the switch port tuple.
IOFSwitch mockSwitch2 = createNiceMock(IOFSwitch.class);
expect(mockSwitch2.getId()).andReturn(2L).anyTimes();
List<SwitchPort> lspt = new ArrayList<SwitchPort>();
lspt.add(new SwitchPort(1L, 101));
lspt.add(new SwitchPort(2L, 102));
HashMap<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
switches.put(1L, mockSwitch);
switches.put(2L, mockSwitch2);
mockControllerProvider.setSwitches(switches);
expect(mockNetVirtManager.getBroadcastSwitchPorts()).
andReturn(lspt).anyTimes();
// Start recording the replay on the mocks
replay(mockNetVirtManager);
replay(mockSwitch);
replay(mockSwitch2);
// Trigger the packet in
Command ret = routing.receive(mockSwitch, pi,
parseAndAnnotate(cntx, pi, dev1, null));
// Get the annotation output for verification
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
// Verify the replay matched our expectations
// Don't veryfiy netVirtManager if the RoutingAction is drop, then NetVirt
// Manager function wouldn't hav been invoked.
verify(mockNetVirtManager);
if (action == RoutingAction.DROP) {
assertEquals(Command.STOP, ret);
} else if (action == RoutingAction.FORWARD_OR_FLOOD){
assertEquals(action, d.getRoutingAction());
assertEquals(1L, d.getSourcePort().getSwitchDPID());
assertEquals(pi.getInPort(), d.getSourcePort().getPort());
assertEquals(dev1, d.getSourceDevice());
assertEquals(2, d.getDestinationDevices().size());
assertEquals(2, d.getMulticastInterfaces().size());
}
}
@Test
public void testVMacAcquisition() {
// Ok to request a vMac outside of the allocated block
assertEquals(true, virtualRouting.acquireVirtualMac(
VirtualRouting.MAX_VIRTUAL_MAC+1));
assertEquals(true, virtualRouting.acquireVirtualMac(
VirtualRouting.MIN_VIRTUAL_MAC-1));
int remainedVMacSize = virtualRouting.reclaimedVMacs.size();
long nextAvailVMac = virtualRouting.nextAvailableVMac;
virtualRouting.relinquishVirtualMAC(
VirtualRouting.MAX_VIRTUAL_MAC+1);
virtualRouting.relinquishVirtualMAC(
VirtualRouting.MIN_VIRTUAL_MAC-1);
assertEquals(remainedVMacSize,
virtualRouting.reclaimedVMacs.size());
assertEquals(nextAvailVMac, virtualRouting.nextAvailableVMac);
long ns1_macl = VirtualRouting.MIN_VIRTUAL_MAC;
assertTrue(virtualRouting.acquireVirtualMac(ns1_macl));
// request for the same vMac should fail
assertFalse(virtualRouting.acquireVirtualMac(ns1_macl));
// Make sure we get the next available vMac
long ns2_macl = ns1_macl + 1;
long acquiredMac = 0;
try {
acquiredMac = virtualRouting.acquireVirtualMac();
} catch (VirtualMACExhaustedException e) {
fail("Unexpected SIVirtualMACExhaustedException exception");
}
assertEquals(ns2_macl, acquiredMac);
// Get a vMac in the middle of the allocated block
long nsxxx_macl = ns2_macl + 5;
assertTrue(virtualRouting.acquireVirtualMac(nsxxx_macl));
// next auto-generated vMac should be ns2_mac+1
long acquiredMac1 = 0;
long acquiredMac2 = 0;
long acquiredMac3 = 0;
long acquiredMac4 = 0;
long acquiredMac5 = 0;
try {
acquiredMac1 = virtualRouting.acquireVirtualMac();
acquiredMac2 = virtualRouting.acquireVirtualMac();
acquiredMac3 = ns2_macl+3;
assertTrue(virtualRouting.acquireVirtualMac(acquiredMac3));
acquiredMac4 = virtualRouting.acquireVirtualMac();
acquiredMac5 = virtualRouting.acquireVirtualMac();
} catch (VirtualMACExhaustedException e) {
fail("Unexpected SIVirtualMACExhaustedException exception");
}
assertEquals(ns2_macl+1, acquiredMac1);
assertEquals(ns2_macl+2, acquiredMac2);
assertEquals(ns2_macl+3, acquiredMac3);
assertEquals(ns2_macl+4, acquiredMac4);
assertEquals(ns2_macl+6, acquiredMac5);
assertEquals(ns2_macl+7, virtualRouting.nextAvailableVMac);
assertEquals(0, virtualRouting.reclaimedVMacs.size());
// Relinquish ns2_mac, the next auto-generated vMac should be ns2_mac
virtualRouting.relinquishVirtualMAC(ns2_macl);
try {
acquiredMac = virtualRouting.acquireVirtualMac();
} catch (VirtualMACExhaustedException e) {
fail("Unexpected SIVirtualMACExhaustedException exception");
}
assertEquals(ns2_macl, acquiredMac);
// simulate the case when all vMacs have been allocated
virtualRouting.reclaimedVMacs.clear();
virtualRouting.nextAvailableVMac =
VirtualRouting.MAX_VIRTUAL_MAC;
try {
acquiredMac = virtualRouting.acquireVirtualMac();
} catch (VirtualMACExhaustedException e) {
fail("Unexpected SIVirtualMACExhaustedException exception");
}
assertEquals(VirtualRouting.MAX_VIRTUAL_MAC, acquiredMac);
try {
acquiredMac = virtualRouting.acquireVirtualMac();
} catch (Exception e) {
assertTrue(e instanceof VirtualMACExhaustedException);
return;
}
fail("SIVirtualMACExhaustedException is not raised.");
}
private OFPacketIn createARPPkt(String hostMACStr, String hostIpStr,
String vIpStr) {
int vIP = IPv4.toIPv4Address(vIpStr);
ARP arprequestVIP = new ARP()
.setHardwareType(ARP.HW_TYPE_ETHERNET)
.setProtocolType(ARP.PROTO_TYPE_IP)
.setHardwareAddressLength((byte) 6)
.setProtocolAddressLength((byte) 4)
.setOpCode(ARP.OP_REQUEST)
.setSenderHardwareAddress(Ethernet.toMACAddress(hostMACStr))
.setSenderProtocolAddress(IPv4.toIPv4AddressBytes(hostIpStr))
.setTargetHardwareAddress(Ethernet.toMACAddress("FF:FF:FF:FF:FF:FF"))
.setTargetProtocolAddress(vIP);
IPacket arprequestPacketVIP = new Ethernet()
.setSourceMACAddress(hostMACStr)
.setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
.setEtherType(Ethernet.TYPE_ARP)
.setPayload(arprequestVIP);
byte[] arpRequestSerializedVIP = arprequestPacketVIP.serialize();
OFPacketIn packetInARPRequestVIP =
((OFPacketIn) (new BasicFactory()).getMessage(OFType.PACKET_IN))
.setBufferId(OFPacketOut.BUFFER_ID_NONE)
.setInPort((short) 1)
.setPacketData(arpRequestSerializedVIP)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) arpRequestSerializedVIP.length);
return packetInARPRequestVIP;
}
private OFPacketIn createICMPPkt(long hostMAC, int hostIp, long vMAC,
int vIp) {
byte[] srcMAC = Ethernet.toByteArray(hostMAC);
byte[] dstMAC = Ethernet.toByteArray(vMAC);
IPacket icmpRequestPacket = new Ethernet()
.setSourceMACAddress(srcMAC)
.setDestinationMACAddress(dstMAC)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setSourceAddress(hostIp)
.setDestinationAddress(vIp)
.setProtocol(IPv4.PROTOCOL_ICMP)
.setTtl((byte) 64)
.setPayload(
new ICMP()
.setIcmpType(ICMP.ECHO_REQUEST)
.setIcmpCode((byte) 0)));
byte[] icmpRequestSerialized = icmpRequestPacket.serialize();
OFPacketIn packetInICMPRequest =
((OFPacketIn) (new BasicFactory()).getMessage(OFType.PACKET_IN))
.setBufferId(OFPacketOut.BUFFER_ID_NONE)
.setInPort((short) 1)
.setPacketData(icmpRequestSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) icmpRequestSerialized.length);
return packetInICMPRequest;
}
private OFPacketIn createTraceroutePkt(long srcMAC, int srcIp, long dstMAC,
int dstIp, byte ttl) {
byte[] srcMACBytes = Ethernet.toByteArray(srcMAC);
byte[] dstMACBytes = Ethernet.toByteArray(dstMAC);
IPacket traceroutePacket = new Ethernet()
.setSourceMACAddress(srcMACBytes)
.setDestinationMACAddress(dstMACBytes)
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setSourceAddress(srcIp)
.setDestinationAddress(dstIp)
.setProtocol(IPv4.PROTOCOL_UDP)
.setTtl(ttl)
.setPayload(
new UDP()
.setDestinationPort(VirtualRouting.TRACEROUTE_PORT_START)));
byte[] tracerouteSerialized = traceroutePacket.serialize();
OFPacketIn packetInTraceroute =
((OFPacketIn) (new BasicFactory()).getMessage(OFType.PACKET_IN))
.setBufferId(OFPacketOut.BUFFER_ID_NONE)
.setInPort((short) 1)
.setPacketData(tracerouteSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) tracerouteSerialized.length);
return packetInTraceroute;
}
protected void setForwardingExpect(IOFSwitch sw, Long swId, int times) {
reset(forwarding);
reset(sw);
// MockSwitch2 expect
List<OFPhysicalPort> ports = new ArrayList<OFPhysicalPort>();
OFPhysicalPort oPort = new OFPhysicalPort();
oPort.setPortNumber((short)1);
ports.add(oPort);
oPort = new OFPhysicalPort();
oPort.setPortNumber((short)2);
ports.add(oPort);
expect(sw.getEnabledPorts()).andReturn(ports).times(times);
if (swId != null) {
expect(sw.getId()).andReturn(swId.longValue()).times(times);
}
expect(forwarding.pushPacketOutToEgressPort(
(Ethernet)EasyMock.anyObject(),
EasyMock.anyShort(),
(SwitchPort)EasyMock.anyObject(),
EasyMock.anyBoolean(),
(String)EasyMock.anyObject(),
(Short)EasyMock.anyShort(),
(ListenerContext)EasyMock.anyObject(),
EasyMock.anyBoolean()))
.andReturn(true)
.times(times);
}
@Test
public void testARPRequestHandler() throws Exception {
String hostMACStr = "ff:ee:dd:cc:bb:aa";
byte[] hostMAC = Ethernet.toMACAddress(hostMACStr);
String hostIPStr = "10.1.1.2";
int hostIP = IPv4.toIPv4Address(hostIPStr);
String vIPStr = "10.1.1.1";
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[5].getName(), null);
Map<String, Object> ip1 = h.createIfaceIp(if1, vIPStr, "255.255.255.0");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1);
h.addIfaceIpAddr(ip1);
IDevice srcDev = mockDeviceManager.learnEntity(Ethernet.toLong(hostMAC),
null, hostIP, 1L, 3);
ListenerContext cntx = new ListenerContext();
List<VNSInterface> ifaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 10; n++) {
ifaces.add(new VNSInterface("testSrcIface2x" + n, netVirt[n], null,
null));
}
INetVirtManagerService.bcStore.put(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES,
ifaces);
VirtualRouting routing = getVirtualRouting();
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
OFPacketIn pi = createARPPkt(hostMACStr, hostIPStr, vIPStr);
replay(mockSwitch);
cntx = parseAndAnnotate(cntx, pi, srcDev, null);
expect(netVirtManager.getInterfaces(srcDev)).andReturn(ifaces).anyTimes();
replay(netVirtManager);
setForwardingExpect(mockSwitch, 1L, 1);
replay(mockSwitch, forwarding);
ARPCommand cmd = virtualRouting.ARPRequestHandler(mockSwitch, pi, cntx,
null);
assertEquals(ARPCommand.CONTINUE, cmd);
/* Now write the routing configuration to the storage and check that
* ARP request processing is stopped
*/
h.writeToStorage(storageSource);
Thread.sleep(1000);
cmd = virtualRouting.ARPRequestHandler(mockSwitch, pi, cntx, null);
assertEquals(ARPCommand.STOP, cmd);
}
@Test
public void testICMPRequestHandler() throws Exception {
String hostMACStr = "ff:ee:dd:33:22:11";
long hostMAC = Ethernet.toLong(Ethernet.toMACAddress(hostMACStr));
String hostIPStr = "10.1.3.3";
int hostIP = IPv4.toIPv4Address(hostIPStr);
long vMAC1 = VirtualRouterManager.VIRTUAL_ROUTING_MAC;
String vIP1Str = "10.1.3.1";
int vIP1 = IPv4.toIPv4Address(vIP1Str);
String vIP2Str = "10.1.4.1";
int vIP2 = IPv4.toIPv4Address(vIP2Str);
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[6].getName(), null);
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[7].getName(), null);
Map<String, Object> ip1 = h.createIfaceIp(if1, vIP1Str,
"255.255.255.0");
Map<String, Object> ip2 = h.createIfaceIp(if2, vIP2Str,
"255.255.255.0");
Map<String, Object> rr1 = h.createRoutingRule(r1, "tt1", null, null,
null, "tt1", null, null,
null, null, null,
"permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2);
h.addIfaceIpAddr(ip1, ip2);
h.addRoutingRule(rr1);
IDevice srcDev = mockDeviceManager.learnEntity(hostMAC, null, hostIP,
1L, 3);
ListenerContext cntx = new ListenerContext();
List<VNSInterface> ifaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 10; n++) {
ifaces.add(new VNSInterface("testSrcIfaces2x" + n, netVirt[n], null,
null));
}
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES, ifaces);
VirtualRouting routing = getVirtualRouting();
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
replay(mockSwitch);
expect(netVirtManager.getInterfaces(srcDev)).andReturn(ifaces).anyTimes();
replay(netVirtManager);
setForwardingExpect(mockSwitch, 1L, 2);
replay(mockSwitch, forwarding);
ICMPCommand cmd;
OFPacketIn pi1 = createICMPPkt(hostMAC, hostIP, vMAC1, vIP1);
cntx = parseAndAnnotate(cntx, pi1, srcDev, null);
cmd = virtualRouting.ICMPRequestHandler(mockSwitch, pi1,
cntx);
assertEquals(ICMPCommand.CONTINUE, cmd);
OFPacketIn pi2 = createICMPPkt(hostMAC, hostIP, vMAC1, vIP2);
cntx = parseAndAnnotate(cntx, pi2, srcDev, null);
cmd = virtualRouting.ICMPRequestHandler(mockSwitch, pi2, cntx);
assertEquals(ICMPCommand.CONTINUE, cmd);
/* Now write the routing configuration to the storage and check that
* ICMP request is processed
*/
h.writeToStorage(storageSource);
Thread.sleep(1000);
cntx = parseAndAnnotate(cntx, pi1, srcDev, null);
cmd = virtualRouting.ICMPRequestHandler(mockSwitch, pi1, cntx);
assertEquals(ICMPCommand.STOP, cmd);
cntx = parseAndAnnotate(cntx, pi2, srcDev, null);
cmd = virtualRouting.ICMPRequestHandler(mockSwitch, pi2, cntx);
assertEquals(ICMPCommand.STOP, cmd);
}
@Test
public void testIsTraceroutePacket() throws Exception {
String srcMACStr = "ff:ee:dd:33:22:11";
long srcMAC = Ethernet.toLong(Ethernet.toMACAddress(srcMACStr));
String srcIPStr = "10.1.3.3";
int srcIP = IPv4.toIPv4Address(srcIPStr);
long dstMAC = VirtualRouterManager.VIRTUAL_ROUTING_MAC;
String dstIPStr = "10.1.4.3";
int dstIP = IPv4.toIPv4Address(dstIPStr);
IDevice srcDev = mockDeviceManager.learnEntity(srcMAC, null, srcIP, 1L,
3);
ListenerContext cntx = new ListenerContext();
OFPacketIn pi1 = createICMPPkt(srcMAC, srcIP, dstMAC, dstIP);
cntx = parseAndAnnotate(cntx, pi1, srcDev, null);
assertEquals(false, VirtualRouting.isTraceroutePacket(cntx));
OFPacketIn pi2 = createTraceroutePkt(srcMAC, srcIP, dstMAC, dstIP,
(byte) 1);
cntx = parseAndAnnotate(cntx, pi2, srcDev, null);
assertEquals(true, VirtualRouting.isTraceroutePacket(cntx));
}
@Test
public void testHandleTraceroute() throws Exception {
String srcMACStr = "ff:ee:dd:33:22:11";
long srcMAC = Ethernet.toLong(Ethernet.toMACAddress(srcMACStr));
String srcIPStr = "10.1.3.3";
int srcIP = IPv4.toIPv4Address(srcIPStr);
long dstMAC = VirtualRouterManager.VIRTUAL_ROUTING_MAC;
String dstIPStr = "10.1.4.3";
int dstIP = IPv4.toIPv4Address(dstIPStr);
String vrIP1Str = "10.1.3.1";
int vrIP1 = IPv4.toIPv4Address(vrIP1Str);
String vrIP2Str = "10.1.4.1";
int vrIP2 = IPv4.toIPv4Address(vrIP2Str);
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[6].getName(), null);
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[7].getName(), null);
Map<String, Object> ip1 = h.createIfaceIp(if1, vrIP1Str,
"255.255.255.0");
Map<String, Object> ip2 = h.createIfaceIp(if2, vrIP2Str,
"255.255.255.0");
Map<String, Object> rr1 = h.createRoutingRule(r1, "tt1", null, null,
null, "tt1", null, null,
null, null, null,
"permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2);
h.addIfaceIpAddr(ip1, ip2);
h.addRoutingRule(rr1);
IDevice srcDev = mockDeviceManager.learnEntity(srcMAC, null, srcIP, 1L,
3);
ListenerContext cntx = new ListenerContext();
List<VNSInterface> ifaces = new ArrayList<VNSInterface>();
for (int n = 0; n < 10; n++) {
ifaces.add(new VNSInterface("testSrcIfaces2x" + n, netVirt[n], null,
null));
}
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES, ifaces);
VirtualRouting routing = getVirtualRouting();
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
replay(mockSwitch);
expect(netVirtManager.getInterfaces(srcDev)).andReturn(ifaces).anyTimes();
replay(netVirtManager);
setForwardingExpect(mockSwitch, 1L, 4);
replay(mockSwitch, forwarding);
Command cmd;
OFPacketIn pi1 = createTraceroutePkt(srcMAC, srcIP, dstMAC, dstIP,
(byte) 1);
cntx = parseAndAnnotate(cntx, pi1, srcDev, null);
cmd = routing.receive(mockSwitch, pi1, cntx);
assertEquals(Command.STOP, cmd);
OFPacketIn pi2 = createTraceroutePkt(srcMAC, srcIP, dstMAC, dstIP,
(byte) 2);
cntx = parseAndAnnotate(cntx, pi2, srcDev, null);
cmd = routing.receive(mockSwitch, pi2, cntx);
assertEquals(Command.CONTINUE, cmd);
OFPacketIn pi3 = createTraceroutePkt(srcMAC, srcIP, dstMAC, vrIP1,
(byte) 2);
cntx = parseAndAnnotate(cntx, pi3, srcDev, null);
cmd = routing.receive(mockSwitch, pi3, cntx);
assertEquals(Command.CONTINUE, cmd);
OFPacketIn pi4 = createTraceroutePkt(srcMAC, srcIP, dstMAC, vrIP2,
(byte) 2);
cntx = parseAndAnnotate(cntx, pi4, srcDev, null);
cmd = routing.receive(mockSwitch, pi4, cntx);
assertEquals(Command.CONTINUE, cmd);
/* Now write the routing configuration to the storage and check that
* traceroute is processed
*/
h.writeToStorage(storageSource);
Thread.sleep(1000);
cntx = parseAndAnnotate(cntx, pi1, srcDev, null);
cmd = routing.receive(mockSwitch, pi1, cntx);
assertEquals(Command.STOP, cmd);
cntx = parseAndAnnotate(cntx, pi2, srcDev, null);
cmd = routing.receive(mockSwitch, pi2, cntx);
assertEquals(Command.CONTINUE, cmd);
cntx = parseAndAnnotate(cntx, pi3, srcDev, null);
cmd = routing.receive(mockSwitch, pi3, cntx);
assertEquals(Command.STOP, cmd);
cntx = parseAndAnnotate(cntx, pi4, srcDev, null);
cmd = routing.receive(mockSwitch, pi4, cntx);
assertEquals(Command.STOP, cmd);
}
@Test
public void testReconcileFlows() throws Exception {
String srcMACStr = "00:11:22:33:44:55";
String dstMACStr = "55:44:33:22:11:00";
short vlan = 20;
int srcIp = IPv4.toIPv4Address("10.1.1.20");
int dstIp = IPv4.toIPv4Address("10.1.2.30");
OFMatchReconcile ofm = new OFMatchReconcile();
OFMatch ofMatch = new OFMatch();
ofMatch.setDataLayerSource(srcMACStr);
ofMatch.setDataLayerDestination(dstMACStr);
ofMatch.setDataLayerVirtualLan(vlan);
ofMatch.setNetworkSource(srcIp);
ofMatch.setNetworkDestination(dstIp);
ofm.ofmWithSwDpid.setOfMatch(ofMatch);
ArrayList<OFMatchReconcile> ofmList = new ArrayList<OFMatchReconcile>();
ofmList.add(ofm);
/* CONTEXT_SRC_IFACES is null so return early from the function */
ofm.rcAction = ReconcileAction.NEW_ENTRY;
Command ret = virtualRouting.reconcileFlows(ofmList);
assertEquals(Command.CONTINUE, ret);
assertEquals(OFMatchReconcile.ReconcileAction.DROP, ofm.rcAction);
/* Source and dest Ifaces are in different NetVirt without virtual routing
* policies to connect them. Check that the flow is dropped
*/
ofm.rcAction = ReconcileAction.NEW_ENTRY;
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(ofm.cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testDstIface1", netVirt[1], null, null));
INetVirtManagerService.bcStore.put(ofm.cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
ret = virtualRouting.reconcileFlows(ofmList);
assertEquals(Command.CONTINUE, ret);
assertEquals(OFMatchReconcile.ReconcileAction.DROP, ofm.rcAction);
/* Source and dest Ifaces are in same NetVirt. Check that the flow is
* forwarded and the original DENY flow cache entry is deleted.
*/
ofm.rcAction = ReconcileAction.NEW_ENTRY;
ofm.action = FlowCacheObj.FCActionDENY;
srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(ofm.cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(ofm.cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
ret = virtualRouting.reconcileFlows(ofmList);
assertEquals(Command.CONTINUE, ret);
assertEquals(OFMatchReconcile.ReconcileAction.DELETE, ofm.rcAction);
/* Source and dest Ifaces are in same NetVirt. Check that the flow is
* forwarded and the original appname which was different is updated
*/
ofm.rcAction = ReconcileAction.NEW_ENTRY;
ofm.action = FlowCacheObj.FCActionPERMIT;
ofm.appInstName = "netVirtX";
int DEFAULT_HINT = OFMatch.OFPFW_ALL & ~(OFMatch.OFPFW_DL_SRC |
OFMatch.OFPFW_DL_DST |
OFMatch.OFPFW_DL_VLAN |
OFMatch.OFPFW_IN_PORT |
OFMatch.OFPFW_DL_TYPE);
ofMatch.setWildcards(DEFAULT_HINT);
ofm.ofmWithSwDpid.setOfMatch(ofMatch);
srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(ofm.cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(ofm.cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
ret = virtualRouting.reconcileFlows(ofmList);
assertEquals(Command.CONTINUE, ret);
assertEquals(OFMatchReconcile.ReconcileAction.APP_INSTANCE_CHANGED,
ofm.rcAction);
assertEquals(netVirt[0].getName(), ofm.newAppInstName);
/* Soure and dest are in different NetVirt, but virtual routing is
* configured to allow flows. This changes the wildcard on the flow and
* the flow cache entry is deleted
*/
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[0].getName(), null);
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[1].getName(), null);
Map<String, Object> rr1 = h.createRoutingRule(r1, "tt1", null, null,
null, "tt1", null, null,
null, null, null,
"permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2);
h.addRoutingRule(rr1);
h.writeToStorage(storageSource);
Thread.sleep(1000);
ofm.rcAction = ReconcileAction.NEW_ENTRY;
ofm.action = FlowCacheObj.FCActionPERMIT;
ofm.appInstName = "netVirtX";
ofMatch.setWildcards(DEFAULT_HINT);
ofm.ofmWithSwDpid.setOfMatch(ofMatch);
srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[1], null, null));
INetVirtManagerService.bcStore.put(ofm.cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(ofm.cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
IDeviceService.fcStore.put(ofm.cntx, IDeviceService.CONTEXT_DST_DEVICE,
dev2);
ret = virtualRouting.reconcileFlows(ofmList);
assertEquals(Command.CONTINUE, ret);
assertEquals(OFMatchReconcile.ReconcileAction.DELETE, ofm.rcAction);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME,
ofm.newAppInstName);
}
public void
testUpdateDestDevice() throws Exception {
ListenerContext cntx = new ListenerContext();
/*
* Setup a single VR interconnecting 3 NetVirtes - netVirt[0], netVirt[1], netVirt[2]
* Source - netVirt[0], OrigDst - netVirt[1], FinalDst - netVirt[2]
* VR Rule: Allow netVirt[0] --> netVirt[1] and netVirt[0] --> netVirt[2]
*/
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[0].getName(), null);
Map<String, Object> ip1 = h.createIfaceIp(if1, "10.0.0.1",
"0.0.0.255");
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[1].getName(), null);
Map<String, Object> ip2 = h.createIfaceIp(if2, "10.0.1.1",
"0.0.0.255");
Map<String, Object> if3 = h.createIface(r1, "if3", true,
netVirt[2].getName(), null);
Map<String, Object> ip3 = h.createIfaceIp(if3, "192.168.1.1",
"0.0.0.255");
Map<String, Object> rr1 =
h.createRoutingRule(r1, "tt1", netVirt[0].getName(), null, null,
null, netVirt[1].getName(),
null, null, null,
null, "permit");
Map<String, Object> rr2 =
h.createRoutingRule(r1, "tt1", netVirt[0].getName(), null, null,
null, netVirt[2].getName(),
null, null, null,
null, "permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2, if3);
h.addIfaceIpAddr(ip1, ip2, ip3);
h.addRoutingRule(rr1, rr2);
h.writeToStorage(storageSource);
Thread.sleep(1000);
/*
* Setup an address space to associate devices
*/
String addressSpaceName = "MyAddressSpace";
Short vlan = 0;
BetterEntityClass addressSpace = new BetterEntityClass(addressSpaceName, vlan);
IEntityClassifierService ecs =
createMock(IEntityClassifierService.class);
expect(ecs.classifyEntity(anyObject(Entity.class)))
.andReturn(addressSpace).anyTimes();
expect(ecs.getKeyFields())
.andReturn(EnumSet.of(DeviceField.VLAN, DeviceField.MAC))
.anyTimes();
ecs.addListener(mockDeviceManager);
expectLastCall().anyTimes();
replay(ecs);
mockDeviceManager.setEntityClassifier(ecs);
/*
* Mock Topology to return true all the time as it should be called
* with switch-port pair that should always be an attachment point
*/
reset(topology);
expect(topology.isAttachmentPointPort(EasyMock.anyLong(),
EasyMock.anyShort())).
andReturn(true).anyTimes();
replay(topology);
/*
* Setup source device, origDstDevice and dstDevice
*/
IDevice srcDevice = mockDeviceManager.learnEntity(
HexString.toLong("00:00:00:00:00:02"),
null,
IPv4.toIPv4Address("10.0.0.2"),
1L, 1);
IDevice origDstDevice = mockDeviceManager.learnEntity(
HexString.toLong("00:00:00:00:00:03"),
null,
IPv4.toIPv4Address("192.168.1.3"),
1L, 2);
IDevice dstDevice = mockDeviceManager.learnEntity(
HexString.toLong("00:00:00:00:00:04"),
null,
IPv4.toIPv4Address("10.0.1.4"),
1L, 3);
/*
* Setup src and dst netVirt ifaces
*/
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> origDstIfaces = new ArrayList<VNSInterface>();
origDstIfaces.add(new VNSInterface("testSrcIface2", netVirt[2], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
origDstIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface3", netVirt[1], null, null));
/*
* Mock NetVirt Manager
*/
reset(netVirtManager);
expect(netVirtManager.getInterfaces(dstDevice))
.andReturn(dstIfaces)
.atLeastOnce();
replay(netVirtManager);
/*
* Mock tunnelManager
*/
reset(tunnelManager);
expect(tunnelManager.isTunnelEndpoint(origDstDevice))
.andReturn(true).anyTimes();
expect(tunnelManager.isTunnelEndpoint(anyObject(IDevice.class)))
.andReturn(false).anyTimes();
expect(tunnelManager.getSwitchDpid(IPv4.toIPv4Address("10.0.1.4")))
.andReturn(null).atLeastOnce();
replay(tunnelManager);
/*
* Build test packet data, packet-in
*/
testPacket = new Ethernet()
.setDestinationMACAddress("00:00:00:00:00:03")
.setSourceMACAddress("00:00:00:00:00:02")
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("10.0.0.2")
.setDestinationAddress("10.0.1.4")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
testPacketSerialized = testPacket.serialize();
OFPacketIn pi = ((OFPacketIn)
mockControllerProvider
.getOFMessageFactory()
.getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short)1)
.setPacketData(testPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) testPacketSerialized.length);
/*
* Setup virtual routing object
*/
VirtualRouting routing = getVirtualRouting();
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
/*
* Replay switch mocker
*/
replay(mockSwitch);
/*
* Finally the test
*/
routing.receive(mockSwitch, pi, parseAndAnnotate(cntx, pi, srcDevice,
origDstDevice));
/*
* Verify mockers
*/
verify(mockSwitch);
verify(topology);
verify(tunnelManager);
verify(netVirtManager);
/*
* Validate routing decision
*/
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
assertTrue(d.getRoutingAction() == RoutingAction.FORWARD);
assertTrue(d.getSourcePort().getSwitchDPID() == 1L);
assertTrue(d.getSourcePort().getPort() == pi.getInPort());
assertEquals(srcDevice, d.getSourceDevice());
assertEquals(1, d.getDestinationDevices().size());
assertEquals(true, d.getDestinationDevices().contains(dstDevice));
/*
* Validate that ORIG_DST_DEVICE in sdnplatform ctx is origDstDevice
*/
assertEquals(origDstDevice,
IDeviceService.fcStore.get(cntx,
IDeviceService.CONTEXT_ORIG_DST_DEVICE));
}
public void
testUpdateDestDeviceReconcileFlows() throws Exception {
ListenerContext cntx = new ListenerContext();
/*
* Setup a single VR interconnecting 3 NetVirtes - netVirt[0], netVirt[1], netVirt[2]
* Source - netVirt[0], OrigDst - netVirt[1], FinalDst - netVirt[2]
* VR Rule: Allow netVirt[0] --> netVirt[1] and netVirt[0] --> netVirt[2]
*/
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[0].getName(), null);
Map<String, Object> ip1 = h.createIfaceIp(if1, "10.0.0.1",
"0.0.0.255");
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[1].getName(), null);
Map<String, Object> ip2 = h.createIfaceIp(if2, "10.0.1.1",
"0.0.0.255");
Map<String, Object> if3 = h.createIface(r1, "if3", true,
netVirt[2].getName(), null);
Map<String, Object> ip3 = h.createIfaceIp(if3, "192.168.1.1",
"0.0.0.255");
Map<String, Object> rr1 =
h.createRoutingRule(r1, "tt1", netVirt[0].getName(), null, null,
null, netVirt[1].getName(),
null, null, null,
null, "permit");
Map<String, Object> rr2 =
h.createRoutingRule(r1, "tt1", netVirt[0].getName(), null, null,
null, netVirt[2].getName(),
null, null, null,
null, "permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2, if3);
h.addIfaceIpAddr(ip1, ip2, ip3);
h.addRoutingRule(rr1, rr2);
h.writeToStorage(storageSource);
Thread.sleep(1000);
/*
* Setup an address space to associate devices
*/
String addressSpaceName = "MyAddressSpace";
Short vlan = 0;
BetterEntityClass addressSpace = new BetterEntityClass(addressSpaceName, vlan);
IEntityClassifierService ecs =
createMock(IEntityClassifierService.class);
expect(ecs.classifyEntity(anyObject(Entity.class)))
.andReturn(addressSpace).anyTimes();
expect(ecs.getKeyFields())
.andReturn(EnumSet.of(DeviceField.VLAN, DeviceField.MAC))
.anyTimes();
ecs.addListener(mockDeviceManager);
expectLastCall().anyTimes();
replay(ecs);
mockDeviceManager.setEntityClassifier(ecs);
/*
* Mock Topology to return true all the time as it should be called
* with switch-port pair that should always be an attachment point
*/
reset(topology);
expect(topology.isAttachmentPointPort(EasyMock.anyLong(),
EasyMock.anyShort())).
andReturn(true).anyTimes();
replay(topology);
/*
* Setup source device, origDstDevice and dstDevice
*/
IDevice srcDevice = mockDeviceManager.learnEntity(
HexString.toLong("00:00:00:00:00:02"),
null,
IPv4.toIPv4Address("10.0.0.2"),
1L, 1);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
IDevice origDstDevice = mockDeviceManager.learnEntity(
HexString.toLong("00:00:00:00:00:03"),
null,
IPv4.toIPv4Address("192.168.1.3"),
1L, 2);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_DST_DEVICE,
origDstDevice);
IDevice dstDevice = mockDeviceManager.learnEntity(
HexString.toLong("00:00:00:00:00:04"),
null,
IPv4.toIPv4Address("10.0.1.4"),
1L, 3);
IFlowCacheService.fcStore.put(cntx,
IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME,
IVirtualRoutingService.VRS_FLOWCACHE_NAME);
/*
* Setup src and dst netVirt ifaces
*/
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
List<VNSInterface> origDstIfaces = new ArrayList<VNSInterface>();
origDstIfaces.add(new VNSInterface("testSrcIface2", netVirt[2], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
origDstIfaces);
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testSrcIface3", netVirt[1], null, null));
/*
* Mock NetVirt Manager
*/
reset(netVirtManager);
expect(netVirtManager.getInterfaces(dstDevice))
.andReturn(dstIfaces)
.atLeastOnce();
replay(netVirtManager);
/*
* Mock tunnelManager
*/
reset(tunnelManager);
expect(tunnelManager.isTunnelEndpoint(origDstDevice))
.andReturn(true).anyTimes();
expect(tunnelManager.isTunnelEndpoint(anyObject(IDevice.class)))
.andReturn(false).anyTimes();
expect(tunnelManager.getSwitchDpid(IPv4.toIPv4Address("10.0.1.4")))
.andReturn(null).atLeastOnce();
replay(tunnelManager);
/*
* Build test packet data, packet-in
*/
testPacket = new Ethernet()
.setDestinationMACAddress("00:00:00:00:00:03")
.setSourceMACAddress("00:00:00:00:00:02")
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("10.0.0.2")
.setDestinationAddress("10.0.1.4")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
testPacketSerialized = testPacket.serialize();
OFPacketIn pi = ((OFPacketIn)
mockControllerProvider
.getOFMessageFactory()
.getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short)1)
.setPacketData(testPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) testPacketSerialized.length);
/*
* Setup virtual routing object
*/
VirtualRouting routing = getVirtualRouting();
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
/*
* Replay switch mocker
*/
replay(mockSwitch);
/*
* Prepare the reconcile flow mods
*/
ArrayList<OFMatchReconcile> ofmRcList = new ArrayList<OFMatchReconcile>();
OFMatchReconcile ofmRc = new OFMatchReconcile();
OFMatch match = new OFMatch();
match.loadFromPacket(testPacketSerialized, (short) 1);
MutableInteger hint = new MutableInteger(VirtualRouting.DEFAULT_HINT);
hint.setValue((hint.intValue() & ~(OFMatch.OFPFW_NW_DST_MASK)));
hint.setValue((hint.intValue() & ~(OFMatch.OFPFW_NW_SRC_MASK)));
match.setWildcards(hint.intValue());
ofmRc.ofmWithSwDpid.setOfMatch(match.clone());
ofmRc.ofmWithSwDpid.setSwitchDataPathId(1L);
ofmRc.rcAction = ReconcileAction.UPDATE_PATH;
ofmRc.cntx = cntx;
ofmRcList.add(ofmRc);
/*
* Finally the test
*/
routing.reconcileFlows(ofmRcList);
/*
* Verify mockers
*/
verify(mockSwitch);
verify(topology);
verify(tunnelManager);
verify(netVirtManager);
/*
* Validate routing decision
*/
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
assertTrue(d.getRoutingAction() == RoutingAction.FORWARD);
assertTrue(d.getSourcePort().getSwitchDPID() == 1L);
assertTrue(d.getSourcePort().getPort() == pi.getInPort());
assertEquals(srcDevice, d.getSourceDevice());
assertEquals(1, d.getDestinationDevices().size());
assertEquals(true, d.getDestinationDevices().contains(dstDevice));
/*
* Validate that ORIG_DST_DEVICE in sdnplatform ctx is origDstDevice
*/
assertEquals(origDstDevice,
IDeviceService.fcStore.get(cntx,
IDeviceService.CONTEXT_ORIG_DST_DEVICE));
}
public void
testUnknownDestWithVR() throws Exception {
ListenerContext cntx = new ListenerContext();
/*
* Setup a single VR interconnecting 3 NetVirtes - netVirt[0], netVirt[1]
* Source - netVirt[0]
* VR Rule: Allow netVirt[0] --> 10.0.1.4 permit
*/
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[0].getName(), null);
Map<String, Object> ip1 = h.createIfaceIp(if1, "10.0.0.1",
"0.0.0.255");
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[1].getName(), null);
Map<String, Object> ip2 = h.createIfaceIp(if2, "10.0.1.1",
"0.0.0.255");
Map<String, Object> rr1 =
h.createRoutingRule(r1, "tt1", netVirt[0].getName(), null, null,
null, null,
"10.0.1.4", "0.0.0.0", null,
null, "permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2);
h.addIfaceIpAddr(ip1, ip2);
h.addRoutingRule(rr1);
h.writeToStorage(storageSource);
Thread.sleep(1000);
/*
* Setup an address space to associate devices
*/
String addressSpaceName = "MyAddressSpace";
Short vlan = 0;
BetterEntityClass addressSpace = new BetterEntityClass(addressSpaceName, vlan);
IEntityClassifierService ecs =
createMock(IEntityClassifierService.class);
expect(ecs.classifyEntity(anyObject(Entity.class)))
.andReturn(addressSpace).anyTimes();
expect(ecs.getKeyFields())
.andReturn(EnumSet.of(DeviceField.VLAN, DeviceField.MAC))
.anyTimes();
ecs.addListener(mockDeviceManager);
expectLastCall().anyTimes();
replay(ecs);
mockDeviceManager.setEntityClassifier(ecs);
/*
* Mock Topology to return true all the time as it should be called
* with switch-port pair that should always be an attachment point
*/
reset(topology);
expect(topology.isAttachmentPointPort(EasyMock.anyLong(),
EasyMock.anyShort())).
andReturn(true).anyTimes();
replay(topology);
/*
* Setup source device only. Do NOT setup destDevice
*/
IDevice srcDevice = mockDeviceManager.learnEntity(
HexString.toLong("00:00:00:00:00:02"),
null,
IPv4.toIPv4Address("10.0.0.2"),
1L, 1);
/*
* Setup src ifaces only
*/
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
/*
* Build test packet data, packet-in
*/
testPacket = new Ethernet()
.setDestinationMACAddress(Ethernet.toByteArray(VirtualRouterManager.VIRTUAL_ROUTING_MAC))
.setSourceMACAddress("00:00:00:00:00:02")
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("10.0.0.2")
.setDestinationAddress("10.0.1.4")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
testPacketSerialized = testPacket.serialize();
OFPacketIn pi = ((OFPacketIn)
mockControllerProvider
.getOFMessageFactory()
.getMessage(OFType.PACKET_IN))
.setBufferId(-1)
.setInPort((short)1)
.setPacketData(testPacketSerialized)
.setReason(OFPacketInReason.NO_MATCH)
.setTotalLength((short) testPacketSerialized.length);
/*
* Setup virtual routing object
*/
VirtualRouting routing = getVirtualRouting();
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
/*
* Replay switch mocker
*/
replay(mockSwitch);
/*
* Finally the test
*/
routing.receive(mockSwitch, pi, parseAndAnnotate(cntx, pi, srcDevice,
null));
/*
* Verify mockers
*/
verify(mockSwitch);
verify(topology);
/*
* Validate routing decision
*/
IRoutingDecision d =
IRoutingDecision.rtStore.get(cntx,
IRoutingDecision.CONTEXT_DECISION);
assertTrue(d.getRoutingAction() == RoutingAction.FORWARD);
assertTrue(d.getSourcePort().getSwitchDPID() == 1L);
assertTrue(d.getSourcePort().getPort() == pi.getInPort());
assertEquals(srcDevice, d.getSourceDevice());
assertEquals(0, d.getDestinationDevices().size());
}
public void
testUnknownDestWithVRReconcile() throws Exception {
ListenerContext cntx = new ListenerContext();
/*
* Setup a single VR interconnecting 3 NetVirtes - netVirt[0], netVirt[1]
* Source - netVirt[0]
* VR Rule: Allow netVirt[0] --> 10.0.1.4 permit
*/
VRTablesTestHelper h = new VRTablesTestHelper();
Map<String, Object> tt1 = h.createTenant("tt1", true);
Map<String, Object> r1 = h.createRouter(tt1, "r1");
Map<String, Object> if1 = h.createIface(r1, "if1", true,
netVirt[0].getName(), null);
Map<String, Object> ip1 = h.createIfaceIp(if1, "10.0.0.1",
"0.0.0.255");
Map<String, Object> if2 = h.createIface(r1, "if2", true,
netVirt[1].getName(), null);
Map<String, Object> ip2 = h.createIfaceIp(if2, "10.0.1.1",
"0.0.0.255");
Map<String, Object> rr1 =
h.createRoutingRule(r1, "tt1", netVirt[0].getName(), null, null,
null, null,
"10.0.1.4", "0.0.0.0", null,
null, "permit");
h.addTenant(tt1);
h.addVirtRtr(r1);
h.addVirtRtrIface(if1, if2);
h.addIfaceIpAddr(ip1, ip2);
h.addRoutingRule(rr1);
h.writeToStorage(storageSource);
Thread.sleep(1000);
/*
* Setup an address space to associate devices
*/
String addressSpaceName = "MyAddressSpace";
Short vlan = 0;
BetterEntityClass addressSpace = new BetterEntityClass(addressSpaceName, vlan);
IEntityClassifierService ecs =
createMock(IEntityClassifierService.class);
expect(ecs.classifyEntity(anyObject(Entity.class)))
.andReturn(addressSpace).anyTimes();
expect(ecs.getKeyFields())
.andReturn(EnumSet.of(DeviceField.VLAN, DeviceField.MAC))
.anyTimes();
ecs.addListener(mockDeviceManager);
expectLastCall().anyTimes();
replay(ecs);
mockDeviceManager.setEntityClassifier(ecs);
/*
* Mock Topology to return true all the time as it should be called
* with switch-port pair that should always be an attachment point
*/
reset(topology);
expect(topology.isAttachmentPointPort(EasyMock.anyLong(),
EasyMock.anyShort())).
andReturn(true).anyTimes();
replay(topology);
/*
* Setup source devices only
*/
IDevice srcDevice = mockDeviceManager.learnEntity(
HexString.toLong("00:00:00:00:00:02"),
null,
IPv4.toIPv4Address("10.0.0.2"),
1L, 1);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
/*
* Setup src ifaces only
*/
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface1", netVirt[0], null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
/*
* Build test packet data, packet-in
*/
testPacket = new Ethernet()
.setDestinationMACAddress(Ethernet.toByteArray(VirtualRouterManager.VIRTUAL_ROUTING_MAC))
.setSourceMACAddress("00:00:00:00:00:02")
.setEtherType(Ethernet.TYPE_IPv4)
.setPayload(
new IPv4()
.setTtl((byte) 128)
.setSourceAddress("10.0.0.2")
.setDestinationAddress("10.0.1.4")
.setPayload(new UDP()
.setSourcePort((short) 5000)
.setDestinationPort((short) 5001)
.setPayload(new Data(new byte[] {0x01}))));
testPacketSerialized = testPacket.serialize();
/*
* Setup virtual routing object
*/
VirtualRouting routing = getVirtualRouting();
routing.setControllerProvider(mockControllerProvider);
routing.setDeviceManager(mockDeviceManager);
/*
* Replay switch mocker
*/
replay(mockSwitch);
/*
* Prepare the reconcile flow mods
*/
ArrayList<OFMatchReconcile> ofmRcList = new ArrayList<OFMatchReconcile>();
OFMatchReconcile ofmRc = new OFMatchReconcile();
OFMatch match = new OFMatch();
match.loadFromPacket(testPacketSerialized, (short) 1);
MutableInteger hint = new MutableInteger(VirtualRouting.DEFAULT_HINT);
hint.setValue((hint.intValue() & ~(OFMatch.OFPFW_NW_DST_MASK)));
hint.setValue((hint.intValue() & ~(OFMatch.OFPFW_NW_SRC_MASK)));
match.setWildcards(hint.intValue());
ofmRc.ofmWithSwDpid.setOfMatch(match.clone());
ofmRc.ofmWithSwDpid.setSwitchDataPathId(1L);
ofmRc.rcAction = ReconcileAction.UPDATE_PATH;
ofmRc.cntx = cntx;
ofmRcList.add(ofmRc);
/*
* Finally the test
*/
routing.reconcileFlows(ofmRcList);
/*
* Verify mockers
*/
verify(mockSwitch);
verify(topology);
/*
* Validate reconcile action
*/
assertEquals(OFMatchReconcile.ReconcileAction.DELETE, ofmRc.rcAction);
}
}