blob: 023940ec55ba64622e7aef0f27d80105f583b2a8 [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;
8import org.onlab.onos.net.ConnectPoint;
9import org.onlab.onos.net.Device;
10import org.onlab.onos.net.DeviceId;
11import org.onlab.onos.net.device.DeviceEvent;
12import org.onlab.onos.net.device.DeviceListener;
13import org.onlab.onos.net.device.DeviceService;
14import org.onlab.onos.net.link.LinkProvider;
15import org.onlab.onos.net.link.LinkProviderRegistry;
16import org.onlab.onos.net.link.LinkProviderService;
17import org.onlab.onos.net.packet.PacketContext;
18import org.onlab.onos.net.packet.PacketProcessor;
19import org.onlab.onos.net.packet.PacketService;
20import org.onlab.onos.net.provider.AbstractProvider;
21import org.onlab.onos.net.provider.ProviderId;
22import org.slf4j.Logger;
23
24import java.util.Map;
25import java.util.concurrent.ConcurrentHashMap;
26
27import static org.slf4j.LoggerFactory.getLogger;
28
29
30/**
31 * Provider which uses an OpenFlow controller to detect network
32 * infrastructure links.
33 */
34@Component(immediate = true)
35public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
36
37 private final Logger log = getLogger(getClass());
38
39 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
40 protected LinkProviderRegistry providerRegistry;
41
42 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
43 protected DeviceService deviceService;
44
45 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
46 protected PacketService packetSevice;
47
48 private LinkProviderService providerService;
49
50 private final boolean useBDDP = true;
51
52
53 private final InternalLinkProvider listener = new InternalLinkProvider();
54
55 protected final Map<DeviceId, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
56
57 /**
58 * Creates an OpenFlow link provider.
59 */
60 public LLDPLinkProvider() {
61 super(new ProviderId("lldp", "org.onlab.onos.provider.lldp"));
62 }
63
64 @Activate
65 public void activate() {
66 providerService = providerRegistry.register(this);
67 deviceService.addListener(listener);
68 packetSevice.addProcessor(listener, 0);
69
70 log.info("Started");
71 }
72
73 @Deactivate
74 public void deactivate() {
75 for (LinkDiscovery ld : discoverers.values()) {
76 ld.stop();
77 }
78 providerRegistry.unregister(this);
79 deviceService.removeListener(listener);
80 packetSevice.removeProcessor(listener);
81 providerService = null;
82
83 log.info("Stopped");
84 }
85
86
87 private class InternalLinkProvider implements PacketProcessor, DeviceListener {
88
89 @Override
90 public void event(DeviceEvent event) {
91 LinkDiscovery ld = null;
92 Device device = event.subject();
93 // it's not a switch so leave.
94 if (device.type() != Device.Type.SWITCH) {
95 return;
96 }
97 switch (event.type()) {
98 case DEVICE_ADDED:
99 discoverers.put(event.subject().id(),
100 new LinkDiscovery(event.subject(), packetSevice,
101 providerService, useBDDP));
102 break;
103 case PORT_ADDED:
104 case PORT_UPDATED:
105 if (event.port().isEnabled()) {
106 ld = discoverers.get(event.subject().id());
107 if (ld == null) {
108 return;
109 }
110 ld.addPort(event.port());
111 } else {
112 ConnectPoint point = new ConnectPoint(event.subject().id(),
113 event.port().number());
114 providerService.linksVanished(point);
115 }
116 break;
117 case PORT_REMOVED:
118 ConnectPoint point = new ConnectPoint(event.subject().id(),
119 event.port().number());
120 providerService.linksVanished(point);
121 break;
122 case DEVICE_REMOVED:
123 case DEVICE_SUSPENDED:
124 ld = discoverers.get(event.subject().id());
125 if (ld == null) {
126 return;
127 }
128 ld.stop();
129 providerService.linksVanished(event.subject().id());
130 break;
131 case DEVICE_AVAILABILITY_CHANGED:
132 ld = discoverers.get(event.subject().id());
133 if (ld == null) {
134 return;
135 }
136 if (deviceService.isAvailable(event.subject().id())) {
137 ld.start();
138 } else {
139 providerService.linksVanished(event.subject().id());
140 ld.stop();
141 }
142 break;
143 case DEVICE_UPDATED:
144 case DEVICE_MASTERSHIP_CHANGED:
145 break;
146 default:
147 log.debug("Unknown event {}", event);
148 }
149 }
150
151 @Override
152 public void process(PacketContext context) {
153 LinkDiscovery ld = discoverers.get(
154 context.inPacket().receivedFrom().deviceId());
155 if (ld == null) {
156 return;
157 }
158
159 if (ld.handleLLDP(context)) {
160 context.block();
161 }
162 }
163 }
164
165}