2019-04-25 15:17:50

by Nico Schottelius

[permalink] [raw]
Subject: How to turn off IPv4 without disabling IPv6


Good morning kernel hackers,

we are a small company in Switzerland running some IPv6 only
networks. The systems in the IPv6 only networks do not need any IPv4
support anymore and thus for switches/routers we turned the support off.

Today we tried to turn off IPv4 in the Linux kernel at compile time.
But it seems that as soon as we turn off CONFIG_INET, CONFIG_IPV6 is
automatically turned off as well.

While you can argue that "turning off IPv4 is not necessary", this is
not our point. As IPv4 resources have depleted almost everywhere in the
world a move to IPv6 is inevitable, especially if you are a small
organisation offering Internet services.

Being a (new) small organisation you are already disadvantaged in terms of
IPv4 resources that you can afford, so our objective is to make the life
in the IPv6 world as easy as possible.

If we can build operating systems that don't run IPv4 anymore,
operators have at least a certain degree of complexity less and can
start fresh into adventures, without having to care about iptables,
about IPv4 routing, etc.

Coming back to my original question: is there a way or how would we turn
off IPv4 support in the Linux kernel? So far the only operating system
that is reported to be able to run without IPv4 is FreeBSD [0], but I
hope we can add more in the near future.

Best,

Nico

[0] https://ungleich.ch/en-us/cms/blog/2019/01/09/die-ipv4-die/

--
Your Swiss, Open Source and IPv6 Virtual Machine. Now on http://www.datacenterlight.ch.


2019-04-25 13:20:47

by Adam Borowski

[permalink] [raw]
Subject: Re: How to turn off IPv4 without disabling IPv6

On Thu, Apr 25, 2019 at 11:32:38AM +0200, Nico Schottelius wrote:
> running some IPv6 only
> networks. The systems in the IPv6 only networks do not need any IPv4
> support anymore and thus for switches/routers we turned the support off.

> Today we tried to turn off IPv4 in the Linux kernel at compile time.
> But it seems that as soon as we turn off CONFIG_INET, CONFIG_IPV6 is
> automatically turned off as well.

Even if you don't want global nor even link-scope IPv4, way too many
programs assume that at least 127.0.0.1 (ie, lo) is working. They can't be
reconfigured to use ::1 without patching and rebuilding.

> Coming back to my original question: is there a way or how would we turn
> off IPv4 support in the Linux kernel?

I believe this is not worth your time for today.

Just do what IPv6-haters do on stock modern distros: have no routes for the
other IP version configured; non-buggy programs will do the right thing.

This seems to work well. Heck, I had a busy dev server with broken IPv4, I
didn't notice that for 1.5 years until I tried to pull something directly
from Github (which is still v4 only).

You're a network admin so you know far more than me wrt anything that goes
over the wire -- but as as a distro developer/user, I'd say there's a
considerable cost to have every of tens of thousands programs shipped by a
distro, and many more that are private to a company/university/etc, updated
to autodetect how to access "localhost" on a particular box.

That's an extra moving part where there was none before. Complexity is bad.
Having the IPv4 stack built just for the lo interface simplifies things.


Meow!
--
⢀⣴⠾⠻⢶⣦⠀
⣾⠁⢠⠒⠀⣿⡁ Did ya know that typing "test -j8" instead of "ctest -j8"
⢿⡄⠘⠷⠚⠋⠀ will make your testsuite pass much faster, and fix bugs?
⠈⠳⣄⠀⠀⠀⠀

2019-04-25 16:45:36

by Marco Davids

[permalink] [raw]
Subject: Re: How to turn off IPv4 without disabling IPv6

Op Thu, Apr 25, 2019 at 13:22, Nico Schottelius wrote:
> if I cannot turn off IPv4, I cannot test what needs to be fixed.

You know what? I actually agree with Nico on this.

It's 2019 and the adoption of IPv6 is actually gaining momentum (at last).

This is absolutely the time to seriously start thinking about unbundling
IP-stacks the kernel, so that IPv4 can be truly disabled at compile time.

That will allow for further testing and fixes, just as Nico suggests.

> You can even fully get rid of ARP. Yes, there will
> be the need for some changes / updates, but all of this can only be
> spotted once IPv4 is turned off.

