Example #1
1
 def build_of_actions(self,inport,action_list):
     ### BUILD OF ACTIONS
     of_actions = []
     for actions in action_list:
         outport = actions['outport']
         del actions['outport']
         if 'srcmac' in actions:
             of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac']))
         if 'dstmac' in actions:
             of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac']))
         if 'srcip' in actions:
             of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip']))
         if 'dstip' in actions:
             of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip']))
         if 'srcport' in actions:
             of_actions.append(of.ofp_action_tp_port.set_src(actions['srcport']))
         if 'dstport' in actions:
             of_actions.append(of.ofp_action_tp_port.set_dst(actions['dstport']))
         if 'vlan_id' in actions:
             if actions['vlan_id'] is None:
                 of_actions.append(of.ofp_action_strip_vlan())
             else:
                 of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id']))
         if 'vlan_pcp' in actions:
             if actions['vlan_pcp'] is None:
                 if not actions['vlan_id'] is None:
                     raise RuntimeError("vlan_id and vlan_pcp must be set together!")
                 pass
             else:
                 of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp']))
         if (not inport is None) and (outport == inport):
             of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
         else:
             of_actions.append(of.ofp_action_output(port=outport))
     return of_actions
Example #2
0
 def build_of_actions(self,inport,action_list):
     ### BUILD OF ACTIONS
     of_actions = []
     for actions in action_list:
         outport = actions['port']
         del actions['port']
         if 'srcmac' in actions:
             of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac']))
         if 'dstmac' in actions:
             of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac']))
         if 'srcip' in actions:
             of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip']))
         if 'dstip' in actions:
             of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip']))
         if 'srcport' in actions:
             of_actions.append(of.ofp_action_tp_port.set_src(actions['srcport']))
         if 'dstport' in actions:
             of_actions.append(of.ofp_action_tp_port.set_dst(actions['dstport']))
         if 'vlan_id' in actions:
             if actions['vlan_id'] is None:
                 of_actions.append(of.ofp_action_strip_vlan())
             else:
                 of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id']))
         if 'vlan_pcp' in actions:
             if actions['vlan_pcp'] is None:
                 if not actions['vlan_id'] is None:
                     raise RuntimeError("vlan_id and vlan_pcp must be set together!")
                 pass
             else:
                 of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp']))
         if (not inport is None) and (outport == inport):
             of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
         else:
             of_actions.append(of.ofp_action_output(port=outport))
     return of_actions
  def resend_packet (self, packet_in, out_ports):
    """
    Instructs the switch to resend a packet that it had sent to us.
    "packet_in" is the ofp_packet_in object the switch had sent to the
    controller due to a table-miss.
    """
    log.debug( "Sending out: %s" % out_ports )

    msg = of.ofp_packet_out()
    msg.data = packet_in
    
    # Add actions for each out port
    for out_port in out_ports:
      # If port is dot1q put on vlan tag
      if self.vlan_to_port[out_port] == 1:
        action = of.ofp_action_vlan_vid(vlan_vid = self.vlan_to_port[packet_in.in_port])
      # Else strip vlan tag
      else:
        action = of.ofp_action_strip_vlan()
      msg.actions.append(action)
      
      # Send the packet out of the specified port
      action = of.ofp_action_output(port = out_port)
      msg.actions.append(action)

    # Send message to switch
    self.connection.send(msg)
    log.debug("Packet sent out: %s" % out_ports )
Example #4
0
    def install_push_rule(self, info, label, ip, raddr, dstaddr):
        '''
    Install a flow rule on an edge switch to push a label
    onto a flow.
    '''

        # message for switch
        msg = of.ofp_flow_mod()

        # match on MAC dst and IP dst
        msg.match.dl_src = None  # wildcard source MAC
        msg.match.dl_dst = dstaddr
        msg.match.dl_type = ethernet.IP_TYPE
        msg.match.nw_src = None  # wildcard source IP
        msg.match.nw_dst = ip

        # actions - rewrite MAC dst and push label
        actions = []
        actions.append(of.ofp_action_dl_addr.set_dst(raddr))
        actions.append(of.ofp_action_vlan_vid(vlan_vid=label))

        # set output port action
        port = self.topology_tracker.get_link_port(info.dpid1, info.dpid2)
        if port is None:
            log.warn("No port connecting {0} --> {1}".format(
                info.dpid1, info.dpid2))
            return
        actions.append(of.ofp_action_output(port=port))
        msg.actions = actions

        # set a timeout and send
        msg.idle_timeout = self.idle_timeout
        self.topology_tracker.graph.node[info.dpid1]['connection'].send(msg)

        return actions
    def knownSend(self, buffer_id, raw_data, out_port, in_port):
        """
        Sends packet to known host
        """

        msg = of.ofp_packet_out()
        msg.in_port = in_port
        if buffer_id != -1 and buffer_id is not None:
            # We got a buffer ID from the switch; use that
            msg.buffer_id = buffer_id
        else:
            # No buffer ID from switch -- we got the raw data
            if raw_data is None:
                # No raw_data specified -- nothing to send!
                return
            msg.data = raw_data

        # Add an action to send to the specified port
        action1 = of.ofp_action_vlan_vid(vlan_vid=VLAN_SPECIAL)
        action2 = of.ofp_action_output(port=out_port)
        msg.actions.append(action1)
        msg.actions.append(action2)

        # Send message to switch
        self.connection.send(msg)
Example #6
0
    def install_path_rule(self, info, inlabel, outlabel):
        '''
    Install a flow rule on a core switch to route based on label.
    '''

        # message for switch
        msg = of.ofp_flow_mod()

        # match on MAC dst and IP dst
        msg.match.dl_src = None  # wildcard MACs
        msg.match.dl_dst = None
        msg.match.dl_vlan = inlabel

        # actions - rewrite MAC dst and push label
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=outlabel))

        # set output port action
        port = self.topology_tracker.get_link_port(info.dpid1, info.dpid2)
        if port is None:
            log.warn("No port connecting {0} --> {1}".format(
                info.dpid1, info.dpid2))
            return
        msg.actions.append(of.ofp_action_output(port=port))

        # set a timeout and send
        #msg.idle_timeout = None # these flows are static
        self.topology_tracker.graph.node[info.dpid1]['connection'].send(msg)
Example #7
0
def flow_3f(inport, input_ip, trans_port, original_port, vlan=0, out_port=2):
    # flow1:

    flow3fmsg.cookie = 0

    flow3fmsg.match.in_port = inport

    flow3fmsg.match.dl_type = 0x0800

    flow3fmsg.match.nw_src = IPAddr(input_ip)
    flow3fmsg.match.nw_proto = 6
    flow3fmsg.match.tp_src = original_port

    # ACTIONS---------------------------------

    flow3ftrans = of.ofp_action_tp_port.set_src(trans_port)
    flow3fout = of.ofp_action_output(port=out_port)

    flow3fsrcIP = of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.2"))

    flow3fsrcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:05"))

    flow3fdstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:06"))
    flow3fvlanid = of.ofp_action_vlan_vid(vlan_vid=vlan)

    flow3fmsg.actions = [
        flow3ftrans, flow3fsrcIP, flow3fsrcMAC, flow3fdstMAC, flow3fvlanid,
        flow3fout
    ]
    return flow3fmsg
    def installPolicyDoneRule(switch):
        """
        Installs rules for packets that were successfully 
        """

        if int(switch) in range(100, 200):
            fm = of.ofp_flow_mod()
            fm.match.dl_vlan = VLAN_DONE
            action = of.ofp_action_output(port=of.OFPP_FLOOD)
            fm.actions.append(action)
            RulesTable.addRule(switch, "core flood to all ports", VLAN_DONE,
                               "flood ports")
            switchesConn[switch].send(fm)
        else:
            fm = of.ofp_flow_mod()
            fm.match.dl_vlan = VLAN_DONE
            allPorts = [
                int(p)
                for p in Discovery.graph.nodes[int(switch)].connection.ports
            ]
            corePorts = Discovery.getPorts(int(switch))
            hostPorts = list(set(allPorts) - set(corePorts))
            RulesTable.addRule(switch, " TOR flood to all hosts ", VLAN_DONE,
                               "all hosts ports")
            action = of.ofp_action_vlan_vid()
            fm.actions.append(action)
            for p in hostPorts:
                if p < of.OFPP_MAX:
                    action = of.ofp_action_output(port=p)
                    fm.actions.append(action)

            switchesConn[switch].send(fm)
Example #9
0
  def _update_step(self):
    if self.update_step > len(self.config.config) - 1:
      self.update_timer.cancel()
      log.warning("Updating Ends.")
      return
    self.config.change_step(self.update_step)
    self.update_timer._next = time.time() +  self.config.next_time

    # redistribute flows based on new configuration
    self.config.reset_real_config()
    self.reset_flowdist_tables()

    # Compute for each port in all source destination pair
    for src in self.sd_path_table:
      for dst in self.sd_path_table[src]:
        id_list = self.sd_path_table[src][dst]
        for srcport in self.sd_srcport_table[src][dst]:
          pid = self.get_pid_by_srcport(id_list, srcport)  # should be None
          if pid is None:
            # Not existed port, choose the last one as default
            pid = id_list[len(id_list) - 1]
            for k in id_list:
              now_split = self.config.now_config
              real_split = self.config.real_config
              if now_split[k-1] > real_split[k-1] or now_split[k-1] == 1:
                pid = k
                break
            # update flow_dist_table and real_config_table
            self.flow_dist_table[pid-1].append(srcport)
            self.config.compute_real_config(id_list, self.flow_dist_table)

          log.warning("pid %s", pid)

          srcip = self.srcip_table[src]
          dstip = self.dstip_table[dst]
          msg = of.ofp_flow_mod( command = of.OFPFC_MODIFY )
          msg.match.dl_type = 0x800
          msg.match.nw_src = IPAddr(srcip)
          msg.match.nw_dst = IPAddr(dstip)
          msg.match.nw_proto = 17
          msg.match.tp_src = srcport
          path = self.path_id_table[pid]
          if len(path) > 3:
            # It is not the last sw, tag it and send into the network
            if USE_VLAN_TAG:
              msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) )
            if USE_ETHERNET_SRC_TAG:
              msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) )
            msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) )
          elif len(path) == 3:
            # last sw, forward to the host
            # msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) )
            msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) )
          sw = path[1]
          core.openflow.sendToDPID(sw, msg)
          # print msg
          # log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid)

    log.warning("Update Step %i ...", self.update_step)
    self.update_step += 1
Example #10
0
		def dropping (duration=None):
			msg.priority=65535
			msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 831)) 		# modify the vlan id from the 830 to 831 
			print "dropping packets from ", IP_attack 			
			for connection in self.myconnections:
				connection.send(msg)  													#send the msg to the switch
				connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) #getting the flux stats
				print "MSG sent"
Example #11
0
def _handle_PacketIn(event):
	global s1_dpid
	# print "PacketIn: ", dpidToStr(event.connection.dpid)

	if event.connection.dpid==s1_dpid:
	   # Flujo entrante por el puerto 3 con dl_vlan = 50 
		msg = of.ofp_flow_mod()
		msg.priority = 100				# A numero mas alto mayor prioridad 
		msg.idle_timeout = 0
		msg.hard_timeout = 0
		msg.match.in_port = 3
		msg.match.dl_vlan = 50
		msg.actions.append(of.ofp_action_output(port = 1))
		event.connection.send(msg)
				
		# Flujo entrante por el puerto 3 con dl_vlan = 60 
		msg = of.ofp_flow_mod()		
		msg.priority = 1
		msg.idle_timeout = 0
		msg.hard_timeout = 0
		msg.match.in_port = 3
		msg.match.dl_vlan = 60
		msg.actions.append(of.ofp_action_output(port = 2))
		event.connection.send(msg)
		
		# Flujo entrante por el puerto 1
		msg = of.ofp_flow_mod()		
		msg.priority = 1
		msg.idle_timeout = 0
		msg.hard_timeout = 0
		msg.match.in_port = 1		
		msg.actions.append([of.ofp_action_vlan_vid(vlan_vid = 50),of.ofp_action_output(port = 3)])
		event.connection.send(msg)
		
		# Flujo entrante por el puerto 2
		msg = of.ofp_flow_mod()		
		msg.priority = 1
		msg.idle_timeout = 0
		msg.hard_timeout = 0
		msg.match.in_port = 2		
		msg.actions.append([of.ofp_action_vlan_vid(vlan_vid = 60),of.ofp_action_output(port = 1)])
		event.connection.send(msg)
Example #12
0
		def honeypot():
			print "Honeypot"	
			msg.actions.append(of.ofp_action_dl_addr.set_dst(mac_honey)) 	# honeypot MAC address
			msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 831)) 		# modify the vlan id from the 830 to 831 
			msg.actions.append(of.ofp_action_nw_addr.set_dst(ip_honeypot))  # action to send the flux to the honey_pot
			msg.actions.append(of.ofp_action_output(port = 6)) 			# which port the honeypot is connected 
																		# see how i can get this port by python
			for connection in self.myconnections:
				connection.send(msg)  													#send the msg to the switch
				connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) #getting the flux stats
				print "MSG sent"
    def _install_hybrid_dynamic_flows(self, event, out_dpid, final_out_port,
                                      packet):
        "Install entry at ingress switch."
        in_name = self.t.id_gen(dpid=event.dpid).name_str()
        #log.info("in_name: %s" % in_name)
        out_name = self.t.id_gen(dpid=out_dpid).name_str()
        #log.info("out_name: %s" % out_name)
        hash_ = self._ecmp_hash(packet)
        src_dst_route = self.r.get_route(in_name, out_name, hash_)
        # Choose a random core switch.
        core_sws = sorted(
            self._raw_dpids(self.t.layer_nodes(self.t.LAYER_CORE)))
        core_sw = random.choice(core_sws)
        core_sw_id = self.t.id_gen(dpid=core_sw)
        core_sw_name = self.t.id_gen(dpid=core_sw).name_str()

        route = self.r.get_route(in_name, core_sw_name, None)
        assert len(route) == 3
        log.info("route: %s" % route)

        match = of.ofp_match.from_packet(packet)

        assert core_sw_id.pod == self.t.k
        core_sw_index = ((core_sw_id.sw - 1) * 2) + (core_sw_id.host - 1)
        #log.info("core_sw_index: %s" % core_sw_index)

        dst_host_index = self.dpid_port_to_host_index(out_dpid, final_out_port)
        #log.info("dst_host_index: %s" % dst_host_index)

        vlan = (dst_host_index << 2) + core_sw_index
        log.info("vlan: %s" % vlan)
        log.info("len(src_dst_route): %i" % len(src_dst_route))

        if len(src_dst_route) == 1:
            # Don't bother with VLAN append; directly send to out port.
            log.info("adding edge-only entry from %s to %s on sw %s" %
                     (match.dl_src, match.dl_dst, in_name))
            self.switches[event.dpid].install(final_out_port,
                                              match,
                                              idle_timeout=HYBRID_IDLE_TIMEOUT,
                                              priority=PRIO_HYBRID_FLOW_DOWN)
        else:
            # Write VLAN and send up
            src_port, dst_port = self.t.port(route[0], route[1])
            actions = [
                of.ofp_action_vlan_vid(vlan_vid=vlan),
                of.ofp_action_output(port=src_port)
            ]
            self.switches[event.dpid].install_multiple(
                actions,
                match,
                idle_timeout=HYBRID_IDLE_TIMEOUT,
                priority=PRIO_HYBRID_FLOW_UP)
