Skip to content

Commit 90c11d4

Browse files
author
Aritra Basu
committed
Add udev ID_NET_NAME_* property restoration for VPP interfaces
Capture ID_NET_NAME_* properties before VPP driver unbind and restore them via udev rules after VPP creates host-facing tap/tun interface. This is needed for IAID generation by DHCPv6 client in systemd-networkd to be consistent across VPP lifecycle on the node. Key changes: - Add new CAPTURE_HOST_UDEV_PROPS hook that runs before PreconfigureLinux() - Store ID_NET_NAME_* values and MAC address while interface still has original driver - Create udev rules for the interface to restore ID_NET_NAME_* values after VPP runs - Cleanup udev rules on VPP shutdown - CAPTURE_HOST_UDEV_PROPS → capture, VPP_DONE_OK/ERRORED → cleanup Signed-off-by: Aritra Basu <[email protected]>
1 parent 6e59606 commit 90c11d4

File tree

3 files changed

+119
-3
lines changed

3 files changed

+119
-3
lines changed

config/config.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ var (
123123
/* Run this before getLinuxConfig() in case this is a script
124124
* that's responsible for creating the interface */
125125
HookScriptBeforeIfRead = StringEnvVar("CALICOVPP_HOOK_BEFORE_IF_READ", DefaultHookScript) // InitScriptTemplate
126+
/* Bash script template run to capture host udev properties before driver unbind */
127+
HookScriptCaptureHostUdevProps = StringEnvVar("CALICOVPP_HOOK_CAPTURE_HOST_UDEV_PROPS", DefaultHookScript)
126128
/* Bash script template run just after getting config
127129
from $CALICOVPP_INTERFACE & before starting VPP */
128130
HookScriptBeforeVppRun = StringEnvVar("CALICOVPP_HOOK_BEFORE_VPP_RUN", DefaultHookScript) // InitPostIfScriptTemplate
@@ -135,6 +137,7 @@ var (
135137

136138
AllHooks = []*string{
137139
HookScriptBeforeIfRead,
140+
HookScriptCaptureHostUdevProps,
138141
HookScriptBeforeVppRun,
139142
HookScriptVppRunning,
140143
HookScriptVppDoneOk,
@@ -164,7 +167,7 @@ func RunHook(hookScript *string, hookName string, params *VppManagerParams, log
164167
return
165168
}
166169

167-
cmd := exec.Command("/bin/bash", "-c", template, hookName)
170+
cmd := exec.Command("/bin/bash", "-c", template, hookName, params.UplinksSpecs[0].InterfaceName)
168171
cmd.Stdout = os.Stdout
169172
cmd.Stderr = os.Stderr
170173
err = cmd.Run()

config/default_hook.sh

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
#!/bin/sh
22

33
HOOK="$0"
4-
chroot /host /bin/sh <<EOSCRIPT
4+
INTERFACE_NAME="$1"
5+
chroot /host /bin/sh -s "$HOOK" "$INTERFACE_NAME" <<'EOSCRIPT'
6+
HOOK="$1"
7+
INTERFACE_NAME="$2"
58
69
fix_dns () {
710
if systemctl status NetworkManager > /dev/null 2>&1; then
@@ -39,22 +42,129 @@ restart_network () {
3942
fi
4043
}
4144
45+
capture_udev_net_name_properties () {
46+
echo "default_hook: Capturing udev net name properties for $INTERFACE_NAME..."
47+
48+
UDEV_INFO=$(udevadm info /sys/class/net/$INTERFACE_NAME 2>/dev/null)
49+
if [ -z "$UDEV_INFO" ]; then
50+
echo "default_hook: Failed to get udevadm info for $INTERFACE_NAME"
51+
return
52+
fi
53+
54+
# Extract ID_NET_NAME_* properties
55+
ID_NET_NAME_ONBOARD=$(echo "$UDEV_INFO" | grep "ID_NET_NAME_ONBOARD=" | sed 's/.*ID_NET_NAME_ONBOARD=//')
56+
ID_NET_NAME_SLOT=$(echo "$UDEV_INFO" | grep "ID_NET_NAME_SLOT=" | sed 's/.*ID_NET_NAME_SLOT=//')
57+
ID_NET_NAME_PATH=$(echo "$UDEV_INFO" | grep "ID_NET_NAME_PATH=" | sed 's/.*ID_NET_NAME_PATH=//')
58+
ID_NET_NAME_MAC=$(echo "$UDEV_INFO" | grep "ID_NET_NAME_MAC=" | sed 's/.*ID_NET_NAME_MAC=//')
59+
60+
# Check if we have any properties to save
61+
if [ -z "$ID_NET_NAME_ONBOARD" ] && [ -z "$ID_NET_NAME_SLOT" ] && [ -z "$ID_NET_NAME_PATH" ] && [ -z "$ID_NET_NAME_MAC" ]; then
62+
echo "default_hook: No udev net name properties found for $INTERFACE_NAME"
63+
return
64+
fi
65+
66+
# Get MAC address
67+
MAC_ADDRESS=$(cat /sys/class/net/$INTERFACE_NAME/address 2>/dev/null)
68+
if [ -z "$MAC_ADDRESS" ]; then
69+
echo "default_hook: Failed to get MAC address for $INTERFACE_NAME"
70+
return
71+
fi
72+
73+
# Save properties to temp file for later use
74+
mkdir -p /var/run/vpp
75+
echo "MAC_ADDRESS=$MAC_ADDRESS" > /var/run/vpp/udev_props_$INTERFACE_NAME
76+
[ -n "$ID_NET_NAME_ONBOARD" ] && echo "ID_NET_NAME_ONBOARD=$ID_NET_NAME_ONBOARD" >> /var/run/vpp/udev_props_$INTERFACE_NAME
77+
[ -n "$ID_NET_NAME_SLOT" ] && echo "ID_NET_NAME_SLOT=$ID_NET_NAME_SLOT" >> /var/run/vpp/udev_props_$INTERFACE_NAME
78+
[ -n "$ID_NET_NAME_PATH" ] && echo "ID_NET_NAME_PATH=$ID_NET_NAME_PATH" >> /var/run/vpp/udev_props_$INTERFACE_NAME
79+
[ -n "$ID_NET_NAME_MAC" ] && echo "ID_NET_NAME_MAC=$ID_NET_NAME_MAC" >> /var/run/vpp/udev_props_$INTERFACE_NAME
80+
81+
echo "default_hook: Captured udev properties for $INTERFACE_NAME (MAC: $MAC_ADDRESS)"
82+
[ -n "$ID_NET_NAME_ONBOARD" ] && echo "default_hook: ID_NET_NAME_ONBOARD=$ID_NET_NAME_ONBOARD"
83+
[ -n "$ID_NET_NAME_SLOT" ] && echo "default_hook: ID_NET_NAME_SLOT=$ID_NET_NAME_SLOT"
84+
[ -n "$ID_NET_NAME_PATH" ] && echo "default_hook: ID_NET_NAME_PATH=$ID_NET_NAME_PATH"
85+
[ -n "$ID_NET_NAME_MAC" ] && echo "default_hook: ID_NET_NAME_MAC=$ID_NET_NAME_MAC"
86+
}
87+
88+
create_udev_net_name_rule () {
89+
PROPS_FILE="/var/run/vpp/udev_props_$INTERFACE_NAME"
90+
if [ ! -f "$PROPS_FILE" ]; then
91+
echo "default_hook: No udev properties captured for $INTERFACE_NAME, skipping rule creation"
92+
return
93+
fi
94+
95+
# Source the properties file
96+
. "$PROPS_FILE"
97+
98+
if [ -z "$MAC_ADDRESS" ]; then
99+
echo "default_hook: No MAC address captured for $INTERFACE_NAME, skipping rule creation"
100+
return
101+
fi
102+
103+
echo "default_hook: Creating udev rule for $INTERFACE_NAME with MAC $MAC_ADDRESS..."
104+
105+
# Build the udev rule
106+
RULE_FILE="/etc/udev/rules.d/99-vpp-restore-id_net_name.rules"
107+
echo "# Re-apply ID_NET_NAME_* properties after Calico VPP creates the host-facing tap/tun netdev." > "$RULE_FILE"
108+
printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s"' "$MAC_ADDRESS" >> "$RULE_FILE"
109+
110+
[ -n "$ID_NET_NAME_ONBOARD" ] && printf ', ENV{ID_NET_NAME_ONBOARD}:="%s"' "$ID_NET_NAME_ONBOARD" >> "$RULE_FILE"
111+
[ -n "$ID_NET_NAME_SLOT" ] && printf ', ENV{ID_NET_NAME_SLOT}:="%s"' "$ID_NET_NAME_SLOT" >> "$RULE_FILE"
112+
[ -n "$ID_NET_NAME_PATH" ] && printf ', ENV{ID_NET_NAME_PATH}:="%s"' "$ID_NET_NAME_PATH" >> "$RULE_FILE"
113+
[ -n "$ID_NET_NAME_MAC" ] && printf ', ENV{ID_NET_NAME_MAC}:="%s"' "$ID_NET_NAME_MAC" >> "$RULE_FILE"
114+
115+
echo "" >> "$RULE_FILE"
116+
117+
echo "default_hook: Created udev rule file at $RULE_FILE"
118+
119+
# Reload udev rules
120+
udevadm control --reload-rules
121+
122+
# Trigger udev for net subsystem to apply the stored ID_NET_NAME_* properties
123+
udevadm trigger --subsystem-match=net --action=add
124+
echo "default_hook: Triggered udev to apply the stored ID_NET_NAME_* properties"
125+
}
126+
127+
remove_udev_net_name_rule () {
128+
RULE_FILE="/etc/udev/rules.d/99-vpp-restore-id_net_name.rules"
129+
PROPS_FILE="/var/run/vpp/udev_props_$INTERFACE_NAME"
130+
131+
if [ -f "$RULE_FILE" ]; then
132+
echo "default_hook: Removing udev rule file $RULE_FILE..."
133+
rm -f "$RULE_FILE"
134+
udevadm control --reload-rules
135+
136+
# Trigger udev for net subsystem to remove the stored ID_NET_NAME_* properties
137+
udevadm trigger --subsystem-match=net --action=change
138+
echo "default_hook: Triggered udev to remove the stored ID_NET_NAME_* properties"
139+
fi
140+
141+
if [ -f "$PROPS_FILE" ]; then
142+
rm -f "$PROPS_FILE"
143+
fi
144+
}
145+
146+
echo "default_hook: Uplink interface name=$INTERFACE_NAME"
42147
if which systemctl > /dev/null; then
43148
echo "default_hook: using systemctl..."
44149
else
45150
echo "default_hook: Init system not supported, network configuration may fail"
46151
exit 1
47152
fi
48153
49-
if [ "$HOOK" = "BEFORE_VPP_RUN" ]; then
154+
if [ "$HOOK" = "CAPTURE_HOST_UDEV_PROPS" ]; then
155+
capture_udev_net_name_properties
156+
elif [ "$HOOK" = "BEFORE_VPP_RUN" ]; then
50157
fix_dns
51158
elif [ "$HOOK" = "VPP_RUNNING" ]; then
159+
create_udev_net_name_rule
52160
restart_network
53161
elif [ "$HOOK" = "VPP_DONE_OK" ]; then
54162
undo_dns_fix
163+
remove_udev_net_name_rule
55164
restart_network
56165
elif [ "$HOOK" = "VPP_ERRORED" ]; then
57166
undo_dns_fix
167+
remove_udev_net_name_rule
58168
restart_network
59169
fi
60170

vpp-manager/vpp_runner.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ func (v *VppRunner) Run(drivers []uplink.UplinkDriver) error {
101101
return errors.Wrap(err, "Error generating VPP config")
102102
}
103103

104+
// Run hook to capture host udev properties before driver unbind
105+
config.RunHook(config.HookScriptCaptureHostUdevProps, "CAPTURE_HOST_UDEV_PROPS", v.params, log)
106+
104107
for idx := range v.conf {
105108
err = v.uplinkDriver[idx].PreconfigureLinux()
106109
if err != nil {

0 commit comments

Comments
 (0)