Commit 4bb7743f authored by Yann Garcia's avatar Yann Garcia
Browse files

Filnlyse the real time emulation

parent 277765cd
Loading
Loading
Loading
Loading
+23 −3
Changes for go-apps/meep-simu5g-bridge/bridge.go: 23 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -67,8 +67,8 @@ func NewBridgeInstance(cfg *bridge.IntegrationConfig) (*BridgeInstance, error) {
		_ = tun.Close()
		return nil, err
	}
	log.Info("Bridge connected to simulator host S at ", cfg.BridgeTCPAddr(),
		" (sandbox host B, scenario=", cfg.Deployment.ScenarioID, ")")
	log.Info("Bridge connected to Network simulation stack at ", cfg.BridgeTCPAddr(),
		" (EdgeNative-Connector, scenario=", cfg.Deployment.ScenarioID, ")")
	return b, nil
}

@@ -180,11 +180,17 @@ func (b *BridgeInstance) loopTunToSocket(ctx context.Context) error {
		}
		pkt := buf[:n]
		ueID := uint16(0)
		if src := ipv4Source(pkt); src != nil {
		src := ipv4Source(pkt)
		if src != nil {
			if idx := b.cfg.ResolveUeIndexFromIP(src); idx >= 0 {
				ueID = uint16(idx)
			}
		}
		if proto := ipv4Proto(pkt); proto == 1 {
			log.Info("TUN UL ICMP bytes=", n, " src=", src, " dst=", ipv4Dest(pkt), " ueId=", ueID)
		} else {
			log.Debug("TUN UL bytes=", n, " proto=", proto, " src=", src, " dst=", ipv4Dest(pkt), " ueId=", ueID)
		}
		frame := bridge.EncodeDataULFrame(ueID, pkt, 0)
		b.mutex.Lock()
		conn := b.conn
@@ -260,3 +266,17 @@ func ipv4Source(pkt []byte) net.IP {
	}
	return net.IP(pkt[12:16]).To4()
}

func ipv4Dest(pkt []byte) net.IP {
	if len(pkt) < 20 || pkt[0]>>4 != 4 {
		return nil
	}
	return net.IP(pkt[16:20]).To4()
}

func ipv4Proto(pkt []byte) uint8 {
	if len(pkt) < 10 || pkt[0]>>4 != 4 {
		return 0
	}
	return pkt[9]
}
+1 −1
Changes for go-packages/meep-nw-simu-catalog/instance.go: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ import (
)

/** Default sim_time_limit sent when CreateInstanceRequest.SimTimeLimit is empty. */
const DefaultSimTimeLimit = "300s"
const DefaultSimTimeLimit = "1800s" // Half an hour

/**
 * @brief POST /v1/instances request body.
+9 −1
Changes for tools/simu5g/install-simu5g-routes-sandbox.sh: 9 added lines, 1 removed line.
Original line number Diff line number Diff line
#!/usr/bin/env bash
# install-simu5g-routes-sandbox.sh — Discover UE/MEC PodIPs from a sandbox namespace
# by pod name, then delegate to install-simu5g-routes.sh (unchanged).
# by pod name, then delegate to install-simu5g-routes.sh (policy routes + SIMU5G iptables).
#
# Classification (among scenario pods):
#   MEC  — pod name starts with MEC_NAME_PREFIX (default: mep)
#   UE   — all other scenario pods with a PodIP
#
# Run apply after a user activates a network scenario (PodIPs exist). Do not run
# this from the Calico dataplane switch — that happens before any sandbox exists.
#
# The derived selectors are informational (kubectl -l cannot express name prefixes);
# this script resolves PodIPs and passes UE_CIDRS / MEC_CIDRS to the base installer.
#
@@ -111,6 +114,7 @@ TUN / host routing (passed through to ${INSTALLER##*/}):
Examples:
  $SCRIPT_NAME discover -n sbx4lesbpo --config-file ${SCRIPT_DIR}/monaco-harbor-integration-config.json
  sudo $SCRIPT_NAME apply -n sbx4lesbpo --config-file ${SCRIPT_DIR}/monaco-harbor-integration-config.json
  # apply: TUN + ip rule table 100 + SIMU5G-FORWARD/STEER iptables for live PodIPs
  # If sudo still sees 0 pods: sudo KUBECONFIG=\$HOME/.kube/config $SCRIPT_NAME apply ...
  sudo $SCRIPT_NAME status
  sudo $SCRIPT_NAME delete-tun
