Skip to content
Snippets Groups Projects
Commit 5d2c766e authored by abat's avatar abat
Browse files

Merge into master from pull request #306:

FL-83/FL-84 Add REST API and Java API for VNF  (https://github.com/floodlight/floodlight/pull/306)
parents b5c21da7 9d77515b
No related branches found
No related tags found
No related merge requests found
package net.floodlightcontroller.virtualnetwork;
import java.util.Collection;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.util.MACAddress;
......@@ -36,4 +37,10 @@ public interface IVirtualNetworkService extends IFloodlightService {
* @param port The logical port the host is attached to.
*/
public void deleteHost(MACAddress mac, String port);
/**
* Return list of all virtual networks.
* @return Collection <VirtualNetwork>
*/
public Collection <VirtualNetwork> listNetworks();
}
package net.floodlightcontroller.virtualnetwork;
import java.io.IOException;
import java.util.Collection;
import net.floodlightcontroller.packet.IPv4;
......@@ -10,6 +11,7 @@ import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.MappingJsonFactory;
import org.restlet.data.Status;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.Put;
import org.restlet.resource.ServerResource;
......@@ -72,6 +74,14 @@ public class NetworkResource extends ServerResource {
jp.close();
}
@Get("json")
public Collection <VirtualNetwork> retrieve() {
IVirtualNetworkService vns =
(IVirtualNetworkService)getContext().getAttributes().
get(IVirtualNetworkService.class.getCanonicalName());
return vns.listNetworks();
}
@Put
@Post
......
package net.floodlightcontroller.virtualnetwork;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import net.floodlightcontroller.util.MACAddress;
/**
* Data structure for storing and outputing information of a virtual network created
* by VirtualNetworkFilter
*
* @author KC Wang
*/
@JsonSerialize(using=VirtualNetworkSerializer.class)
public class VirtualNetwork{
protected String name; // network name
protected String guid; // network id
protected String gateway; // network gateway
protected Collection<MACAddress> hosts; // array of hosts explicitly added to this network
/**
* Constructor requires network name and id
* @param name: network name
* @param guid: network id
*/
public VirtualNetwork(String name, String guid) {
this.name = name;
this.guid = guid;
this.gateway = null;
this.hosts = new ArrayList<MACAddress>();
return;
}
/**
* Sets network gateway IP address
* @param gateway: IP address as String
*/
public void setGateway(String gateway){
this.gateway = gateway;
return;
}
/**
* Adds a host to this network record
* @param host: MAC address as MACAddress
*/
public void addHost(MACAddress host){
this.hosts.add(host);
return;
}
/**
* Removes a host from this network record
* @param host: MAC address as MACAddress
* @return boolean: true: removed, false: host not found
*/
public boolean removeHost(MACAddress host){
Iterator<MACAddress> iter = this.hosts.iterator();
while(iter.hasNext()){
MACAddress element = iter.next();
if(element.equals(host) ){
//assuming MAC address for host is unique
iter.remove();
return true;
}
}
return false;
}
/**
* Removes all hosts from this network record
*/
public void clearHosts(){
this.hosts.clear();
}
}
\ No newline at end of file
......@@ -68,6 +68,7 @@ public class VirtualNetworkFilter
IDeviceService deviceService;
// Our internal state
protected Map<String, VirtualNetwork> vNetsByGuid; // List of all created virtual networks
protected Map<String, String> nameToGuid; // Logical name -> Network ID
protected Map<String, Integer> guidToGateway; // Network ID -> Gateway IP
protected Map<Integer, Set<String>> gatewayToGuid; // Gateway IP -> Network ID
......@@ -87,6 +88,8 @@ public class VirtualNetworkFilter
IPv4.fromIPv4Address(ip), guid);
guidToGateway.put(guid, ip);
if (vNetsByGuid.get(guid) != null)
vNetsByGuid.get(guid).setGateway(IPv4.fromIPv4Address(ip));
if (gatewayToGuid.containsKey(ip)) {
Set<String> gSet = gatewayToGuid.get(ip);
gSet.add(guid);
......@@ -108,6 +111,8 @@ public class VirtualNetworkFilter
if (gwIp == null) return;
Set<String> gSet = gatewayToGuid.get(gwIp);
gSet.remove(guid);
if(vNetsByGuid.get(guid)!=null)
vNetsByGuid.get(guid).setGateway(null);
}
// IVirtualNetworkService
......@@ -135,9 +140,13 @@ public class VirtualNetworkFilter
}
}
nameToGuid.put(network, guid);
vNetsByGuid.put(guid, new VirtualNetwork(network, guid));
// If they don't specify a new gateway the old one will be preserved
if ((gateway != null) && (gateway != 0)) {
addGateway(guid, gateway);
if(vNetsByGuid.get(guid)!=null)
vNetsByGuid.get(guid).setGateway(IPv4.fromIPv4Address(gateway));
}
}
......@@ -163,6 +172,10 @@ public class VirtualNetworkFilter
nameToGuid.remove(name);
deleteGateway(guid);
if(vNetsByGuid.get(guid)!=null){
vNetsByGuid.get(guid).clearHosts();
vNetsByGuid.remove(guid);
}
Collection<MACAddress> deleteList = new ArrayList<MACAddress>();
for (MACAddress host : macToGuid.keySet()) {
if (macToGuid.get(host).equals(guid)) {
......@@ -194,6 +207,8 @@ public class VirtualNetworkFilter
// We ignore old mappings
macToGuid.put(mac, guid);
portToMac.put(port, mac);
if(vNetsByGuid.get(guid)!=null)
vNetsByGuid.get(guid).addHost(new MACAddress(mac.toBytes()));
} else {
log.warn("Could not add MAC {} to network ID {} on port {}, the network does not exist",
new Object[] {mac, guid, port});
......@@ -208,11 +223,15 @@ public class VirtualNetworkFilter
if (mac == null && port == null) return;
if (port != null) {
MACAddress host = portToMac.remove(port);
if(vNetsByGuid.get(macToGuid.get(host)) != null)
vNetsByGuid.get(macToGuid.get(host)).removeHost(host);
macToGuid.remove(host);
} else if (mac != null) {
if (!portToMac.isEmpty()) {
for (Entry<String, MACAddress> entry : portToMac.entrySet()) {
if (entry.getValue().equals(mac)) {
if(vNetsByGuid.get(macToGuid.get(entry.getValue())) != null)
vNetsByGuid.get(macToGuid.get(entry.getValue())).removeHost(entry.getValue());
portToMac.remove(entry.getKey());
macToGuid.remove(entry.getValue());
return;
......@@ -260,6 +279,7 @@ public class VirtualNetworkFilter
restApi = context.getServiceImpl(IRestApiService.class);
deviceService = context.getServiceImpl(IDeviceService.class);
vNetsByGuid = new ConcurrentHashMap<String, VirtualNetwork>();
nameToGuid = new ConcurrentHashMap<String, String>();
guidToGateway = new ConcurrentHashMap<String, Integer>();
gatewayToGuid = new ConcurrentHashMap<Integer, Set<String>>();
......@@ -489,4 +509,10 @@ public class VirtualNetworkFilter
public void deviceVlanChanged(IDevice device) {
// ignore
}
@Override
public Collection <VirtualNetwork> listNetworks() {
return vNetsByGuid.values();
}
}
package net.floodlightcontroller.virtualnetwork;
import java.io.IOException;
import java.util.Iterator;
import net.floodlightcontroller.util.MACAddress;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
/**
* Serialize a VirtualNetwork object
* @author KC Wang
*/
public class VirtualNetworkSerializer extends JsonSerializer<VirtualNetwork> {
@Override
public void serialize(VirtualNetwork vNet, JsonGenerator jGen,
SerializerProvider serializer) throws IOException,
JsonProcessingException {
jGen.writeStartObject();
jGen.writeStringField("name", vNet.name);
jGen.writeStringField("guid", vNet.guid);
jGen.writeStringField("gateway", vNet.gateway);
jGen.writeArrayFieldStart("mac");
Iterator<MACAddress> hit = vNet.hosts.iterator();
while (hit.hasNext())
jGen.writeString(hit.next().toString());
jGen.writeEndArray();
jGen.writeEndObject();
}
}
......@@ -11,6 +11,7 @@ public class VirtualNetworkWebRoutable implements RestletRoutable {
@Override
public Restlet getRestlet(Context context) {
Router router = new Router(context);
router.attach("/tenants/{tenant}/networks", NetworkResource.class); // GET
router.attach("/tenants/{tenant}/networks/{network}", NetworkResource.class); // PUT, DELETE
router.attach("/tenants/{tenant}/networks", NetworkResource.class); // POST
router.attach("/tenants/{tenant}/networks/{network}/ports/{port}/attachment", HostResource.class);
......
# The default configuration for openstack
floodlight.modules = net.floodlightcontroller.storage.memory.MemoryStorageSource,\
net.floodlightcontroller.core.FloodlightProvider,\
net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl,\
net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,\
net.floodlightcontroller.forwarding.Forwarding,\
net.floodlightcontroller.jython.JythonDebugInterface,\
net.floodlightcontroller.counter.CounterStore,\
net.floodlightcontroller.perfmon.PktInProcessingTime,\
net.floodlightcontroller.ui.web.StaticWebRoutable,\
net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter
net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter,\
net.floodlightcontroller.threadpool.ThreadPool
net.floodlightcontroller.restserver.RestApiServer.port = 8080
net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
net.floodlightcontroller.jython.JythonDebugInterface.port = 6655
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment