How to Configure Dual Network Routing on macOS: WIFI for General Traffic and LAN for Specific IPs


5 views

When working with specialized network equipment or industrial devices, we often need to maintain dual network connections on our development machines. Here's my scenario:

WIFI (en1):
- DHCP assigned: 192.168.19.*
- Default route for general internet traffic

LAN (en0):
- Static IP: 192.168.2.10
- Direct connection to switch (no router)
- Must handle only these specific IPs:
  192.168.2.1
  192.168.2.20
  192.168.2.21
  192.168.2.30

The main issue occurs because macOS automatically assigns metric values to network interfaces, and sometimes the LAN interface (en0) gets lower metric than WIFI (en1), causing all traffic to route through en0. Here's what happens when we check the routing table:

$ netstat -rn
Internet:
Destination        Gateway            Flags        Netif
default            192.168.2.1        UGSc         en0   ← Problem!
default            192.168.19.1       UGScI        en1

The most reliable approach is to adjust the network service order in System Preferences:

  1. Go to System Preferences → Network
  2. Click the gear icon at the bottom → Set Service Order
  3. Drag Wi-Fi above Ethernet (en0)
  4. Click OK and Apply

If you prefer command-line configuration or need more granular control, create a startup script:

#!/bin/bash

# Flush existing routes
sudo route -n flush

# Add default route via WiFi
sudo route -n add default 192.168.19.1

# Add specific routes via Ethernet
for ip in 1 20 21 30; do
  sudo route -n add 192.168.2.$ip -interface en0
done

# Verify routing table
netstat -rn

If you encounter "ping: cannot allocate memory" errors, it typically indicates a routing loop or incorrect interface binding. Try these diagnostic commands:

# Check interface status
ifconfig en0
ifconfig en1

# Test connectivity
ping -c 4 -S 192.168.19.3 google.com
ping -c 4 -S 192.168.2.10 192.168.2.1

# Continuous route monitoring (watch for changes)
while true; do netstat -rn; sleep 5; done

For more robust control, consider using macOS's packet filter:

# /etc/pf.conf
wifi_if = "en1"
lan_if = "en0"
lan_net = "192.168.2.0/24"
specific_ips = "{ 192.168.2.1, 192.168.2.20, 192.168.2.21, 192.168.2.30 }"

# Route only specific IPs through LAN
pass out on $wifi_if route-to ($lan_if $lan_net) from any to $specific_ips
pass out on $lan_if route-to ($wifi_if) from any to !$specific_ips

Then load the rules:

sudo pfctl -f /etc/pf.conf
sudo pfctl -e

When working with specialized network devices or lab environments, we often need to maintain simultaneous connections through different interfaces. In this case, we want to route specific LAN traffic through en0 while keeping general internet access via en1 (WiFi). Here's a robust solution that won't break your network configuration.

$ netstat -rn
Internet:
Destination        Gateway            Flags        Netif
default            192.168.2.1        UGSc           en0
default            192.168.19.1       UGScI          en1
192.168.2          link#4             UCS            en0
192.168.19         link#5             UCS            en1

The key problem here is the competing default routes. The system is arbitrarily choosing between them, causing intermittent connectivity.

Instead of using simple route commands, we'll implement policy routing to ensure consistent behavior:

# First, flush all existing routes
sudo route -n flush

# Add the WiFi as default route with higher priority
sudo route -n add default 192.168.19.1 -ifscope en1

# Add specific routes for LAN devices
for ip in 192.168.2.1 192.168.2.20 192.168.2.21 192.168.2.30; do
    sudo route -n add $ip -interface en0
done

# Set the metrics properly (lower metric = higher priority)
sudo networksetup -setnetworkserviceenabled "Wi-Fi" on
sudo networksetup -ordernetworkservices "Wi-Fi" "Thunderbolt Ethernet"

Create a launch daemon to maintain these routes:





    Label
    com.user.networkroutes
    ProgramArguments
    
        /bin/sh
        -c
        
            route -n flush
            route -n add default 192.168.19.1 -ifscope en1
            for ip in 192.168.2.1 192.168.2.20 192.168.2.21 192.168.2.30; do
                route -n add $ip -interface en0
            done
        
    
    RunAtLoad
    
    WatchPaths
    
        /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist
    


Save this as /Library/LaunchDaemons/com.user.networkroutes.plist and load it with:

sudo chown root:wheel /Library/LaunchDaemons/com.user.networkroutes.plist
sudo launchctl load -w /Library/LaunchDaemons/com.user.networkroutes.plist

After implementation, verify with these commands:

# Check routes
netstat -rn

# Test connectivity
ping -c 1 192.168.2.1
ping -c 1 google.com

# Check which interface is used for specific targets
route get 192.168.2.1
route get 8.8.8.8

If you encounter problems:

  1. DNS resolution fails: Ensure your DNS servers are properly set in WiFi configuration
    networksetup -getdnsservers "Wi-Fi"
  2. Routes disappear after sleep: The launch daemon should restore them automatically
  3. Interface priority issues: Explicitly set service order
    networksetup -listnetworkserviceorder