Skip to content

Miscellanous network fixes and improvements#2186

Merged
limetech merged 37 commits into
unraid:masterfrom
bergware:master
May 10, 2025
Merged

Miscellanous network fixes and improvements#2186
limetech merged 37 commits into
unraid:masterfrom
bergware:master

Conversation

@bergware

@bergware bergware commented May 8, 2025

Copy link
Copy Markdown
Contributor
  • allow static IP assignments to co-exist with wireless
  • allow docker host access on wireless interface
  • improved automatic metric assignments
  • improved IP selection on interfaces

Summary by CodeRabbit

  • New Features

    • Added background monitoring of network interfaces to dynamically manage static IP assignments.
    • Introduced separate storage for static IP assignments to improve configuration management.
  • Improvements

    • Centralized and simplified metric calculation using interface indices for consistent network management.
    • Enhanced Docker and wireless network handling with refined IP address and metric assignments.
    • Updated UI elements for default gateway metrics to reflect simplified metric logic.
    • Improved route filtering and address selection focusing on primary global addresses.
    • Optimized service reload and monitoring scripts for immediate and efficient execution.
    • Refined Docker network setup and teardown with selective IP and metric management.
    • Unified IP version handling in wireless scripts with explicit parameters and dynamic metrics.
    • Improved IP address extraction methods and network interface state polling for better reliability.
    • Added helper functions across scripts to standardize interface index retrieval and variable extraction.
    • Enhanced network interface state monitoring with stable state detection and dynamic IP management.
  • Bug Fixes

    • Prevented interference with wireless connections by flushing IP addresses on interface state changes.
  • Chores

    • Updated script metadata and comments for accuracy.
    • Enhanced logging and background execution for network monitoring utilities.

@coderabbitai

coderabbitai Bot commented May 8, 2025

Copy link
Copy Markdown
Contributor
## Walkthrough

This update introduces significant improvements to network interface management and metric assignment across Unraid OS scripts and plugins. Key changes include dynamic calculation of interface metrics based on sysfs indices, refined address and route handling for Docker and wireless interfaces, and the introduction of a new monitoring script for static IP assignments. Several helper functions were added, and command invocations were updated for precision and consistency.

## Changes

| File(s)                                                                                      | Change Summary |
|----------------------------------------------------------------------------------------------|----------------|
| emhttp/plugins/dynamix/Eth0.page, emhttp/plugins/dynamix/EthX.page                          | Simplified the `metric()` function to use only interface name; updated all metric calls to match new signature and concatenation style for VLANs. Adjusted JavaScript event handling for VLAN removal. |
| emhttp/plugins/dynamix/include/RoutingTable.php                                              | Extended route filtering in IP route queries to exclude `linkdown` and `broadcast` (IPv4) and `linkdown` (IPv6). |
| emhttp/plugins/dynamix/scripts/reload_services, emhttp/plugins/dynamix/scripts/update_services | Changed service reload scheduling to use explicit `sleep` in shell before execution, removing direct delay argument passing and immediate queue checking. |
| etc/rc.d/rc.docker                                                                          | Added `index()` and `active()` helpers; refined Docker network interface setup and teardown with improved address and route handling, conditional IP assignment using interface indices, disabled IPv6 on shim interfaces, and enhanced output suppression. Removed complex route metric adjustments and network update checks. |
| etc/rc.d/rc.inet1                                                                           | Updated metadata; added `index()` helper; renamed and simplified carrier check; improved static IP metric assignment using interface indices; disabled IPv6 on macvtap interfaces. |
| etc/rc.d/rc.library.source                                                                  | Changed `ip` command options from `-temporary` to `primary` for address filtering in interface address display and checks. |
| etc/rc.d/rc.local                                                                           | Added silent background launch of `monitor_interface` if present; redirected output of `monitor_nchan` to `/dev/null`. |
| etc/rc.d/rc.nginx                                                                           | Refined LAN IP address extraction in `build_ssl` to use `scope global primary` and reordered filtering commands for precision. Updated file header. |
| etc/rc.d/rc.wireless                                                                        | Added `index()` and `var()` helpers; dynamic metric calculation for IP assignment; unified IP version handling with explicit parameters; added Docker shim interface IPv4 address management; improved cleanup and conditional service restarts based on DNS assignment. |
| sbin/create_network_ini                                                                     | Added `statics.ini.new` for static IP storage; introduced helpers (`var`, `index`, `mask2cidr`); refined IP queries to filter primary addresses; added Docker interface IP management triggered by DHCP events; updated welcome message IP queries. |
| sbin/monitor_interface                                                                      | New script to monitor interfaces and manage static IPs from `statics.ini`, dynamically adding/removing addresses based on link state changes with stability checks and file change detection. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant WebGUI
    participant rc.inet1
    participant rc.wireless
    participant rc.docker
    participant monitor_interface
    participant statics.ini

    User->>WebGUI: Configures network settings
    WebGUI->>rc.inet1: Applies static IPs (uses index() for metric)
    WebGUI->>rc.wireless: Sets wireless IPs (uses index() for metric)
    rc.inet1->>statics.ini: Writes static IP assignments
    rc.wireless->>statics.ini: Writes static IP assignments
    Note over rc.docker: Docker interface setup uses index() for metrics
    monitor_interface->>statics.ini: Reads static IPs and metrics
    monitor_interface->>Network Interfaces: Adds/removes static IPs on link state change

Possibly related PRs

Suggested reviewers

  • ljm42

Poem

🐇
A hop, a skip, a metric anew,
Interfaces counted, precision grew.
Now Docker and Wi-Fi, with metrics so neat,
Assign their addresses, never miss a beat.
With scripts that watch and numbers that flow,
The network’s a garden where good packets grow!


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=unraid/webgui&utm_content=2186):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 14

♻️ Duplicate comments (2)
emhttp/plugins/dynamix/EthX.page (1)

215-217: Same early-evaluation issue for IPv6 template — see previous comment.

etc/rc.d/rc.docker (1)

535-538: ⚠️ Potential issue

docker_network_stop: same ip -br … primary issue

The cleanup pulls an IPv4 string using the unsupported selector:

NET=$(ip -4 -br addr show scope global primary dev shim-wlan0 …)

If the command prints nothing, the subsequent ip addr del is skipped—leaking addresses and leaving shim-wlan0 dirty. Please fix as in earlier comment.

🧹 Nitpick comments (8)
etc/rc.d/rc.nginx (1)

9-9: Update header year once, avoid churn
The header already carries a LimeTech + Bergware stamp; adding a new dated line every micro-change quickly clutters the prologue. Recommend replacing the date with a single “Last-modified:” line that is updated automatically by the build.

emhttp/plugins/dynamix/EthX.page (1)

186-191: Server-side metric default works, but loses IPv4/IPv6 separation
metric('ethX') now yields a single value for both IPv4 and IPv6 default-gateway rows.
If users need independent tweaking (e.g. higher IPv6 metric to prefer IPv4) they’ve lost the knob.

Provide separate defaults or expose one combined “metric” input only when both protocols share the gateway.

sbin/monitor_interface (1)

52-71: Multiple monitors possible – add PID/lockfile
rc.local starts this script in the background but nothing prevents a second instance after reboot or manual invocation, leading to duplicate ip addr add executions.

Create /var/run/monitor_interface.pid and exit when already running.

etc/rc.d/rc.inet1 (1)

385-396: Carrier check good, but DHCP fallback ignores DHCP_METRIC removal
When DHCP is chosen and DHCP_METRIC is empty (now common after automatic metrics), the prior logic to drop -m is fine, yet you removed the explicit -G guard for IPv6. Ensure dhcpcd still honours a default metric when none supplied.

emhttp/plugins/dynamix/Eth0.page (1)

476-480: removeVLAN – make sure the change event is fired on the correct select element

After removing a VLAN row you now resolve the form with closest('form') – good – but you still trigger change on .first() any select. If the first select is disabled/hidden the UI might not refresh.

Recommend narrowing the selector to the protocol field that drives visibility:

- form.find('select').first().trigger('change');
+ form.find('select[name^="PROTOCOL:"]').first().trigger('change');

This guarantees the re-validation logic (selectProtocol) runs.

sbin/create_network_ini (1)

37-49: mask2cidr / cidr2mask rely on nested eval – fragile & unsafe

Both helpers use double-evaluated arithmetic strings; a malformed or malicious netmask/prefix could craft arbitrary arithmetic, and future shell-option hardening (set -euo pipefail, nounset, errexit) will break on expansion errors.

A more robust, readable implementation avoids eval entirely:

mask2cidr() { 
  local IFS=. n=0 oct
  for oct in $1; do
    case $oct in
      255) n=$((n+8));;
      254) n=$((n+7));;
      252) n=$((n+6));;
      248) n=$((n+5));;
      240) n=$((n+4));;
      224) n=$((n+3));;
      192) n=$((n+2));;
      128) n=$((n+1));;
       0)  break;;
      *)  return 1;;           # invalid mask
    esac
  done
  echo "$n"
}

cidr2mask() {
  local n=$1 mask=
  for ((i=0;i<4;i++)); do
    if ((n>=8)); then mask+=255; n=$((n-8))
    else mask+=$((256-2**(8-n))); n=0
    fi
    ((i<3)) && mask+=.
  done
  echo "$mask"
}

Sacrificing a few lines yields auditability and eliminates eval.

etc/rc.d/rc.wireless (1)

138-144: Quote variables in ip addr/route add to survive spaces & empties

The static path now looks like:

