alshabib

link discovery and providers are implemented

...@@ -2,7 +2,7 @@ package org.onlab.onos.net; ...@@ -2,7 +2,7 @@ package org.onlab.onos.net;
2 2
3 import java.util.Objects; 3 import java.util.Objects;
4 4
5 -import static com.google.common.base.MoreObjects.toStringHelper; 5 +import com.google.common.base.MoreObjects;
6 6
7 /** 7 /**
8 * Abstraction of a network connection point expressed as a pair of the 8 * Abstraction of a network connection point expressed as a pair of the
...@@ -42,13 +42,12 @@ public class ConnectPoint { ...@@ -42,13 +42,12 @@ public class ConnectPoint {
42 * @throws java.lang.IllegalStateException if connection point is not 42 * @throws java.lang.IllegalStateException if connection point is not
43 * associated with a device 43 * associated with a device
44 */ 44 */
45 - @SuppressWarnings("unchecked")
46 public DeviceId deviceId() { 45 public DeviceId deviceId() {
47 if (elementId instanceof DeviceId) { 46 if (elementId instanceof DeviceId) {
48 return (DeviceId) elementId; 47 return (DeviceId) elementId;
49 } 48 }
50 throw new IllegalStateException("Connection point not associated " + 49 throw new IllegalStateException("Connection point not associated " +
51 - "with an infrastructure device"); 50 + "with an infrastructure device");
52 } 51 }
53 52
54 /** 53 /**
...@@ -77,7 +76,7 @@ public class ConnectPoint { ...@@ -77,7 +76,7 @@ public class ConnectPoint {
77 76
78 @Override 77 @Override
79 public String toString() { 78 public String toString() {
80 - return toStringHelper(this) 79 + return MoreObjects.toStringHelper(this)
81 .add("elementId", elementId) 80 .add("elementId", elementId)
82 .add("portNumber", portNumber) 81 .add("portNumber", portNumber)
83 .toString(); 82 .toString();
......
1 package org.onlab.onos.net.trivial.impl; 1 package org.onlab.onos.net.trivial.impl;
2 2
3 -import com.google.common.collect.Sets; 3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +import static org.slf4j.LoggerFactory.getLogger;
5 +
6 +import java.util.Set;
7 +
4 import org.apache.felix.scr.annotations.Activate; 8 import org.apache.felix.scr.annotations.Activate;
5 import org.apache.felix.scr.annotations.Component; 9 import org.apache.felix.scr.annotations.Component;
6 import org.apache.felix.scr.annotations.Deactivate; 10 import org.apache.felix.scr.annotations.Deactivate;
...@@ -24,10 +28,7 @@ import org.onlab.onos.net.provider.AbstractProviderRegistry; ...@@ -24,10 +28,7 @@ import org.onlab.onos.net.provider.AbstractProviderRegistry;
24 import org.onlab.onos.net.provider.AbstractProviderService; 28 import org.onlab.onos.net.provider.AbstractProviderService;
25 import org.slf4j.Logger; 29 import org.slf4j.Logger;
26 30
27 -import java.util.Set; 31 +import com.google.common.collect.Sets;
28 -
29 -import static com.google.common.base.Preconditions.checkNotNull;
30 -import static org.slf4j.LoggerFactory.getLogger;
31 32
32 /** 33 /**
33 * Provides basic implementation of the link SB & NB APIs. 34 * Provides basic implementation of the link SB & NB APIs.
...@@ -35,8 +36,8 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -35,8 +36,8 @@ import static org.slf4j.LoggerFactory.getLogger;
35 @Component(immediate = true) 36 @Component(immediate = true)
36 @Service 37 @Service
37 public class SimpleLinkManager 38 public class SimpleLinkManager
38 - extends AbstractProviderRegistry<LinkProvider, LinkProviderService> 39 +extends AbstractProviderRegistry<LinkProvider, LinkProviderService>
39 - implements LinkService, LinkAdminService, LinkProviderRegistry { 40 +implements LinkService, LinkAdminService, LinkProviderRegistry {
40 41
41 private static final String DEVICE_ID_NULL = "Device ID cannot be null"; 42 private static final String DEVICE_ID_NULL = "Device ID cannot be null";
42 private static final String LINK_DESC_NULL = "Link description cannot be null"; 43 private static final String LINK_DESC_NULL = "Link description cannot be null";
...@@ -45,7 +46,7 @@ public class SimpleLinkManager ...@@ -45,7 +46,7 @@ public class SimpleLinkManager
45 private final Logger log = getLogger(getClass()); 46 private final Logger log = getLogger(getClass());
46 47
47 private final AbstractListenerRegistry<LinkEvent, LinkListener> 48 private final AbstractListenerRegistry<LinkEvent, LinkListener>
48 - listenerRegistry = new AbstractListenerRegistry<>(); 49 + listenerRegistry = new AbstractListenerRegistry<>();
49 50
50 private final SimpleLinkStore store = new SimpleLinkStore(); 51 private final SimpleLinkStore store = new SimpleLinkStore();
51 52
...@@ -83,7 +84,7 @@ public class SimpleLinkManager ...@@ -83,7 +84,7 @@ public class SimpleLinkManager
83 public Set<Link> getDeviceLinks(DeviceId deviceId) { 84 public Set<Link> getDeviceLinks(DeviceId deviceId) {
84 checkNotNull(deviceId, DEVICE_ID_NULL); 85 checkNotNull(deviceId, DEVICE_ID_NULL);
85 return Sets.union(store.getDeviceEgressLinks(deviceId), 86 return Sets.union(store.getDeviceEgressLinks(deviceId),
86 - store.getDeviceIngressLinks(deviceId)); 87 + store.getDeviceIngressLinks(deviceId));
87 } 88 }
88 89
89 @Override 90 @Override
...@@ -102,7 +103,7 @@ public class SimpleLinkManager ...@@ -102,7 +103,7 @@ public class SimpleLinkManager
102 public Set<Link> getLinks(ConnectPoint connectPoint) { 103 public Set<Link> getLinks(ConnectPoint connectPoint) {
103 checkNotNull(connectPoint, CONNECT_POINT_NULL); 104 checkNotNull(connectPoint, CONNECT_POINT_NULL);
104 return Sets.union(store.getEgressLinks(connectPoint), 105 return Sets.union(store.getEgressLinks(connectPoint),
105 - store.getIngressLinks(connectPoint)); 106 + store.getIngressLinks(connectPoint));
106 } 107 }
107 108
108 @Override 109 @Override
...@@ -146,7 +147,7 @@ public class SimpleLinkManager ...@@ -146,7 +147,7 @@ public class SimpleLinkManager
146 147
147 // Personalized link provider service issued to the supplied provider. 148 // Personalized link provider service issued to the supplied provider.
148 private class InternalLinkProviderService extends AbstractProviderService<LinkProvider> 149 private class InternalLinkProviderService extends AbstractProviderService<LinkProvider>
149 - implements LinkProviderService { 150 + implements LinkProviderService {
150 151
151 public InternalLinkProviderService(LinkProvider provider) { 152 public InternalLinkProviderService(LinkProvider provider) {
152 super(provider); 153 super(provider);
...@@ -156,9 +157,9 @@ public class SimpleLinkManager ...@@ -156,9 +157,9 @@ public class SimpleLinkManager
156 public void linkDetected(LinkDescription linkDescription) { 157 public void linkDetected(LinkDescription linkDescription) {
157 checkNotNull(linkDescription, LINK_DESC_NULL); 158 checkNotNull(linkDescription, LINK_DESC_NULL);
158 checkValidity(); 159 checkValidity();
159 - log.info("Link {} detected", linkDescription); 160 + log.debug("Link {} detected", linkDescription);
160 LinkEvent event = store.createOrUpdateLink(provider().id(), 161 LinkEvent event = store.createOrUpdateLink(provider().id(),
161 - linkDescription); 162 + linkDescription);
162 post(event); 163 post(event);
163 } 164 }
164 165
...@@ -168,7 +169,7 @@ public class SimpleLinkManager ...@@ -168,7 +169,7 @@ public class SimpleLinkManager
168 checkValidity(); 169 checkValidity();
169 log.info("Link {} vanished", linkDescription); 170 log.info("Link {} vanished", linkDescription);
170 LinkEvent event = store.removeLink(linkDescription.src(), 171 LinkEvent event = store.removeLink(linkDescription.src(),
171 - linkDescription.dst()); 172 + linkDescription.dst());
172 post(event); 173 post(event);
173 } 174 }
174 175
......
...@@ -75,4 +75,9 @@ public final class DefaultPacketContext implements PacketContext { ...@@ -75,4 +75,9 @@ public final class DefaultPacketContext implements PacketContext {
75 return new DefaultPacketContext(s, pkt); 75 return new DefaultPacketContext(s, pkt);
76 } 76 }
77 77
78 + @Override
79 + public Integer inPort() {
80 + return pktin.getInPort().getPortNumber();
81 + }
82 +
78 } 83 }
......
...@@ -48,4 +48,10 @@ public interface PacketContext { ...@@ -48,4 +48,10 @@ public interface PacketContext {
48 * @return the dpid of the switch. 48 * @return the dpid of the switch.
49 */ 49 */
50 public Dpid dpid(); 50 public Dpid dpid();
51 +
52 + /**
53 + * Provide the port on which the packet arrived.
54 + * @return the port
55 + */
56 + public Integer inPort();
51 } 57 }
......
...@@ -415,12 +415,14 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -415,12 +415,14 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
415 OFDescStatsReply drep = (OFDescStatsReply) m; 415 OFDescStatsReply drep = (OFDescStatsReply) m;
416 // Here is where we differentiate between different kinds of switches 416 // Here is where we differentiate between different kinds of switches
417 h.sw = h.controller.getOFSwitchInstance(h.thisdpid, drep, h.ofVersion); 417 h.sw = h.controller.getOFSwitchInstance(h.thisdpid, drep, h.ofVersion);
418 +
418 h.sw.setOFVersion(h.ofVersion); 419 h.sw.setOFVersion(h.ofVersion);
419 h.sw.setFeaturesReply(h.featuresReply); 420 h.sw.setFeaturesReply(h.featuresReply);
420 h.sw.setPortDescReply(h.portDescReply); 421 h.sw.setPortDescReply(h.portDescReply);
421 h.sw.setConnected(true); 422 h.sw.setConnected(true);
422 h.sw.setChannel(h.channel); 423 h.sw.setChannel(h.channel);
423 boolean success = h.sw.connectSwitch(); 424 boolean success = h.sw.connectSwitch();
425 +
424 if (!success) { 426 if (!success) {
425 disconnectDuplicate(h); 427 disconnectDuplicate(h);
426 return; 428 return;
...@@ -432,10 +434,10 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -432,10 +434,10 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
432 log.info("Switch {} bound to class {}, description {}", 434 log.info("Switch {} bound to class {}, description {}",
433 new Object[] {h.sw, h.sw.getClass(), drep }); 435 new Object[] {h.sw, h.sw.getClass(), drep });
434 //Put switch in EQUAL mode until we hear back from the global registry 436 //Put switch in EQUAL mode until we hear back from the global registry
435 - log.debug("Setting new switch {} to EQUAL and sending Role request", 437 + //log.debug("Setting new switch {} to EQUAL and sending Role request",
436 - h.sw.getStringId()); 438 + // h.sw.getStringId());
437 - h.sw.activateEqualSwitch(); 439 + //h.sw.activateEqualSwitch();
438 - h.setSwitchRole(RoleState.EQUAL); 440 + //h.setSwitchRole(RoleState.EQUAL);
439 441
440 h.sw.startDriverHandshake(); 442 h.sw.startDriverHandshake();
441 h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE); 443 h.setState(WAIT_SWITCH_DRIVER_SUB_HANDSHAKE);
......
1 package org.onlab.onos.of.controller.impl; 1 package org.onlab.onos.of.controller.impl;
2 2
3 +import java.util.ArrayList;
4 +import java.util.HashSet;
5 +import java.util.List;
6 +import java.util.Set;
7 +import java.util.concurrent.ConcurrentHashMap;
8 +import java.util.concurrent.locks.Lock;
9 +import java.util.concurrent.locks.ReentrantLock;
10 +
3 import org.apache.felix.scr.annotations.Activate; 11 import org.apache.felix.scr.annotations.Activate;
4 import org.apache.felix.scr.annotations.Component; 12 import org.apache.felix.scr.annotations.Component;
5 import org.apache.felix.scr.annotations.Deactivate; 13 import org.apache.felix.scr.annotations.Deactivate;
6 import org.apache.felix.scr.annotations.Service; 14 import org.apache.felix.scr.annotations.Service;
15 +import org.onlab.onos.of.controller.DefaultPacketContext;
7 import org.onlab.onos.of.controller.Dpid; 16 import org.onlab.onos.of.controller.Dpid;
8 import org.onlab.onos.of.controller.OpenFlowController; 17 import org.onlab.onos.of.controller.OpenFlowController;
9 import org.onlab.onos.of.controller.OpenFlowSwitch; 18 import org.onlab.onos.of.controller.OpenFlowSwitch;
...@@ -12,18 +21,11 @@ import org.onlab.onos.of.controller.PacketListener; ...@@ -12,18 +21,11 @@ import org.onlab.onos.of.controller.PacketListener;
12 import org.onlab.onos.of.controller.RoleState; 21 import org.onlab.onos.of.controller.RoleState;
13 import org.onlab.onos.of.controller.driver.OpenFlowAgent; 22 import org.onlab.onos.of.controller.driver.OpenFlowAgent;
14 import org.projectfloodlight.openflow.protocol.OFMessage; 23 import org.projectfloodlight.openflow.protocol.OFMessage;
24 +import org.projectfloodlight.openflow.protocol.OFPacketIn;
15 import org.projectfloodlight.openflow.protocol.OFPortStatus; 25 import org.projectfloodlight.openflow.protocol.OFPortStatus;
16 import org.slf4j.Logger; 26 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory; 27 import org.slf4j.LoggerFactory;
18 28
19 -import java.util.ArrayList;
20 -import java.util.HashSet;
21 -import java.util.List;
22 -import java.util.Set;
23 -import java.util.concurrent.ConcurrentHashMap;
24 -import java.util.concurrent.locks.Lock;
25 -import java.util.concurrent.locks.ReentrantLock;
26 -
27 @Component(immediate = true) 29 @Component(immediate = true)
28 @Service 30 @Service
29 public class OpenFlowControllerImpl implements OpenFlowController { 31 public class OpenFlowControllerImpl implements OpenFlowController {
...@@ -42,238 +44,244 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -42,238 +44,244 @@ public class OpenFlowControllerImpl implements OpenFlowController {
42 protected Set<OpenFlowSwitchListener> ofEventListener = 44 protected Set<OpenFlowSwitchListener> ofEventListener =
43 new HashSet<>(); 45 new HashSet<>();
44 46
45 - protected List<PacketListener> ofPacketListener = 47 + protected List<PacketListener> ofPacketListener =
46 - new ArrayList<>(); 48 + new ArrayList<>();
47 - 49 +
48 - private final Controller ctrl = new Controller(); 50 + private final Controller ctrl = new Controller();
49 - 51 +
50 - @Activate 52 + @Activate
51 - public void activate() { 53 + public void activate() {
52 - ctrl.start(agent); 54 + ctrl.start(agent);
53 - } 55 + }
54 - 56 +
55 - @Deactivate 57 + @Deactivate
56 - public void deactivate() { 58 + public void deactivate() {
57 - ctrl.stop(); 59 + ctrl.stop();
58 - } 60 + }
59 - 61 +
60 - @Override 62 + @Override
61 - public Iterable<OpenFlowSwitch> getSwitches() { 63 + public Iterable<OpenFlowSwitch> getSwitches() {
62 - return connectedSwitches.values(); 64 + return connectedSwitches.values();
63 - } 65 + }
64 - 66 +
65 - @Override 67 + @Override
66 - public Iterable<OpenFlowSwitch> getMasterSwitches() { 68 + public Iterable<OpenFlowSwitch> getMasterSwitches() {
67 - return activeMasterSwitches.values(); 69 + return activeMasterSwitches.values();
68 - } 70 + }
69 - 71 +
70 - @Override 72 + @Override
71 - public Iterable<OpenFlowSwitch> getEqualSwitches() { 73 + public Iterable<OpenFlowSwitch> getEqualSwitches() {
72 - return activeEqualSwitches.values(); 74 + return activeEqualSwitches.values();
73 - } 75 + }
74 - 76 +
75 - @Override 77 + @Override
76 - public OpenFlowSwitch getSwitch(Dpid dpid) { 78 + public OpenFlowSwitch getSwitch(Dpid dpid) {
77 - return connectedSwitches.get(dpid); 79 + return connectedSwitches.get(dpid);
78 - } 80 + }
79 - 81 +
80 - @Override 82 + @Override
81 - public OpenFlowSwitch getMasterSwitch(Dpid dpid) { 83 + public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
82 - return activeMasterSwitches.get(dpid); 84 + return activeMasterSwitches.get(dpid);
83 - } 85 + }
84 - 86 +
85 - @Override 87 + @Override
86 - public OpenFlowSwitch getEqualSwitch(Dpid dpid) { 88 + public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
87 - return activeEqualSwitches.get(dpid); 89 + return activeEqualSwitches.get(dpid);
88 - } 90 + }
89 - 91 +
90 - @Override 92 + @Override
91 - public void addListener(OpenFlowSwitchListener listener) { 93 + public void addListener(OpenFlowSwitchListener listener) {
92 - if (!ofEventListener.contains(listener)) { 94 + if (!ofEventListener.contains(listener)) {
93 - this.ofEventListener.add(listener); 95 + this.ofEventListener.add(listener);
94 - } 96 + }
95 - } 97 + }
96 - 98 +
97 - @Override 99 + @Override
98 - public void removeListener(OpenFlowSwitchListener listener) { 100 + public void removeListener(OpenFlowSwitchListener listener) {
99 - this.ofEventListener.remove(listener); 101 + this.ofEventListener.remove(listener);
100 - } 102 + }
101 - 103 +
102 - @Override 104 + @Override
103 - public void addPacketListener(int priority, PacketListener listener) { 105 + public void addPacketListener(int priority, PacketListener listener) {
104 - ofPacketListener.add(priority, listener); 106 + ofPacketListener.add(priority, listener);
105 - } 107 + }
106 - 108 +
107 - @Override 109 + @Override
108 - public void removePacketListener(PacketListener listener) { 110 + public void removePacketListener(PacketListener listener) {
109 - ofPacketListener.remove(listener); 111 + ofPacketListener.remove(listener);
110 - } 112 + }
111 - 113 +
112 - @Override 114 + @Override
113 - public void write(Dpid dpid, OFMessage msg) { 115 + public void write(Dpid dpid, OFMessage msg) {
114 - this.getSwitch(dpid).sendMsg(msg); 116 + this.getSwitch(dpid).sendMsg(msg);
115 - } 117 + }
116 - 118 +
117 - @Override 119 + @Override
118 - public void processPacket(Dpid dpid, OFMessage msg) { 120 + public void processPacket(Dpid dpid, OFMessage msg) {
119 - switch (msg.getType()) { 121 + switch (msg.getType()) {
120 - case PORT_STATUS: 122 + case PORT_STATUS:
121 - for (OpenFlowSwitchListener l : ofEventListener) { 123 + for (OpenFlowSwitchListener l : ofEventListener) {
122 - l.portChanged(dpid, (OFPortStatus) msg); 124 + l.portChanged(dpid, (OFPortStatus) msg);
123 - } 125 + }
124 - break; 126 + break;
125 - case PACKET_IN: 127 + case PACKET_IN:
126 - for (PacketListener p : ofPacketListener) { 128 + for (PacketListener p : ofPacketListener) {
127 - //TODO fix me! 129 + //TODO fix me!
128 - p.handlePacket(null); 130 + p.handlePacket(DefaultPacketContext
129 - } 131 + .packetContextFromPacketIn(this.getSwitch(dpid),
130 - break; 132 + (OFPacketIn) msg));
131 - default: 133 + }
132 - log.warn("Handling message type {} not yet implemented", msg.getType()); 134 + break;
133 - } 135 + default:
134 - } 136 + log.warn("Handling message type {} not yet implemented {}",
135 - 137 + msg.getType(), msg);
136 - @Override 138 + }
137 - public void setRole(Dpid dpid, RoleState role) { 139 + }
138 - getSwitch(dpid).setRole(role); 140 +
139 - } 141 + @Override
140 - 142 + public void setRole(Dpid dpid, RoleState role) {
141 - /** 143 + getSwitch(dpid).setRole(role);
142 - * Implementation of an OpenFlow Agent which is responsible for 144 + }
143 - * keeping track of connected switches and the state in which 145 +
144 - * they are. 146 + /**
145 - */ 147 + * Implementation of an OpenFlow Agent which is responsible for
146 - public class OpenFlowSwitchAgent implements OpenFlowAgent { 148 + * keeping track of connected switches and the state in which
147 - 149 + * they are.
148 - private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class); 150 + */
149 - private final Lock switchLock = new ReentrantLock(); 151 + public class OpenFlowSwitchAgent implements OpenFlowAgent {
150 - 152 +
151 - @Override 153 + private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class);
152 - public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) { 154 + private final Lock switchLock = new ReentrantLock();
153 - if (connectedSwitches.get(dpid) != null) { 155 +
154 - log.error("Trying to add connectedSwitch but found a previous " 156 + @Override
155 - + "value for dpid: {}", dpid); 157 + public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
156 - return false; 158 + if (connectedSwitches.get(dpid) != null) {
157 - } else { 159 + log.error("Trying to add connectedSwitch but found a previous "
158 - log.error("Added switch {}", dpid); 160 + + "value for dpid: {}", dpid);
159 - connectedSwitches.put(dpid, sw); 161 + return false;
160 - for (OpenFlowSwitchListener l : ofEventListener) { 162 + } else {
161 - l.switchAdded(dpid); 163 + log.error("Added switch {}", dpid);
162 - } 164 + connectedSwitches.put(dpid, sw);
163 - return true; 165 + for (OpenFlowSwitchListener l : ofEventListener) {
164 - } 166 + l.switchAdded(dpid);
165 - } 167 + }
166 - 168 + return true;
167 - @Override 169 + }
168 - public boolean validActivation(Dpid dpid) { 170 + }
169 - if (connectedSwitches.get(dpid) == null) { 171 +
170 - log.error("Trying to activate switch but is not in " 172 + @Override
171 - + "connected switches: dpid {}. Aborting ..", 173 + public boolean validActivation(Dpid dpid) {
172 - dpid); 174 + if (connectedSwitches.get(dpid) == null) {
173 - return false; 175 + log.error("Trying to activate switch but is not in "
174 - } 176 + + "connected switches: dpid {}. Aborting ..",
175 - if (activeMasterSwitches.get(dpid) != null || 177 + dpid);
176 - activeEqualSwitches.get(dpid) != null) { 178 + return false;
177 - log.error("Trying to activate switch but it is already " 179 + }
178 - + "activated: dpid {}. Found in activeMaster: {} " 180 + if (activeMasterSwitches.get(dpid) != null ||
179 - + "Found in activeEqual: {}. Aborting ..", new Object[]{ 181 + activeEqualSwitches.get(dpid) != null) {
180 - dpid, 182 + log.error("Trying to activate switch but it is already "
181 - (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y', 183 + + "activated: dpid {}. Found in activeMaster: {} "
182 - (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'}); 184 + + "Found in activeEqual: {}. Aborting ..", new Object[]{
183 - return false; 185 + dpid,
184 - } 186 + (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
185 - return true; 187 + (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
186 - } 188 + return false;
187 - 189 + }
188 - 190 + return true;
189 - @Override 191 + }
190 - public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) { 192 +
191 - switchLock.lock(); 193 +
192 - try { 194 + @Override
193 - if (!validActivation(dpid)) { 195 + public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) {
194 - return false; 196 + switchLock.lock();
195 - } 197 + try {
196 - activeMasterSwitches.put(dpid, sw); 198 + if (!validActivation(dpid)) {
197 - return true; 199 + return false;
198 - } finally { 200 + }
199 - switchLock.unlock(); 201 + activeMasterSwitches.put(dpid, sw);
200 - } 202 + return true;
201 - } 203 + } finally {
202 - 204 + switchLock.unlock();
203 - @Override 205 + }
204 - public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) { 206 + }
205 - switchLock.lock(); 207 +
206 - try { 208 + @Override
207 - if (!validActivation(dpid)) { 209 + public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) {
208 - return false; 210 + switchLock.lock();
209 - } 211 + try {
210 - activeEqualSwitches.put(dpid, sw); 212 + if (!validActivation(dpid)) {
211 - log.info("Added Activated EQUAL Switch {}", dpid); 213 + return false;
212 - return true; 214 + }
213 - } finally { 215 + activeEqualSwitches.put(dpid, sw);
214 - switchLock.unlock(); 216 + log.info("Added Activated EQUAL Switch {}", dpid);
215 - } 217 + return true;
216 - } 218 + } finally {
217 - 219 + switchLock.unlock();
218 - @Override 220 + }
219 - public void transitionToMasterSwitch(Dpid dpid) { 221 + }
220 - switchLock.lock(); 222 +
221 - try { 223 + @Override
222 - if (activeMasterSwitches.containsKey(dpid)) { 224 + public void transitionToMasterSwitch(Dpid dpid) {
223 - return; 225 + switchLock.lock();
224 - } 226 + try {
225 - OpenFlowSwitch sw = activeEqualSwitches.remove(dpid); 227 + if (activeMasterSwitches.containsKey(dpid)) {
226 - if (sw == null) { 228 + return;
227 - log.error("Transition to master called on sw {}, but switch " 229 + }
228 - + "was not found in controller-cache", dpid); 230 + OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
229 - return; 231 + if (sw == null) {
230 - } 232 + sw = getSwitch(dpid);
231 - log.info("Transitioned switch {} to MASTER", dpid); 233 + if (sw == null) {
232 - activeMasterSwitches.put(dpid, sw); 234 + log.error("Transition to master called on sw {}, but switch "
233 - } finally { 235 + + "was not found in controller-cache", dpid);
234 - switchLock.unlock(); 236 + return;
235 - } 237 + }
236 - } 238 + }
237 - 239 + log.info("Transitioned switch {} to MASTER", dpid);
238 - 240 + activeMasterSwitches.put(dpid, sw);
239 - @Override 241 + } finally {
240 - public void transitionToEqualSwitch(Dpid dpid) { 242 + switchLock.unlock();
241 - switchLock.lock(); 243 + }
242 - try { 244 + }
243 - if (activeEqualSwitches.containsKey(dpid)) { 245 +
244 - return; 246 +
245 - } 247 + @Override
246 - OpenFlowSwitch sw = activeMasterSwitches.remove(dpid); 248 + public void transitionToEqualSwitch(Dpid dpid) {
247 - if (sw == null) { 249 + switchLock.lock();
248 - log.error("Transition to equal called on sw {}, but switch " 250 + try {
249 - + "was not found in controller-cache", dpid); 251 + if (activeEqualSwitches.containsKey(dpid)) {
250 - return; 252 + return;
251 - } 253 + }
252 - log.info("Transitioned switch {} to EQUAL", dpid); 254 + OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
253 - activeEqualSwitches.put(dpid, sw); 255 + if (sw == null) {
254 - } finally { 256 + log.error("Transition to equal called on sw {}, but switch "
255 - switchLock.unlock(); 257 + + "was not found in controller-cache", dpid);
256 - } 258 + return;
257 - 259 + }
258 - } 260 + log.info("Transitioned switch {} to EQUAL", dpid);
259 - 261 + activeEqualSwitches.put(dpid, sw);
260 - @Override 262 + } finally {
261 - public void removeConnectedSwitch(Dpid dpid) { 263 + switchLock.unlock();
262 - connectedSwitches.remove(dpid); 264 + }
263 - OpenFlowSwitch sw = activeMasterSwitches.remove(dpid); 265 +
264 - if (sw == null) { 266 + }
265 - sw = activeEqualSwitches.remove(dpid); 267 +
266 - } 268 + @Override
267 - for (OpenFlowSwitchListener l : ofEventListener) { 269 + public void removeConnectedSwitch(Dpid dpid) {
268 - l.switchRemoved(dpid); 270 + connectedSwitches.remove(dpid);
269 - } 271 + OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
270 - } 272 + if (sw == null) {
271 - 273 + sw = activeEqualSwitches.remove(dpid);
272 - @Override 274 + }
273 - public void processMessage(Dpid dpid, OFMessage m) { 275 + for (OpenFlowSwitchListener l : ofEventListener) {
274 - processPacket(dpid, m); 276 + l.switchRemoved(dpid);
275 - } 277 + }
276 - } 278 + }
279 +
280 + @Override
281 + public void processMessage(Dpid dpid, OFMessage m) {
282 + processPacket(dpid, m);
283 + }
284 + }
277 285
278 286
279 } 287 }
......
...@@ -84,7 +84,7 @@ class RoleManager implements RoleHandler { ...@@ -84,7 +84,7 @@ class RoleManager implements RoleHandler {
84 default: 84 default:
85 // ensuring that the only two roles sent to 1.0 switches with 85 // ensuring that the only two roles sent to 1.0 switches with
86 // Nicira role support, are MASTER and SLAVE 86 // Nicira role support, are MASTER and SLAVE
87 - roleToSend = OFNiciraControllerRole.ROLE_SLAVE; 87 + roleToSend = OFNiciraControllerRole.ROLE_OTHER;
88 log.warn("Sending Nx Role.SLAVE to switch {}.", sw); 88 log.warn("Sending Nx Role.SLAVE to switch {}.", sw);
89 } 89 }
90 int xid = sw.getNextTransactionId(); 90 int xid = sw.getNextTransactionId();
......
...@@ -50,8 +50,7 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch { ...@@ -50,8 +50,7 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
50 50
51 @Override 51 @Override
52 public void write(OFMessage msg) { 52 public void write(OFMessage msg) {
53 - channel.write(msg); 53 + channel.write(Collections.singletonList(msg));
54 -
55 } 54 }
56 55
57 @Override 56 @Override
......
...@@ -61,6 +61,14 @@ ...@@ -61,6 +61,14 @@
61 <version>18.0</version> 61 <version>18.0</version>
62 </dependency> 62 </dependency>
63 63
64 + <dependency>
65 + <groupId>io.netty</groupId>
66 + <artifactId>netty</artifactId>
67 + <version>3.9.0.Final</version>
68 + </dependency>
69 +
70 +
71 +
64 <dependency> 72 <dependency>
65 <groupId>com.google.guava</groupId> 73 <groupId>com.google.guava</groupId>
66 <artifactId>guava-testlib</artifactId> 74 <artifactId>guava-testlib</artifactId>
......
1 +/*******************************************************************************
2 + * Copyright 2014 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + ******************************************************************************/
16 +package org.onlab.onos.provider.of.link.impl;
17 +
18 +import static org.slf4j.LoggerFactory.getLogger;
19 +
20 +import java.util.Collections;
21 +import java.util.HashMap;
22 +import java.util.HashSet;
23 +import java.util.Iterator;
24 +import java.util.List;
25 +import java.util.Map;
26 +import java.util.Set;
27 +import java.util.concurrent.TimeUnit;
28 +import java.util.concurrent.atomic.AtomicInteger;
29 +
30 +import org.jboss.netty.util.Timeout;
31 +import org.jboss.netty.util.TimerTask;
32 +import org.onlab.onos.net.ConnectPoint;
33 +import org.onlab.onos.net.DeviceId;
34 +import org.onlab.onos.net.Link.Type;
35 +import org.onlab.onos.net.PortNumber;
36 +import org.onlab.onos.net.link.DefaultLinkDescription;
37 +import org.onlab.onos.net.link.LinkDescription;
38 +import org.onlab.onos.net.link.LinkProviderService;
39 +import org.onlab.onos.of.controller.Dpid;
40 +import org.onlab.onos.of.controller.OpenFlowController;
41 +import org.onlab.onos.of.controller.OpenFlowSwitch;
42 +import org.onlab.packet.Ethernet;
43 +import org.onlab.packet.ONLabLddp;
44 +import org.onlab.packet.ONLabLddp.DPIDandPort;
45 +import org.onlab.timer.Timer;
46 +import org.projectfloodlight.openflow.protocol.OFFactory;
47 +import org.projectfloodlight.openflow.protocol.OFMessage;
48 +import org.projectfloodlight.openflow.protocol.OFPacketOut;
49 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
50 +import org.projectfloodlight.openflow.protocol.action.OFAction;
51 +import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
52 +import org.projectfloodlight.openflow.types.OFBufferId;
53 +import org.projectfloodlight.openflow.types.OFPort;
54 +import org.slf4j.Logger;
55 +
56 +
57 +
58 +/**
59 + * Run discovery process from a physical switch. Ports are initially labeled as
60 + * slow ports. When an LLDP is successfully received, label the remote port as
61 + * fast. Every probeRate milliseconds, loop over all fast ports and send an
62 + * LLDP, send an LLDP for a single slow port. Based on FlowVisor topology
63 + * discovery implementation.
64 + *
65 + * TODO: add 'fast discovery' mode: drop LLDPs in destination switch but listen
66 + * for flow_removed messages
67 + */
68 +public class LinkDiscovery implements TimerTask {
69 +
70 + private final OpenFlowSwitch sw;
71 + // send 1 probe every probeRate milliseconds
72 + private final long probeRate;
73 + private final Set<Integer> slowPorts;
74 + private final Set<Integer> fastPorts;
75 + // number of unacknowledged probes per port
76 + private final Map<Integer, AtomicInteger> portProbeCount;
77 + // number of probes to send before link is removed
78 + private static final short MAX_PROBE_COUNT = 3;
79 + private Iterator<Integer> slowIterator;
80 + private final OFFactory ofFactory;
81 + private final Logger log = getLogger(getClass());
82 + private final ONLabLddp lldpPacket;
83 + private final Ethernet ethPacket;
84 + private Ethernet bddpEth;
85 + private final boolean useBDDP;
86 + private final OpenFlowController ctrl;
87 + private final LinkProviderService linkProvider;
88 +
89 + /**
90 + * Instantiates discovery manager for the given physical switch. Creates a
91 + * generic LLDP packet that will be customized for the port it is sent out on.
92 + * Starts the the timer for the discovery process.
93 + *
94 + * @param sw the physical switch
95 + * @param useBDDP flag to also use BDDP for discovery
96 + */
97 + public LinkDiscovery(final OpenFlowSwitch sw,
98 + OpenFlowController ctrl, LinkProviderService providerService, Boolean... useBDDP) {
99 + this.sw = sw;
100 + this.ofFactory = sw.factory();
101 + this.ctrl = ctrl;
102 + this.probeRate = 1000;
103 + this.linkProvider = providerService;
104 + this.slowPorts = Collections.synchronizedSet(new HashSet<Integer>());
105 + this.fastPorts = Collections.synchronizedSet(new HashSet<Integer>());
106 + this.portProbeCount = new HashMap<Integer, AtomicInteger>();
107 + this.lldpPacket = new ONLabLddp();
108 + this.lldpPacket.setSwitch(this.sw.getId());
109 + this.ethPacket = new Ethernet();
110 + this.ethPacket.setEtherType(Ethernet.TYPE_LLDP);
111 + this.ethPacket.setDestinationMACAddress(ONLabLddp.LLDP_NICIRA);
112 + this.ethPacket.setPayload(this.lldpPacket);
113 + this.ethPacket.setPad(true);
114 + this.useBDDP = useBDDP.length > 0 ? useBDDP[0] : false;
115 + if (this.useBDDP) {
116 + this.bddpEth = new Ethernet();
117 + this.bddpEth.setPayload(this.lldpPacket);
118 + this.bddpEth.setEtherType(Ethernet.TYPE_BSN);
119 + this.bddpEth.setDestinationMACAddress(ONLabLddp.BDDP_MULTICAST);
120 + this.bddpEth.setPad(true);
121 + log.info("Using BDDP to discover network");
122 + }
123 + for (OFPortDesc port : sw.getPorts()) {
124 + if (port.getPortNo() != OFPort.LOCAL) {
125 + addPort(port);
126 + }
127 + }
128 + Timer.getTimer().newTimeout(this, this.probeRate,
129 + TimeUnit.MILLISECONDS);
130 + this.log.debug("Started discovery manager for switch {}",
131 + sw.getId());
132 +
133 + }
134 +
135 + /**
136 + * Add physical port port to discovery process.
137 + * Send out initial LLDP and label it as slow port.
138 + *
139 + * @param port the port
140 + */
141 + public void addPort(final OFPortDesc port) {
142 + // Ignore ports that are not on this switch, or already booted. */
143 +
144 + synchronized (this) {
145 + this.log.debug("sending init probe to port {}",
146 + port.getPortNo().getPortNumber());
147 + OFPacketOut pkt;
148 +
149 + pkt = this.createLLDPPacketOut(port);
150 + this.sw.sendMsg(pkt);
151 + if (useBDDP) {
152 + OFPacketOut bpkt = this.createBDDPPacketOut(port);
153 + this.sw.sendMsg(bpkt);
154 + }
155 +
156 + this.slowPorts.add(port.getPortNo().getPortNumber());
157 + this.slowIterator = this.slowPorts.iterator();
158 + }
159 +
160 + }
161 +
162 + /**
163 + * Removes physical port from discovery process.
164 + *
165 + * @param port the port
166 + */
167 + public void removePort(final OFPort port) {
168 + // Ignore ports that are not on this switch
169 +
170 + int portnum = port.getPortNumber();
171 + synchronized (this) {
172 + if (this.slowPorts.contains(portnum)) {
173 + this.slowPorts.remove(portnum);
174 + this.slowIterator = this.slowPorts.iterator();
175 +
176 + } else if (this.fastPorts.contains(portnum)) {
177 + this.fastPorts.remove(portnum);
178 + this.portProbeCount.remove(portnum);
179 + // no iterator to update
180 + } else {
181 + this.log.warn(
182 + "tried to dynamically remove non-existing port {}",
183 + portnum);
184 + }
185 + }
186 +
187 + }
188 +
189 + /**
190 + * Method called by remote port to acknowledge receipt of LLDP sent by
191 + * this port. If slow port, updates label to fast. If fast port, decrements
192 + * number of unacknowledged probes.
193 + *
194 + * @param port the port
195 + */
196 + public void ackProbe(final Integer port) {
197 + final int portNumber = port;
198 + synchronized (this) {
199 + if (this.slowPorts.contains(portNumber)) {
200 + this.log.debug("Setting slow port to fast: {}:{}",
201 + this.sw.getId(), portNumber);
202 + this.slowPorts.remove(portNumber);
203 + this.slowIterator = this.slowPorts.iterator();
204 + this.fastPorts.add(portNumber);
205 + this.portProbeCount.put(portNumber, new AtomicInteger(0));
206 + } else {
207 + if (this.fastPorts.contains(portNumber)) {
208 + this.portProbeCount.get(portNumber).set(0);
209 + } else {
210 + this.log.debug(
211 + "Got ackProbe for non-existing port: {}",
212 + portNumber);
213 + }
214 + }
215 + }
216 + }
217 +
218 + /**
219 + * Creates packet_out LLDP for specified output port.
220 + *
221 + * @param port the port
222 + * @return Packet_out message with LLDP data
223 + * @throws PortMappingException
224 + */
225 + private OFPacketOut createLLDPPacketOut(final OFPortDesc port) {
226 + OFPacketOut.Builder packetOut = this.ofFactory.buildPacketOut();
227 + packetOut.setBufferId(OFBufferId.NO_BUFFER);
228 + OFAction act = this.ofFactory.actions().buildOutput()
229 + .setPort(port.getPortNo()).build();
230 + packetOut.setActions(Collections.singletonList(act));
231 + this.lldpPacket.setPort(port.getPortNo().getPortNumber());
232 + this.ethPacket.setSourceMACAddress(port.getHwAddr().getBytes());
233 +
234 + final byte[] lldp = this.ethPacket.serialize();
235 + packetOut.setData(lldp);
236 + return packetOut.build();
237 + }
238 +
239 + /**
240 + * Creates packet_out BDDP for specified output port.
241 + *
242 + * @param port the port
243 + * @return Packet_out message with LLDP data
244 + * @throws PortMappingException
245 + */
246 + private OFPacketOut createBDDPPacketOut(final OFPortDesc port) {
247 + OFPacketOut.Builder packetOut = sw.factory().buildPacketOut();
248 +
249 + packetOut.setBufferId(OFBufferId.NO_BUFFER);
250 +
251 + OFActionOutput.Builder act = sw.factory().actions().buildOutput()
252 + .setPort(port.getPortNo());
253 + OFAction out = act.build();
254 + packetOut.setActions(Collections.singletonList(out));
255 + this.lldpPacket.setPort(port.getPortNo().getPortNumber());
256 + this.bddpEth.setSourceMACAddress(port.getHwAddr().getBytes());
257 +
258 + final byte[] bddp = this.bddpEth.serialize();
259 + packetOut.setData(bddp);
260 +
261 + return packetOut.build();
262 + }
263 +
264 +
265 + private void sendMsg(final OFMessage msg) {
266 + this.sw.sendMsg(msg);
267 + }
268 +
269 + public String getName() {
270 + return "LinkDiscovery " + this.sw.getStringId();
271 + }
272 +
273 + /*
274 + * Handles an incoming LLDP packet. Creates link in topology and sends ACK
275 + * to port where LLDP originated.
276 + */
277 + @SuppressWarnings("rawtypes")
278 + public void handleLLDP(final Ethernet eth, Integer inPort) {
279 +
280 + final byte[] pkt = eth.serialize();
281 +
282 + if (ONLabLddp.isOVXLLDP(pkt)) {
283 + final Integer dstPort = inPort;
284 + final DPIDandPort dp = ONLabLddp.parseLLDP(pkt);
285 + final OpenFlowSwitch srcSwitch = ctrl.getSwitch(new Dpid(dp.getDpid()));
286 + final Integer srcPort = dp.getPort();
287 + if (srcSwitch == null) {
288 + return;
289 + }
290 + this.ackProbe(srcPort);
291 + ConnectPoint src = new ConnectPoint(
292 + DeviceId.deviceId("of:" + Long.toHexString(srcSwitch.getId())),
293 + PortNumber.portNumber(srcPort));
294 +
295 + ConnectPoint dst = new ConnectPoint(
296 + DeviceId.deviceId("of:" + Long.toHexString(sw.getId())),
297 + PortNumber.portNumber(dstPort));
298 + LinkDescription ld;
299 + if (eth.getEtherType() == Ethernet.TYPE_BSN) {
300 + ld = new DefaultLinkDescription(src, dst, Type.INDIRECT);
301 + } else {
302 + ld = new DefaultLinkDescription(src, dst, Type.DIRECT);
303 + }
304 + linkProvider.linkDetected(ld);
305 + } else {
306 + this.log.debug("Ignoring unknown LLDP");
307 + }
308 + }
309 +
310 + private OFPortDesc findPort(List<OFPortDesc> ports, Integer inPort) {
311 + for (OFPortDesc p : ports) {
312 + if (p.getPortNo().getPortNumber() == inPort) {
313 + return p;
314 + }
315 + }
316 + return null;
317 + }
318 +
319 + /**
320 + * Execute this method every t milliseconds. Loops over all ports
321 + * labeled as fast and sends out an LLDP. Send out an LLDP on a single slow
322 + * port.
323 + *
324 + * @param t timeout
325 + * @throws Exception
326 + */
327 + @Override
328 + public void run(final Timeout t) {
329 + this.log.debug("sending probes");
330 + synchronized (this) {
331 + final Iterator<Integer> fastIterator = this.fastPorts.iterator();
332 + while (fastIterator.hasNext()) {
333 + final Integer portNumber = fastIterator.next();
334 + final int probeCount = this.portProbeCount.get(portNumber)
335 + .getAndIncrement();
336 + OFPortDesc port = findPort(this.sw.getPorts(), portNumber);
337 + if (probeCount < LinkDiscovery.MAX_PROBE_COUNT) {
338 + this.log.debug("sending fast probe to port");
339 +
340 + OFPacketOut pkt = this.createLLDPPacketOut(port);
341 + this.sendMsg(pkt);
342 + if (useBDDP) {
343 + OFPacketOut bpkt = this.createBDDPPacketOut(port);
344 + this.sendMsg(bpkt);
345 + }
346 + } else {
347 + // Update fast and slow ports
348 + fastIterator.remove();
349 + this.slowPorts.add(portNumber);
350 + this.slowIterator = this.slowPorts.iterator();
351 + this.portProbeCount.remove(portNumber);
352 +
353 + // Remove link from topology
354 + final OFPortDesc srcPort = port;
355 +
356 + ConnectPoint cp = new ConnectPoint(
357 + DeviceId.deviceId("of:" + Long.toHexString(sw.getId())),
358 + PortNumber.portNumber(srcPort.getPortNo().getPortNumber()));
359 + linkProvider.linksVanished(cp);
360 + }
361 + }
362 +
363 + // send a probe for the next slow port
364 + if (this.slowPorts.size() > 0) {
365 + if (!this.slowIterator.hasNext()) {
366 + this.slowIterator = this.slowPorts.iterator();
367 + }
368 + if (this.slowIterator.hasNext()) {
369 + final int portNumber = this.slowIterator.next();
370 + this.log.debug("sending slow probe to port {}", portNumber);
371 + OFPortDesc port = findPort(this.sw.getPorts(), portNumber);
372 +
373 + OFPacketOut pkt = this.createLLDPPacketOut(port);
374 + this.sendMsg(pkt);
375 + if (useBDDP) {
376 + OFPacketOut bpkt = this.createBDDPPacketOut(port);
377 + this.sendMsg(bpkt);
378 + }
379 +
380 + }
381 + }
382 + }
383 +
384 + // reschedule timer
385 + Timer.getTimer().newTimeout(this, this.probeRate,
386 + TimeUnit.MILLISECONDS);
387 + }
388 +
389 + public void removeAllPorts() {
390 + for (OFPortDesc port : sw.getPorts()) {
391 + removePort(port.getPortNo());
392 + }
393 + }
394 +
395 +}
...@@ -2,11 +2,17 @@ package org.onlab.onos.provider.of.link.impl; ...@@ -2,11 +2,17 @@ package org.onlab.onos.provider.of.link.impl;
2 2
3 import static org.slf4j.LoggerFactory.getLogger; 3 import static org.slf4j.LoggerFactory.getLogger;
4 4
5 +import java.util.Map;
6 +import java.util.concurrent.ConcurrentHashMap;
7 +
5 import org.apache.felix.scr.annotations.Activate; 8 import org.apache.felix.scr.annotations.Activate;
6 import org.apache.felix.scr.annotations.Component; 9 import org.apache.felix.scr.annotations.Component;
7 import org.apache.felix.scr.annotations.Deactivate; 10 import org.apache.felix.scr.annotations.Deactivate;
8 import org.apache.felix.scr.annotations.Reference; 11 import org.apache.felix.scr.annotations.Reference;
9 import org.apache.felix.scr.annotations.ReferenceCardinality; 12 import org.apache.felix.scr.annotations.ReferenceCardinality;
13 +import org.onlab.onos.net.ConnectPoint;
14 +import org.onlab.onos.net.DeviceId;
15 +import org.onlab.onos.net.PortNumber;
10 import org.onlab.onos.net.link.LinkProvider; 16 import org.onlab.onos.net.link.LinkProvider;
11 import org.onlab.onos.net.link.LinkProviderRegistry; 17 import org.onlab.onos.net.link.LinkProviderRegistry;
12 import org.onlab.onos.net.link.LinkProviderService; 18 import org.onlab.onos.net.link.LinkProviderService;
...@@ -17,6 +23,10 @@ import org.onlab.onos.of.controller.OpenFlowController; ...@@ -17,6 +23,10 @@ import org.onlab.onos.of.controller.OpenFlowController;
17 import org.onlab.onos.of.controller.OpenFlowSwitchListener; 23 import org.onlab.onos.of.controller.OpenFlowSwitchListener;
18 import org.onlab.onos.of.controller.PacketContext; 24 import org.onlab.onos.of.controller.PacketContext;
19 import org.onlab.onos.of.controller.PacketListener; 25 import org.onlab.onos.of.controller.PacketListener;
26 +import org.onlab.timer.Timer;
27 +import org.projectfloodlight.openflow.protocol.OFPortConfig;
28 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
29 +import org.projectfloodlight.openflow.protocol.OFPortState;
20 import org.projectfloodlight.openflow.protocol.OFPortStatus; 30 import org.projectfloodlight.openflow.protocol.OFPortStatus;
21 import org.slf4j.Logger; 31 import org.slf4j.Logger;
22 32
...@@ -37,6 +47,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid ...@@ -37,6 +47,8 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
37 47
38 private LinkProviderService providerService; 48 private LinkProviderService providerService;
39 49
50 + private final boolean useBDDP = true;
51 +
40 private final InternalLinkProvider listener = new InternalLinkProvider(); 52 private final InternalLinkProvider listener = new InternalLinkProvider();
41 53
42 /** 54 /**
...@@ -60,32 +72,61 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid ...@@ -60,32 +72,61 @@ public class OpenFlowLinkProvider extends AbstractProvider implements LinkProvid
60 controller.removeListener(listener); 72 controller.removeListener(listener);
61 controller.removePacketListener(listener); 73 controller.removePacketListener(listener);
62 providerService = null; 74 providerService = null;
75 + Timer.getTimer().stop();
63 log.info("Stopped"); 76 log.info("Stopped");
64 } 77 }
65 78
66 79
67 private class InternalLinkProvider implements PacketListener, OpenFlowSwitchListener { 80 private class InternalLinkProvider implements PacketListener, OpenFlowSwitchListener {
68 81
82 + private final Map<Dpid, LinkDiscovery> discoverers = new ConcurrentHashMap<>();
83 +
69 @Override 84 @Override
70 public void handlePacket(PacketContext pktCtx) { 85 public void handlePacket(PacketContext pktCtx) {
86 + LinkDiscovery ld = discoverers.get(pktCtx.dpid());
87 + if (ld == null) {
88 + return;
89 + }
90 + ld.handleLLDP(pktCtx.parsed(),
91 + pktCtx.inPort());
71 92
72 } 93 }
73 94
74 @Override 95 @Override
75 public void switchAdded(Dpid dpid) { 96 public void switchAdded(Dpid dpid) {
76 - // TODO Auto-generated method stub 97 + discoverers.put(dpid, new LinkDiscovery(controller.getSwitch(dpid),
98 + controller, providerService, useBDDP));
77 99
78 } 100 }
79 101
80 @Override 102 @Override
81 public void switchRemoved(Dpid dpid) { 103 public void switchRemoved(Dpid dpid) {
82 - // TODO Auto-generated method stub 104 + LinkDiscovery ld = this.discoverers.remove(dpid);
83 - 105 + if (ld != null) {
106 + ld.removeAllPorts();
107 + }
108 + providerService.linksVanished(
109 + DeviceId.deviceId("of:" + Long.toHexString(dpid.value())));
84 } 110 }
85 111
86 @Override 112 @Override
87 public void portChanged(Dpid dpid, OFPortStatus status) { 113 public void portChanged(Dpid dpid, OFPortStatus status) {
88 - // TODO Auto-generated method stub 114 + 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 + }
89 130
90 } 131 }
91 132
......
...@@ -25,7 +25,10 @@ ...@@ -25,7 +25,10 @@
25 <dependency> 25 <dependency>
26 <groupId>io.netty</groupId> 26 <groupId>io.netty</groupId>
27 <artifactId>netty</artifactId> 27 <artifactId>netty</artifactId>
28 - <version>3.9.0.Final</version> 28 + </dependency>
29 + <dependency>
30 + <groupId>commons-lang</groupId>
31 + <artifactId>commons-lang</artifactId>
29 </dependency> 32 </dependency>
30 </dependencies> 33 </dependencies>
31 34
......
...@@ -21,6 +21,8 @@ import java.util.LinkedList; ...@@ -21,6 +21,8 @@ import java.util.LinkedList;
21 import java.util.List; 21 import java.util.List;
22 22
23 import org.apache.commons.lang.ArrayUtils; 23 import org.apache.commons.lang.ArrayUtils;
24 +import org.slf4j.Logger;
25 +import org.slf4j.LoggerFactory;
24 26
25 27
26 /** 28 /**
...@@ -31,6 +33,7 @@ import org.apache.commons.lang.ArrayUtils; ...@@ -31,6 +33,7 @@ import org.apache.commons.lang.ArrayUtils;
31 @SuppressWarnings("rawtypes") 33 @SuppressWarnings("rawtypes")
32 public class ONLabLddp extends LLDP { 34 public class ONLabLddp extends LLDP {
33 35
36 + private static final Logger log = LoggerFactory.getLogger(ONLabLddp.class);
34 // ON.Lab OUI and OVX name for organizationally specific TLVs 37 // ON.Lab OUI and OVX name for organizationally specific TLVs
35 public static final byte[] ONLAB_OUI = {(byte) 0xa4, 0x23, 0x05}; 38 public static final byte[] ONLAB_OUI = {(byte) 0xa4, 0x23, 0x05};
36 public static final String OVX_NAME = "OpenVirteX"; 39 public static final String OVX_NAME = "OpenVirteX";
...@@ -50,7 +53,7 @@ public class ONLabLddp extends LLDP { ...@@ -50,7 +53,7 @@ public class ONLabLddp extends LLDP {
50 private static final byte CHASSIS_TLV_SUBTYPE = 4; 53 private static final byte CHASSIS_TLV_SUBTYPE = 4;
51 54
52 private static final byte PORT_TLV_TYPE = 2; 55 private static final byte PORT_TLV_TYPE = 2;
53 - private static final byte PORT_TLV_SIZE = 7; 56 + private static final byte PORT_TLV_SIZE = 5;
54 private static final byte PORT_TLV_SUBTYPE = 2; 57 private static final byte PORT_TLV_SUBTYPE = 2;
55 58
56 private static final byte TTL_TLV_TYPE = 3; 59 private static final byte TTL_TLV_TYPE = 3;
...@@ -60,7 +63,7 @@ public class ONLabLddp extends LLDP { ...@@ -60,7 +63,7 @@ public class ONLabLddp extends LLDP {
60 // 4 = OUI (3) + subtype (1) 63 // 4 = OUI (3) + subtype (1)
61 private static final byte NAME_TLV_SIZE = (byte) (4 + ONLabLddp.OVX_NAME.length()); 64 private static final byte NAME_TLV_SIZE = (byte) (4 + ONLabLddp.OVX_NAME.length());
62 private static final byte NAME_TLV_SUBTYPE = 1; 65 private static final byte NAME_TLV_SUBTYPE = 1;
63 - private static final short NAME_TLV_OFFSET = 32; 66 + private static final short NAME_TLV_OFFSET = 34;
64 private static final short NAME_TLV_HEADER = (short) ((NAME_TLV_TYPE << 9) | NAME_TLV_SIZE); 67 private static final short NAME_TLV_HEADER = (short) ((NAME_TLV_TYPE << 9) | NAME_TLV_SIZE);
65 // Contents of full name TLV 68 // Contents of full name TLV
66 private static final byte[] NAME_TLV = ByteBuffer.allocate(NAME_TLV_SIZE + 2) 69 private static final byte[] NAME_TLV = ByteBuffer.allocate(NAME_TLV_SIZE + 2)
...@@ -85,7 +88,7 @@ public class ONLabLddp extends LLDP { ...@@ -85,7 +88,7 @@ public class ONLabLddp extends LLDP {
85 // Default switch, port number and TTL 88 // Default switch, port number and TTL
86 private static final byte[] DEFAULT_DPID = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 89 private static final byte[] DEFAULT_DPID = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00 }; 90 0x00, 0x00 };
88 - private static final short DEFAULT_PORT = 0; 91 + private static final int DEFAULT_PORT = 0;
89 private static final short DEFAULT_TTL = 120; // in seconds 92 private static final short DEFAULT_TTL = 120; // in seconds
90 93
91 // Minimum and OVX-generated LLDP packet sizes 94 // Minimum and OVX-generated LLDP packet sizes
...@@ -97,7 +100,7 @@ public class ONLabLddp extends LLDP { ...@@ -97,7 +100,7 @@ public class ONLabLddp extends LLDP {
97 // Field offsets in OVX-generated LLDP 100 // Field offsets in OVX-generated LLDP
98 private static final short ETHERTYPE_OFFSET = 12; 101 private static final short ETHERTYPE_OFFSET = 12;
99 private static final short PORT_OFFSET = 26; 102 private static final short PORT_OFFSET = 26;
100 - private static final short DPID_OFFSET = 54; 103 + private static final short DPID_OFFSET = 56;
101 104
102 // Private member fields 105 // Private member fields
103 // Byte arrays for TLV information string 106 // Byte arrays for TLV information string
...@@ -167,10 +170,10 @@ public class ONLabLddp extends LLDP { ...@@ -167,10 +170,10 @@ public class ONLabLddp extends LLDP {
167 * 170 *
168 * @param portNumber the port number 171 * @param portNumber the port number
169 */ 172 */
170 - private void setPortTLV(final long portNumber) { 173 + private void setPortTLV(final int portNumber) {
171 this.bb = ByteBuffer.wrap(this.portId); 174 this.bb = ByteBuffer.wrap(this.portId);
172 this.bb.put(PORT_TLV_SUBTYPE); 175 this.bb.put(PORT_TLV_SUBTYPE);
173 - this.bb.putLong(portNumber); 176 + this.bb.putInt(portNumber);
174 177
175 this.portTLV.setLength(PORT_TLV_SIZE); 178 this.portTLV.setLength(PORT_TLV_SIZE);
176 this.portTLV.setType(PORT_TLV_TYPE); 179 this.portTLV.setType(PORT_TLV_TYPE);
...@@ -240,8 +243,8 @@ public class ONLabLddp extends LLDP { ...@@ -240,8 +243,8 @@ public class ONLabLddp extends LLDP {
240 * 243 *
241 * @param port the port instance 244 * @param port the port instance
242 */ 245 */
243 - public void setPort(long port) { 246 + public void setPort(int port) {
244 - long portNumber = port; 247 + int portNumber = port;
245 this.setPortTLV(portNumber); 248 this.setPortTLV(portNumber);
246 } 249 }
247 250
...@@ -335,7 +338,7 @@ public class ONLabLddp extends LLDP { ...@@ -335,7 +338,7 @@ public class ONLabLddp extends LLDP {
335 * @param packet 338 * @param packet
336 * @return Dpid and port 339 * @return Dpid and port
337 */ 340 */
338 - /* public static long parseLLDP(final byte[] packet) { 341 + public static DPIDandPort parseLLDP(final byte[] packet) {
339 final ByteBuffer bb = ByteBuffer.wrap(packet); 342 final ByteBuffer bb = ByteBuffer.wrap(packet);
340 343
341 // Extra offset due to VLAN tag 344 // Extra offset due to VLAN tag
...@@ -345,10 +348,30 @@ public class ONLabLddp extends LLDP { ...@@ -345,10 +348,30 @@ public class ONLabLddp extends LLDP {
345 offset = 4; 348 offset = 4;
346 } 349 }
347 350
348 - final short port = bb.getLong(PORT_OFFSET + offset); 351 + final int port = bb.getInt(PORT_OFFSET + offset);
349 final long dpid = bb.getLong(DPID_OFFSET + offset); 352 final long dpid = bb.getLong(DPID_OFFSET + offset);
350 353
351 - return dpid 354 + return new DPIDandPort(dpid, port);
352 } 355 }
353 - */ 356 +
357 + public static class DPIDandPort {
358 +
359 + private final long dpid;
360 + private final int port;
361 +
362 + public DPIDandPort(long dpid, int port) {
363 + this.dpid = dpid;
364 + this.port = port;
365 + }
366 +
367 + public long getDpid() {
368 + return this.dpid;
369 + }
370 +
371 + public int getPort() {
372 + return this.port;
373 + }
374 +
375 + }
376 +
354 } 377 }
......
1 +package org.onlab.timer;
2 +
3 +import org.jboss.netty.util.HashedWheelTimer;
4 +
5 +
6 +public final class Timer {
7 +
8 + private Timer() {}
9 +
10 + private static HashedWheelTimer timer;
11 +
12 + public static HashedWheelTimer getTimer() {
13 + if (Timer.timer == null) {
14 + Timer.timer = new HashedWheelTimer();
15 + Timer.timer.start();
16 + }
17 + return Timer.timer;
18 + }
19 +
20 +}