Skip to content
Snippets Groups Projects
Commit 34bc8929 authored by kwanggithub's avatar kwanggithub
Browse files

Merge branch 'backport' of ../../bsckwang/bigswitchcontroller into LB

parents 34710a43 44dad720
No related branches found
No related tags found
No related merge requests found
Showing
with 1084 additions and 381 deletions
package net.floodlightcontroller.loadbalancer;
import java.io.IOException;
import java.util.Collection;
import net.floodlightcontroller.packet.IPv4;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.MappingJsonFactory;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MembersResource extends ServerResource {
protected static Logger log = LoggerFactory.getLogger(MembersResource.class);
@Get("json")
public Collection <LBMember> retrieve() {
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
String memberId = (String) getRequestAttributes().get("member");
if (memberId!=null)
return lbs.listMember(memberId);
else
return lbs.listMembers();
}
@Put
@Post
public LBMember createMember(String postData) {
LBMember member=null;
try {
member=jsonToMember(postData);
} catch (IOException e) {
log.error("Could not parse JSON {}", e.getMessage());
}
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
String memberId = (String) getRequestAttributes().get("member");
if (memberId != null)
return lbs.updateMember(member);
else
return lbs.createMember(member);
}
@Delete
public int removeMember() {
String memberId = (String) getRequestAttributes().get("member");
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
return lbs.removeMember(memberId);
}
protected LBMember jsonToMember(String json) throws IOException {
MappingJsonFactory f = new MappingJsonFactory();
JsonParser jp;
LBMember member = new LBMember();
try {
jp = f.createJsonParser(json);
} catch (JsonParseException e) {
throw new IOException(e);
}
jp.nextToken();
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw new IOException("Expected START_OBJECT");
}
while (jp.nextToken() != JsonToken.END_OBJECT) {
if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
throw new IOException("Expected FIELD_NAME");
}
String n = jp.getCurrentName();
jp.nextToken();
if (jp.getText().equals(""))
continue;
if (n.equals("id")) {
member.id = jp.getText();
continue;
} else
if (n.equals("address")) {
member.address = IPv4.toIPv4Address(jp.getText());
continue;
} else
if (n.equals("port")) {
member.port = Short.parseShort(jp.getText());
continue;
} else
if (n.equals("connection_limit")) {
member.connectionLimit = Integer.parseInt(jp.getText());
continue;
} else
if (n.equals("admin_state")) {
member.adminState = Short.parseShort(jp.getText());
continue;
} else
if (n.equals("status")) {
member.status = Short.parseShort(jp.getText());
continue;
} else
if (n.equals("pool_id")) {
member.poolId = jp.getText();
continue;
}
log.warn("Unrecognized field {} in " +
"parsing Members",
jp.getText());
}
jp.close();
return member;
}
}
package net.floodlightcontroller.loadbalancer;
import java.io.IOException;
import java.util.Collection;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.MappingJsonFactory;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MonitorsResource extends ServerResource {
protected static Logger log = LoggerFactory.getLogger(MonitorsResource.class);
@Get("json")
public Collection <LBMonitor> retrieve() {
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
String monitorId = (String) getRequestAttributes().get("monitor");
if (monitorId!=null)
return lbs.listMonitor(monitorId);
else
return lbs.listMonitors();
}
@Put
@Post
public LBMonitor createMonitor(String postData) {
LBMonitor monitor=null;
try {
monitor=jsonToMonitor(postData);
} catch (IOException e) {
log.error("Could not parse JSON {}", e.getMessage());
}
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
String monitorId = (String) getRequestAttributes().get("monitor");
if (monitorId != null)
return lbs.updateMonitor(monitor);
else
return lbs.createMonitor(monitor);
}
@Delete
public int removeMonitor() {
String monitorId = (String) getRequestAttributes().get("monitor");
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
return lbs.removeMonitor(monitorId);
}
protected LBMonitor jsonToMonitor(String json) throws IOException {
MappingJsonFactory f = new MappingJsonFactory();
JsonParser jp;
LBMonitor monitor = new LBMonitor();
try {
jp = f.createJsonParser(json);
} catch (JsonParseException e) {
throw new IOException(e);
}
jp.nextToken();
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw new IOException("Expected START_OBJECT");
}
while (jp.nextToken() != JsonToken.END_OBJECT) {
if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
throw new IOException("Expected FIELD_NAME");
}
String n = jp.getCurrentName();
jp.nextToken();
if (jp.getText().equals(""))
continue;
else if (n.equals("monitor")) {
while (jp.nextToken() != JsonToken.END_OBJECT) {
String field = jp.getCurrentName();
if (field.equals("id")) {
monitor.id = jp.getText();
continue;
}
if (field.equals("name")) {
monitor.name = jp.getText();
continue;
}
if (field.equals("type")) {
monitor.type = Short.parseShort(jp.getText());
continue;
}
if (field.equals("delay")) {
monitor.delay = Short.parseShort(jp.getText());
continue;
}
if (field.equals("timeout")) {
monitor.timeout = Short.parseShort(jp.getText());
continue;
}
if (field.equals("attempts_before_deactivation")) {
monitor.attemptsBeforeDeactivation = Short.parseShort(jp.getText());
continue;
}
if (field.equals("network_id")) {
monitor.netId = jp.getText();
continue;
}
if (field.equals("address")) {
monitor.address = Integer.parseInt(jp.getText());
continue;
}
if (field.equals("protocol")) {
monitor.protocol = Byte.parseByte(jp.getText());
continue;
}
if (field.equals("port")) {
monitor.port = Short.parseShort(jp.getText());
continue;
}
if (field.equals("admin_state")) {
monitor.adminState = Short.parseShort(jp.getText());
continue;
}
if (field.equals("status")) {
monitor.status = Short.parseShort(jp.getText());
continue;
}
log.warn("Unrecognized field {} in " +
"parsing Vips",
jp.getText());
}
}
}
jp.close();
return monitor;
}
}
package net.floodlightcontroller.loadbalancer;
import java.util.Collection;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PoolMemberResource extends ServerResource {
protected static Logger log = LoggerFactory.getLogger(PoolMemberResource.class);
@Get("json")
public Collection <LBMember> retrieve() {
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
String poolId = (String) getRequestAttributes().get("pool");
if (poolId!=null)
return lbs.listMembersByPool(poolId);
else
return null;
}
}
package net.floodlightcontroller.loadbalancer;
import java.io.IOException;
import java.util.Collection;
import net.floodlightcontroller.packet.IPv4;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.MappingJsonFactory;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PoolsResource extends ServerResource {
protected static Logger log = LoggerFactory.getLogger(PoolsResource.class);
@Get("json")
public Collection <LBPool> retrieve() {
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
String poolId = (String) getRequestAttributes().get("pool");
if (poolId!=null)
return lbs.listPool(poolId);
else
return lbs.listPools();
}
@Put
@Post
public LBPool createPool(String postData) {
LBPool pool=null;
try {
pool=jsonToPool(postData);
} catch (IOException e) {
log.error("Could not parse JSON {}", e.getMessage());
}
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
String poolId = (String) getRequestAttributes().get("pool");
if (poolId != null)
return lbs.updatePool(pool);
else
return lbs.createPool(pool);
}
@Delete
public int removePool() {
String poolId = (String) getRequestAttributes().get("pool");
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
return lbs.removePool(poolId);
}
protected LBPool jsonToPool(String json) throws IOException {
if (json==null) return null;
MappingJsonFactory f = new MappingJsonFactory();
JsonParser jp;
LBPool pool = new LBPool();
try {
jp = f.createJsonParser(json);
} catch (JsonParseException e) {
throw new IOException(e);
}
jp.nextToken();
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw new IOException("Expected START_OBJECT");
}
while (jp.nextToken() != JsonToken.END_OBJECT) {
if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
throw new IOException("Expected FIELD_NAME");
}
String n = jp.getCurrentName();
jp.nextToken();
if (jp.getText().equals(""))
continue;
if (n.equals("id")) {
pool.id = jp.getText();
continue;
}
if (n.equals("tenant_id")) {
pool.tenantId = jp.getText();
continue;
}
if (n.equals("name")) {
pool.name = jp.getText();
continue;
}
if (n.equals("network_id")) {
pool.netId = jp.getText();
continue;
}
if (n.equals("lb_method")) {
pool.lbMethod = Short.parseShort(jp.getText());
continue;
}
if (n.equals("protocol")) {
String tmp = jp.getText();
if (tmp.equalsIgnoreCase("TCP")) {
pool.protocol = IPv4.PROTOCOL_TCP;
} else if (tmp.equalsIgnoreCase("UDP")) {
pool.protocol = IPv4.PROTOCOL_UDP;
} else if (tmp.equalsIgnoreCase("ICMP")) {
pool.protocol = IPv4.PROTOCOL_ICMP;
}
continue;
}
if (n.equals("vip_id")) {
pool.vipId = jp.getText();
continue;
}
log.warn("Unrecognized field {} in " +
"parsing Pools",
jp.getText());
}
jp.close();
return pool;
}
}
package net.floodlightcontroller.loadbalancer;
import java.io.IOException;
import java.util.Collection;
import net.floodlightcontroller.packet.IPv4;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.MappingJsonFactory;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class VipsResource extends ServerResource {
protected static Logger log = LoggerFactory.getLogger(VipsResource.class);
@Get("json")
public Collection <LBVip> retrieve() {
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
String vipId = (String) getRequestAttributes().get("vip");
if (vipId!=null)
return lbs.listVip(vipId);
else
return lbs.listVips();
}
@Put
@Post
public LBVip createVip(String postData) {
LBVip vip=null;
try {
vip=jsonToVip(postData);
} catch (IOException e) {
log.error("Could not parse JSON {}", e.getMessage());
}
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
String vipId = (String) getRequestAttributes().get("vip");
if (vipId != null)
return lbs.updateVip(vip);
else
return lbs.createVip(vip);
}
@Delete
public int removeVip() {
String vipId = (String) getRequestAttributes().get("vip");
ILoadBalancerService lbs =
(ILoadBalancerService)getContext().getAttributes().
get(ILoadBalancerService.class.getCanonicalName());
return lbs.removeVip(vipId);
}
protected LBVip jsonToVip(String json) throws IOException {
if (json==null) return null;
MappingJsonFactory f = new MappingJsonFactory();
JsonParser jp;
LBVip vip = new LBVip();
try {
jp = f.createJsonParser(json);
} catch (JsonParseException e) {
throw new IOException(e);
}
jp.nextToken();
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw new IOException("Expected START_OBJECT");
}
while (jp.nextToken() != JsonToken.END_OBJECT) {
if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
throw new IOException("Expected FIELD_NAME");
}
String n = jp.getCurrentName();
jp.nextToken();
if (jp.getText().equals(""))
continue;
if (n.equals("id")) {
vip.id = jp.getText();
continue;
}
if (n.equals("tenant_id")) {
vip.tenantId = jp.getText();
continue;
}
if (n.equals("name")) {
vip.name = jp.getText();
continue;
}
if (n.equals("network_id")) {
vip.netId = jp.getText();
continue;
}
if (n.equals("protocol")) {
String tmp = jp.getText();
if (tmp.equalsIgnoreCase("TCP")) {
vip.protocol = IPv4.PROTOCOL_TCP;
} else if (tmp.equalsIgnoreCase("UDP")) {
vip.protocol = IPv4.PROTOCOL_UDP;
} else if (tmp.equalsIgnoreCase("ICMP")) {
vip.protocol = IPv4.PROTOCOL_ICMP;
}
continue;
}
if (n.equals("address")) {
vip.address = IPv4.toIPv4Address(jp.getText());
continue;
}
if (n.equals("port")) {
vip.port = Short.parseShort(jp.getText());
continue;
}
if (n.equals("pool_id")) {
vip.pools.add(jp.getText());
continue;
}
log.warn("Unrecognized field {} in " +
"parsing Vips",
jp.getText());
}
jp.close();
return vip;
}
}
......@@ -41,6 +41,10 @@ public interface ITopologyService extends IFloodlightService {
public boolean inSameOpenflowDomain(long switch1, long switch2,
boolean tunnelEnabled);
public Set<Long> getSwitchesInOpenflowDomain(long switchDPID);
public Set<Long> getSwitchesInOpenflowDomain(long switchDPID,
boolean tunnelEnabled);
/**
* Queries whether two switches are in the same island.
* Currently, island and cluster are the same. In future,
......
......@@ -727,7 +727,13 @@ public class TopologyInstance {
protected Set<Long> getSwitchesInOpenflowDomain(long switchId) {
Cluster c = switchClusterMap.get(switchId);
if (c == null) return null;
if (c == null) {
// The switch is not known to topology as there
// are no links connected to it.
Set<Long> nodes = new HashSet<Long>();
nodes.add(switchId);
return nodes;
}
return (c.getNodes());
}
......
......@@ -377,7 +377,8 @@ public class TopologyManager implements
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/**
* Checks if the switchport is a broadcast domain port or not.
*/
......@@ -393,7 +394,8 @@ public class TopologyManager implements
return ti.isBroadcastDomainPort(new NodePortTuple(sw, port));
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/**
* Checks if the new attachment point port is consistent with the
* old attachment point port.
......@@ -467,6 +469,22 @@ public class TopologyManager implements
return ti.getAllowedIncomingBroadcastPort(src,srcPort);
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
@Override
public Set<Long> getSwitchesInOpenflowDomain(long switchDPID) {
return getSwitchesInOpenflowDomain(switchDPID, true);
}
@Override
public Set<Long> getSwitchesInOpenflowDomain(long switchDPID,
boolean tunnelEnabled) {
TopologyInstance ti = getCurrentInstance(tunnelEnabled);
return ti.getSwitchesInOpenflowDomain(switchDPID);
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
@Override
public Set<NodePortTuple> getBroadcastDomainPorts() {
return portBroadcastDomainLinks.keySet();
......
......@@ -23,4 +23,5 @@ net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier
net.floodlightcontroller.devicemanager.test.MockDeviceManager
net.floodlightcontroller.core.test.MockFloodlightProvider
net.floodlightcontroller.core.test.MockThreadPoolService
net.floodlightcontroller.firewall.Firewall
\ No newline at end of file
net.floodlightcontroller.firewall.Firewall
net.floodlightcontroller.loadbalancer.LoadBalancer
\ No newline at end of file
......@@ -13,7 +13,8 @@ net.floodlightcontroller.flowcache.FlowReconcileManager, \
net.floodlightcontroller.jython.JythonDebugInterface,\
net.floodlightcontroller.counter.CounterStore,\
net.floodlightcontroller.perfmon.PktInProcessingTime,\
net.floodlightcontroller.ui.web.StaticWebRoutable
net.floodlightcontroller.ui.web.StaticWebRoutable,\
net.floodlightcontroller.loadbalancer.LoadBalancer
net.floodlightcontroller.restserver.RestApiServer.port = 8080
net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
net.floodlightcontroller.jython.JythonDebugInterface.port = 6655
......
......@@ -80,6 +80,7 @@ import org.junit.Test;
import org.openflow.protocol.OFPacketIn;
import org.openflow.protocol.OFPacketIn.OFPacketInReason;
import org.openflow.protocol.OFPhysicalPort;
import org.openflow.protocol.OFPort;
import org.openflow.protocol.OFType;
import org.openflow.util.HexString;
import org.slf4j.Logger;
......@@ -868,6 +869,73 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 2) }, aps);
}
/**
* This test verifies that the learning behavior on OFPP_LOCAL ports.
* Once a host is learned on OFPP_LOCAL, it is allowed to move only from
* one OFPP_LOCAL to another OFPP_LOCAL port.
* @throws Exception
*/
@Test
public void testLOCALAttachmentPointLearning() throws Exception {
ITopologyService mockTopology = createMock(ITopologyService.class);
expect(mockTopology.getL2DomainId(anyLong())).
andReturn(1L).anyTimes();
expect(mockTopology.isAttachmentPointPort(anyLong(), anyShort())).
andReturn(true).anyTimes();
expect(mockTopology.isBroadcastDomainPort(1L, (short)1)).
andReturn(false).anyTimes();
expect(mockTopology.isBroadcastDomainPort(1L, OFPort.OFPP_LOCAL.getValue())).
andReturn(false).anyTimes();
expect(mockTopology.isBroadcastDomainPort(1L, (short)2)).
andReturn(true).anyTimes();
expect(mockTopology.isInSameBroadcastDomain(1L, (short)1,
1L, OFPort.OFPP_LOCAL.getValue())).andReturn(true).anyTimes();
expect(mockTopology.isInSameBroadcastDomain(1L, OFPort.OFPP_LOCAL.getValue(),
1L, (short)2)).andReturn(true).anyTimes();
expect(mockTopology.isInSameBroadcastDomain(1L, (short)2,
1L, OFPort.OFPP_LOCAL.getValue())).andReturn(true).anyTimes();
expect(mockTopology.isConsistent(anyLong(), anyShort(), anyLong(), anyShort())).andReturn(false).anyTimes();
Date topologyUpdateTime = new Date();
expect(mockTopology.getLastUpdateTime()).andReturn(topologyUpdateTime).
anyTimes();
replay(mockTopology);
deviceManager.topology = mockTopology;
Calendar c = Calendar.getInstance();
Entity entity1 = new Entity(1L, null, 1, 1L, 1, c.getTime());
c.add(Calendar.MILLISECOND,
(int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT/ 2);
Entity entity2 = new Entity(1L, null, null, 1L, (int)OFPort.OFPP_LOCAL.getValue(), c.getTime());
c.add(Calendar.MILLISECOND,
(int)AttachmentPoint.OPENFLOW_TO_EXTERNAL_TIMEOUT + 1);
Entity entity3 = new Entity(1L, null, null, 1L, 2, c.getTime());
IDevice d;
SwitchPort[] aps;
d = deviceManager.learnDeviceByEntity(entity1);
assertEquals(1, deviceManager.getAllDevices().size());
aps = d.getAttachmentPoints();
assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, 1) }, aps);
// Ensure that the attachment point changes to OFPP_LOCAL
d = deviceManager.learnDeviceByEntity(entity2);
assertEquals(1, deviceManager.getAllDevices().size());
aps = d.getAttachmentPoints();
assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, OFPort.OFPP_LOCAL.getValue()) }, aps);
// Even though the new attachment point is consistent with old
// and the time has elapsed, OFPP_LOCAL attachment point should
// be maintained.
d = deviceManager.learnDeviceByEntity(entity3);
assertEquals(1, deviceManager.getAllDevices().size());
aps = d.getAttachmentPoints();
assertArrayEquals(new SwitchPort[] { new SwitchPort(1L, OFPort.OFPP_LOCAL.getValue()) }, aps);
}
@Test
public void testPacketIn() throws Exception {
......
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