From a95a7bdc95caa3c7ac2817175fd5e531cea86082 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Wed, 5 Jul 2017 16:59:57 +0300 Subject: [PATCH] net: Restore sit device from image Same here -- prepare the IFLA_INFO_DATA section using the date from SitEntry. Issue #11 Signed-off-by: Pavel Emelyanov Signed-off-by: Andrei Vagin --- criu/net.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/criu/net.c b/criu/net.c index d760d01953..50d4d4d9a1 100644 --- a/criu/net.c +++ b/criu/net.c @@ -1411,6 +1411,95 @@ static int restore_one_macvlan(struct ns_id *ns, struct net_link *link, int nlsk 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;