[2/4] net: Dump regular sit device

Submitted by Pavel Emelianov on July 5, 2017, 1:59 p.m.

Details

Message ID d138b59d-656c-54a1-00db-29c2bf75fa50@virtuozzo.com
State Accepted
Series "SIT device support"
Headers show

Commit Message

Pavel Emelianov July 5, 2017, 1:59 p.m.
Nothing special here, just parse all known NLAs and keep them
on the image.

Issue #11

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/net.c          | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 images/Makefile     |   1 +
 images/netdev.proto |   3 ++
 images/sit.proto    |  22 +++++++++
 4 files changed, 151 insertions(+), 2 deletions(-)
 create mode 100644 images/sit.proto

Patch hide | download patch | download mbox

diff --git a/criu/net.c b/criu/net.c
index 9dda92a..663c65c 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -55,6 +55,30 @@ 
 #define IFLA_MACVLAN_FLAGS 2
 #endif
 
+enum {
+	IFLA_IPTUN_UNSPEC,
+	IFLA_IPTUN_LINK,
+	IFLA_IPTUN_LOCAL,
+	IFLA_IPTUN_REMOTE,
+	IFLA_IPTUN_TTL,
+	IFLA_IPTUN_TOS,
+	IFLA_IPTUN_ENCAP_LIMIT,
+	IFLA_IPTUN_FLOWINFO,
+	IFLA_IPTUN_FLAGS,
+	IFLA_IPTUN_PROTO,
+	IFLA_IPTUN_PMTUDISC,
+	IFLA_IPTUN_6RD_PREFIX,
+	IFLA_IPTUN_6RD_RELAY_PREFIX,
+	IFLA_IPTUN_6RD_PREFIXLEN,
+	IFLA_IPTUN_6RD_RELAY_PREFIXLEN,
+	IFLA_IPTUN_ENCAP_TYPE,
+	IFLA_IPTUN_ENCAP_FLAGS,
+	IFLA_IPTUN_ENCAP_SPORT,
+	IFLA_IPTUN_ENCAP_DPORT,
+	__IFLA_IPTUN_MAX,
+};
+#define IFLA_IPTUN_MAX  (__IFLA_IPTUN_MAX - 1)
+
 static int ns_sysfs_fd = -1;
 
 int read_ns_sys_file(char *path, char *buf, int len)
@@ -658,6 +682,106 @@  static int dump_one_gre(struct ifinfomsg *ifi, char *kind,
 	return dump_unknown_device(ifi, kind, tb, ns, fds);
 }
 
