alshabib

initial mobility support

Change-Id: Idf42bd2f769b3c687c4acc18241e19970c6cd7e2
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.onlab.onos</groupId>
<artifactId>onos-apps</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>onos-app-mobility</artifactId>
<packaging>bundle</packaging>
<description>ONOS simple Mobility app</description>
</project>
package org.onlab.onos.mobility;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Collection;
import java.util.List;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleService;
import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
import org.onlab.onos.net.flow.criteria.Criterion;
import org.onlab.onos.net.flow.criteria.Criterion.Type;
import org.onlab.onos.net.host.HostEvent;
import org.onlab.onos.net.host.HostListener;
import org.onlab.onos.net.host.HostService;
import org.onlab.packet.MacAddress;
import org.slf4j.Logger;
import com.google.common.collect.Lists;
/**
* Sample reactive forwarding application.
*/
@Component(immediate = true)
public class HostMobility {
private final Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostService hostService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
private ApplicationId appId;
@Activate
public void activate() {
appId = ApplicationId.getAppId();
hostService.addListener(new InternalHostListener());
log.info("Started with Application ID {}", appId.id());
}
@Deactivate
public void deactivate() {
flowRuleService.removeFlowRulesById(appId);
log.info("Stopped");
}
public class InternalHostListener
implements HostListener {
@Override
public void event(HostEvent event) {
switch (event.type()) {
case HOST_ADDED:
case HOST_REMOVED:
case HOST_UPDATED:
// don't care if a host has been added, removed.
break;
case HOST_MOVED:
log.info("Host {} has moved; cleaning up.", event.subject());
cleanup(event.subject());
break;
default:
break;
}
}
private void cleanup(Host host) {
Iterable<Device> devices = deviceService.getDevices();
List<FlowRule> flowRules = Lists.newLinkedList();
for (Device device : devices) {
flowRules.addAll(cleanupDevice(device, host));
}
FlowRule[] flows = new FlowRule[flowRules.size()];
flows = flowRules.toArray(flows);
flowRuleService.removeFlowRules(flows);
}
private Collection<? extends FlowRule> cleanupDevice(Device device, Host host) {
List<FlowRule> flowRules = Lists.newLinkedList();
MacAddress mac = host.mac();
for (FlowRule rule : flowRuleService.getFlowEntries(device.id())) {
for (Criterion c : rule.selector().criteria()) {
if (c.type() == Type.ETH_DST || c.type() == Type.ETH_SRC) {
EthCriterion eth = (EthCriterion) c;
if (eth.mac().equals(mac)) {
flowRules.add(rule);
break;
}
}
}
}
//TODO: handle ip cleanup
return flowRules;
}
}
}
/**
* Trivial application that provides simple form of reactive forwarding.
*/
package org.onlab.onos.mobility;
......@@ -20,6 +20,7 @@
<module>tvue</module>
<module>fwd</module>
<module>foo</module>
<module>mobility</module>
</modules>
<properties>
......
......@@ -161,7 +161,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
switch (stored.state()) {
case ADDED:
case PENDING_ADD:
frp.applyFlowRule(flowRule);
frp.applyFlowRule(stored);
break;
case PENDING_REMOVE:
case REMOVED:
......
......@@ -105,11 +105,9 @@ public class SimpleFlowRuleStore
*/
if (flowEntries.containsEntry(did, f)) {
//synchronized (flowEntries) {
flowEntries.remove(did, f);
flowEntries.put(did, f);
flowEntriesById.remove(rule.appId(), rule);
//}
}
}
......
......@@ -116,6 +116,14 @@
<bundle>mvn:org.onlab.onos/onos-app-fwd/1.0.0-SNAPSHOT</bundle>
</feature>
<feature name="onos-app-mobility" version="1.0.0"
description="ONOS sample forwarding application">
<feature>onos-api</feature>
<bundle>mvn:org.onlab.onos/onos-app-mobility/1.0.0-SNAPSHOT</bundle>
</feature>
<feature name="onos-app-foo" version="1.0.0"
description="ONOS sample playground application">
<feature>onos-api</feature>
......
......@@ -93,7 +93,7 @@ public class FlowModBuilder {
OFFlowMod fm = factory.buildFlowDelete()
.setCookie(U64.of(cookie.value()))
.setBufferId(OFBufferId.NO_BUFFER)
.setActions(actions)
//.setActions(actions)
.setMatch(match)
.setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
.setPriority(priority)
......@@ -104,6 +104,9 @@ public class FlowModBuilder {
private List<OFAction> buildActions() {
List<OFAction> acts = new LinkedList<>();
if (treatment == null) {
return acts;
}
for (Instruction i : treatment.instructions()) {
switch (i.type()) {
case DROP:
......
......@@ -106,10 +106,6 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr
for (Instruction inst : packet.treatment().instructions()) {
if (inst.type().equals(Instruction.Type.OUTPUT)) {
p = portDesc(((OutputInstruction) inst).port());
/*if (!sw.getPorts().contains(p)) {
log.warn("Tried to write out non-existent port {}", p.getPortNo());
continue;
}*/
OFPacketOut po = packetOut(sw, eth, p.getPortNo());
sw.sendMsg(po);
}
......