[[ -n $IP4 && -n $MASK4 ]] && run ip -4 addr add $(unzero $IP4)/$MASK4 metric $INDEX dev $PORT

If $IP4 is empty the test prevents execution, but unquoted $MASK4 or $INDEX containing unexpected whitespace still cause word-splitting. Safer:

- run ip -4 addr add $(unzero $IP4)/$MASK4 metric $INDEX dev $PORT
+ run ip -4 addr add "$(unzero "$IP4")/$MASK4" metric "$INDEX" dev "$PORT"

Apply the same pattern to IPv6 pathways.

etc/rc.d/rc.docker (1)

457-465: Metric computation may collide and overrun

metric $((1000 - 1 + $(index $NETWORK))) gives 999 + ifindex.
Two different shim interfaces can end up with the same metric when underlying NICs share the same ifindex modulo 1000 (e.g. wlan0 = 5, eth0 = 2 produce 1004 vs 1001 – fine, but eth1 with ifindex = 1003 → 2002 exceeds Linux metric limit 1024).
Additionally, negative or blank values break the arithmetic (see first comment).

Recommend:

  1. Cap the metric ≤ 1024.
  2. Use a dedicated base per NIC family to avoid collisions.

Example:

base=800   # shim metric base
idx=$(index "$NETWORK")
(( idx=idx?idx:1 ))
metric=$(( base + idx ))
(( metric>1024 )) && metric=$((1024 - idx))
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 24b40ee and d8c5b24.

📒 Files selected for processing (13)
  • emhttp/plugins/dynamix/Eth0.page (8 hunks)
  • emhttp/plugins/dynamix/EthX.page (6 hunks)
  • emhttp/plugins/dynamix/include/RoutingTable.php (1 hunks)
  • emhttp/plugins/dynamix/scripts/reload_services (0 hunks)
  • emhttp/plugins/dynamix/scripts/update_services (1 hunks)
  • etc/rc.d/rc.docker (7 hunks)
  • etc/rc.d/rc.inet1 (28 hunks)
  • etc/rc.d/rc.library.source (3 hunks)
  • etc/rc.d/rc.local (1 hunks)
  • etc/rc.d/rc.nginx (2 hunks)
  • etc/rc.d/rc.wireless (6 hunks)
  • sbin/create_network_ini (10 hunks)
  • sbin/monitor_interface (1 hunks)
💤 Files with no reviewable changes (1)
  • emhttp/plugins/dynamix/scripts/reload_services
🔇 Additional comments (9)
etc/rc.d/rc.local (2)

83-86: Effective addition of background interface state monitoring.

This new block adds continuous monitoring of network interface states, which aligns well with the PR objective of allowing static IP assignments to coexist with wireless connections. Running it silently with output redirected to /dev/null is appropriate for a background process.


90-90: Consistent handling of monitor process outputs.

Redirecting the output to /dev/null for both monitoring processes ensures consistent behavior and prevents unnecessary output in logs.

emhttp/plugins/dynamix/include/RoutingTable.php (1)

29-30: Improved route filtering for better network visibility.

The enhanced filtering patterns now exclude linkdown and broadcast routes from IPv4 output and linkdown from IPv6 output. This provides a cleaner, more relevant routing table display by removing non-operational or system-internal routes.

These changes align with the PR's objective of improving network configuration flexibility and reliability by ensuring that only meaningful routes are displayed to users.

emhttp/plugins/dynamix/scripts/update_services (1)

18-18: Improved service reload scheduling mechanism.

This change separates the delay logic from the reload_services script, making the process more modular. Now the script schedules a job that performs the delay before calling reload_services without arguments.

This approach provides better separation of concerns - the delay handling is managed by the scheduling system rather than being embedded in the reload_services script itself.

etc/rc.d/rc.library.source (3)

8-8: Updated timestamp reflecting recent modifications.

The timestamp update to May 2025 properly documents when the script was last modified.


59-60: Enhanced IP address selection using primary flag.

Replacing -temporary with primary when listing global scoped IP addresses improves how primary IP addresses are filtered in the show() function. This is a more precise selection criterion for identifying the main IP addresses that should be used for services.

This change aligns with the PR's objective of improving IP selection on network interfaces.


163-163: Consistent address filtering in interface checks.

This change ensures consistent IP address filtering by using the same primary flag in the check() function, maintaining a uniform approach to IP address selection throughout the script.

The change supports the PR's objective of improving automatic metric assignments and IP selection by ensuring that the most appropriate addresses are consistently identified.

etc/rc.d/rc.nginx (1)

540-545: Verify ip flag order – risk of empty LANIP/LANIP6
ip -4 -br addr show scope global primary dev $DEV is valid, however the IPv6 variant
ip -6 -br addr show scope global primary -deprecated dev $DEV relies on a very recent iproute2 where the -deprecated negation flag can follow other selectors.
On older releases the parser errors out and nothing is returned, leaving both LANIP/LANIP6 empty and causing the self-signed certificate logic to mis-behave.

Consider a safer, backwards-compatible form:

LANIP6=$(ip -6 -br addr show dev "$DEV" scope global primary | awk '{print $3;exit}' | sed 's/\/[0-9]*//')
# …then filter deprecated locally:
[[ $(ip -6 addr show dev "$DEV" primary deprecated scope global) ]] && LANIP6=

Or guard the command with || true plus a fallback.

sbin/monitor_interface (1)

60-62: Missing prefixlen will fail on older kernels
ip addr add 192.0.2.5 metric 1000 dev eth1 is rejected unless the address includes the CIDR suffix.
Make sure $IPV4[$i] and $IPV6[$i] carry /xx; otherwise append the correct prefix or abort gracefully.

Comment thread emhttp/plugins/dynamix/EthX.page
Comment thread sbin/monitor_interface
Comment thread etc/rc.d/rc.inet1
Comment thread etc/rc.d/rc.inet1
Comment thread etc/rc.d/rc.inet1
Comment thread etc/rc.d/rc.wireless Outdated
Comment thread etc/rc.d/rc.docker Outdated
Comment thread etc/rc.d/rc.docker
Comment thread etc/rc.d/rc.docker Outdated
Comment thread etc/rc.d/rc.docker

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 4

♻️ Duplicate comments (12)
emhttp/plugins/dynamix/EthX.page (1)

384-408: ⚠️ Potential issue

metric() still called with literal placeholder – breaks new signature & VLAN cloning

metric('ethX.INDEX') is evaluated server-side before JS replaces INDEX, so metric() receives the non-existing interface name ethX.INDEX.
After the recent refactor, metric() expects a real interface (e.g. ethX or ethX.100). The current code therefore returns null/empty, leaving the Metric box blank and confusing users cloning VLANs.

Same issue for the IPv6 field a few lines below.

-  <input type="text" name="METRIC:INDEX" ... value="<?=metric('ethX.INDEX')?>" ...
+  <!-- defer metric calculation until JS knows the actual VLAN id -->
+  <input type="text" name="METRIC:INDEX"
+         data-iface="ethX"
+         value="{{metric_placeholder}}"
+         ...
+  >

Then, in addVLAN() (or equivalent), replace {{metric_placeholder}} with
metric('ethX.' + vlanId) once the new row is instantiated.

This restores correct defaults and resolves the long-standing bug reported earlier.

sbin/monitor_interface (1)

25-33: 🛠️ Refactor suggestion

switch() returns too early – flaps mis-detected after first second

The loop exits on the first match, so even if the interface toggles back
within the 5-second window the change is acted upon.

-for n in {1..5}; do
-  [[ $(state $1) == $2 ]] && return 1 || sleep 1
-done
-return 0
+local stable=0
+for n in {1..5}; do
+  [[ $(state $1) == $2 ]] && stable=$((stable+1)) || stable=0
+  sleep 1
+done
+(( stable == 5 )) && return 1 || return 0

This keeps monitoring until the new state stays unchanged for the full grace
period, eliminating false positives on transient carrier drops.

etc/rc.d/rc.docker (1)

38-41: Guard index() against missing /sys entries

If the interface disappears (USB NIC removed, race condition) cat returns
non-zero and the arithmetic expansion using its output aborts the script.

-index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
-}
+index(){
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
+}
emhttp/plugins/dynamix/Eth0.page (2)

58-65: Metric helper still shells-out & is injection-prone – previous concerns remain
The new metric() implementation keeps using exec("cat …") with raw $eth interpolation. The performance hit (forking cat twice per call) and the potential for command-injection that I pointed out earlier are still present. Please consider replacing the subshells with file_get_contents() (or similar) and hardening the input as suggested in the earlier review.


922-944: Server-side call metric('eth0.INDEX') is evaluated before INDEX is replaced → duplicate metrics
Because the placeholder hasn’t been substituted yet, every newly added VLAN receives the same pre-calculated metric. This was reported in the previous review and is still unresolved.

etc/rc.d/rc.inet1 (3)

401-402: Wildcard fallback still expands to filenames – duplicate index collision risk
$(index *) expands * in the current directory, not to interface names, so the arithmetic still collapses to “highest index + 1 == 1001” for most cases, recreating the collision reported earlier.


407-408: ip addr add … metric … is not accepted by iproute2 (metric belongs to routes)
The address is accepted but the metric is silently ignored (or yields “either ‘peer’ or ‘broadcast’ expected” on older kernels). You need to set the metric on the route, not on the address – see the previous review for two safe patterns.

Also applies to: 414-415


156-160: ⚠️ Potential issue

