def arp_for_router(self, dp, switch): # Learning the router port is really important, so we send an ARP packet to poke it into submission # Note that host .2 may not or may not be a real host, but the reply will always come back to the switch anyway. target_ip_net = self.nib.actual_net_for(switch) src_ip = NetUtils.ip_for_network(target_ip_net, 2) dst_ip = NetUtils.ip_for_network(target_ip_net, 1) # The IP of the router interface will always be a .1 OpenflowUtils.send_arp_request(dp, src_ip, dst_ip)
def packet_in(self, msg): # If we're not doing any IP rewriting, the ARP requests and replies should have been handled by the # the L2 switch. if not self.nib.ip_rewriting(): return cookie = msg.cookie # Ignore all packets that came here by other rules than the ARP rule if cookie != self.ARP_RULE: return dp = msg.datapath pkt = packet.Packet(msg.data) p_eth = pkt.get_protocols(ethernet.ethernet)[0] p_arp = pkt.get_protocols(arp.arp)[0] src_ip = p_arp.src_ip dst_ip = p_arp.dst_ip switch = self.nib.switch_for_dp(dp) in_port = msg.match['in_port'] # We only handle ARP requests for the virtual net here. All ARP replies and requests were # actually forwarded by l2_switch_handler, but no one will answer those for the virtual net. # We formulate ARP responses for those requests here. if p_arp.opcode == arp.ARP_REQUEST: # Translate virtual address to a real one real_dest_ip = self.nib.translate_ip( dst_ip, self.nib.actual_net_for(switch)) if real_dest_ip == None: pass elif self.nib.learned_ip(real_dest_ip): real_dest_mac = self.nib.mac_for_ip(real_dest_ip) OpenflowUtils.send_arp_reply(dp, in_port, p_eth.src, src_ip, real_dest_mac, dst_ip) else: # Send an ARP request to all ports, then just stay out of the way. If the host is up # on an unlearned port, it'll send a response, and that'll trigger learning. Then # when the NEXT ARP request for this address is received (it'll get retried a bunch of # times in practice), the reply can be generated from the ARP cache. # It doesn't matter so much where the ARP reply goes, because this switch will pick it up. switch_net = self.nib.actual_net_for(switch) src_ip = NetUtils.ip_for_network(switch_net, 2) OpenflowUtils.send_arp_request(dp, src_ip, real_dest_ip)
def packet_in(self, msg): # If we're not doing any IP rewriting, the ARP requests and replies should have been handled by the # the L2 switch. if not self.nib.ip_rewriting(): return cookie = msg.cookie # Ignore all packets that came here by other rules than the ARP rule if cookie != self.ARP_RULE: return dp = msg.datapath pkt = packet.Packet(msg.data) p_eth = pkt.get_protocols(ethernet.ethernet)[0] p_arp = pkt.get_protocols(arp.arp)[0] src_ip = p_arp.src_ip dst_ip = p_arp.dst_ip switch = self.nib.switch_for_dp(dp) in_port = msg.match["in_port"] # We only handle ARP requests for the virtual net here. All ARP replies and requests were # actually forwarded by l2_switch_handler, but no one will answer those for the virtual net. # We formulate ARP responses for those requests here. if p_arp.opcode == arp.ARP_REQUEST: # Translate virtual address to a real one real_dest_ip = self.nib.translate_ip(dst_ip, self.nib.actual_net_for(switch)) if real_dest_ip == None: pass elif self.nib.learned_ip(real_dest_ip): real_dest_mac = self.nib.mac_for_ip(real_dest_ip) OpenflowUtils.send_arp_reply(dp, in_port, p_eth.src, src_ip, real_dest_mac, dst_ip) else: # Send an ARP request to all ports, then just stay out of the way. If the host is up # on an unlearned port, it'll send a response, and that'll trigger learning. Then # when the NEXT ARP request for this address is received (it'll get retried a bunch of # times in practice), the reply can be generated from the ARP cache. # It doesn't matter so much where the ARP reply goes, because this switch will pick it up. switch_net = self.nib.actual_net_for(switch) src_ip = NetUtils.ip_for_network(switch_net, 2) OpenflowUtils.send_arp_request(dp, src_ip, real_dest_ip)