blob: 8e5037873384d30894de1d4ba6080443c734d439 [file] [log] [blame]
alshabib7911a052014-10-16 17:49:37 -07001package org.onlab.onos.provider.lldp.impl;
2
3import org.apache.felix.scr.annotations.Activate;
4import org.apache.felix.scr.annotations.Component;
5import org.apache.felix.scr.annotations.Deactivate;
6import org.apache.felix.scr.annotations.Reference;
7import org.apache.felix.scr.annotations.ReferenceCardinality;
alshabib875d6262014-10-17 16:19:40 -07008import org.onlab.onos.mastership.MastershipService;
alshabib7911a052014-10-16 17:49:37 -07009import org.onlab.onos.net.ConnectPoint;
10import org.onlab.onos.net.Device;
11import org.onlab.onos.net.DeviceId;
alshabibacd91832014-10-17 14:38:41 -070012import org.onlab.onos.net.Port;
alshabib7911a052014-10-16 17:49:37 -070013import org.onlab.onos.net.device.DeviceEvent;
14import org.onlab.onos.net.device.DeviceListener;
15import org.onlab.onos.net.device.DeviceService;
16import org.onlab.onos.net.link.LinkProvider;
17import org.onlab.onos.net.link.LinkProviderRegistry;
18import org.onlab.onos.net.link.LinkProviderService;
19import org.onlab.onos.net.packet.PacketContext;
20import org.onlab.onos.net.packet.PacketProcessor;
21import org.onlab.onos.net.packet.PacketService;
22import org.onlab.onos.net.provider.AbstractProvider;
23import org.onlab.onos.net.provider.ProviderId;
24import org.slf4j.Logger;
25
26import java.util.Map;
27import java.util.concurrent.ConcurrentHashMap;
28
29import static org.slf4j.LoggerFactory.getLogger;
30
31
32/**
33 * Provider which uses an OpenFlow controller to detect network
34 * infrastructure links.
35 */
36@Component(immediate = true)
37public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
38
39 private final Logger log = getLogger(getClass());
40
41 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
42 protected LinkProviderRegistry providerRegistry;
43
44 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 protected DeviceService deviceService;
46
47 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
48 protected PacketService packetSevice;
49
alshabib875d6262014-10-17 16:19:40 -070050 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 protected MastershipService masterService;
52
alshabib7911a052014-10-16 17:49:37 -070053 private LinkProviderService providerService;
54
55 private final boolean useBDDP = true;
56
57
58 private final InternalLinkProvider listener = new InternalLinkProvider();
59
60 protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
61
62 /**
63 * Creates an OpenFlow link provider.
64 */
65 public LLDPLinkProvider() {
66 super(new ProviderId("lldp", "org.onlab.onos.provider.lldp"));
67 }
68
69 @Activate
70 public void activate() {
71 providerService = providerRegistry.register(this);
72 deviceService.addListener(listener);
73 packetSevice.addProcessor(listener, 0);
alshabibdfc7afb2014-10-21 20:13:27 -070074 LinkDiscovery ld;
75 for (Device device : deviceService.getDevices()) {
76 ld = new LinkDiscovery(device, packetSevice, masterService,
77 providerService, useBDDP);
78 discoverers.put(device.id(), ld);
79 for (Port p : deviceService.getPorts(device.id())) {
Yuta HIGUCHI00b476f2014-10-25 21:33:07 -070080 if (!p.number().isLogical()) {
81 ld.addPort(p);
82 }
alshabibdfc7afb2014-10-21 20:13:27 -070083 }
84 }
alshabib7911a052014-10-16 17:49:37 -070085
86 log.info("Started");
87 }
88
89 @Deactivate
90 public void deactivate() {
91 for (LinkDiscovery ld : discoverers.values()) {
92 ld.stop();
93 }
94 providerRegistry.unregister(this);
95 deviceService.removeListener(listener);
96 packetSevice.removeProcessor(listener);
97 providerService = null;
98
99 log.info("Stopped");
100 }
101
102
103 private class InternalLinkProvider implements PacketProcessor, DeviceListener {
104
105 @Override
106 public void event(DeviceEvent event) {
107 LinkDiscovery ld = null;
108 Device device = event.subject();
alshabibacd91832014-10-17 14:38:41 -0700109 Port port = event.port();
alshabibdfc7afb2014-10-21 20:13:27 -0700110 if (device == null) {
111 log.error("Device is null.");
112 return;
113 }
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700114 log.trace("{} {} {}", event.type(), event.subject(), event);
alshabib7911a052014-10-16 17:49:37 -0700115 switch (event.type()) {
116 case DEVICE_ADDED:
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700117 case DEVICE_UPDATED:
118 ld = discoverers.get(device.id());
119 if (ld == null) {
120 log.debug("Device added ({}) {}", event.type(), device.id());
121 discoverers.put(device.id(),
122 new LinkDiscovery(device, packetSevice, masterService,
123 providerService, useBDDP));
124 } else {
125 if (ld.isStopped()) {
126 log.debug("Device restarted ({}) {}", event.type(), device.id());
127 ld.start();
128 }
129 }
alshabib7911a052014-10-16 17:49:37 -0700130 break;
131 case PORT_ADDED:
132 case PORT_UPDATED:
133 if (event.port().isEnabled()) {
alshabibacd91832014-10-17 14:38:41 -0700134 ld = discoverers.get(device.id());
alshabib7911a052014-10-16 17:49:37 -0700135 if (ld == null) {
136 return;
137 }
Yuta HIGUCHI00b476f2014-10-25 21:33:07 -0700138 if (!port.number().isLogical()) {
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700139 log.debug("Port added {}", port);
Yuta HIGUCHI00b476f2014-10-25 21:33:07 -0700140 ld.addPort(port);
141 }
alshabib7911a052014-10-16 17:49:37 -0700142 } else {
alshabibacd91832014-10-17 14:38:41 -0700143 ConnectPoint point = new ConnectPoint(device.id(),
144 port.number());
alshabib7911a052014-10-16 17:49:37 -0700145 providerService.linksVanished(point);
146 }
147 break;
148 case PORT_REMOVED:
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700149 log.debug("Port removed {}", port);
alshabibacd91832014-10-17 14:38:41 -0700150 ConnectPoint point = new ConnectPoint(device.id(),
151 port.number());
alshabib7911a052014-10-16 17:49:37 -0700152 providerService.linksVanished(point);
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700153 // TODO: Don't we need to removePort from ld?
alshabib7911a052014-10-16 17:49:37 -0700154 break;
155 case DEVICE_REMOVED:
156 case DEVICE_SUSPENDED:
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700157 log.debug("Device removed {}", device.id());
alshabibacd91832014-10-17 14:38:41 -0700158 ld = discoverers.get(device.id());
alshabib7911a052014-10-16 17:49:37 -0700159 if (ld == null) {
160 return;
161 }
162 ld.stop();
alshabibacd91832014-10-17 14:38:41 -0700163 providerService.linksVanished(device.id());
alshabib7911a052014-10-16 17:49:37 -0700164 break;
165 case DEVICE_AVAILABILITY_CHANGED:
alshabibacd91832014-10-17 14:38:41 -0700166 ld = discoverers.get(device.id());
alshabib7911a052014-10-16 17:49:37 -0700167 if (ld == null) {
168 return;
169 }
alshabibacd91832014-10-17 14:38:41 -0700170 if (deviceService.isAvailable(device.id())) {
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700171 log.debug("Device up {}", device.id());
alshabib7911a052014-10-16 17:49:37 -0700172 ld.start();
173 } else {
alshabibacd91832014-10-17 14:38:41 -0700174 providerService.linksVanished(device.id());
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700175 log.debug("Device down {}", device.id());
alshabib7911a052014-10-16 17:49:37 -0700176 ld.stop();
177 }
178 break;
alshabib7911a052014-10-16 17:49:37 -0700179 case DEVICE_MASTERSHIP_CHANGED:
alshabibdfc7afb2014-10-21 20:13:27 -0700180 if (!discoverers.containsKey(device.id())) {
Yuta HIGUCHIeb24e9d2014-10-26 19:34:20 -0700181 // TODO: ideally, should never reach here
182 log.debug("Device mastership changed ({}) {}", event.type(), device.id());
alshabibdfc7afb2014-10-21 20:13:27 -0700183 discoverers.put(device.id(),
184 new LinkDiscovery(device, packetSevice, masterService,
185 providerService, useBDDP));
186 }
alshabib7911a052014-10-16 17:49:37 -0700187 break;
188 default:
189 log.debug("Unknown event {}", event);
190 }
191 }
192
193 @Override
194 public void process(PacketContext context) {
alshabib4a179dc2014-10-17 17:17:01 -0700195 if (context == null) {
196 return;
197 }
alshabib7911a052014-10-16 17:49:37 -0700198 LinkDiscovery ld = discoverers.get(
199 context.inPacket().receivedFrom().deviceId());
200 if (ld == null) {
201 return;
202 }
203
204 if (ld.handleLLDP(context)) {
205 context.block();
206 }
207 }
208 }
209
210}