In multi-homed macOS environments, corporate VPN tunnels, software development testbeds, and complex local area networks, understanding exactly how the operating system routes network traffic is essential. When a Mac is connected simultaneously to Wi-Fi, Ethernet, and enterprise VPN adapters, routing conflicts can cause internal intranet services, local development containers, or subnets to become unreachable because packets are dispatched through the wrong physical interface.
While macOS provides graphical network configuration under System Settings, the graphical user interface provides no mechanism to view the underlying BSD kernel routing table or define fine-grained host routes. The native BSD route command in macOS Terminal provides direct administrative control over the kernel’s routing tables. With route, administrators can query the exact route chosen for any destination IP, inspect interface metrics, add temporary static routes, and flush corrupted routing caches.
Understanding BSD Kernel Routing Tables in macOS
In macOS, the Darwin kernel maintains an internal routing table consisting of destination subnets, gateway IP addresses, interface names (e.g., en0, en1, utun2), and routing flags. When an application initiates a network connection, the kernel performs a longest-prefix match against the routing table to determine which gateway and interface should transmit the packet.
Common routing flags in macOS include:
U: The route is active and operational (Up).G: The destination requires forwarding through an intermediate Gateway router.H: The route targets a specific individual Host rather than an entire subnet.S: Static route manually created by an administrator.m: Modified route dynamically altered by routing daemons.
Inspecting the Routing Path for a Specific Destination IP
When troubleshooting network reachability to a remote server or internal IP (e.g., 10.200.1.50), querying the specific route chosen by macOS reveals the exact exit interface, gateway, and path parameters.
Open Terminal (located in /Applications/Utilities/Terminal.app) and execute the route get command with the -n flag to prevent slow DNS reverse lookups:
route -n get 10.200.1.50
The output reports granular routing details:
route to: 10.200.1.50
destination: 10.200.0.0
mask: 255.255.0.0
gateway: 192.168.1.1
interface: en0
flags: <UP,GATEWAY,DONE,PRCLX>
recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
0 0 0 0 0 0 1500 0
This report confirms:
- Interface: The exact network adapter carrying the traffic (e.g.,
en0for Wi-Fi/Ethernet). - Gateway: The next-hop router IP address handling transmission.
- MTU: The maximum transmission unit negotiated for the path (typically 1500 for Ethernet or 1420 for VPN tunnels).
Querying the Default Gateway Route
To inspect your default internet gateway route and verify which network interface has priority for unmapped internet traffic, query default:
route -n get default
If you have both a VPN and a physical Wi-Fi connection active, this query confirms whether traffic is exiting through the physical adapter (en0) or routing through the virtual tunnel interface (utun0 or utun1).
Adding a Temporary Static Route via Terminal
When connecting to isolated subnets (such as a laboratory network or staging environment accessible only through a secondary router IP), you can manually add a static route. Modifying routing tables requires administrative privileges (sudo).
To route all traffic destined for the 10.50.0.0/16 subnet through a specific local gateway at 192.168.1.254, execute:
sudo route add -net 10.50.0.0/16 192.168.1.254
To route traffic for a single isolated host IP (e.g., 172.16.5.10) through a specific interface gateway, use the -host flag:
sudo route add -host 172.16.5.10 192.168.1.254
Verify that the route was registered in the kernel by querying the destination:
route -n get 10.50.0.1
Deleting Static Routes
When testing is complete or if a route was entered incorrectly, remove the entry using the delete action with matching network parameters:
sudo route delete -net 10.50.0.0/16
To delete a single host route, run:
sudo route delete -host 172.16.5.10
Flushing the Kernel Routing Cache
If routing tables become corrupted following abrupt VPN disconnects, sleep-wake cycles with changed network locations, or IP address collisions, flush the kernel routing cache to clear dynamic host redirects:
sudo route -n flush
The command outputs confirmation lines as dynamic and host routing entries are purged. The operating system immediately reconstructs clean default routes using active DHCP and interface settings.
By leveraging the BSD route command in macOS Terminal, network administrators and developers can diagnose asymmetric routing paths, verify VPN split-tunnel traffic steering, and manage static routes with complete confidence.