ffffff2003 2023-12-12 20:34 采纳率: 0%
浏览 10
已结题

mininet ryu manager 数据重定向实现

img


为什么每个if都跑进去了但没有实现重定向呢

img


原本的server add是10.0.1.2

<import logging

from ryu.base import app_manager

from ryu.controller import ofp_event

from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER

from ryu.controller.handler import set_ev_cls

from ryu.ofproto import ofproto_v1_3

from ryu.lib.packet import packet, ethernet, ipv4, tcp, ether_types, in_proto, arp

logging.basicConfig(level=logging.INFO)



class SimpleSwitch13(app_manager.RyuApp):

    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]



    def __init__(self, *args, **kwargs):

        super(SimpleSwitch13, self).__init__(*args, **kwargs)

        self.mac_to_port = {}



    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)

    def switch_features_handler(self, ev):

        datapath = ev.msg.datapath

        ofproto = datapath.ofproto

        parser = datapath.ofproto_parser



        # Install table-miss flow entry

        match = parser.OFPMatch()

        actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,

                                          ofproto.OFPCML_NO_BUFFER)]

        self.add_flow(datapath, 0, match, actions)



    def add_flow(self, datapath, priority, match, actions, buffer_id=None):

        ofproto = datapath.ofproto

        parser = datapath.ofproto_parser



        inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,

                                             actions)]

        if buffer_id:

            mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, priority=priority, idle_timeout=5,  match=match, instructions=inst)

        else:

            mod = parser.OFPFlowMod(datapath=datapath, priority=priority,

                                    match=match, instructions=inst)

        datapath.send_msg(mod)



    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)

    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']



        pkt = packet.Packet(msg.data)

        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:

            logging.info("Received")

            match = parser.OFPMatch(in_port=in_port, eth_dst=dst)



            # Check if it is a TCP packet

            if eth.ethertype == ether_types.ETH_TYPE_IP:

                logging.info("Received IPv4 packet")

                ip = pkt.get_protocol(ipv4.ipv4)

                if ip.proto == in_proto.IPPROTO_TCP:

                    logging.info("Received TCP packet")

                    tcp_pkt = pkt.get_protocol(tcp.tcp)



                    # Check if it is a TCP SYN segment

                    if tcp_pkt.bits & tcp.TCP_SYN !=0:

                        logging.info("Handling TCP SYN segment")

                        new_dst_ip = '10.0.1.3'

                        new_dst_mac = '00:00:00:00:00:02'

                        # Create and install a new flow entry

                        actions = [parser.OFPActionSetField(ipv4_dst=new_dst_ip),  parser.OFPActionSetField(eth_dst=new_dst_mac),  parser.OFPActionOutput(out_port)]

                        self.add_flow(datapath, 1, match, actions)



                        # Send out Packet_Out SDN packet with the TCP SYN segment

                        out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,

                                                  in_port=in_port, actions=actions, data=msg.data)

                        datapath.send_msg(out)

                        

                        return

            # Otherwise, install a regular flow entry

            self.add_flow(datapath, 2, match, actions)



        data = None

        if msg.buffer_id == ofproto.OFP_NO_BUFFER:

            logging.info("111")

            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)>
mininet里面是一个sdn控制器和三个host通过s1连接,<client.setIP(ip='10.0.1.5/24', intf='client-eth0')

    server1.setIP(ip='10.0.1.2/24', intf='server1-eth0')

    server2.setIP(ip='10.0.1.3/24', intf='server2-eth0')



    client.setMAC(mac="00:00:00:00:00:03", intf='client-eth0')

    server1.setMAC(mac="00:00:00:00:00:01", intf='server1-eth0')

    server2.setMAC(mac="00:00:00:00:00:02", intf='server2-eth0')    

    >

    client.setIP(ip='10.0.1.5/24', intf='client-eth0')

    server1.setIP(ip='10.0.1.2/24', intf='server1-eth0')

    server2.setIP(ip='10.0.1.3/24', intf='server2-eth0')



    client.setMAC(mac="00:00:00:00:00:03", intf='client-eth0')

    server1.setMAC(mac="00:00:00:00:00:01", intf='server1-eth0')

    server2.setMAC(mac="00:00:00:00:00:02", intf='server2-eth0')    

    

  • 写回答

