Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1047/?format=api
{ "id": 1047, "url": "http://patchwork.ozlabs.org/api/patches/1047/?format=api", "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/87ej3bgnf6.fsf@natisbad.org/", "project": { "id": 7, "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api", "name": "Linux network development", "link_name": "netdev", "list_id": "netdev.vger.kernel.org", "list_email": "netdev@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<87ej3bgnf6.fsf@natisbad.org>", "list_archive_url": null, "date": "2008-09-23T10:35:25", "name": "XFRM: MIGRATE enhancements", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "55ec76bd86c72e9676ce9778222c0bf228bf8854", "submitter": { "id": 439, "url": "http://patchwork.ozlabs.org/api/people/439/?format=api", "name": "Arnaud Ebalard", "email": "arno@natisbad.org" }, "delegate": { "id": 34, "url": "http://patchwork.ozlabs.org/api/users/34/?format=api", "username": "davem", "first_name": "David", "last_name": "Miller", "email": "davem@davemloft.net" }, "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/87ej3bgnf6.fsf@natisbad.org/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/1047/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1047/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<netdev-owner@vger.kernel.org>", "X-Original-To": "patchwork-incoming@ozlabs.org", "Delivered-To": "patchwork-incoming@ozlabs.org", "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.176.167])\n\tby ozlabs.org (Postfix) with ESMTP id 88313DDDEF\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 23 Sep 2008 20:37:28 +1000 (EST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1750943AbYIWKhX (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tTue, 23 Sep 2008 06:37:23 -0400", "(majordomo@vger.kernel.org) by vger.kernel.org id S1750959AbYIWKhW\n\t(ORCPT <rfc822; netdev-outgoing>); Tue, 23 Sep 2008 06:37:22 -0400", "from moog.chdir.org ([88.191.42.160]:60960 \"EHLO moog.chdir.org\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1750869AbYIWKhV (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tTue, 23 Sep 2008 06:37:21 -0400", "from [2001:7a8:78df:2:20d:93ff:fe55:8f78]\n\t(helo=localhost.localdomain)\n\tby moog.chdir.org with esmtpsa (TLS-1.0:RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.63) (envelope-from <arno@natisbad.org>)\n\tid 1Ki5GR-0000iW-VK; Tue, 23 Sep 2008 12:37:04 +0200" ], "From": "arno@natisbad.org (Arnaud Ebalard)", "To": "David Miller <davem@davemloft.net>", "Cc": "netdev@vger.kernel.org, shinta@sfc.wide.ad.jp,\n\tnakam@linux-ipv6.org, yoshfuji@linux-ipv6.org", "Subject": "Re: [PATCH] XFRM: MIGRATE enhancements", "References": "<8763puwrm8.fsf@natisbad.org>\n\t<20080911.034741.263645111.davem@davemloft.net>", "X-PGP-Key-URL": "http://natisbad.org/arno@natisbad.org.asc", "X-Fingerprint": "47EB 85FE B99A AB85 FD09 46F3 0255 957C 047A 5026", "X-Hashcash": [ "1:20:080923:yoshfuji@linux-ipv6.org::aW57xdhk2NDdQZ+K:000000000000000000000000000000000000000pwT", "1:20:080923:shinta@sfc.wide.ad.jp::L9v9mJ1qE4taUUor:00000000000000000000000000000000000000001kBy", "1:20:080923:nakam@linux-ipv6.org::6f1D2GuL/N+5IrgS:000000000000000000000000000000000000000002FNV", "1:20:080923:davem@davemloft.net::rQi4IT1Zm3zwEBx1:0000000000000000000000000000000000000000005xs9", "1:20:080923:netdev@vger.kernel.org::+Vpfro3UtipzqLTE:00000000000000000000000000000000000000077wy" ], "Date": "Tue, 23 Sep 2008 12:35:25 +0200", "Message-ID": "<87ej3bgnf6.fsf@natisbad.org>", "User-Agent": "Gnus/5.110009 (No Gnus v0.9) Emacs/22.2 (gnu/linux)", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=us-ascii", "Sender": "netdev-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<netdev.vger.kernel.org>", "X-Mailing-List": "netdev@vger.kernel.org" }, "content": "Hi,\n\nthis is a resend with an updated patch against today's net-next. I kept\nmy replies to your previous comments below.\n\nDavid Miller <davem@davemloft.net> writes:\n\n> From: arno@natisbad.org (Arnaud Ebalard)\n> Date: Thu, 21 Aug 2008 13:10:39 +0200\n>\n>> XFRM: MIGRATE enhancements (draft-ebalard-mext-pfkey-enhanced-migrate)\n>> \n>> Provides implementation of the enhancements of XFRM/PF_KEY MIGRATE mechanism\n>> specified in draft-ebalard-mext-pfkey-enhanced-migrate-00. Defines associated\n>> PF_KEY SADB_X_EXT_KMADDRESS extension XFMR/netlink XFRMA_KMADDRESS attribute.\n>> \n>> Signed-off-by: Arnaud Ebalard <arno@natisbad.org>\n>\n> I'm mostly ok with this, but:\n>\n>> @@ -1745,18 +1753,19 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,\n>> {\n>> \tstruct xfrm_userpolicy_id *pi = nlmsg_data(nlh);\n>> \tstruct xfrm_migrate m[XFRM_MAX_DEPTH];\n>> +\tstruct xfrm_kmaddress km;\n>> \tu8 type;\n>> \tint err;\n>> \tint n = 0;\n>> \n>> -\tif (attrs[XFRMA_MIGRATE] == NULL)\n>> +\tif (attrs[XFRMA_MIGRATE] == NULL || attrs[XFRMA_KMADDRESS] == NULL)\n>> \t\treturn -EINVAL;\n>\n> This part I don't like.\n>\n> This is a new restriction and will break old binaries.\n\nack. AFAICT, as there is no MIGRATE-aware IKE daemon available (not\ncounting the set of patches I maintain for racoon), previous code will\nonly break deployment that use static keying. But your point is still\ncompletely valid.\n\n> Can't we cook up some kind of default kmaddress object it none is\n> specified by the user?\n\nWe do not want that kind of workaround which would involve additional\nlogic inside the kernel. That logic is explicitly expected from the\nuserland. kmaddress is a PF_KEY/Netlink vehicle from the MIPv6 process\nto the IKE daemon. Kernel should only relays it (if present).\n\n> Generally speaking, when extending existing facilities with new\n> attributes, you cannot make their existence suddenly a requirement.\n> That breaks stuff.\n\nThe attached patch (against current net-next) now makes kmaddress an\noptional attribute/extension of MIGRATE message:\n\n- In all cases (kmaddress extension being there or not), the kernel\n performs his part of the job by processing the MIGRATE message. Just\n like before, and as expected.\n- If the kmaddress extension/attribute is there (provided by the MIPv6\n process either via Netlink or PF_KEY), it will be in the message sent \n back after kernel processing of MIGRATE content.\n- If the kmaddress extension/attribute is missing, the key manager will\n not get it.\n\nWhat do you think?\n\nThanks again for your review.\n\nCheers,\n\na+\n\nFrom: Arnaud Ebalard <arno@natisbad.org>\nDate: Tue, 23 Sep 2008 08:57:56 +0200\nSubject: [PATCH] XFRM: MIGRATE enhancements (draft-ebalard-mext-pfkey-enhanced-migrate)\n\nProvides implementation of the enhancements of XFRM/PF_KEY MIGRATE mechanism\nspecified in draft-ebalard-mext-pfkey-enhanced-migrate-00. Defines associated\nPF_KEY SADB_X_EXT_KMADDRESS extension and XFRM/netlink XFRMA_KMADDRESS\nattribute.\n\nSigned-off-by: Arnaud Ebalard <arno@natisbad.org>\n---\n include/linux/pfkeyv2.h | 13 ++++++-\n include/linux/xfrm.h | 10 +++++\n include/net/xfrm.h | 15 ++++++--\n net/key/af_key.c | 86 +++++++++++++++++++++++++++++++++++++---------\n net/xfrm/xfrm_policy.c | 5 ++-\n net/xfrm/xfrm_state.c | 5 ++-\n net/xfrm/xfrm_user.c | 57 ++++++++++++++++++++++++------\n 7 files changed, 154 insertions(+), 37 deletions(-)", "diff": "diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h\nindex 700725d..01b2629 100644\n--- a/include/linux/pfkeyv2.h\n+++ b/include/linux/pfkeyv2.h\n@@ -226,6 +226,15 @@ struct sadb_x_sec_ctx {\n } __attribute__((packed));\n /* sizeof(struct sadb_sec_ctx) = 8 */\n \n+/* Used by MIGRATE to pass addresses IKE will use to perform\n+ * negotiation with the peer */\n+struct sadb_x_kmaddress {\n+\tuint16_t\tsadb_x_kmaddress_len;\n+\tuint16_t\tsadb_x_kmaddress_exttype;\n+\tuint32_t\tsadb_x_kmaddress_reserved;\n+} __attribute__((packed));\n+/* sizeof(struct sadb_x_kmaddress) == 8 */\n+\n /* Message types */\n #define SADB_RESERVED\t\t0\n #define SADB_GETSPI\t\t1\n@@ -346,7 +355,9 @@ struct sadb_x_sec_ctx {\n #define SADB_X_EXT_NAT_T_DPORT\t\t22\n #define SADB_X_EXT_NAT_T_OA\t\t23\n #define SADB_X_EXT_SEC_CTX\t\t24\n-#define SADB_EXT_MAX\t\t\t24\n+/* Used with MIGRATE to pass @ to IKE for negotiation */\n+#define SADB_X_EXT_KMADDRESS\t\t25\n+#define SADB_EXT_MAX\t\t\t25\n \n /* Identity Extension values */\n #define SADB_IDENTTYPE_RESERVED\t0\ndiff --git a/include/linux/xfrm.h b/include/linux/xfrm.h\nindex fb0c215..4bc1e6b 100644\n--- a/include/linux/xfrm.h\n+++ b/include/linux/xfrm.h\n@@ -279,6 +279,7 @@ enum xfrm_attr_type_t {\n \tXFRMA_POLICY_TYPE,\t/* struct xfrm_userpolicy_type */\n \tXFRMA_MIGRATE,\n \tXFRMA_ALG_AEAD,\t\t/* struct xfrm_algo_aead */\n+\tXFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */\n \t__XFRMA_MAX\n \n #define XFRMA_MAX (__XFRMA_MAX - 1)\n@@ -415,6 +416,15 @@ struct xfrm_user_report {\n \tstruct xfrm_selector\t\tsel;\n };\n \n+/* Used by MIGRATE to pass addresses IKE should use to perform\n+ * SA negotiation with the peer */\n+struct xfrm_user_kmaddress {\n+\txfrm_address_t local;\n+\txfrm_address_t remote;\n+\t__u32\t\t\t\treserved;\n+\t__u16\t\t\t\tfamily;\n+};\n+\n struct xfrm_user_migrate {\n \txfrm_address_t\t\t\told_daddr;\n \txfrm_address_t\t\t\told_saddr;\ndiff --git a/include/net/xfrm.h b/include/net/xfrm.h\nindex 48630b2..37c0d19 100644\n--- a/include/net/xfrm.h\n+++ b/include/net/xfrm.h\n@@ -478,6 +478,13 @@ struct xfrm_policy\n \tstruct xfrm_tmpl \txfrm_vec[XFRM_MAX_DEPTH];\n };\n \n+struct xfrm_kmaddress {\n+\txfrm_address_t local;\n+\txfrm_address_t remote;\n+\tu32\t\t\treserved;\n+\tu16\t\t\tfamily;\n+};\n+\n struct xfrm_migrate {\n \txfrm_address_t\t\told_daddr;\n \txfrm_address_t\t\told_saddr;\n@@ -517,7 +524,7 @@ struct xfrm_mgr\n \tint\t\t\t(*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);\n \tint\t\t\t(*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);\n \tint\t\t\t(*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);\n-\tint\t\t\t(*migrate)(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_bundles);\n+\tint\t\t\t(*migrate)(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_bundles, struct xfrm_kmaddress *k);\n };\n \n extern int xfrm_register_km(struct xfrm_mgr *km);\n@@ -1446,12 +1453,14 @@ extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,\n \n #ifdef CONFIG_XFRM_MIGRATE\n extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n-\t\t struct xfrm_migrate *m, int num_bundles);\n+\t\t struct xfrm_migrate *m, int num_bundles,\n+\t\t struct xfrm_kmaddress *k);\n extern struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m);\n extern struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x,\n \t\t\t\t\t struct xfrm_migrate *m);\n extern int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n-\t\t\tstruct xfrm_migrate *m, int num_bundles);\n+\t\t\tstruct xfrm_migrate *m, int num_bundles,\n+\t\t\tstruct xfrm_kmaddress *k);\n #endif\n \n extern wait_queue_head_t km_waitq;\ndiff --git a/net/key/af_key.c b/net/key/af_key.c\nindex d628df9..0f4e895 100644\n--- a/net/key/af_key.c\n+++ b/net/key/af_key.c\n@@ -372,6 +372,7 @@ static u8 sadb_ext_min_len[] = {\n \t[SADB_X_EXT_NAT_T_DPORT]\t= (u8) sizeof(struct sadb_x_nat_t_port),\n \t[SADB_X_EXT_NAT_T_OA]\t\t= (u8) sizeof(struct sadb_address),\n \t[SADB_X_EXT_SEC_CTX]\t\t= (u8) sizeof(struct sadb_x_sec_ctx),\n+\t[SADB_X_EXT_KMADDRESS]\t\t= (u8) sizeof(struct sadb_x_kmaddress),\n };\n \n /* Verify sadb_address_{len,prefixlen} against sa_family. */\n@@ -2353,24 +2354,21 @@ static int pfkey_sockaddr_pair_size(sa_family_t family)\n \treturn PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2);\n }\n \n-static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq,\n+static int parse_sockaddr_pair(struct sockaddr *sa, int ext_len,\n \t\t\t xfrm_address_t *saddr, xfrm_address_t *daddr,\n \t\t\t u16 *family)\n {\n-\tu8 *sa = (u8 *) (rq + 1);\n \tint af, socklen;\n \n-\tif (rq->sadb_x_ipsecrequest_len <\n-\t pfkey_sockaddr_pair_size(((struct sockaddr *)sa)->sa_family))\n+\tif (ext_len < pfkey_sockaddr_pair_size(sa->sa_family))\n \t\treturn -EINVAL;\n \n-\taf = pfkey_sockaddr_extract((struct sockaddr *) sa,\n-\t\t\t\t saddr);\n+\taf = pfkey_sockaddr_extract(sa, saddr);\n \tif (!af)\n \t\treturn -EINVAL;\n \n \tsocklen = pfkey_sockaddr_len(af);\n-\tif (pfkey_sockaddr_extract((struct sockaddr *) (sa + socklen),\n+\tif (pfkey_sockaddr_extract((struct sockaddr *) (((u8 *)sa) + socklen),\n \t\t\t\t daddr) != af)\n \t\treturn -EINVAL;\n \n@@ -2390,7 +2388,9 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,\n \t\treturn -EINVAL;\n \n \t/* old endoints */\n-\terr = parse_sockaddr_pair(rq1, &m->old_saddr, &m->old_daddr,\n+\terr = parse_sockaddr_pair((struct sockaddr *)(rq1 + 1),\n+\t\t\t\t rq1->sadb_x_ipsecrequest_len,\n+\t\t\t\t &m->old_saddr, &m->old_daddr,\n \t\t\t\t &m->old_family);\n \tif (err)\n \t\treturn err;\n@@ -2403,7 +2403,9 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,\n \t\treturn -EINVAL;\n \n \t/* new endpoints */\n-\terr = parse_sockaddr_pair(rq2, &m->new_saddr, &m->new_daddr,\n+\terr = parse_sockaddr_pair((struct sockaddr *)(rq2 + 1),\n+\t\t\t\t rq2->sadb_x_ipsecrequest_len,\n+\t\t\t\t &m->new_saddr, &m->new_daddr,\n \t\t\t\t &m->new_family);\n \tif (err)\n \t\treturn err;\n@@ -2429,29 +2431,40 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,\n \tint i, len, ret, err = -EINVAL;\n \tu8 dir;\n \tstruct sadb_address *sa;\n+\tstruct sadb_x_kmaddress *kma;\n \tstruct sadb_x_policy *pol;\n \tstruct sadb_x_ipsecrequest *rq;\n \tstruct xfrm_selector sel;\n \tstruct xfrm_migrate m[XFRM_MAX_DEPTH];\n+\tstruct xfrm_kmaddress k;\n \n \tif (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1],\n-\t ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) ||\n+\t\t\t\t ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) ||\n \t !ext_hdrs[SADB_X_EXT_POLICY - 1]) {\n \t\terr = -EINVAL;\n \t\tgoto out;\n \t}\n \n+\tkma = ext_hdrs[SADB_X_EXT_KMADDRESS - 1];\n \tpol = ext_hdrs[SADB_X_EXT_POLICY - 1];\n-\tif (!pol) {\n-\t\terr = -EINVAL;\n-\t\tgoto out;\n-\t}\n \n \tif (pol->sadb_x_policy_dir >= IPSEC_DIR_MAX) {\n \t\terr = -EINVAL;\n \t\tgoto out;\n \t}\n \n+\tif (kma) {\n+\t\t/* convert sadb_x_kmaddress to xfrm_kmaddress */\n+\t\tk.reserved = kma->sadb_x_kmaddress_reserved;\n+\t\tret = parse_sockaddr_pair((struct sockaddr *)(kma + 1),\n+\t\t\t\t\t 8*(kma->sadb_x_kmaddress_len) - sizeof(*kma),\n+\t\t\t\t\t &k.local, &k.remote, &k.family);\n+\t\tif (ret < 0) {\n+\t\t\terr = ret;\n+\t\t\tgoto out;\n+\t\t}\n+\t}\n+\n \tdir = pol->sadb_x_policy_dir - 1;\n \tmemset(&sel, 0, sizeof(sel));\n \n@@ -2496,7 +2509,8 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,\n \t\tgoto out;\n \t}\n \n-\treturn xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i);\n+\treturn xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,\n+\t\t\t kma ? &k : NULL);\n \n out:\n \treturn err;\n@@ -3283,6 +3297,32 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,\n \treturn 0;\n }\n \n+\n+static int set_sadb_kmaddress(struct sk_buff *skb, struct xfrm_kmaddress *k)\n+{\n+\tstruct sadb_x_kmaddress *kma;\n+\tu8 *sa;\n+\tint family = k->family;\n+\tint socklen = pfkey_sockaddr_len(family);\n+\tint size_req;\n+\n+\tsize_req = (sizeof(struct sadb_x_kmaddress) +\n+\t\t pfkey_sockaddr_pair_size(family));\n+\n+\tkma = (struct sadb_x_kmaddress *)skb_put(skb, size_req);\n+\tmemset(kma, 0, size_req);\n+\tkma->sadb_x_kmaddress_len = size_req / 8;\n+\tkma->sadb_x_kmaddress_exttype = SADB_X_EXT_KMADDRESS;\n+\tkma->sadb_x_kmaddress_reserved = k->reserved;\n+\n+\tsa = (u8 *)(kma + 1);\n+\tif (!pfkey_sockaddr_fill(&k->local, 0, (struct sockaddr *)sa, family) ||\n+\t !pfkey_sockaddr_fill(&k->remote, 0, (struct sockaddr *)(sa+socklen), family))\n+\t\treturn -EINVAL;\n+\n+\treturn 0;\n+}\n+\n static int set_ipsecrequest(struct sk_buff *skb,\n \t\t\t uint8_t proto, uint8_t mode, int level,\n \t\t\t uint32_t reqid, uint8_t family,\n@@ -3315,7 +3355,8 @@ static int set_ipsecrequest(struct sk_buff *skb,\n \n #ifdef CONFIG_NET_KEY_MIGRATE\n static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n-\t\t\t struct xfrm_migrate *m, int num_bundles)\n+\t\t\t struct xfrm_migrate *m, int num_bundles,\n+\t\t\t struct xfrm_kmaddress *k)\n {\n \tint i;\n \tint sasize_sel;\n@@ -3332,6 +3373,12 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n \tif (num_bundles <= 0 || num_bundles > XFRM_MAX_DEPTH)\n \t\treturn -EINVAL;\n \n+\tif (k != NULL) {\n+\t\t/* addresses for KM */\n+\t\tsize += PFKEY_ALIGN8(sizeof(struct sadb_x_kmaddress) +\n+\t\t\t\t pfkey_sockaddr_pair_size(k->family));\n+\t}\n+\n \t/* selector */\n \tsasize_sel = pfkey_sockaddr_size(sel->family);\n \tif (!sasize_sel)\n@@ -3368,6 +3415,10 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n \thdr->sadb_msg_seq = 0;\n \thdr->sadb_msg_pid = 0;\n \n+\t/* Addresses to be used by KM for negotiation, if ext is available */\n+\tif (k != NULL && (set_sadb_kmaddress(skb, k) < 0))\n+\t\treturn -EINVAL;\n+\n \t/* selector src */\n \tset_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel);\n \n@@ -3413,7 +3464,8 @@ err:\n }\n #else\n static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n-\t\t\t struct xfrm_migrate *m, int num_bundles)\n+\t\t\t struct xfrm_migrate *m, int num_bundles,\n+\t\t\t struct xfrm_kmaddress *k)\n {\n \treturn -ENOPROTOOPT;\n }\ndiff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c\nindex ef9ccbc..82f7a69 100644\n--- a/net/xfrm/xfrm_policy.c\n+++ b/net/xfrm/xfrm_policy.c\n@@ -2672,7 +2672,8 @@ static int xfrm_migrate_check(struct xfrm_migrate *m, int num_migrate)\n }\n \n int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n-\t\t struct xfrm_migrate *m, int num_migrate)\n+\t\t struct xfrm_migrate *m, int num_migrate,\n+\t\t struct xfrm_kmaddress *k)\n {\n \tint i, err, nx_cur = 0, nx_new = 0;\n \tstruct xfrm_policy *pol = NULL;\n@@ -2716,7 +2717,7 @@ int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n \t}\n \n \t/* Stage 5 - announce */\n-\tkm_migrate(sel, dir, type, m, num_migrate);\n+\tkm_migrate(sel, dir, type, m, num_migrate, k);\n \n \txfrm_pol_put(pol);\n \ndiff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c\nindex 053970e..6b0dc2d 100644\n--- a/net/xfrm/xfrm_state.c\n+++ b/net/xfrm/xfrm_state.c\n@@ -1851,7 +1851,8 @@ EXPORT_SYMBOL(km_policy_expired);\n \n #ifdef CONFIG_XFRM_MIGRATE\n int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n-\t struct xfrm_migrate *m, int num_migrate)\n+\t struct xfrm_migrate *m, int num_migrate,\n+\t struct xfrm_kmaddress *k)\n {\n \tint err = -EINVAL;\n \tint ret;\n@@ -1860,7 +1861,7 @@ int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n \tread_lock(&xfrm_km_lock);\n \tlist_for_each_entry(km, &xfrm_km_list, list) {\n \t\tif (km->migrate) {\n-\t\t\tret = km->migrate(sel, dir, type, m, num_migrate);\n+\t\t\tret = km->migrate(sel, dir, type, m, num_migrate, k);\n \t\t\tif (!ret)\n \t\t\t\terr = ret;\n \t\t}\ndiff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c\nindex 04c4150..22a4447 100644\n--- a/net/xfrm/xfrm_user.c\n+++ b/net/xfrm/xfrm_user.c\n@@ -1710,12 +1710,23 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,\n \n #ifdef CONFIG_XFRM_MIGRATE\n static int copy_from_user_migrate(struct xfrm_migrate *ma,\n+\t\t\t\t struct xfrm_kmaddress *k,\n \t\t\t\t struct nlattr **attrs, int *num)\n {\n \tstruct nlattr *rt = attrs[XFRMA_MIGRATE];\n \tstruct xfrm_user_migrate *um;\n \tint i, num_migrate;\n \n+\tif (k != NULL) {\n+\t\tstruct xfrm_user_kmaddress *uk;\n+\n+\t\tuk = nla_data(attrs[XFRMA_KMADDRESS]);\n+\t\tmemcpy(&k->local, &uk->local, sizeof(k->local));\n+\t\tmemcpy(&k->remote, &uk->remote, sizeof(k->remote));\n+\t\tk->family = uk->family;\n+\t\tk->reserved = uk->reserved;\n+\t}\n+\n \tum = nla_data(rt);\n \tnum_migrate = nla_len(rt) / sizeof(*um);\n \n@@ -1745,6 +1756,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,\n {\n \tstruct xfrm_userpolicy_id *pi = nlmsg_data(nlh);\n \tstruct xfrm_migrate m[XFRM_MAX_DEPTH];\n+\tstruct xfrm_kmaddress km, *kmp;\n \tu8 type;\n \tint err;\n \tint n = 0;\n@@ -1752,19 +1764,20 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,\n \tif (attrs[XFRMA_MIGRATE] == NULL)\n \t\treturn -EINVAL;\n \n+\tkmp = attrs[XFRMA_KMADDRESS] ? &km : NULL;\n+\n \terr = copy_from_user_policy_type(&type, attrs);\n \tif (err)\n \t\treturn err;\n \n-\terr = copy_from_user_migrate((struct xfrm_migrate *)m,\n-\t\t\t\t attrs, &n);\n+\terr = copy_from_user_migrate((struct xfrm_migrate *)m, kmp, attrs, &n);\n \tif (err)\n \t\treturn err;\n \n \tif (!n)\n \t\treturn 0;\n \n-\txfrm_migrate(&pi->sel, pi->dir, type, m, n);\n+\txfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp);\n \n \treturn 0;\n }\n@@ -1795,16 +1808,30 @@ static int copy_to_user_migrate(struct xfrm_migrate *m, struct sk_buff *skb)\n \treturn nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um);\n }\n \n-static inline size_t xfrm_migrate_msgsize(int num_migrate)\n+static int copy_to_user_kmaddress(struct xfrm_kmaddress *k, struct sk_buff *skb)\n+{\n+\tstruct xfrm_user_kmaddress uk;\n+\n+\tmemset(&uk, 0, sizeof(uk));\n+\tuk.family = k->family;\n+\tuk.reserved = k->reserved;\n+\tmemcpy(&uk.local, &k->local, sizeof(uk.local));\n+\tmemcpy(&uk.remote, &k->local, sizeof(uk.remote));\n+\n+\treturn nla_put(skb, XFRMA_KMADDRESS, sizeof(uk), &uk);\n+}\n+\n+static inline size_t xfrm_migrate_msgsize(int num_migrate, int with_kma)\n {\n \treturn NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id))\n-\t + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate)\n-\t + userpolicy_type_attrsize();\n+\t + (with_kma ? nla_total_size(sizeof(struct xfrm_kmaddress)) : 0)\n+\t + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate)\n+\t + userpolicy_type_attrsize();\n }\n \n static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,\n-\t\t\t int num_migrate, struct xfrm_selector *sel,\n-\t\t\t u8 dir, u8 type)\n+\t\t\t int num_migrate, struct xfrm_kmaddress *k,\n+\t\t\t struct xfrm_selector *sel, u8 dir, u8 type)\n {\n \tstruct xfrm_migrate *mp;\n \tstruct xfrm_userpolicy_id *pol_id;\n@@ -1821,6 +1848,9 @@ static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,\n \tmemcpy(&pol_id->sel, sel, sizeof(pol_id->sel));\n \tpol_id->dir = dir;\n \n+\tif (k != NULL && (copy_to_user_kmaddress(k, skb) < 0))\n+\t\t\tgoto nlmsg_failure;\n+\n \tif (copy_to_user_policy_type(type, skb) < 0)\n \t\tgoto nlmsg_failure;\n \n@@ -1836,23 +1866,25 @@ nlmsg_failure:\n }\n \n static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n-\t\t\t struct xfrm_migrate *m, int num_migrate)\n+\t\t\t struct xfrm_migrate *m, int num_migrate,\n+\t\t\t struct xfrm_kmaddress *k)\n {\n \tstruct sk_buff *skb;\n \n-\tskb = nlmsg_new(xfrm_migrate_msgsize(num_migrate), GFP_ATOMIC);\n+\tskb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC);\n \tif (skb == NULL)\n \t\treturn -ENOMEM;\n \n \t/* build migrate */\n-\tif (build_migrate(skb, m, num_migrate, sel, dir, type) < 0)\n+\tif (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0)\n \t\tBUG();\n \n \treturn nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC);\n }\n #else\n static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,\n-\t\t\t struct xfrm_migrate *m, int num_migrate)\n+\t\t\t struct xfrm_migrate *m, int num_migrate,\n+\t\t\t struct xfrm_kmaddress *k)\n {\n \treturn -ENOPROTOOPT;\n }\n@@ -1901,6 +1933,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {\n \t[XFRMA_COADDR]\t\t= { .len = sizeof(xfrm_address_t) },\n \t[XFRMA_POLICY_TYPE]\t= { .len = sizeof(struct xfrm_userpolicy_type)},\n \t[XFRMA_MIGRATE]\t\t= { .len = sizeof(struct xfrm_user_migrate) },\n+\t[XFRMA_KMADDRESS]\t= { .len = sizeof(struct xfrm_user_kmaddress) },\n };\n \n static struct xfrm_link {\n", "prefixes": [] }