def buildPacketOut(self, payload, metadata=None):
     packet_out = p4runtime_pb2.PacketOut()
     packet_out.payload = payload
     if metadata:
         packet_out.metadata.extend([
             self.get_metadata_pb(metadata_id, value)
             for metadata_id, value in metadata.iteritems()
         ])
     return packet_out
Exemple #2
0
    def verify_packet_out(self, pkt, out_port):
        port_hex = stringify(out_port, 2)
        packet_out = p4runtime_pb2.PacketOut()
        packet_out.payload = str(pkt)
        egress_physical_port = packet_out.metadata.add()
        egress_physical_port.metadata_id = 1
        egress_physical_port.value = port_hex

        self.send_packet_out(packet_out)
        testutils.verify_packet(self, pkt, out_port)
Exemple #3
0
 def build_packet_out(self, payload, metadata=None):
     packet_out = p4runtime_pb2.PacketOut()
     packet_out.payload = payload
     if not metadata:
         return packet_out
     for name, value in metadata.items():
         p4info_meta = self.get_packet_metadata("packet_out", name)
         meta = packet_out.metadata.add()
         meta.metadata_id = p4info_meta.id
         meta.value = encode(value, p4info_meta.bitwidth)
     return packet_out
Exemple #4
0
    def sendPacketOutRaw(self, pkt):

        sleep(self.controlPlaneDelay)
        #print "sending packetout to switch %s" % self.name
        packet_out_req = p4runtime_pb2.PacketOut()

        packet_out_req.payload = pkt
        req = p4runtime_pb2.StreamMessageRequest()
        req.packet.CopyFrom(packet_out_req)
        #print "sending packet %s to switch %s" % (req.packet.payload.encode('hex'), self.name)
        self.stream_out_q.put(req)
Exemple #5
0
 def sendPacketOutLabel(self, payload, flowID):
     sleep(self.controlPlaneDelay)
     #print "sending packetout to switch %s" % self.name
     flowIDbyte = ('%%0%dx' % (4 << 1) % flowID).decode('hex')[-4:]
     #flowIDbyte += bytearray(flowID)
     packet_out_req = p4runtime_pb2.PacketOut()
     packet_out_req.payload = bytes('\24\063') + bytes(flowIDbyte) + bytes(
         payload)
     req = p4runtime_pb2.StreamMessageRequest()
     req.packet.CopyFrom(packet_out_req)
     self.stream_out_q.put(req)
    def buildMetadataBasedPacketOut(self,  clabFlag,   linkID, bitmask, level_to_link_id_store_index , port = 255):
        '''

        port_num_t  egress_port;
        bit<7>      _pad;
        //Previous all fields are not necessary for CLB. TODO  at sometime we will trey to clean up them. But at this moment we are not focusing on that
        bit<8> clb_flags; //Here we will keep various falgs for CLB
        //--------bit-7--------|| If this bit is set then reet the counter
        //--------bit-6--------|| If this bit is set then this is a port delete packet
        //--------bit-5--------|| If this bit is set then this is a port insert packet
        //--------bit-4--------|| Other bits are ununsed at this moment
        //--------bit-3--------||
        //--------bit-2--------||
        //--------bit-1--------||
        //--------bit-0--------||


        bit<32> link_id;
        bit<32> bitmask; //Here we are keeping all 32 bit to avoid compile time configuration complexity. At apply blo0ck we will slice necesssary bits.
        bit<32> level_to_link_id_store_index;  //
        '''

        rawPktContent = (255).to_bytes(2,'big') # first 2 byte egressport and padding
        rawPktContent = rawPktContent + (clabFlag).to_bytes(1,'big')
        rawPktContent = rawPktContent + (linkID).to_bytes(4,'big')
        rawPktContent = rawPktContent + (bitmask).to_bytes(4,'big')
        rawPktContent = rawPktContent + (level_to_link_id_store_index).to_bytes(4,'big')

        packet_out_req = p4runtime_pb2.StreamMessageRequest()
        port_hex = port.to_bytes(length=2, byteorder="big")
        packet_out = p4runtime_pb2.PacketOut()
        egress_physical_port = packet_out.metadata.add()
        egress_physical_port.metadata_id = 1
        egress_physical_port.value = port_hex

        clb_flag_metadata_field = packet_out.metadata.add()
        clb_flag_metadata_field.metadata_id = 3
        clb_flag_metadata_field.value = (clabFlag).to_bytes(1,'big')

        linkID_metadata_field = packet_out.metadata.add()
        linkID_metadata_field.metadata_id = 4
        linkID_metadata_field.value = (linkID).to_bytes(4,'big')

        bitmask_metadata_field = packet_out.metadata.add()
        bitmask_metadata_field.metadata_id = 5
        bitmask_metadata_field.value = (bitmask).to_bytes(4,'big')

        level_to_link_id_store_index_metadata_field = packet_out.metadata.add()
        level_to_link_id_store_index_metadata_field.metadata_id = 6
        level_to_link_id_store_index_metadata_field.value = (level_to_link_id_store_index).to_bytes(4,'big')

        packet_out.payload = rawPktContent
        packet_out_req.packet.CopyFrom(packet_out)
        return packet_out_req
