alshabib

initial mobility support

Change-Id: Idf42bd2f769b3c687c4acc18241e19970c6cd7e2
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
5 + <modelVersion>4.0.0</modelVersion>
6 +
7 + <parent>
8 + <groupId>org.onlab.onos</groupId>
9 + <artifactId>onos-apps</artifactId>
10 + <version>1.0.0-SNAPSHOT</version>
11 + <relativePath>../pom.xml</relativePath>
12 + </parent>
13 +
14 + <artifactId>onos-app-mobility</artifactId>
15 + <packaging>bundle</packaging>
16 +
17 + <description>ONOS simple Mobility app</description>
18 +
19 +</project>
1 +package org.onlab.onos.mobility;
2 +import static org.slf4j.LoggerFactory.getLogger;
3 +
4 +import java.util.Collection;
5 +import java.util.List;
6 +
7 +import org.apache.felix.scr.annotations.Activate;
8 +import org.apache.felix.scr.annotations.Component;
9 +import org.apache.felix.scr.annotations.Deactivate;
10 +import org.apache.felix.scr.annotations.Reference;
11 +import org.apache.felix.scr.annotations.ReferenceCardinality;
12 +import org.onlab.onos.ApplicationId;
13 +import org.onlab.onos.net.Device;
14 +import org.onlab.onos.net.Host;
15 +import org.onlab.onos.net.device.DeviceService;
16 +import org.onlab.onos.net.flow.FlowRule;
17 +import org.onlab.onos.net.flow.FlowRuleService;
18 +import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
19 +import org.onlab.onos.net.flow.criteria.Criterion;
20 +import org.onlab.onos.net.flow.criteria.Criterion.Type;
21 +import org.onlab.onos.net.host.HostEvent;
22 +import org.onlab.onos.net.host.HostListener;
23 +import org.onlab.onos.net.host.HostService;
24 +import org.onlab.packet.MacAddress;
25 +import org.slf4j.Logger;
26 +
27 +import com.google.common.collect.Lists;
28 +
29 +
30 +/**
31 + * Sample reactive forwarding application.
32 + */
33 +@Component(immediate = true)
34 +public class HostMobility {
35 +
36 + private final Logger log = getLogger(getClass());
37 +
38 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
39 + protected HostService hostService;
40 +
41 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
42 + protected FlowRuleService flowRuleService;
43 +
44 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 + protected DeviceService deviceService;
46 +
47 + private ApplicationId appId;
48 +
49 + @Activate
50 + public void activate() {
51 + appId = ApplicationId.getAppId();
52 + hostService.addListener(new InternalHostListener());
53 + log.info("Started with Application ID {}", appId.id());
54 + }
55 +
56 + @Deactivate
57 + public void deactivate() {
58 + flowRuleService.removeFlowRulesById(appId);
59 + log.info("Stopped");
60 + }
61 +
62 + public class InternalHostListener
63 + implements HostListener {
64 +
65 + @Override
66 + public void event(HostEvent event) {
67 + switch (event.type()) {
68 + case HOST_ADDED:
69 + case HOST_REMOVED:
70 + case HOST_UPDATED:
71 + // don't care if a host has been added, removed.
72 + break;
73 + case HOST_MOVED:
74 + log.info("Host {} has moved; cleaning up.", event.subject());
75 + cleanup(event.subject());
76 + break;
77 +
78 + default:
79 + break;
80 +
81 + }
82 +
83 + }
84 +
85 + private void cleanup(Host host) {
86 + Iterable<Device> devices = deviceService.getDevices();
87 + List<FlowRule> flowRules = Lists.newLinkedList();
88 + for (Device device : devices) {
89 + flowRules.addAll(cleanupDevice(device, host));
90 + }
91 + FlowRule[] flows = new FlowRule[flowRules.size()];
92 + flows = flowRules.toArray(flows);
93 + flowRuleService.removeFlowRules(flows);
94 + }
95 +
96 + private Collection<? extends FlowRule> cleanupDevice(Device device, Host host) {
97 + List<FlowRule> flowRules = Lists.newLinkedList();
98 + MacAddress mac = host.mac();
99 + for (FlowRule rule : flowRuleService.getFlowEntries(device.id())) {
100 + for (Criterion c : rule.selector().criteria()) {
101 + if (c.type() == Type.ETH_DST || c.type() == Type.ETH_SRC) {
102 + EthCriterion eth = (EthCriterion) c;
103 + if (eth.mac().equals(mac)) {
104 + flowRules.add(rule);
105 + break;
106 + }
107 + }
108 + }
109 + }
110 + //TODO: handle ip cleanup
111 + return flowRules;
112 + }
113 +
114 + }
115 +
116 +}
117 +
118 +
1 +/**
2 + * Trivial application that provides simple form of reactive forwarding.
3 + */
4 +package org.onlab.onos.mobility;
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 <module>tvue</module> 20 <module>tvue</module>
21 <module>fwd</module> 21 <module>fwd</module>
22 <module>foo</module> 22 <module>foo</module>
23 + <module>mobility</module>
23 </modules> 24 </modules>
24 25
25 <properties> 26 <properties>
......
...@@ -161,7 +161,7 @@ implements FlowRuleService, FlowRuleProviderRegistry { ...@@ -161,7 +161,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
161 switch (stored.state()) { 161 switch (stored.state()) {
162 case ADDED: 162 case ADDED:
163 case PENDING_ADD: 163 case PENDING_ADD:
164 - frp.applyFlowRule(flowRule); 164 + frp.applyFlowRule(stored);
165 break; 165 break;
166 case PENDING_REMOVE: 166 case PENDING_REMOVE:
167 case REMOVED: 167 case REMOVED:
......
...@@ -105,11 +105,9 @@ public class SimpleFlowRuleStore ...@@ -105,11 +105,9 @@ public class SimpleFlowRuleStore
105 */ 105 */
106 106
107 if (flowEntries.containsEntry(did, f)) { 107 if (flowEntries.containsEntry(did, f)) {
108 - //synchronized (flowEntries) {
109 flowEntries.remove(did, f); 108 flowEntries.remove(did, f);
110 flowEntries.put(did, f); 109 flowEntries.put(did, f);
111 flowEntriesById.remove(rule.appId(), rule); 110 flowEntriesById.remove(rule.appId(), rule);
112 - //}
113 } 111 }
114 } 112 }
115 113
......
...@@ -116,6 +116,14 @@ ...@@ -116,6 +116,14 @@
116 <bundle>mvn:org.onlab.onos/onos-app-fwd/1.0.0-SNAPSHOT</bundle> 116 <bundle>mvn:org.onlab.onos/onos-app-fwd/1.0.0-SNAPSHOT</bundle>
117 </feature> 117 </feature>
118 118
119 + <feature name="onos-app-mobility" version="1.0.0"
120 + description="ONOS sample forwarding application">
121 + <feature>onos-api</feature>
122 + <bundle>mvn:org.onlab.onos/onos-app-mobility/1.0.0-SNAPSHOT</bundle>
123 + </feature>
124 +
125 +
126 +
119 <feature name="onos-app-foo" version="1.0.0" 127 <feature name="onos-app-foo" version="1.0.0"
120 description="ONOS sample playground application"> 128 description="ONOS sample playground application">
121 <feature>onos-api</feature> 129 <feature>onos-api</feature>
......
...@@ -93,7 +93,7 @@ public class FlowModBuilder { ...@@ -93,7 +93,7 @@ public class FlowModBuilder {
93 OFFlowMod fm = factory.buildFlowDelete() 93 OFFlowMod fm = factory.buildFlowDelete()
94 .setCookie(U64.of(cookie.value())) 94 .setCookie(U64.of(cookie.value()))
95 .setBufferId(OFBufferId.NO_BUFFER) 95 .setBufferId(OFBufferId.NO_BUFFER)
96 - .setActions(actions) 96 + //.setActions(actions)
97 .setMatch(match) 97 .setMatch(match)
98 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 98 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
99 .setPriority(priority) 99 .setPriority(priority)
...@@ -104,6 +104,9 @@ public class FlowModBuilder { ...@@ -104,6 +104,9 @@ public class FlowModBuilder {
104 104
105 private List<OFAction> buildActions() { 105 private List<OFAction> buildActions() {
106 List<OFAction> acts = new LinkedList<>(); 106 List<OFAction> acts = new LinkedList<>();
107 + if (treatment == null) {
108 + return acts;
109 + }
107 for (Instruction i : treatment.instructions()) { 110 for (Instruction i : treatment.instructions()) {
108 switch (i.type()) { 111 switch (i.type()) {
109 case DROP: 112 case DROP:
......
...@@ -106,10 +106,6 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr ...@@ -106,10 +106,6 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr
106 for (Instruction inst : packet.treatment().instructions()) { 106 for (Instruction inst : packet.treatment().instructions()) {
107 if (inst.type().equals(Instruction.Type.OUTPUT)) { 107 if (inst.type().equals(Instruction.Type.OUTPUT)) {
108 p = portDesc(((OutputInstruction) inst).port()); 108 p = portDesc(((OutputInstruction) inst).port());
109 - /*if (!sw.getPorts().contains(p)) {
110 - log.warn("Tried to write out non-existent port {}", p.getPortNo());
111 - continue;
112 - }*/
113 OFPacketOut po = packetOut(sw, eth, p.getPortNo()); 109 OFPacketOut po = packetOut(sw, eth, p.getPortNo());
114 sw.sendMsg(po); 110 sw.sendMsg(po);
115 } 111 }
......