Added restrictions for proxy ARP
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/HostAdminService.java b/core/api/src/main/java/org/onlab/onos/net/host/HostAdminService.java
index 645f729..38cfa2e 100644
--- a/core/api/src/main/java/org/onlab/onos/net/host/HostAdminService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/host/HostAdminService.java
@@ -1,7 +1,5 @@
package org.onlab.onos.net.host;
-import java.util.Set;
-
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.HostId;
@@ -47,20 +45,4 @@
*/
void clearAddresses(ConnectPoint connectPoint);
- /**
- * Returns the addresses information for all connection points.
- *
- * @return the set of address bindings for all connection points
- */
- Set<PortAddresses> getAddressBindings();
-
- /**
- * Retrieves the addresses that have been bound to the given connection
- * point.
- *
- * @param connectPoint the connection point to retrieve address bindings
- * for
- * @return addresses bound to the port
- */
- PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint);
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/host/HostService.java b/core/api/src/main/java/org/onlab/onos/net/host/HostService.java
index a0f51b3..09034eb 100644
--- a/core/api/src/main/java/org/onlab/onos/net/host/HostService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/host/HostService.java
@@ -110,6 +110,23 @@
void requestMac(IpAddress ip);
/**
+ * Returns the addresses information for all connection points.
+ *
+ * @return the set of address bindings for all connection points
+ */
+ Set<PortAddresses> getAddressBindings();
+
+ /**
+ * Retrieves the addresses that have been bound to the given connection
+ * point.
+ *
+ * @param connectPoint the connection point to retrieve address bindings
+ * for
+ * @return addresses bound to the port
+ */
+ PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint);
+
+ /**
* Adds the specified host listener.
*
* @param listener host listener
diff --git a/core/api/src/main/java/org/onlab/onos/net/proxyarp/ProxyArpService.java b/core/api/src/main/java/org/onlab/onos/net/proxyarp/ProxyArpService.java
index 77d1208..1e29a02 100644
--- a/core/api/src/main/java/org/onlab/onos/net/proxyarp/ProxyArpService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/proxyarp/ProxyArpService.java
@@ -1,5 +1,6 @@
package org.onlab.onos.net.proxyarp;
+import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.packet.PacketContext;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpPrefix;
@@ -23,8 +24,9 @@
* will be flooded at all edge ports.
*
* @param eth an arp request
+ * @param inPort the port the request was received on
*/
- void reply(Ethernet eth);
+ void reply(Ethernet eth, ConnectPoint inPort);
/**
* Forwards an ARP request to its destination. Floods at the edge the ARP request if the
diff --git a/core/api/src/test/java/org/onlab/onos/net/host/HostServiceAdapter.java b/core/api/src/test/java/org/onlab/onos/net/host/HostServiceAdapter.java
index f03621c..2394302 100644
--- a/core/api/src/test/java/org/onlab/onos/net/host/HostServiceAdapter.java
+++ b/core/api/src/test/java/org/onlab/onos/net/host/HostServiceAdapter.java
@@ -75,4 +75,14 @@
public void removeListener(HostListener listener) {
}
+ @Override
+ public Set<PortAddresses> getAddressBindings() {
+ return null;
+ }
+
+ @Override
+ public PortAddresses getAddressBindingsForPort(ConnectPoint connectPoint) {
+ return null;
+ }
+
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java b/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java
index ac10384..8a86544 100644
--- a/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManager.java
@@ -5,6 +5,7 @@
import static org.slf4j.LoggerFactory.getLogger;
import java.nio.ByteBuffer;
+import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
@@ -15,6 +16,7 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.HostId;
@@ -27,6 +29,7 @@
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.host.HostService;
+import org.onlab.onos.net.host.PortAddresses;
import org.onlab.onos.net.link.LinkEvent;
import org.onlab.onos.net.link.LinkListener;
import org.onlab.onos.net.link.LinkService;
@@ -37,7 +40,9 @@
import org.onlab.onos.net.proxyarp.ProxyArpService;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.slf4j.Logger;
@@ -101,12 +106,46 @@
}
@Override
- public void reply(Ethernet eth) {
+ public void reply(Ethernet eth, ConnectPoint inPort) {
checkNotNull(eth, REQUEST_NULL);
checkArgument(eth.getEtherType() == Ethernet.TYPE_ARP,
REQUEST_NOT_ARP);
ARP arp = (ARP) eth.getPayload();
checkArgument(arp.getOpCode() == ARP.OP_REQUEST, NOT_ARP_REQUEST);
+ checkNotNull(inPort);
+
+ // If the source address matches one of our external addresses
+ // it could be a request from an internal host to an external
+ // address. Forward it over to the correct port.
+ IpAddress source = IpAddress.valueOf(arp.getSenderProtocolAddress());
+ PortAddresses sourceAddresses = findOutsidePortInSubnet(source);
+ if (sourceAddresses != null && !isOutsidePort(inPort)) {
+ for (IpPrefix subnet : sourceAddresses.ips()) {
+ if (subnet.toIpAddress().equals(source)) {
+ sendTo(eth, sourceAddresses.connectPoint());
+ return;
+ }
+ }
+ }
+
+ // If the request came from outside the network, only reply if it was
+ // for one of our external addresses.
+ if (isOutsidePort(inPort)) {
+ IpAddress target = IpAddress.valueOf(arp.getTargetProtocolAddress());
+ PortAddresses addresses = hostService.getAddressBindingsForPort(inPort);
+
+ for (IpPrefix interfaceAddress : addresses.ips()) {
+ if (interfaceAddress.toIpAddress().equals(target)) {
+ Ethernet arpReply = buildArpReply(interfaceAddress,
+ addresses.mac(), eth);
+ sendTo(arpReply, inPort);
+ }
+ }
+
+ return;
+ }
+
+ // Continue with normal proxy ARP case
VlanId vlan = VlanId.vlanId(eth.getVlanID());
Set<Host> hosts = hostService.getHostsByIp(IpPrefix.valueOf(arp
@@ -128,12 +167,62 @@
return;
}
- Ethernet arpReply = buildArpReply(dst, eth);
+ Ethernet arpReply = buildArpReply(dst.ipAddresses().iterator().next(),
+ dst.mac(), eth);
// TODO: check send status with host service.
+ sendTo(arpReply, src.location());
+ }
+
+ /**
+ * Outputs the given packet out the given port.
+ *
+ * @param packet the packet to send
+ * @param outPort the port to send it out
+ */
+ private void sendTo(Ethernet packet, ConnectPoint outPort) {
+ if (internalPorts.containsEntry(
+ deviceService.getDevice(outPort.deviceId()), outPort.port())) {
+ // Sanity check to make sure we don't send the packet out an
+ // internal port and create a loop (could happen due to
+ // misconfiguration).
+ return;
+ }
+
TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
- builder.setOutput(src.location().port());
- packetService.emit(new DefaultOutboundPacket(src.location().deviceId(),
- builder.build(), ByteBuffer.wrap(arpReply.serialize())));
+ builder.setOutput(outPort.port());
+ packetService.emit(new DefaultOutboundPacket(outPort.deviceId(),
+ builder.build(), ByteBuffer.wrap(packet.serialize())));
+ }
+
+ /**
+ * Finds the port with an address in the subnet of the target address, if
+ * one exists.
+ *
+ * @param target the target address to find a matching external port for
+ * @return a PortAddresses object containing the external addresses if one
+ * was found, otherwise null.
+ */
+ private PortAddresses findOutsidePortInSubnet(IpAddress target) {
+ for (PortAddresses addresses : hostService.getAddressBindings()) {
+ for (IpPrefix prefix : addresses.ips()) {
+ if (prefix.contains(target)) {
+ return new PortAddresses(addresses.connectPoint(),
+ Collections.singleton(prefix), addresses.mac());
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether the given port is an outside-facing port with an IP
+ * address configured.
+ *
+ * @param port the port to check
+ * @return true if the port is an outside-facing port, otherwise false
+ */
+ private boolean isOutsidePort(ConnectPoint port) {
+ return !hostService.getAddressBindingsForPort(port).ips().isEmpty();
}
@Override
@@ -167,7 +256,7 @@
if (arp.getOpCode() == ARP.OP_REPLY) {
forward(ethPkt);
} else if (arp.getOpCode() == ARP.OP_REQUEST) {
- reply(ethPkt);
+ reply(ethPkt, context.inPacket().receivedFrom());
}
context.block();
return true;
@@ -185,12 +274,16 @@
synchronized (externalPorts) {
for (Entry<Device, PortNumber> entry : externalPorts.entries()) {
+ ConnectPoint cp = new ConnectPoint(entry.getKey().id(), entry.getValue());
+ if (isOutsidePort(cp)) {
+ continue;
+ }
+
builder = DefaultTrafficTreatment.builder();
builder.setOutput(entry.getValue());
packetService.emit(new DefaultOutboundPacket(entry.getKey().id(),
builder.build(), buf));
}
-
}
}
@@ -234,15 +327,19 @@
}
/**
- * Builds an arp reply based on a request.
- * @param h the host we want to send to
- * @param request the arp request we got
- * @return an ethernet frame containing the arp reply
+ * Builds an ARP reply based on a request.
+ *
+ * @param srcIp the IP address to use as the reply source
+ * @param srcMac the MAC address to use as the reply source
+ * @param request the ARP request we got
+ * @return an Ethernet frame containing the ARP reply
*/
- private Ethernet buildArpReply(Host h, Ethernet request) {
+ private Ethernet buildArpReply(IpPrefix srcIp, MacAddress srcMac,
+ Ethernet request) {
+
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(request.getSourceMACAddress());
- eth.setSourceMACAddress(h.mac().getAddress());
+ eth.setSourceMACAddress(srcMac.getAddress());
eth.setEtherType(Ethernet.TYPE_ARP);
eth.setVlanID(request.getVlanID());
@@ -253,12 +350,12 @@
arp.setProtocolAddressLength((byte) IpPrefix.INET_LEN);
arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
- arp.setSenderHardwareAddress(h.mac().getAddress());
+ arp.setSenderHardwareAddress(srcMac.getAddress());
arp.setTargetHardwareAddress(request.getSourceMACAddress());
arp.setTargetProtocolAddress(((ARP) request.getPayload())
.getSenderProtocolAddress());
- arp.setSenderProtocolAddress(h.ipAddresses().iterator().next().toRealInt());
+ arp.setSenderProtocolAddress(srcIp.toRealInt());
eth.setPayload(arp);
return eth;
}
diff --git a/core/net/src/test/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManagerTest.java b/core/net/src/test/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManagerTest.java
index ddd4827..fa68761 100644
--- a/core/net/src/test/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManagerTest.java
+++ b/core/net/src/test/java/org/onlab/onos/net/proxyarp/impl/ProxyArpManagerTest.java
@@ -13,6 +13,7 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.Set;
import org.junit.Before;
import org.junit.Test;
@@ -31,6 +32,7 @@
import org.onlab.onos.net.flow.instructions.Instruction;
import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
import org.onlab.onos.net.host.HostService;
+import org.onlab.onos.net.host.PortAddresses;
import org.onlab.onos.net.link.LinkListener;
import org.onlab.onos.net.link.LinkService;
import org.onlab.onos.net.packet.OutboundPacket;
@@ -50,12 +52,13 @@
*/
public class ProxyArpManagerTest {
- private static final int NUM_DEVICES = 4;
+ private static final int NUM_DEVICES = 6;
private static final int NUM_PORTS_PER_DEVICE = 3;
- private static final int NUM_FLOOD_PORTS = 4;
+ private static final int NUM_ADDRESS_PORTS = NUM_DEVICES / 2;
+ private static final int NUM_FLOOD_PORTS = 3;
- private static final IpPrefix IP1 = IpPrefix.valueOf("10.0.0.1/24");
- private static final IpPrefix IP2 = IpPrefix.valueOf("10.0.0.2/24");
+ private static final IpPrefix IP1 = IpPrefix.valueOf("192.168.1.1/24");
+ private static final IpPrefix IP2 = IpPrefix.valueOf("192.168.1.2/24");
private static final ProviderId PID = new ProviderId("of", "foo");
@@ -104,6 +107,9 @@
* The default topology is a unidirectional ring topology. Each switch has
* 3 ports. Ports 2 and 3 have the links to neighbor switches, and port 1
* is free (edge port).
+ * The first half of the switches have IP addresses configured on their
+ * free ports (port 1). The second half of the switches have no IP
+ * addresses configured.
*/
private void createTopology() {
deviceService = createMock(DeviceService.class);
@@ -114,6 +120,7 @@
createDevices(NUM_DEVICES, NUM_PORTS_PER_DEVICE);
createLinks(NUM_DEVICES);
+ addAddressBindings();
}
/**
@@ -138,10 +145,11 @@
ports.add(port);
}
- expect(deviceService.getPorts(devId)).andReturn(ports);
+ expect(deviceService.getPorts(devId)).andReturn(ports).anyTimes();
+ expect(deviceService.getDevice(devId)).andReturn(device).anyTimes();
}
- expect(deviceService.getDevices()).andReturn(devices);
+ expect(deviceService.getDevices()).andReturn(devices).anyTimes();
replay(deviceService);
}
@@ -173,6 +181,31 @@
replay(linkService);
}
+ private void addAddressBindings() {
+ Set<PortAddresses> addresses = Sets.newHashSet();
+
+ for (int i = 1; i <= NUM_ADDRESS_PORTS; i++) {
+ ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1);
+ IpPrefix prefix1 = IpPrefix.valueOf("10.0." + (2 * i - 1) + ".1/24");
+ IpPrefix prefix2 = IpPrefix.valueOf("10.0." + (2 * i) + ".1/24");
+ PortAddresses pa = new PortAddresses(cp,
+ Sets.newHashSet(prefix1, prefix2), MacAddress.valueOf(i));
+ addresses.add(pa);
+
+ expect(hostService.getAddressBindingsForPort(cp))
+ .andReturn(pa).anyTimes();
+ }
+
+ expect(hostService.getAddressBindings()).andReturn(addresses).anyTimes();
+
+ for (int i = 1; i <= NUM_FLOOD_PORTS; i++) {
+ ConnectPoint cp = new ConnectPoint(getDeviceId(i + NUM_ADDRESS_PORTS),
+ P1);
+ expect(hostService.getAddressBindingsForPort(cp))
+ .andReturn(new PortAddresses(cp, null, null)).anyTimes();
+ }
+ }
+
/**
* Tests {@link ProxyArpManager#known(IpPrefix)} in the case where the
* IP address is not known.
@@ -210,10 +243,10 @@
*/
@Test
public void testReplyKnown() {
- Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN1, LOC2,
+ Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(4),
Collections.singleton(IP1));
- Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1,
+ Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5),
Collections.singleton(IP2));
expect(hostService.getHostsByIp(IpPrefix.valueOf(IP1.toOctets())))
@@ -224,11 +257,11 @@
Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1);
- proxyArp.reply(arpRequest);
+ proxyArp.reply(arpRequest, getLocation(5));
assertEquals(1, packetService.packets.size());
Ethernet arpReply = buildArp(ARP.OP_REPLY, MAC1, MAC2, IP1, IP2);
- verifyPacketOut(arpReply, LOC1, packetService.packets.get(0));
+ verifyPacketOut(arpReply, getLocation(5), packetService.packets.get(0));
}
/**
@@ -238,7 +271,7 @@
*/
@Test
public void testReplyUnknown() {
- Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1,
+ Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5),
Collections.singleton(IP2));
expect(hostService.getHostsByIp(IpPrefix.valueOf(IP1.toOctets())))
@@ -249,7 +282,7 @@
Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1);
- proxyArp.reply(arpRequest);
+ proxyArp.reply(arpRequest, getLocation(5));
verifyFlood(arpRequest);
}
@@ -262,10 +295,10 @@
*/
@Test
public void testReplyDifferentVlan() {
- Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN2, LOC2,
+ Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN2, getLocation(4),
Collections.singleton(IP1));
- Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1,
+ Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5),
Collections.singleton(IP2));
expect(hostService.getHostsByIp(IpPrefix.valueOf(IP1.toOctets())))
@@ -276,11 +309,84 @@
Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1);
- proxyArp.reply(arpRequest);
+ proxyArp.reply(arpRequest, getLocation(5));
verifyFlood(arpRequest);
}
+ @Test
+ public void testReplyToRequestForUs() {
+ IpPrefix theirIp = IpPrefix.valueOf("10.0.1.254/24");
+ IpPrefix ourFirstIp = IpPrefix.valueOf("10.0.1.1/24");
+ IpPrefix ourSecondIp = IpPrefix.valueOf("10.0.2.1/24");
+ MacAddress ourMac = MacAddress.valueOf(1L);
+
+ Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1,
+ Collections.singleton(theirIp));
+
+ expect(hostService.getHost(HID2)).andReturn(requestor);
+ replay(hostService);
+
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, theirIp, ourFirstIp);
+
+ proxyArp.reply(arpRequest, LOC1);
+
+ assertEquals(1, packetService.packets.size());
+ Ethernet arpReply = buildArp(ARP.OP_REPLY, ourMac, MAC2, ourFirstIp, theirIp);
+ verifyPacketOut(arpReply, LOC1, packetService.packets.get(0));
+
+ // Test a request for the second address on that port
+ packetService.packets.clear();
+ arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, theirIp, ourSecondIp);
+
+ proxyArp.reply(arpRequest, LOC1);
+
+ assertEquals(1, packetService.packets.size());
+ arpReply = buildArp(ARP.OP_REPLY, ourMac, MAC2, ourSecondIp, theirIp);
+ verifyPacketOut(arpReply, LOC1, packetService.packets.get(0));
+ }
+
+ @Test
+ public void testReplyExternalPortBadRequest() {
+ replay(hostService); // no further host service expectations
+
+ IpPrefix theirIp = IpPrefix.valueOf("10.0.1.254/24");
+
+ // Request for a valid external IP address but coming in the wrong port
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC1, null, theirIp,
+ IpPrefix.valueOf("10.0.3.1"));
+ proxyArp.reply(arpRequest, LOC1);
+ assertEquals(0, packetService.packets.size());
+
+ // Request for a valid internal IP address but coming in an external port
+ packetService.packets.clear();
+ arpRequest = buildArp(ARP.OP_REQUEST, MAC1, null, theirIp, IP1);
+ proxyArp.reply(arpRequest, LOC1);
+ assertEquals(0, packetService.packets.size());
+ }
+
+ @Test
+ public void testReplyToRequestFromUs() {
+ replay(hostService); // no further host service expectations
+
+ IpPrefix ourIp = IpPrefix.valueOf("10.0.1.1/24");
+ MacAddress ourMac = MacAddress.valueOf(1L);
+ IpPrefix theirIp = IpPrefix.valueOf("10.0.1.100/24");
+
+ // This is a request from something inside our network (like a BGP
+ // daemon) to an external host.
+ Ethernet arpRequest = buildArp(ARP.OP_REQUEST, ourMac, null, ourIp, theirIp);
+ proxyArp.reply(arpRequest, getLocation(5));
+
+ assertEquals(1, packetService.packets.size());
+ verifyPacketOut(arpRequest, getLocation(1), packetService.packets.get(0));
+
+ // The same request from a random external port should fail
+ packetService.packets.clear();
+ proxyArp.reply(arpRequest, getLocation(2));
+ assertEquals(0, packetService.packets.size());
+ }
+
/**
* Tests {@link ProxyArpManager#forward(Ethernet)} in the case where the
* destination host is known.
@@ -338,7 +444,8 @@
});
for (int i = 0; i < NUM_FLOOD_PORTS; i++) {
- ConnectPoint cp = new ConnectPoint(getDeviceId(i + 1), PortNumber.portNumber(1));
+ ConnectPoint cp = new ConnectPoint(getDeviceId(NUM_ADDRESS_PORTS + i + 1),
+ PortNumber.portNumber(1));
OutboundPacket outboundPacket = packetService.packets.get(i);
verifyPacketOut(packet, cp, outboundPacket);
@@ -372,6 +479,10 @@
return DeviceId.deviceId("" + i);
}
+ private static HostLocation getLocation(int i) {
+ return new HostLocation(new ConnectPoint(getDeviceId(i), P1), 123L);
+ }
+
/**
* Builds an ARP packet with the given parameters.
*
diff --git a/utils/misc/src/test/java/org/onlab/packet/IpPrefixTest.java b/utils/misc/src/test/java/org/onlab/packet/IpPrefixTest.java
index 297a0f3..5f2bd52 100644
--- a/utils/misc/src/test/java/org/onlab/packet/IpPrefixTest.java
+++ b/utils/misc/src/test/java/org/onlab/packet/IpPrefixTest.java
@@ -108,5 +108,10 @@
IpAddress addr = IpAddress.valueOf("192.168.10.1");
assertTrue(intf.contains(addr));
+
+ IpPrefix intf1 = IpPrefix.valueOf("10.0.0.101/24");
+ IpAddress addr1 = IpAddress.valueOf("10.0.0.4");
+
+ assertTrue(intf1.contains(addr1));
}
}