Exemple #7
0
    def send_packet_out(self, pkt, port):
        packet_out_req = p4runtime_pb2.StreamMessageRequest()

        port_hex = stringify(port, 2)
        packet_out = p4runtime_pb2.PacketOut()
        packet_out.payload = str(pkt)
        egress_physical_port = packet_out.metadata.add()
        egress_physical_port.metadata_id = 1
        egress_physical_port.value = port_hex

        packet_out_req.packet.CopyFrom(packet_out)
        self.stream_out_q.put(packet_out_req)
Exemple #8
0
    def runPacketOutTest(self, pkt):
        for port in [self.port1, self.port2]:
            port_hex = stringify(port, 2)
            packet_out = p4runtime_pb2.PacketOut()
            packet_out.payload = str(pkt)
            egress_physical_port = packet_out.metadata.add()
            egress_physical_port.metadata_id = 1
            egress_physical_port.value = port_hex

            self.send_packet_out(packet_out)
            testutils.verify_packet(self, pkt, port)
        testutils.verify_no_other_packets(self)
Exemple #9
0
def sendDiscpkt(s, port):
    pkt = dpkt.ethernet.Ethernet()
    pkt.src = '\377\377\377\377\377\377'
    pkt.dst = '\377\377\377\377\377\377'
    pkt.type = 0xffff
    pkt.data = '\000' + str(unichr(port)) + s.name
    packet_out_req = p4runtime_pb2.PacketOut()

    # send a disc packet to the destination
    packet_out_req.payload = bytes(pkt)
    req = p4runtime_pb2.StreamMessageRequest()
    req.packet.CopyFrom(packet_out_req)
    s.stream_out_q.put(req)
Exemple #10
0
    def send_packet_out(self, pkt, port, clnt):
        self.packetOutLock.acquire(blocking=True)
        packet_out_req = p4runtime_pb2.StreamMessageRequest()

        # port_hex = stringify(port, 2)
        port_hex = port.to_bytes(length=2, byteorder="big")
        packet_out = p4runtime_pb2.PacketOut()
        packet_out.payload = pkt.encode()
        egress_physical_port = packet_out.metadata.add()
        egress_physical_port.metadata_id = 1
        egress_physical_port.value = port_hex

        packet_out_req.packet.CopyFrom(packet_out)
        clnt.stream_out_q.put(packet_out_req)
        self.packetOutLock.release()
Exemple #11
0
 def run(self):
     for i in range(1, 6):
         packet_out = p4runtime_pb2.PacketOut()
         packet_out.payload = self.generate_lldp_packet(i)
         # del packet_out.metadata[:]
         # p4runtime_metadata1 = p4runtime_pb2.PacketMetadata()
         # p4runtime_metadata1.metadata_id = 1
         # p4runtime_metadata1.value = struct.pack(">H", i)
         # packet_out.metadata.append(p4runtime_metadata1)
         # p4runtime_metadata2 = p4runtime_pb2.PacketMetadata()
         # p4runtime_metadata2.metadata_id = 2
         # p4runtime_metadata2.value = struct.pack(">H", 5)
         # packet_out.metadata.append(p4runtime_metadata2)
         self.sw.PacketOut(packet_out)
         print 'receive'
 def build_packet_out(self, pkt, port, do_forwarding=False):
     packet_out = p4runtime_pb2.PacketOut()
     packet_out.payload = bytes(pkt)
     # egress_port
     port_md = packet_out.metadata.add()
     port_md.metadata_id = 1
     port_md.value = stringify(port, 2)
     # do_forwarding
     do_forwarding_md = packet_out.metadata.add()
     do_forwarding_md.metadata_id = 2
     do_forwarding_md.value = stringify(1 if do_forwarding else 0, 1)
     # pad
     pad_md = packet_out.metadata.add()
     pad_md.metadata_id = 3
     pad_md.value = stringify(0, 1)
     return packet_out
