11
11
import argparse
12
12
import syslog
13
13
import traceback
14
+ import ipaddress
14
15
15
16
16
17
ARP_CHUNK = binascii .unhexlify ('08060001080006040001' ) # defines a part of the packet for ARP Request
17
18
ARP_PAD = binascii .unhexlify ('00' * 18 )
18
19
19
- def generate_arp_entries (filename , all_available_macs ):
20
+ def generate_neighbor_entries (filename , all_available_macs ):
20
21
db = swsssdk .SonicV2Connector (host = '127.0.0.1' )
21
22
db .connect (db .APPL_DB , False ) # Make one attempt only
22
23
23
24
arp_output = []
24
- arp_entries = []
25
+ neighbor_entries = []
25
26
keys = db .keys (db .APPL_DB , 'NEIGH_TABLE:*' )
26
27
keys = [] if keys is None else keys
27
28
for key in keys :
28
29
vlan_name = key .split (':' )[1 ]
29
- ip_addr = key .split (':' )[2 ]
30
30
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 :
32
33
# FIXME: print me to log
33
34
continue
34
35
obj = {
35
36
key : entry ,
36
37
'OP' : 'SET'
37
38
}
38
- arp_entries .append ((vlan_name , entry ['neigh' ].lower (), ip_addr ))
39
39
arp_output .append (obj )
40
40
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
+
41
48
db .close (db .APPL_DB )
42
49
43
50
with open (filename , 'w' ) as fp :
44
51
json .dump (arp_output , fp , indent = 2 , separators = (',' , ': ' ))
45
52
46
- return arp_entries
53
+ return neighbor_entries
47
54
48
55
def is_mac_unicast (mac ):
49
56
first_octet = mac .split (':' )[0 ]
@@ -201,14 +208,19 @@ def send_arp(s, src_mac, src_ip, dst_mac_s, dst_ip_s):
201
208
202
209
return
203
210
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 ):
205
217
ETH_P_ALL = 0x03
206
218
207
219
# 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 }
209
221
210
222
# 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 }
212
224
src_mac_addrs = {src_if :get_iface_mac_addr (src_if ) for src_if in src_ifs }
213
225
214
226
# open raw sockets for all required interfaces
@@ -217,10 +229,13 @@ def garp_send(arp_entries, map_mac_ip_per_vlan):
217
229
sockets [src_if ] = socket .socket (socket .AF_PACKET , socket .SOCK_RAW , socket .htons (ETH_P_ALL ))
218
230
sockets [src_if ].bind ((src_if , 0 ))
219
231
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 :
222
234
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 )
224
239
225
240
# close the raw sockets
226
241
for s in sockets .values ():
@@ -271,9 +286,9 @@ def main():
271
286
print ("Target directory '%s' not found" % root_dir )
272
287
return 3
273
288
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 )
275
290
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 )
277
292
return 0
278
293
279
294
if __name__ == '__main__' :
0 commit comments