Example #14
0
def pClient(username, mac, ip=""):
    # permit traffic from the client to the router - i.e. auth successful
    connection = core.openflow.getConnection(strToDPID(dpid))
    MAC = EthAddr(mac)
    IP = IPAddr(ip)
    vlan = getVLANs(ip)
    query = "INSERT into tbl_nac_session (username,mac_address,ip_address,start_dt) VALUES ('%s','%s','%s',now())" % (
        username, mac, ip)
    msg = None

    # note: if the openflow switch supports L3 matching in addition to L2 matching
    # note: matching on both will result in higher security - but not all support both.
    # note: if we match on L3 and ARP matching is not supported (see sPortal),
    # note: ARPs from the client will not flow to the router but rather to the portal
    # note: so it does not make sense to match on L3 unless we can also match on ARPs
    # note: but technically you could comment out "and dp_supports_arp_match" if you don't
    # note: care that ARPs from clients always go to your portal which runs proxy ARP
    if dp_supports_l3_match and dp_supports_arp_match:
        msg = of.ofp_flow_mod()
        msg.flags = of.OFPFF_SEND_FLOW_REM
        msg.idle_timeout = client_idle_timeout
        msg.priority = 32768
        msg.match.in_port = client_port_match
        msg.match.dl_src = MAC
        msg.match.dl_type = pkt.ethernet.IP_TYPE
        msg.match.nw_src = IP
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted']))
        msg.actions.append(of.ofp_action_output(port=router_port_action))
    else:
        msg = of.ofp_flow_mod()
        msg.flags = of.OFPFF_SEND_FLOW_REM
        msg.idle_timeout = client_idle_timeout
        msg.priority = 32768
        msg.match.dl_src = MAC
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted']))
        msg.actions.append(of.ofp_action_output(port=router_port_action))
    if msg:
        cursor = db.cursor()
        cursor.execute(query)
        connection.send(msg)
Example #15
0
def pClient(username,mac,ip=""):
    # permit traffic from the client to the router - i.e. auth successful
    connection = core.openflow.getConnection(strToDPID(dpid))
    MAC = EthAddr(mac)
    IP  = IPAddr(ip)
    vlan = getVLANs(ip)
    query = "INSERT into tbl_nac_session (username,mac_address,ip_address,start_dt) VALUES ('%s','%s','%s',now())" % (username,mac,ip)
    msg = None

    # note: if the openflow switch supports L3 matching in addition to L2 matching
    # note: matching on both will result in higher security - but not all support both.
    # note: if we match on L3 and ARP matching is not supported (see sPortal),
    # note: ARPs from the client will not flow to the router but rather to the portal
    # note: so it does not make sense to match on L3 unless we can also match on ARPs
    # note: but technically you could comment out "and dp_supports_arp_match" if you don't
    # note: care that ARPs from clients always go to your portal which runs proxy ARP
    if dp_supports_l3_match and dp_supports_arp_match:
        msg = of.ofp_flow_mod()
        msg.flags = of.OFPFF_SEND_FLOW_REM
        msg.idle_timeout = client_idle_timeout
        msg.priority = 32768
        msg.match.in_port = client_port_match
        msg.match.dl_src = MAC
        msg.match.dl_type = pkt.ethernet.IP_TYPE
        msg.match.nw_src = IP
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted']))
        msg.actions.append(of.ofp_action_output(port = router_port_action))
    else:
        msg = of.ofp_flow_mod()
        msg.flags = of.OFPFF_SEND_FLOW_REM
        msg.idle_timeout = client_idle_timeout
        msg.priority = 32768
        msg.match.dl_src = MAC
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted']))
        msg.actions.append(of.ofp_action_output(port = router_port_action))
    if msg:
        cursor = db.cursor()
        cursor.execute(query)
        connection.send(msg)
Example #16
0
		def honeypot():
			print "Honeypot"	
			msg.actions.append(of.ofp_action_dl_addr.set_dst(mac_honey)) 	# honeypot MAC address
			msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 831)) 		# modify the vlan id from the 830 to 831 
			msg.actions.append(of.ofp_action_nw_addr.set_dst(ip_honeypot))  # action to send the flux to the honey_pot
			msg.actions.append(of.ofp_action_output(port = 6)) 			# which port the honeypot is connected 
			ts = time.time()
			st = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S %d-%m-%Y')		
			outputLog.write("Flow Deviated "+ IP_attack +"-->" + IP_dst +' '+ str(st) +'\n')
																		# see how i can get this port by python
			for connection in self.myconnections:
				connection.send(msg)  													#send the msg to the switch
				connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) #getting the flux stats
				print "MSG sent to switchs"
    def unknownSend(self, buffer_id, raw_data, out_port, in_port, switch):
        """
        Sends packet to unknown host
        """

        msg = of.ofp_packet_out()
        msg.in_port = in_port
        if buffer_id != -1 and buffer_id is not None:
            # We got a buffer ID from the switch; use that
            msg.buffer_id = buffer_id
        else:
            # No buffer ID from switch -- we got the raw data
            if raw_data is None:
                # No raw_data specified -- nothing to send!
                return
            msg.data = raw_data

        # Add an action to send to the specified port
        action1 = of.ofp_action_vlan_vid(vlan_vid=VLAN_DONE)
        action2 = of.ofp_action_output(port=out_port)

        msg.actions.append(action1)
        msg.actions.append(action2)
        allPorts = [
            int(p) for p in Discovery.graph.nodes[int(switch)].connection.ports
        ]
        corePorts = Discovery.getPorts(int(switch))
        hostPorts = list(set(allPorts) - set(corePorts))
        for p in hostPorts:
            if p < of.OFPP_MAX:
                action3 = of.ofp_action_vlan_vid()
                action4 = of.ofp_action_output(port=p)
                msg.actions.append(action3)
                msg.actions.append(action4)

        # Send message to switch
        self.connection.send(msg)
Example #18
0
  def _match_action(self,msg):
    
      if len(self.actions) == 1 and self.actions[0] == "" :
          return

      for action in self.actions:
          
        action_name = action.split('=')[0]
        if action_name != "STRIP_VLAN":
            action_argu = action.split('=')[1]
        
        if(action_name == "OUTPUT"):
            msg.actions.append(of.ofp_action_output(port = int(action_argu)))
      
        elif(action_name == "ENQUEUE"):
            port = action_argu.split(':')[0]
            queue_id = action_argu.split(':')[1]
            msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id)))
    
        elif(action_name == "STRIP_VLAN"):
            msg.actions.append(of.ofp_action_strip_vlan())
    
        elif(action_name == "SET_VLAN_VID"):
            msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(action_argu)))
    
        elif(action_name == "SET_VLAN_PCP"):
            msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(action_argu)))
    
        elif(action_name == "SET_DL_SRC"):
            msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(action_argu)))
    
        elif(action_name == "SET_DL_DST"):
            msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(action_argu)))
    
        elif(action_name == "SET_NW_TOS"):
            msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(action_argu)))

        elif(action_name == "SET_NW_SRC"):
            msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(action_argu)))

        elif(action_name == "SET_NW_DST"):
            msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(action_argu)))

        elif(action_name == "SET_TP_SRC"):
            msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(action_argu)))
    
        elif(action_name == "SET_TP_DST"):
            msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(action_argu)))
Example #19
0
		def dropping (duration=duration_block): #this is the time that mflow will be blocked in seconds
			msg.priority=65535
			msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 831)) 		# modify the vlan id from the 830 to 831 
			if duration is not None:
				if not isinstance(duration, tuple):
					duration = (duration,duration)
		 		msg.idle_timeout = duration[0] #this made the flow go back after the specified time
		 		msg.hard_timeout = duration[1]
			print "dropping packets from ", IP_attack 	
			ts = time.time() #create time stamp
			st = datetime.datetime.fromtimestamp(ts).strftime('%d-%m-%Y %H:%M:%S')	#human format time stamp	
			outputLog.write("Flow Blocked "+ IP_attack +"-->" + IP_dst +' '+ str(st) +" detected by "+self.addressSensor[0]+'\n')# creating the log #see how to create a log style
			for connection in self.myconnections:
				connection.send(msg)  													#send the msg to the switch
				connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) #getting the flux stats
				print "MSG sent to switches!"
Example #20
0
  def _install_hybrid_dynamic_flows(self, event, out_dpid, final_out_port, packet):
    "Install entry at ingress switch."
    in_name = self.t.id_gen(dpid = event.dpid).name_str()
    #log.info("in_name: %s" % in_name)
    out_name = self.t.id_gen(dpid = out_dpid).name_str()
    #log.info("out_name: %s" % out_name)
    hash_ = self._ecmp_hash(packet)
    src_dst_route = self.r.get_route(in_name, out_name, hash_, False)
    # Choose a random core switch.
    core_sws = sorted(self._raw_dpids(self.t.layer_nodes(self.t.LAYER_CORE)))
    core_sw = random.choice(core_sws)
    core_sw_id = self.t.id_gen(dpid = core_sw)
    core_sw_name = self.t.id_gen(dpid = core_sw).name_str()

    route = self.r.get_route(in_name, core_sw_name, None, False)
    assert len(route) == 3
    log.info("route: %s" % route)

    match = of.ofp_match.from_packet(packet)

    assert core_sw_id.pod == self.t.k
    core_sw_index = ((core_sw_id.sw - 1) * 2) + (core_sw_id.host - 1)
    #log.info("core_sw_index: %s" % core_sw_index)

    dst_host_index = self.dpid_port_to_host_index(out_dpid, final_out_port)
    #log.info("dst_host_index: %s" % dst_host_index)

    vlan = (dst_host_index << 2) + core_sw_index
    log.info("vlan: %s" % vlan)
    log.info("len(src_dst_route): %i" % len(src_dst_route))

    if len(src_dst_route) == 1:
      # Don't bother with VLAN append; directly send to out port.
      log.info("adding edge-only entry from %s to %s on sw %s" %
               (match.dl_src, match.dl_dst, in_name))
      self.switches[event.dpid].install(final_out_port, match, idle_timeout =
                                     HYBRID_IDLE_TIMEOUT,
                                     priority = PRIO_HYBRID_FLOW_DOWN)
    else:
      # Write VLAN and send up
      src_port, dst_port = self.t.port(route[0], route[1])
      actions = [of.ofp_action_vlan_vid(vlan_vid = vlan),
                 of.ofp_action_output(port = src_port)]
      self.switches[event.dpid].install_multiple(actions, match, idle_timeout =
                                              HYBRID_IDLE_TIMEOUT,
                                              priority = PRIO_HYBRID_FLOW_UP)
Example #21
0
		def install_fwdrule(event,srcip,dstip,outport,vlan=0):
			msg = of.ofp_flow_mod()
			
			#Match 
			msg.match = of.ofp_match()
			msg.match.dl_type = ethernet.IP_TYPE
			msg.match.set_nw_src(IPAddr(srcip, 32), 32)
			msg.match.set_nw_dst(IPAddr(dstip, 32), 32)

			
			if not vlan == 0 : 
				# Need to set VLAN Tag for isolation of tenant traffic.
				msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan)) 

			msg.actions.append(of.ofp_action_output(port = outport))


			msg.data = event.ofp
			msg.in_port = event.port
			event.connection.send(msg)
    def send_packet(self,
                    buffer_id,
                    raw_data,
                    out_port,
                    in_port,
                    vlan_clear=False):
        """
        Sends a packet out of the specified switch port.
        If buffer_id is a valid buffer on the switch, use that. Otherwise,
        send the raw data in raw_data.
        The "in_port" is the port number that packet arrived on.  Use
        OFPP_NONE if you're generating this packet.
        """

        # We tell the switch to take the packet with id buffer_if from in_port
        # and send it to out_port
        # If the switch did not specify a buffer_id, it must have specified
        # the raw data of the packet, so in this case we tell it to send
        # the raw data
        msg = of.ofp_packet_out()
        msg.in_port = in_port
        if buffer_id != -1 and buffer_id is not None:
            # We got a buffer ID from the switch; use that
            msg.buffer_id = buffer_id
        else:
            # No buffer ID from switch -- we got the raw data
            if raw_data is None:
                # No raw_data specified -- nothing to send!
                return
            msg.data = raw_data

        # Add an action to send to the specified port
        if vlan_clear:
            action = of.ofp_action_vlan_vid()
            msg.actions.append(action)

        action = of.ofp_action_output(port=out_port)
        msg.actions.append(action)

        # Send message to switch
        self.connection.send(msg)
Example #23
0
def flow_4f(vlanid):

    ip = ip_vlan_reverse_dict[vlanid]
    #print "flow4f ip - {0}".format(ip)
    flow4fmsg = of.ofp_flow_mod()
    flow4fmsg.cookie = 0
    flow4fmsg.match.in_port = 1
    #flow4fmsg.match.dl_type = 0x8100
    flow4fmsg.match.dl_vlan = vlanid
    flow4fmsg.hard_timeout = 60
    print blocked_ips

    # Clear blocked_ips
    # READ FROM FILE AND UPDATE blocked_ips
    with open("/home/mininet/pox/pox/misc/blocked_ips.txt", "r") as f:
        b_l = []
        for i in f:
            b_l.append(i.strip())
    global blocked_ips
    blocked_ips = b_l
    if str(ip) not in blocked_ips:
        #if True:
        #flow4fmsg.match.nw_src = IPAddr("10.0.0.2")

        # ACTIONS---------------------------------
        flow4fout = of.ofp_action_output(port=2)
        # flow4fsrcIP = of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.2"))
        flow4fsrcMAC = of.ofp_action_dl_addr.set_src(
            EthAddr("00:00:00:00:00:03"))
        flow4fdstMAC = of.ofp_action_dl_addr.set_dst(
            EthAddr("00:00:00:00:00:01"))
        flow4fvlanid = of.ofp_action_vlan_vid(vlan_vid=0)

        flow4fmsg.actions = [
            flow4fsrcMAC, flow4fdstMAC, flow4fvlanid, flow4fout
        ]
    else:
        print "IP is blocked"
    return flow4fmsg
    def two_phase_update(self, config):

        #read all the flow mods
        for dpid,flow_mod_list in config.flowmods.iteritems():
            for flow_mod in flow_mod_list:
                flow_mod.match.dl_vlan = self.vlan 
                core.openflow.getConnection(dpid).send(flow_mod)

        #for all external ports, install vlan mod rules
        for id,sw in core.openflow_topology.topology._entities.iteritems():
            for portid in sw.ports.iterkeys():
                if self.is_external(id,portid) == 1 and portid < 10:
                    match = of.ofp_match(in_port = portid)
                    flow = of.ofp_flow_mod(match = match)
                    flow.command = of.OFPFC_MODIFY_STRICT
                    action = of.ofp_action_vlan_vid(vlan_vid = self.vlan)
                    flow.actions.append(action)
                    core.openflow.getConnection(id).send(flow)

        # Delete the old vlan rules after a certain interval
        Timer(self.delete_interval, self.delete_old_rules, recurring = False)
        return 
