Beispiel #1
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto

        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        LOG.info("packet in %s %s %s %s",
                 dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = msg.in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            self.add_flow(datapath, msg.in_port, dst, actions)

        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,
            actions=actions)
        datapath.send_msg(out)
Beispiel #2
0
def match_eth_to_str(value, mask):
    eth_str = mac.haddr_to_str(value)

    if mask is not None:
        eth_str = eth_str + '/' + mac.haddr_to_str(mask)

    return eth_str
Beispiel #3
0
    def _forward_to_nw_id(self, msg, src, dst, nw_id, out_port):
        assert out_port is not None
        datapath = msg.datapath

        if not self.nw.same_network(datapath.id, nw_id, out_port, NW_ID_EXTERNAL):
            self.logger.debug(
                "packet is blocked src %s dst %s " "from %d to %d on datapath %d",
                haddr_to_str(src),
                haddr_to_str(dst),
                msg.in_port,
                out_port,
                datapath.id,
            )
            return

        self.logger.debug(
            "learned dpid %s in_port %d out_port " "%d src %s dst %s",
            datapath.id,
            msg.in_port,
            out_port,
            haddr_to_str(src),
            haddr_to_str(dst),
        )
        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
        self._modflow_and_send_packet(msg, src, dst, actions)
Beispiel #4
0
    def switch_configuration(self, ev):
        print "Packet in: switch configuration"
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto

        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        dpid = datapath.id
        self.mac2port.dpid_add(dpid)
        LOG.info("Src MAC: %s; Dest MAC: %s", haddr_to_str(src), haddr_to_str(dst))

        self.mac2port.port_add(dpid, msg.in_port, src)
        out_port = self.mac2port.port_get(dpid, dst)

        if out_port == None:
            LOG.info("Output port not found")
            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
        LOG.info("Input port: %s; Output port: %s", msg.in_port, out_port)

        if out_port != ofproto.OFPP_FLOOD:
            rule = nx_match.ClsRule()
            rule.set_in_port(msg.in_port)
            rule.set_dl_dst(dst)
            rule.set_dl_src(src)
            rule.set_nw_dscp(0)
            datapath.send_flow_mod(
                rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
                idle_timeout=0, hard_timeout=0,
                priority=ofproto.OFP_DEFAULT_PRIORITY,
                flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)

        datapath.send_packet_out(msg.buffer_id, msg.in_port, actions)
Beispiel #5
0
def actions_to_str(acts):
    actions = []
    for a in acts:
        action_type = a.cls_action_type
        if action_type == ofproto_v1_0.OFPAT_OUTPUT:
            buf = 'OUTPUT:' + str(a.port)
        elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_VID:
            buf = 'SET_VLAN_VID:' + str(a.vlan_vid)
        elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_PCP:
            buf = 'SET_VLAN_PCP:' + str(a.vlan_pcp)
        elif action_type == ofproto_v1_0.OFPAT_STRIP_VLAN:
            buf = 'STRIP_VLAN'
        elif action_type == ofproto_v1_0.OFPAT_SET_DL_SRC:
            buf = 'SET_DL_SRC:' + haddr_to_str(a.dl_addr)
        elif action_type == ofproto_v1_0.OFPAT_SET_DL_DST:
            buf = 'SET_DL_DST:' + haddr_to_str(a.dl_addr)
        elif action_type==65535:
            if a.subtype==2:
                buf = 'set_tunnel:'+str(a.tun_id)
            else:
                buf='resubmit:(,'+str(a.table)+')'
        else:
            buf='UNKNOWN'
        actions.append(buf)

    return actions
    def packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        match = msg.match.fields
        #for field in match:
            #logger.info("FIELDS==> %s ",field.value)

        logger.info("")
        logger.info("----------------------------------------")
        logger.info("*** PacketIn ***")
        logger.info("in_port=%d, eth_type: %s", in_port, hex(eth_type))
        logger.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id)
        logger.info("packet in datapath_id=%s src=%s dst=%s",
                msg.datapath.id, haddr_to_str(src), haddr_to_str(dst))

        pkt = packet.Packet(msg.data)  # get data of packet
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        dst = eth.dst
        src = eth.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
            # verify if we have a valid buffer_id, if yes avoid to send both
            # flow_mod & packet_out
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                return
            else:
                self.add_flow(datapath, 1, match, actions)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
                                  in_port=in_port, actions=actions, data=data)
        datapath.send_msg(out)
Beispiel #7
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto

        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})
        
        match = msg.match
        in_port = 0
        #iterate through fields - parser should handle this
        #packet in dpid 20015998343868 from 08:00:27:15:d4:53 to ff:ff:ff:ff:ff:ff log_port 0 phy_port 0
        #Field MTInPort(header=2147483652,length=8,n_bytes=4,value=2)
        #Field MTEthType(header=2147486210,length=6,n_bytes=2,value=2054)
        #Field MTArpOp(header=2147494402,length=6,n_bytes=2,value=1)
        #Field MTMetadata(header=2147484680,length=12,n_bytes=8,value=18446744073709551615L)
        #Field MTArpSha(header=2147495942,length=10,n_bytes=6,value="\x08\x00'\x15\xd4S")
        #Field MTEthDst(header=2147485190,length=10,n_bytes=6,value='\xff\xff\xff\xff\xff\xff')
        #Field MTArpSpa(header=2147494916,length=8,n_bytes=4,value=167772161)
        #Field MTArpTha(header=2147496454,length=10,n_bytes=6,value='\x00\x00\x00\x00\x00\x00')

        for o in match.fields:
            if isinstance(o, ofproto_v1_2_parser.MTInPort):
                in_port = o.value
                break

        self.logger.info("packet in dpid %s from %s to %s log_port %s",
                         dpid, haddr_to_str(src), haddr_to_str(dst),
                         in_port)
        
        
        # do we know the mac?
        if src not in self.mac_to_port[dpid]:
            # learn the mac address to avoid FLOOD next time.
            self.mac_to_port[dpid][src] = in_port
            # set a flow to table 0 to allow packets through to table 1
            match = datapath.ofproto_parser.OFPMatch()
            match.set_in_port(in_port)
            match.set_dl_src(src)
            instructions = [datapath.ofproto_parser.OFPInstructionGotoTable(1)]
            self.add_flow(datapath, 0, match, instructions)
            

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
            actions = [datapath.ofproto_parser.OFPActionOutput(out_port, 1500)]
            match = datapath.ofproto_parser.OFPMatch()
            match.set_dl_dst(dst)
            instructions = [datapath.ofproto_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
            self.add_flow(datapath, 1, match, instructions, buffer_id=msg.buffer_id)
        else:
            out_port = ofproto_v1_2.OFPP_FLOOD
            actions = [datapath.ofproto_parser.OFPActionOutput(out_port, 1500)]
            out = datapath.ofproto_parser.OFPPacketOut(
                datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port,
                actions=actions)
            datapath.send_msg(out)
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
       
        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)
        dpid = datapath.id
        print 'mac_to_port',self.mac_to_port,'\n'       
        self.mac_to_port.setdefault(dpid, {})
        print 'mac_to_port',self.mac_to_port,'\n'

        LOG.info("packet in %s %s %s %s",
                 dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = msg.in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
        if out_port != ofproto.OFPP_FLOOD:
            #self.add_flow(datapath, msg.in_port, dst, [datapath.ofproto_parser.OFPActionOutput(datapath.ofproto.OFPP_NORMAL)])
            self.add_flow(datapath, msg.in_port, dst, actions)        
            #add a ipv6 flow table:        
            if _eth_type == ether.ETH_TYPE_IPV6:
                #print _eth_type
                pkt = Packet(array('B',msg.data))          
                for packet in pkt:
                    if isinstance(packet,array):
                        pass
                    else:
                        if packet.protocol_name=='ipv6':
                            ipv6_packet=packet
                        else:
                            pass
                ipv6_src=self._binary_to_ipv6_format(ipv6_packet.src)
                ipv6_dst=self._binary_to_ipv6_format(ipv6_packet.dst)
                print ipv6_src,ipv6_dst
                '''
                # judge if src and dst addr is special 
                # eg: src [0,0,0,0] dst begin with 0xff01 or 0x ff02 
                if ipv6_src == [0,0,0,0] or ipv6_dst[0]&0xff010000 == 0xff010000 or ipv6_dst[0]&0xff020000 == 0xff020000:
                    print 'ipv6 reserved address\n' 
                #elif ipv6_dst[0]&0xfe800000 == 0xfe800000:
                #    print 'ipv6 dst address is Link-Local address'
                else:
                '''                      
                rule={'ipv6_src':ipv6_src,'ipv6_dst':ipv6_dst}
                self.nx_ipv6_add_flow(datapath,rule,actions)
                print 'add a ipv6 flow entry'  
            
           
        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,
            actions=actions)
        datapath.send_msg(out)                 
    def packet_in_handler(self, ev):
        msg = ev.msg
        dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)
        in_port = msg.match.fields[0].value

        LOG.info("----------------------------------------")
        LOG.info("* PacketIn")
        LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type))
        LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id)
        LOG.info("packet in datapath_id=%s src=%s dst=%s",
                 msg.datapath.id, haddr_to_str(src), haddr_to_str(dst))
Beispiel #10
0
 def _flood_to_nw_id(self, msg, src, dst, nw_id):
     datapath = msg.datapath
     actions = []
     self.logger.debug("dpid %s in_port %d src %s dst %s ports %s",
                       datapath.id, msg.in_port,
                       haddr_to_str(src), haddr_to_str(dst),
                       self.nw.dpids.get(datapath.id, {}).items())
     for port_no in self.nw.filter_ports(datapath.id, msg.in_port,
                                         nw_id, NW_ID_EXTERNAL):
         self.logger.debug("port_no %s", port_no)
         actions.append(datapath.ofproto_parser.OFPActionOutput(port_no))
     self._modflow_and_send_packet(msg, src, dst, actions)
