Linux Network Stack Configurations



ip link show
ip link set <DEVICE> mtu 1145
ip link set <DEVICE> up | down

Virtual interfaces


Bridges are Linux's virtual Ethernet swtiches. It forwards Ethernet frames between bridged interfaces and thus extends the broadcast area.

ip link add <NAME> type bridge
ip link set <DEVICE> master <BRIDGE_DEVICE>
ip link set <DEVICE> nomaster
bridge link


ip link add <NAME> type vlan link <DEVICE> id <VLANID>
ip -d link show <NAME>


ip link add gre0 type gre remote local
ip link set gre0 up mtu 1476

Wireless daemons

WiFi adapters are different with Ethernet adapters. You need to regularly scan for available APs and authenticate to them before you can access the link layer. So besides drivers, there are wireless daemons.


ctrl_interface=DIR=/run/wpa_supplicant GROUP=wheel
  ssid="WiFi SSID"
  # wpa_passphrase "WiFi SSID" "[email protected]"

User in the specified group can access the control interface using wpa_cli. Some basic commands:

  • list_networks: List networks in configuration.
  • scan: Scan for available APs.
  • scan_results
  • disable_network <id>
  • enable_network <id>
  • select_network <id>: Disable all other networks except this one.

It's possible to add networks dynamically using add_network, identity and password, but it's not persistent.

Routing tables

ip route show
ip route add | del | show <PREFIX> via <NEXTHOP_ADDRESS> [dev <DEVICE>] [proto <RTPROTO>]
ip route get <ADDRESS>
ip route add via dev wlan0
ip route add default via dev wlan0
ip -6 route add default via fe80::123:4567:89ab:cdef dev wlan0
ip route add via inet6 fe80::123:4567:89ab:cdef dev wlan0

Routes to a longer PREFIX have higher priority. Routes with smaller METRIC have higher priority. Default metric is 0 for IPv4 routes, 1024 for IPv6 routes. Two routes to the same PREFIX with the same METRIC cannot be both added.

RTPROTO for routes added with ip route is 3 (boot) by default. RTPROTO is useful to identify from which program the route is added. Besides numbers, you can also use symbols defined in /etc/iproutes2/rt_protos.

Multiple tables

ip route add <SELECTOR> <NEXTHOP> table <TABLE>
ip route show table all

ip route shows routes in table 254 (main) by default.

Routing policy

ip rule add <PREFIX> | fwmark <FWMARK> table <TABLE>




Linux kernel has a powerful firewall called netfilter. It can not only filter the traffic, but also alter packets, at both L3 and L4. Netfilter can be controlled using either iptables or nftables.

graph LR
ingress --PREROUTING--> r1{R}
subgraph r[Routing decision]
r1 --FORWARD--> r2{R}
r2 --POSTROUTING --> egress
r1 --INPUT--> processes
processes --OUTPUT--> r2

This graph shows the packet flow paths in Linux. Netfilter adds hooks (UPPERCASE words on the graph) on the flow. The corresponding chain gets called when a packet pass through the hooks.


A iptables rule consists of a match pattern and what to do with packets matched (so called target).

A iptables chain is a set of rules. Built-in chains, similar to the main function in C, are directly called when a packet pass through the hooks. User-defined chains, just like custom functions in programming languages, must be called in built-in chains to function. Rules in a chain is executed in order. Some targets, like ACCEPT, REJECT, DROP

iptables -A INPUT -m conntrack --cstate RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -s -j ACCEPT
iptables -D INPUT -s -j ACCEPT
iptables -I 1 INPUT -s -j REJECT
iptables -A INPUT -j DROP
iptables -vL --line-numbers

The graph above is over simplified for explaining tables in iptables. This picture from Wikipedia is more detailed on that. Netfilter subdivides a hook into multiple hooks with different purposes and categorizes them into tables. F. e. the default table filter has INPUT, FORWARD and OUTPUT chains. Both nat and mangle has POSTROUTING chain, but only the one in nat table can utilize MASQUERADE or SNAT targets to perform Network Address Translation.

iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE
iptables -A FORWARD -m conntrack --cstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT

Iptables has built with many extensions (man:iptables-extensions). We have already met the conntrack match extension, MASQURADE and SNAT target extension.

iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j DROP
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
iptables -A INPUT -s -j LOG --log-prefix "Logged packet: "
iptables -t mangle -A OUTPUT -m owner --uid-owner user1 -j MARK --set-mark 0x1111

iptables is for configuring IPv4 firewall. For IPv6 firewall, use ip6tables. Netfilter state is in memory and losses after reboot. Use iptables-persistent to save and restore it.


Dhclient is the reference DHCP client implementation made by ISC. Dhcpcd is the most used one. Dhcpcd has a lot of features, but the defaults just work for most use cases.

dhcpcd --allowinterfaces eth0 wlan0

Dhcpcd allows user to run shell script hooks on events. See man:dhcpcd-run-hooks(8).

The two most used DHCP server implementations are the reference implementation from ISC, dhcpd, and despite the name, dnsmasq. This is an example dhcpd config:

subnet netmask {
  option domain-name-servers;
  option routers;
  option broadcast-address;
  option interface-mtu 1492;


Though there is SLAAC in IPv6, DHCPv6 is still useful in IPv6 Prefix Delegations.

# /etc/dhcpcd.conf
interface ppp0
  ia_na 1  # Request an IPv6 address
  ia_pd 2 eth1/0  # Request a PD and assign it to eth1


Linux kernel itself can accept Router Advertisement and perform SLAAC. When net.ipv6.conf.<INTERFACE>.accept_ra = 1 (default) and net.ipv6.conf.<INTERFACE>.forwarding = 0 (default), kernel accepts RA on this INTERFACE. When net.ipv6.conf.<INTERFACE>.accept_ra = 2, kernel accepts RA on the INTERFACE regardless of the forwarding setting.

Dhcpcd, despite its name, can also handle SLAAC by default. You can turn it off using the ipv6ra_noautoconf option.

The most used Router Advertisement server on Linux is radvd.

# /etc/radvd.conf
interface enp4s0 {
  AdvSendAdvert on;
  AdvLinkMTU 1492;
  prefix ::/64 {
    AdvOnLink on;
    AdvAutonomous on;
    AdvRouterAddr on;


DNS isn't handled by system (Or you can say there is no clear definition of "system" on Linux distros). It's instead handled by libc. Libc gets DNS settings from /etc/resolv.conf. The most important setting in this file is nameserver, which specifies where to send DNS queries.

# /etc/resolv.conf

Routers may announce DNS resolvers through DHCP. So DHCP clients need a way to dynamically update /etc/resolv.conf. Dhcpcd utilizes resolvconf to do that. If you find your /etc/resolv.conf settings constantly get overrided (with comment # Generated by resolvconf), you may want to change /etc/resolvconf.conf instead of /etc/resolv.conf.

# /etc/resolvconf.conf

A common practice for more complex DNS configurations is to run a local DNS recursive server, aka. resolver, and set /etc/resolv.conf to use the local resolver. Dnsmasq may be the easiest among them, its configuration looks like this:

server=  # Default server, note that dnsmasq also reads /etc/resolv.conf
server=/  # Zone specific server

BIND is a general DNS server, but it can also be used as a resolver. Check man:named.conf(5) for more. Systemd-resolved is the resolver ships with systemd, with many advanced features, such as DNS-over-TLS. See man:resolvd.conf(5) for more about it.

Network managers

Network managers utilizes tools above and provide a UI so users can manage their configurations in one place. There are lightweight network managers that many distros ship and use by default, such as ifupdown (Debian), ifcfg (Fedora), netctl (Arch Linux). Feature rich network manager, for example systemd-networkd, NetworkManager and ConnMan, can handle more functions, e.g. VPN, wireless daemons. Many GNU/Linux Desktop Environments has support for interacting with NetworkManager and ConnMan.








nmcli, nmtui



About Me