blob: 7958f993bef5d1e7673c2764f37cc7b2443730b3 [file] [log] [blame]
alshabib4906fab2014-09-29 23:58:12 -07001package org.onlab.onos.mobility;
2import static org.slf4j.LoggerFactory.getLogger;
3
4import java.util.Collection;
5import java.util.List;
6
7import org.apache.felix.scr.annotations.Activate;
8import org.apache.felix.scr.annotations.Component;
9import org.apache.felix.scr.annotations.Deactivate;
10import org.apache.felix.scr.annotations.Reference;
11import org.apache.felix.scr.annotations.ReferenceCardinality;
12import org.onlab.onos.ApplicationId;
13import org.onlab.onos.net.Device;
14import org.onlab.onos.net.Host;
15import org.onlab.onos.net.device.DeviceService;
16import org.onlab.onos.net.flow.FlowRule;
17import org.onlab.onos.net.flow.FlowRuleService;
18import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
19import org.onlab.onos.net.flow.criteria.Criterion;
20import org.onlab.onos.net.flow.criteria.Criterion.Type;
21import org.onlab.onos.net.host.HostEvent;
22import org.onlab.onos.net.host.HostListener;
23import org.onlab.onos.net.host.HostService;
24import org.onlab.packet.MacAddress;
25import org.slf4j.Logger;
26
27import com.google.common.collect.Lists;
28
29
30/**
alshabib0ff17ad2014-09-30 09:46:40 -070031 * Sample mobility application. Cleans up flowmods when a host moves.
alshabib4906fab2014-09-29 23:58:12 -070032 */
33@Component(immediate = true)
34public 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
alshabib0ff17ad2014-09-30 09:46:40 -070085 /**
86 * For a given host, remove any flow rule which references it's addresses.
87 * @param host the host to clean up for
88 */
alshabib4906fab2014-09-29 23:58:12 -070089 private void cleanup(Host host) {
90 Iterable<Device> devices = deviceService.getDevices();
91 List<FlowRule> flowRules = Lists.newLinkedList();
92 for (Device device : devices) {
93 flowRules.addAll(cleanupDevice(device, host));
94 }
95 FlowRule[] flows = new FlowRule[flowRules.size()];
96 flows = flowRules.toArray(flows);
97 flowRuleService.removeFlowRules(flows);
98 }
99
100 private Collection<? extends FlowRule> cleanupDevice(Device device, Host host) {
101 List<FlowRule> flowRules = Lists.newLinkedList();
102 MacAddress mac = host.mac();
103 for (FlowRule rule : flowRuleService.getFlowEntries(device.id())) {
104 for (Criterion c : rule.selector().criteria()) {
105 if (c.type() == Type.ETH_DST || c.type() == Type.ETH_SRC) {
106 EthCriterion eth = (EthCriterion) c;
107 if (eth.mac().equals(mac)) {
108 flowRules.add(rule);
alshabib4906fab2014-09-29 23:58:12 -0700109 }
110 }
111 }
112 }
113 //TODO: handle ip cleanup
114 return flowRules;
115 }
116
117 }
118
119}
120
121