Beispiel #11
0
def match_to_str(m):
    return {'dl_dst': haddr_to_str(m.dl_dst),
            'dl_src': haddr_to_str(m.dl_src),
            'dl_type': m.dl_type,
            'dl_vlan': m.dl_vlan,
            'dl_vlan_pcp': m.dl_vlan_pcp,
            'in_port': m.in_port,
            'nw_dst': socket.inet_ntoa(struct.pack('!I', m.nw_dst)),
            'nw_proto': m.nw_proto,
            'nw_src': socket.inet_ntoa(struct.pack('!I', m.nw_src)),
            'tp_src': m.tp_src,
            'tp_dst': m.tp_dst}
Beispiel #12
0
def match_to_str(m):
    return {'dl_dst': haddr_to_str(m.dl_dst),
            'dl_src': haddr_to_str(m.dl_src),
            'dl_type': m.dl_type,
            'dl_vlan': m.dl_vlan,
            'dl_vlan_pcp': m.dl_vlan_pcp,
            'in_port': m.in_port,
            'nw_dst': nw_dst_to_str(m.wildcards, m.nw_dst),
            'nw_proto': m.nw_proto,
            'nw_src': nw_src_to_str(m.wildcards, m.nw_src),
            'tp_src': m.tp_src,
            'tp_dst': m.tp_dst}
Beispiel #13
0
    def _decode_bridge_id(bridge_id):
        priority = (bridge_id << 12) & 0xf000
        system_id_extension = (bridge_id >> 4) & 0xfff
        mac_addr = (bridge_id >> 16) & 0xffffffffffff

        mac_addr_list = [format((mac_addr >> (8 * i)) & 0xff, '02x')
                         for i in range(0, 6)]
        mac_address = binascii.a2b_hex(''.join(mac_addr_list))

        #TODO:
        from ryu.lib import mac
        print mac.haddr_to_str(mac_address)

        return priority, system_id_extension, mac_address
Beispiel #14
0
 def equal_match(key, value, cls_name, fields):
     for field in fields:
         if cls_name in str(field):
             if key in ['dl_src', 'dl_dst', 'arp_sha', 'arp_tha',
                        'eth_src', 'eth_dst']:
                 eth, mask = _to_match_eth(value)
                 str_eth = mac.haddr_to_str(eth)
                 str_mask = mac.haddr_to_str(mask)
                 str_value = mac.haddr_to_str(field.value)
                 for i in range(0, 17):
                     if str_mask[i] == 'f':
                         eq_(str_eth[i], str_value[i])
                     else:
                         continue
                 eq_(mask, field.mask)
                 return
             elif key in ['nw_src', 'nw_dst', 'ipv4_src', 'ipv4_dst',
                          'arp_spa', 'arp_tpa']:
                 ipv4, mask = _to_match_ip(value)
                 eq_(ipv4, field.value)
                 eq_(mask, field.mask)
                 return
             elif key in ['ipv6_src', 'ipv6_dst']:
                 ipv6, mask = _to_match_ipv6(value)
                 for i in range(0, 8):
                     if mask[i] == 65535:
                         eq_(ipv6[i], field.value[i])
                     else:
                         continue
                 eq_(list(mask), field.mask)
                 return
             elif key == 'ipv6_nd_target':
                 ipv6, mask = _to_match_ipv6(value)
                 for i in range(0, 8):
                     if mask[i] == 65535:
                         eq_(ipv6[i], field.value[i])
                     else:
                         continue
                 return
             elif key == 'ipv6_nd_sll' or key == 'ipv6_nd_tll':
                 eq_(mac.haddr_to_bin(value), field.value)
                 return
             elif key == 'metadata':
                 eq_(int(value, 16), field.value)
                 return
             else:
                 eq_(value, field.value)
                 return
     assert False
Beispiel #15
0
    def test_to_string(self):
        nd_opt = icmpv6.nd_option_la(self.nd_hw_src)
        nd = icmpv6.nd_neighbor(
            self.res, self.dst, self.nd_type, self.nd_length, nd_opt)
        ic = icmpv6.icmpv6(self.type_, self.code, self.csum, nd)

        nd_opt_values = {'hw_src': haddr_to_str(self.nd_hw_src),
                         'data': None}
        _nd_opt_str = ','.join(['%s=%s' % (k, repr(nd_opt_values[k]))
                                for k, v in inspect.getmembers(nd_opt)
                                if k in nd_opt_values])
        nd_opt_str = '%s(%s)' % (icmpv6.nd_option_la.__name__, _nd_opt_str)

        nd_values = {'res': repr(nd.res),
                     'dst': repr(ipv6_to_str(self.dst)),
                     'type_': repr(self.nd_type),
                     'length': repr(self.nd_length),
                     'data': nd_opt_str}
        _nd_str = ','.join(['%s=%s' % (k, nd_values[k])
                            for k, v in inspect.getmembers(nd)
                            if k in nd_values])
        nd_str = '%s(%s)' % (icmpv6.nd_neighbor.__name__, _nd_str)

        icmp_values = {'type_': repr(self.type_),
                       'code': repr(self.code),
                       'csum': repr('0x%x' % self.csum),
                       'data': nd_str}
        _ic_str = ','.join(['%s=%s' % (k, icmp_values[k])
                            for k, v in inspect.getmembers(ic)
                            if k in icmp_values])
        ic_str = '%s(%s)' % (icmpv6.icmpv6.__name__, _ic_str)

        eq_(str(ic), ic_str)
        eq_(repr(ic), ic_str)
Beispiel #16
0
 def to_dict(self):
     return {
         "dpid": dpid_to_str(self.dpid),
         "port_no": port_no_to_str(self.port_no),
         "hw_addr": haddr_to_str(self.hw_addr),
         "name": self.name.rstrip("\0"),
     }
Beispiel #17
0
def match_to_str(ofmatch):
    keys = {
        ofproto_v1_3.OXM_OF_IN_PORT: 'in_port',
        ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src',
        ofproto_v1_3.OXM_OF_ETH_DST: 'dl_dst',
        ofproto_v1_3.OXM_OF_ETH_TYPE: 'dl_type',
        ofproto_v1_3.OXM_OF_VLAN_VID: 'dl_vlan',
        ofproto_v1_3.OXM_OF_IPV4_SRC: 'nw_src',
        ofproto_v1_3.OXM_OF_IPV4_DST: 'nw_dst',
        ofproto_v1_3.OXM_OF_IPV4_SRC_W: 'nw_src',
        ofproto_v1_3.OXM_OF_IPV4_DST_W: 'nw_dst',
        ofproto_v1_3.OXM_OF_IP_PROTO: 'nw_proto',
        ofproto_v1_3.OXM_OF_TCP_SRC: 'tp_src',
        ofproto_v1_3.OXM_OF_TCP_DST: 'tp_dst',
        ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src',
        ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst'
    }

    match = {}
    for match_field in ofmatch.fields:
        key = keys[match_field.header]
        if key == 'dl_src' or key == 'dl_dst':
            value = mac.haddr_to_str(match_field.value)
        elif key == 'nw_src' or key == 'nw_dst':
            value = match_ip_to_str(match_field.value, match_field.mask)
        else:
            value = match_field.value
        match.setdefault(key, value)

    return match
Beispiel #18
0
 def to_dict(self):
     return {
         'dpid': dpid_to_str(self.dpid),
         'port_no': port_no_to_str(self.port_no),
         'hw_addr': haddr_to_str(self.hw_addr),
         'name': self.name.rstrip('\0')
     }
Beispiel #19
0
    def to_rest(openflow):
        of_match = openflow[REST_MATCH]

        mac_dontcare = mac.haddr_to_str(mac.DONTCARE)
        ip_dontcare = '0.0.0.0'
        ipv6_dontcare = '::'

        match = {}
        for key, value in of_match.items():
            if key == REST_SRC_MAC or key == REST_DST_MAC:
                if value == mac_dontcare:
                    continue
            elif key == REST_SRC_IP or key == REST_DST_IP:
                if value == ip_dontcare:
                    continue
            elif key == REST_SRC_IPV6 or key == REST_DST_IPV6:
                if value == ipv6_dontcare:
                    continue
            elif value == 0:
                continue

            if key in Match._CONVERT:
                conv = Match._CONVERT[key]
                conv = dict((value, key) for key, value in conv.items())
                match.setdefault(key, conv[value])
            else:
                match.setdefault(key, value)

        return match
Beispiel #20
0
    def to_rest(openflow):
        of_match = openflow[REST_MATCH]

        mac_dontcare = mac.haddr_to_str(mac.DONTCARE)
        ip_dontcare = '0.0.0.0'

        match = {}
        for key, value in of_match.items():
            if key == REST_SRC_MAC or key == REST_DST_MAC:
                if value == mac_dontcare:
                    continue
            elif key == REST_SRC_IP or key == REST_DST_IP:
                if value == ip_dontcare:
                    continue
            elif value == 0:
                continue

            if key in Match._CONVERT:
                conv = Match._CONVERT[key]
                conv = dict((value, key) for key, value in conv.items())
                match.setdefault(key, conv[value])
            else:
                match.setdefault(key, value)

        return match
    def block_out_sample_in(self, stats):
        ofproto = datapath.ofproto
        #SRC BLOCK FLOW
        src_mac = stats.match.dl_dst
        if not src_mac == self.gateway_mac:
            src_match = datapath.ofproto_parser.OFPMatch(dl_src=src_mac, dl_dst=self.gateway_mac)

            src_flow = datapath.ofproto_parser.OFPFlowMod(
                datapath=datapath, match=src_match, cookie=random_int(),
                command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=2,
                priority=0x6000,
                flags=ofproto.OFPFF_SEND_FLOW_REM)
            datapath.send_msg(src_flow)

        eventlet.sleep(0.1)

        # DST BLOCK FLOW - We only sample this flow for 1 second,
        # Destination does not receive anything.
        dst_mac = stats.match.dl_dst
        if not dst_mac == self.gateway_mac:
            dst_match = datapath.ofproto_parser.OFPMatch(dl_src=self.gateway_mac, dl_dst=dst_mac)

            dst_actions = [datapath.ofproto_parser.OFPActionOutput(monitor_port)]

            dst_flow = datapath.ofproto_parser.OFPFlowMod(
                datapath=datapath, match=dst_match, cookie=random_int(),
                command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=1,
                priority=0x6000,
                flags=ofproto.OFPFF_SEND_FLOW_REM, actions=dst_actions)
            datapath.send_msg(dst_flow)

        #Notify parser of this source/destination being blocked from this point on.
        outgoing_block_mode_v1_dict[(haddr_to_str(src_mac))] = int(time.time() * 1000)
    def test_mac_haddr_to_str(self):
        addr = 'aa:aa:aa:aa:aa:aa'
        val = '\xaa\xaa\xaa\xaa\xaa\xaa'

        res = mac.haddr_to_str(val)

        eq_(addr, res)
