* [gentoo-portage-dev] [PATCH] process: add _has_ipv6() function
@ 2019-08-03 19:30 Zac Medico
2019-08-03 23:37 ` [gentoo-portage-dev] " Mike Gilbert
0 siblings, 1 reply; 5+ messages in thread
From: Zac Medico @ 2019-08-03 19:30 UTC (permalink / raw
To: gentoo-portage-dev; +Cc: Mike Gilbert, Zac Medico
Add _has_ipv6() function and use it in _configure_loopback_interface()
to decide whether to add an IPv6 address.
Bug: https://bugs.gentoo.org/691290
---
lib/portage/process.py | 40 +++++++++++++++++++++++++++++++++++++---
1 file changed, 37 insertions(+), 3 deletions(-)
diff --git a/lib/portage/process.py b/lib/portage/process.py
index 690421815..ca8b0c172 100644
--- a/lib/portage/process.py
+++ b/lib/portage/process.py
@@ -339,6 +339,9 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
fd_pipes[1] = pw
fd_pipes[2] = pw
+ # Cache _has_ipv6() result for use in child processes.
+ _has_ipv6()
+
# This caches the libc library lookup and _unshare_validator results
# in the current process, so that results are cached for use in
# child processes.
@@ -446,6 +449,38 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
# Everything succeeded
return 0
+__has_ipv6 = None
+
+def _has_ipv6():
+ """
+ Test that both userland and kernel support IPv6, by attempting
+ to create a socket and listen on any unused port of the IPv6
+ ::1 loopback address.
+
+ @rtype: bool
+ @return: True if IPv6 is supported, False otherwise.
+ """
+ global __has_ipv6
+
+ if __has_ipv6 is None:
+ if socket.has_ipv6:
+ sock = None
+ try:
+ # python2.7 sockets do not support context management protocol
+ sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
+ sock.bind(('::1', 0))
+ except EnvironmentError:
+ __has_ipv6 = False
+ else:
+ __has_ipv6 = True
+ finally:
+ if sock is not None:
+ sock.close()
+ else:
+ __has_ipv6 = False
+
+ return __has_ipv6
+
def _configure_loopback_interface():
"""
Configure the loopback interface.
@@ -478,9 +513,8 @@ def _configure_loopback_interface():
try:
subprocess.call(['ip', 'address', 'add', '10.0.0.1/8', 'dev', 'lo'])
- with open(os.devnull, 'wb', 0) as devnull:
- subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'],
- stdout=devnull, stderr=devnull)
+ if _has_ipv6():
+ subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'])
except EnvironmentError as e:
writemsg("Error calling 'ip': %s\n" % e.strerror, noiselevel=-1)
--
2.21.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [gentoo-portage-dev] Re: [PATCH] process: add _has_ipv6() function
2019-08-03 19:30 [gentoo-portage-dev] [PATCH] process: add _has_ipv6() function Zac Medico
@ 2019-08-03 23:37 ` Mike Gilbert
2019-08-04 13:34 ` Mike Gilbert
0 siblings, 1 reply; 5+ messages in thread
From: Mike Gilbert @ 2019-08-03 23:37 UTC (permalink / raw
To: Zac Medico; +Cc: gentoo-portage-dev
On Sat, Aug 3, 2019 at 3:30 PM Zac Medico <zmedico@gentoo.org> wrote:
>
> Add _has_ipv6() function and use it in _configure_loopback_interface()
> to decide whether to add an IPv6 address.
>
> Bug: https://bugs.gentoo.org/691290
> ---
> lib/portage/process.py | 40 +++++++++++++++++++++++++++++++++++++---
> 1 file changed, 37 insertions(+), 3 deletions(-)
>
> diff --git a/lib/portage/process.py b/lib/portage/process.py
> index 690421815..ca8b0c172 100644
> --- a/lib/portage/process.py
> +++ b/lib/portage/process.py
> @@ -339,6 +339,9 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
> fd_pipes[1] = pw
> fd_pipes[2] = pw
>
> + # Cache _has_ipv6() result for use in child processes.
> + _has_ipv6()
> +
> # This caches the libc library lookup and _unshare_validator results
> # in the current process, so that results are cached for use in
> # child processes.
> @@ -446,6 +449,38 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
> # Everything succeeded
> return 0
>
> +__has_ipv6 = None
> +
> +def _has_ipv6():
> + """
> + Test that both userland and kernel support IPv6, by attempting
> + to create a socket and listen on any unused port of the IPv6
> + ::1 loopback address.
> +
> + @rtype: bool
> + @return: True if IPv6 is supported, False otherwise.
> + """
> + global __has_ipv6
> +
> + if __has_ipv6 is None:
> + if socket.has_ipv6:
> + sock = None
> + try:
> + # python2.7 sockets do not support context management protocol
> + sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
> + sock.bind(('::1', 0))
> + except EnvironmentError:
> + __has_ipv6 = False
> + else:
> + __has_ipv6 = True
> + finally:
> + if sock is not None:
> + sock.close()
> + else:
> + __has_ipv6 = False
> +
> + return __has_ipv6
> +
> def _configure_loopback_interface():
> """
> Configure the loopback interface.
> @@ -478,9 +513,8 @@ def _configure_loopback_interface():
>
> try:
> subprocess.call(['ip', 'address', 'add', '10.0.0.1/8', 'dev', 'lo'])
> - with open(os.devnull, 'wb', 0) as devnull:
> - subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'],
> - stdout=devnull, stderr=devnull)
> + if _has_ipv6():
> + subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'])
> except EnvironmentError as e:
> writemsg("Error calling 'ip': %s\n" % e.strerror, noiselevel=-1)
>
> --
> 2.21.0
>
This seems reasonable, though I don't have an IPv6-less system to test it on.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [gentoo-portage-dev] Re: [PATCH] process: add _has_ipv6() function
2019-08-03 23:37 ` [gentoo-portage-dev] " Mike Gilbert
@ 2019-08-04 13:34 ` Mike Gilbert
2019-08-04 13:40 ` Mike Gilbert
0 siblings, 1 reply; 5+ messages in thread
From: Mike Gilbert @ 2019-08-04 13:34 UTC (permalink / raw
To: Zac Medico; +Cc: gentoo-portage-dev
On Sat, Aug 3, 2019 at 7:37 PM Mike Gilbert <floppym@gentoo.org> wrote:
>
> On Sat, Aug 3, 2019 at 3:30 PM Zac Medico <zmedico@gentoo.org> wrote:
> >
> > Add _has_ipv6() function and use it in _configure_loopback_interface()
> > to decide whether to add an IPv6 address.
> >
> > Bug: https://bugs.gentoo.org/691290
> > ---
> > lib/portage/process.py | 40 +++++++++++++++++++++++++++++++++++++---
> > 1 file changed, 37 insertions(+), 3 deletions(-)
> >
> > diff --git a/lib/portage/process.py b/lib/portage/process.py
> > index 690421815..ca8b0c172 100644
> > --- a/lib/portage/process.py
> > +++ b/lib/portage/process.py
> > @@ -339,6 +339,9 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
> > fd_pipes[1] = pw
> > fd_pipes[2] = pw
> >
> > + # Cache _has_ipv6() result for use in child processes.
> > + _has_ipv6()
> > +
> > # This caches the libc library lookup and _unshare_validator results
> > # in the current process, so that results are cached for use in
> > # child processes.
> > @@ -446,6 +449,38 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
> > # Everything succeeded
> > return 0
> >
> > +__has_ipv6 = None
> > +
> > +def _has_ipv6():
> > + """
> > + Test that both userland and kernel support IPv6, by attempting
> > + to create a socket and listen on any unused port of the IPv6
> > + ::1 loopback address.
> > +
> > + @rtype: bool
> > + @return: True if IPv6 is supported, False otherwise.
> > + """
> > + global __has_ipv6
> > +
> > + if __has_ipv6 is None:
> > + if socket.has_ipv6:
> > + sock = None
> > + try:
> > + # python2.7 sockets do not support context management protocol
> > + sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
> > + sock.bind(('::1', 0))
> > + except EnvironmentError:
> > + __has_ipv6 = False
> > + else:
> > + __has_ipv6 = True
> > + finally:
> > + if sock is not None:
> > + sock.close()
> > + else:
> > + __has_ipv6 = False
> > +
> > + return __has_ipv6
> > +
> > def _configure_loopback_interface():
> > """
> > Configure the loopback interface.
> > @@ -478,9 +513,8 @@ def _configure_loopback_interface():
> >
> > try:
> > subprocess.call(['ip', 'address', 'add', '10.0.0.1/8', 'dev', 'lo'])
> > - with open(os.devnull, 'wb', 0) as devnull:
> > - subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'],
> > - stdout=devnull, stderr=devnull)
> > + if _has_ipv6():
> > + subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'])
> > except EnvironmentError as e:
> > writemsg("Error calling 'ip': %s\n" % e.strerror, noiselevel=-1)
> >
> > --
> > 2.21.0
> >
>
> This seems reasonable, though I don't have an IPv6-less system to test it on.
While chatting in #gentoo-desktop, we found that it is possible to
have IPv6 enabled, but prohibit IPv6 addresses from being added to
interfaces. This produces the following error from ip:
RTNETLINK answers: Permission denied
https://www.kernel.org/doc/Documentation/networking/ipv6.txt
ipv6.disabled = 0
ipv6.disable_ipv6 = 1
I don't think your __has_ipv6 function will catch this.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [gentoo-portage-dev] Re: [PATCH] process: add _has_ipv6() function
2019-08-04 13:34 ` Mike Gilbert
@ 2019-08-04 13:40 ` Mike Gilbert
2019-08-04 13:46 ` Mike Gilbert
0 siblings, 1 reply; 5+ messages in thread
From: Mike Gilbert @ 2019-08-04 13:40 UTC (permalink / raw
To: Zac Medico; +Cc: gentoo-portage-dev
On Sun, Aug 4, 2019 at 9:34 AM Mike Gilbert <floppym@gentoo.org> wrote:
>
> On Sat, Aug 3, 2019 at 7:37 PM Mike Gilbert <floppym@gentoo.org> wrote:
> >
> > On Sat, Aug 3, 2019 at 3:30 PM Zac Medico <zmedico@gentoo.org> wrote:
> > >
> > > Add _has_ipv6() function and use it in _configure_loopback_interface()
> > > to decide whether to add an IPv6 address.
> > >
> > > Bug: https://bugs.gentoo.org/691290
> > > ---
> > > lib/portage/process.py | 40 +++++++++++++++++++++++++++++++++++++---
> > > 1 file changed, 37 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/lib/portage/process.py b/lib/portage/process.py
> > > index 690421815..ca8b0c172 100644
> > > --- a/lib/portage/process.py
> > > +++ b/lib/portage/process.py
> > > @@ -339,6 +339,9 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
> > > fd_pipes[1] = pw
> > > fd_pipes[2] = pw
> > >
> > > + # Cache _has_ipv6() result for use in child processes.
> > > + _has_ipv6()
> > > +
> > > # This caches the libc library lookup and _unshare_validator results
> > > # in the current process, so that results are cached for use in
> > > # child processes.
> > > @@ -446,6 +449,38 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
> > > # Everything succeeded
> > > return 0
> > >
> > > +__has_ipv6 = None
> > > +
> > > +def _has_ipv6():
> > > + """
> > > + Test that both userland and kernel support IPv6, by attempting
> > > + to create a socket and listen on any unused port of the IPv6
> > > + ::1 loopback address.
> > > +
> > > + @rtype: bool
> > > + @return: True if IPv6 is supported, False otherwise.
> > > + """
> > > + global __has_ipv6
> > > +
> > > + if __has_ipv6 is None:
> > > + if socket.has_ipv6:
> > > + sock = None
> > > + try:
> > > + # python2.7 sockets do not support context management protocol
> > > + sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
> > > + sock.bind(('::1', 0))
> > > + except EnvironmentError:
> > > + __has_ipv6 = False
> > > + else:
> > > + __has_ipv6 = True
> > > + finally:
> > > + if sock is not None:
> > > + sock.close()
> > > + else:
> > > + __has_ipv6 = False
> > > +
> > > + return __has_ipv6
> > > +
> > > def _configure_loopback_interface():
> > > """
> > > Configure the loopback interface.
> > > @@ -478,9 +513,8 @@ def _configure_loopback_interface():
> > >
> > > try:
> > > subprocess.call(['ip', 'address', 'add', '10.0.0.1/8', 'dev', 'lo'])
> > > - with open(os.devnull, 'wb', 0) as devnull:
> > > - subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'],
> > > - stdout=devnull, stderr=devnull)
> > > + if _has_ipv6():
> > > + subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'])
> > > except EnvironmentError as e:
> > > writemsg("Error calling 'ip': %s\n" % e.strerror, noiselevel=-1)
> > >
> > > --
> > > 2.21.0
> > >
> >
> > This seems reasonable, though I don't have an IPv6-less system to test it on.
>
> While chatting in #gentoo-desktop, we found that it is possible to
> have IPv6 enabled, but prohibit IPv6 addresses from being added to
> interfaces. This produces the following error from ip:
>
> RTNETLINK answers: Permission denied
>
> https://www.kernel.org/doc/Documentation/networking/ipv6.txt
>
> ipv6.disabled = 0
> ipv6.disable_ipv6 = 1
>
> I don't think your __has_ipv6 function will catch this.
Possibly the bind('::1', 0) call will fail if the loopback interface
doesn't have that address configured. This appears to be the case when
disable_ipv6 = 1.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [gentoo-portage-dev] Re: [PATCH] process: add _has_ipv6() function
2019-08-04 13:40 ` Mike Gilbert
@ 2019-08-04 13:46 ` Mike Gilbert
0 siblings, 0 replies; 5+ messages in thread
From: Mike Gilbert @ 2019-08-04 13:46 UTC (permalink / raw
To: Zac Medico; +Cc: gentoo-portage-dev
On Sun, Aug 4, 2019 at 9:40 AM Mike Gilbert <floppym@gentoo.org> wrote:
>
> On Sun, Aug 4, 2019 at 9:34 AM Mike Gilbert <floppym@gentoo.org> wrote:
> >
> > On Sat, Aug 3, 2019 at 7:37 PM Mike Gilbert <floppym@gentoo.org> wrote:
> > >
> > > On Sat, Aug 3, 2019 at 3:30 PM Zac Medico <zmedico@gentoo.org> wrote:
> > > >
> > > > Add _has_ipv6() function and use it in _configure_loopback_interface()
> > > > to decide whether to add an IPv6 address.
> > > >
> > > > Bug: https://bugs.gentoo.org/691290
> > > > ---
> > > > lib/portage/process.py | 40 +++++++++++++++++++++++++++++++++++++---
> > > > 1 file changed, 37 insertions(+), 3 deletions(-)
> > > >
> > > > diff --git a/lib/portage/process.py b/lib/portage/process.py
> > > > index 690421815..ca8b0c172 100644
> > > > --- a/lib/portage/process.py
> > > > +++ b/lib/portage/process.py
> > > > @@ -339,6 +339,9 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
> > > > fd_pipes[1] = pw
> > > > fd_pipes[2] = pw
> > > >
> > > > + # Cache _has_ipv6() result for use in child processes.
> > > > + _has_ipv6()
> > > > +
> > > > # This caches the libc library lookup and _unshare_validator results
> > > > # in the current process, so that results are cached for use in
> > > > # child processes.
> > > > @@ -446,6 +449,38 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
> > > > # Everything succeeded
> > > > return 0
> > > >
> > > > +__has_ipv6 = None
> > > > +
> > > > +def _has_ipv6():
> > > > + """
> > > > + Test that both userland and kernel support IPv6, by attempting
> > > > + to create a socket and listen on any unused port of the IPv6
> > > > + ::1 loopback address.
> > > > +
> > > > + @rtype: bool
> > > > + @return: True if IPv6 is supported, False otherwise.
> > > > + """
> > > > + global __has_ipv6
> > > > +
> > > > + if __has_ipv6 is None:
> > > > + if socket.has_ipv6:
> > > > + sock = None
> > > > + try:
> > > > + # python2.7 sockets do not support context management protocol
> > > > + sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
> > > > + sock.bind(('::1', 0))
> > > > + except EnvironmentError:
> > > > + __has_ipv6 = False
> > > > + else:
> > > > + __has_ipv6 = True
> > > > + finally:
> > > > + if sock is not None:
> > > > + sock.close()
> > > > + else:
> > > > + __has_ipv6 = False
> > > > +
> > > > + return __has_ipv6
> > > > +
> > > > def _configure_loopback_interface():
> > > > """
> > > > Configure the loopback interface.
> > > > @@ -478,9 +513,8 @@ def _configure_loopback_interface():
> > > >
> > > > try:
> > > > subprocess.call(['ip', 'address', 'add', '10.0.0.1/8', 'dev', 'lo'])
> > > > - with open(os.devnull, 'wb', 0) as devnull:
> > > > - subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'],
> > > > - stdout=devnull, stderr=devnull)
> > > > + if _has_ipv6():
> > > > + subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo'])
> > > > except EnvironmentError as e:
> > > > writemsg("Error calling 'ip': %s\n" % e.strerror, noiselevel=-1)
> > > >
> > > > --
> > > > 2.21.0
> > > >
> > >
> > > This seems reasonable, though I don't have an IPv6-less system to test it on.
> >
> > While chatting in #gentoo-desktop, we found that it is possible to
> > have IPv6 enabled, but prohibit IPv6 addresses from being added to
> > interfaces. This produces the following error from ip:
> >
> > RTNETLINK answers: Permission denied
> >
> > https://www.kernel.org/doc/Documentation/networking/ipv6.txt
> >
> > ipv6.disabled = 0
> > ipv6.disable_ipv6 = 1
> >
> > I don't think your __has_ipv6 function will catch this.
>
> Possibly the bind('::1', 0) call will fail if the loopback interface
> doesn't have that address configured. This appears to be the case when
> disable_ipv6 = 1.
We confirmed that the bind() call will raise this error, which is good.
OSError: [Errno 99] Cannot assign requested address
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-08-04 13:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-03 19:30 [gentoo-portage-dev] [PATCH] process: add _has_ipv6() function Zac Medico
2019-08-03 23:37 ` [gentoo-portage-dev] " Mike Gilbert
2019-08-04 13:34 ` Mike Gilbert
2019-08-04 13:40 ` Mike Gilbert
2019-08-04 13:46 ` Mike Gilbert
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox