@@ -39,6 +39,38 @@ def enable_interfaces(file):
3939 # Return code of ifup is not reliable, so we do not check it nor log it
4040 logger .info ("Bringing up interface %s" , interface )
4141
42+ def send_gratuitous_arp (file ):
43+ # Get the mapping interface -> device
44+ proc = subprocess .run (["ubus" , "-v" , "call" , "network.interface" , "dump" ], capture_output = True , text = True )
45+ try :
46+ network_dump = json .loads (proc .stdout )
47+ except json .JSONDecodeError :
48+ logger .error ("Can't send gratuitous ARP: failed to decode JSON from network dump" )
49+ return
50+ device_map = {}
51+ for iface in network_dump .get ('interface' , []):
52+ if 'device' in iface and 'interface' in iface :
53+ device_map [iface ['interface' ]] = iface ['device' ]
54+ # Load the file with the interfaces to send gratuitous ARP for
55+ with open (os .path .join (out_dir , file ), 'r' ) as f :
56+ interfaces = json .load (f )
57+ for interface in interfaces :
58+ if 'ipaddr' in interfaces [interface ]:
59+ device = device_map .get (interface )
60+ if not device :
61+ logger .error ("Can't send gratuitous ARP: no device found for interface %s" , interface )
62+ continue
63+ # It should not happen, but ipaddr can contain multiple IPs
64+ ipaddr = interfaces [interface ]['ipaddr' ]
65+ if isinstance (ipaddr , str ):
66+ ipaddr = [ipaddr ]
67+ for ip in ipaddr :
68+ # Remove /mask if present
69+ ip = ip .split ('/' )[0 ]
70+ # Send gratuitous ARP to update switches ARP tables
71+ aproc = subprocess .run (["/usr/bin/arping" , "-c" , "1" , "-U" , "-I" , device , ip ], capture_output = True )
72+ logger .info ("Sending gratuitous ARP on interface %s (%s) for IP %s: %s" , interface , device , ip , "success" if aproc .returncode == 0 else "fail" )
73+
4274def enable_hotspot_mac ():
4375 u = EUci ()
4476 devices = utils .get_all_by_type (u , 'network' , 'device' )
@@ -60,4 +92,5 @@ if __name__ == "__main__":
6092 enable_interfaces ('wg_interfaces' )
6193 enable_interfaces ('ipsec_interfaces' )
6294 enable_hotspot_mac ()
95+ send_gratuitous_arp ('wan_interfaces' )
6396 subprocess .run (["/sbin/reload_config" ], capture_output = True )
0 commit comments