Beispiel #23
0
    def test_mac_haddr_to_str(self):
        addr = "aa:aa:aa:aa:aa:aa"
        val = b"\xaa\xaa\xaa\xaa\xaa\xaa"

        res = mac.haddr_to_str(val)

        eq_(addr, res)
Beispiel #24
0
def match_to_str(ofmatch):
    keys = {ofproto_v1_3.OXM_OF_IN_PORT: 'in_port',
            ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src',
            ofproto_v1_3.OXM_OF_ETH_DST: 'dl_dst',
            ofproto_v1_3.OXM_OF_ETH_TYPE: 'dl_type',
            ofproto_v1_3.OXM_OF_VLAN_VID: 'dl_vlan',
            ofproto_v1_3.OXM_OF_IPV4_SRC: 'nw_src',
            ofproto_v1_3.OXM_OF_IPV4_DST: 'nw_dst',
            ofproto_v1_3.OXM_OF_IPV4_SRC_W: 'nw_src',
            ofproto_v1_3.OXM_OF_IPV4_DST_W: 'nw_dst',
            ofproto_v1_3.OXM_OF_IP_PROTO: 'nw_proto',
            ofproto_v1_3.OXM_OF_TCP_SRC: 'tp_src',
            ofproto_v1_3.OXM_OF_TCP_DST: 'tp_dst',
            ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src',
            ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst',
            ofproto_v1_3.OXM_OF_METADATA: 'metadata',
            ofproto_v1_3.OXM_OF_METADATA_W: 'metadata'}

    match = {}
    for match_field in ofmatch.fields:
        key = keys[match_field.header]
        if key == 'dl_src' or key == 'dl_dst':
            value = mac.haddr_to_str(match_field.value)
        elif key == 'nw_src' or key == 'nw_dst':
            value = match_ip_to_str(match_field.value, match_field.mask)
        elif key == 'metadata':
            value = ('%d/%d' % (match_field.value, match_field.mask)
                     if match_field.mask else '%d' % match_field.value)
        else:
            value = match_field.value
        match.setdefault(key, value)

    return match
Beispiel #25
0
    def test_mac_haddr_to_str_none(self):
        """ addr is None
        """
        addr = None
        val = 'None'
        res = mac.haddr_to_str(addr)

        eq_(val, res)
Beispiel #26
0
    def packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        port = msg.match['in_port']
        pkt = packet.Packet(data=msg.data)

        ofproto = datapath.ofproto

        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.debug("packet in %s %s %s %s", dpid, haddr_to_str(src),
                          haddr_to_str(dst), msg.in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = msg.in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            self.add_flow(datapath, msg.in_port, dst, actions)

        if drop_checker[port] == True:
            self.delete_flow(datapath)

        out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath,
                                                   buffer_id=msg.buffer_id,
                                                   in_port=msg.in_port,
                                                   actions=actions)
        datapath.send_msg(out)

        pkt_dhcp = pkt.get_protocols(dhcp.dhcp)
        if not pkt_dhcp:
            return
        else:
            drop_checker[port] = False
            self._handle_dhcp(datapath, port, pkt)
        return
Beispiel #27
0
    def test_mac_haddr_to_str_none(self):
        """ addr is None
        """
        addr = None
        val = "None"
        res = mac.haddr_to_str(addr)

        eq_(val, res)
Beispiel #28
0
    def _forward_to_nw_id(self, msg, src, dst, nw_id, out_port):
        assert out_port is not None
        datapath = msg.datapath

        if not self.nw.same_network(datapath.id, nw_id, out_port,
                                    NW_ID_EXTERNAL):
            LOG.debug(
                'packet is blocked src %s dst %s '
                'from %d to %d on datapath %d', haddr_to_str(src),
                haddr_to_str(dst), msg.in_port, out_port, datapath.id)
            return

        LOG.debug("learned dpid %s in_port %d out_port %d src %s dst %s",
                  datapath.id, msg.in_port, out_port, haddr_to_str(src),
                  haddr_to_str(dst))
        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
        self._modflow_and_send_packet(msg, src, dst, actions)
Beispiel #29
0
def match_to_str(ofmatch):
    keys = {ofproto_v1_2.OXM_OF_IN_PORT: 'in_port',
            ofproto_v1_2.OXM_OF_IN_PHY_PORT: 'in_phy_port',
            ofproto_v1_2.OXM_OF_ETH_SRC: 'dl_src',
            ofproto_v1_2.OXM_OF_ETH_DST: 'dl_dst',
            ofproto_v1_2.OXM_OF_ETH_TYPE: 'dl_type',
            ofproto_v1_2.OXM_OF_VLAN_VID: 'dl_vlan',
            ofproto_v1_2.OXM_OF_VLAN_PCP: 'vlan_pcp',
            ofproto_v1_2.OXM_OF_IP_DSCP: 'ip_dscp',
            ofproto_v1_2.OXM_OF_IP_ECN: 'ip_ecn',
            ofproto_v1_2.OXM_OF_IPV4_SRC: 'nw_src',
            ofproto_v1_2.OXM_OF_IPV4_DST: 'nw_dst',
            ofproto_v1_2.OXM_OF_IPV4_SRC_W: 'nw_src',
            ofproto_v1_2.OXM_OF_IPV4_DST_W: 'nw_dst',
            ofproto_v1_2.OXM_OF_IP_PROTO: 'nw_proto',
            ofproto_v1_2.OXM_OF_TCP_SRC: 'tp_src',
            ofproto_v1_2.OXM_OF_TCP_DST: 'tp_dst',
            ofproto_v1_2.OXM_OF_UDP_SRC: 'tp_src',
            ofproto_v1_2.OXM_OF_UDP_DST: 'tp_dst',
            ofproto_v1_2.OXM_OF_SCTP_SRC: 'sctp_src',
            ofproto_v1_2.OXM_OF_SCTP_DST: 'sctp_dst',
            ofproto_v1_2.OXM_OF_ICMPV4_TYPE: 'icmpv4_type',
            ofproto_v1_2.OXM_OF_ICMPV4_CODE: 'icmpv4_code',
            ofproto_v1_2.OXM_OF_MPLS_LABEL: 'mpls_label',
            ofproto_v1_2.OXM_OF_MPLS_TC: 'mpls_tc',
            ofproto_v1_2.OXM_OF_ARP_OP: 'arp_op',
            ofproto_v1_2.OXM_OF_ARP_SPA: 'arp_spa',
            ofproto_v1_2.OXM_OF_ARP_TPA: 'arp_tpa',
            ofproto_v1_2.OXM_OF_ARP_SPA_W: 'arp_spa',
            ofproto_v1_2.OXM_OF_ARP_TPA_W: 'arp_tpa',
            ofproto_v1_2.OXM_OF_ARP_SHA: 'arp_sha',
            ofproto_v1_2.OXM_OF_ARP_THA: 'arp_tha',
            ofproto_v1_2.OXM_OF_IPV6_SRC: 'ipv6_src',
            ofproto_v1_2.OXM_OF_IPV6_DST: 'ipv6_dst',
            ofproto_v1_2.OXM_OF_IPV6_SRC_W: 'ipv6_src',
            ofproto_v1_2.OXM_OF_IPV6_DST_W: 'ipv6_dst',
            ofproto_v1_2.OXM_OF_IPV6_FLABEL: 'ipv6_flabel',
            ofproto_v1_2.OXM_OF_ICMPV6_TYPE: 'icmpv6_type',
            ofproto_v1_2.OXM_OF_ICMPV6_CODE: 'icmpv6_code',
            ofproto_v1_2.OXM_OF_IPV6_ND_TARGET: 'ipv6_nd_target',
            ofproto_v1_2.OXM_OF_IPV6_ND_SLL: 'ipv6_nd_sll',
            ofproto_v1_2.OXM_OF_IPV6_ND_TLL: 'ipv6_nd_tll'}

    match = {}
    for match_field in ofmatch.fields:
        key = keys[match_field.header]
        if key == 'dl_src' or key == 'dl_dst':
            value = mac.haddr_to_str(match_field.value)
        elif key == 'nw_src' or key == 'nw_dst' or \
                key == 'arp_spa' or key == 'arp_tpa':
            value = match_ip_to_str(match_field.value, match_field.mask)
        elif key == 'ipv6_src' or key == 'ipv6_dst':
            value = match_ipv6_to_str(match_field.value, match_field.mask)
        else:
            value = match_field.value
        match.setdefault(key, value)

    return match
