blob: f1e38616ee620a52b89b8ab22c63bb57f956fe99 [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;
Ayaka Koshibeab91cc42014-09-25 10:20:52 -070025import org.onlab.onos.openflow.controller.RoleState;
alshabibdf652ad2014-09-09 11:53:19 -070026import org.projectfloodlight.openflow.protocol.OFPortConfig;
27import org.projectfloodlight.openflow.protocol.OFPortDesc;
28import org.projectfloodlight.openflow.protocol.OFPortState;
alshabib289652c2014-09-07 19:09:28 -070029import org.projectfloodlight.openflow.protocol.OFPortStatus;
tome06f8552014-08-26 16:58:42 -070030import org.slf4j.Logger;
tom5f38b3a2014-08-27 23:50:54 -070031
alshabib64231d82014-09-25 18:25:31 -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
alshabib64231d82014-09-25 18:25:31 -070054 protected final Map<Dpid, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
alshabibc944fd02014-09-10 17:55:17 -070055
tome06f8552014-08-26 16:58:42 -070056 /**
57 * Creates an OpenFlow link provider.
58 */
59 public OpenFlowLinkProvider() {
tom7e02cda2014-09-18 12:05:46 -070060 super(new ProviderId("of", "org.onlab.onos.provider.openflow"));
tome06f8552014-08-26 16:58:42 -070061 }
62
63 @Activate
64 public void activate() {
tom96dfcab2014-08-28 09:26:03 -070065 providerService = providerRegistry.register(this);
alshabib289652c2014-09-07 19:09:28 -070066 controller.addListener(listener);
alshabibc4901cd2014-09-05 16:50:40 -070067 controller.addPacketListener(0, listener);
alshabibc944fd02014-09-10 17:55:17 -070068 for (OpenFlowSwitch sw : controller.getSwitches()) {
69 listener.switchAdded(new Dpid(sw.getId()));
70 }
tome06f8552014-08-26 16:58:42 -070071 log.info("Started");
72 }
73
74 @Deactivate
75 public void deactivate() {
alshabibc944fd02014-09-10 17:55:17 -070076 for (LinkDiscovery ld : discoverers.values()) {
77 ld.stop();
78 }
tom96dfcab2014-08-28 09:26:03 -070079 providerRegistry.unregister(this);
alshabib289652c2014-09-07 19:09:28 -070080 controller.removeListener(listener);
alshabibc4901cd2014-09-05 16:50:40 -070081 controller.removePacketListener(listener);
tome06f8552014-08-26 16:58:42 -070082 providerService = null;
alshabibc944fd02014-09-10 17:55:17 -070083
tome06f8552014-08-26 16:58:42 -070084 log.info("Stopped");
85 }
86
alshabibc4901cd2014-09-05 16:50:40 -070087
alshabib289652c2014-09-07 19:09:28 -070088 private class InternalLinkProvider implements PacketListener, OpenFlowSwitchListener {
alshabibc4901cd2014-09-05 16:50:40 -070089
alshabibdf652ad2014-09-09 11:53:19 -070090
alshabibc4901cd2014-09-05 16:50:40 -070091 @Override
alshabibe7031562014-09-12 18:17:37 -070092 public void handlePacket(OpenFlowPacketContext pktCtx) {
alshabibdf652ad2014-09-09 11:53:19 -070093 LinkDiscovery ld = discoverers.get(pktCtx.dpid());
94 if (ld == null) {
95 return;
96 }
alshabib505bc6b2014-09-09 15:04:13 -070097 if (ld.handleLLDP(pktCtx.unparsed(), pktCtx.inPort())) {
alshabib7b2748f2014-09-16 20:21:11 -070098 pktCtx.block();
alshabib505bc6b2014-09-09 15:04:13 -070099 }
alshabibc4901cd2014-09-05 16:50:40 -0700100
101 }
102
alshabib289652c2014-09-07 19:09:28 -0700103 @Override
104 public void switchAdded(Dpid dpid) {
alshabibdf652ad2014-09-09 11:53:19 -0700105 discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid),
alshabib63d5afe2014-09-15 09:40:24 -0700106 controller, providerService, useBDDP));
alshabib289652c2014-09-07 19:09:28 -0700107
108 }
109
110 @Override
111 public void switchRemoved(Dpid dpid) {
alshabibc944fd02014-09-10 17:55:17 -0700112 LinkDiscovery ld = discoverers.remove(dpid);
alshabibdf652ad2014-09-09 11:53:19 -0700113 if (ld != null) {
114 ld.removeAllPorts();
115 }
116 providerService.linksVanished(
117 DeviceId.deviceId("of:" + Long.toHexString(dpid.value())));
alshabib289652c2014-09-07 19:09:28 -0700118 }
119
120 @Override
121 public void portChanged(Dpid dpid, OFPortStatus status) {
alshabibdf652ad2014-09-09 11:53:19 -0700122 LinkDiscovery ld = discoverers.get(dpid);
123 if (ld == null) {
124 return;
125 }
126 final OFPortDesc port = status.getDesc();
127 final boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) &&
128 !port.getConfig().contains(OFPortConfig.PORT_DOWN);
129 if (enabled) {
130 ld.addPort(port);
131 } else {
alshabibc944fd02014-09-10 17:55:17 -0700132 /*
133 * remove port calls linkVanished
134 */
alshabiba159a322014-09-09 14:50:51 -0700135 ld.removePort(port);
alshabibdf652ad2014-09-09 11:53:19 -0700136 }
alshabib289652c2014-09-07 19:09:28 -0700137
138 }
139
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700140 @Override
141 public void roleAssertFailed(Dpid dpid, RoleState role) {
alshabib64231d82014-09-25 18:25:31 -0700142 // do nothing for this.
Ayaka Koshibeab91cc42014-09-25 10:20:52 -0700143 }
144
alshabibc4901cd2014-09-05 16:50:40 -0700145 }
146
tome06f8552014-08-26 16:58:42 -0700147}