diff --git a/src/main/java/net/floodlightcontroller/core/util/AppCookie.java b/src/main/java/net/floodlightcontroller/core/util/AppCookie.java index 370256fb1596f98aee6f1946b4008f8f26e2f3b4..d35e6a9e56631e21f3c13f52db9b6f693199fe76 100644 --- a/src/main/java/net/floodlightcontroller/core/util/AppCookie.java +++ b/src/main/java/net/floodlightcontroller/core/util/AppCookie.java @@ -76,6 +76,13 @@ public class AppCookie { return U64.of(APP_ID_MASK << APP_ID_SHIFT); } + /** + * Returns a mask suitable for matching the User field within a cookie. + */ + static public U64 getUserFieldMask() { + return U64.of(USER_MASK); + } + /** * Encapsulate an application ID and a user block of stuff into a cookie * diff --git a/src/main/java/net/floodlightcontroller/firewall/Firewall.java b/src/main/java/net/floodlightcontroller/firewall/Firewall.java index 0fb28b24c46b73002f63830800bd812c3922595f..d1d07104339d70c8ad25a5abfbe11fe24b73e1f4 100644 --- a/src/main/java/net/floodlightcontroller/firewall/Firewall.java +++ b/src/main/java/net/floodlightcontroller/firewall/Firewall.java @@ -37,6 +37,7 @@ import org.projectfloodlight.openflow.types.IPv4Address; import org.projectfloodlight.openflow.types.IPv4AddressWithMask; import org.projectfloodlight.openflow.types.IpProtocol; import org.projectfloodlight.openflow.types.MacAddress; +import org.projectfloodlight.openflow.types.Masked; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.TransportPort; import org.projectfloodlight.openflow.types.U64; @@ -60,6 +61,7 @@ import net.floodlightcontroller.packet.TCP; import net.floodlightcontroller.packet.UDP; import net.floodlightcontroller.restserver.IRestApiService; import net.floodlightcontroller.routing.IRoutingDecision; +import net.floodlightcontroller.routing.IRoutingService; import net.floodlightcontroller.routing.RoutingDecision; import net.floodlightcontroller.storage.IResultSet; import net.floodlightcontroller.storage.IStorageSourceService; @@ -85,11 +87,13 @@ IFloodlightModule { private static final U64 DENY_BCAST_COOKIE = AppCookie.makeCookie(APP_ID, 0xaaaaaaaa); private static final U64 ALLOW_BCAST_COOKIE = AppCookie.makeCookie(APP_ID, 0x55555555); private static final U64 RULE_MISS_COOKIE = AppCookie.makeCookie(APP_ID, -1); + private static final U64 DEFAULT_COOKIE = AppCookie.makeCookie(APP_ID, 0); // service modules needed protected IFloodlightProviderService floodlightProvider; protected IStorageSourceService storageSource; protected IRestApiService restApi; + protected IRoutingService routingService; protected static Logger logger; protected List<FirewallRule> rules; // protected by synchronized @@ -170,6 +174,7 @@ IFloodlightModule { l.add(IFloodlightProviderService.class); l.add(IStorageSourceService.class); l.add(IRestApiService.class); + l.add(IRoutingService.class); return l; } @@ -335,8 +340,18 @@ IFloodlightModule { @Override public void enableFirewall(boolean enabled) { - logger.info("Setting firewall to {}", enabled); - this.enabled = enabled; + + if(this.enabled != enabled) { + logger.info("Setting firewall to {}", enabled); + this.enabled = enabled; + + List<Masked<U64>> changes = new ArrayList<Masked<U64>>(); + changes.add(Masked.of(DEFAULT_COOKIE, AppCookie.getAppFieldMask())); + + // Add announcement that all firewall decisions changed + routingService.handleRoutingDecisionChange(changes); + } + } @Override @@ -424,6 +439,22 @@ IFloodlightModule { entry.put(COLUMN_PRIORITY, Integer.toString(rule.priority)); entry.put(COLUMN_ACTION, Integer.toString(rule.action.ordinal())); storageSource.insertRow(TABLE_NAME, entry); + + + + U64 singleRuleMask = AppCookie.getAppFieldMask().or(AppCookie.getUserFieldMask()); + List<Masked<U64>> changes = new ArrayList<Masked<U64>>(); + Iterator<FirewallRule> iter = this.rules.iterator(); + while (iter.hasNext()) { + FirewallRule r = iter.next(); + if (r.priority >= rule.priority) { + // + changes.add(Masked.of(AppCookie.makeCookie(APP_ID, r.ruleid), singleRuleMask)); + } + } + changes.add(Masked.of(RULE_MISS_COOKIE, singleRuleMask)); + routingService.handleRoutingDecisionChange(changes); + } @Override @@ -439,6 +470,19 @@ IFloodlightModule { } // delete from database storageSource.deleteRow(TABLE_NAME, Integer.toString(ruleid)); + + //Add announcement that the rule has been deleted + Masked<U64> delDescriptor = Masked.of( + AppCookie.makeCookie(APP_ID, ruleid), + AppCookie.getAppFieldMask().or(AppCookie.getUserFieldMask())); + + List<Masked<U64>> changes = new ArrayList<Masked<U64>>(); + changes.add(delDescriptor); + + //Add announcement that rule is added + // should we try to delete the flow even if not found in this.rules + routingService.handleRoutingDecisionChange(changes); + } /** diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java index 1062f14de6ffc7109a53df84c77722ad4b83f0d9..797ff1876ad07984d5a3f6454599ee60080437a7 100644 --- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java +++ b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java @@ -51,6 +51,8 @@ import net.floodlightcontroller.packet.TCP; import net.floodlightcontroller.packet.UDP; import net.floodlightcontroller.routing.ForwardingBase; import net.floodlightcontroller.routing.IRoutingDecision; +import net.floodlightcontroller.routing.IRoutingDecisionChange; +import net.floodlightcontroller.routing.IRoutingDecisionChangedListener; import net.floodlightcontroller.routing.IRoutingService; import net.floodlightcontroller.routing.Route; import net.floodlightcontroller.topology.ITopologyService; @@ -87,7 +89,7 @@ import org.projectfloodlight.openflow.types.VlanVid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class Forwarding extends ForwardingBase implements IFloodlightModule, IOFSwitchListener, ILinkDiscoveryListener { +public class Forwarding extends ForwardingBase implements IFloodlightModule, IOFSwitchListener, ILinkDiscoveryListener, IRoutingDecisionChangedListener { protected static Logger log = LoggerFactory.getLogger(Forwarding.class); private final U64 DEFAULT_FORWARDING_COOKIE = AppCookie.makeCookie(FORWARDING_APP_ID, 0); @@ -160,6 +162,11 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule, IOF return AppCookie.makeCookie(FORWARDING_APP_ID, user_fields); } + /** */ + public void routingDecisionChanged(IRoutingDecisionChange event) { + //FIXME + } + /** * Converts a sequence of masked IRoutingDecision descriptors into masked Forwarding cookies. * @@ -627,6 +634,7 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule, IOF public void startUp(FloodlightModuleContext context) { super.startUp(); switchService.addOFSwitchListener(this); + routingEngineService.addRoutingDecisionChangedListener(this); /* Register only if we want to remove stale flows */ if (REMOVE_FLOWS_ON_LINK_OR_PORT_DOWN) { @@ -634,6 +642,10 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule, IOF } } + + + + @Override public void switchAdded(DatapathId switchId) { } diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java b/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java index 6d3b67f8e9fda5538b89cc938fb46c0ac917d252..592623fb89b63a758d119833833c9078ac27b67b 100644 --- a/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java +++ b/src/main/java/net/floodlightcontroller/routing/IRoutingDecision.java @@ -66,4 +66,5 @@ public interface IRoutingDecision { public void setHardTimeout(short hardTimeout); public U64 getDescriptor(); public void setDescriptor(U64 descriptor); + } diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingDecisionChange.java b/src/main/java/net/floodlightcontroller/routing/IRoutingDecisionChange.java new file mode 100644 index 0000000000000000000000000000000000000000..54191d6e5a48c064585f922d7c1ea4a31860d7af --- /dev/null +++ b/src/main/java/net/floodlightcontroller/routing/IRoutingDecisionChange.java @@ -0,0 +1,10 @@ +package net.floodlightcontroller.routing; + +import org.projectfloodlight.openflow.types.Masked; +import org.projectfloodlight.openflow.types.U64; + +public interface IRoutingDecisionChange { + + public Iterable<Masked<U64>> getDescriptor(); + +} diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingDecisionChangedListener.java b/src/main/java/net/floodlightcontroller/routing/IRoutingDecisionChangedListener.java new file mode 100644 index 0000000000000000000000000000000000000000..8c8691699e4346d77c57c895d6deb3044d03da0b --- /dev/null +++ b/src/main/java/net/floodlightcontroller/routing/IRoutingDecisionChangedListener.java @@ -0,0 +1,7 @@ +package net.floodlightcontroller.routing; + +public interface IRoutingDecisionChangedListener { + + public void routingDecisionChanged(IRoutingDecisionChange event); + +} diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingService.java b/src/main/java/net/floodlightcontroller/routing/IRoutingService.java index fde607b89cef1ca00a78e8867748c0c2f4c2c795..faf1dba836bca96c7bec26fdaceb22a30014383b 100644 --- a/src/main/java/net/floodlightcontroller/routing/IRoutingService.java +++ b/src/main/java/net/floodlightcontroller/routing/IRoutingService.java @@ -20,6 +20,7 @@ package net.floodlightcontroller.routing; import java.util.ArrayList; import org.projectfloodlight.openflow.types.DatapathId; +import org.projectfloodlight.openflow.types.Masked; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.U64; @@ -82,5 +83,20 @@ public interface IRoutingService extends IFloodlightService { * or not have tunnels as part of the path. */ public boolean routeExists(DatapathId src, DatapathId dst, boolean tunnelEnabled); + + /** Register the RDCListener + * @param listener - The module that wants to listen for events + * */ + public void addRoutingDecisionChangedListener(IRoutingDecisionChangedListener listener); + + /** Remove the RDCListener + * @param listener - The module that wants to stop listening for events + * */ + public void removeRoutingDecisionChangedListener(IRoutingDecisionChangedListener listener); + + /** Handles what the listener actually does + * @param + * */ + public void handleRoutingDecisionChange(Iterable<Masked<U64>> event/* IRoutingDecisionChange event */); } diff --git a/src/main/java/net/floodlightcontroller/routing/RoutingDecision.java b/src/main/java/net/floodlightcontroller/routing/RoutingDecision.java index 8ce5c5c9415fcd14a3dcd34de0264b719b5536f7..9371528dc6f2b8aa5cd0c3f5fc49f37d6f0c81d3 100644 --- a/src/main/java/net/floodlightcontroller/routing/RoutingDecision.java +++ b/src/main/java/net/floodlightcontroller/routing/RoutingDecision.java @@ -136,4 +136,5 @@ public class RoutingDecision implements IRoutingDecision { " wildcard " + ((match == null) ? null : match.toString()); } + } diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java index 09c023e4f2fac5d824553b93ad9e1de4e0832bdb..ec87c3f6b1c7d8eae67df1dd8b07152fbd5bb1da 100644 --- a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java +++ b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java @@ -59,6 +59,8 @@ import net.floodlightcontroller.packet.BSN; import net.floodlightcontroller.packet.Ethernet; import net.floodlightcontroller.packet.LLDP; import net.floodlightcontroller.restserver.IRestApiService; +import net.floodlightcontroller.routing.IRoutingDecisionChange; +import net.floodlightcontroller.routing.IRoutingDecisionChangedListener; import net.floodlightcontroller.routing.IRoutingService; import net.floodlightcontroller.routing.Link; import net.floodlightcontroller.routing.Route; @@ -73,6 +75,7 @@ import org.projectfloodlight.openflow.protocol.OFVersion; import org.projectfloodlight.openflow.protocol.action.OFAction; import org.projectfloodlight.openflow.protocol.match.MatchField; import org.projectfloodlight.openflow.types.DatapathId; +import org.projectfloodlight.openflow.types.Masked; import org.projectfloodlight.openflow.types.OFBufferId; import org.projectfloodlight.openflow.types.OFPort; import org.projectfloodlight.openflow.types.U64; @@ -176,6 +179,9 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo * Topology Event Updater */ protected IEventCategory<TopologyEvent> eventCategory; + + /** Array list that contains all of the decisionChangedListeners */ + protected ArrayList<IRoutingDecisionChangedListener> decisionChangedListeners; /** * Topology Information exposed for a Topology related event - used inside @@ -1531,4 +1537,20 @@ public class TopologyManager implements IFloodlightModule, ITopologyService, IRo return ports; } + + public void addRoutingDecisionChangedListener(IRoutingDecisionChangedListener listener) { + this.decisionChangedListeners.add(listener); + } + + public void removeRoutingDecisionChangedListener(IRoutingDecisionChangedListener listener) { + /**TODO remove the listener now */ + this.decisionChangedListeners.remove(listener); + } + + public void handleRoutingDecisionChange(Iterable<Masked<U64>> event) { + for(IRoutingDecisionChangedListener listener : decisionChangedListeners) { + listener.routingDecisionChanged(event); + } + } + }