Commit 3a2dfbe8acb154905fdc2fd03ec56df42e6c4cc4
Committed by
David S. Miller
1 parent
93adcc80f3
Exists in
master
and in
39 other branches
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) |