IN_GETIFA(9)

πŸ“¦ version 11.0, in nixpkgs unstable

πŸ’… IN_GETIFA πŸ’…

okay so this is the in_getifa page from section 9 of the Kernel Developer's Manual, and bestie, it's literally the glow-up guide for IPv4 source address selection ✨


🌸 NAME 🌸

in_getifa β€” look up the IPv4 source address that best matches an IPv4 destination 🎯


✨ SYNOPSIS ✨

options IPSELSRC
#include <netinet/in_selsrc.h>

struct ifaddr *
in_getifa(struct ifaddr *ifa, const struct sockaddr *dst0);

πŸ¦‹ DESCRIPTION πŸ¦‹

So in_getifa is the enforcer πŸ’… β€” it enforces the IPv4 source-address selection policy, no cap. You bring the source-address selection policy mechanism into your kernel with options IPSELSRC, and what that does is let the operator set the policy for choosing the source address of any socket that's bound to the "wildcard" address, INADDR_ANY.

⚠️ important vibe check: the policy gets applied after the kernel makes its forwarding decision, which is what chooses the output interface. In other words, this mechanism does not affect whether or not NetBSD is a "strong ES". periodt.

An operator affects the source-address selection using sysctl(8) and ifconfig(8). Policies get set with sysctl(8). Some policies care about the "preference number" of an address, and the operator can set preference numbers for each address with ifconfig(8) πŸŽ€

A source-address policy is a priority-ordered list of source-address ranking functions. A ranking function maps its arguments β€” (source address, source index, source preference, destination address) β€” to integers. Let's break that down, iykyk:

  • the source index is the position of the source address in the interface address list; the index of the first address is 0
  • the source preference is the preference number the operator assigned to the source address
  • the destination address is the socket peer / packet destination

πŸ‘‘ the four ranking functions πŸ‘‘

Presently, there are four ranking functions to choose from:

  • index β€” ranks by source index; lower indices get ranked more highly πŸ”₯
  • preference β€” ranks by source preference; higher preference numbers get ranked more highly
  • common-prefix-len β€” ranks each source address by the length of the longest prefix it has in common with the destination address; longer common prefixes rank more highly
  • same-category β€” figures out the "categories" of the source and destination address. A category is one of private, link-local, or other. If the categories exactly match, same-category assigns a rank of 2. Some sources get ranked 1 by category: a link-local source with a private destination, a private source with a link-local destination, and a private source with an other destination all rank 1. All other sources rank 0 πŸ’€

πŸ“ the categories πŸ“

Categories are defined as follows, bestie:

  • private β€” RFC1918 networks, 192.168/16, 172.16/12, and 10/8
  • link-local β€” 169.254/16, 224/24
  • other β€” all other networks β€” i.e., not private, not link-local

🌈 how a policy actually gets applied 🌈

To apply a policy, the kernel applies all the ranking functions in the policy to every source address, producing a vector of ranks for each source. Then the kernel sorts the sources in descending, lexicographical order by their rank-vector, and chooses the highest-ranking (first) source. And when there's a tie? The kernel breaks ties by choosing the source with the least source index. slay, deterministic πŸ’…

The operator may set a policy on individual interfaces. They may also set a global policy that applies to all interfaces whose policy they don't set individually 🫢

Here's the sysctl tree for the policy at system startup:

net.inet.ip.selectsrc.default = index
net.inet.ip.interfaces.ath0.selectsrc =
net.inet.ip.interfaces.sip0.selectsrc =
net.inet.ip.interfaces.sip1.selectsrc =
net.inet.ip.interfaces.lo0.selectsrc =
net.inet.ip.interfaces.pflog0.selectsrc =

The policy on every interface is the "empty" policy, so the default policy applies. The default policy, index, is the "historical" policy in NetBSD 🧚


πŸ’œ overriding stuff πŸ’œ

The operator may override the default policy on ath0:

# sysctl -w net.inet.ip.interfaces.ath0.selectsrc=same-category,common-prefix-len,preference

which yields this policy:

net.inet.ip.selectsrc.default = index
net.inet.ip.interfaces.ath0.selectsrc = same-category,common-prefix-len,preference

The operator may also set a new default:

# sysctl -w net.inet.ip.selectsrc.debug=> same-category,common-prefix-len,preference
# sysctl -w net.inet.ip.interfaces.ath0.selectsrc=
🫣 yes, that => is exactly how it appears in the original β€” copying it character for character, don't come for me

which yields this policy:

net.inet.ip.selectsrc.default = same-category,common-prefix-len,preference
net.inet.ip.interfaces.ath0.selectsrc =

In a number of applications, the policy above will usually pick suitable source addresses if ath0 is configured in this way πŸ’–:

# ifconfig ath0 inet 64.198.255.1/24
# ifconfig ath0 inet 10.0.0.1/24
# ifconfig ath0 inet 169.254.1.1/24
# ifconfig ath0 inet 192.168.49.1/24 preference 5
# ifconfig ath0 inet 192.168.37.1/24 preference 9

There's a sysctl, net.inet.ip.selectsrc.debug, that turns debug messages about source selection on and off. You may set it to 0 (no messages) or 1 ⭐


πŸ” SEE ALSO πŸ”

ifconfig(8), sysctl(8)


πŸ“œ STANDARDS πŸ“œ

The family of IPv6 source-address selection policies defined by RFC3484 resembles the family of IPv4 policies that in_getifa enforces. cousins, basically 🌸


πŸŽ€ AUTHORS πŸŽ€

David Young <dyoung@NetBSD.org> β€” thank you for your service king πŸ‘‘


πŸ’€ BUGS πŸ’€

With options IPSELSRC, a new interface ioctl(2), SIOCSIFADDRPREF, was introduced. It ought to be documented in inet(4). Also, options(4) ought to cross-reference this manual page. some homework left undone, ngl πŸ™ˆ

This work should be used to set IPv6 source-address selection policies, especially the family of policies defined by RFC3484.


and that's the whole page bestie, go configure your interfaces, mwah πŸ’‹

πŸ¦‹ this little number is from the Debian edition of the page, dated February 22, 2007, and it lives at IN_GETIFA(9) β€” iconic, timeless, historic. periodt. πŸ’…βœ¨
πŸ“¦ where this page comes from