Commit 3a2dfbe8acb154905fdc2fd03ec56df42e6c4cc4

Authored by Martin Willi
Committed by David S. Miller
1 parent 93adcc80f3

xfrm: Notify changes in UDP encapsulation via netlink

Add new_mapping() implementation to the netlink xfrm_mgr to notify
address/port changes detected in UDP encapsulated ESP packets.

Signed-off-by: Martin Willi <martin@strongswan.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 66 additions and 0 deletions Side-by-side Diff

include/linux/xfrm.h
... ... @@ -199,6 +199,9 @@
199 199 #define XFRM_MSG_NEWSPDINFO XFRM_MSG_NEWSPDINFO
200 200 XFRM_MSG_GETSPDINFO,
201 201 #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO
  202 +
  203 + XFRM_MSG_MAPPING,
  204 +#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING
202 205 __XFRM_MSG_MAX
203 206 };
204 207 #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
... ... @@ -438,6 +441,15 @@
438 441 __u16 new_family;
439 442 };
440 443  
  444 +struct xfrm_user_mapping {
  445 + struct xfrm_usersa_id id;
  446 + __u32 reqid;
  447 + xfrm_address_t old_saddr;
  448 + xfrm_address_t new_saddr;
  449 + __be16 old_sport;
  450 + __be16 new_sport;
  451 +};
  452 +
441 453 #ifndef __KERNEL__
442 454 /* backwards compatibility for userspace */
443 455 #define XFRMGRP_ACQUIRE 1
... ... @@ -464,6 +476,8 @@
464 476 #define XFRMNLGRP_REPORT XFRMNLGRP_REPORT
465 477 XFRMNLGRP_MIGRATE,
466 478 #define XFRMNLGRP_MIGRATE XFRMNLGRP_MIGRATE
  479 + XFRMNLGRP_MAPPING,
  480 +#define XFRMNLGRP_MAPPING XFRMNLGRP_MAPPING
467 481 __XFRMNLGRP_MAX
468 482 };
469 483 #define XFRMNLGRP_MAX (__XFRMNLGRP_MAX - 1)
net/xfrm/xfrm_user.c
... ... @@ -2503,6 +2503,57 @@
2503 2503 return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_REPORT, GFP_ATOMIC);
2504 2504 }
2505 2505  
  2506 +static inline size_t xfrm_mapping_msgsize(void)
  2507 +{
  2508 + return NLMSG_ALIGN(sizeof(struct xfrm_user_mapping));
  2509 +}
  2510 +
  2511 +static int build_mapping(struct sk_buff *skb, struct xfrm_state *x,
  2512 + xfrm_address_t *new_saddr, __be16 new_sport)
  2513 +{
  2514 + struct xfrm_user_mapping *um;
  2515 + struct nlmsghdr *nlh;
  2516 +
  2517 + nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_MAPPING, sizeof(*um), 0);
  2518 + if (nlh == NULL)
  2519 + return -EMSGSIZE;
  2520 +
  2521 + um = nlmsg_data(nlh);
  2522 +
  2523 + memcpy(&um->id.daddr, &x->id.daddr, sizeof(um->id.daddr));
  2524 + um->id.spi = x->id.spi;
  2525 + um->id.family = x->props.family;
  2526 + um->id.proto = x->id.proto;
  2527 + memcpy(&um->new_saddr, new_saddr, sizeof(um->new_saddr));
  2528 + memcpy(&um->old_saddr, &x->props.saddr, sizeof(um->old_saddr));
  2529 + um->new_sport = new_sport;
  2530 + um->old_sport = x->encap->encap_sport;
  2531 + um->reqid = x->props.reqid;
  2532 +
  2533 + return nlmsg_end(skb, nlh);
  2534 +}
  2535 +
  2536 +static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
  2537 + __be16 sport)
  2538 +{
  2539 + struct sk_buff *skb;
  2540 +
  2541 + if (x->id.proto != IPPROTO_ESP)
  2542 + return -EINVAL;
  2543 +
  2544 + if (!x->encap)
  2545 + return -EINVAL;
  2546 +
  2547 + skb = nlmsg_new(xfrm_mapping_msgsize(), GFP_ATOMIC);
  2548 + if (skb == NULL)
  2549 + return -ENOMEM;
  2550 +
  2551 + if (build_mapping(skb, x, ipaddr, sport) < 0)
  2552 + BUG();
  2553 +
  2554 + return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MAPPING, GFP_ATOMIC);
  2555 +}
  2556 +
2506 2557 static struct xfrm_mgr netlink_mgr = {
2507 2558 .id = "netlink",
2508 2559 .notify = xfrm_send_state_notify,
... ... @@ -2511,6 +2562,7 @@
2511 2562 .notify_policy = xfrm_send_policy_notify,
2512 2563 .report = xfrm_send_report,
2513 2564 .migrate = xfrm_send_migrate,
  2565 + .new_mapping = xfrm_send_mapping,
2514 2566 };
2515 2567  
2516 2568 static int __init xfrm_user_init(void)