Merge pull request #423 from jonohart/master
Fixes for REANNZ deployment issues
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 2124f78..9e7bf61 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -38,6 +38,7 @@
import net.onrc.onos.ofcontroller.core.internal.TopoLinkServiceImpl;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
+import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.ofcontroller.proxyarp.IArpRequester;
import net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager;
import net.onrc.onos.ofcontroller.routing.TopoRouteService;
@@ -82,6 +83,7 @@
protected IFloodlightProviderService floodlightProvider;
protected ITopologyService topology;
protected ITopoRouteService topoRouteService;
+ protected ILinkDiscoveryService linkDiscoveryService;
protected IRestApiService restApi;
protected ProxyArpManager proxyArp;
@@ -256,6 +258,7 @@
// Register floodlight provider and REST handler.
floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
topology = context.getServiceImpl(ITopologyService.class);
+ linkDiscoveryService = context.getServiceImpl(ILinkDiscoveryService.class);
restApi = context.getServiceImpl(IRestApiService.class);
//TODO We'll initialise this here for now, but it should really be done as
@@ -479,13 +482,23 @@
private void addPrefixFlows(Prefix prefix, Interface egressInterface, byte[] nextHopMacAddress) {
log.debug("Adding flows for prefix {} added, next hop mac {}",
prefix, HexString.toHexString(nextHopMacAddress));
-
- //Add a flow to rewrite mac for this prefix to all other border switches
- for (Interface srcInterface : interfaces.values()) {
- if (srcInterface == egressInterface) {
- //Don't push a flow for the switch where this peer is attached
- continue;
+
+ //We only need one flow mod per switch, so pick one interface on each switch
+ Map<Long, Interface> srcInterfaces = new HashMap<Long, Interface>();
+ for (Interface intf : interfaces.values()) {
+ if (!srcInterfaces.containsKey(intf.getDpid())
+ && intf != egressInterface) {
+ srcInterfaces.put(intf.getDpid(), intf);
}
+ }
+
+ //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;
@@ -559,8 +572,13 @@
try {
sw.write(msglist, null);
sw.flush();
+ //Thread.sleep(0, 100000);
+ Thread.sleep(1);
} catch (IOException e) {
log.error("Failure writing flow mod", e);
+ } catch (InterruptedException e) {
+ // TODO handle this properly
+ log.error("Interrupted", e);
}
}
}
@@ -582,21 +600,22 @@
deletePrefixFlows(prefix);
log.debug("Deleting {} to {}", prefix, ribEntry.getNextHop());
- log.debug("is peer {}", bgpPeers.containsKey(ribEntry.getNextHop()));
+
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) {
- log.error("No path found for non-peer path");
- }
+ if (path != null) {
+ //path could be null if we added to the Ptree but didn't push
+ //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());
+ path.decrementUsers();
+ log.debug("users {}, permanent {}", path.getUsers(), path.isPermanent());
+ if (path.getUsers() <= 0 && !path.isPermanent()) {
+ deletePath(path);
+ pushedPaths.remove(path.getDstIpAddress());
+ }
}
}
}
@@ -1035,15 +1054,49 @@
}
}
+ private void setupDefaultDropFlows() {
+ OFFlowMod fm = new OFFlowMod();
+ fm.setMatch(new OFMatch());
+ //No action means drop
+
+ fm.setIdleTimeout((short)0)
+ .setHardTimeout((short)0)
+ .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+ .setCookie(0)
+ .setCommand(OFFlowMod.OFPFC_ADD)
+ .setPriority((short)0)
+ .setLengthU(OFFlowMod.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 {
+ try {
+ sw.write(fm, null);
+ } catch (IOException e) {
+ log.warn("Failure writing default deny flow to switch", e);
+ }
+ }
+ }
+ }
+
private void beginRouting(){
log.debug("Topology is now ready, beginning routing function");
topoRouteTopology = topoRouteService.prepareShortestPathTopo();
setupArpFlows();
+ setupDefaultDropFlows();
setupBgpPaths();
setupFullMesh();
-
+
+ //Suppress link discovery on external-facing router ports
+ for (Interface intf : interfaces.values()) {
+ linkDiscoveryService.AddToSuppressLLDPs(intf.getDpid(), intf.getPort());
+ }
+
bgpUpdatesExecutor.execute(new Runnable() {
@Override
public void run() {