Example #25
0
  def _match_action(self,msg):
    if(self.actions == "OUTPUT"):
      msg.actions.append(of.ofp_action_output(port = int(self.actions_argu)))
      
    elif(self.actions == "enqueue"):
      port = self.actions_argu.split(':')[0]
      queue_id = self.actions_argu.split(':')[1]
      msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id)))
    
    elif(self.actions == "strip-vlan"):
      msg.actions.append(of.ofp_action_strip_vlan())
    
    elif(self.actions == "set-vlan-id"):
      msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu)))
    
    elif(self.actions == "set-vlan-priority"):
      msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu)))
    
    elif(self.actions == "SET_DL_SRC"):
      msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu)))
    
    elif(self.actions == "SET_DL_DST"):
      msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu)))
    
    elif(self.actions == "SET_NW_TOS"):
      msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu)))

    elif(self.actions == "SET_NW_SRC"):
      msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu)))

    elif(self.actions == "SET_NW_DST"):
      msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu)))

    elif(self.actions == "SET_TP_SRC"):
      msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu)))
    
    elif(self.actions == "SET_TP_DST"):
      msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu)))
Example #26
0
 def flood ():
   """ Floods the packet """
   if event.ofp.buffer_id == -1:
     log.warning("Not flooding unbuffered packet on %s",
                 dpidToStr(event.dpid))
     return
   msg = of.ofp_packet_out()
   if time.time() - self.connection.connect_time > FLOOD_DELAY:
     # Only flood if we've been connected for a little while...
     log.debug("%i: flood %s -> %s", event.dpid, packet.src, packet.dst)
     if packet.dst.toInt() < 5 and packet.dst.toInt() < 5 and event.dpid != packet.dst.toInt() and packet.type != ethernet.VLAN_TYPE:
         log.debug("No vlan tag, pushing")
         msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = event.dpid))
     elif packet.src.toInt() < 5 and packet.dst.toInt() < 5 and event.dpid == packet.dst.toInt() and packet.type == ethernet.VLAN_TYPE:
         log.debug("VLAN tag found, popping")
         msg.actions.append(of.ofp_action_header(type=of.ofp_action_type_rev_map['OFPAT_STRIP_VLAN']))
     msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
   else:
     pass
     log.info("Holding down flood for %s", dpidToStr(event.dpid))
   msg.buffer_id = event.ofp.buffer_id
   msg.in_port = event.port
   self.connection.send(msg)
	def coding_switch(self,packet,packet_in):

		#Assign source mac to forwarding table.
		src_mac = packet.src
		dst_mac = packet.dst
		self.fwd_table[src_mac] = packet_in.in_port

		#log.debug("%s \n" % self.fwd_table)

		if dst_mac in self.fwd_table: 

			#Add flow mod
			msg = of.ofp_flow_mod()
			msg.match = of.ofp_match.from_packet(packet) #Contruct exact match based on incoming packet.
			msg.data = packet_in

			if self.check_vlan(packet): #Send VLAN packets back to the same host socket
				msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
				msg.actions.append(of.ofp_action_tp_port(type=of.OFPAT_SET_TP_DST,tp_port=666))
				print("Has VLAN")
			else:
				msg.actions.append(of.ofp_action_output(port = self.fwd_table[dst_mac]))

			#Normal learning switch (No Flow Mods). Used for comparison
			#msg = of.ofp_packet_out() #Instructs switch to send packet out.
			#msg.data = packet_in
			#msg.actions.append(of.ofp_action_output(port = self.fwd_table[dst_mac]))

		else: #Act like a hub and forward to all output ports. 
			msg = of.ofp_packet_out() #Instructs switch to send packet out.
			msg.data = packet_in
			msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))

		#Send message to switch
		msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = 2135))
		self.connection.send(msg)
Example #28
0
  def configureRules (self, event, lruleset):
	""" Configure initial rules """
	
	print "Ready for configure init rules in SW: " + dpidToStr(event.dpid) + " " + str(event.dpid) 
	
	of_fib = parse_of_file(lruleset)
	#print of_fib
	of_list = []
	try:
		of_list = of_fib[dpidToStr(event.dpid)]
	except KeyError:
		print "Oops! There is no information about the Sw " +  dpidToStr(event.dpid) + " in the configuration file"
	 
	#f = open('/tmp/' + dpidToStr(event.dpid), 'wa')
	#f.write( dpidToStr(event.dpid) + " begin " + str(time.time()))
	#of_entry = of_list[0]
	#print of_entry
	
	for of_entry in of_list:
		msg = of.ofp_flow_mod()
		#print "writing OpenFlow entry:", of_entry
		#msg.priority = 42
		
		if "dl_type" in of_entry.keys():
			msg.match.dl_type = int(of_entry["dl_type"], 16)
			 
		if "nw_proto" in of_entry.keys():
			msg.match.nw_proto = int(of_entry["nw_proto"], 10)
			
		#ETH
		if "dl_src" in of_entry.keys():
			msg.match.dl_src = EthAddr(of_entry["dl_src"])
			
		if "dl_dst" in of_entry.keys():
			msg.match.dl_dst = EthAddr(of_entry["dl_dst"])
		#IP	 
		if "nw_src" in of_entry.keys():
			msg.match.nw_src = IPAddr(of_entry["nw_src"])
			
		if "nw_dst" in of_entry.keys():
			msg.match.nw_dst = IPAddr(of_entry["nw_dst"])
		
		if "nw_tos" in of_entry.keys():
			msg.match.nw_tos = int(of_entry["nw_tos"],10)
		
		#UDP
		if "tp_dst" in of_entry.keys():
			msg.match.tp_dst = int(of_entry["tp_dst"],10)
			
		if "tp_src" in of_entry.keys():
			msg.match.tp_src = int(of_entry["tp_src"],10)
		
		#OTHERS
		if "in_port" in of_entry.keys():
			msg.match.in_port = int(of_entry["in_port"],10)
		
		if "dl_vlan" in of_entry.keys():
			msg.match.dl_vlan = int(of_entry["dl_vlan"],16)
	
		if "vlan_tci" in of_entry.keys():
			msg.match.vlan_tci = int(of_entry["vlan_tci"],16)
		
		#msg.match.tp_dst = 80
		# iterate list of actions
		#output
		#vlan
		if "mod_nw_tos" in of_entry["actions"].keys():
			msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(of_entry["actions"]["mod_nw_tos"],10)))
		
		if "mod_vlan_vid" in of_entry["actions"].keys():
			msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(of_entry["actions"]["mod_vlan_vid"],16)))
		 		
		if "mod_dl_src" in of_entry["actions"].keys():
			msg.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(of_entry["actions"]["mod_dl_src"])))
			
		if "mod_dl_dst" in of_entry["actions"].keys():
			print "mod_dl_dst: %s " % of_entry["actions"]["mod_dl_dst"]
			msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(of_entry["actions"]["mod_dl_dst"])))
		
		if "output" in of_entry["actions"].keys():
			msg.actions.append(of.ofp_action_output(port = int(of_entry["actions"]["output"],10)))
			#print "set the output port"
		
		self.connection.send(msg)
	
	#f.write(" ending " + str(time.time()) + "\n")
	#f.close()
	print "Init rules configured, allow traffic for " + dpidToStr(event.dpid)
Example #29
0
    def reply_request(self,
                      success,
                      request_id,
                      event,
                      title_aggr=None,
                      w=None):
        # Build the response
        resp_msg = dts_pb2.ControlResponse()
        resp_msg.status = resp_msg.SUCCESS if success else resp_msg.FAILURE
        if request_id != None:
            resp_msg.request_id = request_id

        if self.aggr and w:  # reply for the second workspace attachment
            print 'title_aggr', title_aggr, 'flow', self.flow
            # Send FLOW_MOD to the swith that is ataching an entity
            title = w.title
            if title_aggr in workspaces_aggr:
                w2 = workspaces_aggr[title_aggr]
            else:
                log.info('Unknown aggregated workspace title')
            title_hash = hashlib.sha256(title).digest()[:12]
            title_hash_aggr = hashlib.sha256(title_aggr).digest()[:12]
            recvRule = of.ofp_flow_mod()
            recvRule.command = of.OFPFC_MODIFY_STRICT
            #recvRule.match.dl_type = 0x0880         # Causes conflicts with user-space switches
            recvRule.match.dl_dst = title_hash_aggr[:6]
            recvRule.match.dl_src = title_hash_aggr[6:]
            recvRule.match.dl_vlan = self.flow
            recvRule.actions.append(
                of.ofp_action_dl_addr.set_dst(title_hash[:6]))
            recvRule.actions.append(
                of.ofp_action_dl_addr.set_src(title_hash[6:]))
            recvRule.actions.append(
                of.ofp_action_enqueue(port=event.port, queue_id=1))
            core.openflow.sendToDPID(event.dpid, recvRule)
            try:
                s = w.switches[event.dpid]
            except KeyError:
                s = w.WPSwitch(event.dpid)
                w.switches[s.dpid] = s
            if event.dpid == w2.path[-1]:
                s.used_ports.add(
                    graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1]) -
                                               1]]['ports'][w2.path[-1]])
            else:
                s.used_ports.add(
                    graph[w2.path[0]][w2.path[w2.path.index(w2.path[0]) +
                                              1]]['ports'][w2.path[0]])
            sendRule = of.ofp_flow_mod()
            sendRule.command = of.OFPFC_MODIFY_STRICT
            #sendRule.match.dl_type = 0x0880        # Causes conflicts with user-space switches
            sendRule.match.dl_dst = title_hash[:6]
            sendRule.match.dl_src = title_hash[6:]
            sendRule.actions.append(
                of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6]))
            sendRule.actions.append(
                of.ofp_action_dl_addr.set_src(title_hash_aggr[6:]))
            sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow))
            for p in s.used_ports:
                sendRule.actions.append(
                    of.ofp_action_enqueue(port=p, queue_id=1))
            core.openflow.sendToDPID(event.dpid, sendRule)
            # Send FLOW_MOD to the switch that created the workspace
            switch1 = wks[w.title]
            print 'OZUUUUUU1', switch1.dpid, switch1.port,
            try:
                s = w.switches[switch1.dpid]
            except KeyError:
                s = w.WPSwitch(switch1.dpid)
                w.switches[s.dpid] = s
            if switch1.dpid == w2.path[0]:
                s.used_ports.add(
                    graph[w2.path[0]][w2.path[w2.path.index(w2.path[0]) +
                                              1]]['ports'][w2.path[0]])
            else:
                s.used_ports.add(
                    graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1]) -
                                               1]]['ports'][w2.path[-1]])
            sendRule = of.ofp_flow_mod()
            sendRule.command = of.OFPFC_MODIFY_STRICT
            #sendRule.match.dl_type = 0x0880          # Causes conflicts with user-space switches
            sendRule.match.dl_dst = title_hash[:6]
            sendRule.match.dl_src = title_hash[6:]
            sendRule.actions.append(
                of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6]))
            sendRule.actions.append(
                of.ofp_action_dl_addr.set_src(title_hash_aggr[6:]))
            sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow))
            for p in s.used_ports:
                sendRule.actions.append(
                    of.ofp_action_enqueue(port=p, queue_id=1))
            core.openflow.sendToDPID(switch1.dpid, sendRule)
            recvRule = of.ofp_flow_mod()
            recvRule.command = of.OFPFC_MODIFY_STRICT
            #recvRule.match.dl_type = 0x0880           # Causes conflicts with user-space switches
            recvRule.match.dl_dst = title_hash_aggr[:6]
            recvRule.match.dl_src = title_hash_aggr[6:]
            recvRule.match.dl_vlan = self.flow
            recvRule.actions.append(
                of.ofp_action_dl_addr.set_dst(title_hash[:6]))
            recvRule.actions.append(
                of.ofp_action_dl_addr.set_src(title_hash[6:]))
            recvRule.actions.append(
                of.ofp_action_enqueue(port=event.port, queue_id=1))
            core.openflow.sendToDPID(switch1.dpid, recvRule)

        resp_msg = resp_msg.SerializeToString()

        # Send response back to the entity
        resp = of.ofp_packet_out()
        if not self.wifi:  # not wifi
            resp.data = ''.join(
                (DTSA.HEADER, struct.pack("<H", len(resp_msg)), resp_msg))
        else:
            resp.data = ''.join(
                (self.addrResp, struct.pack("<H", len(resp_msg)), resp_msg))
        resp.actions.append(of.ofp_action_output(port=event.port))
        event.connection.send(resp)
Example #30
0
    def install_flow(self, pred, action_list):
        switch = pred['switch']

        ### BUILD OF MATCH
        inport = pred['inport']
        match = of.ofp_match()
        match.in_port = pred['inport']
        match.dl_src = pred['srcmac']
        match.dl_dst = pred['dstmac']
        match.dl_type = pred['ethtype']
        if 'vlan_id' in pred:
            match.dl_vlan = pred['vlan_id']
        else:
            match.dl_vlan = 0xffff
        if 'vlan_pcp' in pred:
            match.dl_vlan_pcp = pred['vlan_pcp']
        else:
            match.dl_vlan_pcp = 0
        match.nw_proto = pred['protocol']
        if 'srcip' in pred:
            match.nw_src = pred['srcip']
        if 'dstip' in pred:
            match.nw_dst = pred['dstip']
        if 'tos' in pred:
            match.nw_tos = pred['tos']
        if 'srcport' in pred:
            match.tp_src = pred['srcport']
        if 'dstport' in pred:
            match.tp_dst = pred['dstport']

        ### BUILD OF ACTIONS
        of_actions = []
        for actions in action_list:
            outport = actions['outport']
            del actions['outport']
            if 'srcmac' in actions:
                of_actions.append(
                    of.ofp_action_dl_addr.set_src(actions['srcmac']))
            if 'dstmac' in actions:
                of_actions.append(
                    of.ofp_action_dl_addr.set_dst(actions['dstmac']))
            if 'srcip' in actions:
                of_actions.append(
                    of.ofp_action_nw_addr.set_src(actions['srcip']))
            if 'dstip' in actions:
                of_actions.append(
                    of.ofp_action_nw_addr.set_dst(actions['dstip']))
            if 'vlan_id' in actions:
                if actions['vlan_id'] is None:
                    of_actions.append(of.ofp_action_strip_vlan())
                else:
                    of_actions.append(
                        of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id']))
            if 'vlan_pcp' in actions:
                if actions['vlan_pcp'] is None:
                    if not actions['vlan_id'] is None:
                        raise RuntimeError(
                            "vlan_id and vlan_pcp must be set together!")
                    pass
                else:
                    of_actions.append(
                        of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp']))
            if outport == inport:
                of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
            else:
                of_actions.append(of.ofp_action_output(port=outport))

        msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                              idle_timeout=of.OFP_FLOW_PERMANENT,
                              hard_timeout=of.OFP_FLOW_PERMANENT,
                              match=match,
                              actions=of_actions)
        try:
            self.switches[switch]['connection'].send(msg)
        except RuntimeError, e:
            print "ERROR:install_flow: %s to switch %d" % (str(e), switch)
Example #31
0
    def install_flowrule(self, id, match, action):
        """
    Install a flowrule in an OpenFlow switch.

    :param id: ID of the infra element stored in the NFFG
    :type id: str
    :param match: match part of the rule (keys: in_port, vlan_id)
    :type match: dict
    :param action: action part of the rule (keys: out, vlan_push, vlan_pop)
    :type action: dict
    :return: None
    """
        conn = self.openflow.getConnection(dpid=self.infra_to_dpid[id])
        if not conn:
            log.warning(
                "Missing connection for node element: %s! Skip flowrule "
                "installation..." % id)
            return
        msg = of.ofp_flow_mod()
        msg.match.in_port = match['in_port']
        if 'vlan_id' in match:
            try:
                vlan_id = int(match['vlan_id'])
            except ValueError:
                log.warning(
                    "VLAN_ID: %s in match field is not a valid number! "
                    "Skip flowrule installation..." % match['vlan_id'])
                return
            msg.match.dl_vlan = vlan_id
        # Append explicit matching parameters to OF flowrule
        if 'flowclass' in match:
            for ovs_match_entry in match['flowclass'].split(','):
                kv = ovs_match_entry.split('=')
                # kv = [field, value] ~ ['dl_src', '00:0A:E4:25:6B:B6']
                # msg.match.dl_src = "00:00:00:00:00:01"
                if kv[0] in ('dl_src', 'dl_dst'):
                    setattr(msg.match, kv[0], EthAddr(kv[1]))
                elif kv[0] in ('in_port', 'dl_vlan', 'dl_type', 'ip_proto',
                               'nw_proto', 'nw_tos', 'nw_ttl', 'tp_src',
                               'tp_dst'):
                    setattr(msg.match, kv[0], int(kv[1], 0))
                elif kv[0] in ('nw_src', 'nw_dst'):
                    setattr(msg.match, kv[0], IPAddr(kv[1]))
                else:
                    setattr(msg.match, kv[0], kv[1])
        if 'vlan_push' in action:
            try:
                vlan_push = int(action['vlan_push'])
            except ValueError:
                log.warning(
                    "VLAN_PUSH: %s in action field is not a valid number! "
                    "Skip flowrule installation..." % action['vlan_push'])
                return
            msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan_push))
            # msg.actions.append(of.ofp_action_vlan_vid())
        out = action['out']
        # If out is in the detected saps --> always remove the VLAN tags
        if 'vlan_pop' in action:
            msg.actions.append(of.ofp_action_strip_vlan())
        else:
            try:
                # If next node is a SAP we need to setup the MAC addresses and
                # strip VLAN from the frame explicitly
                if out in self.saps[id]:
                    msg.actions.append(of.ofp_action_strip_vlan())
            except KeyError:
                pass
        try:
            if out in self.saps[id]:
                dl_dst = self.saps[id][str(out)]['dl_dst']
                dl_src = self.saps[id][str(out)]['dl_src']
                msg.actions.append(
                    of.ofp_action_dl_addr.set_dst(EthAddr(dl_dst)))
                msg.actions.append(
                    of.ofp_action_dl_addr.set_src(EthAddr(dl_src)))
        except KeyError:
            pass
        try:
            out_port = int(action['out'])
        except ValueError:
            log.warning(
                "Output port: %s is not a valid port in flowrule action: %s! "
                "Skip flowrule installation..." % (action['out'], action))
            return
        msg.actions.append(of.ofp_action_output(port=out_port))
        log.debug("Install flow entry into INFRA: %s on connection: %s ..." %
                  (id, conn))
        conn.send(msg)
        log.log(VERBOSE, "Sent raw OpenFlow flowrule:\n%s" % msg)
