Esempio n. 1
0
    def _rcv_frame(self, frame):
        pkt = Ether(frame)
        self.log.info('received packet', pkt=pkt)
        if pkt.haslayer(Dot1Q):
            if pkt.haslayer(Dot1AD):
                outer_shim = pkt.getlayer(Dot1AD)
            else:
                outer_shim = pkt.getlayer(Dot1Q)

            if pkt.haslayer(IP) or outer_shim.type == EAP_ETH_TYPE:
                # We don't have any context about the packet at this point.
                # Assume that only downstream traffic is double-tagged.
                if isinstance(outer_shim.payload, Dot1Q):
                    logical_port = int(self.nni_port.port_no)
                else:
                    cvid = outer_shim.vlan
                    logical_port = self.get_subscriber_uni_port(cvid)
                popped_frame = (
                        Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) /
                        outer_shim.payload
                )
                kw = dict(
                    logical_device_id=self.logical_device_id,
                    logical_port_no=logical_port,
                )
                self.log.info('sending-packet-in', **kw)
                self.adapter_agent.send_packet_in(
                    packet=str(popped_frame), **kw)

            elif pkt.haslayer(Raw):
                raw_data = json.loads(pkt.getlayer(Raw).load)
                self.alarms.send_alarm(self, raw_data)
def main(p4info_file_path, bmv2_file_path):

    p4info_helper = p4runtime_lib.helper.P4InfoHelper(p4info_file_path)

    pk = PortKnocking()
    pk.load()

    switches_conf = load_switches_conf()
    firewall_rules = load_firewall_rules()
    forward_rules = load_forward_rules()
    pk_packet_in_rules = load_pk_packet_in_rules()

    try:

        switches = connect_to_switches(switches_conf["switches"])

        send_master_arbitration_updates(switches)

        set_pipelines(switches, p4info_helper, bmv2_file_path)

        install_direct_forwarding_rules(p4info_helper, switches)

        install_firewall_rules(p4info_helper, switches, switches_conf["switches"], firewall_rules["switches"])

        install_port_knock_in_rules(p4info_helper, switches, switches_conf["switches"], pk_packet_in_rules["switches"])

        install_forwarding_rules(p4info_helper, switches, switches_conf["switches"], forward_rules["switches"])

        switch_2 = switches[1]
        while True:
            packet_in = switch_2.PacketIn()
            print("Recibido paquete: "+str(packet_in))
            if packet_in.WhichOneof('update') == 'packet':
                pkt = Ether(_pkt=packet_in.packet.payload)

                src_ip = pkt.getlayer(IP).src
                dst_ip = pkt.getlayer(IP).dst
                tcp_dPort = pkt.getlayer(TCP).dport
                print("SRC IP: " + str(src_ip))
                print("DST IP: " + str(dst_ip))
                print("TCP DPORT: " + str(tcp_dPort))

                if pkt.getlayer(TCP):
                    pk.check(src_ip, dst_ip, tcp_dPort)

                if pk.has_authed(src_ip, dst_ip):
                    install_allowance_rules(p4info_helper, switch_2, src_ip, dst_ip, pk.config["hidden_services"][dst_ip])


    except KeyboardInterrupt:
        print(" Shutting down.")
    except grpc.RpcError as e:
        printGrpcError(e)

    ShutdownAllSwitchConnections()
Esempio n. 3
0
    def on_pkt_rx(self, pkt, start_ts):
        scapy_pkt = Ether(pkt['binary'])

        if scapy_pkt.haslayer('ICMPv6EchoReply'):
            node_ip = scapy_pkt.getlayer(IPv6).src
            hlim = scapy_pkt.getlayer(IPv6).hlim
            dst_ip = scapy_pkt.getlayer(IPv6).dst
            if dst_ip != self.src_ip: # not our ping
                return

            dt = pkt['ts'] - start_ts
            self.result['formatted_string'] = 'Reply from {0}: bytes={1}, time={2:.2f}ms, hlim={3}'.format(node_ip, len(pkt['binary']), dt * 1000, hlim)
            self.result['src_ip'] = node_ip
            self.result['rtt'] = dt * 1000
            self.result['ttl'] = hlim
            self.result['status'] = 'success'
            return self.port.ok(self.result)

        if scapy_pkt.haslayer('ICMPv6ND_NS') and scapy_pkt.haslayer('ICMPv6NDOptSrcLLAddr'):
            node_mac = scapy_pkt.getlayer(ICMPv6NDOptSrcLLAddr).lladdr
            node_ip = scapy_pkt.getlayer(IPv6).src
            dst_ip = scapy_pkt.getlayer(IPv6).dst
            if dst_ip != self.src_ip: # not our ping
                return
            self.send_intermediate(self.generate_ns_na(node_mac, node_ip))

        if scapy_pkt.haslayer('ICMPv6DestUnreach'):
            node_ip = scapy_pkt.getlayer(IPv6).src
            dst_ip = scapy_pkt.getlayer(IPv6).dst
            if dst_ip != self.src_ip: # not our ping
                return
            self.result['formatted_string'] = 'Reply from {0}: Destination host unreachable'.format(node_ip)
            self.result['status'] = 'unreachable'
            return self.port.ok(self.result)