index() returns empty on race → arithmetic expansion will abort script
If /sys/class/net/<iface>/ifindex is momentarily unreadable the function echoes nothing.
Later, INDEX=$((1000 + ${INDEX:- … })) will receive an empty operand and bash aborts with “value too great for base” (or similar). Provide a default of 0 and guard against read errors:

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local f="$SYSTEM/$1/ifindex"
+  [[ -r $f ]] && cat "$f" || echo 0
}
sbin/create_network_ini (1)

32-36: Same fragile index() helper as in rc.inet1
Empty output when ifindex is unreadable will break the arithmetic later in the script (lines 258 ff). Please apply the same fallback logic proposed for rc.inet1.

etc/rc.d/rc.wireless (3)

15-15: ⚠️ Potential issue

$SERVICE vs $SERVICES – variable name still inconsistent

You export SERVICES="/usr/local/emhttp/webGui/scripts/update_services" but later invoke $SERVICE (singular). The typo prevents the script responsible for (re)loading services from ever running.

-[[ $SRV4 == no && (-z $SRV6 || $SRV6 == no) ]] && $SERVICE 5
+[[ $SRV4 == no && (-z $SRV6 || $SRV6 == no) ]] && $SERVICES 5

Do the same replacement in every occurrence (lines 278 & 337).


135-136: ⚠️ Potential issue

Wildcard misuse (index *) still produces unreliable metrics

Passing * to index expands to all filenames in the working directory.
Only the first arg is honoured, so the highest interface index is never found, and the resulting metric may collide with an existing one.

