sp = secpath_dup(skb->sp);
if (!sp) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINERROR);
goto drop;
}
if (skb->sp)
seq = 0;
if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
goto drop;
}
do {
if (skb->sp->len == XFRM_MAX_DEPTH) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
goto drop;
}
x = xfrm_state_lookup(net, daddr, spi, nexthdr, family);
if (x == NULL) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
xfrm_audit_state_notfound(skb, family, spi, seq);
goto drop;
}
spin_lock(&x->lock);
if (unlikely(x->km.state != XFRM_STATE_VALID)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEINVALID);
goto drop_unlock;
}
if ((x->encap ? x->encap->encap_type : 0) != encap_type) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH);
goto drop_unlock;
}
if (x->props.replay_window && xfrm_replay_check(x, skb, seq)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINSTATESEQERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
goto drop_unlock;
}
if (xfrm_state_check_expire(x)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEEXPIRED);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEEXPIRED);
goto drop_unlock;
}
x->type->proto);
x->stats.integrity_failed++;
}
- XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEPROTOERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEPROTOERROR);
goto drop_unlock;
}
}
if (inner_mode->input(x, skb)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
goto drop;
}
err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
if (err < 0) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
goto drop;
}
} while (!err);
do {
err = xfrm_state_check_space(x, skb);
if (err) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
goto error_nolock;
}
err = x->outer_mode->output(x, skb);
if (err) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEMODEERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEMODEERROR);
goto error_nolock;
}
spin_lock_bh(&x->lock);
err = xfrm_state_check_expire(x);
if (err) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEEXPIRED);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEEXPIRED);
goto error;
}
if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
XFRM_SKB_CB(skb)->seq.output = ++x->replay.oseq;
if (unlikely(x->replay.oseq == 0)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATESEQERROR);
x->replay.oseq--;
xfrm_audit_state_replay_overflow(x, skb);
err = -EOVERFLOW;
resume:
if (err) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEPROTOERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEPROTOERROR);
goto error_nolock;
}
if (!(skb->dst = dst_pop(dst))) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
err = -EHOSTUNREACH;
goto error_nolock;
}
int xfrm_output(struct sk_buff *skb)
{
+ struct net *net = dev_net(skb->dst->dev);
int err;
if (skb_is_gso(skb))
if (skb->ip_summed == CHECKSUM_PARTIAL) {
err = skb_checksum_help(skb);
if (err) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
kfree_skb(skb);
return err;
}
int sysctl_xfrm_larval_drop __read_mostly = 1;
-#ifdef CONFIG_XFRM_STATISTICS
-DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics) __read_mostly;
-EXPORT_SYMBOL(xfrm_statistics);
-#endif
-
DEFINE_MUTEX(xfrm_cfg_mutex);
EXPORT_SYMBOL(xfrm_cfg_mutex);
policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
err = PTR_ERR(policy);
if (IS_ERR(policy)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
goto dropdst;
}
}
dir, xfrm_policy_lookup);
err = PTR_ERR(policy);
if (IS_ERR(policy)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
goto dropdst;
}
}
default:
case XFRM_POLICY_BLOCK:
/* Prohibit the flow */
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLBLOCK);
err = -EPERM;
goto error;
*/
dst = xfrm_find_bundle(fl, policy, family);
if (IS_ERR(dst)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
err = PTR_ERR(dst);
goto error;
}
XFRM_POLICY_OUT);
if (pols[1]) {
if (IS_ERR(pols[1])) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
err = PTR_ERR(pols[1]);
goto error;
}
if (pols[1]->action == XFRM_POLICY_BLOCK) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLBLOCK);
err = -EPERM;
goto error;
}
/* EREMOTE tells the caller to generate
* a one-shot blackhole route.
*/
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
xfrm_pol_put(policy);
return -EREMOTE;
}
nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family);
if (nx == -EAGAIN && signal_pending(current)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
err = -ERESTART;
goto error;
}
err = nx;
}
if (err < 0) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
goto error;
}
}
dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig);
err = PTR_ERR(dst);
if (IS_ERR(dst)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLEGENERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLEGENERROR);
goto error;
}
dst_free(dst);
if (pol_dead)
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLDEAD);
else
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
err = -EHOSTUNREACH;
goto error;
}
if (unlikely(err)) {
write_unlock_bh(&policy->lock);
dst_free(dst);
- XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
goto error;
}
fl_dir = policy_to_flow_dir(dir);
if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
return 0;
}
for (i=skb->sp->len-1; i>=0; i--) {
struct xfrm_state *x = skb->sp->xvec[i];
if (!xfrm_selector_match(&x->sel, &fl, family)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMISMATCH);
return 0;
}
}
if (sk && sk->sk_policy[dir]) {
pol = xfrm_sk_policy_lookup(sk, dir, &fl);
if (IS_ERR(pol)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
return 0;
}
}
xfrm_policy_lookup);
if (IS_ERR(pol)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
return 0;
}
if (!pol) {
if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) {
xfrm_secpath_reject(xerr_idx, skb, &fl);
- XFRM_INC_STATS(LINUX_MIB_XFRMINNOPOLS);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS);
return 0;
}
return 1;
XFRM_POLICY_IN);
if (pols[1]) {
if (IS_ERR(pols[1])) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR);
return 0;
}
pols[1]->curlft.use_time = get_seconds();
for (pi = 0; pi < npols; pi++) {
if (pols[pi] != pol &&
pols[pi]->action != XFRM_POLICY_ALLOW) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
goto reject;
}
if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINBUFFERERROR);
goto reject_error;
}
for (i = 0; i < pols[pi]->xfrm_nr; i++)
if (k < -1)
/* "-2 - errored_index" returned */
xerr_idx = -(2+k);
- XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINTMPLMISMATCH);
goto reject;
}
}
if (secpath_has_nontransport(sp, k, &xerr_idx)) {
- XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINTMPLMISMATCH);
goto reject;
}
xfrm_pols_put(pols, npols);
return 1;
}
- XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLBLOCK);
reject:
xfrm_secpath_reject(xerr_idx, skb, &fl);
if (xfrm_decode_session(skb, &fl, family) < 0) {
/* XXX: we should have something like FWDHDRERROR here. */
- XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
return 0;
}
};
#ifdef CONFIG_XFRM_STATISTICS
-static int __init xfrm_statistics_init(void)
+static int __net_init xfrm_statistics_init(struct net *net)
{
- if (snmp_mib_init((void **)xfrm_statistics,
+ if (snmp_mib_init((void **)net->mib.xfrm_statistics,
sizeof(struct linux_xfrm_mib)) < 0)
return -ENOMEM;
return 0;
}
+
+static void xfrm_statistics_fini(struct net *net)
+{
+ snmp_mib_free((void **)net->mib.xfrm_statistics);
+}
+#else
+static int __net_init xfrm_statistics_init(struct net *net)
+{
+ return 0;
+}
+
+static void xfrm_statistics_fini(struct net *net)
+{
+}
#endif
static int __net_init xfrm_policy_init(struct net *net)
{
int rv;
+ rv = xfrm_statistics_init(net);
+ if (rv < 0)
+ goto out_statistics;
rv = xfrm_state_init(net);
if (rv < 0)
goto out_state;
out_policy:
xfrm_state_fini(net);
out_state:
+ xfrm_statistics_fini(net);
+out_statistics:
return rv;
}
{
xfrm_policy_fini(net);
xfrm_state_fini(net);
+ xfrm_statistics_fini(net);
}
static struct pernet_operations __net_initdata xfrm_net_ops = {
void __init xfrm_init(void)
{
register_pernet_subsys(&xfrm_net_ops);
-#ifdef CONFIG_XFRM_STATISTICS
- xfrm_statistics_init();
-#endif
xfrm_input_init();
#ifdef CONFIG_XFRM_STATISTICS
xfrm_proc_init();