@@ -265,6 +269,10 @@ for i, ep in enumerate(cfg.get("mecEndpoints", [])):
pathlib.Path(out_path).write_text(json.dumps(cfg, indent=2) + "\n")
PY
  mv "$tmp" "$CONFIG_FILE"
  chmod 644 "$CONFIG_FILE" 2>/dev/null || true
  if [[ -n "${SUDO_USER:-}" && "$SUDO_USER" != "root" ]]; then
    chown "${SUDO_USER}:" "$CONFIG_FILE" 2>/dev/null || true
  fi
  rm -f "$pairs"
  log "updated sandboxIpCidr in $CONFIG_FILE from live PodIPs"
}
+277 −21
Changes for tools/simu5g/install-simu5g-routes.sh: 277 added lines, 21 removed lines.
Original line number Diff line number Diff line
@@ -2,7 +2,9 @@
# install-simu5g-routes.sh — Host routing on sandbox host B for Simu5G TUN bridge.
#
# Steers UE→MEC (and optionally MEC→UE) pod traffic through simu5g-br0 using
# policy routing so CNI downlink from the bridge still uses the overlay route.
# policy routing. Packets arriving on the TUN (bridge DATA_DL) use
# `iif TUN lookup main` so Calico per-pod /32s deliver downlink. Calico cali*
# rp_filter is set to 0 — strict RPF drops this asymmetric path.
#
# Usage:
#   sudo ./install-simu5g-routes.sh apply
@@ -18,6 +20,12 @@
#   Do NOT set CNI_DEV to a Calico per-pod veth (cali*). Downlink uses existing /32 routes.
#   UPLINK_ONLY=1  (1: skip MEC→UE policy rules; 0: bidirectional steer; default 0)
#   STATE_DIR=/var/lib/simu5g-routes
#
# Also installs host iptables (run after a scenario is activated — PodIPs are required):
#   filter SIMU5G-FORWARD     ACCEPT in/out TUN + UE↔MEC
#   raw    SIMU5G-RAW-PREROUTING  ACCEPT UE↔MEC before cali-PREROUTING
#     (Calico raw rule: mark 0x80000 + rpfilter invert → DROP; policy routing
#      to TUN fails that RPF so ICMP never reaches filter FORWARD / the TUN)

set -euo pipefail

@@ -42,6 +50,13 @@ readonly UE_POD_SELECTOR="${UE_POD_SELECTOR:-meepOrigin=scenario}"
readonly MEC_POD_SELECTOR="${MEC_POD_SELECTOR:-meepOrigin=scenario}"
readonly UPLINK_ONLY="${UPLINK_ONLY:-0}"
readonly RULE_PRIO_BASE="${RULE_PRIO_BASE:-9000}"
readonly TUN_IIF_PRIO="${TUN_IIF_PRIO:-8800}"
readonly CALI_IIF_PRIO="${CALI_IIF_PRIO:-8820}"
readonly IPT_FWD_CHAIN="${IPT_FWD_CHAIN:-SIMU5G-FORWARD}"
readonly IPT_RAW_CHAIN="${IPT_RAW_CHAIN:-SIMU5G-RAW-PREROUTING}"
readonly IPT_MANGLE_CHAIN="${IPT_MANGLE_CHAIN:-SIMU5G-STEER}"
readonly FWMARK="${FWMARK:-0x7355}"
readonly FWMARK_PRIO="${FWMARK_PRIO:-8900}"