Beispiel #30
0
    def _port_del(self, ev):
        # free mac addresses associated to this VM port,
        # and delete related flow entries for later reuse of mac address

        dps_needs_barrier = set()

        msg = ev.msg
        datapath = msg.datapath
        datapath_id = datapath.id
        port_no = msg.desc.port_no

        rule = nx_match.ClsRule()
        rule.set_in_port(port_no)
        datapath.send_flow_del(rule=rule, cookie=0)

        rule = nx_match.ClsRule()
        datapath.send_flow_del(rule=rule, cookie=0, out_port=port_no)
        dps_needs_barrier.add(datapath)

        try:
            port_nw_id = self.nw.get_network(datapath_id, port_no)
        except PortUnknown:
            # race condition between rest api delete port
            # and openflow port deletion ofp_event
            pass
        else:
            if port_nw_id in (NW_ID_UNKNOWN, NW_ID_EXTERNAL):
                datapath.send_barrier()
                return

        for mac_ in self.mac2port.mac_list(datapath_id, port_no):
            for (_dpid, dp) in self.dpset.get_all():
                if self.mac2port.port_get(dp.id, mac_) is None:
                    continue

                rule = nx_match.ClsRule()
                rule.set_dl_src(mac_)
                dp.send_flow_del(rule=rule, cookie=0)

                rule = nx_match.ClsRule()
                rule.set_dl_dst(mac_)
                dp.send_flow_del(rule=rule, cookie=0)
                dps_needs_barrier.add(dp)

                self.mac2port.mac_del(dp.id, mac_)

            try:
                self.mac2net.del_mac(mac_)
                self.api_db.delMAC(haddr_to_str(mac_))
            except MacAddressNotFound:
                # Race condition between del_mac REST API and OF port_del ofp_event
                # Other possibility is that Ryu has been restarted after a crash
                pass

        self.nw.port_deleted(datapath.id, port_no)

        for dp in dps_needs_barrier:
            dp.send_barrier()
Beispiel #31
0
 def __str__(self):
     return "EventVMPort<dpid %s port_no %d " "network_id %s tunnel_key %s mac %s add_del %s>" % (
         dpid_lib.dpid_to_str(self.dpid),
         self.port_no,
         self.network_id,
         self.tunnel_key,
         mac.haddr_to_str(self.mac_address),
         self.add_del,
     )
Beispiel #32
0
 def lists(self, _req, network_id, dpid, port_id, **_kwargs):
     dpid = dpid_lib.str_to_dpid(dpid)
     port_id = int(port_id)
     try:
         body = json.dumps([mac_lib.haddr_to_str(mac_addr) for mac_addr in
                            self.nw.list_mac(dpid, port_id)])
     except PortNotFound:
         return Response(status=404)
     return Response(content_type='application/json', body=body)
Beispiel #33
0
def get_eth_src(msg):
    dp = msg.datapath
    eth_src = None
    for f in msg.match.fields:
        if f.header == dp.ofproto.OXM_OF_ETH_SRC:
            eth_src = haddr_to_str(f.value)
    if eth_src is None:
        eth_src = Ether(str(msg.data)).src
    return eth_src
    def packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocol(ethernet.ethernet)

        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.debug("packet in %s %s %s %s",
                          dpid, haddr_to_str(src), haddr_to_str(dst),
                          msg.in_port)

        self.logger.info("===============Message: %d================", self.msg_num)
        self.logger.info("packet in %s %s %s %s", dpid, eth.src, eth.dst, msg.in_port)
        self.logger.info("src: %s, out_port: %s", eth.src, msg.in_port)
        self.logger.info("------------------------------------")

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = msg.in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            self.add_flow(datapath, msg.in_port, dst, actions)

        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,
            actions=actions)

        self.msg_num += 1
        self.logger.info("===========================================")

        datapath.send_msg(out)
Beispiel #35
0
    def lists(self, _req, network_id, dpid, port_id, **_kwargs):
        dpid = dpid_lib.str_to_dpid(dpid)
        port_id = int(port_id)
        try:
            body = json.dumps([mac_lib.haddr_to_str(mac_addr) for mac_addr in
                               self.nw.list_mac(dpid, port_id)])
        except PortNotFound:
            return Response(status=404)

        return Response(content_type='application/json', body=body)
Beispiel #36
0
    def add_mac(self, mac, nw_id, nw_id_external=None):
        _nw_id = self.mac_to_net.get(mac)
        if _nw_id == nw_id:
            return

        # allow changing from nw_id_external to known nw id
        if _nw_id is None or _nw_id == nw_id_external:
            self.mac_to_net[mac] = nw_id
            LOG.debug("overwrite nw_id: mac %s nw old %s new %s", haddr_to_str(mac), _nw_id, nw_id)
            return

        if nw_id == nw_id_external:
            # this can happens when the packet traverses
            # VM-> tap-> ovs-> ext-port-> wire-> ext-port-> ovs-> tap-> VM
            return

        LOG.warn("duplicated nw_id: mac %s nw old %s new %s", haddr_to_str(mac), _nw_id, nw_id)

        raise MacAddressDuplicated(mac=mac)
Beispiel #37
0
 def equal_str(key, value, match_str):
     if key in ['dl_src', 'dl_dst', 'arp_sha', 'arp_tha']:
         eth_1, mask_1 = _to_match_eth(value)
         eth_2, mask_2 = _to_match_eth(match_str[key])
         str_eth_1 = mac.haddr_to_str(eth_1)
         str_mask_1 = mac.haddr_to_str(mask_1)
         str_eth_2 = mac.haddr_to_str(eth_2)
         for i in range(0, 17):
             if str_mask_1[i] == 'f':
                 eq_(str_eth_1[i], str_eth_2[i])
             else:
                 continue
         eq_(mask_1, mask_2)
         return
     elif key in['nw_src', 'nw_dst', 'arp_spa', 'arp_tpa']:
         ipv4_1, ip_mask_1 = _to_match_ip(value)
         ipv4_2, ip_mask_2 = _to_match_ip(match_str[key])
         eq_(ipv4_1, ipv4_2)
         eq_(ip_mask_1, ip_mask_2)
         return
     elif key in ['ipv6_src', 'ipv6_dst']:
         ipv6_1, netmask_1 = _to_match_ipv6(value)
         ipv6_2, netmask_2 = _to_match_ipv6(match_str[key])
         for i in range(0, 8):
             if netmask_1[i] == 65535:
                 eq_(ipv6_1[i], ipv6_2[i])
             else:
                 continue
         eq_(netmask_1, netmask_2)
         return
     elif key == 'ipv6_nd_target':
         ipv6_1, netmask_1 = _to_match_ipv6(value)
         ipv6_2, netmask_2 = _to_match_ipv6(match_str[key])
         for i in range(0, 8):
             if netmask_1[i] == 65535:
                 eq_(ipv6_1[i], ipv6_2[i])
             else:
                 continue
         return
     elif key == 'metadata':
         eq_(str(int(value, 16)), match_str[key])
         return
     eq_(value, match_str[key])
Beispiel #38
0
def match_to_str(m):

    match = {}

    if ~m.wildcards & ofproto_v1_0.OFPFW_IN_PORT:
        match['in_port'] = m.in_port

    if ~m.wildcards & ofproto_v1_0.OFPFW_DL_SRC:
        match['dl_src'] = haddr_to_str(m.dl_src)

    if ~m.wildcards & ofproto_v1_0.OFPFW_DL_DST:
        match['dl_dst'] = haddr_to_str(m.dl_dst)

    if ~m.wildcards & ofproto_v1_0.OFPFW_DL_VLAN:
        match['dl_vlan'] = m.dl_vlan

    if ~m.wildcards & ofproto_v1_0.OFPFW_DL_VLAN_PCP:
        match['dl_vlan_pcp'] = m.dl_vlan_pcp

    if ~m.wildcards & ofproto_v1_0.OFPFW_DL_TYPE:
        match['dl_type'] = m.dl_type

    if ~m.wildcards & ofproto_v1_0.OFPFW_NW_TOS:
        match['nw_tos'] = m.nw_tos

    if ~m.wildcards & ofproto_v1_0.OFPFW_NW_PROTO:
        match['nw_proto'] = m.nw_proto

    if ~m.wildcards & ofproto_v1_0.OFPFW_NW_SRC_ALL:
        match['nw_src'] = nw_src_to_str(m.wildcards, m.nw_src)

    if ~m.wildcards & ofproto_v1_0.OFPFW_NW_DST_ALL:
        match['nw_dst'] = nw_dst_to_str(m.wildcards, m.nw_dst)

    if ~m.wildcards & ofproto_v1_0.OFPFW_TP_SRC:
        match['tp_src'] = m.tp_src

    if ~m.wildcards & ofproto_v1_0.OFPFW_TP_DST:
        match['tp_dst'] = m.tp_dst

    return match