16条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2023-12-13 09:53
    关注
    获得0.60元问题酬金

    引自强大而免费的微信小程序:皆我百晓生

    实现数据重定向的关键是在控制器实现对数据包的流量处理和流表项的添加。在给定的代码中,控制器先通过学习源MAC地址发送到的端口,然后根据目标MAC地址决定发送到哪个端口。

    要实现重定向,需要在以下部分添加代码:

    1. 在控制器的packet_in_handler方法中,根据目标MAC地址判断是否需要重定向。
    2. 在需要重定向的情况下,修改目标IP地址和目标MAC地址,并将重定向动作添加到actions列表中。
    3. 添加新的流表项,将符合条件的目标MAC地址和目标IP地址进行重定向。

    根据您的要求,可以在以下部分添加重定向的代码:

    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:
        logging.info("Received")
        match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
    
        # Check if it is a TCP packet
        if eth.ethertype == ether_types.ETH_TYPE_IP:
            logging.info("Received IPv4 packet")
            ip = pkt.get_protocol(ipv4.ipv4)
            if ip.proto == in_proto.IPPROTO_TCP:
                logging.info("Received TCP packet")
                tcp_pkt = pkt.get_protocol(tcp.tcp)
    
                # Check if it is a TCP SYN segment
                if tcp_pkt.bits & tcp.TCP_SYN !=0:
                    logging.info("Handling TCP SYN segment")
                    new_dst_ip = '10.0.1.3'
                    new_dst_mac = '00:00:00:00:00:02'
                    # Create and install a new flow entry
                    actions = [parser.OFPActionSetField(ipv4_dst=new_dst_ip), parser.OFPActionSetField(eth_dst=new_dst_mac), parser.OFPActionOutput(out_port)]
                    self.add_flow(datapath, 1, match, actions)
                    # Send out Packet_Out SDN packet with the TCP SYN segment
                    out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
                                              in_port=in_port, actions=actions, data=msg.data)
                    datapath.send_msg(out)
                    return
        # Otherwise, install a regular flow entry
        self.add_flow(datapath, 2, match, actions)
    

    这段代码首先判断目标MAC地址是否在控制器已学习的地址表中,如果在地址表中,则直接发送到对应端口;如果不在地址表中,则进行数据包洪泛。如果目标MAC地址在地址表中,进一步判断是否是TCP包,并且是否是TCP SYN段。如果是TCP SYN段,将目标IP地址和目标MAC地址修改为重定向的地址,并安装一个新的流表项进行重定向。然后将重定向动作添加到actions列表中,并发送出Packet_Out消息。

    另外,在switch_features_handler方法中,已经设置了一个表项来处理TableMiss情况,这个表项会将所有未匹配的流量发送到控制器,可以根据需要对此进行修改。

    注意,要使上述重定向生效,需要保证Mininet网络连接到正确的控制器,并且控制器代码能够正常运行。另外,需要确保主机的IP和MAC地址与控制器中设置的一致。

    希望能对您的问题有所帮助!如果您还有任何疑问,请随时向我提问。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 12月21日
  • 修改了问题 12月13日
  • 赞助了问题酬金15元 12月13日
  • 创建了问题 12月12日

悬赏问题

  • ¥15 已知平面坐标系(非直角坐标系)内三个点的坐标,反求两坐标轴的夹角
  • ¥15 webots有问题,无响应
  • ¥15 数据量少可以用MK趋势分析吗
  • ¥15 使用VH6501干扰RTR位,CANoe上显示的错误帧不足32个就进入bus off快慢恢复,为什么?
  • ¥15 大智慧怎么编写一个选股程序
  • ¥100 python 调用 cgps 命令获取 实时位置信息
  • ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
  • ¥15 C语言使用vscode编码错误
  • ¥15 用KSV5转成本时,如何不生成那笔中间凭证
  • ¥20 ensp怎么配置让PC1和PC2通讯上