[Devel] [PATCH 3/4] Add IPv6 address checkpoint handler
Dan Smith
danms at us.ibm.com
Thu Apr 8 10:48:51 PDT 2010
Signed-off-by: Dan Smith <danms at us.ibm.com>
---
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
+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");
+ 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");
+ 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 at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers
More information about the Devel
mailing list