Esempio n. 4
0
    def packet_out(self, egress_port, msg):
        pkt = Ether(msg)
        self.log.debug('packet out',
                       egress_port=egress_port,
                       device_id=self.device_id,
                       logical_device_id=self.logical_device_id,
                       packet=str(pkt).encode("HEX"))

        # Find port type
        egress_port_type = self.platform.intf_id_to_port_type_name(egress_port)
        if egress_port_type == Port.ETHERNET_UNI:

            if pkt.haslayer(Dot1Q):
                outer_shim = pkt.getlayer(Dot1Q)
                if isinstance(outer_shim.payload, Dot1Q):
                    # If double tag, remove the outer tag
                    payload = (
                        Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) /
                        outer_shim.payload)
                else:
                    payload = pkt
            else:
                payload = pkt

            send_pkt = binascii.unhexlify(str(payload).encode("HEX"))

            self.log.debug(
                'sending-packet-to-ONU',
                egress_port=egress_port,
                intf_id=self.platform.intf_id_from_uni_port_num(egress_port),
                onu_id=self.platform.onu_id_from_port_num(egress_port),
                uni_id=self.platform.uni_id_from_port_num(egress_port),
                port_no=egress_port,
                packet=str(payload).encode("HEX"))

            onu_pkt = openolt_pb2.OnuPacket(
                intf_id=self.platform.intf_id_from_uni_port_num(egress_port),
                onu_id=self.platform.onu_id_from_port_num(egress_port),
                port_no=egress_port,
                pkt=send_pkt)

            self.stub.OnuPacketOut(onu_pkt)

        elif egress_port_type == Port.ETHERNET_NNI:
            self.log.debug('sending-packet-to-uplink',
                           egress_port=egress_port,
                           packet=str(pkt).encode("HEX"))

            send_pkt = binascii.unhexlify(str(pkt).encode("HEX"))

            uplink_pkt = openolt_pb2.UplinkPacket(
                intf_id=self.platform.intf_id_from_nni_port_num(egress_port),
                pkt=send_pkt)

            self.stub.UplinkPacketOut(uplink_pkt)

        else:
            self.log.warn('Packet-out-to-this-interface-type-not-implemented',
                          egress_port=egress_port,
                          port_type=egress_port_type)
Esempio n. 5
0
    def packet_out(self, egress_port, msg):
        pkt = Ether(msg)
        self.log.info('packet out', egress_port=egress_port,
                packet=str(pkt).encode("HEX"))

        if pkt.haslayer(Dot1Q):
            outer_shim = pkt.getlayer(Dot1Q)
            if isinstance(outer_shim.payload, Dot1Q):
                payload = (
                    Ether(src=pkt.src, dst=pkt.dst, type=outer_shim.type) /
                    outer_shim.payload
                )
            else:
                payload = pkt
        else:
            payload = pkt

        self.log.info('sending-packet-to-device', egress_port=egress_port,
                packet=str(payload).encode("HEX"))

        send_pkt = binascii.unhexlify(str(payload).encode("HEX"))

        onu_pkt = openolt_pb2.OnuPacket(intf_id=intf_id_from_port_num(egress_port),
                onu_id=onu_id_from_port_num(egress_port), pkt=send_pkt)

        self.stub.OnuPacketOut(onu_packet)
