From 4ab47d47af20addd6ecee1ece0205b1fbf483942 Mon Sep 17 00:00:00 2001 From: Antony Antony Date: Tue, 6 Jun 2017 12:12:13 +0200 Subject: xfrm: extend MIGRATE with UDP encapsulation port Add UDP encapsulation port to XFRM_MSG_MIGRATE using an optional netlink attribute XFRMA_ENCAP. The devices that support IKE MOBIKE extension (RFC-4555 Section 3.8) could go to sleep for a few minutes and wake up. When it wake up the NAT mapping could have expired, the device send a MOBIKE UPDATE_SA message to migrate the IPsec SA. The change could be a change UDP encapsulation port, IP address, or both. Reported-by: Paul Wouters Signed-off-by: Antony Antony Reviewed-by: Richard Guy Briggs Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_user.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'net/xfrm/xfrm_user.c') diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 38614df33ec8..fb98892f7d89 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2243,6 +2243,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, int err; int n = 0; struct net *net = sock_net(skb->sk); + struct xfrm_encap_tmpl *encap = NULL; if (attrs[XFRMA_MIGRATE] == NULL) return -EINVAL; @@ -2260,9 +2261,18 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, if (!n) return 0; - xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net); + if (attrs[XFRMA_ENCAP]) { + encap = kmemdup(nla_data(attrs[XFRMA_ENCAP]), + sizeof(*encap), GFP_KERNEL); + if (!encap) + return 0; + } - return 0; + err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap); + + kfree(encap); + + return err; } #else static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh, -- cgit v1.2.1 From 8bafd73093f2f431f5a363f8057abc0ccc118853 Mon Sep 17 00:00:00 2001 From: Antony Antony Date: Tue, 6 Jun 2017 12:12:14 +0200 Subject: xfrm: add UDP encapsulation port in migrate message Add XFRMA_ENCAP, UDP encapsulation port, to km_migrate announcement to userland. Only add if XFRMA_ENCAP was in user migrate request. Signed-off-by: Antony Antony Reviewed-by: Richard Guy Briggs Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_user.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'net/xfrm/xfrm_user.c') diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index fb98892f7d89..6197c7231bc7 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2314,17 +2314,20 @@ static int copy_to_user_kmaddress(const struct xfrm_kmaddress *k, struct sk_buff return nla_put(skb, XFRMA_KMADDRESS, sizeof(uk), &uk); } -static inline size_t xfrm_migrate_msgsize(int num_migrate, int with_kma) +static inline size_t xfrm_migrate_msgsize(int num_migrate, int with_kma, + int with_encp) { return NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id)) + (with_kma ? nla_total_size(sizeof(struct xfrm_kmaddress)) : 0) + + (with_encp ? nla_total_size(sizeof(struct xfrm_encap_tmpl)) : 0) + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate) + userpolicy_type_attrsize(); } static int build_migrate(struct sk_buff *skb, const struct xfrm_migrate *m, int num_migrate, const struct xfrm_kmaddress *k, - const struct xfrm_selector *sel, u8 dir, u8 type) + const struct xfrm_selector *sel, + const struct xfrm_encap_tmpl *encap, u8 dir, u8 type) { const struct xfrm_migrate *mp; struct xfrm_userpolicy_id *pol_id; @@ -2346,6 +2349,11 @@ static int build_migrate(struct sk_buff *skb, const struct xfrm_migrate *m, if (err) goto out_cancel; } + if (encap) { + err = nla_put(skb, XFRMA_ENCAP, sizeof(*encap), encap); + if (err) + goto out_cancel; + } err = copy_to_user_policy_type(type, skb); if (err) goto out_cancel; @@ -2365,17 +2373,19 @@ out_cancel: static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, const struct xfrm_migrate *m, int num_migrate, - const struct xfrm_kmaddress *k) + const struct xfrm_kmaddress *k, + const struct xfrm_encap_tmpl *encap) { struct net *net = &init_net; struct sk_buff *skb; - skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC); + skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k, !!encap), + GFP_ATOMIC); if (skb == NULL) return -ENOMEM; /* build migrate */ - if (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0) + if (build_migrate(skb, m, num_migrate, k, sel, encap, dir, type) < 0) BUG(); return xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_MIGRATE); @@ -2383,7 +2393,8 @@ static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, #else static int xfrm_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, const struct xfrm_migrate *m, int num_migrate, - const struct xfrm_kmaddress *k) + const struct xfrm_kmaddress *k, + const struct xfrm_encap_tmpl *encap) { return -ENOPROTOOPT; } -- cgit v1.2.1