· 7 years ago · Dec 11, 2018, 11:40 AM
1package net.floodlightcontroller.cgrmodule;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Collections;
6import java.util.HashMap;
7import java.util.HashSet;
8import java.util.Iterator;
9import java.util.List;
10import java.util.Map;
11import java.util.Map.Entry;
12import java.util.Set;
13import java.util.concurrent.ConcurrentHashMap;
14
15import org.projectfloodlight.openflow.protocol.OFFlowMod;
16import org.projectfloodlight.openflow.protocol.OFFlowModCommand;
17import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
18import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
19import org.projectfloodlight.openflow.protocol.OFMessage;
20import org.projectfloodlight.openflow.protocol.OFPacketIn;
21import org.projectfloodlight.openflow.protocol.OFPacketOut;
22import org.projectfloodlight.openflow.protocol.OFType;
23import org.projectfloodlight.openflow.protocol.OFVersion;
24import org.projectfloodlight.openflow.protocol.action.OFAction;
25import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
26import org.projectfloodlight.openflow.protocol.action.OFActions;
27import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
28import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions;
29import org.projectfloodlight.openflow.protocol.instruction.OFInstructions;
30import org.projectfloodlight.openflow.protocol.match.Match;
31import org.projectfloodlight.openflow.protocol.match.MatchField;
32import org.projectfloodlight.openflow.types.EthType;
33import org.projectfloodlight.openflow.types.IPv4Address;
34import org.projectfloodlight.openflow.types.IpProtocol;
35import org.projectfloodlight.openflow.types.MacAddress;
36import org.projectfloodlight.openflow.types.OFBufferId;
37import org.projectfloodlight.openflow.types.OFPort;
38import org.projectfloodlight.openflow.types.OFVlanVidMatch;
39import org.projectfloodlight.openflow.types.TableId;
40import org.projectfloodlight.openflow.types.TransportPort;
41import org.projectfloodlight.openflow.types.U64;
42import org.projectfloodlight.openflow.types.VlanVid;
43import org.projectfloodlight.openflow.util.LRULinkedHashMap;
44import org.slf4j.Logger;
45import org.slf4j.LoggerFactory;
46
47import javafx.util.Pair;
48import net.floodlightcontroller.cgrmodule.util.*;
49import net.floodlightcontroller.core.FloodlightContext;
50import net.floodlightcontroller.core.IControllerCompletionListener;
51import net.floodlightcontroller.core.IFloodlightProviderService;
52import net.floodlightcontroller.core.IOFMessageListener;
53import net.floodlightcontroller.core.IOFSwitch;
54import net.floodlightcontroller.core.module.FloodlightModuleContext;
55import net.floodlightcontroller.core.module.FloodlightModuleException;
56import net.floodlightcontroller.core.module.IFloodlightModule;
57import net.floodlightcontroller.core.module.IFloodlightService;
58import net.floodlightcontroller.learningswitch.LearningSwitch;
59import net.floodlightcontroller.packet.Ethernet;
60import net.floodlightcontroller.packet.IPv4;
61import net.floodlightcontroller.packet.TCP;
62import net.floodlightcontroller.util.OFMessageUtils;
63
64public class CGRmodule implements IFloodlightModule, IOFMessageListener
65{
66 protected static Logger log = LoggerFactory.getLogger(CGRmodule.class);
67
68 // Module dependencies
69 protected IFloodlightProviderService floodlightProviderService;
70
71 // Stores the learned state for each switch
72 protected Map<IOFSwitch, Map<MacAddress, OFPort>> ControllerMap;
73
74 // Stores the number of connections for a given MAC address.
75 protected Map<IOFSwitch, Map<Pair<IPv4Address,TransportPort>, Integer>> TCPLinkCounterMap;
76
77 // flow-mod - for use in the cookie
78 public static final int LEARNING_SWITCH_APP_ID = 1;
79 // LOOK! This should probably go in some class that encapsulates
80 // the app cookie management
81 public static final int APP_ID_BITS = 12;
82 public static final int APP_ID_SHIFT = (64 - APP_ID_BITS);
83 public static final long LEARNING_SWITCH_COOKIE = (long) (LEARNING_SWITCH_APP_ID & ((1 << APP_ID_BITS) - 1)) << APP_ID_SHIFT;
84
85 // more flow-mod defaults
86 protected static short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 5; // in seconds
87 protected static short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0; // infinite
88 protected static short FLOWMOD_PRIORITY = 100;
89 protected static short DEFAULT_PRIORITY = 10;
90
91 // for managing our map sizes
92 protected static final int MAX_MACS_PER_SWITCH = 1000;
93
94 // CGR Firewall module
95 protected static final int MAX_DESTINATION_NUMBER = 3;
96 protected static final int MAX_ELEPHANT_FLOWS = 3;
97 protected static final int ELEPHANT_FLOW_BW = 10;
98
99 // normally, setup reverse flow as well. Disable only for using cbench for comparison with NOX etc.
100 protected static final boolean LEARNING_SWITCH_REVERSE_FLOW = true;
101
102 /**
103 * @param floodlightProvider the floodlightProvider to set
104 */
105 public void setFloodlightProvider(IFloodlightProviderService floodlightProviderService) {
106 this.floodlightProviderService = floodlightProviderService;
107 }
108
109 @Override
110 public String getName()
111 {
112 return "CGRModule";
113 }
114
115 /**
116 * Adds a host to the MAC->SwitchPort mapping
117 * @param sw The switch to add the mapping to
118 * @param mac The MAC address of the host to add
119 * @param portVal The switchport that the host is on
120 */
121 protected void addToPortMap(IOFSwitch sw, MacAddress mac, OFPort portVal)
122 {
123 Map<MacAddress, OFPort> swMap = ControllerMap.get(sw);
124
125 // Check if the switch already exists
126 if (swMap == null) {
127 swMap = new LRULinkedHashMap<MacAddress, OFPort>(MAX_MACS_PER_SWITCH);
128 ControllerMap.put(sw, swMap);
129 }
130
131 if ( swMap.putIfAbsent(mac, portVal) != portVal) {
132 swMap.replace(mac, portVal);
133 log.info( "Sw: " + sw
134 + " --- New PortMAC: "
135 + " MAC {} PORT {}",
136 new Object[]{ mac.toString(),
137 portVal});
138 }
139 }
140 protected void addToTCPLinkCounterMap(IOFSwitch sw, Pair<IPv4Address,TransportPort> ipport)
141 {
142 Map<Pair<IPv4Address,TransportPort>, Integer> TCPmap = TCPLinkCounterMap.get(sw);
143
144 // Check if the switch already exists
145 if (TCPmap == null)
146 {
147 TCPmap = new LRULinkedHashMap<Pair<IPv4Address,TransportPort>,Integer>(MAX_MACS_PER_SWITCH);
148 TCPLinkCounterMap.put(sw, TCPmap);
149 }
150
151 if ( TCPmap.containsKey(ipport))
152 {
153 TCPmap.replace(ipport, TCPmap.get(ipport)+1);
154 log.info( "Sw: " + sw
155 + " --- New PortTCP: "
156 + " IP/TCP {} Counter {}",
157 new Object[]{ ipport.toString(), //pode dar merda
158 TCPmap.get(ipport)+1});
159 }
160 else
161 {
162 TCPmap.put(ipport, 1);
163 }
164
165 }
166
167 /**
168 * Removes a host from the MAC->SwitchPort mapping
169 * @param sw The switch to remove the mapping from
170 * @param mac The MAC address of the host to remove
171 */
172 protected void removeFromPortMap(IOFSwitch sw, MacAddress mac) {
173
174 Map<MacAddress, OFPort> swMap = ControllerMap.get(sw);
175 if (swMap != null) {
176 swMap.remove(mac);
177 log.info( "Sw: " + sw
178 + " --- Removed PortMAC: "
179 + " MAC {}",
180 new Object[]{ mac.toString()});
181 }
182 }
183
184 /**
185 * Get the port that a MAC is associated with
186 * @param sw The switch to get the mapping from
187 * @param mac The MAC address to get
188 * @return The port the host is on
189 */
190 public OFPort getFromPortMap(IOFSwitch sw, MacAddress mac) {
191 Map<MacAddress, OFPort> swMap = ControllerMap.get(sw);
192 if (swMap != null) {
193 return swMap.get(mac);
194 }
195
196 // if none found
197 return null;
198 }
199
200 /**
201 * Clears the MAC -> SwitchPort map for all switches
202 */
203 public void clearLearnedTable() {
204 ControllerMap.clear();
205 }
206
207 /**
208 * Clears the MAC/VLAN -> SwitchPort map for a single switch
209 * @param sw The switch to clear the mapping for
210 */
211 public void clearLearnedTable(IOFSwitch sw) {
212 Map<MacAddress, OFPort> swMap = ControllerMap.get(sw);
213 if (swMap != null) {
214 swMap.clear();
215 }
216 }
217
218 protected Match createMatchFromPacket(IOFSwitch sw, OFPort inPort, FloodlightContext cntx)
219 {
220 // The packet in match will only contain the port number.
221 // We need to add in specifics for the hosts we're routing between.
222 Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
223 MacAddress srcMac = eth.getSourceMACAddress();
224 MacAddress dstMac = eth.getDestinationMACAddress();
225
226 Match.Builder mb = sw.getOFFactory().buildMatch();
227 mb.setExact(MatchField.IN_PORT, inPort)
228 .setExact(MatchField.ETH_SRC, srcMac)
229 .setExact(MatchField.ETH_DST, dstMac);
230 //.setExact(MatchField.TCP_DST)
231 return mb.build();
232 }
233
234 protected Match createMatchFromTCPPacket(IOFSwitch sw, OFPort inPort, FloodlightContext cntx)
235 {
236 // The packet in match will only contain the port number.
237 // We need to add in specifics for the hosts we're routing between.
238 Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
239 MacAddress srcMac = eth.getSourceMACAddress();
240 MacAddress dstMac = eth.getDestinationMACAddress();
241
242 if ( eth.getEtherType() == EthType.IPv4 )
243 {
244 IPv4 ipv4 = (IPv4) eth.getPayload();
245 IPv4Address ipv4Src = ipv4.getSourceAddress();
246 IPv4Address ipv4Dest = ipv4.getDestinationAddress();
247
248 if ( ipv4.getProtocol() == IpProtocol.TCP )
249 {
250 TCP tcp = (TCP) ipv4.getPayload();
251 TransportPort portSrc = tcp.getSourcePort();
252 TransportPort portDest = tcp.getDestinationPort();
253
254 Match.Builder mb = sw.getOFFactory().buildMatch();
255 mb.setExact(MatchField.IN_PORT, inPort)
256 .setExact(MatchField.ETH_SRC, srcMac)
257 .setExact(MatchField.ETH_DST, dstMac)
258 .setExact(MatchField.IPV4_SRC, ipv4Src)
259 .setExact(MatchField.IPV4_DST, ipv4Dest)
260 .setExact(MatchField.TCP_DST, portDest)
261 .setExact(MatchField.TCP_SRC, portSrc);
262 return mb.build();
263 } // End of TCP
264 } // End of IPv4
265 return null;
266 }
267
268 protected Match createReverseMatchfromMatch(IOFSwitch sw, OFPort outPort, Match match)
269 {
270 Match.Builder rev_match = match.createBuilder();
271 rev_match.setExact(MatchField.IN_PORT, outPort)
272 .setExact(MatchField.ETH_SRC, match.get(MatchField.ETH_DST))
273 .setExact(MatchField.ETH_DST, match.get(MatchField.ETH_SRC));
274 return rev_match.build();
275 }
276
277 protected Match createReverseMatchfromMatch(IOFSwitch sw, Match match)
278 {
279 Match.Builder rev_match = match.createBuilder();
280 rev_match.setExact(MatchField.ETH_SRC, match.get(MatchField.ETH_DST))
281 .setExact(MatchField.ETH_DST, match.get(MatchField.ETH_SRC));
282
283 return rev_match.build();
284 }
285
286 protected void createFlowMod(IOFSwitch sw, OFPort Port, Match match, OFVersion version, short prio, Boolean remFlag)
287 {
288 // Action List
289 List<OFAction> al = new ArrayList<OFAction>();
290 OFActionOutput output = sw.getOFFactory().actions().buildOutput()
291 .setPort(Port) // outPort is the port trough which the sw should send the Matching Packets
292 .setMaxLen(0xffFFffFF)
293 .build();
294 al.add(output);
295
296
297 // Write the flow mod using SwitchCommands install rule method since it receives either instructions or actions
298 // depending on the OpenFlow Version you should do the following:
299 if (version.compareTo(OFVersion.OF_13) == 0 )
300 {
301 OFInstructionApplyActions applyActions = sw.getOFFactory().instructions().buildApplyActions().setActions(al).build(); //use the instructions builder to build an applyActions instruction with the given action list.
302 ArrayList<OFInstruction> instructionList = new ArrayList<OFInstruction>();
303 instructionList.add(applyActions); //add the applyActions Instruction to the Instruction list
304 SwitchCommands.installRule(sw, TableId.of(0), prio, match, instructionList, null, CGRmodule.FLOWMOD_DEFAULT_HARD_TIMEOUT, CGRmodule.FLOWMOD_DEFAULT_IDLE_TIMEOUT, OFBufferId.NO_BUFFER, remFlag);
305
306 } else {
307 SwitchCommands.installRule(sw, null, prio, match, null, al, CGRmodule.FLOWMOD_DEFAULT_HARD_TIMEOUT, CGRmodule.FLOWMOD_DEFAULT_IDLE_TIMEOUT, OFBufferId.NO_BUFFER, remFlag);
308 }
309 }
310
311 /**
312 * Processes a OFPacketIn message. If the switch has learned the MAC to port mapping
313 * for the pair it will write a FlowMod for. If the mapping has not been learned the
314 * we will flood the packet.
315 * @param sw
316 * @param pi
317 * @param cntx
318 * @return
319 */
320 @SuppressWarnings("unused")
321 private Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx)
322 {
323 Integer lnk_count;
324
325 // Read inPort and declare outPort
326 OFPort inPort = (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT));
327 OFPort outPort;
328
329 /* Read packet header attributes into a Match object */
330 Match match = createMatchFromPacket(sw, inPort, cntx);
331 MacAddress sourceMac = match.get(MatchField.ETH_SRC);
332 MacAddress destMac = match.get(MatchField.ETH_DST);
333
334 if (sourceMac == null)
335 {
336 sourceMac = MacAddress.NONE;
337 }
338 if (destMac == null)
339 {
340 destMac = MacAddress.NONE;
341 }
342
343 if ((destMac.getLong() & 0xfffffffffff0L) == 0x0180c2000000L)
344 {
345 if (log.isTraceEnabled())
346 {
347 log.info("ignoring packet addressed to 802.1D/Q reserved addr: switch {} dest MAC {}",
348 new Object[]{ sw,
349 destMac.toString() });
350 }
351 return Command.STOP;
352 }
353
354 if ( (sourceMac.getLong() & 0x010000000000L) == 0)
355 {
356 // If source MAC is a unicast address, learn the port for this MAC/VLAN
357 addToPortMap(sw, sourceMac, inPort); // If the entry already exists, it is replaced
358 }
359
360 // Check if port for destination MAC is known
361 // If so output flow-mod and/or packet
362 // If link destination number is exceeded, drop
363 if ( (outPort = getFromPortMap(sw, destMac)) == null)
364 {
365 // No port entry for the given MAC - Flood the packet
366 SwitchCommands.sendPacketOutPacketIn(sw, OFPort.FLOOD, pi);
367 log.info( "Sw: " + sw
368 + " ... Flooding: "
369 + "SRC {} DEST {}",
370 new Object[]{ sourceMac.toString(),
371 destMac.toString()});
372 } // End of Flood
373 else
374 {
375 // If there is no MacLinkCounter entry for the SourceMAC
376 // Push packet to switch
377 SwitchCommands.sendPacketOutPacketIn(sw, outPort, pi);
378 log.info( "Sw: " + sw
379 + " ... Sending packet to known destination port: "
380 + "SRC {} DEST {} inP {} outP {} {}",
381 new Object[]{ sourceMac.toString(),
382 destMac.toString(),
383 inPort.getPortNumber(),
384 outPort.getPortNumber() });
385
386 // Extract Ethernet Packet
387 Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
388
389 if ( eth.getEtherType() == EthType.IPv4 )
390 {
391 IPv4 ipv4 = (IPv4) eth.getPayload();
392
393 IPv4Address ipv4src = ipv4.getSourceAddress();
394 IPv4Address ipv4dest = ipv4.getDestinationAddress();
395
396 if ( ipv4.getProtocol() == IpProtocol.TCP )
397 {
398 TCP tcp = (TCP) ipv4.getPayload();
399
400 TransportPort portSrc = tcp.getSourcePort();
401 TransportPort portDest = tcp.getDestinationPort();
402 Pair<IPv4Address,TransportPort> ipport = new Pair<IPv4Address,TransportPort>(ipv4src, portSrc);
403
404 Match tcpmatch = createMatchFromTCPPacket(sw, outPort, cntx);
405
406 if ( ( lnk_count = TCPLinkCounterMap.get(ipport) ) != null && lnk_count >= MAX_DESTINATION_NUMBER)
407 {
408 // Link Destinations exceeded, drop packet.
409 log.info( "Sw: " + sw
410 + " ---> Excessive Connections: "
411 + "TCP {} IP {} LinkCount {}",
412 new Object[]{ portSrc.toString(),
413 ipv4src.toString(),
414 lnk_count });
415
416 } // End of Max Connections
417 else
418 {
419 addToTCPLinkCounterMap(sw, ipport);
420 // Create TCP/PORT Flow
421 createFlowMod(sw, outPort, tcpmatch, pi.getVersion(), CGRmodule.FLOWMOD_PRIORITY, true);
422
423 log.info( "Sw: " + sw
424 + " *** New TCP Flow: "
425 + "IP_SRC {}:{} IP_DEST {}:{} PORT {}",
426 new Object[]{ ipv4src.toString(),
427 portSrc.toString(),
428 ipv4dest.toString(),
429 portDest.toString(),
430 outPort.getPortNumber() });
431
432 } // End of Create New Flow - Maximum Connections not reached
433 } // End of TCP Packet
434 } // End of IPv4 Packet
435
436 if (sourceMac != null && destMac != null)
437 {
438 // Add flow table entry matching source MAC, dest MAC and input port
439 // that sends to the port we previously learned for the dest MAC.
440 // We write FlowMods with Buffer ID none then explicitly PacketOut the buffered packet
441 createFlowMod(sw, outPort, match, pi.getVersion(), CGRmodule.DEFAULT_PRIORITY, false);
442
443 // Also add a flow table entry with source and destination MACs reversed, and
444 // input and output ports reversed.
445 if (LEARNING_SWITCH_REVERSE_FLOW && false)
446 {
447 // Create Reserve Match
448 Match rev_match = createReverseMatchfromMatch(sw, inPort, match); // CHECK PORT TO USE /IN/OUT
449 createFlowMod(sw, inPort, rev_match, pi.getVersion(), CGRmodule.DEFAULT_PRIORITY, false);
450 }
451
452 } // End of srcMac & srcDest != NULL
453 } // End of Know Destination Port
454 return Command.STOP;
455 }
456
457 /**
458 * Processes a flow removed message.
459 * @param sw The switch that sent the flow removed message.
460 * @param flowRemovedMessage The flow removed message.
461 * @return Whether to continue processing this message or stop.
462 */
463 @SuppressWarnings("unused")
464 private Command processFlowRemovedMessage(IOFSwitch sw, OFFlowRemoved flowRemovedMessage) {
465 Integer lnk_count;
466 Match match = flowRemovedMessage.getMatch();
467 MacAddress srcMac = match.get(MatchField.ETH_SRC);
468 MacAddress dstMac = match.get(MatchField.ETH_DST);
469
470 IPv4Address srcIPv4 = match.get(MatchField.IPV4_SRC);
471 IPv4Address dstIPv4 = match.get(MatchField.IPV4_DST);
472
473 TransportPort srcPort = match.get(MatchField.TCP_SRC);
474 TransportPort dstPort = match.get(MatchField.TCP_DST);
475
476 if (srcIPv4 != null
477 && dstIPv4 != null
478 && srcPort != null
479 && dstPort != null)
480 {
481 Pair<IPv4Address,TransportPort> ipport = new Pair<IPv4Address,TransportPort>(srcIPv4, srcPort);
482
483 // Decrement MAC counter links
484 if ( (lnk_count = TCPLinkCounterMap.get(ipport) ) != null /*&& lnk_count > 0*/)
485 {
486 TCPLinkCounterMap.replace(ipport, --lnk_count);
487 }
488
489 log.info( "Sw: " + sw
490 + " *** TCP Flow Removed: "
491 + "SRC {} LinkCount {}",
492 new Object[]{ ipport.toString(),
493 TCPLinkCounterMap.get(ipport) });
494 } // End of TCP Match
495
496 // When a flow entry expires, it means the device with the matching source
497 // MAC address either stopped sending packets or moved to a different
498 // port. If the device moved, we can't know where it went until it sends
499 // another packet, allowing us to re-learn its port. Meanwhile we remove
500 // it from the macToPortMap to revert to flooding packets to this device.
501 removeFromPortMap(sw, srcMac);
502
503 // Also, if packets keep coming from another device (e.g. from ping), the
504 // corresponding reverse flow entry will never expire on its own and will
505 // send the packets to the wrong port (the matching input port of the
506 // expired flow entry), so we must delete the reverse entry explicitly.
507 if(LEARNING_SWITCH_REVERSE_FLOW && false)
508 {
509 Match rev_match = createReverseMatchfromMatch(sw, match);
510 SwitchCommands.removeRules(sw, rev_match, flowRemovedMessage.getVersion() );
511 }
512
513 return Command.CONTINUE;
514 }
515
516 // IOFMessageListener
517
518 @Override
519 public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
520 switch (msg.getType())
521 {
522 case PACKET_IN:
523 return this.processPacketInMessage(sw, (OFPacketIn) msg, cntx);
524 case FLOW_REMOVED:
525 return this.processFlowRemovedMessage(sw, (OFFlowRemoved) msg);
526 case ERROR:
527 log.info("received an error {} from switch {}", msg, sw);
528 return Command.CONTINUE;
529 default:
530 log.error("received an unexpected message {} from switch {}", msg, sw);
531 return Command.CONTINUE;
532 }
533 }
534
535 @Override
536 public boolean isCallbackOrderingPrereq(OFType type, String name) {
537 return false;
538 }
539
540 @Override
541 public boolean isCallbackOrderingPostreq(OFType type, String name) {
542 return (type.equals(OFType.PACKET_IN) && name.equals("forwarding")) ;
543 }
544
545 // IFloodlightModule
546
547 /**
548 * Tell the module system which services we provide.
549 */
550 @Override
551 public Collection<Class<? extends IFloodlightService>> getModuleServices()
552 { return null; }
553
554 /**
555 * Tell the module system which services we implement.
556 */
557 @Override
558 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls()
559 { return null; }
560
561 @Override
562 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
563 Collection<Class<? extends IFloodlightService>> l =
564 new ArrayList<Class<? extends IFloodlightService>>();
565 l.add(IFloodlightProviderService.class);
566 return l;
567 }
568
569 @Override
570 public void init(FloodlightModuleContext context) throws FloodlightModuleException {
571 ControllerMap = new ConcurrentHashMap<IOFSwitch, Map<MacAddress, OFPort>>();
572 TCPLinkCounterMap = new ConcurrentHashMap< Pair<IPv4Address,TransportPort>, Integer>();
573 floodlightProviderService = context.getServiceImpl(IFloodlightProviderService.class);
574 log.info("CGR module started {}");
575 }
576
577 @Override
578 public void startUp(FloodlightModuleContext context)
579 {
580 // paag: register the IControllerCompletionListener
581 floodlightProviderService.addOFMessageListener(OFType.PACKET_IN, this);
582 floodlightProviderService.addOFMessageListener(OFType.FLOW_REMOVED, this);
583 floodlightProviderService.addOFMessageListener(OFType.ERROR, this);
584
585 // read our config options
586 Map<String, String> configOptions = context.getConfigParams(this);
587 try {
588 String idleTimeout = configOptions.get("idletimeout");
589 if (idleTimeout != null) {
590 FLOWMOD_DEFAULT_IDLE_TIMEOUT = Short.parseShort(idleTimeout);
591 }
592 } catch (NumberFormatException e) {
593 log.warn("Error parsing flow idle timeout, " +
594 "using default of {} seconds", FLOWMOD_DEFAULT_IDLE_TIMEOUT);
595 }
596 try {
597 String hardTimeout = configOptions.get("hardtimeout");
598 if (hardTimeout != null) {
599 FLOWMOD_DEFAULT_HARD_TIMEOUT = Short.parseShort(hardTimeout);
600 }
601 } catch (NumberFormatException e) {
602 log.warn("Error parsing flow hard timeout, " +
603 "using default of {} seconds", FLOWMOD_DEFAULT_HARD_TIMEOUT);
604 }
605 try {
606 String priority = configOptions.get("priority");
607 if (priority != null) {
608 FLOWMOD_PRIORITY = Short.parseShort(priority);
609 }
610 } catch (NumberFormatException e) {
611 log.warn("Error parsing flow priority, " +
612 "using default of {}",
613 FLOWMOD_PRIORITY);
614 }
615 log.debug("FlowMod idle timeout set to {} seconds", FLOWMOD_DEFAULT_IDLE_TIMEOUT);
616 log.debug("FlowMod hard timeout set to {} seconds", FLOWMOD_DEFAULT_HARD_TIMEOUT);
617 log.debug("FlowMod priority set to {}", FLOWMOD_PRIORITY);
618 }
619
620}