Beispiel #39
0
def actions_to_str(acts):
    actions = []
    for a in acts:
        action_type = a.cls_action_type

        if action_type == ofproto_v1_0.OFPAT_OUTPUT:
            port = UTIL.ofp_port_to_user(a.port)
            buf = 'OUTPUT:' + str(port)
        elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_VID:
            buf = 'SET_VLAN_VID:' + str(a.vlan_vid)
        elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_PCP:
            buf = 'SET_VLAN_PCP:' + str(a.vlan_pcp)
        elif action_type == ofproto_v1_0.OFPAT_STRIP_VLAN:
            buf = 'STRIP_VLAN'
        elif action_type == ofproto_v1_0.OFPAT_SET_DL_SRC:
            buf = 'SET_DL_SRC:' + haddr_to_str(a.dl_addr)
        elif action_type == ofproto_v1_0.OFPAT_SET_DL_DST:
            buf = 'SET_DL_DST:' + haddr_to_str(a.dl_addr)
        elif action_type == ofproto_v1_0.OFPAT_SET_NW_SRC:
            buf = 'SET_NW_SRC:' + \
                  socket.inet_ntoa(struct.pack('!I', a.nw_addr))
        elif action_type == ofproto_v1_0.OFPAT_SET_NW_DST:
            buf = 'SET_NW_DST:' + \
                  socket.inet_ntoa(struct.pack('!I', a.nw_addr))
        elif action_type == ofproto_v1_0.OFPAT_SET_NW_TOS:
            buf = 'SET_NW_TOS:' + str(a.tos)
        elif action_type == ofproto_v1_0.OFPAT_SET_TP_SRC:
            buf = 'SET_TP_SRC:' + str(a.tp)
        elif action_type == ofproto_v1_0.OFPAT_SET_TP_DST:
            buf = 'SET_TP_DST:' + str(a.tp)
        elif action_type == ofproto_v1_0.OFPAT_ENQUEUE:
            port = UTIL.ofp_port_to_user(a.port)
            queue = UTIL.ofp_queue_to_user(a.queue_id)
            buf = 'ENQUEUE:' + str(port) + ":" + str(queue)
        elif action_type == ofproto_v1_0.OFPAT_VENDOR:
            buf = 'VENDOR'
        else:
            buf = 'UNKNOWN'
        actions.append(buf)

    return actions
    def add_mac(self, mac, nw_id, nw_id_external=None):
        _nw_id = self.mac_to_net.get(mac)
        if _nw_id == nw_id:
            return

        # allow changing from nw_id_external to known nw id
        if _nw_id is None or _nw_id == nw_id_external:
            self.mac_to_net[mac] = nw_id
            LOG.debug('overwrite nw_id: mac %s nw old %s new %s',
                      haddr_to_str(mac), _nw_id, nw_id)
            return

        if nw_id == nw_id_external:
            # this can happens when the packet traverses
            # VM-> tap-> ovs-> ext-port-> wire-> ext-port-> ovs-> tap-> VM
            return

        LOG.warning('duplicated nw_id: mac %s nw old %s new %s',
                    haddr_to_str(mac), _nw_id, nw_id)

        raise MacAddressDuplicated(mac=mac)
Beispiel #41
0
    def packetInHandler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto

        dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        dpid = datapath.id
        self.mac2port.dpid_add(dpid)
        LOG.info("packet in %s %s %s %s", dpid, haddr_to_str(src),
                 haddr_to_str(dst), msg.in_port)

        self.mac2port.port_add(dpid, msg.in_port, src)
        out_port = self.mac2port.port_get(dpid, dst)

        if out_port == None:
            LOG.info("out_port not found")
            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        if out_port != ofproto.OFPP_FLOOD:
            wildcards = ofproto.OFPFW_ALL
            wildcards &= ~(ofproto.OFPFW_IN_PORT | ofproto.OFPFW_DL_DST
                           | ofproto.OFPFW_NW_TOS)
            match = datapath.ofproto_parser.OFPMatch(
                wildcards, msg.in_port, haddr_to_bin('00:00:00:00:00:00'), dst,
                0, 0, 0, 0, 0, 0, 0, 0, 0)

            datapath.send_flow_mod(match=match,
                                   cookie=0,
                                   command=ofproto.OFPFC_ADD,
                                   idle_timeout=0,
                                   hard_timeout=0,
                                   priority=32768,
                                   flags=ofproto.OFPFF_SEND_FLOW_REM,
                                   actions=actions)

        datapath.send_packet_out(msg.buffer_id, msg.in_port, actions)
Beispiel #42
0
    def port_add(self, dpid, port, mac):
        """
        :returns: old port if learned. (this may be = port)
                  None otherwise
        """
        old_port = self.mac_to_port[dpid].get(mac, None)
        self.mac_to_port[dpid][mac] = port

        if old_port is not None and old_port != port:
            LOG.debug('port_add: 0x%016x 0x%04x %s', dpid, port,
                      haddr_to_str(mac))

        return old_port
Beispiel #43
0
def actions_to_str(acts):
    actions = []
    for a in acts:
        action_type = a.cls_action_type

        if action_type == ofproto_v1_0.OFPAT_OUTPUT:
            buf = 'OUTPUT:' + str(a.port)
        elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_VID:
            buf = 'SET_VLAN_VID:' + str(a.vlan_vid)
        elif action_type == ofproto_v1_0.OFPAT_SET_VLAN_PCP:
            buf = 'SET_VLAN_PCP:' + str(a.vlan_pcp)
        elif action_type == ofproto_v1_0.OFPAT_STRIP_VLAN:
            buf = 'STRIP_VLAN'
        elif action_type == ofproto_v1_0.OFPAT_SET_DL_SRC:
            buf = 'SET_DL_SRC:' + haddr_to_str(a.dl_addr)
        elif action_type == ofproto_v1_0.OFPAT_SET_DL_DST:
            buf = 'SET_DL_DST:' + haddr_to_str(a.dl_addr)
        else:
            buf = 'UNKNOWN'
        actions.append(buf)

    return actions
Beispiel #44
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto

        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        dpid = datapath.id
        self.mac2port.dpid_add(dpid)
        LOG.info("packet in %s %s %s %s", dpid, haddr_to_str(src),
                 haddr_to_str(dst), msg.in_port)

        self.mac2port.port_add(dpid, msg.in_port, src)
        out_port = self.mac2port.port_get(dpid, dst)

        if out_port == None:
            LOG.info("out_port not found")
            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        if out_port != ofproto.OFPP_FLOOD:
            rule = nx_match.ClsRule()
            rule.set_in_port(msg.in_port)
            rule.set_dl_dst(dst)
            rule.set_dl_type(nx_match.ETH_TYPE_IP)
            rule.set_nw_dscp(0)
            datapath.send_flow_mod(rule=rule,
                                   cookie=0,
                                   command=ofproto.OFPFC_ADD,
                                   idle_timeout=0,
                                   hard_timeout=0,
                                   priority=ofproto.OFP_DEFAULT_PRIORITY,
                                   flags=ofproto.OFPFF_SEND_FLOW_REM,
                                   actions=actions)

        datapath.send_packet_out(msg.buffer_id, msg.in_port, actions)
def _packet_in_handler(self, ev):

    pkt = packet.Packet(array.array('B', ev.msg.data))
    eth_pkt = pkt.get_protocol(ethernet.ethernet)
    arp_pkt = pkt.get_protocol(arp.arp)
    ip4_pkt = pkt.get_protocol(ipv4.ipv4)
    if arp_pkt:
        pak = arp_pkt
    elif ip4_pkt:
        pak = ip4_pkt
    else:
        pak = eth_pkt
    self.logger.info('  _packet_in_handler: src_mac -> %s' % eth_pkt.src)
    self.logger.info('  _packet_in_handler: dst_mac -> %s' % eth_pkt.dst)
    self.logger.info('  _packet_in_handler: %s' % pak)
    self.logger.info('  ------')
    src = eth_pkt.src  # Set up the src and dst variables so you can use them
    dst = eth_pkt.dst
    ## Mike Pennington's modifications end here


    msg = ev.msg
    datapath = msg.datapath
    ofproto = datapath.ofproto

    dpid = datapath.id
    self.mac_to_port.setdefault(dpid, {})

    # learn a mac address to avoid FLOOD next time.
    self.mac_to_port[dpid][src] = msg.in_port

    if dst in self.mac_to_port[dpid]:
        out_port = self.mac_to_port[dpid][dst]
    else:
        out_port = ofproto.OFPP_FLOOD

    actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

    # install a flow to avoid packet_in next time
    if out_port != ofproto.OFPP_FLOOD:
        self.add_flow(datapath, msg.in_port, dst, actions)

    out = datapath.ofproto_parser.OFPPacketOut(
        datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,
        actions=actions)
    datapath.send_msg(out)
    if (haddr_to_str(src) == "00:00:00:00:00:01"):
        print "src"
                self.counterTraffic +=1
Beispiel #46
0
    def packet_in_handler(self, ev):
        print("[DEDALO] Nuevo paquete\n")
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto

        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.debug("packet in %s %s %s %s",
                          dpid, haddr_to_str(src), haddr_to_str(dst),
                          msg.in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = msg.in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        print("[DEDALO] Paquete entrante en " + str(dpid) + " con MAC destino " + haddr_to_str(dst) + " sale por el puerto " + str(out_port))

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            self.add_flow(datapath, msg.in_port, dst, actions)

        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,
            actions=actions)
        datapath.send_msg(out)
        print("[DEDALO] Tabla CAM: " + str(self.mac_to_port))
Beispiel #47
0
    def block_out_sample_in(self, stats):
        ofproto = datapath.ofproto
        #SRC BLOCK FLOW
        src_mac = stats.match.dl_dst
        if not src_mac == self.gateway_mac:
            src_match = datapath.ofproto_parser.OFPMatch(
                dl_src=src_mac, dl_dst=self.gateway_mac)

            src_flow = datapath.ofproto_parser.OFPFlowMod(
                datapath=datapath,
                match=src_match,
                cookie=random_int(),
                command=ofproto.OFPFC_ADD,
                idle_timeout=0,
                hard_timeout=2,
                priority=0x6000,
                flags=ofproto.OFPFF_SEND_FLOW_REM)
            datapath.send_msg(src_flow)

        eventlet.sleep(0.1)

        # DST BLOCK FLOW - We only sample this flow for 1 second,
        # Destination does not receive anything.
        dst_mac = stats.match.dl_dst
        if not dst_mac == self.gateway_mac:
            dst_match = datapath.ofproto_parser.OFPMatch(
                dl_src=self.gateway_mac, dl_dst=dst_mac)

            dst_actions = [
                datapath.ofproto_parser.OFPActionOutput(monitor_port)
            ]

            dst_flow = datapath.ofproto_parser.OFPFlowMod(
                datapath=datapath,
                match=dst_match,
                cookie=random_int(),
                command=ofproto.OFPFC_ADD,
                idle_timeout=0,
                hard_timeout=1,
                priority=0x6000,
                flags=ofproto.OFPFF_SEND_FLOW_REM,
                actions=dst_actions)
            datapath.send_msg(dst_flow)

        #Notify parser of this source/destination being blocked from this point on.
        outgoing_block_mode_v1_dict[(haddr_to_str(src_mac))] = int(
            time.time() * 1000)
