Skip to content
65 changes: 58 additions & 7 deletions scripts/setup-jetson.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,37 @@ error() {
exit 1
}

# Returns 0 when `br_netfilter` is loaded AND both bridge-nf-call-iptables
# and bridge-nf-call-ip6tables sysctls are already set to 1. Used so we
# can skip host-state changes on Jetson images that ship with this
# configured out of the box.
bridge_netfilter_ready() {
[[ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]] \
&& [[ -f /proc/sys/net/bridge/bridge-nf-call-ip6tables ]] \
&& [[ "$(cat /proc/sys/net/bridge/bridge-nf-call-iptables 2>/dev/null)" == "1" ]] \
&& [[ "$(cat /proc/sys/net/bridge/bridge-nf-call-ip6tables 2>/dev/null)" == "1" ]]
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

# Load br_netfilter and flip the bridge-nf-call-{ip,ip6}tables sysctls,
# then persist all three across reboots. Required for k3s (running inside
# the OpenShell gateway container) to NAT pod → ClusterIP traffic;
# without this the kube-proxy iptables rules are written but never
# matched for bridged pod traffic, so sandbox pods cannot reach CoreDNS.
# ip6tables is flipped alongside iptables to keep IPv4 and IPv6 cluster
# services consistent and match the manual workaround validated on #2418.
apply_br_netfilter_setup() {
"${SUDO[@]}" modprobe br_netfilter
"${SUDO[@]}" sysctl -w net.bridge.bridge-nf-call-iptables=1 >/dev/null
"${SUDO[@]}" sysctl -w net.bridge.bridge-nf-call-ip6tables=1 >/dev/null

# Persist across reboots
echo "br_netfilter" | "${SUDO[@]}" tee /etc/modules-load.d/nemoclaw.conf >/dev/null
{
echo "net.bridge.bridge-nf-call-iptables=1"
echo "net.bridge.bridge-nf-call-ip6tables=1"
} | "${SUDO[@]}" tee /etc/sysctl.d/99-nemoclaw.conf >/dev/null
}

get_jetpack_version() {
local release_line release revision l4t_version

Expand All @@ -32,7 +63,32 @@ get_jetpack_version() {
fi

if ((release >= 39)); then
info "Jetson detected (L4T $l4t_version) — this version does not require any host setup" >&2
# JP7 R39 does not need iptables / daemon.json changes, but k3s inside
# the OpenShell gateway container still needs br_netfilter +
# bridge-nf-call-{ip,ip6}tables=1 for ClusterIP service routing. Some
# R39 kernel images ship with it already in place, so check first and
# only apply when missing — avoids planting NemoClaw-owned drop-ins in
# /etc/modules-load.d and /etc/sysctl.d on systems that don't need
# them. See #2418.
if bridge_netfilter_ready; then
info "Jetson detected (L4T $l4t_version) — br_netfilter already configured; no host setup needed" >&2
else
info "Jetson detected (L4T $l4t_version) — loading br_netfilter (required by k3s inside the OpenShell gateway; see #2418)" >&2
if ((EUID != 0)); then
"${SUDO[@]}" true >/dev/null \
|| error "Sudo is required to load br_netfilter and write /etc/modules-load.d and /etc/sysctl.d drop-ins."
fi
apply_br_netfilter_setup
# Read the values back from /proc (not just "we set it to 1") so the
# log is actual evidence that the apply path landed — useful when a
# user is validating the fix on their own Jetson and needs to confirm
# from log output alone that the runtime state is correct.
local v4 v6
v4="$(cat /proc/sys/net/bridge/bridge-nf-call-iptables 2>/dev/null || echo '?')"
v6="$(cat /proc/sys/net/bridge/bridge-nf-call-ip6tables 2>/dev/null || echo '?')"
info "br_netfilter runtime: bridge-nf-call-iptables=$v4, bridge-nf-call-ip6tables=$v6 — sandbox → ClusterIP routing (CoreDNS, services) is unblocked; no docker or k3s restart needed" >&2
info "Reboot persistence: /etc/modules-load.d/nemoclaw.conf, /etc/sysctl.d/99-nemoclaw.conf" >&2
fi
return 0
fi

Expand Down Expand Up @@ -124,12 +180,7 @@ PYEOF
;;
esac

"${SUDO[@]}" modprobe br_netfilter
"${SUDO[@]}" sysctl -w net.bridge.bridge-nf-call-iptables=1 >/dev/null

# Persist across reboots
echo "br_netfilter" | "${SUDO[@]}" tee /etc/modules-load.d/nemoclaw.conf >/dev/null
echo "net.bridge.bridge-nf-call-iptables=1" | "${SUDO[@]}" tee /etc/sysctl.d/99-nemoclaw.conf >/dev/null
apply_br_netfilter_setup
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

if [[ "$jetpack_version" == "jp6" ]]; then
"${SUDO[@]}" systemctl restart docker
Expand Down
Loading