Example #32
0
def configureRules(connection, lruleset):
    """ Configure initial rules """

    #print "Ready for configure init rules in SW: " + dpidToStr(connection.dpid) + " " + str(connection.dpid)

    of_fib = parse_of_file(lruleset)
    #print of_fib
    of_list = []
    try:
        of_list = of_fib[dpidToStr(connection.dpid)]
    except KeyError:
        print "Oops! There are no for the Sw " + dpidToStr(connection.dpid)

    #f = open('/tmp/' + dpidToStr(event.dpid), 'wa')
    #f.write( dpidToStr(event.dpid) + " begin " + str(time.time()))
    #of_entry = of_list[0]
    #print of_entry

    for of_entry in of_list:
        msg = of.ofp_flow_mod()
        #print "writing OpenFlow entry:", of_entry
        #msg.priority = 42

        if "dl_type" in of_entry.keys():
            msg.match.dl_type = int(of_entry["dl_type"], 16)

        if "nw_proto" in of_entry.keys():
            msg.match.nw_proto = int(of_entry["nw_proto"], 10)

        #ETH
        if "dl_src" in of_entry.keys():
            msg.match.dl_src = EthAddr(of_entry["dl_src"])

        if "dl_dst" in of_entry.keys():
            msg.match.dl_dst = EthAddr(of_entry["dl_dst"])
        #IP
        if "nw_src" in of_entry.keys():
            msg.match.nw_src = of_entry["nw_src"]
            #msg.match.nw_src = IPAddr(of_entry["nw_src"])

        if "nw_dst" in of_entry.keys():
            msg.match.nw_dst = of_entry["nw_dst"]
            #msg.match.nw_dst = IPAddr(of_entry["nw_dst"])

        if "nw_tos" in of_entry.keys():
            msg.match.nw_tos = int(of_entry["nw_tos"], 10)

        #UDP
        if "tp_dst" in of_entry.keys():
            msg.match.tp_dst = int(of_entry["tp_dst"], 10)

        if "tp_src" in of_entry.keys():
            msg.match.tp_src = int(of_entry["tp_src"], 10)

        #OTHERS
        if "in_port" in of_entry.keys():
            msg.match.in_port = int(of_entry["in_port"], 10)

        if "dl_vlan" in of_entry.keys():
            msg.match.dl_vlan = int(of_entry["dl_vlan"], 10)

        if "dl_vlan_pcp" in of_entry.keys():
            msg.match.dl_vlan_pcp = int(of_entry["dl_vlan_pcp"], 10)

        #msg.match.tp_dst = 80
        # iterate list of actions
        #output
        #vlan
        if "mod_nw_tos" in of_entry["actions"].keys():
            msg.actions.append(
                of.ofp_action_nw_tos(
                    nw_tos=int(of_entry["actions"]["mod_nw_tos"], 10)))

        if "mod_vlan_vid" in of_entry["actions"].keys():
            msg.actions.append(
                of.ofp_action_vlan_vid(
                    vlan_vid=int(of_entry["actions"]["mod_vlan_vid"], 10)))

        if "mod_vlan_pcp" in of_entry["actions"].keys():
            msg.actions.append(
                of.ofp_action_vlan_pcp(
                    vlan_pcp=int(of_entry["actions"]["mod_vlan_pcp"], 10)))

        if "mod_dl_src" in of_entry["actions"].keys():
            msg.actions.append(
                of.ofp_action_dl_addr.set_src(
                    EthAddr(of_entry["actions"]["mod_dl_src"])))

        if "mod_dl_dst" in of_entry["actions"].keys():
            msg.actions.append(
                of.ofp_action_dl_addr.set_dst(
                    EthAddr(of_entry["actions"]["mod_dl_dst"])))

        if "output" in of_entry["actions"].keys():
            msg.actions.append(
                of.ofp_action_output(
                    port=int(of_entry["actions"]["output"], 10)))
            #print "set the output port"

        connection.send(msg)

    #f.write(" ending " + str(time.time()) + "\n")
    #f.close()
    print "Rules configured, allow traffic for " + dpidToStr(connection.dpid)
  def send_table (self):
    if self.connection is None:
      self.log.debug("Can't send table: disconnected")
      return

    clear = of.ofp_flow_mod(command=of.OFPFC_DELETE)
    self.connection.send(clear)
    self.connection.send(of.ofp_barrier_request())

    # From DHCPD
    msg = of.ofp_flow_mod()
    msg.match = of.ofp_match()
    msg.match.dl_type = pkt.ethernet.IP_TYPE
    msg.match.nw_proto = pkt.ipv4.UDP_PROTOCOL
    #msg.match.nw_dst = IP_BROADCAST
    msg.match.tp_src = pkt.dhcp.CLIENT_PORT
    msg.match.tp_dst = pkt.dhcp.SERVER_PORT
    msg.actions.append(of.ofp_action_output(port = of.OFPP_CONTROLLER))
    #msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
    self.connection.send(msg)

    core.openflow_discovery.install_flow(self.connection)

    '''
    self.mac_to_vid = {
    00.00.00.00.00.00 = 1
    }
    '''

    self.edge_ports = []
    for port in self.ports:
      pn = port.port_no
      if pn < 0 or pn >= of.OFPP_MAX: continue

      if core.openflow_discovery.is_edge_port(self.dpid, pn):
        self.edge_ports.append(pn)
        src = self
        for dst in switches_by_dpid.itervalues():
          if dst is src: continue
          p = _get_path(src, dst)
          if p is None: continue

          msg = of.ofp_flow_mod()
          msg.priority += 1
          msg.match = of.ofp_match()
          msg.match.dl_type = pkt.ethernet.IP_TYPE
          #msg.match.nw_dst = "%s/%s" % (dst.network, dst.subnet)
          msg.match.in_port = pn
          msg.match.nw_src = "10.%s.%s.0/255.255.255.0" % (self._id,pn)
          msg.match.nw_dst = "%s/%s" % (dst.network, "255.255.0.0")
          msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.vid_by_port(pn)))
          msg.actions.append(of.ofp_action_output(port=p[0][1]))
          self.connection.send(msg)



    src = self
    for dst in switches_by_dpid.itervalues():
      if dst is src: continue
      p = _get_path(src, dst)
      if p is None: continue

      msg = of.ofp_flow_mod()
      msg.match = of.ofp_match()
      msg.match.dl_type = pkt.ethernet.IP_TYPE
      #msg.match.nw_dst = "%s/%s" % (dst.network, dst.subnet)
      msg.match.nw_dst = "%s/%s" % (dst.network, "255.255.0.0")

      msg.actions.append(of.ofp_action_output(port=p[0][1]))
      self.connection.send(msg)

    """
    # Can just do this instead of MAC learning if you run arp_responder...
    for port in self.ports:
      p = port.port_no
      if p < 0 or p >= of.OFPP_MAX: continue
      msg = of.ofp_flow_mod()
      msg.match = of.ofp_match()
      msg.match.dl_type = pkt.ethernet.IP_TYPE
      msg.match.nw_dst = "10.%s.%s.0/255.255.255.0" % (self._id,p)
      msg.actions.append(of.ofp_action_output(port=p))
      self.connection.send(msg)
    """

    for ip,mac in self.ip_to_mac.iteritems():
      self._send_rewrite_rule(ip, mac)

    flood_ports = []
    for port in self.ports:
      p = port.port_no
      if p < 0 or p >= of.OFPP_MAX: continue

      if core.openflow_discovery.is_edge_port(self.dpid, p):
        flood_ports.append(p)

      msg = of.ofp_flow_mod()
      msg.priority -= 1
      msg.match = of.ofp_match()
      msg.match.dl_type = pkt.ethernet.IP_TYPE
      msg.match.nw_dst = "10.%s.%s.0/255.255.255.0" % (self._id,p)
      msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
      self.connection.send(msg)

    msg = of.ofp_flow_mod()
    msg.priority -= 1
    msg.match = of.ofp_match()
    msg.match.dl_type = pkt.ethernet.IP_TYPE
    msg.match.nw_dst = "255.255.255.255"
    for p in flood_ports:
      msg.actions.append(of.ofp_action_output(port=p))
    self.connection.send(msg)
  def act_like_switch (self, packet, packet_in):
    """
    Implement switch-like behavior.
    """

    # Here's some psuedocode to start you off implementing a learning
    # switch.  You'll need to rewrite it as real Python code.
    log.debug("DPID: %s" % self.connection.dpid)

    # Learn source vlan of the packet
    if packet.type == ethernet.VLAN_TYPE:
      src_vlan = packet.find('vlan').id
    else:
      src_vlan = self.vlan_to_port[packet_in.in_port]

    log.debug("Source VLAN: %s" % src_vlan) 

    # Learn the port for the source MAC
    self.mac_to_port[packet.src] = packet_in.in_port # add or update mac table entry

    # Ports to send out the packet
    out_ports = []

    #if the port associated with the destination MAC of the packet is known
    if packet.dst in self.mac_to_port: 
      log.debug("Mac is in table")

      dst_vlan = self.vlan_to_port[self.mac_to_port[packet.dst]]

      #if the port is in the same vlan as sending port
      if src_vlan == dst_vlan or dst_vlan == 1:

        # Send packet out the associated port
        out_ports.append(self.mac_to_port[packet.dst])
        self.resend_packet(packet_in, out_ports)
        
        log.debug("Installing flow. Source port: %s. Destination port: %s.", packet_in.in_port, self.mac_to_port[packet.dst])

        # Install the flow table entry
        msg = of.ofp_flow_mod()

        ## Set fields to match received packet
        msg.match = of.ofp_match(dl_dst = packet.dst)
        
        #< Set other fields of flow_mod (timeouts? buffer_id?) >
        msg.idle_timeout = 60
        
        # Add action to add vlan tag or strip it
        if dst_vlan == 1:
          action = of.ofp_action_vlan_vid(vlan_vid = src_vlan)
        else:
          action = of.ofp_action_strip_vlan()
        msg.actions.append(action)

        # Add action to resend packet out of the specified port
        msg.actions.append(of.ofp_action_output(port = self.mac_to_port[packet.dst]))
        self.connection.send(msg)
        
    else:
      # Sending to all ports in same vlan as the input port or dot1q port, ignore port connected to controller
      log.debug("Adress is not in table, flooding: ")
      for port in self.connection.ports:
        if port != packet_in.in_port and (self.vlan_to_port[port] == src_vlan or self.vlan_to_port[port] == 1):
           out_ports.append(port)
      log.debug(out_ports)
      if len(out_ports) > 0:
        self.resend_packet(packet_in, out_ports)