Beispiel #48
0
def match_to_str(ofmatch):
    keys = {ofproto_v1_3.OXM_OF_IN_PORT: 'in_port',
            ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src',
            ofproto_v1_3.OXM_OF_ETH_DST: 'dl_dst',
            ofproto_v1_3.OXM_OF_ETH_TYPE: 'dl_type',
            ofproto_v1_3.OXM_OF_VLAN_VID: 'dl_vlan',
            ofproto_v1_3.OXM_OF_IPV4_SRC: 'nw_src',
            ofproto_v1_3.OXM_OF_IPV4_DST: 'nw_dst',
            ofproto_v1_3.OXM_OF_IPV4_SRC_W: 'nw_src',
            ofproto_v1_3.OXM_OF_IPV4_DST_W: 'nw_dst',
            ofproto_v1_3.OXM_OF_IP_PROTO: 'nw_proto',
            ofproto_v1_3.OXM_OF_TCP_SRC: 'tp_src',
            ofproto_v1_3.OXM_OF_TCP_DST: 'tp_dst',
            ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src',
            ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst',
            ofproto_v1_3.OXM_OF_MPLS_LABEL: 'mpls_label',
            ofproto_v1_3.OXM_OF_METADATA: 'metadata',
            ofproto_v1_3.OXM_OF_METADATA_W: 'metadata',
            ofproto_v1_3.OXM_OF_ARP_SPA: 'arp_spa',
            ofproto_v1_3.OXM_OF_ARP_TPA: 'arp_tpa',
            ofproto_v1_3.OXM_OF_ARP_SPA_W: 'arp_spa',
            ofproto_v1_3.OXM_OF_ARP_TPA_W: 'arp_tpa',
            ofproto_v1_3.OXM_OF_IPV6_SRC: 'ipv6_src',
            ofproto_v1_3.OXM_OF_IPV6_DST: 'ipv6_dst',
            ofproto_v1_3.OXM_OF_IPV6_SRC_W: 'ipv6_src',
            ofproto_v1_3.OXM_OF_IPV6_DST_W: 'ipv6_dst'}

    match = {}
    for match_field in ofmatch.fields:
        key = keys[match_field.header]
        if key == 'dl_src' or key == 'dl_dst':
            value = mac.haddr_to_str(match_field.value)
        elif key == 'nw_src' or key == 'nw_dst' or \
                key == 'arp_spa' or key == 'arp_tpa':
            value = match_ip_to_str(match_field.value, match_field.mask)
        elif key == 'ipv6_src' or key == 'ipv6_dst':
            value = match_ipv6_to_str(match_field.value, match_field.mask)
        elif key == 'metadata':
            value = ('%d/%d' % (match_field.value, match_field.mask)
                     if match_field.mask else '%d' % match_field.value)
        else:
            value = match_field.value
        match.setdefault(key, value)

    return match
Beispiel #49
0
    def to_del_openflow(of_match):
        mac_dontcare = mac.haddr_to_str(mac.DONTCARE)
        ip_dontcare = '0.0.0.0'

        match = {}
        for key, value in of_match.items():
            if key == REST_SRC_MAC or key == REST_DST_MAC:
                if value == mac_dontcare:
                    continue
            elif key == REST_SRC_IP or key == REST_DST_IP:
                if value == ip_dontcare:
                    continue
            elif value == 0:
                continue

            match.setdefault(key, value)

        return match
Beispiel #50
0
	def _upstream_collector(self, pkt):
		(version, msg_type, msg_len, xid) = ofproto_parser.header(pkt)

		# Switch configuration messages
		if msg_type == ofproto_v1_0.OFPT_FEATURES_REPLY:
			# print("Reply xid: " + hex(xid))
			msg = ofproto_v1_0_parser.OFPSwitchFeatures.parser(self.datapath, version, msg_type, msg_len, xid, pkt)
			match = ofproto_v1_0_parser.OFPMatch(dl_type=ETH_TYPE_LLDP, dl_dst=lldp.LLDP_MAC_NEAREST_BRIDGE)
			cookie = 0
			command = ofproto_v1_0.OFPFC_ADD
			idle_timeout = hard_timeout = 0
			priority = 0
			buffer_id = ofproto_v1_0.OFP_NO_BUFFER
			out_port = ofproto_v1_0.OFPP_NONE
			flags = 0
			actions = [ofproto_v1_0_parser.OFPActionOutput(ofproto_v1_0.OFPP_CONTROLLER)]
			mod = ofproto_v1_0_parser.OFPFlowMod(self.datapath, match, cookie, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, flags, actions)
			mod.serialize()

			self.id = msg.datapath_id
			self.ports = msg.ports

			# print(str(self.id) + " : Receive Features Reply Message")
			# print(msg)

			for port in self.ports.values():
				db_message = {"switch_id": hex(self.id),
							  "port_no": port.port_no,
							  "hw_addr": port.hw_addr,
							  "timestamp": datetime.datetime.utcnow()}

				try:
					self.db.switch_port.insert_one(db_message)
				except:
					if(self.id != None):
						print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database")
					else:
						print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database")

				pkt_lldp = packet.Packet()

				dst = BROADCAST_STR
				src = port.hw_addr
				ethertype = ETH_TYPE_LLDP
				eth_pkt = ethernet.ethernet(dst, src, ethertype)
				pkt_lldp.add_protocol(eth_pkt)

				tlv_chassis_id = lldp.ChassisID(
					subtype=lldp.ChassisID.SUB_LOCALLY_ASSIGNED,
					chassis_id='dpid:%s' % dpid_to_str(self.id))

				tlv_port_id = lldp.PortID(subtype=lldp.PortID.SUB_PORT_COMPONENT,
										  port_id=struct.pack('!I', port.port_no))

				tlv_ttl = lldp.TTL(ttl=120)
				tlv_desc = lldp.PortDescription(port_description="ProxyTopologyMonitorLLDP")
				tlv_end = lldp.End()

				tlvs = (tlv_chassis_id, tlv_port_id, tlv_ttl, tlv_desc, tlv_end)
				lldp_pkt = lldp.lldp(tlvs)
				pkt_lldp.add_protocol(lldp_pkt)

				pkt_lldp.serialize()

				actions = [ofproto_v1_0_parser.OFPActionOutput(port.port_no)]
				out = ofproto_v1_0_parser.OFPPacketOut(
					datapath=self.datapath, in_port=ofproto_v1_0.OFPP_CONTROLLER,
					buffer_id=ofproto_v1_0.OFP_NO_BUFFER, actions=actions,
					data=pkt_lldp.data)
				out.serialize()

				try:
					self.switch_socket.send(out.buf)
				except:
					if(self.id != None):
						print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Broken Pipe (Downstream : LLDP Message)")
					else:
						print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Broken Pipe (Downstream : LLDP Message)")
					# self._close()
					pass

		elif msg_type == ofproto_v1_0.OFPT_STATS_REPLY:
			msg = ofproto_v1_0_parser.OFPPortStatsReply.parser(self.datapath, version, msg_type, msg_len, xid, pkt)
			if(type(msg) is ofproto_v1_0_parser.OFPFlowStatsReply):
				# print(str(self.id) + " : Receive Flow Stats Message")
				# print(msg.body)

				for flow in msg.body:
					db_message = {"switch": hex(self.id),
								  "message": {
									  "header": {
										  "version": msg.version,
										  "type": msg.msg_type,
										  "length": msg.msg_len,
										  "xid": msg.xid
									  },
									  "match": {
										  "wildcards": flow.match.wildcards,
										  "in_port": flow.match.in_port,
										  "dl_src": mac.haddr_to_str(flow.match.dl_src),
										  "dl_dst": mac.haddr_to_str(flow.match.dl_dst),
										  "dl_vlan": flow.match.dl_vlan,
										  "dl_vlan_pcp": flow.match.dl_vlan_pcp,
										  "dl_type": flow.match.dl_type,
										  "nw_tos": flow.match.nw_tos,
										  "nw_proto": flow.match.nw_proto,
										  "nw_src": ip.ipv4_to_str(flow.match.nw_src),
										  "nw_dst": ip.ipv4_to_str(flow.match.nw_dst),
										  "tp_src": flow.match.tp_src,
										  "tp_dst": flow.match.tp_dst
									  },
									  "cookie": flow.cookie,
									  "idle_timeout": flow.idle_timeout,
									  "hard_timeout": flow.hard_timeout,
									  "priority": flow.priority,
									  "flags": msg.flags,
									  "actions": []
								  },
								  "timestamp": datetime.datetime.utcnow()}

					for action in flow.actions:
						db_message["message"]["actions"].append(vars(action));

					try:
						self.db.flow_stats.insert_one(db_message)
					except:
						if(self.id != None):
							print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database")
						else:
							print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database")
						pass

			if(type(msg) is ofproto_v1_0_parser.OFPPortStatsReply):
				# print(str(self.id) + " : Receive Port Stats Message")
				# print(msg.body)

				for port in msg.body:
					# print(port)
					db_message = {"switch": hex(self.id),
								  "port_no": port.port_no,
								  "rx_packets": port.rx_packets,
								  "tx_packets": port.tx_packets,
								  "rx_bytes": port.rx_bytes,
								  "tx_bytes": port.tx_bytes,
								  "rx_dropped": port.rx_dropped,
								  "tx_dropped": port.tx_dropped,
								  "rx_errors": port.rx_errors,
								  "tx_errors": port.tx_errors,
								  "rx_frame_err": port.rx_frame_err,
								  "rx_over_err": port.rx_over_err,
								  "rx_crc_err": port.rx_crc_err,
								  "collisions": port.collisions,
								  "timestamp": datetime.datetime.utcnow()}

					try:
						self.db.port_stats.insert_one(db_message)
					except:
						if(self.id != None):
							print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database")
						else:
							print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database")

				pass

		# Asynchronous messages
		elif msg_type == ofproto_v1_0.OFPT_PACKET_IN:
			msg = ofproto_v1_0_parser.OFPPacketIn.parser(self.datapath, version, msg_type, msg_len, xid, pkt)
			pkt_msg = packet.Packet(msg.data)

			if pkt_msg.get_protocol(ethernet.ethernet).ethertype == ETH_TYPE_LLDP:
				lldp_msg = pkt_msg.get_protocol(lldp.lldp)

				if lldp_msg != None:
					if lldp_msg.tlvs[3].tlv_info == "ProxyTopologyMonitorLLDP":

						(port,) = struct.unpack('!I', lldp_msg.tlvs[1].port_id)
						switch_src = str_to_dpid(lldp_msg.tlvs[0].chassis_id[5:])

						# print(str(self.id) + " : Receive Proxy LLDP Packet")
						# print(lldp_msg)

						# Write to database
						try:
							self.db.topology.insert_one({"switch_dst": hex(self.id),
													 	 "port_dst": port,
													 	 "switch_src": hex(switch_src),
													 	 "port_src": msg.in_port,
													 	 "timestamp": datetime.datetime.utcnow()})
						except:
							if(self.id != None):
								print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database")
							else:
								print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database")

						return

					elif lldp_msg.tlvs[3].tlv_info != "ProxyTopologyMonitorLLDP":
						# print(lldp_msg)
						# print("Controller LLDP packet")
						pass
