@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 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
  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
  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 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 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());
  }