[CRIU] [PATCH v2 2/3] inet: remember ipv6 connections' ifindex for restore
Pavel Emelyanov
xemul at parallels.com
Wed Nov 25 01:35:21 PST 2015
> @@ -298,6 +301,21 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
>
> ie.v6only = val ? true : false;
> ie.has_v6only = true;
> +
> + /* ifindex only matters on source ports for bind, so let's
> + * find only that ifindex. */
> + if (getsockopt(lfd, SOL_SOCKET, SO_BINDTODEVICE, device, &len) < 0) {
> + pr_perror("can't get ifname");
> + goto err;
> + }
> +
> + if (len > 0) {
> + ie.ifname = xstrdup(device);
> + if (!ie.ifname)
> + goto err;
> + } else {
> + pr_warn("couldn't find ifname for %d, can't bind\n", id);
The "no device" is a valid situation actually. Would you (incrementally is OK)
relax this check to
else if (len == 0)
/* do nothing, it's OK not to have a device */
;
?
> + }
> }
>
> ie.src_addr = xmalloc(pb_repeated_size(&ie, src_addr));
> @@ -607,7 +625,7 @@ union sockaddr_inet {
> };
>
> static int restore_sockaddr(union sockaddr_inet *sa,
> - int family, u32 pb_port, u32 *pb_addr)
> + int family, u32 pb_port, u32 *pb_addr, u32 ifindex)
> {
> BUILD_BUG_ON(sizeof(sa->v4.sin_addr.s_addr) > PB_ALEN_INET * sizeof(u32));
> BUILD_BUG_ON(sizeof(sa->v6.sin6_addr.s6_addr) > PB_ALEN_INET6 * sizeof(u32));
> @@ -625,6 +643,12 @@ static int restore_sockaddr(union sockaddr_inet *sa,
> sa->v6.sin6_family = AF_INET6;
> sa->v6.sin6_port = htons(pb_port);
> memcpy(sa->v6.sin6_addr.s6_addr, pb_addr, sizeof(sa->v6.sin6_addr.s6_addr));
> +
> + /* Here although the struct member is called scope_id, the
> + * kernel really wants ifindex. See
> + * /net/ipv6/af_inet6.c:inet6_bind for details.
The inet6_bind doesn't _always_ require a device, but only for __ipv6_addr_needs_scope_id :)
Do I get it right that for those cases we will have ie->ifname == NULL at dump?
> + */
> + sa->v6.sin6_scope_id = ifindex;
> return sizeof(sa->v6);
> }
>
More information about the CRIU
mailing list