Beispiel #51
0
	def _downstream_parse(self, pkt):
		try:
			self.switch_socket.send(pkt)
		except:
			if(self.id != None):
				print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Broken Pipe (Downstream)")
			else:
				print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Broken Pipe (Downstream)")
			# self._close()
			# pass

		(version, msg_type, msg_len, xid) = ofproto_parser.header(pkt)

		# Controller command messages
		if msg_type == ofproto_v1_0.OFPT_FLOW_MOD:
			msg = ofproto_v1_0_parser.OFPFlowMod.parser(self.datapath, version, msg_type, msg_len, xid, pkt)

			# print(str(self.id) + " : Receive Flow Mod Message")

			# Write to database
			db_message = {"switch": hex(self.id),
						  "message": {
							  "header": {
								  "version": version,
								  "type": msg_type,
								  "length": msg_len,
								  "xid": xid
							  },
							  "match": {
								  "wildcards": msg.match.wildcards,
								  "in_port": msg.match.in_port,
								  "dl_src": mac.haddr_to_str(msg.match.dl_src),
								  "dl_dst": mac.haddr_to_str(msg.match.dl_dst),
								  "dl_vlan": msg.match.dl_vlan,
								  "dl_vlan_pcp": msg.match.dl_vlan_pcp,
								  "dl_type": msg.match.dl_type,
								  "nw_tos": msg.match.nw_tos,
								  "nw_proto": msg.match.nw_proto,
								  "nw_src": ip.ipv4_to_str(msg.match.nw_src),
								  "nw_dst": ip.ipv4_to_str(msg.match.nw_dst),
								  "tp_src": msg.match.tp_src,
								  "tp_dst": msg.match.tp_dst
							  },
							  "cookie": msg.cookie,
							  "command": msg.command,
							  "idle_timeout": msg.idle_timeout,
							  "hard_timeout": msg.hard_timeout,
							  "priority": msg.priority,
							  "buffer_id": msg.buffer_id,
							  "out_port": msg.out_port,
							  "flags": msg.flags,
							  "actions": []
						  },
						  "timestamp": datetime.datetime.utcnow()}
			
			for action in msg.actions:
				db_message["message"]["actions"].append(vars(action))

			# print(db_message)

			try:
				self.db.flow_mods.insert_one(db_message)
				# if(self.id != None):
				# 	print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : [" + str(hex(self.id)) + "] --- Received FlowMod message")
				# else:
				# 	print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : [" + str(self.id) + "] --- Received FlowMod message")
			except:
				if(self.id != None):
					print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(hex(self.id)) + "] --- Failed to write data into database")
				else:
					print(datetime.datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S') + " : ERROR [" + str(self.id) + "] --- Failed to write data into database")
				pass
Beispiel #52
0
    def test_mac_haddr_to_str_assert(self):
        val = b'\xaa\xaa\xaa\xaa\xaa'

        res = mac.haddr_to_str(val)
Beispiel #53
0
    def packet_in_handler(self, ev):
        # LOG.debug('packet in ev %s msg %s', ev, ev.msg)
        msg = ev.msg
        datapath = msg.datapath

        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        try:
            port_nw_id = self.nw.get_network(datapath.id, msg.in_port)
        except PortUnknown:
            port_nw_id = NW_ID_UNKNOWN

        if port_nw_id != NW_ID_UNKNOWN:
            # Here it is assumed that the
            # (port <-> network id)/(mac <-> network id) relationship
            # is stable once the port is created. The port will be destroyed
            # before assigning new network id to the given port.
            # This is correct nova-network/nova-compute.
            try:
                # allow external -> known nw id change
                self.mac2net.add_mac(src, port_nw_id, NW_ID_EXTERNAL)
            except MacAddressDuplicated:
                LOG.warn(
                    'mac address %s is already in use.'
                    ' So (dpid %s, port %s) can not use it', haddr_to_str(src),
                    datapath.id, msg.in_port)
                #
                # should we install drop action pro-actively for future?
                #
                self._drop_packet(msg)
                return

        old_port = self.mac2port.port_add(datapath.id, msg.in_port, src)
        if old_port is not None and old_port != msg.in_port:
            # We really overwrite already learned mac address.
            # So discard already installed stale flow entry which conflicts
            # new port.
            rule = nx_match.ClsRule()
            rule.set_dl_dst(src)
            datapath.send_flow_mod(
                rule=rule,
                cookie=0,
                command=datapath.ofproto.OFPFC_DELETE,
                idle_timeout=0,
                hard_timeout=0,
                priority=datapath.ofproto.OFP_DEFAULT_PRIORITY,
                out_port=old_port)

            # to make sure the old flow entries are purged.
            datapath.send_barrier()

        src_nw_id = self.mac2net.get_network(src, NW_ID_UNKNOWN)
        dst_nw_id = self.mac2net.get_network(dst, NW_ID_UNKNOWN)

        # we handle multicast packet as same as broadcast
        broadcast = (dst == mac.BROADCAST) or mac.is_multicast(dst)
        out_port = self.mac2port.port_get(datapath.id, dst)

        #
        # there are several combinations:
        # in_port: known nw_id, external, unknown nw,
        # src mac: known nw_id, external, unknown nw,
        # dst mac: known nw_id, external, unknown nw, and broadcast/multicast
        # where known nw_id: is quantum network id
        #       external: means that these ports are connected to outside
        #       unknown nw: means that we don't know this port is bounded to
        #                   specific nw_id or external
        #       broadcast: the destination mac address is broadcast address
        #                  (or multicast address)
        #
        # Can the following logic be refined/shortened?
        #

        # When NW_ID_UNKNOWN is found, registering ports might be delayed.
        # So just drop only this packet and not install flow entry.
        # It is expected that when next packet arrives, the port is registers
        # with some network id

        if port_nw_id != NW_ID_EXTERNAL and port_nw_id != NW_ID_UNKNOWN:
            if broadcast:
                # flood to all ports of external or src_nw_id
                self._flood_to_nw_id(msg, src, dst, src_nw_id)
            elif src_nw_id == NW_ID_EXTERNAL:
                self._modflow_and_drop_packet(msg, src, dst)
                return
            elif src_nw_id == NW_ID_UNKNOWN:
                self._drop_packet(msg)
                return
            else:
                # src_nw_id != NW_ID_EXTERNAL and src_nw_id != NW_ID_UNKNOWN:
                #
                # try learned mac check if the port is net_id
                # or
                # flood to all ports of external or src_nw_id
                self._learned_mac_or_flood_to_nw_id(msg, src, dst, src_nw_id,
                                                    out_port)

        elif port_nw_id == NW_ID_EXTERNAL:
            if src_nw_id != NW_ID_EXTERNAL and src_nw_id != NW_ID_UNKNOWN:
                if broadcast:
                    # flood to all ports of external or src_nw_id
                    self._flood_to_nw_id(msg, src, dst, src_nw_id)
                elif (dst_nw_id != NW_ID_EXTERNAL
                      and dst_nw_id != NW_ID_UNKNOWN):
                    if src_nw_id == dst_nw_id:
                        # try learned mac
                        # check if the port is external or same net_id
                        # or
                        # flood to all ports of external or src_nw_id
                        self._learned_mac_or_flood_to_nw_id(
                            msg, src, dst, src_nw_id, out_port)
                    else:
                        # should not occur?
                        LOG.debug("should this case happen?")
                        self._drop_packet(msg)
                elif dst_nw_id == NW_ID_EXTERNAL:
                    # try learned mac
                    # or
                    # flood to all ports of external or src_nw_id
                    self._learned_mac_or_flood_to_nw_id(
                        msg, src, dst, src_nw_id, out_port)
                else:
                    assert dst_nw_id == NW_ID_UNKNOWN
                    LOG.debug("Unknown dst_nw_id")
                    self._drop_packet(msg)
            elif src_nw_id == NW_ID_EXTERNAL:
                self._modflow_and_drop_packet(msg, src, dst)
            else:
                # should not occur?
                assert src_nw_id == NW_ID_UNKNOWN
                self._drop_packet(msg)
        else:
            # drop packets
            assert port_nw_id == NW_ID_UNKNOWN
            self._drop_packet(msg)
Beispiel #54
0
 def haddr_to_str(self, addr):
     return mac.haddr_to_str(addr)
Beispiel #55
0
    def packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)

        match = msg.match.fields
        #for field in match:
        #logger.info("FIELDS==> %s ",field.value)

        logger.info("")
        logger.info("----------------------------------------")
        logger.info("*** PacketIn ***")
        logger.info("in_port=%d, eth_type: %s", in_port, hex(eth_type))
        logger.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id)
        logger.info("packet in datapath_id=%s src=%s dst=%s", msg.datapath.id,
                    haddr_to_str(src), haddr_to_str(dst))

        pkt = packet.Packet(msg.data)  # get data of packet
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        dst = eth.dst
        src = eth.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
            # verify if we have a valid buffer_id, if yes avoid to send both
            # flow_mod & packet_out
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                return
            else:
                self.add_flow(datapath, 1, match, actions)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=msg.buffer_id,
                                  in_port=in_port,
                                  actions=actions,
                                  data=data)
        datapath.send_msg(out)
