What is the difference between "all", "default" and "eth*" in /proc/sys/net/ipv[46]/conf/?
Solution 1
I'm going to supply a new answer to this question, since many Google search results lead here, and the internet has a lot of outdated information and misinformation about this.
net.ipv{4,6}.conf.default.*
@Martin von Wittich's correct about the behavior of default
-- it's applied to new interfaces only. For a host's interfaces, the default
setting will only apply when new devices are created, and host interfaces are traditionally only created at boot time. Therefore, if you simply change the default
parameter, the value isn't applied to the host interfaces until the host is rebooted.
The behavior is different for containers, Kubernetes and CNI. New container interfaces are created all the time. Therefore if you simply change the default
parameter it will apply to new interfaces created by new containers, but not for existing container interfaces and not for host interfaces. This can be very confusing!
net.ipv{4,6}.conf.all.*
vs. net.ipv{4,6}.conf.<net device>.*
The behavior of net.ipv{4,6}.conf.all.*
, is different depending on the which parameter is being changed, as pointed out by @gaia & @odivlad. The real answer is in the Kernel's documentation and has changed over time (as with rp_filter
, which is a popular parameter for multi-homed systems). Martin's answer above is was on the right track but is now out of date.
The behavior for this feature is documented in the Kernel documentation, which you can find at https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt or https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/networking/ip-sysctl.txt?h=linux-4.15.y (Select your particular Kernel version in the upper right-hand corner).
For example, the value for rp_filter
will be MAXed (not ANDed as stated previously):
The max value from conf/{all,interface}/rp_filter is used
when doing source validation on the {interface}.
arp_filter
, on the other hand, is ORed:
arp_filter for the interface will be enabled if at least one of
conf/{all,interface}/arp_filter is set to TRUE,
it will be disabled otherwise
But what about accept_ra
? Well, Kernel 4.15 documentation doesn't state the behavior in that case, and it's actually not allowed any more on a per-interface basis IIRC. It used to be allowed in Kernel 2.6 (CentOS 6, etc).
Solution 2
I've found the answer while still writing the question. I've decided to post it anyway because others may find this insightful, and then answer it myself; I hope this is not frowned upon :)
As far as I researched for IPv4 some time ago, the "default" value gets
copied to newly created interfaces only once.
"all" on the other hand allways gets applied in addition to the current
setting, but it depends on the exact setting, if its ORed, ANDed, or
whatevered:
log_martians OR
accept_redirects AND
forwarding ?
mc_forwarding AND
medium_id
proxy_arp OR
shared_media OR
secure_redirects OR
send_redirects OR
bootp_relay AND
accept_source_route AND
rp_filter AND
arp_filter OR
arp_announce MAX
arp_ignore MAX
arp_accept
app_solicit
disable_policy
disable_xfrm
tag
(see include/linux/inetdevice.h:83 for IN_DEV_{AND,OR,MAX}CONF)
Putting a new value in "all" doesn't change the value you read from
"$interface", but it only gets computed and used internally.
He doesn't cover accept_ra
but at least it's clear now how all
and default
work, or rather, how they do not work as I would have expected.
Solution 3
The handler for accept_ra
in net/ipv6/addrconf.c
is proc_dointvec
. So generic interface code has previously generated an array of all
and interface-specific entries, and writing into these with sysctl
or procfs just puts the value you specify in the array.
We are concerned with how those values are then used
You'll see from callers of ipv6_accept_ra()
function in include/net/ipv6.h
that every caller uses a specific interface to call that function.
So there is nowhere in the kernel that net.ipv6.conf.all.accept_ra
is ever used except to store a procfs entry, as far as I can see.
If you want to change accept_ra
of every interface with one command, you can do this:
for TUNABLE in $(sysctl -aN --pattern "accept_ra$")
do
sysctl -w "$TUNABLE=0"
done
I'm about 4 years late but this is the correct answer :P
Related videos on Youtube
![Martin von Wittich](https://i.stack.imgur.com/WUKbM.jpg?s=256&g=1)
Martin von Wittich
I'm a software developer working for the German company IServ GmbH.
Updated on September 18, 2022Comments
-
Martin von Wittich almost 2 years
In sysctl, the
/proc/sys/net/ipv[46]/conf/
keys have the following subkeys:all
,default
, and a key for each network interface. For example, on a machine with a single network interface eth0, it will look like this:iserv ~ # ll /proc/sys/net/ipv[46]/conf/ /proc/sys/net/ipv4/conf/: insgesamt 0 dr-xr-xr-x 0 root root 0 12. Sep 23:30 all/ dr-xr-xr-x 0 root root 0 12. Sep 23:30 default/ dr-xr-xr-x 0 root root 0 12. Sep 23:30 eth0/ dr-xr-xr-x 0 root root 0 12. Sep 23:30 lo/ /proc/sys/net/ipv6/conf/: insgesamt 0 dr-xr-xr-x 0 root root 0 12. Sep 23:30 all/ dr-xr-xr-x 0 root root 0 12. Sep 23:30 default/ dr-xr-xr-x 0 root root 0 12. Sep 23:30 eth0/ dr-xr-xr-x 0 root root 0 12. Sep 23:30 lo/
All the respective settings exist in each key separately. For example, if I want to disable IPv6 Router Advertisements with the
accept_ra
value, this value exists four times:iserv ~ # sysctl -a 2>/dev/null | grep "accept_ra " net.ipv6.conf.all.accept_ra = 1 net.ipv6.conf.default.accept_ra = 1 net.ipv6.conf.lo.accept_ra = 1 net.ipv6.conf.eth0.accept_ra = 1
My question now is: which of these values do I need to change? I figured
all
(to change all existing interfaces) anddefault
(to change all new interfaces that may appear later), but changing these still leaves the value at 1 for lo and eth0:iserv ~ # sysctl -w net.ipv6.conf.all.accept_ra=0 net.ipv6.conf.all.accept_ra = 0 iserv ~ # sysctl -w net.ipv6.conf.default.accept_ra=0 net.ipv6.conf.default.accept_ra = 0 iserv ~ # sysctl -a 2>/dev/null | grep "accept_ra " net.ipv6.conf.all.accept_ra = 0 net.ipv6.conf.default.accept_ra = 0 net.ipv6.conf.lo.accept_ra = 1 net.ipv6.conf.eth0.accept_ra = 1
Will the machine now accept Router Advertisements on eth0, or will it not?
-
Martin von Wittich almost 11 yearsOh well, I've found the answer while still writing the question. I will answer it myself in 7 hours (the site won't allow me to do so sooner). Until then here's the link: marc.info/?l=linux-kernel&m=123606366021995&w=2
-
odivlad over 6 yearsAccording to github.com/torvalds/linux/commit/… rp_filter logic was changed 9 years ago. Previously it was ANDed and than changed to MAX.
-
-
mattia.b89 over 7 yearsand for IPv6 stuff? e.g. I'm looking for the
use_tempaddr
parameter... -
Gaia almost 6 yearsrp_filter logic was changed 9 years ago. Previously it was ANDed and than changed to MAX. See "The max value from conf/{all,interface}/rp_filter is used when doing source validation on the {interface}." in git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/… and github.com/torvalds/linux/commit/… (via unix.stackexchange.com/a/427455/18568)
-
qin almost 5 yearssysctl (procps version 3.2.8): error: Unknown parameter "-aN"
-
mvorisek almost 5 years@Gaia Great comment!
-
Mark Norgren almost 3 yearsThanks @Gaia : That's where we can find the real answer-- in the actual documentation source.
-
Mark Norgren almost 3 yearsThanks Martin! It's amazing how hard it is to find answers to these simple questions. I used your answer below for years.
-
Blaise Wang over 2 yearsThanks, your answer does help a lot!