[CRIU] [PATCH 2/2] inet: set IP_FREEBIND before binding socket to an ipv6 address
Pavel Emelyanov
xemul at parallels.com
Thu Nov 19 05:52:40 PST 2015
On 11/19/2015 03:38 PM, Andrew Vagin wrote:
> 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,
Where? If we're in this if branch then rst_freebin is false and we
don't even call restore_opt() below.
> 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.
Yes, "no" is the default and you just set "no" _again_ here. Why?
>>
>>> + }
>>> +
>>> return 0;
>>> }
>>>
>>>
>>
> .
>
More information about the CRIU
mailing list