Esempio n. 6
0
    def process_actions(flow, frame):
        egress_port = None
        for action in get_actions(flow):

            if action.type == OUTPUT:
                egress_port = action.output.port

            elif action.type == POP_VLAN:
                if frame.haslayer(Dot1Q):
                    shim = frame.getlayer(Dot1Q)
                    frame = Ether(
                        src=frame.src,
                        dst=frame.dst,
                        type=shim.type) / shim.payload

            elif action.type == PUSH_VLAN:
                frame = (
                    Ether(src=frame.src, dst=frame.dst,
                          type=action.push.ethertype) /
                    Dot1Q(type=frame.type) /
                    frame.payload
                )

            elif action.type == SET_FIELD:
                assert (action.set_field.field.oxm_class ==
                        ofp.OFPXMC_OPENFLOW_BASIC)
                field = action.set_field.field.ofb_field

                if field.type == VLAN_VID:
                    shim = frame.getlayer(Dot1Q)
                    shim.vlan = field.vlan_vid & 4095

                elif field.type == VLAN_PCP:
                    shim = frame.getlayer(Dot1Q)
                    shim.prio = field.vlan_pcp

                else:
                    raise NotImplementedError('set_field.field.type=%d'
                                              % field.type)

            else:
                raise NotImplementedError('action.type=%d' % action.type)

        return egress_port, frame
def main(p4info_file_path, bmv2_file_path):
    # Instantiate a P4Runtime helper from the p4info file

    ip2id_l = {}
    id_manager = IdManager(2**16 - 1)

    p4info_helper = p4runtime_lib.helper.P4InfoHelper(p4info_file_path)

    switches_conf = load_switches_conf()
    pr_rules = load_pr_rules()
    sdnc_pi_rules = load_sdnc_pkt_in_rules()
    fwd_rules = load_fwd_rules()
    pk_rules = load_pk_rules()

    try:

        switches = connect_to_switches(switches_conf["switches"])

        send_master_arbitration_updates(switches)

        set_pipelines(switches, p4info_helper, bmv2_file_path)

        install_direct_forwarding_rules(p4info_helper, switches)

        install_rules_protected_services(p4info_helper, switches,
                                         switches_conf, pr_rules["switches"])

        install_port_knock_in_rules(p4info_helper, switches, switches_conf,
                                    sdnc_pi_rules["switches"])

        install_forwarding_rules(p4info_helper, switches, switches_conf,
                                 fwd_rules["switches"])

        switch_2 = switches[1]
        while True:
            packet_in = switch_2.PacketIn()
            if packet_in.WhichOneof('update') == 'packet':
                pkt = Ether(_pkt=packet_in.packet.payload)

                src_ip = pkt.getlayer(IP).src
                print("SRC IP: " + str(src_ip))

                new_id = id_manager.get_id()
                print("New ID: " + str(new_id))
                ip2id_l[str(src_ip)] = new_id

                install_pip2id_rules(p4info_helper, switches, src_ip, new_id)
                install_pk_rules(p4info_helper, switches, switches_conf,
                                 pk_rules["switches"])

    except KeyboardInterrupt:
        print(" Shutting down.")
    except grpc.RpcError as e:
        printGrpcError(e)

    ShutdownAllSwitchConnections()
Esempio n. 8
0
    def packet_out(self, egress_port, msg):
        self.log.debug('sending-packet-out', egress_port=egress_port,
                       msg_hex=hexify(msg))
        pkt = Ether(msg)
        out_pkt = pkt
        self.log.debug("packet_out: incoming: %s" % pkt.summary())
        if egress_port != self.nni_port.port_no:
            # don't do the vlan manipulation for the NNI port, vlans are already correct
            if pkt.haslayer(Dot1Q):
                if pkt.haslayer(Dot1AD):
                    outer_shim = pkt.getlayer(Dot1AD)
                else:
                    outer_shim = pkt.getlayer(Dot1Q)
                if isinstance(outer_shim.payload, Dot1Q):
                    # If double tag, remove the outer tag
                    out_pkt = (
                            Ether(src=pkt.src, dst=pkt.dst,
                                  type=outer_shim.type) /
                            outer_shim.payload
                    )
                else:
                    out_pkt = pkt
            else:
                # Add egress port as VLAN tag
                out_pkt = (
                    Ether(src=pkt.src, dst=pkt.dst) /
                    Dot1Q(vlan=egress_port, type=pkt.type) /
                    pkt.payload
                )
        self.log.debug("packet_out: outgoing: %s" % out_pkt.summary())

        # TODO need better way of mapping logical ports to PON ports
        out_port = self.nni_port.port_no if egress_port == self.nni_port.port_no else 1

        if self.ponsim_comm == 'grpc':
            # send over grpc stream
            stub = ponsim_pb2_grpc.PonSimStub(self.get_channel())
            frame = PonSimFrame(id=self.device_id, payload=str(out_pkt), out_port=out_port)
            stub.SendFrame(frame)
        else:
            # send over frameio
            self.io_port.send(str(out_pkt))
