[CRIU] [PATCH 2/2] inet: set IP_FREEBIND before binding socket to an ipv6 address

Andrew Vagin avagin at virtuozzo.com
Thu Nov 19 04:38:44 PST 2015


On Thu, Nov 19, 2015 at 03:33:37PM +0300, Pavel Emelyanov wrote:
> On 11/18/2015 06:58 PM, Andrey Vagin wrote:
> > From: Andrew Vagin <avagin at virtuozzo.com>
> > 
> > When we restore ipv6 addresses, they go through a “tentative” phase
> > and sockets could not be bound to them in this moment.
> > 
> > Reported-by: Ross Boucher <boucher at gmail.com>
> > Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
> > ---
> >  sk-inet.c | 29 ++++++++++++++++++++++++-----
> >  1 file changed, 24 insertions(+), 5 deletions(-)
> > 
> > diff --git a/sk-inet.c b/sk-inet.c
> > index 779a1bd..a973000 100644
> > --- a/sk-inet.c
> > +++ b/sk-inet.c
> > @@ -633,17 +633,29 @@ static int restore_sockaddr(union sockaddr_inet *sa,
> >  
> >  int inet_bind(int sk, struct inet_sk_info *ii)
> >  {
> > +	bool rst_freebind = false;
> >  	union sockaddr_inet addr;
> >  	int addr_size;
> > -	int val;
> >  
> >  	addr_size = restore_sockaddr(&addr, ii->ie->family,
> >  			ii->ie->src_port, ii->ie->src_addr);
> >  
> > -	val = 1;
> > -	if (setsockopt(sk, SOL_IP, IP_FREEBIND, &val, sizeof(int))) {
> > -		pr_perror("Unable to set IP_FREEBIND");
> > -		return -1;
> > +	/*
> > +	 * ipv6 addresses go through a “tentative” phase and
> > +	 * sockets could not be bound to them in this moment
> > +	 * without setting IP_FREEBIND.
> > +	 */
> > +	if (ii->ie->family == AF_INET6) {
> > +		int yes = 1;
> > +
> > +		if (restore_opt(sk, SOL_IP, IP_FREEBIND, &yes))
> > +			return -1;
> > +
> > +		if (ii->ie->ip_opts && ii->ie->ip_opts->freebind)
> > +			/* don't restore freebind in restore_ip_opts() */
> 
> At all? When will it get restored then?

We set the right value here, so we don't need to restore it in
restore_ip_opts()
> 
> > +			ii->ie->ip_opts->has_freebind = false;
> > +		else
> > +			rst_freebind = true;
> >  	}
> >  
> >  	if (bind(sk, (struct sockaddr *)&addr, addr_size) == -1) {
> > @@ -651,6 +663,13 @@ int inet_bind(int sk, struct inet_sk_info *ii)
> >  		return -1;
> >  	}
> >  
> > +	if (rst_freebind) {
> > +		int no = 0;
> > +
> > +		if (restore_opt(sk, SOL_IP, IP_FREEBIND, &no))
> > +			return -1;
> 
> Why here? Why not delay "NO" till actual options restore?

because we restore only "yes", "no" is default.

> 
> > +	}
> > +
> >  	return 0;
> >  }
> >  
> > 
> 


More information about the CRIU mailing list