Skip to content

RDKEMW-21581: Network connection recovery script should handle IPv4-only/IPv6-only networks - #570

Merged
nhanasi merged 6 commits into
developfrom
topic/RDKEMW-21581
Jul 29, 2026
Merged

RDKEMW-21581: Network connection recovery script should handle IPv4-only/IPv6-only networks#570
nhanasi merged 6 commits into
developfrom
topic/RDKEMW-21581

Conversation

@tukken-comcast

Copy link
Copy Markdown
Contributor

Reason for change: fix network connection recovery script
Test Procedure: See ticket
Priority: P1
Risk: Medium

@tukken-comcast
tukken-comcast requested a review from a team as a code owner July 14, 2026 17:38
Copilot AI review requested due to automatic review settings July 14, 2026 17:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the RDK network connection recovery script to make packet-loss based recovery decisions correctly on IPv4-only, IPv6-only, and dual-stack networks.

Changes:

  • Refactors logging by adding a log() helper and converting many direct echo ... >> $logsFile calls to log ....
  • Updates packet-loss probing and recovery decision logic to evaluate “bad vs good connectivity” per routed IP stack (IPv4/IPv6), rather than requiring both stacks to be present.
  • Adds lightweight state tracking (/tmp/.ncr_laststate) to log route/loss transitions only when they change.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/rdk/networkConnectionRecovery.sh Outdated
Copilot AI review requested due to automatic review settings July 15, 2026 09:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

lib/rdk/networkConnectionRecovery.sh:244

  • pingCmd is built as a single string including -I $gwIp_interface, but gwIp_interface can be empty if ip route parsing fails. In that case the script would attempt to run ping -I -c ..., which errors and makes packetLoss unparseable. Build the base command first and only append -I <iface> when the interface value is non-empty.
    if [ "$version" = "V4" ] ; then
      gwIp=$(/sbin/ip -4 route | awk '/default/ { print $3 }' | head -n1 | awk '{print $1;}')
      gwIp_interface=$(/sbin/ip -4 route | awk '/default/ { print $5 }' | head -n1 | awk '{print $1;}')
      pingCmd="ping -I $gwIp_interface"
    elif [ "$version" = "V6" ] ; then
      gwIp=$(/sbin/ip -6 route | awk '/default/ { print $3 }' | head -n1 | awk '{print $1;}')
      gwIp_interface=$(/sbin/ip -6 route | awk '/default/ { print $5 }' | head -n1 | awk '{print $1;}')
      pingCmd="ping6 -I $gwIp_interface"
    fi

Comment thread lib/rdk/networkConnectionRecovery.sh Outdated
Copilot AI review requested due to automatic review settings July 15, 2026 10:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment thread lib/rdk/networkConnectionRecovery.sh
Copilot AI review requested due to automatic review settings July 17, 2026 14:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

lib/rdk/networkConnectionRecovery.sh:243

  • Same issue for IPv6: if $gwIp_interface is empty, ping6 -I will treat -c as the interface name and the probe will fail, producing an empty/unparseable packet-loss result.
      gwIp=$(/sbin/ip -6 route | awk '/default/ { print $3 }' | head -n1 | awk '{print $1;}')
      gwIp_interface=$(/sbin/ip -6 route | awk '/default/ { print $5 }' | head -n1 | awk '{print $1;}')
      pingCmd="ping6 -I $gwIp_interface"

Comment on lines +238 to +239
gwIp_interface=$(/sbin/ip -4 route | awk '/default/ { print $5 }' | head -n1 | awk '{print $1;}')
pingCmd="ping -I $gwIp_interface"
Comment on lines 49 to 51
tmpFile="/tmp/.Connection.txt"
prevStateFile="/tmp/.ncr_laststate"
wifiDriverErrors=0
Copilot AI review requested due to automatic review settings July 17, 2026 14:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment thread lib/rdk/networkConnectionRecovery.sh
Copilot AI review requested due to automatic review settings July 22, 2026 18:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

lib/rdk/networkConnectionRecovery.sh:239

  • In checkPacketLoss(V4), default-route parsing can yield an interface name when the route is of the form default dev <if> (no via), which makes gwIp non-IP and causes ping to fail / packet loss to become unparseable. Also, building ping -I $gwIp_interface breaks when the interface field is missing/empty (it will consume -c as the interface). Parsing via/dev explicitly and only adding -I when an interface is present avoids both failure modes.
    if [ "$version" = "V4" ] ; then
      gwIp=$(/sbin/ip -4 route | awk '/default/ { print $3 }' | head -n1 | awk '{print $1;}')
      gwIp_interface=$(/sbin/ip -4 route | awk '/default/ { print $5 }' | head -n1 | awk '{print $1;}')
      pingCmd="ping -I $gwIp_interface"

lib/rdk/networkConnectionRecovery.sh:244

  • In checkPacketLoss(V6), the same route parsing issue exists as V4: if the default route does not contain via, gwIp becomes non-IP (often the interface), and ping6 -I $gwIp_interface misbehaves when $gwIp_interface is empty. Parse via/dev explicitly and only add -I when an interface is present.
    elif [ "$version" = "V6" ] ; then
      gwIp=$(/sbin/ip -6 route | awk '/default/ { print $3 }' | head -n1 | awk '{print $1;}')
      gwIp_interface=$(/sbin/ip -6 route | awk '/default/ { print $5 }' | head -n1 | awk '{print $1;}')
      pingCmd="ping6 -I $gwIp_interface"
    fi