I couldn't agree more.

--
Marco

2019-04-25 17:29:31

by Nico Schottelius

[permalink] [raw]
Subject: Re: How to turn off IPv4 without disabling IPv6


Hey Adam,

thanks for the fast response.


Adam Borowski <[email protected]> writes:

> On Thu, Apr 25, 2019 at 11:32:38AM +0200, Nico Schottelius wrote:
>> running some IPv6 only
>> networks. The systems in the IPv6 only networks do not need any IPv4
>> support anymore and thus for switches/routers we turned the support off.
>
>> Today we tried to turn off IPv4 in the Linux kernel at compile time.
>> But it seems that as soon as we turn off CONFIG_INET, CONFIG_IPV6 is
>> automatically turned off as well.
>
> Even if you don't want global nor even link-scope IPv4, way too many
> programs assume that at least 127.0.0.1 (ie, lo) is working. They can't be
> reconfigured to use ::1 without patching and rebuilding.

I think we have to distinguish here between 2 kinds of programs:

- stuff that listen()s
- stuff that connect()s

Afaics, the latter does not need any lo connectivity, neither v4 nor
v6. It will use whatever IP address the kernel chooses for outgoing
connections.

For the former, I agree that there might be software that actually
fails without having 127.0.0.1. However, if they bind to 0.0.0.0, the
software will actually not work in IPv6 only network anyway.

The big problem here is:

if I cannot turn off IPv4, I cannot test what needs to be fixed.

> [...]
> That's an extra moving part where there was none before. Complexity is bad.
> Having the IPv4 stack built just for the lo interface simplifies
> things.

I tend to disagree with this statement: turning off IPv4 first off all
reduces complexity. You can even fully get rid of ARP. Yes, there will
be the need for some changes / updates, but all of this can only be
spotted once IPv4 is turned off.

Best,

Nico

--
Your Swiss, Open Source and IPv6 Virtual Machine. Now on http://www.datacenterlight.ch.

2019-04-25 20:41:51

by Willy Tarreau

[permalink] [raw]
Subject: Re: How to turn off IPv4 without disabling IPv6

On Thu, Apr 25, 2019 at 06:42:52PM +0200, Marco Davids wrote:
> Op Thu, Apr 25, 2019 at 13:22, Nico Schottelius wrote:
> > if I cannot turn off IPv4, I cannot test what needs to be fixed.
>
> You know what? I actually agree with Nico on this.
>
> It's 2019 and the adoption of IPv6 is actually gaining momentum (at last).
>
> This is absolutely the time to seriously start thinking about unbundling
> IP-stacks the kernel, so that IPv4 can be truly disabled at compile time.
>
> That will allow for further testing and fixes, just as Nico suggests.

While I can understand the value in doing this, I think that there's
much more value in being able to disable it at run time, precisely
because if you have to reboot to a different kernel for each and every
minor application issue you meet, it will take ages before you converge
to something usable.

Probably that for such tests instead you should use a sysctl to allow/deny
IPv4 socket creation. It should be more than enough for program validation.
Something like the following code (not even compile-tested) could possibly
be sufficient.

Just my two cents,
Willy

-------------

diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 104a666..aa9ac80 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -83,6 +83,8 @@ struct netns_ipv4 {
struct xt_table *nat_table;
#endif

+ int sysctl_disable;
+
int sysctl_icmp_echo_ignore_all;
int sysctl_icmp_echo_ignore_broadcasts;
int sysctl_icmp_ignore_bogus_error_responses;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index eab3ebd..0784c41 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -255,6 +255,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
int try_loading_module = 0;
int err;

+ if (net->ipv4.sysctl_disable)
+ return -EAFNOSUPPORT;
+
if (protocol < 0 || protocol >= IPPROTO_MAX)
return -EINVAL;

diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index eeb4041..73a7ead 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -555,6 +555,13 @@ static struct ctl_table ipv4_table[] = {

static struct ctl_table ipv4_net_table[] = {
{
+ .procname = "disable",
+ .data = &init_net.ipv4.sysctl_disable,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
+ {
.procname = "icmp_echo_ignore_all",
.data = &init_net.ipv4.sysctl_icmp_echo_ignore_all,
.maxlen = sizeof(int),