aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2008-11-25 20:59:52 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-25 20:59:52 -0500
commit59c9940ed0ef026673cac52f2eaed77af7d486da (patch)
treed7d4e38e693178f16000eaa5ae03f415f3197f7a /net/xfrm/xfrm_policy.c
parent4fb236bac9fc7d51e2267866de6d4c30e549d2f8 (diff)
netns xfrm: per-netns MIBs
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c82
1 files changed, 47 insertions, 35 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index fcf8c928285a..e239a25e571c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -36,11 +36,6 @@
36 36
37int sysctl_xfrm_larval_drop __read_mostly = 1; 37int sysctl_xfrm_larval_drop __read_mostly = 1;
38 38
39#ifdef CONFIG_XFRM_STATISTICS
40DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics) __read_mostly;
41EXPORT_SYMBOL(xfrm_statistics);
42#endif
43
44DEFINE_MUTEX(xfrm_cfg_mutex); 39DEFINE_MUTEX(xfrm_cfg_mutex);
45EXPORT_SYMBOL(xfrm_cfg_mutex); 40EXPORT_SYMBOL(xfrm_cfg_mutex);
46 41
@@ -1570,7 +1565,7 @@ restart:
1570 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); 1565 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
1571 err = PTR_ERR(policy); 1566 err = PTR_ERR(policy);
1572 if (IS_ERR(policy)) { 1567 if (IS_ERR(policy)) {
1573 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR); 1568 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
1574 goto dropdst; 1569 goto dropdst;
1575 } 1570 }
1576 } 1571 }
@@ -1585,7 +1580,7 @@ restart:
1585 dir, xfrm_policy_lookup); 1580 dir, xfrm_policy_lookup);
1586 err = PTR_ERR(policy); 1581 err = PTR_ERR(policy);
1587 if (IS_ERR(policy)) { 1582 if (IS_ERR(policy)) {
1588 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR); 1583 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
1589 goto dropdst; 1584 goto dropdst;
1590 } 1585 }
1591 } 1586 }
@@ -1608,7 +1603,7 @@ restart:
1608 default: 1603 default:
1609 case XFRM_POLICY_BLOCK: 1604 case XFRM_POLICY_BLOCK:
1610 /* Prohibit the flow */ 1605 /* Prohibit the flow */
1611 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK); 1606 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLBLOCK);
1612 err = -EPERM; 1607 err = -EPERM;
1613 goto error; 1608 goto error;
1614 1609
@@ -1628,7 +1623,7 @@ restart:
1628 */ 1623 */
1629 dst = xfrm_find_bundle(fl, policy, family); 1624 dst = xfrm_find_bundle(fl, policy, family);
1630 if (IS_ERR(dst)) { 1625 if (IS_ERR(dst)) {
1631 XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); 1626 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
1632 err = PTR_ERR(dst); 1627 err = PTR_ERR(dst);
1633 goto error; 1628 goto error;
1634 } 1629 }
@@ -1644,12 +1639,12 @@ restart:
1644 XFRM_POLICY_OUT); 1639 XFRM_POLICY_OUT);
1645 if (pols[1]) { 1640 if (pols[1]) {
1646 if (IS_ERR(pols[1])) { 1641 if (IS_ERR(pols[1])) {
1647 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR); 1642 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
1648 err = PTR_ERR(pols[1]); 1643 err = PTR_ERR(pols[1]);
1649 goto error; 1644 goto error;
1650 } 1645 }
1651 if (pols[1]->action == XFRM_POLICY_BLOCK) { 1646 if (pols[1]->action == XFRM_POLICY_BLOCK) {
1652 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK); 1647 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLBLOCK);
1653 err = -EPERM; 1648 err = -EPERM;
1654 goto error; 1649 goto error;
1655 } 1650 }
@@ -1680,7 +1675,7 @@ restart:
1680 /* EREMOTE tells the caller to generate 1675 /* EREMOTE tells the caller to generate
1681 * a one-shot blackhole route. 1676 * a one-shot blackhole route.
1682 */ 1677 */
1683 XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES); 1678 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
1684 xfrm_pol_put(policy); 1679 xfrm_pol_put(policy);
1685 return -EREMOTE; 1680 return -EREMOTE;
1686 } 1681 }
@@ -1696,7 +1691,7 @@ restart:
1696 nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family); 1691 nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family);
1697 1692
1698 if (nx == -EAGAIN && signal_pending(current)) { 1693 if (nx == -EAGAIN && signal_pending(current)) {
1699 XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES); 1694 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
1700 err = -ERESTART; 1695 err = -ERESTART;
1701 goto error; 1696 goto error;
1702 } 1697 }
@@ -1708,7 +1703,7 @@ restart:
1708 err = nx; 1703 err = nx;
1709 } 1704 }
1710 if (err < 0) { 1705 if (err < 0) {
1711 XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES); 1706 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
1712 goto error; 1707 goto error;
1713 } 1708 }
1714 } 1709 }
@@ -1721,7 +1716,7 @@ restart:
1721 dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig); 1716 dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig);
1722 err = PTR_ERR(dst); 1717 err = PTR_ERR(dst);
1723 if (IS_ERR(dst)) { 1718 if (IS_ERR(dst)) {
1724 XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLEGENERROR); 1719 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLEGENERROR);
1725 goto error; 1720 goto error;
1726 } 1721 }
1727 1722
@@ -1742,9 +1737,9 @@ restart:
1742 dst_free(dst); 1737 dst_free(dst);
1743 1738
1744 if (pol_dead) 1739 if (pol_dead)
1745 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD); 1740 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLDEAD);
1746 else 1741 else
1747 XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); 1742 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
1748 err = -EHOSTUNREACH; 1743 err = -EHOSTUNREACH;
1749 goto error; 1744 goto error;
1750 } 1745 }
@@ -1756,7 +1751,7 @@ restart:
1756 if (unlikely(err)) { 1751 if (unlikely(err)) {
1757 write_unlock_bh(&policy->lock); 1752 write_unlock_bh(&policy->lock);
1758 dst_free(dst); 1753 dst_free(dst);
1759 XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); 1754 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
1760 goto error; 1755 goto error;
1761 } 1756 }
1762 1757
@@ -1912,7 +1907,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1912 fl_dir = policy_to_flow_dir(dir); 1907 fl_dir = policy_to_flow_dir(dir);
1913 1908
1914 if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) { 1909 if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) {
1915 XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); 1910 XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
1916 return 0; 1911 return 0;
1917 } 1912 }
1918 1913
@@ -1925,7 +1920,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1925 for (i=skb->sp->len-1; i>=0; i--) { 1920 for (i=skb->sp->len-1; i>=0; i--) {
1926 struct xfrm_state *x = skb->sp->xvec[i]; 1921 struct xfrm_state *x = skb->sp->xvec[i];
1927 if (!xfrm_selector_match(&x->sel, &fl, family)) { 1922 if (!xfrm_selector_match(&x->sel, &fl, family)) {
1928 XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH); 1923 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH);
1929 return 0; 1924 return 0;
1930 } 1925 }
1931 } 1926 }
@@ -1935,7 +1930,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1935 if (sk && sk->sk_policy[dir]) { 1930 if (sk && sk->sk_policy[dir]) {
1936 pol = xfrm_sk_policy_lookup(sk, dir, &fl); 1931 pol = xfrm_sk_policy_lookup(sk, dir, &fl);
1937 if (IS_ERR(pol)) { 1932 if (IS_ERR(pol)) {
1938 XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); 1933 XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
1939 return 0; 1934 return 0;
1940 } 1935 }
1941 } 1936 }
@@ -1945,14 +1940,14 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1945 xfrm_policy_lookup); 1940 xfrm_policy_lookup);
1946 1941
1947 if (IS_ERR(pol)) { 1942 if (IS_ERR(pol)) {
1948 XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); 1943 XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
1949 return 0; 1944 return 0;
1950 } 1945 }
1951 1946
1952 if (!pol) { 1947 if (!pol) {
1953 if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { 1948 if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) {
1954 xfrm_secpath_reject(xerr_idx, skb, &fl); 1949 xfrm_secpath_reject(xerr_idx, skb, &fl);
1955 XFRM_INC_STATS(LINUX_MIB_XFRMINNOPOLS); 1950 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS);
1956 return 0; 1951 return 0;
1957 } 1952 }
1958 return 1; 1953 return 1;
@@ -1969,7 +1964,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1969 XFRM_POLICY_IN); 1964 XFRM_POLICY_IN);
1970 if (pols[1]) { 1965 if (pols[1]) {
1971 if (IS_ERR(pols[1])) { 1966 if (IS_ERR(pols[1])) {
1972 XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR); 1967 XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
1973 return 0; 1968 return 0;
1974 } 1969 }
1975 pols[1]->curlft.use_time = get_seconds(); 1970 pols[1]->curlft.use_time = get_seconds();
@@ -1993,11 +1988,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1993 for (pi = 0; pi < npols; pi++) { 1988 for (pi = 0; pi < npols; pi++) {
1994 if (pols[pi] != pol && 1989 if (pols[pi] != pol &&
1995 pols[pi]->action != XFRM_POLICY_ALLOW) { 1990 pols[pi]->action != XFRM_POLICY_ALLOW) {
1996 XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK); 1991 XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
1997 goto reject; 1992 goto reject;
1998 } 1993 }
1999 if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) { 1994 if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) {
2000 XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); 1995 XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
2001 goto reject_error; 1996 goto reject_error;
2002 } 1997 }
2003 for (i = 0; i < pols[pi]->xfrm_nr; i++) 1998 for (i = 0; i < pols[pi]->xfrm_nr; i++)
@@ -2021,20 +2016,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
2021 if (k < -1) 2016 if (k < -1)
2022 /* "-2 - errored_index" returned */ 2017 /* "-2 - errored_index" returned */
2023 xerr_idx = -(2+k); 2018 xerr_idx = -(2+k);
2024 XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH); 2019 XFRM_INC_STATS(net, LINUX_MIB_XFRMINTMPLMISMATCH);
2025 goto reject; 2020 goto reject;
2026 } 2021 }
2027 } 2022 }
2028 2023
2029 if (secpath_has_nontransport(sp, k, &xerr_idx)) { 2024 if (secpath_has_nontransport(sp, k, &xerr_idx)) {
2030 XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH); 2025 XFRM_INC_STATS(net, LINUX_MIB_XFRMINTMPLMISMATCH);
2031 goto reject; 2026 goto reject;
2032 } 2027 }
2033 2028
2034 xfrm_pols_put(pols, npols); 2029 xfrm_pols_put(pols, npols);
2035 return 1; 2030 return 1;
2036 } 2031 }
2037 XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK); 2032 XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
2038 2033
2039reject: 2034reject:
2040 xfrm_secpath_reject(xerr_idx, skb, &fl); 2035 xfrm_secpath_reject(xerr_idx, skb, &fl);
@@ -2051,7 +2046,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
2051 2046
2052 if (xfrm_decode_session(skb, &fl, family) < 0) { 2047 if (xfrm_decode_session(skb, &fl, family) < 0) {
2053 /* XXX: we should have something like FWDHDRERROR here. */ 2048 /* XXX: we should have something like FWDHDRERROR here. */
2054 XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); 2049 XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
2055 return 0; 2050 return 0;
2056 } 2051 }
2057 2052
@@ -2380,13 +2375,27 @@ static struct notifier_block xfrm_dev_notifier = {
2380}; 2375};
2381 2376
2382#ifdef CONFIG_XFRM_STATISTICS 2377#ifdef CONFIG_XFRM_STATISTICS
2383static int __init xfrm_statistics_init(void) 2378static int __net_init xfrm_statistics_init(struct net *net)
2384{ 2379{
2385 if (snmp_mib_init((void **)xfrm_statistics, 2380 if (snmp_mib_init((void **)net->mib.xfrm_statistics,
2386 sizeof(struct linux_xfrm_mib)) < 0) 2381 sizeof(struct linux_xfrm_mib)) < 0)
2387 return -ENOMEM; 2382 return -ENOMEM;
2388 return 0; 2383 return 0;
2389} 2384}
2385
2386static void xfrm_statistics_fini(struct net *net)
2387{
2388 snmp_mib_free((void **)net->mib.xfrm_statistics);
2389}
2390#else
2391static int __net_init xfrm_statistics_init(struct net *net)
2392{
2393 return 0;
2394}
2395
2396static void xfrm_statistics_fini(struct net *net)
2397{
2398}
2390#endif 2399#endif
2391 2400
2392static int __net_init xfrm_policy_init(struct net *net) 2401static int __net_init xfrm_policy_init(struct net *net)
@@ -2480,6 +2489,9 @@ static int __net_init xfrm_net_init(struct net *net)
2480{ 2489{
2481 int rv; 2490 int rv;
2482 2491
2492 rv = xfrm_statistics_init(net);
2493 if (rv < 0)
2494 goto out_statistics;
2483 rv = xfrm_state_init(net); 2495 rv = xfrm_state_init(net);
2484 if (rv < 0) 2496 if (rv < 0)
2485 goto out_state; 2497 goto out_state;
@@ -2491,6 +2503,8 @@ static int __net_init xfrm_net_init(struct net *net)
2491out_policy: 2503out_policy:
2492 xfrm_state_fini(net); 2504 xfrm_state_fini(net);
2493out_state: 2505out_state:
2506 xfrm_statistics_fini(net);
2507out_statistics:
2494 return rv; 2508 return rv;
2495} 2509}
2496 2510
@@ -2498,6 +2512,7 @@ static void __net_exit xfrm_net_exit(struct net *net)
2498{ 2512{
2499 xfrm_policy_fini(net); 2513 xfrm_policy_fini(net);
2500 xfrm_state_fini(net); 2514 xfrm_state_fini(net);
2515 xfrm_statistics_fini(net);
2501} 2516}
2502 2517
2503static struct pernet_operations __net_initdata xfrm_net_ops = { 2518static struct pernet_operations __net_initdata xfrm_net_ops = {
@@ -2508,9 +2523,6 @@ static struct pernet_operations __net_initdata xfrm_net_ops = {
2508void __init xfrm_init(void) 2523void __init xfrm_init(void)
2509{ 2524{
2510 register_pernet_subsys(&xfrm_net_ops); 2525 register_pernet_subsys(&xfrm_net_ops);
2511#ifdef CONFIG_XFRM_STATISTICS
2512 xfrm_statistics_init();
2513#endif
2514 xfrm_input_init(); 2526 xfrm_input_init();
2515#ifdef CONFIG_XFRM_STATISTICS 2527#ifdef CONFIG_XFRM_STATISTICS
2516 xfrm_proc_init(); 2528 xfrm_proc_init();