Beispiel #56
0
 def __str__(self):
     return ('EventVMPort<dpid %s port_no %d '
             'network_id %s tunnel_key %s mac %s add_del %s>' %
             (dpid_lib.dpid_to_str(self.dpid), self.port_no,
              self.network_id, self.tunnel_key,
              mac.haddr_to_str(self.mac_address), self.add_del))
Beispiel #57
0
def match_to_str(ofmatch):
    keys = {ofproto_v1_3.OXM_OF_IN_PORT: 'in_port',
            ofproto_v1_3.OXM_OF_IN_PHY_PORT: 'in_phy_port',
            ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src',
            ofproto_v1_3.OXM_OF_ETH_DST: 'dl_dst',
            ofproto_v1_3.OXM_OF_ETH_TYPE: 'dl_type',
            ofproto_v1_3.OXM_OF_VLAN_VID: 'dl_vlan',
            ofproto_v1_3.OXM_OF_VLAN_PCP: 'vlan_pcp',
            ofproto_v1_3.OXM_OF_IP_DSCP: 'ip_dscp',
            ofproto_v1_3.OXM_OF_IP_ECN: 'ip_ecn',
            ofproto_v1_3.OXM_OF_IPV4_SRC: 'nw_src',
            ofproto_v1_3.OXM_OF_IPV4_DST: 'nw_dst',
            ofproto_v1_3.OXM_OF_IPV4_SRC_W: 'nw_src',
            ofproto_v1_3.OXM_OF_IPV4_DST_W: 'nw_dst',
            ofproto_v1_3.OXM_OF_IP_PROTO: 'nw_proto',
            ofproto_v1_3.OXM_OF_TCP_SRC: 'tp_src',
            ofproto_v1_3.OXM_OF_TCP_DST: 'tp_dst',
            ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src',
            ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst',
            ofproto_v1_3.OXM_OF_SCTP_SRC: 'sctp_src',
            ofproto_v1_3.OXM_OF_SCTP_DST: 'sctp_dst',
            ofproto_v1_3.OXM_OF_ICMPV4_TYPE: 'icmpv4_type',
            ofproto_v1_3.OXM_OF_ICMPV4_CODE: 'icmpv4_code',
            ofproto_v1_3.OXM_OF_MPLS_LABEL: 'mpls_label',
            ofproto_v1_3.OXM_OF_MPLS_TC: 'mpls_tc',
            ofproto_v1_3.OXM_OF_MPLS_BOS: 'mpls_bos',
            ofproto_v1_3.OXM_OF_METADATA: 'metadata',
            ofproto_v1_3.OXM_OF_METADATA_W: 'metadata',
            ofproto_v1_3.OXM_OF_STATE: 'state',
            ofproto_v1_3.OXM_OF_FLAGS: 'flags',
            ofproto_v1_3.OXM_OF_FLAGS_W: 'flags',
            ofproto_v1_3.OXM_OF_ARP_OP: 'arp_op',
            ofproto_v1_3.OXM_OF_ARP_SPA: 'arp_spa',
            ofproto_v1_3.OXM_OF_ARP_TPA: 'arp_tpa',
            ofproto_v1_3.OXM_OF_ARP_SPA_W: 'arp_spa',
            ofproto_v1_3.OXM_OF_ARP_TPA_W: 'arp_tpa',
            ofproto_v1_3.OXM_OF_ARP_SHA: 'arp_sha',
            ofproto_v1_3.OXM_OF_ARP_THA: 'arp_tha',
            ofproto_v1_3.OXM_OF_IPV6_SRC: 'ipv6_src',
            ofproto_v1_3.OXM_OF_IPV6_DST: 'ipv6_dst',
            ofproto_v1_3.OXM_OF_IPV6_SRC_W: 'ipv6_src',
            ofproto_v1_3.OXM_OF_IPV6_DST_W: 'ipv6_dst',
            ofproto_v1_3.OXM_OF_IPV6_FLABEL: 'ipv6_flabel',
            ofproto_v1_3.OXM_OF_ICMPV6_TYPE: 'icmpv6_type',
            ofproto_v1_3.OXM_OF_ICMPV6_CODE: 'icmpv6_code',
            ofproto_v1_3.OXM_OF_IPV6_ND_TARGET: 'ipv6_nd_target',
            ofproto_v1_3.OXM_OF_IPV6_ND_SLL: 'ipv6_nd_sll',
            ofproto_v1_3.OXM_OF_IPV6_ND_TLL: 'ipv6_nd_tll',
            ofproto_v1_3.OXM_OF_PBB_ISID: 'pbb_isid',
            ofproto_v1_3.OXM_OF_TUNNEL_ID: 'tunnel_id',
            ofproto_v1_3.OXM_OF_IPV6_EXTHDR: 'ipv6_exthdr'}

    match = {}
    for match_field in ofmatch.fields:
        key = keys[match_field.header]
        if key == 'dl_src' or key == 'dl_dst' or key == 'arp_sha' or \
                key == 'arp_tha' or key == 'ipv6_nd_tll' or \
                key == 'ipv6_nd_sll':
            value = mac.haddr_to_str(match_field.value)
        elif key == 'nw_src' or key == 'nw_dst' or \
                key == 'arp_spa' or key == 'arp_tpa':
            value = match_ip_to_str(match_field.value, match_field.mask)
        elif key == 'ipv6_src' or key == 'ipv6_dst':
            value = match_ipv6_to_str(match_field.value, match_field.mask)
        elif key == 'metadata':
            value = ('%d/%d' % (match_field.value, match_field.mask)
                     if match_field.mask else '%d' % match_field.value)
        else:
            value = match_field.value
        match.setdefault(key, value)

    return match
Beispiel #58
0
    def sample_first_block_later(self, stats):
        # DST flow with slightly higher priority
        ofproto = datapath.ofproto
        dst_mac = stats.match.dl_dst
        if not dst_mac == self.gateway_mac:
            dst_match = datapath.ofproto_parser.OFPMatch(
                dl_src=self.gateway_mac, dl_dst=dst_mac)

            dst_actions = stats.actions
            dst_actions.append(
                datapath.ofproto_parser.OFPActionOutput(monitor_port))

            dst_flow = datapath.ofproto_parser.OFPFlowMod(
                datapath=datapath,
                match=dst_match,
                cookie=random_int(),
                command=ofproto.OFPFC_ADD,
                idle_timeout=0,
                hard_timeout=2,
                priority=0x6001,
                flags=ofproto.OFPFF_SEND_FLOW_REM,
                actions=dst_actions)
            datapath.send_msg(dst_flow)

        outgoing_block_mode_v2_dict[(haddr_to_str(dst_mac))] = []
        # Time of installing first sample flow.
        outgoing_block_mode_v2_dict[(haddr_to_str(dst_mac))].append(
            int(time.time() * 1000))

        # Not sampling this flow for now. Could check relation between outgoing requests
        # and incoming responses if we sampled this.
        src_mac = stats.match.dl_dst
        if not src_mac == self.gateway_mac:
            src_match = datapath.ofproto_parser.OFPMatch(
                dl_src=src_mac, dl_dst=self.gateway_mac)

            src_actions = [
                datapath.ofproto_parser.OFPActionOutput(self.gateway_port)
            ]

            src_flow = datapath.ofproto_parser.OFPFlowMod(
                datapath=datapath,
                match=src_match,
                cookie=random_int(),
                command=ofproto.OFPFC_ADD,
                idle_timeout=0,
                hard_timeout=2,
                priority=0x6001,
                flags=ofproto.OFPFF_SEND_FLOW_REM,
                actions=src_actions)
            datapath.send_msg(src_flow)

        #SRC BLOCK FLOW
        src_mac = stats.match.dl_dst
        if not src_mac == self.gateway_mac:
            src_match = datapath.ofproto_parser.OFPMatch(
                dl_src=src_mac, dl_dst=self.gateway_mac)

            src_flow = datapath.ofproto_parser.OFPFlowMod(
                datapath=datapath,
                match=src_match,
                cookie=random_int(),
                command=ofproto.OFPFC_ADD,
                idle_timeout=0,
                hard_timeout=3,
                priority=0x6000,
                flags=ofproto.OFPFF_SEND_FLOW_REM)
            datapath.send_msg(src_flow)

        # Time of installing DROP flow. We do not want to count packets after this flow expired
        # (3 seconds from this moment on)
        outgoing_block_mode_v2_dict[(haddr_to_str(dst_mac))].append(
            int(time.time() * 1000))

        # DST BLOCK FLOW - We only sample this flow for 1 second,
        # destination does not receive anything.
        dst_mac = stats.match.dl_dst
        if not dst_mac == self.gateway_mac:
            dst_match = datapath.ofproto_parser.OFPMatch(
                dl_src=self.gateway_mac, dl_dst=dst_mac)

            dst_actions = [
                datapath.ofproto_parser.OFPActionOutput(monitor_port)
            ]

            dst_flow = datapath.ofproto_parser.OFPFlowMod(
                datapath=datapath,
                match=dst_match,
                cookie=random_int(),
                command=ofproto.OFPFC_ADD,
                idle_timeout=0,
                hard_timeout=3,
                priority=0x6000,
                flags=ofproto.OFPFF_SEND_FLOW_REM,
                actions=dst_actions)
            datapath.send_msg(dst_flow)