Esempio n. 9
0
    def _rcv_frame(self, frame):
        pkt = Ether(frame)

        if pkt.haslayer(Dot1Q):
            outer_shim = pkt.getlayer(Dot1Q)

            if isinstance(outer_shim.payload, Dot1Q):
                inner_shim = outer_shim.payload
                cvid = inner_shim.vlan
                popped_frame = (
                    Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) /
                    inner_shim.payload)
                self.log.info('sending-packet-in',
                              device_id=self.device_id,
                              port=cvid)
                yield self.core_proxy.send_packet_in(device_id=self.device_id,
                                                     port=cvid,
                                                     packet=str(popped_frame))
            elif pkt.haslayer(Raw):
                raw_data = json.loads(pkt.getlayer(Raw).load)
                self.alarms.send_alarm(self, raw_data)
Esempio n. 10
0
    def on_pkt_rx(self, pkt, start_ts):
        # convert to scapy
        scapy_pkt = Ether(pkt['binary'])

        if scapy_pkt.haslayer('ICMPv6ND_NS') and scapy_pkt.haslayer('ICMPv6NDOptSrcLLAddr'):
            node_mac = scapy_pkt.getlayer(ICMPv6NDOptSrcLLAddr).lladdr
            node_ip = scapy_pkt.getlayer(IPv6).src
            if node_ip not in self.responses:
                self.send_intermediate(self.generate_ns_na(node_mac, node_ip))

        elif scapy_pkt.haslayer('ICMPv6ND_NA'):
            is_router = scapy_pkt.getlayer(ICMPv6ND_NA).R
            node_ip = scapy_pkt.getlayer(ICMPv6ND_NA).tgt
            dst_ip  = scapy_pkt.getlayer(IPv6).dst
            node_mac = scapy_pkt.src
            if node_ip not in self.responses and dst_ip == self.src_ip:
                self.responses[node_ip] = {'type': 'Router' if is_router else 'Host', 'mac': node_mac}

        elif scapy_pkt.haslayer('ICMPv6EchoReply'):
            node_mac = scapy_pkt.src
            node_ip = scapy_pkt.getlayer(IPv6).src
            if node_ip == self.dst_ip and node_ip != 'ff02::1': # for ping ipv6
                return self.port.ok([{'type': 'N/A', 'ipv6': node_ip, 'mac': node_mac}])
            if node_ip not in self.responses:
                self.send_intermediate(self.generate_ns_na(node_mac, node_ip))
Esempio n. 11
0
    def _rcv_frame(self, frame):
        pkt = Ether(frame)

        if pkt.haslayer(Dot1Q):
            outer_shim = pkt.getlayer(Dot1Q)

            if isinstance(outer_shim.payload, Dot1Q):
                inner_shim = outer_shim.payload
                cvid = inner_shim.vlan
                logical_port = cvid
                popped_frame = (
                    Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) /
                    inner_shim.payload)
                kw = dict(
                    logical_device_id=self.logical_device_id,
                    logical_port_no=logical_port,
                )
                self.log.info('sending-packet-in', **kw)
                self.adapter_agent.send_packet_in(packet=str(popped_frame),
                                                  **kw)
            elif pkt.haslayer(Raw):
                raw_data = json.loads(pkt.getlayer(Raw).load)
                self.alarms.send_alarm(self, raw_data)
