[3/4] net: Restore sit device from image

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

Details

Message ID 47998a1a-b84b-0042-fd99-92774367b865@virtuozzo.com
State Accepted
Series "SIT device support"
Commit 1e01754f996b7ed2ccabb7f45d9efbf441db8a68
Headers show

Commit Message

Pavel Emelianov July 5, 2017, 1:59 p.m.
Same here -- prepare the IFLA_INFO_DATA section using the
date from SitEntry.

Issue #11

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/net.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/net.c b/criu/net.c
index 663c65c..8b479fc 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1411,6 +1411,95 @@  out:
 	return ret;
 }
 
+static int sit_link_info(struct ns_id *ns, struct net_link *link, struct newlink_req *req)
+{
+	struct rtattr *sit_data;
+	NetDeviceEntry *nde = link->nde;
+	SitEntry *se = nde->sit;
+
+	if (!se) {
+		pr_err("Missing sit entry %d\n", nde->ifindex);
+		return -1;
+	}
+
+	addattr_l(&req->h, sizeof(*req), IFLA_INFO_KIND, "sit", 3);
+	sit_data = NLMSG_TAIL(&req->h);
+	addattr_l(&req->h, sizeof(*req), IFLA_INFO_DATA, NULL, 0);
+
+#define DECODE_ENTRY(__type, __ifla, __proto) do {				\
+			__type aux;						\
+			if (se->has_##__proto) {				\
+				aux = se->__proto;				\
+				addattr_l(&req->h, sizeof(*req), __ifla,	\
+						&aux, sizeof(__type));		\
+			}							\
+		} while (0)
+
+	if (se->n_local) {
+		if (se->n_local != 1) {
+			pr_err("Too long local addr for sit\n");
+			return -1;
+		}
+		addattr_l(&req->h, sizeof(*req), IFLA_IPTUN_LOCAL, se->local, sizeof(u32));
+	}
+
+	if (se->n_remote) {
+		if (se->n_remote != 1) {
+			pr_err("Too long remote addr for sit\n");
+			return -1;
+		}
+		addattr_l(&req->h, sizeof(*req), IFLA_IPTUN_REMOTE, se->remote, sizeof(u32));
+	}
+
+	DECODE_ENTRY(u32, IFLA_IPTUN_LINK,  link);
+	DECODE_ENTRY(u8,  IFLA_IPTUN_TTL,   ttl);
+	DECODE_ENTRY(u8,  IFLA_IPTUN_TOS,   tos);
+	DECODE_ENTRY(u16, IFLA_IPTUN_FLAGS, flags);
+	DECODE_ENTRY(u8,  IFLA_IPTUN_PROTO, proto);
+
+	if (se->has_pmtudisc && se->pmtudisc) {
+		u8 aux = 1;
+		addattr_l(&req->h, sizeof(*req), IFLA_IPTUN_PMTUDISC, &aux, sizeof(u8));
+	}
+
+	DECODE_ENTRY(u16, IFLA_IPTUN_ENCAP_TYPE,  encap_type);
+	DECODE_ENTRY(u16, IFLA_IPTUN_ENCAP_FLAGS, encap_flags);
+	DECODE_ENTRY(u16, IFLA_IPTUN_ENCAP_SPORT, encap_sport);
+	DECODE_ENTRY(u16, IFLA_IPTUN_ENCAP_DPORT, encap_dport);
+
+	if (!se->has_rd_prefixlen) {
+		u16 aux;
+
+		if (se->n_rd_prefix != 4) {
+			pr_err("Bad 6rd prefixlen for sit\n");
+			return -1;
+		}
+
+		aux = se->rd_prefixlen;
+		addattr_l(&req->h, sizeof(*req), IFLA_IPTUN_6RD_PREFIXLEN, &aux, sizeof(u16));
+		addattr_l(&req->h, sizeof(*req), IFLA_IPTUN_6RD_PREFIX, se->rd_prefix, 4 * sizeof(u32));
+
+		if (!se->has_relay_prefixlen)
+			goto skip;
+
+		if (se->n_relay_prefix != 1) {
+			pr_err("Bad 6rd relay prefixlen for sit\n");
+			return -1;
+		}
+
+		aux = se->relay_prefixlen;
+		addattr_l(&req->h, sizeof(*req), IFLA_IPTUN_6RD_RELAY_PREFIXLEN, &aux, sizeof(u16));
+		addattr_l(&req->h, sizeof(*req), IFLA_IPTUN_6RD_RELAY_PREFIX, se->relay_prefix, sizeof(u32));
+skip:;
+	}
+
+#undef DECODE_ENTRY
+
+	sit_data->rta_len = (void *)NLMSG_TAIL(&req->h) - (void *)sit_data;
+
+	return 0;
+}
+
 static int __restore_link(struct ns_id *ns, struct net_link *link, int nlsk)
 {
 	NetDeviceEntry *nde = link->nde;
@@ -1431,6 +1520,8 @@  static int __restore_link(struct ns_id *ns, struct net_link *link, int nlsk)
 		return restore_one_link(ns, link, nlsk, bridge_link_info, NULL);
 	case ND_TYPE__MACVLAN:
 		return restore_one_macvlan(ns, link, nlsk);
+	case ND_TYPE__SIT:
+		return restore_one_link(ns, link, nlsk, sit_link_info, NULL);
 	default:
 		pr_err("Unsupported link type %d\n", link->nde->type);
 		break;