From dd82ca142b1b50c4beb217a18304d48f105986fa Mon Sep 17 00:00:00 2001 From: gord_chen Date: Mon, 10 Aug 2026 17:06:01 +0800 Subject: [PATCH] [ZTP] Re-assert front panel port config after ZTP profile removal When ZTP completes, ztp-profile.sh remove deletes ZTP|mode from CONFIG_DB and then restarts interfaces-config. interfaces-config regenerates /etc/network/interfaces from interfaces.j2, whose ZTP in-band block is gated on ZTP['mode'] being defined. With that table gone the block is no longer rendered and the regenerated file contains no Ethernet stanza at all. interfaces-config.sh then runs "systemctl restart networking", which performs "ifdown -a" followed by "ifup -a". ifupdown2 tears down every front panel port it had adopted for ZTP in-band DHCP, and ifup -a does not bring them back because they are no longer listed. The netdev is left administratively down with its MTU reset to the kernel default of 1500, while CONFIG_DB, APPL_DB and the ASIC all continue to report the port as up. portmgrd only acts on CONFIG_DB events and keeps no desired state, so it never notices nor corrects the drift. The port stays down until something writes CONFIG_DB, which is why a manual config interface shutdown/startup recovers it. Anything running on the Linux netdev, LLDP and DHCP in particular, stops working on the affected port while "show interfaces status" keeps reporting up/up, since that command reads APPL_DB. Which ports are affected depends on which ones happened to be oper up when interfaces-config sampled APPL_DB with redis-dump, so the failure can look intermittent. Re-assert the front panel port configuration after the interfaces-config restart. Writing any field of CONFIG_DB PORT| back with its current value produces a keyspace event, and SubscriberStateTable delivers the entire hash to the consumer, so portmgrd re-applies both mtu and admin_status. The write is idempotent and does not flap a port that is already up. Measured on a 54 port platform: the loop issues 108 portmgrd re-applications, mtu and admin_status for each port, and completes in 1.8 seconds. interfaces-config.service and networking.service are both Type=oneshot and neither restart uses --no-block, so ifdown/ifup have completed by the time the loop runs. Signed-off-by: gord_chen --- src/usr/lib/ztp/ztp-profile.sh | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/usr/lib/ztp/ztp-profile.sh b/src/usr/lib/ztp/ztp-profile.sh index c447389..e4af2b0 100755 --- a/src/usr/lib/ztp/ztp-profile.sh +++ b/src/usr/lib/ztp/ztp-profile.sh @@ -290,6 +290,37 @@ if [ "$CMD" = "remove" ] ; then updateActivity "Restarting network configuration" # Restart interface configuration to stop DHCP systemctl restart interfaces-config + + # Re-assert front panel port configuration. + # + # interfaces-config regenerates /etc/network/interfaces from interfaces.j2. + # Now that ZTP|mode has been removed above, the ZTP in-band block of that + # template is no longer rendered, so the regenerated file contains no Ethernet + # stanza at all. The "systemctl restart networking" performed by + # interfaces-config.sh then runs "ifdown -a" followed by "ifup -a": ifupdown2 + # tears down every front panel port it had adopted for ZTP in-band DHCP, and + # "ifup -a" does not bring them back because they are no longer listed. The + # netdev is left administratively down with its MTU reset to the kernel default, + # while CONFIG_DB, APPL_DB and the ASIC all still report the port as up. + # + # portmgrd only acts on CONFIG_DB events and keeps no desired state, so it + # never notices nor corrects this drift. Writing any field of + # CONFIG_DB PORT| back with its current value produces a keyspace event, + # and SubscriberStateTable delivers the entire hash, so portmgrd re-applies both + # mtu and admin_status. This is idempotent: a port that is already up is not + # flapped. + # + # interfaces-config.service and networking.service are both Type=oneshot, and + # neither restart above uses --no-block, so ifdown/ifup have completed by the + # time this loop runs. + updateActivity "Re-asserting front panel port configuration" + for port_key in $(sonic-db-cli CONFIG_DB KEYS 'PORT|Ethernet*'); do + port_admin_status="$(sonic-db-cli CONFIG_DB HGET "${port_key}" admin_status)" + if [ -n "${port_admin_status}" ]; then + sonic-db-cli CONFIG_DB HSET "${port_key}" admin_status \ + "${port_admin_status}" > /dev/null + fi + done fi # Remove ZTP DHCP policy