diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-30 11:14:42 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-30 11:14:42 -0400 |
| commit | 152a6a9da1bd3ed5dcbbf6ff17c7ebde0eb9a754 (patch) | |
| tree | cad354802870b7d4bc0402a6a6da44bd1f610bc6 /net/xfrm | |
| parent | cd9bb7e7367c03400d6e918fd3502820fc3b9084 (diff) | |
| parent | 80787ebc2bbd8e675d8b9ff8cfa40f15134feebe (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (21 commits)
[IPV4] SNMP: Support OutMcastPkts and OutBcastPkts
[IPV4] SNMP: Support InMcastPkts and InBcastPkts
[IPV4] SNMP: Support InTruncatedPkts
[IPV4] SNMP: Support InNoRoutes
[SNMP]: Add definitions for {In,Out}BcastPkts
[TCP] FRTO: RFC4138 allows Nagle override when new data must be sent
[TCP] FRTO: Delay skb available check until it's mandatory
[XFRM]: Restrict upper layer information by bundle.
[TCP]: Catch skb with S+L bugs earlier
[PATCH] INET : IPV4 UDP lookups converted to a 2 pass algo
[L2TP]: Add the ability to autoload a pppox protocol module.
[SKB]: Introduce skb_queue_walk_safe()
[AF_IUCV/IUCV]: smp_call_function deadlock
[IPV6]: Fix slab corruption running ip6sic
[TCP]: Update references in two old comments
[XFRM]: Export SPD info
[IPV6]: Track device renames in snmp6.
[SCTP]: Fix sctp_getsockopt_local_addrs_old() to use local storage.
[NET]: Remove NETIF_F_INTERNAL_STATS, default to internal stats.
[NETPOLL]: Remove CONFIG_NETPOLL_RX
...
Diffstat (limited to 'net/xfrm')
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 71 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 77 |
2 files changed, 147 insertions, 1 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 762926009c04..263e34e45265 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; |
| @@ -1330,6 +1344,40 @@ xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx, | |||
| 1330 | return err; | 1344 | return err; |
| 1331 | } | 1345 | } |
| 1332 | 1346 | ||
| 1347 | static int inline | ||
| 1348 | xfrm_dst_alloc_copy(void **target, void *src, int size) | ||
| 1349 | { | ||
| 1350 | if (!*target) { | ||
| 1351 | *target = kmalloc(size, GFP_ATOMIC); | ||
| 1352 | if (!*target) | ||
| 1353 | return -ENOMEM; | ||
| 1354 | } | ||
| 1355 | memcpy(*target, src, size); | ||
| 1356 | return 0; | ||
| 1357 | } | ||
| 1358 | |||
| 1359 | static int inline | ||
| 1360 | xfrm_dst_update_parent(struct dst_entry *dst, struct xfrm_selector *sel) | ||
| 1361 | { | ||
| 1362 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 1363 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
| 1364 | return xfrm_dst_alloc_copy((void **)&(xdst->partner), | ||
| 1365 | sel, sizeof(*sel)); | ||
| 1366 | #else | ||
| 1367 | return 0; | ||
| 1368 | #endif | ||
| 1369 | } | ||
| 1370 | |||
| 1371 | static int inline | ||
| 1372 | xfrm_dst_update_origin(struct dst_entry *dst, struct flowi *fl) | ||
| 1373 | { | ||
| 1374 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 1375 | struct xfrm_dst *xdst = (struct xfrm_dst *)dst; | ||
| 1376 | return xfrm_dst_alloc_copy((void **)&(xdst->origin), fl, sizeof(*fl)); | ||
| 1377 | #else | ||
| 1378 | return 0; | ||
| 1379 | #endif | ||
| 1380 | } | ||
| 1333 | 1381 | ||
| 1334 | static int stale_bundle(struct dst_entry *dst); | 1382 | static int stale_bundle(struct dst_entry *dst); |
| 1335 | 1383 | ||
| @@ -1518,6 +1566,18 @@ restart: | |||
| 1518 | err = -EHOSTUNREACH; | 1566 | err = -EHOSTUNREACH; |
| 1519 | goto error; | 1567 | goto error; |
| 1520 | } | 1568 | } |
| 1569 | |||
| 1570 | if (npols > 1) | ||
| 1571 | err = xfrm_dst_update_parent(dst, &pols[1]->selector); | ||
| 1572 | else | ||
| 1573 | err = xfrm_dst_update_origin(dst, fl); | ||
| 1574 | if (unlikely(err)) { | ||
| 1575 | write_unlock_bh(&policy->lock); | ||
| 1576 | if (dst) | ||
| 1577 | dst_free(dst); | ||
| 1578 | goto error; | ||
| 1579 | } | ||
| 1580 | |||
| 1521 | dst->next = policy->bundles; | 1581 | dst->next = policy->bundles; |
| 1522 | policy->bundles = dst; | 1582 | policy->bundles = dst; |
| 1523 | dst_hold(dst); | 1583 | dst_hold(dst); |
| @@ -1933,6 +1993,15 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, | |||
| 1933 | if (!dst_check(dst->path, ((struct xfrm_dst *)dst)->path_cookie) || | 1993 | if (!dst_check(dst->path, ((struct xfrm_dst *)dst)->path_cookie) || |
| 1934 | (dst->dev && !netif_running(dst->dev))) | 1994 | (dst->dev && !netif_running(dst->dev))) |
| 1935 | return 0; | 1995 | return 0; |
| 1996 | #ifdef CONFIG_XFRM_SUB_POLICY | ||
| 1997 | if (fl) { | ||
| 1998 | if (first->origin && !flow_cache_uli_match(first->origin, fl)) | ||
| 1999 | return 0; | ||
| 2000 | if (first->partner && | ||
| 2001 | !xfrm_selector_match(first->partner, fl, family)) | ||
| 2002 | return 0; | ||
| 2003 | } | ||
| 2004 | #endif | ||
| 1936 | 2005 | ||
| 1937 | last = NULL; | 2006 | last = NULL; |
| 1938 | 2007 | ||
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) |
