Merge pull request #424 from jonohart/master
Code cleanup of SDNIP and ARP code
diff --git a/src/main/java/net/floodlightcontroller/packet/IPv4.java b/src/main/java/net/floodlightcontroller/packet/IPv4.java
index 01f886d..85f21ca 100644
--- a/src/main/java/net/floodlightcontroller/packet/IPv4.java
+++ b/src/main/java/net/floodlightcontroller/packet/IPv4.java
@@ -31,6 +31,7 @@
*
*/
public class IPv4 extends BasePacket {
+ public static final int ADDRESS_LENGTH = 4;
public static final byte PROTOCOL_ICMP = 0x1;
public static final byte PROTOCOL_TCP = 0x6;
public static final byte PROTOCOL_UDP = 0x11;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpPeer.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpPeer.java
index e98c3e8..fa11c17 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpPeer.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpPeer.java
@@ -7,24 +7,20 @@
import com.google.common.net.InetAddresses;
public class BgpPeer {
- private String interfaceName;
- private InetAddress ipAddress;
+ private final String interfaceName;
+ private final InetAddress ipAddress;
+
+ public BgpPeer(@JsonProperty("interface") String interfaceName,
+ @JsonProperty("ipAddress") String ipAddress) {
+ this.interfaceName = interfaceName;
+ this.ipAddress = InetAddresses.forString(ipAddress);
+ }
public String getInterfaceName() {
return interfaceName;
}
-
- @JsonProperty("interface")
- public void setInterfaceName(String interfaceName) {
- this.interfaceName = interfaceName;
- }
-
+
public InetAddress getIpAddress() {
return ipAddress;
}
-
- @JsonProperty("ipAddress")
- public void setIpAddress(String ipAddress) {
- this.ipAddress = InetAddresses.forString(ipAddress);
- }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index 9e7bf61..960d001 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -76,7 +76,7 @@
public class BgpRoute implements IFloodlightModule, IBgpRouteService,
ITopologyListener, IArpRequester,
- IOFSwitchListener {
+ IOFSwitchListener, ILayer3InfoService {
protected static Logger log = LoggerFactory.getLogger(BgpRoute.class);
@@ -158,7 +158,6 @@
ldu.getDst(), ldu.getDstPort());
if (activeLinks.contains(l)){
- log.debug("Not found: {}", l);
it.remove();
}
}
@@ -263,7 +262,7 @@
//TODO We'll initialise this here for now, but it should really be done as
//part of the controller core
- proxyArp = new ProxyArpManager(floodlightProvider, topology);
+ proxyArp = new ProxyArpManager(floodlightProvider, topology, this);
linkUpdates = new ArrayList<LDUpdate>();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
@@ -308,8 +307,6 @@
log.debug("Config file set to {}", configFilename);
readGatewaysConfiguration(configFilename);
-
- proxyArp.setL3Mode(interfacePtrie, interfaces.values(), bgpdMacAddress);
}
@Override
@@ -466,7 +463,7 @@
Path path = pushedPaths.get(dstIpAddress);
if (path == null) {
path = new Path(egressInterface, dstIpAddress);
- setUpDataPath(path, MACAddress.valueOf(nextHopMacAddress));
+ calculateAndPushPath(path, MACAddress.valueOf(nextHopMacAddress));
pushedPaths.put(dstIpAddress, path);
}
@@ -493,14 +490,7 @@
}
//Add a flow to rewrite mac for this prefix to all other border switches
- //for (Interface srcInterface : interfaces.values()) {
for (Interface srcInterface : srcInterfaces.values()) {
- //if (srcInterface == egressInterface) {
- //Don't push a flow for the switch where this peer is attached
- //continue;
- //}
-
-
DataPath shortestPath;
if (topoRouteTopology == null) {
shortestPath = topoRouteService.getShortestPath(
@@ -572,7 +562,12 @@
try {
sw.write(msglist, null);
sw.flush();
- //Thread.sleep(0, 100000);
+
+ /*
+ * XXX Rate limit hack!
+ * This should be solved properly by adding a rate limiting
+ * layer on top of the switches if we know they need it.
+ */
Thread.sleep(1);
} catch (IOException e) {
log.error("Failure writing flow mod", e);
@@ -603,7 +598,6 @@
if (!bgpPeers.containsKey(ribEntry.getNextHop())) {
log.debug("Getting path for route with non-peer nexthop");
- //Path path = prefixToPath.get(prefix);
Path path = prefixToPath.remove(prefix);
if (path != null) {
@@ -611,7 +605,6 @@
//flows yet because we were waiting to resolve ARP
path.decrementUsers();
- log.debug("users {}, permanent {}", path.getUsers(), path.isPermanent());
if (path.getUsers() <= 0 && !path.isPermanent()) {
deletePath(path);
pushedPaths.remove(path.getDstIpAddress());
@@ -620,28 +613,37 @@
}
}
- private void deletePrefixFlows(Prefix prefix) {
+ private void deletePrefixFlows(Prefix prefix) {
+ log.debug("Deleting flows for prefix {}", prefix);
+
Collection<PushedFlowMod> pushedFlowMods
= pushedFlows.removeAll(prefix);
for (PushedFlowMod pfm : pushedFlowMods) {
- log.debug("Pushing a DELETE flow mod to {}, matches prefix {} with mac-rewrite {}",
- new Object[] {HexString.toHexString(pfm.getDpid()),
- pfm.getFlowMod().getMatch().getNetworkDestination() +
- pfm.getFlowMod().getMatch().getNetworkDestinationMaskLen(),
- HexString.toHexString(((OFActionDataLayerDestination)pfm.getFlowMod().getActions().get(0))
- .getDataLayerAddress())});
+ if (log.isTraceEnabled()) {
+ log.trace("Pushing a DELETE flow mod to {}, matches prefix {} with mac-rewrite {}",
+ new Object[] {HexString.toHexString(pfm.getDpid()),
+ pfm.getFlowMod().getMatch().getNetworkDestination() +
+ pfm.getFlowMod().getMatch().getNetworkDestinationMaskLen(),
+ HexString.toHexString(((OFActionDataLayerDestination)pfm.getFlowMod().getActions().get(0))
+ .getDataLayerAddress())});
+ }
sendDeleteFlowMod(pfm.getFlowMod(), pfm.getDpid());
}
}
private void deletePath(Path path) {
+ log.debug("Deleting flows for path to {}",
+ path.getDstIpAddress().getHostAddress());
+
for (PushedFlowMod pfm : path.getFlowMods()) {
- log.debug("Pushing a DELETE flow mod to {}, dst MAC {}",
- new Object[] {HexString.toHexString(pfm.getDpid()),
- HexString.toHexString(pfm.getFlowMod().getMatch().getDataLayerDestination())
- });
+ if (log.isTraceEnabled()) {
+ log.trace("Pushing a DELETE flow mod to {}, dst MAC {}",
+ new Object[] {HexString.toHexString(pfm.getDpid()),
+ HexString.toHexString(pfm.getFlowMod().getMatch().getDataLayerDestination())
+ });
+ }
sendDeleteFlowMod(pfm.getFlowMod(), pfm.getDpid());
}
@@ -703,14 +705,10 @@
}
//If we know the MAC, lets go ahead and push the paths to this peer
- setUpDataPath(path, MACAddress.valueOf(mac));
+ calculateAndPushPath(path, MACAddress.valueOf(mac));
}
}
- private void setUpDataPath(Path path, MACAddress dstMacAddress) {
- calculateAndPushPath(path, dstMacAddress);
- }
-
private void calculateAndPushPath(Path path, MACAddress dstMacAddress) {
Interface dstInterface = path.getDstInterface();
@@ -726,20 +724,18 @@
DataPath shortestPath;
if (topoRouteTopology == null) {
- log.debug("Using database topo");
shortestPath = topoRouteService.getShortestPath(
srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
}
else {
- log.debug("Using prepared topo");
shortestPath = topoRouteService.getTopoShortestPath(topoRouteTopology,
srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
}
if (shortestPath == null){
- log.debug("Shortest path between {} and {} not found",
+ log.warn("Shortest path between {} and {} not found",
srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
- return; // just quit here?
+ return;
}
pushedFlows.addAll(installPath(shortestPath.flowEntries(), dstMacAddress));
@@ -766,6 +762,7 @@
.setBufferId(OFPacketOut.BUFFER_ID_NONE)
.setCookie(L2_FWD_COOKIE)
.setCommand(OFFlowMod.OFPFC_ADD)
+ .setPriority(SDNIP_PRIORITY)
.setActions(actions)
.setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
@@ -989,7 +986,7 @@
}
}
else {
- setUpDataPath(path, MACAddress.valueOf(macAddress));
+ calculateAndPushPath(path, MACAddress.valueOf(macAddress));
pushedPaths.put(path.getDstIpAddress(), path);
}
}
@@ -1057,7 +1054,7 @@
private void setupDefaultDropFlows() {
OFFlowMod fm = new OFFlowMod();
fm.setMatch(new OFMatch());
- //No action means drop
+ fm.setActions(new ArrayList<OFAction>()); //No action means drop
fm.setIdleTimeout((short)0)
.setHardTimeout((short)0)
@@ -1067,14 +1064,52 @@
.setPriority((short)0)
.setLengthU(OFFlowMod.MINIMUM_LENGTH);
+ OFFlowMod fmLLDP;
+ OFFlowMod fmBDDP;
+ try {
+ fmLLDP = fm.clone();
+ fmBDDP = fm.clone();
+ } catch (CloneNotSupportedException e1) {
+ log.error("Error cloning flow mod", e1);
+ return;
+ }
+
+ OFMatch matchLLDP = new OFMatch();
+ matchLLDP.setDataLayerType((short)0x8942);
+ matchLLDP.setWildcards(matchLLDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
+ fmLLDP.setMatch(matchLLDP);
+
+ OFMatch matchBDDP = new OFMatch();
+ matchBDDP.setDataLayerType((short)0x88cc);
+ matchBDDP.setWildcards(matchBDDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
+ fmBDDP.setMatch(matchBDDP);
+
+ OFActionOutput action = new OFActionOutput();
+ action.setPort(OFPort.OFPP_CONTROLLER.getValue());
+ action.setMaxLength((short)0xffff);
+ List<OFAction> actions = new ArrayList<OFAction>(1);
+ actions.add(action);
+
+ fmLLDP.setActions(actions);
+ fmBDDP.setActions(actions);
+
+ fmLLDP.setPriority(ARP_PRIORITY);
+ fmLLDP.setLengthU(OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);
+ fmBDDP.setPriority(ARP_PRIORITY);
+ fmBDDP.setLengthU(OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);
+
for (String strdpid : switches){
IOFSwitch sw = floodlightProvider.getSwitches().get(HexString.toLong(strdpid));
if (sw == null) {
log.debug("Couldn't find switch to push default deny flow");
}
else {
+ List<OFMessage> msgList = new ArrayList<OFMessage>();
+ msgList.add(fm);
+ msgList.add(fmLLDP);
+ msgList.add(fmBDDP);
try {
- sw.write(fm, null);
+ sw.write(msgList, null);
} catch (IOException e) {
log.warn("Failure writing default deny flow to switch", e);
}
@@ -1214,20 +1249,54 @@
}
@Override
- public void removedSwitch(IOFSwitch sw) {
- // TODO Auto-generated method stub
-
- }
+ public void removedSwitch(IOFSwitch sw) {}
@Override
- public void switchPortChanged(Long switchId) {
- // TODO Auto-generated method stub
-
- }
+ public void switchPortChanged(Long switchId) {}
@Override
public String getName() {
- // TODO Auto-generated method stub
- return null;
+ return "BgpRoute";
+ }
+
+ /*
+ * ILayer3InfoService methods
+ */
+
+ @Override
+ public boolean isInterfaceAddress(InetAddress address) {
+ Interface intf = interfacePtrie.match(new Prefix(address.getAddress(), 32));
+ return (intf != null && intf.getIpAddress().equals(address));
+ }
+
+ @Override
+ public boolean inConnectedNetwork(InetAddress address) {
+ Interface intf = interfacePtrie.match(new Prefix(address.getAddress(), 32));
+ return (intf != null && !intf.getIpAddress().equals(address));
+ }
+
+ @Override
+ public boolean fromExternalNetwork(long inDpid, short inPort) {
+ for (Interface intf : interfaces.values()) {
+ if (intf.getDpid() == inDpid && intf.getPort() == inPort) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Interface getOutgoingInterface(InetAddress dstIpAddress) {
+ return interfacePtrie.match(new Prefix(dstIpAddress.getAddress(), 32));
+ }
+
+ @Override
+ public boolean hasLayer3Configuration() {
+ return !interfaces.isEmpty();
+ }
+
+ @Override
+ public MACAddress getRouterMacAddress() {
+ return bgpdMacAddress;
}
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
index f058843..8403f71 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRouteResource.java
@@ -15,20 +15,6 @@
protected static Logger log = LoggerFactory.getLogger(BgpRouteResource.class);
- private String addrToString(byte [] addr) {
- String str = "";
-
- for (int i = 0; i < 4; i++) {
- int val = (addr[i] & 0xff);
- str += val;
- if (i != 3)
- str += ".";
- }
-
- return str;
- }
-
- //@SuppressWarnings("unused")
@Get
public String get(String fmJson) {
String dest = (String) getRequestAttributes().get("dest");
@@ -38,45 +24,23 @@
if (dest != null) {
//TODO Needs to be changed to use the new RestClient.get().
-
-
- //Prefix p;
- //try {
- // p = new Prefix(dest, 32);
- //} catch (UnknownHostException e) {
- //if (p == null) {
- // return "[GET]: dest address format is wrong";
- //}
// the dest here refers to router-id
//bgpdRestIp includes port number, such as 1.1.1.1:8080
String BGPdRestIp = bgpRoute.getBGPdRestIp();
String url="http://"+BGPdRestIp+"/wm/bgp/"+dest;
- RestClient.get(url);
+ //Doesn't actually do anything with the response
+ RestClient.get(url);
output="Get rib from bgpd finished!\n";
return output;
}
else {
- //Ptree ptree = bgpRoute.getPtree();
IPatriciaTrie<RibEntry> ptree = bgpRoute.getPtree();
output += "{\n \"rib\": [\n";
boolean printed = false;
- /*
- for (PtreeNode node = ptree.begin(); node!= null; node = ptree.next(node)) {
- if (node.rib == null) {
- continue;
- }
- if (printed == true) {
- output += ",\n";
- }
- output += " {\"prefix\": \"" + addrToString(node.key) + "/" + node.keyBits +"\", ";
- output += "\"nexthop\": \"" + addrToString(node.rib.nextHop.getAddress()) +"\"}";
- printed = true;
- }*/
-
synchronized(ptree) {
Iterator<IPatriciaTrie.Entry<RibEntry>> it = ptree.iterator();
while (it.hasNext()) {
@@ -88,42 +52,22 @@
output += " {\"prefix\": \"" + entry.getPrefix() +"\", ";
output += "\"nexthop\": \"" + entry.getValue().getNextHop().getHostAddress() +"\"}";
- //output += ",\n";
printed = true;
}
}
- //output += "{\"router_id\": \"" + addrToString(node.rib.routerId.getAddress()) +"\"}\n";
output += "\n ]\n}\n";
}
return output;
}
- //unused?
- /*
- public static ByteBuffer toByteBuffer(String value) throws UnsupportedEncodingException {
- return ByteBuffer.wrap(value.getBytes("UTF-8"));
- }
- */
-
- //unused?
- /*
- public static String toString(ByteBuffer buffer) throws UnsupportedEncodingException {
- byte[] bytes = new byte[buffer.remaining()];
- buffer.get(bytes);
- return new String(bytes, "UTF-8");
- }
- */
-
@Post
public String store(String fmJson) {
IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
get(IBgpRouteService.class.getCanonicalName());
- //Ptree ptree = bgpRoute.getPtree();
-
String routerId = (String) getRequestAttributes().get("routerid");
String prefix = (String) getRequestAttributes().get("prefix");
String mask = (String) getRequestAttributes().get("mask");
@@ -151,18 +95,6 @@
bgpRoute.newRibUpdate(new RibUpdate(Operation.UPDATE, p, rib));
- /*
- PtreeNode node = ptree.acquire(p.getAddress(), p.getPrefixLength());
-
- if (node.rib != null) {
- node.rib = null;
- ptree.delReference(node);
- }
- node.rib = rib;
-
- bgpRoute.prefixAdded(node);
- */
-
reply = "[POST: " + prefix + "/" + mask + ":" + nexthop + "]";
log.info(reply);
}
@@ -185,8 +117,6 @@
IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
get(IBgpRouteService.class.getCanonicalName());
- //Ptree ptree = bgpRoute.getPtree();
-
String routerId = (String) getRequestAttributes().get("routerid");
String prefix = (String) getRequestAttributes().get("prefix");
String mask = (String) getRequestAttributes().get("mask");
@@ -214,29 +144,6 @@
bgpRoute.newRibUpdate(new RibUpdate(Operation.DELETE, p, r));
- /*
- PtreeNode node = ptree.lookup(p.getAddress(), p.getPrefixLength());
-
- //Remove the flows from the switches before the rib is lost
- //Theory: we could get a delete for a prefix not in the Ptree.
- //This would result in a null node being returned. We could get a delete for
- //a node that's not actually there, but is a aggregate node. This would result
- //in a non-null node with a null rib. Only a non-null node with a non-null
- //rib is an actual prefix in the Ptree.
- if (node != null && node.rib != null){
- bgpRoute.prefixDeleted(node);
- }
-
-
-
- if (node != null && node.rib != null) {
- if (r.equals(node.rib)) {
- node.rib = null;
- ptree.delReference(node);
- }
- }
- */
-
reply =reply + "[DELE: " + prefix + "/" + mask + ":" + nextHop + "]";
}
else {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/GatewayRouter.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/GatewayRouter.java
deleted file mode 100644
index e893acf..0000000
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/GatewayRouter.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package net.onrc.onos.ofcontroller.bgproute;
-
-import net.floodlightcontroller.util.MACAddress;
-import net.onrc.onos.ofcontroller.util.Dpid;
-import net.onrc.onos.ofcontroller.util.IPv4;
-import net.onrc.onos.ofcontroller.util.Port;
-import net.onrc.onos.ofcontroller.util.SwitchPort;
-
-import org.codehaus.jackson.annotate.JsonProperty;
-import org.openflow.util.HexString;
-
-public class GatewayRouter {
- private SwitchPort attachmentPoint = null;
- private long dpid;
- private short port;
- private MACAddress routerMac;
- private IPv4 routerIp;
- private IPv4 myIpAddress;
-
-
- public SwitchPort getAttachmentPoint() {
- if (attachmentPoint == null){
- attachmentPoint = new SwitchPort(new Dpid(dpid), new Port(port));
- }
- return attachmentPoint;
- }
-
- public long getDpid() {
- return dpid;
- }
-
- @JsonProperty("attachmentDpid")
- public void setDpid(String dpid) {
- this.dpid = HexString.toLong(dpid);
- }
-
- public short getPort() {
- return port;
- }
-
- @JsonProperty("attachmentPort")
- public void setPort(short port) {
- this.port = port;
- }
-
- public MACAddress getRouterMac() {
- return routerMac;
- }
-
- @JsonProperty("macAddress")
- public void setRouterMac(String routerMac) {
- this.routerMac = MACAddress.valueOf(routerMac);;
- }
-
- public IPv4 getRouterIp() {
- return routerIp;
- }
-
- @JsonProperty("ipAddress")
- public void setRouterIp(String routerIp) {
- this.routerIp = new IPv4(routerIp);
- }
-
- public IPv4 getMyIpAddress() {
- return myIpAddress;
- }
-
- @JsonProperty("myIpAddress")
- public void setMyIpAddress(String myIpAddress) {
- this.myIpAddress = new IPv4(myIpAddress);
- }
-}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/ILayer3InfoService.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/ILayer3InfoService.java
new file mode 100644
index 0000000..00ddd68
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/ILayer3InfoService.java
@@ -0,0 +1,35 @@
+package net.onrc.onos.ofcontroller.bgproute;
+
+import java.net.InetAddress;
+
+import net.floodlightcontroller.util.MACAddress;
+
+/**
+ * Provides information about the layer 3 properties of the network.
+ * This is based on IP addresses configured on ports in the network.
+ *
+ */
+public interface ILayer3InfoService {
+ public boolean isInterfaceAddress(InetAddress address);
+ public boolean inConnectedNetwork(InetAddress address);
+ public boolean fromExternalNetwork(long inDpid, short inPort);
+
+ /**
+ * Retrieves the {@link Interface} object for the interface that packets
+ * to dstIpAddress will be sent out of. Returns null if dstIpAddress is not
+ * in a directly connected network, or if no interfaces are configured.
+ * @param dstIpAddress Destination IP address that we want to match to
+ * an outgoing interface
+ * @return The {@link Interface} object if found, null if not
+ */
+ public Interface getOutgoingInterface(InetAddress dstIpAddress);
+
+ /**
+ * Returns whether this controller has a layer 3 configuration
+ * (i.e. interfaces and IP addresses)
+ * @return True if IP addresses are configured, false if not
+ */
+ public boolean hasLayer3Configuration();
+
+ public MACAddress getRouterMacAddress();
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java
index 088c18e..48b60d8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Interface.java
@@ -6,68 +6,57 @@
import net.onrc.onos.ofcontroller.util.Port;
import net.onrc.onos.ofcontroller.util.SwitchPort;
+import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
import org.openflow.util.HexString;
import com.google.common.net.InetAddresses;
public class Interface {
- private String name;
- private SwitchPort switchPort = null;
- private long dpid;
- private short port;
- private InetAddress ipAddress;
- private int prefixLength;
+ private final String name;
+ private final SwitchPort switchPort;
+ private final long dpid;
+ private final short port;
+ private final InetAddress ipAddress;
+ private final int prefixLength;
+
+ @JsonCreator
+ public Interface (@JsonProperty("name") String name,
+ @JsonProperty("dpid") String dpid,
+ @JsonProperty("port") short port,
+ @JsonProperty("ipAddress") String ipAddress,
+ @JsonProperty("prefixLength") int prefixLength) {
+ this.name = name;
+ this.dpid = HexString.toLong(dpid);
+ this.port = port;
+ this.ipAddress = InetAddresses.forString(ipAddress);
+ this.prefixLength = prefixLength;
+ this.switchPort = new SwitchPort(new Dpid(this.dpid), new Port(this.port));
+ }
public String getName() {
return name;
}
- @JsonProperty("name")
- public void setName(String name) {
- this.name = name;
- }
-
- public synchronized SwitchPort getSwitchPort() {
- if (switchPort == null){
- switchPort = new SwitchPort(new Dpid(dpid), new Port(port));
- }
- return switchPort;
+ public SwitchPort getSwitchPort() {
+ //TODO SwitchPort, Dpid and Port are mutable, but they could probably
+ //be made immutable which would prevent the need to copy
+ return new SwitchPort(new Dpid(dpid), new Port(port));
}
public long getDpid() {
return dpid;
}
- @JsonProperty("dpid")
- public void setDpid(String dpid) {
- this.dpid = HexString.toLong(dpid);
- }
-
public short getPort() {
return port;
}
- @JsonProperty("port")
- public void setPort(short port) {
- this.port = port;
- }
-
public InetAddress getIpAddress() {
return ipAddress;
}
- @JsonProperty("ipAddress")
- public void setIpAddress(String ipAddress) {
- this.ipAddress = InetAddresses.forString(ipAddress);
- }
-
public int getPrefixLength() {
return prefixLength;
}
-
- @JsonProperty("prefixLength")
- public void setPrefixLength(int prefixLength) {
- this.prefixLength = prefixLength;
- }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/PushedFlowMod.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/PushedFlowMod.java
index 56f4c04..fd9ba6f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/PushedFlowMod.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/PushedFlowMod.java
@@ -2,6 +2,13 @@
import org.openflow.protocol.OFFlowMod;
+/**
+ * Wraps up a DPID and a OFFlowMod so we know how to delete
+ * the flow if we have to.
+ *
+ * TODO This functionality should be handled by ONOS's flow layer in future.
+ *
+ */
public class PushedFlowMod {
private long dpid;
private OFFlowMod flowMod;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibEntry.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibEntry.java
index 8087471..1520c60 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibEntry.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibEntry.java
@@ -5,8 +5,8 @@
import com.google.common.net.InetAddresses;
public class RibEntry {
- private InetAddress routerId;
- private InetAddress nextHop;
+ private final InetAddress routerId;
+ private final InetAddress nextHop;
public RibEntry(InetAddress routerId, InetAddress nextHop) {
this.routerId = routerId;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibUpdate.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibUpdate.java
index 7d4d7a5..d866304 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibUpdate.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/RibUpdate.java
@@ -3,9 +3,9 @@
public class RibUpdate {
public enum Operation {UPDATE, DELETE};
- private Operation operation;
- private Prefix prefix;
- private RibEntry ribEntry;
+ private final Operation operation;
+ private final Prefix prefix;
+ private final RibEntry ribEntry;
public RibUpdate(Operation operation, Prefix prefix, RibEntry ribEntry) {
this.operation = operation;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
index 3374fa7..b7c97f8 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
@@ -227,6 +227,9 @@
IPortObject p = op.searchPort(dpid, port.getPortNumber());
if (p != null) {
log.error("SwitchStorage:addPort dpid:{} port:{} exists", dpid, port.getPortNumber());
+ p.setState("ACTIVE");
+ p.setPortState(port.getState());
+ p.setDesc(port.getName());
} else {
p = op.newPort(dpid, port.getPortNumber());
p.setState("ACTIVE");
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index 493d58e..6e12f28 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -19,11 +19,11 @@
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.packet.ARP;
import net.floodlightcontroller.packet.Ethernet;
+import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.util.MACAddress;
-import net.onrc.onos.ofcontroller.bgproute.IPatriciaTrie;
+import net.onrc.onos.ofcontroller.bgproute.ILayer3InfoService;
import net.onrc.onos.ofcontroller.bgproute.Interface;
-import net.onrc.onos.ofcontroller.bgproute.Prefix;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
@@ -40,32 +40,24 @@
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
-//TODO have L2 and also L3 mode, where it takes into account interface addresses
//TODO REST API to inspect ARP table
public class ProxyArpManager implements IProxyArpService, IOFMessageListener {
- private static Logger log = LoggerFactory.getLogger(ProxyArpManager.class);
+ private final static Logger log = LoggerFactory.getLogger(ProxyArpManager.class);
private final long ARP_ENTRY_TIMEOUT = 600000; //ms (== 10 mins)
private final long ARP_TIMER_PERIOD = 60000; //ms (== 1 min)
- protected IFloodlightProviderService floodlightProvider;
- protected ITopologyService topology;
+ private IFloodlightProviderService floodlightProvider;
+ private ITopologyService topology;
+ private ILayer3InfoService layer3;
- protected Map<InetAddress, ArpTableEntry> arpTable;
+ private Map<InetAddress, ArpTableEntry> arpTable;
- protected SetMultimap<InetAddress, ArpRequest> arpRequests;
-
- public enum Mode {L2_MODE, L3_MODE}
-
- private Mode mode;
- private IPatriciaTrie<Interface> interfacePtrie = null;
- private Collection<Interface> interfaces = null;
- private MACAddress routerMacAddress = null;
- //private SwitchPort bgpdAttachmentPoint = null;
+ private SetMultimap<InetAddress, ArpRequest> arpRequests;
private class ArpRequest {
- private IArpRequester requester;
+ private final IArpRequester requester;
private boolean retry;
private long requestTime;
@@ -91,36 +83,24 @@
}
public void dispatchReply(InetAddress ipAddress, byte[] replyMacAddress) {
- log.debug("Dispatching reply for {} to {}", ipAddress.getHostAddress(),
- requester);
requester.arpResponse(ipAddress, replyMacAddress);
}
}
public ProxyArpManager(IFloodlightProviderService floodlightProvider,
- ITopologyService topology){
+ ITopologyService topology, ILayer3InfoService layer3){
this.floodlightProvider = floodlightProvider;
this.topology = topology;
+ this.layer3 = layer3;
arpTable = new HashMap<InetAddress, ArpTableEntry>();
arpRequests = Multimaps.synchronizedSetMultimap(
HashMultimap.<InetAddress, ArpRequest>create());
-
- mode = Mode.L2_MODE;
- }
-
- public void setL3Mode(IPatriciaTrie<Interface> interfacePtrie,
- Collection<Interface> interfaces, MACAddress routerMacAddress) {
- this.interfacePtrie = interfacePtrie;
- this.interfaces = interfaces;
- this.routerMacAddress = routerMacAddress;
-
- mode = Mode.L3_MODE;
}
public void startUp() {
- Timer arpTimer = new Timer();
+ Timer arpTimer = new Timer("arp-processing");
arpTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
@@ -225,49 +205,31 @@
}
protected void handleArpRequest(IOFSwitch sw, OFPacketIn pi, ARP arp) {
- log.trace("ARP request received for {}",
- bytesToStringAddr(arp.getTargetProtocolAddress()));
+ if (log.isTraceEnabled()) {
+ log.trace("ARP request received for {}",
+ inetAddressToString(arp.getTargetProtocolAddress()));
+ }
InetAddress target;
- InetAddress source;
try {
target = InetAddress.getByAddress(arp.getTargetProtocolAddress());
- source = InetAddress.getByAddress(arp.getSenderProtocolAddress());
} catch (UnknownHostException e) {
log.debug("Invalid address in ARP request", e);
return;
}
-
- if (mode == Mode.L3_MODE) {
-
- //if (originatedOutsideNetwork(source)) {
- if (originatedOutsideNetwork(sw.getId(), pi.getInPort())) {
- //If the request came from outside our network, we only care if
- //it was a request for one of our interfaces.
- if (isInterfaceAddress(target)) {
- log.trace("ARP request for our interface. Sending reply {} => {}",
- target.getHostAddress(), routerMacAddress.toString());
- sendArpReply(arp, sw.getId(), pi.getInPort(), routerMacAddress.toBytes());
- }
- return;
+
+ if (layer3.fromExternalNetwork(sw.getId(), pi.getInPort())) {
+ //If the request came from outside our network, we only care if
+ //it was a request for one of our interfaces.
+ if (layer3.isInterfaceAddress(target)) {
+ log.trace("ARP request for our interface. Sending reply {} => {}",
+ target.getHostAddress(), layer3.getRouterMacAddress());
+
+ sendArpReply(arp, sw.getId(), pi.getInPort(),
+ layer3.getRouterMacAddress().toBytes());
}
- /*
- Interface intf = interfacePtrie.match(new Prefix(target.getAddress(), 32));
- //if (intf != null && target.equals(intf.getIpAddress())) {
- if (intf != null) {
- if (target.equals(intf.getIpAddress())) {
- //ARP request for one of our interfaces, we can reply straight away
- sendArpReply(arp, sw.getId(), pi.getInPort(), routerMacAddress.toBytes());
- }
- // If we didn't enter the above if block, then we found a matching
- // interface for the target IP but the request wasn't for us.
- // This is someone else ARPing for a different host in the subnet.
- // We shouldn't do anything in this case - if we let processing continue
- // we'll end up erroneously re-broadcasting an ARP for someone else.
- return;
- }
- */
+ return;
}
byte[] mac = lookupArpTable(arp.getTargetProtocolAddress());
@@ -280,25 +242,28 @@
new HostArpRequester(this, arp, sw.getId(), pi.getInPort()), false));
//Flood the request out edge ports
- //broadcastArpRequestOutEdge(pi.getPacketData(), sw.getId(), pi.getInPort());
sendArpRequestToSwitches(target, pi.getPacketData(), sw.getId(), pi.getInPort());
}
else {
//We know the address, so send a reply
- log.trace("Sending reply: {} => {} to host at {}/{}", new Object [] {
- bytesToStringAddr(arp.getTargetProtocolAddress()),
- MACAddress.valueOf(mac).toString(),
- HexString.toHexString(sw.getId()), pi.getInPort()});
+ if (log.isTraceEnabled()) {
+ log.trace("Sending reply: {} => {} to host at {}/{}", new Object [] {
+ inetAddressToString(arp.getTargetProtocolAddress()),
+ MACAddress.valueOf(mac).toString(),
+ HexString.toHexString(sw.getId()), pi.getInPort()});
+ }
sendArpReply(arp, sw.getId(), pi.getInPort(), mac);
}
}
protected void handleArpReply(IOFSwitch sw, OFPacketIn pi, ARP arp){
- log.trace("ARP reply recieved: {} => {}, on {}/{}", new Object[] {
- bytesToStringAddr(arp.getSenderProtocolAddress()),
- HexString.toHexString(arp.getSenderHardwareAddress()),
- HexString.toHexString(sw.getId()), pi.getInPort()});
+ if (log.isTraceEnabled()) {
+ log.trace("ARP reply recieved: {} => {}, on {}/{}", new Object[] {
+ inetAddressToString(arp.getSenderProtocolAddress()),
+ HexString.toHexString(arp.getSenderHardwareAddress()),
+ HexString.toHexString(sw.getId()), pi.getInPort()});
+ }
updateArpTable(arp);
@@ -307,6 +272,7 @@
try {
addr = InetAddress.getByAddress(arp.getSenderProtocolAddress());
} catch (UnknownHostException e) {
+ log.debug("Invalid address in ARP reply", e);
return;
}
@@ -319,7 +285,6 @@
while (it.hasNext()) {
ArpRequest request = it.next();
it.remove();
- //request.dispatchReply(addr, arp.getSenderHardwareAddress());
requestsToSend.add(request);
}
}
@@ -335,21 +300,22 @@
try {
addr = InetAddress.getByAddress(ipAddress);
} catch (UnknownHostException e) {
- log.warn("Unable to create InetAddress", e);
+ log.debug("Unable to create InetAddress", e);
return null;
}
ArpTableEntry arpEntry = arpTable.get(addr);
if (arpEntry == null){
- //log.debug("MAC for {} unknown", bytesToStringAddr(ipAddress));
return null;
}
if (System.currentTimeMillis() - arpEntry.getTimeLastSeen()
> ARP_ENTRY_TIMEOUT){
//Entry has timed out so we'll remove it and return null
- log.debug("Timing out old ARP entry for {}", bytesToStringAddr(ipAddress));
+ log.trace("Removing expired ARP entry for {}",
+ inetAddressToString(ipAddress));
+
arpTable.remove(addr);
return null;
}
@@ -362,7 +328,7 @@
try {
addr = InetAddress.getByAddress(arp.getSenderProtocolAddress());
} catch (UnknownHostException e) {
- log.warn("Unable to create InetAddress", e);
+ log.debug("Unable to create InetAddress", e);
return;
}
@@ -380,10 +346,14 @@
}
private void sendArpRequestForAddress(InetAddress ipAddress) {
- //TODO what should the sender IP address be? Probably not 0.0.0.0
+ //TODO what should the sender IP address and MAC address be if no
+ //IP addresses are configured? Will there ever be a need to send
+ //ARP requests from the controller in that case?
+ //All-zero MAC address doesn't seem to work - hosts don't respond to it
+
byte[] zeroIpv4 = {0x0, 0x0, 0x0, 0x0};
byte[] zeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
- //byte[] bgpdMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x01};
+ byte[] genericNonZeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x01};
byte[] broadcastMac = {(byte)0xff, (byte)0xff, (byte)0xff,
(byte)0xff, (byte)0xff, (byte)0xff};
@@ -392,56 +362,62 @@
arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
.setProtocolType(ARP.PROTO_TYPE_IP)
.setHardwareAddressLength((byte)Ethernet.DATALAYER_ADDRESS_LENGTH)
- .setProtocolAddressLength((byte)4) //can't find the constant anywhere
+ .setProtocolAddressLength((byte)IPv4.ADDRESS_LENGTH)
.setOpCode(ARP.OP_REQUEST)
- //.setSenderHardwareAddress(bgpdMac)
- .setSenderHardwareAddress(routerMacAddress.toBytes())
- //.setSenderProtocolAddress(zeroIpv4)
.setTargetHardwareAddress(zeroMac)
.setTargetProtocolAddress(ipAddress.getAddress());
+ MACAddress routerMacAddress = layer3.getRouterMacAddress();
+ //TODO hack for now as it's unclear what the MAC address should be
+ byte[] senderMacAddress = genericNonZeroMac;
+ if (routerMacAddress != null) {
+ senderMacAddress = routerMacAddress.toBytes();
+ }
+ arpRequest.setSenderHardwareAddress(senderMacAddress);
+
byte[] senderIPAddress = zeroIpv4;
- if (mode == Mode.L3_MODE) {
- Interface intf = interfacePtrie.match(new Prefix(ipAddress.getAddress(), 32));
- if (intf != null) {
- senderIPAddress = intf.getIpAddress().getAddress();
- }
+ Interface intf = layer3.getOutgoingInterface(ipAddress);
+ if (intf != null) {
+ senderIPAddress = intf.getIpAddress().getAddress();
}
arpRequest.setSenderProtocolAddress(senderIPAddress);
Ethernet eth = new Ethernet();
- eth.setSourceMACAddress(routerMacAddress.toBytes())
+ eth.setSourceMACAddress(senderMacAddress)
.setDestinationMACAddress(broadcastMac)
.setEtherType(Ethernet.TYPE_ARP)
.setPayload(arpRequest);
- //broadcastArpRequestOutEdge(eth.serialize(), 0, OFPort.OFPP_NONE.getValue());
sendArpRequestToSwitches(ipAddress, eth.serialize());
}
private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest) {
- sendArpRequestToSwitches(dstAddress, arpRequest, 0, OFPort.OFPP_NONE.getValue());
+ sendArpRequestToSwitches(dstAddress, arpRequest,
+ 0, OFPort.OFPP_NONE.getValue());
}
+
private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest,
long inSwitch, short inPort) {
- if (mode == Mode.L2_MODE) {
- //log.debug("mode is l2");
- broadcastArpRequestOutEdge(arpRequest, inSwitch, inPort);
- }
- else if (mode == Mode.L3_MODE) {
- //log.debug("mode is l3");
- //TODO the case where it should be broadcast out all non-interface
- //edge ports
- Interface intf = interfacePtrie.match(new Prefix(dstAddress.getAddress(), 32));
+
+ if (layer3.hasLayer3Configuration()) {
+ Interface intf = layer3.getOutgoingInterface(dstAddress);
if (intf != null) {
sendArpRequestOutPort(arpRequest, intf.getDpid(), intf.getPort());
}
else {
- log.debug("No interface found to send ARP request for {}",
+ //TODO here it should be broadcast out all non-interface edge ports.
+ //I think we can assume that if it's not a request for an external
+ //network, it's an ARP for a host in our own network. So we want to
+ //send it out all edge ports that don't have an interface configured
+ //to ensure it reaches all hosts in our network.
+ log.debug("No interface found to send ARP request for {}",
dstAddress.getHostAddress());
}
}
+ else {
+ broadcastArpRequestOutEdge(arpRequest, inSwitch, inPort);
+ }
}
private void broadcastArpRequestOutEdge(byte[] arpRequest, long inSwitch, short inPort) {
@@ -471,7 +447,6 @@
}
actions.add(new OFActionOutput(portNum));
- //log.debug("Broadcasting out {}/{}", HexString.toHexString(sw.getId()), portNum);
}
po.setActions(actions);
@@ -493,7 +468,10 @@
}
private void sendArpRequestOutPort(byte[] arpRequest, long dpid, short port) {
- log.debug("Sending ARP request out {}/{}", HexString.toHexString(dpid), port);
+ if (log.isTraceEnabled()) {
+ log.trace("Sending ARP request out {}/{}",
+ HexString.toHexString(dpid), port);
+ }
OFPacketOut po = new OFPacketOut();
po.setInPort(OFPort.OFPP_NONE)
@@ -511,7 +489,7 @@
IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
if (sw == null) {
- log.debug("Switch not found when sending ARP request");
+ log.warn("Switch not found when sending ARP request");
return;
}
@@ -523,17 +501,32 @@
}
}
+ private String inetAddressToString(byte[] bytes) {
+ try {
+ return InetAddress.getByAddress(bytes).getHostAddress();
+ } catch (UnknownHostException e) {
+ log.debug("Invalid IP address", e);
+ return "";
+ }
+ }
+
+ /*
+ * IProxyArpService methods
+ */
+
public void sendArpReply(ARP arpRequest, long dpid, short port, byte[] targetMac) {
- log.trace("Sending reply {} => {} to {}", new Object[] {
- bytesToStringAddr(arpRequest.getTargetProtocolAddress()),
- HexString.toHexString(targetMac),
- bytesToStringAddr(arpRequest.getSenderProtocolAddress())});
+ if (log.isTraceEnabled()) {
+ log.trace("Sending reply {} => {} to {}", new Object[] {
+ inetAddressToString(arpRequest.getTargetProtocolAddress()),
+ HexString.toHexString(targetMac),
+ inetAddressToString(arpRequest.getSenderProtocolAddress())});
+ }
ARP arpReply = new ARP();
arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET)
.setProtocolType(ARP.PROTO_TYPE_IP)
.setHardwareAddressLength((byte)Ethernet.DATALAYER_ADDRESS_LENGTH)
- .setProtocolAddressLength((byte)4) //can't find the constant anywhere
+ .setProtocolAddressLength((byte)IPv4.ADDRESS_LENGTH)
.setOpCode(ARP.OP_REPLY)
.setSenderHardwareAddress(targetMac)
.setSenderProtocolAddress(arpRequest.getTargetProtocolAddress())
@@ -564,34 +557,19 @@
IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
if (sw == null) {
- log.error("Switch {} not found when sending ARP reply",
+ log.warn("Switch {} not found when sending ARP reply",
HexString.toHexString(dpid));
return;
}
try {
- log.debug("Sending ARP reply to {}/{}", HexString.toHexString(sw.getId()), port);
sw.write(msgList, null);
sw.flush();
} catch (IOException e) {
- log.warn("Failure writing packet out to switch", e);
+ log.error("Failure writing packet out to switch", e);
}
}
- //TODO this should be put somewhere more central. I use it in BgpRoute as well.
- //We need a HexString.toHexString() equivalent.
- private String bytesToStringAddr(byte[] bytes) {
- InetAddress addr;
- try {
- addr = InetAddress.getByAddress(bytes);
- } catch (UnknownHostException e) {
- log.warn(" ", e);
- return "";
- }
- if (addr == null) return "";
- else return addr.getHostAddress();
- }
-
@Override
public byte[] getMacAddress(InetAddress ipAddress) {
return lookupArpTable(ipAddress.getAddress());
@@ -601,57 +579,10 @@
public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
boolean retry) {
arpRequests.put(ipAddress, new ArpRequest(requester, retry));
- //storeRequester(ipAddress, requester, retry);
//Sanity check to make sure we don't send a request for our own address
- if (!isInterfaceAddress(ipAddress)) {
+ if (!layer3.isInterfaceAddress(ipAddress)) {
sendArpRequestForAddress(ipAddress);
}
}
-
- /*
- * TODO These methods might be more suited to some kind of L3 information service
- * that ProxyArpManager could query, rather than having the information
- * embedded in ProxyArpManager. There may be many modules that need L3 information.
- */
-
- private boolean originatedOutsideNetwork(InetAddress source) {
- Interface intf = interfacePtrie.match(new Prefix(source.getAddress(), 32));
- if (intf != null) {
- if (intf.getIpAddress().equals(source)) {
- // This request must have been originated by us (the controller)
- return false;
- }
- else {
- // Source was in one of our interface subnets, but wasn't us.
- // It must be external.
- return true;
- }
- }
- else {
- // Source is not in one of our interface subnets. It's probably a host
- // in our network as we should only receive ARPs broadcast by external
- // hosts if they're in the same subnet.
- return false;
- }
- }
-
- private boolean originatedOutsideNetwork(long inDpid, short inPort) {
- for (Interface intf : interfaces) {
- if (intf.getDpid() == inDpid && intf.getPort() == inPort) {
- return true;
- }
- }
- return false;
- }
-
- private boolean isInterfaceAddress(InetAddress address) {
- Interface intf = interfacePtrie.match(new Prefix(address.getAddress(), 32));
- return (intf != null && intf.getIpAddress().equals(address));
- }
-
- private boolean inInterfaceSubnet(InetAddress address) {
- Interface intf = interfacePtrie.match(new Prefix(address.getAddress(), 32));
- return (intf != null && !intf.getIpAddress().equals(address));
- }
}