Example #35
0
    def install_flow(self,pred,action_list):
        switch = pred['switch']

        ### BUILD OF MATCH
        inport = pred['inport']
        match = of.ofp_match()
        match.in_port = pred['inport']
        match.dl_src = pred['srcmac']
        match.dl_dst = pred['dstmac']
        match.dl_type = pred['ethtype']
        if 'vlan_id' in pred:
            match.dl_vlan = pred['vlan_id']
        else:
            match.dl_vlan = 0xffff
        if 'vlan_pcp' in pred:
            match.dl_vlan_pcp = pred['vlan_pcp']
        else:
            match.dl_vlan_pcp = 0
        match.nw_proto = pred['protocol']
        if 'srcip' in pred:
            match.nw_src = pred['srcip']
        if 'dstip' in pred:
            match.nw_dst = pred['dstip']
        if 'tos' in pred:
            match.nw_tos = pred['tos']
        if 'srcport' in pred:
            match.tp_src = pred['srcport']
        if 'dstport' in pred:
            match.tp_dst = pred['dstport']

        ### BUILD OF ACTIONS
        of_actions = []
        for actions in action_list:
            outport = actions['outport']
            del actions['outport']
            if 'srcmac' in actions:
                of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac']))
            if 'dstmac' in actions:
                of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac']))
            if 'srcip' in actions:
                of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip']))
            if 'dstip' in actions:
                of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip']))
            if 'vlan_id' in actions:
                if actions['vlan_id'] is None:
                    of_actions.append(of.ofp_action_strip_vlan())
                else:
                    of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id']))
            if 'vlan_pcp' in actions:
                if actions['vlan_pcp'] is None:
                    if not actions['vlan_id'] is None:
                        raise RuntimeError("vlan_id and vlan_pcp must be set together!")
                    pass
                else:
                    of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp']))
            if outport == inport:
                of_actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
            else:
                of_actions.append(of.ofp_action_output(port=outport))

        msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                              idle_timeout=of.OFP_FLOW_PERMANENT,
                              hard_timeout=of.OFP_FLOW_PERMANENT,
                              match=match,
                              actions=of_actions)
        try:
            self.switches[switch]['connection'].send(msg)
        except RuntimeError, e:
            print "ERROR:install_flow: %s to switch %d" % (str(e),switch)
    def reply_request(self, success, request_id, event, title_aggr=None, w = None):
        # Build the response
        resp_msg = dts_pb2.ControlResponse()
        resp_msg.status = resp_msg.SUCCESS if success else resp_msg.FAILURE
        if request_id != None:
            resp_msg.request_id = request_id

        if self.aggr and w:                            # reply for the second workspace attachment
            print 'title_aggr', title_aggr, 'flow', self.flow
            # Send FLOW_MOD to the swith that is ataching an entity
            title      = w.title
            if title_aggr in workspaces_aggr:
                w2 = workspaces_aggr[title_aggr]
            else:
                log.info('Unknown aggregated workspace title')
            title_hash      = hashlib.sha256(title).digest()[:12]
            title_hash_aggr = hashlib.sha256(title_aggr).digest()[:12]
            recvRule = of.ofp_flow_mod()
            recvRule.command = of.OFPFC_MODIFY_STRICT
            #recvRule.match.dl_type = 0x0880         # Causes conflicts with user-space switches
            recvRule.match.dl_dst = title_hash_aggr[:6]
            recvRule.match.dl_src = title_hash_aggr[6:]
            recvRule.match.dl_vlan = self.flow
            recvRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash[:6]))
            recvRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash[6:]))
            recvRule.actions.append(of.ofp_action_enqueue(port=event.port, queue_id=1))
            core.openflow.sendToDPID(event.dpid, recvRule)
            try:
                s = w.switches[event.dpid]
            except KeyError:
                s = w.WPSwitch(event.dpid)
                w.switches[s.dpid] = s
            if event.dpid == w2.path[-1]:
                s.used_ports.add(graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1])-1]]['ports'][w2.path[-1]])
            else:
                s.used_ports.add(graph[w2.path[0]][w2.path[w2.path.index(w2.path[0])+1]]['ports'][w2.path[0]])
            sendRule = of.ofp_flow_mod()
            sendRule.command = of.OFPFC_MODIFY_STRICT
            #sendRule.match.dl_type = 0x0880        # Causes conflicts with user-space switches
            sendRule.match.dl_dst = title_hash[:6]
            sendRule.match.dl_src = title_hash[6:]
            sendRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6]))
            sendRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash_aggr[6:]))
            sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow))
            for p in s.used_ports:
                sendRule.actions.append(of.ofp_action_enqueue(port=p, queue_id=1))
            core.openflow.sendToDPID(event.dpid, sendRule)
            # Send FLOW_MOD to the switch that created the workspace
            switch1 = wks[w.title]
            print 'OZUUUUUU1', switch1.dpid, switch1.port,
            try:
                s = w.switches[switch1.dpid]
            except KeyError:
                s = w.WPSwitch(switch1.dpid)
                w.switches[s.dpid] = s
            if switch1.dpid == w2.path[0]:
                s.used_ports.add(graph[w2.path[0]][w2.path[w2.path.index(w2.path[0])+1]]['ports'][w2.path[0]])
            else:
                s.used_ports.add(graph[w2.path[-1]][w2.path[w2.path.index(w2.path[-1])-1]]['ports'][w2.path[-1]])
            sendRule = of.ofp_flow_mod()
            sendRule.command = of.OFPFC_MODIFY_STRICT
            #sendRule.match.dl_type = 0x0880          # Causes conflicts with user-space switches
            sendRule.match.dl_dst = title_hash[:6]
            sendRule.match.dl_src = title_hash[6:]
            sendRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash_aggr[:6]))
            sendRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash_aggr[6:]))
            sendRule.actions.append(of.ofp_action_vlan_vid(vlan_vid=self.flow))
            for p in s.used_ports:
                sendRule.actions.append(of.ofp_action_enqueue(port=p, queue_id=1))
            core.openflow.sendToDPID(switch1.dpid, sendRule)
            recvRule = of.ofp_flow_mod()
            recvRule.command = of.OFPFC_MODIFY_STRICT
            #recvRule.match.dl_type = 0x0880           # Causes conflicts with user-space switches
            recvRule.match.dl_dst = title_hash_aggr[:6]
            recvRule.match.dl_src = title_hash_aggr[6:]
            recvRule.match.dl_vlan = self.flow
            recvRule.actions.append(of.ofp_action_dl_addr.set_dst(title_hash[:6]))
            recvRule.actions.append(of.ofp_action_dl_addr.set_src(title_hash[6:]))
            recvRule.actions.append(of.ofp_action_enqueue(port=event.port, queue_id=1))
            core.openflow.sendToDPID(switch1.dpid, recvRule)

        resp_msg = resp_msg.SerializeToString()

        # Send response back to the entity
        resp = of.ofp_packet_out()
        if not self.wifi:             # not wifi
            resp.data = ''.join((DTSA.HEADER, struct.pack("<H", len(resp_msg)), resp_msg))
        else:
            resp.data = ''.join((self.addrResp, struct.pack("<H", len(resp_msg)), resp_msg))
        resp.actions.append(of.ofp_action_output(port = event.port))
        event.connection.send(resp)
Example #37
0
def sPortal(connection):
    for network, vlan in networks.iteritems():

        # permit DNS to flow from clients to router
        msg = of.ofp_flow_mod()
        msg.priority = 20
        msg.match.in_port = client_port_match
        msg.match.dl_vlan = vlan['untrusted']
        msg.match.dl_type = 0x0800
        msg.match.nw_proto = 17
        msg.match.tp_dst = 53
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted']))
        msg.actions.append(of.ofp_action_output(port=router_port_action))
        connection.send(msg)

        # permit DHCP to flow from clients to router
        msg = of.ofp_flow_mod()
        msg.priority = 20
        msg.match.in_port = client_port_match
        msg.match.dl_vlan = vlan['untrusted']
        msg.match.dl_type = 0x0800
        msg.match.nw_proto = 17
        msg.match.tp_src = 68
        msg.match.tp_dst = 67
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['trusted']))
        msg.actions.append(of.ofp_action_output(port=router_port_action))
        connection.send(msg)

        # permit ARP to flow from clients to router (if supported)
        # otherwise, pre-authenticated clients will ARP to captive portal
        # which should be running proxy-arp so there should still be no problem
        if dp_supports_arp_match:
            msg = of.ofp_flow_mod()
            msg.priority = 20
            msg.match.in_port = client_port_match
            msg.match.dl_vlan = vlan['untrusted']
            msg.match.dl_type = pkt.ethernet.ARP_TYPE
            msg.actions.append(
                of.ofp_action_vlan_vid(vlan_vid=vlan['trusted']))
            msg.actions.append(of.ofp_action_output(port=router_port_action))
            connection.send(msg)

        # send traffic from the client to the portal
        msg = of.ofp_flow_mod()
        msg.priority = 10
        msg.match.in_port = client_port_match
        msg.match.dl_vlan = vlan['untrusted']
        msg.actions.append(of.ofp_action_dl_addr.set_dst(portal))
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['portal']))
        msg.actions.append(of.ofp_action_output(port=portal_port_action))
        connection.send(msg)

        # send IP traffic from the portal back to the client
        msg = of.ofp_flow_mod()
        msg.priority = 10
        msg.match.in_port = portal_port_match
        msg.match.dl_vlan = vlan['portal']
        msg.match.dl_src = portal
        # note - commented out because the switch under test can't match IP networks yet
        # note - this means for now that the "networks" array can only contain one network
        # note - we would have to also match ARP which is also not supported via the device under test
        #msg.match.dl_type = pkt.ethernet.IP_TYPE
        #msg.match.nw_dst = network
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['untrusted']))
        msg.actions.append(of.ofp_action_output(port=client_port_action))
        connection.send(msg)

        # send IP traffic from the router back to the client
        msg = of.ofp_flow_mod()
        msg.priority = 10
        msg.match.in_port = router_port_match
        msg.match.dl_vlan = vlan['trusted']
        msg.match.dl_src = router
        # note - commented out because the switch under test can't match IP networks yet
        # note - this means for now that teh "networks" array can only contain one network
        # note - we would have to also match ARP which is also not supported via the device under test
        #msg.match.dl_type = pkt.ethernet.IP_TYPE
        #msg.match.nw_dst = network
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlan['untrusted']))
        msg.actions.append(of.ofp_action_output(port=client_port_action))
        connection.send(msg)
Example #38
0
from pox.core import core
from pox.lib.addresses import IPAddr
from pox.lib.addresses import EthAddr
import pox.openflow.libopenflow_01 as of

log = core.getLogger()

#1: 
switch0 = 0000000000000005
flow0msg = of.ofp_flow_mod() 
flow0msg.cookie = 0 
flow0msg.priority = 32768
flow0msg.match.in_port = 1
flow0msg.match.nw_proto = 6
# ACTIONS---------------------------------
flow0vlan_id = of.ofp_action_vlan_vid (vlan_vid = 10)
flow0out = of.ofp_action_output (port = 3)
flow0msg.actions = [flow0vlan_id, flow0out] 

#2: 
switch1 = 0000000000000005
flow1msg = of.ofp_flow_mod() 
flow1msg.cookie = 0 
flow1msg.priority = 32768
flow1msg.match.in_port = 2
flow1msg.match.nw_proto = 6
# ACTIONS---------------------------------
flow1vlan_id = of.ofp_action_vlan_vid (vlan_vid = 20)
flow1out = of.ofp_action_output (port = 3)
flow1msg.actions = [flow1vlan_id, flow1out] 
Example #39
0
  def __handle_PacketIn(self, event):
    packet = event.parsed
    src = packet.src.toStr()
    dst = packet.dst.toStr()

    if self.lat_test:
      if packet.type != 0x5566:
        # not test packet, drop it
        return

      src = self._MAC_to_int(src)
      dst = self._MAC_to_int(dst)

      timeinit, = struct.unpack('!I', packet.find('ethernet').payload)
      timediff = time.time()*1000 - self.system_time - timeinit
      
      if src in self.adj_test:
        if dst in self.adj_test[src]:
          self.adj[src][dst] = timediff
          del self.adj_test[src][dst]

      if dst in self.sw_test:
        self.sw_lat[dst] = timediff
        self.sw_test.remove(dst)

      return

    pid = 0

    if src in self.hosts:
      for d in self.sd_path_table[src]:
        # FIXME: Pick one as default
        # Maybe we should apply flood function to broadcasting
        for sd_path_id in self.sd_path_table[src][d]:
          pid = sd_path_id
          # log.warning("Packet Vid = %i", pid)

      
      if dst in self.hosts:
        if self.config.config_set:
          id_list = self.sd_path_table[src][dst]
          # last one, in case not found
          pid = len(id_list) - 1
          
          sum_of_all = 0
          for x in id_list:
            sum_of_all += self.config.now_config[x-1]
          
          rand_num = sum_of_all * random.random()
          for x in id_list:
            rand_num -= self.config.now_config[x-1]  # Since the path ID starts from 1, which is different from the index
            if rand_num < 0:
              # path_id should start from 1
              pid = x
              break
          log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid) 
        else:
          # FIXME: path selection
          for sd_path_id in self.sd_path_table[src][dst]:    
            # There exists a path
            pid = sd_path_id
            # log.warning("Packet Vid = %i", pid)

      msg = of.ofp_packet_out( data = event.ofp )
      if pid != 0:
        # There exists a path
        path = self.path_id_table[pid]
        if len(path) > 3:
          # It is not the last sw, tag it and send into the network
          if USE_VLAN_TAG:
            msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) )
          if USE_ETHERNET_SRC_TAG:
            msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) )
          msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) )
        elif len(path) == 3:
          # last sw, forward to the host
          # msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) )
          msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) )

      event.connection.send(msg)
Example #40
0
  def _handle_PacketIn (self, event):
    """
    Handles packet in messages from the switch to implement above algorithm.
    """

    packet = event.parse()

    def flood ():
      """ Floods the packet """
      if event.ofp.buffer_id == -1:
        log.warning("Not flooding unbuffered packet on %s",
                    dpidToStr(event.dpid))
        return
      msg = of.ofp_packet_out()
      if time.time() - self.connection.connect_time > FLOOD_DELAY:
        # Only flood if we've been connected for a little while...
        #log.debug("%i: flood %s -> %s", event.dpid, packet.src, packet.dst)
        msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
      else:
        pass
        #log.info("Holding down flood for %s", dpidToStr(event.dpid))
      msg.buffer_id = event.ofp.buffer_id
      msg.in_port = event.port
      self.connection.send(msg)

    def drop (duration = None):
      """
      Drops this packet and optionally installs a flow to continue
      dropping similar ones for a while
      """
      if duration is not None:
        if not isinstance(duration, tuple):
          duration = (duration,duration)
        msg = of.ofp_flow_mod()
        msg.match = of.ofp_match.from_packet(packet)
        msg.idle_timeout = duration[0]
        msg.hard_timeout = duration[1]
        msg.buffer_id = event.ofp.buffer_id
        self.connection.send(msg)
      elif event.ofp.buffer_id != -1:
        msg = of.ofp_packet_out()
        msg.buffer_id = event.ofp.buffer_id
        msg.in_port = event.port
        self.connection.send(msg)

    self.macToPort[packet.src] = event.port # 1

    if not self.transparent:
      if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered(): # 2
        drop()
        return

    if packet.dst.isMulticast():
      flood() # 3a
    else:
      if packet.dst not in self.macToPort: # 4
        log.debug("Port for %s unknown -- flooding" % (packet.dst,))
        flood() # 4a
      else:
        port = self.macToPort[packet.dst]
        if port == event.port: # 5
          # 5a
          log.warning("Same port for packet from %s -> %s on %s.  Drop." %
                      (packet.src, packet.dst, port), dpidToStr(event.dpid))
          drop(10)
          return
        # 6
        log.debug("installing flow for %s.%i -> %s.%i" %
                  (packet.src, event.port, packet.dst, port))
        
        log.debug("\nDPG: test code to include rule to install VLAN tag\n") 
        
        # DPG CODE IS IN THIS AREA ************************************************************************************************************
        msg = of.ofp_flow_mod()
        msg.match = of.ofp_match.from_packet(packet)
        msg.idle_timeout = 100000
        msg.hard_timeout = 300000
        msg.actions.append(of.ofp_action_output(port = port))   
        vlan_vid = self._get_next_vlad_id()
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan_vid))
        #msg.actions.append(of.ofp_action_vlan_vid())
        #msg.actions.append(of.ofp_action_vlan_vid(self._get_next_vlad_id()))
        msg.buffer_id = event.ofp.buffer_id # 6a
        self.connection.send(msg)
        
        log.debug("\n ---------------------------------------------------")
        log.debug("DPG: here is the flow")
        log.debug(msg)
        log.debug(" --------------------------------------------------- \n")