+static int dump_sit(NetDeviceEntry *nde, struct cr_imgset *imgset, struct nlattr **info)
+{
+	int ret;
+	struct nlattr *data[__IFLA_IPTUN_MAX];
+	SitEntry se = SIT_ENTRY__INIT;
+	/* There are for IP(v6) addresses kernel feeds to us */
+	uint32_t a_local, a_remote, rd_prefix[4], rl_prefix;
+
+	if (!info || !info[IFLA_INFO_DATA]) {
+		pr_err("no data for sit\n");
+		return -1;
+	}
+
+	pr_info("Some data for SIT provided\n");
+	ret = nla_parse_nested(data, IFLA_IPTUN_MAX, info[IFLA_INFO_DATA], NULL);
+	if (ret < 0) {
+		pr_err("failed ot parse sit data\n");
+		return -1;
+	}
+
+#define ENCODE_ENTRY(__type, __ifla, __proto)	do {			\
+		if (data[__ifla]) {					\
+			se.__proto = *(__type *)nla_data(data[__ifla]);	\
+			if (se.__proto)					\
+				se.has_##__proto = true;		\
+		}							\
+	} while (0)
+
+	if (data[IFLA_IPTUN_LOCAL]) {
+		a_local = *(u32 *)nla_data(data[IFLA_IPTUN_LOCAL]);
+		if (a_local != 0) {
+			se.n_local = 1;
+			se.local = &a_local;
+		}
+	}
+
+	if (data[IFLA_IPTUN_REMOTE]) {
+		a_remote = *(u32 *)nla_data(data[IFLA_IPTUN_REMOTE]);
+		if (a_remote != 0) {
+			se.n_remote = 1;
+			se.remote = &a_remote;
+		}
+	}
+
+	ENCODE_ENTRY(u32, IFLA_IPTUN_LINK,  link);
+	ENCODE_ENTRY(u8,  IFLA_IPTUN_TTL,   ttl);
+	ENCODE_ENTRY(u8,  IFLA_IPTUN_TOS,   tos);
+	ENCODE_ENTRY(u16, IFLA_IPTUN_FLAGS, flags);
+	ENCODE_ENTRY(u8,  IFLA_IPTUN_PROTO, proto);
+
+	if (data[IFLA_IPTUN_PMTUDISC]) {
+		u8 v;
+
+		v = *(u8 *)nla_data(data[IFLA_IPTUN_PMTUDISC]);
+		if (v)
+			se.pmtudisc = se.has_pmtudisc = true;
+	}
+
+	ENCODE_ENTRY(u16, IFLA_IPTUN_ENCAP_TYPE,  encap_type);
+	ENCODE_ENTRY(u16, IFLA_IPTUN_ENCAP_FLAGS, encap_flags);
+	ENCODE_ENTRY(u16, IFLA_IPTUN_ENCAP_SPORT, encap_sport);
+	ENCODE_ENTRY(u16, IFLA_IPTUN_ENCAP_DPORT, encap_dport);
+
+	if (data[IFLA_IPTUN_6RD_PREFIXLEN]) {
+		se.rd_prefixlen = *(u16 *)nla_data(data[IFLA_IPTUN_6RD_PREFIXLEN]);
+		if (!se.rd_prefixlen)
+			goto skip;
+
+		if (!data[IFLA_IPTUN_6RD_PREFIX]) {
+			pr_err("No 6rd prefix for sit device\n");
+			return -1;
+		}
+
+		se.has_rd_prefixlen = true;
+		memcpy(&rd_prefix, nla_data(data[IFLA_IPTUN_6RD_PREFIX]), sizeof(rd_prefix));
+		se.n_rd_prefix = 4;
+		se.rd_prefix = rd_prefix;
+
+		se.relay_prefixlen = *(u16 *)nla_data(data[IFLA_IPTUN_6RD_RELAY_PREFIXLEN]);
+		if (!se.relay_prefixlen)
+			goto skip;
+
+		if (!data[IFLA_IPTUN_6RD_RELAY_PREFIX]) {
+			pr_err("No 6rd relay prefix for sit device\n");
+			return -1;
+		}
+
+		se.has_relay_prefixlen = true;
+		memcpy(&rl_prefix, nla_data(data[IFLA_IPTUN_6RD_RELAY_PREFIX]), sizeof(rl_prefix));
+		se.n_relay_prefix = 1;
+		se.relay_prefix = &rl_prefix;
+skip:;
+	}
+
+#undef ENCODE_ENTRY
+
+	nde->sit = &se;
+	return write_netdev_img(nde, imgset, info);
+}
+
 static int dump_one_sit(struct ifinfomsg *ifi, char *kind,
 		struct nlattr **tb, struct ns_id *ns, struct cr_imgset *fds)
 {
@@ -679,8 +803,7 @@  static int dump_one_sit(struct ifinfomsg *ifi, char *kind,
 		return 0;
 	}
 
-	pr_warn("SIT device %s not supported natively\n", name);
-	return dump_unknown_device(ifi, kind, tb, ns, fds);
+	return dump_one_netdev(ND_TYPE__SIT, ifi, tb, ns, fds, dump_sit);
 }
 
 static int list_one_link(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
diff --git a/images/Makefile b/images/Makefile
index 0c1f6e7..e62dd52 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -60,6 +60,7 @@  proto-obj-y	+= time.o
 proto-obj-y	+= sysctl.o
 proto-obj-y	+= autofs.o
 proto-obj-y	+= macvlan.o
+proto-obj-y	+= sit.o
 proto-obj-y	+= remote-image.o
 
 CFLAGS		+= -iquote $(obj)/
diff --git a/images/netdev.proto b/images/netdev.proto
index 564dd43..0cd116e 100644
--- a/images/netdev.proto
+++ b/images/netdev.proto
@@ -4,6 +4,7 @@  import "macvlan.proto";
 import "opts.proto";
 import "tun.proto";
 import "sysctl.proto";
+import "sit.proto";
 
 enum nd_type {
 	LOOPBACK	= 1;
@@ -19,6 +20,7 @@  enum nd_type {
 	VENET		= 5; /* OpenVZ device */
 	BRIDGE		= 6;
 	MACVLAN		= 7;
+	SIT		= 8;
 }
 
 message net_device_entry {
@@ -44,6 +46,7 @@  message net_device_entry {
 	optional uint32 peer_nsid	= 13;
 
 	optional uint32 master		= 14;
+	optional sit_entry sit		= 15;
 }
 
 message netns_id {
diff --git a/images/sit.proto b/images/sit.proto
new file mode 100644
index 0000000..7ca91cc
--- /dev/null
+++ b/images/sit.proto
@@ -0,0 +1,22 @@ 
+syntax = "proto2";
+
+import "opts.proto";
+
+message sit_entry {
+	optional uint32 link		= 1;
+	repeated uint32 local		= 2 [(criu).ipadd = true];
+	repeated uint32 remote		= 3 [(criu).ipadd = true];
+	optional uint32 ttl		= 4;
+	optional uint32 tos		= 5;
+	optional bool   pmtudisc	= 6;
+	optional uint32 proto		= 7;
+	optional uint32 flags		= 8;
+	optional uint32 encap_type	= 9;
+	optional uint32 encap_flags	= 10;
+	optional uint32 encap_sport	= 11;
+	optional uint32 encap_dport	= 12;
+	optional uint32 rd_prefixlen	= 13;
+	repeated uint32 rd_prefix	= 14 [(criu).ipadd = true];
+	optional uint32 relay_prefixlen	= 15;
+	repeated uint32 relay_prefix	= 16 [(criu).ipadd = true];
+};