Esempio n. 12
0
    def run(self):
        """
        Infinite loop that receives from the host's interface, 
        checks if the message is a control message or a normal packet 
        and treats it accordingly.
        Calls the general control packet handler if the message was a control message.
        Filters the received traffic for packet belonging to an active handover.
        :return: 
        """
        try:
            while True:
                buf = self.sock.recv(1500)

                eth_type = struct.unpack_from('!H', buf, 12)[0]

                # logging.info(repr(pkt))
                if eth_type == CONTROL_MESSAGE_ETHER_TYPE:
                    pkt = Ether(buf)
                    # control message
                    # logging.info("CONTROL MESSAGE RECEIVED")
                    msg, length = HandoverMessage.parser(
                        bytearray(pkt.getlayer(Raw).load))
                    if msg.cmd == HandoverMessage.CMD_TRANSPORT_PKT:
                        # wrapped queued message from controller. queue it locally
                        self.queue_msg(self.handovers[msg.handover_id],
                                       msg.tlvs[0].payload, True)
                        # logging.info("queue from controller {}".format(self.port_id))
                    else:
                        self.control_msg_handler(self.port_id, msg)
                else:
                    matching_handover = False
                    with self.handovers_lock:
                        if self.handovers:
                            for id, handover in self.handovers.items():
                                if handover.matches_packet(self.port_id, buf):
                                    # this packet belongs to this handover. lets queue it
                                    # logging.info('found matching handover at {}'.format(['ingress', 'egress'][self.id]))
                                    self.queue_msg(handover, buf, False)
                                    matching_handover = True
                                    break

                    if not matching_handover:
                        self.send(buf)
        except:
            logging.error(traceback.format_exc())
Esempio n. 13
0
 def rcv_io(self, port, frame):
     self.log.info('received',
                   iface_name=port.iface_name,
                   frame_len=len(frame))
     pkt = Ether(frame)
     if pkt.haslayer(Dot1Q):
         outer_shim = pkt.getlayer(Dot1Q)
         if isinstance(outer_shim.payload, Dot1Q):
             inner_shim = outer_shim.payload
             cvid = inner_shim.vlan
             logical_port = cvid
             popped_frame = (
                 Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) /
                 inner_shim.payload)
             kw = dict(
                 logical_device_id=self.logical_device_id,
                 logical_port_no=logical_port,
             )
             self.log.info('sending-packet-in', **kw)
             self.adapter_agent.send_packet_in(packet=str(popped_frame),
                                               **kw)
