Quoting Dan Smith (danms@xxxxxxxxxx): > Signed-off-by: Dan Smith <danms@xxxxxxxxxx> > --- > include/linux/checkpoint_hdr.h | 8 +++ > net/ipv6/addrconf.c | 95 ++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 103 insertions(+), 0 deletions(-) > > diff --git a/include/linux/checkpoint_hdr.h b/include/linux/checkpoint_hdr.h > index 13bf62c..98aa79c 100644 > --- a/include/linux/checkpoint_hdr.h > +++ b/include/linux/checkpoint_hdr.h > @@ -804,6 +804,7 @@ struct ckpt_hdr_netdev { > > enum ckpt_netdev_addr_types { > CKPT_NETDEV_ADDR_IPV4, > + CKPT_NETDEV_ADDR_IPV6, > CKPT_NETDEV_ADDR_MAX > }; > > @@ -816,6 +817,13 @@ struct ckpt_netdev_addr { > __be32 inet4_mask; > __be32 inet4_broadcast; > }; > + struct { > + struct in6_addr inet6_addr; > + __u32 inet6_prefix_len; > + __u32 inet6_valid_lft; > + __u32 inet6_prefered_lft; > + __u16 inet6_scope; > + }; > } __attribute__((aligned(8))); > } __attribute__((aligned(8))); > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index 143791d..75cc3b8 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -87,6 +87,8 @@ > #include <linux/proc_fs.h> > #include <linux/seq_file.h> > > +#include <linux/checkpoint.h> > + > /* Set to 3 to get tracing... */ > #define ACONF_DEBUG 2 > > @@ -4514,6 +4516,91 @@ int unregister_inet6addr_notifier(struct notifier_block *nb) > > EXPORT_SYMBOL(unregister_inet6addr_notifier); > > +#ifdef CONFIG_NETNS_CHECKPOING How could that be defined? :) > +static int inet6_checkpoint(struct ckpt_ctx *ctx, struct net_device *dev, > + int index, int max, > + struct ckpt_netdev_addr *addrs) > +{ > + struct inet6_dev *indev = dev->ip6_ptr; > + struct inet6_ifaddr *addr; > + struct ifmcaddr6 *mcaddr; > + struct ifacaddr6 *acaddr; > + > + for (addr = indev->addr_list; addr; addr = addr->if_next) { > + if (ipv6_addr_scope(&addr->addr)) > + continue; /* Ignore non-global scope addresses */ > + > + addrs[index].type = CKPT_NETDEV_ADDR_IPV6; > + > + ipv6_addr_copy(&addrs[index].inet6_addr, &addr->addr); > + > + ckpt_debug("Checkpointed inet6: %pI6\n", &addr->addr); > + > + addrs[index].inet6_prefix_len = addr->prefix_len; > + addrs[index].inet6_valid_lft = addr->valid_lft; > + addrs[index].inet6_prefered_lft = addr->prefered_lft; > + addrs[index].inet6_scope = addr->scope; > + > + if (++index >= max) > + return -E2BIG; > + } > + > + for (mcaddr = indev->mc_list; mcaddr; mcaddr = mcaddr->next) { > + if (ipv6_addr_scope(&mcaddr->mca_addr)) > + continue; /* Ignore non-global scope addresses */ > + > + /* TODO */ > + > + /* Multicast addresses are not supported, so do not > + * allow checkpoint to continue if one is assigned > + */ > + ckpt_debug("ipv6 multicast addresses are not supported\n"); Again, I'd prefer ckpt_err here. Note that in my last email that really was a q - if you're under spinlock here, then you can't use ckpt_err(). > + return -EINVAL; > + } > + > + for (acaddr = indev->ac_list; acaddr; acaddr = acaddr->aca_next) { > + if (ipv6_addr_scope(&acaddr->aca_addr)) > + continue; /* Ignore non-global scope addresses */ > + > + /* TODO */ > + > + /* Anycast addresses are not supported, so do not > + * allow checkpoint to continue if one is assigned > + */ > + ckpt_debug("ipv6 anycast addresses are not supported\n"); and here > + return -EINVAL; > + } > + > + return index; > +} > + > +static int inet6_restore(struct ckpt_ctx *ctx, > + struct net_device *dev, > + struct net *net, > + struct ckpt_netdev_addr *addr) > +{ > + int ret; > + > + rtnl_lock(); > + ret = inet6_addr_add(net, dev->ifindex, &addr->inet6_addr, > + addr->inet6_prefix_len, IFA_F_PERMANENT, > + INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); > + rtnl_unlock(); > + if (ret < 0) > + ckpt_err(ctx, ret, "Failed to set address %pI6\n", > + &addr->inet6_addr); > + > + return ret; > +} > + > +struct ckpt_netdev_addr_handler inet6_addr_handler = { > + .type = CKPT_NETDEV_ADDR_IPV6, > + .owner = THIS_MODULE, > + .checkpoint_addr = inet6_checkpoint, > + .restore_addr = inet6_restore, > +}; > +#endif /* CONFIG_NETNS_CHECKPOINT */ > + > /* > * Init / cleanup code > */ > @@ -4572,6 +4659,10 @@ int __init addrconf_init(void) > > ipv6_addr_label_rtnl_register(); > > +#ifdef CONFIG_NETNS_CHECKPOINT > + ckpt_netdev_addr_register(&inet6_addr_handler); > +#endif > + > return 0; > errout: > unregister_netdevice_notifier(&ipv6_dev_notf); > @@ -4590,6 +4681,10 @@ void addrconf_cleanup(void) > unregister_netdevice_notifier(&ipv6_dev_notf); > unregister_pernet_subsys(&addrconf_ops); > > +#ifdef CONFIG_NETNS_CHECKPOINT > + ckpt_netdev_addr_unregister(&inet6_addr_handler); > +#endif > + > rtnl_lock(); > > /* clean dev list */ > -- > 1.6.2.5 _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers