Need a unique gift idea?
A Pastebin account makes a great Christmas gift
SHARE
TWEET

Untitled

a guest Dec 6th, 2018 76 Never
Upgrade to PRO!
ENDING IN00days00hours00mins00secs
 
  1. package net.floodlightcontroller.cgrmodule;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.Collections;
  6. import java.util.HashMap;
  7. import java.util.HashSet;
  8. import java.util.List;
  9. import java.util.Map;
  10. import java.util.Set;
  11. import java.util.concurrent.ConcurrentHashMap;
  12.  
  13. import org.projectfloodlight.openflow.protocol.OFFlowMod;
  14. import org.projectfloodlight.openflow.protocol.OFFlowModCommand;
  15. import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
  16. import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
  17. import org.projectfloodlight.openflow.protocol.OFMessage;
  18. import org.projectfloodlight.openflow.protocol.OFPacketIn;
  19. import org.projectfloodlight.openflow.protocol.OFPacketOut;
  20. import org.projectfloodlight.openflow.protocol.OFType;
  21. import org.projectfloodlight.openflow.protocol.OFVersion;
  22. import org.projectfloodlight.openflow.protocol.action.OFAction;
  23. import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
  24. import org.projectfloodlight.openflow.protocol.action.OFActions;
  25. import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
  26. import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions;
  27. import org.projectfloodlight.openflow.protocol.instruction.OFInstructions;
  28. import org.projectfloodlight.openflow.protocol.match.Match;
  29. import org.projectfloodlight.openflow.protocol.match.MatchField;
  30. import org.projectfloodlight.openflow.types.MacAddress;
  31. import org.projectfloodlight.openflow.types.OFBufferId;
  32. import org.projectfloodlight.openflow.types.OFPort;
  33. import org.projectfloodlight.openflow.types.OFVlanVidMatch;
  34. import org.projectfloodlight.openflow.types.TableId;
  35. import org.projectfloodlight.openflow.types.U64;
  36. import org.projectfloodlight.openflow.types.VlanVid;
  37. import org.projectfloodlight.openflow.util.LRULinkedHashMap;
  38. import org.slf4j.Logger;
  39. import org.slf4j.LoggerFactory;
  40.  
  41. import net.floodlightcontroller.cgrmodule.util.*;
  42. import net.floodlightcontroller.core.FloodlightContext;
  43. import net.floodlightcontroller.core.IControllerCompletionListener;
  44. import net.floodlightcontroller.core.IFloodlightProviderService;
  45. import net.floodlightcontroller.core.IOFMessageListener;
  46. import net.floodlightcontroller.core.IOFSwitch;
  47. import net.floodlightcontroller.core.module.FloodlightModuleContext;
  48. import net.floodlightcontroller.core.module.FloodlightModuleException;
  49. import net.floodlightcontroller.core.module.IFloodlightModule;
  50. import net.floodlightcontroller.core.module.IFloodlightService;
  51. import net.floodlightcontroller.learningswitch.LearningSwitch;
  52. import net.floodlightcontroller.packet.Ethernet;
  53. import net.floodlightcontroller.util.OFMessageUtils;
  54.  
  55. public class CGRmodule implements IFloodlightModule, IOFMessageListener {
  56.     protected static Logger log = LoggerFactory.getLogger(CGRmodule.class);
  57.  
  58.     // Module dependencies
  59.     protected IFloodlightProviderService floodlightProviderService;
  60.  
  61.     // Stores the learned state for each switch
  62.     protected Map<IOFSwitch, Map<MacAddress, OFPort>> macToSwitchPortMap;
  63.    
  64.     // flow-mod - for use in the cookie
  65.     public static final int LEARNING_SWITCH_APP_ID = 1;
  66.     // LOOK! This should probably go in some class that encapsulates
  67.     // the app cookie management
  68.     public static final int APP_ID_BITS = 12;
  69.     public static final int APP_ID_SHIFT = (64 - APP_ID_BITS);
  70.     public static final long LEARNING_SWITCH_COOKIE = (long) (LEARNING_SWITCH_APP_ID & ((1 << APP_ID_BITS) - 1)) << APP_ID_SHIFT;
  71.  
  72.     // more flow-mod defaults
  73.     protected static short FLOWMOD_DEFAULT_IDLE_TIMEOUT = 5; // in seconds
  74.     protected static short FLOWMOD_DEFAULT_HARD_TIMEOUT = 0; // infinite
  75.     protected static short FLOWMOD_PRIORITY = 100;
  76.  
  77.     // for managing our map sizes
  78.     protected static final int MAX_MACS_PER_SWITCH  = 1000;
  79.  
  80.     // normally, setup reverse flow as well. Disable only for using cbench for comparison with NOX etc.
  81.     protected static final boolean LEARNING_SWITCH_REVERSE_FLOW = true;
  82.    
  83.     /**
  84.      * @param floodlightProvider the floodlightProvider to set
  85.      */
  86.     public void setFloodlightProvider(IFloodlightProviderService floodlightProviderService) {
  87.         this.floodlightProviderService = floodlightProviderService;
  88.     }
  89.  
  90.     @Override
  91.     public String getName() {
  92.         return "CGRModule";
  93.     }
  94.  
  95.     /**
  96.      * Adds a host to the MAC->SwitchPort mapping
  97.      * @param sw The switch to add the mapping to
  98.      * @param mac The MAC address of the host to add
  99.      * @param portVal The switchport that the host is on
  100.      */
  101.     protected void addToPortMap(IOFSwitch sw, MacAddress mac, OFPort portVal) {
  102.         Map<MacAddress, OFPort> swMap = macToSwitchPortMap.get(sw);
  103.  
  104.         if (swMap == null) {
  105.             swMap = new LRULinkedHashMap<MacAddress, OFPort>(MAX_MACS_PER_SWITCH);
  106.             macToSwitchPortMap.put(sw, swMap);
  107.         }
  108.         swMap.put(mac, portVal);
  109.     }
  110.  
  111.     /**
  112.      * Removes a host from the MAC->SwitchPort mapping
  113.      * @param sw The switch to remove the mapping from
  114.      * @param mac The MAC address of the host to remove
  115.      */
  116.     protected void removeFromPortMap(IOFSwitch sw, MacAddress mac) {
  117.  
  118.         Map<MacAddress, OFPort> swMap = macToSwitchPortMap.get(sw);
  119.         if (swMap != null) {
  120.             swMap.remove(mac);
  121.         }
  122.     }
  123.  
  124.     /**
  125.      * Get the port that a MAC is associated with
  126.      * @param sw The switch to get the mapping from
  127.      * @param mac The MAC address to get
  128.      * @return The port the host is on
  129.      */
  130.     public OFPort getFromPortMap(IOFSwitch sw, MacAddress mac) {
  131.         Map<MacAddress, OFPort> swMap = macToSwitchPortMap.get(sw);
  132.         if (swMap != null) {
  133.             return swMap.get(mac);
  134.         }
  135.  
  136.         // if none found
  137.         return null;
  138.     }
  139.  
  140.     /**
  141.      * Clears the MAC -> SwitchPort map for all switches
  142.      */
  143.     public void clearLearnedTable() {
  144.         macToSwitchPortMap.clear();
  145.     }
  146.  
  147.     /**
  148.      * Clears the MAC/VLAN -> SwitchPort map for a single switch
  149.      * @param sw The switch to clear the mapping for
  150.      */
  151.     public void clearLearnedTable(IOFSwitch sw) {
  152.         Map<MacAddress, OFPort> swMap = macToSwitchPortMap.get(sw);
  153.         if (swMap != null) {
  154.             swMap.clear();
  155.         }
  156.     }
  157.    
  158.     protected Match createMatchFromPacket(IOFSwitch sw, OFPort inPort, FloodlightContext cntx) {
  159.         // The packet in match will only contain the port number.
  160.         // We need to add in specifics for the hosts we're routing between.
  161.         Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
  162.         MacAddress srcMac = eth.getSourceMACAddress();
  163.         MacAddress dstMac = eth.getDestinationMACAddress();
  164.  
  165.         Match.Builder mb = sw.getOFFactory().buildMatch();
  166.         mb.setExact(MatchField.IN_PORT, inPort)
  167.         .setExact(MatchField.ETH_SRC, srcMac)
  168.         .setExact(MatchField.ETH_DST, dstMac);
  169.         return mb.build();
  170.     }
  171.  
  172.     /**
  173.      * Processes a OFPacketIn message. If the switch has learned the MAC to port mapping
  174.      * for the pair it will write a FlowMod for. If the mapping has not been learned the
  175.      * we will flood the packet.
  176.      * @param sw
  177.      * @param pi
  178.      * @param cntx
  179.      * @return
  180.      */
  181.     private Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
  182.         OFPort inPort = (pi.getVersion().compareTo(OFVersion.OF_12) < 0 ? pi.getInPort() : pi.getMatch().get(MatchField.IN_PORT));
  183.        
  184.         /* Read packet header attributes into a Match object */
  185.         Match m = createMatchFromPacket(sw, inPort, cntx);
  186.         MacAddress sourceMac = m.get(MatchField.ETH_SRC);
  187.         MacAddress destMac = m.get(MatchField.ETH_DST);
  188.  
  189.         if (sourceMac == null) {
  190.             sourceMac = MacAddress.NONE;
  191.         }
  192.         if (destMac == null) {
  193.             destMac = MacAddress.NONE;
  194.         }
  195.        
  196.         if ((destMac.getLong() & 0xfffffffffff0L) == 0x0180c2000000L) {
  197.             if (log.isTraceEnabled()) {
  198.                 log.trace("ignoring packet addressed to 802.1D/Q reserved addr: switch {} dest MAC {}",
  199.                         new Object[]{ sw, destMac.toString() });
  200.             }
  201.             return Command.STOP;
  202.         }
  203.         if ((sourceMac.getLong() & 0x010000000000L) == 0) {
  204.           // If source MAC is a unicast address, learn the port for this MAC/VLAN
  205.            
  206.         }
  207.         //check if port for destination MAC is known
  208.         // If so output flow-mod and/or packet
  209.        
  210.         //for now it floods trough all ports like a hub.
  211.         SwitchCommands.sendPacketOutPacketIn(sw, OFPort.FLOOD, pi);
  212.         // Add flow table entry matching source MAC, dest MAC and input port
  213.         // that sends to the port we previously learned for the dest MAC.  Also
  214.         // add a flow table entry with source and destination MACs reversed, and
  215.         // input and output ports reversed.  When either entry expires due to idle
  216.         // timeout, remove the other one.  This ensures that if a device moves to
  217.         // a different port, a constant stream of packets headed to the device at
  218.         // its former location does not keep the stale entry alive forever.
  219.         // We write FlowMods with Buffer ID none then explicitly PacketOut the buffered packet
  220.        
  221.         // to send the packet in back as a packet out to the previously learned port outPort use;
  222.         //SwitchCommands.sendPacketOutPacketIn(outSw, outPort, pi)
  223.        
  224.         // you should then write the flow mod using SwitchCommands install rule method since it receives either instructions or actions
  225.         // depending on the OpenFlow Version you should do the following:
  226.     /* 
  227.         OFActions actions = sw.getOFFactory().actions(); //actions builder
  228.         List<OFAction> al = new ArrayList<OFAction>();
  229.         OFActionOutput output = actions.buildOutput()
  230.                 .setPort(outPort)    // outPort is the port trough which the sw should send the Matching Packets
  231.                 .setMaxLen(0xffFFffFF)
  232.                 .build();
  233.         al.add(output);
  234.    
  235.         if (pi.getVersion().compareTo(OFVersion.OF_13)==0){
  236.                 OFInstructions instructions =  sw.getOFFactory().instructions(); //instructions builder
  237.                 OFInstructionApplyActions applyActions = instructions.buildApplyActions().setActions(al).build(); //use the instructions builder to build an applyActions instruction with the given action list.
  238.                 ArrayList<OFInstruction> instructionList = new ArrayList<OFInstruction>();
  239.                 instructionList.add(applyActions); //add the applyActions Instruction to the Instruction list
  240.                 SwitchCommands.installRule(sw, TableId.of(0), CGRL2Switch.FLOWMOD_PRIORITY, match, instructionList, null, CGRL2Switch.FLOWMOD_DEFAULT_HARD_TIMEOUT, CGRL2Switch.FLOWMOD_DEFAULT_IDLE_TIMEOUT, OFBufferId.NO_BUFFER);
  241.         } else SwitchCommands.installRule(sw, TableId.of(0), CGRL2Switch.FLOWMOD_PRIORITY, match, null, al, CGRL2Switch.FLOWMOD_DEFAULT_HARD_TIMEOUT, CGRL2Switch.FLOWMOD_DEFAULT_IDLE_TIMEOUT, OFBufferId.NO_BUFFER);
  242. */
  243.            
  244.         //
  245.         return Command.STOP;
  246.     }
  247.  
  248.     /**
  249.      * Processes a flow removed message.
  250.      * @param sw The switch that sent the flow removed message.
  251.      * @param flowRemovedMessage The flow removed message.
  252.      * @return Whether to continue processing this message or stop.
  253.      */
  254.     private Command processFlowRemovedMessage(IOFSwitch sw, OFFlowRemoved flowRemovedMessage) {
  255.         if (log.isTraceEnabled()) {
  256.             log.trace("{} flow entry removed {}", sw, flowRemovedMessage);
  257.         }
  258.         Match match = flowRemovedMessage.getMatch();
  259.         // When a flow entry expires, it means the device with the matching source
  260.         // MAC address either stopped sending packets or moved to a different
  261.         // port.  If the device moved, we can't know where it went until it sends
  262.         // another packet, allowing us to re-learn its port.  Meanwhile we remove
  263.         // it from the macToPortMap to revert to flooding packets to this device.
  264.        
  265.         // Also, if packets keep coming from another device (e.g. from ping), the
  266.         // corresponding reverse flow entry will never expire on its own and will
  267.         // send the packets to the wrong port (the matching input port of the
  268.         // expired flow entry), so we must delete the reverse entry explicitly.
  269.        
  270.         return Command.CONTINUE;
  271.     }
  272.  
  273.     // IOFMessageListener
  274.  
  275.     @Override
  276.     public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
  277.         switch (msg.getType()) {
  278.         case PACKET_IN:
  279.             return this.processPacketInMessage(sw, (OFPacketIn) msg, cntx);
  280.         case FLOW_REMOVED:
  281.             return this.processFlowRemovedMessage(sw, (OFFlowRemoved) msg);
  282.         case ERROR:
  283.             log.info("received an error {} from switch {}", msg, sw);
  284.             return Command.CONTINUE;
  285.         default:
  286.             log.error("received an unexpected message {} from switch {}", msg, sw);
  287.             return Command.CONTINUE;
  288.         }
  289.     }
  290.  
  291.     @Override
  292.     public boolean isCallbackOrderingPrereq(OFType type, String name) {
  293.         return false;
  294.     }
  295.  
  296.     @Override
  297.     public boolean isCallbackOrderingPostreq(OFType type, String name) {
  298.         return (type.equals(OFType.PACKET_IN) && name.equals("forwarding")) ;
  299.     }
  300.    
  301.     // IFloodlightModule
  302.  
  303.     /**
  304.      * Tell the module system which services we provide.
  305.      */
  306.     @Override
  307.     public Collection<Class<? extends IFloodlightService>> getModuleServices()
  308.     { return null; }
  309.  
  310.     /**
  311.      * Tell the module system which services we implement.
  312.      */
  313.     @Override
  314.     public Map<Class<? extends IFloodlightService>, IFloodlightService>
  315.             getServiceImpls()
  316.     { return null; }
  317.  
  318.     @Override
  319.     public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
  320.         Collection<Class<? extends IFloodlightService>> l =
  321.                 new ArrayList<Class<? extends IFloodlightService>>();
  322.         l.add(IFloodlightProviderService.class);
  323.         return l;
  324.     }
  325.  
  326.     @Override
  327.     public void init(FloodlightModuleContext context) throws FloodlightModuleException {
  328.         macToSwitchPortMap = new ConcurrentHashMap<IOFSwitch, Map<MacAddress, OFPort>>();
  329.         floodlightProviderService = context.getServiceImpl(IFloodlightProviderService.class);
  330.         log.info("CGR module started {}");
  331.     }
  332.  
  333.     @Override
  334.     public void startUp(FloodlightModuleContext context) {
  335.         // paag: register the IControllerCompletionListener
  336.         floodlightProviderService.addOFMessageListener(OFType.PACKET_IN, this);
  337.         floodlightProviderService.addOFMessageListener(OFType.FLOW_REMOVED, this);
  338.         floodlightProviderService.addOFMessageListener(OFType.ERROR, this);
  339.  
  340.         // read our config options
  341.         Map<String, String> configOptions = context.getConfigParams(this);
  342.         try {
  343.             String idleTimeout = configOptions.get("idletimeout");
  344.             if (idleTimeout != null) {
  345.                 FLOWMOD_DEFAULT_IDLE_TIMEOUT = Short.parseShort(idleTimeout);
  346.             }
  347.         } catch (NumberFormatException e) {
  348.             log.warn("Error parsing flow idle timeout, " +
  349.                     "using default of {} seconds", FLOWMOD_DEFAULT_IDLE_TIMEOUT);
  350.         }
  351.         try {
  352.             String hardTimeout = configOptions.get("hardtimeout");
  353.             if (hardTimeout != null) {
  354.                 FLOWMOD_DEFAULT_HARD_TIMEOUT = Short.parseShort(hardTimeout);
  355.             }
  356.         } catch (NumberFormatException e) {
  357.             log.warn("Error parsing flow hard timeout, " +
  358.                     "using default of {} seconds", FLOWMOD_DEFAULT_HARD_TIMEOUT);
  359.         }
  360.         try {
  361.             String priority = configOptions.get("priority");
  362.             if (priority != null) {
  363.                 FLOWMOD_PRIORITY = Short.parseShort(priority);
  364.             }
  365.         } catch (NumberFormatException e) {
  366.             log.warn("Error parsing flow priority, " +
  367.                     "using default of {}",
  368.                     FLOWMOD_PRIORITY);
  369.         }
  370.         log.debug("FlowMod idle timeout set to {} seconds", FLOWMOD_DEFAULT_IDLE_TIMEOUT);
  371.         log.debug("FlowMod hard timeout set to {} seconds", FLOWMOD_DEFAULT_HARD_TIMEOUT);
  372.         log.debug("FlowMod priority set to {}", FLOWMOD_PRIORITY);
  373.     }
  374.  
  375. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top