Merge branch 'master' into arpononos
diff --git a/conf/onos.properties b/conf/onos.properties
index e858adb..ee75680 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -10,7 +10,8 @@
net.onrc.onos.datagrid.HazelcastDatagrid,\
net.onrc.onos.ofcontroller.flowmanager.FlowManager,\
net.onrc.onos.ofcontroller.topology.TopologyManager,\
-net.onrc.onos.registry.controller.ZookeeperRegistry
+net.onrc.onos.registry.controller.ZookeeperRegistry, \
+net.onrc.onos.ofcontroller.core.module.OnosModuleLoader
net.floodlightcontroller.restserver.RestApiServer.port = 8080
net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
net.floodlightcontroller.core.FloodlightProvider.workerthreads = 16
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
index 232deed..bf30297 100644
--- a/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
+++ b/src/main/java/net/onrc/onos/graph/GraphDBConnection.java
@@ -7,7 +7,6 @@
import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.diskstorage.StorageException;
import com.tinkerpop.blueprints.TransactionalGraph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.wrappers.event.EventTransactionalGraph;
@@ -82,6 +81,9 @@
if (!s.contains("switch_state")) {
graph.createKeyIndex("switch_state", Vertex.class);
}
+ if (!s.contains("ipv4_address")) {
+ graph.createKeyIndex("ipv4_address", Vertex.class);
+ }
graph.commit();
eg = new EventTransactionalGraph<TitanGraph>(graph);
}
diff --git a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
index f1e9b46..489eb5e 100644
--- a/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
+++ b/src/main/java/net/onrc/onos/graph/GraphDBOperation.java
@@ -1,11 +1,14 @@
package net.onrc.onos.graph;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IBaseObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowEntry;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IFlowPath;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
@@ -225,6 +228,44 @@
FramedGraph<TitanGraph> fg = conn.getFramedGraph();
if (fg != null) fg.removeVertex(dev.asVertex());
}
+
+ public IIpv4Address newIpv4Address() {
+ return newVertex("ipv4Address", IIpv4Address.class);
+ }
+
+ private <T extends IBaseObject> T newVertex(String type, Class<T> vertexType) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ T newVertex = fg.addVertex(null, vertexType);
+ if (newVertex != null) {
+ newVertex.setType(type);
+ }
+ return newVertex;
+ }
+
+ public IIpv4Address searchIpv4Address(int intIpv4Address) {
+ return searchForVertex("ipv4_address", intIpv4Address, IIpv4Address.class);
+ }
+
+ private <T> T searchForVertex(String propertyName, Object propertyValue, Class<T> vertexType) {
+ FramedGraph<TitanGraph> fg = conn.getFramedGraph();
+ if (fg != null) {
+ Iterator<T> it =
+ fg.getVertices(propertyName, propertyValue, vertexType).iterator();
+ if (it.hasNext()) {
+ return it.next();
+ }
+ }
+ return null;
+ }
+
+ public IIpv4Address ensureIpv4Address(int intIpv4Address) {
+ IIpv4Address ipv4Vertex = searchIpv4Address(intIpv4Address);
+ if (ipv4Vertex == null) {
+ ipv4Vertex = newIpv4Address();
+ ipv4Vertex.setIpv4Address(intIpv4Address);
+ }
+ return ipv4Vertex;
+ }
/**
* Create and return a flow path object.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index d84d30d..a3c8f1f 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -34,13 +34,13 @@
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.ofcontroller.bgproute.RibUpdate.Operation;
import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoLinkService;
+import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
import net.onrc.onos.ofcontroller.core.internal.TopoLinkServiceImpl;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.ofcontroller.proxyarp.IArpRequester;
import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
-import net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager;
import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
import net.onrc.onos.ofcontroller.topology.Topology;
import net.onrc.onos.ofcontroller.topology.TopologyManager;
@@ -77,7 +77,7 @@
public class BgpRoute implements IFloodlightModule, IBgpRouteService,
ITopologyListener, IArpRequester,
- IOFSwitchListener, ILayer3InfoService,
+ IOFSwitchListener, IConfigInfoService,
IProxyArpService {
private final static Logger log = LoggerFactory.getLogger(BgpRoute.class);
@@ -88,7 +88,7 @@
private ILinkDiscoveryService linkDiscoveryService;
private IRestApiService restApi;
- private ProxyArpManager proxyArp;
+ private IProxyArpService proxyArp;
private IPatriciaTrie<RibEntry> ptree;
private IPatriciaTrie<Interface> interfacePtrie;
@@ -230,6 +230,7 @@
Collection<Class<? extends IFloodlightService>> l
= new ArrayList<Class<? extends IFloodlightService>>();
l.add(IBgpRouteService.class);
+ l.add(IConfigInfoService.class);
return l;
}
@@ -238,7 +239,7 @@
Map<Class<? extends IFloodlightService>, IFloodlightService> m
= new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
m.put(IBgpRouteService.class, this);
- m.put(IProxyArpService.class, this);
+ m.put(IConfigInfoService.class, this);
return m;
}
@@ -269,7 +270,9 @@
//TODO We'll initialise this here for now, but it should really be done as
//part of the controller core
- proxyArp = new ProxyArpManager(floodlightProvider, topologyService, this, restApi);
+ //proxyArp = new ProxyArpManager(floodlightProvider, topologyService, this, restApi);
+ //proxyArp = new ProxyArpManager();
+ proxyArp = context.getServiceImpl(IProxyArpService.class);
linkUpdates = new ArrayList<LDUpdate>();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
@@ -324,9 +327,9 @@
topologyService.addListener(this);
floodlightProvider.addOFSwitchListener(this);
- proxyArp.startUp(vlan);
+ //proxyArp.startUp(vlan);
- floodlightProvider.addOFMessageListener(OFType.PACKET_IN, proxyArp);
+ //floodlightProvider.addOFMessageListener(OFType.PACKET_IN, proxyArp);
//Retrieve the RIB from BGPd during startup
retrieveRib();
@@ -1238,7 +1241,7 @@
}
/*
- * ILayer3InfoService methods
+ * IConfigInfoService methods
*/
@Override
@@ -1277,6 +1280,11 @@
public MACAddress getRouterMacAddress() {
return bgpdMacAddress;
}
+
+ @Override
+ public short getVlan() {
+ return vlan;
+ }
/*
* TODO This is a hack to get the REST API to work for ProxyArpManager.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java
index 7fabc72..4c81d1b 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/Configuration.java
@@ -47,7 +47,7 @@
public void setBgpdMacAddress(String strMacAddress) {
this.bgpdMacAddress = MACAddress.valueOf(strMacAddress);
}
-
+
public List<String> getSwitches() {
return Collections.unmodifiableList(switches);
}
@@ -65,7 +65,7 @@
public void setSwitches(List<String> switches) {
this.switches = switches;
}
-
+
public List<Interface> getInterfaces() {
return Collections.unmodifiableList(interfaces);
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
index 7310d8c..be495b9 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/IDeviceStorage.java
@@ -9,7 +9,7 @@
public IDeviceObject updateDevice(IDevice device);
public void removeDevice(IDevice device);
public IDeviceObject getDeviceByMac(String mac);
- public IDeviceObject getDeviceByIP(String ip);
+ public IDeviceObject getDeviceByIP(int ipv4Address);
public void changeDeviceAttachments(IDevice device);
public void changeDeviceIPv4Address(IDevice device);
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
index 6f13080..6b84d32 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/INetMapTopologyObjects.java
@@ -149,12 +149,6 @@
@Property("dl_addr")
public void setMACAddress(String macaddr);
- @JsonProperty("ipv4")
- @Property("nw_addr")
- public String getIPAddress();
- @Property("nw_addr")
- public void setIPAddress(String ipaddr);
-
@JsonIgnore
@Adjacency(label="host",direction = Direction.IN)
public Iterable<IPortObject> getAttachedPorts();
@@ -171,6 +165,23 @@
@GremlinGroovy("it.in('host').in('on')")
public Iterable<ISwitchObject> getSwitch();
+ //
+ // IPv4 Addresses
+ //
+ @JsonProperty("ipv4addresses")
+ @Adjacency(label="hasAddress")
+ public Iterable<IIpv4Address> getIpv4Addresses();
+
+ @JsonIgnore
+ @GremlinGroovy("it.out('hasAddress').has('ipv4', ipv4Address)")
+ public IIpv4Address getIpv4Address(@GremlinParam("ipv4Address") final int ipv4Address);
+
+ @Adjacency(label="hasAddress")
+ public void addIpv4Address(final IIpv4Address ipv4Address);
+
+ @Adjacency(label="hasAddress")
+ public void removeIpv4Address(final IIpv4Address ipv4Address);
+
/* @JsonProperty("dpid")
@GremlinGroovy("_().in('host').in('on').next().getProperty('dpid')")
public Iterable<String> getSwitchDPID();
@@ -183,7 +194,21 @@
@GremlinGroovy("_().in('host').in('on').path(){it.number}{it.dpid}")
public Iterable<SwitchPort> getAttachmentPoints();*/
}
-
+
+ public interface IIpv4Address extends IBaseObject {
+
+ @JsonProperty("ipv4")
+ @Property("ipv4_address")
+ public int getIpv4Address();
+
+ @Property("ipv4_address")
+ public void setIpv4Address(int ipv4Address);
+
+ @JsonIgnore
+ @GremlinGroovy("it.in('hasAddress')")
+ public IDeviceObject getDevice();
+ }
+
public interface IFlowPath extends IBaseObject {
@JsonProperty("flowId")
@Property("flow_id")
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/config/DefaultConfiguration.java b/src/main/java/net/onrc/onos/ofcontroller/core/config/DefaultConfiguration.java
new file mode 100644
index 0000000..d9a291f
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/config/DefaultConfiguration.java
@@ -0,0 +1,47 @@
+package net.onrc.onos.ofcontroller.core.config;
+
+import java.net.InetAddress;
+
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.bgproute.Interface;
+
+import org.openflow.util.HexString;
+
+public class DefaultConfiguration implements IConfigInfoService {
+
+ @Override
+ public boolean isInterfaceAddress(InetAddress address) {
+ return false;
+ }
+
+ @Override
+ public boolean inConnectedNetwork(InetAddress address) {
+ return false;
+ }
+
+ @Override
+ public boolean fromExternalNetwork(long inDpid, short inPort) {
+ return false;
+ }
+
+ @Override
+ public Interface getOutgoingInterface(InetAddress dstIpAddress) {
+ return null;
+ }
+
+ @Override
+ public boolean hasLayer3Configuration() {
+ return false;
+ }
+
+ @Override
+ public MACAddress getRouterMacAddress() {
+ return MACAddress.valueOf(HexString.fromHexString("000000000001"));
+ }
+
+ @Override
+ public short getVlan() {
+ return 0;
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/ILayer3InfoService.java b/src/main/java/net/onrc/onos/ofcontroller/core/config/IConfigInfoService.java
similarity index 67%
rename from src/main/java/net/onrc/onos/ofcontroller/bgproute/ILayer3InfoService.java
rename to src/main/java/net/onrc/onos/ofcontroller/core/config/IConfigInfoService.java
index 00ddd68..7bbf483 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/ILayer3InfoService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/config/IConfigInfoService.java
@@ -1,15 +1,17 @@
-package net.onrc.onos.ofcontroller.bgproute;
+package net.onrc.onos.ofcontroller.core.config;
import java.net.InetAddress;
import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.bgproute.Interface;
+import net.onrc.onos.ofcontroller.core.module.IOnosService;
/**
* Provides information about the layer 3 properties of the network.
* This is based on IP addresses configured on ports in the network.
*
*/
-public interface ILayer3InfoService {
+public interface IConfigInfoService extends IOnosService {
public boolean isInterfaceAddress(InetAddress address);
public boolean inConnectedNetwork(InetAddress address);
public boolean fromExternalNetwork(long inDpid, short inPort);
@@ -32,4 +34,15 @@
public boolean hasLayer3Configuration();
public MACAddress getRouterMacAddress();
+
+ /**
+ * We currently have basic vlan support for the situation when the contr
+ * is running within a single vlan. In this case, packets sent from the
+ * controller (e.g. ARP) need to be tagged with that vlan.
+ * @return The vlan id configured in the config file,
+ * or 0 if no vlan is configured.
+ */
+ public short getVlan();
+
+
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
index 63eaacb..256008a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/DeviceStorageImpl.java
@@ -1,30 +1,31 @@
package net.onrc.onos.ofcontroller.core.internal;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+
+import net.floodlightcontroller.devicemanager.IDevice;
+import net.floodlightcontroller.devicemanager.SwitchPort;
+import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.ofcontroller.core.IDeviceStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IIpv4Address;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
+
import org.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.thinkaurelius.titan.core.TitanException;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.SwitchPort;
-import net.floodlightcontroller.packet.IPv4;
-import net.onrc.onos.graph.GraphDBOperation;
-import net.onrc.onos.ofcontroller.core.IDeviceStorage;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
-import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
-import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;
/**
* This is the class for storing the information of devices into CassandraDB
* @author Pankaj
*/
public class DeviceStorageImpl implements IDeviceStorage {
+ protected final static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
private GraphDBOperation ope;
- protected final static Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);
/***
* Initialize function. Before you use this class, please call this method
@@ -32,10 +33,10 @@
*/
@Override
public void init(String conf) {
- try{
+ try {
ope = new GraphDBOperation(conf);
- } catch(Exception e) {
- log.error(e.getMessage());
+ } catch (TitanException e) {
+ log.error("Couldn't open graph operation", e);
}
}
@@ -67,39 +68,31 @@
IDeviceObject obj = null;
try {
if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
- log.debug("Adding device {}: found existing device",device.getMACAddressString());
+ log.debug("Adding device {}: found existing device", device.getMACAddressString());
} else {
obj = ope.newDevice();
- log.debug("Adding device {}: creating new device",device.getMACAddressString());
+ log.debug("Adding device {}: creating new device", device.getMACAddressString());
}
- changeDeviceAttachments(device, obj);
-
- String multiIntString = "";
- for(Integer intValue : device.getIPv4Addresses()) {
- if (multiIntString == null || multiIntString.isEmpty()){
- multiIntString = IPv4.fromIPv4Address(intValue);
- multiIntString = "[" + IPv4.fromIPv4Address(intValue);
- }else{
- multiIntString += "," + IPv4.fromIPv4Address(intValue);
- }
- }
-
- if(multiIntString.toString() != null && !multiIntString.toString().isEmpty()){
- obj.setIPAddress(multiIntString + "]");
- }
-
- obj.setMACAddress(device.getMACAddressString());
- obj.setType("device");
- obj.setState("ACTIVE");
- ope.commit();
- log.debug("Adding device {}",device.getMACAddressString());
- } catch (Exception e) {
+ changeDeviceAttachments(device, obj);
+
+ for (Integer intIpv4Address : device.getIPv4Addresses()) {
+ obj.addIpv4Address(ope.ensureIpv4Address(intIpv4Address));
+ }
+
+ obj.setMACAddress(device.getMACAddressString());
+ obj.setType("device");
+ obj.setState("ACTIVE");
+ ope.commit();
+
+ //log.debug("Adding device {}",device.getMACAddressString());
+ } catch (TitanException e) {
ope.rollback();
log.error(":addDevice mac:{} failed", device.getMACAddressString());
obj = null;
- }
- return obj;
+ }
+
+ return obj;
}
/***
@@ -125,7 +118,7 @@
ope.commit();
log.error("DeviceStorage:removeDevice mac:{} done", device.getMACAddressString());
}
- } catch (Exception e) {
+ } catch (TitanException e) {
ope.rollback();
log.error("DeviceStorage:removeDevice mac:{} failed", device.getMACAddressString());
}
@@ -147,23 +140,15 @@
* @return IDeviceObject you want to get.
*/
@Override
- public IDeviceObject getDeviceByIP(String ip) {
- try
- {
- for(IDeviceObject dev : ope.getDevices()){
- String ips;
- if((ips = dev.getIPAddress()) != null){
- String nw_addr_wob = ips.replace("[", "").replace("]", "");
- ArrayList<String> iplists = Lists.newArrayList(nw_addr_wob.split(","));
- if(iplists.contains(ip)){
- return dev;
- }
- }
+ public IDeviceObject getDeviceByIP(int ipv4Address) {
+ try {
+ IIpv4Address ipv4AddressVertex = ope.searchIpv4Address(ipv4Address);
+ if (ipv4AddressVertex != null) {
+ return ipv4AddressVertex.getDevice();
}
return null;
}
- catch (Exception e)
- {
+ catch (TitanException e) {
log.error("DeviceStorage:getDeviceByIP:{} failed");
return null;
}
@@ -178,14 +163,14 @@
IDeviceObject obj = null;
try {
if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
- log.debug("Changing device ports {}: found existing device",device.getMACAddressString());
+ log.debug("Changing device ports {}: found existing device", device.getMACAddressString());
changeDeviceAttachments(device, obj);
ope.commit();
} else {
- log.debug("failed to search device...now adding {}",device.getMACAddressString());
+ log.debug("failed to search device...now adding {}", device.getMACAddressString());
addDevice(device);
- }
- } catch (Exception e) {
+ }
+ } catch (TitanException e) {
ope.rollback();
log.error(":addDevice mac:{} failed", device.getMACAddressString());
}
@@ -199,33 +184,33 @@
public void changeDeviceAttachments(IDevice device, IDeviceObject obj) {
SwitchPort[] attachmentPoints = device.getAttachmentPoints();
List<IPortObject> attachedPorts = Lists.newArrayList(obj.getAttachedPorts());
-
- for (SwitchPort ap : attachmentPoints) {
- //Check weather there is the port
- IPortObject port = ope.searchPort( HexString.toHexString(ap.getSwitchDPID()),
- (short) ap.getPort());
- log.debug("New Switch Port is {},{}", HexString.toHexString(ap.getSwitchDPID()),(short) ap.getPort());
-
- if(port != null){
- if(attachedPorts.contains(port))
- {
- log.debug("This is the port you already attached {}: do nothing",device.getMACAddressString());
- //This port will be remained, so remove from the removed port lists.
- attachedPorts.remove(port);
- } else {
- log.debug("Adding device {}: attaching to port",device.getMACAddressString());
- port.setDevice(obj);
- }
-
- log.debug("port number is {}", port.getNumber().toString());
- log.debug("port desc is {}", port.getDesc());
- }
- }
-
- for (IPortObject port: attachedPorts) {
- log.debug("Detouching the device {}: detouching from port",device.getMACAddressString());
- port.removeDevice(obj);
- }
+
+ for (SwitchPort ap : attachmentPoints) {
+ //Check if there is the port
+ IPortObject port = ope.searchPort(HexString.toHexString(ap.getSwitchDPID()),
+ (short) ap.getPort());
+ log.debug("New Switch Port is {},{}",
+ HexString.toHexString(ap.getSwitchDPID()), (short) ap.getPort());
+
+ if (port != null){
+ if (attachedPorts.contains(port)) {
+ log.debug("This is the port you already attached {}: do nothing", device.getMACAddressString());
+ //This port will be remained, so remove from the removed port lists.
+ attachedPorts.remove(port);
+ } else {
+ log.debug("Adding device {}: attaching to port", device.getMACAddressString());
+ port.setDevice(obj);
+ }
+
+ log.debug("port number is {}", port.getNumber().toString());
+ log.debug("port desc is {}", port.getDesc());
+ }
+ }
+
+ for (IPortObject port: attachedPorts) {
+ log.debug("Detaching the device {}: detaching from port", device.getMACAddressString());
+ port.removeDevice(obj);
+ }
}
/***
@@ -234,22 +219,24 @@
*/
@Override
public void changeDeviceIPv4Address(IDevice device) {
+ log.debug("Changing IP address for {} to {}", device.getMACAddressString(),
+ device.getIPv4Addresses());
IDeviceObject obj;
try {
if ((obj = ope.searchDevice(device.getMACAddressString())) != null) {
-
- String multiIntString = "";
- for(Integer intValue : device.getIPv4Addresses()){
- if (multiIntString == null || multiIntString.isEmpty()){
- multiIntString = "[" + IPv4.fromIPv4Address(intValue);
- } else {
- multiIntString += "," + IPv4.fromIPv4Address(intValue);
- }
+ for (int ipv4Address : device.getIPv4Addresses()) {
+ if (obj.getIpv4Address(ipv4Address) == null) {
+ IIpv4Address dbIpv4Address = ope.ensureIpv4Address(ipv4Address);
+ obj.addIpv4Address(dbIpv4Address);
+ }
}
- if(multiIntString != null && !multiIntString.isEmpty()){
- obj.setIPAddress(multiIntString + "]");
- }
+ List<Integer> deviceIpv4Addresses = Arrays.asList(device.getIPv4Addresses());
+ for (IIpv4Address dbIpv4Address : obj.getIpv4Addresses()) {
+ if (!deviceIpv4Addresses.contains(dbIpv4Address.getIpv4Address())) {
+ obj.removeIpv4Address(dbIpv4Address);
+ }
+ }
ope.commit();
} else {
@@ -257,7 +244,7 @@
}
} catch (TitanException e) {
ope.rollback();
- log.error(":changeDeviceIPv4Address mac:{} failed due to exception {}", device.getMACAddressString(),e);
+ log.error(":changeDeviceIPv4Address mac:{} failed due to exception {}", device.getMACAddressString(), e);
}
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
index ac61b51..1735a36 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/internal/SwitchStorageImpl.java
@@ -342,6 +342,11 @@
}
}
+ // TODO There's an issue here where a port with that ID could already
+ // exist when we try to add this one (because it's left over from an
+ // old topology). We need to remove an old port with the same ID when
+ // we add the new port. Also it seems that old ports like this are
+ // never cleaned up and will remain in the DB in the ACTIVE state forever.
private IPortObject addPortImpl(ISwitchObject sw, short portNum) {
IPortObject p = op.newPort(sw.getDPID(), portNum);
p.setState("ACTIVE");
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/module/IOnosService.java b/src/main/java/net/onrc/onos/ofcontroller/core/module/IOnosService.java
new file mode 100644
index 0000000..5828366
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/module/IOnosService.java
@@ -0,0 +1,7 @@
+package net.onrc.onos.ofcontroller.core.module;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+public interface IOnosService extends IFloodlightService {
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/module/OnosModuleLoader.java b/src/main/java/net/onrc/onos/ofcontroller/core/module/OnosModuleLoader.java
new file mode 100644
index 0000000..bd7cf49
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/module/OnosModuleLoader.java
@@ -0,0 +1,86 @@
+package net.onrc.onos.ofcontroller.core.module;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.devicemanager.IDeviceService;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.topology.ITopologyService;
+import net.onrc.onos.ofcontroller.core.config.DefaultConfiguration;
+import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
+import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
+import net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager;
+
+public class OnosModuleLoader implements IFloodlightModule {
+ private IFloodlightProviderService floodlightProvider;
+ private ITopologyService topology;
+ private IDeviceService deviceService;
+ private IConfigInfoService config;
+ private IRestApiService restApi;
+
+ private ProxyArpManager arpManager;
+
+ public OnosModuleLoader() {
+ arpManager = new ProxyArpManager();
+ }
+
+ @Override
+ public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+ List<Class<? extends IFloodlightService>> services =
+ new ArrayList<Class<? extends IFloodlightService>>();
+ services.add(IProxyArpService.class);
+ return services;
+ }
+
+ @Override
+ public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+ Map<Class<? extends IFloodlightService>, IFloodlightService> impls =
+ new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+ impls.put(IProxyArpService.class, arpManager);
+ 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(ITopologyService.class);
+ dependencies.add(IDeviceService.class);
+ //dependencies.add(IConfigInfoService.class);
+ dependencies.add(IRestApiService.class);
+ return dependencies;
+ }
+
+ @Override
+ public void init(FloodlightModuleContext context)
+ throws FloodlightModuleException {
+ floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+ topology = context.getServiceImpl(ITopologyService.class);
+ deviceService = context.getServiceImpl(IDeviceService.class);
+ restApi = context.getServiceImpl(IRestApiService.class);
+
+ //This could be null because it's not mandatory to have an
+ //IConfigInfoService loaded.
+ config = context.getServiceImpl(IConfigInfoService.class);
+ if (config == null) {
+ config = new DefaultConfiguration();
+ }
+
+ arpManager.init(floodlightProvider, topology, deviceService, config, restApi);
+ }
+
+ @Override
+ public void startUp(FloodlightModuleContext context) {
+ arpManager.startUp();
+ }
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
index 97844d3..71546a1 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
@@ -3,11 +3,11 @@
import java.net.InetAddress;
import java.util.List;
-import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.core.module.IOnosService;
//Extends IFloodlightService so we can access it from REST API resources
-public interface IProxyArpService extends IFloodlightService{
+public interface IProxyArpService extends IOnosService{
/**
* Returns the MAC address if there is a valid entry in the cache.
* Otherwise returns null.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index 0151212..a5dabc9 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -5,6 +5,7 @@
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -16,14 +17,18 @@
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.devicemanager.IDeviceService;
import net.floodlightcontroller.packet.ARP;
import net.floodlightcontroller.packet.Ethernet;
import net.floodlightcontroller.packet.IPv4;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.util.MACAddress;
-import net.onrc.onos.ofcontroller.bgproute.ILayer3InfoService;
import net.onrc.onos.ofcontroller.bgproute.Interface;
+import net.onrc.onos.ofcontroller.core.IDeviceStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
+import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
@@ -39,6 +44,7 @@
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
+import com.google.common.net.InetAddresses;
public class ProxyArpManager implements IProxyArpService, IOFMessageListener {
private final static Logger log = LoggerFactory.getLogger(ProxyArpManager.class);
@@ -47,17 +53,20 @@
private static final int ARP_REQUEST_TIMEOUT = 2000; //ms
- private final IFloodlightProviderService floodlightProvider;
- private final ITopologyService topology;
- private final ILayer3InfoService layer3;
- private final IRestApiService restApi;
+ private IFloodlightProviderService floodlightProvider;
+ private ITopologyService topology;
+ private IDeviceService deviceService;
+ private IConfigInfoService configService;
+ private IRestApiService restApi;
+
+ private IDeviceStorage deviceStorage;
private short vlan;
private static final short NO_VLAN = 0;
- private final ArpCache arpCache;
+ private ArpCache arpCache;
- private final SetMultimap<InetAddress, ArpRequest> arpRequests;
+ private SetMultimap<InetAddress, ArpRequest> arpRequests;
private static class ArpRequest {
private final IArpRequester requester;
@@ -106,12 +115,21 @@
}
}
+ /*
public ProxyArpManager(IFloodlightProviderService floodlightProvider,
- ITopologyService topology, ILayer3InfoService layer3,
+ ITopologyService topology, IConfigInfoService configService,
IRestApiService restApi){
+
+ }
+ */
+
+ public void init(IFloodlightProviderService floodlightProvider,
+ ITopologyService topology, IDeviceService deviceService,
+ IConfigInfoService config, IRestApiService restApi){
this.floodlightProvider = floodlightProvider;
this.topology = topology;
- this.layer3 = layer3;
+ this.deviceService = deviceService;
+ this.configService = config;
this.restApi = restApi;
arpCache = new ArpCache();
@@ -120,11 +138,15 @@
HashMultimap.<InetAddress, ArpRequest>create());
}
- public void startUp(short vlan) {
- this.vlan = vlan;
+ public void startUp() {
+ this.vlan = configService.getVlan();
log.info("vlan set to {}", this.vlan);
restApi.addRestletRoutable(new ArpWebRoutable());
+ floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+
+ deviceStorage = new DeviceStorageImpl();
+ deviceStorage.init("");
Timer arpTimer = new Timer("arp-processing");
arpTimer.scheduleAtFixedRate(new TimerTask() {
@@ -188,12 +210,17 @@
@Override
public String getName() {
- return "ProxyArpManager";
+ return "proxyarpmanager";
}
@Override
public boolean isCallbackOrderingPrereq(OFType type, String name) {
- return false;
+ if (type == OFType.PACKET_IN) {
+ return "devicemanager".equals(name);
+ }
+ else {
+ return false;
+ }
}
@Override
@@ -218,10 +245,14 @@
ARP arp = (ARP) eth.getPayload();
if (arp.getOpCode() == ARP.OP_REQUEST) {
+ //TODO check what the DeviceManager does about propagating
+ //or swallowing ARPs. We want to go after DeviceManager in the
+ //chain but we really need it to CONTINUE ARP packets so we can
+ //get them.
handleArpRequest(sw, pi, arp);
}
else if (arp.getOpCode() == ARP.OP_REPLY) {
- handleArpReply(sw, pi, arp);
+ //handleArpReply(sw, pi, arp);
}
}
@@ -244,31 +275,56 @@
return;
}
- if (layer3.fromExternalNetwork(sw.getId(), pi.getInPort())) {
+ if (configService.fromExternalNetwork(sw.getId(), pi.getInPort())) {
//If the request came from outside our network, we only care if
//it was a request for one of our interfaces.
- if (layer3.isInterfaceAddress(target)) {
+ if (configService.isInterfaceAddress(target)) {
log.trace("ARP request for our interface. Sending reply {} => {}",
- target.getHostAddress(), layer3.getRouterMacAddress());
+ target.getHostAddress(), configService.getRouterMacAddress());
sendArpReply(arp, sw.getId(), pi.getInPort(),
- layer3.getRouterMacAddress());
+ configService.getRouterMacAddress());
}
return;
}
- MACAddress macAddress = arpCache.lookup(target);
+ //MACAddress macAddress = arpCache.lookup(target);
- if (macAddress == null){
+ //IDevice dstDevice = deviceService.fcStore.get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
+ //Iterator<? extends IDevice> it = deviceService.queryDevices(
+ //null, null, InetAddresses.coerceToInteger(target), null, null);
+
+ //IDevice targetDevice = null;
+ //if (it.hasNext()) {
+ //targetDevice = it.next();
+ //}
+ IDeviceObject targetDevice =
+ deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(target));
+
+ if (targetDevice != null) {
+ //We have the device in our database, so send a reply
+ MACAddress macAddress = MACAddress.valueOf(targetDevice.getMACAddress());
+
+ if (log.isTraceEnabled()) {
+ log.trace("Sending reply: {} => {} to host at {}/{}", new Object [] {
+ inetAddressToString(arp.getTargetProtocolAddress()),
+ macAddress.toString(),
+ HexString.toHexString(sw.getId()), pi.getInPort()});
+ }
+
+ sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
+ }
+
+ /*if (macAddress == null){
//MAC address is not in our ARP cache.
//Record where the request came from so we know where to send the reply
- arpRequests.put(target, new ArpRequest(
- new HostArpRequester(arp, sw.getId(), pi.getInPort()), false));
+ //arpRequests.put(target, new ArpRequest(
+ //new HostArpRequester(arp, sw.getId(), pi.getInPort()), false));
//Flood the request out edge ports
- sendArpRequestToSwitches(target, pi.getPacketData(), sw.getId(), pi.getInPort());
+ //sendArpRequestToSwitches(target, pi.getPacketData(), sw.getId(), pi.getInPort());
}
else {
//We know the address, so send a reply
@@ -280,7 +336,7 @@
}
sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
- }
+ }*/
}
private void handleArpReply(IOFSwitch sw, OFPacketIn pi, ARP arp){
@@ -345,7 +401,7 @@
.setTargetHardwareAddress(zeroMac)
.setTargetProtocolAddress(ipAddress.getAddress());
- MACAddress routerMacAddress = layer3.getRouterMacAddress();
+ MACAddress routerMacAddress = configService.getRouterMacAddress();
//TODO hack for now as it's unclear what the MAC address should be
byte[] senderMacAddress = genericNonZeroMac;
if (routerMacAddress != null) {
@@ -354,7 +410,7 @@
arpRequest.setSenderHardwareAddress(senderMacAddress);
byte[] senderIPAddress = zeroIpv4;
- Interface intf = layer3.getOutgoingInterface(ipAddress);
+ Interface intf = configService.getOutgoingInterface(ipAddress);
if (intf != null) {
senderIPAddress = intf.getIpAddress().getAddress();
}
@@ -383,8 +439,8 @@
private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest,
long inSwitch, short inPort) {
- if (layer3.hasLayer3Configuration()) {
- Interface intf = layer3.getOutgoingInterface(dstAddress);
+ if (configService.hasLayer3Configuration()) {
+ Interface intf = configService.getOutgoingInterface(dstAddress);
if (intf != null) {
sendArpRequestOutPort(arpRequest, intf.getDpid(), intf.getPort());
}
@@ -409,11 +465,12 @@
Set<Short> linkPorts = topology.getPortsWithLinks(sw.getId());
if (linkPorts == null){
- //I think this means the switch isn't known to topology yet.
- //Maybe it only just joined.
- continue;
+ //I think this means the switch doesn't have any links.
+ //continue;
+ linkPorts = new HashSet<Short>();
}
+
OFPacketOut po = new OFPacketOut();
po.setInPort(OFPort.OFPP_NONE)
.setBufferId(-1)
@@ -571,7 +628,7 @@
arpRequests.put(ipAddress, new ArpRequest(requester, retry));
//Sanity check to make sure we don't send a request for our own address
- if (!layer3.isInterfaceAddress(ipAddress)) {
+ if (!configService.isInterfaceAddress(ipAddress)) {
sendArpRequestForAddress(ipAddress);
}
}
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index 99ded31..7c4bc1a 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -24,3 +24,4 @@
net.onrc.onos.ofcontroller.bgproute.BgpRoute
net.onrc.onos.registry.controller.ZookeeperRegistry
net.onrc.onos.registry.controller.StandaloneRegistry
+net.onrc.onos.ofcontroller.core.module.OnosModuleLoader
\ No newline at end of file