From 07a7c1070ed382ad4562e3a0d453fd2001d92f7b Mon Sep 17 00:00:00 2001 From: Krzysztof Piotr Oledzki Date: Mon, 21 Jul 2008 10:01:14 -0700 Subject: netlink: add NLA_PUT_BE64 macro Add NLA_PUT_BE64 macro required for 64bit counters in netfilter Signed-off-by: Krzysztof Piotr Oledzki Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/net/netlink.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/net') diff --git a/include/net/netlink.h b/include/net/netlink.h index dfc3701dfcc..18024b8cecb 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -896,6 +896,9 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype, #define NLA_PUT_U64(skb, attrtype, value) \ NLA_PUT_TYPE(skb, u64, attrtype, value) +#define NLA_PUT_BE64(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, __be64, attrtype, value) + #define NLA_PUT_STRING(skb, attrtype, value) \ NLA_PUT(skb, attrtype, strlen(value) + 1, value) -- cgit v1.2.3-70-g09d2 From 584015727a3b88b46602b20077b46cd04f8b4ab3 Mon Sep 17 00:00:00 2001 From: Krzysztof Piotr Oledzki Date: Mon, 21 Jul 2008 10:01:34 -0700 Subject: netfilter: accounting rework: ct_extend + 64bit counters (v4) Initially netfilter has had 64bit counters for conntrack-based accounting, but it was changed in 2.6.14 to save memory. Unfortunately in-kernel 64bit counters are still required, for example for "connbytes" extension. However, 64bit counters waste a lot of memory and it was not possible to enable/disable it runtime. This patch: - reimplements accounting with respect to the extension infrastructure, - makes one global version of seq_print_acct() instead of two seq_print_counters(), - makes it possible to enable it at boot time (for CONFIG_SYSCTL/CONFIG_SYSFS=n), - makes it possible to enable/disable it at runtime by sysctl or sysfs, - extends counters from 32bit to 64bit, - renames ip_conntrack_counter -> nf_conn_counter, - enables accounting code unconditionally (no longer depends on CONFIG_NF_CT_ACCT), - set initial accounting enable state based on CONFIG_NF_CT_ACCT - removes buggy IPCT_COUNTER_FILLING event handling. If accounting is enabled newly created connections get additional acct extend. Old connections are not changed as it is not possible to add a ct_extend area to confirmed conntrack. Accounting is performed for all connections with acct extend regardless of a current state of "net.netfilter.nf_conntrack_acct". Signed-off-by: Krzysztof Piotr Oledzki Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- Documentation/feature-removal-schedule.txt | 10 ++ Documentation/kernel-parameters.txt | 7 ++ include/linux/netfilter/nf_conntrack_common.h | 8 +- include/linux/netfilter/nfnetlink_conntrack.h | 8 +- include/net/netfilter/nf_conntrack.h | 6 -- include/net/netfilter/nf_conntrack_acct.h | 51 ++++++++++ include/net/netfilter/nf_conntrack_extend.h | 2 + .../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 18 +--- net/netfilter/Kconfig | 9 ++ net/netfilter/Makefile | 2 +- net/netfilter/nf_conntrack_acct.c | 104 +++++++++++++++++++++ net/netfilter/nf_conntrack_core.c | 39 +++++--- net/netfilter/nf_conntrack_netlink.c | 44 +++++---- net/netfilter/nf_conntrack_standalone.c | 18 +--- net/netfilter/xt_connbytes.c | 8 +- 15 files changed, 248 insertions(+), 86 deletions(-) create mode 100644 include/net/netfilter/nf_conntrack_acct.h create mode 100644 net/netfilter/nf_conntrack_acct.c (limited to 'include/net') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 86334b6f823..9f73587219e 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -336,3 +336,13 @@ When: After the only user (hal) has seen a release with the patches Why: Over 1K .text/.data size reduction, data is available in other ways (ioctls) Who: Johannes Berg + +--------------------------- + +What: CONFIG_NF_CT_ACCT +When: 2.6.29 +Why: Accounting can now be enabled/disabled without kernel recompilation. + Currently used only to set a default value for a feature that is also + controlled by a kernel/module/sysfs/sysctl parameter. +Who: Krzysztof Piotr Oledzki + diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 09ad7450647..e4ef2758440 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1279,6 +1279,13 @@ and is between 256 and 4096 characters. It is defined in the file This usage is only documented in each driver source file if at all. + nf_conntrack.acct= + [NETFILTER] Enable connection tracking flow accounting + 0 to disable accounting + 1 to enable accounting + Default value depends on CONFIG_NF_CT_ACCT that is + going to be removed in 2.6.29. + nfsaddrs= [NFS] See Documentation/filesystems/nfsroot.txt. diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h index bad1eb760f6..885cbe28226 100644 --- a/include/linux/netfilter/nf_conntrack_common.h +++ b/include/linux/netfilter/nf_conntrack_common.h @@ -122,7 +122,7 @@ enum ip_conntrack_events IPCT_NATINFO_BIT = 10, IPCT_NATINFO = (1 << IPCT_NATINFO_BIT), - /* Counter highest bit has been set */ + /* Counter highest bit has been set, unused */ IPCT_COUNTER_FILLING_BIT = 11, IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT), @@ -145,12 +145,6 @@ enum ip_conntrack_expect_events { }; #ifdef __KERNEL__ -struct ip_conntrack_counter -{ - u_int32_t packets; - u_int32_t bytes; -}; - struct ip_conntrack_stat { unsigned int searched; diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h index 759bc043dc6..c19595c8930 100644 --- a/include/linux/netfilter/nfnetlink_conntrack.h +++ b/include/linux/netfilter/nfnetlink_conntrack.h @@ -115,10 +115,10 @@ enum ctattr_protoinfo_sctp { enum ctattr_counters { CTA_COUNTERS_UNSPEC, - CTA_COUNTERS_PACKETS, /* old 64bit counters */ - CTA_COUNTERS_BYTES, /* old 64bit counters */ - CTA_COUNTERS32_PACKETS, - CTA_COUNTERS32_BYTES, + CTA_COUNTERS_PACKETS, /* 64bit counters */ + CTA_COUNTERS_BYTES, /* 64bit counters */ + CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */ + CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */ __CTA_COUNTERS_MAX }; #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1) diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 8f5b75734dd..0741ad592da 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -88,7 +88,6 @@ struct nf_conn_help { u8 expecting[NF_CT_MAX_EXPECT_CLASSES]; }; - #include #include @@ -111,11 +110,6 @@ struct nf_conn /* Timer function; drops refcnt when it goes off. */ struct timer_list timeout; -#ifdef CONFIG_NF_CT_ACCT - /* Accounting Information (same cache line as other written members) */ - struct ip_conntrack_counter counters[IP_CT_DIR_MAX]; -#endif - #if defined(CONFIG_NF_CONNTRACK_MARK) u_int32_t mark; #endif diff --git a/include/net/netfilter/nf_conntrack_acct.h b/include/net/netfilter/nf_conntrack_acct.h new file mode 100644 index 00000000000..5d5ae55d54c --- /dev/null +++ b/include/net/netfilter/nf_conntrack_acct.h @@ -0,0 +1,51 @@ +/* + * (C) 2008 Krzysztof Piotr Oledzki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _NF_CONNTRACK_ACCT_H +#define _NF_CONNTRACK_ACCT_H +#include +#include +#include +#include + +struct nf_conn_counter { + u_int64_t packets; + u_int64_t bytes; +}; + +extern int nf_ct_acct; + +static inline +struct nf_conn_counter *nf_conn_acct_find(const struct nf_conn *ct) +{ + return nf_ct_ext_find(ct, NF_CT_EXT_ACCT); +} + +static inline +struct nf_conn_counter *nf_ct_acct_ext_add(struct nf_conn *ct, gfp_t gfp) +{ + struct nf_conn_counter *acct; + + if (!nf_ct_acct) + return NULL; + + acct = nf_ct_ext_add(ct, NF_CT_EXT_ACCT, gfp); + if (!acct) + pr_debug("failed to add accounting extension area"); + + + return acct; +}; + +extern unsigned int +seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir); + +extern int nf_conntrack_acct_init(void); +extern void nf_conntrack_acct_fini(void); + +#endif /* _NF_CONNTRACK_ACCT_H */ diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h index f80c0ed6d87..da8ee52613a 100644 --- a/include/net/netfilter/nf_conntrack_extend.h +++ b/include/net/netfilter/nf_conntrack_extend.h @@ -7,11 +7,13 @@ enum nf_ct_ext_id { NF_CT_EXT_HELPER, NF_CT_EXT_NAT, + NF_CT_EXT_ACCT, NF_CT_EXT_NUM, }; #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help #define NF_CT_EXT_NAT_TYPE struct nf_conn_nat +#define NF_CT_EXT_ACCT_TYPE struct nf_conn_counter /* Extensions: optional stuff which isn't permanently in struct. */ struct nf_ct_ext { diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index 40a46d48249..3a020720e40 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c @@ -18,19 +18,7 @@ #include #include #include - -#ifdef CONFIG_NF_CT_ACCT -static unsigned int -seq_print_counters(struct seq_file *s, - const struct ip_conntrack_counter *counter) -{ - return seq_printf(s, "packets=%llu bytes=%llu ", - (unsigned long long)counter->packets, - (unsigned long long)counter->bytes); -} -#else -#define seq_print_counters(x, y) 0 -#endif +#include struct ct_iter_state { unsigned int bucket; @@ -127,7 +115,7 @@ static int ct_seq_show(struct seq_file *s, void *v) l3proto, l4proto)) return -ENOSPC; - if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL])) + if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL)) return -ENOSPC; if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) @@ -138,7 +126,7 @@ static int ct_seq_show(struct seq_file *s, void *v) l3proto, l4proto)) return -ENOSPC; - if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY])) + if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) return -ENOSPC; if (test_bit(IPS_ASSURED_BIT, &ct->status)) diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 316c7af1d2b..ee898e74808 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -49,6 +49,15 @@ config NF_CT_ACCT Those counters can be used for flow-based accounting or the `connbytes' match. + Please note that currently this option only sets a default state. + You may change it at boot time with nf_conntrack.acct=0/1 kernel + paramater or by loading the nf_conntrack module with acct=0/1. + + You may also disable/enable it on a running system with: + sysctl net.netfilter.nf_conntrack_acct=0/1 + + This option will be removed in 2.6.29. + If unsure, say `N'. config NF_CONNTRACK_MARK diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 5c4b183f642..3bd2cc556ae 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -1,6 +1,6 @@ netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o -nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o +nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o nf_conntrack_extend.o nf_conntrack_acct.o nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o obj-$(CONFIG_NETFILTER) = netfilter.o diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c new file mode 100644 index 00000000000..59bd8b903a1 --- /dev/null +++ b/net/netfilter/nf_conntrack_acct.c @@ -0,0 +1,104 @@ +/* Accouting handling for netfilter. */ + +/* + * (C) 2008 Krzysztof Piotr Oledzki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_NF_CT_ACCT +#define NF_CT_ACCT_DEFAULT 1 +#else +#define NF_CT_ACCT_DEFAULT 0 +#endif + +int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT; +EXPORT_SYMBOL_GPL(nf_ct_acct); + +module_param_named(acct, nf_ct_acct, bool, 0644); +MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting."); + +#ifdef CONFIG_SYSCTL +static struct ctl_table_header *acct_sysctl_header; +static struct ctl_table acct_sysctl_table[] = { + { + .ctl_name = CTL_UNNUMBERED, + .procname = "nf_conntrack_acct", + .data = &nf_ct_acct, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + {} +}; +#endif /* CONFIG_SYSCTL */ + +unsigned int +seq_print_acct(struct seq_file *s, const struct nf_conn *ct, int dir) +{ + struct nf_conn_counter *acct; + + acct = nf_conn_acct_find(ct); + if (!acct) + return 0; + + return seq_printf(s, "packets=%llu bytes=%llu ", + (unsigned long long)acct[dir].packets, + (unsigned long long)acct[dir].bytes); +}; +EXPORT_SYMBOL_GPL(seq_print_acct); + +static struct nf_ct_ext_type acct_extend __read_mostly = { + .len = sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]), + .align = __alignof__(struct nf_conn_counter[IP_CT_DIR_MAX]), + .id = NF_CT_EXT_ACCT, +}; + +int nf_conntrack_acct_init(void) +{ + int ret; + +#ifdef CONFIG_NF_CT_ACCT + printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n"); + printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n"); + printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n"); +#endif + + ret = nf_ct_extend_register(&acct_extend); + if (ret < 0) { + printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n"); + return ret; + } + +#ifdef CONFIG_SYSCTL + acct_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, + acct_sysctl_table); + + if (!acct_sysctl_header) { + nf_ct_extend_unregister(&acct_extend); + + printk(KERN_ERR "nf_conntrack_acct: can't register to sysctl.\n"); + return -ENOMEM; + } +#endif + + return 0; +} + +void nf_conntrack_acct_fini(void) +{ +#ifdef CONFIG_SYSCTL + unregister_sysctl_table(acct_sysctl_header); +#endif + nf_ct_extend_unregister(&acct_extend); +} diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 28d03e64200..c519d090bdb 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -37,6 +37,7 @@ #include #include #include +#include #define NF_CONNTRACK_VERSION "0.5.0" @@ -555,6 +556,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, return NULL; } + nf_ct_acct_ext_add(ct, GFP_ATOMIC); + spin_lock_bh(&nf_conntrack_lock); exp = nf_ct_find_expectation(tuple); if (exp) { @@ -828,17 +831,16 @@ void __nf_ct_refresh_acct(struct nf_conn *ct, } acct: -#ifdef CONFIG_NF_CT_ACCT if (do_acct) { - ct->counters[CTINFO2DIR(ctinfo)].packets++; - ct->counters[CTINFO2DIR(ctinfo)].bytes += - skb->len - skb_network_offset(skb); + struct nf_conn_counter *acct; - if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000) - || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000)) - event |= IPCT_COUNTER_FILLING; + acct = nf_conn_acct_find(ct); + if (acct) { + acct[CTINFO2DIR(ctinfo)].packets++; + acct[CTINFO2DIR(ctinfo)].bytes += + skb->len - skb_network_offset(skb); + } } -#endif spin_unlock_bh(&nf_conntrack_lock); @@ -853,15 +855,19 @@ bool __nf_ct_kill_acct(struct nf_conn *ct, const struct sk_buff *skb, int do_acct) { -#ifdef CONFIG_NF_CT_ACCT if (do_acct) { + struct nf_conn_counter *acct; + spin_lock_bh(&nf_conntrack_lock); - ct->counters[CTINFO2DIR(ctinfo)].packets++; - ct->counters[CTINFO2DIR(ctinfo)].bytes += - skb->len - skb_network_offset(skb); + acct = nf_conn_acct_find(ct); + if (acct) { + acct[CTINFO2DIR(ctinfo)].packets++; + acct[CTINFO2DIR(ctinfo)].bytes += + skb->len - skb_network_offset(skb); + } spin_unlock_bh(&nf_conntrack_lock); } -#endif + if (del_timer(&ct->timeout)) { ct->timeout.function((unsigned long)ct); return true; @@ -1029,6 +1035,7 @@ void nf_conntrack_cleanup(void) nf_conntrack_proto_fini(); nf_conntrack_helper_fini(); nf_conntrack_expect_fini(); + nf_conntrack_acct_fini(); } struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced) @@ -1168,6 +1175,10 @@ int __init nf_conntrack_init(void) if (ret < 0) goto out_fini_expect; + ret = nf_conntrack_acct_init(); + if (ret < 0) + goto out_fini_helper; + /* For use by REJECT target */ rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); @@ -1180,6 +1191,8 @@ int __init nf_conntrack_init(void) return ret; +out_fini_helper: + nf_conntrack_helper_fini(); out_fini_expect: nf_conntrack_expect_fini(); out_fini_proto: diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 95a7967731f..105a616c5c7 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef CONFIG_NF_NAT_NEEDED #include #include @@ -206,22 +207,26 @@ nla_put_failure: return -1; } -#ifdef CONFIG_NF_CT_ACCT static int ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct, enum ip_conntrack_dir dir) { enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; struct nlattr *nest_count; + const struct nf_conn_counter *acct; + + acct = nf_conn_acct_find(ct); + if (!acct) + return 0; nest_count = nla_nest_start(skb, type | NLA_F_NESTED); if (!nest_count) goto nla_put_failure; - NLA_PUT_BE32(skb, CTA_COUNTERS32_PACKETS, - htonl(ct->counters[dir].packets)); - NLA_PUT_BE32(skb, CTA_COUNTERS32_BYTES, - htonl(ct->counters[dir].bytes)); + NLA_PUT_BE64(skb, CTA_COUNTERS_PACKETS, + cpu_to_be64(acct[dir].packets)); + NLA_PUT_BE64(skb, CTA_COUNTERS_BYTES, + cpu_to_be64(acct[dir].bytes)); nla_nest_end(skb, nest_count); @@ -230,9 +235,6 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct, nla_put_failure: return -1; } -#else -#define ctnetlink_dump_counters(a, b, c) (0) -#endif #ifdef CONFIG_NF_CONNTRACK_MARK static inline int @@ -501,11 +503,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this, goto nla_put_failure; #endif - if (events & IPCT_COUNTER_FILLING && - (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || - ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)) - goto nla_put_failure; - if (events & IPCT_RELATED && ctnetlink_dump_master(skb, ct) < 0) goto nla_put_failure; @@ -576,11 +573,15 @@ restart: cb->args[1] = (unsigned long)ct; goto out; } -#ifdef CONFIG_NF_CT_ACCT + if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == - IPCTNL_MSG_CT_GET_CTRZERO) - memset(&ct->counters, 0, sizeof(ct->counters)); -#endif + IPCTNL_MSG_CT_GET_CTRZERO) { + struct nf_conn_counter *acct; + + acct = nf_conn_acct_find(ct); + if (acct) + memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX])); + } } if (cb->args[1]) { cb->args[1] = 0; @@ -832,14 +833,9 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, u_int8_t u3 = nfmsg->nfgen_family; int err = 0; - if (nlh->nlmsg_flags & NLM_F_DUMP) { -#ifndef CONFIG_NF_CT_ACCT - if (NFNL_MSG_TYPE(nlh->nlmsg_type) == IPCTNL_MSG_CT_GET_CTRZERO) - return -ENOTSUPP; -#endif + if (nlh->nlmsg_flags & NLM_F_DUMP) return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, ctnetlink_done); - } if (cda[CTA_TUPLE_ORIG]) err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3); @@ -1152,6 +1148,8 @@ ctnetlink_create_conntrack(struct nlattr *cda[], goto err; } + nf_ct_acct_ext_add(ct, GFP_KERNEL); + #if defined(CONFIG_NF_CONNTRACK_MARK) if (cda[CTA_MARK]) ct->mark = ntohl(nla_get_be32(cda[CTA_MARK])); diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 46ea542d0df..869ef9349d0 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -25,6 +25,7 @@ #include #include #include +#include MODULE_LICENSE("GPL"); @@ -38,19 +39,6 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple, } EXPORT_SYMBOL_GPL(print_tuple); -#ifdef CONFIG_NF_CT_ACCT -static unsigned int -seq_print_counters(struct seq_file *s, - const struct ip_conntrack_counter *counter) -{ - return seq_printf(s, "packets=%llu bytes=%llu ", - (unsigned long long)counter->packets, - (unsigned long long)counter->bytes); -} -#else -#define seq_print_counters(x, y) 0 -#endif - struct ct_iter_state { unsigned int bucket; }; @@ -146,7 +134,7 @@ static int ct_seq_show(struct seq_file *s, void *v) l3proto, l4proto)) return -ENOSPC; - if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL])) + if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL)) return -ENOSPC; if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) @@ -157,7 +145,7 @@ static int ct_seq_show(struct seq_file *s, void *v) l3proto, l4proto)) return -ENOSPC; - if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY])) + if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) return -ENOSPC; if (test_bit(IPS_ASSURED_BIT, &ct->status)) diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c index d7e8983cd37..3e39c4fe193 100644 --- a/net/netfilter/xt_connbytes.c +++ b/net/netfilter/xt_connbytes.c @@ -8,6 +8,7 @@ #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte "); @@ -27,12 +28,15 @@ connbytes_mt(const struct sk_buff *skb, const struct net_device *in, u_int64_t what = 0; /* initialize to make gcc happy */ u_int64_t bytes = 0; u_int64_t pkts = 0; - const struct ip_conntrack_counter *counters; + const struct nf_conn_counter *counters; ct = nf_ct_get(skb, &ctinfo); if (!ct) return false; - counters = ct->counters; + + counters = nf_conn_acct_find(ct); + if (!counters) + return false; switch (sinfo->what) { case XT_CONNBYTES_PKTS: -- cgit v1.2.3-70-g09d2 From abd0b198ea699578c3c3476d646c91842e19dbd2 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 22 Jul 2008 14:20:45 -0700 Subject: sctp: make sctp_outq_flush() static sctp_outq_flush() can now become static. Signed-off-by: Adrian Bunk Acked-by: Neil Horman Signed-off-by: David S. Miller --- include/net/sctp/structs.h | 1 - net/sctp/outqueue.c | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include/net') diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 70eb64a7e1a..535a18f57a1 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1161,7 +1161,6 @@ void sctp_outq_init(struct sctp_association *, struct sctp_outq *); void sctp_outq_teardown(struct sctp_outq *); void sctp_outq_free(struct sctp_outq*); int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk); -int sctp_outq_flush(struct sctp_outq *, int); int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *); int sctp_outq_is_empty(const struct sctp_outq *); void sctp_outq_restart(struct sctp_outq *); diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 70ead8dc348..4328ad5439c 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -71,6 +71,8 @@ static void sctp_mark_missing(struct sctp_outq *q, static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn); +static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout); + /* Add data to the front of the queue. */ static inline void sctp_outq_head_data(struct sctp_outq *q, struct sctp_chunk *ch) @@ -712,7 +714,7 @@ int sctp_outq_uncork(struct sctp_outq *q) * locking concerns must be made. Today we use the sock lock to protect * this function. */ -int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) +static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) { struct sctp_packet *packet; struct sctp_packet singleton; -- cgit v1.2.3-70-g09d2 From 888c848ed34bd5f8cb56567624c0d951ab35174e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 22 Jul 2008 14:21:58 -0700 Subject: ipv6: make struct ipv6_devconf static struct ipv6_devconf can now become static. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller --- include/net/if_inet6.h | 2 -- net/ipv6/addrconf.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'include/net') diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index db66c792774..c8effa4b1fe 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -193,8 +193,6 @@ struct inet6_dev struct rcu_head rcu; }; -extern struct ipv6_devconf ipv6_devconf; - static inline void ipv6_eth_mc_map(struct in6_addr *addr, char *buf) { /* diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 9f4fcce6379..74d543d504a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -153,7 +153,7 @@ static int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); -struct ipv6_devconf ipv6_devconf __read_mostly = { +static struct ipv6_devconf ipv6_devconf __read_mostly = { .forwarding = 0, .hop_limit = IPV6_DEFAULT_HOPLIMIT, .mtu6 = IPV6_MIN_MTU, -- cgit v1.2.3-70-g09d2 From 417f28bb340725544c36b35465444d2fd57232b8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jul 2008 14:33:45 -0700 Subject: netns: dont alloc ipv6 fib timer list FIB timer list is a trivial size structure, avoid indirection and just put it in existing ns. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/netns/ipv6.h | 2 +- net/ipv6/ip6_fib.c | 40 +++++++++++++--------------------------- 2 files changed, 14 insertions(+), 28 deletions(-) (limited to 'include/net') diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 5bacd838e88..2932721180c 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -39,7 +39,7 @@ struct netns_ipv6 { #endif struct rt6_info *ip6_null_entry; struct rt6_statistics *rt6_stats; - struct timer_list *ip6_fib_timer; + struct timer_list ip6_fib_timer; struct hlist_head *fib_table_hash; struct fib6_table *fib6_main_tbl; struct dst_ops *ip6_dst_ops; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 944095cf5e3..e0922975c41 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -661,16 +661,16 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, static __inline__ void fib6_start_gc(struct net *net, struct rt6_info *rt) { - if (!timer_pending(net->ipv6.ip6_fib_timer) && + if (!timer_pending(&net->ipv6.ip6_fib_timer) && (rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE))) - mod_timer(net->ipv6.ip6_fib_timer, + mod_timer(&net->ipv6.ip6_fib_timer, jiffies + net->ipv6.sysctl.ip6_rt_gc_interval); } void fib6_force_start_gc(struct net *net) { - if (!timer_pending(net->ipv6.ip6_fib_timer)) - mod_timer(net->ipv6.ip6_fib_timer, + if (!timer_pending(&net->ipv6.ip6_fib_timer)) + mod_timer(&net->ipv6.ip6_fib_timer, jiffies + net->ipv6.sysctl.ip6_rt_gc_interval); } @@ -1449,7 +1449,7 @@ void fib6_run_gc(unsigned long expires, struct net *net) } else { local_bh_disable(); if (!spin_trylock(&fib6_gc_lock)) { - mod_timer(net->ipv6.ip6_fib_timer, jiffies + HZ); + mod_timer(&net->ipv6.ip6_fib_timer, jiffies + HZ); local_bh_enable(); return; } @@ -1462,12 +1462,10 @@ void fib6_run_gc(unsigned long expires, struct net *net) fib6_clean_all(net, fib6_age, 0, NULL); if (gc_args.more) - mod_timer(net->ipv6.ip6_fib_timer, jiffies + + mod_timer(&net->ipv6.ip6_fib_timer, jiffies + net->ipv6.sysctl.ip6_rt_gc_interval); - else { - del_timer(net->ipv6.ip6_fib_timer); - net->ipv6.ip6_fib_timer->expires = 0; - } + else + del_timer(&net->ipv6.ip6_fib_timer); spin_unlock_bh(&fib6_gc_lock); } @@ -1478,16 +1476,7 @@ static void fib6_gc_timer_cb(unsigned long arg) static int fib6_net_init(struct net *net) { - int ret; - struct timer_list *timer; - - ret = -ENOMEM; - timer = kzalloc(sizeof(*timer), GFP_KERNEL); - if (!timer) - goto out; - - setup_timer(timer, fib6_gc_timer_cb, (unsigned long)net); - net->ipv6.ip6_fib_timer = timer; + setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL); if (!net->ipv6.rt6_stats) @@ -1521,9 +1510,7 @@ static int fib6_net_init(struct net *net) #endif fib6_tables_init(net); - ret = 0; -out: - return ret; + return 0; #ifdef CONFIG_IPV6_MULTIPLE_TABLES out_fib6_main_tbl: @@ -1534,15 +1521,14 @@ out_fib_table_hash: out_rt6_stats: kfree(net->ipv6.rt6_stats); out_timer: - kfree(timer); - goto out; + return -ENOMEM; } static void fib6_net_exit(struct net *net) { rt6_ifdown(net, NULL); - del_timer_sync(net->ipv6.ip6_fib_timer); - kfree(net->ipv6.ip6_fib_timer); + del_timer_sync(&net->ipv6.ip6_fib_timer); + #ifdef CONFIG_IPV6_MULTIPLE_TABLES kfree(net->ipv6.fib6_local_tbl); #endif -- cgit v1.2.3-70-g09d2 From 3d0f24a74e7957593a5622eb5c04ed6860dd8391 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 22 Jul 2008 14:35:50 -0700 Subject: ipv6: icmp6_dst_gc return change Change icmp6_dst_gc to return the one value the caller cares about rather than using call by reference. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/net/ip6_route.h | 2 +- net/ipv6/ip6_fib.c | 3 +-- net/ipv6/route.c | 10 ++++------ 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'include/net') diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 9313491e3da..2f8b3c06a10 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -68,7 +68,7 @@ extern struct rt6_info *rt6_lookup(struct net *net, extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct neighbour *neigh, const struct in6_addr *addr); -extern int icmp6_dst_gc(int *more); +extern int icmp6_dst_gc(void); extern void fib6_force_start_gc(struct net *net); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index c72fd2461ca..08ea2de28d6 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1453,9 +1453,8 @@ void fib6_run_gc(unsigned long expires, struct net *net) } gc_args.timeout = net->ipv6.sysctl.ip6_rt_gc_interval; } - gc_args.more = 0; - icmp6_dst_gc(&gc_args.more); + gc_args.more = icmp6_dst_gc(); fib6_clean_all(net, fib6_age, 0, NULL); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 615b328de25..86540b24b27 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -978,13 +978,12 @@ out: return &rt->u.dst; } -int icmp6_dst_gc(int *more) +int icmp6_dst_gc(void) { struct dst_entry *dst, *next, **pprev; - int freed; + int more = 0; next = NULL; - freed = 0; spin_lock_bh(&icmp6_dst_lock); pprev = &icmp6_dst_gc_list; @@ -993,16 +992,15 @@ int icmp6_dst_gc(int *more) if (!atomic_read(&dst->__refcnt)) { *pprev = dst->next; dst_free(dst); - freed++; } else { pprev = &dst->next; - (*more)++; + ++more; } } spin_unlock_bh(&icmp6_dst_lock); - return freed; + return more; } static int ip6_dst_gc(struct dst_ops *ops) -- cgit v1.2.3-70-g09d2 From 6fccab671f2f0a24b799f29a4ec878f62d34656c Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 25 Jul 2008 02:54:40 -0700 Subject: ipsec: ipcomp - Merge IPComp implementations This patch merges the IPv4/IPv6 IPComp implementations since most of the code is identical. As a result future enhancements will no longer need to be duplicated. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/net/ipcomp.h | 6 + net/ipv4/Kconfig | 4 +- net/ipv4/ipcomp.c | 315 +------------------------------------------- net/ipv6/Kconfig | 4 +- net/ipv6/ipcomp6.c | 298 +---------------------------------------- net/xfrm/Kconfig | 6 + net/xfrm/Makefile | 1 + net/xfrm/xfrm_ipcomp.c | 349 +++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 377 insertions(+), 606 deletions(-) create mode 100644 net/xfrm/xfrm_ipcomp.c (limited to 'include/net') diff --git a/include/net/ipcomp.h b/include/net/ipcomp.h index 330b74e813a..2a1092abaa0 100644 --- a/include/net/ipcomp.h +++ b/include/net/ipcomp.h @@ -14,6 +14,12 @@ struct ipcomp_data { struct ip_comp_hdr; struct sk_buff; +struct xfrm_state; + +int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb); +int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb); +void ipcomp_destroy(struct xfrm_state *x); +int ipcomp_init_state(struct xfrm_state *x); static inline struct ip_comp_hdr *ip_comp_hdr(const struct sk_buff *skb) { diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 4670683b468..591ea23639c 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -356,10 +356,8 @@ config INET_ESP config INET_IPCOMP tristate "IP: IPComp transformation" - select XFRM select INET_XFRM_TUNNEL - select CRYPTO - select CRYPTO_DEFLATE + select XFRM_IPCOMP ---help--- Support for IP Payload Compression Protocol (IPComp) (RFC3173), typically needed for IPsec. diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index a75807b971b..a42b64d040c 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -14,153 +14,14 @@ * - Adaptive compression. */ #include -#include #include -#include -#include -#include -#include -#include #include -#include #include #include #include #include #include - -struct ipcomp_tfms { - struct list_head list; - struct crypto_comp **tfms; - int users; -}; - -static DEFINE_MUTEX(ipcomp_resource_mutex); -static void **ipcomp_scratches; -static int ipcomp_scratch_users; -static LIST_HEAD(ipcomp_tfms_list); - -static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) -{ - struct ipcomp_data *ipcd = x->data; - const int plen = skb->len; - int dlen = IPCOMP_SCRATCH_SIZE; - const u8 *start = skb->data; - const int cpu = get_cpu(); - u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); - struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); - int err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen); - - if (err) - goto out; - - if (dlen < (plen + sizeof(struct ip_comp_hdr))) { - err = -EINVAL; - goto out; - } - - err = pskb_expand_head(skb, 0, dlen - plen, GFP_ATOMIC); - if (err) - goto out; - - skb->truesize += dlen - plen; - __skb_put(skb, dlen - plen); - skb_copy_to_linear_data(skb, scratch, dlen); -out: - put_cpu(); - return err; -} - -static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) -{ - int nexthdr; - int err = -ENOMEM; - struct ip_comp_hdr *ipch; - - if (skb_linearize_cow(skb)) - goto out; - - skb->ip_summed = CHECKSUM_NONE; - - /* Remove ipcomp header and decompress original payload */ - ipch = (void *)skb->data; - nexthdr = ipch->nexthdr; - - skb->transport_header = skb->network_header + sizeof(*ipch); - __skb_pull(skb, sizeof(*ipch)); - err = ipcomp_decompress(x, skb); - if (err) - goto out; - - err = nexthdr; - -out: - return err; -} - -static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) -{ - struct ipcomp_data *ipcd = x->data; - const int plen = skb->len; - int dlen = IPCOMP_SCRATCH_SIZE; - u8 *start = skb->data; - const int cpu = get_cpu(); - u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); - struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); - int err; - - local_bh_disable(); - err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); - local_bh_enable(); - if (err) - goto out; - - if ((dlen + sizeof(struct ip_comp_hdr)) >= plen) { - err = -EMSGSIZE; - goto out; - } - - memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); - put_cpu(); - - pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr)); - return 0; - -out: - put_cpu(); - return err; -} - -static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb) -{ - int err; - struct ip_comp_hdr *ipch; - struct ipcomp_data *ipcd = x->data; - - if (skb->len < ipcd->threshold) { - /* Don't bother compressing */ - goto out_ok; - } - - if (skb_linearize_cow(skb)) - goto out_ok; - - err = ipcomp_compress(x, skb); - - if (err) { - goto out_ok; - } - - /* Install ipcomp header, convert into ipcomp datagram. */ - ipch = ip_comp_hdr(skb); - ipch->nexthdr = *skb_mac_header(skb); - ipch->flags = 0; - ipch->cpi = htons((u16 )ntohl(x->id.spi)); - *skb_mac_header(skb) = IPPROTO_COMP; -out_ok: - skb_push(skb, -skb_network_offset(skb)); - return 0; -} +#include static void ipcomp4_err(struct sk_buff *skb, u32 info) { @@ -241,156 +102,12 @@ out: return err; } -static void ipcomp_free_scratches(void) -{ - int i; - void **scratches; - - if (--ipcomp_scratch_users) - return; - - scratches = ipcomp_scratches; - if (!scratches) - return; - - for_each_possible_cpu(i) - vfree(*per_cpu_ptr(scratches, i)); - - free_percpu(scratches); -} - -static void **ipcomp_alloc_scratches(void) -{ - int i; - void **scratches; - - if (ipcomp_scratch_users++) - return ipcomp_scratches; - - scratches = alloc_percpu(void *); - if (!scratches) - return NULL; - - ipcomp_scratches = scratches; - - for_each_possible_cpu(i) { - void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); - if (!scratch) - return NULL; - *per_cpu_ptr(scratches, i) = scratch; - } - - return scratches; -} - -static void ipcomp_free_tfms(struct crypto_comp **tfms) -{ - struct ipcomp_tfms *pos; - int cpu; - - list_for_each_entry(pos, &ipcomp_tfms_list, list) { - if (pos->tfms == tfms) - break; - } - - BUG_TRAP(pos); - - if (--pos->users) - return; - - list_del(&pos->list); - kfree(pos); - - if (!tfms) - return; - - for_each_possible_cpu(cpu) { - struct crypto_comp *tfm = *per_cpu_ptr(tfms, cpu); - crypto_free_comp(tfm); - } - free_percpu(tfms); -} - -static struct crypto_comp **ipcomp_alloc_tfms(const char *alg_name) -{ - struct ipcomp_tfms *pos; - struct crypto_comp **tfms; - int cpu; - - /* This can be any valid CPU ID so we don't need locking. */ - cpu = raw_smp_processor_id(); - - list_for_each_entry(pos, &ipcomp_tfms_list, list) { - struct crypto_comp *tfm; - - tfms = pos->tfms; - tfm = *per_cpu_ptr(tfms, cpu); - - if (!strcmp(crypto_comp_name(tfm), alg_name)) { - pos->users++; - return tfms; - } - } - - pos = kmalloc(sizeof(*pos), GFP_KERNEL); - if (!pos) - return NULL; - - pos->users = 1; - INIT_LIST_HEAD(&pos->list); - list_add(&pos->list, &ipcomp_tfms_list); - - pos->tfms = tfms = alloc_percpu(struct crypto_comp *); - if (!tfms) - goto error; - - for_each_possible_cpu(cpu) { - struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - goto error; - *per_cpu_ptr(tfms, cpu) = tfm; - } - - return tfms; - -error: - ipcomp_free_tfms(tfms); - return NULL; -} - -static void ipcomp_free_data(struct ipcomp_data *ipcd) -{ - if (ipcd->tfms) - ipcomp_free_tfms(ipcd->tfms); - ipcomp_free_scratches(); -} - -static void ipcomp_destroy(struct xfrm_state *x) -{ - struct ipcomp_data *ipcd = x->data; - if (!ipcd) - return; - xfrm_state_delete_tunnel(x); - mutex_lock(&ipcomp_resource_mutex); - ipcomp_free_data(ipcd); - mutex_unlock(&ipcomp_resource_mutex); - kfree(ipcd); -} - -static int ipcomp_init_state(struct xfrm_state *x) +static int ipcomp4_init_state(struct xfrm_state *x) { int err; struct ipcomp_data *ipcd; struct xfrm_algo_desc *calg_desc; - err = -EINVAL; - if (!x->calg) - goto out; - - if (x->encap) - goto out; - x->props.header_len = 0; switch (x->props.mode) { case XFRM_MODE_TRANSPORT: @@ -402,40 +119,22 @@ static int ipcomp_init_state(struct xfrm_state *x) goto out; } - err = -ENOMEM; - ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL); - if (!ipcd) + err = ipcomp_init_state(x); + if (err) goto out; - mutex_lock(&ipcomp_resource_mutex); - if (!ipcomp_alloc_scratches()) - goto error; - - ipcd->tfms = ipcomp_alloc_tfms(x->calg->alg_name); - if (!ipcd->tfms) - goto error; - mutex_unlock(&ipcomp_resource_mutex); - if (x->props.mode == XFRM_MODE_TUNNEL) { err = ipcomp_tunnel_attach(x); if (err) goto error_tunnel; } - calg_desc = xfrm_calg_get_byname(x->calg->alg_name, 0); - BUG_ON(!calg_desc); - ipcd->threshold = calg_desc->uinfo.comp.threshold; - x->data = ipcd; err = 0; out: return err; error_tunnel: - mutex_lock(&ipcomp_resource_mutex); -error: - ipcomp_free_data(ipcd); - mutex_unlock(&ipcomp_resource_mutex); - kfree(ipcd); + ipcomp_destroy(x); goto out; } @@ -443,7 +142,7 @@ static const struct xfrm_type ipcomp_type = { .description = "IPCOMP4", .owner = THIS_MODULE, .proto = IPPROTO_COMP, - .init_state = ipcomp_init_state, + .init_state = ipcomp4_init_state, .destructor = ipcomp_destroy, .input = ipcomp_input, .output = ipcomp_output @@ -481,7 +180,7 @@ module_init(ipcomp4_init); module_exit(ipcomp4_fini); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) - RFC3173"); +MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp/IPv4) - RFC3173"); MODULE_AUTHOR("James Morris "); MODULE_ALIAS_XFRM_TYPE(AF_INET, XFRM_PROTO_COMP); diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index 42814a2ec9d..ec992159b5f 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -96,10 +96,8 @@ config INET6_ESP config INET6_IPCOMP tristate "IPv6: IPComp transformation" - select XFRM select INET6_XFRM_TUNNEL - select CRYPTO - select CRYPTO_DEFLATE + select XFRM_IPCOMP ---help--- Support for IP Payload Compression Protocol (IPComp) (RFC3173), typically needed for IPsec. diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index ee6de425ce6..0cfcea42153 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -50,125 +50,6 @@ #include #include -struct ipcomp6_tfms { - struct list_head list; - struct crypto_comp **tfms; - int users; -}; - -static DEFINE_MUTEX(ipcomp6_resource_mutex); -static void **ipcomp6_scratches; -static int ipcomp6_scratch_users; -static LIST_HEAD(ipcomp6_tfms_list); - -static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) -{ - int nexthdr; - int err = -ENOMEM; - struct ip_comp_hdr *ipch; - int plen, dlen; - struct ipcomp_data *ipcd = x->data; - u8 *start, *scratch; - struct crypto_comp *tfm; - int cpu; - - if (skb_linearize_cow(skb)) - goto out; - - skb->ip_summed = CHECKSUM_NONE; - - /* Remove ipcomp header and decompress original payload */ - ipch = (void *)skb->data; - nexthdr = ipch->nexthdr; - - skb->transport_header = skb->network_header + sizeof(*ipch); - __skb_pull(skb, sizeof(*ipch)); - - /* decompression */ - plen = skb->len; - dlen = IPCOMP_SCRATCH_SIZE; - start = skb->data; - - cpu = get_cpu(); - scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); - tfm = *per_cpu_ptr(ipcd->tfms, cpu); - - err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen); - if (err) - goto out_put_cpu; - - if (dlen < (plen + sizeof(*ipch))) { - err = -EINVAL; - goto out_put_cpu; - } - - err = pskb_expand_head(skb, 0, dlen - plen, GFP_ATOMIC); - if (err) { - goto out_put_cpu; - } - - skb->truesize += dlen - plen; - __skb_put(skb, dlen - plen); - skb_copy_to_linear_data(skb, scratch, dlen); - err = nexthdr; - -out_put_cpu: - put_cpu(); -out: - return err; -} - -static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb) -{ - int err; - struct ip_comp_hdr *ipch; - struct ipcomp_data *ipcd = x->data; - int plen, dlen; - u8 *start, *scratch; - struct crypto_comp *tfm; - int cpu; - - /* check whether datagram len is larger than threshold */ - if (skb->len < ipcd->threshold) { - goto out_ok; - } - - if (skb_linearize_cow(skb)) - goto out_ok; - - /* compression */ - plen = skb->len; - dlen = IPCOMP_SCRATCH_SIZE; - start = skb->data; - - cpu = get_cpu(); - scratch = *per_cpu_ptr(ipcomp6_scratches, cpu); - tfm = *per_cpu_ptr(ipcd->tfms, cpu); - - local_bh_disable(); - err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); - local_bh_enable(); - if (err || (dlen + sizeof(*ipch)) >= plen) { - put_cpu(); - goto out_ok; - } - memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); - put_cpu(); - pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr)); - - /* insert ipcomp header and replace datagram */ - ipch = ip_comp_hdr(skb); - ipch->nexthdr = *skb_mac_header(skb); - ipch->flags = 0; - ipch->cpi = htons((u16 )ntohl(x->id.spi)); - *skb_mac_header(skb) = IPPROTO_COMP; - -out_ok: - skb_push(skb, -skb_network_offset(skb)); - - return 0; -} - static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, int type, int code, int offset, __be32 info) { @@ -251,161 +132,12 @@ out: return err; } -static void ipcomp6_free_scratches(void) -{ - int i; - void **scratches; - - if (--ipcomp6_scratch_users) - return; - - scratches = ipcomp6_scratches; - if (!scratches) - return; - - for_each_possible_cpu(i) { - void *scratch = *per_cpu_ptr(scratches, i); - - vfree(scratch); - } - - free_percpu(scratches); -} - -static void **ipcomp6_alloc_scratches(void) -{ - int i; - void **scratches; - - if (ipcomp6_scratch_users++) - return ipcomp6_scratches; - - scratches = alloc_percpu(void *); - if (!scratches) - return NULL; - - ipcomp6_scratches = scratches; - - for_each_possible_cpu(i) { - void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); - if (!scratch) - return NULL; - *per_cpu_ptr(scratches, i) = scratch; - } - - return scratches; -} - -static void ipcomp6_free_tfms(struct crypto_comp **tfms) -{ - struct ipcomp6_tfms *pos; - int cpu; - - list_for_each_entry(pos, &ipcomp6_tfms_list, list) { - if (pos->tfms == tfms) - break; - } - - BUG_TRAP(pos); - - if (--pos->users) - return; - - list_del(&pos->list); - kfree(pos); - - if (!tfms) - return; - - for_each_possible_cpu(cpu) { - struct crypto_comp *tfm = *per_cpu_ptr(tfms, cpu); - crypto_free_comp(tfm); - } - free_percpu(tfms); -} - -static struct crypto_comp **ipcomp6_alloc_tfms(const char *alg_name) -{ - struct ipcomp6_tfms *pos; - struct crypto_comp **tfms; - int cpu; - - /* This can be any valid CPU ID so we don't need locking. */ - cpu = raw_smp_processor_id(); - - list_for_each_entry(pos, &ipcomp6_tfms_list, list) { - struct crypto_comp *tfm; - - tfms = pos->tfms; - tfm = *per_cpu_ptr(tfms, cpu); - - if (!strcmp(crypto_comp_name(tfm), alg_name)) { - pos->users++; - return tfms; - } - } - - pos = kmalloc(sizeof(*pos), GFP_KERNEL); - if (!pos) - return NULL; - - pos->users = 1; - INIT_LIST_HEAD(&pos->list); - list_add(&pos->list, &ipcomp6_tfms_list); - - pos->tfms = tfms = alloc_percpu(struct crypto_comp *); - if (!tfms) - goto error; - - for_each_possible_cpu(cpu) { - struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - goto error; - *per_cpu_ptr(tfms, cpu) = tfm; - } - - return tfms; - -error: - ipcomp6_free_tfms(tfms); - return NULL; -} - -static void ipcomp6_free_data(struct ipcomp_data *ipcd) -{ - if (ipcd->tfms) - ipcomp6_free_tfms(ipcd->tfms); - ipcomp6_free_scratches(); -} - -static void ipcomp6_destroy(struct xfrm_state *x) -{ - struct ipcomp_data *ipcd = x->data; - if (!ipcd) - return; - xfrm_state_delete_tunnel(x); - mutex_lock(&ipcomp6_resource_mutex); - ipcomp6_free_data(ipcd); - mutex_unlock(&ipcomp6_resource_mutex); - kfree(ipcd); - - xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr); -} - static int ipcomp6_init_state(struct xfrm_state *x) { int err; struct ipcomp_data *ipcd; struct xfrm_algo_desc *calg_desc; - err = -EINVAL; - if (!x->calg) - goto out; - - if (x->encap) - goto out; - x->props.header_len = 0; switch (x->props.mode) { case XFRM_MODE_TRANSPORT: @@ -417,39 +149,21 @@ static int ipcomp6_init_state(struct xfrm_state *x) goto out; } - err = -ENOMEM; - ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL); - if (!ipcd) + err = ipcomp_init_state(x); + if (err) goto out; - mutex_lock(&ipcomp6_resource_mutex); - if (!ipcomp6_alloc_scratches()) - goto error; - - ipcd->tfms = ipcomp6_alloc_tfms(x->calg->alg_name); - if (!ipcd->tfms) - goto error; - mutex_unlock(&ipcomp6_resource_mutex); - if (x->props.mode == XFRM_MODE_TUNNEL) { err = ipcomp6_tunnel_attach(x); if (err) goto error_tunnel; } - calg_desc = xfrm_calg_get_byname(x->calg->alg_name, 0); - BUG_ON(!calg_desc); - ipcd->threshold = calg_desc->uinfo.comp.threshold; - x->data = ipcd; err = 0; out: return err; error_tunnel: - mutex_lock(&ipcomp6_resource_mutex); -error: - ipcomp6_free_data(ipcd); - mutex_unlock(&ipcomp6_resource_mutex); - kfree(ipcd); + ipcomp_destroy(x); goto out; } @@ -460,9 +174,9 @@ static const struct xfrm_type ipcomp6_type = .owner = THIS_MODULE, .proto = IPPROTO_COMP, .init_state = ipcomp6_init_state, - .destructor = ipcomp6_destroy, - .input = ipcomp6_input, - .output = ipcomp6_output, + .destructor = ipcomp_destroy, + .input = ipcomp_input, + .output = ipcomp_output, .hdr_offset = xfrm6_find_1stfragopt, }; diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig index 9201ef8ad90..6d081674515 100644 --- a/net/xfrm/Kconfig +++ b/net/xfrm/Kconfig @@ -46,6 +46,12 @@ config XFRM_STATISTICS If unsure, say N. +config XFRM_IPCOMP + tristate + select XFRM + select CRYPTO + select CRYPTO_DEFLATE + config NET_KEY tristate "PF_KEY sockets" select XFRM diff --git a/net/xfrm/Makefile b/net/xfrm/Makefile index 332cfb0ff56..0f439a72cca 100644 --- a/net/xfrm/Makefile +++ b/net/xfrm/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_hash.o \ xfrm_input.o xfrm_output.o xfrm_algo.o obj-$(CONFIG_XFRM_STATISTICS) += xfrm_proc.o obj-$(CONFIG_XFRM_USER) += xfrm_user.o +obj-$(CONFIG_XFRM_IPCOMP) += xfrm_ipcomp.o diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c new file mode 100644 index 00000000000..b51e804fbba --- /dev/null +++ b/net/xfrm/xfrm_ipcomp.c @@ -0,0 +1,349 @@ +/* + * IP Payload Compression Protocol (IPComp) - RFC3173. + * + * Copyright (c) 2003 James Morris + * Copyright (c) 2003-2008 Herbert Xu + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Todo: + * - Tunable compression parameters. + * - Compression stats. + * - Adaptive compression. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ipcomp_tfms { + struct list_head list; + struct crypto_comp **tfms; + int users; +}; + +static DEFINE_MUTEX(ipcomp_resource_mutex); +static void **ipcomp_scratches; +static int ipcomp_scratch_users; +static LIST_HEAD(ipcomp_tfms_list); + +static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb) +{ + struct ipcomp_data *ipcd = x->data; + const int plen = skb->len; + int dlen = IPCOMP_SCRATCH_SIZE; + const u8 *start = skb->data; + const int cpu = get_cpu(); + u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); + struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); + int err = crypto_comp_decompress(tfm, start, plen, scratch, &dlen); + + if (err) + goto out; + + if (dlen < (plen + sizeof(struct ip_comp_hdr))) { + err = -EINVAL; + goto out; + } + + err = pskb_expand_head(skb, 0, dlen - plen, GFP_ATOMIC); + if (err) + goto out; + + skb->truesize += dlen - plen; + __skb_put(skb, dlen - plen); + skb_copy_to_linear_data(skb, scratch, dlen); +out: + put_cpu(); + return err; +} + +int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) +{ + int nexthdr; + int err = -ENOMEM; + struct ip_comp_hdr *ipch; + + if (skb_linearize_cow(skb)) + goto out; + + skb->ip_summed = CHECKSUM_NONE; + + /* Remove ipcomp header and decompress original payload */ + ipch = (void *)skb->data; + nexthdr = ipch->nexthdr; + + skb->transport_header = skb->network_header + sizeof(*ipch); + __skb_pull(skb, sizeof(*ipch)); + err = ipcomp_decompress(x, skb); + if (err) + goto out; + + err = nexthdr; + +out: + return err; +} +EXPORT_SYMBOL_GPL(ipcomp_input); + +static int ipcomp_compress(struct xfrm_state *x, struct sk_buff *skb) +{ + struct ipcomp_data *ipcd = x->data; + const int plen = skb->len; + int dlen = IPCOMP_SCRATCH_SIZE; + u8 *start = skb->data; + const int cpu = get_cpu(); + u8 *scratch = *per_cpu_ptr(ipcomp_scratches, cpu); + struct crypto_comp *tfm = *per_cpu_ptr(ipcd->tfms, cpu); + int err; + + local_bh_disable(); + err = crypto_comp_compress(tfm, start, plen, scratch, &dlen); + local_bh_enable(); + if (err) + goto out; + + if ((dlen + sizeof(struct ip_comp_hdr)) >= plen) { + err = -EMSGSIZE; + goto out; + } + + memcpy(start + sizeof(struct ip_comp_hdr), scratch, dlen); + put_cpu(); + + pskb_trim(skb, dlen + sizeof(struct ip_comp_hdr)); + return 0; + +out: + put_cpu(); + return err; +} + +int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb) +{ + int err; + struct ip_comp_hdr *ipch; + struct ipcomp_data *ipcd = x->data; + + if (skb->len < ipcd->threshold) { + /* Don't bother compressing */ + goto out_ok; + } + + if (skb_linearize_cow(skb)) + goto out_ok; + + err = ipcomp_compress(x, skb); + + if (err) { + goto out_ok; + } + + /* Install ipcomp header, convert into ipcomp datagram. */ + ipch = ip_comp_hdr(skb); + ipch->nexthdr = *skb_mac_header(skb); + ipch->flags = 0; + ipch->cpi = htons((u16 )ntohl(x->id.spi)); + *skb_mac_header(skb) = IPPROTO_COMP; +out_ok: + skb_push(skb, -skb_network_offset(skb)); + return 0; +} +EXPORT_SYMBOL_GPL(ipcomp_output); + +static void ipcomp_free_scratches(void) +{ + int i; + void **scratches; + + if (--ipcomp_scratch_users) + return; + + scratches = ipcomp_scratches; + if (!scratches) + return; + + for_each_possible_cpu(i) + vfree(*per_cpu_ptr(scratches, i)); + + free_percpu(scratches); +} + +static void **ipcomp_alloc_scratches(void) +{ + int i; + void **scratches; + + if (ipcomp_scratch_users++) + return ipcomp_scratches; + + scratches = alloc_percpu(void *); + if (!scratches) + return NULL; + + ipcomp_scratches = scratches; + + for_each_possible_cpu(i) { + void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); + if (!scratch) + return NULL; + *per_cpu_ptr(scratches, i) = scratch; + } + + return scratches; +} + +static void ipcomp_free_tfms(struct crypto_comp **tfms) +{ + struct ipcomp_tfms *pos; + int cpu; + + list_for_each_entry(pos, &ipcomp_tfms_list, list) { + if (pos->tfms == tfms) + break; + } + + BUG_TRAP(pos); + + if (--pos->users) + return; + + list_del(&pos->list); + kfree(pos); + + if (!tfms) + return; + + for_each_possible_cpu(cpu) { + struct crypto_comp *tfm = *per_cpu_ptr(tfms, cpu); + crypto_free_comp(tfm); + } + free_percpu(tfms); +} + +static struct crypto_comp **ipcomp_alloc_tfms(const char *alg_name) +{ + struct ipcomp_tfms *pos; + struct crypto_comp **tfms; + int cpu; + + /* This can be any valid CPU ID so we don't need locking. */ + cpu = raw_smp_processor_id(); + + list_for_each_entry(pos, &ipcomp_tfms_list, list) { + struct crypto_comp *tfm; + + tfms = pos->tfms; + tfm = *per_cpu_ptr(tfms, cpu); + + if (!strcmp(crypto_comp_name(tfm), alg_name)) { + pos->users++; + return tfms; + } + } + + pos = kmalloc(sizeof(*pos), GFP_KERNEL); + if (!pos) + return NULL; + + pos->users = 1; + INIT_LIST_HEAD(&pos->list); + list_add(&pos->list, &ipcomp_tfms_list); + + pos->tfms = tfms = alloc_percpu(struct crypto_comp *); + if (!tfms) + goto error; + + for_each_possible_cpu(cpu) { + struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm)) + goto error; + *per_cpu_ptr(tfms, cpu) = tfm; + } + + return tfms; + +error: + ipcomp_free_tfms(tfms); + return NULL; +} + +static void ipcomp_free_data(struct ipcomp_data *ipcd) +{ + if (ipcd->tfms) + ipcomp_free_tfms(ipcd->tfms); + ipcomp_free_scratches(); +} + +void ipcomp_destroy(struct xfrm_state *x) +{ + struct ipcomp_data *ipcd = x->data; + if (!ipcd) + return; + xfrm_state_delete_tunnel(x); + mutex_lock(&ipcomp_resource_mutex); + ipcomp_free_data(ipcd); + mutex_unlock(&ipcomp_resource_mutex); + kfree(ipcd); +} +EXPORT_SYMBOL_GPL(ipcomp_destroy); + +int ipcomp_init_state(struct xfrm_state *x) +{ + int err; + struct ipcomp_data *ipcd; + struct xfrm_algo_desc *calg_desc; + + err = -EINVAL; + if (!x->calg) + goto out; + + if (x->encap) + goto out; + + err = -ENOMEM; + ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL); + if (!ipcd) + goto out; + + mutex_lock(&ipcomp_resource_mutex); + if (!ipcomp_alloc_scratches()) + goto error; + + ipcd->tfms = ipcomp_alloc_tfms(x->calg->alg_name); + if (!ipcd->tfms) + goto error; + mutex_unlock(&ipcomp_resource_mutex); + + calg_desc = xfrm_calg_get_byname(x->calg->alg_name, 0); + BUG_ON(!calg_desc); + ipcd->threshold = calg_desc->uinfo.comp.threshold; + x->data = ipcd; + err = 0; +out: + return err; + +error: + ipcomp_free_data(ipcd); + mutex_unlock(&ipcomp_resource_mutex); + kfree(ipcd); + goto out; +} +EXPORT_SYMBOL_GPL(ipcomp_init_state); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("IP Payload Compression Protocol (IPComp) - RFC3173"); +MODULE_AUTHOR("James Morris "); -- cgit v1.2.3-70-g09d2 From 8b5ac31e27135a6f2c210c40d03bf8f1b3a86b77 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 25 Jul 2008 01:45:26 -0700 Subject: include: use get/put_unaligned_* helpers Signed-off-by: Harvey Harrison Cc: "John W. Linville" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/reiserfs_fs.h | 4 ++-- include/linux/smb_fs.h | 19 +++++++------------ include/net/ieee80211_radiotap.h | 2 +- 3 files changed, 10 insertions(+), 15 deletions(-) (limited to 'include/net') diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 4aacaeecb56..e9963af16cd 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -526,8 +526,8 @@ struct item_head { ** p is the array of __u32, i is the index into the array, v is the value ** to store there. */ -#define get_block_num(p, i) le32_to_cpu(get_unaligned((p) + (i))) -#define put_block_num(p, i, v) put_unaligned(cpu_to_le32(v), (p) + (i)) +#define get_block_num(p, i) get_unaligned_le32((p) + (i)) +#define put_block_num(p, i, v) put_unaligned_le32((v), (p) + (i)) // // in old version uniqueness field shows key type diff --git a/include/linux/smb_fs.h b/include/linux/smb_fs.h index 2c5cd55f44f..923cd8a247b 100644 --- a/include/linux/smb_fs.h +++ b/include/linux/smb_fs.h @@ -43,18 +43,13 @@ static inline struct smb_inode_info *SMB_I(struct inode *inode) } /* macro names are short for word, double-word, long value (?) */ -#define WVAL(buf,pos) \ - (le16_to_cpu(get_unaligned((__le16 *)((u8 *)(buf) + (pos))))) -#define DVAL(buf,pos) \ - (le32_to_cpu(get_unaligned((__le32 *)((u8 *)(buf) + (pos))))) -#define LVAL(buf,pos) \ - (le64_to_cpu(get_unaligned((__le64 *)((u8 *)(buf) + (pos))))) -#define WSET(buf,pos,val) \ - put_unaligned(cpu_to_le16((u16)(val)), (__le16 *)((u8 *)(buf) + (pos))) -#define DSET(buf,pos,val) \ - put_unaligned(cpu_to_le32((u32)(val)), (__le32 *)((u8 *)(buf) + (pos))) -#define LSET(buf,pos,val) \ - put_unaligned(cpu_to_le64((u64)(val)), (__le64 *)((u8 *)(buf) + (pos))) +#define WVAL(buf, pos) (get_unaligned_le16((u8 *)(buf) + (pos))) +#define DVAL(buf, pos) (get_unaligned_le32((u8 *)(buf) + (pos))) +#define LVAL(buf, pos) (get_unaligned_le64((u8 *)(buf) + (pos))) + +#define WSET(buf, pos, val) put_unaligned_le16((val), (u8 *)(buf) + (pos)) +#define DSET(buf, pos, val) put_unaligned_le32((val), (u8 *)(buf) + (pos)) +#define LSET(buf, pos, val) put_unaligned_le64((val), (u8 *)(buf) + (pos)) /* where to find the base of the SMB packet proper */ #define smb_base(buf) ((u8 *)(((u8 *)(buf))+4)) diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h index dfd8bf66ce2..d364fd594ea 100644 --- a/include/net/ieee80211_radiotap.h +++ b/include/net/ieee80211_radiotap.h @@ -262,7 +262,7 @@ static inline int ieee80211_get_radiotap_len(unsigned char *data) struct ieee80211_radiotap_header *hdr = (struct ieee80211_radiotap_header *)data; - return le16_to_cpu(get_unaligned(&hdr->it_len)); + return get_unaligned_le16(&hdr->it_len); } #endif /* IEEE80211_RADIOTAP_H */ -- cgit v1.2.3-70-g09d2 From 547b792cac0a038b9dbf958d3c120df3740b5572 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Fri, 25 Jul 2008 21:43:18 -0700 Subject: net: convert BUG_TRAP to generic WARN_ON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes legacy reinvent-the-wheel type thing. The generic machinery integrates much better to automated debugging aids such as kerneloops.org (and others), and is unambiguous due to better naming. Non-intuively BUG_TRAP() is actually equal to WARN_ON() rather than BUG_ON() though some might actually be promoted to BUG_ON() but I left that to future. I could make at least one BUILD_BUG_ON conversion. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/net/request_sock.h | 5 +++-- net/appletalk/ddp.c | 4 ++-- net/core/datagram.c | 8 ++++---- net/core/dev.c | 10 +++++----- net/core/request_sock.c | 2 +- net/core/skbuff.c | 20 ++++++++++---------- net/core/stream.c | 6 +++--- net/core/user_dma.c | 5 ++--- net/dccp/dccp.h | 2 +- net/dccp/input.c | 2 +- net/dccp/ipv4.c | 2 +- net/dccp/ipv6.c | 2 +- net/dccp/proto.c | 4 ++-- net/dccp/timer.c | 2 +- net/ipv4/af_inet.c | 14 +++++++------- net/ipv4/devinet.c | 6 +++--- net/ipv4/inet_connection_sock.c | 18 +++++++++--------- net/ipv4/inet_fragment.c | 4 ++-- net/ipv4/inet_hashtables.c | 8 ++++---- net/ipv4/inet_timewait_sock.c | 2 +- net/ipv4/ip_fragment.c | 4 ++-- net/ipv4/ip_output.c | 2 +- net/ipv4/tcp.c | 12 ++++++------ net/ipv4/tcp_input.c | 20 ++++++++++---------- net/ipv4/tcp_ipv4.c | 2 +- net/ipv4/tcp_timer.c | 2 +- net/ipv6/addrconf.c | 11 +++++++---- net/ipv6/af_inet6.c | 2 +- net/ipv6/inet6_connection_sock.c | 2 +- net/ipv6/inet6_hashtables.c | 4 ++-- net/ipv6/ip6_fib.c | 31 ++++++++++++++++--------------- net/ipv6/ip6_output.c | 2 +- net/ipv6/mip6.c | 8 ++++---- net/ipv6/netfilter/nf_conntrack_reasm.c | 4 ++-- net/ipv6/reassembly.c | 4 ++-- net/ipv6/tcp_ipv6.c | 2 +- net/key/af_key.c | 4 ++-- net/netlink/af_netlink.c | 7 ++++--- net/packet/af_packet.c | 4 ++-- net/rxrpc/af_rxrpc.c | 6 +++--- net/sched/act_api.c | 2 +- net/sched/act_police.c | 2 +- net/sched/cls_u32.c | 10 +++++----- net/sched/sch_cbq.c | 4 ++-- net/sched/sch_generic.c | 2 +- net/sched/sch_htb.c | 16 ++++++++-------- net/sctp/associola.c | 2 +- net/unix/af_unix.c | 8 ++++---- net/xfrm/xfrm_algo.c | 4 ++-- net/xfrm/xfrm_ipcomp.c | 3 +-- net/xfrm/xfrm_state.c | 2 +- 51 files changed, 159 insertions(+), 155 deletions(-) (limited to 'include/net') diff --git a/include/net/request_sock.h b/include/net/request_sock.h index 0c96e7bed5d..8d6e991ef4d 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -170,7 +171,7 @@ static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue { struct request_sock *req = queue->rskq_accept_head; - BUG_TRAP(req != NULL); + WARN_ON(req == NULL); queue->rskq_accept_head = req->dl_next; if (queue->rskq_accept_head == NULL) @@ -185,7 +186,7 @@ static inline struct sock *reqsk_queue_get_child(struct request_sock_queue *queu struct request_sock *req = reqsk_queue_remove(queue); struct sock *child = req->sk; - BUG_TRAP(child != NULL); + WARN_ON(child == NULL); sk_acceptq_removed(parent); __reqsk_free(req); diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 07b5b82c5ea..0c850427a85 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -959,7 +959,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -986,7 +986,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, for (; list; list = list->next) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; if ((copy = end - offset) > 0) { diff --git a/net/core/datagram.c b/net/core/datagram.c index 8a28fc93b72..dd61dcad601 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -285,7 +285,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -315,7 +315,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset, for (; list; list = list->next) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -366,7 +366,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -402,7 +402,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, for (; list; list=list->next) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; if ((copy = end - offset) > 0) { diff --git a/net/core/dev.c b/net/core/dev.c index ccf97f9f37e..c6f9c83745e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1973,7 +1973,7 @@ static void net_tx_action(struct softirq_action *h) struct sk_buff *skb = clist; clist = clist->next; - BUG_TRAP(!atomic_read(&skb->users)); + WARN_ON(atomic_read(&skb->users)); __kfree_skb(skb); } } @@ -3847,7 +3847,7 @@ static void rollback_registered(struct net_device *dev) dev->uninit(dev); /* Notifier chain MUST detach us from master device. */ - BUG_TRAP(!dev->master); + WARN_ON(dev->master); /* Remove entries from kobject tree */ netdev_unregister_kobject(dev); @@ -4169,9 +4169,9 @@ void netdev_run_todo(void) /* paranoia */ BUG_ON(atomic_read(&dev->refcnt)); - BUG_TRAP(!dev->ip_ptr); - BUG_TRAP(!dev->ip6_ptr); - BUG_TRAP(!dev->dn_ptr); + WARN_ON(dev->ip_ptr); + WARN_ON(dev->ip6_ptr); + WARN_ON(dev->dn_ptr); if (dev->destructor) dev->destructor(dev); diff --git a/net/core/request_sock.c b/net/core/request_sock.c index 2d3035d3abd..7552495aff7 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c @@ -123,7 +123,7 @@ void reqsk_queue_destroy(struct request_sock_queue *queue) } } - BUG_TRAP(lopt->qlen == 0); + WARN_ON(lopt->qlen != 0); if (lopt_size > PAGE_SIZE) vfree(lopt); else diff --git a/net/core/skbuff.c b/net/core/skbuff.c index e4115672b6c..4e0c9227418 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -1200,7 +1200,7 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -1229,7 +1229,7 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) for (; list; list = list->next) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -1475,7 +1475,7 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + frag->size; if ((copy = end - offset) > 0) { @@ -1503,7 +1503,7 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len) for (; list; list = list->next) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -1552,7 +1552,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -1581,7 +1581,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset, for (; list; list = list->next) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -1629,7 +1629,7 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -1662,7 +1662,7 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, __wsum csum2; int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; if ((copy = end - offset) > 0) { @@ -2373,7 +2373,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -2397,7 +2397,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len) for (; list; list = list->next) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; if ((copy = end - offset) > 0) { diff --git a/net/core/stream.c b/net/core/stream.c index 4a0ad152c9c..a6b3437ff08 100644 --- a/net/core/stream.c +++ b/net/core/stream.c @@ -192,13 +192,13 @@ void sk_stream_kill_queues(struct sock *sk) __skb_queue_purge(&sk->sk_error_queue); /* Next, the write queue. */ - BUG_TRAP(skb_queue_empty(&sk->sk_write_queue)); + WARN_ON(!skb_queue_empty(&sk->sk_write_queue)); /* Account for returned memory. */ sk_mem_reclaim(sk); - BUG_TRAP(!sk->sk_wmem_queued); - BUG_TRAP(!sk->sk_forward_alloc); + WARN_ON(sk->sk_wmem_queued); + WARN_ON(sk->sk_forward_alloc); /* It is _impossible_ for the backlog to contain anything * when we get here. All user references to this socket diff --git a/net/core/user_dma.c b/net/core/user_dma.c index c77aff9c6eb..53c6b67b287 100644 --- a/net/core/user_dma.c +++ b/net/core/user_dma.c @@ -27,7 +27,6 @@ #include #include -#include /* for BUG_TRAP */ #include #include @@ -71,7 +70,7 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + skb_shinfo(skb)->frags[i].size; copy = end - offset; @@ -100,7 +99,7 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan, for (; list; list = list->next) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; copy = end - offset; diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 32617e0576c..743d85fcd65 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -164,7 +164,7 @@ static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp) { s64 delta = dccp_delta_seqno(s1, s2); - BUG_TRAP(delta >= 0); + WARN_ON(delta < 0); return (u64)delta <= ndp + 1; } diff --git a/net/dccp/input.c b/net/dccp/input.c index 08392ed86c2..df2f110df94 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -413,7 +413,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, /* Stop the REQUEST timer */ inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); - BUG_TRAP(sk->sk_send_head != NULL); + WARN_ON(sk->sk_send_head == NULL); __kfree_skb(sk->sk_send_head); sk->sk_send_head = NULL; diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 2622ace17c4..a835b88237c 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -283,7 +283,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) * ICMPs are not backlogged, hence we cannot get an established * socket here. */ - BUG_TRAP(!req->sk); + WARN_ON(req->sk); if (seq != dccp_rsk(req)->dreq_iss) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index b74e8b2cbe5..da509127e00 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -186,7 +186,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, * ICMPs are not backlogged, hence we cannot get an established * socket here. */ - BUG_TRAP(req->sk == NULL); + WARN_ON(req->sk != NULL); if (seq != dccp_rsk(req)->dreq_iss) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); diff --git a/net/dccp/proto.c b/net/dccp/proto.c index a0b56009611..b622d974485 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -327,7 +327,7 @@ int dccp_disconnect(struct sock *sk, int flags) inet_csk_delack_init(sk); __sk_dst_reset(sk); - BUG_TRAP(!inet->num || icsk->icsk_bind_hash); + WARN_ON(inet->num && !icsk->icsk_bind_hash); sk->sk_error_report(sk); return err; @@ -981,7 +981,7 @@ adjudge_to_death: */ local_bh_disable(); bh_lock_sock(sk); - BUG_TRAP(!sock_owned_by_user(sk)); + WARN_ON(sock_owned_by_user(sk)); /* Have we already been destroyed by a softirq or backlog? */ if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED) diff --git a/net/dccp/timer.c b/net/dccp/timer.c index 3608d5342ca..6a5b961b6f5 100644 --- a/net/dccp/timer.c +++ b/net/dccp/timer.c @@ -106,7 +106,7 @@ static void dccp_retransmit_timer(struct sock *sk) * -- Acks in client-PARTOPEN state (sec. 8.1.5) * -- CloseReq in server-CLOSEREQ state (sec. 8.3) * -- Close in node-CLOSING state (sec. 8.3) */ - BUG_TRAP(sk->sk_send_head != NULL); + WARN_ON(sk->sk_send_head == NULL); /* * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index dd919d84285..a107f49eea4 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -148,10 +148,10 @@ void inet_sock_destruct(struct sock *sk) return; } - BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); - BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); - BUG_TRAP(!sk->sk_wmem_queued); - BUG_TRAP(!sk->sk_forward_alloc); + WARN_ON(atomic_read(&sk->sk_rmem_alloc)); + WARN_ON(atomic_read(&sk->sk_wmem_alloc)); + WARN_ON(sk->sk_wmem_queued); + WARN_ON(sk->sk_forward_alloc); kfree(inet->opt); dst_release(sk->sk_dst_cache); @@ -341,7 +341,7 @@ lookup_protocol: answer_flags = answer->flags; rcu_read_unlock(); - BUG_TRAP(answer_prot->slab != NULL); + WARN_ON(answer_prot->slab == NULL); err = -ENOBUFS; sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot); @@ -661,8 +661,8 @@ int inet_accept(struct socket *sock, struct socket *newsock, int flags) lock_sock(sk2); - BUG_TRAP((1 << sk2->sk_state) & - (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE)); + WARN_ON(!((1 << sk2->sk_state) & + (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT | TCPF_CLOSE))); sock_graft(sk2, newsock); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 2e667e2f90d..91d3d96805d 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -138,8 +138,8 @@ void in_dev_finish_destroy(struct in_device *idev) { struct net_device *dev = idev->dev; - BUG_TRAP(!idev->ifa_list); - BUG_TRAP(!idev->mc_list); + WARN_ON(idev->ifa_list); + WARN_ON(idev->mc_list); #ifdef NET_REFCNT_DEBUG printk(KERN_DEBUG "in_dev_finish_destroy: %p=%s\n", idev, dev ? dev->name : "NIL"); @@ -399,7 +399,7 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa) } ipv4_devconf_setall(in_dev); if (ifa->ifa_dev != in_dev) { - BUG_TRAP(!ifa->ifa_dev); + WARN_ON(ifa->ifa_dev); in_dev_hold(in_dev); ifa->ifa_dev = in_dev; } diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index bb81c958b74..0c1ae68ee84 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -167,7 +167,7 @@ tb_not_found: success: if (!inet_csk(sk)->icsk_bind_hash) inet_bind_hash(sk, tb, snum); - BUG_TRAP(inet_csk(sk)->icsk_bind_hash == tb); + WARN_ON(inet_csk(sk)->icsk_bind_hash != tb); ret = 0; fail_unlock: @@ -260,7 +260,7 @@ struct sock *inet_csk_accept(struct sock *sk, int flags, int *err) } newsk = reqsk_queue_get_child(&icsk->icsk_accept_queue, sk); - BUG_TRAP(newsk->sk_state != TCP_SYN_RECV); + WARN_ON(newsk->sk_state == TCP_SYN_RECV); out: release_sock(sk); return newsk; @@ -386,7 +386,7 @@ struct request_sock *inet_csk_search_req(const struct sock *sk, ireq->rmt_addr == raddr && ireq->loc_addr == laddr && AF_INET_FAMILY(req->rsk_ops->family)) { - BUG_TRAP(!req->sk); + WARN_ON(req->sk); *prevp = prev; break; } @@ -539,14 +539,14 @@ EXPORT_SYMBOL_GPL(inet_csk_clone); */ void inet_csk_destroy_sock(struct sock *sk) { - BUG_TRAP(sk->sk_state == TCP_CLOSE); - BUG_TRAP(sock_flag(sk, SOCK_DEAD)); + WARN_ON(sk->sk_state != TCP_CLOSE); + WARN_ON(!sock_flag(sk, SOCK_DEAD)); /* It cannot be in hash table! */ - BUG_TRAP(sk_unhashed(sk)); + WARN_ON(!sk_unhashed(sk)); /* If it has not 0 inet_sk(sk)->num, it must be bound */ - BUG_TRAP(!inet_sk(sk)->num || inet_csk(sk)->icsk_bind_hash); + WARN_ON(inet_sk(sk)->num && !inet_csk(sk)->icsk_bind_hash); sk->sk_prot->destroy(sk); @@ -629,7 +629,7 @@ void inet_csk_listen_stop(struct sock *sk) local_bh_disable(); bh_lock_sock(child); - BUG_TRAP(!sock_owned_by_user(child)); + WARN_ON(sock_owned_by_user(child)); sock_hold(child); sk->sk_prot->disconnect(child, O_NONBLOCK); @@ -647,7 +647,7 @@ void inet_csk_listen_stop(struct sock *sk) sk_acceptq_removed(sk); __reqsk_free(req); } - BUG_TRAP(!sk->sk_ack_backlog); + WARN_ON(sk->sk_ack_backlog); } EXPORT_SYMBOL_GPL(inet_csk_listen_stop); diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 0546a0bc97e..6c52e08f786 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c @@ -134,8 +134,8 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f, struct sk_buff *fp; struct netns_frags *nf; - BUG_TRAP(q->last_in & INET_FRAG_COMPLETE); - BUG_TRAP(del_timer(&q->timer) == 0); + WARN_ON(!(q->last_in & INET_FRAG_COMPLETE)); + WARN_ON(del_timer(&q->timer) != 0); /* Release all fragment data. */ fp = q->fragments; diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 115f53722d2..44981906fb9 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -305,7 +305,7 @@ unique: inet->num = lport; inet->sport = htons(lport); sk->sk_hash = hash; - BUG_TRAP(sk_unhashed(sk)); + WARN_ON(!sk_unhashed(sk)); __sk_add_node(sk, &head->chain); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); write_unlock(lock); @@ -342,7 +342,7 @@ void __inet_hash_nolisten(struct sock *sk) rwlock_t *lock; struct inet_ehash_bucket *head; - BUG_TRAP(sk_unhashed(sk)); + WARN_ON(!sk_unhashed(sk)); sk->sk_hash = inet_sk_ehashfn(sk); head = inet_ehash_bucket(hashinfo, sk->sk_hash); @@ -367,7 +367,7 @@ static void __inet_hash(struct sock *sk) return; } - BUG_TRAP(sk_unhashed(sk)); + WARN_ON(!sk_unhashed(sk)); list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; lock = &hashinfo->lhash_lock; @@ -450,7 +450,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, */ inet_bind_bucket_for_each(tb, node, &head->chain) { if (tb->ib_net == net && tb->port == port) { - BUG_TRAP(!hlist_empty(&tb->owners)); + WARN_ON(hlist_empty(&tb->owners)); if (tb->fastreuse >= 0) goto next_port; if (!check_established(death_row, sk, diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index 75c2def8f9a..d985bd613d2 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c @@ -86,7 +86,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, hashinfo->bhash_size)]; spin_lock(&bhead->lock); tw->tw_tb = icsk->icsk_bind_hash; - BUG_TRAP(icsk->icsk_bind_hash); + WARN_ON(!icsk->icsk_bind_hash); inet_twsk_add_bind_node(tw, &tw->tw_tb->owners); spin_unlock(&bhead->lock); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 38d38f05801..2152d222b95 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -488,8 +488,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, qp->q.fragments = head; } - BUG_TRAP(head != NULL); - BUG_TRAP(FRAG_CB(head)->offset == 0); + WARN_ON(head == NULL); + WARN_ON(FRAG_CB(head)->offset != 0); /* Allocate a new buffer for the datagram. */ ihlen = ip_hdrlen(head); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 465544f6281..d533a89e08d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -118,7 +118,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) __skb_pull(newskb, skb_network_offset(newskb)); newskb->pkt_type = PACKET_LOOPBACK; newskb->ip_summed = CHECKSUM_UNNECESSARY; - BUG_TRAP(newskb->dst); + WARN_ON(!newskb->dst); netif_rx(newskb); return 0; } diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0b491bf03db..1ab341e5d3e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1096,7 +1096,7 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied) #if TCP_DEBUG struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); - BUG_TRAP(!skb || before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); + WARN_ON(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)); #endif if (inet_csk_ack_scheduled(sk)) { @@ -1358,7 +1358,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, goto found_ok_skb; if (tcp_hdr(skb)->fin) goto found_fin_ok; - BUG_TRAP(flags & MSG_PEEK); + WARN_ON(!(flags & MSG_PEEK)); skb = skb->next; } while (skb != (struct sk_buff *)&sk->sk_receive_queue); @@ -1421,8 +1421,8 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, tp->ucopy.len = len; - BUG_TRAP(tp->copied_seq == tp->rcv_nxt || - (flags & (MSG_PEEK | MSG_TRUNC))); + WARN_ON(tp->copied_seq != tp->rcv_nxt && + !(flags & (MSG_PEEK | MSG_TRUNC))); /* Ugly... If prequeue is not empty, we have to * process it before releasing socket, otherwise @@ -1844,7 +1844,7 @@ adjudge_to_death: */ local_bh_disable(); bh_lock_sock(sk); - BUG_TRAP(!sock_owned_by_user(sk)); + WARN_ON(sock_owned_by_user(sk)); /* Have we already been destroyed by a softirq or backlog? */ if (state != TCP_CLOSE && sk->sk_state == TCP_CLOSE) @@ -1973,7 +1973,7 @@ int tcp_disconnect(struct sock *sk, int flags) memset(&tp->rx_opt, 0, sizeof(tp->rx_opt)); __sk_dst_reset(sk); - BUG_TRAP(!inet->num || icsk->icsk_bind_hash); + WARN_ON(inet->num && !icsk->icsk_bind_hash); sk->sk_error_report(sk); return err; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 75efd244f2a..67ccce2a96b 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1629,10 +1629,10 @@ advance_sp: out: #if FASTRETRANS_DEBUG > 0 - BUG_TRAP((int)tp->sacked_out >= 0); - BUG_TRAP((int)tp->lost_out >= 0); - BUG_TRAP((int)tp->retrans_out >= 0); - BUG_TRAP((int)tcp_packets_in_flight(tp) >= 0); + WARN_ON((int)tp->sacked_out < 0); + WARN_ON((int)tp->lost_out < 0); + WARN_ON((int)tp->retrans_out < 0); + WARN_ON((int)tcp_packets_in_flight(tp) < 0); #endif return flag; } @@ -2181,7 +2181,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) int err; unsigned int mss; - BUG_TRAP(packets <= tp->packets_out); + WARN_ON(packets > tp->packets_out); if (tp->lost_skb_hint) { skb = tp->lost_skb_hint; cnt = tp->lost_cnt_hint; @@ -2610,7 +2610,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) /* E. Check state exit conditions. State can be terminated * when high_seq is ACKed. */ if (icsk->icsk_ca_state == TCP_CA_Open) { - BUG_TRAP(tp->retrans_out == 0); + WARN_ON(tp->retrans_out != 0); tp->retrans_stamp = 0; } else if (!before(tp->snd_una, tp->high_seq)) { switch (icsk->icsk_ca_state) { @@ -2972,9 +2972,9 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets) } #if FASTRETRANS_DEBUG > 0 - BUG_TRAP((int)tp->sacked_out >= 0); - BUG_TRAP((int)tp->lost_out >= 0); - BUG_TRAP((int)tp->retrans_out >= 0); + WARN_ON((int)tp->sacked_out < 0); + WARN_ON((int)tp->lost_out < 0); + WARN_ON((int)tp->retrans_out < 0); if (!tp->packets_out && tcp_is_sack(tp)) { icsk = inet_csk(sk); if (tp->lost_out) { @@ -3877,7 +3877,7 @@ static void tcp_sack_remove(struct tcp_sock *tp) int i; /* RCV.NXT must cover all the block! */ - BUG_TRAP(!before(tp->rcv_nxt, sp->end_seq)); + WARN_ON(before(tp->rcv_nxt, sp->end_seq)); /* Zap this SACK, by moving forward any other SACKS. */ for (i=this_sack+1; i < num_sacks; i++) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index a82df630756..a2b06d0cc26 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -418,7 +418,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) /* ICMPs are not backlogged, hence we cannot get an established socket here. */ - BUG_TRAP(!req->sk); + WARN_ON(req->sk); if (seq != tcp_rsk(req)->snt_isn) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 328e0cf42b3..5ab6ba19c3c 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -287,7 +287,7 @@ static void tcp_retransmit_timer(struct sock *sk) if (!tp->packets_out) goto out; - BUG_TRAP(!tcp_write_queue_empty(sk)); + WARN_ON(tcp_write_queue_empty(sk)); if (!tp->snd_wnd && !sock_flag(sk, SOCK_DEAD) && !((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV))) { diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 74d543d504a..a7842c54f58 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -313,8 +313,10 @@ static void in6_dev_finish_destroy_rcu(struct rcu_head *head) void in6_dev_finish_destroy(struct inet6_dev *idev) { struct net_device *dev = idev->dev; - BUG_TRAP(idev->addr_list==NULL); - BUG_TRAP(idev->mc_list==NULL); + + WARN_ON(idev->addr_list != NULL); + WARN_ON(idev->mc_list != NULL); + #ifdef NET_REFCNT_DEBUG printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL"); #endif @@ -517,8 +519,9 @@ static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) { - BUG_TRAP(ifp->if_next==NULL); - BUG_TRAP(ifp->lst_next==NULL); + WARN_ON(ifp->if_next != NULL); + WARN_ON(ifp->lst_next != NULL); + #ifdef NET_REFCNT_DEBUG printk(KERN_DEBUG "inet6_ifa_finish_destroy\n"); #endif diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3d828bc4b1c..0843c4d6218 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -153,7 +153,7 @@ lookup_protocol: answer_flags = answer->flags; rcu_read_unlock(); - BUG_TRAP(answer_prot->slab != NULL); + WARN_ON(answer_prot->slab == NULL); err = -ENOBUFS; sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot); diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 87801cc1b2f..16d43f20b32 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -98,7 +98,7 @@ struct request_sock *inet6_csk_search_req(const struct sock *sk, ipv6_addr_equal(&treq->rmt_addr, raddr) && ipv6_addr_equal(&treq->loc_addr, laddr) && (!treq->iif || treq->iif == iif)) { - BUG_TRAP(req->sk == NULL); + WARN_ON(req->sk != NULL); *prevp = prev; return req; } diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 00a8a5f9380..1646a565825 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -28,7 +28,7 @@ void __inet6_hash(struct sock *sk) struct hlist_head *list; rwlock_t *lock; - BUG_TRAP(sk_unhashed(sk)); + WARN_ON(!sk_unhashed(sk)); if (sk->sk_state == TCP_LISTEN) { list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; @@ -202,7 +202,7 @@ unique: * in hash table socket with a funny identity. */ inet->num = lport; inet->sport = htons(lport); - BUG_TRAP(sk_unhashed(sk)); + WARN_ON(!sk_unhashed(sk)); __sk_add_node(sk, &head->chain); sk->sk_hash = hash; sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 08ea2de28d6..52dddc25d3e 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -287,7 +287,7 @@ static int fib6_dump_node(struct fib6_walker_t *w) w->leaf = rt; return 1; } - BUG_TRAP(res!=0); + WARN_ON(res == 0); } w->leaf = NULL; return 0; @@ -778,7 +778,7 @@ out: pn->leaf = fib6_find_prefix(info->nl_net, pn); #if RT6_DEBUG >= 2 if (!pn->leaf) { - BUG_TRAP(pn->leaf != NULL); + WARN_ON(pn->leaf == NULL); pn->leaf = info->nl_net->ipv6.ip6_null_entry; } #endif @@ -942,7 +942,7 @@ struct fib6_node * fib6_locate(struct fib6_node *root, #ifdef CONFIG_IPV6_SUBTREES if (src_len) { - BUG_TRAP(saddr!=NULL); + WARN_ON(saddr == NULL); if (fn && fn->subtree) fn = fib6_locate_1(fn->subtree, saddr, src_len, offsetof(struct rt6_info, rt6i_src)); @@ -996,9 +996,9 @@ static struct fib6_node *fib6_repair_tree(struct net *net, RT6_TRACE("fixing tree: plen=%d iter=%d\n", fn->fn_bit, iter); iter++; - BUG_TRAP(!(fn->fn_flags&RTN_RTINFO)); - BUG_TRAP(!(fn->fn_flags&RTN_TL_ROOT)); - BUG_TRAP(fn->leaf==NULL); + WARN_ON(fn->fn_flags & RTN_RTINFO); + WARN_ON(fn->fn_flags & RTN_TL_ROOT); + WARN_ON(fn->leaf != NULL); children = 0; child = NULL; @@ -1014,7 +1014,7 @@ static struct fib6_node *fib6_repair_tree(struct net *net, fn->leaf = fib6_find_prefix(net, fn); #if RT6_DEBUG >= 2 if (fn->leaf==NULL) { - BUG_TRAP(fn->leaf); + WARN_ON(!fn->leaf); fn->leaf = net->ipv6.ip6_null_entry; } #endif @@ -1025,16 +1025,17 @@ static struct fib6_node *fib6_repair_tree(struct net *net, pn = fn->parent; #ifdef CONFIG_IPV6_SUBTREES if (FIB6_SUBTREE(pn) == fn) { - BUG_TRAP(fn->fn_flags&RTN_ROOT); + WARN_ON(!(fn->fn_flags & RTN_ROOT)); FIB6_SUBTREE(pn) = NULL; nstate = FWS_L; } else { - BUG_TRAP(!(fn->fn_flags&RTN_ROOT)); + WARN_ON(fn->fn_flags & RTN_ROOT); #endif if (pn->right == fn) pn->right = child; else if (pn->left == fn) pn->left = child; #if RT6_DEBUG >= 2 - else BUG_TRAP(0); + else + WARN_ON(1); #endif if (child) child->parent = pn; @@ -1154,14 +1155,14 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info) #if RT6_DEBUG >= 2 if (rt->u.dst.obsolete>0) { - BUG_TRAP(fn==NULL); + WARN_ON(fn != NULL); return -ENOENT; } #endif if (fn == NULL || rt == net->ipv6.ip6_null_entry) return -ENOENT; - BUG_TRAP(fn->fn_flags&RTN_RTINFO); + WARN_ON(!(fn->fn_flags & RTN_RTINFO)); if (!(rt->rt6i_flags&RTF_CACHE)) { struct fib6_node *pn = fn; @@ -1266,7 +1267,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) w->node = pn; #ifdef CONFIG_IPV6_SUBTREES if (FIB6_SUBTREE(pn) == fn) { - BUG_TRAP(fn->fn_flags&RTN_ROOT); + WARN_ON(!(fn->fn_flags & RTN_ROOT)); w->state = FWS_L; continue; } @@ -1281,7 +1282,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) continue; } #if RT6_DEBUG >= 2 - BUG_TRAP(0); + WARN_ON(1); #endif } } @@ -1323,7 +1324,7 @@ static int fib6_clean_node(struct fib6_walker_t *w) } return 0; } - BUG_TRAP(res==0); + WARN_ON(res != 0); } w->leaf = rt; return 0; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 6407c64ea4a..6811901e6b1 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -116,7 +116,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb) __skb_pull(newskb, skb_network_offset(newskb)); newskb->pkt_type = PACKET_LOOPBACK; newskb->ip_summed = CHECKSUM_UNNECESSARY; - BUG_TRAP(newskb->dst); + WARN_ON(!newskb->dst); netif_rx(newskb); return 0; diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c index ad1cc5bbf97..31295c8f619 100644 --- a/net/ipv6/mip6.c +++ b/net/ipv6/mip6.c @@ -164,8 +164,8 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb) calc_padlen(sizeof(*dstopt), 6)); hao->type = IPV6_TLV_HAO; + BUILD_BUG_ON(sizeof(*hao) != 18); hao->length = sizeof(*hao) - 2; - BUG_TRAP(hao->length == 16); len = ((char *)hao - (char *)dstopt) + sizeof(*hao); @@ -174,7 +174,7 @@ static int mip6_destopt_output(struct xfrm_state *x, struct sk_buff *skb) memcpy(&iph->saddr, x->coaddr, sizeof(iph->saddr)); spin_unlock_bh(&x->lock); - BUG_TRAP(len == x->props.header_len); + WARN_ON(len != x->props.header_len); dstopt->hdrlen = (x->props.header_len >> 3) - 1; return 0; @@ -317,7 +317,7 @@ static int mip6_destopt_init_state(struct xfrm_state *x) x->props.header_len = sizeof(struct ipv6_destopt_hdr) + calc_padlen(sizeof(struct ipv6_destopt_hdr), 6) + sizeof(struct ipv6_destopt_hao); - BUG_TRAP(x->props.header_len == 24); + WARN_ON(x->props.header_len != 24); return 0; } @@ -380,7 +380,7 @@ static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb) rt2->rt_hdr.segments_left = 1; memset(&rt2->reserved, 0, sizeof(rt2->reserved)); - BUG_TRAP(rt2->rt_hdr.hdrlen == 2); + WARN_ON(rt2->rt_hdr.hdrlen != 2); memcpy(&rt2->addr, &iph->daddr, sizeof(rt2->addr)); spin_lock_bh(&x->lock); diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index cf20bc4fd60..52d06dd4b81 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -416,8 +416,8 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) fq_kill(fq); - BUG_TRAP(head != NULL); - BUG_TRAP(NFCT_FRAG6_CB(head)->offset == 0); + WARN_ON(head == NULL); + WARN_ON(NFCT_FRAG6_CB(head)->offset != 0); /* Unfragmented part is taken from the first segment. */ payload_len = ((head->data - skb_network_header(head)) - diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 6ab957ec2dd..89184b576e2 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -473,8 +473,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, fq->q.fragments = head; } - BUG_TRAP(head != NULL); - BUG_TRAP(FRAG6_CB(head)->offset == 0); + WARN_ON(head == NULL); + WARN_ON(FRAG6_CB(head)->offset != 0); /* Unfragmented part is taken from the first segment. */ payload_len = ((head->data - skb_network_header(head)) - diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index ae45f983501..cff778b23a7 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -421,7 +421,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, /* ICMPs are not backlogged, hence we cannot get * an established socket here. */ - BUG_TRAP(req->sk == NULL); + WARN_ON(req->sk != NULL); if (seq != tcp_rsk(req)->snt_isn) { NET_INC_STATS_BH(net, LINUX_MIB_OUTOFWINDOWICMPS); diff --git a/net/key/af_key.c b/net/key/af_key.c index f0fc46c8038..d628df97e02 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -96,8 +96,8 @@ static void pfkey_sock_destruct(struct sock *sk) return; } - BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); - BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); + WARN_ON(atomic_read(&sk->sk_rmem_alloc)); + WARN_ON(atomic_read(&sk->sk_wmem_alloc)); atomic_dec(&pfkey_socks_nr); } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 98bfe277eab..b0eacc0007c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -158,9 +158,10 @@ static void netlink_sock_destruct(struct sock *sk) printk(KERN_ERR "Freeing alive netlink socket %p\n", sk); return; } - BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); - BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); - BUG_TRAP(!nlk_sk(sk)->groups); + + WARN_ON(atomic_read(&sk->sk_rmem_alloc)); + WARN_ON(atomic_read(&sk->sk_wmem_alloc)); + WARN_ON(nlk_sk(sk)->groups); } /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index d56cae112dc..c718e7e3f7d 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -260,8 +260,8 @@ static inline struct packet_sock *pkt_sk(struct sock *sk) static void packet_sock_destruct(struct sock *sk) { - BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); - BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); + WARN_ON(atomic_read(&sk->sk_rmem_alloc)); + WARN_ON(atomic_read(&sk->sk_wmem_alloc)); if (!sock_flag(sk, SOCK_DEAD)) { printk("Attempt to release alive packet socket: %p\n", sk); diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 4b2682feeed..32e489118be 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -660,9 +660,9 @@ static void rxrpc_sock_destructor(struct sock *sk) rxrpc_purge_queue(&sk->sk_receive_queue); - BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); - BUG_TRAP(sk_unhashed(sk)); - BUG_TRAP(!sk->sk_socket); + WARN_ON(atomic_read(&sk->sk_wmem_alloc)); + WARN_ON(!sk_unhashed(sk)); + WARN_ON(sk->sk_socket); if (!sock_flag(sk, SOCK_DEAD)) { printk("Attempt to release alive rxrpc socket: %p\n", sk); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 74e662cbb2c..d308c19aa3f 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -41,7 +41,7 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) return; } } - BUG_TRAP(0); + WARN_ON(1); } EXPORT_SYMBOL(tcf_hash_destroy); diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 32c3f9d9fb7..38015b49394 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -116,7 +116,7 @@ static void tcf_police_destroy(struct tcf_police *p) return; } } - BUG_TRAP(0); + WARN_ON(1); } static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = { diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 527db2559dd..246f9065ce3 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -345,7 +345,7 @@ static int u32_delete_key(struct tcf_proto *tp, struct tc_u_knode* key) } } } - BUG_TRAP(0); + WARN_ON(1); return 0; } @@ -368,7 +368,7 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht) struct tc_u_common *tp_c = tp->data; struct tc_u_hnode **hn; - BUG_TRAP(!ht->refcnt); + WARN_ON(ht->refcnt); u32_clear_hnode(tp, ht); @@ -380,7 +380,7 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht) } } - BUG_TRAP(0); + WARN_ON(1); return -ENOENT; } @@ -389,7 +389,7 @@ static void u32_destroy(struct tcf_proto *tp) struct tc_u_common *tp_c = tp->data; struct tc_u_hnode *root_ht = xchg(&tp->root, NULL); - BUG_TRAP(root_ht != NULL); + WARN_ON(root_ht == NULL); if (root_ht && --root_ht->refcnt == 0) u32_destroy_hnode(tp, root_ht); @@ -407,7 +407,7 @@ static void u32_destroy(struct tcf_proto *tp) while ((ht = tp_c->hlist) != NULL) { tp_c->hlist = ht->next; - BUG_TRAP(ht->refcnt == 0); + WARN_ON(ht->refcnt != 0); kfree(ht); } diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index f1d2f8ec8b4..14954bf4a68 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1175,7 +1175,7 @@ static void cbq_unlink_class(struct cbq_class *this) this->tparent->children = NULL; } } else { - BUG_TRAP(this->sibling == this); + WARN_ON(this->sibling != this); } } @@ -1699,7 +1699,7 @@ static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) { struct cbq_sched_data *q = qdisc_priv(sch); - BUG_TRAP(!cl->filters); + WARN_ON(cl->filters); tcf_destroy_chain(&cl->filter_list); qdisc_destroy(cl->q); diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 43abd4d27ea..fd2a6cadb11 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -746,5 +746,5 @@ void dev_shutdown(struct net_device *dev) { netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); shutdown_scheduler_queue(dev, &dev->rx_queue, NULL); - BUG_TRAP(!timer_pending(&dev->watchdog_timer)); + WARN_ON(timer_pending(&dev->watchdog_timer)); } diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 30c999c61b0..75a40951c4f 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -524,7 +524,7 @@ htb_change_class_mode(struct htb_sched *q, struct htb_class *cl, long *diff) */ static inline void htb_activate(struct htb_sched *q, struct htb_class *cl) { - BUG_TRAP(!cl->level && cl->un.leaf.q && cl->un.leaf.q->q.qlen); + WARN_ON(cl->level || !cl->un.leaf.q || !cl->un.leaf.q->q.qlen); if (!cl->prio_activity) { cl->prio_activity = 1 << (cl->un.leaf.aprio = cl->un.leaf.prio); @@ -542,7 +542,7 @@ static inline void htb_activate(struct htb_sched *q, struct htb_class *cl) */ static inline void htb_deactivate(struct htb_sched *q, struct htb_class *cl) { - BUG_TRAP(cl->prio_activity); + WARN_ON(!cl->prio_activity); htb_deactivate_prios(q, cl); cl->prio_activity = 0; @@ -757,7 +757,7 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio, u32 *pid; } stk[TC_HTB_MAXDEPTH], *sp = stk; - BUG_TRAP(tree->rb_node); + WARN_ON(!tree->rb_node); sp->root = tree->rb_node; sp->pptr = pptr; sp->pid = pid; @@ -777,7 +777,7 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio, *sp->pptr = (*sp->pptr)->rb_left; if (sp > stk) { sp--; - BUG_TRAP(*sp->pptr); + WARN_ON(!*sp->pptr); if (!*sp->pptr) return NULL; htb_next_rb_node(sp->pptr); @@ -792,7 +792,7 @@ static struct htb_class *htb_lookup_leaf(struct rb_root *tree, int prio, sp->pid = cl->un.inner.last_ptr_id + prio; } } - BUG_TRAP(0); + WARN_ON(1); return NULL; } @@ -810,7 +810,7 @@ static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, int prio, do { next: - BUG_TRAP(cl); + WARN_ON(!cl); if (!cl) return NULL; @@ -1185,7 +1185,7 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl, { struct htb_class *parent = cl->parent; - BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity); + WARN_ON(cl->level || !cl->un.leaf.q || cl->prio_activity); if (parent->cmode != HTB_CAN_SEND) htb_safe_rb_erase(&parent->pq_node, q->wait_pq + parent->level); @@ -1205,7 +1205,7 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl, static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) { if (!cl->level) { - BUG_TRAP(cl->un.leaf.q); + WARN_ON(!cl->un.leaf.q); qdisc_destroy(cl->un.leaf.q); } gen_kill_estimator(&cl->bstats, &cl->rate_est); diff --git a/net/sctp/associola.c b/net/sctp/associola.c index ec2a0a33fd7..8472b8b349c 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -464,7 +464,7 @@ static void sctp_association_destroy(struct sctp_association *asoc) spin_unlock_bh(&sctp_assocs_id_lock); } - BUG_TRAP(!atomic_read(&asoc->rmem_alloc)); + WARN_ON(atomic_read(&asoc->rmem_alloc)); if (asoc->base.malloced) { kfree(asoc); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 70ceb1604ad..24eb214581d 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -227,7 +227,7 @@ static void __unix_remove_socket(struct sock *sk) static void __unix_insert_socket(struct hlist_head *list, struct sock *sk) { - BUG_TRAP(sk_unhashed(sk)); + WARN_ON(!sk_unhashed(sk)); sk_add_node(sk, list); } @@ -350,9 +350,9 @@ static void unix_sock_destructor(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); - BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); - BUG_TRAP(sk_unhashed(sk)); - BUG_TRAP(!sk->sk_socket); + WARN_ON(atomic_read(&sk->sk_wmem_alloc)); + WARN_ON(!sk_unhashed(sk)); + WARN_ON(sk->sk_socket); if (!sock_flag(sk, SOCK_DEAD)) { printk("Attempt to release alive unix socket: %p\n", sk); return; diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 23a2cc04b8c..96036cf2216 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c @@ -718,7 +718,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + skb_shinfo(skb)->frags[i].size; if ((copy = end - offset) > 0) { @@ -748,7 +748,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, for (; list; list = list->next) { int end; - BUG_TRAP(start <= offset + len); + WARN_ON(start > offset + len); end = start + list->len; if ((copy = end - offset) > 0) { diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c index 800f669083f..c609a4b98e1 100644 --- a/net/xfrm/xfrm_ipcomp.c +++ b/net/xfrm/xfrm_ipcomp.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -251,7 +250,7 @@ static void ipcomp_free_tfms(struct crypto_comp **tfms) break; } - BUG_TRAP(pos); + WARN_ON(!pos); if (--pos->users) return; diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 72fddafd891..4c6914ef7d9 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -538,7 +538,7 @@ EXPORT_SYMBOL(xfrm_state_alloc); void __xfrm_state_destroy(struct xfrm_state *x) { - BUG_TRAP(x->km.state == XFRM_STATE_DEAD); + WARN_ON(x->km.state != XFRM_STATE_DEAD); spin_lock_bh(&xfrm_state_lock); list_del(&x->all); -- cgit v1.2.3-70-g09d2 From 734550921e9b7ab924a43aa3d0bd4239dac4fbf1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 14 Jul 2008 21:22:20 -0400 Subject: [PATCH] beginning of sysctl cleanup - ctl_table_set New object: set of sysctls [currently - root and per-net-ns]. Contains: pointer to parent set, list of tables and "should I see this set?" method (->is_seen(set)). Current lists of tables are subsumed by that; net-ns contains such a beast. ->lookup() for ctl_table_root returns pointer to ctl_table_set instead of that to ->list of that ctl_table_set. [folded compile fixes by rdd for configs without sysctl] Signed-off-by: Al Viro --- include/linux/sysctl.h | 15 +++++++++++++-- include/net/net_namespace.h | 4 +++- kernel/sysctl.c | 41 +++++++++++++++++++++++++++++++---------- net/sysctl_net.c | 22 ++++++++++------------ 4 files changed, 57 insertions(+), 25 deletions(-) (limited to 'include/net') diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 24141b4d1a1..c1e0cf408af 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -947,6 +947,16 @@ struct ctl_table; struct nsproxy; struct ctl_table_root; +struct ctl_table_set { + struct list_head list; + struct ctl_table_set *parent; + int (*is_seen)(struct ctl_table_set *); +}; + +extern void setup_sysctl_set(struct ctl_table_set *p, + struct ctl_table_set *parent, + int (*is_seen)(struct ctl_table_set *)); + extern struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev); extern struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces, struct ctl_table_header *prev); @@ -1049,8 +1059,8 @@ struct ctl_table struct ctl_table_root { struct list_head root_list; - struct list_head header_list; - struct list_head *(*lookup)(struct ctl_table_root *root, + struct ctl_table_set default_set; + struct ctl_table_set *(*lookup)(struct ctl_table_root *root, struct nsproxy *namespaces); int (*permissions)(struct ctl_table_root *root, struct nsproxy *namespaces, struct ctl_table *table); @@ -1066,6 +1076,7 @@ struct ctl_table_header struct completion *unregistering; struct ctl_table *ctl_table_arg; struct ctl_table_root *root; + struct ctl_table_set *set; }; /* struct ctl_path describes where in the hierarchy a table is added */ diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 3855620b78a..a8eb43cf0c7 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -38,7 +38,9 @@ struct net { struct proc_dir_entry *proc_net; struct proc_dir_entry *proc_net_stat; - struct list_head sysctl_table_headers; +#ifdef CONFIG_SYSCTL + struct ctl_table_set sysctls; +#endif struct net_device *loopback_dev; /* The loopback */ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 35a50db9b6c..8ee4a0619fb 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -160,12 +160,13 @@ static struct ctl_table root_table[]; static struct ctl_table_root sysctl_table_root; static struct ctl_table_header root_table_header = { .ctl_table = root_table, - .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.header_list), + .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list), .root = &sysctl_table_root, + .set = &sysctl_table_root.default_set, }; static struct ctl_table_root sysctl_table_root = { .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list), - .header_list = LIST_HEAD_INIT(root_table_header.ctl_entry), + .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry), }; static struct ctl_table kern_table[]; @@ -1403,14 +1404,20 @@ void sysctl_head_finish(struct ctl_table_header *head) spin_unlock(&sysctl_lock); } +static struct ctl_table_set * +lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces) +{ + struct ctl_table_set *set = &root->default_set; + if (root->lookup) + set = root->lookup(root, namespaces); + return set; +} + static struct list_head * lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces) { - struct list_head *header_list; - header_list = &root->header_list; - if (root->lookup) - header_list = root->lookup(root, namespaces); - return header_list; + struct ctl_table_set *set = lookup_header_set(root, namespaces); + return &set->list; } struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces, @@ -1720,7 +1727,6 @@ struct ctl_table_header *__register_sysctl_paths( struct nsproxy *namespaces, const struct ctl_path *path, struct ctl_table *table) { - struct list_head *header_list; struct ctl_table_header *header; struct ctl_table *new, **prevp; unsigned int n, npath; @@ -1772,8 +1778,8 @@ struct ctl_table_header *__register_sysctl_paths( } #endif spin_lock(&sysctl_lock); - header_list = lookup_header_list(root, namespaces); - list_add_tail(&header->ctl_entry, header_list); + header->set = lookup_header_set(root, namespaces); + list_add_tail(&header->ctl_entry, &header->set->list); spin_unlock(&sysctl_lock); return header; @@ -1832,6 +1838,15 @@ void unregister_sysctl_table(struct ctl_table_header * header) kfree(header); } +void setup_sysctl_set(struct ctl_table_set *p, + struct ctl_table_set *parent, + int (*is_seen)(struct ctl_table_set *)) +{ + INIT_LIST_HEAD(&p->list); + p->parent = parent ? parent : &sysctl_table_root.default_set; + p->is_seen = is_seen; +} + #else /* !CONFIG_SYSCTL */ struct ctl_table_header *register_sysctl_table(struct ctl_table * table) { @@ -1848,6 +1863,12 @@ void unregister_sysctl_table(struct ctl_table_header * table) { } +void setup_sysctl_set(struct ctl_table_set *p, + struct ctl_table_set *parent, + int (*is_seen)(struct ctl_table_set *)) +{ +} + #endif /* CONFIG_SYSCTL */ /* diff --git a/net/sysctl_net.c b/net/sysctl_net.c index 63ada437fc2..cefbc367d8b 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c @@ -29,10 +29,15 @@ #include #endif -static struct list_head * +static struct ctl_table_set * net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces) { - return &namespaces->net_ns->sysctl_table_headers; + return &namespaces->net_ns->sysctls; +} + +static int is_seen(struct ctl_table_set *set) +{ + return ¤t->nsproxy->net_ns->sysctls == set; } /* Return standard mode bits for table entry. */ @@ -53,13 +58,6 @@ static struct ctl_table_root net_sysctl_root = { .permissions = net_ctl_permissions, }; -static LIST_HEAD(net_sysctl_ro_tables); -static struct list_head *net_ctl_ro_header_lookup(struct ctl_table_root *root, - struct nsproxy *namespaces) -{ - return &net_sysctl_ro_tables; -} - static int net_ctl_ro_header_perms(struct ctl_table_root *root, struct nsproxy *namespaces, struct ctl_table *table) { @@ -70,19 +68,18 @@ static int net_ctl_ro_header_perms(struct ctl_table_root *root, } static struct ctl_table_root net_sysctl_ro_root = { - .lookup = net_ctl_ro_header_lookup, .permissions = net_ctl_ro_header_perms, }; static int sysctl_net_init(struct net *net) { - INIT_LIST_HEAD(&net->sysctl_table_headers); + setup_sysctl_set(&net->sysctls, NULL, is_seen); return 0; } static void sysctl_net_exit(struct net *net) { - WARN_ON(!list_empty(&net->sysctl_table_headers)); + WARN_ON(!list_empty(&net->sysctls.list)); return; } @@ -98,6 +95,7 @@ static __init int sysctl_init(void) if (ret) goto out; register_sysctl_root(&net_sysctl_root); + setup_sysctl_set(&net_sysctl_ro_root.default_set, NULL, NULL); register_sysctl_root(&net_sysctl_ro_root); out: return ret; -- cgit v1.2.3-70-g09d2 From bd7b1533cd6a68c734062aa69394bec7e2b1718e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 15 Jul 2008 16:00:59 -0400 Subject: [PATCH] sysctl: make sure that /proc/sys/net/ipv4 appears before per-ns ones Massage ipv4 initialization - make sure that net.ipv4 appears as non-per-net-namespace before it shows up in per-net-namespace sysctls. That's the only change outside of sysctl.c needed to get sane ordering rules and data structures for sysctls (esp. for procfs side of that mess). Signed-off-by: Al Viro --- include/net/ip.h | 2 ++ net/ipv4/af_inet.c | 4 ++++ net/ipv4/sysctl_net_ipv4.c | 7 +++++++ 3 files changed, 13 insertions(+) (limited to 'include/net') diff --git a/include/net/ip.h b/include/net/ip.h index b5862b97520..250e6ef025a 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -188,6 +188,8 @@ extern int sysctl_ip_dynaddr; extern void ipfrag_init(void); +extern void ip_static_sysctl_init(void); + #ifdef CONFIG_INET #include diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f440a9f5492..354f6b54e49 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1439,6 +1439,10 @@ static int __init inet_init(void) (void)sock_register(&inet_family_ops); +#ifdef CONFIG_SYSCTL + ip_static_sysctl_init(); +#endif + /* * Add all the base protocols. */ diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 14ef202a225..d63e9388d92 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -882,4 +882,11 @@ static __init int sysctl_ipv4_init(void) return 0; } +/* set enough of tree skeleton to get rid of ordering problems */ +void __init ip_static_sysctl_init(void) +{ + static ctl_table table[1]; + register_sysctl_paths(net_ipv4_ctl_path, table); +} + __initcall(sysctl_ipv4_init); -- cgit v1.2.3-70-g09d2 From 516e0cc5646f377ab80fcc2ee639892eccb99853 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 26 Jul 2008 00:39:17 -0400 Subject: [PATCH] f_count may wrap around make it atomic_long_t; while we are at it, get rid of useless checks in affs, hfs and hpfs - ->open() always has it equal to 1, ->release() - to 0. Signed-off-by: Al Viro --- drivers/net/ppp_generic.c | 6 +++--- fs/affs/file.c | 4 ---- fs/aio.c | 6 +++--- fs/file_table.c | 10 +++++----- fs/hfs/inode.c | 4 ---- fs/hfsplus/inode.c | 4 ---- include/linux/fs.h | 6 +++--- include/net/af_unix.h | 2 +- net/sched/sch_atm.c | 4 ++-- net/unix/af_unix.c | 2 +- net/unix/garbage.c | 18 +++++++++--------- 11 files changed, 27 insertions(+), 39 deletions(-) (limited to 'include/net') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 739b3ab7bcc..ddccc074a76 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -581,12 +581,12 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (file == ppp->owner) ppp_shutdown_interface(ppp); } - if (atomic_read(&file->f_count) <= 2) { + if (atomic_long_read(&file->f_count) <= 2) { ppp_release(NULL, file); err = 0; } else - printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%d\n", - atomic_read(&file->f_count)); + printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%ld\n", + atomic_long_read(&file->f_count)); unlock_kernel(); return err; } diff --git a/fs/affs/file.c b/fs/affs/file.c index 6eac7bdeec9..1377b1240b6 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -46,8 +46,6 @@ const struct inode_operations affs_file_inode_operations = { static int affs_file_open(struct inode *inode, struct file *filp) { - if (atomic_read(&filp->f_count) != 1) - return 0; pr_debug("AFFS: open(%lu,%d)\n", inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); atomic_inc(&AFFS_I(inode)->i_opencnt); @@ -57,8 +55,6 @@ affs_file_open(struct inode *inode, struct file *filp) static int affs_file_release(struct inode *inode, struct file *filp) { - if (atomic_read(&filp->f_count) != 0) - return 0; pr_debug("AFFS: release(%lu, %d)\n", inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); diff --git a/fs/aio.c b/fs/aio.c index 0051fd94b44..f658441d566 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -512,8 +512,8 @@ static void aio_fput_routine(struct work_struct *data) */ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) { - dprintk(KERN_DEBUG "aio_put(%p): f_count=%d\n", - req, atomic_read(&req->ki_filp->f_count)); + dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n", + req, atomic_long_read(&req->ki_filp->f_count)); assert_spin_locked(&ctx->ctx_lock); @@ -528,7 +528,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) /* Must be done under the lock to serialise against cancellation. * Call this aio_fput as it duplicates fput via the fput_work. */ - if (unlikely(atomic_dec_and_test(&req->ki_filp->f_count))) { + if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) { get_ioctx(ctx); spin_lock(&fput_lock); list_add(&req->ki_list, &fput_head); diff --git a/fs/file_table.c b/fs/file_table.c index 83084225b4c..f45a4493f9e 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -120,7 +120,7 @@ struct file *get_empty_filp(void) tsk = current; INIT_LIST_HEAD(&f->f_u.fu_list); - atomic_set(&f->f_count, 1); + atomic_long_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); f->f_uid = tsk->fsuid; f->f_gid = tsk->fsgid; @@ -219,7 +219,7 @@ EXPORT_SYMBOL(init_file); void fput(struct file *file) { - if (atomic_dec_and_test(&file->f_count)) + if (atomic_long_dec_and_test(&file->f_count)) __fput(file); } @@ -294,7 +294,7 @@ struct file *fget(unsigned int fd) rcu_read_lock(); file = fcheck_files(files, fd); if (file) { - if (!atomic_inc_not_zero(&file->f_count)) { + if (!atomic_long_inc_not_zero(&file->f_count)) { /* File object ref couldn't be taken */ rcu_read_unlock(); return NULL; @@ -326,7 +326,7 @@ struct file *fget_light(unsigned int fd, int *fput_needed) rcu_read_lock(); file = fcheck_files(files, fd); if (file) { - if (atomic_inc_not_zero(&file->f_count)) + if (atomic_long_inc_not_zero(&file->f_count)) *fput_needed = 1; else /* Didn't get the reference, someone's freed */ @@ -341,7 +341,7 @@ struct file *fget_light(unsigned int fd, int *fput_needed) void put_filp(struct file *file) { - if (atomic_dec_and_test(&file->f_count)) { + if (atomic_long_dec_and_test(&file->f_count)) { security_file_free(file); file_kill(file); file_free(file); diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index aa73f3fd5dd..7e19835efa2 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c @@ -522,8 +522,6 @@ static int hfs_file_open(struct inode *inode, struct file *file) { if (HFS_IS_RSRC(inode)) inode = HFS_I(inode)->rsrc_inode; - if (atomic_read(&file->f_count) != 1) - return 0; atomic_inc(&HFS_I(inode)->opencnt); return 0; } @@ -534,8 +532,6 @@ static int hfs_file_release(struct inode *inode, struct file *file) if (HFS_IS_RSRC(inode)) inode = HFS_I(inode)->rsrc_inode; - if (atomic_read(&file->f_count) != 0) - return 0; if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) { mutex_lock(&inode->i_mutex); hfs_file_truncate(inode); diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index d4014e3044d..b085d64a2b6 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -254,8 +254,6 @@ static int hfsplus_file_open(struct inode *inode, struct file *file) { if (HFSPLUS_IS_RSRC(inode)) inode = HFSPLUS_I(inode).rsrc_inode; - if (atomic_read(&file->f_count) != 1) - return 0; atomic_inc(&HFSPLUS_I(inode).opencnt); return 0; } @@ -266,8 +264,6 @@ static int hfsplus_file_release(struct inode *inode, struct file *file) if (HFSPLUS_IS_RSRC(inode)) inode = HFSPLUS_I(inode).rsrc_inode; - if (atomic_read(&file->f_count) != 0) - return 0; if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) { mutex_lock(&inode->i_mutex); hfsplus_file_truncate(inode); diff --git a/include/linux/fs.h b/include/linux/fs.h index 9d2de4cadab..7676fa1c20a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -795,7 +795,7 @@ struct file { #define f_dentry f_path.dentry #define f_vfsmnt f_path.mnt const struct file_operations *f_op; - atomic_t f_count; + atomic_long_t f_count; unsigned int f_flags; mode_t f_mode; loff_t f_pos; @@ -824,8 +824,8 @@ extern spinlock_t files_lock; #define file_list_lock() spin_lock(&files_lock); #define file_list_unlock() spin_unlock(&files_lock); -#define get_file(x) atomic_inc(&(x)->f_count) -#define file_count(x) atomic_read(&(x)->f_count) +#define get_file(x) atomic_long_inc(&(x)->f_count) +#define file_count(x) atomic_long_read(&(x)->f_count) #ifdef CONFIG_DEBUG_WRITECOUNT static inline void file_take_write(struct file *f) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 2dfa96b0575..7dd29b7e461 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -51,7 +51,7 @@ struct unix_sock { struct sock *peer; struct sock *other; struct list_head link; - atomic_t inflight; + atomic_long_t inflight; spinlock_t lock; unsigned int gc_candidate : 1; wait_queue_head_t peer_wait; diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 04faa835be1..6b517b9dac5 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -162,7 +162,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl) qdisc_destroy(flow->q); tcf_destroy_chain(&flow->filter_list); if (flow->sock) { - pr_debug("atm_tc_put: f_count %d\n", + pr_debug("atm_tc_put: f_count %ld\n", file_count(flow->sock->file)); flow->vcc->pop = flow->old_pop; sockfd_put(flow->sock); @@ -259,7 +259,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, sock = sockfd_lookup(fd, &error); if (!sock) return error; /* f_count++ */ - pr_debug("atm_tc_change: f_count %d\n", file_count(sock->file)); + pr_debug("atm_tc_change: f_count %ld\n", file_count(sock->file)); if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) { error = -EPROTOTYPE; goto err_out; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 70ceb1604ad..6e7fec74bdb 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -603,7 +603,7 @@ static struct sock * unix_create1(struct net *net, struct socket *sock) u->dentry = NULL; u->mnt = NULL; spin_lock_init(&u->lock); - atomic_set(&u->inflight, 0); + atomic_long_set(&u->inflight, 0); INIT_LIST_HEAD(&u->link); mutex_init(&u->readlock); /* single task reading lock */ init_waitqueue_head(&u->peer_wait); diff --git a/net/unix/garbage.c b/net/unix/garbage.c index ebdff3d877a..2a27b84f740 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -127,7 +127,7 @@ void unix_inflight(struct file *fp) if(s) { struct unix_sock *u = unix_sk(s); spin_lock(&unix_gc_lock); - if (atomic_inc_return(&u->inflight) == 1) { + if (atomic_long_inc_return(&u->inflight) == 1) { BUG_ON(!list_empty(&u->link)); list_add_tail(&u->link, &gc_inflight_list); } else { @@ -145,7 +145,7 @@ void unix_notinflight(struct file *fp) struct unix_sock *u = unix_sk(s); spin_lock(&unix_gc_lock); BUG_ON(list_empty(&u->link)); - if (atomic_dec_and_test(&u->inflight)) + if (atomic_long_dec_and_test(&u->inflight)) list_del_init(&u->link); unix_tot_inflight--; spin_unlock(&unix_gc_lock); @@ -237,17 +237,17 @@ static void scan_children(struct sock *x, void (*func)(struct unix_sock *), static void dec_inflight(struct unix_sock *usk) { - atomic_dec(&usk->inflight); + atomic_long_dec(&usk->inflight); } static void inc_inflight(struct unix_sock *usk) { - atomic_inc(&usk->inflight); + atomic_long_inc(&usk->inflight); } static void inc_inflight_move_tail(struct unix_sock *u) { - atomic_inc(&u->inflight); + atomic_long_inc(&u->inflight); /* * If this is still a candidate, move it to the end of the * list, so that it's checked even if it was already passed @@ -288,11 +288,11 @@ void unix_gc(void) * before the detach without atomicity guarantees. */ list_for_each_entry_safe(u, next, &gc_inflight_list, link) { - int total_refs; - int inflight_refs; + long total_refs; + long inflight_refs; total_refs = file_count(u->sk.sk_socket->file); - inflight_refs = atomic_read(&u->inflight); + inflight_refs = atomic_long_read(&u->inflight); BUG_ON(inflight_refs < 1); BUG_ON(total_refs < inflight_refs); @@ -324,7 +324,7 @@ void unix_gc(void) /* Move cursor to after the current position. */ list_move(&cursor, &u->link); - if (atomic_read(&u->inflight) > 0) { + if (atomic_long_read(&u->inflight) > 0) { list_move_tail(&u->link, &gc_inflight_list); u->gc_candidate = 0; scan_children(&u->sk, inc_inflight_move_tail, NULL); -- cgit v1.2.3-70-g09d2 From eeb61f719c00c626115852bbc91189dc3011a844 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 27 Jul 2008 08:59:33 +0100 Subject: missing bits of net-namespace / sysctl Piss-poor sysctl registration API strikes again, film at 11... What we really need is _pathname_ required to be present in already registered table, so that kernel could warn about bad order. That's the next target for sysctl stuff (and generally saner and more explicit order of initialization of ipv[46] internals wouldn't hurt either). For the time being, here are full fixups required by ..._rotable() stuff; we make per-net sysctl sets descendents of "ro" one and make sure that sufficient skeleton is there before we start registering per-net sysctls. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- include/net/ipv6.h | 2 ++ include/net/route.h | 2 -- net/ipv4/route.c | 11 ++++++++++- net/ipv4/sysctl_net_ipv4.c | 14 -------------- net/ipv6/af_inet6.c | 12 ++++++++++++ net/ipv6/sysctl_net_ipv6.c | 16 ++++++++++++++++ net/sysctl_net.c | 4 +++- 7 files changed, 43 insertions(+), 18 deletions(-) (limited to 'include/net') diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 2d5c18514a2..113028fb8f6 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -608,6 +608,8 @@ extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net); extern struct ctl_table *ipv6_route_sysctl_init(struct net *net); extern int ipv6_sysctl_register(void); extern void ipv6_sysctl_unregister(void); +extern int ipv6_static_sysctl_register(void); +extern void ipv6_static_sysctl_unregister(void); #endif #endif /* __KERNEL__ */ diff --git a/include/net/route.h b/include/net/route.h index 3140cc50085..4f0d8c14736 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -204,6 +204,4 @@ static inline struct inet_peer *rt_get_peer(struct rtable *rt) return rt->peer; } -extern ctl_table ipv4_route_table[]; - #endif /* _ROUTE_H */ diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a507c5e27d0..380d6474cf6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2914,7 +2914,7 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, return 0; } -ctl_table ipv4_route_table[] = { +static ctl_table ipv4_route_table[] = { { .ctl_name = NET_IPV4_ROUTE_GC_THRESH, .procname = "gc_thresh", @@ -3216,6 +3216,15 @@ int __init ip_rt_init(void) return rc; } +/* + * We really need to sanitize the damn ipv4 init order, then all + * this nonsense will go away. + */ +void __init ip_static_sysctl_init(void) +{ + register_sysctl_paths(ipv4_route_path, ipv4_route_table); +} + EXPORT_SYMBOL(__ip_select_ident); EXPORT_SYMBOL(ip_route_input); EXPORT_SYMBOL(ip_route_output_key); diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index d63e9388d92..770d827f5ab 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -401,13 +401,6 @@ static struct ctl_table ipv4_table[] = { .proc_handler = &ipv4_local_port_range, .strategy = &ipv4_sysctl_local_port_range, }, - { - .ctl_name = NET_IPV4_ROUTE, - .procname = "route", - .maxlen = 0, - .mode = 0555, - .child = ipv4_route_table - }, #ifdef CONFIG_IP_MULTICAST { .ctl_name = NET_IPV4_IGMP_MAX_MEMBERSHIPS, @@ -882,11 +875,4 @@ static __init int sysctl_ipv4_init(void) return 0; } -/* set enough of tree skeleton to get rid of ordering problems */ -void __init ip_static_sysctl_init(void) -{ - static ctl_table table[1]; - register_sysctl_paths(net_ipv4_ctl_path, table); -} - __initcall(sysctl_ipv4_init); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index c708ca84229..95055f8c3f3 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -934,6 +934,11 @@ static int __init inet6_init(void) if (err) goto out_unregister_sock; +#ifdef CONFIG_SYSCTL + err = ipv6_static_sysctl_register(); + if (err) + goto static_sysctl_fail; +#endif /* * ipngwg API draft makes clear that the correct semantics * for TCP and UDP is to consider one TCP and UDP instance @@ -1058,6 +1063,10 @@ ipmr_fail: icmp_fail: unregister_pernet_subsys(&inet6_net_ops); register_pernet_fail: +#ifdef CONFIG_SYSCTL + ipv6_static_sysctl_unregister(); +static_sysctl_fail: +#endif cleanup_ipv6_mibs(); out_unregister_sock: sock_unregister(PF_INET6); @@ -1113,6 +1122,9 @@ static void __exit inet6_exit(void) rawv6_exit(); unregister_pernet_subsys(&inet6_net_ops); +#ifdef CONFIG_SYSCTL + ipv6_static_sysctl_unregister(); +#endif cleanup_ipv6_mibs(); proto_unregister(&rawv6_prot); proto_unregister(&udplitev6_prot); diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 5c99274558b..e6dfaeac6be 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -150,3 +150,19 @@ void ipv6_sysctl_unregister(void) unregister_net_sysctl_table(ip6_header); unregister_pernet_subsys(&ipv6_sysctl_net_ops); } + +static struct ctl_table_header *ip6_base; + +int ipv6_static_sysctl_register(void) +{ + static struct ctl_table empty[1]; + ip6_base = register_net_sysctl_rotable(net_ipv6_ctl_path, empty); + if (ip6_base == NULL) + return -ENOMEM; + return 0; +} + +void ipv6_static_sysctl_unregister(void) +{ + unregister_net_sysctl_table(ip6_base); +} diff --git a/net/sysctl_net.c b/net/sysctl_net.c index cefbc367d8b..972201cd5fa 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c @@ -73,7 +73,9 @@ static struct ctl_table_root net_sysctl_ro_root = { static int sysctl_net_init(struct net *net) { - setup_sysctl_set(&net->sysctls, NULL, is_seen); + setup_sysctl_set(&net->sysctls, + &net_sysctl_ro_root.default_set, + is_seen); return 0; } -- cgit v1.2.3-70-g09d2