Example #41
0
    def _match_action(self, msg):

        if len(self.actions) == 1 and self.actions[0] == "":
            return

        for action in self.actions:

            action_name = action.split('=')[0]
            if action_name != "STRIP_VLAN":
                action_argu = action.split('=')[1]

            if (action_name == "OUTPUT"):
                msg.actions.append(of.ofp_action_output(port=int(action_argu)))

            elif (action_name == "ENQUEUE"):
                port = action_argu.split(':')[0]
                queue_id = action_argu.split(':')[1]
                msg.actions.append(
                    of.ofp_action_enqueue(port=int(port),
                                          queue_id=int(queue_id)))

            elif (action_name == "STRIP_VLAN"):
                msg.actions.append(of.ofp_action_strip_vlan())

            elif (action_name == "SET_VLAN_VID"):
                msg.actions.append(
                    of.ofp_action_vlan_vid(vlan_vid=int(action_argu)))

            elif (action_name == "SET_VLAN_PCP"):
                msg.actions.append(
                    of.ofp_action_vlan_pcp(vlan_pcp=int(action_argu)))

            elif (action_name == "SET_DL_SRC"):
                msg.actions.append(
                    of.ofp_action_dl_addr(type=4,
                                          dl_addr=EthAddr(action_argu)))

            elif (action_name == "SET_DL_DST"):
                msg.actions.append(
                    of.ofp_action_dl_addr(type=5,
                                          dl_addr=EthAddr(action_argu)))

            elif (action_name == "SET_NW_TOS"):
                msg.actions.append(
                    of.ofp_action_nw_tos(nw_tos=int(action_argu)))

            elif (action_name == "SET_NW_SRC"):
                msg.actions.append(
                    of.ofp_action_nw_addr(type=6, nw_addr=IPAddr(action_argu)))

            elif (action_name == "SET_NW_DST"):
                msg.actions.append(
                    of.ofp_action_nw_addr(type=7, nw_addr=IPAddr(action_argu)))

            elif (action_name == "SET_TP_SRC"):
                msg.actions.append(
                    of.ofp_action_tp_port(type=9, tp_port=int(action_argu)))

            elif (action_name == "SET_TP_DST"):
                msg.actions.append(
                    of.ofp_action_tp_port(type=10, tp_port=int(action_argu)))
Example #42
0
    def _handle_PacketIn(self, event):

        packet = event.parsed

        def getVlan(port, id_):

            res = None
            if (id_ != None):
                res = id_
            else:

                tabla = importData()

                for i in tabla:
                    for j in i.get('ports'):
                        if (j.get('port') == port):
                            res = i.get('vlan')

                return res

        def tagType(portname, vlanname):
            tabla = importData()
            for i in tabla:
                if i.get('vlan') == str(vlanname):
                    for j in i.get('ports'):
                        if (j.get('port') == str(portname)):
                            ttype = j.get('type')
                            return ttype

        def flood(message=None):

            srcPort = str(event.port)
            if (packet.find('vlan') is not None):
                vlanId = getVlan(srcPort, packet.find('vlan').id)
            else:
                vlanId = getVlan(srcPort, None)

            put = True
            for i in self.macToPort:
                if ((i.get('mac') == packet.src)
                        and (i.get('port') == int(srcPort))
                        and (i.get('vlan') == vlanId)):
                    put = False

            if (put):
                self.macToPort.append({
                    'mac': packet.src,
                    'port': int(srcPort),
                    'vlan': vlanId
                })

            taggedPorts = []
            untaggedPorts = []
            tabla = importData()

            for i in tabla:
                if i.get('vlan') == str(vlanId):
                    for j in i.get('ports'):
                        if (j.get('port') != srcPort
                                and j.get('type') == "tagged"):
                            taggedPorts.append(j.get('port'))
                        if (j.get('port') != srcPort
                                and j.get('type') == "untagged"):
                            untaggedPorts.append(j.get('port'))

            tag = tagType(srcPort, vlanId)

            msg = of.ofp_flow_mod()
            msg.match.in_port = int(srcPort)

            # Tagged
            if tag == "tagged":
                # print ("FLOOD from T-port {0}").format(srcPort)
                # T a T
                for i in taggedPorts:
                    msg.actions.append(of.ofp_action_output(port=int(i)))
        # T a U
                if untaggedPorts != []:
                    msg.actions.append(of.ofp_action_strip_vlan())
                for i in untaggedPorts:
                    msg.actions.append(of.ofp_action_output(port=int(i)))
        # Untagged
            if tag == "untagged":
                # print ("FLOOD from U-port {0}").format(srcPort)
                # U a U
                for i in untaggedPorts:
                    msg.actions.append(of.ofp_action_output(port=int(i)))

        # U a T
                if taggedPorts != []:
                    msg.actions.append(
                        of.ofp_action_vlan_vid(vlan_vid=int(vlanId)))
                for i in taggedPorts:
                    msg.actions.append(of.ofp_action_output(port=int(i)))

            self.connection.send(msg)
            return

        def drop(duration=None):
            """
      Drops this packet and optionally installs a flow to continue
      dropping similar ones for a while
      """
            if duration is not None:
                if not isinstance(duration, tuple):
                    duration = (duration, duration)
                msg = of.ofp_flow_mod()
                msg.match = of.ofp_match.from_packet(packet)
                msg.idle_timeout = duration[0]
                msg.hard_timeout = duration[1]
                msg.buffer_id = event.ofp.buffer_id
                self.connection.send(msg)
            elif event.ofp.buffer_id is not None:
                msg = of.ofp_packet_out()
                msg.buffer_id = event.ofp.buffer_id
                msg.in_port = event.port
                self.connection.send(msg)

        if not self.transparent:  # 2
            if packet.type == packet.LLDP_TYPE or packet.dst.isBridgeFiltered(
            ):
                drop()  # 2a
                return

        if packet.dst.is_multicast:
            flood()  # 3a

        else:

            vlan = None

            if (packet.find('vlan') is not None):
                vlan = packet.find('vlan').id
            else:
                vlan = None

            found = False

            if vlan != None:

                for i in self.macToPort:
                    if (i.get('mac') == packet.dst and i.get('vlan') == vlan):
                        port = int(i.get('port'))
                        found = True

            if vlan == None:
                tabla = importData()

                for j in tabla:
                    for k in j.get('ports'):
                        if (str(event.port) == str(k.get('port'))
                                and k.get('type') == "untagged"):
                            # port = k.get('port')
                            vlan = j.get('vlan')

                if (vlan != None):
                    for i in self.macToPort:
                        if (str(i.get('mac')) == str(packet.dst)
                                and str(i.get('vlan')) == str(vlan)):
                            port = i.get('port')
                            found = True

            if not found:  # 4
                flood("Port for %s unknown -- flooding" % (packet.dst, ))  # 4a

            else:

                vlanId = vlan

                put = True
                for i in self.macToPort:
                    if ((i.get('mac') == packet.src)
                            and (i.get('port') == int(event.port))
                            and (i.get('vlan') == vlanId)):
                        put = False

                if (put):
                    self.macToPort.append({
                        'mac': packet.src,
                        'port': int(event.port),
                        'vlan': vlanId
                    })

                if port == event.port:  # 5
                    log.warning(
                        "Same port for packet from %s -> %s on %s.%s.  Drop." %
                        (packet.src, packet.dst, dpid_to_str(
                            event.dpid), port))
                    drop(10)
                    return

                tag1 = tagType(str(event.port), str(vlanId))
                tag2 = tagType(str(port), str(vlanId))

                msg = of.ofp_flow_mod()
                msg.match = of.ofp_match.from_packet(packet, event.port)
                msg.idle_timeout = 10
                msg.hard_timeout = 30
                msg.data = event.ofp  # 6a

                # Tagged
                if tag1 == "tagged":
                    if tag2 == "tagged":
                        msg.actions.append(
                            of.ofp_action_output(port=int(port)))
                    if tag2 == "untagged":
                        msg.actions.append(of.ofp_action_strip_vlan())
                        msg.actions.append(
                            of.ofp_action_output(port=int(port)))

                # Untagged
                if tag1 == "untagged":
                    if tag2 == "untagged":
                        msg.actions.append(
                            of.ofp_action_output(port=int(port)))
                    if tag2 == "tagged":
                        msg.actions.append(
                            of.ofp_action_vlan_vid(vlan_vid=int(vlanId)))
                        msg.actions.append(
                            of.ofp_action_output(port=int(port)))

                self.connection.send(msg)
                return
Example #43
0
  def _modify_flow(self,command_type):
    
    msg = of.ofp_flow_mod()
    print self.payload
    if command_type == "MOD_ST":
      msg.command = of.OFPFC_MODIFY_STRICT
    elif command_type == "MOD":
      msg.command = of.OFPFC_MODIFY

    if self.payload.has_key("wildcards"):
      msg.match.wildcards = int(self.payload['wildcards'])
    
    if self.payload.has_key("dstIP"):
      msg.match.nw_dst = IPAddr(self.payload['dstIP'])
    
    if self.payload.has_key("srcMac"):
      msg.match.dl_src = EthAddr(self.payload['srcMac'])
    
    if self.payload.has_key("srcIP"):
      msg.match.nw_src = IPAddr(self.payload['srcIP'])
    
    if self.payload.has_key("dstMac"):
      msg.match.dl_dst = EthAddr(self.payload['dstMac'])
    
    if self.payload.has_key("hardTimeout"):
      msg.hard_timeout = int(self.payload['hardTimeout'])
    
    if self.payload.has_key("srcPort"):
      msg.match.tp_src = int(self.payload['srcPort'])
    
    if self.payload.has_key("priority"):
      msg.priority = int(self.payload['priority'])
    
    if self.payload.has_key("ingressPort"):
      msg.match.in_port = int(self.payload['ingressPort'])
    
    if self.payload.has_key("vlan"):
      msg.match.dl_vlan = int(self.payload['vlan'])
    
    if self.payload.has_key("ether-type"):
      msg.match.dl_type = int(self.payload['ether-type'])
    
    if self.payload.has_key("duration"):
      msg.duration_sec = int(self.payload['duration'])
    
    if self.payload.has_key("idleTimeout"):
      msg.idle_timeout = int(self.payload['idleTimeout'])
    
    if self.payload.has_key("netProtocol"):
      msg.match.nw_proto = int(self.payload['netProtocol'])


    self.dpid = self.payload['switch'].replace(':','-')[6:]
    self._parse_actions(self.payload['actions'])

    for connection in core.openflow._connections.values() :

      # print dpidToStr(connection.dpid)
      conn_dpid = str(dpidToStr(connection.dpid))
      print conn_dpid
      if conn_dpid == self.dpid:
        """match actions"""
        if(self.actions == "OUTPUT"):
          msg.actions.append(of.ofp_action_output(port = int(self.actions_argu)))
        
        elif(self.actions == "enqueue"):
          port = self.actions_argu.split(':')[0]
          queue_id = self.actions_argu.split(':')[1]
          msg.actions.append(of.ofp_action_enqueue(port = int(port) , queue_id = int(queue_id)))
        
        elif(self.actions == "strip-vlan"):
          msg.actions.append(of.ofp_action_strip_vlan())
        
        elif(self.actions == "set-vlan-id"):
          msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = int(self.actions_argu)))
        
        elif(self.actions == "set-vlan-priority"):
          msg.actions.append(of.ofp_action_vlan_pcp(vlan_pcp = int(self.actions_argu)))
        
        elif(self.actions == "SET_DL_SRC"):
          msg.actions.append(of.ofp_action_dl_addr(type = 4 , dl_addr = EthAddr(self.actions_argu)))
        
        elif(self.actions == "SET_DL_DST"):
          msg.actions.append(of.ofp_action_dl_addr(type = 5 , dl_addr = EthAddr(self.actions_argu)))
        
        elif(self.actions == "SET_NW_TOS"):
          msg.actions.append(of.ofp_action_nw_tos(nw_tos = int(self.actions_argu)))

        elif(self.actions == "SET_NW_SRC"):
          msg.actions.append(of.ofp_action_nw_addr(type = 6 , nw_addr = IPAddr(self.actions_argu)))

        elif(self.actions == "SET_NW_DST"):
          msg.actions.append(of.ofp_action_nw_addr(type = 7 , nw_addr = IPAddr(self.actions_argu)))

        elif(self.actions == "SET_TP_SRC"):
          msg.actions.append(of.ofp_action_tp_port(type = 9 , tp_port = int(self.actions_argu)))
        
        elif(self.actions == "SET_TP_DST"):
          msg.actions.append(of.ofp_action_tp_port(type = 10 , tp_port = int(self.actions_argu)))

        connection.send(msg)
Example #44
0
    def _modify_flow(self, command_type):

        msg = of.ofp_flow_mod()
        print self.payload
        if command_type == "MOD_ST":
            msg.command = of.OFPFC_MODIFY_STRICT
        elif command_type == "MOD":
            msg.command = of.OFPFC_MODIFY

        if self.payload.has_key("wildcards"):
            msg.match.wildcards = int(self.payload['wildcards'])

        if self.payload.has_key("dstIP"):
            msg.match.nw_dst = IPAddr(self.payload['dstIP'])

        if self.payload.has_key("srcMac"):
            msg.match.dl_src = EthAddr(self.payload['srcMac'])

        if self.payload.has_key("srcIP"):
            msg.match.nw_src = IPAddr(self.payload['srcIP'])

        if self.payload.has_key("dstMac"):
            msg.match.dl_dst = EthAddr(self.payload['dstMac'])

        if self.payload.has_key("hardTimeout"):
            msg.hard_timeout = int(self.payload['hardTimeout'])

        if self.payload.has_key("srcPort"):
            msg.match.tp_src = int(self.payload['srcPort'])

        if self.payload.has_key("priority"):
            msg.priority = int(self.payload['priority'])

        if self.payload.has_key("ingressPort"):
            msg.match.in_port = int(self.payload['ingressPort'])

        if self.payload.has_key("vlan"):
            msg.match.dl_vlan = int(self.payload['vlan'])

        if self.payload.has_key("ether-type"):
            msg.match.dl_type = int(self.payload['ether-type'])

        if self.payload.has_key("duration"):
            msg.duration_sec = int(self.payload['duration'])

        if self.payload.has_key("idleTimeout"):
            msg.idle_timeout = int(self.payload['idleTimeout'])

        if self.payload.has_key("netProtocol"):
            msg.match.nw_proto = int(self.payload['netProtocol'])

        self.dpid = self.payload['switch'].replace(':', '-')[6:]
        self._parse_actions(self.payload['actions'])

        for connection in core.openflow._connections.values():

            # print dpidToStr(connection.dpid)
            conn_dpid = str(dpidToStr(connection.dpid))
            print conn_dpid
            if conn_dpid == self.dpid:
                """match actions"""
                if (self.actions == "OUTPUT"):
                    msg.actions.append(
                        of.ofp_action_output(port=int(self.actions_argu)))

                elif (self.actions == "enqueue"):
                    port = self.actions_argu.split(':')[0]
                    queue_id = self.actions_argu.split(':')[1]
                    msg.actions.append(
                        of.ofp_action_enqueue(port=int(port),
                                              queue_id=int(queue_id)))

                elif (self.actions == "strip-vlan"):
                    msg.actions.append(of.ofp_action_strip_vlan())

                elif (self.actions == "set-vlan-id"):
                    msg.actions.append(
                        of.ofp_action_vlan_vid(
                            vlan_vid=int(self.actions_argu)))

                elif (self.actions == "set-vlan-priority"):
                    msg.actions.append(
                        of.ofp_action_vlan_pcp(
                            vlan_pcp=int(self.actions_argu)))

                elif (self.actions == "SET_DL_SRC"):
                    msg.actions.append(
                        of.ofp_action_dl_addr(type=4,
                                              dl_addr=EthAddr(
                                                  self.actions_argu)))

                elif (self.actions == "SET_DL_DST"):
                    msg.actions.append(
                        of.ofp_action_dl_addr(type=5,
                                              dl_addr=EthAddr(
                                                  self.actions_argu)))

                elif (self.actions == "SET_NW_TOS"):
                    msg.actions.append(
                        of.ofp_action_nw_tos(nw_tos=int(self.actions_argu)))

                elif (self.actions == "SET_NW_SRC"):
                    msg.actions.append(
                        of.ofp_action_nw_addr(type=6,
                                              nw_addr=IPAddr(
                                                  self.actions_argu)))

                elif (self.actions == "SET_NW_DST"):
                    msg.actions.append(
                        of.ofp_action_nw_addr(type=7,
                                              nw_addr=IPAddr(
                                                  self.actions_argu)))

                elif (self.actions == "SET_TP_SRC"):
                    msg.actions.append(
                        of.ofp_action_tp_port(type=9,
                                              tp_port=int(self.actions_argu)))

                elif (self.actions == "SET_TP_DST"):
                    msg.actions.append(
                        of.ofp_action_tp_port(type=10,
                                              tp_port=int(self.actions_argu)))

                connection.send(msg)
