[CRIU] [PATCH v2 2/3] inet: remember ipv6 connections' ifindex for restore
Tycho Andersen
tycho.andersen at canonical.com
Mon Nov 30 07:41:55 PST 2015
On Mon, Nov 30, 2015 at 11:48:12AM +0300, Pavel Emelyanov wrote:
> On 11/27/2015 07:02 PM, Tycho Andersen wrote:
> > On Wed, Nov 25, 2015 at 12:35:21PM +0300, Pavel Emelyanov wrote:
> >>> @@ -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 */
> >> ;
> >>
> >> ?
> >
> > Right, that's why I just put it as a warning, because it's not
> > necessarily fatal unless there is something bound to this device.
> > Anyway, I can send another version (or patch on top if you happen to
> > apply this before monday).
>
> OK, I've applied 2 and 3. About the 1st one -- Andrey had some concern about it,
> I've asked him to send his thoughts on the mailing list.
>
> >>> + }
> >>> }
> >>>
> >>> 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?
> >
> > I think you mean ie->ifname != NULL here? I don't know, but I sure
> > hope so :). If the device doesn't have an ifname, I don't know how we
> > can resolve the ifindex to pass to bind() on restore. Since the
> > original socket creator would have this restriction too, I think it
> > *should* always work :)
>
> OK, that's how I thought. Would you also add this as an additional code comment?
Yep, sounds good. Perhaps we can copy __ipv6_addr_needs_scope_id (or
something similar) to the dumping code, and then fail dump when we
require a scope id, dropping that pr_warn. Anyway, I'll take a look
and send a patch.
Tycho
More information about the CRIU
mailing list