From 07a78893a0c85c82e64e47bbe3bc5b06f664dabcd2b6bce699a4a4315479a35a Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Thu, 18 Sep 2025 11:15:58 +0300 Subject: [PATCH] netreconf --- netreconf | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100755 netreconf diff --git a/netreconf b/netreconf new file mode 100755 index 0000000..f10ae23 --- /dev/null +++ b/netreconf @@ -0,0 +1,70 @@ +#!/usr/bin/env tclsh +# Generate network reconfiguration commands, based on dsc's net/ +# configuration and current interfaces state. +# Copyright (C) 2025 Sergey Matveev +# +# That script calls dsc command, so do not forget proper $DSC_STASH value. +# It outputs ip-* commands to stdout, intending you to feed to the shell. + +proc list-addrs {iface} { + set addrs [list] + catch {exec ip addr list dev $iface} lines + foreach l [split $lines \n] { + if {[regexp {inet (\S+)} $l _ addr]} { + lappend addrs $addr + } + if {[regexp {inet6 (\S+)} $l _ addr] && [string range $addr 0 4] != "fe80:"} { + lappend addrs $addr + } + } + return $addrs +} + +# Get list of non-loopback system interfaces +set sysIfaces [list] +foreach l [split [exec ip link] \n] { + if {[regexp {^\d+: (\w+): } $l _ iface] && $iface != "lo"} { + lappend sysIfaces $iface + } +} + +set dscIfaces [split [exec dsc get net/*] \n] + +foreach iface $sysIfaces { + if {[lsearch -exact $dscIfaces $iface] == -1} { + # If interface is not mentioned in dsc, then disable it and remove + # all addresses, as they are still known to the system + puts "ip link set $iface down" + foreach addr [list-addrs $iface] { + puts "ip addr del $addr dev $iface" + } + } else { + set mtu [exec dsc get net/$iface/mtu] + puts "ip link set $iface mtu $mtu" + puts "ip link set $iface up" + } +} + +foreach iface $dscIfaces { + if {[lsearch -exact $sysIfaces $iface] == -1} { + # If dsc's interface is not present in the system, skip it + continue + } + set dscAddrs [list] + foreach addr [split [exec dsc get net/$iface/addr/*] \n] { + set prefixlen [exec dsc get net/$iface/addr/$addr/prefixlen] + lappend dscAddrs $addr/$prefixlen + } + foreach addr [list-addrs $iface] { + set idx [lsearch -exact $dscAddrs $addr] + if {$idx == -1} { + puts "ip addr del $addr dev $iface" + } else { + # Address is already present + set $dscAddrs [lreplace $dscAddrs $idx $idx] + } + } + foreach addr $dscAddrs { + puts "ip addr add $addr dev $iface" + } +} -- 2.51.0