blob: 05719226a9a5c4d19bbd8ed9ff0a39800756e72f [file] [log] [blame]
tome06f8552014-08-26 16:58:42 -07001package org.onlab.onos.provider.of.link.impl;
2
alshabib63d5afe2014-09-15 09:40:24 -07003import static org.slf4j.LoggerFactory.getLogger;
4
5import java.util.Map;
6import java.util.concurrent.ConcurrentHashMap;
7
tome06f8552014-08-26 16:58:42 -07008import org.apache.felix.scr.annotations.Activate;
9import org.apache.felix.scr.annotations.Component;
10import org.apache.felix.scr.annotations.Deactivate;
11import org.apache.felix.scr.annotations.Reference;
12import org.apache.felix.scr.annotations.ReferenceCardinality;
alshabibdf652ad2014-09-09 11:53:19 -070013import org.onlab.onos.net.DeviceId;
tome06f8552014-08-26 16:58:42 -070014import org.onlab.onos.net.link.LinkProvider;
tom96dfcab2014-08-28 09:26:03 -070015import org.onlab.onos.net.link.LinkProviderRegistry;
tome06f8552014-08-26 16:58:42 -070016import org.onlab.onos.net.link.LinkProviderService;
17import org.onlab.onos.net.provider.AbstractProvider;
18import org.onlab.onos.net.provider.ProviderId;
tom9c94c5b2014-09-17 13:14:42 -070019import org.onlab.onos.openflow.controller.Dpid;
20import org.onlab.onos.openflow.controller.OpenFlowController;
21import org.onlab.onos.openflow.controller.OpenFlowPacketContext;
22import org.onlab.onos.openflow.controller.OpenFlowSwitch;
23import org.onlab.onos.openflow.controller.OpenFlowSwitchListener;
24import org.onlab.onos.openflow.controller.PacketListener;
alshabibdf652ad2014-09-09 11:53:19 -070025import org.projectfloodlight.openflow.protocol.OFPortConfig;
26import org.projectfloodlight.openflow.protocol.OFPortDesc;
27import org.projectfloodlight.openflow.protocol.OFPortState;
alshabib289652c2014-09-07 19:09:28 -070028import org.projectfloodlight.openflow.protocol.OFPortStatus;
tome06f8552014-08-26 16:58:42 -070029import org.slf4j.Logger;
tom5f38b3a2014-08-27 23:50:54 -070030
tome06f8552014-08-26 16:58:42 -070031/**
tomb1260e42014-08-26 18:39:57 -070032 * Provider which uses an OpenFlow controller to detect network
tome06f8552014-08-26 16:58:42 -070033 * infrastructure links.
34 */
tomb1260e42014-08-26 18:39:57 -070035@Component(immediate = true)
tome06f8552014-08-26 16:58:42 -070036public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvider {
37
tom5f38b3a2014-08-27 23:50:54 -070038 private final Logger log = getLogger(getClass());
tome06f8552014-08-26 16:58:42 -070039
40 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom96dfcab2014-08-28 09:26:03 -070041 protected LinkProviderRegistry providerRegistry;
tome06f8552014-08-26 16:58:42 -070042
tom5f38b3a2014-08-27 23:50:54 -070043 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
44 protected OpenFlowController controller;
tome06f8552014-08-26 16:58:42 -070045
tom5f38b3a2014-08-27 23:50:54 -070046 private LinkProviderService providerService;
tome06f8552014-08-26 16:58:42 -070047
alshabibdf652ad2014-09-09 11:53:19 -070048 private final boolean useBDDP = true;
49
alshabib289652c2014-09-07 19:09:28 -070050 private final InternalLinkProvider listener = new InternalLinkProvider();
alshabibc4901cd2014-09-05 16:50:40 -070051
alshabibc944fd02014-09-10 17:55:17 -070052 private final Map<Dpid, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
53
tome06f8552014-08-26 16:58:42 -070054 /**
55 * Creates an OpenFlow link provider.
56 */
57 public OpenFlowLinkProvider() {
tom7e02cda2014-09-18 12:05:46 -070058 super(new ProviderId("of", "org.onlab.onos.provider.openflow"));
tome06f8552014-08-26 16:58:42 -070059 }
60
61 @Activate
62 public void activate() {
tom96dfcab2014-08-28 09:26:03 -070063 providerService = providerRegistry.register(this);
alshabib289652c2014-09-07 19:09:28 -070064 controller.addListener(listener);
alshabibc4901cd2014-09-05 16:50:40 -070065 controller.addPacketListener(0, listener);
alshabibc944fd02014-09-10 17:55:17 -070066 for (OpenFlowSwitch sw : controller.getSwitches()) {
67 listener.switchAdded(new Dpid(sw.getId()));
68 }
tome06f8552014-08-26 16:58:42 -070069 log.info("Started");
70 }
71
72 @Deactivate
73 public void deactivate() {
alshabibc944fd02014-09-10 17:55:17 -070074 for (LinkDiscovery ld : discoverers.values()) {
75 ld.stop();
76 }
tom96dfcab2014-08-28 09:26:03 -070077 providerRegistry.unregister(this);
alshabib289652c2014-09-07 19:09:28 -070078 controller.removeListener(listener);
alshabibc4901cd2014-09-05 16:50:40 -070079 controller.removePacketListener(listener);
tome06f8552014-08-26 16:58:42 -070080 providerService = null;
alshabibc944fd02014-09-10 17:55:17 -070081
tome06f8552014-08-26 16:58:42 -070082 log.info("Stopped");
83 }
84
alshabibc4901cd2014-09-05 16:50:40 -070085
alshabib289652c2014-09-07 19:09:28 -070086 private class InternalLinkProvider implements PacketListener, OpenFlowSwitchListener {
alshabibc4901cd2014-09-05 16:50:40 -070087
alshabibdf652ad2014-09-09 11:53:19 -070088
alshabibc4901cd2014-09-05 16:50:40 -070089 @Override
alshabibe7031562014-09-12 18:17:37 -070090 public void handlePacket(OpenFlowPacketContext pktCtx) {
alshabibdf652ad2014-09-09 11:53:19 -070091 LinkDiscovery ld = discoverers.get(pktCtx.dpid());
92 if (ld == null) {
93 return;
94 }
alshabib505bc6b2014-09-09 15:04:13 -070095 if (ld.handleLLDP(pktCtx.unparsed(), pktCtx.inPort())) {
alshabib7b2748f2014-09-16 20:21:11 -070096 pktCtx.block();
alshabib505bc6b2014-09-09 15:04:13 -070097 }
alshabibc4901cd2014-09-05 16:50:40 -070098
99 }
100
alshabib289652c2014-09-07 19:09:28 -0700101 @Override
102 public void switchAdded(Dpid dpid) {
alshabibdf652ad2014-09-09 11:53:19 -0700103 discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid),
alshabib63d5afe2014-09-15 09:40:24 -0700104 controller, providerService, useBDDP));
alshabib289652c2014-09-07 19:09:28 -0700105
106 }
107
108 @Override
109 public void switchRemoved(Dpid dpid) {
alshabibc944fd02014-09-10 17:55:17 -0700110 LinkDiscovery ld = discoverers.remove(dpid);
alshabibdf652ad2014-09-09 11:53:19 -0700111 if (ld != null) {
112 ld.removeAllPorts();
113 }
114 providerService.linksVanished(
115 DeviceId.deviceId("of:" + Long.toHexString(dpid.value())));
alshabib289652c2014-09-07 19:09:28 -0700116 }
117
118 @Override
119 public void portChanged(Dpid dpid, OFPortStatus status) {
alshabibdf652ad2014-09-09 11:53:19 -0700120 LinkDiscovery ld = discoverers.get(dpid);
121 if (ld == null) {
122 return;
123 }
124 final OFPortDesc port = status.getDesc();
125 final boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) &&
126 !port.getConfig().contains(OFPortConfig.PORT_DOWN);
127 if (enabled) {
128 ld.addPort(port);
129 } else {
alshabibc944fd02014-09-10 17:55:17 -0700130 /*
131 * remove port calls linkVanished
132 */
alshabiba159a322014-09-09 14:50:51 -0700133 ld.removePort(port);
alshabibdf652ad2014-09-09 11:53:19 -0700134 }
alshabib289652c2014-09-07 19:09:28 -0700135
136 }
137
alshabibc4901cd2014-09-05 16:50:40 -0700138 }
139
tome06f8552014-08-26 16:58:42 -0700140}