log() { printf '[%s] %s\n' "$SCRIPT_NAME" "$*"; }
die() { log "ERROR: $*"; exit 1; }
@@ -197,6 +212,9 @@ resolve_cni_dev() {
    elif calico_present; then
      log "Calico detected: TUN downlink uses existing per-pod /32 routes; no shared overlay device"
      SKIP_CNI_HOST_ROUTES=1
      if ip link show bpfin.cali >/dev/null 2>&1; then
        log "WARN: bpfin.cali present (Felix BPF). Pod-to-pod skips Linux ip rule. Switch with: sudo ./tools/simu5g/switch-calico-dataplane.sh iptables"
      fi
    fi
  fi
}
@@ -226,21 +244,121 @@ setup_tun() {

setup_sysctl() {
  run_state sysctl net.ipv4.ip_forward=1
  for dev in all default "$TUN_DEV" "$MGMT_DEV" ${CNI_DEV:+"$CNI_DEV"} bpfin.cali; do
    [[ -d "/proc/sys/net/ipv4/conf/$dev" ]] || continue
    run_state rp_filter "$dev"
  # Strict rp_filter on cali* + fwmark/from-to rules: reverse-path lookup hits
  # table 100 (TUN) instead of the ingress veth → kernel drops the packet
  # (TX on TUN stays ~0, overlay ping dies). max(all, interface) is used, so
  # every cali* must be 0 — all/default/TUN alone is not enough.
  local proc dev
  for proc in /proc/sys/net/ipv4/conf/*/rp_filter; do
    [[ -e "$proc" ]] || continue
    dev="$(basename "$(dirname "$proc")")"
    case "$dev" in
      lo) continue ;;
    esac
    echo 0 > "$proc" || true
    state_append "rp_filter|${dev}"
  done
  log "rp_filter=0 on all/default/${TUN_DEV}/cali* (asymmetric TUN path)"
  if [[ -w "/proc/sys/net/ipv6/conf/${TUN_DEV}/disable_ipv6" ]]; then
    echo 1 > "/proc/sys/net/ipv6/conf/${TUN_DEV}/disable_ipv6" || true
  fi
}

# Drop leftover table-100 rules (from/to, iif cali, old PodIPs). Keep iif TUN → main.
flush_stale_policy_rules() {
  local pref n=0
  while read -r pref; do
    [[ -n "$pref" ]] || continue
    ip rule del pref "$pref" 2>/dev/null || true
    n=$((n + 1))
  done < <(ip rule list | awk '
    /fwmark/ { next }
    /lookup[[:space:]]+(simu5g|100)([[:space:]]|$)/ {
      pref=$1; sub(/:$/, "", pref)
      if (pref ~ /^[0-9]+$/) print pref
    }')
  if [[ "$n" -gt 0 ]]; then
    log "flushed ${n} stale ip rule(s) from table ${RT_TABLE_NAME}"
  fi
}

cni_dev_for_ip() {
  local dev
  dev="$(ip -o route show "$1" 2>/dev/null | awk '{print $3; exit}')"
  case "$dev" in
    cali*) printf '%s' "$dev" ;;
  esac
}

# Calico forwarded FIB lookups often omit saddr, so "from UE to MEC" never hits.
# iif of the workload veth is always set — that is what actually steers to TUN.
apply_cali_iif_rules() {
  local ue mec ue_dev mec_dev prio=$CALI_IIF_PRIO
  while IFS= read -r ue; do
    [[ -n "$ue" ]] || continue
    ue="${ue%%/*}"
    ue_dev="$(cni_dev_for_ip "$ue")"
    if [[ -z "$ue_dev" ]]; then
      log "WARN: no cali* device for UE ${ue} — skip iif rule"
      continue
    fi
    while IFS= read -r mec; do
      [[ -n "$mec" ]] || continue
      mec="${mec%%/*}"
      mec_dev="$(cni_dev_for_ip "$mec")"
      if [[ -z "$mec_dev" ]]; then
        log "WARN: no cali* device for MEC ${mec} — skip iif rule"
        continue
      fi
      if ! ip rule list | grep -qE "iif ${ue_dev}[[:space:]].* to ${mec}[[:space:]].* lookup (${RT_TABLE_ID}|${RT_TABLE_NAME})"; then
        run_state rule iif "$ue_dev" to "$mec" lookup "$RT_TABLE_ID" priority "$prio"
        log "policy: iif ${ue_dev} to ${mec} → table ${RT_TABLE_NAME}"
      fi
      prio=$((prio + 1))
      if [[ "$UPLINK_ONLY" != "1" ]]; then
        if ! ip rule list | grep -qE "iif ${mec_dev}[[:space:]].* to ${ue}[[:space:]].* lookup (${RT_TABLE_ID}|${RT_TABLE_NAME})"; then
          run_state rule iif "$mec_dev" to "$ue" lookup "$RT_TABLE_ID" priority "$prio"
          log "policy: iif ${mec_dev} to ${ue} → table ${RT_TABLE_NAME}"
        fi
        prio=$((prio + 1))
      fi
    done < <(split_csv "$MEC_CIDRS")
  done < <(split_csv "$UE_CIDRS")
}

refresh_tun_routes() {
  ip link set "$TUN_DEV" up 2>/dev/null || true
  # onlink: table 100 is installed before the bridge attaches; without it the
  # kernel marks nexthops linkdown and drops iif-matched packets with TX=0.
  ip route replace default dev "$TUN_DEV" table "$RT_TABLE_ID" onlink 2>/dev/null \
    || ip route replace default dev "$TUN_DEV" table "$RT_TABLE_ID" 2>/dev/null || true
  local ip32
  while IFS= read -r ip32; do
    [[ -n "$ip32" ]] || continue
    ip32="${ip32%%/*}"
    ip route replace "${ip32}/32" dev "$TUN_DEV" table "$RT_TABLE_ID" onlink 2>/dev/null \
      || ip route replace "${ip32}/32" dev "$TUN_DEV" table "$RT_TABLE_ID" 2>/dev/null || true
  done < <({ split_csv "$UE_CIDRS"; split_csv "$MEC_CIDRS"; })
  ip route flush cache 2>/dev/null || true
}

apply_policy_routes() {
  local ue mec prio=$RULE_PRIO_BASE
  ensure_rt_table
  flush_stale_policy_rules

  # Always (re)install table 100 with onlink so iif rules are not a black hole.
  refresh_tun_routes

  # Cellular-steered traffic uses TUN. Creating the first route instantiates the FIB table.
  if ! ip route show table "$RT_TABLE_ID" 2>/dev/null | grep -q "dev ${TUN_DEV}"; then
    run_state route table "$RT_TABLE_ID" default dev "$TUN_DEV"
  # Packets arriving from the bridge (iif TUN) must use main/Calico /32s.
  # Without this, from MEC→UE lookup table 100 sends DATA_DL back into the TUN.
  if ! ip rule list | grep -qE "${TUN_IIF_PRIO}:.*iif ${TUN_DEV}.*lookup main"; then
    run_state rule iif "$TUN_DEV" lookup main priority "$TUN_IIF_PRIO"
    log "policy: iif ${TUN_DEV} lookup main prio ${TUN_IIF_PRIO} (TUN downlink → Calico)"
  fi

  apply_cali_iif_rules

  while IFS= read -r ue; do
    [[ -n "$ue" ]] || continue
    local ue_ip=${ue%%/*}
@@ -278,6 +396,127 @@ apply_policy_routes() {
      fi
    done < <({ split_csv "$UE_CIDRS"; split_csv "$MEC_CIDRS"; })
  fi
  refresh_tun_routes
}

ipt_ensure_chain() {
  local table=$1 chain=$2
  if [[ "$table" == "filter" ]]; then
    iptables -N "$chain" 2>/dev/null || iptables -F "$chain"
  else
    iptables -t "$table" -N "$chain" 2>/dev/null || iptables -t "$table" -F "$chain"
  fi
}

ipt_ensure_jump() {
  local table=$1 parent=$2 chain=$3
  if [[ "$table" == "filter" ]]; then
    iptables -C "$parent" -j "$chain" 2>/dev/null || iptables -I "$parent" 1 -j "$chain"
  else
    # Append mangle: Calico writes marks later in PREROUTING. Insert-at-1 loses
    # 0x7355 when Felix --set-mark overwrites it, then fwmark lookup never hits
    # table 100 and Calico FORWARD drops the wiped mark.
    iptables -t "$table" -C "$parent" -j "$chain" 2>/dev/null || iptables -t "$table" -A "$parent" -j "$chain"
  fi
}

# Run STEER last in mangle PREROUTING so it wins over Calico's mark rewrite.
restack_steer() {
  iptables -t mangle -C PREROUTING -j "$IPT_MANGLE_CHAIN" 2>/dev/null || return 0
  iptables -t mangle -D PREROUTING -j "$IPT_MANGLE_CHAIN" 2>/dev/null || true
  iptables -t mangle -A PREROUTING -j "$IPT_MANGLE_CHAIN"
  log "mangle PREROUTING: ${IPT_MANGLE_CHAIN} is last (after Calico)"
}

ipt_delete_jump() {
  local table=$1 parent=$2 chain=$3
  if [[ "$table" == "filter" ]]; then
    iptables -D "$parent" -j "$chain" 2>/dev/null || true
    iptables -F "$chain" 2>/dev/null || true
    iptables -X "$chain" 2>/dev/null || true
  else
    iptables -t "$table" -D "$parent" -j "$chain" 2>/dev/null || true
    iptables -t "$table" -F "$chain" 2>/dev/null || true
    iptables -t "$table" -X "$chain" 2>/dev/null || true
  fi
}

# TUN ACCEPT in FORWARD only. Do not MARK — Calico owns skb->mark; touching it
# drops overlay (TX=0 on TUN and 100% ping loss). Steering is ip rule iif cali*.
apply_simu5g_iptables() {
  ipt_ensure_chain filter "$IPT_FWD_CHAIN"
  iptables -A "$IPT_FWD_CHAIN" -i "$TUN_DEV" -j ACCEPT
  iptables -A "$IPT_FWD_CHAIN" -o "$TUN_DEV" -j ACCEPT
  local ue mec
  while IFS= read -r ue; do
    [[ -n "$ue" ]] || continue
    while IFS= read -r mec; do
      [[ -n "$mec" ]] || continue
      iptables -A "$IPT_FWD_CHAIN" -s "${ue%%/*}" -d "${mec%%/*}" -j ACCEPT
      iptables -A "$IPT_FWD_CHAIN" -s "${mec%%/*}" -d "${ue%%/*}" -j ACCEPT
    done < <(split_csv "$MEC_CIDRS")
  done < <(split_csv "$UE_CIDRS")
  ipt_ensure_jump filter FORWARD "$IPT_FWD_CHAIN"
  ensure_tun_accept_before_calico
  apply_raw_rpf_bypass
  log "iptables filter ${IPT_FWD_CHAIN}: ACCEPT ${TUN_DEV} + UE↔MEC pairs"
}

# Calico raw cali-PREROUTING marks iif cali+ with 0x80000 then:
#   DROP mark 0x80000/0x80000 rpfilter validmark invert
# Policy routing to TUN makes reverse-path fail that match, so ICMP dies in
# raw PREROUTING (FORWARD -o TUN stays 0). ACCEPT UE↔MEC first so the DROP
# never sees those packets. Felix Append leaves this jump at position 1.
apply_raw_rpf_bypass() {
  ipt_ensure_chain raw "$IPT_RAW_CHAIN"
  local ue mec
  while IFS= read -r ue; do
    [[ -n "$ue" ]] || continue
    while IFS= read -r mec; do
      [[ -n "$mec" ]] || continue
      iptables -t raw -A "$IPT_RAW_CHAIN" -s "${ue%%/*}" -d "${mec%%/*}" -j ACCEPT
      iptables -t raw -A "$IPT_RAW_CHAIN" -s "${mec%%/*}" -d "${ue%%/*}" -j ACCEPT
    done < <(split_csv "$MEC_CIDRS")
  done < <(split_csv "$UE_CIDRS")
  if iptables -t raw -C PREROUTING -j "$IPT_RAW_CHAIN" 2>/dev/null; then
    iptables -t raw -D PREROUTING -j "$IPT_RAW_CHAIN"
  fi
  iptables -t raw -I PREROUTING 1 -j "$IPT_RAW_CHAIN"
  log "iptables raw ${IPT_RAW_CHAIN} at PREROUTING:1 (skip Calico rpfilter for UE↔MEC)"
}

# Calico forwarded packets often miss "ip rule from <UE>"; MARK + fwmark rule is the fallback.
# Felix Insert mode puts cali-FORWARD first (policy drop) and never reaches SIMU5G-FORWARD
# for oif=TUN, so ping dies after apply. Put TUN ACCEPT at FORWARD head and tell Felix to Append.
ensure_tun_accept_before_calico() {
  if command -v "${KUBECTL}" >/dev/null 2>&1; then
    "$KUBECTL" patch felixconfiguration default --type merge \
      -p '{"spec":{"chainInsertMode":"Append"}}' >/dev/null \
      && log "Felix chainInsertMode=Append (keeps TUN ACCEPT above cali-FORWARD)" \
      || log "WARN: could not patch Felix chainInsertMode"
  fi
  iptables -C FORWARD -o "$TUN_DEV" -j ACCEPT 2>/dev/null || iptables -I FORWARD 1 -o "$TUN_DEV" -j ACCEPT
  iptables -C FORWARD -i "$TUN_DEV" -j ACCEPT 2>/dev/null || iptables -I FORWARD 1 -i "$TUN_DEV" -j ACCEPT
  if iptables -L cali-FORWARD -n >/dev/null 2>&1; then
    iptables -C cali-FORWARD -o "$TUN_DEV" -j ACCEPT 2>/dev/null || iptables -I cali-FORWARD 1 -o "$TUN_DEV" -j ACCEPT
    iptables -C cali-FORWARD -i "$TUN_DEV" -j ACCEPT 2>/dev/null || iptables -I cali-FORWARD 1 -i "$TUN_DEV" -j ACCEPT
  fi
}

flush_simu5g_iptables() {
  ip rule del priority "$TUN_IIF_PRIO" iif "$TUN_DEV" lookup main 2>/dev/null || true
  ip rule del fwmark "${FWMARK}/${FWMARK}" lookup "$RT_TABLE_ID" priority "$FWMARK_PRIO" 2>/dev/null || true
  ip rule del fwmark "$FWMARK" lookup "$RT_TABLE_ID" priority "$FWMARK_PRIO" 2>/dev/null || \
    ip rule del fwmark "$FWMARK" lookup "$RT_TABLE_ID" 2>/dev/null || true
  iptables -D FORWARD -o "$TUN_DEV" -j ACCEPT 2>/dev/null || true
  iptables -D FORWARD -i "$TUN_DEV" -j ACCEPT 2>/dev/null || true
  iptables -D cali-FORWARD -o "$TUN_DEV" -j ACCEPT 2>/dev/null || true
  iptables -D cali-FORWARD -i "$TUN_DEV" -j ACCEPT 2>/dev/null || true
  ipt_delete_jump raw PREROUTING "$IPT_RAW_CHAIN"
  ipt_delete_jump mangle PREROUTING "$IPT_MANGLE_CHAIN"
  ipt_delete_jump mangle FORWARD "$IPT_MANGLE_CHAIN"
  ipt_delete_jump filter FORWARD "$IPT_FWD_CHAIN"
  log "removed ${IPT_FWD_CHAIN}, ${IPT_RAW_CHAIN}, ${IPT_MANGLE_CHAIN}, fwmark ${FWMARK}"
}

cmd_apply() {
@@ -291,6 +530,7 @@ cmd_apply() {
  setup_tun
  setup_sysctl
  apply_policy_routes
  apply_simu5g_iptables
  log "apply complete — state saved to $STATE_FILE"
  log "start bridge: go run ./go-apps/meep-simu5g-bridge --config $CONFIG_FILE"
  cmd_status
@@ -300,22 +540,38 @@ cmd_status() {
  log "=== routing table (main) ==="
  ip route show table main | sed 's/^/  /'
  log "=== policy rules (simu5g-related) ==="
  ip rule list | grep -E "lookup (${RT_TABLE_ID}|${RT_TABLE_NAME})( |$)" | sed 's/^/  /' || true
  ip rule list | grep -E "lookup (${RT_TABLE_ID}|${RT_TABLE_NAME})( |$)|iif ${TUN_DEV}" | sed 's/^/  /' || true
  log "=== table ${RT_TABLE_NAME} (${RT_TABLE_ID}) ==="
  ip route show table "$RT_TABLE_ID" 2>/dev/null | sed 's/^/  /' || true
  log "=== interfaces ==="
  ip -br addr show "$TUN_DEV" "$MGMT_DEV" ${CNI_DEV:+"$CNI_DEV"} 2>/dev/null | sed 's/^/  /' || true
  log "=== rp_filter ==="
  for dev in "$TUN_DEV" "$MGMT_DEV" ${CNI_DEV:+"$CNI_DEV"}; do
  local dev ncali=0
  for dev in all default "$TUN_DEV" "$MGMT_DEV"; do
    [[ -r "/proc/sys/net/ipv4/conf/$dev/rp_filter" ]] \
      && printf '  %s rp_filter=%s\n' "$dev" "$(cat "/proc/sys/net/ipv4/conf/$dev/rp_filter")"
  done
  for dev in /proc/sys/net/ipv4/conf/cali*/rp_filter; do
    [[ -e "$dev" ]] || continue
    ncali=$((ncali + 1))
    if [[ "$ncali" -le 3 || "$(cat "$dev")" != 0 ]]; then
      printf '  %s rp_filter=%s\n' "$(basename "$(dirname "$dev")")" "$(cat "$dev")"
    fi
  done
  if [[ "$ncali" -gt 3 ]]; then
    log "  ... ${ncali} cali* interfaces (showing first 3 + any != 0)"
  fi
  log "=== iptables filter ${IPT_FWD_CHAIN} ==="
  iptables -S "$IPT_FWD_CHAIN" 2>/dev/null | sed 's/^/  /' || log "  (chain absent)"
  log "=== iptables raw ${IPT_RAW_CHAIN} ==="
  iptables -t raw -S "$IPT_RAW_CHAIN" 2>/dev/null | sed 's/^/  /' || log "  (chain absent)"
  log "=== iptables mangle ${IPT_MANGLE_CHAIN} ==="
  iptables -t mangle -S "$IPT_MANGLE_CHAIN" 2>/dev/null | sed 's/^/  /' || log "  (chain absent)"
}

rollback_rule() {
  # state: rule|from X to Y lookup Z priority N
  local args=("$@")
  ip rule del "${args[@]}" 2>/dev/null || log "WARN: could not del rule ${args[*]}"
  # Already removed by flush_stale_policy_rules — do not WARN.
  ip rule del "$@" 2>/dev/null || true
}

rollback_route() {
@@ -325,7 +581,13 @@ rollback_route() {

cmd_rollback() {
  require_root rollback
  [[ -f "$STATE_FILE" ]] || die "no state file at $STATE_FILE — nothing to roll back"
  flush_simu5g_iptables
  flush_stale_policy_rules
  if [[ ! -f "$STATE_FILE" ]]; then
    ip link del "$TUN_DEV" 2>/dev/null || true
    log "no state file at $STATE_FILE — iptables/ip rules flushed, TUN removed if present"
    return 0
  fi

  log "rolling back from $STATE_FILE"
  tac "$STATE_FILE" | while IFS='|' read -r kind rest; do
@@ -341,19 +603,13 @@ cmd_rollback() {
      tun)
        ip link del "$TUN_DEV" 2>/dev/null || true
        ;;
      rp_filter)
        dev=${rest%% *}
        [[ -w "/proc/sys/net/ipv4/conf/$dev/rp_filter" ]] && echo 1 > "/proc/sys/net/ipv4/conf/$dev/rp_filter"
        ;;
      sysctl)
        sysctl -w net.ipv4.ip_forward=0 >/dev/null 2>&1 || true
        ;;
      tun_addr|link_up|forward) ;;
      rp_filter|sysctl|tun_addr|link_up|forward) ;;
      *) log "WARN: unknown state record: $kind|$rest" ;;
    esac
  done

  rm -f "$STATE_FILE"
  ip link del "$TUN_DEV" 2>/dev/null || true
  log "rollback complete"
}