Example #45
0
def _handle_PacketIn(event):
	global s1_dpid, s2_dpid
	# print "PacketIn: ", dpidToStr(event.connection.dpid)
	
	# switch s1
	if event.connection.dpid==s1_dpid:

	   # Flujos para la tabla de flujos del switch
		flow_s1_0 = of.ofp_flow_mod()
		flow_s1_0.priority = 32768 # A mayor valor mas prioridad
		flow_s1_0.match.in_port = 1
		flow_s1_0vlan_id = of.ofp_action_vlan_vid(vlan_vid = 10)
		flow_s1_queue1 = of.ofp_action_enqueue(port = 3, queue_id = 1)
		flow_s1_0.actions = [flow_s1_0vlan_id,flow_s1_queue1]
		
		flow_s1_1 = of.ofp_flow_mod()
		flow_s1_1.priority = 32768 # A mayor valor mas prioridad
		flow_s1_1.match.in_port = 2
		flow_s1_1vlan_id = of.ofp_action_vlan_vid(vlan_vid = 20)
		flow_s1_queue2 = of.ofp_action_enqueue(port = 3, queue_id = 2)
		flow_s1_1.actions = [flow_s1_1vlan_id,flow_s1_queue2]


	   	flow_s1_2 = of.ofp_flow_mod()
		flow_s1_2.priority = 32768 # A mayor valor mas prioridad
		flow_s1_2.match.dl_vlan = 10
		flow_s1_2stripvlan = of.ofp_action_strip_vlan()
		flow_s1_2out = of.ofp_action_output(port = 1)
		flow_s1_2.actions = [flow_s1_2stripvlan,flow_s1_2out]
			   
	   	flow_s1_3 = of.ofp_flow_mod()
		flow_s1_3.priority = 32768 # A mayor valor mas prioridad
		flow_s1_3.match.dl_vlan = 20
		flow_s1_3stripvlan = of.ofp_action_strip_vlan()
		flow_s1_3out = of.ofp_action_output(port = 2)
		flow_s1_3.actions = [flow_s1_3stripvlan,flow_s1_3out]
		
		# Instalacion de los flujos previamente definidos
		core.openflow.sendToDPID(s1_dpid,flow_s1_0)
		core.openflow.sendToDPID(s1_dpid,flow_s1_1)
		core.openflow.sendToDPID(s1_dpid,flow_s1_2)
		core.openflow.sendToDPID(s1_dpid,flow_s1_3)
	
	# switch s2
	if event.connection.dpid==s2_dpid:			
		
		# Flujos para la tabla de flujos del switch
		flow_s2_0 = of.ofp_flow_mod()
		flow_s2_0.priority = 32768 # A mayor valor mas prioridad
		flow_s2_0.match.in_port = 2
		flow_s2_0vlan_id = of.ofp_action_vlan_vid(vlan_vid = 20)
		flow_s2_queue2 = of.ofp_action_enqueue(port = 1, queue_id = 2)
		flow_s2_0.actions = [flow_s2_0vlan_id,flow_s2_queue2]
		
		flow_s2_1 = of.ofp_flow_mod()
		flow_s2_1.priority = 32768 # A mayor valor mas prioridad
		flow_s2_1.match.in_port = 3
		flow_s2_1vlan_id = of.ofp_action_vlan_vid(vlan_vid = 10)
		flow_s2_queue1 = of.ofp_action_enqueue(port = 1, queue_id = 1)
		flow_s2_1.actions = [flow_s2_1vlan_id,flow_s2_queue1]

	   	flow_s2_2 = of.ofp_flow_mod()
		flow_s2_2.priority = 32768 # A mayor valor mas prioridad
		flow_s2_2.match.dl_vlan = 10
		flow_s2_2stripvlan = of.ofp_action_strip_vlan()
		flow_s2_2out = of.ofp_action_output(port = 3)
		flow_s2_2.actions = [flow_s2_2stripvlan,flow_s2_2out]
			   
	   	flow_s2_3 = of.ofp_flow_mod()
		flow_s2_3.priority = 32768 # A mayor valor mas prioridad
		flow_s2_3.match.dl_vlan = 20
		flow_s2_3stripvlan = of.ofp_action_strip_vlan()
		flow_s2_3out = of.ofp_action_output(port = 2)
		flow_s2_3.actions = [flow_s2_3stripvlan,flow_s2_3out]	
		
		# Instalacion de los flujos previamente definidos
		core.openflow.sendToDPID(s2_dpid,flow_s2_0)
		core.openflow.sendToDPID(s2_dpid,flow_s2_1)
		core.openflow.sendToDPID(s2_dpid,flow_s2_2)
		core.openflow.sendToDPID(s2_dpid,flow_s2_3)
Example #46
0
def sPortal(connection):
    for network,vlan in networks.iteritems():

        # permit DNS to flow from clients to router
        msg = of.ofp_flow_mod()
        msg.priority = 20
        msg.match.in_port = client_port_match
        msg.match.dl_vlan = vlan['untrusted']
        msg.match.dl_type = 0x0800
        msg.match.nw_proto = 17
        msg.match.tp_dst = 53
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted']))
        msg.actions.append(of.ofp_action_output(port = router_port_action))
        connection.send(msg)

        # permit DHCP to flow from clients to router
        msg = of.ofp_flow_mod()
        msg.priority = 20
        msg.match.in_port = client_port_match
        msg.match.dl_vlan = vlan['untrusted']
        msg.match.dl_type = 0x0800
        msg.match.nw_proto = 17
        msg.match.tp_src = 68
        msg.match.tp_dst = 67
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted']))
        msg.actions.append(of.ofp_action_output(port = router_port_action))
        connection.send(msg)

        # permit ARP to flow from clients to router (if supported)
        # otherwise, pre-authenticated clients will ARP to captive portal
        # which should be running proxy-arp so there should still be no problem
        if dp_supports_arp_match:
            msg = of.ofp_flow_mod()
            msg.priority = 20
            msg.match.in_port = client_port_match
            msg.match.dl_vlan = vlan['untrusted']
            msg.match.dl_type = pkt.ethernet.ARP_TYPE
            msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['trusted']))
            msg.actions.append(of.ofp_action_output(port = router_port_action))
            connection.send(msg)        

        # send traffic from the client to the portal
        msg = of.ofp_flow_mod()
        msg.priority = 10
        msg.match.in_port = client_port_match
        msg.match.dl_vlan = vlan['untrusted']
        msg.actions.append(of.ofp_action_dl_addr.set_dst(portal))
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['portal']))
        msg.actions.append(of.ofp_action_output(port = portal_port_action))
        connection.send(msg)


        # send IP traffic from the portal back to the client
        msg = of.ofp_flow_mod()
        msg.priority = 10
        msg.match.in_port = portal_port_match
        msg.match.dl_vlan = vlan['portal']
        msg.match.dl_src = portal
        # note - commented out because the switch under test can't match IP networks yet
        # note - this means for now that the "networks" array can only contain one network
        # note - we would have to also match ARP which is also not supported via the device under test
        #msg.match.dl_type = pkt.ethernet.IP_TYPE
        #msg.match.nw_dst = network
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['untrusted']))
        msg.actions.append(of.ofp_action_output(port = client_port_action))
        connection.send(msg)

        # send IP traffic from the router back to the client
        msg = of.ofp_flow_mod()
        msg.priority = 10
        msg.match.in_port = router_port_match
        msg.match.dl_vlan = vlan['trusted']
        msg.match.dl_src = router
        # note - commented out because the switch under test can't match IP networks yet
        # note - this means for now that teh "networks" array can only contain one network
        # note - we would have to also match ARP which is also not supported via the device under test
        #msg.match.dl_type = pkt.ethernet.IP_TYPE
        #msg.match.nw_dst = network
        msg.actions.append(of.ofp_action_vlan_vid(vlan_vid = vlan['untrusted']))
        msg.actions.append(of.ofp_action_output(port = client_port_action))
        connection.send(msg)
    def installNFToRRules(switch):
        """
        Installs rules to ToR switches that have one or more NF
        connected to them
        """

        for pol in policies:
            mList = pol.match
            cList = pol.chain

            lastNFSwitch = services[cList[(len(cList) - 1)]][NF_DPID]
            if lastNFSwitch == switch:
                fm = Tutorial.matchBuilder(mList)
                fm.match.in_port = int(services[cList[(len(cList) -
                                                       1)]][NF_PORT])
                action = of.ofp_action_output(port=of.OFPP_CONTROLLER)
                fm.actions.append(action)
                RulesTable.addRule(switch, mList, "null", "controller port",
                                   services[cList[(len(cList) - 1)]][NF_PORT])
                switchesConn[switch].send(fm)

            if len(cList) >= 2:
                for i in range(len(cList) - 1):
                    nfSwitch = services[cList[i]][NF_DPID]
                    if nfSwitch == switch:
                        nf2Switch = services[cList[(i + 1)]][NF_DPID]
                        if nf2Switch == switch:
                            fm = Tutorial.matchBuilder(mList)
                            nfPort = services[cList[i]][NF_PORT]
                            nfTag = services[cList[i]][NF_VLAN]
                            nf2Port = services[cList[(i + 1)]][NF_PORT]
                            fm.match.in_port = int(nfPort)
                            action = of.ofp_action_output(port=int(nf2Port))
                            fm.actions.append(action)
                            RulesTable.addRule(switch, mList, "null", nf2Port,
                                               nfPort)
                            switchesConn[switch].send(fm)
                        else:
                            fm = Tutorial.matchBuilder(mList)
                            nfPort = services[cList[i]][NF_PORT]

                            # corePort = str(coreSwitches[randint(0, (len(coreSwitches) - 1))])

                            coreSwitch = coreSwitches[0]
                            corePort = Discovery.getPort(
                                int(switch), int(coreSwitch))
                            if corePort is None:
                                configHelper[2] = False
                                return

                            nfTag = services[cList[i]][NF_VLAN]
                            fm.match.in_port = int(nfPort)
                            action1 = of.ofp_action_vlan_vid(
                                vlan_vid=int(nfTag))
                            action2 = of.ofp_action_output(port=int(corePort))
                            fm.actions.append(action1)
                            fm.actions.append(action2)
                            RulesTable.addRule(switch, mList, "null", corePort,
                                               nfPort, nfTag)
                            switchesConn[switch].send(fm)

        for pol2 in policies:
            mList = pol2.match
            cList = pol2.chain

            fm = Tutorial.matchBuilder(mList)

            # corePort = str(coreSwitches[randint(0, (len(coreSwitches) - 1))])

            if services[cList[0]][NF_DPID] != switch:
                coreSwitch = coreSwitches[0]
                corePort = Discovery.getPort(int(switch), int(coreSwitch))
                if corePort is None:
                    configHelper[2] = False
                    return

                fm.match.dl_vlan = of.OFP_VLAN_NONE
                action = of.ofp_action_output(port=int(corePort))
                fm.actions.append(action)
                RulesTable.addRule(switch, mList, None, corePort)
                switchesConn[switch].send(fm)

            for c in cList:
                nfSwitch = services[c][NF_DPID]
                cIndx = cList.index(c)
                if nfSwitch == switch:
                    if cIndx == 0 or (cIndx > 0 and services[cList[
                        (cIndx - 1)]][NF_DPID] != switch):
                        if cIndx == 0:
                            allPorts = [
                                int(p) for p in Discovery.graph.nodes[int(
                                    switch)].connection.ports
                            ]
                        else:
                            allPorts = Discovery.getPorts(int(switch))
                        for p in allPorts:
                            if p < of.OFPP_MAX and p != int(
                                    services[c][NF_PORT]):
                                fm = Tutorial.matchBuilder(mList)
                                fm.match.in_port = int(p)
                                nfPort = services[c][NF_PORT]
                                if cIndx == 0:
                                    fm.match.dl_vlan = of.OFP_VLAN_NONE
                                    RulesTable.addRule(switch, mList, None,
                                                       nfPort, p)
                                else:
                                    fm.match.dl_vlan = services[cList[(
                                        cIndx - 1)]][NF_VLAN]
                                    RulesTable.addRule(
                                        switch, mList,
                                        services[cList[(cIndx - 1)]][NF_VLAN],
                                        nfPort, p)
                                action1 = of.ofp_action_vlan_vid()
                                action2 = of.ofp_action_output(
                                    port=int(nfPort))
                                fm.actions.append(action1)
                                fm.actions.append(action2)
                                switchesConn[switch].send(fm)
