aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/mib.h3
-rw-r--r--include/net/xfrm.h13
-rw-r--r--net/ipv6/xfrm6_input.c9
-rw-r--r--net/xfrm/xfrm_input.c22
-rw-r--r--net/xfrm/xfrm_output.c15
-rw-r--r--net/xfrm/xfrm_policy.c82
-rw-r--r--net/xfrm/xfrm_proc.c2
7 files changed, 81 insertions, 65 deletions
diff --git a/include/net/netns/mib.h b/include/net/netns/mib.h
index 10cb7c336de5..0b44112e2366 100644
--- a/include/net/netns/mib.h
+++ b/include/net/netns/mib.h
@@ -20,6 +20,9 @@ struct netns_mib {
20 DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); 20 DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
21 DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics); 21 DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
22#endif 22#endif
23#ifdef CONFIG_XFRM_STATISTICS
24 DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
25#endif
23}; 26};
24 27
25#endif 28#endif
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index d076f3d34278..78ec3e8a95ed 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -38,14 +38,13 @@
38 MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto)) 38 MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
39 39
40#ifdef CONFIG_XFRM_STATISTICS 40#ifdef CONFIG_XFRM_STATISTICS
41DECLARE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics); 41#define XFRM_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.xfrm_statistics, field)
42#define XFRM_INC_STATS(field) SNMP_INC_STATS(xfrm_statistics, field) 42#define XFRM_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.xfrm_statistics, field)
43#define XFRM_INC_STATS_BH(field) SNMP_INC_STATS_BH(xfrm_statistics, field) 43#define XFRM_INC_STATS_USER(net, field) SNMP_INC_STATS_USER((net)-mib.xfrm_statistics, field)
44#define XFRM_INC_STATS_USER(field) SNMP_INC_STATS_USER(xfrm_statistics, field)
45#else 44#else
46#define XFRM_INC_STATS(field) 45#define XFRM_INC_STATS(net, field) ((void)(net))
47#define XFRM_INC_STATS_BH(field) 46#define XFRM_INC_STATS_BH(net, field) ((void)(net))
48#define XFRM_INC_STATS_USER(field) 47#define XFRM_INC_STATS_USER(net, field) ((void)(net))
49#endif 48#endif
50 49
51extern u32 sysctl_xfrm_aevent_etime; 50extern u32 sysctl_xfrm_aevent_etime;
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index b69766a77743..9084582d236b 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -58,6 +58,7 @@ EXPORT_SYMBOL(xfrm6_rcv);
58int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, 58int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
59 xfrm_address_t *saddr, u8 proto) 59 xfrm_address_t *saddr, u8 proto)
60{ 60{
61 struct net *net = dev_net(skb->dev);
61 struct xfrm_state *x = NULL; 62 struct xfrm_state *x = NULL;
62 int i = 0; 63 int i = 0;
63 64
@@ -67,7 +68,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
67 68
68 sp = secpath_dup(skb->sp); 69 sp = secpath_dup(skb->sp);
69 if (!sp) { 70 if (!sp) {
70 XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); 71 XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
71 goto drop; 72 goto drop;
72 } 73 }
73 if (skb->sp) 74 if (skb->sp)
@@ -76,7 +77,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
76 } 77 }
77 78
78 if (1 + skb->sp->len == XFRM_MAX_DEPTH) { 79 if (1 + skb->sp->len == XFRM_MAX_DEPTH) {
79 XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); 80 XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
80 goto drop; 81 goto drop;
81 } 82 }
82 83
@@ -100,7 +101,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
100 break; 101 break;
101 } 102 }
102 103
103 x = xfrm_state_lookup_byaddr(&init_net, dst, src, proto, AF_INET6); 104 x = xfrm_state_lookup_byaddr(net, dst, src, proto, AF_INET6);
104 if (!x) 105 if (!x)
105 continue; 106 continue;
106 107
@@ -122,7 +123,7 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
122 } 123 }
123 124
124 if (!x) { 125 if (!x) {
125 XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); 126 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
126 xfrm_audit_state_notfound_simple(skb, AF_INET6); 127 xfrm_audit_state_notfound_simple(skb, AF_INET6);
127 goto drop; 128 goto drop;
128 } 129 }
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index a714dce03dc4..b4a13178fb40 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -128,7 +128,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
128 128
129 sp = secpath_dup(skb->sp); 129 sp = secpath_dup(skb->sp);
130 if (!sp) { 130 if (!sp) {
131 XFRM_INC_STATS(LINUX_MIB_XFRMINERROR); 131 XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
132 goto drop; 132 goto drop;
133 } 133 }
134 if (skb->sp) 134 if (skb->sp)
@@ -142,19 +142,19 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
142 142
143 seq = 0; 143 seq = 0;
144 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) { 144 if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
145 XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); 145 XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
146 goto drop; 146 goto drop;
147 } 147 }
148 148
149 do { 149 do {
150 if (skb->sp->len == XFRM_MAX_DEPTH) { 150 if (skb->sp->len == XFRM_MAX_DEPTH) {
151 XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR); 151 XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
152 goto drop; 152 goto drop;
153 } 153 }
154 154
155 x = xfrm_state_lookup(net, daddr, spi, nexthdr, family); 155 x = xfrm_state_lookup(net, daddr, spi, nexthdr, family);
156 if (x == NULL) { 156 if (x == NULL) {
157 XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES); 157 XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
158 xfrm_audit_state_notfound(skb, family, spi, seq); 158 xfrm_audit_state_notfound(skb, family, spi, seq);
159 goto drop; 159 goto drop;
160 } 160 }
@@ -163,22 +163,22 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
163 163
164 spin_lock(&x->lock); 164 spin_lock(&x->lock);
165 if (unlikely(x->km.state != XFRM_STATE_VALID)) { 165 if (unlikely(x->km.state != XFRM_STATE_VALID)) {
166 XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID); 166 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEINVALID);
167 goto drop_unlock; 167 goto drop_unlock;
168 } 168 }
169 169
170 if ((x->encap ? x->encap->encap_type : 0) != encap_type) { 170 if ((x->encap ? x->encap->encap_type : 0) != encap_type) {
171 XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH); 171 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH);
172 goto drop_unlock; 172 goto drop_unlock;
173 } 173 }
174 174
175 if (x->props.replay_window && xfrm_replay_check(x, skb, seq)) { 175 if (x->props.replay_window && xfrm_replay_check(x, skb, seq)) {
176 XFRM_INC_STATS(LINUX_MIB_XFRMINSTATESEQERROR); 176 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
177 goto drop_unlock; 177 goto drop_unlock;
178 } 178 }
179 179
180 if (xfrm_state_check_expire(x)) { 180 if (xfrm_state_check_expire(x)) {
181 XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEEXPIRED); 181 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEEXPIRED);
182 goto drop_unlock; 182 goto drop_unlock;
183 } 183 }
184 184
@@ -199,7 +199,7 @@ resume:
199 x->type->proto); 199 x->type->proto);
200 x->stats.integrity_failed++; 200 x->stats.integrity_failed++;
201 } 201 }
202 XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEPROTOERROR); 202 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR);
203 goto drop_unlock; 203 goto drop_unlock;
204 } 204 }
205 205
@@ -225,7 +225,7 @@ resume:
225 } 225 }
226 226
227 if (inner_mode->input(x, skb)) { 227 if (inner_mode->input(x, skb)) {
228 XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR); 228 XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
229 goto drop; 229 goto drop;
230 } 230 }
231 231
@@ -243,7 +243,7 @@ resume:
243 243
244 err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); 244 err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
245 if (err < 0) { 245 if (err < 0) {
246 XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR); 246 XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
247 goto drop; 247 goto drop;
248 } 248 }
249 } while (!err); 249 } while (!err);
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index ba90e5e50ffc..c235597ba8dd 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -49,27 +49,27 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
49 do { 49 do {
50 err = xfrm_state_check_space(x, skb); 50 err = xfrm_state_check_space(x, skb);
51 if (err) { 51 if (err) {
52 XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR); 52 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
53 goto error_nolock; 53 goto error_nolock;
54 } 54 }
55 55
56 err = x->outer_mode->output(x, skb); 56 err = x->outer_mode->output(x, skb);
57 if (err) { 57 if (err) {
58 XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEMODEERROR); 58 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEMODEERROR);
59 goto error_nolock; 59 goto error_nolock;
60 } 60 }
61 61
62 spin_lock_bh(&x->lock); 62 spin_lock_bh(&x->lock);
63 err = xfrm_state_check_expire(x); 63 err = xfrm_state_check_expire(x);
64 if (err) { 64 if (err) {
65 XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEEXPIRED); 65 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEEXPIRED);
66 goto error; 66 goto error;
67 } 67 }
68 68
69 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { 69 if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
70 XFRM_SKB_CB(skb)->seq.output = ++x->replay.oseq; 70 XFRM_SKB_CB(skb)->seq.output = ++x->replay.oseq;
71 if (unlikely(x->replay.oseq == 0)) { 71 if (unlikely(x->replay.oseq == 0)) {
72 XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR); 72 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATESEQERROR);
73 x->replay.oseq--; 73 x->replay.oseq--;
74 xfrm_audit_state_replay_overflow(x, skb); 74 xfrm_audit_state_replay_overflow(x, skb);
75 err = -EOVERFLOW; 75 err = -EOVERFLOW;
@@ -90,12 +90,12 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
90 90
91resume: 91resume:
92 if (err) { 92 if (err) {
93 XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEPROTOERROR); 93 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEPROTOERROR);
94 goto error_nolock; 94 goto error_nolock;
95 } 95 }
96 96
97 if (!(skb->dst = dst_pop(dst))) { 97 if (!(skb->dst = dst_pop(dst))) {
98 XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR); 98 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
99 err = -EHOSTUNREACH; 99 err = -EHOSTUNREACH;
100 goto error_nolock; 100 goto error_nolock;
101 } 101 }
@@ -179,6 +179,7 @@ static int xfrm_output_gso(struct sk_buff *skb)
179 179
180int xfrm_output(struct sk_buff *skb) 180int xfrm_output(struct sk_buff *skb)
181{ 181{
182 struct net *net = dev_net(skb->dst->dev);
182 int err; 183 int err;
183 184
184 if (skb_is_gso(skb)) 185 if (skb_is_gso(skb))
@@ -187,7 +188,7 @@ int xfrm_output(struct sk_buff *skb)
187 if (skb->ip_summed == CHECKSUM_PARTIAL) { 188 if (skb->ip_summed == CHECKSUM_PARTIAL) {
188 err = skb_checksum_help(skb); 189 err = skb_checksum_help(skb);
189 if (err) { 190 if (err) {
190 XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR); 191 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
191 kfree_skb(skb); 192 kfree_skb(skb);
192 return err; 193 return err;
193 } 194 }
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();
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
index 2b0db13f0cda..27a2ab92d874 100644
--- a/net/xfrm/xfrm_proc.c
+++ b/net/xfrm/xfrm_proc.c
@@ -62,7 +62,7 @@ static int xfrm_statistics_seq_show(struct seq_file *seq, void *v)
62 int i; 62 int i;
63 for (i=0; xfrm_mib_list[i].name; i++) 63 for (i=0; xfrm_mib_list[i].name; i++)
64 seq_printf(seq, "%-24s\t%lu\n", xfrm_mib_list[i].name, 64 seq_printf(seq, "%-24s\t%lu\n", xfrm_mib_list[i].name,
65 fold_field((void **)xfrm_statistics, 65 fold_field((void **)init_net.mib.xfrm_statistics,
66 xfrm_mib_list[i].entry)); 66 xfrm_mib_list[i].entry));
67 return 0; 67 return 0;
68} 68}