Exemple #13
0
 def encode_packet_out_metadata(self, pktout_dict):
     ret = p4runtime_pb2.PacketOut()
     ret.payload = pktout_dict['payload']
     pktout_info = self.controller_packet_metadata_dict_key_name(
         "packet_out")
     for k, v in pktout_dict['metadata'].items():
         md = ret.metadata.add()
         md.metadata_id = pktout_info[k]['id']
         # I am not sure, but it seems that perhaps some code after
         # this point expects the bytes array of the values of the
         # controller metadata fields to be the full width of the
         # field, not the abbreviated version that omits leading 0
         # bytes that most P4Runtime API messages expect.
         bitwidth = pktout_info[k]['bitwidth']
         bytewidth = (bitwidth + 7) // 8
         #logging.debug("dbg encode k=%s v=%s bitwidth=%s bytewidth=%s"
         #              "" % (k, v, bitwidth, bytewidth))
         md.value = stringify(v, bytewidth)
     return ret
    def buildMetadataBasedPacketOut(self,
                                    isDelete,
                                    rank,
                                    port,
                                    rankMinIndex,
                                    rankMaxIndex,
                                    newPortIndex,
                                    bitmask,
                                    packet_out_port=255):
        '''

        port_num_t  egress_port;
        bit<7>      _pad;
        //Previous all fields are not necessary for CLB. TODO  at sometime we will trey to clean up them. But at this moment we are not focusing on that
        bit<8> top_k_path_flags; //Here we will keep various falgs for CLB
        //--------bit-7--------|| If this bit is set then reet the counter
        //--------bit-6--------|| If this bit is set then this is a port delete packet
        //--------bit-5--------|| If this bit is set then this is a port insert packet
        //--------bit-4--------|| Other bits are ununsed at this moment
        //--------bit-3--------||
        //--------bit-2--------||
        //--------bit-1--------||
        //--------bit-0--------||

        bit<K> bitmask;
        bit<32> rank;
        bit<32> port;
        bit<32> rank_max_index;
        bit<32> rank_min_index;
        bit<32> new_port_index;
        '''
        # logger.info("for device "+self.p4dev.devName+"  Packet built for rank : "+str(rank)+" port :"+str(port)+" minindex : "+
        #             str(rankMinIndex)+" maxindex :"+str(rankMaxIndex)+" portIndex "+str(newPortIndex)+" Packet type "+(str(isDelete))+ " Bitmask "+str(bitmask))

        rawPktContent = (255).to_bytes(
            2, 'big')  # first 2 byte egressport and padding
        if (isDelete == True):
            rawPktContent = rawPktContent + (128).to_bytes(1, 'big')
            topKPathFalgs = 128
        else:
            rawPktContent = rawPktContent + (0).to_bytes(1, 'big')
            topKPathFalgs = 0
        # rawPktContent = rawPktContent + (linkID).to_bytes(4,'big')
        # rawPktContent = rawPktContent + (bitmask).to_bytes(4,'big')
        # rawPktContent = rawPktContent + (level_to_link_id_store_index).to_bytes(4,'big')

        packet_out_req = p4runtime_pb2.StreamMessageRequest()
        packet_out_port_hex = packet_out_port.to_bytes(length=2,
                                                       byteorder="big")
        packet_out = p4runtime_pb2.PacketOut()
        egress_physical_port = packet_out.metadata.add()
        egress_physical_port.metadata_id = 1
        egress_physical_port.value = packet_out_port_hex

        topKPathFalgs_metadata_field = packet_out.metadata.add()
        topKPathFalgs_metadata_field.metadata_id = 3
        topKPathFalgs_metadata_field.value = (topKPathFalgs).to_bytes(1, 'big')

        bitmask_metadata_field = packet_out.metadata.add()
        bitmask_metadata_field.metadata_id = 4
        bitmask_metadata_field.value = (bitmask).to_bytes(4, 'big')

        rank_metadata_field = packet_out.metadata.add()
        rank_metadata_field.metadata_id = 5
        rank_metadata_field.value = (rank).to_bytes(4, 'big')

        port_metadata_field = packet_out.metadata.add()
        port_metadata_field.metadata_id = 6
        port_metadata_field.value = (port).to_bytes(4, 'big')

        rankMaxIndex_metadata_field = packet_out.metadata.add()
        rankMaxIndex_metadata_field.metadata_id = 7
        rankMaxIndex_metadata_field.value = (rankMaxIndex).to_bytes(4, 'big')

        rankMinIndex_metadata_field = packet_out.metadata.add()
        rankMinIndex_metadata_field.metadata_id = 8
        rankMinIndex_metadata_field.value = (rankMinIndex).to_bytes(4, 'big')

        newPortIndex_metadata_field = packet_out.metadata.add()
        newPortIndex_metadata_field.metadata_id = 9
        newPortIndex_metadata_field.value = (newPortIndex).to_bytes(4, 'big')

        packet_out.payload = rawPktContent
        packet_out_req.packet.CopyFrom(packet_out)
        return packet_out_req