-INDEX=$(index $PORT)
-INDEX=$((3000 + ${INDEX:-$(($(index * | sort -n | tail -1) + 1))}))
+# First try the real ifindex of $PORT ; otherwise derive the max index + 1
+INDEX=$(index "$PORT")
+if [[ -z $INDEX ]]; then
+  INDEX=$(ls -1 "$SYSTEM"/*/ifindex | xargs -n1 cat | sort -n | tail -1)
+  INDEX=$((INDEX + 1))
+fi
+INDEX=$((3000 + INDEX))

278-279: ⚠️ Potential issue

Undefined $SERVICE still used when restarting services

Same typo as previously reported — replace with $SERVICES or rename the variable consistently across the script to ensure conditional service restarts work.

Also applies to: 337-338

🧹 Nitpick comments (2)
emhttp/plugins/dynamix/Eth0.page (1)

730-731: min="0" accepts metric 0 but UI text says “lower is more preferred” – still confusing
Allowing 0 here while VLAN templates start at 1 keeps the old inconsistency. It also collides with Linux’ default‐route metric if other tools later normalise to 0. Consider aligning all numeric inputs (METRIC, METRIC6) to the same lower bound.

Also applies to: 753-754

etc/rc.d/rc.wireless (1)

32-35: Function index() needs quoting & safer path handling

  1. $1 is interpolated into a path without quotes, so interface names with glob/IFS characters could break.
  2. cat will emit an error when $SYSTEM/$1/ifindex is missing; consider returning a default or propagating a clear error.

Minimal hardening:

-index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+index() {
+  local ifname=$1
+  [[ -r "$SYSTEM/$ifname/ifindex" ]] && cat "$SYSTEM/$ifname/ifindex"
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 24b40ee and 288dca6.

📒 Files selected for processing (13)
  • emhttp/plugins/dynamix/Eth0.page (8 hunks)
  • emhttp/plugins/dynamix/EthX.page (6 hunks)
  • emhttp/plugins/dynamix/include/RoutingTable.php (1 hunks)
  • emhttp/plugins/dynamix/scripts/reload_services (0 hunks)
  • emhttp/plugins/dynamix/scripts/update_services (1 hunks)
  • etc/rc.d/rc.docker (7 hunks)
  • etc/rc.d/rc.inet1 (28 hunks)
  • etc/rc.d/rc.library.source (3 hunks)
  • etc/rc.d/rc.local (1 hunks)
  • etc/rc.d/rc.nginx (2 hunks)
  • etc/rc.d/rc.wireless (6 hunks)
  • sbin/create_network_ini (10 hunks)
  • sbin/monitor_interface (1 hunks)
💤 Files with no reviewable changes (1)
  • emhttp/plugins/dynamix/scripts/reload_services
🔇 Additional comments (8)
etc/rc.d/rc.local (2)

83-86: Monitor interface addition improves network stability

This new code block integrates the interface state monitoring system into the Unraid OS startup process, which is essential for dynamically managing static IP assignments as interfaces change state.


90-90: Output redirection is properly aligned with previous change

Modifying the monitor_nchan invocation to redirect output to /dev/null keeps error handling consistent with the newly added monitor_interface invocation.

emhttp/plugins/dynamix/scripts/update_services (1)

18-18: Improved separation of concerns in service reloading

This modification properly decouples delay handling from the reload_services script by using the 'at' command to schedule execution after the specified delay. This approach is more flexible and follows better scripting practices.

emhttp/plugins/dynamix/include/RoutingTable.php (1)

29-30: Enhanced routing table filtering improves UI relevance

The extended grep patterns remove unnecessary routes like linkdown and broadcast entries from the routing table display. This makes the routing table more focused on relevant, active routes that administrators need to see.

These improvements align well with the PR objective of enhancing IP selection on network interfaces by ensuring only relevant route entries are shown in the UI.

etc/rc.d/rc.library.source (3)

8-8: Version comment updated appropriately

The timestamp in the comment has been updated to reflect the latest changes to the file.


59-60: Improved IP address filtering for better network management

Switching from -temporary to primary flag in the IP command focuses on primary addresses, which is a more appropriate filtering approach for interface management.

This change is crucial for the PR objective of allowing static IP assignments to coexist with wireless connections, as it ensures that the system correctly identifies and uses primary addresses for network operations.


163-163: Consistent primary address filtering in network interface detection

This change maintains consistency with the earlier modifications to use primary address filtering instead of temporary address exclusion.

The approach of focusing on primary addresses across all IP address retrieval operations in the library creates a more reliable basis for the automatic metric assignments mentioned in the PR objectives.

emhttp/plugins/dynamix/Eth0.page (1)

476-480: Nice simplification of removeVLAN selector handling
Using closest('form') followed by a single change trigger makes the intent clearer and removes brittle ID parsing. ✔️

Comment thread etc/rc.d/rc.nginx
Comment thread etc/rc.d/rc.docker
Comment thread sbin/create_network_ini
Comment thread etc/rc.d/rc.wireless Outdated
@bergware bergware marked this pull request as draft May 8, 2025 18:13
@bergware bergware marked this pull request as ready for review May 9, 2025 09:33

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 0

♻️ Duplicate comments (6)
etc/rc.d/rc.docker (6)

38-41: ⚠️ Potential issue

Guard index() against missing /sys entries

The index() function will fail if the interface doesn't exist or if the ifindex file is inaccessible, which could cause script failures when the output is used in arithmetic operations (e.g., line 427, 451).

Apply this fix:

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}

This keeps the script resilient when an interface disappears unexpectedly.


221-221: ⚠️ Potential issue

Fix incompatible primary filter with brief output format

The ip -br addr show command does not support the primary flag, causing $THISIP to be empty and breaking downstream logic.

Replace with:

-    local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
+    local THISIP=$(ip -4 addr show scope global primary dev "$LAN" | awk 'NR==1{print $2}' | cut -d/ -f1)

223-223: ⚠️ Potential issue

Fix incorrect route lookup syntax

The current command doesn't include the to keyword needed for proper routing lookups.

Update to:

-      local NETWORK=$(ip -4 route show "$THISIP" dev "$LAN" | awk '{print $1;exit}')
+      local NETWORK=$(ip -4 route show to "$THISIP" dev "$LAN" | awk '{print $1;exit}')

349-349: ⚠️ Potential issue

Fix incompatible primary filter with brief output format

Same issue as on line 221 - the ip -br addr show command doesn't support primary filtering.

Replace with:

-      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}') || IPV4=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 addr show scope global primary dev "$NETWORK" | awk 'NR==1{print $2}' | cut -d/ -f1) || IPV4=

359-359: 🛠️ Refactor suggestion

Update IPv6 address retrieval to match IPv4 pattern

The IPv6 address retrieval also uses -br which is inconsistent with the needed pattern for primary.

Replace with:

-      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $NETWORK | awk -v RS='[[:space:]]+' '(NR>2){print}' | grep -Pvm1 '^.+/128|^$') || IPV6=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 addr show scope global primary -deprecated dev "$NETWORK" | awk 'NR==1{print $2}' | grep -Pvm1 '^.+/128|^$') || IPV6=

506-508: ⚠️ Potential issue

Fix incompatible primary filter in shim-wlan0 cleanup

The primary filter doesn't work with brief output format here either.

Replace with:

-    NET=$(ip -4 -br addr show scope global primary dev shim-wlan0 | awk '{print $3,$4,$5;exit}')
+    NET=$(ip -4 addr show scope global primary dev shim-wlan0 | awk 'NR==1{print $2,$3,$4}' | cut -d/ -f1)
🧹 Nitpick comments (1)
etc/rc.d/rc.docker (1)

457-458: Consider quoting variables in command substitution

When running commands in a subshell, consider quoting paths and variable references.

-          IPS="$(ip -4 -br addr show scope global dev $VHOST | awk '{$1="";$2="";print;exit}' | sed -r 's/ metric [0-9]+//g')"
+          IPS="$(ip -4 -br addr show scope global dev "$VHOST" | awk '{$1="";$2="";print;exit}' | sed -r 's/ metric [0-9]+//g')"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 1ba2f4b and 7ea1095.

📒 Files selected for processing (1)
  • etc/rc.d/rc.docker (9 hunks)
🔇 Additional comments (3)
etc/rc.d/rc.docker (3)

444-451: Good enhancement: Interface-specific metric calculations

Nice improvement to handle different interface types with appropriate base metrics (3000 for wireless, 1000 for others). This helps prioritize routing correctly between wired and wireless interfaces.


454-459: Good implementation of smart IP assignment

The code now only adds the parent's IPv4 address if not already present, which avoids duplicate addresses. Using metric $INDEX ensures consistent routing priorities.


427-428: Add guard against invalid interface metrics

The metric calculation depends on the index() function which currently doesn't handle errors properly.

If the index() function is updated as recommended, this line should work correctly. Otherwise, ensure that a default value is used if $(index $NETWORK) returns empty:

-          NET="$IPV4 metric $((1000 - 1 + $(index $NETWORK)))"
+          local net_index=$(index $NETWORK)
+          net_index=${net_index:-0}
+          NET="$IPV4 metric $((1000 - 1 + net_index))"

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

♻️ Duplicate comments (3)
etc/rc.d/rc.docker (3)

38-41: Guard index() against missing /sys entries

The new index() function doesn't handle cases where the interface doesn't exist. This could lead to empty values being used in arithmetic expressions, causing "value required" errors that abort the script.

Apply this fix to make the script more resilient when interfaces disappear:

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}

221-223: Fix incorrect IP commands using brief mode with primary filter

The ip -4 -br addr show command with the primary flag doesn't work correctly as the brief mode doesn't support the primary filter. Additionally, the route lookup syntax is incorrect.

Apply these fixes:

-    local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
-    local NETWORK=$(ip -4 route show $THISIP dev $LAN | awk '{print $1;exit}')
+    local THISIP=$(ip -4 addr show scope global primary dev $LAN | awk 'NR==1{print $2}' | cut -d/ -f1)
+    local NETWORK=$(ip -4 route show to $THISIP dev $LAN | awk '{print $1;exit}')

505-508: 🛠️ Refactor suggestion

Fix shim-wlan0 cleanup command

The cleanup for shim-wlan0 uses the problematic brief mode with primary filter that doesn't work correctly.

Apply this fix:

if [[ -e $SYSTEM/shim-wlan0 ]]; then
-  NET=$(ip -4 -br addr show scope global primary dev shim-wlan0 | awk '{print $3,$4,$5;exit}')
+  NET=$(ip -4 addr show scope global primary dev shim-wlan0 | awk 'NR==1{split($2,a,"/"); print a[1]" metric "$NF}')
  [[ -n $NET ]] && run ip addr del $NET dev shim-wlan0
fi
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 7ea1095 and d5305b6.

📒 Files selected for processing (1)
  • etc/rc.d/rc.docker (9 hunks)
🔇 Additional comments (2)
etc/rc.d/rc.docker (2)

404-406: Network removal logic is now unconditional

The code now removes and recreates Docker networks unconditionally, which simplifies logic but could cause momentary network disruptions during restarts.


499-503: Improved condition for selective interface cleanup

This change now properly excludes wlan interfaces from address flushing, which aligns with the dynamic metric approach and prevents potential connectivity issues.

Comment thread etc/rc.d/rc.docker Outdated
Comment thread etc/rc.d/rc.docker Outdated

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

♻️ Duplicate comments (11)
etc/rc.d/rc.docker (11)

221-221: ⚠️ Potential issue

Fix the IP address retrieval to work correctly with 'primary' flag

The ip -br command doesn't support the primary filter, causing this command to return nothing and breaking downstream logic.

-local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
+local THISIP=$(ip -4 addr show scope global primary dev $LAN | awk 'NR==1{print $2}' | cut -d/ -f1)

This change uses the full-format command which properly supports the primary flag.


223-223: ⚠️ Potential issue

Add the to keyword to ensure correct route lookup

The current route lookup syntax is incorrect and may fail to retrieve the network.

-local NETWORK=$(ip -4 route show $THISIP dev $LAN | awk '{print $1;exit}')
+local NETWORK=$(ip -4 route show to $THISIP dev $LAN | awk '{print $1;exit}')

Without the to keyword, $NETWORK may be empty and subsequent operations will fail.


348-348: ⚠️ Potential issue

Fix IPv4 retrieval for custom networks

Same issue as line 221 - the brief format doesn't support primary filtering.

-[[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}') || IPV4=
+[[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 addr show scope global primary dev $NETWORK | awk 'NR==1{print $2}' | cut -d/ -f1) || IPV4=

359-359: ⚠️ Potential issue

Fix IPv6 retrieval for custom networks

Same issue as with the IPv4 retrieval - brief format doesn't support primary filtering.

-[[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $NETWORK | awk -v RS='[[:space:]]+' '(NR>2){print}' | grep -Pvm1 '^.+/128|^$') || IPV6=
+[[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 addr show scope global primary -deprecated dev $NETWORK | awk '/inet6/{print $2}' | grep -Pvm1 '^.+/128|^$') || IPV6=

427-428: 🛠️ Refactor suggestion

Add safeguards to the metric calculation for bridge networks

The current implementation could fail if the index function returns nothing.

-NET="$IPV4 metric $((1000 - 1 + $(index $NETWORK)))"
+local idx=$(index $NETWORK)
+idx=${idx:-0}
+NET="$IPV4 metric $((1000 - 1 + idx))"

This change stores the index in a variable with a default value of 0 if empty.


431-431: 🛠️ Refactor suggestion

Add existence check before writing to IPv6 configuration

The current implementation assumes the IPv6 configuration directory exists.

-echo 1 >$CONF6/$LINK/disable_ipv6
+[[ -d $CONF6/$LINK ]] && echo 1 >$CONF6/$LINK/disable_ipv6

This change prevents errors if the directory doesn't exist.


451-451: 🛠️ Refactor suggestion

Add safeguards to the metric calculation for non-bridge interfaces

Same issue as line 427 - needs protection against empty index values.

-INDEX=$(($INDEX - 1 + $(index $NETWORK)))
+local idx=$(index $NETWORK)
+idx=${idx:-0}
+INDEX=$(($INDEX - 1 + idx))

454-454: 🛠️ Refactor suggestion

Add existence check before writing to IPv6 configuration

Same issue as line 431 - needs to check if the directory exists.

-echo 1 >$CONF6/$VHOST/disable_ipv6
+[[ -d $CONF6/$VHOST ]] && echo 1 >$CONF6/$VHOST/disable_ipv6

457-457: 🛠️ Refactor suggestion

Fix IP address retrieval for vhost interface

The current implementation might not correctly extract IP addresses.

-IPS="$(ip -4 -br addr show scope global dev $VHOST | awk '{$1="";$2="";print;exit}' | sed -r 's/ metric [0-9]+//g')"
+IPS="$(ip -4 addr show scope global dev $VHOST | awk '{for(i=1;i<=NF;i++) if($i~/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+$/) {print $i}}' | sed -r 's/ metric [0-9]+//g')"

This change uses a more robust pattern matching approach to extract IPv4 addresses.


506-506: ⚠️ Potential issue

Fix IP address retrieval for shim-wlan0 cleanup

Same issue as other IP retrieval lines - brief format doesn't support primary filtering.

-NET=$(ip -4 -br addr show scope global primary dev shim-wlan0 | awk '{print $3,$4,$5;exit}')
+NET=$(ip -4 addr show scope global primary dev shim-wlan0 | awk 'NR==1{print $2,$3,$4}' | sed 's|/[0-9]*||')

38-41: 🛠️ Refactor suggestion

Strengthen the index() function against missing interfaces

This new helper function reads interface indices from sysfs, but lacks error handling when interfaces don't exist. When used in arithmetic expressions (lines 427, 451), it could cause script failures.

Apply this defensive implementation:

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}

This ensures a default value of 0 when an interface doesn't exist or is temporarily unavailable, preventing arithmetic errors.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 255f3b9 and 82026ec.

📒 Files selected for processing (1)
  • etc/rc.d/rc.docker (10 hunks)

Comment thread etc/rc.d/rc.docker Outdated

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

♻️ Duplicate comments (10)
etc/rc.d/rc.docker (10)

221-226: ⚠️ Potential issue

Fix broken ip command with unsupported primary flag in brief mode

The ip -br addr show command does not support the primary flag, causing the command to potentially return nothing, which breaks downstream logic.

Apply this fix:

-    local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
+    local THISIP=$(ip -4 addr show scope global primary dev $LAN | awk 'NR==1{print $2}' | cut -d/ -f1)

38-41: ⚠️ Potential issue

Implement error handling for the index() function

The index() function could return an empty string if the interface doesn't exist or the file isn't readable, which would cause arithmetic errors when used in expressions like $((1000 - 1 + $(index $NETWORK))).

Apply this fix to make the function resilient to missing interfaces:

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}

227-229: ⚠️ Potential issue

Add missing to keyword in route lookup

The route lookup command is missing the to keyword, which can cause $NETWORK to be empty when calling ip route add inside the container.

Apply this fix:

-      local NETWORK=$(ip -4 route show $THISIP dev $LAN | awk '{print $1;exit}')
+      local NETWORK=$(ip -4 route show to $THISIP dev $LAN | awk '{print $1;exit}')

341-342: ⚠️ Potential issue

Fix unsupported primary flag in brief IP command (IPv4)

The ip -br addr show command does not support the primary flag here too, causing the command to potentially return nothing.

Apply this fix:

-      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}') || IPV4=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 addr show scope global primary dev $NETWORK | awk 'NR==1{print $2}' | cut -d/ -f1) || IPV4=

352-353: ⚠️ Potential issue

Fix unsupported primary flag in brief IP command (IPv6)

The ip -br addr show command does not support the primary flag for IPv6 address selection either.

Apply this fix:

-      # get IPv6 address - ignore any /128 networks
-      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $NETWORK | awk -v RS='[[:space:]]+' '(NR>2){print}' | grep -Pvm1 '^.+/128|^$') || IPV6=
+      # get IPv6 address - ignore any /128 networks
+      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 addr show scope global primary -deprecated dev $NETWORK | awk '!/\/128/ && /inet6/{print $2; exit}') || IPV6=

354-354: ⚠️ Potential issue

Add missing to keyword in IPv6 route lookup

The IPv6 route lookup command is missing the to keyword, which can cause incorrect subnet determination.

Apply this fix:

-        SUBNET6=$(ip -6 route show $IPV6 dev $NETWORK | awk '{print $1;exit}')
+        SUBNET6=$(ip -6 route show to $IPV6 dev $NETWORK | awk '{print $1;exit}')

420-428: ⚠️ Potential issue

Add safeguards to dynamic metric calculation for bridge networks

The metric calculation could fail if the index function returns nothing, and the IPv6 configuration lacks an existence check.

Apply these fixes:

-  NET="$IPV4 metric $((1000 - 1 + $(index $NETWORK)))"
+  local idx=$(index $NETWORK)
+  idx=${idx:-0}
+  NET="$IPV4 metric $((1000 - 1 + idx))"
   # create shim interface
   [[ -e $SYSTEM/$LINK ]] || run ip link add link $NETWORK name $LINK type $ATTACH mode $MODE
   # disable IPv6 on shim interface
-  echo 1 >$CONF6/$LINK/disable_ipv6
+  [[ -d $CONF6/$LINK ]] && echo 1 >$CONF6/$LINK/disable_ipv6

437-452: ⚠️ Potential issue

Add safeguards to dynamic metric calculation for non-bridge interfaces

Similar to the bridge networks, the metric calculation and IPv6 configuration for non-bridge interfaces need safeguards.

Apply these fixes:

  if [[ $TYPE == wlan ]]; then
    VHOST=shim-$NETWORK
    INDEX=3000
  else
    VHOST=vhost${NETWORK//[^0-9.]/}         
    INDEX=1000
  fi
-  INDEX=$(($INDEX - 1 + $(index $NETWORK)))
+  local idx=$(index $NETWORK)
+  idx=${idx:-0}
+  INDEX=$(($INDEX - 1 + idx))
  if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then
    # disable IPv6 on vhost interface
-    echo 1 >$CONF6/$VHOST/disable_ipv6
+    [[ -d $CONF6/$VHOST ]] && echo 1 >$CONF6/$VHOST/disable_ipv6
    run ip -6 addr flush dev $VHOST
    # copy parent IPv4 address to vhost interface
-    IPS="$(ip -4 -br addr show scope global dev $VHOST | awk '{$1="";$2="";print;exit}' | sed -r 's/ metric [0-9]+//g')"
+    IPS="$(ip -4 addr show scope global dev $VHOST | awk '{for(i=1;i<=NF;i++) if($i~/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+$/) {print $i}}' | sed -r 's/ metric [0-9]+//g')"

447-448: ⚠️ Potential issue

Add existence check before manipulating $VHOST IPv6 settings

There's a potential issue when $DOCKER_ALLOW_ACCESS toggles from yes to no, where $VHOST may not exist yet the script attempts to manipulate it.

Add an existence guard for the IPv6 operations:

  # disable IPv6 on vhost interface
-  echo 1 >$CONF6/$VHOST/disable_ipv6
-  run ip -6 addr flush dev $VHOST
+  if [[ -e $SYSTEM/$VHOST ]]; then
+    [[ -d $CONF6/$VHOST ]] && echo 1 >$CONF6/$VHOST/disable_ipv6
+    run ip -6 addr flush dev $VHOST
+  fi

492-495: ⚠️ Potential issue

Fix unsupported primary flag in brief IP command for shim-wlan0 cleanup

Another instance of the same issue with the primary flag in brief mode, this time in the shim-wlan0 cleanup.

Apply this fix:

if [[ -e $SYSTEM/shim-wlan0 ]]; then
-  NET=$(ip -4 -br addr show scope global primary dev shim-wlan0 | awk '{print $3,$4,$5;exit}')
+  NET=$(ip -4 addr show scope global primary dev shim-wlan0 | awk 'NR==1{print $2" "$3" "$4}' | cut -d/ -f1)
  [[ -n $NET ]] && run ip addr del $NET dev shim-wlan0
fi
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between dfd599b and f8eedad.

📒 Files selected for processing (1)
  • etc/rc.d/rc.docker (12 hunks)
🔇 Additional comments (2)
etc/rc.d/rc.docker (2)

42-52: Well-implemented active() function

The new active() function correctly handles interface substitution, resolving physical interfaces to their bridge or bond counterparts when they exist. This improves the network setup logic throughout the script.


398-399: Improved network management strategy

Unconditionally removing and recreating Docker networks ensures a clean state and helps prevent inconsistencies that might arise from partial updates.

Comment thread etc/rc.d/rc.docker
Comment thread etc/rc.d/rc.docker Outdated
@ljm42 ljm42 added the 7.2 label May 9, 2025

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 0

♻️ Duplicate comments (9)
etc/rc.d/rc.docker (9)

516-516: Wrap container_add_route with the run helper for consistent error handling

The container_add_route function itself suppresses errors and doesn't log failures, so invoking it directly will miss both error trapping and logging provided by the run wrapper.

-          container_add_route $CONTAINER
+          run container_add_route $CONTAINER

Let's verify if this change is needed:

#!/bin/bash
echo "Analyzing container_add_route function:"
sed -n '/container_add_route/,/^}/p' etc/rc.d/rc.docker | grep -n "run "

echo
echo "Verify if function handles its own output:"
sed -n '/container_add_route/,/^}/p' etc/rc.d/rc.docker

38-41: ⚠️ Potential issue

Improve the index() function to handle missing interfaces

The function doesn't handle cases where the interface doesn't exist or the read fails, which could lead to errors when using the returned value in arithmetic contexts (lines 424, 448).

Apply this fix to make the script more resilient when an interface disappears:

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}

232-232: ⚠️ Potential issue

Fix unsupported "primary" filter in brief IP commands

The ip -br addr show command does not support the primary flag, which could cause the command to return nothing and break downstream logic.

Replace with:

-    local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
+    local THISIP=$(ip -4 addr show scope global primary dev $LAN | awk 'NR==1{print $2}' | cut -d/ -f1)

234-234: ⚠️ Potential issue

Add the to keyword to ensure correct IPv4 route lookup

The current command syntax for route lookup doesn't specify the "to" keyword, which may cause issues with route identification.

-      local NETWORK=$(ip -4 route show $THISIP dev $LAN | awk '{print $1;exit}')
+      local NETWORK=$(ip -4 route show to $THISIP dev $LAN | awk '{print $1;exit}')

347-348: ⚠️ Potential issue

Fix multiple occurrences of the "primary" filter issue

The ip command with -br and primary doesn't work together here and in several other places.

-      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}') || IPV4=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 addr show scope global primary dev $NETWORK | awk 'NR==1{print $2}' | cut -d/ -f1) || IPV4=

358-360: ⚠️ Potential issue

Fix IPv6 address retrieval and route lookup

Both the IPv6 address retrieval and route lookup have the same issues as the IPv4 ones.

-      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $NETWORK | awk -v RS='[[:space:]]+' '(NR>2){print}' | grep -Pvm1 '^.+/128|^$') || IPV6=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 addr show scope global primary -deprecated dev $NETWORK | awk 'NR==1{print $2}' | grep -Pvm1 '^.+/128|^$') || IPV6=
       if [[ -n $IPV6 ]]; then
-        SUBNET6=$(ip -6 route show $IPV6 dev $NETWORK | awk '{print $1;exit}')
+        SUBNET6=$(ip -6 route show to $IPV6 dev $NETWORK | awk '{print $1;exit}')

424-432: 🛠️ Refactor suggestion

Dynamic metric calculation for bridge networks needs safeguards

The metric calculation could fail if the index function returns nothing, and the IPv6 configuration lacks an existence check.

-          IPV4="$IPV4 metric $((1000 - 1 + $(index $NETWORK)))"
+          local idx=$(index $NETWORK)
+          idx=${idx:-0}
+          IPV4="$IPV4 metric $((1000 - 1 + idx))"
           # create shim interface
           [[ -e $SYSTEM/$LINK ]] || run ip link add link $NETWORK name $LINK type $ATTACH mode $MODE
           # disable IPv6 on shim interface
-          echo 1 >$CONF6/$LINK/disable_ipv6
+          [[ -d $CONF6/$LINK ]] && echo 1 >$CONF6/$LINK/disable_ipv6

441-456: 🛠️ Refactor suggestion

Dynamic metric calculation for non-bridge interfaces needs safeguards

Similar to the bridge network case, the metric calculation and IPv6 configuration need safeguards.

        if [[ $TYPE == wlan ]]; then
          VHOST=shim-$NETWORK
          INDEX=3000
        else
          VHOST=vhost${NETWORK//[^0-9.]/}         
          INDEX=1000
        fi
-        INDEX=$(($INDEX - 1 + $(index $NETWORK)))
+        local idx=$(index $NETWORK)
+        idx=${idx:-0}
+        INDEX=$(($INDEX - 1 + idx))
        if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then
          # disable IPv6 on vhost interface
-          echo 1 >$CONF6/$VHOST/disable_ipv6
+          [[ -d $CONF6/$VHOST ]] && echo 1 >$CONF6/$VHOST/disable_ipv6
          run ip -6 addr flush dev $VHOST
          # copy parent IPv4 address to vhost interface
-          IPS="$(ip -4 -br addr show scope global dev $VHOST | awk '{$1="";$2="";print;exit}' | sed -r 's/ metric [0-9]+//g')"
+          IPS="$(ip -4 addr show scope global dev $VHOST | awk '{for(i=1;i<=NF;i++) if($i~/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+$/) {print $i}}' | sed -r 's/ metric [0-9]+//g')"

497-498: ⚠️ Potential issue

Fix broken IP address retrieval on shim-wlan0

This uses the problematic brief mode for IP address retrieval with primary filter.

-    IPV4=$(ip -4 -br addr show scope global primary dev shim-wlan0 | awk '{print $3,$4,$5;exit}')
+    IPV4=$(ip -4 addr show scope global primary dev shim-wlan0 | awk 'NR==1{print $2}')
🧹 Nitpick comments (1)
etc/rc.d/rc.docker (1)

187-189: New ipv4_exists() function is clean but could use improved command

The function uses -br addr show to which is good, but could be more robust.

Consider using grep for more accurate matching:

ipv4_exists(){
-  ip -4 -br addr show to $2 dev $1 | awk '{print $3;exit}'
+  ip -4 addr show dev $1 | grep -q "inet $2/"
+  return $?
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 3c5b532 and 91ddc7d.

📒 Files selected for processing (1)
  • etc/rc.d/rc.docker (13 hunks)
🔇 Additional comments (2)
etc/rc.d/rc.docker (2)

43-52: Good addition of the active() helper function

This function properly resolves eth interfaces to their active form (br or bond) when applicable, improving consistency throughout the script.


178-179: Good improvement for wireless interfaces

The forced ipvlan driver for wlan interfaces ensures compatibility with wireless networks that don't support promiscuous mode.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

♻️ Duplicate comments (12)
etc/rc.d/rc.docker (12)

38-41: Guard index() against missing /sys entries

The function retrieves the interface index but doesn't handle the case where the interface doesn't exist, which could break arithmetic operations that use this value.

Apply this defensive coding fix:

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}

232-233: Use full ip addr show - brief mode drops primary filter

The -br (brief) output format does not support the primary filter, causing this command to return nothing and breaking downstream logic.

-  local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
+  local THISIP=$(ip -4 addr show scope global primary dev $LAN | awk 'NR==1{print $2}' | cut -d/ -f1)

234-235: Fix incorrect ip route lookup

The current command is missing the to keyword, causing $NETWORK to be potentially empty.

-  local NETWORK=$(ip -4 route show $THISIP dev $LAN | awk '{print $1;exit}')
+  local NETWORK=$(ip -4 route show to $THISIP dev $LAN | awk '{print $1;exit}')

347-348: Use full ip addr show for IPv4 address retrieval

The -br (brief) output format does not support the primary filter, causing this command to return nothing and breaking Docker network setup.

-[[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}') || IPV4=
+[[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 addr show scope global primary dev $NETWORK | awk 'NR==1{print $2}' | cut -d/ -f1) || IPV4=

358-360: Fix IPv6 address retrieval and route lookup

The IPv6 address retrieval has two issues:

  1. The -br format doesn't support primary filtering
  2. The route lookup needs the to keyword
-# get IPv6 address - ignore any /128 networks
-[[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $NETWORK | awk -v RS='[[:space:]]+' '(NR>2){print}' | grep -Pvm1 '^.+/128|^$') || IPV6=
-SUBNET6=$(ip -6 route show $IPV6 dev $NETWORK | awk '{print $1;exit}')
+# get IPv6 address - ignore any /128 networks
+[[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 addr show scope global primary -deprecated dev $NETWORK | awk '/inet6/{for(i=1;i<=NF;i++) if($i~/^[0-9a-f]+:[0-9a-f:]+\/[0-9]+$/ && !($i~/\/128$/)) {print $i; exit}}') || IPV6=
+SUBNET6=$(ip -6 route show to $IPV6 dev $NETWORK | awk '{print $1;exit}')

424-425: Ensure metrics calculation handles missing indices

The dynamic metric calculation could fail if the index function returns nothing.

-IPV4="$IPV4 metric $((1000 - 1 + $(index $NETWORK)))"
+local idx=$(index $NETWORK)
+idx=${idx:-0}
+IPV4="$IPV4 metric $((1000 - 1 + idx))"

441-449: Fix the dynamic metric calculation for wireless and other interfaces

Similar to the bridge interface case, the metric calculation needs safeguards against missing indices.

if [[ $TYPE == wlan ]]; then
  VHOST=shim-$NETWORK
  INDEX=3000
else
  VHOST=vhost${NETWORK//[^0-9.]/}
  INDEX=1000
fi
-INDEX=$(($INDEX - 1 + $(index $NETWORK)))
+local idx=$(index $NETWORK)
+idx=${idx:-0}
+INDEX=$(($INDEX - 1 + idx))

451-452: Add existence check for IPv6 operations on vhost interfaces

The script doesn't check if the IPv6 configuration directory exists before accessing it.

-echo 1 >$CONF6/$VHOST/disable_ipv6
-run ip -6 addr flush dev $VHOST
+[[ -d $CONF6/$VHOST ]] && echo 1 >$CONF6/$VHOST/disable_ipv6
+run ip -6 addr flush dev $VHOST

454-455: Improve IP address retrieval and comparison on vhost interface

The current implementation uses a brittle awk approach and a regex comparison that may not reliably detect the address.

-IPS="$(ip -4 -br addr show scope global dev $VHOST | awk '{$1="";$2="";print;exit}' | sed -r 's/ metric [0-9]+//g')"
-[[ ! $IPS =~ $IPV4 ]] && run ip addr add $IPV4 metric $INDEX dev $VHOST
+if ! ip -4 addr show dev $VHOST | grep -q "$IPV4"; then
+  run ip addr add $IPV4 metric $INDEX dev $VHOST
+fi

496-499: Fix IPv4 address retrieval for shim-wlan0 cleanup

The same issue with -br addr show primary not supporting the primary filter applies here.

if [[ -e $SYSTEM/shim-wlan0 ]]; then
-  IPV4=$(ip -4 -br addr show scope global primary dev shim-wlan0 | awk '{print $3,$4,$5;exit}')
+  IPV4=$(ip -4 addr show scope global primary dev shim-wlan0 | awk 'NR==1{for(i=1;i<=NF;i++) if($i~/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+$/) {print $i}}')
  [[ -n $IPV4 ]] && run ip addr del $IPV4 dev shim-wlan0
fi

516-516: Wrap container_add_route with the run helper

The container_add_route function itself suppresses errors and doesn't log failures. Invoking it directly will miss both error trapping and logging.

-container_add_route $CONTAINER
+run container_add_route $CONTAINER

428-429: ⚠️ Potential issue

Add existence check before IPv6 operations

The script doesn't check if the IPv6 configuration directory exists before accessing it.

-echo 1 >$CONF6/$LINK/disable_ipv6
-run ip -6 addr flush dev $LINK
+[[ -d $CONF6/$LINK ]] && echo 1 >$CONF6/$LINK/disable_ipv6
+run ip -6 addr flush dev $LINK
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 4370bf8 and 92cc39f.

📒 Files selected for processing (1)
  • etc/rc.d/rc.docker (12 hunks)
🔇 Additional comments (2)
etc/rc.d/rc.docker (2)

43-52: LGTM!

The new active() helper function provides a clean abstraction to map Ethernet interfaces to their corresponding bridge or bond interfaces, supporting the correct handling of interface references throughout the script.


457-459: LGTM!

The code properly removes parent IPv4 addresses from vhost interfaces when Docker access is disabled but the address exists.

Comment thread etc/rc.d/rc.docker Outdated

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

♻️ Duplicate comments (8)
sbin/create_network_ini (2)

149-156: Repeated issues already reported: unsupported primary filter in -br mode and metric on ip addr add

The code still:

  • uses ip -[46] -br addr show … primary …-br doesn’t support the
    primary selector, the command returns nothing;
  • passes metric to ip addr add/del, which iproute2 ignores (or errors)
    because metrics belong to routes, not addresses;
  • calculates INDEX with $(index …) without a default, risking a crash.

These concerns were raised in earlier reviews; please address or justify.

Also applies to: 171-177, 204-208, 224-226, 253-269, 280-291


33-35: ⚠️ Potential issue

index() returns empty on failure – guard to avoid arithmetic aborts

index() directly cats the sysfs file and prints nothing when the interface
doesn’t exist (USB NIC removed, race-condition, typo).
Down-stream arithmetic such as INDEX=$((… + $(index $interface))) then receives
an empty string and the whole script exits with “value required”.

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}
etc/rc.d/rc.inet1 (2)

152-156: index() helper still lacks fallback value

Same risk as previously flagged: when /sys/class/net/$iface/ifindex
vanishes, arithmetic with an empty string aborts the script.


398-404: Metrics applied to addresses and index * fallback remain unresolved

ip addr add … metric $INDEX is still used – unsupported by iproute2;
• fallback INDEX=$((1000 + ${INDEX:-$(($(index * | …))})) expands * to
filenames, producing nonsense.

Issues already noted in prior reviews.

Also applies to: 410-411

etc/rc.d/rc.docker (4)

38-42: index() without default value can crash arithmetic later

Identical problem as in other scripts – please add a safe default.


187-189: ipv4_exists() uses incorrect & unsupported command combo

ip -4 -br addr show to … is syntactically wrong (to filters routes, not
addresses) and -br doesn’t understand to. See previous review.


232-235: Brief-mode ip … primary + metric-on-address issues persist

The same two issues (unsupported primary filter with -br and illegal
metric on ip addr add/del) appear multiple times in these blocks.

Also applies to: 348-361, 425-456, 497-499


516-516: container_add_route should be wrapped with run for uniform logging

Earlier feedback highlighted the loss of error capture when calling this helper
directly; it hasn’t been changed.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 92cc39f and 1050c7a.

📒 Files selected for processing (3)
  • etc/rc.d/rc.docker (12 hunks)
  • etc/rc.d/rc.inet1 (28 hunks)
  • sbin/create_network_ini (10 hunks)

Comment thread sbin/create_network_ini

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 0

♻️ Duplicate comments (9)
etc/rc.d/rc.docker (9)

38-41: Protect index() from non-existent interfaces

The index() function doesn't handle the case when an interface doesn't exist, which could cause arithmetic errors later when used in calculations like $((1000 - 1 + $(index $NETWORK))).

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}

221-236: Fix unsupported primary filter in brief mode

The ip -br addr show command doesn't support the primary flag, causing the command to return empty results.

  if [[ $PID -gt 0 && "eth0 br0 bond0 wlan0" =~ $LAN ]]; then
-    local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
+    local THISIP=$(ip -4 addr show scope global primary dev $LAN | awk 'NR==1{print $2}' | cut -d/ -f1)
    for CFG in /etc/wireguard/wg*.cfg ; do
      local NETWORK=$(ip -4 route show to $THISIP dev $LAN | awk '{print $1;exit}')
      [[ -n $NETWORK ]] && nsenter -n -t $PID ip -4 route add $NETWORK via ${THISIP%/*} dev $LAN 2>/dev/null
    done
  fi

347-350: Fix unsupported primary filter in brief mode (IPV4 retrieval)

Same issue here - ip -br addr show doesn't support the primary flag.

-      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}') || IPV4=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 addr show scope global primary dev $NETWORK | awk 'NR==1{print $2}') || IPV4=
      if [[ -n $IPV4 ]]; then
        SUBNET=$(ip -4 route show to $IPV4 dev $NETWORK | awk '{print $1;exit}')

358-361: Fix unsupported primary filter in brief mode (IPV6 retrieval)

Same issue - also, the current IPv6 address retrieval could be simplified.

-      # get IPv6 address - ignore any /128 networks
-      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $NETWORK | awk -v RS='[[:space:]]+' '(NR>2){print}' | grep -Pvm1 '^.+/128|^$') || IPV6=
+      # get IPv6 address - ignore any /128 networks
+      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 addr show scope global primary -deprecated dev $NETWORK | awk '/inet6/ && !/:128$/ {print $2; exit}') || IPV6=
      if [[ -n $IPV6 ]]; then
        SUBNET6=$(ip -6 route show to $IPV6 dev $NETWORK | awk '{print $1;exit}')

441-456: Guard dynamic metric calculation for non-bridge interfaces

Same issue with the index calculation, plus missing existence check for IPv6 configuration.

      else
        if [[ $TYPE == wlan ]]; then
          VHOST=shim-$NETWORK
          INDEX=3000
        else
          VHOST=vhost${NETWORK//[^0-9.]/}
          INDEX=1000
        fi
-        INDEX=$(($INDEX - 1 + $(index $NETWORK)))
+        local idx=$(index $NETWORK)
+        idx=${idx:-0}
+        INDEX=$(($INDEX - 1 + idx))
        if [[ -n $IPV4 && $DOCKER_ALLOW_ACCESS == yes ]]; then
          # disable IPv6 on vhost interface
-          echo 1 >$CONF6/$VHOST/disable_ipv6
+          [[ -d $CONF6/$VHOST ]] && echo 1 >$CONF6/$VHOST/disable_ipv6
          run ip -6 addr flush dev $VHOST
          # copy parent IPv4 address to vhost interface
-          IPS="$(ip -4 -br addr show scope global dev $VHOST | awk '{$1="";$2="";print;exit}' | sed -r 's/ metric [0-9]+//g')"
+          IPS="$(ip -4 addr show scope global dev $VHOST | awk '{for(i=1;i<=NF;i++) if($i~/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+$/) {print $i}}' | sed -r 's/ metric [0-9]+//g')"
          [[ ! $IPS =~ $IPV4 ]] && run ip addr add $IPV4 metric $INDEX dev $VHOST

496-499: Fix unsupported primary filter in brief mode (shim-wlan0 cleanup)

Another instance of using brief mode with the primary flag.

  if [[ -e $SYSTEM/shim-wlan0 ]]; then
-    IPV4=$(ip -4 -br addr show scope global primary dev shim-wlan0 | awk '{print $3,$4,$5;exit}')
+    IPV4=$(ip -4 addr show scope global primary dev shim-wlan0 | awk '/inet / {print $2, $3, $4; exit}')
    [[ -n $IPV4 ]] && run ip addr del $IPV4 dev shim-wlan0
  fi

516-517: Wrap container_add_route with run helper

The container_add_route function should be wrapped with the run helper for consistent error handling.

-          container_add_route $CONTAINER
+          run container_add_route $CONTAINER
          log "$CONTAINER: started successfully!" &

423-432: ⚠️ Potential issue

Guard against arithmetic errors in metric calculation

Use a safe approach to handle potentially empty index values to prevent arithmetic errors.

        if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then
-          IPV4="$IPV4 metric $((1000 - 1 + $(index $NETWORK)))"
+          local idx=$(index $NETWORK)
+          idx=${idx:-0}
+          IPV4="$IPV4 metric $((1000 - 1 + idx))"
          # create shim interface
          [[ -e $SYSTEM/$LINK ]] || run ip link add link $NETWORK name $LINK type $ATTACH mode $MODE
          # disable IPv6 on shim interface
-          echo 1 >$CONF6/$LINK/disable_ipv6
+          [[ -d $CONF6/$LINK ]] && echo 1 >$CONF6/$LINK/disable_ipv6
          run ip -6 addr flush dev $LINK
          # copy parent IPv4 address to shim interface
          run ip addr add $IPV4 dev $LINK

187-189: ⚠️ Potential issue

Fix parameter order in ipv4_exists() function

The current function has parameters in an unusual order and the command syntax is incorrect. It tries to filter addresses by the second parameter but uses "show $2" which doesn't work for filtering addresses.

ipv4_exists(){
-  ip -4 -br addr show $2 dev $1 | awk '{print $3;exit}'
+  ip -4 addr show dev $1 | grep -q "$2" && echo "$2" || echo ""
}
🧹 Nitpick comments (1)
etc/rc.d/rc.docker (1)

401-403: Improve network operation messages and error handling

The current implementation suppresses all error output when removing networks, which could hide important errors during network setup.

      # delete and recreate unconditionally
      log "Processing... $NETWORK"
-      docker network rm $NETWORK &>/dev/null
+      docker network rm $NETWORK 2>/dev/null || true
      docker network create -d $ATTACH $SUBNET $GATEWAY $SERVER $RANGE $SUBNET6 $GATEWAY6 $SERVER6 -o parent=$VHOST $NETWORK | xargs docker network inspect -f "created network $ATTACH {{.Name}} with subnets: {{range .IPAM.Config}}{{.Subnet}}; {{end}}" 2>/dev/null | log
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 1050c7a and 018d9fe.

📒 Files selected for processing (1)
  • etc/rc.d/rc.docker (12 hunks)

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

♻️ Duplicate comments (10)
etc/rc.d/rc.docker (10)

221-236: ⚠️ Potential issue

Fix unsupported "primary" filter in brief IP commands

The ip -br addr show command does not support the primary flag, so calls like this return nothing and break downstream logic.

-    local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
+    local THISIP=$(ip -4 addr show scope global primary dev $LAN" | awk 'NR==1{print $2}' | cut -d/ -f1)

Also, good job adding the to keyword in the route lookup below, but make sure the above IP retrieval works first.


38-41: ⚠️ Potential issue

Guard index() against missing /sys entries

The function retrieves an interface's index from sysfs but doesn't handle errors when interfaces don't exist. This could cause arithmetic errors later when used in metric calculations.

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}

187-190: ⚠️ Potential issue

Fix parameter order in ipv4_exists() function

The ip -4 -br addr show to $2 dev $1 command has a logical issue - the to parameter filters routes, not addresses. This won't work as intended for verifying IPv4 address existence.

ipv4_exists(){
-  ip -4 -br addr show to $2 dev $1 | awk '{print $3;exit}'
+  ip -4 addr show dev $1 | grep -q "$2" && echo "$2" || echo ""
}

348-364: ⚠️ Potential issue

Fix IPv4/IPv6 address retrieval in multiple places

Similar to earlier issues, these commands using -br with the primary flag will fail since brief mode doesn't support the primary filter.

-      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}') || IPV4=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 addr show scope global primary dev $NETWORK | awk 'NR==1{print $2}' | cut -d/ -f1) || IPV4=
-      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $NETWORK | awk -v RS='[[:space:]]+' '(NR>2){print}' | grep -Pvm1 '^.+/128|^$') || IPV6=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 addr show scope global primary -deprecated dev $NETWORK | awk '/inet6/{print $2}' | grep -Pvm1 '^.+/128|^$') || IPV6=

The IPv6 route lookup is correctly using the to keyword.


425-426: ⚠️ Potential issue

Dynamic metric calculation for bridge networks needs safeguards

The metric calculation could fail if the index function returns nothing. Add error handling to avoid arithmetic errors.

-          IPV4="$IPV4 metric $((1000 - 1 + $(index $NETWORK)))"
+          local idx=$(index $NETWORK)
+          idx=${idx:-0}
+          IPV4="$IPV4 metric $((1000 - 1 + idx))"

429-431: ⚠️ Potential issue

Missing existence check before manipulating IPv6 configuration

The script tries to disable IPv6 and flush addresses without checking if the interface exists.

          # disable IPv6 on shim interface
-          echo 1 >$CONF6/$LINK/disable_ipv6
-          run ip -6 addr flush dev $LINK
+          [[ -d $CONF6/$LINK ]] && echo 1 >$CONF6/$LINK/disable_ipv6
+          [[ -e $SYSTEM/$LINK ]] && run ip -6 addr flush dev $LINK

442-456: ⚠️ Potential issue

Dynamic metric calculation for non-bridge interfaces needs safeguards

Similar to the bridge network case, the metric calculation and IPv6 configuration need safeguards.

        INDEX=$(($INDEX - 1 + $(index $NETWORK)))
+        local idx=$(index $NETWORK)
+        idx=${idx:-0}
+        INDEX=$(($INDEX - 1 + idx))
        if [[ $DOCKER_ALLOW_ACCESS == yes && -n $IPV4 ]]; then
          # disable IPv6 on vhost interface
-          echo 1 >$CONF6/$VHOST/disable_ipv6
+          [[ -d $CONF6/$VHOST ]] && echo 1 >$CONF6/$VHOST/disable_ipv6

496-499: ⚠️ Potential issue

Fix IPv4 address retrieval for shim-wlan0 cleanup

This also uses the problematic brief mode with primary filter.

  if [[ -e $SYSTEM/shim-wlan0 ]]; then
-    IPV4=$(ip -4 -br addr show scope global primary dev shim-wlan0 | awk '{print $3,$4,$5;exit}')
+    IPV4=$(ip -4 addr show scope global primary dev shim-wlan0 | awk '/inet /{print $2,$3,$4}' | head -1)
    [[ -n $IPV4 ]] && run ip addr del $IPV4 dev shim-wlan0
  fi

516-516: ⚠️ Potential issue

Wrap container_add_route with the run helper for consistent error handling

The run wrapper was removed when calling container_add_route. This could impact error handling and logging.

-          container_add_route $CONTAINER
+          run container_add_route $CONTAINER

361-361: ⚠️ Potential issue

Add the to keyword to ensure correct IPv6 route lookup

Similar to the IPv4 route lookup, this needs the to keyword.

-        SUBNET6=$(ip -6 route show $IPV6 dev $NETWORK | awk '{print $1;exit}')
+        SUBNET6=$(ip -6 route show to $IPV6 dev $NETWORK | awk '{print $1;exit}')
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 2d0208f and daab120.

📒 Files selected for processing (1)
  • etc/rc.d/rc.docker (12 hunks)
🔇 Additional comments (3)
etc/rc.d/rc.docker (3)

43-52: Solid implementation of the active() helper function

The function properly handles interface name resolution by checking for corresponding bridge or bond interfaces, which improves network handling flexibility.


116-116: Correct route lookup syntax with to keyword

Good improvement using the correct syntax for IPv6 route lookup by adding the to keyword, which helps retrieve the proper route information.


179-180: Proper handling for wlan interfaces

Forcing ipvlan attachment mode for wireless interfaces is appropriate as it allows network connectivity without requiring wireless interfaces to operate in promiscuous mode.

Comment thread etc/rc.d/rc.docker Outdated

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

♻️ Duplicate comments (8)
etc/rc.d/rc.docker (8)

38-41: ⚠️ Potential issue

Fix potential arithmetic expansion error when interface doesn't exist

The current index() function doesn't handle the case when an interface doesn't exist, which could cause arithmetic errors when used in calculations.

Apply this fix to make the script resilient:

index(){
-  cat $SYSTEM/$1/ifindex 2>/dev/null
+  local idx
+  idx=$(cat "$SYSTEM/$1/ifindex" 2>/dev/null) || idx=0
+  echo "$idx"
}

515-516: 🛠️ Refactor suggestion

Wrap container_add_route with run helper

The container_add_route function suppresses errors and doesn't log failures. Using it directly bypasses error trapping and logging.

Apply this fix:

-          container_add_route $CONTAINER
+          run container_add_route $CONTAINER

442-449: ⚠️ Potential issue

Add safety checks for index in non-bridge interface metric calculation

Similar to the bridge case, this metric calculation needs a fallback value.

Apply this fix:

        if [[ $TYPE == wlan ]]; then
          VHOST=shim-$NETWORK
          INDEX=3000
        else
          VHOST=vhost${NETWORK//[^0-9.]/}
          INDEX=1000
        fi
-        INDEX=$(($INDEX - 1 + $(index $NETWORK)))
+        local idx=$(index $NETWORK)
+        idx=${idx:-0}
+        INDEX=$(($INDEX - 1 + idx))

347-350: ⚠️ Potential issue

Fix multiple unsupported primary filter instances

Same issue with -br not supporting primary filter. This will cause $IPV4 to be empty.

Apply this fix:

-      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 -br addr show scope global primary dev $NETWORK | awk '{print $3;exit}') || IPV4=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "4" ]] && IPV4=$(ip -4 addr show scope global primary dev $NETWORK | awk 'NR==1{print $2}') || IPV4=

And for the next line:

-        SUBNET=$(ip -4 route show to $IPV4 dev $NETWORK | awk '{print $1;exit}')
+        SUBNET=$(ip -4 route show to "${IPV4%/*}" dev $NETWORK | awk '{print $1;exit}')

358-360: ⚠️ Potential issue

Fix IPv6 address retrieval and route lookup

The IPv6 address retrieval has the same issue with -br and primary, and the route lookup should include the to keyword.

Apply this fix:

-      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 -br addr show scope global primary -deprecated dev $NETWORK | awk -v RS='[[:space:]]+' '(NR>2){print}' | grep -Pvm1 '^.+/128|^$') || IPV6=
+      [[ -z ${!AUTO} || ${!AUTO} =~ "6" ]] && IPV6=$(ip -6 addr show scope global primary -deprecated dev $NETWORK | awk '{if(NR>1 && $0 !~ "/128") {print $2; exit}}') || IPV6=

And for the next line:

-        SUBNET6=$(ip -6 route show to $IPV6 dev $NETWORK | awk '{print $1;exit}')
+        SUBNET6=$(ip -6 route show to "${IPV6%/*}" dev $NETWORK | awk '{print $1;exit}')

187-189: ⚠️ Potential issue

Fix incorrect parameter order in ipv4_exist()

The current implementation uses to which is for route filtering, not address filtering. This won't correctly detect IP address existence.

Apply this fix:

ipv4_exist(){
-  ip -4 -br addr show to $2 dev $1 | awk '{print $3;exit}'
+  ip -4 addr show dev "$1" | grep -w "${2}/" | awk '{print $2;exit}'
}

450-455: ⚠️ Potential issue

Add existence check before manipulating IPv6 configuration

When $DOCKER_ALLOW_ACCESS changes, the directory might not exist yet causing errors.

Apply this fix:

        if [[ -n $IPV4 && $DOCKER_ALLOW_ACCESS == yes ]]; then
          # disable IPv6 on vhost interface
-          echo 1 >$CONF6/$VHOST/disable_ipv6
+          [[ -d $CONF6/$VHOST ]] && echo 1 >$CONF6/$VHOST/disable_ipv6
          run ip -6 addr flush dev $VHOST
          # copy parent IPv4 address to vhost interface
-          [[ -z $(ipv4_exist $VHOST ${IPV4%/*}) ]] && run ip addr add $IPV4 metric $INDEX dev $VHOST
+          [[ -z $(ipv4_exist "$VHOST" "${IPV4%/*}") ]] && run ip addr add "$IPV4" metric $INDEX dev "$VHOST"

232-235: ⚠️ Potential issue

Fix unsupported primary filter in brief IP command

The ip -br addr show command does not support the primary flag, which causes the command to return nothing.

Apply this fix:

-    local THISIP=$(ip -4 -br addr show scope global primary dev $LAN | awk '{print $3;exit}')
+    local THISIP=$(ip -4 addr show scope global primary dev "$LAN" | awk 'NR==1{print $2}' | cut -d/ -f1)
🧹 Nitpick comments (1)
etc/rc.d/rc.docker (1)

456-459: Properly quote variables in address removal

Ensure variables are properly quoted to avoid word splitting with spaces or special characters.

Apply this fix:

-          run ip addr del $IPV4 metric $INDEX dev $VHOST
+          run ip addr del "$IPV4" metric $INDEX dev "$VHOST"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between daab120 and db3bc98.

📒 Files selected for processing (1)
  • etc/rc.d/rc.docker (12 hunks)
🔇 Additional comments (2)
etc/rc.d/rc.docker (2)

44-52: LGTM - Good mapping implementation for active interfaces

The active() function correctly handles the mapping of ethernet interfaces to their corresponding bridge or bonded interfaces.


221-223: Function read_dom() is using IFS correctly

The XML parsing helper function correctly sets IFS and reads entity content.

Comment thread etc/rc.d/rc.docker
Comment thread etc/rc.d/rc.docker
@limetech limetech merged commit 1e0895b into unraid:master May 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants