blob: a91c96fbc524b07adcd5359d26b04ed699497499 [file] [log] [blame]
pingping-lina2cbfad2013-03-07 08:39:21 +08001package net.floodlightcontroller.bgproute;
2
Jonathan Harte7e1c6e2013-06-04 20:50:23 -07003import java.io.IOException;
4import java.net.InetAddress;
Jonathan Hart61ba9372013-05-19 20:10:29 -07005import java.net.UnknownHostException;
pingping-lina2cbfad2013-03-07 08:39:21 +08006import java.util.ArrayList;
Jonathan Hart61ba9372013-05-19 20:10:29 -07007import java.util.Collection;
pingping-lina2cbfad2013-03-07 08:39:21 +08008import java.util.HashMap;
Jonathan Harte7e1c6e2013-06-04 20:50:23 -07009import java.util.HashSet;
10import java.util.List;
Jonathan Hart61ba9372013-05-19 20:10:29 -070011import java.util.Map;
Jonathan Harte7e1c6e2013-06-04 20:50:23 -070012import java.util.Set;
pingping-lina2cbfad2013-03-07 08:39:21 +080013
Jonathan Hart61ba9372013-05-19 20:10:29 -070014import net.floodlightcontroller.core.IFloodlightProviderService;
Jonathan Harte7e1c6e2013-06-04 20:50:23 -070015import net.floodlightcontroller.core.INetMapTopologyService.ITopoRouteService;
16import net.floodlightcontroller.core.IOFSwitch;
pingping-lina2cbfad2013-03-07 08:39:21 +080017import net.floodlightcontroller.core.module.FloodlightModuleContext;
18import net.floodlightcontroller.core.module.FloodlightModuleException;
19import net.floodlightcontroller.core.module.IFloodlightModule;
20import net.floodlightcontroller.core.module.IFloodlightService;
Jonathan Harte7e1c6e2013-06-04 20:50:23 -070021import net.floodlightcontroller.devicemanager.IDeviceService;
22import net.floodlightcontroller.packet.Ethernet;
pingping-lina2cbfad2013-03-07 08:39:21 +080023import net.floodlightcontroller.restserver.IRestApiService;
24import net.floodlightcontroller.topology.ITopologyListener;
25import net.floodlightcontroller.topology.ITopologyService;
Jonathan Harte7e1c6e2013-06-04 20:50:23 -070026import net.floodlightcontroller.util.DataPath;
27import net.floodlightcontroller.util.Dpid;
28import net.floodlightcontroller.util.FlowEntry;
29import net.floodlightcontroller.util.IPv4;
30import net.floodlightcontroller.util.MACAddress;
31import net.floodlightcontroller.util.Port;
32import net.floodlightcontroller.util.SwitchPort;
pingping-line2a09ca2013-03-23 09:33:58 +080033import net.sf.json.JSONArray;
34import net.sf.json.JSONObject;
35import net.sf.json.JSONSerializer;
pingping-lina2cbfad2013-03-07 08:39:21 +080036
Jonathan Harte7e1c6e2013-06-04 20:50:23 -070037import org.openflow.protocol.OFFlowMod;
38import org.openflow.protocol.OFMatch;
39import org.openflow.protocol.OFMessage;
40import org.openflow.protocol.OFPacketOut;
41import org.openflow.protocol.OFType;
42import org.openflow.protocol.action.OFAction;
43import org.openflow.protocol.action.OFActionDataLayerDestination;
44import org.openflow.protocol.action.OFActionOutput;
pingping-lina2cbfad2013-03-07 08:39:21 +080045import org.slf4j.Logger;
46import org.slf4j.LoggerFactory;
47
Jonathan Harte7e1c6e2013-06-04 20:50:23 -070048import com.google.common.net.InetAddresses;
49
pingping-lina2cbfad2013-03-07 08:39:21 +080050public class BgpRoute implements IFloodlightModule, IBgpRouteService, ITopologyListener {
51
52 protected static Logger log = LoggerFactory.getLogger(BgpRoute.class);
53
54 protected IFloodlightProviderService floodlightProvider;
55 protected ITopologyService topology;
Jonathan Harte7e1c6e2013-06-04 20:50:23 -070056 protected ITopoRouteService topoRouteService;
57 protected IDeviceService devices;
58 protected IRestApiService restApi;
59
pingping-lina2cbfad2013-03-07 08:39:21 +080060
61 protected static Ptree ptree;
Jonathan Hart61ba9372013-05-19 20:10:29 -070062 protected String bgpdRestIp;
63 protected String routerId;
pingping-line2a09ca2013-03-23 09:33:58 +080064
Jonathan Harte7e1c6e2013-06-04 20:50:23 -070065 protected Set<InetAddress> routerIpAddresses;
66
67 //We need to identify our flows somehow. But like it says in LearningSwitch.java,
68 //the controller/OS should hand out cookie IDs to prevent conflicts.
69 protected final long APP_COOKIE = 0xa0000000000000L;
70 //Cookie for flows that do L2 forwarding within SDN domain to egress routers
71 protected final long L2_FWD_COOKIE = APP_COOKIE + 1;
72 //Cookie for flows in ingress switches that rewrite the MAC address
73 protected final long MAC_RW_COOKIE = APP_COOKIE + 2;
74
75 //TODO temporary
76 protected List<GatewayRouter> gatewayRouters;
77
78 private void initGateways(){
79 gatewayRouters = new ArrayList<GatewayRouter>();
80 //00:00:00:00:00:00:0s0:a3 port 1
81 gatewayRouters.add(
82 new GatewayRouter(new SwitchPort(new Dpid(163L), new Port((short)1)),
83 new MACAddress(new byte[] {0x00, 0x00, 0x00, 0x00, 0x02, 0x01}),
84 new IPv4("192.168.10.1")));
85 //00:00:00:00:00:00:00:a5 port 1
86 //gatewayRouters.add(new SwitchPort(new Dpid(165L), new Port((short)1)));
87 gatewayRouters.add(
88 new GatewayRouter(new SwitchPort(new Dpid(165L), new Port((short)1)),
89 new MACAddress(new byte[] {0x00, 0x00, 0x00, 0x00, 0x02, 0x02}),
90 new IPv4("192.168.20.1")));
91 //00:00:00:00:00:00:00:a2 port 1
92 //gatewayRouters.add(new SwitchPort(new Dpid(162L), new Port((short)1)));
93 gatewayRouters.add(
94 new GatewayRouter(new SwitchPort(new Dpid(162L), new Port((short)1)),
95 new MACAddress(new byte[] {0x00, 0x00, 0x00, 0x00, 0x03, 0x01}),
96 new IPv4("192.168.30.1")));
97 //00:00:00:00:00:00:00:a6
98 //gatewayRouters.add(new SwitchPort(new Dpid(166L), new Port((short)1)));
99 gatewayRouters.add(
100 new GatewayRouter(new SwitchPort(new Dpid(166L), new Port((short)1)),
101 new MACAddress(new byte[] {0x00, 0x00, 0x00, 0x00, 0x04, 0x01}),
102 new IPv4("192.168.40.1")));
103
104 }
pingping-lina2cbfad2013-03-07 08:39:21 +0800105
106 @Override
107 public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Jonathan Hart61ba9372013-05-19 20:10:29 -0700108 Collection<Class<? extends IFloodlightService>> l
109 = new ArrayList<Class<? extends IFloodlightService>>();
pingping-lina2cbfad2013-03-07 08:39:21 +0800110 l.add(IBgpRouteService.class);
111 return l;
112 }
113
114 @Override
115 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Jonathan Hart61ba9372013-05-19 20:10:29 -0700116 Map<Class<? extends IFloodlightService>, IFloodlightService> m
117 = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
pingping-line2a09ca2013-03-23 09:33:58 +0800118 m.put(IBgpRouteService.class, this);
pingping-lina2cbfad2013-03-07 08:39:21 +0800119 return m;
120 }
121
pingping-lina2cbfad2013-03-07 08:39:21 +0800122 @Override
123 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Jonathan Hart61ba9372013-05-19 20:10:29 -0700124 Collection<Class<? extends IFloodlightService>> l
125 = new ArrayList<Class<? extends IFloodlightService>>();
pingping-lina2cbfad2013-03-07 08:39:21 +0800126 l.add(IFloodlightProviderService.class);
127 l.add(ITopologyService.class);
Jonathan Harte7e1c6e2013-06-04 20:50:23 -0700128 l.add(ITopoRouteService.class);
129 l.add(IDeviceService.class);
130 l.add(IRestApiService.class);
131 //l.add(IBgpRouteService.class);
pingping-lina2cbfad2013-03-07 08:39:21 +0800132 return l;
133 }
134
135 @Override
136 public void init(FloodlightModuleContext context)
137 throws FloodlightModuleException {
138
Jonathan Harte7e1c6e2013-06-04 20:50:23 -0700139 initGateways();
140
pingping-lina2cbfad2013-03-07 08:39:21 +0800141 ptree = new Ptree(32);
Jonathan Harte7e1c6e2013-06-04 20:50:23 -0700142
143 routerIpAddresses = new HashSet<InetAddress>();
pingping-lina2cbfad2013-03-07 08:39:21 +0800144
145 // Register floodlight provider and REST handler.
146 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
pingping-lina2cbfad2013-03-07 08:39:21 +0800147 topology = context.getServiceImpl(ITopologyService.class);
Jonathan Harte7e1c6e2013-06-04 20:50:23 -0700148 topoRouteService = context.getServiceImpl(ITopoRouteService.class);
149 devices = context.getServiceImpl(IDeviceService.class);
150 restApi = context.getServiceImpl(IRestApiService.class);
pingping-lina2cbfad2013-03-07 08:39:21 +0800151
Jonathan Hart61ba9372013-05-19 20:10:29 -0700152 //Read in config values
153 bgpdRestIp = context.getConfigParams(this).get("BgpdRestIp");
154 if (bgpdRestIp == null){
155 log.error("BgpdRestIp property not found in config file");
156 System.exit(1);
157 }
158 else {
159 log.info("BgpdRestIp set to {}", bgpdRestIp);
160 }
161
162 routerId = context.getConfigParams(this).get("RouterId");
163 if (routerId == null){
164 log.error("RouterId property not found in config file");
165 System.exit(1);
166 }
167 else {
168 log.info("RouterId set to {}", routerId);
169 }
pingping-lina2cbfad2013-03-07 08:39:21 +0800170 // Test.
171 //test();
172 }
173
174 public Ptree getPtree() {
175 return ptree;
176 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700177
178 public void clearPtree() {
179 //ptree = null;
180 ptree = new Ptree(32);
pingping-line2a09ca2013-03-23 09:33:58 +0800181 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700182
pingping-line2a09ca2013-03-23 09:33:58 +0800183 public String getBGPdRestIp() {
Jonathan Hart61ba9372013-05-19 20:10:29 -0700184 return bgpdRestIp;
pingping-line2a09ca2013-03-23 09:33:58 +0800185 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700186
pingping-line2a09ca2013-03-23 09:33:58 +0800187 public String getRouterId() {
Jonathan Hart61ba9372013-05-19 20:10:29 -0700188 return routerId;
pingping-line2a09ca2013-03-23 09:33:58 +0800189 }
pingping-lina2cbfad2013-03-07 08:39:21 +0800190
191 // Return nexthop address as byte array.
192 public Rib lookupRib(byte[] dest) {
193 if (ptree == null) {
194 log.debug("lookupRib: ptree null");
195 return null;
196 }
197
198 PtreeNode node = ptree.match(dest, 32);
199 if (node == null) {
200 log.debug("lookupRib: ptree node null");
201 return null;
202 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700203
pingping-lina2cbfad2013-03-07 08:39:21 +0800204 if (node.rib == null) {
205 log.debug("lookupRib: ptree rib null");
206 return null;
207 }
Jonathan Hart61ba9372013-05-19 20:10:29 -0700208
pingping-lina2cbfad2013-03-07 08:39:21 +0800209 ptree.delReference(node);
210
211 return node.rib;
212 }
213
Jonathan Hart61ba9372013-05-19 20:10:29 -0700214 //TODO looks like this should be a unit test
pingping-lina2cbfad2013-03-07 08:39:21 +0800215 @SuppressWarnings("unused")
Jonathan Hart61ba9372013-05-19 20:10:29 -0700216 private void test() throws UnknownHostException {
pingping-lina2cbfad2013-03-07 08:39:21 +0800217 System.out.println("Here it is");
218 Prefix p = new Prefix("128.0.0.0", 8);
219 Prefix q = new Prefix("8.0.0.0", 8);
220 Prefix r = new Prefix("10.0.0.0", 24);
221 Prefix a = new Prefix("10.0.0.1", 32);
222
223 ptree.acquire(p.getAddress(), p.masklen);
224 ptree.acquire(q.getAddress(), q.masklen);
225 ptree.acquire(r.getAddress(), r.masklen);
226
227 System.out.println("Traverse start");
228 for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
229 Prefix p_result = new Prefix(node.key, node.keyBits);
230 }
231
232 PtreeNode n = ptree.match(a.getAddress(), a.masklen);
233 if (n != null) {
234 System.out.println("Matched prefix for 10.0.0.1:");
235 Prefix x = new Prefix(n.key, n.keyBits);
236 ptree.delReference(n);
237 }
238
239 n = ptree.lookup(p.getAddress(), p.masklen);
240 if (n != null) {
241 ptree.delReference(n);
242 ptree.delReference(n);
243 }
244 System.out.println("Traverse start");
245 for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
246 Prefix p_result = new Prefix(node.key, node.keyBits);
247 }
248
249 n = ptree.lookup(q.getAddress(), q.masklen);
250 if (n != null) {
251 ptree.delReference(n);
252 ptree.delReference(n);
253 }
254 System.out.println("Traverse start");
255 for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
256 Prefix p_result = new Prefix(node.key, node.keyBits);
257 }
258
259 n = ptree.lookup(r.getAddress(), r.masklen);
260 if (n != null) {
261 ptree.delReference(n);
262 ptree.delReference(n);
263 }
264 System.out.println("Traverse start");
265 for (PtreeNode node = ptree.begin(); node != null; node = ptree.next(node)) {
266 Prefix p_result = new Prefix(node.key, node.keyBits);
267 }
268
269 }
270
Jonathan Hart61ba9372013-05-19 20:10:29 -0700271 private void retrieveRib(){
272 String url = "http://" + bgpdRestIp + "/wm/bgp/" + routerId;
273 String response = RestClient.get(url);
274
275 if (response.equals("")){
276 return;
277 }
278
279 response = response.replaceAll("\"", "'");
280 JSONObject jsonObj = (JSONObject) JSONSerializer.toJSON(response);
281 JSONArray rib_json_array = jsonObj.getJSONArray("rib");
282 String router_id = jsonObj.getString("router-id");
283
284 int size = rib_json_array.size();
285
286 log.info("Retrived RIB of {} entries from BGPd", size);
287
288 for (int j = 0; j < size; j++) {
289 JSONObject second_json_object = rib_json_array.getJSONObject(j);
290 String prefix = second_json_object.getString("prefix");
291 String nexthop = second_json_object.getString("nexthop");
292
293 //insert each rib entry into the local rib;
294 String[] substring = prefix.split("/");
295 String prefix1 = substring[0];
296 String mask1 = substring[1];
297
298 Prefix p;
299 try {
300 p = new Prefix(prefix1, Integer.valueOf(mask1));
301 } catch (NumberFormatException e) {
302 log.warn("Wrong mask format in RIB JSON: {}", mask1);
303 continue;
304 } catch (UnknownHostException e1) {
305 log.warn("Wrong prefix format in RIB JSON: {}", prefix1);
306 continue;
307 }
308
309 PtreeNode node = ptree.acquire(p.getAddress(), p.masklen);
310 Rib rib = new Rib(router_id, nexthop, p.masklen);
311
312 if (node.rib != null) {
313 node.rib = null;
314 ptree.delReference(node);
315 }
316
317 node.rib = rib;
Jonathan Harte7e1c6e2013-06-04 20:50:23 -0700318
319 newPrefix(node);
Jonathan Hart61ba9372013-05-19 20:10:29 -0700320 }
321 }
322
Jonathan Harte7e1c6e2013-06-04 20:50:23 -0700323 private void newPrefix(PtreeNode node) {
324 //Add a flow to rewrite mac for this prefix to all border switches
325 GatewayRouter thisRouter = null;
326 for (GatewayRouter router : gatewayRouters){
327 log.debug("Matching router ip {} with RIB routerId {}",
328 router.getRouterIp().value(), InetAddresses.coerceToInteger(node.rib.routerId));
329
330 if (router.getRouterIp().value() == InetAddresses.coerceToInteger(node.rib.routerId)){
331 thisRouter = router;
332 break;
333 }
334 }
335
336 if (thisRouter == null){
337 log.error("Couldn't find advertising router in router list for prefix {}", node.rib);
338 return; //just quit out here? This is probably a configuration error
339 }
340
341 for (GatewayRouter ingressRouter : gatewayRouters){
342 if (ingressRouter == thisRouter) {
343 continue;
344 }
345
346 DataPath shortestPath = topoRouteService.getShortestPath(
347 ingressRouter.getAttachmentPoint(), thisRouter.getAttachmentPoint());
348
349 if (shortestPath == null){
350 log.debug("Shortest path between {} and {} not found",
351 ingressRouter.getAttachmentPoint(), thisRouter.getAttachmentPoint());
352 return; // just quit here?
353 }
354
355 //TODO check the shortest path against the cached version we
356 //calculated before. If they don't match up that's a problem
357
358 //Set up the flow mod
359 OFFlowMod fm =
360 (OFFlowMod) floodlightProvider.getOFMessageFactory()
361 .getMessage(OFType.FLOW_MOD);
362
363 fm.setIdleTimeout((short)0)
364 .setHardTimeout((short)0)
365 .setBufferId(OFPacketOut.BUFFER_ID_NONE)
366 .setCookie(MAC_RW_COOKIE)
367 .setCommand(OFFlowMod.OFPFC_ADD)
368 //.setMatch(match)
369 //.setActions(actions)
370 .setLengthU(OFFlowMod.MINIMUM_LENGTH
371 + OFActionDataLayerDestination.MINIMUM_LENGTH
372 + OFActionOutput.MINIMUM_LENGTH);
373
374 OFMatch match = new OFMatch();
375 match.setDataLayerType(Ethernet.TYPE_IPv4);
376 //match.setNetworkDestination(InetAddresses.coerceToInteger(node.rib.getNextHop()));
377 //TODO set mask length
378
379 log.debug("finding prefix, {}", InetAddresses.fromInteger(node.keyBits).toString());
380 //match.setFromCIDR(node.keyBits, which)
381 //match.setw
382 //fm.setMatch(match);
383
384 //Set up MAC rewrite action
385 OFActionDataLayerDestination macRewriteAction = new OFActionDataLayerDestination();
386 macRewriteAction.setDataLayerAddress(thisRouter.getRouterMac().toBytes());
387
388 //Set up output action
389 OFActionOutput outputAction = new OFActionOutput();
390 outputAction.setMaxLength((short)0xffff); //TODO check what this is (and if needed for mac rewrite)
391
392 List<OFAction> actions = new ArrayList<OFAction>();
393 actions.add(macRewriteAction);
394 actions.add(outputAction);
395 fm.setActions(actions);
396
397 //Write to switch
398 IOFSwitch sw = floodlightProvider.getSwitches()
399 .get(ingressRouter.getAttachmentPoint().dpid().value());
400
401 if (sw == null){
402 log.warn("Switch not found when pushing flow mod");
403 continue;
404 }
405
406 List<OFMessage> msglist = new ArrayList<OFMessage>();
407 msglist.add(fm);
408 try {
409 sw.write(msglist, null);
410 sw.flush();
411 } catch (IOException e) {
412 log.error("Failure writing flow mod", e);
413 }
414 }
415 }
416
417 private void prefixDelete(PtreeNode node) {
418 //Remove MAC rewriting flows from other border switches
419 }
420
421 /*
422 * On startup we need to calculate a full mesh of paths between all gateway
423 * switches
424 */
425 private void calculateFullMesh(){
426 Map<IOFSwitch, SwitchPort> gatewaySwitches = new HashMap<IOFSwitch, SwitchPort>();
427
428 //have to account for switches not being there, paths not being found.
429
430 //for (SwitchPort switchPort : gatewayRouters){
431 for (GatewayRouter router : gatewayRouters){
432 SwitchPort switchPort = router.getAttachmentPoint();
433
434 IOFSwitch sw = floodlightProvider.getSwitches().get(switchPort.dpid().value());
435
436 if (sw == null){
437 log.debug("Gateway switch {} not here yet", switchPort.dpid().value());
438 return; // just quit here?
439 }
440
441 //Only need to know 1 external-facing port from each gateway switch
442 //which we can feed into shortest path calculation
443 if (!gatewaySwitches.containsKey(sw)){
444 gatewaySwitches.put(sw, switchPort);
445 }
446
447 }
448 log.debug("size {}", gatewaySwitches.size());
449
450 //For each border router, calculate and install a path from every other
451 //border switch to said border router. However, don't install the entry
452 //in to the first hop switch, as we need to install an entry to rewrite
453 //for each prefix received. This will be done later when prefixes have
454 //actually been received.
455
456 //for (Map.Entry<IOFSwitch, SwitchPort> src : gatewaySwitches.entrySet()){
457 for (GatewayRouter dstRouter : gatewayRouters){
458 SwitchPort routerAttachmentPoint = dstRouter.getAttachmentPoint();
459 for (Map.Entry<IOFSwitch, SwitchPort> src : gatewaySwitches.entrySet()) {
460 //List<IOFSwitch> switches = new ArrayList<IOFSwitch>(gatewaySwitches.keySet());
461
462 if (routerAttachmentPoint.dpid().value() ==
463 src.getKey().getId()){
464 continue;
465 }
466
467 DataPath shortestPath = topoRouteService.getShortestPath(
468 src.getValue(), routerAttachmentPoint);
469
470 if (shortestPath == null){
471 log.debug("Shortest path between {} and {} not found",
472 src.getValue(), routerAttachmentPoint);
473 return; // just quit here?
474 }
475
476 /*
477 List<FlowEntry> flowEntries = shortestPath.flowEntries();
478
479 for (FlowEntry e : shortestPath.flowEntries()){
480 log.debug("fish: {}" , e.dpid().toString());
481 }*/
482
483 //install flows
484 installPath(shortestPath.flowEntries(), dstRouter);
485 }
486 }
487 }
488
489 private void installPath(List<FlowEntry> flowEntries, GatewayRouter router){
490
491 //Set up the flow mod
492 OFFlowMod fm =
493 (OFFlowMod) floodlightProvider.getOFMessageFactory()
494 .getMessage(OFType.FLOW_MOD);
495
496 OFActionOutput action = new OFActionOutput();
497 action.setMaxLength((short)0xffff);
498 List<OFAction> actions = new ArrayList<OFAction>();
499 actions.add(action);
500
501 fm.setIdleTimeout((short)0)
502 .setHardTimeout((short)0)
503 .setBufferId(OFPacketOut.BUFFER_ID_NONE)
504 .setCookie(L2_FWD_COOKIE)
505 .setCommand(OFFlowMod.OFPFC_ADD)
506 //.setMatch(match)
507 .setActions(actions)
508 .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
509
510 //Don't push the first flow entry. We need to push entries in the
511 //first switch based on IP prefix which we don't know yet.
512 for (int i = 1; i < flowEntries.size(); i++){
513 FlowEntry flowEntry = flowEntries.get(i);
514
515 OFMatch match = new OFMatch();
516 match.setDataLayerDestination(router.getRouterMac().toBytes());
517 match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
518 ((OFActionOutput) fm.getActions().get(0)).setPort(flowEntry.outPort().value());
519
520 fm.setMatch(match);
521
522 IOFSwitch sw = floodlightProvider.getSwitches().get(flowEntry.dpid().value());
523
524 if (sw == null){
525 log.warn("Switch not found when pushing flow mod");
526 continue;
527 }
528
529 List<OFMessage> msglist = new ArrayList<OFMessage>();
530 msglist.add(fm);
531 try {
532 sw.write(msglist, null);
533 sw.flush();
534 } catch (IOException e) {
535 log.error("Failure writing flow mod", e);
536 }
537
538 try {
539 fm = fm.clone();
540 } catch (CloneNotSupportedException e1) {
541 log.error("Failure cloning flow mod", e1);
542 }
543 }
544 }
545
pingping-lina2cbfad2013-03-07 08:39:21 +0800546 @Override
547 public void startUp(FloodlightModuleContext context) {
pingping-line2a09ca2013-03-23 09:33:58 +0800548 restApi.addRestletRoutable(new BgpRouteWebRoutable());
Jonathan Hart61ba9372013-05-19 20:10:29 -0700549 topology.addListener(this);
pingping-line2a09ca2013-03-23 09:33:58 +0800550
Jonathan Hart61ba9372013-05-19 20:10:29 -0700551 //Retrieve the RIB from BGPd during startup
552 retrieveRib();
Jonathan Harte7e1c6e2013-06-04 20:50:23 -0700553
554 //Don't have to do this as we'll never have switches connected here
555 //calculateFullMesh();
pingping-lina2cbfad2013-03-07 08:39:21 +0800556 }
557
558 @Override
559 public void topologyChanged() {
Jonathan Harte7e1c6e2013-06-04 20:50:23 -0700560 //Probably need to look at all changes, not just port changes
561 /*
pingping-lina2cbfad2013-03-07 08:39:21 +0800562 boolean change = false;
563 String changelog = "";
564
565 for (LDUpdate ldu : topology.getLastLinkUpdates()) {
566 if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_DOWN)) {
567 change = true;
568 changelog = changelog + " down ";
569 } else if (ldu.getOperation().equals(ILinkDiscovery.UpdateOperation.PORT_UP)) {
570 change = true;
571 changelog = changelog + " up ";
572 }
573 }
574 log.info ("received topo change" + changelog);
575
576 if (change) {
Jonathan Hart61ba9372013-05-19 20:10:29 -0700577 //RestClient.get ("http://localhost:5000/topo_change");
pingping-lina2cbfad2013-03-07 08:39:21 +0800578 }
Jonathan Harte7e1c6e2013-06-04 20:50:23 -0700579 */
580 calculateFullMesh();
pingping-lina2cbfad2013-03-07 08:39:21 +0800581 }
582}