Esempio n. 14
0
def process_pcap(pcap_file_name):
    func_name = "process_pcap - "
    print(func_name + "opening file:" + pcap_file_name)
    count = 0
    interesting_packet_count = 0

    for (
            pkt_data,
            pkt_metadata,
    ) in RawPcapReader(pcap_file_name):
        count += 1

        ether_pkt = Ether(pkt_data)
        '''
        if 'type' not in ether_pkt.fields:
            # LLC frames will have 'len' instead of 'type'.
            # We disregard those
            continue
        '''
        print(func_name + "packet[" + str(count) + "] content:\n")
        #print(ether_pkt.show())
        isis_common_header = "ISIS Common Header"

        for key, val in ether_pkt.fields.items():
            print(str(key) + ":" + str(val))

        if not ether_pkt.haslayer(isis_common_header):
            print(func_name + "packet[" + str(count) +
                  "] is NOT an ISIS packet, ignore it")
            continue

        isis_hello_pdu_type_num = 17
        isis_common_header_feilds = ether_pkt.getlayer(
            isis_common_header).fields
        for key, val in isis_common_header_feilds.items():
            print(str(key) + ":" + str(val))
            if val == isis_hello_pdu_type_num:
                print(func_name + "packet[" + str(count) +
                      "] is ISIS Hello PDU")
        '''
    def handle_packet_in(self, ind_info):
        self.log.info('Received Packet-In', ind_info=ind_info)

        pkt = Ether(ind_info['packet'])
        if pkt.haslayer(Dot1Q):
            outer_shim = pkt.getlayer(Dot1Q)
            if isinstance(outer_shim.payload, Dot1Q):
                inner_shim = outer_shim.payload
                cvid = inner_shim.vlan
                logical_port = cvid
                popped_frame = (
                    Ether(src=pkt.src, dst=pkt.dst, type=inner_shim.type) /
                    inner_shim.payload)
                kw = dict(
                    logical_device_id=self.logical_device_id,
                    logical_port_no=logical_port,
                )
                self.log.info('sending-packet-in', **kw)
                self.adapter_agent.send_packet_in(packet=str(popped_frame),
                                                  **kw)

        reactor.callLater(1, self.process_packet_in)
Esempio n. 16
0
def extract_one_packet(buf):
    """Extract one packet from the incoming buf buffer.

    Takes string as input and looks for first whole packet in it.
    If it finds one, it returns substring from the buf parameter.

    :param buf: String representation of incoming packet buffer.
    :type buf: str
    :returns: String representation of first packet in buf.
    :rtype: str
    """
    pkt_len = 0

    if len(buf) < 60:
        return None

    try:
        ether_type = Ether(buf[0:14]).type
    except AttributeError:
        raise RuntimeError(f"No EtherType in packet {buf!r}")

    if ether_type == ETH_P_IP:
        # 14 is Ethernet fame header size.
        # 4 bytes is just enough to look for length in ip header.
        # ip total length contains just the IP packet length so add the Ether
        #     header.
        pkt_len = Ether(buf[0:14 + 4]).len + 14
        if len(buf) < 60:
            return None
    elif ether_type == ETH_P_IPV6:
        if not Ether(buf[0:14 + 6]).haslayer(IPv6):
            raise RuntimeError(f"Invalid IPv6 packet {buf!r}")
        # ... to add to the above, 40 bytes is the length of IPV6 header.
        #   The ipv6.len only contains length of the payload and not the header
        pkt_len = Ether(buf)[u"IPv6"].plen + 14 + 40
        if len(buf) < 60:
            return None
    elif ether_type == ETH_P_ARP:
        pkt = Ether(buf[:20])
        if not pkt.haslayer(ARP):
            raise RuntimeError(u"Incomplete ARP packet")
        # len(eth) + arp(2 hw addr type + 2 proto addr type
        #                + 1b len + 1b len + 2b operation)

        pkt_len = 14 + 8
        pkt_len += 2 * pkt.getlayer(ARP).hwlen
        pkt_len += 2 * pkt.getlayer(ARP).plen

        del pkt
    elif ether_type == 32821:  # RARP (Reverse ARP)
        pkt = Ether(buf[:20])
        pkt.type = ETH_P_ARP  # Change to ARP so it works with scapy
        pkt = Ether(pkt)
        if not pkt.haslayer(ARP):
            pkt.show()
            raise RuntimeError(u"Incomplete RARP packet")

        # len(eth) + arp(2 hw addr type + 2 proto addr type
        #                + 1b len + 1b len + 2b operation)
        pkt_len = 14 + 8
        pkt_len += 2 * pkt.getlayer(ARP).hwlen
        pkt_len += 2 * pkt.getlayer(ARP).plen

        del pkt
    else:
        raise RuntimeError(f"Unknown protocol {ether_type}")

    if pkt_len < 60:
        pkt_len = 60

    if len(buf) < pkt_len:
        return None

    return buf[0:pkt_len]
Esempio n. 17
0
    def _rcv_io(self, port, frame):

        log.info('frame-received', frame=hexify(frame))

        # make into frame to extract source mac
        response = Ether(frame)

        if response.haslayer(Dot1Q):

            # All OAM responses from the OLT should have a TIBIT_MGMT_VLAN.
            # Responses from the ONUs should have a TIBIT_MGMT_VLAN followed by a ONU CTAG
            # All packet-in frames will have the TIBIT_PACKET_IN_VLAN.
            if response.getlayer(Dot1Q).type == 0x8100:

                if response.getlayer(Dot1Q).vlan == TIBIT_PACKET_IN_VLAN:

                    inner_tag_and_rest = response.payload.payload

                    if isinstance(inner_tag_and_rest, Dot1Q):

                        cvid = inner_tag_and_rest.vlan

                        frame = Ether(src=response.src,
                                      dst=response.dst,
                                      type=inner_tag_and_rest.type) /\
                                      inner_tag_and_rest.payload

                        _, logical_device_id = self.vlan_to_device_ids.get(cvid)
                        if logical_device_id is None:
                            log.error('invalid-cvid', cvid=cvid)
                        else:
                            self.adapter_agent.send_packet_in(
                                logical_device_id=logical_device_id,
                                logical_port_no=cvid,  # C-VID encodes port no
                                packet=str(frame))

                    else:
                        log.error('packet-in-single-tagged',
                                  frame=hexify(response))

                else:
                    ## Mgmt responses received from the ONU
                    ## Since the type of the first layer is 0x8100,
                    ## then the frame must have an inner tag layer
                    olt_mac = response.src
                    device_id = self.device_ids[olt_mac]
                    channel_id = response[Dot1Q:2].vlan
                    log.info('received_channel_id', channel_id=channel_id,
                             device_id=device_id)

                    proxy_address=Device.ProxyAddress(
                        device_id=device_id,
                        channel_id=channel_id
                        )
                    # pop dot1q header(s)
                    msg = response.payload.payload
                    self.adapter_agent.receive_proxied_message(proxy_address, msg)

            else:
                ## Mgmt responses received from the OLT
                ## enqueue incoming parsed frame to right device
                log.info('received-dot1q-not-8100')
                self.incoming_queues[response.src].put(response)
Esempio n. 18
0
def main(p4info_file_path, bmv2_file_path):
    # Instantiate a P4Runtime helper from the p4info file
    mac_to_port = defaultdict(dict)
    p4info_helper = helper.P4InfoHelper(p4info_file_path)

    try:
        # Create a switch connection object for s1 and s2;
        # this is backed by a P4Runtime gRPC connection.
        # Also, dump all P4Runtime messages sent to switch to given txt files.
        s1 = bmv2.Bmv2SwitchConnection(
            name='s0',
            address='127.0.0.1:50051',
            device_id=1)

        # Send master arbitration update message to establish this controller as
        # master (required by P4Runtime before performing any other write operation)
        s1.MasterArbitrationUpdate()

        # Install the P4 program on the switches
        s1.SetForwardingPipelineConfig(p4info=p4info_helper.p4info,
                                       bmv2_json_file_path=bmv2_file_path)
        print "Installed P4 Program using SetForwardingPipelineConfig on s1"

        # Write the rules that tunnel traffic from h1-h2 to s1
        # writeIpv4Rules(p4info_helper, sw_id=s1, dst_ip_addr="10.10.10.1", port = 1)
        # writeIpv4Rules(p4info_helper, sw_id=s1, dst_ip_addr="10.10.10.2", port = 2)
        # writeIpv4Rules(p4info_helper, sw_id=s1, dst_ip_addr="10.10.3.3", port = 3)
        # readTableRules(p4info_helper, s1)
        mc_group_entry = p4info_helper.buildMulticastGroupEntry(1, replicas=[
            {'egress_port': 1, 'instance': 1},
            {'egress_port': 2, 'instance': 2},
            {'egress_port': 3, 'instance': 3},
            {'egress_port': 4, 'instance': 4},
            {'egress_port': 5, 'instance': 5},
            {'egress_port': 64, 'instance': 64}

        ])
        s1.WritePREEntry(mc_group_entry)
        print "Installed mgrp on s1."
        writeBroadcastRules(p4info_helper, s1)
        readTableRules(p4info_helper, s1)

        lldp_thread = LLDP_Thread(s1)
        # lldp_thread.run()
        # lldp_thread.start()
        # counter = 0

        while True:
            packetin = s1.PacketIn()
            # counter += 1
            payload = packetin.packet.payload
            pkt = Ether(_pkt=payload[12:])
            # metadata = packetin.packet.metadata[0]
            # metadata_id = metadata.metadata_id
            # port = metadata.value
            # pkt_type = packetin.packet.metadata[1].value
            zeros = struct.unpack(">q", payload[:8])[0]
            port = struct.unpack(">H", payload[8:10])[0]
            type = struct.unpack(">H", payload[10:12])[0]

            if zeros == 0:
                pkt_eth_src = pkt.getlayer(Ether).src
                pkt_eth_dst = pkt.getlayer(Ether).dst
                ether_type = pkt.getlayer(Ether).type

                # self send lldp
                if type == 5:
                    pass
                elif type == 4:
                    pass
                else:
                    lldp_thread.run()
                    # if pkt_eth_src in mac_to_port[s1.name]:
                    #     writeIpv4Rules(p4info_helper,s1,pkt_eth_src,mac_to_port[s1.name][pkt_eth_src])

                    # if ether_type == 2048 or ether_type == 2054:
                    # writeIpv4Rules(p4info_helper, s1, pkt_eth_src, port)

                    mac_to_port[s1.name][pkt_eth_src] = port
                    if pkt_eth_dst not in mac_to_port[s1.name]:
                        writeFloodingRules(p4info_helper, s1, pkt_eth_src, pkt_eth_dst)
                    else:
                        writeIpv4Rules(p4info_helper, s1, pkt_eth_src, pkt_eth_dst, mac_to_port[s1.name][pkt_eth_dst])
                        writeIpv4Rules(p4info_helper, s1, pkt_eth_dst, pkt_eth_src, mac_to_port[s1.name][pkt_eth_src])
                    readTableRules(p4info_helper, s1)

                    packet_out = p4runtime_pb2.PacketOut()
                    packet_out.payload = payload[12:]
                    # def packet_Out(s1,packetout):
                    #     s1.PacketOut(packetout)
                    # thread.start_new_thread(packet_Out,(s1,packet_out))
                    # packet_out.metadata = metadata
                    s1.PacketOut(packet_out)
                    # if counter % 10 == 0:
            else:
                pass

    except KeyboardInterrupt:
        print " Shutting down."
    except grpc.RpcError as e:
        printGrpcError(e)

    ShutdownAllSwitchConnections()
Esempio n. 19
0
    def packet_out_process(self, topic, msg):

        def get_port_out(opo):
            for action in opo.actions:
                if action.type == OUTPUT:
                    return action.output.port

        pb = Parse(loads(msg), ofp.PacketOut(), ignore_unknown_fields=True)

        logical_device_id = pb.id
        ofp_packet_out = pb.packet_out

        self.log.debug("received packet-out form kafka",
                       logical_device_id=logical_device_id,
                       ofp_packet_out=ofp_packet_out)

        egress_port = get_port_out(ofp_packet_out)
        msg = ofp_packet_out.data

        self.log.debug('rcv-packet-out', logical_device_id=logical_device_id,
                       egress_port=egress_port,
                       # adapter_name=self.adapter_name,
                       data=hexify(msg))

        pkt = Ether(msg)
        self.log.debug('packet out', egress_port=egress_port,
                       packet=str(pkt).encode("HEX"))

        # Find port type
        egress_port_type = self.device.platform \
            .intf_id_to_port_type_name(egress_port)

        if egress_port_type == Port.ETHERNET_UNI:

            if pkt.haslayer(Dot1Q):
                outer_shim = pkt.getlayer(Dot1Q)
                if isinstance(outer_shim.payload, Dot1Q):
                    # If double tag, remove the outer tag
                    payload = (
                            Ether(src=pkt.src, dst=pkt.dst,
                                  type=outer_shim.type) /
                            outer_shim.payload
                    )
                else:
                    payload = pkt
            else:
                payload = pkt

            send_pkt = binascii.unhexlify(str(payload).encode("HEX"))

            self.log.debug(
                'sending-packet-to-ONU', egress_port=egress_port,
                intf_id=self.device.platform.intf_id_from_uni_port_num(
                    egress_port),
                onu_id=self.device.platform.onu_id_from_port_num(egress_port),
                uni_id=self.device.platform.uni_id_from_port_num(egress_port),
                port_no=egress_port,
                packet=str(payload).encode("HEX"))

            onu_pkt = openolt_pb2.OnuPacket(
                intf_id=self.device.platform.intf_id_from_uni_port_num(
                    egress_port),
                onu_id=self.device.platform.onu_id_from_port_num(egress_port),
                port_no=egress_port,
                pkt=send_pkt)

            self.device.stub.OnuPacketOut(onu_pkt)

        elif egress_port_type == Port.ETHERNET_NNI:
            self.log.debug('sending-packet-to-uplink', egress_port=egress_port,
                           packet=str(pkt).encode("HEX"))

            send_pkt = binascii.unhexlify(str(pkt).encode("HEX"))

            uplink_pkt = openolt_pb2.UplinkPacket(
                intf_id=self.device.platform.intf_id_from_nni_port_num(
                    egress_port),
                pkt=send_pkt)

            self.device.stub.UplinkPacketOut(uplink_pkt)

        else:
            self.log.warn('Packet-out-to-this-interface-type-not-implemented',
                          egress_port=egress_port,
                          port_type=egress_port_type)