Exemple #15
0
    def sendPacketOutMigration(self, flowID, migProcessFlowID, migSubProtocol,
                               migSequenceID, migVNFID, migSessionID,
                               networkInfo):
        # allocate buffers:
        # buff_migSubProtocol = array('b', b' '*8)
        # buff_migSequenceID = array('b',b' '* 16)
        # buff_migVNFID = array('b',b' '* 8)
        # buff_migSrcSw = array('b',b' '*8)
        # buff_migDstsw = array('b',b' '*8)
        # buff_migStatus = array('b',b' '*8)
        # buff_migSessionID = array('b',b' '*8)
        sleep(self.controlPlaneDelay)

        buff_indicator = bitstring.BitArray(uint=int(0x3341), length=16)
        buff_migSubProtocol = bitstring.BitArray(uint=int(migSubProtocol),
                                                 length=8)
        buff_migSequenceID = bitstring.BitArray(uint=int(migSequenceID),
                                                length=16)
        buff_migVNFID = bitstring.BitArray(uint=int(migVNFID), length=8)
        buff_migSessionID = bitstring.BitArray(uint=int(migSessionID),
                                               length=8)
        buff_migProcessFlowID = bitstring.BitArray(uint=int(migProcessFlowID),
                                                   length=32)
        buff_flowID = bitstring.BitArray(
            uint=int(flowID), length=32)  # the flowid that is migrated
        header = buff_migSubProtocol + buff_migSequenceID + buff_migVNFID + buff_migSessionID

        if 'srcIP' in networkInfo and 'dstIP' in networkInfo and 'srcPort' in networkInfo and 'dstPort' in networkInfo and 'ipProtocol' in networkInfo:
            buff_migSrcIP = bitstring.BitArray(uint=int(
                struct.unpack("!I",
                              socket.inet_aton(networkInfo['srcIP']))[0]),
                                               length=32)
            buff_migDstIP = bitstring.BitArray(uint=int(
                struct.unpack("!I",
                              socket.inet_aton(networkInfo['dstIP']))[0]),
                                               length=32)
            buff_migSrcPort = bitstring.BitArray(uint=int(
                networkInfo['srcPort']),
                                                 length=16)
            buff_migDstPort = bitstring.BitArray(uint=int(
                networkInfo['dstPort']),
                                                 length=16)
            buff_migIPProtocol = bitstring.BitArray(uint=int(
                networkInfo['ipProtocol']),
                                                    length=8)

            netInfoHeader = buff_flowID + buff_migSrcIP + buff_migDstIP + buff_migSrcPort + buff_migDstPort + buff_migIPProtocol
            header = header + netInfoHeader
        # else:
        #     buff_ind = bitstring.BitArray(uint=int(0x1433), length=16)
        #     netInfoHeader = buff_ind + buff_flowID
        #     header = header + netInfoHeader

        #print "sending packetout to switch %s" % self.name
        packet_out_req = p4runtime_pb2.PacketOut()

        packet_out_req.payload = buff_indicator.tobytes(
        ) + buff_migProcessFlowID.tobytes() + header.tobytes()
        req = p4runtime_pb2.StreamMessageRequest()
        req.packet.CopyFrom(packet_out_req)
        #print "sending packet %s to switch %s" % (req.packet.payload.encode('hex'), self.name)
        self.stream_out_q.put(req)
Exemple #16
0
 def packet_out_msg(self,pl,meta):
     return p4runtime_pb2.PacketOut(payload=pl,metadata=meta)
    def get_stream_packet(self, type_, timeout=1):
        start = time.time()
        try:
            while True:
                remaining = timeout - (time.time() - start)
                if remaining < 0:
                    break
                msg = self.stream_in_q.get(timeout=remaining)
                if not msg.HasField(type_):
                    continue
                return msg
        except:  # timeout expired
            pass
        return None

    def send_packet_out(self, packet):
        packet_out_req = p4runtime_pb2.StreamMessageRequest()
        packet_out_req.packet.CopyFrom(packet)
        self.stream_out_q.put(packet_out_req)

if __name__ == '__main__':
    test = Test()
    test.set_up_stream()
    test.update_config()
    if args.loopback:
        packet_out = p4runtime_pb2.PacketOut()
        packet_out.payload = "\xab" * 100
        test.send_packet_out(packet_out)
        test.get_packet_in()
    test.tear_down_stream()
Exemple #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()