Example #48
0
  def __handle_PacketIn(self, event):
    packet = event.parsed
    src = packet.src.toStr()
    dst = packet.dst.toStr()

    # Extract IP information
    ip   = packet.find('ipv4')
    udpp = packet.find('udp')
    if ip:
      # it is not a good way to define a variable, anyway
      srcip = ip.srcip
      dstip = ip.dstip
      self.srcip_table[src] = srcip
      self.dstip_table[dst] = dstip
      if udpp:
        srcport = udpp.srcport
        # Each src-dst pair has several ports
        if srcport not in self.sd_srcport_table[src][dst]:
          # New port discovered
          self.sd_srcport_table[src][dst].append(srcport)

    # Latency test packets handling
    if self.lat_test:
      if packet.type != 0x5566:
        # not test packet, drop it
        return

      src = self._MAC_to_int(src)
      dst = self._MAC_to_int(dst)

      timeinit, = struct.unpack('!I', packet.find('ethernet').payload)
      timediff = time.time()*1000 - self.system_time - timeinit

      if src in self.adj_test:
        if dst in self.adj_test[src]:
          self.adj[src][dst] = timediff
          del self.adj_test[src][dst]

      if dst in self.sw_test:
        self.sw_lat[dst] = timediff
        self.sw_test.remove(dst)

      return

    # assign path id
    pid = 0

    if src in self.hosts:
      for d in self.sd_path_table[src]:
        # FIXME: Pick one as default
        # Maybe we should apply flood function to broadcasting
        for sd_path_id in self.sd_path_table[src][d]:
          pid = sd_path_id
          # log.warning("Packet Vid = %i", pid)

      if dst in self.hosts:
        if self.config.config_set:
          if ip and udpp:
            # If the packet is an IP/UDP packet
            id_list = self.sd_path_table[src][dst]
            # last one, in case not found
            pid = self.get_pid_by_srcport(id_list, srcport)
            if pid is None:
              # Not existed port, choose the last one as default
              pid = id_list[len(id_list) - 1]
              for k in id_list:
                now_split = self.config.now_config
                real_split = self.config.real_config
                # log.warning("now %s real %s", now_split, real_split )
                if now_split[k-1] > real_split[k-1] or now_split[k-1] == 1:
                  pid = k
                  break
              # update flow_dist_table and real_config_table
              self.flow_dist_table[pid-1].append(srcport)
              self.config.compute_real_config(id_list, self.flow_dist_table)
          else:
            id_list = self.sd_path_table[src][dst]
            # last one, in case not found
            pid = id_list[len(id_list) - 1]
          
            sum_of_all = 0
            for x in id_list:
              sum_of_all += self.config.now_config[x-1]
            
            rand_num = sum_of_all * random.random()
            for x in id_list:
              rand_num -= self.config.now_config[x-1]  # Since the path ID starts from 1, which is different from the index
              if rand_num < 0:
                # path_id should start from 1
                pid = x
                break
          # log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid) 
        else:
          # FIXME: path selection
          for sd_path_id in self.sd_path_table[src][dst]:
            # There exists a path
            pid = sd_path_id
            # log.warning("Packet Vid = %i", pid)        

      if ip and udpp:
        # FIXME: Do we need to modify the flow whenever the packet in?
        msg = of.ofp_flow_mod()
        msg.match.dl_type = 0x800
        msg.match.nw_src = IPAddr(srcip)
        msg.match.nw_dst = IPAddr(dstip)
        msg.match.nw_proto = 17
        msg.match.tp_src = srcport
        # slog.warning("Add rule for port %s", srcport)
      else:
        msg = of.ofp_packet_out(data = event.ofp)

      if pid != 0:
        # There exists a path
        path = self.path_id_table[pid]
        if len(path) > 3:
        # It is not the last sw, tag it and send into the network
          if USE_VLAN_TAG:
            msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) )
          if USE_ETHERNET_SRC_TAG:
            msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) )
          msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) )
        elif len(path) == 3:
          # last sw, forward to the host
          #msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) )
          msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) )

      event.connection.send(msg)

    """
Example #49
0
  def _update_step(self):
    if self.update_step > len(self.config.config) - 1:
      self.update_timer.cancel()
      log.warning("Updating Ends.")
      return
    self.update_timer._interval = 10
    self.config.change_step(self.update_step)

    #redistribute flows based on new configuration
    for i in self.config.real_config:
      for j in self.config.real_config[i]:
        self.config.real_config[i][j] = 0.0
    for sd_id in self.flow_dist_table:
      for path in self.flow_dist_table[sd_id]:
        self.flow_dist_table[sd_id][path] = []

    for src in self.sd_srcport_table:
      for dst in self.sd_srcport_table[src]:
        sd_id = self.sd_pair[src][dst]
        id_list = self.config.now_config[sd_id]
        real_split = self.config.real_config[sd_id]
        cur_dist = self.flow_dist_table[sd_id]
        for srcport in self.sd_srcport_table[src][dst]:
          # last one, in case not found
          pid = len(id_list) - 1
          for k,x in enumerate(id_list):
            if x > real_split[k] or x == 1:
              pid = k + 1
              # update flow_dist_table and real_config_table
              cur_dist[k].append(srcport)
              num_flow = len(self.sd_srcport_table[src][dst])
              self.config.compute_real_config(sd_id, num_flow, cur_dist)
              #print 'compute_real_config', self.config.real_config[sd_id][k]
              break

          srcip = self.srcip_table[src]
          dstip = self.dstip_table[dst]
          msg = of.ofp_flow_mod(command = of.OFPFC_MODIFY_STRICT)
          msg.match.dl_type = 0x800
          msg.match.nw_src = IPAddr(srcip)
          msg.match.nw_dst = IPAddr(dstip)
          msg.match.nw_proto = 17
          msg.match.tp_src = srcport
          path = self.path_id_table[pid]
          if len(path) > 3:
            # It is not the last sw, tag it and send into the network
            if USE_VLAN_TAG:
              msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) )
            if USE_ETHERNET_SRC_TAG:
              msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) )
            msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) )
          elif len(path) == 3:
            # last sw, forward to the host
            # msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) )
            msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) )
          sw = path[1]
          core.openflow.sendToDPID(sw, msg)
          #print msg
          log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid)

    log.warning("Update Step %i ...", self.update_step)
    self.update_step += 1
Example #50
0
        def flood(message=None):

            srcPort = str(event.port)
            if (packet.find('vlan') is not None):
                vlanId = getVlan(srcPort, packet.find('vlan').id)
            else:
                vlanId = getVlan(srcPort, None)

            put = True
            for i in self.macToPort:
                if ((i.get('mac') == packet.src)
                        and (i.get('port') == int(srcPort))
                        and (i.get('vlan') == vlanId)):
                    put = False

            if (put):
                self.macToPort.append({
                    'mac': packet.src,
                    'port': int(srcPort),
                    'vlan': vlanId
                })

            taggedPorts = []
            untaggedPorts = []
            tabla = importData()

            for i in tabla:
                if i.get('vlan') == str(vlanId):
                    for j in i.get('ports'):
                        if (j.get('port') != srcPort
                                and j.get('type') == "tagged"):
                            taggedPorts.append(j.get('port'))
                        if (j.get('port') != srcPort
                                and j.get('type') == "untagged"):
                            untaggedPorts.append(j.get('port'))

            tag = tagType(srcPort, vlanId)

            msg = of.ofp_flow_mod()
            msg.match.in_port = int(srcPort)

            # Tagged
            if tag == "tagged":
                # print ("FLOOD from T-port {0}").format(srcPort)
                # T a T
                for i in taggedPorts:
                    msg.actions.append(of.ofp_action_output(port=int(i)))
        # T a U
                if untaggedPorts != []:
                    msg.actions.append(of.ofp_action_strip_vlan())
                for i in untaggedPorts:
                    msg.actions.append(of.ofp_action_output(port=int(i)))
        # Untagged
            if tag == "untagged":
                # print ("FLOOD from U-port {0}").format(srcPort)
                # U a U
                for i in untaggedPorts:
                    msg.actions.append(of.ofp_action_output(port=int(i)))

        # U a T
                if taggedPorts != []:
                    msg.actions.append(
                        of.ofp_action_vlan_vid(vlan_vid=int(vlanId)))
                for i in taggedPorts:
                    msg.actions.append(of.ofp_action_output(port=int(i)))

            self.connection.send(msg)
            return
Example #51
0
    def build_nx_actions(self,inport,action_list,table_id,pipeline):
        ### BUILD NX ACTIONS
        of_actions = []
        ctlr_outport = False # there is a controller outport action
        phys_outports = list() # list of physical outports to forward out of
        possibly_resubmit_next_table = False # should packet be passed on to next table?
        atleast_one_action = False

        for actions in action_list:
            atleast_one_action = True
            if 'srcmac' in actions:
                of_actions.append(of.ofp_action_dl_addr.set_src(actions['srcmac']))
            if 'dstmac' in actions:
                of_actions.append(of.ofp_action_dl_addr.set_dst(actions['dstmac']))
            if 'srcip' in actions:
                of_actions.append(of.ofp_action_nw_addr.set_src(actions['srcip']))
            if 'dstip' in actions:
                of_actions.append(of.ofp_action_nw_addr.set_dst(actions['dstip']))
            if 'srcport' in actions:
                of_actions.append(of.ofp_action_tp_port.set_src(actions['srcport']))
            if 'dstport' in actions:
                of_actions.append(of.ofp_action_tp_port.set_dst(actions['dstport']))
            if 'vlan_id' in actions:
                if actions['vlan_id'] is None:
                    of_actions.append(of.ofp_action_strip_vlan())
                else:
                    of_actions.append(of.ofp_action_vlan_vid(vlan_vid=actions['vlan_id']))
            if 'vlan_pcp' in actions:
                if actions['vlan_pcp'] is None:
                    if not actions['vlan_id'] is None:
                        raise RuntimeError("vlan_id and vlan_pcp must be set together!")
                    pass
                else:
                    of_actions.append(of.ofp_action_vlan_pcp(vlan_pcp=actions['vlan_pcp']))

            assert 'port' in actions
            outport = actions['port']

            if outport == of.OFPP_CONTROLLER:
                ctlr_outport = True
            else:
                """ There is either a physical output action (i.e., on a
                non-controller port), or a "send to next table" action."""
                possibly_resubmit_next_table = True
                if outport != CUSTOM_NEXT_TABLE_PORT:
                    phys_outports.append(outport)
                """ Otherwise there are no physical outports; just a possibility
                of resubmitting to the next table. Pass. """

        """In general, actual packet forwarding may have to wait until the final table
        in the pipeline. This means we must determine if there is a "next" table
        that processes the packet from here, or if this is the last one.

        But first, the easy part. There are exactly three cases where a
        forwarding table *will* in fact "immediately forward" a packet according
        to the current rule (and all previous table stages that processed the
        packet), without waiting for any other further processing:

        (1) if the packet is dropped by the current rule,
        (2) if the packet is forwarded to the controller port, or
        (3) if this is the last stage of the pipeline.

        In the case of (1) and (2), packet forwarding may happen immediately and
        only depend on the current rule. But in (3), the forwarding decision
        must take the current rule as well as previous port changes into
        account, as follows:

        (a) if the current rule specifies an output port, forward the packet out
        of that port.

        (b) if the current rule does not specify an outport, then forward the
        packet out of the port using the value stored in the dedicated
        per-packet port register.

        If neither of (1)-(3) above is true, then we take the following
        approach:

        (a) if there is an outport set by this rule, write that value into the
        dedicated per-packet register that contains the current port the
        packet is in.

        (b) if there is no outport set by this rule, and if this is table id 0,
        move the value of the inport into the dedicated per-packet port
        register. This denotes that the packet is currently still on its inport.

        (c) resubmit the packet to the "next" table (according to the pipeline).
        """
        exists_next_table = table_id in pipeline.edges

        # Decide first on "immediate forwarding" conditions:
        immediately_fwd = True
        if not atleast_one_action: # (1) drop
            of_actions = []
        elif ctlr_outport: # (2) controller
            of_actions = []
            of_actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
        elif possibly_resubmit_next_table and (not exists_next_table):
            # (3) last stage of pipeline
            if len(phys_outports) > 0: # fwd out of latest assigned ports
                for p in phys_outports:
                    of_actions.append(of.ofp_action_output(port=p))
            else:
                # fwd out of stored port value
                of_actions.append(nx.nx_output_reg(reg=nx.NXM_NX_REG2,
                                                   nbits=16))
        elif (not exists_next_table) and (not possibly_resubmit_next_table):
            raise RuntimeError("Unexpected condition in multi-stage processing")
        else: # must resubmit packet to subsequent tables for processing
            immediately_fwd = False

        if immediately_fwd:
            return of_actions

        # Act on packet with knowledge that subsequent tables must process it
        assert (possibly_resubmit_next_table and exists_next_table and
                (not immediately_fwd))
        next_table = pipeline.edges[table_id]
        if len(phys_outports) > 0:
            # move port register to latest assigned port values
            for p in phys_outports:
                of_actions.append(nx.nx_reg_load(dst=nx.NXM_NX_REG2,
                                                 value=p, nbits=16))
                of_actions.append(nx.nx_action_resubmit.resubmit_table(
                    table=next_table))
        elif table_id == 0:
            # move the inport value to reg2.
            of_actions.append(nx.nx_reg_move(src=nx.NXM_OF_IN_PORT,
                                             dst=nx.NXM_NX_REG2,
                                             nbits=16))
            of_actions.append(nx.nx_action_resubmit.resubmit_table(
                table=next_table))
        else:
            of_actions.append(nx.nx_action_resubmit.resubmit_table(
                table=next_table))
        return of_actions
Example #52
0
  def __handle_PacketIn(self, event):
    packet = event.parsed
    src = packet.src.toStr()
    dst = packet.dst.toStr()
    ip = packet.find('ipv4')
    udpp = packet.find('udp')
    if ip:
      srcip = ip.srcip
      dstip = ip.dstip
      self.srcip_table[src] = srcip
      self.dstip_table[dst] = dstip
      if udpp:
        srcport = udpp.srcport
        if srcport not in self.sd_srcport_table[src][dst]:
          self.sd_srcport_table[src][dst].append(srcport)
          #print(self.sd_srcport_table[src][dst])

    if self.lat_test:
      if packet.type != 0x5566:
        # not test packet, drop it
        return

      src = self._MAC_to_int(src)
      dst = self._MAC_to_int(dst)

      timeinit, = struct.unpack('!I', packet.find('ethernet').payload)
      timediff = time.time()*1000 - self.system_time - timeinit

      if src in self.adj_test:
        if dst in self.adj_test[src]:
          self.adj[src][dst] = timediff
          del self.adj_test[src][dst]

      if dst in self.sw_test:
        self.sw_lat[dst] = timediff
        self.sw_test.remove(dst)

      return

    pid = 0

    if src in self.hosts:
      for d in self.sd_path_table[src]:
        # FIXME: Pick one as default
        # Maybe we should apply flood function to broadcasting
        for sd_path_id in self.sd_path_table[src][d]:
          pid = sd_path_id
          # log.warning("Packet Vid = %i", pid)

      if dst in self.hosts:
        if ip and udpp and self.config.config_set:
          sd_id = self.sd_pair[src][dst]
          id_list = self.config.now_config[sd_id]
          real_split = self.config.real_config[sd_id]
          cur_dist = self.flow_dist_table[sd_id]
          # last one, in case not found
          pid = len(id_list) - 1
          if scrport in cur_dist.values:
            pid = self.get_pid_by_scrport(sd_id, scrport)
          else:
            for k,x in enumerate(id_list):
              if x > real_split[k] or x == 1:
                pid = k + 1
                # update flow_dist_table and real_config_table
                self.flow_dist_table[sd_id][k].append(srcport)
                num_flow = len(self.sd_srcport_table[src][dst])
                self.config.compute_real_config(sd_id, num_flow, cur_dist)
                break
          log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid)

        elif self.config.config_set:
          id_list = self.config.now_config[self.sd_pair[src][dst]]
          # last one, in case not found
          pid = len(id_list) - 1
          rand_num = random.random()
          for k,x in enumerate(id_list):
            rand_num -= x
            if rand_num < 0:
              # path_id should start from 1
              pid = k + 1
              break
          log.warning("SD pair %i, pid %i", self.sd_pair[src][dst], pid)
        else:
          # FIXME: path selection
          for sd_path_id in self.sd_path_table[src][dst]:
            # There exists a path
            pid = sd_path_id
            # log.warning("Packet Vid = %i", pid)

      if ip and udpp:
        msg = of.ofp_flow_mod()
        msg.match.dl_type = 0x800
        msg.match.nw_src = IPAddr(srcip)
        msg.match.nw_dst = IPAddr(dstip)
        msg.match.nw_proto = 17
        msg.match.tp_src = srcport
      else:
        msg = of.ofp_packet_out(data = event.ofp)
      if pid != 0:
        # There exists a path
        path = self.path_id_table[pid]
        if len(path) > 3:
        # It is not the last sw, tag it and send into the network
          if USE_VLAN_TAG:
            msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) )
          if USE_ETHERNET_SRC_TAG:
            msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) )
          msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) )
        elif len(path) == 3:
          # last sw, forward to the host
          #msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) )
          msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) )

      """
      msg = of.ofp_packet_out( data = event.ofp )
      if pid != 0:
        # There exists a path
        path = self.path_id_table[pid]
        if len(path) > 3:
          # It is not the last sw, tag it and send into the network
          if USE_VLAN_TAG:
            msg.actions.append( of.ofp_action_vlan_vid( vlan_vid = pid ) )
          if USE_ETHERNET_SRC_TAG:
            msg.actions.append( of.ofp_action_dl_addr.set_src( EthAddr( self._int_to_MAC( pid ) ) ) )
          msg.actions.append( of.ofp_action_output( port = self.ports[path[1]][path[2]] ) )
        elif len(path) == 3:
          # last sw, forward to the host
          # msg.actions.append( of.ofp_action_output( port = of.OFPP_FLOOD ) )
          msg.actions.append( of.ofp_action_output( port = self.hadj[path[2]][path[1]] ) )
      """

      event.connection.send(msg)