@bpunnuru bpunnuru left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

Balaji Punnuru and others added 5 commits July 29, 2026 19:22
…led.

Signed-off-by: Balaji Punnuru <Balaji_Punnuru@comcast.com>
…covery trigger

Recovery now fires only when no routed IP stack has acceptable
connectivity and at least one routed stack is at/above the reassociate
tolerance. This fixes the IPv4-only / IPv6-only case where a stack with
no default route left packetsLost at 0 and suppressed recovery.

Also folded in reliability/logging fixes:
- clear stale gwIp on the V6 test-hook path
- guard packet-loss comparisons against unparseable ping output
- emit SYST_WARN_GW100PERC_PACKETLOSS to the logs file on every run
- ping the IPv4 default-route interface explicitly (ping -I)
- log total ipv4/ipv6 packet loss when above threshold
- simplify the trigger to anyGood/anyBad classification
… packet-loss fix

- Introduce a log() helper that prepends the timestamp and appends to
  $logsFile, and convert the timestamped echo call sites to use it.
- Rename packetsLostipv4/packetsLostipv6 globals to
  ipv4PacketLoss/ipv6PacketLoss for clarity.
- Reset the per-call packetLoss to "" at the top of checkPacketLoss and
  guard the packet-loss telemetry block with [ -n "$packetLoss" ], so a
  routeless or unparseable ping no longer reuses the other family's value
  or triggers integer-comparison errors.
- Fix a "[" spacing bug in checkWifiDrvErrors.

Telemetry markers and t2CountNotify calls are unchanged.
…ate change

Emit a "network state changed" line with the per-stack route-present flags
and packet-loss values only when the snapshot differs from the previous run
(persisted in /tmp/.ncr_laststate), so field logs capture every transition
without printing on every run. Debugging aid for customer-site triage.
- Drop the temporary DEBUG_NCR field-debug logging; retain the
  "network state changed" transition log (now unprefixed).
- checkWifiDrvErrors(): $dir already holds the full debugfs path, so remove
  the duplicated /sys/kernel/debug/ieee80211/ prefix from the log messages,
  and capture the cat exit status so the failure log reports the real status
  instead of the enclosing test's result.
- Replace bashisms with POSIX/busybox-ash equivalents: source -> .,
  [[ =~ ]] -> case, [[ ]] -> [ ], and {1..9} -> explicit list (the brace
  form never expands under busybox ash, which had left the
  WIFIV_WARN_PL_20..90PERC packet-loss markers non-functional on target).
- Minor whitespace cleanup in checkDnsFile().
Reinstate the field-triage log marker for 100% packet loss that was lost
when checkPacketLoss() moved to a tolerance-based recovery decision. The
new log-only marker "100% Packet loss is observed on all routed IP stacks"
fires when every routed IP stack shows exactly 100% loss. It is independent
of WifiReassociateTolerance and does not alter the recovery/return path, so
recovery behaviour is unchanged. Unlike the legacy dual-stack
"...for both ipv4 and ipv6" print, it is also emitted correctly on
IPv4-only and IPv6-only networks. Triage associates the old and new strings
to the same 100%-packet-loss marker for trend continuity across images.

Also capitalise the "Packet loss more than 10% observed" marker (was
lowercase "packet loss ...") since triage marker matching is case-sensitive.
Copilot AI review requested due to automatic review settings July 29, 2026 13:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

lib/rdk/networkConnectionRecovery.sh:239

  • In checkPacketLoss(V4), the interface is parsed as field 5 from ip route, and then used unconditionally with ping -I. For some valid default-route formats (e.g. default dev eth0 ...), field positions differ and $gwIp_interface can be empty/incorrect, which can make ping -I treat -c as the interface and break packet-loss detection.
    if [ "$version" = "V4" ] ; then
      gwIp=$(/sbin/ip -4 route | awk '/default/ { print $3 }' | head -n1 | awk '{print $1;}')
      gwIp_interface=$(/sbin/ip -4 route | awk '/default/ { print $5 }' | head -n1 | awk '{print $1;}')
      pingCmd="ping -I $gwIp_interface"

lib/rdk/networkConnectionRecovery.sh:243

  • In checkPacketLoss(V6), ping6 -I $gwIp_interface is built even if the route parse fails to produce an interface (or the default route format doesn’t place the interface in field 5). This can turn into ping6 -I -c ... and cause packet loss to be treated as unmeasurable.
    elif [ "$version" = "V6" ] ; then
      gwIp=$(/sbin/ip -6 route | awk '/default/ { print $3 }' | head -n1 | awk '{print $1;}')
      gwIp_interface=$(/sbin/ip -6 route | awk '/default/ { print $5 }' | head -n1 | awk '{print $1;}')
      pingCmd="ping6 -I $gwIp_interface"

lib/rdk/networkConnectionRecovery.sh:250

  • gwResponse captures only stdout from ping. If ping fails due to invalid arguments (e.g., malformed -I), gwResponse becomes empty and packetLoss parses as empty, leading to malformed telemetry lines like TELEMETRY_GATEWAY_PACKET_LOSS:,$gwIp. Consider capturing stderr and forcing a numeric fallback when the packet-loss parse fails.
    gwResponse=$($pingCmd -c "$pingCount" -i "$pingInterval" "$gwIp")
    packetLoss=$(echo "$gwResponse" | grep "packet"|awk '{print $7}'|cut -d'%' -f1)

@nhanasi
nhanasi merged commit 244c7a0 into develop Jul 29, 2026
5 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 29, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants