blob: 737ef004d42e60ae30a677c5e5263990bcbb5502 [file] [log] [blame]
tome06f8552014-08-26 16:58:42 -07001package org.onlab.onos.provider.of.link.impl;
2
alshabibc4901cd2014-09-05 16:50:40 -07003import static org.slf4j.LoggerFactory.getLogger;
4
alshabibdf652ad2014-09-09 11:53:19 -07005import 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.ConnectPoint;
14import org.onlab.onos.net.DeviceId;
15import org.onlab.onos.net.PortNumber;
tome06f8552014-08-26 16:58:42 -070016import org.onlab.onos.net.link.LinkProvider;
tom96dfcab2014-08-28 09:26:03 -070017import org.onlab.onos.net.link.LinkProviderRegistry;
tome06f8552014-08-26 16:58:42 -070018import org.onlab.onos.net.link.LinkProviderService;
19import org.onlab.onos.net.provider.AbstractProvider;
20import org.onlab.onos.net.provider.ProviderId;
alshabib289652c2014-09-07 19:09:28 -070021import org.onlab.onos.of.controller.Dpid;
tom5f38b3a2014-08-27 23:50:54 -070022import org.onlab.onos.of.controller.OpenFlowController;
alshabib289652c2014-09-07 19:09:28 -070023import org.onlab.onos.of.controller.OpenFlowSwitchListener;
alshabibc4901cd2014-09-05 16:50:40 -070024import org.onlab.onos.of.controller.PacketContext;
25import org.onlab.onos.of.controller.PacketListener;
alshabibdf652ad2014-09-09 11:53:19 -070026import org.onlab.timer.Timer;
27import org.projectfloodlight.openflow.protocol.OFPortConfig;
28import org.projectfloodlight.openflow.protocol.OFPortDesc;
29import org.projectfloodlight.openflow.protocol.OFPortState;
alshabib289652c2014-09-07 19:09:28 -070030import org.projectfloodlight.openflow.protocol.OFPortStatus;
tome06f8552014-08-26 16:58:42 -070031import org.slf4j.Logger;
tom5f38b3a2014-08-27 23:50:54 -070032
tome06f8552014-08-26 16:58:42 -070033/**
tomb1260e42014-08-26 18:39:57 -070034 * Provider which uses an OpenFlow controller to detect network
tome06f8552014-08-26 16:58:42 -070035 * infrastructure links.
36 */
tomb1260e42014-08-26 18:39:57 -070037@Component(immediate = true)
tome06f8552014-08-26 16:58:42 -070038public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvider {
39
tom5f38b3a2014-08-27 23:50:54 -070040 private final Logger log = getLogger(getClass());
tome06f8552014-08-26 16:58:42 -070041
42 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom96dfcab2014-08-28 09:26:03 -070043 protected LinkProviderRegistry providerRegistry;
tome06f8552014-08-26 16:58:42 -070044
tom5f38b3a2014-08-27 23:50:54 -070045 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
46 protected OpenFlowController controller;
tome06f8552014-08-26 16:58:42 -070047
tom5f38b3a2014-08-27 23:50:54 -070048 private LinkProviderService providerService;
tome06f8552014-08-26 16:58:42 -070049
alshabibdf652ad2014-09-09 11:53:19 -070050 private final boolean useBDDP = true;
51
alshabib289652c2014-09-07 19:09:28 -070052 private final InternalLinkProvider listener = new InternalLinkProvider();
alshabibc4901cd2014-09-05 16:50:40 -070053
tome06f8552014-08-26 16:58:42 -070054 /**
55 * Creates an OpenFlow link provider.
56 */
57 public OpenFlowLinkProvider() {
58 super(new ProviderId("org.onlab.onos.provider.of.link"));
59 }
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);
tome06f8552014-08-26 16:58:42 -070066 log.info("Started");
67 }
68
69 @Deactivate
70 public void deactivate() {
tom96dfcab2014-08-28 09:26:03 -070071 providerRegistry.unregister(this);
alshabib289652c2014-09-07 19:09:28 -070072 controller.removeListener(listener);
alshabibc4901cd2014-09-05 16:50:40 -070073 controller.removePacketListener(listener);
tome06f8552014-08-26 16:58:42 -070074 providerService = null;
alshabibdf652ad2014-09-09 11:53:19 -070075 Timer.getTimer().stop();
tome06f8552014-08-26 16:58:42 -070076 log.info("Stopped");
77 }
78
alshabibc4901cd2014-09-05 16:50:40 -070079
alshabib289652c2014-09-07 19:09:28 -070080 private class InternalLinkProvider implements PacketListener, OpenFlowSwitchListener {
alshabibc4901cd2014-09-05 16:50:40 -070081
alshabibdf652ad2014-09-09 11:53:19 -070082 private final Map<Dpid, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
83
alshabibc4901cd2014-09-05 16:50:40 -070084 @Override
85 public void handlePacket(PacketContext pktCtx) {
alshabibdf652ad2014-09-09 11:53:19 -070086 LinkDiscovery ld = discoverers.get(pktCtx.dpid());
87 if (ld == null) {
88 return;
89 }
90 ld.handleLLDP(pktCtx.parsed(),
91 pktCtx.inPort());
alshabibc4901cd2014-09-05 16:50:40 -070092
93 }
94
alshabib289652c2014-09-07 19:09:28 -070095 @Override
96 public void switchAdded(Dpid dpid) {
alshabibdf652ad2014-09-09 11:53:19 -070097 discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid),
98 controller, providerService, useBDDP));
alshabib289652c2014-09-07 19:09:28 -070099
100 }
101
102 @Override
103 public void switchRemoved(Dpid dpid) {
alshabibdf652ad2014-09-09 11:53:19 -0700104 LinkDiscovery ld = this.discoverers.remove(dpid);
105 if (ld != null) {
106 ld.removeAllPorts();
107 }
108 providerService.linksVanished(
109 DeviceId.deviceId("of:" + Long.toHexString(dpid.value())));
alshabib289652c2014-09-07 19:09:28 -0700110 }
111
112 @Override
113 public void portChanged(Dpid dpid, OFPortStatus status) {
alshabibdf652ad2014-09-09 11:53:19 -0700114 LinkDiscovery ld = discoverers.get(dpid);
115 if (ld == null) {
116 return;
117 }
118 final OFPortDesc port = status.getDesc();
119 final boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) &&
120 !port.getConfig().contains(OFPortConfig.PORT_DOWN);
121 if (enabled) {
122 ld.addPort(port);
123 } else {
124 ConnectPoint cp = new ConnectPoint(
125 DeviceId.deviceId("of:" + Long.toHexString(dpid.value())),
126 PortNumber.portNumber(port.getPortNo().getPortNumber()));
127 providerService.linksVanished(cp);
128 ld.removePort(port.getPortNo());
129 }
alshabib289652c2014-09-07 19:09:28 -0700130
131 }
132
alshabibc4901cd2014-09-05 16:50:40 -0700133 }
134
tome06f8552014-08-26 16:58:42 -0700135}