alshabib

implementing flowremoved handling

1 package org.onlab.onos.of.controller.impl; 1 package org.onlab.onos.of.controller.impl;
2 2
3 +import static org.onlab.util.Tools.namedThreads;
4 +
3 import java.util.HashSet; 5 import java.util.HashSet;
6 +import java.util.List;
7 +import java.util.Map;
4 import java.util.Set; 8 import java.util.Set;
5 import java.util.concurrent.ConcurrentHashMap; 9 import java.util.concurrent.ConcurrentHashMap;
10 +import java.util.concurrent.ExecutorService;
11 +import java.util.concurrent.Executors;
6 import java.util.concurrent.locks.Lock; 12 import java.util.concurrent.locks.Lock;
7 import java.util.concurrent.locks.ReentrantLock; 13 import java.util.concurrent.locks.ReentrantLock;
8 14
...@@ -13,6 +19,7 @@ import org.apache.felix.scr.annotations.Service; ...@@ -13,6 +19,7 @@ import org.apache.felix.scr.annotations.Service;
13 import org.onlab.onos.of.controller.DefaultOpenFlowPacketContext; 19 import org.onlab.onos.of.controller.DefaultOpenFlowPacketContext;
14 import org.onlab.onos.of.controller.Dpid; 20 import org.onlab.onos.of.controller.Dpid;
15 import org.onlab.onos.of.controller.OpenFlowController; 21 import org.onlab.onos.of.controller.OpenFlowController;
22 +import org.onlab.onos.of.controller.OpenFlowEventListener;
16 import org.onlab.onos.of.controller.OpenFlowPacketContext; 23 import org.onlab.onos.of.controller.OpenFlowPacketContext;
17 import org.onlab.onos.of.controller.OpenFlowSwitch; 24 import org.onlab.onos.of.controller.OpenFlowSwitch;
18 import org.onlab.onos.of.controller.OpenFlowSwitchListener; 25 import org.onlab.onos.of.controller.OpenFlowSwitchListener;
...@@ -22,10 +29,12 @@ import org.onlab.onos.of.controller.driver.OpenFlowAgent; ...@@ -22,10 +29,12 @@ import org.onlab.onos.of.controller.driver.OpenFlowAgent;
22 import org.projectfloodlight.openflow.protocol.OFMessage; 29 import org.projectfloodlight.openflow.protocol.OFMessage;
23 import org.projectfloodlight.openflow.protocol.OFPacketIn; 30 import org.projectfloodlight.openflow.protocol.OFPacketIn;
24 import org.projectfloodlight.openflow.protocol.OFPortStatus; 31 import org.projectfloodlight.openflow.protocol.OFPortStatus;
32 +import org.projectfloodlight.openflow.protocol.OFType;
25 import org.slf4j.Logger; 33 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory; 34 import org.slf4j.LoggerFactory;
27 35
28 import com.google.common.collect.ArrayListMultimap; 36 import com.google.common.collect.ArrayListMultimap;
37 +import com.google.common.collect.Maps;
29 import com.google.common.collect.Multimap; 38 import com.google.common.collect.Multimap;
30 39
31 @Component(immediate = true) 40 @Component(immediate = true)
...@@ -35,6 +44,10 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -35,6 +44,10 @@ public class OpenFlowControllerImpl implements OpenFlowController {
35 private static final Logger log = 44 private static final Logger log =
36 LoggerFactory.getLogger(OpenFlowControllerImpl.class); 45 LoggerFactory.getLogger(OpenFlowControllerImpl.class);
37 46
47 + private final ExecutorService executor = Executors.newFixedThreadPool(16,
48 + namedThreads("of-event-dispatch-%d"));
49 +
50 +
38 protected ConcurrentHashMap<Dpid, OpenFlowSwitch> connectedSwitches = 51 protected ConcurrentHashMap<Dpid, OpenFlowSwitch> connectedSwitches =
39 new ConcurrentHashMap<Dpid, OpenFlowSwitch>(); 52 new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
40 protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeMasterSwitches = 53 protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeMasterSwitches =
...@@ -43,11 +56,12 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -43,11 +56,12 @@ public class OpenFlowControllerImpl implements OpenFlowController {
43 new ConcurrentHashMap<Dpid, OpenFlowSwitch>(); 56 new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
44 57
45 protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent(); 58 protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
46 - protected Set<OpenFlowSwitchListener> ofEventListener = new HashSet<>(); 59 + protected Set<OpenFlowSwitchListener> ofSwitchListener = new HashSet<>();
47 60
48 protected Multimap<Integer, PacketListener> ofPacketListener = 61 protected Multimap<Integer, PacketListener> ofPacketListener =
49 ArrayListMultimap.create(); 62 ArrayListMultimap.create();
50 63
64 + protected Map<OFType, List<OpenFlowEventListener>> ofEventListener = Maps.newHashMap();
51 65
52 private final Controller ctrl = new Controller(); 66 private final Controller ctrl = new Controller();
53 67
...@@ -93,14 +107,14 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -93,14 +107,14 @@ public class OpenFlowControllerImpl implements OpenFlowController {
93 107
94 @Override 108 @Override
95 public void addListener(OpenFlowSwitchListener listener) { 109 public void addListener(OpenFlowSwitchListener listener) {
96 - if (!ofEventListener.contains(listener)) { 110 + if (!ofSwitchListener.contains(listener)) {
97 - this.ofEventListener.add(listener); 111 + this.ofSwitchListener.add(listener);
98 } 112 }
99 } 113 }
100 114
101 @Override 115 @Override
102 public void removeListener(OpenFlowSwitchListener listener) { 116 public void removeListener(OpenFlowSwitchListener listener) {
103 - this.ofEventListener.remove(listener); 117 + this.ofSwitchListener.remove(listener);
104 } 118 }
105 119
106 @Override 120 @Override
...@@ -122,7 +136,7 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -122,7 +136,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
122 public void processPacket(Dpid dpid, OFMessage msg) { 136 public void processPacket(Dpid dpid, OFMessage msg) {
123 switch (msg.getType()) { 137 switch (msg.getType()) {
124 case PORT_STATUS: 138 case PORT_STATUS:
125 - for (OpenFlowSwitchListener l : ofEventListener) { 139 + for (OpenFlowSwitchListener l : ofSwitchListener) {
126 l.portChanged(dpid, (OFPortStatus) msg); 140 l.portChanged(dpid, (OFPortStatus) msg);
127 } 141 }
128 break; 142 break;
...@@ -134,6 +148,12 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -134,6 +148,12 @@ public class OpenFlowControllerImpl implements OpenFlowController {
134 p.handlePacket(pktCtx); 148 p.handlePacket(pktCtx);
135 } 149 }
136 break; 150 break;
151 + case FLOW_REMOVED:
152 + case ERROR:
153 + case STATS_REPLY:
154 + case BARRIER_REPLY:
155 + executor.submit(new OFMessageHandler(dpid, msg));
156 + break;
137 default: 157 default:
138 log.warn("Handling message type {} not yet implemented {}", 158 log.warn("Handling message type {} not yet implemented {}",
139 msg.getType(), msg); 159 msg.getType(), msg);
...@@ -164,7 +184,7 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -164,7 +184,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
164 } else { 184 } else {
165 log.error("Added switch {}", dpid); 185 log.error("Added switch {}", dpid);
166 connectedSwitches.put(dpid, sw); 186 connectedSwitches.put(dpid, sw);
167 - for (OpenFlowSwitchListener l : ofEventListener) { 187 + for (OpenFlowSwitchListener l : ofSwitchListener) {
168 l.switchAdded(dpid); 188 l.switchAdded(dpid);
169 } 189 }
170 return true; 190 return true;
...@@ -277,7 +297,7 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -277,7 +297,7 @@ public class OpenFlowControllerImpl implements OpenFlowController {
277 if (sw == null) { 297 if (sw == null) {
278 sw = activeEqualSwitches.remove(dpid); 298 sw = activeEqualSwitches.remove(dpid);
279 } 299 }
280 - for (OpenFlowSwitchListener l : ofEventListener) { 300 + for (OpenFlowSwitchListener l : ofSwitchListener) {
281 l.switchRemoved(dpid); 301 l.switchRemoved(dpid);
282 } 302 }
283 } 303 }
...@@ -288,5 +308,26 @@ public class OpenFlowControllerImpl implements OpenFlowController { ...@@ -288,5 +308,26 @@ public class OpenFlowControllerImpl implements OpenFlowController {
288 } 308 }
289 } 309 }
290 310
311 + private final class OFMessageHandler implements Runnable {
312 +
313 + private final OFMessage msg;
314 + private final Dpid dpid;
315 +
316 + public OFMessageHandler(Dpid dpid, OFMessage msg) {
317 + this.msg = msg;
318 + this.dpid = dpid;
319 + }
320 +
321 + @Override
322 + public void run() {
323 + List<OpenFlowEventListener> listeners =
324 + ofEventListener.get(OFType.FLOW_REMOVED);
325 + for (OpenFlowEventListener listener : listeners) {
326 + listener.handleMessage(dpid, msg);
327 + }
328 + }
329 +
330 + }
331 +
291 332
292 } 333 }
......
...@@ -46,7 +46,7 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext { ...@@ -46,7 +46,7 @@ public class OpenFlowCorePacketContext extends DefaultPacketContext {
46 private void sendBufferedPacket() { 46 private void sendBufferedPacket() {
47 List<Instruction> ins = treatmentBuilder().build().instructions(); 47 List<Instruction> ins = treatmentBuilder().build().instructions();
48 OFPort p = null; 48 OFPort p = null;
49 - //TODO: support arbitrary list of treatments 49 + //TODO: support arbitrary list of treatments must be supported in ofPacketContext
50 for (Instruction i : ins) { 50 for (Instruction i : ins) {
51 if (i.type() == Type.OUTPUT) { 51 if (i.type() == Type.OUTPUT) {
52 p = buildPort(((OutputInstruction) i).port()); 52 p = buildPort(((OutputInstruction) i).port());
......
...@@ -118,7 +118,7 @@ public final class IpAddress { ...@@ -118,7 +118,7 @@ public final class IpAddress {
118 if (mask > MAX_INET_MASK) { 118 if (mask > MAX_INET_MASK) {
119 throw new IllegalArgumentException( 119 throw new IllegalArgumentException(
120 "Value of subnet mask cannot exceed " 120 "Value of subnet mask cannot exceed "
121 - + MAX_INET_MASK); 121 + + MAX_INET_MASK);
122 } 122 }
123 } 123 }
124 124
...@@ -200,7 +200,7 @@ public final class IpAddress { ...@@ -200,7 +200,7 @@ public final class IpAddress {
200 byte [] net = new byte [4]; 200 byte [] net = new byte [4];
201 byte [] mask = bytes(mask()); 201 byte [] mask = bytes(mask());
202 for (int i = 0; i < INET_LEN; i++) { 202 for (int i = 0; i < INET_LEN; i++) {
203 - net[i] = (byte) (octets[i] & mask[i]); 203 + net[i] = (byte) (octets[i] & mask[i]);
204 } 204 }
205 return new IpAddress(version, net, netmask); 205 return new IpAddress(version, net, netmask);
206 } 206 }
...@@ -221,11 +221,15 @@ public final class IpAddress { ...@@ -221,11 +221,15 @@ public final class IpAddress {
221 byte [] host = new byte [INET_LEN]; 221 byte [] host = new byte [INET_LEN];
222 byte [] mask = bytes(mask()); 222 byte [] mask = bytes(mask());
223 for (int i = 0; i < INET_LEN; i++) { 223 for (int i = 0; i < INET_LEN; i++) {
224 - host[i] = (byte) (octets[i] & ~mask[i]); 224 + host[i] = (byte) (octets[i] & ~mask[i]);
225 } 225 }
226 return new IpAddress(version, host, netmask); 226 return new IpAddress(version, host, netmask);
227 } 227 }
228 228
229 + public boolean isMasked() {
230 + return mask() != 0;
231 + }
232 +
229 @Override 233 @Override
230 public int hashCode() { 234 public int hashCode() {
231 final int prime = 31; 235 final int prime = 31;
......