blob: b7ba4c745525bfd415346651698f4194f804dfe6 [file] [log] [blame]
alshabib54ebd9c2014-08-27 18:38:41 -07001package org.onlab.onos.of.controller.impl.internal;
2
3import java.util.ArrayList;
4import java.util.concurrent.ConcurrentHashMap;
5import java.util.concurrent.locks.Lock;
6import java.util.concurrent.locks.ReentrantLock;
7
8import 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.Service;
12import org.onlab.onos.of.controller.Dpid;
13import org.onlab.onos.of.controller.OpenFlowController;
14import org.onlab.onos.of.controller.OpenFlowSwitch;
15import org.onlab.onos.of.controller.OpenFlowSwitchListener;
16import org.onlab.onos.of.controller.PacketListener;
17import org.onlab.onos.of.controller.RoleState;
alshabib6171f182014-09-02 19:00:32 -070018import org.onlab.onos.of.controller.driver.AbstractOpenFlowSwitch;
19import org.onlab.onos.of.controller.driver.OpenFlowAgent;
alshabib54ebd9c2014-08-27 18:38:41 -070020import org.projectfloodlight.openflow.protocol.OFMessage;
alshabib54ebd9c2014-08-27 18:38:41 -070021import org.slf4j.Logger;
22import org.slf4j.LoggerFactory;
23
24@Component(immediate = true)
25@Service
26public class OpenFlowControllerImpl implements OpenFlowController {
27
alshabibd777b202014-08-28 17:52:55 -070028 private static final Logger log =
29 LoggerFactory.getLogger(OpenFlowControllerImpl.class);
30
alshabib6171f182014-09-02 19:00:32 -070031 protected ConcurrentHashMap<Dpid, OpenFlowSwitch> connectedSwitches =
32 new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
33 protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeMasterSwitches =
34 new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
35 protected ConcurrentHashMap<Dpid, OpenFlowSwitch> activeEqualSwitches =
36 new ConcurrentHashMap<Dpid, OpenFlowSwitch>();
alshabib54ebd9c2014-08-27 18:38:41 -070037
38 protected OpenFlowSwitchAgent agent = new OpenFlowSwitchAgent();
alshabibd777b202014-08-28 17:52:55 -070039 protected ArrayList<OpenFlowSwitchListener> ofEventListener =
40 new ArrayList<OpenFlowSwitchListener>();
alshabib54ebd9c2014-08-27 18:38:41 -070041
42 private final Controller ctrl = new Controller();
43
44 @Activate
45 public void activate() {
46 ctrl.start(agent);
47 }
48
49 @Deactivate
50 public void deactivate() {
51 ctrl.stop();
52 }
53
54 @Override
55 public Iterable<OpenFlowSwitch> getSwitches() {
56 return connectedSwitches.values();
57 }
58
59 @Override
60 public Iterable<OpenFlowSwitch> getMasterSwitches() {
61 return activeMasterSwitches.values();
62 }
63
64 @Override
65 public Iterable<OpenFlowSwitch> getEqualSwitches() {
66 return activeEqualSwitches.values();
67 }
68
69 @Override
70 public OpenFlowSwitch getSwitch(Dpid dpid) {
71 return connectedSwitches.get(dpid.value());
72 }
73
74 @Override
75 public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
76 return activeMasterSwitches.get(dpid.value());
77 }
78
79 @Override
80 public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
81 return activeEqualSwitches.get(dpid.value()); }
82
83 @Override
84 public void addListener(OpenFlowSwitchListener listener) {
85 if (!ofEventListener.contains(listener)) {
86 this.ofEventListener.add(listener);
87 }
88 }
89
90 @Override
91 public void removeListener(OpenFlowSwitchListener listener) {
92 this.ofEventListener.remove(listener);
93 }
94
95 @Override
96 public void addPacketListener(int priority, PacketListener listener) {
97 // TODO Auto-generated method stub
98
99 }
100
101 @Override
102 public void removePacketListener(PacketListener listener) {
103 // TODO Auto-generated method stub
104
105 }
106
107 @Override
108 public void write(Dpid dpid, OFMessage msg) {
alshabibd777b202014-08-28 17:52:55 -0700109 this.getSwitch(dpid).sendMsg(msg);
alshabib54ebd9c2014-08-27 18:38:41 -0700110 }
111
112 @Override
113 public void processPacket(OFMessage msg) {
alshabibd777b202014-08-28 17:52:55 -0700114 log.info("Got message {}", msg);
alshabib54ebd9c2014-08-27 18:38:41 -0700115 }
116
117 @Override
118 public void setRole(Dpid dpid, RoleState role) {
alshabibd777b202014-08-28 17:52:55 -0700119 ((AbstractOpenFlowSwitch) getSwitch(dpid)).setRole(role);
alshabib54ebd9c2014-08-27 18:38:41 -0700120 }
121
alshabib6171f182014-09-02 19:00:32 -0700122 public class OpenFlowSwitchAgent implements OpenFlowAgent {
alshabib54ebd9c2014-08-27 18:38:41 -0700123
124 private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class);
alshabib6171f182014-09-02 19:00:32 -0700125 private final Lock switchLock = new ReentrantLock();
alshabib54ebd9c2014-08-27 18:38:41 -0700126
alshabib6171f182014-09-02 19:00:32 -0700127 @Override
128 public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
alshabib54ebd9c2014-08-27 18:38:41 -0700129 if (connectedSwitches.get(dpid) != null) {
130 log.error("Trying to add connectedSwitch but found a previous "
131 + "value for dpid: {}", dpid);
132 return false;
133 } else {
134 log.error("Added switch {}", dpid);
135 connectedSwitches.put(dpid, sw);
136 for (OpenFlowSwitchListener l : ofEventListener) {
alshabib6171f182014-09-02 19:00:32 -0700137 l.switchAdded(dpid);
alshabib54ebd9c2014-08-27 18:38:41 -0700138 }
139 return true;
140 }
141 }
142
alshabib6171f182014-09-02 19:00:32 -0700143 @Override
144 public boolean validActivation(Dpid dpid) {
alshabib54ebd9c2014-08-27 18:38:41 -0700145 if (connectedSwitches.get(dpid) == null) {
146 log.error("Trying to activate switch but is not in "
147 + "connected switches: dpid {}. Aborting ..",
alshabib6171f182014-09-02 19:00:32 -0700148 dpid);
alshabib54ebd9c2014-08-27 18:38:41 -0700149 return false;
150 }
151 if (activeMasterSwitches.get(dpid) != null ||
152 activeEqualSwitches.get(dpid) != null) {
153 log.error("Trying to activate switch but it is already "
154 + "activated: dpid {}. Found in activeMaster: {} "
155 + "Found in activeEqual: {}. Aborting ..", new Object[] {
alshabib6171f182014-09-02 19:00:32 -0700156 dpid,
alshabib54ebd9c2014-08-27 18:38:41 -0700157 (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
alshabib6171f182014-09-02 19:00:32 -0700158 (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
alshabib54ebd9c2014-08-27 18:38:41 -0700159 return false;
160 }
161 return true;
162 }
163
alshabib6171f182014-09-02 19:00:32 -0700164
165 @Override
166 public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) {
alshabib54ebd9c2014-08-27 18:38:41 -0700167 switchLock.lock();
168 try {
169 if (!validActivation(dpid)) {
170 return false;
171 }
172 activeMasterSwitches.put(dpid, sw);
173 return true;
174 } finally {
175 switchLock.unlock();
176 }
alshabib6171f182014-09-02 19:00:32 -0700177 }
alshabib54ebd9c2014-08-27 18:38:41 -0700178
alshabib6171f182014-09-02 19:00:32 -0700179 @Override
180 public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) {
alshabib54ebd9c2014-08-27 18:38:41 -0700181 switchLock.lock();
182 try {
alshabib6171f182014-09-02 19:00:32 -0700183 if (!validActivation(dpid)) {
184 return false;
185 }
186 activeEqualSwitches.put(dpid, sw);
187 log.info("Added Activated EQUAL Switch {}", dpid);
188 return true;
alshabib54ebd9c2014-08-27 18:38:41 -0700189 } finally {
190 switchLock.unlock();
191 }
192 }
193
alshabib6171f182014-09-02 19:00:32 -0700194 @Override
195 public void transitionToMasterSwitch(Dpid dpid) {
alshabib54ebd9c2014-08-27 18:38:41 -0700196 switchLock.lock();
197 try {
alshabibd777b202014-08-28 17:52:55 -0700198 if (activeMasterSwitches.containsKey(dpid)) {
199 return;
200 }
alshabib54ebd9c2014-08-27 18:38:41 -0700201 OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
202 if (sw == null) {
203 log.error("Transition to master called on sw {}, but switch "
204 + "was not found in controller-cache", dpid);
205 return;
206 }
207 activeMasterSwitches.put(dpid, sw);
208 } finally {
209 switchLock.unlock();
210 }
211 }
212
213
alshabib6171f182014-09-02 19:00:32 -0700214 @Override
215 public void transitionToEqualSwitch(Dpid dpid) {
alshabib54ebd9c2014-08-27 18:38:41 -0700216 switchLock.lock();
217 try {
alshabibd777b202014-08-28 17:52:55 -0700218 if (activeEqualSwitches.containsKey(dpid)) {
219 return;
220 }
alshabib54ebd9c2014-08-27 18:38:41 -0700221 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
222 if (sw == null) {
223 log.error("Transition to equal called on sw {}, but switch "
224 + "was not found in controller-cache", dpid);
225 return;
226 }
227 activeEqualSwitches.put(dpid, sw);
228 } finally {
229 switchLock.unlock();
230 }
231
232 }
233
alshabib6171f182014-09-02 19:00:32 -0700234 @Override
235 public void removeConnectedSwitch(Dpid dpid) {
alshabib54ebd9c2014-08-27 18:38:41 -0700236 connectedSwitches.remove(dpid);
237 OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
238 if (sw == null) {
239 sw = activeEqualSwitches.remove(dpid);
240 }
241 for (OpenFlowSwitchListener l : ofEventListener) {
alshabib6171f182014-09-02 19:00:32 -0700242 l.switchRemoved(dpid);
alshabib54ebd9c2014-08-27 18:38:41 -0700243 }
244 }
245
alshabib6171f182014-09-02 19:00:32 -0700246 @Override
alshabib54ebd9c2014-08-27 18:38:41 -0700247 public void processMessage(OFMessage m) {
248 processPacket(m);
249 }
250 }
251
252
253
254}