blob: a2bf045a923e7bb0ec499ad8ae37191ee0c0e16c [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;
tom8bf2e6b2014-09-10 20:53:54 -070026import org.onlab.util.Timer;
alshabibdf652ad2014-09-09 11:53:19 -070027import 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 }
alshabib505bc6b2014-09-09 15:04:13 -070090 if (ld.handleLLDP(pktCtx.unparsed(), pktCtx.inPort())) {
91 pktCtx.block();
92 }
alshabibc4901cd2014-09-05 16:50:40 -070093
94 }
95
alshabib289652c2014-09-07 19:09:28 -070096 @Override
97 public void switchAdded(Dpid dpid) {
alshabibdf652ad2014-09-09 11:53:19 -070098 discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid),
99 controller, providerService, useBDDP));
alshabib289652c2014-09-07 19:09:28 -0700100
101 }
102
103 @Override
104 public void switchRemoved(Dpid dpid) {
alshabibdf652ad2014-09-09 11:53:19 -0700105 LinkDiscovery ld = this.discoverers.remove(dpid);
106 if (ld != null) {
107 ld.removeAllPorts();
108 }
109 providerService.linksVanished(
110 DeviceId.deviceId("of:" + Long.toHexString(dpid.value())));
alshabib289652c2014-09-07 19:09:28 -0700111 }
112
113 @Override
114 public void portChanged(Dpid dpid, OFPortStatus status) {
alshabibdf652ad2014-09-09 11:53:19 -0700115 LinkDiscovery ld = discoverers.get(dpid);
116 if (ld == null) {
117 return;
118 }
119 final OFPortDesc port = status.getDesc();
120 final boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) &&
121 !port.getConfig().contains(OFPortConfig.PORT_DOWN);
122 if (enabled) {
123 ld.addPort(port);
124 } else {
125 ConnectPoint cp = new ConnectPoint(
126 DeviceId.deviceId("of:" + Long.toHexString(dpid.value())),
127 PortNumber.portNumber(port.getPortNo().getPortNumber()));
128 providerService.linksVanished(cp);
alshabiba159a322014-09-09 14:50:51 -0700129 ld.removePort(port);
alshabibdf652ad2014-09-09 11:53:19 -0700130 }
alshabib289652c2014-09-07 19:09:28 -0700131
132 }
133
alshabibc4901cd2014-09-05 16:50:40 -0700134 }
135
tome06f8552014-08-26 16:58:42 -0700136}