Fix checkstyle whitespace issues - WHITESPACE ONLY
Change-Id: Ic205c1afd639c6008d61d9de95cb764eeb6238ca
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/BgpPeer.java b/src/main/java/net/onrc/onos/apps/bgproute/BgpPeer.java
index 32ea288..d103918 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/BgpPeer.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/BgpPeer.java
@@ -7,20 +7,20 @@
import com.google.common.net.InetAddresses;
public class BgpPeer {
- 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;
- }
+ private final String interfaceName;
+ private final InetAddress ipAddress;
- public InetAddress getIpAddress() {
- return ipAddress;
- }
+ public BgpPeer(@JsonProperty("interface") String interfaceName,
+ @JsonProperty("ipAddress") String ipAddress) {
+ this.interfaceName = interfaceName;
+ this.ipAddress = InetAddresses.forString(ipAddress);
+ }
+
+ public String getInterfaceName() {
+ return interfaceName;
+ }
+
+ public InetAddress getIpAddress() {
+ return ipAddress;
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/apps/bgproute/BgpRoute.java
index 881e925..b2fcbc0 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/BgpRoute.java
@@ -73,1318 +73,1310 @@
import com.google.common.util.concurrent.ThreadFactoryBuilder;
public class BgpRoute implements IFloodlightModule, IBgpRouteService,
- IArpRequester,
- IOFSwitchListener, IConfigInfoService {
+ IArpRequester,
+ IOFSwitchListener, IConfigInfoService {
- private final static Logger log = LoggerFactory.getLogger(BgpRoute.class);
+ private final static Logger log = LoggerFactory.getLogger(BgpRoute.class);
- private IFloodlightProviderService floodlightProvider;
- private ILinkDiscoveryService linkDiscoveryService;
- private IRestApiService restApi;
- private IProxyArpService proxyArp;
+ private IFloodlightProviderService floodlightProvider;
+ private ILinkDiscoveryService linkDiscoveryService;
+ private IRestApiService restApi;
+ private IProxyArpService proxyArp;
- private IPatriciaTrie<RibEntry> ptree;
- private IPatriciaTrie<Interface> interfacePtrie;
- private BlockingQueue<RibUpdate> ribUpdates;
+ private IPatriciaTrie<RibEntry> ptree;
+ private IPatriciaTrie<Interface> interfacePtrie;
+ private BlockingQueue<RibUpdate> ribUpdates;
- private String bgpdRestIp;
- private String routerId;
- private String configFilename = "config.json";
+ private String bgpdRestIp;
+ private String routerId;
+ private String configFilename = "config.json";
- //We need to identify our flows somehow. But like it says in LearningSwitch.java,
- //the controller/OS should hand out cookie IDs to prevent conflicts.
- private final long APP_COOKIE = 0xa0000000000000L;
- //Cookie for flows that do L2 forwarding within SDN domain to egress routers
- private final long L2_FWD_COOKIE = APP_COOKIE + 1;
- //Cookie for flows in ingress switches that rewrite the MAC address
- private final long MAC_RW_COOKIE = APP_COOKIE + 2;
- //Cookie for flows that setup BGP paths
- private final long BGP_COOKIE = APP_COOKIE + 3;
- //Forwarding uses priority 0, and the mac rewrite entries in ingress switches
- //need to be higher priority than this otherwise the rewrite may not get done
- private final short SDNIP_PRIORITY = 10;
- private final short ARP_PRIORITY = 20;
+ //We need to identify our flows somehow. But like it says in LearningSwitch.java,
+ //the controller/OS should hand out cookie IDs to prevent conflicts.
+ private final long APP_COOKIE = 0xa0000000000000L;
+ //Cookie for flows that do L2 forwarding within SDN domain to egress routers
+ private final long L2_FWD_COOKIE = APP_COOKIE + 1;
+ //Cookie for flows in ingress switches that rewrite the MAC address
+ private final long MAC_RW_COOKIE = APP_COOKIE + 2;
+ //Cookie for flows that setup BGP paths
+ private final long BGP_COOKIE = APP_COOKIE + 3;
+ //Forwarding uses priority 0, and the mac rewrite entries in ingress switches
+ //need to be higher priority than this otherwise the rewrite may not get done
+ private final short SDNIP_PRIORITY = 10;
+ private final short ARP_PRIORITY = 20;
- private final short BGP_PORT = 179;
+ private final short BGP_PORT = 179;
- private final int TOPO_DETECTION_WAIT = 2; //seconds
+ private final int TOPO_DETECTION_WAIT = 2; //seconds
- //Configuration stuff
- private List<String> switches;
- private Map<String, Interface> interfaces;
- private Map<InetAddress, BgpPeer> bgpPeers;
- private SwitchPort bgpdAttachmentPoint;
- private MACAddress bgpdMacAddress;
- private short vlan;
+ //Configuration stuff
+ private List<String> switches;
+ private Map<String, Interface> interfaces;
+ private Map<InetAddress, BgpPeer> bgpPeers;
+ private SwitchPort bgpdAttachmentPoint;
+ private MACAddress bgpdMacAddress;
+ private short vlan;
- //True when all switches have connected
- private volatile boolean switchesConnected = false;
- //True when we have a full mesh of shortest paths between gateways
- private volatile boolean topologyReady = false;
+ //True when all switches have connected
+ private volatile boolean switchesConnected = false;
+ //True when we have a full mesh of shortest paths between gateways
+ private volatile boolean topologyReady = false;
- private ArrayList<LDUpdate> linkUpdates;
- private SingletonTask topologyChangeDetectorTask;
+ private ArrayList<LDUpdate> linkUpdates;
+ private SingletonTask topologyChangeDetectorTask;
- private SetMultimap<InetAddress, RibUpdate> prefixesWaitingOnArp;
+ private SetMultimap<InetAddress, RibUpdate> prefixesWaitingOnArp;
- private Map<InetAddress, Path> pathsWaitingOnArp;
+ private Map<InetAddress, Path> pathsWaitingOnArp;
- private ExecutorService bgpUpdatesExecutor;
+ private ExecutorService bgpUpdatesExecutor;
- private Map<InetAddress, Path> pushedPaths;
- private Map<Prefix, Path> prefixToPath;
-// private Multimap<Prefix, PushedFlowMod> pushedFlows;
- private Multimap<Prefix, FlowId> pushedFlowIds;
+ private Map<InetAddress, Path> pushedPaths;
+ private Map<Prefix, Path> prefixToPath;
+ // private Multimap<Prefix, PushedFlowMod> pushedFlows;
+ private Multimap<Prefix, FlowId> pushedFlowIds;
- private FlowCache flowCache;
+ private FlowCache flowCache;
- // TODO: Fix for the new Topology Network Graph
- // private volatile Topology topology = null;
+ // TODO: Fix for the new Topology Network Graph
+ // private volatile Topology topology = null;
- private class TopologyChangeDetector implements Runnable {
- @Override
- public void run() {
- log.debug("Running topology change detection task");
- synchronized (linkUpdates) {
- //This is the model the REST API uses to retrieve network graph info
- // TODO: Fix the code below after topoLinkService was removed
- /*
- ITopoLinkService topoLinkService = new TopoLinkServiceImpl();
+ private class TopologyChangeDetector implements Runnable {
+ @Override
+ public void run() {
+ log.debug("Running topology change detection task");
+ synchronized (linkUpdates) {
+ //This is the model the REST API uses to retrieve network graph info
+ // TODO: Fix the code below after topoLinkService was removed
+ /*
+ ITopoLinkService topoLinkService = new TopoLinkServiceImpl();
- List<Link> activeLinks = topoLinkService.getActiveLinks();
+ List<Link> activeLinks = topoLinkService.getActiveLinks();
- Iterator<LDUpdate> it = linkUpdates.iterator();
- while (it.hasNext()){
- LDUpdate ldu = it.next();
- Link l = new Link(ldu.getSrc(), ldu.getSrcPort(),
- ldu.getDst(), ldu.getDstPort());
+ Iterator<LDUpdate> it = linkUpdates.iterator();
+ while (it.hasNext()){
+ LDUpdate ldu = it.next();
+ Link l = new Link(ldu.getSrc(), ldu.getSrcPort(),
+ ldu.getDst(), ldu.getDstPort());
- if (activeLinks.contains(l)){
- it.remove();
- }
- }
- */
- }
+ if (activeLinks.contains(l)){
+ it.remove();
+ }
+ }
+ */
+ }
- if (!topologyReady) {
- if (linkUpdates.isEmpty()){
- //All updates have been seen in network map.
- //We can check if topology is ready
- log.debug("No known changes outstanding. Checking topology now");
- checkStatus();
- }
- else {
- //We know of some link updates that haven't propagated to the database yet
- log.debug("Some changes not found in network map - {} links missing", linkUpdates.size());
- topologyChangeDetectorTask.reschedule(TOPO_DETECTION_WAIT, TimeUnit.SECONDS);
- }
- }
- }
- }
+ if (!topologyReady) {
+ if (linkUpdates.isEmpty()) {
+ //All updates have been seen in network map.
+ //We can check if topology is ready
+ log.debug("No known changes outstanding. Checking topology now");
+ checkStatus();
+ } else {
+ //We know of some link updates that haven't propagated to the database yet
+ log.debug("Some changes not found in network map - {} links missing", linkUpdates.size());
+ topologyChangeDetectorTask.reschedule(TOPO_DETECTION_WAIT, TimeUnit.SECONDS);
+ }
+ }
+ }
+ }
- private void readConfiguration(String configFilename){
- File gatewaysFile = new File(configFilename);
- ObjectMapper mapper = new ObjectMapper();
+ private void readConfiguration(String configFilename) {
+ File gatewaysFile = new File(configFilename);
+ ObjectMapper mapper = new ObjectMapper();
- try {
- Configuration config = mapper.readValue(gatewaysFile, Configuration.class);
+ try {
+ Configuration config = mapper.readValue(gatewaysFile, Configuration.class);
- switches = config.getSwitches();
- interfaces = new HashMap<String, Interface>();
- for (Interface intf : config.getInterfaces()){
- interfaces.put(intf.getName(), intf);
- }
- bgpPeers = new HashMap<InetAddress, BgpPeer>();
- for (BgpPeer peer : config.getPeers()){
- bgpPeers.put(peer.getIpAddress(), peer);
- }
+ switches = config.getSwitches();
+ interfaces = new HashMap<String, Interface>();
+ for (Interface intf : config.getInterfaces()) {
+ interfaces.put(intf.getName(), intf);
+ }
+ bgpPeers = new HashMap<InetAddress, BgpPeer>();
+ for (BgpPeer peer : config.getPeers()) {
+ bgpPeers.put(peer.getIpAddress(), peer);
+ }
- bgpdAttachmentPoint = new SwitchPort(
- new Dpid(config.getBgpdAttachmentDpid()),
- new Port(config.getBgpdAttachmentPort()));
+ bgpdAttachmentPoint = new SwitchPort(
+ new Dpid(config.getBgpdAttachmentDpid()),
+ new Port(config.getBgpdAttachmentPort()));
- bgpdMacAddress = config.getBgpdMacAddress();
- vlan = config.getVlan();
- } catch (JsonParseException e) {
- log.error("Error in JSON file", e);
- System.exit(1);
- } catch (JsonMappingException e) {
- log.error("Error in JSON file", e);
- System.exit(1);
- } catch (IOException e) {
- log.error("Error reading JSON file", e);
- System.exit(1);
- }
+ bgpdMacAddress = config.getBgpdMacAddress();
+ vlan = config.getVlan();
+ } catch (JsonParseException e) {
+ log.error("Error in JSON file", e);
+ System.exit(1);
+ } catch (JsonMappingException e) {
+ log.error("Error in JSON file", e);
+ System.exit(1);
+ } catch (IOException e) {
+ log.error("Error reading JSON file", e);
+ System.exit(1);
+ }
- //Populate the interface Patricia Trie
- for (Interface intf : interfaces.values()) {
- Prefix prefix = new Prefix(intf.getIpAddress().getAddress(), intf.getPrefixLength());
- interfacePtrie.put(prefix, intf);
- }
- }
+ //Populate the interface Patricia Trie
+ for (Interface intf : interfaces.values()) {
+ Prefix prefix = new Prefix(intf.getIpAddress().getAddress(), intf.getPrefixLength());
+ interfacePtrie.put(prefix, intf);
+ }
+ }
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l
- = new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IBgpRouteService.class);
- l.add(IConfigInfoService.class);
- return l;
- }
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+ Collection<Class<? extends IFloodlightService>> l
+ = new ArrayList<Class<? extends IFloodlightService>>();
+ l.add(IBgpRouteService.class);
+ l.add(IConfigInfoService.class);
+ return l;
+ }
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
- Map<Class<? extends IFloodlightService>, IFloodlightService> m
- = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
- m.put(IBgpRouteService.class, this);
- m.put(IConfigInfoService.class, this);
- return m;
- }
+ @Override
+ public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+ Map<Class<? extends IFloodlightService>, IFloodlightService> m
+ = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+ m.put(IBgpRouteService.class, this);
+ m.put(IConfigInfoService.class, this);
+ return m;
+ }
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l
- = new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- l.add(IRestApiService.class);
- return l;
- }
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+ Collection<Class<? extends IFloodlightService>> l
+ = new ArrayList<Class<? extends IFloodlightService>>();
+ l.add(IFloodlightProviderService.class);
+ l.add(IRestApiService.class);
+ return l;
+ }
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
+ @Override
+ public void init(FloodlightModuleContext context)
+ throws FloodlightModuleException {
- ptree = new PatriciaTrie<RibEntry>(32);
- interfacePtrie = new PatriciaTrie<Interface>(32);
+ ptree = new PatriciaTrie<RibEntry>(32);
+ interfacePtrie = new PatriciaTrie<Interface>(32);
- ribUpdates = new LinkedBlockingQueue<RibUpdate>();
+ ribUpdates = new LinkedBlockingQueue<RibUpdate>();
- // Register floodlight provider and REST handler.
- floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
- linkDiscoveryService = context.getServiceImpl(ILinkDiscoveryService.class);
- restApi = context.getServiceImpl(IRestApiService.class);
- proxyArp = context.getServiceImpl(IProxyArpService.class);
+ // Register floodlight provider and REST handler.
+ floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+ linkDiscoveryService = context.getServiceImpl(ILinkDiscoveryService.class);
+ restApi = context.getServiceImpl(IRestApiService.class);
+ proxyArp = context.getServiceImpl(IProxyArpService.class);
- linkUpdates = new ArrayList<LDUpdate>();
- ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
- topologyChangeDetectorTask = new SingletonTask(executor, new TopologyChangeDetector());
+ linkUpdates = new ArrayList<LDUpdate>();
+ ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
+ topologyChangeDetectorTask = new SingletonTask(executor, new TopologyChangeDetector());
- pathsWaitingOnArp = new HashMap<InetAddress, Path>();
- prefixesWaitingOnArp = Multimaps.synchronizedSetMultimap(
- HashMultimap.<InetAddress, RibUpdate>create());
+ pathsWaitingOnArp = new HashMap<InetAddress, Path>();
+ prefixesWaitingOnArp = Multimaps.synchronizedSetMultimap(
+ HashMultimap.<InetAddress, RibUpdate>create());
- pushedPaths = new HashMap<InetAddress, Path>();
- prefixToPath = new HashMap<Prefix, Path>();
-// pushedFlows = HashMultimap.<Prefix, PushedFlowMod>create();
- pushedFlowIds = HashMultimap.<Prefix, FlowId>create();
+ pushedPaths = new HashMap<InetAddress, Path>();
+ prefixToPath = new HashMap<Prefix, Path>();
+// pushedFlows = HashMultimap.<Prefix, PushedFlowMod>create();
+ pushedFlowIds = HashMultimap.<Prefix, FlowId>create();
- flowCache = new FlowCache(floodlightProvider);
+ flowCache = new FlowCache(floodlightProvider);
- bgpUpdatesExecutor = Executors.newSingleThreadExecutor(
- new ThreadFactoryBuilder().setNameFormat("bgp-updates-%d").build());
+ bgpUpdatesExecutor = Executors.newSingleThreadExecutor(
+ new ThreadFactoryBuilder().setNameFormat("bgp-updates-%d").build());
- //Read in config values
- bgpdRestIp = context.getConfigParams(this).get("BgpdRestIp");
- if (bgpdRestIp == null){
- log.error("BgpdRestIp property not found in config file");
- System.exit(1);
- }
- else {
- log.info("BgpdRestIp set to {}", bgpdRestIp);
- }
+ //Read in config values
+ bgpdRestIp = context.getConfigParams(this).get("BgpdRestIp");
+ if (bgpdRestIp == null) {
+ log.error("BgpdRestIp property not found in config file");
+ System.exit(1);
+ } else {
+ log.info("BgpdRestIp set to {}", bgpdRestIp);
+ }
- routerId = context.getConfigParams(this).get("RouterId");
- if (routerId == null){
- log.error("RouterId property not found in config file");
- System.exit(1);
- }
- else {
- log.info("RouterId set to {}", routerId);
- }
+ routerId = context.getConfigParams(this).get("RouterId");
+ if (routerId == null) {
+ log.error("RouterId property not found in config file");
+ System.exit(1);
+ } else {
+ log.info("RouterId set to {}", routerId);
+ }
- String configFilenameParameter = context.getConfigParams(this).get("configfile");
- if (configFilenameParameter != null){
- configFilename = configFilenameParameter;
- }
- log.debug("Config file set to {}", configFilename);
+ String configFilenameParameter = context.getConfigParams(this).get("configfile");
+ if (configFilenameParameter != null) {
+ configFilename = configFilenameParameter;
+ }
+ log.debug("Config file set to {}", configFilename);
- readConfiguration(configFilename);
- }
+ readConfiguration(configFilename);
+ }
- @Override
- public void startUp(FloodlightModuleContext context) {
- restApi.addRestletRoutable(new BgpRouteWebRoutable());
- floodlightProvider.addOFSwitchListener(this);
+ @Override
+ public void startUp(FloodlightModuleContext context) {
+ restApi.addRestletRoutable(new BgpRouteWebRoutable());
+ floodlightProvider.addOFSwitchListener(this);
- //Retrieve the RIB from BGPd during startup
- retrieveRib();
- }
+ //Retrieve the RIB from BGPd during startup
+ retrieveRib();
+ }
- @Override
- public IPatriciaTrie<RibEntry> getPtree() {
- return ptree;
- }
+ @Override
+ public IPatriciaTrie<RibEntry> getPtree() {
+ return ptree;
+ }
- @Override
- public void clearPtree() {
- ptree = new PatriciaTrie<RibEntry>(32);
- }
+ @Override
+ public void clearPtree() {
+ ptree = new PatriciaTrie<RibEntry>(32);
+ }
- @Override
- public String getBGPdRestIp() {
- return bgpdRestIp;
- }
+ @Override
+ public String getBGPdRestIp() {
+ return bgpdRestIp;
+ }
- @Override
- public String getRouterId() {
- return routerId;
- }
+ @Override
+ public String getRouterId() {
+ return routerId;
+ }
- private void retrieveRib(){
- String url = "http://" + bgpdRestIp + "/wm/bgp/" + routerId;
- String response = RestClient.get(url);
+ private void retrieveRib() {
+ String url = "http://" + bgpdRestIp + "/wm/bgp/" + routerId;
+ String response = RestClient.get(url);
- if (response.equals("")){
- return;
- }
+ if (response.equals("")) {
+ return;
+ }
- response = response.replaceAll("\"", "'");
- JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(response);
- JSONArray rib_json_array = jsonObj.getJSONArray("rib");
- String router_id = jsonObj.getString("router-id");
+ response = response.replaceAll("\"", "'");
+ JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(response);
+ JSONArray rib_json_array = jsonObj.getJSONArray("rib");
+ String router_id = jsonObj.getString("router-id");
- int size = rib_json_array.size();
+ int size = rib_json_array.size();
- log.info("Retrived RIB of {} entries from BGPd", size);
+ log.info("Retrived RIB of {} entries from BGPd", size);
- for (int j = 0; j < size; j++) {
- JSONObject second_json_object = rib_json_array.getJSONObject(j);
- String prefix = second_json_object.getString("prefix");
- String nexthop = second_json_object.getString("nexthop");
+ for (int j = 0; j < size; j++) {
+ JSONObject second_json_object = rib_json_array.getJSONObject(j);
+ String prefix = second_json_object.getString("prefix");
+ String nexthop = second_json_object.getString("nexthop");
- //insert each rib entry into the local rib;
- String[] substring = prefix.split("/");
- String prefix1 = substring[0];
- String mask1 = substring[1];
+ //insert each rib entry into the local rib;
+ String[] substring = prefix.split("/");
+ String prefix1 = substring[0];
+ String mask1 = substring[1];
- Prefix p;
- try {
- p = new Prefix(prefix1, Integer.valueOf(mask1));
- } catch (NumberFormatException e) {
- log.warn("Wrong mask format in RIB JSON: {}", mask1);
- continue;
- } catch (IllegalArgumentException e1) {
- log.warn("Wrong prefix format in RIB JSON: {}", prefix1);
- continue;
- }
+ Prefix p;
+ try {
+ p = new Prefix(prefix1, Integer.valueOf(mask1));
+ } catch (NumberFormatException e) {
+ log.warn("Wrong mask format in RIB JSON: {}", mask1);
+ continue;
+ } catch (IllegalArgumentException e1) {
+ log.warn("Wrong prefix format in RIB JSON: {}", prefix1);
+ continue;
+ }
- RibEntry rib = new RibEntry(router_id, nexthop);
+ RibEntry rib = new RibEntry(router_id, nexthop);
- try {
- ribUpdates.put(new RibUpdate(Operation.UPDATE, p, rib));
- } catch (InterruptedException e) {
- log.debug("Interrupted while pushing onto update queue");
- }
- }
- }
+ try {
+ ribUpdates.put(new RibUpdate(Operation.UPDATE, p, rib));
+ } catch (InterruptedException e) {
+ log.debug("Interrupted while pushing onto update queue");
+ }
+ }
+ }
- @Override
- public void newRibUpdate(RibUpdate update) {
- try {
- ribUpdates.put(update);
- } catch (InterruptedException e) {
- log.debug("Interrupted while putting on ribUpdates queue", e);
- Thread.currentThread().interrupt();
- }
- }
+ @Override
+ public void newRibUpdate(RibUpdate update) {
+ try {
+ ribUpdates.put(update);
+ } catch (InterruptedException e) {
+ log.debug("Interrupted while putting on ribUpdates queue", e);
+ Thread.currentThread().interrupt();
+ }
+ }
- public synchronized void processRibAdd(RibUpdate update) {
- Prefix prefix = update.getPrefix();
+ public synchronized void processRibAdd(RibUpdate update) {
+ Prefix prefix = update.getPrefix();
- log.debug("Processing prefix add {}", prefix);
+ log.debug("Processing prefix add {}", prefix);
- RibEntry rib = ptree.put(prefix, update.getRibEntry());
+ RibEntry rib = ptree.put(prefix, update.getRibEntry());
- if (rib != null && !rib.equals(update.getRibEntry())) {
- //There was an existing nexthop for this prefix. This update supersedes that,
- //so we need to remove the old flows for this prefix from the switches
- _processDeletePrefix(prefix, rib);
- }
+ if (rib != null && !rib.equals(update.getRibEntry())) {
+ //There was an existing nexthop for this prefix. This update supersedes that,
+ //so we need to remove the old flows for this prefix from the switches
+ _processDeletePrefix(prefix, rib);
+ }
- if (update.getRibEntry().getNextHop().equals(
- InetAddresses.forString("0.0.0.0"))) {
- //Route originated by SDN domain
- //We don't handle these at the moment
- log.debug("Own route {} to {}", prefix,
- update.getRibEntry().getNextHop().getHostAddress());
- return;
- }
+ if (update.getRibEntry().getNextHop().equals(
+ InetAddresses.forString("0.0.0.0"))) {
+ //Route originated by SDN domain
+ //We don't handle these at the moment
+ log.debug("Own route {} to {}", prefix,
+ update.getRibEntry().getNextHop().getHostAddress());
+ return;
+ }
- _processRibAdd(update);
- }
+ _processRibAdd(update);
+ }
- private void _processRibAdd(RibUpdate update) {
- Prefix prefix = update.getPrefix();
- RibEntry rib = update.getRibEntry();
+ private void _processRibAdd(RibUpdate update) {
+ Prefix prefix = update.getPrefix();
+ RibEntry rib = update.getRibEntry();
- InetAddress dstIpAddress = rib.getNextHop();
- MACAddress nextHopMacAddress = null;
+ InetAddress dstIpAddress = rib.getNextHop();
+ MACAddress nextHopMacAddress = null;
- // See if we know the MAC address of the next hop
- // TODO if we do not treat the next hop as a device in the future, we need to update this
- // TODO: Fix the code below after deviceStorage was removed
- /*
- IDeviceObject nextHopDevice =
- deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(dstIpAddress));
+ // See if we know the MAC address of the next hop
+ // TODO if we do not treat the next hop as a device in the future, we need to update this
+ // TODO: Fix the code below after deviceStorage was removed
+ /*
+ IDeviceObject nextHopDevice =
+ deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(dstIpAddress));
- if (nextHopDevice == null){
- log.debug("NextHopDevice for IP: {} is null", dstIpAddress);
- prefixesWaitingOnArp.put(dstIpAddress,
- new RibUpdate(Operation.UPDATE, prefix, rib));
- proxyArp.sendArpRequest(dstIpAddress, this, true);
- return;
+ if (nextHopDevice == null){
+ log.debug("NextHopDevice for IP: {} is null", dstIpAddress);
+ prefixesWaitingOnArp.put(dstIpAddress,
+ new RibUpdate(Operation.UPDATE, prefix, rib));
+ proxyArp.sendArpRequest(dstIpAddress, this, true);
+ return;
- }
- nextHopMacAddress = MACAddress.valueOf(nextHopDevice.getMACAddress());
- */
+ }
+ nextHopMacAddress = MACAddress.valueOf(nextHopDevice.getMACAddress());
+ */
- // Find the attachment point (egress interface) of the next hop
- Interface egressInterface = null;
- if (bgpPeers.containsKey(dstIpAddress)) {
- //Route to a peer
- log.debug("Route to peer {}", dstIpAddress);
- BgpPeer peer = bgpPeers.get(dstIpAddress);
- egressInterface = interfaces.get(peer.getInterfaceName());
- }
- else {
- //Route to non-peer
- log.debug("Route to non-peer {}", dstIpAddress);
- egressInterface = interfacePtrie.match(
- new Prefix(dstIpAddress.getAddress(), 32));
- if (egressInterface == null) {
- log.warn("No outgoing interface found for {}", dstIpAddress.getHostAddress());
- return;
- }
- }
+ // Find the attachment point (egress interface) of the next hop
+ Interface egressInterface = null;
+ if (bgpPeers.containsKey(dstIpAddress)) {
+ //Route to a peer
+ log.debug("Route to peer {}", dstIpAddress);
+ BgpPeer peer = bgpPeers.get(dstIpAddress);
+ egressInterface = interfaces.get(peer.getInterfaceName());
+ } else {
+ //Route to non-peer
+ log.debug("Route to non-peer {}", dstIpAddress);
+ egressInterface = interfacePtrie.match(
+ new Prefix(dstIpAddress.getAddress(), 32));
+ if (egressInterface == null) {
+ log.warn("No outgoing interface found for {}", dstIpAddress.getHostAddress());
+ return;
+ }
+ }
- if (nextHopMacAddress == null) {
- prefixesWaitingOnArp.put(dstIpAddress,
- new RibUpdate(Operation.UPDATE, prefix, rib));
- proxyArp.sendArpRequest(dstIpAddress, this, true);
- return;
- }
- else {
- if (!bgpPeers.containsKey(dstIpAddress)) {
- //If the prefix is for a non-peer we need to ensure there's a path,
- //and push one if there isn't.
- Path path = pushedPaths.get(dstIpAddress);
- if (path == null) {
- path = new Path(egressInterface, dstIpAddress);
- calculateAndPushPath(path, nextHopMacAddress);
- pushedPaths.put(dstIpAddress, path);
- }
+ if (nextHopMacAddress == null) {
+ prefixesWaitingOnArp.put(dstIpAddress,
+ new RibUpdate(Operation.UPDATE, prefix, rib));
+ proxyArp.sendArpRequest(dstIpAddress, this, true);
+ return;
+ } else {
+ if (!bgpPeers.containsKey(dstIpAddress)) {
+ //If the prefix is for a non-peer we need to ensure there's a path,
+ //and push one if there isn't.
+ Path path = pushedPaths.get(dstIpAddress);
+ if (path == null) {
+ path = new Path(egressInterface, dstIpAddress);
+ calculateAndPushPath(path, nextHopMacAddress);
+ pushedPaths.put(dstIpAddress, path);
+ }
- path.incrementUsers();
- prefixToPath.put(prefix, path);
- }
+ path.incrementUsers();
+ prefixToPath.put(prefix, path);
+ }
- //For all prefixes we need to add the first-hop mac-rewriting flows
- addPrefixFlows(prefix, egressInterface, nextHopMacAddress);
- }
- }
+ //For all prefixes we need to add the first-hop mac-rewriting flows
+ addPrefixFlows(prefix, egressInterface, nextHopMacAddress);
+ }
+ }
- /**
- * Add a flow to match dst-IP prefix and rewrite MAC for one IP prefix
- * to all other border switches
- */
- private void addPrefixFlows(Prefix prefix, Interface egressInterface,
- MACAddress nextHopMacAddress) {
- log.debug("Adding flows for prefix {}, next hop mac {}",
- prefix, nextHopMacAddress);
+ /**
+ * Add a flow to match dst-IP prefix and rewrite MAC for one IP prefix
+ * to all other border switches
+ */
+ private void addPrefixFlows(Prefix prefix, Interface egressInterface,
+ MACAddress nextHopMacAddress) {
+ log.debug("Adding flows for prefix {}, next hop mac {}",
+ prefix, nextHopMacAddress);
- FlowPath flowPath = new FlowPath();
- flowPath.setInstallerId(new CallerId("SDNIP"));
+ FlowPath flowPath = new FlowPath();
+ flowPath.setInstallerId(new CallerId("SDNIP"));
- // Set flowPath FlowPathType and FlowPathUserState
- flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
- flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
+ // Set flowPath FlowPathType and FlowPathUserState
+ flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
+ flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
- // Insert dst-ip prefix based forwarding and MAC rewrite flow entry
- // only to the first-host switches
- FlowPathFlags flowPathFlags = new FlowPathFlags();
- flowPathFlags.setFlags(FlowPathFlags.KEEP_ONLY_FIRST_HOP_ENTRY);
- flowPath.setFlowPathFlags(flowPathFlags);
+ // Insert dst-ip prefix based forwarding and MAC rewrite flow entry
+ // only to the first-host switches
+ FlowPathFlags flowPathFlags = new FlowPathFlags();
+ flowPathFlags.setFlags(FlowPathFlags.KEEP_ONLY_FIRST_HOP_ENTRY);
+ flowPath.setFlowPathFlags(flowPathFlags);
- // Create the DataPath object: dstSwitchPort
- SwitchPort dstPort = new SwitchPort();
- dstPort.setDpid(new Dpid(egressInterface.getDpid()));
- dstPort.setPort(new Port(egressInterface.getPort()));
+ // Create the DataPath object: dstSwitchPort
+ SwitchPort dstPort = new SwitchPort();
+ dstPort.setDpid(new Dpid(egressInterface.getDpid()));
+ dstPort.setPort(new Port(egressInterface.getPort()));
- // 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.equals(egressInterface)) {
- srcInterfaces.put(intf.getDpid(), intf);
- }
- }
- for (Interface srcInterface : srcInterfaces.values()) {
+ // 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.equals(egressInterface)) {
+ srcInterfaces.put(intf.getDpid(), intf);
+ }
+ }
+ for (Interface srcInterface : srcInterfaces.values()) {
- if (egressInterface.equals(srcInterface)){
- continue;
- }
+ if (egressInterface.equals(srcInterface)) {
+ continue;
+ }
- // Create flowPath FlowId
- flowPath.setFlowId(new FlowId());
+ // Create flowPath FlowId
+ flowPath.setFlowId(new FlowId());
- // Create DataPath object: srcSwitchPort
- SwitchPort srcPort = new SwitchPort();
- srcPort.setDpid(new Dpid(srcInterface.getDpid()));
- srcPort.setPort(new Port(srcInterface.getPort()));
+ // Create DataPath object: srcSwitchPort
+ SwitchPort srcPort = new SwitchPort();
+ srcPort.setDpid(new Dpid(srcInterface.getDpid()));
+ srcPort.setPort(new Port(srcInterface.getPort()));
- DataPath dataPath = new DataPath();
- dataPath.setSrcPort(srcPort);
- dataPath.setDstPort(dstPort);
- flowPath.setDataPath(dataPath);
+ DataPath dataPath = new DataPath();
+ dataPath.setSrcPort(srcPort);
+ dataPath.setDstPort(dstPort);
+ flowPath.setDataPath(dataPath);
- // Create flow path matching condition(s): IPv4 Prefix
- FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
- flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPv4);
- IPv4Net dstIPv4Net= new IPv4Net(prefix.toString());
- flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
- flowPath.setFlowEntryMatch(flowEntryMatch);
+ // Create flow path matching condition(s): IPv4 Prefix
+ FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
+ flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPv4);
+ IPv4Net dstIPv4Net = new IPv4Net(prefix.toString());
+ flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
+ flowPath.setFlowEntryMatch(flowEntryMatch);
- /*
- * Create the Flow Entry Action(s): dst-MAC rewrite action
- */
- FlowEntryActions flowEntryActions = new FlowEntryActions();
- FlowEntryAction flowEntryAction1 = new FlowEntryAction();
- flowEntryAction1.setActionSetEthernetDstAddr(nextHopMacAddress);
- // flowEntryAction1.actionSetEthernetDstAddr(nextHopMacAddress);
- flowEntryActions.addAction(flowEntryAction1);
- flowPath.setFlowEntryActions(flowEntryActions);
+ /*
+ * Create the Flow Entry Action(s): dst-MAC rewrite action
+ */
+ FlowEntryActions flowEntryActions = new FlowEntryActions();
+ FlowEntryAction flowEntryAction1 = new FlowEntryAction();
+ flowEntryAction1.setActionSetEthernetDstAddr(nextHopMacAddress);
+ // flowEntryAction1.actionSetEthernetDstAddr(nextHopMacAddress);
+ flowEntryActions.addAction(flowEntryAction1);
+ flowPath.setFlowEntryActions(flowEntryActions);
- // Flow Path installation, only to first hop switches
- // TODO: Add the flow by using the new Path Intent framework
- /*
- if (flowManagerService.addFlow(flowPath) == null) {
- log.error("Failed to install flow path to the first hop for " +
- "prefix: {}, nextHopMacAddress: {}", prefix.getAddress(),
- nextHopMacAddress);
- }
- else {
- log.debug("Successfully installed flow path to the first hop " +
- "for prefix: {}, nextHopMacAddress: {}", prefix.getAddress(),
- nextHopMacAddress);
+ // Flow Path installation, only to first hop switches
+ // TODO: Add the flow by using the new Path Intent framework
+ /*
+ if (flowManagerService.addFlow(flowPath) == null) {
+ log.error("Failed to install flow path to the first hop for " +
+ "prefix: {}, nextHopMacAddress: {}", prefix.getAddress(),
+ nextHopMacAddress);
+ }
+ else {
+ log.debug("Successfully installed flow path to the first hop " +
+ "for prefix: {}, nextHopMacAddress: {}", prefix.getAddress(),
+ nextHopMacAddress);
- pushedFlowIds.put(prefix, flowPath.flowId());
- }
- */
- }
- }
+ pushedFlowIds.put(prefix, flowPath.flowId());
+ }
+ */
+ }
+ }
- public synchronized void processRibDelete(RibUpdate update) {
- Prefix prefix = update.getPrefix();
+ public synchronized void processRibDelete(RibUpdate update) {
+ Prefix prefix = update.getPrefix();
- if (ptree.remove(prefix, update.getRibEntry())) {
- /*
- * Only delete flows if an entry was actually removed from the trie.
- * If no entry was removed, the <prefix, nexthop> wasn't there so
- * it's probably already been removed and we don't need to do anything
- */
- _processDeletePrefix(prefix, update.getRibEntry());
- }
- }
+ if (ptree.remove(prefix, update.getRibEntry())) {
+ /*
+ * Only delete flows if an entry was actually removed from the trie.
+ * If no entry was removed, the <prefix, nexthop> wasn't there so
+ * it's probably already been removed and we don't need to do anything
+ */
+ _processDeletePrefix(prefix, update.getRibEntry());
+ }
+ }
- private void _processDeletePrefix(Prefix prefix, RibEntry ribEntry) {
- deletePrefixFlows(prefix);
+ private void _processDeletePrefix(Prefix prefix, RibEntry ribEntry) {
+ deletePrefixFlows(prefix);
- log.debug("Deleting {} to {}", prefix, ribEntry.getNextHop());
+ log.debug("Deleting {} to {}", prefix, ribEntry.getNextHop());
- if (!bgpPeers.containsKey(ribEntry.getNextHop())) {
- log.debug("Getting path for route with non-peer nexthop");
- Path path = prefixToPath.remove(prefix);
+ if (!bgpPeers.containsKey(ribEntry.getNextHop())) {
+ log.debug("Getting path for route with non-peer nexthop");
+ Path path = prefixToPath.remove(prefix);
- 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
+ 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();
- if (path.getUsers() <= 0 && !path.isPermanent()) {
- deletePath(path);
- pushedPaths.remove(path.getDstIpAddress());
- }
- }
- }
- }
+ path.decrementUsers();
+ if (path.getUsers() <= 0 && !path.isPermanent()) {
+ deletePath(path);
+ pushedPaths.remove(path.getDstIpAddress());
+ }
+ }
+ }
+ }
- // TODO have not tested this module
- private void deletePrefixFlows(Prefix prefix) {
- log.debug("Deleting flows for prefix {}", prefix);
+ // TODO have not tested this module
+ private void deletePrefixFlows(Prefix prefix) {
+ log.debug("Deleting flows for prefix {}", prefix);
- Collection<FlowId> flowIds = pushedFlowIds.removeAll(prefix);
- for (FlowId flowId : flowIds) {
- // TODO: Delete the flow by using the new Path Intent framework
- /*
- if (log.isTraceEnabled()) {
- //Trace the flow status by flowPath in the switch before deleting it
- log.trace("Pushing a DELETE flow mod to flowPath : {}",
- flowManagerService.getFlow(flowId).toString());
- }
+ Collection<FlowId> flowIds = pushedFlowIds.removeAll(prefix);
+ for (FlowId flowId : flowIds) {
+ // TODO: Delete the flow by using the new Path Intent framework
+ /*
+ if (log.isTraceEnabled()) {
+ //Trace the flow status by flowPath in the switch before deleting it
+ log.trace("Pushing a DELETE flow mod to flowPath : {}",
+ flowManagerService.getFlow(flowId).toString());
+ }
- if( flowManagerService.deleteFlow(flowId))
- {
- log.debug("Successfully deleted FlowId: {}",flowId);
- }
- else
- {
- log.debug("Failed to delete FlowId: {}",flowId);
- }
- */
- }
- }
+ if( flowManagerService.deleteFlow(flowId))
+ {
+ log.debug("Successfully deleted FlowId: {}",flowId);
+ }
+ else
+ {
+ log.debug("Failed to delete FlowId: {}",flowId);
+ }
+ */
+ }
+ }
- // TODO need to record the path and then delete here
- private void deletePath(Path path) {
- log.debug("Deleting flows for path to {}",
- path.getDstIpAddress().getHostAddress());
+ // TODO need to record the path and then delete here
+ private void deletePath(Path path) {
+ log.debug("Deleting flows for path to {}",
+ path.getDstIpAddress().getHostAddress());
- // TODO need update
- /*for (PushedFlowMod pfm : path.getFlowMods()) {
- 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())
- });
- }
+ // TODO need update
+ /*for (PushedFlowMod pfm : path.getFlowMods()) {
+ 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());
- }*/
- }
+ sendDeleteFlowMod(pfm.getFlowMod(), pfm.getDpid());
+ }*/
+ }
- //TODO test next-hop changes
- //TODO check delete/add synchronization
+ //TODO test next-hop changes
+ //TODO check delete/add synchronization
- /**
- * On startup, we need to calculate a full mesh of paths between all gateway
- * switches
- */
- private void setupFullMesh(){
- //For each border router, calculate and install a path from every other
- //border switch to said border router. However, don't install the entry
- //in to the first hop switch, as we need to install an entry to rewrite
- //for each prefix received. This will be done later when prefixes have
- //actually been received.
+ /**
+ * On startup, we need to calculate a full mesh of paths between all gateway
+ * switches
+ */
+ private void setupFullMesh() {
+ //For each border router, calculate and install a path from every other
+ //border switch to said border router. However, don't install the entry
+ //in to the first hop switch, as we need to install an entry to rewrite
+ //for each prefix received. This will be done later when prefixes have
+ //actually been received.
- for (BgpPeer peer : bgpPeers.values()) {
- Interface peerInterface = interfaces.get(peer.getInterfaceName());
+ for (BgpPeer peer : bgpPeers.values()) {
+ Interface peerInterface = interfaces.get(peer.getInterfaceName());
- //We know there's not already a Path here pushed, because this is
- //called before all other routing
- Path path = new Path(peerInterface, peer.getIpAddress());
- path.setPermanent();
+ //We know there's not already a Path here pushed, because this is
+ //called before all other routing
+ Path path = new Path(peerInterface, peer.getIpAddress());
+ path.setPermanent();
- //See if we know the MAC address of the peer. If not we can't
- //do anything until we learn it
- // TODO: Fix the code below after deviceStorage was removed
- MACAddress macAddress = null;
- /*
- IDeviceObject nextHopDevice =
- deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(peer.getIpAddress()));
+ //See if we know the MAC address of the peer. If not we can't
+ //do anything until we learn it
+ // TODO: Fix the code below after deviceStorage was removed
+ MACAddress macAddress = null;
+ /*
+ IDeviceObject nextHopDevice =
+ deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(peer.getIpAddress()));
- if(nextHopDevice == null){
- log.debug("There is no DeviceObject for {}", peer.getIpAddress().getHostAddress());
- //Put in the pending paths list first
- pathsWaitingOnArp.put(peer.getIpAddress(), path);
- proxyArp.sendArpRequest(peer.getIpAddress(), this, true);
- continue;
- }
+ if(nextHopDevice == null){
+ log.debug("There is no DeviceObject for {}", peer.getIpAddress().getHostAddress());
+ //Put in the pending paths list first
+ pathsWaitingOnArp.put(peer.getIpAddress(), path);
+ proxyArp.sendArpRequest(peer.getIpAddress(), this, true);
+ continue;
+ }
- macAddress = MACAddress.valueOf(nextHopDevice.getMACAddress());
- */
+ macAddress = MACAddress.valueOf(nextHopDevice.getMACAddress());
+ */
- if (macAddress == null) {
- log.debug("Don't know MAC for {}", peer.getIpAddress().getHostAddress());
- //Put in the pending paths list first
- pathsWaitingOnArp.put(peer.getIpAddress(), path);
- proxyArp.sendArpRequest(peer.getIpAddress(), this, true);
- continue;
- }
+ if (macAddress == null) {
+ log.debug("Don't know MAC for {}", peer.getIpAddress().getHostAddress());
+ //Put in the pending paths list first
+ pathsWaitingOnArp.put(peer.getIpAddress(), path);
+ proxyArp.sendArpRequest(peer.getIpAddress(), this, true);
+ continue;
+ }
- //If we know the MAC, lets go ahead and push the paths to this peer
- calculateAndPushPath(path, macAddress);
- }
- }
+ //If we know the MAC, lets go ahead and push the paths to this peer
+ calculateAndPushPath(path, macAddress);
+ }
+ }
- private void calculateAndPushPath(Path path, MACAddress dstMacAddress) {
- Interface dstInterface = path.getDstInterface();
+ private void calculateAndPushPath(Path path, MACAddress dstMacAddress) {
+ Interface dstInterface = path.getDstInterface();
- log.debug("Setting up path to {}, {}", path.getDstIpAddress().getHostAddress(),
- dstMacAddress);
+ log.debug("Setting up path to {}, {}", path.getDstIpAddress().getHostAddress(),
+ dstMacAddress);
- FlowPath flowPath = new FlowPath();
+ FlowPath flowPath = new FlowPath();
- flowPath.setInstallerId(new CallerId("SDNIP"));
+ flowPath.setInstallerId(new CallerId("SDNIP"));
- // Set flowPath FlowPathType and FlowPathUserState
- flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
- flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
+ // Set flowPath FlowPathType and FlowPathUserState
+ flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
+ flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
- // Insert the dest-mac based forwarding flow entry to the non-first-hop switches
- FlowPathFlags flowPathFlags = new FlowPathFlags();
- flowPathFlags.setFlags(FlowPathFlags.DISCARD_FIRST_HOP_ENTRY);
- flowPath.setFlowPathFlags(flowPathFlags);
+ // Insert the dest-mac based forwarding flow entry to the non-first-hop switches
+ FlowPathFlags flowPathFlags = new FlowPathFlags();
+ flowPathFlags.setFlags(FlowPathFlags.DISCARD_FIRST_HOP_ENTRY);
+ flowPath.setFlowPathFlags(flowPathFlags);
+
+ // Create the DataPath object: dstSwitchPort
+ SwitchPort dstPort = new SwitchPort();
+ dstPort.setDpid(new Dpid(dstInterface.getDpid()));
+ dstPort.setPort(new Port(dstInterface.getPort()));
- // Create the DataPath object: dstSwitchPort
- SwitchPort dstPort = new SwitchPort();
- dstPort.setDpid(new Dpid(dstInterface.getDpid()));
- dstPort.setPort(new Port(dstInterface.getPort()));
+ for (Interface srcInterface : interfaces.values()) {
- for (Interface srcInterface : interfaces.values()) {
+ if (dstInterface.equals(srcInterface)) {
+ continue;
+ }
- if (dstInterface.equals(srcInterface)){
- continue;
- }
+ // Create flowPath FlowId
+ flowPath.setFlowId(new FlowId());
- // Create flowPath FlowId
- flowPath.setFlowId(new FlowId());
+ // Create the DataPath object: srcSwitchPort
+ SwitchPort srcPort = new SwitchPort();
+ srcPort.setDpid(new Dpid(srcInterface.getDpid()));
+ srcPort.setPort(new Port(srcInterface.getPort()));
- // Create the DataPath object: srcSwitchPort
- SwitchPort srcPort = new SwitchPort();
- srcPort.setDpid(new Dpid(srcInterface.getDpid()));
- srcPort.setPort(new Port(srcInterface.getPort()));
+ DataPath dataPath = new DataPath();
+ dataPath.setSrcPort(srcPort);
+ dataPath.setDstPort(dstPort);
+ flowPath.setDataPath(dataPath);
- DataPath dataPath = new DataPath();
- dataPath.setSrcPort(srcPort);
- dataPath.setDstPort(dstPort);
- flowPath.setDataPath(dataPath);
+ // Create the Flow Path Match condition(s)
+ FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
+ flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPv4);
+ flowEntryMatch.enableDstMac(dstMacAddress);
+ flowPath.setFlowEntryMatch(flowEntryMatch);
- // Create the Flow Path Match condition(s)
- FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
- flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPv4);
- flowEntryMatch.enableDstMac(dstMacAddress);
- flowPath.setFlowEntryMatch(flowEntryMatch);
+ // NOTE: No need to add ACTION_OUTPUT. It is implied when creating
+ // Shortest Path Flow, and is always the last action for the Flow Entries
+ log.debug("FlowPath of MAC based forwarding: {}", flowPath.toString());
+ // TODO: Add the flow by using the new Path Intent framework
+ /*
+ if (flowManagerService.addFlow(flowPath) == null) {
+ log.error("Failed to set up MAC based forwarding path to {}, {}",
+ path.getDstIpAddress().getHostAddress(),dstMacAddress);
+ }
+ else {
+ log.debug("Successfully set up MAC based forwarding path to {}, {}",
+ path.getDstIpAddress().getHostAddress(),dstMacAddress);
+ }
+ */
+ }
+ }
- // NOTE: No need to add ACTION_OUTPUT. It is implied when creating
- // Shortest Path Flow, and is always the last action for the Flow Entries
- log.debug("FlowPath of MAC based forwarding: {}", flowPath.toString());
- // TODO: Add the flow by using the new Path Intent framework
- /*
- if (flowManagerService.addFlow(flowPath) == null) {
- log.error("Failed to set up MAC based forwarding path to {}, {}",
- path.getDstIpAddress().getHostAddress(),dstMacAddress);
- }
- else {
- log.debug("Successfully set up MAC based forwarding path to {}, {}",
- path.getDstIpAddress().getHostAddress(),dstMacAddress);
- }
- */
- }
- }
+ /**
+ * Pre-actively install all BGP traffic paths from BGP host attachment point
+ * in SDN network to all the virtual gateways to BGP peers in other networks
+ */
+ private void setupBgpPaths() {
- /**
- * Pre-actively install all BGP traffic paths from BGP host attachment point
- * in SDN network to all the virtual gateways to BGP peers in other networks
- */
- private void setupBgpPaths(){
+ for (BgpPeer bgpPeer : bgpPeers.values()) {
- for (BgpPeer bgpPeer : bgpPeers.values()){
+ FlowPath flowPath = new FlowPath();
+ flowPath.setInstallerId(new CallerId("SDNIP"));
- FlowPath flowPath = new FlowPath();
- flowPath.setInstallerId(new CallerId("SDNIP"));
+ // Set flowPath FlowPathType and FlowPathUserState
+ flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
+ flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
- // Set flowPath FlowPathType and FlowPathUserState
- flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
- flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
+ // Install flow paths between BGPd and its peers
+ // There is no need to set the FlowPathFlags
+ flowPath.setFlowPathFlags(new FlowPathFlags(0));
- // Install flow paths between BGPd and its peers
- // There is no need to set the FlowPathFlags
- flowPath.setFlowPathFlags(new FlowPathFlags(0));
+ Interface peerInterface = interfaces.get(bgpPeer.getInterfaceName());
- Interface peerInterface = interfaces.get(bgpPeer.getInterfaceName());
+ // Create the Flow Path Match condition(s)
+ FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
+ flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPv4);
- // Create the Flow Path Match condition(s)
- FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
- flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPv4);
+ // Match both source address and dest address
+ IPv4Net dstIPv4Net = new IPv4Net(bgpPeer.getIpAddress().getHostAddress() + "/32");
+ flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
- // Match both source address and dest address
- IPv4Net dstIPv4Net= new IPv4Net(bgpPeer.getIpAddress().getHostAddress()+"/32");
- flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
+ IPv4Net srcIPv4Net = new IPv4Net(peerInterface.getIpAddress().getHostAddress() + "/32");
+ flowEntryMatch.enableSrcIPv4Net(srcIPv4Net);
- IPv4Net srcIPv4Net= new IPv4Net(peerInterface.getIpAddress().getHostAddress()+"/32");
- flowEntryMatch.enableSrcIPv4Net(srcIPv4Net);
+ // Match TCP protocol
+ flowEntryMatch.enableIpProto(IPv4.PROTOCOL_TCP);
- // Match TCP protocol
- flowEntryMatch.enableIpProto(IPv4.PROTOCOL_TCP);
+ // Match destination TCP port
+ flowEntryMatch.enableDstTcpUdpPort(BGP_PORT);
+ flowPath.setFlowEntryMatch(flowEntryMatch);
- // Match destination TCP port
- flowEntryMatch.enableDstTcpUdpPort(BGP_PORT);
- flowPath.setFlowEntryMatch(flowEntryMatch);
+ /**
+ * Create the DataPath: BGP -> BGP peer
+ */
+ // Flow path for src-TCP-port
+ DataPath dataPath = new DataPath();
- /**
- * Create the DataPath: BGP -> BGP peer
- */
- // Flow path for src-TCP-port
- DataPath dataPath = new DataPath();
+ SwitchPort srcPort = new SwitchPort();
+ srcPort.setDpid(bgpdAttachmentPoint.dpid());
+ srcPort.setPort(bgpdAttachmentPoint.port());
+ dataPath.setSrcPort(srcPort);
- SwitchPort srcPort = new SwitchPort();
- srcPort.setDpid(bgpdAttachmentPoint.dpid());
- srcPort.setPort(bgpdAttachmentPoint.port());
- dataPath.setSrcPort(srcPort);
+ SwitchPort dstPort = new SwitchPort();
+ dstPort.setDpid(new Dpid(peerInterface.getDpid()));
+ dstPort.setPort(new Port(peerInterface.getSwitchPort().port()));
+ dataPath.setDstPort(dstPort);
- SwitchPort dstPort = new SwitchPort();
- dstPort.setDpid(new Dpid(peerInterface.getDpid()));
- dstPort.setPort(new Port(peerInterface.getSwitchPort().port()));
- dataPath.setDstPort(dstPort);
+ flowPath.setDataPath(dataPath);
- flowPath.setDataPath(dataPath);
+ // TODO: Add the flow by using the new Path Intent framework
+ /*
+ if (flowManagerService.addFlow(flowPath) == null) {
+ log.error("Failed to set up path BGP -> peer {}"+"; dst-TCP-port:179",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ else {
+ log.debug("Successfully set up path BGP -> peer {}"+"; dst-TCP-port:179",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ */
- // TODO: Add the flow by using the new Path Intent framework
- /*
- if (flowManagerService.addFlow(flowPath) == null) {
- log.error("Failed to set up path BGP -> peer {}"+"; dst-TCP-port:179",
- bgpPeer.getIpAddress().getHostAddress());
- }
- else {
- log.debug("Successfully set up path BGP -> peer {}"+"; dst-TCP-port:179",
- bgpPeer.getIpAddress().getHostAddress());
- }
- */
+ // Disable dst-TCP-port, and set src-TCP-port
+ flowEntryMatch.disableDstTcpUdpPort();
+ flowEntryMatch.enableSrcTcpUdpPort(BGP_PORT);
+ flowPath.setFlowEntryMatch(flowEntryMatch);
- // Disable dst-TCP-port, and set src-TCP-port
- flowEntryMatch.disableDstTcpUdpPort();
- flowEntryMatch.enableSrcTcpUdpPort(BGP_PORT);
- flowPath.setFlowEntryMatch(flowEntryMatch);
+ // Create a new FlowId
+ flowPath.setFlowId(new FlowId());
- // Create a new FlowId
- flowPath.setFlowId(new FlowId());
+ // TODO: Add the flow by using the new Path Intent framework
+ /*
+ if (flowManagerService.addFlow(flowPath) == null) {
+ log.error("Failed to set up path BGP -> Peer {}" + "; src-TCP-port:179",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ else {
+ log.debug("Successfully set up path BGP -> Peer {}" + "; src-TCP-port:179",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ */
- // TODO: Add the flow by using the new Path Intent framework
- /*
- if (flowManagerService.addFlow(flowPath) == null) {
- log.error("Failed to set up path BGP -> Peer {}" + "; src-TCP-port:179",
- bgpPeer.getIpAddress().getHostAddress());
- }
- else {
- log.debug("Successfully set up path BGP -> Peer {}" + "; src-TCP-port:179",
- bgpPeer.getIpAddress().getHostAddress());
- }
- */
+ /**
+ * Create the DataPath: BGP <-BGP peer
+ */
+ // Reversed BGP flow path for src-TCP-port
+ flowPath.setFlowId(new FlowId());
- /**
- * Create the DataPath: BGP <-BGP peer
- */
- // Reversed BGP flow path for src-TCP-port
- flowPath.setFlowId(new FlowId());
+ DataPath reverse_dataPath = new DataPath();
- DataPath reverse_dataPath = new DataPath();
+ SwitchPort reverse_dstPort = new SwitchPort();
+ reverse_dstPort.setDpid(bgpdAttachmentPoint.dpid());
+ reverse_dstPort.setPort(bgpdAttachmentPoint.port());
+ reverse_dataPath.setDstPort(reverse_dstPort);
- SwitchPort reverse_dstPort = new SwitchPort();
- reverse_dstPort.setDpid(bgpdAttachmentPoint.dpid());
- reverse_dstPort.setPort(bgpdAttachmentPoint.port());
- reverse_dataPath.setDstPort(reverse_dstPort);
+ SwitchPort reverse_srcPort = new SwitchPort();
+ reverse_srcPort.setDpid(new Dpid(peerInterface.getDpid()));
+ reverse_srcPort.setPort(new Port(peerInterface.getSwitchPort().port()));
+ reverse_dataPath.setSrcPort(reverse_srcPort);
+ flowPath.setDataPath(reverse_dataPath);
- SwitchPort reverse_srcPort = new SwitchPort();
- reverse_srcPort.setDpid(new Dpid(peerInterface.getDpid()));
- reverse_srcPort.setPort(new Port(peerInterface.getSwitchPort().port()));
- reverse_dataPath.setSrcPort(reverse_srcPort);
- flowPath.setDataPath(reverse_dataPath);
+ // reverse the dst IP and src IP addresses
+ flowEntryMatch.enableDstIPv4Net(srcIPv4Net);
+ flowEntryMatch.enableSrcIPv4Net(dstIPv4Net);
+ flowPath.setFlowEntryMatch(flowEntryMatch);
- // reverse the dst IP and src IP addresses
- flowEntryMatch.enableDstIPv4Net(srcIPv4Net);
- flowEntryMatch.enableSrcIPv4Net(dstIPv4Net);
- flowPath.setFlowEntryMatch(flowEntryMatch);
+ log.debug("Reversed BGP FlowPath: {}", flowPath.toString());
- log.debug("Reversed BGP FlowPath: {}", flowPath.toString());
+ // TODO: Add the flow by using the new Path Intent framework
+ /*
+ if (flowManagerService.addFlow(flowPath) == null) {
- // TODO: Add the flow by using the new Path Intent framework
- /*
- if (flowManagerService.addFlow(flowPath) == null) {
+ log.error("Failed to set up path BGP <- Peer {}" + "; src-TCP-port:179",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ else {
+ log.debug("Successfully set up path BGP <- Peer {}" + "; src-TCP-port:179",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ */
- log.error("Failed to set up path BGP <- Peer {}" + "; src-TCP-port:179",
- bgpPeer.getIpAddress().getHostAddress());
- }
- else {
- log.debug("Successfully set up path BGP <- Peer {}" + "; src-TCP-port:179",
- bgpPeer.getIpAddress().getHostAddress());
- }
- */
+ // Reversed BGP flow path for dst-TCP-port
+ flowPath.setFlowId(new FlowId());
- // Reversed BGP flow path for dst-TCP-port
- flowPath.setFlowId(new FlowId());
+ // Disable src-TCP-port, and set the dst-TCP-port
+ flowEntryMatch.disableSrcTcpUdpPort();
+ flowEntryMatch.enableDstTcpUdpPort(BGP_PORT);
+ flowPath.setFlowEntryMatch(flowEntryMatch);
- // Disable src-TCP-port, and set the dst-TCP-port
- flowEntryMatch.disableSrcTcpUdpPort();
- flowEntryMatch.enableDstTcpUdpPort(BGP_PORT);
- flowPath.setFlowEntryMatch(flowEntryMatch);
+ log.debug("Reversed BGP FlowPath: {}", flowPath.toString());
- log.debug("Reversed BGP FlowPath: {}", flowPath.toString());
+ // TODO: Add the flow by using the new Path Intent framework
+ /*
+ if (flowManagerService.addFlow(flowPath) == null) {
+ log.error("Failed to setting up path BGP <- Peer {}" + "; dst-TCP-port:179",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ else {
+ log.debug("Successfully setting up path BGP <- Peer {}" + "; dst-TCP-port:179",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ */
- // TODO: Add the flow by using the new Path Intent framework
- /*
- if (flowManagerService.addFlow(flowPath) == null) {
- log.error("Failed to setting up path BGP <- Peer {}" + "; dst-TCP-port:179",
- bgpPeer.getIpAddress().getHostAddress());
- }
- else {
- log.debug("Successfully setting up path BGP <- Peer {}" + "; dst-TCP-port:179",
- bgpPeer.getIpAddress().getHostAddress());
- }
- */
+ /**
+ * ICMP paths between BGPd and its peers
+ */
+ //match ICMP protocol BGP <- Peer
+ flowPath.setFlowId(new FlowId());
- /**
- * ICMP paths between BGPd and its peers
- */
- //match ICMP protocol BGP <- Peer
- flowPath.setFlowId(new FlowId());
+ flowEntryMatch.enableIpProto(IPv4.PROTOCOL_ICMP);
+ flowEntryMatch.disableSrcTcpUdpPort();
+ flowEntryMatch.disableDstTcpUdpPort();
- flowEntryMatch.enableIpProto(IPv4.PROTOCOL_ICMP);
- flowEntryMatch.disableSrcTcpUdpPort();
- flowEntryMatch.disableDstTcpUdpPort();
+ flowPath.setFlowEntryMatch(flowEntryMatch);
- flowPath.setFlowEntryMatch(flowEntryMatch);
+ flowPath.setDataPath(reverse_dataPath);
- flowPath.setDataPath(reverse_dataPath);
+ log.debug("Reversed ICMP FlowPath: {}", flowPath.toString());
- log.debug("Reversed ICMP FlowPath: {}", flowPath.toString());
+ // TODO: Add the flow by using the new Path Intent framework
+ /*
+ if (flowManagerService.addFlow(flowPath) == null) {
- // TODO: Add the flow by using the new Path Intent framework
- /*
- if (flowManagerService.addFlow(flowPath) == null) {
+ log.error("Failed to set up ICMP path BGP <- Peer {}",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ else {
+ log.debug("Successfully set up ICMP path BGP <- Peer {}",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ */
- log.error("Failed to set up ICMP path BGP <- Peer {}",
- bgpPeer.getIpAddress().getHostAddress());
- }
- else {
- log.debug("Successfully set up ICMP path BGP <- Peer {}",
- bgpPeer.getIpAddress().getHostAddress());
- }
- */
+ //match ICMP protocol BGP -> Peer
+ flowPath.setFlowId(new FlowId());
- //match ICMP protocol BGP -> Peer
- flowPath.setFlowId(new FlowId());
+ flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
+ flowEntryMatch.enableSrcIPv4Net(srcIPv4Net);
+ flowPath.setFlowEntryMatch(flowEntryMatch);
- flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
- flowEntryMatch.enableSrcIPv4Net(srcIPv4Net);
- flowPath.setFlowEntryMatch(flowEntryMatch);
+ flowPath.setDataPath(dataPath);
- flowPath.setDataPath(dataPath);
+ log.debug("ICMP flowPath: {}", flowPath.toString());
- log.debug("ICMP flowPath: {}", flowPath.toString());
+ // TODO: Add the flow by using the new Path Intent framework
+ /*
+ if (flowManagerService.addFlow(flowPath) == null) {
- // TODO: Add the flow by using the new Path Intent framework
- /*
- if (flowManagerService.addFlow(flowPath) == null) {
+ log.error("Failed to set up ICMP path BGP -> Peer {}",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ else {
+ log.debug("Successfully set up ICMP path BGP -> Peer {}",
+ bgpPeer.getIpAddress().getHostAddress());
+ }
+ */
+ }
+ }
- log.error("Failed to set up ICMP path BGP -> Peer {}",
- bgpPeer.getIpAddress().getHostAddress());
- }
- else {
- log.debug("Successfully set up ICMP path BGP -> Peer {}",
- bgpPeer.getIpAddress().getHostAddress());
- }
- */
- }
- }
+ @Override
+ public void arpResponse(InetAddress ipAddress, MACAddress macAddress) {
+ log.debug("Received ARP response: {} => {}",
+ ipAddress.getHostAddress(), macAddress);
- @Override
- public void arpResponse(InetAddress ipAddress, MACAddress macAddress) {
- log.debug("Received ARP response: {} => {}",
- ipAddress.getHostAddress(), macAddress);
+ /*
+ * We synchronize on this to prevent changes to the ptree while we're pushing
+ * flows to the switches. If the ptree changes, the ptree and switches
+ * could get out of sync.
+ */
+ synchronized (this) {
+ Path path = pathsWaitingOnArp.remove(ipAddress);
- /*
- * We synchronize on this to prevent changes to the ptree while we're pushing
- * flows to the switches. If the ptree changes, the ptree and switches
- * could get out of sync.
- */
- synchronized (this) {
- Path path = pathsWaitingOnArp.remove(ipAddress);
+ if (path != null) {
+ log.debug("Pushing path to {} at {} on {}", new Object[]{
+ path.getDstIpAddress().getHostAddress(), macAddress,
+ path.getDstInterface().getSwitchPort()});
+ //These paths should always be to BGP peers. Paths to non-peers are
+ //handled once the first prefix is ready to push
+ if (pushedPaths.containsKey(path.getDstIpAddress())) {
+ //A path already got pushed to this endpoint while we were waiting
+ //for ARP. We'll copy over the permanent attribute if it is set on this path.
+ if (path.isPermanent()) {
+ pushedPaths.get(path.getDstIpAddress()).setPermanent();
+ }
+ } else {
+ calculateAndPushPath(path, macAddress);
+ pushedPaths.put(path.getDstIpAddress(), path);
+ }
+ }
- if (path != null) {
- log.debug("Pushing path to {} at {} on {}", new Object[] {
- path.getDstIpAddress().getHostAddress(), macAddress,
- path.getDstInterface().getSwitchPort()});
- //These paths should always be to BGP peers. Paths to non-peers are
- //handled once the first prefix is ready to push
- if (pushedPaths.containsKey(path.getDstIpAddress())) {
- //A path already got pushed to this endpoint while we were waiting
- //for ARP. We'll copy over the permanent attribute if it is set on this path.
- if (path.isPermanent()) {
- pushedPaths.get(path.getDstIpAddress()).setPermanent();
- }
- }
- else {
- calculateAndPushPath(path, macAddress);
- pushedPaths.put(path.getDstIpAddress(), path);
- }
- }
+ Set<RibUpdate> prefixesToPush = prefixesWaitingOnArp.removeAll(ipAddress);
- Set<RibUpdate> prefixesToPush = prefixesWaitingOnArp.removeAll(ipAddress);
+ for (RibUpdate update : prefixesToPush) {
+ //These will always be adds
- for (RibUpdate update : prefixesToPush) {
- //These will always be adds
+ RibEntry rib = ptree.lookup(update.getPrefix());
+ if (rib != null && rib.equals(update.getRibEntry())) {
+ log.debug("Pushing prefix {} next hop {}", update.getPrefix(),
+ rib.getNextHop().getHostAddress());
+ //We only push prefix flows if the prefix is still in the ptree
+ //and the next hop is the same as our update. The prefix could
+ //have been removed while we were waiting for the ARP, or the
+ //next hop could have changed.
+ _processRibAdd(update);
+ } else {
+ log.debug("Received ARP response, but {},{} is no longer in ptree",
+ update.getPrefix(), update.getRibEntry());
+ }
+ }
+ }
+ }
- RibEntry rib = ptree.lookup(update.getPrefix());
- if (rib != null && rib.equals(update.getRibEntry())) {
- log.debug("Pushing prefix {} next hop {}", update.getPrefix(),
- rib.getNextHop().getHostAddress());
- //We only push prefix flows if the prefix is still in the ptree
- //and the next hop is the same as our update. The prefix could
- //have been removed while we were waiting for the ARP, or the
- //next hop could have changed.
- _processRibAdd(update);
- } else {
- log.debug("Received ARP response, but {},{} is no longer in ptree",
- update.getPrefix(), update.getRibEntry());
- }
- }
- }
- }
+ //TODO wait the priority module of the flow Manager
+ private void setupArpFlows() {
+ OFMatch match = new OFMatch();
+ match.setDataLayerType(Ethernet.TYPE_ARP);
+ match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
- //TODO wait the priority module of the flow Manager
- private void setupArpFlows() {
- OFMatch match = new OFMatch();
- match.setDataLayerType(Ethernet.TYPE_ARP);
- match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+ OFFlowMod fm = new OFFlowMod();
+ fm.setMatch(match);
- OFFlowMod fm = new OFFlowMod();
- fm.setMatch(match);
+ OFActionOutput action = new OFActionOutput();
+ action.setPort(OFPort.OFPP_CONTROLLER.getValue());
+ action.setMaxLength((short) 0xffff);
+ List<OFAction> actions = new ArrayList<OFAction>(1);
+ actions.add(action);
+ fm.setActions(actions);
- OFActionOutput action = new OFActionOutput();
- action.setPort(OFPort.OFPP_CONTROLLER.getValue());
- action.setMaxLength((short)0xffff);
- List<OFAction> actions = new ArrayList<OFAction>(1);
- actions.add(action);
- fm.setActions(actions);
+ fm.setIdleTimeout((short) 0)
+ .setHardTimeout((short) 0)
+ .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+ .setCookie(0)
+ .setCommand(OFFlowMod.OFPFC_ADD)
+ .setPriority(ARP_PRIORITY)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);
- fm.setIdleTimeout((short)0)
- .setHardTimeout((short)0)
- .setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setCookie(0)
- .setCommand(OFFlowMod.OFPFC_ADD)
- .setPriority(ARP_PRIORITY)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);
+ for (String strdpid : switches) {
+ flowCache.write(HexString.toLong(strdpid), fm);
+ }
+ }
- for (String strdpid : switches){
- flowCache.write(HexString.toLong(strdpid), fm);
- }
- }
- //TODO need update, waiting for the priority feature from flow Manager
- private void setupDefaultDropFlows() {
- OFFlowMod fm = new OFFlowMod();
- fm.setMatch(new OFMatch());
- fm.setActions(new ArrayList<OFAction>()); //No action means drop
+ //TODO need update, waiting for the priority feature from flow Manager
+ private void setupDefaultDropFlows() {
+ OFFlowMod fm = new OFFlowMod();
+ fm.setMatch(new OFMatch());
+ fm.setActions(new ArrayList<OFAction>()); //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);
+ 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);
- OFFlowMod fmLLDP;
- OFFlowMod fmBDDP;
- try {
- fmLLDP = fm.clone();
- fmBDDP = fm.clone();
- } catch (CloneNotSupportedException e1) {
- log.error("Error cloning flow mod", e1);
- return;
- }
+ 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)0x88cc);
- matchLLDP.setWildcards(matchLLDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
- fmLLDP.setMatch(matchLLDP);
+ OFMatch matchLLDP = new OFMatch();
+ matchLLDP.setDataLayerType((short) 0x88cc);
+ matchLLDP.setWildcards(matchLLDP.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
+ fmLLDP.setMatch(matchLLDP);
- OFMatch matchBDDP = new OFMatch();
- matchBDDP.setDataLayerType((short)0x8942);
- matchBDDP.setWildcards(matchBDDP.getWildcards() & ~ OFMatch.OFPFW_DL_TYPE);
- fmBDDP.setMatch(matchBDDP);
+ OFMatch matchBDDP = new OFMatch();
+ matchBDDP.setDataLayerType((short) 0x8942);
+ 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);
+ 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.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);
+ fmLLDP.setPriority(ARP_PRIORITY);
+ fmLLDP.setLengthU(OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);
+ fmBDDP.setPriority(ARP_PRIORITY);
+ fmBDDP.setLengthU(OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);
- List<OFFlowMod> flowModList = new ArrayList<OFFlowMod>(3);
- flowModList.add(fm);
- flowModList.add(fmLLDP);
- flowModList.add(fmBDDP);
+ List<OFFlowMod> flowModList = new ArrayList<OFFlowMod>(3);
+ flowModList.add(fm);
+ flowModList.add(fmLLDP);
+ flowModList.add(fmBDDP);
- for (String strdpid : switches){
- flowCache.write(HexString.toLong(strdpid), flowModList);
- }
- }
+ for (String strdpid : switches) {
+ flowCache.write(HexString.toLong(strdpid), flowModList);
+ }
+ }
- private void beginRouting(){
- log.debug("Topology is now ready, beginning routing function");
- // TODO: Fix for the new Topology Network Graph
- // topology = topologyNetService.newDatabaseTopology();
+ private void beginRouting() {
+ log.debug("Topology is now ready, beginning routing function");
+ // TODO: Fix for the new Topology Network Graph
+ // topology = topologyNetService.newDatabaseTopology();
- // Wait Pavlin's API. We need the following functions.
- /*setupArpFlows();
- setupDefaultDropFlows();*/
+ // Wait Pavlin's API. We need the following functions.
+ /*setupArpFlows();
+ setupDefaultDropFlows();*/
- setupBgpPaths();
- setupFullMesh();
+ setupBgpPaths();
+ setupFullMesh();
- //Suppress link discovery on external-facing router ports
- for (Interface intf : interfaces.values()) {
- linkDiscoveryService.AddToSuppressLLDPs(intf.getDpid(), intf.getPort());
- }
+ //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() {
- doUpdatesThread();
- }
- });
- }
+ bgpUpdatesExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ doUpdatesThread();
+ }
+ });
+ }
- // Before inserting the paths for BGP traffic, we should check
- // whether all the switches in the configure file are discovered by onos.
- private void checkSwitchesConnected(){
- for (String dpid : switches){
- // TODO: Fix the code below after topoSwitchSerice was removed
- /*
- Iterator<ISwitchObject> activeSwitches = topoSwitchService.
- getActiveSwitches().iterator();
- while(activeSwitches.hasNext())
- {
- ISwitchObject switchObject = activeSwitches.next();
- if (switchObject.getDPID().equals(dpid)) {
- break;
- }
- if(activeSwitches.hasNext() == false) {
- log.debug("Not all switches are here yet");
- return;
- }
- }
- */
- }
- switchesConnected = true;
- }
+ // Before inserting the paths for BGP traffic, we should check
+ // whether all the switches in the configure file are discovered by onos.
+ private void checkSwitchesConnected() {
+ for (String dpid : switches) {
+ // TODO: Fix the code below after topoSwitchSerice was removed
+ /*
+ Iterator<ISwitchObject> activeSwitches = topoSwitchService.
+ getActiveSwitches().iterator();
+ while(activeSwitches.hasNext())
+ {
+ ISwitchObject switchObject = activeSwitches.next();
+ if (switchObject.getDPID().equals(dpid)) {
+ break;
+ }
+ if(activeSwitches.hasNext() == false) {
+ log.debug("Not all switches are here yet");
+ return;
+ }
+ }
+ */
+ }
+ switchesConnected = true;
+ }
- //Actually we only need to go half way round to verify full mesh connectivity
- //(n^2)/2
- private void checkTopologyReady(){
- for (Interface dstInterface : interfaces.values()) {
- for (Interface srcInterface : interfaces.values()) {
- if (dstInterface.equals(srcInterface)) {
- continue;
- }
+ //Actually we only need to go half way round to verify full mesh connectivity
+ //(n^2)/2
+ private void checkTopologyReady() {
+ for (Interface dstInterface : interfaces.values()) {
+ for (Interface srcInterface : interfaces.values()) {
+ if (dstInterface.equals(srcInterface)) {
+ continue;
+ }
- // TODO: Fix for the new Topology Network Graph
- /*
- DataPath shortestPath = topologyNetService.getDatabaseShortestPath(
- srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
+ // TODO: Fix for the new Topology Network Graph
+ /*
+ DataPath shortestPath = topologyNetService.getDatabaseShortestPath(
+ srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
- if (shortestPath == null){
- log.debug("Shortest path between {} and {} not found",
- srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
- return;
- }
- */
- }
- }
- topologyReady = true;
- }
+ if (shortestPath == null){
+ log.debug("Shortest path between {} and {} not found",
+ srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
+ return;
+ }
+ */
+ }
+ }
+ topologyReady = true;
+ }
- private void checkStatus(){
- if (!switchesConnected){
- checkSwitchesConnected();
- }
- boolean oldTopologyReadyStatus = topologyReady;
- if (switchesConnected && !topologyReady){
- checkTopologyReady();
- }
- if (!oldTopologyReadyStatus && topologyReady){
- beginRouting();
- }
- }
+ private void checkStatus() {
+ if (!switchesConnected) {
+ checkSwitchesConnected();
+ }
+ boolean oldTopologyReadyStatus = topologyReady;
+ if (switchesConnected && !topologyReady) {
+ checkTopologyReady();
+ }
+ if (!oldTopologyReadyStatus && topologyReady) {
+ beginRouting();
+ }
+ }
- private void doUpdatesThread() {
- boolean interrupted = false;
- try {
- while (true) {
- try {
- RibUpdate update = ribUpdates.take();
- switch (update.getOperation()){
- case UPDATE:
- if (validateUpdate(update)) {
- processRibAdd(update);
- }
- else {
- log.debug("Rib UPDATE out of order: {} via {}",
- update.getPrefix(), update.getRibEntry().getNextHop());
- }
- break;
- case DELETE:
- if (validateUpdate(update)) {
- processRibDelete(update);
- }
- else {
- log.debug("Rib DELETE out of order: {} via {}",
- update.getPrefix(), update.getRibEntry().getNextHop());
- }
- break;
- }
- } catch (InterruptedException e) {
- log.debug("Interrupted while taking from updates queue", e);
- interrupted = true;
- } catch (Exception e) {
- log.debug("exception", e);
- }
- }
- } finally {
- if (interrupted) {
- Thread.currentThread().interrupt();
- }
- }
- }
+ private void doUpdatesThread() {
+ boolean interrupted = false;
+ try {
+ while (true) {
+ try {
+ RibUpdate update = ribUpdates.take();
+ switch (update.getOperation()) {
+ case UPDATE:
+ if (validateUpdate(update)) {
+ processRibAdd(update);
+ } else {
+ log.debug("Rib UPDATE out of order: {} via {}",
+ update.getPrefix(), update.getRibEntry().getNextHop());
+ }
+ break;
+ case DELETE:
+ if (validateUpdate(update)) {
+ processRibDelete(update);
+ } else {
+ log.debug("Rib DELETE out of order: {} via {}",
+ update.getPrefix(), update.getRibEntry().getNextHop());
+ }
+ break;
+ }
+ } catch (InterruptedException e) {
+ log.debug("Interrupted while taking from updates queue", e);
+ interrupted = true;
+ } catch (Exception e) {
+ log.debug("exception", e);
+ }
+ }
+ } finally {
+ if (interrupted) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
- private boolean validateUpdate(RibUpdate update) {
- RibEntry newEntry = update.getRibEntry();
- RibEntry oldEntry = ptree.lookup(update.getPrefix());
+ private boolean validateUpdate(RibUpdate update) {
+ RibEntry newEntry = update.getRibEntry();
+ RibEntry oldEntry = ptree.lookup(update.getPrefix());
- //If there is no existing entry we must assume this is the most recent
- //update. However this might not always be the case as we might have a
- //POST then DELETE reordering.
- //if (oldEntry == null || !newEntry.getNextHop().equals(oldEntry.getNextHop())) {
- if (oldEntry == null) {
- return true;
- }
+ //If there is no existing entry we must assume this is the most recent
+ //update. However this might not always be the case as we might have a
+ //POST then DELETE reordering.
+ //if (oldEntry == null || !newEntry.getNextHop().equals(oldEntry.getNextHop())) {
+ if (oldEntry == null) {
+ return true;
+ }
- // This handles the case where routes are gathered in the initial
- // request because they don't have sequence number info
- if (newEntry.getSysUpTime() == -1 && newEntry.getSequenceNum() == -1) {
- return true;
- }
+ // This handles the case where routes are gathered in the initial
+ // request because they don't have sequence number info
+ if (newEntry.getSysUpTime() == -1 && newEntry.getSequenceNum() == -1) {
+ return true;
+ }
- if (newEntry.getSysUpTime() > oldEntry.getSysUpTime()) {
- return true;
- }
- else if (newEntry.getSysUpTime() == oldEntry.getSysUpTime()) {
- if (newEntry.getSequenceNum() > oldEntry.getSequenceNum()) {
- return true;
- }
- else {
- return false;
- }
- }
- else {
- return false;
- }
- }
+ if (newEntry.getSysUpTime() > oldEntry.getSysUpTime()) {
+ return true;
+ } else if (newEntry.getSysUpTime() == oldEntry.getSysUpTime()) {
+ if (newEntry.getSequenceNum() > oldEntry.getSequenceNum()) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
- // The code below should be reimplemented after removal of Floodlight's
- // ITopologyService API. It should be implemented on top of network graph
- // notifications. (It was pretty hacky anyway...)
- /*
- @Override
- public void topologyChanged() {
- if (topologyReady) {
- return;
- }
+ // The code below should be reimplemented after removal of Floodlight's
+ // ITopologyService API. It should be implemented on top of network graph
+ // notifications. (It was pretty hacky anyway...)
+ /*
+ @Override
+ public void topologyChanged() {
+ if (topologyReady) {
+ return;
+ }
- boolean refreshNeeded = false;
- for (LDUpdate ldu : topologyService.getLastLinkUpdates()){
- if (!ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_UPDATED)){
- //We don't need to recalculate anything for just link updates
- //They happen very frequently
- refreshNeeded = true;
- }
+ boolean refreshNeeded = false;
+ for (LDUpdate ldu : topologyService.getLastLinkUpdates()){
+ if (!ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_UPDATED)){
+ //We don't need to recalculate anything for just link updates
+ //They happen very frequently
+ refreshNeeded = true;
+ }
- log.debug("Topo change {}", ldu.getOperation());
+ log.debug("Topo change {}", ldu.getOperation());
- if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_ADDED)){
- synchronized (linkUpdates) {
- linkUpdates.add(ldu);
- }
- }
- }
+ if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.LINK_ADDED)){
+ synchronized (linkUpdates) {
+ linkUpdates.add(ldu);
+ }
+ }
+ }
- if (refreshNeeded && !topologyReady){
- topologyChangeDetectorTask.reschedule(TOPO_DETECTION_WAIT, TimeUnit.SECONDS);
- }
- }
- */
+ if (refreshNeeded && !topologyReady){
+ topologyChangeDetectorTask.reschedule(TOPO_DETECTION_WAIT, TimeUnit.SECONDS);
+ }
+ }
+ */
- @Override
- public void addedSwitch(IOFSwitch sw) {
- if (!topologyReady) {
- sw.clearAllFlowMods();
- }
+ @Override
+ public void addedSwitch(IOFSwitch sw) {
+ if (!topologyReady) {
+ sw.clearAllFlowMods();
+ }
- flowCache.switchConnected(sw);
- }
+ flowCache.switchConnected(sw);
+ }
- @Override
- public void removedSwitch(IOFSwitch sw) {}
+ @Override
+ public void removedSwitch(IOFSwitch sw) {
+ }
- @Override
- public void switchPortChanged(Long switchId) {}
+ @Override
+ public void switchPortChanged(Long switchId) {
+ }
- @Override
- public String getName() {
- return "BgpRoute";
- }
+ @Override
+ public String getName() {
+ return "BgpRoute";
+ }
- /*
- * IConfigInfoService methods
- */
+ /*
+ * IConfigInfoService 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 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 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 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 Interface getOutgoingInterface(InetAddress dstIpAddress) {
+ return interfacePtrie.match(new Prefix(dstIpAddress.getAddress(), 32));
+ }
- @Override
- public boolean hasLayer3Configuration() {
- return !interfaces.isEmpty();
- }
+ @Override
+ public boolean hasLayer3Configuration() {
+ return !interfaces.isEmpty();
+ }
- @Override
- public MACAddress getRouterMacAddress() {
- return bgpdMacAddress;
- }
+ @Override
+ public MACAddress getRouterMacAddress() {
+ return bgpdMacAddress;
+ }
- @Override
- public short getVlan() {
- return vlan;
- }
+ @Override
+ public short getVlan() {
+ return vlan;
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteResource.java b/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteResource.java
index cbb1634..2e14757 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteResource.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteResource.java
@@ -13,164 +13,160 @@
public class BgpRouteResource extends ServerResource {
- protected final static Logger log = LoggerFactory.getLogger(BgpRouteResource.class);
+ protected final static Logger log = LoggerFactory.getLogger(BgpRouteResource.class);
- @Get
- public String get(String fmJson) {
- String dest = (String) getRequestAttributes().get("dest");
- String output = "";
- IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
- get(IBgpRouteService.class.getCanonicalName());
+ @Get
+ public String get(String fmJson) {
+ String dest = (String) getRequestAttributes().get("dest");
+ String output = "";
+ IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
+ get(IBgpRouteService.class.getCanonicalName());
- if (dest != null) {
- //TODO Needs to be changed to use the new RestClient.get().
+ if (dest != null) {
+ //TODO Needs to be changed to use the new RestClient.get().
- // 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;
+ // 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;
- //Doesn't actually do anything with the response
- RestClient.get(url);
-
- output="Get rib from bgpd finished!\n";
- return output;
- }
- else {
- IPatriciaTrie<RibEntry> ptree = bgpRoute.getPtree();
- output += "{\n \"rib\": [\n";
- boolean printed = false;
-
- synchronized(ptree) {
- Iterator<IPatriciaTrie.Entry<RibEntry>> it = ptree.iterator();
- while (it.hasNext()) {
- IPatriciaTrie.Entry<RibEntry> entry = it.next();
-
- if (printed == true) {
- output += ",\n";
- }
-
- output += " {\"prefix\": \"" + entry.getPrefix() +"\", ";
- output += "\"nexthop\": \"" + entry.getValue().getNextHop().getHostAddress() +"\"}";
-
- printed = true;
- }
- }
-
- output += "\n ]\n}\n";
- }
-
- return output;
- }
+ //Doesn't actually do anything with the response
+ RestClient.get(url);
- @Post
- public String store(String fmJson) {
- IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
- get(IBgpRouteService.class.getCanonicalName());
+ output = "Get rib from bgpd finished!\n";
+ return output;
+ } else {
+ IPatriciaTrie<RibEntry> ptree = bgpRoute.getPtree();
+ output += "{\n \"rib\": [\n";
+ boolean printed = false;
- String strSysuptime = (String) getRequestAttributes().get("sysuptime");
- String strSequence = (String) getRequestAttributes().get("sequence");
- String routerId = (String) getRequestAttributes().get("routerid");
- String prefix = (String) getRequestAttributes().get("prefix");
- String mask = (String) getRequestAttributes().get("mask");
- String nexthop = (String) getRequestAttributes().get("nexthop");
- String capability = (String) getRequestAttributes().get("capability");
-
- log.debug("sysuptime: {}", strSysuptime);
- log.debug("sequence: {}", strSequence);
+ synchronized (ptree) {
+ Iterator<IPatriciaTrie.Entry<RibEntry>> it = ptree.iterator();
+ while (it.hasNext()) {
+ IPatriciaTrie.Entry<RibEntry> entry = it.next();
- String reply = "";
+ if (printed == true) {
+ output += ",\n";
+ }
- if (capability == null) {
- // this is a prefix add
- Prefix p;
- long sysUpTime, sequenceNum;
- try {
- p = new Prefix(prefix, Integer.valueOf(mask));
- sysUpTime = Long.parseLong(strSysuptime);
- sequenceNum = Long.parseLong(strSequence);
- } catch (NumberFormatException e) {
- reply = "[POST: mask format is wrong]";
- log.info(reply);
- return reply + "\n";
- } catch (IllegalArgumentException e1) {
- reply = "[POST: prefix format is wrong]";
- log.info(reply);
- return reply + "\n";
- }
-
- RibEntry rib = new RibEntry(routerId, nexthop, sysUpTime, sequenceNum);
+ output += " {\"prefix\": \"" + entry.getPrefix() + "\", ";
+ output += "\"nexthop\": \"" + entry.getValue().getNextHop().getHostAddress() + "\"}";
- bgpRoute.newRibUpdate(new RibUpdate(Operation.UPDATE, p, rib));
-
- reply = "[POST: " + prefix + "/" + mask + ":" + nexthop + "]";
- log.info(reply);
- }
- else if(capability.equals("1")) {
- reply = "[POST-capability: " + capability + "]\n";
- log.info(reply);
- // to store the number in the top node of the Ptree
- }
- else {
- reply = "[POST-capability: " + capability + "]\n";
- log.info(reply);
- // to store the number in the top node of the Ptree
- }
+ printed = true;
+ }
+ }
- return reply + "\n";
- }
+ output += "\n ]\n}\n";
+ }
- @Delete
- public String delete(String fmJson) {
- IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
- get(IBgpRouteService.class.getCanonicalName());
+ return output;
+ }
- String strSysuptime = (String) getRequestAttributes().get("sysuptime");
- String strSequence = (String) getRequestAttributes().get("sequence");
- String routerId = (String) getRequestAttributes().get("routerid");
- String prefix = (String) getRequestAttributes().get("prefix");
- String mask = (String) getRequestAttributes().get("mask");
- String nextHop = (String) getRequestAttributes().get("nexthop");
- String capability = (String) getRequestAttributes().get("capability");
+ @Post
+ public String store(String fmJson) {
+ IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
+ get(IBgpRouteService.class.getCanonicalName());
- log.debug("sysuptime: {}", strSysuptime);
- log.debug("sequence: {}", strSequence);
-
- String reply = "";
+ String strSysuptime = (String) getRequestAttributes().get("sysuptime");
+ String strSequence = (String) getRequestAttributes().get("sequence");
+ String routerId = (String) getRequestAttributes().get("routerid");
+ String prefix = (String) getRequestAttributes().get("prefix");
+ String mask = (String) getRequestAttributes().get("mask");
+ String nexthop = (String) getRequestAttributes().get("nexthop");
+ String capability = (String) getRequestAttributes().get("capability");
- if (capability == null) {
- // this is a prefix delete
- Prefix p;
- long sysUpTime, sequenceNum;
- try {
- p = new Prefix(prefix, Integer.valueOf(mask));
- sysUpTime = Long.parseLong(strSysuptime);
- sequenceNum = Long.parseLong(strSequence);
- } catch (NumberFormatException e) {
- reply = "[DELE: mask format is wrong]";
- log.info(reply);
- return reply + "\n";
- } catch (IllegalArgumentException e1) {
- reply = "[DELE: prefix format is wrong]";
- log.info(reply);
- return reply + "\n";
- }
-
- RibEntry r = new RibEntry(routerId, nextHop, sysUpTime, sequenceNum);
-
- bgpRoute.newRibUpdate(new RibUpdate(Operation.DELETE, p, r));
-
- reply =reply + "[DELE: " + prefix + "/" + mask + ":" + nextHop + "]";
- }
- else {
- // clear the local rib: Ptree
- bgpRoute.clearPtree();
- reply = "[DELE-capability: " + capability + "; The local RibEntry is cleared!]\n";
+ log.debug("sysuptime: {}", strSysuptime);
+ log.debug("sequence: {}", strSequence);
- // to store the number in the top node of the Ptree
- }
-
- log.info(reply);
- return reply + "\n";
- }
+ String reply = "";
+
+ if (capability == null) {
+ // this is a prefix add
+ Prefix p;
+ long sysUpTime, sequenceNum;
+ try {
+ p = new Prefix(prefix, Integer.valueOf(mask));
+ sysUpTime = Long.parseLong(strSysuptime);
+ sequenceNum = Long.parseLong(strSequence);
+ } catch (NumberFormatException e) {
+ reply = "[POST: mask format is wrong]";
+ log.info(reply);
+ return reply + "\n";
+ } catch (IllegalArgumentException e1) {
+ reply = "[POST: prefix format is wrong]";
+ log.info(reply);
+ return reply + "\n";
+ }
+
+ RibEntry rib = new RibEntry(routerId, nexthop, sysUpTime, sequenceNum);
+
+ bgpRoute.newRibUpdate(new RibUpdate(Operation.UPDATE, p, rib));
+
+ reply = "[POST: " + prefix + "/" + mask + ":" + nexthop + "]";
+ log.info(reply);
+ } else if (capability.equals("1")) {
+ reply = "[POST-capability: " + capability + "]\n";
+ log.info(reply);
+ // to store the number in the top node of the Ptree
+ } else {
+ reply = "[POST-capability: " + capability + "]\n";
+ log.info(reply);
+ // to store the number in the top node of the Ptree
+ }
+
+ return reply + "\n";
+ }
+
+ @Delete
+ public String delete(String fmJson) {
+ IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
+ get(IBgpRouteService.class.getCanonicalName());
+
+ String strSysuptime = (String) getRequestAttributes().get("sysuptime");
+ String strSequence = (String) getRequestAttributes().get("sequence");
+ String routerId = (String) getRequestAttributes().get("routerid");
+ String prefix = (String) getRequestAttributes().get("prefix");
+ String mask = (String) getRequestAttributes().get("mask");
+ String nextHop = (String) getRequestAttributes().get("nexthop");
+ String capability = (String) getRequestAttributes().get("capability");
+
+ log.debug("sysuptime: {}", strSysuptime);
+ log.debug("sequence: {}", strSequence);
+
+ String reply = "";
+
+ if (capability == null) {
+ // this is a prefix delete
+ Prefix p;
+ long sysUpTime, sequenceNum;
+ try {
+ p = new Prefix(prefix, Integer.valueOf(mask));
+ sysUpTime = Long.parseLong(strSysuptime);
+ sequenceNum = Long.parseLong(strSequence);
+ } catch (NumberFormatException e) {
+ reply = "[DELE: mask format is wrong]";
+ log.info(reply);
+ return reply + "\n";
+ } catch (IllegalArgumentException e1) {
+ reply = "[DELE: prefix format is wrong]";
+ log.info(reply);
+ return reply + "\n";
+ }
+
+ RibEntry r = new RibEntry(routerId, nextHop, sysUpTime, sequenceNum);
+
+ bgpRoute.newRibUpdate(new RibUpdate(Operation.DELETE, p, r));
+
+ reply = reply + "[DELE: " + prefix + "/" + mask + ":" + nextHop + "]";
+ } else {
+ // clear the local rib: Ptree
+ bgpRoute.clearPtree();
+ reply = "[DELE-capability: " + capability + "; The local RibEntry is cleared!]\n";
+
+ // to store the number in the top node of the Ptree
+ }
+
+ log.info(reply);
+ return reply + "\n";
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteResourceSynch.java b/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteResourceSynch.java
index 5e33bc5..20fc71b 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteResourceSynch.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteResourceSynch.java
@@ -9,63 +9,65 @@
public class BgpRouteResourceSynch extends ServerResource {
-
- protected final static Logger log = LoggerFactory
+
+ protected final static Logger log = LoggerFactory
.getLogger(BgpRouteResource.class);
-
- @Post
- public String store(String fmJson) {
-
- IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
+
+ @Post
+ public String store(String fmJson) {
+
+ IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
get(IBgpRouteService.class.getCanonicalName());
-
- String router_id = (String) getRequestAttributes().get("routerid");
- String prefix = (String) getRequestAttributes().get("prefix");
- String mask = (String) getRequestAttributes().get("mask");
- String nexthop = (String) getRequestAttributes().get("nexthop");
-
- try{
-
- String BGPdRestIp = bgpRoute.getBGPdRestIp();
-
- //bgpdRestIp includes port number, such as 1.1.1.1:8080
- RestClient.post("http://"+BGPdRestIp+"/wm/bgp/"+router_id+"/"+prefix+"/"+mask+"/"+nexthop);
- }catch(Exception e)
- {e.printStackTrace();}
-
- String reply = "";
- reply = "[POST: " + prefix + "/" + mask + ":" + nexthop + "/synch]";
- log.info(reply);
-
- return reply + "\n";
-
-
- }
-
- @Delete
- public String delete(String fmJson) {
- IBgpRouteService bgpRoute = (IBgpRouteService)getContext().getAttributes().
- get(IBgpRouteService.class.getCanonicalName());
-
- String routerId = (String) getRequestAttributes().get("routerid");
- String prefix = (String) getRequestAttributes().get("prefix");
- String mask = (String) getRequestAttributes().get("mask");
- String nextHop = (String) getRequestAttributes().get("nexthop");
-
- String reply = "";
- try{
- String BGPdRestIp = bgpRoute.getBGPdRestIp();
-
- RestClient.delete("http://"+BGPdRestIp+"/wm/bgp/"+routerId+"/"+prefix+"/"+mask+"/"+nextHop);
-
- }catch(Exception e)
- {e.printStackTrace();}
-
- reply =reply + "[DELE: " + prefix + "/" + mask + ":" + nextHop + "/synch]";
-
- log.info(reply);
+
+ String router_id = (String) getRequestAttributes().get("routerid");
+ String prefix = (String) getRequestAttributes().get("prefix");
+ String mask = (String) getRequestAttributes().get("mask");
+ String nexthop = (String) getRequestAttributes().get("nexthop");
+
+ try {
+
+ String BGPdRestIp = bgpRoute.getBGPdRestIp();
+
+ //bgpdRestIp includes port number, such as 1.1.1.1:8080
+ RestClient.post("http://" + BGPdRestIp + "/wm/bgp/" + router_id + "/" + prefix + "/" + mask + "/" + nexthop);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ String reply = "";
+ reply = "[POST: " + prefix + "/" + mask + ":" + nexthop + "/synch]";
+ log.info(reply);
+
+ return reply + "\n";
- return reply + "\n";
- }
+ }
+
+ @Delete
+ public String delete(String fmJson) {
+ IBgpRouteService bgpRoute = (IBgpRouteService) getContext().getAttributes().
+ get(IBgpRouteService.class.getCanonicalName());
+
+ String routerId = (String) getRequestAttributes().get("routerid");
+ String prefix = (String) getRequestAttributes().get("prefix");
+ String mask = (String) getRequestAttributes().get("mask");
+ String nextHop = (String) getRequestAttributes().get("nexthop");
+
+ String reply = "";
+ try {
+ String BGPdRestIp = bgpRoute.getBGPdRestIp();
+
+ RestClient.delete("http://" + BGPdRestIp + "/wm/bgp/" + routerId + "/" + prefix + "/" + mask + "/" + nextHop);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ reply = reply + "[DELE: " + prefix + "/" + mask + ":" + nextHop + "/synch]";
+
+ log.info(reply);
+
+
+ return reply + "\n";
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteWebRoutable.java b/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteWebRoutable.java
index 7d304e8..a05015e 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteWebRoutable.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/BgpRouteWebRoutable.java
@@ -7,19 +7,19 @@
import org.restlet.routing.Router;
public class BgpRouteWebRoutable implements RestletRoutable {
- @Override
- public Restlet getRestlet(Context context) {
- Router router = new Router(context);
- router.attach("/json", BgpRouteResource.class);
- router.attach("/rib/{dest}", BgpRouteResource.class);
- router.attach("/{sysuptime}/{sequence}/{routerid}/{prefix}/{mask}/{nexthop}", BgpRouteResource.class);
- router.attach("/{routerid}/{prefix}/{mask}/{nexthop}/synch", BgpRouteResourceSynch.class);
- router.attach("/{routerid}/{capability}", BgpRouteResource.class);
- return router;
- }
-
- @Override
- public String basePath() {
- return "/wm/bgp";
- }
+ @Override
+ public Restlet getRestlet(Context context) {
+ Router router = new Router(context);
+ router.attach("/json", BgpRouteResource.class);
+ router.attach("/rib/{dest}", BgpRouteResource.class);
+ router.attach("/{sysuptime}/{sequence}/{routerid}/{prefix}/{mask}/{nexthop}", BgpRouteResource.class);
+ router.attach("/{routerid}/{prefix}/{mask}/{nexthop}/synch", BgpRouteResourceSynch.class);
+ router.attach("/{routerid}/{capability}", BgpRouteResource.class);
+ return router;
+ }
+
+ @Override
+ public String basePath() {
+ return "/wm/bgp";
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/Configuration.java b/src/main/java/net/onrc/onos/apps/bgproute/Configuration.java
index 6f02fe3..314324d 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/Configuration.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/Configuration.java
@@ -9,79 +9,79 @@
import org.openflow.util.HexString;
public class Configuration {
- private long bgpdAttachmentDpid;
- private short bgpdAttachmentPort;
- private MACAddress bgpdMacAddress;
- private short vlan;
- private List<String> switches;
- private List<Interface> interfaces;
- private List<BgpPeer> peers;
-
- public Configuration() {
- // TODO Auto-generated constructor stub
- }
+ private long bgpdAttachmentDpid;
+ private short bgpdAttachmentPort;
+ private MACAddress bgpdMacAddress;
+ private short vlan;
+ private List<String> switches;
+ private List<Interface> interfaces;
+ private List<BgpPeer> peers;
- public long getBgpdAttachmentDpid() {
- return bgpdAttachmentDpid;
- }
+ public Configuration() {
+ // TODO Auto-generated constructor stub
+ }
- @JsonProperty("bgpdAttachmentDpid")
- public void setBgpdAttachmentDpid(String bgpdAttachmentDpid) {
- this.bgpdAttachmentDpid = HexString.toLong(bgpdAttachmentDpid);
- }
+ public long getBgpdAttachmentDpid() {
+ return bgpdAttachmentDpid;
+ }
- public short getBgpdAttachmentPort() {
- return bgpdAttachmentPort;
- }
+ @JsonProperty("bgpdAttachmentDpid")
+ public void setBgpdAttachmentDpid(String bgpdAttachmentDpid) {
+ this.bgpdAttachmentDpid = HexString.toLong(bgpdAttachmentDpid);
+ }
- @JsonProperty("bgpdAttachmentPort")
- public void setBgpdAttachmentPort(short bgpdAttachmentPort) {
- this.bgpdAttachmentPort = bgpdAttachmentPort;
- }
-
- public MACAddress getBgpdMacAddress() {
- return bgpdMacAddress;
- }
+ public short getBgpdAttachmentPort() {
+ return bgpdAttachmentPort;
+ }
- @JsonProperty("bgpdMacAddress")
- public void setBgpdMacAddress(String strMacAddress) {
- this.bgpdMacAddress = MACAddress.valueOf(strMacAddress);
- }
-
- public List<String> getSwitches() {
- return Collections.unmodifiableList(switches);
- }
-
- @JsonProperty("vlan")
- public void setVlan(short vlan) {
- this.vlan = vlan;
- }
-
- public short getVlan() {
- return vlan;
- }
+ @JsonProperty("bgpdAttachmentPort")
+ public void setBgpdAttachmentPort(short bgpdAttachmentPort) {
+ this.bgpdAttachmentPort = bgpdAttachmentPort;
+ }
- @JsonProperty("switches")
- public void setSwitches(List<String> switches) {
- this.switches = switches;
- }
-
- public List<Interface> getInterfaces() {
- return Collections.unmodifiableList(interfaces);
- }
+ public MACAddress getBgpdMacAddress() {
+ return bgpdMacAddress;
+ }
- @JsonProperty("interfaces")
- public void setInterfaces(List<Interface> interfaces) {
- this.interfaces = interfaces;
- }
-
- public List<BgpPeer> getPeers() {
- return Collections.unmodifiableList(peers);
- }
+ @JsonProperty("bgpdMacAddress")
+ public void setBgpdMacAddress(String strMacAddress) {
+ this.bgpdMacAddress = MACAddress.valueOf(strMacAddress);
+ }
- @JsonProperty("bgpPeers")
- public void setPeers(List<BgpPeer> peers) {
- this.peers = peers;
- }
+ public List<String> getSwitches() {
+ return Collections.unmodifiableList(switches);
+ }
+
+ @JsonProperty("vlan")
+ public void setVlan(short vlan) {
+ this.vlan = vlan;
+ }
+
+ public short getVlan() {
+ return vlan;
+ }
+
+ @JsonProperty("switches")
+ public void setSwitches(List<String> switches) {
+ this.switches = switches;
+ }
+
+ public List<Interface> getInterfaces() {
+ return Collections.unmodifiableList(interfaces);
+ }
+
+ @JsonProperty("interfaces")
+ public void setInterfaces(List<Interface> interfaces) {
+ this.interfaces = interfaces;
+ }
+
+ public List<BgpPeer> getPeers() {
+ return Collections.unmodifiableList(peers);
+ }
+
+ @JsonProperty("bgpPeers")
+ public void setPeers(List<BgpPeer> peers) {
+ this.peers = peers;
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/FlowCache.java b/src/main/java/net/onrc/onos/apps/bgproute/FlowCache.java
index 31bbc95..145224b 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/FlowCache.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/FlowCache.java
@@ -19,140 +19,138 @@
import org.slf4j.LoggerFactory;
public class FlowCache {
- private final static Logger log = LoggerFactory.getLogger(FlowCache.class);
-
- private IFloodlightProviderService floodlightProvider;
-
- private Map<Long, List<OFFlowMod>> flowCache;
-
- private Comparator<OFFlowMod> cookieComparator = new Comparator<OFFlowMod>() {
- @Override
- public int compare(OFFlowMod fm1, OFFlowMod fm2) {
- long difference = fm2.getCookie() - fm1.getCookie();
-
- if (difference > 0) {
- return 1;
- }
- else if (difference < 0) {
- return -1;
- }
- else {
- return 0;
- }
- }
- };
-
- public FlowCache(IFloodlightProviderService floodlightProvider) {
- this.floodlightProvider = floodlightProvider;
-
- flowCache = new HashMap<Long, List<OFFlowMod>>();
- }
+ private final static Logger log = LoggerFactory.getLogger(FlowCache.class);
- public synchronized void write(long dpid, OFFlowMod flowMod) {
- List<OFFlowMod> flowModList = new ArrayList<OFFlowMod>(1);
- flowModList.add(flowMod);
- write(dpid, flowModList);
- }
-
- public synchronized void write(long dpid, List<OFFlowMod> flowMods) {
- ensureCacheForSwitch(dpid);
-
- List<OFFlowMod> clones = new ArrayList<OFFlowMod>(flowMods.size());
-
- //Somehow the OFFlowMods we get passed in will change later on.
- //No idea how this happens, but we can just clone to prevent problems
- try {
- for (OFFlowMod fm : flowMods) {
- clones.add(fm.clone());
- }
- } catch (CloneNotSupportedException e) {
- log.debug("Clone exception", e);
- }
-
- flowCache.get(dpid).addAll(clones);
-
- IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
-
- if (sw == null) {
- log.debug("Switch not found when writing flow mods");
- return;
- }
+ private IFloodlightProviderService floodlightProvider;
- List<OFMessage> msgList = new ArrayList<OFMessage>(clones.size());
- msgList.addAll(clones);
-
- try {
- sw.write(msgList, null);
- } catch (IOException e) {
- log.error("Error writing to switch", e);
- }
-
+ private Map<Long, List<OFFlowMod>> flowCache;
- }
-
- public synchronized void delete(long dpid, OFFlowMod flowMod) {
- List<OFFlowMod> flowModList = new ArrayList<OFFlowMod>(1);
- flowModList.add(flowMod);
- delete(dpid, flowModList);
- }
-
- public synchronized void delete(long dpid, List<OFFlowMod> flowMods) {
- ensureCacheForSwitch(dpid);
-
- //Remove the flow mods from the cache first before we alter them
- flowCache.get(dpid).removeAll(flowMods);
-
- //Alter the original flow mods to make them delete flow mods
- for (OFFlowMod fm : flowMods) {
- fm.setCommand(OFFlowMod.OFPFC_DELETE_STRICT)
- .setOutPort(OFPort.OFPP_NONE)
- .setLengthU(OFFlowMod.MINIMUM_LENGTH);
-
- fm.getActions().clear();
- }
-
- IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
- if (sw == null) {
- log.debug("Switch not found when writing flow mods");
- return;
- }
-
- List<OFMessage> msgList = new ArrayList<OFMessage>(flowMods.size());
- msgList.addAll(flowMods);
-
- try {
- sw.write(msgList, null);
- } catch (IOException e) {
- log.error("Error writing to switch", e);
- }
- }
-
- //TODO can the Prontos handle being sent all flow mods in one message?
- public synchronized void switchConnected(IOFSwitch sw) {
- log.debug("Switch connected: {}", sw);
-
- ensureCacheForSwitch(sw.getId());
-
- List<OFFlowMod> flowMods = flowCache.get(sw.getId());
+ private Comparator<OFFlowMod> cookieComparator = new Comparator<OFFlowMod>() {
+ @Override
+ public int compare(OFFlowMod fm1, OFFlowMod fm2) {
+ long difference = fm2.getCookie() - fm1.getCookie();
- Collections.sort(flowMods, cookieComparator);
-
- sw.clearAllFlowMods();
-
- List<OFMessage> messages = new ArrayList<OFMessage>(flowMods.size());
- messages.addAll(flowMods);
-
- try {
- sw.write(messages, null);
- } catch (IOException e) {
- log.error("Failure writing flow mods to switch {}",
- HexString.toHexString(sw.getId()));
- }
- }
-
- private void ensureCacheForSwitch(long dpid) {
- if (!flowCache.containsKey(dpid)) {
- flowCache.put(dpid, new ArrayList<OFFlowMod>());
- }
- }
+ if (difference > 0) {
+ return 1;
+ } else if (difference < 0) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+ };
+
+ public FlowCache(IFloodlightProviderService floodlightProvider) {
+ this.floodlightProvider = floodlightProvider;
+
+ flowCache = new HashMap<Long, List<OFFlowMod>>();
+ }
+
+ public synchronized void write(long dpid, OFFlowMod flowMod) {
+ List<OFFlowMod> flowModList = new ArrayList<OFFlowMod>(1);
+ flowModList.add(flowMod);
+ write(dpid, flowModList);
+ }
+
+ public synchronized void write(long dpid, List<OFFlowMod> flowMods) {
+ ensureCacheForSwitch(dpid);
+
+ List<OFFlowMod> clones = new ArrayList<OFFlowMod>(flowMods.size());
+
+ //Somehow the OFFlowMods we get passed in will change later on.
+ //No idea how this happens, but we can just clone to prevent problems
+ try {
+ for (OFFlowMod fm : flowMods) {
+ clones.add(fm.clone());
+ }
+ } catch (CloneNotSupportedException e) {
+ log.debug("Clone exception", e);
+ }
+
+ flowCache.get(dpid).addAll(clones);
+
+ IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
+
+ if (sw == null) {
+ log.debug("Switch not found when writing flow mods");
+ return;
+ }
+
+ List<OFMessage> msgList = new ArrayList<OFMessage>(clones.size());
+ msgList.addAll(clones);
+
+ try {
+ sw.write(msgList, null);
+ } catch (IOException e) {
+ log.error("Error writing to switch", e);
+ }
+
+
+ }
+
+ public synchronized void delete(long dpid, OFFlowMod flowMod) {
+ List<OFFlowMod> flowModList = new ArrayList<OFFlowMod>(1);
+ flowModList.add(flowMod);
+ delete(dpid, flowModList);
+ }
+
+ public synchronized void delete(long dpid, List<OFFlowMod> flowMods) {
+ ensureCacheForSwitch(dpid);
+
+ //Remove the flow mods from the cache first before we alter them
+ flowCache.get(dpid).removeAll(flowMods);
+
+ //Alter the original flow mods to make them delete flow mods
+ for (OFFlowMod fm : flowMods) {
+ fm.setCommand(OFFlowMod.OFPFC_DELETE_STRICT)
+ .setOutPort(OFPort.OFPP_NONE)
+ .setLengthU(OFFlowMod.MINIMUM_LENGTH);
+
+ fm.getActions().clear();
+ }
+
+ IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
+ if (sw == null) {
+ log.debug("Switch not found when writing flow mods");
+ return;
+ }
+
+ List<OFMessage> msgList = new ArrayList<OFMessage>(flowMods.size());
+ msgList.addAll(flowMods);
+
+ try {
+ sw.write(msgList, null);
+ } catch (IOException e) {
+ log.error("Error writing to switch", e);
+ }
+ }
+
+ //TODO can the Prontos handle being sent all flow mods in one message?
+ public synchronized void switchConnected(IOFSwitch sw) {
+ log.debug("Switch connected: {}", sw);
+
+ ensureCacheForSwitch(sw.getId());
+
+ List<OFFlowMod> flowMods = flowCache.get(sw.getId());
+
+ Collections.sort(flowMods, cookieComparator);
+
+ sw.clearAllFlowMods();
+
+ List<OFMessage> messages = new ArrayList<OFMessage>(flowMods.size());
+ messages.addAll(flowMods);
+
+ try {
+ sw.write(messages, null);
+ } catch (IOException e) {
+ log.error("Failure writing flow mods to switch {}",
+ HexString.toHexString(sw.getId()));
+ }
+ }
+
+ private void ensureCacheForSwitch(long dpid) {
+ if (!flowCache.containsKey(dpid)) {
+ flowCache.put(dpid, new ArrayList<OFFlowMod>());
+ }
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/IBgpRouteService.java b/src/main/java/net/onrc/onos/apps/bgproute/IBgpRouteService.java
index 56d5393..95b81bf 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/IBgpRouteService.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/IBgpRouteService.java
@@ -4,24 +4,25 @@
public interface IBgpRouteService extends IFloodlightService {
- //public RibEntry lookupRib(byte[] dest);
+ //public RibEntry lookupRib(byte[] dest);
- //public Ptree getPtree();
- public IPatriciaTrie<RibEntry> getPtree();
+ //public Ptree getPtree();
+ public IPatriciaTrie<RibEntry> getPtree();
- public String getBGPdRestIp();
+ public String getBGPdRestIp();
- public String getRouterId();
+ public String getRouterId();
- public void clearPtree();
-
- /**
- * Pass a RIB update to the {@link IBgpRouteService}
- * @param update
- */
- public void newRibUpdate(RibUpdate update);
-
- //TODO This functionality should be provided by some sort of Ptree listener framework
- //public void prefixAdded(PtreeNode node);
- //public void prefixDeleted(PtreeNode node);
+ public void clearPtree();
+
+ /**
+ * Pass a RIB update to the {@link IBgpRouteService}
+ *
+ * @param update
+ */
+ public void newRibUpdate(RibUpdate update);
+
+ //TODO This functionality should be provided by some sort of Ptree listener framework
+ //public void prefixAdded(PtreeNode node);
+ //public void prefixDeleted(PtreeNode node);
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/IPatriciaTrie.java b/src/main/java/net/onrc/onos/apps/bgproute/IPatriciaTrie.java
index 854b340..bd4508a 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/IPatriciaTrie.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/IPatriciaTrie.java
@@ -3,18 +3,19 @@
import java.util.Iterator;
public interface IPatriciaTrie<V> {
- public V put(Prefix prefix, V value);
-
- public V lookup(Prefix prefix);
-
- public V match(Prefix prefix);
-
- public boolean remove(Prefix prefix, V value);
-
- public Iterator<Entry<V>> iterator();
-
- interface Entry<V> {
- public Prefix getPrefix();
- public V getValue();
- }
+ public V put(Prefix prefix, V value);
+
+ public V lookup(Prefix prefix);
+
+ public V match(Prefix prefix);
+
+ public boolean remove(Prefix prefix, V value);
+
+ public Iterator<Entry<V>> iterator();
+
+ interface Entry<V> {
+ public Prefix getPrefix();
+
+ public V getValue();
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/Interface.java b/src/main/java/net/onrc/onos/apps/bgproute/Interface.java
index b5c762d..52e9a32 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/Interface.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/Interface.java
@@ -13,75 +13,75 @@
import com.google.common.net.InetAddresses;
public class Interface {
- private final String name;
- 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;
- }
-
- public String getName() {
- return name;
- }
+ private final String name;
+ private final long dpid;
+ private final short port;
+ private final InetAddress ipAddress;
+ private final int prefixLength;
- 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;
- }
+ @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;
+ }
- public short getPort() {
- return port;
- }
+ public String getName() {
+ return name;
+ }
- public InetAddress getIpAddress() {
- return ipAddress;
- }
+ 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 int getPrefixLength() {
- return prefixLength;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == null || !(other instanceof Interface)) {
- return false;
- }
-
- Interface otherInterface = (Interface)other;
-
- //Don't check switchPort as it's comprised of dpid and port
- return (name.equals(otherInterface.name)) &&
- (dpid == otherInterface.dpid) &&
- (port == otherInterface.port) &&
- (ipAddress.equals(otherInterface.ipAddress)) &&
- (prefixLength == otherInterface.prefixLength);
- }
-
- @Override
- public int hashCode() {
- int hash = 17;
- hash = 31 * hash + name.hashCode();
- hash = 31 * hash + (int)(dpid ^ dpid >>> 32);
- hash = 31 * hash + (int)port;
- hash = 31 * hash + ipAddress.hashCode();
- hash = 31 * hash + prefixLength;
- return hash;
- }
+ public long getDpid() {
+ return dpid;
+ }
+
+ public short getPort() {
+ return port;
+ }
+
+ public InetAddress getIpAddress() {
+ return ipAddress;
+ }
+
+ public int getPrefixLength() {
+ return prefixLength;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null || !(other instanceof Interface)) {
+ return false;
+ }
+
+ Interface otherInterface = (Interface) other;
+
+ //Don't check switchPort as it's comprised of dpid and port
+ return (name.equals(otherInterface.name)) &&
+ (dpid == otherInterface.dpid) &&
+ (port == otherInterface.port) &&
+ (ipAddress.equals(otherInterface.ipAddress)) &&
+ (prefixLength == otherInterface.prefixLength);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 17;
+ hash = 31 * hash + name.hashCode();
+ hash = 31 * hash + (int) (dpid ^ dpid >>> 32);
+ hash = 31 * hash + (int) port;
+ hash = 31 * hash + ipAddress.hashCode();
+ hash = 31 * hash + prefixLength;
+ return hash;
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/Path.java b/src/main/java/net/onrc/onos/apps/bgproute/Path.java
index cd0b1b6..3ecf7c7 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/Path.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/Path.java
@@ -11,51 +11,51 @@
public class Path {
- private Interface dstInterface;
- private InetAddress dstIpAddress;
- private int numUsers = 0;
-
- private List<PushedFlowMod> flowMods = null;
- private boolean permanent = false;
-
- public Path(Interface dstInterface, InetAddress dstIpAddress) {
- this.dstInterface = dstInterface;
- this.dstIpAddress = dstIpAddress;
- }
+ private Interface dstInterface;
+ private InetAddress dstIpAddress;
+ private int numUsers = 0;
- public Interface getDstInterface() {
- return dstInterface;
- }
+ private List<PushedFlowMod> flowMods = null;
+ private boolean permanent = false;
- public InetAddress getDstIpAddress() {
- return dstIpAddress;
- }
-
- public void incrementUsers() {
- numUsers++;
- }
-
- public void decrementUsers() {
- numUsers--;
- }
-
- public int getUsers() {
- return numUsers;
- }
-
- public List<PushedFlowMod> getFlowMods() {
- return Collections.unmodifiableList(flowMods);
- }
-
- public void setFlowMods(List<PushedFlowMod> flowMods) {
- this.flowMods = flowMods;
- }
-
- public boolean isPermanent() {
- return permanent;
- }
-
- public void setPermanent() {
- permanent = true;
- }
+ public Path(Interface dstInterface, InetAddress dstIpAddress) {
+ this.dstInterface = dstInterface;
+ this.dstIpAddress = dstIpAddress;
+ }
+
+ public Interface getDstInterface() {
+ return dstInterface;
+ }
+
+ public InetAddress getDstIpAddress() {
+ return dstIpAddress;
+ }
+
+ public void incrementUsers() {
+ numUsers++;
+ }
+
+ public void decrementUsers() {
+ numUsers--;
+ }
+
+ public int getUsers() {
+ return numUsers;
+ }
+
+ public List<PushedFlowMod> getFlowMods() {
+ return Collections.unmodifiableList(flowMods);
+ }
+
+ public void setFlowMods(List<PushedFlowMod> flowMods) {
+ this.flowMods = flowMods;
+ }
+
+ public boolean isPermanent() {
+ return permanent;
+ }
+
+ public void setPermanent() {
+ permanent = true;
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/PatriciaTrie.java b/src/main/java/net/onrc/onos/apps/bgproute/PatriciaTrie.java
index 9badd11..8225d7d 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/PatriciaTrie.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/PatriciaTrie.java
@@ -4,503 +4,500 @@
import java.util.NoSuchElementException;
public class PatriciaTrie<V> implements IPatriciaTrie<V> {
- private final byte maskBits[] = {(byte)0x00, (byte)0x80, (byte)0xc0, (byte)0xe0, (byte)0xf0,
- (byte)0xf8, (byte)0xfc, (byte)0xfe, (byte)0xff};
-
- private int maxPrefixLength;
-
- private Node top;
+ private final byte maskBits[] = {(byte) 0x00, (byte) 0x80, (byte) 0xc0, (byte) 0xe0, (byte) 0xf0,
+ (byte) 0xf8, (byte) 0xfc, (byte) 0xfe, (byte) 0xff};
- public PatriciaTrie(int maxPrefixLength) {
- this.maxPrefixLength = maxPrefixLength;
- }
+ private int maxPrefixLength;
- @Override
- public synchronized V put(Prefix prefix, V value) {
- if (prefix == null || value == null) {
- throw new NullPointerException();
- }
-
- if (prefix.getPrefixLength() > maxPrefixLength) {
- throw new IllegalArgumentException(String.format(
- "Prefix length %d is greater than max prefix length %d",
- prefix.getPrefixLength(), maxPrefixLength));
- }
-
- Node node = top;
- Node match = null;
-
- while (node != null
- && node.prefix.getPrefixLength() <= prefix.getPrefixLength()
- && key_match(node.prefix.getAddress(), node.prefix.getPrefixLength(), prefix.getAddress(), prefix.getPrefixLength()) == true) {
- if (node.prefix.getPrefixLength() == prefix.getPrefixLength()) {
- /*
- * Prefix is already in tree. This may be an aggregate node, in which case
- * we are inserting a new prefix, or it could be an actual node, in which
- * case we are inserting a new nexthop for the prefix and should return
- * the old nexthop.
- */
- V oldValue = node.value;
- node.value = value;
- return oldValue;
- }
+ private Node top;
- match = node;
-
- if (bit_check(prefix.getAddress(), node.prefix.getPrefixLength()) == true) {
- node = node.right;
- } else {
- node = node.left;
- }
- }
+ public PatriciaTrie(int maxPrefixLength) {
+ this.maxPrefixLength = maxPrefixLength;
+ }
- Node add = null;
-
- if (node == null) {
- //add = new Node(p, r);
- add = new Node(prefix);
- add.value = value;
-
- if (match != null) {
- node_link(match, add);
- } else {
- top = add;
- }
- } else {
- add = node_common(node, prefix.getAddress(), prefix.getPrefixLength());
- if (add == null) {
- //I think this is -ENOMEM?
- //return null;
- }
-
- if (match != null) {
- node_link(match, add);
- } else {
- top = add;
- }
- node_link(add, node);
-
- if (add.prefix.getPrefixLength() != prefix.getPrefixLength()) {
- match = add;
-
- //add = new Node(p, r);
- add = new Node(prefix);
- add.value = value;
- node_link(match, add);
- }
- else {
- add.value = value;
- }
- }
-
- //If we added a new Node, there was no previous mapping
- return null;
- //return addReference(add);
- }
-
- /*exact match*/
- @Override
- public synchronized V lookup(Prefix prefix) {
- if (prefix.getPrefixLength() > maxPrefixLength) {
- return null;
- }
-
- /*
- Node node = top;
-
- while (node != null
- && node.prefix.getPrefixLength() <= p.getPrefixLength()
- && key_match(node.prefix.getAddress(), node.prefix.getPrefixLength(), p.getAddress(), p.getPrefixLength()) == true) {
- if (node.prefix.getPrefixLength() == p.getPrefixLength()) {
- //return addReference(node);
- return node.rib;
- }
-
- if (bit_check(p.getAddress(), node.prefix.getPrefixLength()) == true) {
- node = node.right;
- } else {
- node = node.left;
- }
- }
- */
-
- Node node = findNode(prefix);
-
- return node == null ? null : node.value;
- }
-
- /*closest containing prefix*/
- @Override
- public synchronized V match(Prefix prefix) {
- //TODO
- if (prefix.getPrefixLength() > maxPrefixLength) {
- return null;
- }
-
- Node closestNode = findClosestNode(prefix);
-
- return closestNode == null ? null : closestNode.value;
- }
-
- @Override
- public synchronized boolean remove(Prefix prefix, V value) {
- Node child;
- Node parent;
-
- if (prefix == null || value == null) {
- return false;
- }
-
- Node node = findNode(prefix);
-
- if (node == null || node.isAggregate() || !node.value.equals(value)) {
- //Given <prefix, nexthop> mapping is not in the tree
- return false;
- }
-
- if (node.left != null && node.right != null) {
- //Remove the RibEntry entry and leave this node as an aggregate node
- //In the future, maybe we should re-evaluate what the aggregate prefix should be?
- //It shouldn't necessarily stay the same.
- //More complicated if the above prefix is also aggregate.
- node.value = null;
- return true;
- }
-
- if (node.left != null) {
- child = node.left;
- } else {
- child = node.right;
- }
-
- parent = node.parent;
-
- if (child != null) {
- child.parent = parent;
- }
-
- if (parent != null) {
- if (parent.left == node) {
- parent.left = child;
- } else {
- parent.right = child;
- }
- } else {
- top = child;
- }
-
- /*
- * TODO not sure what to do here. I think this is lazily deleting aggregate nodes,
- * notice that it used to do nothing if it detected both children were not null earlier.
- * But here, what we really should do is reevaluate the aggregate prefix of the parent
- * node (if it is indeed an aggregate). Because at the moment, no aggregate node will ever
- * be removed. BUT, I don't actually think this presents a correctness problem, at
- * least from an external point of view.
- */
- //if (parent != null && parent.refCount == 0) {
- //node_remove(parent);
- //}
-
- return true;
- }
-
- @Override
- public Iterator<Entry<V>> iterator() {
- return new PatriciaTrieIterator(top);
- }
-
- private Node findNode(Prefix prefix) {
- Node node = top;
-
- while (node != null
- && node.prefix.getPrefixLength() <= prefix.getPrefixLength()
- && key_match(node.prefix.getAddress(), node.prefix.getPrefixLength(), prefix.getAddress(), prefix.getPrefixLength()) == true) {
- if (node.prefix.getPrefixLength() == prefix.getPrefixLength()) {
- //return addReference(node);
- return node;
- }
-
- if (bit_check(prefix.getAddress(), node.prefix.getPrefixLength()) == true) {
- node = node.right;
- } else {
- node = node.left;
- }
- }
-
- return null;
- }
-
- private Node findClosestNode(Prefix prefix) {
- Node node = top;
- Node match = null;
-
- while (node != null
- && node.prefix.getPrefixLength() <= prefix.getPrefixLength()
- && key_match(node.prefix.getAddress(), node.prefix.getPrefixLength(), prefix.getAddress(), prefix.getPrefixLength()) == true) {
- if (!node.isAggregate()) {
- match = node;
- }
-
- if (bit_check(prefix.getAddress(), node.prefix.getPrefixLength()) == true) {
- node = node.right;
- } else {
- node = node.left;
- }
- }
-
- return match;
- }
-
- /*
- * Receives a 1-based bit index
- * Returns a 1-based byte index
- * eg. (0 => 1), 1 => 1, 8 => 1, 9 => 2, 17 => 3
- */
- private int getByteContainingBit(int bitNumber) {
- return Math.max((bitNumber + 7) / 8, 1);
- }
-
- private boolean key_match(byte [] key1, int key1_len, byte [] key2, int key2_len) {
- //int offset;
- //int shift;
-
- if (key1_len > key2_len) {
- return false;
- }
-
- int offset = (Math.min(key1_len, key2_len)) / 8;
- int shift = (Math.min(key1_len, key2_len)) % 8;
-
- if (shift != 0) {
- if ((maskBits[shift] & (key1[offset] ^ key2[offset])) != 0) {
- return false;
- }
- }
-
- while (offset != 0) {
- offset--;
- if (key1[offset] != key2[offset]) {
- return false;
- }
- }
- return true;
- }
-
- private boolean bit_check(byte [] key, int key_bits) {
- int offset = key_bits / 8;
- int shift = 7 - (key_bits % 8);
- int bit = key[offset] & 0xff;
+ @Override
+ public synchronized V put(Prefix prefix, V value) {
+ if (prefix == null || value == null) {
+ throw new NullPointerException();
+ }
- bit >>= shift;
-
- if ((bit & 1) == 1) {
- return true;
- } else {
- return false;
- }
- }
-
- private void node_link(Node node, Node add) {
- boolean bit = bit_check(add.prefix.getAddress(), node.prefix.getPrefixLength());
-
- if (bit == true) {
- node.right = add;
- } else {
- node.left = add;
- }
- add.parent = node;
- }
-
- private Node node_common(Node node, byte [] key, int key_bits) {
- int i;
- int limit = Math.min(node.prefix.getPrefixLength(), key_bits) / 8;
+ if (prefix.getPrefixLength() > maxPrefixLength) {
+ throw new IllegalArgumentException(String.format(
+ "Prefix length %d is greater than max prefix length %d",
+ prefix.getPrefixLength(), maxPrefixLength));
+ }
- for (i = 0; i < limit; i++) {
- if (node.prefix.getAddress()[i] != key[i]) {
- break;
- }
- }
-
- int common_len = i * 8;
- int boundary = 0;
+ Node node = top;
+ Node match = null;
- if (common_len != key_bits) {
- byte diff = (byte)(node.prefix.getAddress()[i] ^ key[i]);
- byte mask = (byte)0x80;
- int shift_mask = 0;
-
- while (common_len < key_bits && ((mask & diff) == 0)) {
- boundary = 1;
+ while (node != null
+ && node.prefix.getPrefixLength() <= prefix.getPrefixLength()
+ && key_match(node.prefix.getAddress(), node.prefix.getPrefixLength(), prefix.getAddress(), prefix.getPrefixLength()) == true) {
+ if (node.prefix.getPrefixLength() == prefix.getPrefixLength()) {
+ /*
+ * Prefix is already in tree. This may be an aggregate node, in which case
+ * we are inserting a new prefix, or it could be an actual node, in which
+ * case we are inserting a new nexthop for the prefix and should return
+ * the old nexthop.
+ */
+ V oldValue = node.value;
+ node.value = value;
+ return oldValue;
+ }
- shift_mask = (mask & 0xff);
- shift_mask >>= 1;
- mask = (byte)shift_mask;
+ match = node;
- common_len++;
- }
- }
-
- //Node add = new Node(null, common_len, maxKeyOctets);
- //if (add == null)
- //Another -ENOMEM;
- //return null;
-
- //Creating a new Prefix with a prefix length of common_len
- //Bits are copied from node's up until the common_len'th bit
- //RibEntry is null, because this is an aggregate prefix - it's not
- //actually been added to the trie.
-
- byte[] newPrefix = new byte[getByteContainingBit(maxPrefixLength)];
-
- int j;
- for (j = 0; j < i; j++)
- newPrefix[j] = node.prefix.getAddress()[j];
+ if (bit_check(prefix.getAddress(), node.prefix.getPrefixLength()) == true) {
+ node = node.right;
+ } else {
+ node = node.left;
+ }
+ }
- if (boundary != 0)
- newPrefix[j] = (byte)(node.prefix.getAddress()[j] & maskBits[common_len % 8]);
-
- //return new Node(new Prefix(newPrefix, common_len), null);
- return new Node(new Prefix(newPrefix, common_len));
- //return add;
- }
-
- private class Node {
- public Node parent = null;
- public Node left = null;
- public Node right = null;
-
- public final Prefix prefix;
- public V value;
-
- //public Node(Prefix p, RibEntry r) {
- // this.prefix = p;
- // this.rib = r;
- //}
- public Node(Prefix p) {
- this.prefix = p;
- }
-
- public boolean isAggregate() {
- return value == null;
- }
-
- public Entry<V> getEntry() {
- return new PatriciaTrieEntry(prefix, value);
- }
- }
-
- private class PatriciaTrieEntry implements Entry<V> {
- private Prefix prefix;
- private V value;
-
- public PatriciaTrieEntry(Prefix prefix, V value) {
- this.prefix = prefix;
- this.value = value;
- }
-
- @Override
- public Prefix getPrefix() {
- return prefix;
- }
-
- @Override
- public V getValue() {
- return value;
- }
- }
-
- private class PatriciaTrieIterator implements Iterator<Entry<V>> {
-
- private Node current;
- private boolean started = false;
-
- public PatriciaTrieIterator(Node start) {
- current = start;
-
- //If the start is an aggregate node fast forward to find the next valid node
- if (current != null && current.isAggregate()) {
- current = findNext(current);
- }
- }
+ Node add = null;
- @Override
- public boolean hasNext() {
- if (current == null) {
- return false;
- }
-
- if (!started) {
- return true;
- }
-
- return findNext(current) != null;
- }
+ if (node == null) {
+ //add = new Node(p, r);
+ add = new Node(prefix);
+ add.value = value;
- @Override
- public Entry<V> next() {
- if (current == null) {
- throw new NoSuchElementException();
- }
-
- if (!started) {
- started = true;
- return current.getEntry();
- }
-
- current = findNext(current);
- if (current == null) {
- throw new NoSuchElementException();
- }
-
- return current.getEntry();
- }
+ if (match != null) {
+ node_link(match, add);
+ } else {
+ top = add;
+ }
+ } else {
+ add = node_common(node, prefix.getAddress(), prefix.getPrefixLength());
+ if (add == null) {
+ //I think this is -ENOMEM?
+ //return null;
+ }
- @Override
- public void remove() {
- // TODO This could be implemented, if it were needed
- throw new NoSuchElementException();
- }
-
- private Node findNext(Node node) {
- Node next = null;
-
- if (node.left != null) {
- next = node.left;
- //addReference(next);
- //delReference(node);
- //return next;
- }
- else if (node.right != null) {
- next = node.right;
- //addReference(next);
- //delReference(node);
- //return next;
- }
- else {
- //Node start = node;
- while (node.parent != null) {
- if (node.parent.left == node && node.parent.right != null) {
- next = node.parent.right;
- //addReference(next);
- //delReference(start);
- //return next;
- break;
- }
- node = node.parent;
- }
- }
-
- if (next == null) {
- return null;
- }
-
- //If the node doesn't have a value, it's not an actual node, it's an artifically
- //inserted aggregate node. We don't want to return these to the user.
- if (next.isAggregate()) {
- return findNext(next);
- }
-
- return next;
- }
- }
+ if (match != null) {
+ node_link(match, add);
+ } else {
+ top = add;
+ }
+ node_link(add, node);
+
+ if (add.prefix.getPrefixLength() != prefix.getPrefixLength()) {
+ match = add;
+
+ //add = new Node(p, r);
+ add = new Node(prefix);
+ add.value = value;
+ node_link(match, add);
+ } else {
+ add.value = value;
+ }
+ }
+
+ //If we added a new Node, there was no previous mapping
+ return null;
+ //return addReference(add);
+ }
+
+ /*exact match*/
+ @Override
+ public synchronized V lookup(Prefix prefix) {
+ if (prefix.getPrefixLength() > maxPrefixLength) {
+ return null;
+ }
+
+ /*
+ Node node = top;
+
+ while (node != null
+ && node.prefix.getPrefixLength() <= p.getPrefixLength()
+ && key_match(node.prefix.getAddress(), node.prefix.getPrefixLength(), p.getAddress(), p.getPrefixLength()) == true) {
+ if (node.prefix.getPrefixLength() == p.getPrefixLength()) {
+ //return addReference(node);
+ return node.rib;
+ }
+
+ if (bit_check(p.getAddress(), node.prefix.getPrefixLength()) == true) {
+ node = node.right;
+ } else {
+ node = node.left;
+ }
+ }
+ */
+
+ Node node = findNode(prefix);
+
+ return node == null ? null : node.value;
+ }
+
+ /*closest containing prefix*/
+ @Override
+ public synchronized V match(Prefix prefix) {
+ //TODO
+ if (prefix.getPrefixLength() > maxPrefixLength) {
+ return null;
+ }
+
+ Node closestNode = findClosestNode(prefix);
+
+ return closestNode == null ? null : closestNode.value;
+ }
+
+ @Override
+ public synchronized boolean remove(Prefix prefix, V value) {
+ Node child;
+ Node parent;
+
+ if (prefix == null || value == null) {
+ return false;
+ }
+
+ Node node = findNode(prefix);
+
+ if (node == null || node.isAggregate() || !node.value.equals(value)) {
+ //Given <prefix, nexthop> mapping is not in the tree
+ return false;
+ }
+
+ if (node.left != null && node.right != null) {
+ //Remove the RibEntry entry and leave this node as an aggregate node
+ //In the future, maybe we should re-evaluate what the aggregate prefix should be?
+ //It shouldn't necessarily stay the same.
+ //More complicated if the above prefix is also aggregate.
+ node.value = null;
+ return true;
+ }
+
+ if (node.left != null) {
+ child = node.left;
+ } else {
+ child = node.right;
+ }
+
+ parent = node.parent;
+
+ if (child != null) {
+ child.parent = parent;
+ }
+
+ if (parent != null) {
+ if (parent.left == node) {
+ parent.left = child;
+ } else {
+ parent.right = child;
+ }
+ } else {
+ top = child;
+ }
+
+ /*
+ * TODO not sure what to do here. I think this is lazily deleting aggregate nodes,
+ * notice that it used to do nothing if it detected both children were not null earlier.
+ * But here, what we really should do is reevaluate the aggregate prefix of the parent
+ * node (if it is indeed an aggregate). Because at the moment, no aggregate node will ever
+ * be removed. BUT, I don't actually think this presents a correctness problem, at
+ * least from an external point of view.
+ */
+ //if (parent != null && parent.refCount == 0) {
+ //node_remove(parent);
+ //}
+
+ return true;
+ }
+
+ @Override
+ public Iterator<Entry<V>> iterator() {
+ return new PatriciaTrieIterator(top);
+ }
+
+ private Node findNode(Prefix prefix) {
+ Node node = top;
+
+ while (node != null
+ && node.prefix.getPrefixLength() <= prefix.getPrefixLength()
+ && key_match(node.prefix.getAddress(), node.prefix.getPrefixLength(), prefix.getAddress(), prefix.getPrefixLength()) == true) {
+ if (node.prefix.getPrefixLength() == prefix.getPrefixLength()) {
+ //return addReference(node);
+ return node;
+ }
+
+ if (bit_check(prefix.getAddress(), node.prefix.getPrefixLength()) == true) {
+ node = node.right;
+ } else {
+ node = node.left;
+ }
+ }
+
+ return null;
+ }
+
+ private Node findClosestNode(Prefix prefix) {
+ Node node = top;
+ Node match = null;
+
+ while (node != null
+ && node.prefix.getPrefixLength() <= prefix.getPrefixLength()
+ && key_match(node.prefix.getAddress(), node.prefix.getPrefixLength(), prefix.getAddress(), prefix.getPrefixLength()) == true) {
+ if (!node.isAggregate()) {
+ match = node;
+ }
+
+ if (bit_check(prefix.getAddress(), node.prefix.getPrefixLength()) == true) {
+ node = node.right;
+ } else {
+ node = node.left;
+ }
+ }
+
+ return match;
+ }
+
+ /*
+ * Receives a 1-based bit index
+ * Returns a 1-based byte index
+ * eg. (0 => 1), 1 => 1, 8 => 1, 9 => 2, 17 => 3
+ */
+ private int getByteContainingBit(int bitNumber) {
+ return Math.max((bitNumber + 7) / 8, 1);
+ }
+
+ private boolean key_match(byte[] key1, int key1_len, byte[] key2, int key2_len) {
+ //int offset;
+ //int shift;
+
+ if (key1_len > key2_len) {
+ return false;
+ }
+
+ int offset = (Math.min(key1_len, key2_len)) / 8;
+ int shift = (Math.min(key1_len, key2_len)) % 8;
+
+ if (shift != 0) {
+ if ((maskBits[shift] & (key1[offset] ^ key2[offset])) != 0) {
+ return false;
+ }
+ }
+
+ while (offset != 0) {
+ offset--;
+ if (key1[offset] != key2[offset]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean bit_check(byte[] key, int key_bits) {
+ int offset = key_bits / 8;
+ int shift = 7 - (key_bits % 8);
+ int bit = key[offset] & 0xff;
+
+ bit >>= shift;
+
+ if ((bit & 1) == 1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private void node_link(Node node, Node add) {
+ boolean bit = bit_check(add.prefix.getAddress(), node.prefix.getPrefixLength());
+
+ if (bit == true) {
+ node.right = add;
+ } else {
+ node.left = add;
+ }
+ add.parent = node;
+ }
+
+ private Node node_common(Node node, byte[] key, int key_bits) {
+ int i;
+ int limit = Math.min(node.prefix.getPrefixLength(), key_bits) / 8;
+
+ for (i = 0; i < limit; i++) {
+ if (node.prefix.getAddress()[i] != key[i]) {
+ break;
+ }
+ }
+
+ int common_len = i * 8;
+ int boundary = 0;
+
+ if (common_len != key_bits) {
+ byte diff = (byte) (node.prefix.getAddress()[i] ^ key[i]);
+ byte mask = (byte) 0x80;
+ int shift_mask = 0;
+
+ while (common_len < key_bits && ((mask & diff) == 0)) {
+ boundary = 1;
+
+ shift_mask = (mask & 0xff);
+ shift_mask >>= 1;
+ mask = (byte) shift_mask;
+
+ common_len++;
+ }
+ }
+
+ //Node add = new Node(null, common_len, maxKeyOctets);
+ //if (add == null)
+ //Another -ENOMEM;
+ //return null;
+
+ //Creating a new Prefix with a prefix length of common_len
+ //Bits are copied from node's up until the common_len'th bit
+ //RibEntry is null, because this is an aggregate prefix - it's not
+ //actually been added to the trie.
+
+ byte[] newPrefix = new byte[getByteContainingBit(maxPrefixLength)];
+
+ int j;
+ for (j = 0; j < i; j++)
+ newPrefix[j] = node.prefix.getAddress()[j];
+
+ if (boundary != 0)
+ newPrefix[j] = (byte) (node.prefix.getAddress()[j] & maskBits[common_len % 8]);
+
+ //return new Node(new Prefix(newPrefix, common_len), null);
+ return new Node(new Prefix(newPrefix, common_len));
+ //return add;
+ }
+
+ private class Node {
+ public Node parent = null;
+ public Node left = null;
+ public Node right = null;
+
+ public final Prefix prefix;
+ public V value;
+
+ //public Node(Prefix p, RibEntry r) {
+ // this.prefix = p;
+ // this.rib = r;
+ //}
+ public Node(Prefix p) {
+ this.prefix = p;
+ }
+
+ public boolean isAggregate() {
+ return value == null;
+ }
+
+ public Entry<V> getEntry() {
+ return new PatriciaTrieEntry(prefix, value);
+ }
+ }
+
+ private class PatriciaTrieEntry implements Entry<V> {
+ private Prefix prefix;
+ private V value;
+
+ public PatriciaTrieEntry(Prefix prefix, V value) {
+ this.prefix = prefix;
+ this.value = value;
+ }
+
+ @Override
+ public Prefix getPrefix() {
+ return prefix;
+ }
+
+ @Override
+ public V getValue() {
+ return value;
+ }
+ }
+
+ private class PatriciaTrieIterator implements Iterator<Entry<V>> {
+
+ private Node current;
+ private boolean started = false;
+
+ public PatriciaTrieIterator(Node start) {
+ current = start;
+
+ //If the start is an aggregate node fast forward to find the next valid node
+ if (current != null && current.isAggregate()) {
+ current = findNext(current);
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (current == null) {
+ return false;
+ }
+
+ if (!started) {
+ return true;
+ }
+
+ return findNext(current) != null;
+ }
+
+ @Override
+ public Entry<V> next() {
+ if (current == null) {
+ throw new NoSuchElementException();
+ }
+
+ if (!started) {
+ started = true;
+ return current.getEntry();
+ }
+
+ current = findNext(current);
+ if (current == null) {
+ throw new NoSuchElementException();
+ }
+
+ return current.getEntry();
+ }
+
+ @Override
+ public void remove() {
+ // TODO This could be implemented, if it were needed
+ throw new NoSuchElementException();
+ }
+
+ private Node findNext(Node node) {
+ Node next = null;
+
+ if (node.left != null) {
+ next = node.left;
+ //addReference(next);
+ //delReference(node);
+ //return next;
+ } else if (node.right != null) {
+ next = node.right;
+ //addReference(next);
+ //delReference(node);
+ //return next;
+ } else {
+ //Node start = node;
+ while (node.parent != null) {
+ if (node.parent.left == node && node.parent.right != null) {
+ next = node.parent.right;
+ //addReference(next);
+ //delReference(start);
+ //return next;
+ break;
+ }
+ node = node.parent;
+ }
+ }
+
+ if (next == null) {
+ return null;
+ }
+
+ //If the node doesn't have a value, it's not an actual node, it's an artifically
+ //inserted aggregate node. We don't want to return these to the user.
+ if (next.isAggregate()) {
+ return findNext(next);
+ }
+
+ return next;
+ }
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/Prefix.java b/src/main/java/net/onrc/onos/apps/bgproute/Prefix.java
index 8539759..5e5ba91 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/Prefix.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/Prefix.java
@@ -7,129 +7,129 @@
import com.google.common.net.InetAddresses;
public class Prefix {
- private final int MAX_BYTES = 4;
-
- private final int prefixLength;
- private final byte[] address;
-
- //For verifying the arguments and pretty printing
- private final InetAddress inetAddress;
-
- public Prefix(byte[] addr, int prefixLength) {
- if (addr == null || addr.length != MAX_BYTES ||
- prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
- throw new IllegalArgumentException();
- }
+ private final int MAX_BYTES = 4;
- address = canonicalizeAddress(addr, prefixLength);
- this.prefixLength = prefixLength;
-
- try {
- inetAddress = InetAddress.getByAddress(address);
- } catch (UnknownHostException e) {
- throw new IllegalArgumentException();
- }
- }
+ private final int prefixLength;
+ private final byte[] address;
- public Prefix(String strAddress, int prefixLength) {
- byte[] addr = null;
- addr = InetAddresses.forString(strAddress).getAddress();
-
- if (addr == null || addr.length != MAX_BYTES ||
- prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
- throw new IllegalArgumentException();
- }
-
- address = canonicalizeAddress(addr, prefixLength);
- this.prefixLength = prefixLength;
-
- try {
- inetAddress = InetAddress.getByAddress(address);
- } catch (UnknownHostException e) {
- throw new IllegalArgumentException();
- }
- }
-
- private byte[] canonicalizeAddress(byte[] address, int prefixLength) {
- byte[] result = new byte[address.length];
-
- if (prefixLength == 0) {
- for (int i = 0; i < MAX_BYTES; i++) {
- result[i] = 0;
- }
-
- return result;
- }
-
- result = Arrays.copyOf(address, address.length);
-
- //Set all bytes after the end of the prefix to 0
- int lastByteIndex = (prefixLength - 1) / Byte.SIZE;
- for (int i = lastByteIndex; i < MAX_BYTES; i++) {
- result[i] = 0;
- }
-
- byte lastByte = address[lastByteIndex];
- byte mask = 0;
- byte msb = (byte) 0x80;
- int lastBit = (prefixLength - 1) % Byte.SIZE;
- for (int i = 0; i < Byte.SIZE; i++) {
- if (i <= lastBit) {
- mask |= (msb >> i);
- }
- }
+ //For verifying the arguments and pretty printing
+ private final InetAddress inetAddress;
- result[lastByteIndex] = (byte) (lastByte & mask);
-
- return result;
- }
+ public Prefix(byte[] addr, int prefixLength) {
+ if (addr == null || addr.length != MAX_BYTES ||
+ prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
+ throw new IllegalArgumentException();
+ }
- public int getPrefixLength() {
- return prefixLength;
- }
-
- public byte[] getAddress() {
- return address;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == null || !(other instanceof Prefix)) {
- return false;
- }
-
- Prefix otherPrefix = (Prefix) other;
-
- return (Arrays.equals(address, otherPrefix.address)) &&
- (prefixLength == otherPrefix.prefixLength);
- }
-
- @Override
- public int hashCode() {
- int hash = 17;
- hash = 31 * hash + prefixLength;
- hash = 31 * hash + Arrays.hashCode(address);
- return hash;
- }
-
- @Override
- public String toString() {
- return inetAddress.getHostAddress() + "/" + prefixLength;
- }
-
- public String printAsBits() {
- String result = "";
- for (int i = 0; i < address.length; i++) {
- byte b = address[i];
- for (int j = 0; j < Byte.SIZE; j++) {
- byte mask = (byte) (0x80 >>> j);
- result += ((b & mask) == 0)? "0" : "1";
- if (i*Byte.SIZE+j == prefixLength-1) {
- return result;
- }
- }
- result += " ";
- }
- return result.substring(0, result.length() - 1);
- }
+ address = canonicalizeAddress(addr, prefixLength);
+ this.prefixLength = prefixLength;
+
+ try {
+ inetAddress = InetAddress.getByAddress(address);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public Prefix(String strAddress, int prefixLength) {
+ byte[] addr = null;
+ addr = InetAddresses.forString(strAddress).getAddress();
+
+ if (addr == null || addr.length != MAX_BYTES ||
+ prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
+ throw new IllegalArgumentException();
+ }
+
+ address = canonicalizeAddress(addr, prefixLength);
+ this.prefixLength = prefixLength;
+
+ try {
+ inetAddress = InetAddress.getByAddress(address);
+ } catch (UnknownHostException e) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private byte[] canonicalizeAddress(byte[] address, int prefixLength) {
+ byte[] result = new byte[address.length];
+
+ if (prefixLength == 0) {
+ for (int i = 0; i < MAX_BYTES; i++) {
+ result[i] = 0;
+ }
+
+ return result;
+ }
+
+ result = Arrays.copyOf(address, address.length);
+
+ //Set all bytes after the end of the prefix to 0
+ int lastByteIndex = (prefixLength - 1) / Byte.SIZE;
+ for (int i = lastByteIndex; i < MAX_BYTES; i++) {
+ result[i] = 0;
+ }
+
+ byte lastByte = address[lastByteIndex];
+ byte mask = 0;
+ byte msb = (byte) 0x80;
+ int lastBit = (prefixLength - 1) % Byte.SIZE;
+ for (int i = 0; i < Byte.SIZE; i++) {
+ if (i <= lastBit) {
+ mask |= (msb >> i);
+ }
+ }
+
+ result[lastByteIndex] = (byte) (lastByte & mask);
+
+ return result;
+ }
+
+ public int getPrefixLength() {
+ return prefixLength;
+ }
+
+ public byte[] getAddress() {
+ return address;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null || !(other instanceof Prefix)) {
+ return false;
+ }
+
+ Prefix otherPrefix = (Prefix) other;
+
+ return (Arrays.equals(address, otherPrefix.address)) &&
+ (prefixLength == otherPrefix.prefixLength);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 17;
+ hash = 31 * hash + prefixLength;
+ hash = 31 * hash + Arrays.hashCode(address);
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ return inetAddress.getHostAddress() + "/" + prefixLength;
+ }
+
+ public String printAsBits() {
+ String result = "";
+ for (int i = 0; i < address.length; i++) {
+ byte b = address[i];
+ for (int j = 0; j < Byte.SIZE; j++) {
+ byte mask = (byte) (0x80 >>> j);
+ result += ((b & mask) == 0) ? "0" : "1";
+ if (i * Byte.SIZE + j == prefixLength - 1) {
+ return result;
+ }
+ }
+ result += " ";
+ }
+ return result.substring(0, result.length() - 1);
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/Ptree.java b/src/main/java/net/onrc/onos/apps/bgproute/Ptree.java
index 682066a..9a0400f 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/Ptree.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/Ptree.java
@@ -11,312 +11,312 @@
* we don't leak them out the the Ptree.
*/
public class Ptree {
- private int maxKeyBits;
- private int maxKeyOctets;
- //private int refCount;
- private PtreeNode top;
- private byte maskBits[] = { (byte)0x00, (byte)0x80, (byte)0xc0, (byte)0xe0, (byte)0xf0, (byte)0xf8, (byte)0xfc, (byte)0xfe, (byte)0xff };
-
- public Ptree(int max_key_bits) {
- maxKeyBits = max_key_bits;
- maxKeyOctets = bit_to_octet(max_key_bits);
- //refCount = 0;
- }
-
- public synchronized PtreeNode acquire(byte [] key) {
- return acquire(key, maxKeyBits);
- }
-
- public synchronized PtreeNode acquire(byte [] key, int key_bits) {
- if (key_bits > maxKeyBits) {
- return null;
- }
-
- PtreeNode node = top;
- PtreeNode match = null;
-
- while (node != null
- && node.keyBits <= key_bits
- && key_match(node.key, node.keyBits, key, key_bits) == true) {
- if (node.keyBits == key_bits) {
- return addReference(node);
- }
+ private int maxKeyBits;
+ private int maxKeyOctets;
+ //private int refCount;
+ private PtreeNode top;
+ private byte maskBits[] = {(byte) 0x00, (byte) 0x80, (byte) 0xc0, (byte) 0xe0, (byte) 0xf0, (byte) 0xf8, (byte) 0xfc, (byte) 0xfe, (byte) 0xff};
- match = node;
-
- if (bit_check(key, node.keyBits) == true) {
- node = node.right;
- } else {
- node = node.left;
- }
- }
+ public Ptree(int max_key_bits) {
+ maxKeyBits = max_key_bits;
+ maxKeyOctets = bit_to_octet(max_key_bits);
+ //refCount = 0;
+ }
- PtreeNode add = null;
-
- if (node == null) {
- add = new PtreeNode(key, key_bits, maxKeyOctets);
-
- if (match != null) {
- node_link(match, add);
- } else {
- top = add;
- }
- } else {
- add = node_common(node, key, key_bits);
- if (add == null) {
- return null;
- }
-
- if (match != null) {
- node_link(match, add);
- } else {
- top = add;
- }
- node_link(add, node);
-
- if (add.keyBits != key_bits) {
- match = add;
-
- add = new PtreeNode(key, key_bits, maxKeyOctets);
- node_link(match, add);
- }
- }
-
- return addReference(add);
- }
+ public synchronized PtreeNode acquire(byte[] key) {
+ return acquire(key, maxKeyBits);
+ }
- public synchronized PtreeNode lookup(byte [] key, int key_bits) {
- if (key_bits > maxKeyBits) {
- return null;
- }
-
- PtreeNode node = top;
-
- while (node != null
- && node.keyBits <= key_bits
- && key_match(node.key, node.keyBits, key, key_bits) == true) {
- if (node.keyBits == key_bits) {
- return addReference(node);
- }
-
- if (bit_check(key, node.keyBits) == true) {
- node = node.right;
- } else {
- node = node.left;
- }
- }
- return null;
- }
-
- public synchronized PtreeNode match(byte [] key, int key_bits) {
- if (key_bits > maxKeyBits) {
- return null;
- }
- PtreeNode node = top;
- PtreeNode matched = null;
+ public synchronized PtreeNode acquire(byte[] key, int key_bits) {
+ if (key_bits > maxKeyBits) {
+ return null;
+ }
- if(node!=null)
-
- while (node != null
- && node.keyBits <= key_bits
- && key_match(node.key, node.keyBits, key, key_bits) == true) {
- matched = node;
-
- if (bit_check(key, node.keyBits) == true) {
- node = node.right;
- } else {
- node = node.left;
- }
- }
-
- if (matched != null) {
- return addReference(matched);
- }
-
- return null;
- }
-
- public synchronized PtreeNode begin() {
- if (top == null) {
- return null;
- }
- return addReference(top);
- }
-
- public synchronized PtreeNode next(PtreeNode node) {
- PtreeNode next;
-
- if (node.left != null) {
- next = node.left;
- addReference(next);
- delReference(node);
- return next;
- }
- if (node.right != null) {
- next = node.right;
- addReference(next);
- delReference(node);
- return next;
- }
-
- PtreeNode start = node;
- while (node.parent != null) {
- if (node.parent.left == node && node.parent.right != null) {
- next = node.parent.right;
- addReference(next);
- delReference(start);
- return next;
- }
- node = node.parent;
- }
-
- delReference(start);
-
- return null;
- }
+ PtreeNode node = top;
+ PtreeNode match = null;
- static public int bit_to_octet(int key_bits) {
- return Math.max((key_bits + 7) / 8, 1);
- }
+ while (node != null
+ && node.keyBits <= key_bits
+ && key_match(node.key, node.keyBits, key, key_bits) == true) {
+ if (node.keyBits == key_bits) {
+ return addReference(node);
+ }
- private PtreeNode addReference(PtreeNode node) {
- node.refCount++;
- return node;
- }
-
- public synchronized void delReference(PtreeNode node) {
- if (node.refCount > 0) {
- node.refCount--;
- }
- if (node.refCount == 0) {
- node_remove(node);
- }
- }
-
- private boolean key_match(byte [] key1, int key1_len, byte [] key2, int key2_len) {
- int offset;
- int shift;
-
- if (key1_len > key2_len) {
- return false;
- }
-
- offset = (Math.min(key1_len, key2_len)) / 8;
- shift = (Math.min(key1_len, key2_len)) % 8;
-
- if (shift != 0) {
- if ((maskBits[shift] & (key1[offset] ^ key2[offset])) != 0) {
- return false;
- }
- }
-
- while (offset != 0) {
- offset--;
- if (key1[offset] != key2[offset]) {
- return false;
- }
- }
- return true;
- }
-
- private boolean bit_check(byte [] key, int key_bits) {
- int offset = key_bits / 8;
- int shift = 7 - (key_bits % 8);
- int bit = key[offset] & 0xff;
+ match = node;
- bit >>= shift;
-
- if ((bit & 1) == 1) {
- return true;
- } else {
- return false;
- }
- }
-
- private void node_link(PtreeNode node, PtreeNode add) {
- boolean bit = bit_check(add.key, node.keyBits);
-
- if (bit == true) {
- node.right = add;
- } else {
- node.left = add;
- }
- add.parent = node;
- }
-
- private PtreeNode node_common(PtreeNode node, byte [] key, int key_bits) {
- int i;
- int limit = Math.min(node.keyBits, key_bits) / 8;
+ if (bit_check(key, node.keyBits) == true) {
+ node = node.right;
+ } else {
+ node = node.left;
+ }
+ }
- for (i = 0; i < limit; i++) {
- if (node.key[i] != key[i]) {
- break;
- }
- }
-
- int common_len = i * 8;
- int boundary = 0;
+ PtreeNode add = null;
- if (common_len != key_bits) {
- byte diff = (byte)(node.key[i] ^ key[i]);
- byte mask = (byte)0x80;
- int shift_mask = 0;
-
- while (common_len < key_bits && ((mask & diff) == 0)) {
- boundary = 1;
+ if (node == null) {
+ add = new PtreeNode(key, key_bits, maxKeyOctets);
- shift_mask = (mask & 0xff);
- shift_mask >>= 1;
- mask = (byte)shift_mask;
+ if (match != null) {
+ node_link(match, add);
+ } else {
+ top = add;
+ }
+ } else {
+ add = node_common(node, key, key_bits);
+ if (add == null) {
+ return null;
+ }
- common_len++;
- }
- }
-
- PtreeNode add = new PtreeNode(null, common_len, maxKeyOctets);
-
- int j;
- for (j = 0; j < i; j++)
- add.key[j] = node.key[j];
+ if (match != null) {
+ node_link(match, add);
+ } else {
+ top = add;
+ }
+ node_link(add, node);
- if (boundary != 0)
- add.key[j] = (byte)(node.key[j] & maskBits[add.keyBits % 8]);
-
- return add;
- }
-
- private void node_remove(PtreeNode node) {
- PtreeNode child;
- PtreeNode parent;
-
- if (node.left != null && node.right != null) {
- return;
- }
-
- if (node.left != null) {
- child = node.left;
- } else {
- child = node.right;
- }
-
- parent = node.parent;
-
- if (child != null) {
- child.parent = parent;
- }
-
- if (parent != null) {
- if (parent.left == node) {
- parent.left = child;
- } else {
- parent.right = child;
- }
- } else {
- top = child;
- }
-
- if (parent != null && parent.refCount == 0) {
- node_remove(parent);
- }
- }
+ if (add.keyBits != key_bits) {
+ match = add;
+
+ add = new PtreeNode(key, key_bits, maxKeyOctets);
+ node_link(match, add);
+ }
+ }
+
+ return addReference(add);
+ }
+
+ public synchronized PtreeNode lookup(byte[] key, int key_bits) {
+ if (key_bits > maxKeyBits) {
+ return null;
+ }
+
+ PtreeNode node = top;
+
+ while (node != null
+ && node.keyBits <= key_bits
+ && key_match(node.key, node.keyBits, key, key_bits) == true) {
+ if (node.keyBits == key_bits) {
+ return addReference(node);
+ }
+
+ if (bit_check(key, node.keyBits) == true) {
+ node = node.right;
+ } else {
+ node = node.left;
+ }
+ }
+ return null;
+ }
+
+ public synchronized PtreeNode match(byte[] key, int key_bits) {
+ if (key_bits > maxKeyBits) {
+ return null;
+ }
+ PtreeNode node = top;
+ PtreeNode matched = null;
+
+ if (node != null)
+
+ while (node != null
+ && node.keyBits <= key_bits
+ && key_match(node.key, node.keyBits, key, key_bits) == true) {
+ matched = node;
+
+ if (bit_check(key, node.keyBits) == true) {
+ node = node.right;
+ } else {
+ node = node.left;
+ }
+ }
+
+ if (matched != null) {
+ return addReference(matched);
+ }
+
+ return null;
+ }
+
+ public synchronized PtreeNode begin() {
+ if (top == null) {
+ return null;
+ }
+ return addReference(top);
+ }
+
+ public synchronized PtreeNode next(PtreeNode node) {
+ PtreeNode next;
+
+ if (node.left != null) {
+ next = node.left;
+ addReference(next);
+ delReference(node);
+ return next;
+ }
+ if (node.right != null) {
+ next = node.right;
+ addReference(next);
+ delReference(node);
+ return next;
+ }
+
+ PtreeNode start = node;
+ while (node.parent != null) {
+ if (node.parent.left == node && node.parent.right != null) {
+ next = node.parent.right;
+ addReference(next);
+ delReference(start);
+ return next;
+ }
+ node = node.parent;
+ }
+
+ delReference(start);
+
+ return null;
+ }
+
+ static public int bit_to_octet(int key_bits) {
+ return Math.max((key_bits + 7) / 8, 1);
+ }
+
+ private PtreeNode addReference(PtreeNode node) {
+ node.refCount++;
+ return node;
+ }
+
+ public synchronized void delReference(PtreeNode node) {
+ if (node.refCount > 0) {
+ node.refCount--;
+ }
+ if (node.refCount == 0) {
+ node_remove(node);
+ }
+ }
+
+ private boolean key_match(byte[] key1, int key1_len, byte[] key2, int key2_len) {
+ int offset;
+ int shift;
+
+ if (key1_len > key2_len) {
+ return false;
+ }
+
+ offset = (Math.min(key1_len, key2_len)) / 8;
+ shift = (Math.min(key1_len, key2_len)) % 8;
+
+ if (shift != 0) {
+ if ((maskBits[shift] & (key1[offset] ^ key2[offset])) != 0) {
+ return false;
+ }
+ }
+
+ while (offset != 0) {
+ offset--;
+ if (key1[offset] != key2[offset]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean bit_check(byte[] key, int key_bits) {
+ int offset = key_bits / 8;
+ int shift = 7 - (key_bits % 8);
+ int bit = key[offset] & 0xff;
+
+ bit >>= shift;
+
+ if ((bit & 1) == 1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private void node_link(PtreeNode node, PtreeNode add) {
+ boolean bit = bit_check(add.key, node.keyBits);
+
+ if (bit == true) {
+ node.right = add;
+ } else {
+ node.left = add;
+ }
+ add.parent = node;
+ }
+
+ private PtreeNode node_common(PtreeNode node, byte[] key, int key_bits) {
+ int i;
+ int limit = Math.min(node.keyBits, key_bits) / 8;
+
+ for (i = 0; i < limit; i++) {
+ if (node.key[i] != key[i]) {
+ break;
+ }
+ }
+
+ int common_len = i * 8;
+ int boundary = 0;
+
+ if (common_len != key_bits) {
+ byte diff = (byte) (node.key[i] ^ key[i]);
+ byte mask = (byte) 0x80;
+ int shift_mask = 0;
+
+ while (common_len < key_bits && ((mask & diff) == 0)) {
+ boundary = 1;
+
+ shift_mask = (mask & 0xff);
+ shift_mask >>= 1;
+ mask = (byte) shift_mask;
+
+ common_len++;
+ }
+ }
+
+ PtreeNode add = new PtreeNode(null, common_len, maxKeyOctets);
+
+ int j;
+ for (j = 0; j < i; j++)
+ add.key[j] = node.key[j];
+
+ if (boundary != 0)
+ add.key[j] = (byte) (node.key[j] & maskBits[add.keyBits % 8]);
+
+ return add;
+ }
+
+ private void node_remove(PtreeNode node) {
+ PtreeNode child;
+ PtreeNode parent;
+
+ if (node.left != null && node.right != null) {
+ return;
+ }
+
+ if (node.left != null) {
+ child = node.left;
+ } else {
+ child = node.right;
+ }
+
+ parent = node.parent;
+
+ if (child != null) {
+ child.parent = parent;
+ }
+
+ if (parent != null) {
+ if (parent.left == node) {
+ parent.left = child;
+ } else {
+ parent.right = child;
+ }
+ } else {
+ top = child;
+ }
+
+ if (parent != null && parent.refCount == 0) {
+ node_remove(parent);
+ }
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/PtreeNode.java b/src/main/java/net/onrc/onos/apps/bgproute/PtreeNode.java
index d20b7c4..e1b4c55 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/PtreeNode.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/PtreeNode.java
@@ -4,41 +4,41 @@
import org.slf4j.LoggerFactory;
public class PtreeNode {
- public PtreeNode parent;
- public PtreeNode left;
- public PtreeNode right;
-
- public byte key[];
- public int keyBits;
-
- public int refCount;
-
- public RibEntry rib;
- protected final static Logger log = LoggerFactory.getLogger(BgpRoute.class);
-
- PtreeNode(byte [] key, int key_bits, int max_key_octet) {
- parent = null;
- left = null;
- right = null;
- refCount = 0;
- rib = null;
- this.key = new byte[max_key_octet];
- this.keyBits = key_bits;
- log.debug("inside Ptreenode constructor key {} bits {}", key, key_bits);
-
- int octet = Ptree.bit_to_octet(key_bits);
- for (int i = 0; i < max_key_octet; i++) {
- if (i < octet) {
- if (key != null) {
- log.debug(octet + ": filling key[{}] {}", i, key[i]);
- this.key[i] = key[i];
- } else {
- log.debug("no filling, null key", i);
- }
- } else {
- log.debug("filling key {} as 0", i);
- this.key[i] = 0;
- }
- }
- }
+ public PtreeNode parent;
+ public PtreeNode left;
+ public PtreeNode right;
+
+ public byte key[];
+ public int keyBits;
+
+ public int refCount;
+
+ public RibEntry rib;
+ protected final static Logger log = LoggerFactory.getLogger(BgpRoute.class);
+
+ PtreeNode(byte[] key, int key_bits, int max_key_octet) {
+ parent = null;
+ left = null;
+ right = null;
+ refCount = 0;
+ rib = null;
+ this.key = new byte[max_key_octet];
+ this.keyBits = key_bits;
+ log.debug("inside Ptreenode constructor key {} bits {}", key, key_bits);
+
+ int octet = Ptree.bit_to_octet(key_bits);
+ for (int i = 0; i < max_key_octet; i++) {
+ if (i < octet) {
+ if (key != null) {
+ log.debug(octet + ": filling key[{}] {}", i, key[i]);
+ this.key[i] = key[i];
+ } else {
+ log.debug("no filling, null key", i);
+ }
+ } else {
+ log.debug("filling key {} as 0", i);
+ this.key[i] = 0;
+ }
+ }
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/PushedFlowMod.java b/src/main/java/net/onrc/onos/apps/bgproute/PushedFlowMod.java
index 1908050..612a704 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/PushedFlowMod.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/PushedFlowMod.java
@@ -5,28 +5,27 @@
/**
* Wraps up a DPID and a OFFlowMod so we know how to delete
* the flow if we have to.
- *
+ * <p/>
* TODO This functionality should be handled by ONOS's flow layer in future.
- *
*/
public class PushedFlowMod {
- private long dpid;
- private OFFlowMod flowMod;
-
- public PushedFlowMod(long dpid, OFFlowMod flowMod) {
- this.dpid = dpid;
- try {
- this.flowMod = flowMod.clone();
- } catch (CloneNotSupportedException e) {
- this.flowMod = flowMod;
- }
- }
-
- public long getDpid() {
- return dpid;
- }
-
- public OFFlowMod getFlowMod() {
- return flowMod;
- }
+ private long dpid;
+ private OFFlowMod flowMod;
+
+ public PushedFlowMod(long dpid, OFFlowMod flowMod) {
+ this.dpid = dpid;
+ try {
+ this.flowMod = flowMod.clone();
+ } catch (CloneNotSupportedException e) {
+ this.flowMod = flowMod;
+ }
+ }
+
+ public long getDpid() {
+ return dpid;
+ }
+
+ public OFFlowMod getFlowMod() {
+ return flowMod;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/RestClient.java b/src/main/java/net/onrc/onos/apps/bgproute/RestClient.java
index d085e6c..5ea4699 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/RestClient.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/RestClient.java
@@ -13,92 +13,92 @@
public class RestClient {
- protected final static Logger log = LoggerFactory.getLogger(RestClient.class);
+ protected final static Logger log = LoggerFactory.getLogger(RestClient.class);
- public static String get(String str) {
- StringBuilder response = new StringBuilder();
+ public static String get(String str) {
+ StringBuilder response = new StringBuilder();
- try {
+ try {
- URL url = new URL(str);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setConnectTimeout(2 * 1000); //2 seconds
- conn.setRequestMethod("GET");
- conn.setRequestProperty("Accept", "application/json");
+ URL url = new URL(str);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setConnectTimeout(2 * 1000); //2 seconds
+ conn.setRequestMethod("GET");
+ conn.setRequestProperty("Accept", "application/json");
- if (conn.getResponseCode() != 200) {
- throw new RuntimeException("Failed : HTTP error code : "
- + conn.getResponseCode());
- }
+ if (conn.getResponseCode() != 200) {
+ throw new RuntimeException("Failed : HTTP error code : "
+ + conn.getResponseCode());
+ }
- if (!conn.getContentType().equals("application/json")){
- log.warn("The content received from {} is not json", str);
- }
+ if (!conn.getContentType().equals("application/json")) {
+ log.warn("The content received from {} is not json", str);
+ }
- BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
- String line;
- while ((line = br.readLine()) != null) {
- response.append(line);
- }
-
- br.close();
- conn.disconnect();
-
- } catch (MalformedURLException e) {
- log.error("Malformed URL for GET request", e);
- } catch (ConnectTimeoutException e) {
- log.warn("Couldn't connect remote REST server");
- } catch (IOException e) {
- log.warn("Couldn't connect remote REST server");
- }
-
- return response.toString();
- }
+ BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
+ String line;
+ while ((line = br.readLine()) != null) {
+ response.append(line);
+ }
- public static void post (String str) {
+ br.close();
+ conn.disconnect();
- try {
- URL url = new URL(str);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setDoOutput(true);
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Content-Type", "application/json");
+ } catch (MalformedURLException e) {
+ log.error("Malformed URL for GET request", e);
+ } catch (ConnectTimeoutException e) {
+ log.warn("Couldn't connect remote REST server");
+ } catch (IOException e) {
+ log.warn("Couldn't connect remote REST server");
+ }
- if (conn.getResponseCode() != 200) {
- throw new RuntimeException("Failed : HTTP error code : "
- + conn.getResponseCode());
- }
+ return response.toString();
+ }
- conn.disconnect();
+ public static void post(String str) {
- } catch (MalformedURLException e) {
- log.error("Malformed URL for GET request", e);
- } catch (IOException e) {
- log.warn("Couldn't connect remote REST server");
- }
- }
+ try {
+ URL url = new URL(str);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setDoOutput(true);
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Content-Type", "application/json");
+
+ if (conn.getResponseCode() != 200) {
+ throw new RuntimeException("Failed : HTTP error code : "
+ + conn.getResponseCode());
+ }
+
+ conn.disconnect();
+
+ } catch (MalformedURLException e) {
+ log.error("Malformed URL for GET request", e);
+ } catch (IOException e) {
+ log.warn("Couldn't connect remote REST server");
+ }
+ }
- public static void delete (String str) {
+ public static void delete(String str) {
- try {
- URL url = new URL(str);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setRequestMethod("DELETE");
- conn.setRequestProperty("Accept", "application/json");
+ try {
+ URL url = new URL(str);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setRequestMethod("DELETE");
+ conn.setRequestProperty("Accept", "application/json");
- if (conn.getResponseCode() != 200) {
- throw new RuntimeException("Failed : HTTP error code : "
- + conn.getResponseCode());
- }
+ if (conn.getResponseCode() != 200) {
+ throw new RuntimeException("Failed : HTTP error code : "
+ + conn.getResponseCode());
+ }
- conn.disconnect();
+ conn.disconnect();
- } catch (MalformedURLException e) {
- log.error("Malformed URL for GET request", e);
- } catch (IOException e) {
- log.warn("Couldn't connect remote REST server");
- }
- }
+ } catch (MalformedURLException e) {
+ log.error("Malformed URL for GET request", e);
+ } catch (IOException e) {
+ log.warn("Couldn't connect remote REST server");
+ }
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/RibEntry.java b/src/main/java/net/onrc/onos/apps/bgproute/RibEntry.java
index 16f5aff..4dccd5f 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/RibEntry.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/RibEntry.java
@@ -5,76 +5,76 @@
import com.google.common.net.InetAddresses;
public class RibEntry {
- private final InetAddress routerId;
- private final InetAddress nextHop;
+ private final InetAddress routerId;
+ private final InetAddress nextHop;
- /*
- * Store the sequence number information provided on the update here for
- * now. I think this *should* really be in the RibUpdate, and we should
- * store RibUpdates in the Ptrie. But, that's a bigger change to change
- * what the Ptrie stores.
- */
- private final long sysUpTime;
- private final long sequenceNum;
-
- /*
- * Marker for RibEntries where we don't have sequence number info.
- * The user of this class should make sure they don't check this data
- * if they don't provide it.
- */
- private final static long NULL_TIME = -1;
-
- public RibEntry(InetAddress routerId, InetAddress nextHop) {
- this.routerId = routerId;
- this.nextHop = nextHop;
- sequenceNum = NULL_TIME;
- sysUpTime = NULL_TIME;
- }
-
- public RibEntry(String routerId, String nextHop) {
- this.routerId = InetAddresses.forString(routerId);
- this.nextHop = InetAddresses.forString(nextHop);
- sequenceNum = NULL_TIME;
- sysUpTime = NULL_TIME;
- }
-
- public RibEntry(String routerId, String nextHop, long sysUpTime
- , long sequenceNum) {
- this.routerId = InetAddresses.forString(routerId);
- this.nextHop = InetAddresses.forString(nextHop);
- this.sequenceNum = sequenceNum;
- this.sysUpTime = sysUpTime;
- }
-
- public InetAddress getNextHop() {
- return nextHop;
- }
-
- public long getSysUpTime() {
- return sysUpTime;
- }
-
- public long getSequenceNum() {
- return sequenceNum;
- }
-
- @Override
- public boolean equals(Object other) {
- if (other == null || !(other instanceof RibEntry)) {
- return false;
- }
-
- RibEntry otherRibEntry = (RibEntry) other;
-
- return this.routerId.equals(otherRibEntry.routerId)
- && this.nextHop.equals(otherRibEntry.nextHop);
- }
-
- @Override
- public int hashCode() {
- int hash = 17;
- hash = 31 * hash + routerId.hashCode();
- hash = 31 * hash + nextHop.hashCode();
- return hash;
- }
+ /*
+ * Store the sequence number information provided on the update here for
+ * now. I think this *should* really be in the RibUpdate, and we should
+ * store RibUpdates in the Ptrie. But, that's a bigger change to change
+ * what the Ptrie stores.
+ */
+ private final long sysUpTime;
+ private final long sequenceNum;
+
+ /*
+ * Marker for RibEntries where we don't have sequence number info.
+ * The user of this class should make sure they don't check this data
+ * if they don't provide it.
+ */
+ private final static long NULL_TIME = -1;
+
+ public RibEntry(InetAddress routerId, InetAddress nextHop) {
+ this.routerId = routerId;
+ this.nextHop = nextHop;
+ sequenceNum = NULL_TIME;
+ sysUpTime = NULL_TIME;
+ }
+
+ public RibEntry(String routerId, String nextHop) {
+ this.routerId = InetAddresses.forString(routerId);
+ this.nextHop = InetAddresses.forString(nextHop);
+ sequenceNum = NULL_TIME;
+ sysUpTime = NULL_TIME;
+ }
+
+ public RibEntry(String routerId, String nextHop, long sysUpTime
+ , long sequenceNum) {
+ this.routerId = InetAddresses.forString(routerId);
+ this.nextHop = InetAddresses.forString(nextHop);
+ this.sequenceNum = sequenceNum;
+ this.sysUpTime = sysUpTime;
+ }
+
+ public InetAddress getNextHop() {
+ return nextHop;
+ }
+
+ public long getSysUpTime() {
+ return sysUpTime;
+ }
+
+ public long getSequenceNum() {
+ return sequenceNum;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other == null || !(other instanceof RibEntry)) {
+ return false;
+ }
+
+ RibEntry otherRibEntry = (RibEntry) other;
+
+ return this.routerId.equals(otherRibEntry.routerId)
+ && this.nextHop.equals(otherRibEntry.nextHop);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 17;
+ hash = 31 * hash + routerId.hashCode();
+ hash = 31 * hash + nextHop.hashCode();
+ return hash;
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/bgproute/RibUpdate.java b/src/main/java/net/onrc/onos/apps/bgproute/RibUpdate.java
index d69a538..0faa94f 100644
--- a/src/main/java/net/onrc/onos/apps/bgproute/RibUpdate.java
+++ b/src/main/java/net/onrc/onos/apps/bgproute/RibUpdate.java
@@ -1,27 +1,30 @@
package net.onrc.onos.apps.bgproute;
public class RibUpdate {
- public enum Operation {UPDATE, DELETE};
-
- private final Operation operation;
- private final Prefix prefix;
- private final RibEntry ribEntry;
-
- public RibUpdate(Operation operation, Prefix prefix, RibEntry ribEntry) {
- this.operation = operation;
- this.prefix = prefix;
- this.ribEntry = ribEntry;
- }
+ public enum Operation {
+ UPDATE,
+ DELETE
+ }
- public Operation getOperation() {
- return operation;
- }
+ private final Operation operation;
+ private final Prefix prefix;
+ private final RibEntry ribEntry;
- public Prefix getPrefix() {
- return prefix;
- }
+ public RibUpdate(Operation operation, Prefix prefix, RibEntry ribEntry) {
+ this.operation = operation;
+ this.prefix = prefix;
+ this.ribEntry = ribEntry;
+ }
- public RibEntry getRibEntry() {
- return ribEntry;
- }
+ public Operation getOperation() {
+ return operation;
+ }
+
+ public Prefix getPrefix() {
+ return prefix;
+ }
+
+ public RibEntry getRibEntry() {
+ return ribEntry;
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/forwarding/Forwarding.java b/src/main/java/net/onrc/onos/apps/forwarding/Forwarding.java
index bdafdcd..2ed8ba5 100644
--- a/src/main/java/net/onrc/onos/apps/forwarding/Forwarding.java
+++ b/src/main/java/net/onrc/onos/apps/forwarding/Forwarding.java
@@ -62,529 +62,526 @@
import com.google.common.collect.ListMultimap;
public class Forwarding implements IOFMessageListener, IFloodlightModule,
- IForwardingService, IEventChannelListener<Long, IntentStateList> {
- private final static Logger log = LoggerFactory.getLogger(Forwarding.class);
-
- private final int SLEEP_TIME_FOR_DB_DEVICE_INSTALLED = 100; // milliseconds
- private final static int NUMBER_OF_THREAD_FOR_EXECUTOR = 1;
-
- private final static ScheduledExecutorService executor = Executors.newScheduledThreadPool(NUMBER_OF_THREAD_FOR_EXECUTOR);
-
- private final String callerId = "Forwarding";
-
- private IFloodlightProviderService floodlightProvider;
- private IFlowPusherService flowPusher;
- private IDatagridService datagrid;
+ IForwardingService, IEventChannelListener<Long, IntentStateList> {
+ private final static Logger log = LoggerFactory.getLogger(Forwarding.class);
- private IEventChannel<Long, BroadcastPacketOutNotification> eventChannel;
- private static final String SINGLE_PACKET_OUT_CHANNEL_NAME = "onos.forwarding.packet_out";
+ private final int SLEEP_TIME_FOR_DB_DEVICE_INSTALLED = 100; // milliseconds
+ private final static int NUMBER_OF_THREAD_FOR_EXECUTOR = 1;
- private IControllerRegistryService controllerRegistryService;
-
- private INetworkGraphService networkGraphService;
- private NetworkGraph networkGraph;
- private IPathCalcRuntimeService pathRuntime;
- private IntentMap intentMap;
-
- // TODO it seems there is a Guava collection that will time out entries.
- // We should see if this will work here.
- private Map<Path, PushedFlow> pendingFlows;
- private ListMultimap<String, PacketToPush> waitingPackets;
-
- private final Object lock = new Object();
-
- private class PacketToPush {
- public final OFPacketOut packet;
- public final long dpid;
-
- public PacketToPush(OFPacketOut packet, long dpid) {
- this.packet = packet;
- this.dpid = dpid;
- }
- }
-
- private class PushedFlow {
- public final String intentId;
- public boolean installed = false;
- public short firstOutPort;
-
- public PushedFlow(String flowId) {
- this.intentId = flowId;
- }
- }
-
- private final class Path {
- public final MACAddress srcMac;
- public final MACAddress dstMac;
-
- public Path(MACAddress srcMac, MACAddress dstMac) {
- this.srcMac = srcMac;
- this.dstMac = dstMac;
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof Path)) {
- return false;
- }
-
- Path otherPath = (Path) other;
- return srcMac.equals(otherPath.srcMac) &&
- dstMac.equals(otherPath.dstMac);
- }
-
- @Override
- public int hashCode() {
- int hash = 17;
- hash = 31 * hash + srcMac.hashCode();
- hash = 31 * hash + dstMac.hashCode();
- return hash;
- }
-
- @Override
- public String toString() {
- return "(" + srcMac + ") => (" + dstMac + ")";
- }
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- List<Class<? extends IFloodlightService>> services =
- new ArrayList<Class<? extends IFloodlightService>>(1);
- services.add(IForwardingService.class);
- return services;
- }
+ private final static ScheduledExecutorService executor = Executors.newScheduledThreadPool(NUMBER_OF_THREAD_FOR_EXECUTOR);
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
- Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
- new HashMap<Class<? extends IFloodlightService>, IFloodlightService>(1);
- impls.put(IForwardingService.class, this);
- return impls;
- }
+ private final String callerId = "Forwarding";
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- List<Class<? extends IFloodlightService>> dependencies =
- new ArrayList<Class<? extends IFloodlightService>>();
- dependencies.add(IFloodlightProviderService.class);
- dependencies.add(IFlowPusherService.class);
- dependencies.add(IControllerRegistryService.class);
- dependencies.add(IOnosDeviceService.class);
- dependencies.add(IDatagridService.class);
- dependencies.add(INetworkGraphService.class);
- dependencies.add(IPathCalcRuntimeService.class);
- // We don't use the IProxyArpService directly, but reactive forwarding
- // requires it to be loaded and answering ARP requests
- dependencies.add(IProxyArpService.class);
- return dependencies;
- }
-
- @Override
- public void init(FloodlightModuleContext context) {
- floodlightProvider =
- context.getServiceImpl(IFloodlightProviderService.class);
- flowPusher = context.getServiceImpl(IFlowPusherService.class);
- datagrid = context.getServiceImpl(IDatagridService.class);
- controllerRegistryService = context.getServiceImpl(IControllerRegistryService.class);
- networkGraphService = context.getServiceImpl(INetworkGraphService.class);
+ private IFloodlightProviderService floodlightProvider;
+ private IFlowPusherService flowPusher;
+ private IDatagridService datagrid;
+
+ private IEventChannel<Long, BroadcastPacketOutNotification> eventChannel;
+ private static final String SINGLE_PACKET_OUT_CHANNEL_NAME = "onos.forwarding.packet_out";
+
+ private IControllerRegistryService controllerRegistryService;
+
+ private INetworkGraphService networkGraphService;
+ private NetworkGraph networkGraph;
+ private IPathCalcRuntimeService pathRuntime;
+ private IntentMap intentMap;
+
+ // TODO it seems there is a Guava collection that will time out entries.
+ // We should see if this will work here.
+ private Map<Path, PushedFlow> pendingFlows;
+ private ListMultimap<String, PacketToPush> waitingPackets;
+
+ private final Object lock = new Object();
+
+ private class PacketToPush {
+ public final OFPacketOut packet;
+ public final long dpid;
+
+ public PacketToPush(OFPacketOut packet, long dpid) {
+ this.packet = packet;
+ this.dpid = dpid;
+ }
+ }
+
+ private class PushedFlow {
+ public final String intentId;
+ public boolean installed = false;
+ public short firstOutPort;
+
+ public PushedFlow(String flowId) {
+ this.intentId = flowId;
+ }
+ }
+
+ private final class Path {
+ public final MACAddress srcMac;
+ public final MACAddress dstMac;
+
+ public Path(MACAddress srcMac, MACAddress dstMac) {
+ this.srcMac = srcMac;
+ this.dstMac = dstMac;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof Path)) {
+ return false;
+ }
+
+ Path otherPath = (Path) other;
+ return srcMac.equals(otherPath.srcMac) &&
+ dstMac.equals(otherPath.dstMac);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 17;
+ hash = 31 * hash + srcMac.hashCode();
+ hash = 31 * hash + dstMac.hashCode();
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ return "(" + srcMac + ") => (" + dstMac + ")";
+ }
+ }
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+ List<Class<? extends IFloodlightService>> services =
+ new ArrayList<Class<? extends IFloodlightService>>(1);
+ services.add(IForwardingService.class);
+ return services;
+ }
+
+ @Override
+ public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+ Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
+ new HashMap<Class<? extends IFloodlightService>, IFloodlightService>(1);
+ impls.put(IForwardingService.class, this);
+ return impls;
+ }
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+ List<Class<? extends IFloodlightService>> dependencies =
+ new ArrayList<Class<? extends IFloodlightService>>();
+ dependencies.add(IFloodlightProviderService.class);
+ dependencies.add(IFlowPusherService.class);
+ dependencies.add(IControllerRegistryService.class);
+ dependencies.add(IOnosDeviceService.class);
+ dependencies.add(IDatagridService.class);
+ dependencies.add(INetworkGraphService.class);
+ dependencies.add(IPathCalcRuntimeService.class);
+ // We don't use the IProxyArpService directly, but reactive forwarding
+ // requires it to be loaded and answering ARP requests
+ dependencies.add(IProxyArpService.class);
+ return dependencies;
+ }
+
+ @Override
+ public void init(FloodlightModuleContext context) {
+ floodlightProvider =
+ context.getServiceImpl(IFloodlightProviderService.class);
+ flowPusher = context.getServiceImpl(IFlowPusherService.class);
+ datagrid = context.getServiceImpl(IDatagridService.class);
+ controllerRegistryService = context.getServiceImpl(IControllerRegistryService.class);
+ networkGraphService = context.getServiceImpl(INetworkGraphService.class);
pathRuntime = context.getServiceImpl(IPathCalcRuntimeService.class);
-
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- pendingFlows = new HashMap<Path, PushedFlow>();
- waitingPackets = LinkedListMultimap.create();
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
+ floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- eventChannel = datagrid.createChannel(SINGLE_PACKET_OUT_CHANNEL_NAME,
- Long.class,
- BroadcastPacketOutNotification.class);
- networkGraph = networkGraphService.getNetworkGraph();
- intentMap = pathRuntime.getPathIntents();
- datagrid.addListener("onos.pathintent_state", this, Long.class, IntentStateList.class);
- }
+ pendingFlows = new HashMap<Path, PushedFlow>();
+ waitingPackets = LinkedListMultimap.create();
+ }
- @Override
- public String getName() {
- return "onosforwarding";
- }
+ @Override
+ public void startUp(FloodlightModuleContext context) {
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- return (type == OFType.PACKET_IN) &&
- (name.equals("devicemanager") || name.equals("proxyarpmanager")
- || name.equals("onosdevicemanager"));
- }
+ eventChannel = datagrid.createChannel(SINGLE_PACKET_OUT_CHANNEL_NAME,
+ Long.class,
+ BroadcastPacketOutNotification.class);
+ networkGraph = networkGraphService.getNetworkGraph();
+ intentMap = pathRuntime.getPathIntents();
+ datagrid.addListener("onos.pathintent_state", this, Long.class, IntentStateList.class);
+ }
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return false;
- }
+ @Override
+ public String getName() {
+ return "onosforwarding";
+ }
- @Override
- public Command receive(
- IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-
- if (msg.getType() != OFType.PACKET_IN) {
- return Command.CONTINUE;
- }
-
- OFPacketIn pi = (OFPacketIn) msg;
-
- Ethernet eth = IFloodlightProviderService.bcStore.
- get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
- log.debug("Receive PACKET_IN swId {}, portId {}", sw.getId(), pi.getInPort());
-
- if (eth.getEtherType() != Ethernet.TYPE_IPv4) {
- return Command.CONTINUE;
- }
-
- if (eth.isBroadcast() || eth.isMulticast()) {
- handleBroadcast(sw, pi, eth);
- }
- else {
- // Unicast
- handlePacketIn(sw, pi, eth);
- }
-
- return Command.STOP;
- }
-
- private void handleBroadcast(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
- if (log.isTraceEnabled()) {
- log.trace("Sending broadcast packet to other ONOS instances");
- }
+ @Override
+ public boolean isCallbackOrderingPrereq(OFType type, String name) {
+ return (type == OFType.PACKET_IN) &&
+ (name.equals("devicemanager") || name.equals("proxyarpmanager")
+ || name.equals("onosdevicemanager"));
+ }
- //We don't use address information, so 0 is put into the third argument.
- BroadcastPacketOutNotification key =
- new BroadcastPacketOutNotification(
- eth.serialize(),
- 0, sw.getId(),
- pi.getInPort());
- eventChannel.addTransientEntry(eth.getDestinationMAC().toLong(), key);
- }
-
- private void handlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth){
- log.debug("Start handlePacketIn swId {}, portId {}", sw.getId(), pi.getInPort());
+ @Override
+ public boolean isCallbackOrderingPostreq(OFType type, String name) {
+ return false;
+ }
- String destinationMac =
- HexString.toHexString(eth.getDestinationMACAddress());
-
- //FIXME getDeviceByMac() is a blocking call, so it may be better way to handle it to avoid the condition.
- Device deviceObject = networkGraph.getDeviceByMac(MACAddress.valueOf(destinationMac));
+ @Override
+ public Command receive(
+ IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
- if (deviceObject == null) {
- log.debug("No device entry found for {}",
- destinationMac);
+ if (msg.getType() != OFType.PACKET_IN) {
+ return Command.CONTINUE;
+ }
- //Device is not in the DB, so wait it until the device is added.
- executor.schedule(new WaitDeviceArp(sw, pi, eth), SLEEP_TIME_FOR_DB_DEVICE_INSTALLED, TimeUnit.MILLISECONDS);
- return;
- }
+ OFPacketIn pi = (OFPacketIn) msg;
- continueHandlePacketIn(sw, pi, eth, deviceObject);
- }
-
- private class WaitDeviceArp implements Runnable {
- IOFSwitch sw;
- OFPacketIn pi;
- Ethernet eth;
+ Ethernet eth = IFloodlightProviderService.bcStore.
+ get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
- public WaitDeviceArp(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
- super();
- this.sw = sw;
- this.pi = pi;
- this.eth = eth;
- }
+ log.debug("Receive PACKET_IN swId {}, portId {}", sw.getId(), pi.getInPort());
- @Override
- public void run() {
- Device deviceObject = networkGraph.getDeviceByMac(MACAddress.valueOf(eth.getDestinationMACAddress()));
- if(deviceObject == null){
- log.debug("wait {}ms and device was not found. Send broadcast packet and the thread finish.", SLEEP_TIME_FOR_DB_DEVICE_INSTALLED);
- handleBroadcast(sw, pi, eth);
- return;
- }
- log.debug("wait {}ms and device {} was found, continue",SLEEP_TIME_FOR_DB_DEVICE_INSTALLED, deviceObject.getMacAddress());
- continueHandlePacketIn(sw, pi, eth, deviceObject);
- }
- }
+ if (eth.getEtherType() != Ethernet.TYPE_IPv4) {
+ return Command.CONTINUE;
+ }
- private void continueHandlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth, Device deviceObject) {
+ if (eth.isBroadcast() || eth.isMulticast()) {
+ handleBroadcast(sw, pi, eth);
+ } else {
+ // Unicast
+ handlePacketIn(sw, pi, eth);
+ }
- log.debug("Start continuehandlePacketIn");
-
- //Iterator<IPortObject> ports = deviceObject.getAttachedPorts().iterator();
- Iterator<net.onrc.onos.core.topology.Port> ports = deviceObject.getAttachmentPoints().iterator();
- if (!ports.hasNext()) {
- log.debug("No attachment point found for device {} - broadcasting packet",
- deviceObject.getMacAddress());
- handleBroadcast(sw, pi, eth);
- return;
- }
+ return Command.STOP;
+ }
- //This code assumes the device has only one port. It should be problem.
- net.onrc.onos.core.topology.Port portObject = ports.next();
- short destinationPort = portObject.getNumber().shortValue();
- Switch switchObject = portObject.getSwitch();
- long destinationDpid = switchObject.getDpid();
-
- // TODO SwitchPort, Dpid and Port should probably be immutable
- SwitchPort srcSwitchPort = new SwitchPort(
- new Dpid(sw.getId()), new Port(pi.getInPort()));
- SwitchPort dstSwitchPort = new SwitchPort(
- new Dpid(destinationDpid), new Port(destinationPort));
-
- MACAddress srcMacAddress = MACAddress.valueOf(eth.getSourceMACAddress());
- MACAddress dstMacAddress = MACAddress.valueOf(eth.getDestinationMACAddress());
-
- synchronized (lock) {
- //TODO check concurrency
- Path pathspec = new Path(srcMacAddress, dstMacAddress);
- PushedFlow existingFlow = pendingFlows.get(pathspec);
+ private void handleBroadcast(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
+ if (log.isTraceEnabled()) {
+ log.trace("Sending broadcast packet to other ONOS instances");
+ }
- //A path is installed side by side to reduce a path timeout and a wrong state.
- if (existingFlow != null) {
- // We've already start to install a flow for this pair of MAC addresses
- if(log.isDebugEnabled()) {
- log.debug("Found existing the same pathspec {}, intent ID is {}",
- pathspec,
- existingFlow.intentId);
- }
-
- OFPacketOut po = constructPacketOut(pi, sw);
-
- // Find the correct port here. We just assume the PI is from
- // the first hop switch, but this is definitely not always
- // the case. We'll have to retrieve the flow from HZ every time
- // because it could change (be rerouted) sometimes.
- if (existingFlow.installed) {
- // Flow has been sent to the switches so it is safe to
- // send a packet out now
+ //We don't use address information, so 0 is put into the third argument.
+ BroadcastPacketOutNotification key =
+ new BroadcastPacketOutNotification(
+ eth.serialize(),
+ 0, sw.getId(),
+ pi.getInPort());
+ eventChannel.addTransientEntry(eth.getDestinationMAC().toLong(), key);
+ }
- Intent intent = intentMap.getIntent(existingFlow.intentId);
- PathIntent pathIntent = null;
- if(intent instanceof PathIntent) {
- pathIntent = (PathIntent)intent;
- } else {
- log.debug("Intent {} is not PathIntent. Return.", intent.getId());
- return;
- }
-
- Boolean isflowEntryForThisSwitch = false;
- net.onrc.onos.core.topology.Path path = pathIntent.getPath();
+ private void handlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
+ log.debug("Start handlePacketIn swId {}, portId {}", sw.getId(), pi.getInPort());
- for(Iterator<LinkEvent> i = path.iterator(); i.hasNext();) {
- LinkEvent le = (LinkEvent)i.next();
- if(le.getSrc().dpid == sw.getId()) {
- log.debug("src {} dst {}", le.getSrc(), le.getDst());
- isflowEntryForThisSwitch = true;
- break;
- }
- }
-
- if (isflowEntryForThisSwitch == false) {
- // If we don't find a flow entry for that switch, then we're
- // in the middle of a rerouting (or something's gone wrong).
- // This packet will be dropped as a victim of the rerouting.
- log.debug("Dropping packet on flow {} between {}-{}",
- existingFlow.intentId,
- srcMacAddress, dstMacAddress);
- } else {
- log.debug("Sending packet out from sw {}, outport{}", sw, existingFlow.firstOutPort);
- sendPacketOut(sw, po, existingFlow.firstOutPort);
- }
- }
- else {
- // Flow path has not yet been installed to switches so save the
- // packet out for later
- log.debug("Put a packet into the waitng list. flowId {}", existingFlow.intentId);
- waitingPackets.put(existingFlow.intentId, new PacketToPush(po, sw.getId()));
- }
- return;
- }
+ String destinationMac =
+ HexString.toHexString(eth.getDestinationMACAddress());
- log.debug("Adding new flow between {} at {} and {} at {}",
- new Object[]{srcMacAddress, srcSwitchPort, dstMacAddress, dstSwitchPort});
-
- String intentId = callerId + ":" + controllerRegistryService.getNextUniqueId();
- IntentOperationList operations = new IntentOperationList();
- ShortestPathIntent intent = new ShortestPathIntent(intentId,
- sw.getId(), pi.getInPort(), srcMacAddress.toLong(),
- destinationDpid, destinationPort, dstMacAddress.toLong());
- IntentOperation.Operator operator = IntentOperation.Operator.ADD;
- operations.add(operator, intent);
- pathRuntime.executeIntentOperations(operations);
+ //FIXME getDeviceByMac() is a blocking call, so it may be better way to handle it to avoid the condition.
+ Device deviceObject = networkGraph.getDeviceByMac(MACAddress.valueOf(destinationMac));
- OFPacketOut po = constructPacketOut(pi, sw);
-
- // Add to waiting lists
- pendingFlows.put(pathspec, new PushedFlow(intentId));
- log.debug("Put a Path {} in the pending flow, intent ID {}", pathspec, intentId);
- waitingPackets.put(intentId, new PacketToPush(po, sw.getId()));
- log.debug("Put a Packet in the wating list. related pathspec {}", pathspec);
-
- }
- }
+ if (deviceObject == null) {
+ log.debug("No device entry found for {}",
+ destinationMac);
- private OFPacketOut constructPacketOut(OFPacketIn pi, IOFSwitch sw) {
- OFPacketOut po = new OFPacketOut();
- po.setInPort(OFPort.OFPP_NONE)
- .setInPort(pi.getInPort())
- .setActions(new ArrayList<OFAction>())
- .setLengthU(OFPacketOut.MINIMUM_LENGTH);
-
- if (sw.getBuffers() == 0) {
- po.setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setPacketData(pi.getPacketData())
- .setLengthU(po.getLengthU() + po.getPacketData().length);
- }
- else {
- po.setBufferId(pi.getBufferId());
- }
-
- return po;
- }
+ //Device is not in the DB, so wait it until the device is added.
+ executor.schedule(new WaitDeviceArp(sw, pi, eth), SLEEP_TIME_FOR_DB_DEVICE_INSTALLED, TimeUnit.MILLISECONDS);
+ return;
+ }
- @Override
- public void flowsInstalled(Collection<FlowPath> installedFlowPaths) {
- }
-
- @Override
- public void flowRemoved(FlowPath removedFlowPath) {
- }
-
- public void flowRemoved(PathIntent removedIntent) {
- if(log.isTraceEnabled()){
- log.trace("Path {} was removed", removedIntent.getParentIntent().getId());
- }
+ continueHandlePacketIn(sw, pi, eth, deviceObject);
+ }
- ShortestPathIntent spfIntent = (ShortestPathIntent) removedIntent.getParentIntent();
- MACAddress srcMacAddress = MACAddress.valueOf(spfIntent.getSrcMac());
- MACAddress dstMacAddress = MACAddress.valueOf(spfIntent.getDstMac());
- Path removedPath = new Path(srcMacAddress, dstMacAddress);
-
- synchronized (lock) {
- // There *shouldn't* be any packets queued if the flow has
- // just been removed.
- List<PacketToPush> packets = waitingPackets.removeAll(spfIntent.getId());
- if (!packets.isEmpty()) {
- log.warn("Removed flow {} has packets queued.", spfIntent.getId());
- }
- pendingFlows.remove(removedPath);
- log.debug("Removed from the pendingFlow: Path {}, Flow ID {}", removedPath, spfIntent.getId());
- }
- }
-
- private void flowInstalled(PathIntent installedPath) {
- if(log.isTraceEnabled()){
- log.trace("Path {} was installed", installedPath.getParentIntent().getId());
- }
-
- ShortestPathIntent spfIntent = (ShortestPathIntent) installedPath.getParentIntent();
- MACAddress srcMacAddress = MACAddress.valueOf(spfIntent.getSrcMac());
- MACAddress dstMacAddress = MACAddress.valueOf(spfIntent.getDstMac());
- Path path = new Path(srcMacAddress, dstMacAddress);
- log.debug("Path spec {}", path);
-
- // TODO waiting packets should time out. We could request a path that
- // can't be installed right now because of a network partition. The path
- // may eventually be installed, but we may have received thousands of
- // packets in the meantime and probably don't want to send very old packets.
-
- List<PacketToPush> packets = null;
- net.onrc.onos.core.topology.Path graphPath = installedPath.getPath();
-
- log.debug("path{}", graphPath);
- Short outPort = graphPath.get(0).getSrc().getNumber().shortValue();
-
- PushedFlow existingFlow = null;
-
- synchronized (lock) {
- existingFlow = pendingFlows.get(path);
+ private class WaitDeviceArp implements Runnable {
+ IOFSwitch sw;
+ OFPacketIn pi;
+ Ethernet eth;
- if (existingFlow != null) {
- existingFlow.installed = true;
- existingFlow.firstOutPort = outPort;
- } else {
- log.debug("ExistingFlow {} is null", path);
- return;
- }
+ public WaitDeviceArp(IOFSwitch sw, OFPacketIn pi, Ethernet eth) {
+ super();
+ this.sw = sw;
+ this.pi = pi;
+ this.eth = eth;
+ }
- //Check both existing flow are installed status.
- if(existingFlow.installed){
- packets = waitingPackets.removeAll(existingFlow.intentId);
- if(log.isDebugEnabled()){
- log.debug("removed my packets {} to push from waitingPackets. outPort {} size {}",
- existingFlow.intentId, existingFlow.firstOutPort, packets.size());
- }
- }else{
- log.debug("Forward or reverse flows hasn't been pushed yet. return");
- return;
- }
- }
-
- for (PacketToPush packet : packets) {
- log.debug("Start packetToPush to sw {}, outPort {}, path {}", packet.dpid, existingFlow.firstOutPort, path);
- IOFSwitch sw = floodlightProvider.getSwitches().get(packet.dpid);
- sendPacketOut(sw, packet.packet, existingFlow.firstOutPort);
- }
- }
-
- private void sendPacketOut(IOFSwitch sw, OFPacketOut po, short outPort) {
- po.getActions().add(new OFActionOutput(outPort));
- po.setActionsLength((short)
- (po.getActionsLength() + OFActionOutput.MINIMUM_LENGTH));
- po.setLengthU(po.getLengthU() + OFActionOutput.MINIMUM_LENGTH);
-
- flowPusher.add(sw, po);
- }
+ @Override
+ public void run() {
+ Device deviceObject = networkGraph.getDeviceByMac(MACAddress.valueOf(eth.getDestinationMACAddress()));
+ if (deviceObject == null) {
+ log.debug("wait {}ms and device was not found. Send broadcast packet and the thread finish.", SLEEP_TIME_FOR_DB_DEVICE_INSTALLED);
+ handleBroadcast(sw, pi, eth);
+ return;
+ }
+ log.debug("wait {}ms and device {} was found, continue", SLEEP_TIME_FOR_DB_DEVICE_INSTALLED, deviceObject.getMacAddress());
+ continueHandlePacketIn(sw, pi, eth, deviceObject);
+ }
+ }
- @Override
- public void entryAdded(IntentStateList value) {
- entryUpdated(value);
-
- }
+ private void continueHandlePacketIn(IOFSwitch sw, OFPacketIn pi, Ethernet eth, Device deviceObject) {
- @Override
- public void entryRemoved(IntentStateList value) {
- //no-op
- }
+ log.debug("Start continuehandlePacketIn");
- @Override
- public void entryUpdated(IntentStateList value) {
- for (Entry<String, IntentState> entry: value.entrySet()) {
- log.debug("path intent key {}, value {}", entry.getKey(), entry.getValue());
- PathIntent pathIntent = (PathIntent) intentMap.getIntent(entry.getKey());
- if (pathIntent == null)
- continue;
-
- if (!(pathIntent.getParentIntent() instanceof ShortestPathIntent))
- continue;
+ //Iterator<IPortObject> ports = deviceObject.getAttachedPorts().iterator();
+ Iterator<net.onrc.onos.core.topology.Port> ports = deviceObject.getAttachmentPoints().iterator();
+ if (!ports.hasNext()) {
+ log.debug("No attachment point found for device {} - broadcasting packet",
+ deviceObject.getMacAddress());
+ handleBroadcast(sw, pi, eth);
+ return;
+ }
- IntentState state = entry.getValue();
- switch (state) {
- case INST_REQ:
- break;
- case INST_ACK:
- flowInstalled(pathIntent);
- break;
- case INST_NACK:
- break;
- case DEL_REQ:
- break;
- case DEL_ACK:
- flowRemoved(pathIntent);
- break;
- case DEL_PENDING:
- break;
- default:
- break;
- }
- }
- }
+ //This code assumes the device has only one port. It should be problem.
+ net.onrc.onos.core.topology.Port portObject = ports.next();
+ short destinationPort = portObject.getNumber().shortValue();
+ Switch switchObject = portObject.getSwitch();
+ long destinationDpid = switchObject.getDpid();
+
+ // TODO SwitchPort, Dpid and Port should probably be immutable
+ SwitchPort srcSwitchPort = new SwitchPort(
+ new Dpid(sw.getId()), new Port(pi.getInPort()));
+ SwitchPort dstSwitchPort = new SwitchPort(
+ new Dpid(destinationDpid), new Port(destinationPort));
+
+ MACAddress srcMacAddress = MACAddress.valueOf(eth.getSourceMACAddress());
+ MACAddress dstMacAddress = MACAddress.valueOf(eth.getDestinationMACAddress());
+
+ synchronized (lock) {
+ //TODO check concurrency
+ Path pathspec = new Path(srcMacAddress, dstMacAddress);
+ PushedFlow existingFlow = pendingFlows.get(pathspec);
+
+ //A path is installed side by side to reduce a path timeout and a wrong state.
+ if (existingFlow != null) {
+ // We've already start to install a flow for this pair of MAC addresses
+ if (log.isDebugEnabled()) {
+ log.debug("Found existing the same pathspec {}, intent ID is {}",
+ pathspec,
+ existingFlow.intentId);
+ }
+
+ OFPacketOut po = constructPacketOut(pi, sw);
+
+ // Find the correct port here. We just assume the PI is from
+ // the first hop switch, but this is definitely not always
+ // the case. We'll have to retrieve the flow from HZ every time
+ // because it could change (be rerouted) sometimes.
+ if (existingFlow.installed) {
+ // Flow has been sent to the switches so it is safe to
+ // send a packet out now
+
+ Intent intent = intentMap.getIntent(existingFlow.intentId);
+ PathIntent pathIntent = null;
+ if (intent instanceof PathIntent) {
+ pathIntent = (PathIntent) intent;
+ } else {
+ log.debug("Intent {} is not PathIntent. Return.", intent.getId());
+ return;
+ }
+
+ Boolean isflowEntryForThisSwitch = false;
+ net.onrc.onos.core.topology.Path path = pathIntent.getPath();
+
+ for (Iterator<LinkEvent> i = path.iterator(); i.hasNext(); ) {
+ LinkEvent le = (LinkEvent) i.next();
+ if (le.getSrc().dpid == sw.getId()) {
+ log.debug("src {} dst {}", le.getSrc(), le.getDst());
+ isflowEntryForThisSwitch = true;
+ break;
+ }
+ }
+
+ if (isflowEntryForThisSwitch == false) {
+ // If we don't find a flow entry for that switch, then we're
+ // in the middle of a rerouting (or something's gone wrong).
+ // This packet will be dropped as a victim of the rerouting.
+ log.debug("Dropping packet on flow {} between {}-{}",
+ existingFlow.intentId,
+ srcMacAddress, dstMacAddress);
+ } else {
+ log.debug("Sending packet out from sw {}, outport{}", sw, existingFlow.firstOutPort);
+ sendPacketOut(sw, po, existingFlow.firstOutPort);
+ }
+ } else {
+ // Flow path has not yet been installed to switches so save the
+ // packet out for later
+ log.debug("Put a packet into the waitng list. flowId {}", existingFlow.intentId);
+ waitingPackets.put(existingFlow.intentId, new PacketToPush(po, sw.getId()));
+ }
+ return;
+ }
+
+ log.debug("Adding new flow between {} at {} and {} at {}",
+ new Object[]{srcMacAddress, srcSwitchPort, dstMacAddress, dstSwitchPort});
+
+ String intentId = callerId + ":" + controllerRegistryService.getNextUniqueId();
+ IntentOperationList operations = new IntentOperationList();
+ ShortestPathIntent intent = new ShortestPathIntent(intentId,
+ sw.getId(), pi.getInPort(), srcMacAddress.toLong(),
+ destinationDpid, destinationPort, dstMacAddress.toLong());
+ IntentOperation.Operator operator = IntentOperation.Operator.ADD;
+ operations.add(operator, intent);
+ pathRuntime.executeIntentOperations(operations);
+
+ OFPacketOut po = constructPacketOut(pi, sw);
+
+ // Add to waiting lists
+ pendingFlows.put(pathspec, new PushedFlow(intentId));
+ log.debug("Put a Path {} in the pending flow, intent ID {}", pathspec, intentId);
+ waitingPackets.put(intentId, new PacketToPush(po, sw.getId()));
+ log.debug("Put a Packet in the wating list. related pathspec {}", pathspec);
+
+ }
+ }
+
+ private OFPacketOut constructPacketOut(OFPacketIn pi, IOFSwitch sw) {
+ OFPacketOut po = new OFPacketOut();
+ po.setInPort(OFPort.OFPP_NONE)
+ .setInPort(pi.getInPort())
+ .setActions(new ArrayList<OFAction>())
+ .setLengthU(OFPacketOut.MINIMUM_LENGTH);
+
+ if (sw.getBuffers() == 0) {
+ po.setBufferId(OFPacketOut.BUFFER_ID_NONE)
+ .setPacketData(pi.getPacketData())
+ .setLengthU(po.getLengthU() + po.getPacketData().length);
+ } else {
+ po.setBufferId(pi.getBufferId());
+ }
+
+ return po;
+ }
+
+ @Override
+ public void flowsInstalled(Collection<FlowPath> installedFlowPaths) {
+ }
+
+ @Override
+ public void flowRemoved(FlowPath removedFlowPath) {
+ }
+
+ public void flowRemoved(PathIntent removedIntent) {
+ if (log.isTraceEnabled()) {
+ log.trace("Path {} was removed", removedIntent.getParentIntent().getId());
+ }
+
+ ShortestPathIntent spfIntent = (ShortestPathIntent) removedIntent.getParentIntent();
+ MACAddress srcMacAddress = MACAddress.valueOf(spfIntent.getSrcMac());
+ MACAddress dstMacAddress = MACAddress.valueOf(spfIntent.getDstMac());
+ Path removedPath = new Path(srcMacAddress, dstMacAddress);
+
+ synchronized (lock) {
+ // There *shouldn't* be any packets queued if the flow has
+ // just been removed.
+ List<PacketToPush> packets = waitingPackets.removeAll(spfIntent.getId());
+ if (!packets.isEmpty()) {
+ log.warn("Removed flow {} has packets queued.", spfIntent.getId());
+ }
+ pendingFlows.remove(removedPath);
+ log.debug("Removed from the pendingFlow: Path {}, Flow ID {}", removedPath, spfIntent.getId());
+ }
+ }
+
+ private void flowInstalled(PathIntent installedPath) {
+ if (log.isTraceEnabled()) {
+ log.trace("Path {} was installed", installedPath.getParentIntent().getId());
+ }
+
+ ShortestPathIntent spfIntent = (ShortestPathIntent) installedPath.getParentIntent();
+ MACAddress srcMacAddress = MACAddress.valueOf(spfIntent.getSrcMac());
+ MACAddress dstMacAddress = MACAddress.valueOf(spfIntent.getDstMac());
+ Path path = new Path(srcMacAddress, dstMacAddress);
+ log.debug("Path spec {}", path);
+
+ // TODO waiting packets should time out. We could request a path that
+ // can't be installed right now because of a network partition. The path
+ // may eventually be installed, but we may have received thousands of
+ // packets in the meantime and probably don't want to send very old packets.
+
+ List<PacketToPush> packets = null;
+ net.onrc.onos.core.topology.Path graphPath = installedPath.getPath();
+
+ log.debug("path{}", graphPath);
+ Short outPort = graphPath.get(0).getSrc().getNumber().shortValue();
+
+ PushedFlow existingFlow = null;
+
+ synchronized (lock) {
+ existingFlow = pendingFlows.get(path);
+
+ if (existingFlow != null) {
+ existingFlow.installed = true;
+ existingFlow.firstOutPort = outPort;
+ } else {
+ log.debug("ExistingFlow {} is null", path);
+ return;
+ }
+
+ //Check both existing flow are installed status.
+ if (existingFlow.installed) {
+ packets = waitingPackets.removeAll(existingFlow.intentId);
+ if (log.isDebugEnabled()) {
+ log.debug("removed my packets {} to push from waitingPackets. outPort {} size {}",
+ existingFlow.intentId, existingFlow.firstOutPort, packets.size());
+ }
+ } else {
+ log.debug("Forward or reverse flows hasn't been pushed yet. return");
+ return;
+ }
+ }
+
+ for (PacketToPush packet : packets) {
+ log.debug("Start packetToPush to sw {}, outPort {}, path {}", packet.dpid, existingFlow.firstOutPort, path);
+ IOFSwitch sw = floodlightProvider.getSwitches().get(packet.dpid);
+ sendPacketOut(sw, packet.packet, existingFlow.firstOutPort);
+ }
+ }
+
+ private void sendPacketOut(IOFSwitch sw, OFPacketOut po, short outPort) {
+ po.getActions().add(new OFActionOutput(outPort));
+ po.setActionsLength((short)
+ (po.getActionsLength() + OFActionOutput.MINIMUM_LENGTH));
+ po.setLengthU(po.getLengthU() + OFActionOutput.MINIMUM_LENGTH);
+
+ flowPusher.add(sw, po);
+ }
+
+ @Override
+ public void entryAdded(IntentStateList value) {
+ entryUpdated(value);
+
+ }
+
+ @Override
+ public void entryRemoved(IntentStateList value) {
+ //no-op
+ }
+
+ @Override
+ public void entryUpdated(IntentStateList value) {
+ for (Entry<String, IntentState> entry : value.entrySet()) {
+ log.debug("path intent key {}, value {}", entry.getKey(), entry.getValue());
+ PathIntent pathIntent = (PathIntent) intentMap.getIntent(entry.getKey());
+ if (pathIntent == null)
+ continue;
+
+ if (!(pathIntent.getParentIntent() instanceof ShortestPathIntent))
+ continue;
+
+ IntentState state = entry.getValue();
+ switch (state) {
+ case INST_REQ:
+ break;
+ case INST_ACK:
+ flowInstalled(pathIntent);
+ break;
+ case INST_NACK:
+ break;
+ case DEL_REQ:
+ break;
+ case DEL_ACK:
+ flowRemoved(pathIntent);
+ break;
+ case DEL_PENDING:
+ break;
+ default:
+ break;
+ }
+ }
+ }
}
diff --git a/src/main/java/net/onrc/onos/apps/forwarding/IForwardingService.java b/src/main/java/net/onrc/onos/apps/forwarding/IForwardingService.java
index 375da88..6968999 100644
--- a/src/main/java/net/onrc/onos/apps/forwarding/IForwardingService.java
+++ b/src/main/java/net/onrc/onos/apps/forwarding/IForwardingService.java
@@ -8,26 +8,26 @@
/**
* Temporary interface that allows the Forwarding module to be
* notified when a flow has been installed.
- *
+ * <p/>
* This should be refactored to a listener framework in the future.
- * @author jono
*
+ * @author jono
*/
public interface IForwardingService extends IFloodlightService {
- /**
- * Notify the Forwarding module that a collection of flows has been
- * installed in the network.
- *
- * @param installedFlowPaths the collection of FlowPaths that have
- * been installed in the network.
- */
- public void flowsInstalled(Collection<FlowPath> installedFlowPaths);
-
- /**
- * Notify the Forwarding module that a flow has expired and been
- * removed from the network.
- *
- * @param removedFlowPath The FlowPath that was removed
- */
- public void flowRemoved(FlowPath removedFlowPath);
+ /**
+ * Notify the Forwarding module that a collection of flows has been
+ * installed in the network.
+ *
+ * @param installedFlowPaths the collection of FlowPaths that have
+ * been installed in the network.
+ */
+ public void flowsInstalled(Collection<FlowPath> installedFlowPaths);
+
+ /**
+ * Notify the Forwarding module that a flow has expired and been
+ * removed from the network.
+ *
+ * @param removedFlowPath The FlowPath that was removed
+ */
+ public void flowRemoved(FlowPath removedFlowPath);
}
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/ArpCache.java b/src/main/java/net/onrc/onos/apps/proxyarp/ArpCache.java
index f2e2891..f8c1589 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/ArpCache.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/ArpCache.java
@@ -43,6 +43,7 @@
/**
* Class constructor, specifying the MAC address for the entry.
+ *
* @param macAddress MAC address for the entry
*/
public ArpCacheEntry(MACAddress macAddress) {
@@ -52,6 +53,7 @@
/**
* Returns the MAC address this entry represents.
+ *
* @return this entry's MAC address
*/
public MACAddress getMacAddress() {
@@ -60,6 +62,7 @@
/**
* Update the timestamp for this entry.
+ *
* @param time the new timestamp to update the entry with
*/
public void setTimeLastSeen(long time) {
@@ -68,6 +71,7 @@
/**
* Returns whether the entry has timed out or not.
+ *
* @return true if the entry has timed out.
*/
public boolean isExpired() {
@@ -84,6 +88,7 @@
/**
* Get the MAC address that is mapped to an IP address in the ARP cache.
+ *
* @param ipAddress the IP address to look up
* @return the MAC address if found in the cache, null if not
*/
@@ -110,7 +115,8 @@
* Update an entry in the ARP cache. If the IP to MAC mapping is already
* in the cache, its timestamp will be updated. If not, the entry will
* be added with a new timestamp of the current time.
- * @param ipAddress the IP address that will be mapped in the cache
+ *
+ * @param ipAddress the IP address that will be mapped in the cache
* @param macAddress the MAC address that maps to {@code ipAddress}
*/
synchronized void update(InetAddress ipAddress, MACAddress macAddress) {
@@ -125,8 +131,8 @@
/**
* Retrieve a list of all mappings in the ARP cache.
- * @return list of all ARP mappings, formatted as a human-readable string
*
+ * @return list of all ARP mappings, formatted as a human-readable string
*/
synchronized List<String> getMappings() {
List<String> result = new ArrayList<String>(arpCache.size());
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/ArpCacheResource.java b/src/main/java/net/onrc/onos/apps/proxyarp/ArpCacheResource.java
index 7bf2a5a..70818c9 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/ArpCacheResource.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/ArpCacheResource.java
@@ -7,12 +7,12 @@
/**
* REST resource to view the IP to MAC mappings in the ARP cache.
- *
*/
public class ArpCacheResource extends ServerResource {
/**
* Handler for a REST call to retrieve the ARP cache.
+ *
* @return list of mappings formatted as a human-readable string.
*/
@Get("json")
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/ArpReplyNotification.java b/src/main/java/net/onrc/onos/apps/proxyarp/ArpReplyNotification.java
index bde2734..9866359 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/ArpReplyNotification.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/ArpReplyNotification.java
@@ -15,20 +15,24 @@
private int targetAddress;
private MACAddress targetMacAddress;
- protected ArpReplyNotification() {}
+ protected ArpReplyNotification() {
+ }
+
/**
* Class constructor.
- * @param targetAddress IP address received from the ARP reply
+ *
+ * @param targetAddress IP address received from the ARP reply
* @param targetMacAddress MAC address received from the ARP reply
*/
public ArpReplyNotification(int targetAddress,
- MACAddress targetMacAddress) {
+ MACAddress targetMacAddress) {
this.targetAddress = targetAddress;
this.targetMacAddress = targetMacAddress;
}
/**
* Returns the IP address of the ARP reply.
+ *
* @return the IP address
*/
public int getTargetAddress() {
@@ -37,6 +41,7 @@
/**
* Returns the MAC address of the ARP reply.
+ *
* @return the MAC address
*/
public MACAddress getTargetMacAddress() {
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/BroadcastPacketOutNotification.java b/src/main/java/net/onrc/onos/apps/proxyarp/BroadcastPacketOutNotification.java
index c2097f2..5f70cf1 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/BroadcastPacketOutNotification.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/BroadcastPacketOutNotification.java
@@ -1,16 +1,15 @@
package net.onrc.onos.apps.proxyarp;
-
// TODO This class is too generic to be handled by ProxyArpService.
// TODO The generic broadcast packet shouldn't contain an IP address which is
// only for ARP packets.
+
/**
* Notification to all ONOS instances to broadcast this packet out the edge of
* the network. The edge is defined as any port that doesn't have a link to
* another switch. The one exception is the port that the packet was received
* on.
- *
*/
public class BroadcastPacketOutNotification extends PacketOutNotification {
@@ -21,32 +20,29 @@
private final short inPort;
protected BroadcastPacketOutNotification() {
- super();
+ super();
this.address = -1;
this.inSwitch = -1;
this.inPort = -1;
}
+
/**
* Class constructor.
*
- * @param packet
- * packet data to send in the packet-out
- * @param address
- * target IP address if the packet is an ARP packet
- * @param inSwitch
- * dpid of the switch the packet was received on
- * @param inPort
- * port number of the receiving port
+ * @param packet packet data to send in the packet-out
+ * @param address target IP address if the packet is an ARP packet
+ * @param inSwitch dpid of the switch the packet was received on
+ * @param inPort port number of the receiving port
*/
public BroadcastPacketOutNotification(byte[] packet, int address,
- long inSwitch, short inPort) {
+ long inSwitch, short inPort) {
super(packet);
this.address = address;
this.inSwitch = inSwitch;
this.inPort = inPort;
}
-
+
/**
* Get the dpid of the switch the packet was received on.
*
@@ -69,7 +65,7 @@
* Get the target IP address if the packet is an ARP packet.
*
* @return the target IP address for ARP packets, or null if the packet is
- * not an ARP packet
+ * not an ARP packet
*/
public int getTargetAddress() {
return address;
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/IArpRequester.java b/src/main/java/net/onrc/onos/apps/proxyarp/IArpRequester.java
index ddc0ab4..ec83b28 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/IArpRequester.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/IArpRequester.java
@@ -7,7 +7,6 @@
/**
* Callback interface for modules using the {@link IProxyArpService} to send ARP
* requests.
- *
*/
public interface IArpRequester {
/**
@@ -15,10 +14,8 @@
* it receives a reply for a request previously submitted by this
* {@code IArpRequester}.
*
- * @param ipAddress
- * The IP address than an ARP request was sent for
- * @param macAddress
- * The MAC address mapped to the requested IP address
+ * @param ipAddress The IP address than an ARP request was sent for
+ * @param macAddress The MAC address mapped to the requested IP address
*/
public void arpResponse(InetAddress ipAddress, MACAddress macAddress);
}
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/IProxyArpService.java b/src/main/java/net/onrc/onos/apps/proxyarp/IProxyArpService.java
index 1cdf18c..7093d3b 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/IProxyArpService.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/IProxyArpService.java
@@ -7,6 +7,7 @@
import net.floodlightcontroller.util.MACAddress;
// Extends IFloodlightService so we can access it from REST API resources
+
/**
* Provides ARP services to other modules.
*/
@@ -17,7 +18,7 @@
*
* @param ipAddress the IP address to request the ARP mapping for
* @return the MACAddress that maps to the specified IP address, or null if
- * no mapping is found
+ * no mapping is found
*/
public MACAddress getMacAddress(InetAddress ipAddress);
@@ -28,10 +29,10 @@
* @param ipAddress the IP address to send an ARP request for
* @param requester the {@link IArpRequester} object that will be called if
* a reply is received
- * @param retry whether to keep sending requests until the MAC is learnt
+ * @param retry whether to keep sending requests until the MAC is learnt
*/
public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
- boolean retry);
+ boolean retry);
/**
* Returns a snapshot of the entire ARP cache.
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/PacketOutNotification.java b/src/main/java/net/onrc/onos/apps/proxyarp/PacketOutNotification.java
index bd64e59..c0b56a7 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/PacketOutNotification.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/PacketOutNotification.java
@@ -8,20 +8,21 @@
* abstract base class that will be subclassed by specific types of
* notifications.
*/
-public abstract class PacketOutNotification implements Serializable{
+public abstract class PacketOutNotification implements Serializable {
private static final long serialVersionUID = 1L;
protected final byte[] packet;
-
+
/**
* Class constructor.
+ *
* @param packet the packet data to send in the packet-out
*/
public PacketOutNotification() {
- packet = null;
+ packet = null;
}
-
+
public PacketOutNotification(byte[] packet) {
this.packet = packet;
}
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/apps/proxyarp/ProxyArpManager.java
index f876310..805e657 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/ProxyArpManager.java
@@ -55,7 +55,7 @@
import com.google.common.collect.SetMultimap;
public class ProxyArpManager implements IProxyArpService, IOFMessageListener,
- IFloodlightModule {
+ IFloodlightModule {
private static final Logger log = LoggerFactory
.getLogger(ProxyArpManager.class);
@@ -72,16 +72,16 @@
private static final String BROADCAST_PACKET_OUT_CHANNEL_NAME = "onos.broadcast_packet_out";
private static final String SINGLE_PACKET_OUT_CHANNEL_NAME = "onos.single_packet_out";
private ArpReplyEventHandler arpReplyEventHandler = new ArpReplyEventHandler();
- private BroadcastPacketOutEventHandler broadcastPacketOutEventHandler = new BroadcastPacketOutEventHandler();
+ private BroadcastPacketOutEventHandler broadcastPacketOutEventHandler = new BroadcastPacketOutEventHandler();
private SinglePacketOutEventHandler singlePacketOutEventHandler = new SinglePacketOutEventHandler();
private IConfigInfoService configService;
private IRestApiService restApi;
private IFlowPusherService flowPusher;
-
- private INetworkGraphService networkGraphService;
- private NetworkGraph networkGraph;
- private IOnosDeviceService onosDeviceService;
+
+ private INetworkGraphService networkGraphService;
+ private NetworkGraph networkGraph;
+ private IOnosDeviceService onosDeviceService;
private short vlan;
private static final short NO_VLAN = 0;
@@ -89,123 +89,123 @@
private SetMultimap<InetAddress, ArpRequest> arpRequests;
private class BroadcastPacketOutEventHandler implements
- IEventChannelListener<Long, BroadcastPacketOutNotification> {
+ IEventChannelListener<Long, BroadcastPacketOutNotification> {
- @Override
- public void entryAdded(BroadcastPacketOutNotification value) {
- if(log.isTraceEnabled()) {
- log.trace("entryAdded ip{}, sw {}, port {}, packet {}", value.getTargetAddress(), value.getInSwitch(), value.getInPort(), value.packet.length);
- }
- BroadcastPacketOutNotification notification = (BroadcastPacketOutNotification) value;
- broadcastArpRequestOutMyEdge(notification.packet,
- notification.getInSwitch(),
- notification.getInPort());
-
- // set timestamp
- ByteBuffer buffer = ByteBuffer.allocate(4);
- buffer.putInt(notification.getTargetAddress());
- InetAddress addr = null;
- try {
- addr = InetAddress.getByAddress(buffer.array());
- } catch (UnknownHostException e) {
- log.error("Exception:", e);
- }
-
- if (addr != null) {
- for (ArpRequest request : arpRequests.get(addr)) {
- request.setRequestTime();
- }
- }
- }
-
- @Override
- public void entryUpdated(BroadcastPacketOutNotification value) {
- log.debug("entryUpdated");
- // TODO: For now, entryUpdated() is processed as entryAdded()
- entryAdded(value);
- }
-
- @Override
- public void entryRemoved(BroadcastPacketOutNotification value) {
- log.debug("entryRemoved");
- // TODO: Not implemented. Revisit when this module is refactored
- }
+ @Override
+ public void entryAdded(BroadcastPacketOutNotification value) {
+ if (log.isTraceEnabled()) {
+ log.trace("entryAdded ip{}, sw {}, port {}, packet {}", value.getTargetAddress(), value.getInSwitch(), value.getInPort(), value.packet.length);
+ }
+ BroadcastPacketOutNotification notification = (BroadcastPacketOutNotification) value;
+ broadcastArpRequestOutMyEdge(notification.packet,
+ notification.getInSwitch(),
+ notification.getInPort());
+
+ // set timestamp
+ ByteBuffer buffer = ByteBuffer.allocate(4);
+ buffer.putInt(notification.getTargetAddress());
+ InetAddress addr = null;
+ try {
+ addr = InetAddress.getByAddress(buffer.array());
+ } catch (UnknownHostException e) {
+ log.error("Exception:", e);
+ }
+
+ if (addr != null) {
+ for (ArpRequest request : arpRequests.get(addr)) {
+ request.setRequestTime();
+ }
+ }
+ }
+
+ @Override
+ public void entryUpdated(BroadcastPacketOutNotification value) {
+ log.debug("entryUpdated");
+ // TODO: For now, entryUpdated() is processed as entryAdded()
+ entryAdded(value);
+ }
+
+ @Override
+ public void entryRemoved(BroadcastPacketOutNotification value) {
+ log.debug("entryRemoved");
+ // TODO: Not implemented. Revisit when this module is refactored
+ }
}
-
+
private class SinglePacketOutEventHandler implements
- IEventChannelListener<Long, SinglePacketOutNotification> {
- @Override
- public void entryAdded(SinglePacketOutNotification packetOutNotification) {
- log.debug("entryAdded");
- SinglePacketOutNotification notification =
- (SinglePacketOutNotification) packetOutNotification;
- sendArpRequestOutPort(notification.packet,
- notification.getOutSwitch(),
- notification.getOutPort());
-
- // set timestamp
- ByteBuffer buffer = ByteBuffer.allocate(4);
- buffer.putInt(notification.getTargetAddress());
- InetAddress addr = null;
- try {
- addr = InetAddress.getByAddress(buffer.array());
- } catch (UnknownHostException e) {
- log.error("Exception:", e);
- }
-
- if (addr != null) {
- for (ArpRequest request : arpRequests.get(addr)) {
- request.setRequestTime();
- }
- }
- }
-
- @Override
- public void entryUpdated(SinglePacketOutNotification packetOutNotification) {
- log.debug("entryUpdated");
- // TODO: For now, entryUpdated() is processed as entryAdded()
- entryAdded(packetOutNotification);
- }
-
- @Override
- public void entryRemoved(SinglePacketOutNotification packetOutNotification) {
- log.debug("entryRemoved");
- // TODO: Not implemented. Revisit when this module is refactored
- }
+ IEventChannelListener<Long, SinglePacketOutNotification> {
+ @Override
+ public void entryAdded(SinglePacketOutNotification packetOutNotification) {
+ log.debug("entryAdded");
+ SinglePacketOutNotification notification =
+ (SinglePacketOutNotification) packetOutNotification;
+ sendArpRequestOutPort(notification.packet,
+ notification.getOutSwitch(),
+ notification.getOutPort());
+
+ // set timestamp
+ ByteBuffer buffer = ByteBuffer.allocate(4);
+ buffer.putInt(notification.getTargetAddress());
+ InetAddress addr = null;
+ try {
+ addr = InetAddress.getByAddress(buffer.array());
+ } catch (UnknownHostException e) {
+ log.error("Exception:", e);
+ }
+
+ if (addr != null) {
+ for (ArpRequest request : arpRequests.get(addr)) {
+ request.setRequestTime();
+ }
+ }
+ }
+
+ @Override
+ public void entryUpdated(SinglePacketOutNotification packetOutNotification) {
+ log.debug("entryUpdated");
+ // TODO: For now, entryUpdated() is processed as entryAdded()
+ entryAdded(packetOutNotification);
+ }
+
+ @Override
+ public void entryRemoved(SinglePacketOutNotification packetOutNotification) {
+ log.debug("entryRemoved");
+ // TODO: Not implemented. Revisit when this module is refactored
+ }
}
private class ArpReplyEventHandler implements
- IEventChannelListener<Long, ArpReplyNotification> {
-
- @Override
- public void entryAdded(ArpReplyNotification arpReply) {
- log.debug("Received ARP reply notification for ip {}, mac {}",
- arpReply.getTargetAddress(), arpReply.getTargetMacAddress());
- ByteBuffer buffer = ByteBuffer.allocate(4);
- buffer.putInt(arpReply.getTargetAddress());
- InetAddress addr = null;
- try {
- addr = InetAddress.getByAddress(buffer.array());
- } catch (UnknownHostException e) {
- log.error("Exception:", e);
- }
-
- if(addr != null) {
- sendArpReplyToWaitingRequesters(addr,
- arpReply.getTargetMacAddress());
- }
- }
+ IEventChannelListener<Long, ArpReplyNotification> {
- @Override
- public void entryUpdated(ArpReplyNotification arpReply) {
- // TODO: For now, entryUpdated() is processed as entryAdded()
- entryAdded(arpReply);
- }
+ @Override
+ public void entryAdded(ArpReplyNotification arpReply) {
+ log.debug("Received ARP reply notification for ip {}, mac {}",
+ arpReply.getTargetAddress(), arpReply.getTargetMacAddress());
+ ByteBuffer buffer = ByteBuffer.allocate(4);
+ buffer.putInt(arpReply.getTargetAddress());
+ InetAddress addr = null;
+ try {
+ addr = InetAddress.getByAddress(buffer.array());
+ } catch (UnknownHostException e) {
+ log.error("Exception:", e);
+ }
- @Override
- public void entryRemoved(ArpReplyNotification arpReply) {
- // TODO: Not implemented. Revisit when this module is refactored
- }
+ if (addr != null) {
+ sendArpReplyToWaitingRequesters(addr,
+ arpReply.getTargetMacAddress());
+ }
+ }
+
+ @Override
+ public void entryUpdated(ArpReplyNotification arpReply) {
+ // TODO: For now, entryUpdated() is processed as entryAdded()
+ entryAdded(arpReply);
+ }
+
+ @Override
+ public void entryRemoved(ArpReplyNotification arpReply) {
+ // TODO: Not implemented. Revisit when this module is refactored
+ }
}
private static class ArpRequest {
@@ -234,7 +234,7 @@
}
public void dispatchReply(InetAddress ipAddress,
- MACAddress replyMacAddress) {
+ MACAddress replyMacAddress) {
requester.arpResponse(ipAddress, replyMacAddress);
}
@@ -260,10 +260,10 @@
ProxyArpManager.this.sendArpReply(arpRequest, dpid, port,
macAddress);
}
-
- public ARP getArpRequest() {
- return arpRequest;
- }
+
+ public ARP getArpRequest() {
+ return arpRequest;
+ }
}
@Override
@@ -298,7 +298,7 @@
@Override
public void init(FloodlightModuleContext context) {
- this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+ this.floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
this.configService = context.getServiceImpl(IConfigInfoService.class);
this.restApi = context.getServiceImpl(IRestApiService.class);
this.datagrid = context.getServiceImpl(IDatagridService.class);
@@ -320,25 +320,25 @@
restApi.addRestletRoutable(new ArpWebRoutable());
floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
- networkGraph = networkGraphService.getNetworkGraph();
-
- //
- // Event notification setup: channels and event handlers
- //
- broadcastPacketOutEventChannel = datagrid.addListener(BROADCAST_PACKET_OUT_CHANNEL_NAME,
- broadcastPacketOutEventHandler,
- Long.class,
- BroadcastPacketOutNotification.class);
-
- singlePacketOutEventChannel = datagrid.addListener(SINGLE_PACKET_OUT_CHANNEL_NAME,
- singlePacketOutEventHandler,
- Long.class,
- SinglePacketOutNotification.class);
-
- arpReplyEventChannel = datagrid.addListener(ARP_REPLY_CHANNEL_NAME,
- arpReplyEventHandler,
- Long.class,
- ArpReplyNotification.class);
+ networkGraph = networkGraphService.getNetworkGraph();
+
+ //
+ // Event notification setup: channels and event handlers
+ //
+ broadcastPacketOutEventChannel = datagrid.addListener(BROADCAST_PACKET_OUT_CHANNEL_NAME,
+ broadcastPacketOutEventHandler,
+ Long.class,
+ BroadcastPacketOutNotification.class);
+
+ singlePacketOutEventChannel = datagrid.addListener(SINGLE_PACKET_OUT_CHANNEL_NAME,
+ singlePacketOutEventHandler,
+ Long.class,
+ SinglePacketOutNotification.class);
+
+ arpReplyEventChannel = datagrid.addListener(ARP_REPLY_CHANNEL_NAME,
+ arpReplyEventHandler,
+ Long.class,
+ ArpReplyNotification.class);
Timer arpTimer = new Timer("arp-processing");
arpTimer.scheduleAtFixedRate(new TimerTask() {
@@ -373,17 +373,17 @@
log.debug("Cleaning expired ARP request for {}", entry
.getKey().getHostAddress());
- // If the ARP request is expired and then delete the device
- // TODO check whether this is OK from this thread
- HostArpRequester requester = (HostArpRequester) request.requester;
- ARP req = requester.getArpRequest();
- Device targetDev = networkGraph.getDeviceByMac(MACAddress.valueOf(req.getTargetHardwareAddress()));
- if(targetDev != null) {
- onosDeviceService.deleteOnosDeviceByMac(MACAddress.valueOf(req.getTargetHardwareAddress()));
- if (log.isDebugEnabled()) {
- log.debug("RemoveDevice: {} due to no have not recieve the ARP reply", targetDev.getMacAddress());
- }
- }
+ // If the ARP request is expired and then delete the device
+ // TODO check whether this is OK from this thread
+ HostArpRequester requester = (HostArpRequester) request.requester;
+ ARP req = requester.getArpRequest();
+ Device targetDev = networkGraph.getDeviceByMac(MACAddress.valueOf(req.getTargetHardwareAddress()));
+ if (targetDev != null) {
+ onosDeviceService.deleteOnosDeviceByMac(MACAddress.valueOf(req.getTargetHardwareAddress()));
+ if (log.isDebugEnabled()) {
+ log.debug("RemoveDevice: {} due to no have not recieve the ARP reply", targetDev.getMacAddress());
+ }
+ }
it.remove();
@@ -460,7 +460,7 @@
}
private void handleArpRequest(IOFSwitch sw, OFPacketIn pi, ARP arp,
- Ethernet eth) {
+ Ethernet eth) {
if (log.isTraceEnabled()) {
log.trace("ARP request received for {}",
inetAddressToString(arp.getTargetProtocolAddress()));
@@ -492,86 +492,84 @@
// MACAddress macAddress = arpCache.lookup(target);
- arpRequests.put(target, new ArpRequest(
- new HostArpRequester(arp, sw.getId(), pi.getInPort()), false));
-
- Device targetDevice = networkGraph.getDeviceByMac(MACAddress.valueOf(arp.getTargetHardwareAddress()));
+ arpRequests.put(target, new ArpRequest(
+ new HostArpRequester(arp, sw.getId(), pi.getInPort()), false));
- if (targetDevice == null) {
- if (log.isTraceEnabled()) {
- log.trace("No device info found for {} - broadcasting",
- target.getHostAddress());
- }
-
- // We don't know the device so broadcast the request out
- BroadcastPacketOutNotification key =
- new BroadcastPacketOutNotification(eth.serialize(),
- ByteBuffer.wrap(arp.getTargetProtocolAddress()).getInt(), sw.getId(), pi.getInPort());
- log.debug("broadcastPacketOutEventChannel mac {}, ip {}, dpid {}, port {}, paket {}", eth.getSourceMAC().toLong(),
- ByteBuffer.wrap(arp.getTargetProtocolAddress()).getInt(), sw.getId(), pi.getInPort(), eth.serialize().length);
- broadcastPacketOutEventChannel.addTransientEntry(eth.getDestinationMAC().toLong(), key);
- }
- else {
- // Even if the device exists in our database, we do not reply to
- // the request directly, but check whether the device is still valid
- MACAddress macAddress = MACAddress.valueOf(arp.getTargetHardwareAddress());
+ Device targetDevice = networkGraph.getDeviceByMac(MACAddress.valueOf(arp.getTargetHardwareAddress()));
- if (log.isTraceEnabled()) {
- log.trace("The target Device Record in DB is: {} => {} from ARP request host at {}/{}",
- new Object [] {
- inetAddressToString(arp.getTargetProtocolAddress()),
- macAddress,
- HexString.toHexString(sw.getId()), pi.getInPort()});
- }
+ if (targetDevice == null) {
+ if (log.isTraceEnabled()) {
+ log.trace("No device info found for {} - broadcasting",
+ target.getHostAddress());
+ }
- // sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
+ // We don't know the device so broadcast the request out
+ BroadcastPacketOutNotification key =
+ new BroadcastPacketOutNotification(eth.serialize(),
+ ByteBuffer.wrap(arp.getTargetProtocolAddress()).getInt(), sw.getId(), pi.getInPort());
+ log.debug("broadcastPacketOutEventChannel mac {}, ip {}, dpid {}, port {}, paket {}", eth.getSourceMAC().toLong(),
+ ByteBuffer.wrap(arp.getTargetProtocolAddress()).getInt(), sw.getId(), pi.getInPort(), eth.serialize().length);
+ broadcastPacketOutEventChannel.addTransientEntry(eth.getDestinationMAC().toLong(), key);
+ } else {
+ // Even if the device exists in our database, we do not reply to
+ // the request directly, but check whether the device is still valid
+ MACAddress macAddress = MACAddress.valueOf(arp.getTargetHardwareAddress());
- Iterable<net.onrc.onos.core.topology.Port> outPorts = targetDevice.getAttachmentPoints();
+ if (log.isTraceEnabled()) {
+ log.trace("The target Device Record in DB is: {} => {} from ARP request host at {}/{}",
+ new Object[]{
+ inetAddressToString(arp.getTargetProtocolAddress()),
+ macAddress,
+ HexString.toHexString(sw.getId()), pi.getInPort()});
+ }
- if (!outPorts.iterator().hasNext()){
- if (log.isTraceEnabled()) {
- log.trace("Device {} exists but is not connected to any ports" +
- " - broadcasting", macAddress);
- }
-
-// BroadcastPacketOutNotification key =
-// new BroadcastPacketOutNotification(eth.serialize(),
-// target, sw.getId(), pi.getInPort());
-// broadcastPacketOutEventChannel.addTransientEntry(eth.getDestinationMAC().toLong(), key);
- }
- else {
- for (net.onrc.onos.core.topology.Port portObject : outPorts) {
- //long outSwitch = 0;
- //short outPort = 0;
+ // sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
- if(portObject.getOutgoingLink() != null || portObject.getIncomingLink() != null) {
- continue;
- }
-
- short outPort = portObject.getNumber().shortValue();
- Switch outSwitchObject = portObject.getSwitch();
- long outSwitch = outSwitchObject.getDpid();
-
- if (log.isTraceEnabled()) {
- log.trace("Probing device {} on port {}/{}",
- new Object[] {macAddress,
- HexString.toHexString(outSwitch), outPort});
- }
-
- SinglePacketOutNotification key =
- new SinglePacketOutNotification(eth.serialize(),
- ByteBuffer.wrap(target.getAddress()).getInt(), outSwitch, outPort);
- singlePacketOutEventChannel.addTransientEntry(eth.getDestinationMAC().toLong(), key);
- }
- }
- }
+ Iterable<net.onrc.onos.core.topology.Port> outPorts = targetDevice.getAttachmentPoints();
+
+ if (!outPorts.iterator().hasNext()) {
+ if (log.isTraceEnabled()) {
+ log.trace("Device {} exists but is not connected to any ports" +
+ " - broadcasting", macAddress);
+ }
+
+// BroadcastPacketOutNotification key =
+// new BroadcastPacketOutNotification(eth.serialize(),
+// target, sw.getId(), pi.getInPort());
+// broadcastPacketOutEventChannel.addTransientEntry(eth.getDestinationMAC().toLong(), key);
+ } else {
+ for (net.onrc.onos.core.topology.Port portObject : outPorts) {
+ //long outSwitch = 0;
+ //short outPort = 0;
+
+ if (portObject.getOutgoingLink() != null || portObject.getIncomingLink() != null) {
+ continue;
+ }
+
+ short outPort = portObject.getNumber().shortValue();
+ Switch outSwitchObject = portObject.getSwitch();
+ long outSwitch = outSwitchObject.getDpid();
+
+ if (log.isTraceEnabled()) {
+ log.trace("Probing device {} on port {}/{}",
+ new Object[]{macAddress,
+ HexString.toHexString(outSwitch), outPort});
+ }
+
+ SinglePacketOutNotification key =
+ new SinglePacketOutNotification(eth.serialize(),
+ ByteBuffer.wrap(target.getAddress()).getInt(), outSwitch, outPort);
+ singlePacketOutEventChannel.addTransientEntry(eth.getDestinationMAC().toLong(), key);
+ }
+ }
+ }
}
// Not used because device manager currently updates the database
// for ARP replies. May be useful in the future.
private void handleArpReply(IOFSwitch sw, OFPacketIn pi, ARP arp) {
if (log.isTraceEnabled()) {
- log.trace("ARP reply recieved: {} => {}, on {}/{}", new Object[] {
+ log.trace("ARP reply recieved: {} => {}, on {}/{}", new Object[]{
inetAddressToString(arp.getSenderProtocolAddress()),
HexString.toHexString(arp.getSenderHardwareAddress()),
HexString.toHexString(sw.getId()), pi.getInPort()});
@@ -660,19 +658,19 @@
}
// sendArpRequestToSwitches(ipAddress, eth.serialize());
- SinglePacketOutNotification key =
- new SinglePacketOutNotification(eth.serialize(), ByteBuffer.wrap(ipAddress.getAddress()).getInt(),
- intf.getDpid(), intf.getPort());
- singlePacketOutEventChannel.addTransientEntry(MACAddress.valueOf(senderMacAddress).toLong(), key);
+ SinglePacketOutNotification key =
+ new SinglePacketOutNotification(eth.serialize(), ByteBuffer.wrap(ipAddress.getAddress()).getInt(),
+ intf.getDpid(), intf.getPort());
+ singlePacketOutEventChannel.addTransientEntry(MACAddress.valueOf(senderMacAddress).toLong(), key);
}
-
+
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) {
+ byte[] arpRequest, long inSwitch, short inPort) {
if (configService.hasLayer3Configuration()) {
Interface intf = configService.getOutgoingInterface(dstAddress);
@@ -718,14 +716,14 @@
MACAddress mac = new MACAddress(arp.getSenderHardwareAddress());
- ArpReplyNotification key =
- new ArpReplyNotification(ByteBuffer.wrap(targetAddress.getAddress()).getInt(), mac);
- log.debug("ArpReplyNotification ip {}, mac{}", ByteBuffer.wrap(targetAddress.getAddress()).getInt(), mac);
- arpReplyEventChannel.addTransientEntry(mac.toLong(), key);
+ ArpReplyNotification key =
+ new ArpReplyNotification(ByteBuffer.wrap(targetAddress.getAddress()).getInt(), mac);
+ log.debug("ArpReplyNotification ip {}, mac{}", ByteBuffer.wrap(targetAddress.getAddress()).getInt(), mac);
+ arpReplyEventChannel.addTransientEntry(mac.toLong(), key);
}
private void broadcastArpRequestOutMyEdge(byte[] arpRequest, long inSwitch,
- short inPort) {
+ short inPort) {
List<SwitchPort> switchPorts = new ArrayList<SwitchPort>();
for (IOFSwitch sw : floodlightProvider.getSwitches().values()) {
@@ -736,27 +734,27 @@
List<OFAction> actions = new ArrayList<OFAction>();
- Switch graphSw = networkGraph.getSwitch(sw.getId());
- Collection<net.onrc.onos.core.topology.Port> ports = graphSw.getPorts();
-
- if (ports == null) {
- continue;
- }
-
- for (net.onrc.onos.core.topology.Port portObject : ports) {
- if (portObject.getOutgoingLink() == null && portObject.getNumber() > 0) {
- Long portNumber = portObject.getNumber();
-
- if (sw.getId() == inSwitch && portNumber.shortValue() == inPort) {
- // This is the port that the ARP message came in,
- // so don't broadcast out this port
- continue;
- }
- switchPorts.add(new SwitchPort(new Dpid(sw.getId()),
- new net.onrc.onos.core.util.Port(portNumber.shortValue())));
- actions.add(new OFActionOutput(portNumber.shortValue()));
- }
- }
+ Switch graphSw = networkGraph.getSwitch(sw.getId());
+ Collection<net.onrc.onos.core.topology.Port> ports = graphSw.getPorts();
+
+ if (ports == null) {
+ continue;
+ }
+
+ for (net.onrc.onos.core.topology.Port portObject : ports) {
+ if (portObject.getOutgoingLink() == null && portObject.getNumber() > 0) {
+ Long portNumber = portObject.getNumber();
+
+ if (sw.getId() == inSwitch && portNumber.shortValue() == inPort) {
+ // This is the port that the ARP message came in,
+ // so don't broadcast out this port
+ continue;
+ }
+ switchPorts.add(new SwitchPort(new Dpid(sw.getId()),
+ new net.onrc.onos.core.util.Port(portNumber.shortValue())));
+ actions.add(new OFActionOutput(portNumber.shortValue()));
+ }
+ }
po.setActions(actions);
short actionsLength = (short) (actions.size() * OFActionOutput.MINIMUM_LENGTH);
@@ -801,11 +799,11 @@
}
private void sendArpReply(ARP arpRequest, long dpid, short port,
- MACAddress targetMac) {
+ MACAddress targetMac) {
if (log.isTraceEnabled()) {
log.trace(
"Sending reply {} => {} to {}",
- new Object[] {
+ new Object[]{
inetAddressToString(arpRequest
.getTargetProtocolAddress()),
targetMac,
@@ -883,7 +881,7 @@
@Override
public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
- boolean retry) {
+ boolean retry) {
arpRequests.put(ipAddress, new ArpRequest(requester, retry));
// Sanity check to make sure we don't send a request for our own address
@@ -898,7 +896,7 @@
}
private void sendArpReplyToWaitingRequesters(InetAddress address,
- MACAddress mac) {
+ MACAddress mac) {
log.debug("Sending ARP reply for {} to requesters",
address.getHostAddress());
@@ -920,16 +918,16 @@
//TODO here, comment outed from long time ago. I will check if we need it later.
/*IDeviceObject deviceObject = deviceStorage.getDeviceByIP(
- InetAddresses.coerceToInteger(address));
+ InetAddresses.coerceToInteger(address));
MACAddress mac = MACAddress.valueOf(deviceObject.getMACAddress());
log.debug("Found {} at {} in network map",
- address.getHostAddress(), mac);*/
+ address.getHostAddress(), mac);*/
// Don't hold an ARP lock while dispatching requests
for (ArpRequest request : requestsToSend) {
request.dispatchReply(address, mac);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/net/onrc/onos/apps/proxyarp/SinglePacketOutNotification.java b/src/main/java/net/onrc/onos/apps/proxyarp/SinglePacketOutNotification.java
index 8ee255b..ff5ab87 100644
--- a/src/main/java/net/onrc/onos/apps/proxyarp/SinglePacketOutNotification.java
+++ b/src/main/java/net/onrc/onos/apps/proxyarp/SinglePacketOutNotification.java
@@ -1,8 +1,8 @@
package net.onrc.onos.apps.proxyarp;
-
// TODO This class is too generic to be handled by ProxyArpService.
+
/**
* Notification to another ONOS instance to send a packet out a single port.
*/
@@ -16,13 +16,14 @@
/**
* Class constructor.
- * @param packet the packet data to send in the packet-out
- * @param address target IP address if the packet is an ARP packet
+ *
+ * @param packet the packet data to send in the packet-out
+ * @param address target IP address if the packet is an ARP packet
* @param outSwitch the dpid of the switch to send the packet on
- * @param outPort the port number of the port to send the packet out
+ * @param outPort the port number of the port to send the packet out
*/
public SinglePacketOutNotification(byte[] packet, int address,
- long outSwitch, short outPort) {
+ long outSwitch, short outPort) {
super(packet);
this.address = address;
@@ -32,6 +33,7 @@
/**
* Get the dpid of the switch the packet will be sent out.
+ *
* @return the switch's dpid
*/
public long getOutSwitch() {
@@ -40,6 +42,7 @@
/**
* Get the port number of the port the packet will be sent out.
+ *
* @return the port number
*/
public short getOutPort() {
@@ -48,8 +51,9 @@
/**
* Get the target IP address if the packet is an ARP packet.
+ *
* @return the target IP address for ARP packets, or null if the packet is
- * not an ARP packet
+ * not an ARP packet
*/
public int getTargetAddress() {
return address;