/*
* 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.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.sdnplatform.core.ListenerContext;
import org.sdnplatform.devicemanager.IDevice;
import org.sdnplatform.devicemanager.IDeviceService;
import org.sdnplatform.devicemanager.SwitchPort;
import org.sdnplatform.devicemanager.internal.Device;
import org.sdnplatform.flowcache.IFlowCacheService;
import org.sdnplatform.forwarding.IRewriteService;
import org.sdnplatform.linkdiscovery.ILinkDiscoveryService;
import org.sdnplatform.netvirt.core.VNS;
import org.sdnplatform.netvirt.core.VNSInterface;
import org.sdnplatform.netvirt.manager.INetVirtManagerService;
import org.sdnplatform.netvirt.virtualrouting.ForwardingAction;
import org.sdnplatform.netvirt.virtualrouting.GatewayNode;
import org.sdnplatform.netvirt.virtualrouting.IGatewayPool;
import org.sdnplatform.netvirt.virtualrouting.IVirtualMacService;
import org.sdnplatform.netvirt.virtualrouting.IVirtualRoutingService;
import org.sdnplatform.netvirt.virtualrouting.internal.VirtualRouterManager;
import org.sdnplatform.netvirt.virtualrouting.internal.VirtualRouterManager.RoutingRuleParams;
import org.sdnplatform.packet.Ethernet;
import org.sdnplatform.packet.IPv4;
import org.sdnplatform.routing.IRoutingService;
import org.sdnplatform.routing.Route;
import org.sdnplatform.routing.IRoutingDecision.RoutingAction;
import org.sdnplatform.test.PlatformTestCase;
import org.sdnplatform.topology.ITopologyService;
import org.sdnplatform.topology.NodePortTuple;
import org.sdnplatform.tunnelmanager.ITunnelManagerService;
import org.sdnplatform.util.IPV4Subnet;
import org.sdnplatform.util.MACAddress;
public class VirtualRouterManagerTest extends PlatformTestCase {
protected VirtualRouterManager vrm;
protected IVirtualMacService vMacService;
protected IRewriteService rewriteService;
protected IDeviceService deviceManager;
protected INetVirtManagerService netVirtManager;
protected ILinkDiscoveryService linkDiscovery;
protected ITopologyService topology;
protected IRoutingService routingEngine;
private ITunnelManagerService tunnelManager;
@Before
public void setUp() throws Exception {
super.setUp();
vMacService = createMock(IVirtualMacService.class);
rewriteService = createMock(IRewriteService.class);
deviceManager = createMock(IDeviceService.class);
netVirtManager = createMock(INetVirtManagerService.class);
linkDiscovery = createMock(ILinkDiscoveryService.class);
topology = createNiceMock(ITopologyService.class);
routingEngine = createNiceMock(IRoutingService.class);
tunnelManager = createMock(ITunnelManagerService.class);
vrm = new VirtualRouterManager();
vrm.setvMacManager(vMacService);
vrm.setRewriteService(rewriteService);
vrm.setNetVirtManager(netVirtManager);
vrm.setDeviceManager(deviceManager);
vrm.setLinkDiscovery(linkDiscovery);
vrm.setTopology(topology);
vrm.setRoutingService(routingEngine);
vrm.setTunnelManager(tunnelManager);
Map<Integer, MACAddress> staticArpMap =
new HashMap<Integer, MACAddress>();
vrm.setStaticArpTable(staticArpMap);
}
@Test
/* This test only tests internal working of the class */
public void testCreateTenant() {
vrm.createTenant("t1", true);
assertNotNull(vrm.tenants.get("t1"));
assertTrue(vrm.tenants.get("t1").active);
assertEquals(vrm.tenants.get("t1").name, "t1");
vrm.createTenant("t2", false);
assertNotNull(vrm.tenants.get("t2"));
assertFalse(vrm.tenants.get("t2").active);
assertEquals(vrm.tenants.get("t2").name, "t2");
assertEquals(2, vrm.tenants.size());
}
@Test
/* This test only tests internal working of the class */
public void testCreateVirtualRouter() throws Exception {
linkDiscovery.
addMACToIgnoreList(VirtualRouterManager.VIRTUAL_ROUTING_MAC, 0);
expectLastCall().times(1);
replay(linkDiscovery);
vrm.createTenant("t1", true);
vrm.createVirtualRouter("r1", "t1");
assertNotNull(vrm.vRouters.get("t1|r1"));
assertEquals("t1", vrm.vRouters.get("t1|r1").getTenant());
assertEquals("t1|r1", vrm.vRouters.get("t1|r1").getName());
try {
/* Attempting to add a router to a non existing tenant should throw
* an exception
*/
vrm.createVirtualRouter("r2", "t2");
fail();
} catch (IllegalArgumentException e) {
/* Exception should be thrown */
}
assertNull(vrm.vRouters.get("t2|r2"));
verify(linkDiscovery);
}
@Test
/* This test only tests internal working of the class */
public void testAddVRouterIface() throws Exception {
linkDiscovery.
addMACToIgnoreList(VirtualRouterManager.VIRTUAL_ROUTING_MAC, 0);
expectLastCall().times(2);
replay(linkDiscovery);
vrm.createTenant("t1", true);
vrm.createTenant("t2", true);
long vMac1 = Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:55"));
expect(vMacService.acquireVirtualMac()).andReturn(vMac1).anyTimes();
replay(vMacService);
vrm.createVirtualRouter("r1", "t1");
vrm.createVirtualRouter("r2", "t2");
verify(linkDiscovery);
vrm.addVRouterIface("t1|r1", "if1", "t1|netVirt1", null, true);
assertNotNull(vrm.netVirtToRouterMap.get("t1|netVirt1"));
vrm.addVRouterIface("t1|r1", "if2", null, "t2|r2", true);
assertEquals(1, vrm.netVirtToRouterMap.size());
try {
vrm.addVRouterIface("r1", "if3", "t1|netVirt2", null, true);
fail();
} catch (IllegalArgumentException e) {
/* Invalid owner router name */
}
try {
vrm.addVRouterIface("t2|r1", "if3", "t1|netVirt2", null, true);
fail();
} catch (IllegalArgumentException e) {
/* Invalid owner tenant name */
}
try {
vrm.addVRouterIface("t1|r3", "if3", "t1|netVirt2", null, true);
fail();
} catch (IllegalArgumentException e) {
/* Unknown owner router name */
}
try {
vrm.addVRouterIface("t1|r1", "if3", "t1|netVirt2", "t1|r2", true);
fail();
} catch (IllegalArgumentException e) {
/* Cannot connect an interface to both a netVirt and a router */
}
try {
vrm.addVRouterIface("t1|r1", "if3", "netVirt2", null, true);
fail();
} catch (IllegalArgumentException e) {
/* Invalid netVirt name */
}
try {
vrm.addVRouterIface("t1|r1", "if3", "t2|netVirt2", null, true);
fail();
} catch (IllegalArgumentException e) {
/* Invalid tenant in netVirt name */
}
try {
vrm.addVRouterIface("t1|r1", "if3", null, "r2", true);
fail();
} catch (IllegalArgumentException e) {
/* Invalid router name */
}
try {
vrm.addVRouterIface("t1|r1", "if3", null, null, false);
fail();
} catch (IllegalArgumentException e) {
/* Both router and netVirt cannot be null */
}
}
@Test
/* This test only tests internal working of the class */
public void testAddIfaceIp() throws Exception {
vrm.createTenant("t1", true);
vrm.createVirtualRouter("r1", "t1");
vrm.addVRouterIface("t1|r1", "if1", "t1|netVirt1", null, true);
vrm.addIfaceIp("t1|r1|if1", "10.0.1.1", "0.0.255.255");
try {
vrm.addIfaceIp("r1|if1", "10.20.2.2", "0.0.0.255");
fail();
} catch (IllegalArgumentException e) {
/* Invalid owner interface name */
}
try {
vrm.addIfaceIp("t2|r1|if1", "10.20.2.2", "0.0.0.255");
fail();
} catch (IllegalArgumentException e) {
/* Unknown tenant name */
}
try {
vrm.addIfaceIp("t1|r2|if1", "10.20.2.2", "0.0.0.255");
fail();
} catch (IllegalArgumentException e) {
/* Unknown router name */
}
}
@Test
public void testAddGatewayPool() throws Exception {
vrm.createTenant("tx", true);
vrm.createVirtualRouter("rx", "tx");
vrm.addGatewayPool("tx|rx", "test-gateway-pool");
try {
vrm.addGatewayPool("tx|rinvalid", "test-gateway-pool");
fail();
} catch (IllegalArgumentException e) {
/* Invalid router name */
}
IGatewayPool gatewayPool = vrm.getGatewayPool("tx|rx",
"test-gateway-pool");
assertNotNull(gatewayPool);
assertEquals("test-gateway-pool", gatewayPool.getName());
Map<String, GatewayNode> gatewayNodes = gatewayPool.getGatewayNodes();
assertEquals(0, gatewayNodes.size());
}
@Test
public void testAddGatewayNodes() throws Exception {
vrm.createTenant("tx", true);
vrm.createVirtualRouter("rx", "tx");
vrm.addGatewayPool("tx|rx", "test-gateway-pool");
IGatewayPool gatewayPool = vrm.getGatewayPool("tx|rx",
"test-gateway-pool");
assertNotNull(gatewayPool);
assertEquals("test-gateway-pool", gatewayPool.getName());
Map<String, GatewayNode> gatewayNodes = gatewayPool.getGatewayNodes();
assertEquals(0, gatewayNodes.size());
gatewayPool.addGatewayNode("10.0.0.1");
gatewayNodes = gatewayPool.getGatewayNodes();
assertEquals(1, gatewayNodes.size());
assertNotNull(gatewayNodes.get("10.0.0.1"));
}
private RoutingRuleParams createRuleParams(String owner, String srcTenant,
String srcNetVirt, String srcIp,
String srcMask, String dstTenant,
String dstNetVirt, String dstIp,
String dstMask, String outIface,
String nextHopIp,
String action) {
RoutingRuleParams p = new RoutingRuleParams();
p.owner = owner;
p.srcTenant = srcTenant;
p.srcVNS = srcNetVirt;
p.srcIp = srcIp;
p.srcMask = srcMask;
p.dstTenant = dstTenant;
p.dstVNS = dstNetVirt;
p.dstIp = dstIp;
p.dstMask = dstMask;
p.outIface = outIface;
p.nextHopIp = nextHopIp;
p.action = action;
return p;
}
private RoutingRuleParams createRuleParamsWithNextHopGatewayPool(
String owner, String srcTenant,
String srcNetVirt, String srcIp,
String srcMask, String dstTenant,
String dstNetVirt, String dstIp,
String dstMask, String outIface,
String nextHopIp,
String action,
String nextHopGatewayPool) {
RoutingRuleParams p = new RoutingRuleParams();
p.owner = owner;
p.srcTenant = srcTenant;
p.srcVNS = srcNetVirt;
p.srcIp = srcIp;
p.srcMask = srcMask;
p.dstTenant = dstTenant;
p.dstVNS = dstNetVirt;
p.dstIp = dstIp;
p.dstMask = dstMask;
p.outIface = outIface;
p.nextHopIp = nextHopIp;
p.action = action;
p.nextHopGatewayPool = nextHopGatewayPool;
return p;
}
@Test
/* This test only tests internal working of the class */
public void testAddRoutingRule() throws Exception {
vrm.createTenant("t1", true);
vrm.createVirtualRouter("r1", "t1");
vrm.addVRouterIface("t1|r1", "if1", "t1|netVirt1", null, true);
vrm.addVRouterIface("t1|r1", "if2", "t1|netVirt2", null, true);
vrm.addRoutingRule(createRuleParamsWithNextHopGatewayPool("t1|r1", null,
"t1|netVirt1", null,
null, null, "t1|netVirt2", null, null,
"t1|r1|if1", null, "permit",
"t1|r1|test-gateway-pool"));
try {
vrm.addRoutingRule(createRuleParams("r1", null, "t1|netVirt1", null,
null, null, "t1|netVirt2", null,
null, "t1|r1|if1", null,
"permit"));
fail();
} catch (IllegalArgumentException e) {
/* Invalid owner router name */
}
try {
vrm.addRoutingRule(createRuleParams("t2|r1", null, "t1|netVirt1", null,
null, null, "t1|netVirt2", null,
null, "t1|r1|if1", null,
"permit"));
fail();
} catch (IllegalArgumentException e) {
/* Unknown tenant name */
}
try {
vrm.addRoutingRule(createRuleParams("t1|r2", null, "t1|netVirt1", null,
null, null, "t1|netVirt2", null,
null, "t1|r1|if1", null,
"permit"));
fail();
} catch (IllegalArgumentException e) {
/* Unknown router name */
}
try {
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t1|netVirt1", null,
null, null, "t1|netVirt2", null,
null, "r1|if1", null,
"permit"));
fail();
} catch (IllegalArgumentException e) {
/* Invalid outgoing interface name */
}
try {
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t1|netVirt1", null,
null, null, "t1|netVirt2", null,
null, "t2|r1|if1", null,
"permit"));
fail();
} catch (IllegalArgumentException e) {
/* Invalid tenant in outgoing interface name */
}
try {
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t1|netVirt1", null,
null, null, "t1|netVirt2", null,
null, "t1|r2|if1", null,
"permit"));
fail();
} catch (IllegalArgumentException e) {
/* Invalid router in outgoing interface name */
}
try {
vrm.addRoutingRule(createRuleParams("t1|r1", "t2", null, null, null,
null, "t1|netVirt2", null, null,
"t1|r2|if1", null, "permit"));
fail();
} catch (IllegalArgumentException e) {
/* Unknown srcTenant */
}
try {
vrm.addRoutingRule(createRuleParams("t1|r1", "t1", null, null, null,
"t2", null, null, null,
"t1|r2|if1", null, "permit"));
fail();
} catch (IllegalArgumentException e) {
/* Unknown dstTenant */
}
try {
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t1|netVirt3", null,
null, "t1", null, null, null,
"t1|r2|if1", null, "permit"));
fail();
} catch (IllegalArgumentException e) {
/* src NetVirt not attached to any router */
}
try {
vrm.addRoutingRule(createRuleParams("t1|r1", "t1", null, null, null,
null, "t1|netVirt3", null, null,
"t1|r2|if1", null, "permit"));
fail();
} catch (IllegalArgumentException e) {
/* dst NetVirt not attached to any router */
}
}
@Test
public void testConnected() throws Exception {
vrm.createTenant("t1", true);
vrm.createTenant("t2", true);
vrm.createTenant("system", true);
vrm.createTenant("tx", true);
long vMac1 = Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:55"));
expect(vMacService.acquireVirtualMac()).andReturn(vMac1).anyTimes();
replay(vMacService);
vrm.createVirtualRouter("r1", "t1");
vrm.createVirtualRouter("r2", "t2");
vrm.createVirtualRouter("rs", "system");
vrm.createVirtualRouter("rx", "tx");
vrm.addVRouterIface("t1|r1", "if1", "t1|netVirt1", null, true);
vrm.addVRouterIface("t1|r1", "if2", "t1|netVirt2", null, true);
vrm.addVRouterIface("t1|r1", "ifs", null, "system|rs", true);
vrm.addVRouterIface("t2|r2", "if1", "t2|netVirt1", null, true);
vrm.addVRouterIface("t2|r2", "if2", "t2|netVirt2", null, false);
vrm.addVRouterIface("t2|r2", "ifs", null, "system|rs", true);
vrm.addVRouterIface("system|rs", "if1", null, "t1|r1", true);
vrm.addVRouterIface("system|rs", "if2", null, "t2|r2", true);
vrm.addVRouterIface("system|rs", "ifx", null, "tx|rx", true);
vrm.addVRouterIface("tx|rx", "if1", "tx|netVirtx", null, true);
vrm.addVRouterIface("tx|rx", "ifs", null, "system|rs", false);
vrm.addRoutingRule(createRuleParams("t1|r1", "t1", null, null, null,
null, null, "0.0.0.0",
"255.255.255.255", null, null,
"permit"));
vrm.addRoutingRule(createRuleParams("system|rs", "t1", null, null, null,
"t2", null, null, null, null, null,
"permit"));
vrm.addRoutingRule(createRuleParams("t2|r2", "t1", null, null, null,
null, "t2|netVirt1", null, null, null,
null, "permit"));
int ip1 = IPv4.toIPv4Address("10.1.1.2");
int ip2 = IPv4.toIPv4Address("10.2.1.2");
VNS netVirtA1 = new VNS("t1|netVirt1");
VNS netVirtB1 = new VNS("t2|netVirt1");
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface", netVirtB1, null, null));
boolean found = vrm.connected(srcIfaces, dstIfaces, ip1, ip2);
/* A route from t1|netVirt1 to t2|netVirt1 through system|rs so expect 'true' */
assertEquals(true, found);
ip2 = IPv4.toIPv4Address("10.2.2.2");
VNS netVirtB2 = new VNS("t2|netVirt2");
dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface", netVirtB2, null, null));
found = vrm.connected(srcIfaces, dstIfaces, ip1, ip2);
/* Interface to netVirtB2 is disabled so vRouter would return drop */
assertEquals(false, found);
vrm.addRoutingRule(createRuleParams("system|rs", "t1", null, null, null,
"tx", null, null, null, null, null,
"permit"));
ip2 = IPv4.toIPv4Address("192.168.0.20");
VNS netVirtx = new VNS("tx|netVirtx");
dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface", netVirtx, null, null));
found = vrm.connected(srcIfaces, dstIfaces, ip1, ip2);
/* Interface on rx from rs is down so return drop */
assertEquals(false, found);
ip1 = IPv4.toIPv4Address("10.2.2.20");
ip2 = IPv4.toIPv4Address("10.1.2.20");
srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtB2, null, null));
dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface", netVirtA1, null, null));
found = vrm.connected(srcIfaces, dstIfaces, ip1, ip2);
/* Interface connecting netVirtB2 to r2 is down so return drop */
assertEquals(false, found);
ip1 = IPv4.toIPv4Address("10.1.1.20");
ip2 = IPv4.toIPv4Address("10.1.1.25");
srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface", netVirtA1, null, null));
found = vrm.connected(srcIfaces, dstIfaces, ip1, ip2);
/* Both source and dest are in the same netVirt so return true */
assertEquals(true, found);
ip2 = IPv4.toIPv4Address("10.1.5.20");
VNS netVirtA5 = new VNS("t1|netVirt5");
srcIfaces = new ArrayList<VNSInterface>();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA5, null, null));
dstIfaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface", netVirtA1, null, null));
found = vrm.connected(srcIfaces, dstIfaces, ip1, ip2);
/* Source netVirt is not connected to router */
assertEquals(false, found);
verify(vMacService);
}
public void testGetForwardingAction() throws Exception {
long srcMAC = Ethernet.
toLong(Ethernet.toMACAddress("00:11:22:33:44:55"));
long dstMAC = Ethernet.
toLong(Ethernet.toMACAddress("55:44:33:22:11:00"));
long nextHopMAC = Ethernet.
toLong(Ethernet.toMACAddress("bb:ee:55:77:00:11"));
short vlan = 20;
long vMac = VirtualRouterManager.VIRTUAL_ROUTING_MAC;
int srcIp = IPv4.toIPv4Address("10.1.1.20");
int dstIp = IPv4.toIPv4Address("10.1.2.30");
int dstIp2 = IPv4.toIPv4Address("10.1.2.35");
String nextHopIpStr = "10.1.2.25";
int nextHopIp = IPv4.toIPv4Address(nextHopIpStr);
VNS netVirtA1 = new VNS("t1|netVirt1");
VNS netVirtA2 = new VNS("t1|netVirt2");
VNS netVirtA3 = new VNS("t1|netVirt3");
VNS netVirtA4 = new VNS("t1|netVirt4");
ListenerContext cntx = new ListenerContext();
Device srcDevice = createMock(Device.class);
Device dstDevice = createMock(Device.class);
Device nextHopDevice = createMock(Device.class);
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
List<VNSInterface> nextHopIfaces = new ArrayList<VNSInterface>();
ArrayList<Device> dstList = new ArrayList<Device>();
dstList.add(dstDevice);
Iterator<Device> dstIter = dstList.iterator();
ArrayList<Device> srcList = new ArrayList<Device>();
srcList.add(srcDevice);
Iterator<Device> srcIter = srcList.iterator();
ArrayList<Device> nextHopList = new ArrayList<Device>();
nextHopList.add(nextHopDevice);
Iterator<Device> nextHopIter = nextHopList.iterator();
Integer[] srcIpArr = new Integer[1];
srcIpArr[0] = srcIp;
Integer[] dstIpArr = new Integer[1];
dstIpArr[0] = dstIp;
Integer[] nextHopIpArr = new Integer[1];
nextHopIpArr[0] = nextHopIp;
srcDevice.getEntityClass();
expectLastCall().andReturn(null).anyTimes();
expect(deviceManager.findClassDevice(null, dstMAC, vlan, dstIp)).
andReturn(dstDevice).anyTimes();
expect(deviceManager.findClassDevice(null, nextHopMAC, vlan, nextHopIp)).
andReturn(nextHopDevice).anyTimes();
EasyMock.<Iterator<? extends IDevice>>expect(deviceManager.
queryClassDevices(null, null, null, new Integer(dstIp), null, null)).
andReturn(dstIter).anyTimes();
EasyMock.<Iterator<? extends IDevice>>expect(deviceManager.
queryClassDevices(null, null, null, new Integer(dstIp2), null, null)).
andReturn(dstIter).anyTimes();
EasyMock.<Iterator<? extends IDevice>>expect(deviceManager.
queryClassDevices(null, null, null, new Integer(srcIp), null, null)).
andReturn(srcIter).anyTimes();
EasyMock.<Iterator<? extends IDevice>>expect(deviceManager.
queryClassDevices(null, null, null, new Integer(nextHopIp), null, null)).
andReturn(nextHopIter).anyTimes();
expect(dstDevice.getMACAddress()).andReturn(dstMAC).anyTimes();
expect(srcDevice.getMACAddress()).andReturn(srcMAC).anyTimes();
expect(nextHopDevice.getMACAddress()).andReturn(nextHopMAC).anyTimes();
expect(dstDevice.getIPv4Addresses()).andReturn(dstIpArr).anyTimes();
expect(srcDevice.getIPv4Addresses()).andReturn(srcIpArr).anyTimes();
expect(nextHopDevice.getIPv4Addresses()).andReturn(nextHopIpArr).anyTimes();
expect(vMacService.acquireVirtualMac()).andReturn(vMac).anyTimes();
expect(netVirtManager.getInterfaces(dstDevice)).
andReturn(dstIfaces).anyTimes();
expect(netVirtManager.getInterfaces(srcDevice)).
andReturn(srcIfaces).anyTimes();
expect(netVirtManager.getInterfaces(nextHopDevice)).
andReturn(nextHopIfaces).anyTimes();
expect(netVirtManager.getVNS("t1|netVirt1")).andReturn(netVirtA1).anyTimes();
expect(netVirtManager.getVNS("t1|netVirt2")).andReturn(netVirtA2).anyTimes();
expect(netVirtManager.getVNS("t1|netVirt3")).andReturn(netVirtA3).anyTimes();
expect(netVirtManager.getVNS("t1|netVirt4")).andReturn(netVirtA4).anyTimes();
expect(tunnelManager.isTunnelEndpoint(anyObject(IDevice.class)))
.andReturn(false).anyTimes();
replay(tunnelManager);
/* Simulate the rewrite manager expectations according to the order of
* the tests
*/
/* TEST4 */
rewriteService.setIngressDstMac(EasyMock.eq(new Long(vMac)),
EasyMock.eq(new Long(dstMAC)),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
rewriteService.setTtlDecrement(EasyMock.eq(1),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
/* TEST5 */
rewriteService.setIngressDstMac(EasyMock.eq(new Long(vMac)),
EasyMock.eq(new Long(dstMAC)),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
rewriteService.setTtlDecrement(EasyMock.eq(1),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
/* TEST6 */
rewriteService.setIngressDstMac(EasyMock.eq(new Long(vMac)),
EasyMock.eq(new Long(nextHopMAC)),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
rewriteService.setTtlDecrement(EasyMock.eq(1),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
rewriteService.setEgressSrcMac(EasyMock.eq(new Long(srcMAC)),
EasyMock.eq(new Long(vMac)),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
/* TEST7 */
rewriteService.setIngressDstMac(EasyMock.eq(new Long(vMac)),
EasyMock.eq(new Long(nextHopMAC)),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
rewriteService.setTtlDecrement(EasyMock.eq(1),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
rewriteService.setEgressSrcMac(EasyMock.eq(new Long(srcMAC)),
EasyMock.eq(new Long(vMac)),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
/* TEST8 */
rewriteService.setEgressSrcMac(EasyMock.eq(new Long(srcMAC)),
EasyMock.eq(new Long(vMac)),
(ListenerContext)EasyMock.anyObject());
expectLastCall().once();
replay(srcDevice, dstDevice, nextHopDevice, deviceManager, vMacService,
netVirtManager, rewriteService);
/* TEST1: No common NetVirt and virtual routing not setup so return drop */
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_DST_DEVICE,
dstDevice);
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
dstIfaces.add(new VNSInterface("testDstIface", netVirtA2, null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
ForwardingAction fAction = vrm.getForwardingAction(srcMAC, dstMAC, vlan,
Ethernet.TYPE_IPv4,
srcIp, dstIp, cntx);
assertEquals(RoutingAction.DROP, fAction.getAction());
String fcAppName = IFlowCacheService.fcStore.
get(cntx, IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME, fcAppName);
List<VNSInterface> retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
List<VNSInterface> retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
assertNull(retSrcIfaces);
assertNull(retDstIfaces);
/* TEST2: Source and dest are in same NetVirts, so action returned is
* forward
*/
cntx = new ListenerContext();
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_DST_DEVICE,
dstDevice);
srcIfaces.clear();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
srcIfaces.add(new VNSInterface("testSrcIface2", netVirtA3, null, null));
dstIfaces.clear();
dstIfaces.add(new VNSInterface("testDstIface", netVirtA2, null, null));
dstIfaces.add(new VNSInterface("testDstIface2", netVirtA3, null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
fAction = vrm.getForwardingAction(srcMAC, dstMAC, vlan,
Ethernet.TYPE_IPv4, srcIp, dstIp,
cntx);
assertEquals(RoutingAction.FORWARD, fAction.getAction());
assertEquals(false, fAction.isVirtualRouted());
fcAppName = IFlowCacheService.fcStore.
get(cntx, IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
/* The common netVirt is encapsulated in the flow cache app name */
assertEquals("t1|netVirt3", fcAppName);
retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
assertEquals(netVirtA3, retSrcIfaces.get(0).getParentVNS());
assertEquals(netVirtA3, retDstIfaces.get(0).getParentVNS());
/* TEST3: Virtual routing has been setup so allow communcation */
/* Connect NetVirt A1/A2/A3 with virtual routing */
vrm.createTenant("t1", true);
vrm.createVirtualRouter("r1", "t1");
vrm.addVRouterIface("t1|r1", "if1", "t1|netVirt1", null, true);
vrm.addVRouterIface("t1|r1", "if2", "t1|netVirt2", null, true);
vrm.addVRouterIface("t1|r1", "if3", "t1|netVirt3", null, true);
/* Allow all packets from tenant A */
vrm.addRoutingRule(createRuleParams("t1|r1", "t1", null, null, null,
null, null, "0.0.0.0",
"255.255.255.255", null, null,
"permit"));
cntx = new ListenerContext();
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_DST_DEVICE,
dstDevice);
srcIfaces.clear();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
srcIfaces.add(new VNSInterface("testSrcIface2", netVirtA2, null, null));
dstIfaces.clear();
dstIfaces.add(new VNSInterface("testDstIface", netVirtA3, null, null));
dstIfaces.add(new VNSInterface("testDstIface2", netVirtA4, null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
dstIfaces);
fAction = vrm.getForwardingAction(srcMAC, dstMAC, vlan,
Ethernet.TYPE_IPv4, srcIp, dstIp,
cntx);
assertEquals(RoutingAction.FORWARD, fAction.getAction());
assertEquals(true, fAction.isVirtualRouted());
fcAppName = IFlowCacheService.fcStore.
get(cntx, IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME, fcAppName);
retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
assertEquals(netVirtA1, retSrcIfaces.get(0).getParentVNS());
assertEquals(netVirtA3, retDstIfaces.get(0).getParentVNS());
/* TEST4: Send packet with dstMac as virtual router MAC. There is a
* static ARP entry for the dest device using which the device is
* found
*/
Map<Integer, MACAddress> staticArpMap =
new HashMap<Integer, MACAddress>();
/* Add the dest IP to the static ARP table */
staticArpMap.put(new Integer(dstIp),
new MACAddress(Ethernet.toByteArray(dstMAC)));
vrm.setStaticArpTable(staticArpMap);
cntx = new ListenerContext();
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
srcIfaces.clear();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
dstIfaces.clear();
dstIfaces.add(new VNSInterface("testDstIface", netVirtA3, null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
/* NetVirtA1 is allowed to communicate to A3 so action is forward */
fAction = vrm.getForwardingAction(srcMAC, vMac, vlan,
Ethernet.TYPE_IPv4, srcIp, dstIp,
cntx);
assertEquals(RoutingAction.FORWARD, fAction.getAction());
assertEquals(true, fAction.isVirtualRouted());
fcAppName = IFlowCacheService.fcStore.
get(cntx, IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME, fcAppName);
retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
IDevice retDstDev = IDeviceService.fcStore.
get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
assertEquals(netVirtA1, retSrcIfaces.get(0).getParentVNS());
assertEquals(netVirtA3, retDstIfaces.get(0).getParentVNS());
assertEquals(dstDevice, retDstDev);
/* TEST5: Send packet with dstMac as virtual router MAC. There is no
* static ARP entry and so the device is looked up successfully by IP
*/
cntx = new ListenerContext();
/* Add empty static ARP table */
staticArpMap = new HashMap<Integer, MACAddress>();
vrm.setStaticArpTable(staticArpMap);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
srcIfaces.clear();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
dstIfaces.clear();
dstIfaces.add(new VNSInterface("testDstIface", netVirtA3, null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
/* NetVirtA1 is allowed to communicate to A3 so action is forward */
fAction = vrm.getForwardingAction(srcMAC, vMac, vlan,
Ethernet.TYPE_IPv4, srcIp, dstIp,
cntx);
assertEquals(RoutingAction.FORWARD, fAction.getAction());
assertEquals(true, fAction.isVirtualRouted());
fcAppName = IFlowCacheService.fcStore.
get(cntx, IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME, fcAppName);
retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
retDstDev = IDeviceService.fcStore.
get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
assertEquals(netVirtA1, retSrcIfaces.get(0).getParentVNS());
assertEquals(netVirtA3, retDstIfaces.get(0).getParentVNS());
assertEquals(dstDevice, retDstDev);
/* TEST6: Test pure L3 routing with a next hop configured. The
* destination device is a silent host but the next hop is known
*/
/* Add a pure L3 routing rule */
vrm.addIfaceIp("t1|r1|if1", "10.1.1.0", "0.0.0.255");
vrm.addIfaceIp("t1|r1|if2", "10.1.2.0", "0.0.0.255");
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t1|netVirt1", null,
null, null, null, "10.1.2.0",
"0.0.0.255", null, nextHopIpStr,
"permit"));
cntx = new ListenerContext();
/* Add empty static ARP table */
staticArpMap = new HashMap<Integer, MACAddress>();
vrm.setStaticArpTable(staticArpMap);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
srcIfaces.clear();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
dstIfaces.clear();
nextHopIfaces.clear();
nextHopIfaces.add(new VNSInterface("nextHopIface", netVirtA2, null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
/* 10.1.1.x is allowed to communicate with 10.1.2.x so action is
* forward
*/
fAction = vrm.getForwardingAction(srcMAC, vMac, vlan,
Ethernet.TYPE_IPv4, srcIp, dstIp2,
cntx);
assertEquals(RoutingAction.FORWARD, fAction.getAction());
assertEquals(true, fAction.isVirtualRouted());
fcAppName = IFlowCacheService.fcStore.
get(cntx, IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME, fcAppName);
retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
retDstDev = IDeviceService.fcStore.
get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
assertEquals(netVirtA1, retSrcIfaces.get(0).getParentVNS());
assertEquals(netVirtA2, retDstIfaces.get(0).getParentVNS());
assertEquals(nextHopDevice, retDstDev);
/* TEST7: Test pure L3 routing with a next hop configured. The
* destination device is a silent host but the next hop is known using
* static ARP entry
* The only difference from TEST6 is the presence of static ARP entry
*/
cntx = new ListenerContext();
staticArpMap = new HashMap<Integer, MACAddress>();
/* Add the next hop IP to the static ARP table */
staticArpMap.put(new Integer(nextHopIp),
new MACAddress(Ethernet.toByteArray(nextHopMAC)));
vrm.setStaticArpTable(staticArpMap);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
srcIfaces.clear();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
dstIfaces.clear();
nextHopIfaces.clear();
nextHopIfaces.add(new VNSInterface("nextHopIface", netVirtA2, null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
/* 10.1.1.x is allowed to communicate with 10.1.2.x so action is
* forward
*/
fAction = vrm.getForwardingAction(srcMAC, vMac, vlan,
Ethernet.TYPE_IPv4, srcIp, dstIp2,
cntx);
assertEquals(RoutingAction.FORWARD, fAction.getAction());
assertEquals(true, fAction.isVirtualRouted());
fcAppName = IFlowCacheService.fcStore.
get(cntx, IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME, fcAppName);
retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
retDstDev = IDeviceService.fcStore.
get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
assertEquals(netVirtA1, retSrcIfaces.get(0).getParentVNS());
assertEquals(netVirtA2, retDstIfaces.get(0).getParentVNS());
assertEquals(nextHopDevice, retDstDev);
/* TEST8: Test the case where a static ARP is configured but it is not
* required since the packet is already destined to that MAC. This
* simulates packet from an intermediate switch which sees packet after
* dest MAC rewrite
*/
cntx = new ListenerContext();
staticArpMap = new HashMap<Integer, MACAddress>();
/* Add the next hop IP to the static ARP table */
staticArpMap.put(new Integer(nextHopIp),
new MACAddress(Ethernet.toByteArray(nextHopMAC)));
vrm.setStaticArpTable(staticArpMap);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_DST_DEVICE,
nextHopDevice);
srcIfaces.clear();
srcIfaces.add(new VNSInterface("testSrcIface", netVirtA1, null, null));
dstIfaces.clear();
nextHopIfaces.clear();
nextHopIfaces.add(new VNSInterface("nextHopIface", netVirtA2, null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
/* The next hop interface is already discovered by device manager */
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_DST_IFACES,
nextHopIfaces);
/* 10.1.1.x is allowed to communicate with 10.1.2.x so action is
* forward
*/
fAction = vrm.getForwardingAction(srcMAC, nextHopMAC, vlan,
Ethernet.TYPE_IPv4, srcIp, dstIp2,
cntx);
assertEquals(RoutingAction.FORWARD, fAction.getAction());
assertEquals(true, fAction.isVirtualRouted());
fcAppName = IFlowCacheService.fcStore.
get(cntx, IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME, fcAppName);
retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
retDstDev = IDeviceService.fcStore.
get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
assertEquals(netVirtA1, retSrcIfaces.get(0).getParentVNS());
assertEquals(netVirtA2, retDstIfaces.get(0).getParentVNS());
assertEquals(nextHopDevice, retDstDev);
verify(srcDevice, dstDevice, nextHopDevice, deviceManager, vMacService,
netVirtManager, rewriteService);
}
/*
* Logical Topology
* ----------------
*
* 10.0.0.1/24 +------+ 10.0.1.1/24
* ---------| VR |-------
* | +------+ |
* | |
* |[NetVirt DB: 10.0.0.0/24] | [NetVirt Web : 10.0.1.0/24]
* ------- ---------------------------------
* | | | |
* | | +---|----------|------+
* +---+ +---+ | +-----+ +-----+ |
* | A | | B | | | GW1 | | GW2 | | Web-Gateway-Pool
* +---+ +---+ | +-----+ +-----+ |
* 10.0.0.2 10.0.1.2 +---------------------+
*
* Test Context:
* -------------
* o A wants to talk to B
* o Packet which hits the controller as a packet IN has the following
* header fields:
* - SRC IP: 10.0.0.2
* - DST IP: 10.0.1.2
* - SRC MAC: 00:00:00:00:00:01
* - DST MAC: VR's MAC
* - VLAN: Untagged (null)
* o VR has a rule to permit traffic from A to B with next hop as a gateway
* pool = "Web-Gateway-Pool"
*
* Test Objective:
* ---------------
* o When VirtualRouting calls getForwardingAction() with the above fields,
* it should return a ForwardingAction that has a
* nextHopGatewayPool = "Web-Gateway-Pool"
* o Also, the dstDevice in the SDN Platform context should point to the
* node which is closest to A. The computation of the closest node uses
* RoutingEngine and Topology APIs which will be mocked so that either
* GW1 or GW2 will be returned. For a view on how GW1, GW2, A are mocked
* up w.r.t physical topo: see Physical Topology section in the comments
* below.
*
* Physical Topology(A, GW1, GW2):
* ------------------
* +-------+
* | |
* | 2 2 | --- GW2
* | 1 |
* +-------+
* |
* |
* +-------+
* | 3 |
* | 1 2 | --- GW1
* | 1 |
* +-------+
* |
* A
*/
@Test
public void testGetForwardingActionGatewayPool() throws Exception {
/*
* Setup Source [IP, MAC, Device]
*/
long srcMAC = Ethernet.toLong(Ethernet.toMACAddress("00:00:00:00:00:01"));
int srcIp = IPv4.toIPv4Address("10.0.0.2");
Integer[] srcIpArr = new Integer[1];
srcIpArr[0] = srcIp;
Device srcDevice = createMock(Device.class);
srcDevice.getEntityClass();
expectLastCall().andReturn(null).anyTimes();
expect(srcDevice.getMACAddress()).andReturn(srcMAC).anyTimes();
expect(srcDevice.getIPv4Addresses()).andReturn(srcIpArr).anyTimes();
/*
* Setup Destination [IP, MAC, Device]
*/
long dstMAC = Ethernet.toLong(Ethernet.toMACAddress("00:00:00:00:00:02"));
int dstIp = IPv4.toIPv4Address("10.0.1.2");
Integer[] dstIpArr = new Integer[1];
dstIpArr[0] = dstIp;
Device dstDevice = createMock(Device.class);
expect(dstDevice.getMACAddress()).andReturn(dstMAC).anyTimes();
expect(dstDevice.getIPv4Addresses()).andReturn(dstIpArr).anyTimes();
expect(deviceManager.findClassDevice(null, dstMAC, (short)0, dstIp)).
andReturn(dstDevice).anyTimes();
ArrayList<Device> dstList = new ArrayList<Device>();
dstList.add(dstDevice);
Iterator<Device> dstIter = dstList.iterator();
EasyMock.<Iterator<? extends IDevice>>expect(deviceManager.
queryClassDevices(null, null, null, new Integer(dstIp), null, null)).
andReturn(dstIter).anyTimes();
/*
* Setup Gateway Node1 [IP, MAC, Device]
*/
long gw1MAC = Ethernet.toLong(Ethernet.toMACAddress("00:00:00:00:00:03"));
int gw1Ip = IPv4.toIPv4Address("10.0.1.3");
Integer[] gw1IpArr = new Integer[1];
gw1IpArr[0] = gw1Ip;
Device gw1Device = createMock(Device.class);
expect(gw1Device.getMACAddress()).andReturn(gw1MAC).anyTimes();
expect(gw1Device.getIPv4Addresses()).andReturn(gw1IpArr).anyTimes();
expect(deviceManager.findClassDevice(null, gw1MAC, (short)0, gw1Ip)).
andReturn(gw1Device).anyTimes();
ArrayList<Device> gw1List = new ArrayList<Device>();
gw1List.add(gw1Device);
Iterator<Device> gw1Iter = gw1List.iterator();
EasyMock.<Iterator<? extends IDevice>>expect(deviceManager.
queryClassDevices(null, null, null, new Integer(gw1Ip), null, null)).
andReturn(gw1Iter).once();
/*
* Setup Gateway Node2 [IP, MAC, Device]
*/
long gw2MAC = Ethernet.toLong(Ethernet.toMACAddress("00:00:00:00:00:04"));
int gw2Ip = IPv4.toIPv4Address("10.0.1.4");
Integer[] gw2IpArr = new Integer[1];
gw2IpArr[0] = gw2Ip;
Device gw2Device = createMock(Device.class);
expect(gw2Device.getMACAddress()).andReturn(gw2MAC).anyTimes();
expect(gw2Device.getIPv4Addresses()).andReturn(gw2IpArr).anyTimes();
expect(deviceManager.findClassDevice(null, gw2MAC, (short)0, gw2Ip)).
andReturn(gw2Device).anyTimes();
ArrayList<Device> gw2List = new ArrayList<Device>();
gw2List.add(gw2Device);
Iterator<Device> gw2Iter = gw2List.iterator();
EasyMock.<Iterator<? extends IDevice>>expect(deviceManager.
queryClassDevices(null, null, null, new Integer(gw2Ip), null, null)).
andReturn(gw2Iter).anyTimes();
/*
* Setup Virtual Router MAC and vMacService to always return same vMac
*/
long vMac = VirtualRouterManager.VIRTUAL_ROUTING_MAC;
expect(vMacService.acquireVirtualMac()).andReturn(vMac).anyTimes();
/*
* Setup NetVirt and NetVirt interfaces for the devices
*/
VNS dbNetVirt = new VNS("coke|db");
VNS webNetVirt = new VNS("coke|web");
List<VNSInterface> srcIfaces = new ArrayList<VNSInterface>();
List<VNSInterface> dstIfaces = new ArrayList<VNSInterface>();
List<VNSInterface> gw1Ifaces = new ArrayList<VNSInterface>();
List<VNSInterface> gw2Ifaces = new ArrayList<VNSInterface>();
dstIfaces.add(new VNSInterface("testDstIface", webNetVirt, null, null));
gw1Ifaces.add(new VNSInterface("testGw1Iface", webNetVirt, null, null));
gw2Ifaces.add(new VNSInterface("testGw2Iface", webNetVirt, null, null));
expect(netVirtManager.getInterfaces(dstDevice)).andReturn(dstIfaces).anyTimes();
expect(netVirtManager.getInterfaces(srcDevice)).andReturn(srcIfaces).anyTimes();
expect(netVirtManager.getInterfaces(gw1Device)).andReturn(gw1Ifaces).anyTimes();
expect(netVirtManager.getInterfaces(gw2Device)).andReturn(gw2Ifaces).anyTimes();
expect(netVirtManager.getVNS("coke|db")).andReturn(dbNetVirt).anyTimes();
expect(netVirtManager.getVNS("coke|web")).andReturn(webNetVirt).anyTimes();
/*
* Setup the Virtual Router
*/
vrm.createTenant("coke", true);
vrm.createVirtualRouter("vr", "coke");
vrm.addVRouterIface("coke|vr", "if-db", "coke|db", null, true);
vrm.addIfaceIp("coke|vr|if-db", "10.0.0.0", "0.0.0.255");
vrm.addVRouterIface("coke|vr", "if-web", "coke|web", null, true);
vrm.addIfaceIp("coke|vr|if-web", "10.0.1.0", "0.0.0.255");
vrm.addGatewayPool("coke|vr", "Web-Gateway-Pool");
vrm.addGatewayPoolNode("coke|vr|Web-Gateway-Pool", "10.0.1.3");
vrm.addGatewayPoolNode("coke|vr|Web-Gateway-Pool", "10.0.1.4");
/*
* Setup Static ARP Table for dstIp, gw1Ip, gw2Ip
*/
Map<Integer, MACAddress> staticArpMap = new HashMap<Integer, MACAddress>();
staticArpMap.put(new Integer(dstIp),
new MACAddress(Ethernet.toByteArray(dstMAC)));
staticArpMap.put(new Integer(gw1Ip),
new MACAddress(Ethernet.toByteArray(gw1MAC)));
staticArpMap.put(new Integer(gw2Ip),
new MACAddress(Ethernet.toByteArray(gw2MAC)));
vrm.setStaticArpTable(staticArpMap);
/*
* Add a host specific route to permit traffic from A to B via
* a nexthop gateway pool
*/
vrm.addRoutingRule(createRuleParamsWithNextHopGatewayPool("coke|vr",
null, null,
"10.0.0.2", "255.255.255.255",
null, null,
"10.0.1.2", "255.255.255.255",
null, null,
"permit", "coke|vr|Web-Gateway-Pool"));
/*
* Prepare the listener context
* DstDevice, DstInterfaces are obtained by getForwardingAction() as:
* dstIp --> dstMac(from static arp table) --> dstDevice --> dstInterfaces
*/
ListenerContext cntx = new ListenerContext();
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
srcIfaces.add(new VNSInterface("testSrcIface", dbNetVirt, null, null));
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
/*
* Mock Up device attachment points for srcDevice
*/
SwitchPort srcAP = new SwitchPort(1L, (int)1);
SwitchPort[] srcAPs = new SwitchPort[1];
srcAPs[0] = srcAP;
expect(srcDevice.getAttachmentPoints()).andReturn(srcAPs).anyTimes();
/*
* Mock Up device attachment points for gw1Device
*/
SwitchPort gw1AP = new SwitchPort(1L, (int)2);
SwitchPort[] gw1APs = new SwitchPort[1];
gw1APs[0] = gw1AP;
expect(gw1Device.getAttachmentPoints()).andReturn(gw1APs).anyTimes();
/*
* Mock Up device attachment points for gw2Device
*/
SwitchPort gw2AP = new SwitchPort(2L, (int)2);
SwitchPort[] gw2APs = new SwitchPort[1];
gw2APs[0] = gw2AP;
expect(gw2Device.getAttachmentPoints()).andReturn(gw2APs).anyTimes();
/*
* Setup mock routes
*/
Route routeAToGW1 = new Route(srcMAC, gw1MAC);
routeAToGW1.getPath().add(new NodePortTuple(1L, (short)1));
routeAToGW1.getPath().add(new NodePortTuple(1L, (short)2));
Route routeAToGW2 = new Route(srcMAC, gw2MAC);
routeAToGW2.getPath().add(new NodePortTuple(1L, (short)1));
routeAToGW2.getPath().add(new NodePortTuple(1L, (short)3));
routeAToGW2.getPath().add(new NodePortTuple(2L, (short)1));
routeAToGW2.getPath().add(new NodePortTuple(2L, (short)2));
/*
* Mock Up topology and routing engine to return the appropriate mock
* objects.
*/
expect(topology.getL2DomainId(1L)).andReturn(1L).anyTimes();
expect(topology.getL2DomainId(2L)).andReturn(1L).anyTimes();
expect(topology.isAttachmentPointPort(1L, (short)1)).andReturn(true).
anyTimes();
expect(topology.isAttachmentPointPort(1L, (short)2)).andReturn(true).
anyTimes();
expect(topology.isAttachmentPointPort(2L, (short)2)).andReturn(true).
anyTimes();
expect(routingEngine.getRoute(1L, (short)1, 1L, (short)2, 0)).
andReturn(routeAToGW1).times(2);
expect(routingEngine.getRoute(1L, (short)1, 2L, (short)2, 0)).
andReturn(routeAToGW2).times(2);
/*
* Setup the Rewrite service mock ups
*/
rewriteService.setIngressDstMac(EasyMock.eq(new Long(vMac)),
EasyMock.eq(new Long(gw1MAC)),
(ListenerContext)EasyMock.anyObject());
expectLastCall().times(2);
rewriteService.setTtlDecrement(EasyMock.eq(1),
(ListenerContext)EasyMock.anyObject());
expectLastCall().times(2);
rewriteService.setEgressSrcMac(EasyMock.eq(new Long(srcMAC)),
EasyMock.eq(new Long(vMac)),
(ListenerContext)EasyMock.anyObject());
expectLastCall().times(2);
/*
* Activate the mock ups
*/
replay(srcDevice, dstDevice, gw1Device, gw2Device, deviceManager,
vMacService, netVirtManager, topology, routingEngine, rewriteService);
/*
* Test I
*/
ForwardingAction fAction = vrm.getForwardingAction(srcMAC, vMac,
(short)0,
Ethernet.TYPE_IPv4,
srcIp, dstIp, cntx);
/*
* Verify Test I output
*/
assertEquals(RoutingAction.FORWARD, fAction.getAction());
assertEquals(true, fAction.isVirtualRouted());
assertEquals("Web-Gateway-Pool", fAction.getNextHopGatewayPool());
assertEquals("coke|vr", fAction.getNextHopGatewayPoolRouter().getName());
assertEquals(gw1Ip, fAction.getNextHopIp());
assertEquals(vMac, fAction.getNewSrcMac());
assertEquals(gw1Device, IDeviceService.fcStore.get(cntx,
IDeviceService.CONTEXT_DST_DEVICE));
String fcAppName = IFlowCacheService.fcStore.get(cntx,
IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME, fcAppName);
List<VNSInterface> retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
List<VNSInterface> retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
assertEquals(dbNetVirt, retSrcIfaces.get(0).getParentVNS());
assertEquals(webNetVirt, retDstIfaces.get(0).getParentVNS());
/*
* Test II:
* Repeat the test with no Static ARPs for dst, gw1 and gw2. This would
* test the capability to query the devices based purely on IP Addresses.
*/
staticArpMap.remove(new Integer(dstIp));
staticArpMap.remove(new Integer(gw1Ip));
staticArpMap.remove(new Integer(gw2Ip));
cntx = new ListenerContext();
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
fAction = vrm.getForwardingAction(srcMAC, vMac,
(short)0,
Ethernet.TYPE_IPv4,
srcIp, dstIp, cntx);
/*
* Verify Test II output
*/
assertEquals(RoutingAction.FORWARD, fAction.getAction());
assertEquals(true, fAction.isVirtualRouted());
assertEquals("Web-Gateway-Pool", fAction.getNextHopGatewayPool());
assertEquals("coke|vr", fAction.getNextHopGatewayPoolRouter().getName());
assertEquals(gw1Ip, fAction.getNextHopIp());
assertEquals(vMac, fAction.getNewSrcMac());
assertEquals(gw1Device, IDeviceService.fcStore.get(cntx,
IDeviceService.CONTEXT_DST_DEVICE));
fcAppName = IFlowCacheService.fcStore.get(cntx,
IFlowCacheService.FLOWCACHE_APP_INSTANCE_NAME);
assertEquals(IVirtualRoutingService.VRS_FLOWCACHE_NAME, fcAppName);
retSrcIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_SRC_IFACES);
retDstIfaces = INetVirtManagerService.bcStore.
get(cntx, INetVirtManagerService.CONTEXT_DST_IFACES);
assertEquals(dbNetVirt, retSrcIfaces.get(0).getParentVNS());
assertEquals(webNetVirt, retDstIfaces.get(0).getParentVNS());
/*
* Test III:
* Repeat the test with no nodes reachable in the gateway pool,
* this is simulated by annihilating the gateway pool nodes
* For this test, put back the ARP entry for the DstIp just for
* the convenience of not having to set up the iterator again.
*/
vrm.removeGatewayPoolNode("coke|vr|Web-Gateway-Pool", "10.0.1.3");
vrm.removeGatewayPoolNode("coke|vr|Web-Gateway-Pool", "10.0.1.4");
staticArpMap.put(new Integer(dstIp),
new MACAddress(Ethernet.toByteArray(dstMAC)));
cntx = new ListenerContext();
IDeviceService.fcStore.put(cntx, IDeviceService.CONTEXT_SRC_DEVICE,
srcDevice);
INetVirtManagerService.bcStore.put(cntx,
INetVirtManagerService.CONTEXT_SRC_IFACES,
srcIfaces);
fAction = vrm.getForwardingAction(srcMAC, vMac,
(short)0,
Ethernet.TYPE_IPv4,
srcIp, dstIp, cntx);
/*
* Verify Test III output
*/
assertEquals(RoutingAction.DROP, fAction.getAction());
/*
* Verify the mockers
*/
verify(srcDevice, dstDevice, gw1Device, gw2Device, deviceManager,
vMacService, netVirtManager, topology, routingEngine, rewriteService);
}
/* XXX Only use one MAC for all virtual routers
public void testRelinquishMacs() throws Exception {
vrm.createTenant("t1", true);
vrm.createTenant("t2", true);
vrm.createTenant("system", true);
vrm.createTenant("tx", true);
long vMac1 =
Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:55"));
expect(vMacService.acquireVirtualMac()).andReturn(vMac1).once();
long vMac2 =
Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:56"));
expect(vMacService.acquireVirtualMac()).andReturn(vMac2).once();
long vMac3 =
Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:57"));
expect(vMacService.acquireVirtualMac()).andReturn(vMac3).once();
long vMac4 =
Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:58"));
expect(vMacService.acquireVirtualMac()).andReturn(vMac4).once();
vMacService.relinquishVirtualMAC(vMac1);
expectLastCall().once();
vMacService.relinquishVirtualMAC(vMac2);
expectLastCall().once();
vMacService.relinquishVirtualMAC(vMac3);
expectLastCall().once();
vMacService.relinquishVirtualMAC(vMac4);
expectLastCall().once();
replay(vMacService);
vrm.createVirtualRouter("r1", "t1");
vrm.createVirtualRouter("r2", "t2");
vrm.createVirtualRouter("rs", "system");
vrm.createVirtualRouter("rx", "tx");
vrm.relinquishVMacs();
verify(vMacService);
}
*/
@Test
public void testSubnetOwner() {
IPV4Subnet ips1 = new IPV4Subnet("10.1.1.1/24");
IPV4Subnet ips2 = new IPV4Subnet("10.1.1.1/16");
IPV4Subnet ips3 = new IPV4Subnet("10.2.1.1/24");
vrm.addSubnetOwner(ips1, "t1|r1");
vrm.addSubnetOwner(ips2, "t1|r2");
vrm.addSubnetOwner(ips3, "t2|r1");
String owner;
IPV4Subnet test = new IPV4Subnet("10.1.1.2/32");
owner = vrm.findSubnetOwner(test);
/* The most specific subnet is chosen */
assertEquals(owner, "t1|r1");
test = new IPV4Subnet("10.1.2.2/32");
owner = vrm.findSubnetOwner(test);
assertEquals(owner, "t1|r2");
test = new IPV4Subnet("10.2.1.4/32");
owner = vrm.findSubnetOwner(test);
assertEquals(owner, "t2|r1");
test = new IPV4Subnet("192.168.1.1/32");
owner = vrm.findSubnetOwner(test);
assertNull(owner);
}
@Test
public void testGetRtrVMac() throws Exception {
vrm.createTenant("t1", true);
vrm.createTenant("t2", true);
vrm.createTenant("system", true);
String ipr1if1str = "10.1.1.1";
String ipr1if2str = "10.1.2.1";
String ipr2if1str = "10.2.1.1";
String ipr2if2str = "10.2.2.1";
vrm.createVirtualRouter("r1", "t1");
vrm.createVirtualRouter("r2", "t2");
vrm.createVirtualRouter("rs", "system");
vrm.addVRouterIface("t1|r1", "if1", "t1|netVirt1", null, true);
vrm.addIfaceIp("t1|r1|if1", ipr1if1str, "0.0.0.255");
vrm.addVRouterIface("t1|r1", "if2", "t1|netVirt2", null, true);
vrm.addIfaceIp("t1|r1|if2", ipr1if2str, "0.0.0.255");
vrm.addVRouterIface("t1|r1", "ifs", null, "system|rs", true);
vrm.addVRouterIface("t2|r2", "if1", "t2|netVirt1", null, true);
vrm.addIfaceIp("t2|r2|if1", ipr2if1str, "0.0.0.255");
vrm.addVRouterIface("t2|r2", "if2", "t2|netVirt2", null, false);
vrm.addIfaceIp("t2|r2|if2", ipr2if2str, "0.0.0.255");
vrm.addVRouterIface("t2|r2", "ifs", null, "system|rs", true);
vrm.addVRouterIface("system|rs", "if1", null, "t1|r1", true);
vrm.addVRouterIface("system|rs", "if2", null, "t2|r2", true);
/* Allow t1 to communicate with any other host in t1 */
vrm.addRoutingRule(createRuleParams("t1|r1", "t1", null, null,
null, "t1", null, null, null,
null, null, "permit"));
/* Allow t1|netVirt1 to communicate with t2|netVirt1 and vice versa */
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t1|netVirt1", null,
null, null, "t2|netVirt1", null, null,
null, null, "permit"));
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t2|netVirt1", null,
null, null, "t1|netVirt1", null, null,
null, null, "permit"));
/* Allow t1 to communicate to t2 and vice versa */
vrm.addRoutingRule(createRuleParams("system|rs", "t1", null, null, null,
"t2", null, null, null, null, null,
"permit"));
vrm.addRoutingRule(createRuleParams("system|rs", "t2", null, null, null,
"t1", null, null, null, null, null,
"permit"));
/* Allow t1|netVirt1 to communicate with t2|netVirt1 and vice versa */
vrm.addRoutingRule(createRuleParams("t2|r2", null, "t1|netVirt1", null,
null, null, "t2|netVirt1", null, null,
null, null, "permit"));
vrm.addRoutingRule(createRuleParams("t2|r2", null, "t2|netVirt1", null,
null, null, "t1|netVirt1", null, null,
null, null, "permit"));
/* Allow t2|netVirt1 to communicate with t2|netVirt2 but NOT vice versa */
vrm.addRoutingRule(createRuleParams("t2|r2", null, "t2|netVirt1", null,
null, null, "t2|netVirt2", null, null,
null, null, "permit"));
/* Allow t2|netVirt2 to communicate with t1|netVirt1 but NOT vice versa */
vrm.addRoutingRule(createRuleParams("t2|r2", null, "t2|netVirt2", null,
null, null, "t1|netVirt1", null, null,
null, null, "permit"));
VNS netVirtA1 = new VNS("t1|netVirt1");
VNS netVirtA2 = new VNS("t1|netVirt2");
VNS netVirtA3 = new VNS("t1|netVirt3");
VNS netVirtB1 = new VNS("t2|netVirt1");
VNS netVirtB2 = new VNS("t2|netVirt2");
expect(netVirtManager.getVNS("t1|netVirt1")).andReturn(netVirtA1).anyTimes();
expect(netVirtManager.getVNS("t1|netVirt2")).andReturn(netVirtA2).anyTimes();
expect(netVirtManager.getVNS("t2|netVirt1")).andReturn(netVirtB1).anyTimes();
expect(netVirtManager.getVNS("t2|netVirt2")).andReturn(netVirtB2).anyTimes();
replay(netVirtManager);
int ipA1 = IPv4.toIPv4Address("10.1.1.2");
int ipA2 = IPv4.toIPv4Address("10.1.2.2");
int ipA3 = IPv4.toIPv4Address("10.1.3.2");
int ipB1 = IPv4.toIPv4Address("10.2.1.2");
int ipB2 = IPv4.toIPv4Address("10.2.2.2");
int ipr1if1 = IPv4.toIPv4Address(ipr1if1str);
int ipr1if2 = IPv4.toIPv4Address(ipr1if2str);
int ipr2if1 = IPv4.toIPv4Address(ipr2if1str);
int ipr2if2 = IPv4.toIPv4Address(ipr2if2str);
long vMac;
vMac = vrm.getRtrVMac(netVirtA1, ipA1, ipr1if1);
assertEquals(VirtualRouterManager.VIRTUAL_ROUTING_MAC, vMac);
vMac = vrm.getRtrVMac(netVirtA2, ipA2, ipr1if2);
assertEquals(VirtualRouterManager.VIRTUAL_ROUTING_MAC, vMac);
vMac = vrm.getRtrVMac(netVirtB1, ipB1, ipr2if1);
assertEquals(VirtualRouterManager.VIRTUAL_ROUTING_MAC, vMac);
vMac = vrm.getRtrVMac(netVirtB2, ipB2, ipr2if2);
assertEquals(VirtualRouterManager.VIRTUAL_ROUTING_MAC, vMac);
vMac = vrm.getRtrVMac(netVirtA1, ipA1, ipr1if2);
assertEquals(VirtualRouterManager.VIRTUAL_ROUTING_MAC, vMac);
vMac = vrm.getRtrVMac(netVirtA1, ipA1, ipr2if1);
assertEquals(VirtualRouterManager.VIRTUAL_ROUTING_MAC, vMac);
/* No route from netVirt B1 to netVirt B2 */
vMac = vrm.getRtrVMac(netVirtB1, ipB1, ipr2if2);
assertEquals(0, vMac);
/* No route from netVirt A1 to netVirt B2 */
vMac = vrm.getRtrVMac(netVirtB2, ipB2, ipr1if1);
assertEquals(0, vMac);
/* The dest IP does not belong to a router */
vMac = vrm.getRtrVMac(netVirtA1, ipA1, ipB1);
assertEquals(0, vMac);
/* The source NetVirt is not connected to a router */
vMac = vrm.getRtrVMac(netVirtA3, ipA3, ipr1if1);
assertEquals(0, vMac);
verify(netVirtManager);
}
@Test
public void testGetRtrIp() throws Exception {
vrm.createTenant("t1", true);
vrm.createTenant("t2", true);
vrm.createTenant("system", true);
String ipr1if1str = "10.1.1.1";
String ipr1if2str = "10.1.2.1";
String ipr2if1str = "10.2.1.1";
String ipr2if2str = "10.2.2.1";
vrm.createVirtualRouter("r1", "t1");
vrm.createVirtualRouter("r2", "t2");
vrm.createVirtualRouter("rs", "system");
vrm.addVRouterIface("t1|r1", "if1", "t1|netVirt1", null, true);
vrm.addIfaceIp("t1|r1|if1", ipr1if1str, "0.0.0.255");
/* If1 has 2 IPs. The second IP is the same as r2 if1 IP */
vrm.addIfaceIp("t1|r1|if1", ipr2if1str, "0.0.0.255");
vrm.addVRouterIface("t1|r1", "if2", "t1|netVirt2", null, true);
vrm.addIfaceIp("t1|r1|if2", ipr1if2str, "0.0.0.255");
vrm.addVRouterIface("t1|r1", "ifs", null, "system|rs", true);
vrm.addVRouterIface("t2|r2", "if1", "t2|netVirt1", null, true);
vrm.addIfaceIp("t2|r2|if1", ipr2if1str, "0.0.0.255");
vrm.addVRouterIface("t2|r2", "if2", "t2|netVirt2", null, false);
vrm.addIfaceIp("t2|r2|if2", ipr2if2str, "0.0.0.255");
vrm.addVRouterIface("t2|r2", "ifs", null, "system|rs", true);
vrm.addVRouterIface("system|rs", "if1", null, "t1|r1", true);
vrm.addVRouterIface("system|rs", "if2", null, "t2|r2", true);
/* Allow t1 to communicate with any other host in t1 */
vrm.addRoutingRule(createRuleParams("t1|r1", "t1", null, null,
null, "t1", null, null, null,
null, null, "permit"));
/* Allow t1|netVirt1 to communicate with t2|netVirt1 and vice versa */
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t1|netVirt1", null,
null, null, "t2|netVirt1", null, null,
null, null, "permit"));
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t2|netVirt1", null,
null, null, "t1|netVirt1", null, null,
null, null, "permit"));
/* Allow t2|netVirt2 to communicate with t1|netVirt1 but not vice versa */
vrm.addRoutingRule(createRuleParams("t1|r1", null, "t2|netVirt2", null,
null, null, "t1|netVirt1", null, null,
null, null, "permit"));
/* Allow t1 to communicate to t2 and vice versa */
vrm.addRoutingRule(createRuleParams("system|rs", "t1", null, null, null,
"t2", null, null, null, null, null,
"permit"));
vrm.addRoutingRule(createRuleParams("system|rs", "t2", null, null, null,
"t1", null, null, null, null, null,
"permit"));
/* Allow t1|netVirt1 to communicate with t2|netVirt1 and vice versa */
vrm.addRoutingRule(createRuleParams("t2|r2", null, "t1|netVirt1", null,
null, null, "t2|netVirt1", null, null,
null, null, "permit"));
vrm.addRoutingRule(createRuleParams("t2|r2", null, "t2|netVirt1", null,
null, null, "t1|netVirt1", null, null,
null, null, "permit"));
/* Allow t2|netVirt1 to communicate with t2|netVirt2 but NOT vice versa */
vrm.addRoutingRule(createRuleParams("t2|r2", null, "t2|netVirt1", null,
null, null, "t2|netVirt2", null, null,
null, null, "permit"));
/* Allow t2|netVirt2 to communicate with t1|netVirt1 but NOT vice versa */
vrm.addRoutingRule(createRuleParams("t2|r2", null, "t2|netVirt2", null,
null, null, "t1|netVirt1", null, null,
null, null, "permit"));
VNS netVirtA1 = new VNS("t1|netVirt1");
VNS netVirtA2 = new VNS("t1|netVirt2");
VNS netVirtA3 = new VNS("t1|netVirt3");
VNS netVirtB1 = new VNS("t2|netVirt1");
VNS netVirtB2 = new VNS("t2|netVirt2");
expect(netVirtManager.getVNS("t1|netVirt1")).andReturn(netVirtA1).anyTimes();
expect(netVirtManager.getVNS("t1|netVirt2")).andReturn(netVirtA2).anyTimes();
expect(netVirtManager.getVNS("t2|netVirt1")).andReturn(netVirtB1).anyTimes();
expect(netVirtManager.getVNS("t2|netVirt2")).andReturn(netVirtB2).anyTimes();
replay(netVirtManager);
int ipA1 = IPv4.toIPv4Address("10.1.1.2");
int ipB1 = IPv4.toIPv4Address("10.2.1.2");
int ipB2 = IPv4.toIPv4Address("10.2.2.2");
int ipr1if1 = IPv4.toIPv4Address(ipr1if1str);
int ipr2if1 = IPv4.toIPv4Address(ipr2if1str);
int retIp;
/* netVirtA3 is not connected to any router so expect 0 */
retIp = vrm.getRtrIp(netVirtA3, ipA1, ipr1if1);
assertEquals(0, retIp);
/* netVirtA1 is connected to interface if1 so return if1 ip */
retIp = vrm.getRtrIp(netVirtA1, ipA1, ipr1if1);
assertEquals(ipr1if1, retIp);
/* netVirtA1 is connected to interface if1 so return if1 ip, even though
* this IP belongs to some other interface as well
*/
retIp = vrm.getRtrIp(netVirtA1, ipA1, ipr2if1);
assertEquals(ipr2if1, retIp);
/* netVirtB1 is connected to interface if1 of router r2 so return if1 ip */
retIp = vrm.getRtrIp(netVirtB1, ipB1, ipr2if1);
assertEquals(ipr2if1, retIp);
/* netVirtB1 is allowed to communicate to netVirtA1 so it can reach interface
* if1 of router r1
*/
retIp = vrm.getRtrIp(netVirtB1, ipB1, ipr1if1);
assertEquals(ipr1if1, retIp);
/* netVirtB2 is allowed to communicate to netVirtA1 but the reverse path is not
* permitted. So return 0
*/
retIp = vrm.getRtrIp(netVirtB2, ipB2, ipr1if1);
assertEquals(0, retIp);
/* netVirtA1 and netVirtB1 are allowed to communicate so when this happens
* return the interface ip of r1 if1
*/
retIp = vrm.getRtrIp(netVirtA1, ipA1, ipB1);
assertEquals(ipr1if1, retIp);
}
}