/* * 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 java.util.Map; import org.easymock.EasyMock; import org.junit.Before; import static org.easymock.EasyMock.*; import org.junit.Test; import org.sdnplatform.netvirt.core.VNS; import org.sdnplatform.netvirt.virtualrouting.ForwardingAction; import org.sdnplatform.netvirt.virtualrouting.GatewayNode; import org.sdnplatform.netvirt.virtualrouting.internal.GatewayPoolImpl; import org.sdnplatform.netvirt.virtualrouting.internal.VRouterImpl; import org.sdnplatform.netvirt.virtualrouting.internal.VRouterInterface; import org.sdnplatform.netvirt.virtualrouting.internal.VirtualRouterManager; import org.sdnplatform.packet.Ethernet; import org.sdnplatform.packet.IPv4; import org.sdnplatform.routing.IRoutingDecision.RoutingAction; import org.sdnplatform.test.PlatformTestCase; import org.sdnplatform.util.IPV4Subnet; public class VRouterTest extends PlatformTestCase { private VRouterImpl vr; private static Long vMac1 = Ethernet. toLong(Ethernet.toMACAddress("00:11:22:33:44:55")); VirtualRouterManager vRtrManager; @Before public void setUp() throws Exception { super.setUp(); vRtrManager = createMock(VirtualRouterManager.class); vr = new VRouterImpl("r1", "t1", vMac1, vRtrManager); } @Test public void testGetters() { assertEquals("r1", vr.getName()); assertEquals("t1", vr.getTenant()); } @Test /* This test tests internal working of the class alone */ public void testCreateInterface() { vr.createInterface("if1", "netVirt1", null, true); assertNotNull(vr.getInterfaceMap().get("if1")); assertEquals(true, vr.getInterfaceMap().get("if1").isNetVirt()); vr.createInterface("if2", null, "rtr1", true); assertNotNull(vr.getInterfaceMap().get("if2")); assertEquals(false, vr.getInterfaceMap().get("if2").isNetVirt()); assertEquals(2, vr.getInterfaceMap().size()); } @Test /* This test tests internal working of the class alone */ public void testAssignInterfaceAddr() throws Exception { try { vr.assignInterfaceAddr("if1", "10.10.1.1", "255.255.0.0"); fail(); } catch (IllegalArgumentException e) { /* An exception must have been thrown */ } vr.createInterface("if1", "netVirt1", null, true); vr.createInterface("if2", null, "rtr1", true); vr.assignInterfaceAddr("if1", "10.10.1.1", "255.255.0.0"); IPV4Subnet addr = new IPV4Subnet("10.10.1.1/16"); assertNotNull(vr.getInterfaceMap().get("if1").getAddrs().contains(addr)); vr.assignInterfaceAddr("if2", "200.10.1.1", "255.255.255.0"); addr = new IPV4Subnet("200.10.1.1/24"); assertNotNull(vr.getInterfaceMap().get("if2").getAddrs().contains(addr)); vr.assignInterfaceAddr("if1", "10.20.1.1", "255.255.0.0"); addr = new IPV4Subnet("10.20.1.1/16"); assertNotNull(vr.getInterfaceMap().get("if1").getAddrs().contains(addr)); assertEquals(2, vr.getInterfaceMap().get("if1").getAddrs().size()); } @Test /* This test tests internal working of the class alone */ public void testAddRoutingRule() throws Exception { vr.createInterface("if1", "netVirt1", null, true); vr.createInterface("if2", "netVirt2", null, true); vr.createInterface("ifs", null, "rtr1", true); /* Test putting rules in the SrcHostRuleMap */ vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", null, "netVirt1", null, null, null, null, "permit"); assertEquals(1, vr.getSrcHostRuleMap().get("10.10.1.1").ruleSet.size()); vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", "tenant1", null, null, null, null, null, "permit"); assertEquals(2, vr.getSrcHostRuleMap().get("10.10.1.1").ruleSet.size()); vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", null, null, "10.20.1.1", "0.0.0.0", null, null, "permit"); assertEquals(3, vr.getSrcHostRuleMap().get("10.10.1.1").ruleSet.size()); vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", null, null, "10.10.0.0", "0.0.255.255", null, null, "permit"); assertEquals(1, vr.getSrcHostRuleMap().get("10.10.1.1").subnetTrie.size()); vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", null, null, "255.255.255.255", "255.255.255.255", null, null, "deny"); assertEquals(2, vr.getSrcHostRuleMap().get("10.10.1.1").subnetTrie.size()); /* Test putting rules in the SrcNetVirtRuleMap */ vr.addRoutingRule(null, "netVirt1", null, null, null, "netVirt2", null, null, "if2", null, "deny"); assertEquals(1, vr.getSrcNetVirtRuleMap().get("netVirt1").ruleSet.size()); vr.addRoutingRule(null, "netVirt1", null, null, null, null, "10.20.1.1", "0.0.0.0", "if2", null, "deny"); assertEquals(2, vr.getSrcNetVirtRuleMap().get("netVirt1").ruleSet.size()); vr.addRoutingRule(null, "netVirt1", null, null, "Tenant2", null, null, null, "if2", null, "permit"); assertEquals(3, vr.getSrcNetVirtRuleMap().get("netVirt1").ruleSet.size()); vr.addRoutingRule(null, "netVirt1", null, null, null, null, "10.30.0.0", "0.0.255.255", "ifs", "10.30.1.1", "permit"); assertEquals(1, vr.getSrcNetVirtRuleMap().get("netVirt1").subnetTrie.size()); vr.addRoutingRule(null, "netVirt1", null, null, null, null, "0.0.0.0", "255.255.255.255", null, null, "deny"); assertEquals(2, vr.getSrcNetVirtRuleMap().get("netVirt1").subnetTrie.size()); /* Test putting rules in the SrcTenantRuleMap */ vr.addRoutingRule("t1", null, null, null, null, null, "10.30.1.1", "0.0.0.0", "ifs", null, "permit"); assertEquals(1, vr.getSrcTenantRuleMap().get("t1").ruleSet.size()); vr.addRoutingRule("t1", null, null, null, "t2", null, null, null, null, null, "permit"); assertEquals(2, vr.getSrcTenantRuleMap().get("t1").ruleSet.size()); vr.addRoutingRule("t1", null, null, null, null, "netVirt4", null, null, null, null, "permit"); assertEquals(3, vr.getSrcTenantRuleMap().get("t1").ruleSet.size()); vr.addRoutingRule("t1", null, null, null, null, null, "10.30.0.0", "0.0.255.255", null, null, "deny"); assertEquals(1, vr.getSrcTenantRuleMap().get("t1").subnetTrie.size()); vr.addRoutingRule("t1", null, null, null, null, null, "255.255.255.255", "255.255.255.255", "ifs", null, "permit"); assertEquals(2, vr.getSrcTenantRuleMap().get("t1").subnetTrie.size()); /* Test putting rules in the srcSubnetRuleTrie */ vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", null, null, "10.30.0.1", "0.0.0.0", "ifs", null, "permit"); IPV4Subnet addr = new IPV4Subnet("10.10.0.0/16"); assertEquals(1, vr.getSrcSubnetRuleTrie().get(addr).ruleSet.size()); vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", "t2", null, null, null, "ifs", null, "permit"); assertEquals(2, vr.getSrcSubnetRuleTrie().get(addr).ruleSet.size()); vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", null, "netVirt4", null, null, "ifs", null, "permit"); assertEquals(3, vr.getSrcSubnetRuleTrie().get(addr).ruleSet.size()); vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", null, null, "10.30.0.1", "0.0.255.255", null, null, "deny"); assertEquals(1, vr.getSrcSubnetRuleTrie().get(addr).subnetTrie.size()); vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", null, null, "255.255.255.255", "255.255.255.255", null, null, "permit"); assertEquals(2, vr.getSrcSubnetRuleTrie().get(addr).subnetTrie.size()); try { /* Use an invalid interface and see whether there is an exception */ vr.addRoutingRule(null, "netVirt1", null, null,"t2", null, null, null, "if3", null, "permit"); fail(); } catch (IllegalArgumentException e) { /* Exception should be thrown */ } } @Test public void testAddRoutingRuleWithNextHopGatewayPool() throws Exception { vr.createInterface("if1", "netVirt1", null, true); vr.createInterface("if2", "netVirt2", null, true); vr.createInterface("ifs", null, "rtr1", true); /* Test putting rules in the SrcHostRuleMap */ vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", null, "netVirt1", null, null, null, null, "permit", "testpool"); assertEquals(1, vr.getSrcHostRuleMap().get("10.10.1.1").ruleSet.size()); vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", "tenant1", null, null, null, null, null, "permit", "testpool"); assertEquals(2, vr.getSrcHostRuleMap().get("10.10.1.1").ruleSet.size()); vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", null, null, "10.20.1.1", "0.0.0.0", null, null, "permit", "testpool"); assertEquals(3, vr.getSrcHostRuleMap().get("10.10.1.1").ruleSet.size()); vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", null, null, "10.10.0.0", "0.0.255.255", null, null, "permit", "testpool"); assertEquals(1, vr.getSrcHostRuleMap().get("10.10.1.1").subnetTrie.size()); vr.addRoutingRule(null, null, "10.10.1.1", "0.0.0.0", null, null, "255.255.255.255", "255.255.255.255", null, null, "deny", "testpool"); assertEquals(2, vr.getSrcHostRuleMap().get("10.10.1.1").subnetTrie.size()); /* Test putting rules in the SrcNetVirtRuleMap */ vr.addRoutingRule(null, "netVirt1", null, null, null, "netVirt2", null, null, "if2", null, "deny", "testpool"); assertEquals(1, vr.getSrcNetVirtRuleMap().get("netVirt1").ruleSet.size()); vr.addRoutingRule(null, "netVirt1", null, null, null, null, "10.20.1.1", "0.0.0.0", "if2", null, "deny", "testpool"); assertEquals(2, vr.getSrcNetVirtRuleMap().get("netVirt1").ruleSet.size()); vr.addRoutingRule(null, "netVirt1", null, null, "Tenant2", null, null, null, "if2", null, "permit", "testpool"); assertEquals(3, vr.getSrcNetVirtRuleMap().get("netVirt1").ruleSet.size()); vr.addRoutingRule(null, "netVirt1", null, null, null, null, "10.30.0.0", "0.0.255.255", "ifs", "10.30.1.1", "permit", null); assertEquals(1, vr.getSrcNetVirtRuleMap().get("netVirt1").subnetTrie.size()); vr.addRoutingRule(null, "netVirt1", null, null, null, null, "0.0.0.0", "255.255.255.255", null, null, "deny", "testpool"); assertEquals(2, vr.getSrcNetVirtRuleMap().get("netVirt1").subnetTrie.size()); /* Test putting rules in the SrcTenantRuleMap */ vr.addRoutingRule("t1", null, null, null, null, null, "10.30.1.1", "0.0.0.0", "ifs", null, "permit", "testpool"); assertEquals(1, vr.getSrcTenantRuleMap().get("t1").ruleSet.size()); vr.addRoutingRule("t1", null, null, null, "t2", null, null, null, null, null, "permit", "testpool"); assertEquals(2, vr.getSrcTenantRuleMap().get("t1").ruleSet.size()); vr.addRoutingRule("t1", null, null, null, null, "netVirt4", null, null, null, null, "permit", "testpool"); assertEquals(3, vr.getSrcTenantRuleMap().get("t1").ruleSet.size()); vr.addRoutingRule("t1", null, null, null, null, null, "10.30.0.0", "0.0.255.255", null, null, "deny", "testpool"); assertEquals(1, vr.getSrcTenantRuleMap().get("t1").subnetTrie.size()); vr.addRoutingRule("t1", null, null, null, null, null, "255.255.255.255", "255.255.255.255", "ifs", null, "permit", "testpool"); assertEquals(2, vr.getSrcTenantRuleMap().get("t1").subnetTrie.size()); /* Test putting rules in the srcSubnetRuleTrie */ vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", null, null, "10.30.0.1", "0.0.0.0", "ifs", null, "permit", "testpool"); IPV4Subnet addr = new IPV4Subnet("10.10.0.0/16"); assertEquals(1, vr.getSrcSubnetRuleTrie().get(addr).ruleSet.size()); vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", "t2", null, null, null, "ifs", null, "permit", "testpool"); assertEquals(2, vr.getSrcSubnetRuleTrie().get(addr).ruleSet.size()); vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", null, "netVirt4", null, null, "ifs", null, "permit", "testpool"); assertEquals(3, vr.getSrcSubnetRuleTrie().get(addr).ruleSet.size()); vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", null, null, "10.30.0.1", "0.0.255.255", null, null, "deny", "testpool"); assertEquals(1, vr.getSrcSubnetRuleTrie().get(addr).subnetTrie.size()); vr.addRoutingRule(null, null, "10.10.0.0", "0.0.255.255", null, null, "255.255.255.255", "255.255.255.255", null, null, "permit", "testpool"); assertEquals(2, vr.getSrcSubnetRuleTrie().get(addr).subnetTrie.size()); try { /* Use an invalid interface and see whether there is an exception */ vr.addRoutingRule(null, "netVirt1", null, null,"t2", null, null, null, "if3", null, "permit", "testpool"); fail(); } catch (IllegalArgumentException e) { /* Exception should be thrown */ } } @Test public void testIsIfaceDown() { vr.createInterface("if1", "t1|netVirt1", null, true); vr.createInterface("if2", "t1|netVirt2", null, false); vr.createInterface("if3", null, "t2|r2", true); vr.createInterface("if4", null, "t2|r3", false); boolean down; down = vr.isIfaceDown("t1|netVirt1"); assertEquals(false, down); down = vr.isIfaceDown("t1|netVirt2"); assertEquals(true, down); down = vr.isIfaceDown("t2|r2"); assertEquals(false, down); down = vr.isIfaceDown("t2|r3"); assertEquals(true, down); down = vr.isIfaceDown("t2|r4"); assertEquals(true, down); } @Test public void testGetForwardingAction() throws Exception { vr.createInterface("if1", "t1|netVirt1", null, true); vr.createInterface("if2", "t1|netVirt2", null, true); vr.createInterface("if3", "t1|netVirt3", null, false); vr.createInterface("ifs", null, "system|rs", true); vr.assignInterfaceAddr("if1", "10.1.1.1", "0.0.0.255"); vr.assignInterfaceAddr("if2", "10.1.2.1", "0.0.0.255"); vr.assignInterfaceAddr("if3", "10.1.3.1", "0.0.0.255"); VRouterImpl vr2 = new VRouterImpl("r2", "t2", vMac1, vRtrManager); vr2.createInterface("if1", "t2|netVirt1", null, true); vr2.createInterface("if2", "t2|netVirt2", null, true); vr2.createInterface("if3", "t2|netVirt3", null, true); vr2.createInterface("ifs", null, "system|rs", true); /* External tenant router */ VRouterImpl vrx = new VRouterImpl("rx", "tx", vMac1, vRtrManager); vrx.createInterface("if1", "tx|netVirtx", null, true); vrx.createInterface("ifs", null, "system|rs", true); /* System Router */ VRouterImpl vrs = new VRouterImpl("rs", "system", vMac1, vRtrManager); vrs.createInterface("if1", null, "t1|r1", true); vrs.createInterface("if2", null, "t2|r2", true); vrs.createInterface("ifx", null, "tx|rx", true); 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 netVirtx = new VNS("tx|netVirtx"); int ip1, ip2; ip1 = IPv4.toIPv4Address("10.1.1.2"); ip2 = IPv4.toIPv4Address("10.1.2.2"); ForwardingAction action; /* There is no routing rule so packet is dropped */ action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, netVirtA2, ip2); assertEquals(RoutingAction.DROP, action.getAction()); vr.addRoutingRule(null, null, "10.1.1.2", "0.0.0.0", null, null, "0.0.0.0", "255.255.255.255", null, null, "permit"); /* Test routing between NetVirts on the same tenant */ action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, netVirtA2, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals(null, action.getNextRtrName()); assertEquals(ip2, action.getNextHopIp()); assertEquals("t1|netVirt2", action.getDstNetVirtName()); assertEquals(vMac1.longValue(), action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* Since interface if3 is down, the packet is dropped */ ip2 = IPv4.toIPv4Address("10.1.3.2"); action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, netVirtA3, ip2); assertEquals(RoutingAction.DROP, action.getAction()); /* The interface to the system router is picked by default */ ip2 = IPv4.toIPv4Address("10.2.1.2"); action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, netVirtB1, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("system|rs", action.getNextRtrName()); assertEquals(ip2, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); vr.addRoutingRule(null, null, "10.1.1.2", "0.0.0.0", null, null, "10.2.1.0", "0.0.0.255", null, null, "deny"); /* The same connection above is denied. Tests whether we pick the * longest prefix match */ action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, netVirtB1, ip2); assertEquals(RoutingAction.DROP, action.getAction()); vr.addRoutingRule(null, null, "10.1.1.2", "0.0.0.0", null, null, "10.2.1.0", "0.0.0.127", null, null, "permit"); /* Longer prefix match still */ action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, netVirtB1, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("system|rs", action.getNextRtrName()); assertEquals(ip2, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); vr.addRoutingRule(null, null, "10.1.1.2", "0.0.0.0", "t2", null, null, null, null, null, "deny"); /* Tenant rule is given more priority */ action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, netVirtB1, ip2); assertEquals(RoutingAction.DROP, action.getAction()); vr.addRoutingRule(null, null, "10.1.1.2", "0.0.0.0", null, "t2|netVirt1", null, null, null, null, "permit"); /* NetVirt rule is higher priority */ action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, netVirtB1, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("system|rs", action.getNextRtrName()); assertEquals(ip2, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* Host rule has higher priority */ int ip3 = IPv4.toIPv4Address("11.11.11.11"); vr.addRoutingRule(null, null, "10.1.1.2", "0.0.0.0", null, null, "10.2.1.2", "0.0.0.0", "if2", "11.11.11.11", "permit"); action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, netVirtB1, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals(null, action.getNextRtrName()); assertEquals(ip3, action.getNextHopIp()); assertEquals("t1|netVirt2", action.getDstNetVirtName()); assertEquals(vMac1.longValue(), action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); vr.addRoutingRule(null, "t1|netVirt2", null, null, null, null, "10.2.1.2", "0.0.0.0", "if2", "11.11.11.11", "permit"); /* We dont send packet out of the interface it came in */ ip1 = IPv4.toIPv4Address("10.1.2.2"); action = vr.getForwardingAction("t1|netVirt2", netVirtA2, ip1, netVirtB1, ip2); assertEquals(RoutingAction.DROP, action.getAction()); /* A more traditional routing config */ vr.addRoutingRule(null, "t1|netVirt2", null, null, "t2", null, null, null, null, null, "permit"); ip2 = IPv4.toIPv4Address("10.2.1.4"); action = vr.getForwardingAction("t1|netVirt2", netVirtA2, ip1, netVirtB1, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("system|rs", action.getNextRtrName()); assertEquals(ip2, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* Try this out in the system router policy */ vrs.addRoutingRule("t1", null, null, null, "t2", null, null, null, null, null, "permit"); action = vrs.getForwardingAction("t1|r1", netVirtA2, ip1, netVirtB1, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("t2|r2", action.getNextRtrName()); assertEquals(ip2, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* Handle the packet at the ingress of t2|r2 */ vr2.addRoutingRule("t1", null, null, null, null, "t2|netVirt1", null, null, null, null, "permit"); action = vr2.getForwardingAction("system|rs", netVirtA2, ip1, netVirtB1, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals(null, action.getNextRtrName()); assertEquals(ip2, action.getNextHopIp()); assertEquals("t2|netVirt1", action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* Check that an invalid input interface is handled correctly */ action = vrs.getForwardingAction("system|rs", netVirtA2, ip1, netVirtB1, ip2); assertEquals(RoutingAction.DROP, action.getAction()); /* Check that the packet is dropped if there isnt any rule found */ ip1 = IPv4.toIPv4Address("10.2.1.5"); ip2 = IPv4.toIPv4Address("192.168.0.20"); action = vr2.getForwardingAction("t2|netVirt1", netVirtB1, ip1, netVirtx, ip2); assertEquals(RoutingAction.DROP, action.getAction()); vr2.addRoutingRule("t2", null, null, null, null, "t1|netVirt1", null, null, null, null, "permit"); action = vr2.getForwardingAction("t2|netVirt1", netVirtB1, ip1, netVirtx, ip2); assertEquals(RoutingAction.DROP, action.getAction()); vr2.addRoutingRule(null, null, "10.2.1.0", "0.0.0.255", null, null, "192.168.0.0", "0.0.255.255", null, null, "permit"); action = vr2.getForwardingAction("t2|netVirt1", netVirtB1, ip1, netVirtx, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("system|rs", action.getNextRtrName()); assertEquals(ip2, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* A more specific subnet match will take precedence */ vr2.addRoutingRule(null, null, "10.2.1.0", "0.0.0.255", null, null, "192.168.0.0", "0.0.0.255", null, null, "drop"); action = vr2.getForwardingAction("t2|netVirt1", netVirtB1, ip1, netVirtx, ip2); assertEquals(RoutingAction.DROP, action.getAction()); } @Test public void testGetForwardingActionSilentHost() throws Exception { expect(vRtrManager.findSubnetOwner(EasyMock.anyObject(IPV4Subnet.class))). andReturn("t2|r2").times(2); expect(vRtrManager.findSubnetOwner(EasyMock.anyObject(IPV4Subnet.class))). andReturn(null).once(); vRtrManager.addSubnetOwner(EasyMock.anyObject(IPV4Subnet.class), EasyMock.anyObject(String.class)); expectLastCall().times(3); vRtrManager.addIfaceIpMap(EasyMock.anyInt(), EasyMock.anyObject(VRouterInterface.class)); expectLastCall().anyTimes(); replay(vRtrManager); vr.createInterface("if1", "t1|netVirt1", null, true); vr.createInterface("if2", "t1|netVirt2", null, true); vr.createInterface("ifs", null, "system|rs", true); vr.assignInterfaceAddr("if1", "10.1.1.1", "0.0.0.255"); vr.assignInterfaceAddr("if2", "10.1.2.1", "0.0.0.255"); VRouterImpl vr2 = new VRouterImpl("r2", "t2", vMac1, vRtrManager); vr2.createInterface("if1", "t2|netVirt1", null, true); vr2.createInterface("if2", "t2|netVirt2", null, true); vr2.createInterface("ifs", null, "system|rs", true); vr2.assignInterfaceAddr("if1", "10.2.1.1", "0.0.0.255"); /* External tenant router */ VRouterImpl vrx = new VRouterImpl("rx", "tx", vMac1, vRtrManager); vrx.createInterface("if1", "tx|netVirtx", null, true); vrx.createInterface("ifs", null, "system|rs", true); /* System Router */ VRouterImpl vrs = new VRouterImpl("rs", "system", vMac1, vRtrManager); vrs.createInterface("if1", null, "t1|r1", true); vrs.createInterface("if2", null, "t2|r2", true); vrs.createInterface("ifx", null, "tx|rx", true); VNS netVirtA1 = new VNS("t1|netVirt1"); int ip1, ip2, ip3; ip1 = IPv4.toIPv4Address("10.1.1.2"); ip2 = IPv4.toIPv4Address("10.1.2.2"); ip3 = IPv4.toIPv4Address("10.2.1.2"); ForwardingAction action; /* Allow host 10.1.1.2 to talk to all other hosts */ vr.addRoutingRule(null, null, "10.1.1.2", "0.0.0.0", null, null, "255.255.255.255", "255.255.255.255", null, null, "permit"); /* Testing for a silent host. The dest device entity is null */ action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, null, ip2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals(null, action.getNextRtrName()); assertEquals(ip2, action.getNextHopIp()); assertEquals("t1|netVirt2", action.getDstNetVirtName()); assertEquals(vMac1.longValue(), action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); action = vr.getForwardingAction("t1|netVirt1", netVirtA1, ip1, null, ip3); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("system|rs", action.getNextRtrName()); assertEquals(ip3, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* Allow all hosts in NetVirtA1 subnet to talk to any other hosts */ vrs.addRoutingRule(null, null, "10.1.1.0", "0.0.0.255", null, null, "0.0.0.0", "255.255.255.255", null, null, "permit"); action = vrs.getForwardingAction("t1|r1", netVirtA1, ip1, null, ip3); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("t2|r2", action.getNextRtrName()); assertEquals(ip3, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* Send a packet to an unknown subnet and see that it is dropped * Note that we have set the vRtrManager object to return null for the * call to findSubnetOwner after the second time. */ ip3 = IPv4.toIPv4Address("192.168.0.1"); action = vrs.getForwardingAction("t1|r1", netVirtA1, ip1, null, ip3); assertEquals(RoutingAction.DROP, action.getAction()); verify(vRtrManager); } /* Test the working of the system router when it is configured to allow all * traffic (full mesh) */ @Test public void testGetForwardingActionSystemRtr() throws Exception { expect(vRtrManager.findSubnetOwner(EasyMock.anyObject(IPV4Subnet.class))). andReturn(null).once(); expect(vRtrManager.findSubnetOwner(EasyMock.anyObject(IPV4Subnet.class))). andReturn("B|vrB").times(1); replay(vRtrManager); /* System Router */ VRouterImpl vrs = new VRouterImpl("rs", "system", vMac1, vRtrManager); vrs.createInterface("if1", null, "A|vrA", true); vrs.createInterface("if2", null, "B|vrB", true); vrs.createInterface("ifexternal", null, "external|vrX", true); VNS netVirtA1 = new VNS("A|netVirtA1"); int ipA1, ipB1, ipX; ipA1 = IPv4.toIPv4Address("10.1.1.2"); ipB1 = IPv4.toIPv4Address("10.1.2.2"); ipX = IPv4.toIPv4Address("8.8.8.8"); ForwardingAction action; /* Allow all communication */ vrs.addRoutingRule(null, null, "10.0.0.0", "255.255.255.255", null, null, "10.0.0.0", "255.255.255.255", null, null, "permit"); /* Testing for a silent host. The dest device entity is null */ action = vrs.getForwardingAction("A|vrA", netVirtA1, ipA1, null, ipX); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("external|vrX", action.getNextRtrName()); assertEquals(ipX, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* Inter tenant communication is allowed */ action = vrs.getForwardingAction("A|vrA", netVirtA1, ipA1, null, ipB1); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("B|vrB", action.getNextRtrName()); assertEquals(ipB1, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); /* Communication from external tenant is correctly routed */ VNS netVirtX = new VNS("external|netVirtX"); action = vrs.getForwardingAction("external|vrX", netVirtX, ipX, netVirtA1, ipA1); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("A|vrA", action.getNextRtrName()); assertEquals(ipA1, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); verify(vRtrManager); } /* Test the working of the system router when it is configured to allow only * external NetVirt traffic */ @Test public void testGetForwardingActionSystemRtr2() throws Exception { /* System Router */ VRouterImpl vrs = new VRouterImpl("rs", "system", vMac1, vRtrManager); vrs.createInterface("if1", null, "A|vrA", true); vrs.createInterface("if2", null, "B|vrB", true); vrs.createInterface("ifexternal", null, "external|vrX", true); VNS netVirtA1 = new VNS("A|netVirtA1"); int ipA1, ipB1, ipX; ipA1 = IPv4.toIPv4Address("10.1.1.2"); ipB1 = IPv4.toIPv4Address("10.1.2.2"); ipX = IPv4.toIPv4Address("8.8.8.8"); ForwardingAction action; /* any to any go to external router */ vrs.addRoutingRule(null, null, "10.0.0.0", "255.255.255.255", null, null, "10.0.0.0", "255.255.255.255", "ifexternal", null, "permit"); /* External to any allow */ vrs.addRoutingRule("external", null, null, null, null, null, "10.0.0.0", "255.255.255.255", null, null, "permit"); /* Testing for a silent host. The dest device entity is null */ action = vrs.getForwardingAction("A|vrA", netVirtA1, ipA1, null, ipX); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("external|vrX", action.getNextRtrName()); assertEquals(ipX, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); /* Inter tenant communication is sent to external router as well */ action = vrs.getForwardingAction("A|vrA", netVirtA1, ipA1, null, ipB1); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("external|vrX", action.getNextRtrName()); assertEquals(ipB1, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); /* Communication from external tenant is correctly routed */ VNS netVirtX = new VNS("external|netVirtX"); action = vrs.getForwardingAction("external|vrX", netVirtX, ipX, netVirtA1, ipA1); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals("A|vrA", action.getNextRtrName()); assertEquals(ipA1, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals(0, action.getNewSrcMac()); assertEquals(null, action.getNextHopGatewayPool()); assertEquals(null, action.getNextHopGatewayPoolRouter()); } /* Test the working of the router when it is configured with a rule having * a next hop IP */ @Test public void testGetForwardingActionNHIp() throws Exception { vr.createInterface("if1", "A|netVirtA1", null, true); vr.createInterface("if2", "A|netVirtA2", null, true); vr.createInterface("ifs", null, "system|rs", true); vr.assignInterfaceAddr("if1", "10.1.1.1", "0.0.0.255"); vr.assignInterfaceAddr("if2", "10.1.2.1", "0.0.0.255"); String ipA1str, ipA2str, ipnhstr, ipXstr; ipA1str = "10.1.1.2"; ipA2str = "10.1.2.12"; ipnhstr = "10.1.2.2"; ipXstr = "192.168.1.1"; int ipA1, ipA2, ipnh, ipX; ipA1 = IPv4.toIPv4Address(ipA1str); ipA2 = IPv4.toIPv4Address(ipA2str); ipnh = IPv4.toIPv4Address(ipnhstr); ipX = IPv4.toIPv4Address(ipXstr); ForwardingAction action; VNS netVirtA1 = new VNS("A|netVirtA1"); VNS netVirtA2 = new VNS("A|netVirtA2"); VNS netVirtX = new VNS("X|netVirtX"); /* Tenant A to any send to next hop ip */ vr.addRoutingRule("A", null, null, null, null, null, "10.0.0.0", "255.255.255.255", null, ipnhstr, "permit"); /* Next hop is in the same NetVirt as the dest NetVirt */ action = vr.getForwardingAction("A|netVirtA1", netVirtA1, ipA1, netVirtA2, ipA2); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals(null, action.getNextRtrName()); assertEquals(ipnh, action.getNextHopIp()); assertEquals("A|netVirtA2", action.getDstNetVirtName()); assertEquals(vMac1.longValue(), action.getNewSrcMac()); /* Next hop is in a different NetVirt as the dest NetVirt */ action = vr.getForwardingAction("A|netVirtA1", netVirtA1, ipA1, netVirtX, ipX); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals(null, action.getNextRtrName()); assertEquals(ipnh, action.getNextHopIp()); assertEquals("A|netVirtA2", action.getDstNetVirtName()); assertEquals(vMac1.longValue(), action.getNewSrcMac()); /* The next hop is not connected to any subnet of the router */ /* netVirtA1 to any send to ipX */ vr.addRoutingRule(null, "A|netVirtA1", null, null, null, null, "10.0.0.0", "255.255.255.255", null, ipXstr, "permit"); action = vr.getForwardingAction("A|netVirtA1", netVirtA1, ipA1, netVirtA2, ipA2); assertEquals(RoutingAction.DROP, action.getAction()); assertEquals(null, action.getNextRtrName()); assertEquals(0, action.getNextHopIp()); assertEquals(null, action.getDstNetVirtName()); assertEquals((long) 0, action.getNewSrcMac()); } @Test public void testGetForwardingActionNextHopGatewayPool() { /* External router belonging to an external tenant */ VRouterImpl vrx = new VRouterImpl("rx", "tx", vMac1, vRtrManager); vrx.createInterface("if-external", "tx|netVirtx", null, true); vrx.createInterface("if-system", null, "rs", true); /* NetVirt attached to the tenant "t1" */ VNS netVirtA1 = new VNS("t1|netVirt1"); /* Source IP of the packet */ int ip1 = IPv4.toIPv4Address("10.0.0.1"); /* NetVirt attached to the external tenant */ VNS netVirtX1 = new VNS("tx|netVirtx"); /* Destination IP of the packet */ int ipx = IPv4.toIPv4Address("8.8.8.8"); /* * Setup a routing rule to permit traffic from * tenant|netVirt = "t1"|"netVirt1" to tenant|netVirt = "tx|netVirtx" and send it to * the gateway pool "test-gateway-pool" */ vrx.addRoutingRule("t1", "t1|netVirt1", null, null, "tx", "tx|netVirtx", null, null, "if-external", null, "permit", "test-gateway-pool"); /* * Now, invoke getForwardingAction on the virtual router object * corresponding to the external virtual router to determine * the forwarding action for traffic from tenant("t1")|netVirt("netVirt1") * to the tenant("tx")|netVirt("netVirtx") */ ForwardingAction action = vrx.getForwardingAction("rs", netVirtA1, ip1, netVirtX1, ipx); assertEquals(RoutingAction.FORWARD, action.getAction()); assertEquals(null, action.getNextRtrName()); assertEquals(0, action.getNextHopIp()); assertEquals("tx|netVirtx", action.getDstNetVirtName()); assertEquals((long)0, action.getNewSrcMac()); assertEquals("test-gateway-pool", action.getNextHopGatewayPool()); assertEquals(vrx, action.getNextHopGatewayPoolRouter()); } @Test public void testGetVMac() throws Exception { vr.createInterface("if1", "t1|netVirt1", null, true); vr.createInterface("if2", "t1|netVirt2", null, true); vr.createInterface("if3", "t1|netVirt3", null, false); vr.createInterface("ifs", null, "system|rs", true); vr.assignInterfaceAddr("if1", "10.1.1.1", "255.255.255.0"); vr.assignInterfaceAddr("if1", "10.2.1.1", "255.255.255.0"); vr.assignInterfaceAddr("if2", "10.1.2.1", "255.255.255.0"); vr.assignInterfaceAddr("if3", "10.1.3.1", "255.255.255.0"); vr.assignInterfaceAddr("ifs", "192.168.1.1", "255.255.255.0"); int ip = IPv4.toIPv4Address("10.1.1.1"); long vMac = vr.getVMac("t1|netVirt1", ip); long expectedVMac = Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:55")); assertEquals(expectedVMac, vMac); ip = IPv4.toIPv4Address("10.2.1.1"); vMac = vr.getVMac("t1|netVirt1", ip); assertEquals(expectedVMac, vMac); ip = IPv4.toIPv4Address("10.1.3.1"); vMac = vr.getVMac("t1|netVirt3", ip); assertEquals(expectedVMac, vMac); ip = IPv4.toIPv4Address("192.168.1.1"); vMac = vr.getVMac("system|rs", ip); assertEquals(expectedVMac, vMac); ip = IPv4.toIPv4Address("10.2.1.1"); vMac = vr.getVMac("netVirt1", ip); assertEquals(0, vMac); ip = IPv4.toIPv4Address("10.2.1.2"); vMac = vr.getVMac("t1|netVirt1", ip); assertEquals(0, vMac); } @Test public void testGetRtrIp() throws Exception { String if1ip1str = "10.1.1.1"; String if1ip2str = "10.2.1.1"; String if2ipstr = "10.1.2.1"; String if3ipstr = "10.1.3.1"; String ifsipstr = "192.168.1.1"; int if1ip1 = IPv4.toIPv4Address(if1ip1str); int if1ip2 = IPv4.toIPv4Address(if1ip2str); vr.createInterface("if1", "t1|netVirt1", null, true); vr.createInterface("if2", "t1|netVirt2", null, true); vr.createInterface("if3", "t1|netVirt3", null, false); vr.createInterface("ifs", null, "system|rs", true); vr.assignInterfaceAddr("if1", if1ip1str, "0.0.0.255"); vr.assignInterfaceAddr("if1", if1ip2str, "0.0.0.255"); vr.assignInterfaceAddr("if2", if2ipstr, "0.0.0.255"); vr.assignInterfaceAddr("if3", if3ipstr, "0.0.0.255"); vr.assignInterfaceAddr("ifs", ifsipstr, "0.0.0.255"); int ip, retIp; /* The IP belongs to the first subnet of if1 */ ip = IPv4.toIPv4Address("10.1.1.3"); retIp = vr.getRtrIp("t1|netVirt1", ip); assertEquals(if1ip1, retIp); /* The IP belongs to the second subnet of if1 */ ip = IPv4.toIPv4Address("10.2.1.3"); retIp = vr.getRtrIp("t1|netVirt1", ip); assertEquals(if1ip2, retIp); /* The IP does not belong to any subnet of the router */ ip = IPv4.toIPv4Address("10.10.2.3"); retIp = vr.getRtrIp("t1|netVirt1", ip); assertEquals(0, retIp); /* The NetVirt is not attached to the router */ ip = IPv4.toIPv4Address("10.1.1.3"); retIp = vr.getRtrIp("t1|netVirtX", ip); assertEquals(0, retIp); } /* * Note: The following tests on the gateway pool/node related APIs in * VirutalRouterImpl class ensure only that the IGatewayPool API usage is * correct. It does not cover in detail the test cases for the IGatewayPool * APIs. Please refer GatewayPoolTest.java for detailed tests on the * IGatewayPool interface. */ @Test public void testCreateGatewayPool() { String gatewayPoolName1 = "testGatewayPool1"; vr.createGatewayPool(gatewayPoolName1); GatewayPoolImpl gatewayPool1 = vr.getGatewayPool(gatewayPoolName1); assertNotNull(gatewayPool1); assertEquals("testGatewayPool1", gatewayPool1.getName()); String gatewayPoolName2 = "testGatewayPool2"; vr.createGatewayPool(gatewayPoolName2); GatewayPoolImpl gatewayPool2 = vr.getGatewayPool(gatewayPoolName2); assertNotNull(gatewayPool2); assertEquals("testGatewayPool2", gatewayPool2.getName()); } @Test public void testAddGatewayNode() { String gatewayPoolName = "testGatewayPool"; vr.createGatewayPool(gatewayPoolName); vr.addGatewayPoolNode(gatewayPoolName, "10.0.0.1"); vr.addGatewayPoolNode(gatewayPoolName, "10.0.0.2"); GatewayPoolImpl gatewayPool = vr.getGatewayPool(gatewayPoolName); assertNotNull(gatewayPool); assertEquals("testGatewayPool", gatewayPool.getName()); Map<String, GatewayNode> nodes = gatewayPool.getGatewayNodes(); assertNotNull(nodes); assertEquals(2, nodes.size()); GatewayNode node1 = nodes.get("10.0.0.1"); assertEquals("10.0.0.1", IPv4.fromIPv4Address(node1.getIp())); GatewayNode node2 = nodes.get("10.0.0.2"); assertEquals("10.0.0.2", IPv4.fromIPv4Address(node2.getIp())); } @Test public void testAddGatewayNodeInvalidPool() throws Exception { try { vr.addGatewayPoolNode("nonExistentGatewayPool", "10.0.0.1"); fail(); } catch (IllegalArgumentException e) { assertEquals(IllegalArgumentException.class, e.getClass()); } } @Test public void getOptimalGatewayNodeIPInvalidPool() throws Exception { try { vr.getOptimalGatewayNodeInfo("nonExistentGatewayPool", null, (short)1); fail(); } catch (IllegalArgumentException e) { assertEquals(IllegalArgumentException.class, e.getClass()); } } }