diff options
| -rw-r--r-- | include/linux/xfrm.h | 35 | ||||
| -rw-r--r-- | include/net/xfrm.h | 13 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 16 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 77 |
4 files changed, 140 insertions, 1 deletions
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 9c656a5cf842..a5d53e0fe152 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h | |||
| @@ -185,6 +185,11 @@ enum { | |||
| 185 | #define XFRM_MSG_NEWSADINFO XFRM_MSG_NEWSADINFO | 185 | #define XFRM_MSG_NEWSADINFO XFRM_MSG_NEWSADINFO |
| 186 | XFRM_MSG_GETSADINFO, | 186 | XFRM_MSG_GETSADINFO, |
| 187 | #define XFRM_MSG_GETSADINFO XFRM_MSG_GETSADINFO | 187 | #define XFRM_MSG_GETSADINFO XFRM_MSG_GETSADINFO |
| 188 | |||
| 189 | XFRM_MSG_NEWSPDINFO, | ||
| 190 | #define XFRM_MSG_NEWSPDINFO XFRM_MSG_NEWSPDINFO | ||
| 191 | XFRM_MSG_GETSPDINFO, | ||
| 192 | #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO | ||
| 188 | __XFRM_MSG_MAX | 193 | __XFRM_MSG_MAX |
| 189 | }; | 194 | }; |
| 190 | #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) | 195 | #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) |
| @@ -290,6 +295,36 @@ enum xfrm_sadattr_type_t { | |||
| 290 | #define XFRMA_SAD_MAX (__XFRMA_SAD_MAX - 1) | 295 | #define XFRMA_SAD_MAX (__XFRMA_SAD_MAX - 1) |
| 291 | }; | 296 | }; |
| 292 | 297 | ||
| 298 | /* SPD Table filter flags */ | ||
| 299 | enum xfrm_spd_ftype_t { | ||
| 300 | XFRM_SPD_UNSPEC, | ||
| 301 | XFRM_SPD_HMASK=1, | ||
| 302 | XFRM_SPD_HMAX=2, | ||
| 303 | XFRM_SPD_ICNT=4, | ||
| 304 | XFRM_SPD_OCNT=8, | ||
| 305 | XFRM_SPD_FCNT=16, | ||
| 306 | XFRM_SPD_ISCNT=32, | ||
| 307 | XFRM_SPD_OSCNT=64, | ||
| 308 | XFRM_SPD_FSCNT=128, | ||
| 309 | __XFRM_SPD_MAX | ||
| 310 | |||
| 311 | #define XFRM_SPD_MAX (__XFRM_SPD_MAX - 1) | ||
| 312 | }; | ||
| 313 | enum xfrm_spdattr_type_t { | ||
| 314 | XFRMA_SPD_UNSPEC, | ||
| 315 | XFRMA_SPDHMASK, | ||
| 316 | XFRMA_SPDHMAX, | ||
| 317 | XFRMA_SPDICNT, | ||
| 318 | XFRMA_SPDOCNT, | ||
| 319 | XFRMA_SPDFCNT, | ||
| 320 | XFRMA_SPDISCNT, | ||
| 321 | XFRMA_SPDOSCNT, | ||
| 322 | XFRMA_SPDFSCNT, | ||
| 323 | __XFRMA_SPD_MAX | ||
| 324 | |||
| 325 | #define XFRMA_SPD_MAX (__XFRMA_SPD_MAX - 1) | ||
| 326 | }; | ||
| 327 | |||
| 293 | struct xfrm_usersa_info { | 328 | struct xfrm_usersa_info { |
| 294 | struct xfrm_selector sel; | 329 | struct xfrm_selector sel; |
| 295 | struct xfrm_id id; | 330 | struct xfrm_id id; |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 8287081d77f2..9561bf817b02 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
| @@ -423,6 +423,18 @@ struct xfrm_sadinfo | |||
| 423 | u32 sadhmcnt; /* max allowed hash bkts */ | 423 | u32 sadhmcnt; /* max allowed hash bkts */ |
| 424 | u32 sadcnt; /* current running count */ | 424 | u32 sadcnt; /* current running count */ |
| 425 | }; | 425 | }; |
| 426 | |||
| 427 | struct xfrm_spdinfo | ||
| 428 | { | ||
| 429 | u32 incnt; | ||
| 430 | u32 outcnt; | ||
| 431 | u32 fwdcnt; | ||
| 432 | u32 inscnt; | ||
| 433 | u32 outscnt; | ||
| 434 | u32 fwdscnt; | ||
| 435 | u32 spdhcnt; | ||
| 436 | u32 spdhmcnt; | ||
| 437 | }; | ||
| 426 | #ifdef CONFIG_AUDITSYSCALL | 438 | #ifdef CONFIG_AUDITSYSCALL |
| 427 | extern void xfrm_audit_log(uid_t auid, u32 secid, int type, int result, | 439 | extern void xfrm_audit_log(uid_t auid, u32 secid, int type, int result, |
| 428 | struct xfrm_policy *xp, struct xfrm_state *x); | 440 | struct xfrm_policy *xp, struct xfrm_state *x); |
| @@ -946,6 +958,7 @@ extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); | |||
| 946 | extern int xfrm_state_delete(struct xfrm_state *x); | 958 | extern int xfrm_state_delete(struct xfrm_state *x); |
| 947 | extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); | 959 | extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); |
| 948 | extern void xfrm_sad_getinfo(struct xfrm_sadinfo *si); | 960 | extern void xfrm_sad_getinfo(struct xfrm_sadinfo *si); |
| 961 | extern void xfrm_spd_getinfo(struct xfrm_spdinfo *si); | ||
| 949 | extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); | 962 | extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); |
| 950 | extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq); | 963 | extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq); |
| 951 | extern void xfrm_replay_notify(struct xfrm_state *x, int event); | 964 | extern void xfrm_replay_notify(struct xfrm_state *x, int event); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 762926009c04..dbf9d96a2f0b 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -579,8 +579,22 @@ static inline int xfrm_byidx_should_resize(int total) | |||
| 579 | return 0; | 579 | return 0; |
| 580 | } | 580 | } |
| 581 | 581 | ||
| 582 | static DEFINE_MUTEX(hash_resize_mutex); | 582 | void xfrm_spd_getinfo(struct xfrm_spdinfo *si) |
| 583 | { | ||
| 584 | read_lock_bh(&xfrm_policy_lock); | ||
| 585 | si->incnt = xfrm_policy_count[XFRM_POLICY_IN]; | ||
| 586 | si->outcnt = xfrm_policy_count[XFRM_POLICY_OUT]; | ||
| 587 | si->fwdcnt = xfrm_policy_count[XFRM_POLICY_FWD]; | ||
| 588 | si->inscnt = xfrm_policy_count[XFRM_POLICY_IN+XFRM_POLICY_MAX]; | ||
| 589 | si->outscnt = xfrm_policy_count[XFRM_POLICY_OUT+XFRM_POLICY_MAX]; | ||
| 590 | si->fwdscnt = xfrm_policy_count[XFRM_POLICY_FWD+XFRM_POLICY_MAX]; | ||
| 591 | si->spdhcnt = xfrm_idx_hmask; | ||
| 592 | si->spdhmcnt = xfrm_policy_hashmax; | ||
| 593 | read_unlock_bh(&xfrm_policy_lock); | ||
| 594 | } | ||
| 595 | EXPORT_SYMBOL(xfrm_spd_getinfo); | ||
| 583 | 596 | ||
| 597 | static DEFINE_MUTEX(hash_resize_mutex); | ||
| 584 | static void xfrm_hash_resize(struct work_struct *__unused) | 598 | static void xfrm_hash_resize(struct work_struct *__unused) |
| 585 | { | 599 | { |
| 586 | int dir, total; | 600 | int dir, total; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 69110fed64b6..4210d91624cd 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -672,6 +672,81 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb, | |||
| 672 | return skb; | 672 | return skb; |
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | static int build_spdinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) | ||
| 676 | { | ||
| 677 | struct xfrm_spdinfo si; | ||
| 678 | struct nlmsghdr *nlh; | ||
| 679 | u32 *f; | ||
| 680 | |||
| 681 | nlh = nlmsg_put(skb, pid, seq, XFRM_MSG_NEWSPDINFO, sizeof(u32), 0); | ||
| 682 | if (nlh == NULL) /* shouldnt really happen ... */ | ||
| 683 | return -EMSGSIZE; | ||
| 684 | |||
| 685 | f = nlmsg_data(nlh); | ||
| 686 | *f = flags; | ||
| 687 | xfrm_spd_getinfo(&si); | ||
| 688 | |||
| 689 | if (flags & XFRM_SPD_HMASK) | ||
| 690 | NLA_PUT_U32(skb, XFRMA_SPDHMASK, si.spdhcnt); | ||
| 691 | if (flags & XFRM_SPD_HMAX) | ||
| 692 | NLA_PUT_U32(skb, XFRMA_SPDHMAX, si.spdhmcnt); | ||
| 693 | if (flags & XFRM_SPD_ICNT) | ||
| 694 | NLA_PUT_U32(skb, XFRMA_SPDICNT, si.incnt); | ||
| 695 | if (flags & XFRM_SPD_OCNT) | ||
| 696 | NLA_PUT_U32(skb, XFRMA_SPDOCNT, si.outcnt); | ||
| 697 | if (flags & XFRM_SPD_FCNT) | ||
| 698 | NLA_PUT_U32(skb, XFRMA_SPDFCNT, si.fwdcnt); | ||
| 699 | if (flags & XFRM_SPD_ISCNT) | ||
| 700 | NLA_PUT_U32(skb, XFRMA_SPDISCNT, si.inscnt); | ||
| 701 | if (flags & XFRM_SPD_OSCNT) | ||
| 702 | NLA_PUT_U32(skb, XFRMA_SPDOSCNT, si.inscnt); | ||
| 703 | if (flags & XFRM_SPD_FSCNT) | ||
| 704 | NLA_PUT_U32(skb, XFRMA_SPDFSCNT, si.inscnt); | ||
| 705 | |||
| 706 | return nlmsg_end(skb, nlh); | ||
| 707 | |||
| 708 | nla_put_failure: | ||
| 709 | nlmsg_cancel(skb, nlh); | ||
| 710 | return -EMSGSIZE; | ||
| 711 | } | ||
| 712 | |||
| 713 | static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh, | ||
| 714 | struct rtattr **xfrma) | ||
| 715 | { | ||
| 716 | struct sk_buff *r_skb; | ||
| 717 | u32 *flags = NLMSG_DATA(nlh); | ||
| 718 | u32 spid = NETLINK_CB(skb).pid; | ||
| 719 | u32 seq = nlh->nlmsg_seq; | ||
| 720 | int len = NLMSG_LENGTH(sizeof(u32)); | ||
| 721 | |||
| 722 | |||
| 723 | if (*flags & XFRM_SPD_HMASK) | ||
| 724 | len += RTA_SPACE(sizeof(u32)); | ||
| 725 | if (*flags & XFRM_SPD_HMAX) | ||
| 726 | len += RTA_SPACE(sizeof(u32)); | ||
| 727 | if (*flags & XFRM_SPD_ICNT) | ||
| 728 | len += RTA_SPACE(sizeof(u32)); | ||
| 729 | if (*flags & XFRM_SPD_OCNT) | ||
| 730 | len += RTA_SPACE(sizeof(u32)); | ||
| 731 | if (*flags & XFRM_SPD_FCNT) | ||
| 732 | len += RTA_SPACE(sizeof(u32)); | ||
| 733 | if (*flags & XFRM_SPD_ISCNT) | ||
| 734 | len += RTA_SPACE(sizeof(u32)); | ||
| 735 | if (*flags & XFRM_SPD_OSCNT) | ||
| 736 | len += RTA_SPACE(sizeof(u32)); | ||
| 737 | if (*flags & XFRM_SPD_FSCNT) | ||
| 738 | len += RTA_SPACE(sizeof(u32)); | ||
| 739 | |||
| 740 | r_skb = alloc_skb(len, GFP_ATOMIC); | ||
| 741 | if (r_skb == NULL) | ||
| 742 | return -ENOMEM; | ||
| 743 | |||
| 744 | if (build_spdinfo(r_skb, spid, seq, *flags) < 0) | ||
| 745 | BUG(); | ||
| 746 | |||
| 747 | return nlmsg_unicast(xfrm_nl, r_skb, spid); | ||
| 748 | } | ||
| 749 | |||
| 675 | static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) | 750 | static int build_sadinfo(struct sk_buff *skb, u32 pid, u32 seq, u32 flags) |
| 676 | { | 751 | { |
| 677 | struct xfrm_sadinfo si; | 752 | struct xfrm_sadinfo si; |
| @@ -1879,6 +1954,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { | |||
| 1879 | [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report), | 1954 | [XFRM_MSG_REPORT - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_report), |
| 1880 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), | 1955 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
| 1881 | [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = NLMSG_LENGTH(sizeof(u32)), | 1956 | [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = NLMSG_LENGTH(sizeof(u32)), |
| 1957 | [XFRM_MSG_GETSPDINFO - XFRM_MSG_BASE] = NLMSG_LENGTH(sizeof(u32)), | ||
| 1882 | }; | 1958 | }; |
| 1883 | 1959 | ||
| 1884 | #undef XMSGSIZE | 1960 | #undef XMSGSIZE |
| @@ -1907,6 +1983,7 @@ static struct xfrm_link { | |||
| 1907 | [XFRM_MSG_GETAE - XFRM_MSG_BASE] = { .doit = xfrm_get_ae }, | 1983 | [XFRM_MSG_GETAE - XFRM_MSG_BASE] = { .doit = xfrm_get_ae }, |
| 1908 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = { .doit = xfrm_do_migrate }, | 1984 | [XFRM_MSG_MIGRATE - XFRM_MSG_BASE] = { .doit = xfrm_do_migrate }, |
| 1909 | [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = { .doit = xfrm_get_sadinfo }, | 1985 | [XFRM_MSG_GETSADINFO - XFRM_MSG_BASE] = { .doit = xfrm_get_sadinfo }, |
| 1986 | [XFRM_MSG_GETSPDINFO - XFRM_MSG_BASE] = { .doit = xfrm_get_spdinfo }, | ||
| 1910 | }; | 1987 | }; |
| 1911 | 1988 | ||
| 1912 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 1989 | static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