+9 −9
Changes for tools/simu5g/monaco-harbor-integration-config.json: 9 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -31,49 +31,49 @@
  "ueMappings": [
    {
      "ueId": "ue-car-0",
      "sandboxIpCidr": "192.168.108.187/32",
      "sandboxIpCidr": "192.168.108.147/32",
      "simu5gModulePath": "MonacoHarbor.ue_car[0]"
    },
    {
      "ueId": "ue-car-1",
      "sandboxIpCidr": "192.168.108.148/32",
      "sandboxIpCidr": "192.168.108.185/32",
      "simu5gModulePath": "MonacoHarbor.ue_car[1]"
    },
    {
      "ueId": "ue-car-2",
      "sandboxIpCidr": "192.168.108.184/32",
      "sandboxIpCidr": "192.168.108.180/32",
      "simu5gModulePath": "MonacoHarbor.ue_car[2]"
    },
    {
      "ueId": "ue-car-3",
      "sandboxIpCidr": "192.168.108.149/32",
      "sandboxIpCidr": "192.168.108.150/32",
      "simu5gModulePath": "MonacoHarbor.ue_car[3]"
    },
    {
      "ueId": "ue-ped-0",
      "sandboxIpCidr": "192.168.108.150/32",
      "sandboxIpCidr": "192.168.108.130/32",
      "simu5gModulePath": "MonacoHarbor.ue_ped[0]"
    },
    {
      "ueId": "ue-ped-1",
      "sandboxIpCidr": "192.168.108.182/32",
      "sandboxIpCidr": "192.168.108.136/32",
      "simu5gModulePath": "MonacoHarbor.ue_ped[1]"
    },
    {
      "ueId": "ue-ped-2",
      "sandboxIpCidr": "192.168.108.171/32",
      "sandboxIpCidr": "192.168.108.179/32",
      "simu5gModulePath": "MonacoHarbor.ue_ped[2]"
    },
    {
      "ueId": "ue-ped-3",
      "sandboxIpCidr": "192.168.108.188/32",
      "sandboxIpCidr": "192.168.108.135/32",
      "simu5gModulePath": "MonacoHarbor.ue_ped[3]"
    }
  ],
  "mecEndpoints": [
    {
      "endpointId": "mep1",
      "sandboxIpCidr": "192.168.108.181/32",
      "sandboxIpCidr": "192.168.108.134/32",
      "simu5gModulePath": "router"
    }
  ],
Loading