Расширение топологии mininet для поддержки многоадресной рассылки - PullRequest
0 голосов
/ 08 мая 2019

У меня есть следующая топология mininet

   (r1)-----(r2)
   /          \
  (s1)      (s2)
  /   \       /\
(h1)(h2)   (h3) (h4) 

и контроллер открытого потока, подключенный к маршрутизаторам и коммутаторам.Приведенный ниже код предназначен для пересылки пакетов между локальными сетями и отправки ответов arp.Я хочу расширить эту топологию, чтобы она поддерживала многоадресную передачу.h1 и h3 относятся к многоадресной группе 239.0.0.1, а h2, h4 - к группе 239.0.0.2.Я хочу перенаправлять трафик только на необходимые порты и статически знать, какие порты задействованы в каждой многоадресной группе.Кто-нибудь может предложить какую-нибудь помощь?

#

Код выполняется каждый раз, когда я получаю событие пакета

    def _packet_in_handler(self, ev):
    msg = ev.msg
    datapath = msg.datapath
    dpid = datapath.id
    ofproto = datapath.ofproto

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

    dst = eth.dst
    src = eth.src

    self.mac_to_port.setdefault(dpid, {})

    self.logger.info("packet in %s %s %s %s \n", dpid, src, dst, msg.in_port)

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

    if dpid == 0x1A:  # left router
        if eth.ethertype == ether_types.ETH_TYPE_ARP:  # this packet is ARP packet
            arpPacket = pkt.get_protocol(arp.arp)

            if arpPacket.opcode == arp.ARP_REQUEST:

                self.logger.info("ARP Request received from Left Router")
                dest_ip = arpPacket.dst_ip
                src = arpPacket.src_mac
                source_ip = arpPacket.src_ip
                port = msg.in_port

                if dest_ip == LEFT_GW_IP1:
                    self.send_arp_reply(datapath, RIGHT_GW_MAC1, LEFT_GW_IP1, src, source_ip, port)
                else:
                    self.logger.info("Error")
                    return
            return

        elif eth.ethertype == ether_types.ETH_TYPE_IP:  # this packet is IP packet
            self.logger.info("IP packet received from left router!")
            ip_packet = pkt.get_protocol(ipv4.ipv4)
            source_ip = ip_packet.src
            dest_ip = ip_packet.dst

            # packets destined inside the left LAN
            if dest_ip == H1_IP or dest_ip == H2_IP:
                src = LEFT_GW_MAC1
                dst = BROADCAST
                dest_ip = LEFT_SUBNET_IP
                port = 2
                self.send_ip(datapath, src, source_ip, dst, dest_ip, port, msg)

            else:  # packets are destined to the right LAN
                dest_ip = RIGHT_SUBNET_IP
                src = LEFT_GW_MAC2
                dst = RIGHT_GW_MAC1
                port = 1
                self.send_ip(datapath, src, source_ip, dst, dest_ip, port, msg)

                return
        return
    if dpid == 0x1B:  # right router
        if eth.ethertype == ether_types.ETH_TYPE_ARP:  # this packet is ARP packet
            arpPacket = pkt.get_protocol(arp.arp)
            if arpPacket.opcode == arp.ARP_REQUEST:
                self.logger.info("ARP Request received from right router")
                dest_ip = arpPacket.dst_ip
                src = arpPacket.src_mac
                source_ip = arpPacket.src_ip
                port = msg.in_port

                if dest_ip == RIGHT_GW_IP2:
                    self.send_arp_reply(datapath, RIGHT_GW_MAC2, RIGHT_GW_IP2, src, source_ip, port)

                else:
                    self.logger.info("Error")
                    return

        elif eth.ethertype == ether_types.ETH_TYPE_IP:  # this packet is IP packet

            self.logger.info("IP packet received from right router!")
            ip_packet = pkt.get_protocol(ipv4.ipv4)
            port = msg.in_port
            source_ip = ip_packet.src
            dest_ip = ip_packet.dst
            src = eth.src

            # packets destined inside the right LAN
            if dest_ip == H3_IP or dest_ip == H4_IP:
                src = RIGHT_GW_MAC2
                dst = BROADCAST
                dest_ip = RIGHT_SUBNET_IP
                port = 2
                self.send_ip(datapath, src, source_ip, dst, dest_ip, port, msg)

            # packets that have to be forwarded to the left LAN
            else:   # dest_ip == H1_IP or dest_ip == H2_IP:
                dest_ip = LEFT_SUBNET_IP
                src = RIGHT_GW_MAC1
                dst = LEFT_GW_MAC2
                port = 1
                self.send_ip(datapath, src, source_ip, dst, dest_ip, port, msg)

            return
        return

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

    match = datapath.ofproto_parser.OFPMatch(
        in_port=msg.in_port, dl_dst=haddr_to_bin(dst))

    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, match, actions)

    data = None
    if msg.buffer_id == ofproto.OFP_NO_BUFFER:
        data = msg.data

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