Last active
January 28, 2021 07:09
-
-
Save pyther/188be6c60f180fbc98fa2e22799ef3bc to your computer and use it in GitHub Desktop.
Listens for networkd signals and deprecate the ip6 route on the interface when the interface gets reconfigured
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from functools import cache | |
import argparse | |
import dbus | |
import subprocess | |
import json | |
import dbus.mainloop.glib | |
from gi.repository import GLib as glib | |
IFACE = None | |
PREFIX = None | |
def ip_addr_show(dev): | |
cmd = ['ip', '-j', '-6', 'addr', 'show', 'dev', dev] | |
p = subprocess.run(cmd, capture_output=True, check=True) | |
stdout = p.stdout.decode('utf-8') | |
return json.loads(stdout) | |
def deprecate_address(dev, prefix): | |
addrs = [x for x in ip_addr_show(dev)[0]['addr_info'] | |
if x['local'].startswith(prefix)] | |
if not len(addrs): | |
print(f"address matching {prefix} on {dev} not found") | |
return | |
# Deprecate all matching Addresses | |
for addr in addrs: | |
if addr['preferred_life_time'] == 0: | |
return | |
local = str(addr['local']) | |
valid = str(addr['valid_life_time']) | |
cmd = ['ip', 'addr', 'change', local, 'dev', dev, 'valid_lft', valid, 'preferred_lft', '0'] | |
subprocess.run(cmd, capture_output=True, check=True) | |
print(f"{dev}: deprecated {local} valid_lft {valid} preferred_lft 0") | |
return | |
@cache | |
def get_ifindex(dev): | |
with open(f"/sys/class/net/{dev}/ifindex") as fd: | |
idx = fd.readline().strip() | |
return idx | |
def property_changed(typ, data, _, path): | |
if typ != 'org.freedesktop.network1.Link': | |
return | |
if not path.startswith('/org/freedesktop/network1/link/_'): | |
return | |
idx = path.replace('/org/freedesktop/network1/link/_', '').split('/')[0] | |
idx = chr(int(idx[:2], 16)) | |
try: | |
ifindex = get_ifindex(IFACE) | |
except IOError: | |
return | |
# Ignore changes for interfaces we don't care about | |
if idx != ifindex: | |
return | |
# When address lifetime is refreshed, the AdministrativeState property | |
# changes to 'configuring', then transitions to 'configured' | |
if data.get('AdministrativeState') != 'configured': | |
return | |
deprecate_address(IFACE, PREFIX) | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description='deprecate ip6 address') | |
parser.add_argument('-i', '--interface', required=True, | |
help='interface to deprecate address on') | |
parser.add_argument('-p', '--prefix', default='2001:506', | |
help='address prefix to match against') | |
args = parser.parse_args() | |
IFACE = args.interface | |
PREFIX = args.prefix | |
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) | |
bus = dbus.SystemBus() | |
bus.add_signal_receiver(property_changed, | |
bus_name='org.freedesktop.network1', | |
signal_name='PropertiesChanged', | |
path_keyword='path') | |
print("Monitoring org.freedesktop.network1") | |
mainloop = glib.MainLoop() | |
mainloop.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment