1111import argparse
1212import syslog
1313import traceback
14+ import ipaddress
1415
1516
1617ARP_CHUNK = binascii .unhexlify ('08060001080006040001' ) # defines a part of the packet for ARP Request
1718ARP_PAD = binascii .unhexlify ('00' * 18 )
1819
19- def generate_arp_entries (filename , all_available_macs ):
20+ def generate_neighbor_entries (filename , all_available_macs ):
2021 db = swsssdk .SonicV2Connector (host = '127.0.0.1' )
2122 db .connect (db .APPL_DB , False ) # Make one attempt only
2223
2324 arp_output = []
24- arp_entries = []
25+ neighbor_entries = []
2526 keys = db .keys (db .APPL_DB , 'NEIGH_TABLE:*' )
2627 keys = [] if keys is None else keys
2728 for key in keys :
2829 vlan_name = key .split (':' )[1 ]
29- ip_addr = key .split (':' )[2 ]
3030 entry = db .get_all (db .APPL_DB , key )
31- if (vlan_name , entry ['neigh' ].lower ()) not in all_available_macs :
31+ mac = entry ['neigh' ].lower ()
32+ if (vlan_name , mac ) not in all_available_macs :
3233 # FIXME: print me to log
3334 continue
3435 obj = {
3536 key : entry ,
3637 'OP' : 'SET'
3738 }
38- arp_entries .append ((vlan_name , entry ['neigh' ].lower (), ip_addr ))
3939 arp_output .append (obj )
4040
41+ ip_addr = key .split (':' )[2 ]
42+ if ipaddress .ip_interface (ip_addr ).ip .version != 4 :
43+ #This is ipv6 address
44+ ip_addr = key .replace (key .split (':' )[0 ] + ':' + key .split (':' )[1 ] + ':' , '' )
45+ neighbor_entries .append ((vlan_name , mac , ip_addr ))
46+ syslog .syslog (syslog .LOG_INFO , "Neighbor entry: [Vlan: %s, Mac: %s, Ip: %s]" % (vlan_name , mac , ip_addr ))
47+
4148 db .close (db .APPL_DB )
4249
4350 with open (filename , 'w' ) as fp :
4451 json .dump (arp_output , fp , indent = 2 , separators = (',' , ': ' ))
4552
46- return arp_entries
53+ return neighbor_entries
4754
4855def is_mac_unicast (mac ):
4956 first_octet = mac .split (':' )[0 ]
@@ -201,14 +208,19 @@ def send_arp(s, src_mac, src_ip, dst_mac_s, dst_ip_s):
201208
202209 return
203210
204- def garp_send (arp_entries , map_mac_ip_per_vlan ):
211+ def send_ndp (s , src_mac , src_ip , dst_mac_s , dst_ip_s ):
212+ #TODO: Implement send in neighbor solicitation format
213+
214+ return
215+
216+ def send_garp_nd (neighbor_entries , map_mac_ip_per_vlan ):
205217 ETH_P_ALL = 0x03
206218
207219 # generate source ip addresses for arp packets
208- src_ip_addrs = {vlan_name :get_iface_ip_addr (vlan_name ) for vlan_name ,_ ,_ in arp_entries }
220+ src_ip_addrs = {vlan_name :get_iface_ip_addr (vlan_name ) for vlan_name ,_ ,_ in neighbor_entries }
209221
210222 # generate source mac addresses for arp packets
211- src_ifs = {map_mac_ip_per_vlan [vlan_name ][dst_mac ] for vlan_name , dst_mac , _ in arp_entries }
223+ src_ifs = {map_mac_ip_per_vlan [vlan_name ][dst_mac ] for vlan_name , dst_mac , _ in neighbor_entries }
212224 src_mac_addrs = {src_if :get_iface_mac_addr (src_if ) for src_if in src_ifs }
213225
214226 # open raw sockets for all required interfaces
@@ -217,10 +229,13 @@ def garp_send(arp_entries, map_mac_ip_per_vlan):
217229 sockets [src_if ] = socket .socket (socket .AF_PACKET , socket .SOCK_RAW , socket .htons (ETH_P_ALL ))
218230 sockets [src_if ].bind ((src_if , 0 ))
219231
220- # send arp packets
221- for vlan_name , dst_mac , dst_ip in arp_entries :
232+ # send arp/ndp packets
233+ for vlan_name , dst_mac , dst_ip in neighbor_entries :
222234 src_if = map_mac_ip_per_vlan [vlan_name ][dst_mac ]
223- send_arp (sockets [src_if ], src_mac_addrs [src_if ], src_ip_addrs [vlan_name ], dst_mac , dst_ip )
235+ if ipaddress .ip_interface (dst_ip ).ip .version == 4 :
236+ send_arp (sockets [src_if ], src_mac_addrs [src_if ], src_ip_addrs [vlan_name ], dst_mac , dst_ip )
237+ else :
238+ send_ndp (sockets [src_if ], src_mac_addrs [src_if ], src_ip_addrs [vlan_name ], dst_mac , dst_ip )
224239
225240 # close the raw sockets
226241 for s in sockets .values ():
@@ -271,9 +286,9 @@ def main():
271286 print ("Target directory '%s' not found" % root_dir )
272287 return 3
273288 all_available_macs , map_mac_ip_per_vlan = generate_fdb_entries (root_dir + '/fdb.json' )
274- arp_entries = generate_arp_entries (root_dir + '/arp.json' , all_available_macs )
289+ neighbor_entries = generate_neighbor_entries (root_dir + '/arp.json' , all_available_macs )
275290 generate_default_route_entries (root_dir + '/default_routes.json' )
276- garp_send ( arp_entries , map_mac_ip_per_vlan )
291+ send_garp_nd ( neighbor_entries , map_mac_ip_per_vlan )
277292 return 0
278293
279294if __name__ == '__main__' :
0 commit comments