我具有以下小型网络拓扑
(r1)-----(r2)
/ \
(s1) (s2)
/ \ /\
(h1)(h2) (h3) (h4)
,以及连接到路由器和交换机的openflow控制器。 下面的代码应该在局域网之间转发数据包并发送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)