p4 cpu的交互

实验目的

控制交换机将包克隆到cpu,并接收和处理来自cpu的包

  1. 对于p4文件,需要处理来自cpu的包并且根据接收的端口号转发,如果不是来自cpu的包,将包发到cpu
  2. 对于拓扑文件,需要对交换机开启cpu接口
  3. 对于控制器,需要增加cpu_seesion,并且监听包的接收,然后解析包的结构并将数据发送回交换机

建立拓扑时,交换机的最后一个接口会与cpu相连
cpu接收封包发送封包的方法如下

import nnpy
import struct
from scapy.all import sniff, Packet, BitField, raw

from p4utils.utils.helper import load_topo
from p4utils.utils.sswitch_p4runtime_API import SimpleSwitchP4RuntimeAPI
from p4utils.utils.sswitch_thrift_API import SimpleSwitchThriftAPI
from scapy.layers.l2 import Ether
from scapy.sendrecv import sendp


class CpuInHeader(Packet):
    name = "cpu_in"
    fields_desc = [
        BitField("ingress_port", 0, 9),
        BitField("_pad", 0, 7)
    ]


class CpuOutHeader(Packet):
    name = "cpu_out"
    fields_desc = [
        BitField("egress_port", 0, 9),
        BitField("_pad", 0, 7)
    ]

class CpuController:

    def __init__(self, sw_name):
        self.topo = load_topo('topology.json')
        self.sw_name = sw_name
        self.cpu_port_intf = 0
        self.cpu_port = self.topo.get_cpu_port_index(self.sw_name)
        device_id = self.topo.get_p4switch_id(sw_name)
        grpc_port = self.topo.get_grpc_port(sw_name)
        sw_data = self.topo.get_p4rtswitches()[sw_name]
        self.controller = SimpleSwitchP4RuntimeAPI(device_id, grpc_port,
                                                   p4rt_path=sw_data['p4rt_path'],
                                                   json_path=sw_data['json_path'])
        self.init()

    def init(self):
        self.reset()

    def reset(self):
        self.controller.reset_state()
        thrift_port = self.topo.get_thrift_port(self.sw_name)
        controller_thrift = SimpleSwitchThriftAPI(thrift_port)
        controller_thrift.reset_state()

    def add_clone_session(self):
        if self.cpu_port:
            self.controller.cs_create(100, [self.cpu_port])

    def deal_pack(self, pack):
        ingress_port = pack.ingress_port
        if ingress_port == 1:
            egress_port = 2
        else:
            egress_port = 1
        send_pack = CpuOutHeader()
        send_pack.payload = pack.payload
        mac_pack = Ether(raw(send_pack.load))
#        mac_pack.show()
        send_pack.egress_port = egress_port
        send_pack._pad = 0
#        send_pack.show()
        return send_pack

    def send_msg_cpu(self, pack):

        sendp(pack, iface=self.cpu_port_intf, verbose=False)

    def recv_msg_cpu(self, pkt):
        pack = CpuInHeader(raw(pkt))
        #print("this is receive")
        #pack.show()
        pack = self.deal_pack(pack)
        #print("this is send")
        #pack.show()
        mac = Ether(raw(pack.payload))
        mac.show()
        #print('send a packet')
        #self.send_msg_cpu(pack)

    def run_cpu_port_loop(self):
        self.cpu_port_intf = str(self.topo.get_cpu_port_intf(self.sw_name).replace("eth0", "eth1"))
        sniff(iface = self.cpu_port_intf, prn = self.recv_msg_cpu)

if __name__ == "__main__":
    CpuController('s1').run_cpu_port_loop()
#bind_layers(Ether, MyTunnel, type=TYPE_MYTUNNEL)
#bind_layers(MyTunnel, IP, pid=TYPE_IPV4)

p4文件可以send_to_cpu 或者clone_to_cpu,

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值