aboutsummaryrefslogtreecommitdiff
path: root/net/netfilter
diff options
context:
space:
mode:
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nf_conntrack_core.c234
-rw-r--r--net/netfilter/nf_conntrack_expect.c53
-rw-r--r--net/netfilter/nf_conntrack_h323_asn1.c156
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c23
-rw-r--r--net/netfilter/nf_conntrack_h323_types.c346
-rw-r--r--net/netfilter/nf_conntrack_helper.c60
-rw-r--r--net/netfilter/nf_conntrack_irc.c2
-rw-r--r--net/netfilter/nf_conntrack_netlink.c68
-rw-r--r--net/netfilter/nf_conntrack_pptp.c14
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c6
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c6
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c6
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c192
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c19
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c19
-rw-r--r--net/netfilter/nf_conntrack_sane.c9
-rw-r--r--net/netfilter/nf_conntrack_sip.c29
-rw-r--r--net/netfilter/nf_conntrack_standalone.c66
-rw-r--r--net/netfilter/nf_conntrack_tftp.c5
-rw-r--r--net/netfilter/nf_log.c2
-rw-r--r--net/netfilter/nfnetlink_log.c4
-rw-r--r--net/netfilter/nfnetlink_queue.c6
-rw-r--r--net/netfilter/x_tables.c313
-rw-r--r--net/netfilter/xt_TCPMSS.c62
-rw-r--r--net/netfilter/xt_connlimit.c6
-rw-r--r--net/netfilter/xt_conntrack.c50
-rw-r--r--net/netfilter/xt_hashlimit.c326
-rw-r--r--net/netfilter/xt_iprange.c2
-rw-r--r--net/netfilter/xt_owner.c14
29 files changed, 1292 insertions, 806 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 078fff0335a..327e847d270 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -40,7 +40,7 @@
#define NF_CONNTRACK_VERSION "0.5.0"
-DEFINE_RWLOCK(nf_conntrack_lock);
+DEFINE_SPINLOCK(nf_conntrack_lock);
EXPORT_SYMBOL_GPL(nf_conntrack_lock);
/* nf_conntrack_standalone needs this */
@@ -73,15 +73,19 @@ static unsigned int nf_conntrack_hash_rnd;
static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
unsigned int size, unsigned int rnd)
{
- unsigned int a, b;
-
- a = jhash2(tuple->src.u3.all, ARRAY_SIZE(tuple->src.u3.all),
- (tuple->src.l3num << 16) | tuple->dst.protonum);
- b = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
- ((__force __u16)tuple->src.u.all << 16) |
- (__force __u16)tuple->dst.u.all);
-
- return ((u64)jhash_2words(a, b, rnd) * size) >> 32;
+ unsigned int n;
+ u_int32_t h;
+
+ /* The direction must be ignored, so we hash everything up to the
+ * destination ports (which is a multiple of 4) and treat the last
+ * three bytes manually.
+ */
+ n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32);
+ h = jhash2((u32 *)tuple, n,
+ rnd ^ (((__force __u16)tuple->dst.u.all << 16) |
+ tuple->dst.protonum));
+
+ return ((u64)h * size) >> 32;
}
static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
@@ -166,8 +170,8 @@ static void
clean_from_lists(struct nf_conn *ct)
{
pr_debug("clean_from_lists(%p)\n", ct);
- hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
- hlist_del(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
+ hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
+ hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
/* Destroy all pending expectations */
nf_ct_remove_expectations(ct);
@@ -199,7 +203,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
rcu_read_unlock();
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
/* Expectations will have been removed in clean_from_lists,
* except TFTP can create an expectation on the first packet,
* before connection is in the list, so we need to clean here,
@@ -213,7 +217,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
}
NF_CT_STAT_INC(delete);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
if (ct->master)
nf_ct_put(ct->master);
@@ -236,26 +240,24 @@ static void death_by_timeout(unsigned long ul_conntrack)
rcu_read_unlock();
}
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
/* Inside lock so preempt is disabled on module removal path.
* Otherwise we can get spurious warnings. */
NF_CT_STAT_INC(delete_list);
clean_from_lists(ct);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
nf_ct_put(ct);
}
struct nf_conntrack_tuple_hash *
-__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
- const struct nf_conn *ignored_conntrack)
+__nf_conntrack_find(const struct nf_conntrack_tuple *tuple)
{
struct nf_conntrack_tuple_hash *h;
struct hlist_node *n;
unsigned int hash = hash_conntrack(tuple);
- hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
- if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
- nf_ct_tuple_equal(tuple, &h->tuple)) {
+ hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
+ if (nf_ct_tuple_equal(tuple, &h->tuple)) {
NF_CT_STAT_INC(found);
return h;
}
@@ -271,12 +273,16 @@ struct nf_conntrack_tuple_hash *
nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple)
{
struct nf_conntrack_tuple_hash *h;
+ struct nf_conn *ct;
- read_lock_bh(&nf_conntrack_lock);
- h = __nf_conntrack_find(tuple, NULL);
- if (h)
- atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
+ h = __nf_conntrack_find(tuple);
+ if (h) {
+ ct = nf_ct_tuplehash_to_ctrack(h);
+ if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
+ h = NULL;
+ }
+ rcu_read_unlock();
return h;
}
@@ -286,10 +292,10 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
unsigned int hash,
unsigned int repl_hash)
{
- hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
- &nf_conntrack_hash[hash]);
- hlist_add_head(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
- &nf_conntrack_hash[repl_hash]);
+ hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
+ &nf_conntrack_hash[hash]);
+ hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
+ &nf_conntrack_hash[repl_hash]);
}
void nf_conntrack_hash_insert(struct nf_conn *ct)
@@ -299,9 +305,9 @@ void nf_conntrack_hash_insert(struct nf_conn *ct)
hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
__nf_conntrack_hash_insert(ct, hash, repl_hash);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
}
EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert);
@@ -338,7 +344,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
pr_debug("Confirming conntrack %p\n", ct);
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
/* See if there's one in the list already, including reverse:
NAT could have grabbed it without realizing, since we're
@@ -364,7 +370,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
atomic_inc(&ct->ct_general.use);
set_bit(IPS_CONFIRMED_BIT, &ct->status);
NF_CT_STAT_INC(insert);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
help = nfct_help(ct);
if (help && help->helper)
nf_conntrack_event_cache(IPCT_HELPER, skb);
@@ -379,7 +385,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
out:
NF_CT_STAT_INC(insert_failed);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return NF_DROP;
}
EXPORT_SYMBOL_GPL(__nf_conntrack_confirm);
@@ -391,12 +397,22 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
const struct nf_conn *ignored_conntrack)
{
struct nf_conntrack_tuple_hash *h;
+ struct hlist_node *n;
+ unsigned int hash = hash_conntrack(tuple);
- read_lock_bh(&nf_conntrack_lock);
- h = __nf_conntrack_find(tuple, ignored_conntrack);
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
+ if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
+ nf_ct_tuple_equal(tuple, &h->tuple)) {
+ NF_CT_STAT_INC(found);
+ rcu_read_unlock();
+ return 1;
+ }
+ NF_CT_STAT_INC(searched);
+ }
+ rcu_read_unlock();
- return h != NULL;
+ return 0;
}
EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
@@ -404,7 +420,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
/* There's a small race here where we may free a just-assured
connection. Too bad: we're in trouble anyway. */
-static int early_drop(unsigned int hash)
+static noinline int early_drop(unsigned int hash)
{
/* Use oldest entry, which is roughly LRU */
struct nf_conntrack_tuple_hash *h;
@@ -413,21 +429,23 @@ static int early_drop(unsigned int hash)
unsigned int i, cnt = 0;
int dropped = 0;
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
for (i = 0; i < nf_conntrack_htable_size; i++) {
- hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) {
+ hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash],
+ hnode) {
tmp = nf_ct_tuplehash_to_ctrack(h);
if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
ct = tmp;
cnt++;
}
+
+ if (ct && unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
+ ct = NULL;
if (ct || cnt >= NF_CT_EVICTION_RANGE)
break;
hash = (hash + 1) % nf_conntrack_htable_size;
}
- if (ct)
- atomic_inc(&ct->ct_general.use);
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
if (!ct)
return dropped;
@@ -444,7 +462,7 @@ static int early_drop(unsigned int hash)
struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
const struct nf_conntrack_tuple *repl)
{
- struct nf_conn *conntrack = NULL;
+ struct nf_conn *ct = NULL;
if (unlikely(!nf_conntrack_hash_rnd_initted)) {
get_random_bytes(&nf_conntrack_hash_rnd, 4);
@@ -454,8 +472,8 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
/* We don't want any race condition at early drop stage */
atomic_inc(&nf_conntrack_count);
- if (nf_conntrack_max
- && atomic_read(&nf_conntrack_count) > nf_conntrack_max) {
+ if (nf_conntrack_max &&
+ unlikely(atomic_read(&nf_conntrack_count) > nf_conntrack_max)) {
unsigned int hash = hash_conntrack(orig);
if (!early_drop(hash)) {
atomic_dec(&nf_conntrack_count);
@@ -467,30 +485,37 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
}
}
- conntrack = kmem_cache_zalloc(nf_conntrack_cachep, GFP_ATOMIC);
- if (conntrack == NULL) {
+ ct = kmem_cache_zalloc(nf_conntrack_cachep, GFP_ATOMIC);
+ if (ct == NULL) {
pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
atomic_dec(&nf_conntrack_count);
return ERR_PTR(-ENOMEM);
}
- atomic_set(&conntrack->ct_general.use, 1);
- conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
- conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
+ atomic_set(&ct->ct_general.use, 1);
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
+ ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
/* Don't set timer yet: wait for confirmation */
- setup_timer(&conntrack->timeout, death_by_timeout,
- (unsigned long)conntrack);
+ setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
+ INIT_RCU_HEAD(&ct->rcu);
- return conntrack;
+ return ct;
}
EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
-void nf_conntrack_free(struct nf_conn *conntrack)
+static void nf_conntrack_free_rcu(struct rcu_head *head)
{
- nf_ct_ext_free(conntrack);
- kmem_cache_free(nf_conntrack_cachep, conntrack);
+ struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
+
+ nf_ct_ext_free(ct);
+ kmem_cache_free(nf_conntrack_cachep, ct);
atomic_dec(&nf_conntrack_count);
}
+
+void nf_conntrack_free(struct nf_conn *ct)
+{
+ call_rcu(&ct->rcu, nf_conntrack_free_rcu);
+}
EXPORT_SYMBOL_GPL(nf_conntrack_free);
/* Allocate a new conntrack: we return -ENOMEM if classification
@@ -502,7 +527,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
struct sk_buff *skb,
unsigned int dataoff)
{
- struct nf_conn *conntrack;
+ struct nf_conn *ct;
struct nf_conn_help *help;
struct nf_conntrack_tuple repl_tuple;
struct nf_conntrack_expect *exp;
@@ -512,46 +537,46 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
return NULL;
}
- conntrack = nf_conntrack_alloc(tuple, &repl_tuple);
- if (conntrack == NULL || IS_ERR(conntrack)) {
+ ct = nf_conntrack_alloc(tuple, &repl_tuple);
+ if (ct == NULL || IS_ERR(ct)) {
pr_debug("Can't allocate conntrack.\n");
- return (struct nf_conntrack_tuple_hash *)conntrack;
+ return (struct nf_conntrack_tuple_hash *)ct;
}
- if (!l4proto->new(conntrack, skb, dataoff)) {
- nf_conntrack_free(conntrack);
+ if (!l4proto->new(ct, skb, dataoff)) {
+ nf_conntrack_free(ct);
pr_debug("init conntrack: can't track with proto module\n");
return NULL;
}
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
exp = nf_ct_find_expectation(tuple);
if (exp) {
pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
- conntrack, exp);
+ ct, exp);
/* Welcome, Mr. Bond. We've been expecting you... */
- __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
- conntrack->master = exp->master;
+ __set_bit(IPS_EXPECTED_BIT, &ct->status);
+ ct->master = exp->master;
if (exp->helper) {
- help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+ help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
if (help)
rcu_assign_pointer(help->helper, exp->helper);
}
#ifdef CONFIG_NF_CONNTRACK_MARK
- conntrack->mark = exp->master->mark;
+ ct->mark = exp->master->mark;
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
- conntrack->secmark = exp->master->secmark;
+ ct->secmark = exp->master->secmark;
#endif
- nf_conntrack_get(&conntrack->master->ct_general);
+ nf_conntrack_get(&ct->master->ct_general);
NF_CT_STAT_INC(expect_new);
} else {
struct nf_conntrack_helper *helper;
helper = __nf_ct_helper_find(&repl_tuple);
if (helper) {
- help = nf_ct_helper_ext_add(conntrack, GFP_ATOMIC);
+ help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
if (help)
rcu_assign_pointer(help->helper, helper);
}
@@ -559,18 +584,17 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
}
/* Overload tuple linked list to put us in unconfirmed list. */
- hlist_add_head(&conntrack->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
- &unconfirmed);
+ hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, &unconfirmed);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
if (exp) {
if (exp->expectfn)
- exp->expectfn(conntrack, exp);
+ exp->expectfn(ct, exp);
nf_ct_expect_put(exp);
}
- return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
+ return &ct->tuplehash[IP_CT_DIR_ORIGINAL];
}
/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
@@ -729,7 +753,6 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_helper *helper;
- write_lock_bh(&nf_conntrack_lock);
/* Should be unconfirmed, so not in hash table yet */
NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
@@ -738,8 +761,9 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
if (ct->master || (help && help->expecting != 0))
- goto out;
+ return;
+ rcu_read_lock();
helper = __nf_ct_helper_find(newreply);
if (helper == NULL) {
if (help)
@@ -757,7 +781,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
rcu_assign_pointer(help->helper, helper);
out:
- write_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
@@ -773,13 +797,11 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
NF_CT_ASSERT(skb);
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
/* Only update if this is not a fixed timeout */
- if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status)) {
- write_unlock_bh(&nf_conntrack_lock);
- return;
- }
+ if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status))
+ goto acct;
/* If not in hash table, timer will not be active yet */
if (!nf_ct_is_confirmed(ct)) {
@@ -799,6 +821,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
}
}
+acct:
#ifdef CONFIG_NF_CT_ACCT
if (do_acct) {
ct->counters[CTINFO2DIR(ctinfo)].packets++;
@@ -811,7 +834,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
}
#endif
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
/* must be unlocked when calling event cache */
if (event)
@@ -879,14 +902,6 @@ static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
nf_conntrack_get(nskb->nfct);
}
-static inline int
-do_iter(const struct nf_conntrack_tuple_hash *i,
- int (*iter)(struct nf_conn *i, void *data),
- void *data)
-{
- return iter(nf_ct_tuplehash_to_ctrack(i), data);
-}
-
/* Bring out ya dead! */
static struct nf_conn *
get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
@@ -896,7 +911,7 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
struct nf_conn *ct;
struct hlist_node *n;
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
hlist_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnode) {
ct = nf_ct_tuplehash_to_ctrack(h);
@@ -909,11 +924,11 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
if (iter(ct, data))
set_bit(IPS_DYING_BIT, &ct->status);
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return NULL;
found:
atomic_inc(&ct->ct_general.use);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return ct;
}
@@ -939,7 +954,7 @@ static int kill_all(struct nf_conn *i, void *data)
return 1;
}
-void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, int size)
+void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int size)
{
if (vmalloced)
vfree(hash);
@@ -988,7 +1003,7 @@ void nf_conntrack_cleanup(void)
nf_conntrack_expect_fini();
}
-struct hlist_head *nf_ct_alloc_hashtable(int *sizep, int *vmalloced)
+struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
{
struct hlist_head *hash;
unsigned int size, i;
@@ -1015,8 +1030,8 @@ EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable);
int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
{
- int i, bucket, hashsize, vmalloced;
- int old_vmalloced, old_size;
+ int i, bucket, vmalloced, old_vmalloced;
+ unsigned int hashsize, old_size;
int rnd;
struct hlist_head *hash, *old_hash;
struct nf_conntrack_tuple_hash *h;
@@ -1025,7 +1040,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
if (!nf_conntrack_htable_size)
return param_set_uint(val, kp);
- hashsize = simple_strtol(val, NULL, 0);
+ hashsize = simple_strtoul(val, NULL, 0);
if (!hashsize)
return -EINVAL;
@@ -1037,12 +1052,17 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
* use a newrandom seed */
get_random_bytes(&rnd, 4);
- write_lock_bh(&nf_conntrack_lock);
+ /* Lookups in the old hash might happen in parallel, which means we
+ * might get false negatives during connection lookup. New connections
+ * created because of a false negative won't make it into the hash
+ * though since that required taking the lock.
+ */
+ spin_lock_bh(&nf_conntrack_lock);
for (i = 0; i < nf_conntrack_htable_size; i++) {
while (!hlist_empty(&nf_conntrack_hash[i])) {
h = hlist_entry(nf_conntrack_hash[i].first,
struct nf_conntrack_tuple_hash, hnode);
- hlist_del(&h->hnode);
+ hlist_del_rcu(&h->hnode);
bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
hlist_add_head(&h->hnode, &hash[bucket]);
}
@@ -1055,7 +1075,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
nf_conntrack_vmalloc = vmalloced;
nf_conntrack_hash = hash;
nf_conntrack_hash_rnd = rnd;
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
nf_ct_free_hashtable(old_hash, old_vmalloced, old_size);
return 0;
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index e0cd9d00aa6..e06bf0028bb 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -50,7 +50,7 @@ void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
NF_CT_ASSERT(master_help);
NF_CT_ASSERT(!timer_pending(&exp->timeout));
- hlist_del(&exp->hnode);
+ hlist_del_rcu(&exp->hnode);
nf_ct_expect_count--;
hlist_del(&exp->lnode);
@@ -65,9 +65,9 @@ static void nf_ct_expectation_timed_out(unsigned long ul_expect)
{
struct nf_conntrack_expect *exp = (void *)ul_expect;
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
nf_ct_unlink_expect(exp);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
nf_ct_expect_put(exp);
}
@@ -97,7 +97,7 @@ __nf_ct_expect_find(const struct nf_conntrack_tuple *tuple)
return NULL;
h = nf_ct_expect_dst_hash(tuple);
- hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
+ hlist_for_each_entry_rcu(i, n, &nf_ct_expect_hash[h], hnode) {
if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
return i;
}
@@ -111,11 +111,11 @@ nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple)
{
struct nf_conntrack_expect *i;
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
i = __nf_ct_expect_find(tuple);
- if (i)
- atomic_inc(&i->use);
- read_unlock_bh(&nf_conntrack_lock);
+ if (i && !atomic_inc_not_zero(&i->use))
+ i = NULL;
+ rcu_read_unlock();
return i;
}
@@ -201,12 +201,12 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
/* Generally a bad idea to call this: could have matched already. */
void nf_ct_unexpect_related(struct nf_conntrack_expect *exp)
{
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
if (del_timer(&exp->timeout)) {
nf_ct_unlink_expect(exp);
nf_ct_expect_put(exp);
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
}
EXPORT_SYMBOL_GPL(nf_ct_unexpect_related);
@@ -223,6 +223,7 @@ struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
new->master = me;
atomic_set(&new->use, 1);
+ INIT_RCU_HEAD(&new->rcu);
return new;
}
EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
@@ -278,10 +279,18 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
}
EXPORT_SYMBOL_GPL(nf_ct_expect_init);
+static void nf_ct_expect_free_rcu(struct rcu_head *head)
+{
+ struct nf_conntrack_expect *exp;
+
+ exp = container_of(head, struct nf_conntrack_expect, rcu);
+ kmem_cache_free(nf_ct_expect_cachep, exp);
+}
+
void nf_ct_expect_put(struct nf_conntrack_expect *exp)
{
if (atomic_dec_and_test(&exp->use))
- kmem_cache_free(nf_ct_expect_cachep, exp);
+ call_rcu(&exp->rcu, nf_ct_expect_free_rcu);
}
EXPORT_SYMBOL_GPL(nf_ct_expect_put);
@@ -295,7 +304,7 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
hlist_add_head(&exp->lnode, &master_help->expectations);
master_help->expecting++;
- hlist_add_head(&exp->hnode, &nf_ct_expect_hash[h]);
+ hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]);
nf_ct_expect_count++;
setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
@@ -346,7 +355,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
NF_CT_ASSERT(master_help);
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
if (!master_help->helper) {
ret = -ESHUTDOWN;
goto out;
@@ -381,7 +390,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
nf_ct_expect_event(IPEXP_NEW, expect);
ret = 0;
out:
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return ret;
}
EXPORT_SYMBOL_GPL(nf_ct_expect_related);
@@ -394,10 +403,12 @@ struct ct_expect_iter_state {
static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
{
struct ct_expect_iter_state *st = seq->private;
+ struct hlist_node *n;
for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
- if (!hlist_empty(&nf_ct_expect_hash[st->bucket]))
- return nf_ct_expect_hash[st->bucket].first;
+ n = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
+ if (n)
+ return n;
}
return NULL;
}
@@ -407,11 +418,11 @@ static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
{
struct ct_expect_iter_state *st = seq->private;
- head = head->next;
+ head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_ct_expect_hsize)
return NULL;
- head = nf_ct_expect_hash[st->bucket].first;
+ head = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
}
return head;
}
@@ -427,8 +438,9 @@ static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
}
static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
return ct_expect_get_idx(seq, *pos);
}
@@ -439,8 +451,9 @@ static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
}
static void exp_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
{
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
static int exp_seq_show(struct seq_file *s, void *v)
diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c
index ff66fba514f..867882313e4 100644
--- a/net/netfilter/nf_conntrack_h323_asn1.c
+++ b/net/netfilter/nf_conntrack_h323_asn1.c
@@ -87,7 +87,7 @@ typedef struct field_t {
unsigned char ub;
unsigned short attr;
unsigned short offset;
- struct field_t *fields;
+ const struct field_t *fields;
} field_t;
/* Bit Stream */
@@ -96,7 +96,7 @@ typedef struct {
unsigned char *beg;
unsigned char *end;
unsigned char *cur;
- unsigned bit;
+ unsigned int bit;
} bitstr_t;
/* Tool Functions */
@@ -104,29 +104,29 @@ typedef struct {
#define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;}
#define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;}
#define CHECK_BOUND(bs,n) if((bs)->cur+(n)>(bs)->end)return(H323_ERROR_BOUND)
-static unsigned get_len(bitstr_t * bs);
-static unsigned get_bit(bitstr_t * bs);
-static unsigned get_bits(bitstr_t * bs, unsigned b);
-static unsigned get_bitmap(bitstr_t * bs, unsigned b);
-static unsigned get_uint(bitstr_t * bs, int b);
+static unsigned int get_len(bitstr_t *bs);
+static unsigned int get_bit(bitstr_t *bs);
+static unsigned int get_bits(bitstr_t *bs, unsigned int b);
+static unsigned int get_bitmap(bitstr_t *bs, unsigned int b);
+static unsigned int get_uint(bitstr_t *bs, int b);
/* Decoder Functions */
-static int decode_nul(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_bool(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_oid(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_int(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_enum(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_seq(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level);
-static int decode_choice(bitstr_t * bs, field_t * f, char *base, int level);
+static int decode_nul(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_bool(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_oid(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_int(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_enum(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_bitstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_numstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_octstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_bmpstr(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_seq(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_seqof(bitstr_t *bs, const struct field_t *f, char *base, int level);
+static int decode_choice(bitstr_t *bs, const struct field_t *f, char *base, int level);
/* Decoder Functions Vector */
-typedef int (*decoder_t) (bitstr_t *, field_t *, char *, int);
-static decoder_t Decoders[] = {
+typedef int (*decoder_t)(bitstr_t *, const struct field_t *, char *, int);
+static const decoder_t Decoders[] = {
decode_nul,
decode_bool,
decode_oid,
@@ -150,9 +150,9 @@ static decoder_t Decoders[] = {
* Functions
****************************************************************************/
/* Assume bs is aligned && v < 16384 */
-unsigned get_len(bitstr_t * bs)
+static unsigned int get_len(bitstr_t *bs)
{
- unsigned v;
+ unsigned int v;
v = *bs->cur++;
@@ -166,9 +166,9 @@ unsigned get_len(bitstr_t * bs)
}
/****************************************************************************/
-unsigned get_bit(bitstr_t * bs)
+static unsigned int get_bit(bitstr_t *bs)
{
- unsigned b = (*bs->cur) & (0x80 >> bs->bit);
+ unsigned int b = (*bs->cur) & (0x80 >> bs->bit);
INC_BIT(bs);
@@ -177,9 +177,9 @@ unsigned get_bit(bitstr_t * bs)
/****************************************************************************/
/* Assume b <= 8 */
-unsigned get_bits(bitstr_t * bs, unsigned b)
+static unsigned int get_bits(bitstr_t *bs, unsigned int b)
{
- unsigned v, l;
+ unsigned int v, l;
v = (*bs->cur) & (0xffU >> bs->bit);
l = b + bs->bit;
@@ -203,9 +203,9 @@ unsigned get_bits(bitstr_t * bs, unsigned b)
/****************************************************************************/
/* Assume b <= 32 */
-unsigned get_bitmap(bitstr_t * bs, unsigned b)
+static unsigned int get_bitmap(bitstr_t *bs, unsigned int b)
{
- unsigned v, l, shift, bytes;
+ unsigned int v, l, shift, bytes;
if (!b)
return 0;
@@ -213,18 +213,18 @@ unsigned get_bitmap(bitstr_t * bs, unsigned b)
l = bs->bit + b;
if (l < 8) {
- v = (unsigned) (*bs->cur) << (bs->bit + 24);
+ v = (unsigned int)(*bs->cur) << (bs->bit + 24);
bs->bit = l;
} else if (l == 8) {
- v = (unsigned) (*bs->cur++) << (bs->bit + 24);
+ v = (unsigned int)(*bs->cur++) << (bs->bit + 24);
bs->bit = 0;
} else {
for (bytes = l >> 3, shift = 24, v = 0; bytes;
bytes--, shift -= 8)
- v |= (unsigned) (*bs->cur++) << shift;
+ v |= (unsigned int)(*bs->cur++) << shift;
if (l < 32) {
- v |= (unsigned) (*bs->cur) << shift;
+ v |= (unsigned int)(*bs->cur) << shift;
v <<= bs->bit;
} else if (l > 32) {
v <<= bs->bit;
@@ -242,9 +242,9 @@ unsigned get_bitmap(bitstr_t * bs, unsigned b)
/****************************************************************************
* Assume bs is aligned and sizeof(unsigned int) == 4
****************************************************************************/
-unsigned get_uint(bitstr_t * bs, int b)
+static unsigned int get_uint(bitstr_t *bs, int b)
{
- unsigned v = 0;
+ unsigned int v = 0;
switch (b) {
case 4:
@@ -264,7 +264,8 @@ unsigned get_uint(bitstr_t * bs, int b)
}
/****************************************************************************/
-int decode_nul(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_nul(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -272,7 +273,8 @@ int decode_nul(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_bool(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_bool(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -283,7 +285,8 @@ int decode_bool(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_oid(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_oid(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
int len;
@@ -299,9 +302,10 @@ int decode_oid(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_int(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
@@ -318,9 +322,9 @@ int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
len = get_bits(bs, 2) + 1;
BYTE_ALIGN(bs);
if (base && (f->attr & DECODE)) { /* timeToLive */
- unsigned v = get_uint(bs, len) + f->lb;
+ unsigned int v = get_uint(bs, len) + f->lb;
PRINT(" = %u", v);
- *((unsigned *) (base + f->offset)) = v;
+ *((unsigned int *)(base + f->offset)) = v;
}
bs->cur += len;
break;
@@ -342,7 +346,8 @@ int decode_int(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_enum(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_enum(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -357,9 +362,10 @@ int decode_enum(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_bitstr(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -390,9 +396,10 @@ int decode_bitstr(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_numstr(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -407,9 +414,10 @@ int decode_numstr(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_octstr(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s", level * TAB_SIZE, " ", f->name);
@@ -424,7 +432,7 @@ int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
bs->cur[0], bs->cur[1],
bs->cur[2], bs->cur[3],
bs->cur[4] * 256 + bs->cur[5]));
- *((unsigned *) (base + f->offset)) =
+ *((unsigned int *)(base + f->offset)) =
bs->cur - bs->buf;
}
}
@@ -455,9 +463,10 @@ int decode_octstr(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_bmpstr(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned len;
+ unsigned int len;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -480,11 +489,12 @@ int decode_bmpstr(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_seq(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
+ unsigned int ext, bmp, i, opt, len = 0, bmp2, bmp2_len;
int err;
- field_t *son;
+ const struct field_t *son;
unsigned char *beg = NULL;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -498,7 +508,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
/* Get fields bitmap */
bmp = get_bitmap(bs, f->sz);
if (base)
- *(unsigned *) base = bmp;
+ *(unsigned int *)base = bmp;
/* Decode the root components */
for (i = opt = 0, son = f->fields; i < f->lb; i++, son++) {
@@ -550,7 +560,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
bmp2 = get_bitmap(bs, bmp2_len);
bmp |= bmp2 >> f->sz;
if (base)
- *(unsigned *) base = bmp;
+ *(unsigned int *)base = bmp;
BYTE_ALIGN(bs);
/* Decode the extension components */
@@ -596,11 +606,12 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_seqof(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned count, effective_count = 0, i, len = 0;
+ unsigned int count, effective_count = 0, i, len = 0;
int err;
- field_t *son;
+ const struct field_t *son;
unsigned char *beg = NULL;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -636,8 +647,8 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
/* Write Count */
if (base) {
effective_count = count > f->ub ? f->ub : count;
- *(unsigned *) base = effective_count;
- base += sizeof(unsigned);
+ *(unsigned int *)base = effective_count;
+ base += sizeof(unsigned int);
}
/* Decode nested field */
@@ -685,11 +696,12 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
/****************************************************************************/
-int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
+static int decode_choice(bitstr_t *bs, const struct field_t *f,
+ char *base, int level)
{
- unsigned type, ext, len = 0;
+ unsigned int type, ext, len = 0;
int err;
- field_t *son;
+ const struct field_t *son;
unsigned char *beg = NULL;
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
@@ -710,7 +722,7 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
/* Write Type */
if (base)
- *(unsigned *) base = type;
+ *(unsigned int *)base = type;
/* Check Range */
if (type >= f->ub) { /* Newer version? */
@@ -754,9 +766,9 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
}
/****************************************************************************/
-int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras)
+int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage *ras)
{
- static field_t ras_message = {
+ static const struct field_t ras_message = {
FNAME("RasMessage") CHOICE, 5, 24, 32, DECODE | EXT,
0, _RasMessage
};
@@ -771,9 +783,9 @@ int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras)
/****************************************************************************/
static int DecodeH323_UserInformation(unsigned char *buf, unsigned char *beg,
- size_t sz, H323_UserInformation * uuie)
+ size_t sz, H323_UserInformation *uuie)
{
- static field_t h323_userinformation = {
+ static const struct field_t h323_userinformation = {
FNAME("H323-UserInformation") SEQ, 1, 2, 2, DECODE | EXT,
0, _H323_UserInformation
};
@@ -792,7 +804,7 @@ int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
MultimediaSystemControlMessage *
mscm)
{
- static field_t multimediasystemcontrolmessage = {
+ static const struct field_t multimediasystemcontrolmessage = {
FNAME("MultimediaSystemControlMessage") CHOICE, 2, 4, 4,
DECODE | EXT, 0, _MultimediaSystemControlMessage
};
@@ -807,7 +819,7 @@ int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz,
}
/****************************************************************************/
-int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931)
+int DecodeQ931(unsigned char *buf, size_t sz, Q931 *q931)
{
unsigned char *p = buf;
int len;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 872c1aa3124..62137879e6a 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -114,7 +114,8 @@ static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff,
{
struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
int dir = CTINFO2DIR(ctinfo);
- struct tcphdr _tcph, *th;
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
int tcpdatalen;
int tcpdataoff;
unsigned char *tpkt;
@@ -212,11 +213,11 @@ static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff,
}
/****************************************************************************/
-static int get_h245_addr(struct nf_conn *ct, unsigned char *data,
+static int get_h245_addr(struct nf_conn *ct, const unsigned char *data,
H245_TransportAddress *taddr,
union nf_inet_addr *addr, __be16 *port)
{
- unsigned char *p;
+ const unsigned char *p;
int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
int len;
@@ -625,7 +626,7 @@ int get_h225_addr(struct nf_conn *ct, unsigned char *data,
TransportAddress *taddr,
union nf_inet_addr *addr, __be16 *port)
{
- unsigned char *p;
+ const unsigned char *p;
int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
int len;
@@ -704,9 +705,8 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
/* If the calling party is on the same side of the forward-to party,
* we don't need to track the second call */
-static int callforward_do_filter(union nf_inet_addr *src,
- union nf_inet_addr *dst,
- int family)
+static int callforward_do_filter(const union nf_inet_addr *src,
+ const union nf_inet_addr *dst, int family)
{
const struct nf_afinfo *afinfo;
struct flowi fl1, fl2;
@@ -1185,7 +1185,8 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
static unsigned char *get_udp_data(struct sk_buff *skb, unsigned int protoff,
int *datalen)
{
- struct udphdr _uh, *uh;
+ const struct udphdr *uh;
+ struct udphdr _uh;
int dataoff;
uh = skb_header_pointer(skb, protoff, sizeof(_uh), &_uh);
@@ -1415,7 +1416,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
nf_ct_refresh(ct, skb, info->timeout * HZ);
/* Set expect timeout */
- read_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3,
info->sig_port[!dir]);
if (exp) {
@@ -1425,7 +1426,7 @@ static int process_rcf(struct sk_buff *skb, struct nf_conn *ct,
NF_CT_DUMP_TUPLE(&exp->tuple);
set_expect_timeout(exp, info->timeout);
}
- read_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
}
return 0;
@@ -1468,7 +1469,7 @@ static int process_arq(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
unsigned char **data, AdmissionRequest *arq)
{
- struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
+ const struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
int dir = CTINFO2DIR(ctinfo);
__be16 port;
union nf_inet_addr addr;
diff --git a/net/netfilter/nf_conntrack_h323_types.c b/net/netfilter/nf_conntrack_h323_types.c
index 3a21fdf1a26..d880f3523c1 100644
--- a/net/netfilter/nf_conntrack_h323_types.c
+++ b/net/netfilter/nf_conntrack_h323_types.c
@@ -5,22 +5,22 @@
* This source code is licensed under General Public License version 2.
*/
-static field_t _TransportAddress_ipAddress[] = { /* SEQUENCE */
+static const struct field_t _TransportAddress_ipAddress[] = { /* SEQUENCE */
{FNAME("ip") OCTSTR, FIXD, 4, 0, DECODE,
offsetof(TransportAddress_ipAddress, ip), NULL},
{FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress_ipSourceRoute_route[] = { /* SEQUENCE OF */
+static const struct field_t _TransportAddress_ipSourceRoute_route[] = { /* SEQUENCE OF */
{FNAME("item") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress_ipSourceRoute_routing[] = { /* CHOICE */
+static const struct field_t _TransportAddress_ipSourceRoute_routing[] = { /* CHOICE */
{FNAME("strict") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("loose") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress_ipSourceRoute[] = { /* SEQUENCE */
+static const struct field_t _TransportAddress_ipSourceRoute[] = { /* SEQUENCE */
{FNAME("ip") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
{FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("route") SEQOF, SEMI, 0, 0, SKIP, 0,
@@ -29,37 +29,37 @@ static field_t _TransportAddress_ipSourceRoute[] = { /* SEQUENCE */
_TransportAddress_ipSourceRoute_routing},
};
-static field_t _TransportAddress_ipxAddress[] = { /* SEQUENCE */
+static const struct field_t _TransportAddress_ipxAddress[] = { /* SEQUENCE */
{FNAME("node") OCTSTR, FIXD, 6, 0, SKIP, 0, NULL},
{FNAME("netnum") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
{FNAME("port") OCTSTR, FIXD, 2, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */
+static const struct field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */
{FNAME("ip") OCTSTR, FIXD, 16, 0, DECODE,
offsetof(TransportAddress_ip6Address, ip), NULL},
{FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H221NonStandard[] = { /* SEQUENCE */
+static const struct field_t _H221NonStandard[] = { /* SEQUENCE */
{FNAME("t35CountryCode") INT, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("t35Extension") INT, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("manufacturerCode") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _NonStandardIdentifier[] = { /* CHOICE */
+static const struct field_t _NonStandardIdentifier[] = { /* CHOICE */
{FNAME("object") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("h221NonStandard") SEQ, 0, 3, 3, SKIP | EXT, 0,
_H221NonStandard},
};
-static field_t _NonStandardParameter[] = { /* SEQUENCE */
+static const struct field_t _NonStandardParameter[] = { /* SEQUENCE */
{FNAME("nonStandardIdentifier") CHOICE, 1, 2, 2, SKIP | EXT, 0,
_NonStandardIdentifier},
{FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _TransportAddress[] = { /* CHOICE */
+static const struct field_t _TransportAddress[] = { /* CHOICE */
{FNAME("ipAddress") SEQ, 0, 2, 2, DECODE,
offsetof(TransportAddress, ipAddress), _TransportAddress_ipAddress},
{FNAME("ipSourceRoute") SEQ, 0, 4, 4, SKIP | EXT, 0,
@@ -75,7 +75,7 @@ static field_t _TransportAddress[] = { /* CHOICE */
_NonStandardParameter},
};
-static field_t _AliasAddress[] = { /* CHOICE */
+static const struct field_t _AliasAddress[] = { /* CHOICE */
{FNAME("dialedDigits") NUMDGT, 7, 1, 0, SKIP, 0, NULL},
{FNAME("h323-ID") BMPSTR, BYTE, 1, 0, SKIP, 0, NULL},
{FNAME("url-ID") IA5STR, WORD, 1, 0, SKIP, 0, NULL},
@@ -85,78 +85,78 @@ static field_t _AliasAddress[] = { /* CHOICE */
{FNAME("mobileUIM") CHOICE, 1, 2, 2, SKIP | EXT, 0, NULL},
};
-static field_t _Setup_UUIE_sourceAddress[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_sourceAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _VendorIdentifier[] = { /* SEQUENCE */
+static const struct field_t _VendorIdentifier[] = { /* SEQUENCE */
{FNAME("vendor") SEQ, 0, 3, 3, SKIP | EXT, 0, _H221NonStandard},
{FNAME("productId") OCTSTR, BYTE, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("versionId") OCTSTR, BYTE, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _GatekeeperInfo[] = { /* SEQUENCE */
+static const struct field_t _GatekeeperInfo[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
};
-static field_t _H310Caps[] = { /* SEQUENCE */
+static const struct field_t _H310Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H320Caps[] = { /* SEQUENCE */
+static const struct field_t _H320Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H321Caps[] = { /* SEQUENCE */
+static const struct field_t _H321Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H322Caps[] = { /* SEQUENCE */
+static const struct field_t _H322Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H323Caps[] = { /* SEQUENCE */
+static const struct field_t _H323Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H324Caps[] = { /* SEQUENCE */
+static const struct field_t _H324Caps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _VoiceCaps[] = { /* SEQUENCE */
+static const struct field_t _VoiceCaps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _T120OnlyCaps[] = { /* SEQUENCE */
+static const struct field_t _T120OnlyCaps[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("dataRatesSupported") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("supportedPrefixes") SEQOF, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _SupportedProtocols[] = { /* CHOICE */
+static const struct field_t _SupportedProtocols[] = { /* CHOICE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP, 0,
_NonStandardParameter},
{FNAME("h310") SEQ, 1, 1, 3, SKIP | EXT, 0, _H310Caps},
@@ -171,29 +171,29 @@ static field_t _SupportedProtocols[] = { /* CHOICE */
{FNAME("t38FaxAnnexbOnly") SEQ, 2, 5, 5, SKIP | EXT, 0, NULL},
};
-static field_t _GatewayInfo_protocol[] = { /* SEQUENCE OF */
+static const struct field_t _GatewayInfo_protocol[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 4, 9, 11, SKIP | EXT, 0, _SupportedProtocols},
};
-static field_t _GatewayInfo[] = { /* SEQUENCE */
+static const struct field_t _GatewayInfo[] = { /* SEQUENCE */
{FNAME("protocol") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
_GatewayInfo_protocol},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
};
-static field_t _McuInfo[] = { /* SEQUENCE */
+static const struct field_t _McuInfo[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("protocol") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
};
-static field_t _TerminalInfo[] = { /* SEQUENCE */
+static const struct field_t _TerminalInfo[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
};
-static field_t _EndpointType[] = { /* SEQUENCE */
+static const struct field_t _EndpointType[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("vendor") SEQ, 2, 3, 3, SKIP | EXT | OPT, 0,
@@ -210,19 +210,19 @@ static field_t _EndpointType[] = { /* SEQUENCE */
0, NULL},
};
-static field_t _Setup_UUIE_destinationAddress[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_destinationAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _Setup_UUIE_destExtraCallInfo[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_destExtraCallInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _Setup_UUIE_destExtraCRV[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_destExtraCRV[] = { /* SEQUENCE OF */
{FNAME("item") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _Setup_UUIE_conferenceGoal[] = { /* CHOICE */
+static const struct field_t _Setup_UUIE_conferenceGoal[] = { /* CHOICE */
{FNAME("create") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("join") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("invite") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -231,12 +231,12 @@ static field_t _Setup_UUIE_conferenceGoal[] = { /* CHOICE */
0, NULL},
};
-static field_t _Q954Details[] = { /* SEQUENCE */
+static const struct field_t _Q954Details[] = { /* SEQUENCE */
{FNAME("conferenceCalling") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("threePartyService") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _QseriesOptions[] = { /* SEQUENCE */
+static const struct field_t _QseriesOptions[] = { /* SEQUENCE */
{FNAME("q932Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("q951Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("q952Full") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -247,32 +247,32 @@ static field_t _QseriesOptions[] = { /* SEQUENCE */
{FNAME("q954Info") SEQ, 0, 2, 2, SKIP | EXT, 0, _Q954Details},
};
-static field_t _CallType[] = { /* CHOICE */
+static const struct field_t _CallType[] = { /* CHOICE */
{FNAME("pointToPoint") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("oneToN") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("nToOne") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("nToN") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H245_NonStandardIdentifier_h221NonStandard[] = { /* SEQUENCE */
+static const struct field_t _H245_NonStandardIdentifier_h221NonStandard[] = { /* SEQUENCE */
{FNAME("t35CountryCode") INT, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("t35Extension") INT, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("manufacturerCode") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H245_NonStandardIdentifier[] = { /* CHOICE */
+static const struct field_t _H245_NonStandardIdentifier[] = { /* CHOICE */
{FNAME("object") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("h221NonStandard") SEQ, 0, 3, 3, SKIP, 0,
_H245_NonStandardIdentifier_h221NonStandard},
};
-static field_t _H245_NonStandardParameter[] = { /* SEQUENCE */
+static const struct field_t _H245_NonStandardParameter[] = { /* SEQUENCE */
{FNAME("nonStandardIdentifier") CHOICE, 1, 2, 2, SKIP, 0,
_H245_NonStandardIdentifier},
{FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H261VideoCapability[] = { /* SEQUENCE */
+static const struct field_t _H261VideoCapability[] = { /* SEQUENCE */
{FNAME("qcifMPI") INT, 2, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("cifMPI") INT, 2, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("temporalSpatialTradeOffCapability") BOOL, FIXD, 0, 0, SKIP, 0,
@@ -282,7 +282,7 @@ static field_t _H261VideoCapability[] = { /* SEQUENCE */
{FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H262VideoCapability[] = { /* SEQUENCE */
+static const struct field_t _H262VideoCapability[] = { /* SEQUENCE */
{FNAME("profileAndLevel-SPatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("profileAndLevel-MPatLL") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("profileAndLevel-MPatML") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -304,7 +304,7 @@ static field_t _H262VideoCapability[] = { /* SEQUENCE */
{FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _H263VideoCapability[] = { /* SEQUENCE */
+static const struct field_t _H263VideoCapability[] = { /* SEQUENCE */
{FNAME("sqcifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("qcifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("cifMPI") INT, 5, 1, 0, SKIP | OPT, 0, NULL},
@@ -330,7 +330,7 @@ static field_t _H263VideoCapability[] = { /* SEQUENCE */
{FNAME("h263Options") SEQ, 5, 29, 31, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _IS11172VideoCapability[] = { /* SEQUENCE */
+static const struct field_t _IS11172VideoCapability[] = { /* SEQUENCE */
{FNAME("constrainedBitstream") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("videoBitRate") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("vbvBufferSize") INT, CONS, 0, 0, SKIP | OPT, 0, NULL},
@@ -341,7 +341,7 @@ static field_t _IS11172VideoCapability[] = { /* SEQUENCE */
{FNAME("videoBadMBsCap") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _VideoCapability[] = { /* CHOICE */
+static const struct field_t _VideoCapability[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("h261VideoCapability") SEQ, 2, 5, 6, SKIP | EXT, 0,
@@ -355,12 +355,12 @@ static field_t _VideoCapability[] = { /* CHOICE */
{FNAME("genericVideoCapability") SEQ, 5, 6, 6, SKIP | EXT, 0, NULL},
};
-static field_t _AudioCapability_g7231[] = { /* SEQUENCE */
+static const struct field_t _AudioCapability_g7231[] = { /* SEQUENCE */
{FNAME("maxAl-sduAudioFrames") INT, BYTE, 1, 0, SKIP, 0, NULL},
{FNAME("silenceSuppression") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _IS11172AudioCapability[] = { /* SEQUENCE */
+static const struct field_t _IS11172AudioCapability[] = { /* SEQUENCE */
{FNAME("audioLayer1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("audioLayer2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("audioLayer3") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -372,7 +372,7 @@ static field_t _IS11172AudioCapability[] = { /* SEQUENCE */
{FNAME("bitRate") INT, WORD, 1, 0, SKIP, 0, NULL},
};
-static field_t _IS13818AudioCapability[] = { /* SEQUENCE */
+static const struct field_t _IS13818AudioCapability[] = { /* SEQUENCE */
{FNAME("audioLayer1") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("audioLayer2") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("audioLayer3") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -396,7 +396,7 @@ static field_t _IS13818AudioCapability[] = { /* SEQUENCE */
{FNAME("bitRate") INT, WORD, 1, 0, SKIP, 0, NULL},
};
-static field_t _AudioCapability[] = { /* CHOICE */
+static const struct field_t _AudioCapability[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("g711Alaw64k") INT, BYTE, 1, 0, SKIP, 0, NULL},
@@ -424,7 +424,7 @@ static field_t _AudioCapability[] = { /* CHOICE */
{FNAME("g729Extensions") SEQ, 1, 8, 8, SKIP | EXT, 0, NULL},
};
-static field_t _DataProtocolCapability[] = { /* CHOICE */
+static const struct field_t _DataProtocolCapability[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("v14buffered") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -442,7 +442,7 @@ static field_t _DataProtocolCapability[] = { /* CHOICE */
{FNAME("udp") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _T84Profile_t84Restricted[] = { /* SEQUENCE */
+static const struct field_t _T84Profile_t84Restricted[] = { /* SEQUENCE */
{FNAME("qcif") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("cif") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("ccir601Seq") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -464,25 +464,25 @@ static field_t _T84Profile_t84Restricted[] = { /* SEQUENCE */
{FNAME("digPhotoHighProg") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _T84Profile[] = { /* CHOICE */
+static const struct field_t _T84Profile[] = { /* CHOICE */
{FNAME("t84Unrestricted") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("t84Restricted") SEQ, 0, 19, 19, SKIP | EXT, 0,
_T84Profile_t84Restricted},
};
-static field_t _DataApplicationCapability_application_t84[] = { /* SEQUENCE */
+static const struct field_t _DataApplicationCapability_application_t84[] = { /* SEQUENCE */
{FNAME("t84Protocol") CHOICE, 3, 7, 14, SKIP | EXT, 0,
_DataProtocolCapability},
{FNAME("t84Profile") CHOICE, 1, 2, 2, SKIP, 0, _T84Profile},
};
-static field_t _DataApplicationCapability_application_nlpid[] = { /* SEQUENCE */
+static const struct field_t _DataApplicationCapability_application_nlpid[] = { /* SEQUENCE */
{FNAME("nlpidProtocol") CHOICE, 3, 7, 14, SKIP | EXT, 0,
_DataProtocolCapability},
{FNAME("nlpidData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _DataApplicationCapability_application[] = { /* CHOICE */
+static const struct field_t _DataApplicationCapability_application[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("t120") CHOICE, 3, 7, 14, DECODE | EXT,
@@ -509,20 +509,20 @@ static field_t _DataApplicationCapability_application[] = { /* CHOICE */
{FNAME("genericDataCapability") SEQ, 5, 6, 6, SKIP | EXT, 0, NULL},
};
-static field_t _DataApplicationCapability[] = { /* SEQUENCE */
+static const struct field_t _DataApplicationCapability[] = { /* SEQUENCE */
{FNAME("application") CHOICE, 4, 10, 14, DECODE | EXT,
offsetof(DataApplicationCapability, application),
_DataApplicationCapability_application},
{FNAME("maxBitRate") INT, CONS, 0, 0, SKIP, 0, NULL},
};
-static field_t _EncryptionMode[] = { /* CHOICE */
+static const struct field_t _EncryptionMode[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("h233Encryption") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _DataType[] = { /* CHOICE */
+static const struct field_t _DataType[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("nullData") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -538,7 +538,7 @@ static field_t _DataType[] = { /* CHOICE */
{FNAME("multiplexedStream") SEQ, 0, 2, 2, SKIP | EXT, 0, NULL},
};
-static field_t _H222LogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _H222LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("resourceID") INT, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("subChannelID") INT, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("pcr-pid") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
@@ -546,12 +546,12 @@ static field_t _H222LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("streamDescriptors") OCTSTR, SEMI, 0, 0, SKIP | OPT, 0, NULL},
};
-static field_t _H223LogicalChannelParameters_adaptationLayerType_al3[] = { /* SEQUENCE */
+static const struct field_t _H223LogicalChannelParameters_adaptationLayerType_al3[] = { /* SEQUENCE */
{FNAME("controlFieldOctets") INT, 2, 0, 0, SKIP, 0, NULL},
{FNAME("sendBufferSize") INT, CONS, 0, 0, SKIP, 0, NULL},
};
-static field_t _H223LogicalChannelParameters_adaptationLayerType[] = { /* CHOICE */
+static const struct field_t _H223LogicalChannelParameters_adaptationLayerType[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0,
_H245_NonStandardParameter},
{FNAME("al1Framed") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -565,53 +565,53 @@ static field_t _H223LogicalChannelParameters_adaptationLayerType[] = { /* CHOICE
{FNAME("al3M") SEQ, 0, 5, 6, SKIP | EXT, 0, NULL},
};
-static field_t _H223LogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _H223LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("adaptationLayerType") CHOICE, 3, 6, 9, SKIP | EXT, 0,
_H223LogicalChannelParameters_adaptationLayerType},
{FNAME("segmentableFlag") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _CRCLength[] = { /* CHOICE */
+static const struct field_t _CRCLength[] = { /* CHOICE */
{FNAME("crc8bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("crc16bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("crc32bit") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76HDLCParameters[] = { /* SEQUENCE */
+static const struct field_t _V76HDLCParameters[] = { /* SEQUENCE */
{FNAME("crcLength") CHOICE, 2, 3, 3, SKIP | EXT, 0, _CRCLength},
{FNAME("n401") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("loopbackTestProcedure") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76LogicalChannelParameters_suspendResume[] = { /* CHOICE */
+static const struct field_t _V76LogicalChannelParameters_suspendResume[] = { /* CHOICE */
{FNAME("noSuspendResume") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("suspendResumewAddress") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("suspendResumewoAddress") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76LogicalChannelParameters_mode_eRM_recovery[] = { /* CHOICE */
+static const struct field_t _V76LogicalChannelParameters_mode_eRM_recovery[] = { /* CHOICE */
{FNAME("rej") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("sREJ") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("mSREJ") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76LogicalChannelParameters_mode_eRM[] = { /* SEQUENCE */
+static const struct field_t _V76LogicalChannelParameters_mode_eRM[] = { /* SEQUENCE */
{FNAME("windowSize") INT, 7, 1, 0, SKIP, 0, NULL},
{FNAME("recovery") CHOICE, 2, 3, 3, SKIP | EXT, 0,
_V76LogicalChannelParameters_mode_eRM_recovery},
};
-static field_t _V76LogicalChannelParameters_mode[] = { /* CHOICE */
+static const struct field_t _V76LogicalChannelParameters_mode[] = { /* CHOICE */
{FNAME("eRM") SEQ, 0, 2, 2, SKIP | EXT, 0,
_V76LogicalChannelParameters_mode_eRM},
{FNAME("uNERM") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V75Parameters[] = { /* SEQUENCE */
+static const struct field_t _V75Parameters[] = { /* SEQUENCE */
{FNAME("audioHeaderPresent") BOOL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _V76LogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _V76LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("hdlcParameters") SEQ, 0, 3, 3, SKIP | EXT, 0,
_V76HDLCParameters},
{FNAME("suspendResume") CHOICE, 2, 3, 3, SKIP | EXT, 0,
@@ -622,38 +622,38 @@ static field_t _V76LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("v75Parameters") SEQ, 0, 1, 1, SKIP | EXT, 0, _V75Parameters},
};
-static field_t _H2250LogicalChannelParameters_nonStandard[] = { /* SEQUENCE OF */
+static const struct field_t _H2250LogicalChannelParameters_nonStandard[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 0, 2, 2, SKIP, 0, _H245_NonStandardParameter},
};
-static field_t _UnicastAddress_iPAddress[] = { /* SEQUENCE */
+static const struct field_t _UnicastAddress_iPAddress[] = { /* SEQUENCE */
{FNAME("network") OCTSTR, FIXD, 4, 0, DECODE,
offsetof(UnicastAddress_iPAddress, network), NULL},
{FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iPXAddress[] = { /* SEQUENCE */
+static const struct field_t _UnicastAddress_iPXAddress[] = { /* SEQUENCE */
{FNAME("node") OCTSTR, FIXD, 6, 0, SKIP, 0, NULL},
{FNAME("netnum") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
{FNAME("tsapIdentifier") OCTSTR, FIXD, 2, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iP6Address[] = { /* SEQUENCE */
+static const struct field_t _UnicastAddress_iP6Address[] = { /* SEQUENCE */
{FNAME("network") OCTSTR, FIXD, 16, 0, DECODE,
offsetof(UnicastAddress_iP6Address, network), NULL},
{FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iPSourceRouteAddress_routing[] = { /* CHOICE */
+static const struct field_t _UnicastAddress_iPSourceRouteAddress_routing[] = { /* CHOICE */
{FNAME("strict") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("loose") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iPSourceRouteAddress_route[] = { /* SEQUENCE OF */
+static const struct field_t _UnicastAddress_iPSourceRouteAddress_route[] = { /* SEQUENCE OF */
{FNAME("item") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
};
-static field_t _UnicastAddress_iPSourceRouteAddress[] = { /* SEQUENCE */
+static const struct field_t _UnicastAddress_iPSourceRouteAddress[] = { /* SEQUENCE */
{FNAME("routing") CHOICE, 1, 2, 2, SKIP, 0,
_UnicastAddress_iPSourceRouteAddress_routing},
{FNAME("network") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
@@ -662,7 +662,7 @@ static field_t _UnicastAddress_iPSourceRouteAddress[] = { /* SEQUENCE */
_UnicastAddress_iPSourceRouteAddress_route},
};
-static field_t _UnicastAddress[] = { /* CHOICE */
+static const struct field_t _UnicastAddress[] = { /* CHOICE */
{FNAME("iPAddress") SEQ, 0, 2, 2, DECODE | EXT,
offsetof(UnicastAddress, iPAddress), _UnicastAddress_iPAddress},
{FNAME("iPXAddress") SEQ, 0, 3, 3, SKIP | EXT, 0,
@@ -676,17 +676,17 @@ static field_t _UnicastAddress[] = { /* CHOICE */
{FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, NULL},
};
-static field_t _MulticastAddress_iPAddress[] = { /* SEQUENCE */
+static const struct field_t _MulticastAddress_iPAddress[] = { /* SEQUENCE */
{FNAME("network") OCTSTR, FIXD, 4, 0, SKIP, 0, NULL},
{FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _MulticastAddress_iP6Address[] = { /* SEQUENCE */
+static const struct field_t _MulticastAddress_iP6Address[] = { /* SEQUENCE */
{FNAME("network") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
{FNAME("tsapIdentifier") INT, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _MulticastAddress[] = { /* CHOICE */
+static const struct field_t _MulticastAddress[] = { /* CHOICE */
{FNAME("iPAddress") SEQ, 0, 2, 2, SKIP | EXT, 0,
_MulticastAddress_iPAddress},
{FNAME("iP6Address") SEQ, 0, 2, 2, SKIP | EXT, 0,
@@ -695,14 +695,14 @@ static field_t _MulticastAddress[] = { /* CHOICE */
{FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, NULL},
};
-static field_t _H245_TransportAddress[] = { /* CHOICE */
+static const struct field_t _H245_TransportAddress[] = { /* CHOICE */
{FNAME("unicastAddress") CHOICE, 3, 5, 7, DECODE | EXT,
offsetof(H245_TransportAddress, unicastAddress), _UnicastAddress},
{FNAME("multicastAddress") CHOICE, 1, 2, 4, SKIP | EXT, 0,
_MulticastAddress},
};
-static field_t _H2250LogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _H2250LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("nonStandard") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
_H2250LogicalChannelParameters_nonStandard},
{FNAME("sessionID") INT, BYTE, 0, 0, SKIP, 0, NULL},
@@ -728,7 +728,7 @@ static field_t _H2250LogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("source") SEQ, 0, 2, 2, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
+static const struct field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
{FNAME("h222LogicalChannelParameters") SEQ, 3, 5, 5, SKIP | EXT, 0,
_H222LogicalChannelParameters},
{FNAME("h223LogicalChannelParameters") SEQ, 0, 2, 2, SKIP | EXT, 0,
@@ -742,7 +742,7 @@ static field_t _OpenLogicalChannel_forwardLogicalChannelParameters_multiplexPara
{FNAME("none") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("dataType") CHOICE, 3, 6, 9, DECODE | EXT,
offsetof(OpenLogicalChannel_forwardLogicalChannelParameters,
@@ -756,7 +756,7 @@ static field_t _OpenLogicalChannel_forwardLogicalChannelParameters[] = { /* SEQU
{FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
+static const struct field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
{FNAME("h223LogicalChannelParameters") SEQ, 0, 2, 2, SKIP | EXT, 0,
_H223LogicalChannelParameters},
{FNAME("v76LogicalChannelParameters") SEQ, 0, 5, 5, SKIP | EXT, 0,
@@ -767,7 +767,7 @@ static field_t _OpenLogicalChannel_reverseLogicalChannelParameters_multiplexPara
h2250LogicalChannelParameters), _H2250LogicalChannelParameters},
};
-static field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("dataType") CHOICE, 3, 6, 9, SKIP | EXT, 0, _DataType},
{FNAME("multiplexParameters") CHOICE, 1, 2, 3, DECODE | EXT | OPT,
offsetof(OpenLogicalChannel_reverseLogicalChannelParameters,
@@ -778,23 +778,23 @@ static field_t _OpenLogicalChannel_reverseLogicalChannelParameters[] = { /* SEQU
{FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _NetworkAccessParameters_distribution[] = { /* CHOICE */
+static const struct field_t _NetworkAccessParameters_distribution[] = { /* CHOICE */
{FNAME("unicast") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("multicast") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _Q2931Address_address[] = { /* CHOICE */
+static const struct field_t _Q2931Address_address[] = { /* CHOICE */
{FNAME("internationalNumber") NUMSTR, 4, 1, 0, SKIP, 0, NULL},
{FNAME("nsapAddress") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
};
-static field_t _Q2931Address[] = { /* SEQUENCE */
+static const struct field_t _Q2931Address[] = { /* SEQUENCE */
{FNAME("address") CHOICE, 1, 2, 2, SKIP | EXT, 0,
_Q2931Address_address},
{FNAME("subaddress") OCTSTR, 5, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _NetworkAccessParameters_networkAddress[] = { /* CHOICE */
+static const struct field_t _NetworkAccessParameters_networkAddress[] = { /* CHOICE */
{FNAME("q2931Address") SEQ, 1, 2, 2, SKIP | EXT, 0, _Q2931Address},
{FNAME("e164Address") NUMDGT, 7, 1, 0, SKIP, 0, NULL},
{FNAME("localAreaAddress") CHOICE, 1, 2, 2, DECODE | EXT,
@@ -802,7 +802,7 @@ static field_t _NetworkAccessParameters_networkAddress[] = { /* CHOICE */
_H245_TransportAddress},
};
-static field_t _NetworkAccessParameters[] = { /* SEQUENCE */
+static const struct field_t _NetworkAccessParameters[] = { /* SEQUENCE */
{FNAME("distribution") CHOICE, 1, 2, 2, SKIP | EXT | OPT, 0,
_NetworkAccessParameters_distribution},
{FNAME("networkAddress") CHOICE, 2, 3, 3, DECODE | EXT,
@@ -814,7 +814,7 @@ static field_t _NetworkAccessParameters[] = { /* SEQUENCE */
NULL},
};
-static field_t _OpenLogicalChannel[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannel[] = { /* SEQUENCE */
{FNAME("forwardLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("forwardLogicalChannelParameters") SEQ, 1, 3, 5, DECODE | EXT,
offsetof(OpenLogicalChannel, forwardLogicalChannelParameters),
@@ -829,13 +829,13 @@ static field_t _OpenLogicalChannel[] = { /* SEQUENCE */
{FNAME("encryptionSync") SEQ, 2, 4, 4, STOP | EXT | OPT, 0, NULL},
};
-static field_t _Setup_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Setup_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Setup_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Setup_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
offsetof(Setup_UUIE, h245Address), _TransportAddress},
@@ -894,13 +894,13 @@ static field_t _Setup_UUIE[] = { /* SEQUENCE */
NULL},
};
-static field_t _CallProceeding_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _CallProceeding_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _CallProceeding_UUIE[] = { /* SEQUENCE */
+static const struct field_t _CallProceeding_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
_EndpointType},
@@ -920,13 +920,13 @@ static field_t _CallProceeding_UUIE[] = { /* SEQUENCE */
{FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _Connect_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Connect_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Connect_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Connect_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("h245Address") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
offsetof(Connect_UUIE, h245Address), _TransportAddress},
@@ -954,13 +954,13 @@ static field_t _Connect_UUIE[] = { /* SEQUENCE */
{FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _Alerting_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Alerting_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Alerting_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Alerting_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
_EndpointType},
@@ -986,7 +986,7 @@ static field_t _Alerting_UUIE[] = { /* SEQUENCE */
{FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _Information_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Information_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("callIdentifier") SEQ, 0, 1, 1, SKIP | EXT, 0, NULL},
{FNAME("tokens") SEQOF, SEMI, 0, 0, SKIP | OPT, 0, NULL},
@@ -996,7 +996,7 @@ static field_t _Information_UUIE[] = { /* SEQUENCE */
{FNAME("circuitInfo") SEQ, 3, 3, 3, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _ReleaseCompleteReason[] = { /* CHOICE */
+static const struct field_t _ReleaseCompleteReason[] = { /* CHOICE */
{FNAME("noBandwidth") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("gatekeeperResources") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("unreachableDestination") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -1022,7 +1022,7 @@ static field_t _ReleaseCompleteReason[] = { /* CHOICE */
{FNAME("tunnelledSignallingRejected") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _ReleaseComplete_UUIE[] = { /* SEQUENCE */
+static const struct field_t _ReleaseComplete_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("reason") CHOICE, 4, 12, 22, SKIP | EXT | OPT, 0,
_ReleaseCompleteReason},
@@ -1039,11 +1039,11 @@ static field_t _ReleaseComplete_UUIE[] = { /* SEQUENCE */
{FNAME("featureSet") SEQ, 3, 4, 4, SKIP | EXT | OPT, 0, NULL},
};
-static field_t _Facility_UUIE_alternativeAliasAddress[] = { /* SEQUENCE OF */
+static const struct field_t _Facility_UUIE_alternativeAliasAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _FacilityReason[] = { /* CHOICE */
+static const struct field_t _FacilityReason[] = { /* CHOICE */
{FNAME("routeCallToGatekeeper") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("callForwarded") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("routeCallToMC") NUL, FIXD, 0, 0, SKIP, 0, NULL},
@@ -1057,13 +1057,13 @@ static field_t _FacilityReason[] = { /* CHOICE */
{FNAME("transportedInformation") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _Facility_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Facility_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Facility_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Facility_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("alternativeAddress") CHOICE, 3, 7, 7, DECODE | EXT | OPT,
offsetof(Facility_UUIE, alternativeAddress), _TransportAddress},
@@ -1094,17 +1094,17 @@ static field_t _Facility_UUIE[] = { /* SEQUENCE */
NULL},
};
-static field_t _CallIdentifier[] = { /* SEQUENCE */
+static const struct field_t _CallIdentifier[] = { /* SEQUENCE */
{FNAME("guid") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
};
-static field_t _SecurityServiceMode[] = { /* CHOICE */
+static const struct field_t _SecurityServiceMode[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0, _NonStandardParameter},
{FNAME("none") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("default") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _SecurityCapabilities[] = { /* SEQUENCE */
+static const struct field_t _SecurityCapabilities[] = { /* SEQUENCE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("encryption") CHOICE, 2, 3, 3, SKIP | EXT, 0,
@@ -1115,30 +1115,30 @@ static field_t _SecurityCapabilities[] = { /* SEQUENCE */
_SecurityServiceMode},
};
-static field_t _H245Security[] = { /* CHOICE */
+static const struct field_t _H245Security[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 2, 2, SKIP, 0, _NonStandardParameter},
{FNAME("noSecurity") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("tls") SEQ, 1, 4, 4, SKIP | EXT, 0, _SecurityCapabilities},
{FNAME("ipsec") SEQ, 1, 4, 4, SKIP | EXT, 0, _SecurityCapabilities},
};
-static field_t _DHset[] = { /* SEQUENCE */
+static const struct field_t _DHset[] = { /* SEQUENCE */
{FNAME("halfkey") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("modSize") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
{FNAME("generator") BITSTR, WORD, 0, 0, SKIP, 0, NULL},
};
-static field_t _TypedCertificate[] = { /* SEQUENCE */
+static const struct field_t _TypedCertificate[] = { /* SEQUENCE */
{FNAME("type") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("certificate") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _H235_NonStandardParameter[] = { /* SEQUENCE */
+static const struct field_t _H235_NonStandardParameter[] = { /* SEQUENCE */
{FNAME("nonStandardIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("data") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _ClearToken[] = { /* SEQUENCE */
+static const struct field_t _ClearToken[] = { /* SEQUENCE */
{FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("timeStamp") INT, CONS, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("password") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
@@ -1154,120 +1154,120 @@ static field_t _ClearToken[] = { /* SEQUENCE */
{FNAME("sendersID") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _Progress_UUIE_tokens[] = { /* SEQUENCE OF */
+static const struct field_t _Progress_UUIE_tokens[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 8, 9, 11, SKIP | EXT, 0, _ClearToken},
};
-static field_t _Params[] = { /* SEQUENCE */
+static const struct field_t _Params[] = { /* SEQUENCE */
{FNAME("ranInt") INT, UNCO, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("iv8") OCTSTR, FIXD, 8, 0, SKIP | OPT, 0, NULL},
{FNAME("iv16") OCTSTR, FIXD, 16, 0, SKIP | OPT, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoEPPwdHash_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPPwdHash_token[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoEPPwdHash[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPPwdHash[] = { /* SEQUENCE */
{FNAME("alias") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
{FNAME("timeStamp") INT, CONS, 1, 0, SKIP, 0, NULL},
{FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
_CryptoH323Token_cryptoEPPwdHash_token},
};
-static field_t _CryptoH323Token_cryptoGKPwdHash_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKPwdHash_token[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoGKPwdHash[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKPwdHash[] = { /* SEQUENCE */
{FNAME("gatekeeperId") BMPSTR, 7, 1, 0, SKIP, 0, NULL},
{FNAME("timeStamp") INT, CONS, 1, 0, SKIP, 0, NULL},
{FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
_CryptoH323Token_cryptoGKPwdHash_token},
};
-static field_t _CryptoH323Token_cryptoEPPwdEncr[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPPwdEncr[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoGKPwdEncr[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKPwdEncr[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoEPCert[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoEPCert[] = { /* SEQUENCE */
{FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoGKCert[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoGKCert[] = { /* SEQUENCE */
{FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoH323Token_cryptoFastStart[] = { /* SEQUENCE */
+static const struct field_t _CryptoH323Token_cryptoFastStart[] = { /* SEQUENCE */
{FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken_cryptoEncryptedToken_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoEncryptedToken_token[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken_cryptoEncryptedToken[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoEncryptedToken[] = { /* SEQUENCE */
{FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
_CryptoToken_cryptoEncryptedToken_token},
};
-static field_t _CryptoToken_cryptoSignedToken_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoSignedToken_token[] = { /* SEQUENCE */
{FNAME("toBeSigned") SEQ, 8, 9, 11, SKIP | OPEN | EXT, 0, NULL},
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("signature") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken_cryptoSignedToken[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoSignedToken[] = { /* SEQUENCE */
{FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("token") SEQ, 0, 4, 4, SKIP, 0,
_CryptoToken_cryptoSignedToken_token},
};
-static field_t _CryptoToken_cryptoHashedToken_token[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoHashedToken_token[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("hash") BITSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken_cryptoHashedToken[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoHashedToken[] = { /* SEQUENCE */
{FNAME("tokenOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("hashedVals") SEQ, 8, 9, 11, SKIP | EXT, 0, _ClearToken},
{FNAME("token") SEQ, 0, 3, 3, SKIP, 0,
_CryptoToken_cryptoHashedToken_token},
};
-static field_t _CryptoToken_cryptoPwdEncr[] = { /* SEQUENCE */
+static const struct field_t _CryptoToken_cryptoPwdEncr[] = { /* SEQUENCE */
{FNAME("algorithmOID") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("paramS") SEQ, 2, 2, 3, SKIP | EXT, 0, _Params},
{FNAME("encryptedData") OCTSTR, SEMI, 0, 0, SKIP, 0, NULL},
};
-static field_t _CryptoToken[] = { /* CHOICE */
+static const struct field_t _CryptoToken[] = { /* CHOICE */
{FNAME("cryptoEncryptedToken") SEQ, 0, 2, 2, SKIP, 0,
_CryptoToken_cryptoEncryptedToken},
{FNAME("cryptoSignedToken") SEQ, 0, 2, 2, SKIP, 0,
@@ -1278,7 +1278,7 @@ static field_t _CryptoToken[] = { /* CHOICE */
_CryptoToken_cryptoPwdEncr},
};
-static field_t _CryptoH323Token[] = { /* CHOICE */
+static const struct field_t _CryptoH323Token[] = { /* CHOICE */
{FNAME("cryptoEPPwdHash") SEQ, 0, 3, 3, SKIP, 0,
_CryptoH323Token_cryptoEPPwdHash},
{FNAME("cryptoGKPwdHash") SEQ, 0, 3, 3, SKIP, 0,
@@ -1297,17 +1297,17 @@ static field_t _CryptoH323Token[] = { /* CHOICE */
_CryptoToken},
};
-static field_t _Progress_UUIE_cryptoTokens[] = { /* SEQUENCE OF */
+static const struct field_t _Progress_UUIE_cryptoTokens[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 8, 8, SKIP | EXT, 0, _CryptoH323Token},
};
-static field_t _Progress_UUIE_fastStart[] = { /* SEQUENCE OF */
+static const struct field_t _Progress_UUIE_fastStart[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 1, 3, 5, DECODE | OPEN | EXT,
sizeof(OpenLogicalChannel), _OpenLogicalChannel}
,
};
-static field_t _Progress_UUIE[] = { /* SEQUENCE */
+static const struct field_t _Progress_UUIE[] = { /* SEQUENCE */
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("destinationInfo") SEQ, 6, 8, 10, SKIP | EXT, 0,
_EndpointType},
@@ -1328,7 +1328,7 @@ static field_t _Progress_UUIE[] = { /* SEQUENCE */
{FNAME("fastConnectRefused") NUL, FIXD, 0, 0, SKIP | OPT, 0, NULL},
};
-static field_t _H323_UU_PDU_h323_message_body[] = { /* CHOICE */
+static const struct field_t _H323_UU_PDU_h323_message_body[] = { /* CHOICE */
{FNAME("setup") SEQ, 7, 13, 39, DECODE | EXT,
offsetof(H323_UU_PDU_h323_message_body, setup), _Setup_UUIE},
{FNAME("callProceeding") SEQ, 1, 3, 12, DECODE | EXT,
@@ -1352,7 +1352,7 @@ static field_t _H323_UU_PDU_h323_message_body[] = { /* CHOICE */
{FNAME("notify") SEQ, 2, 4, 4, SKIP | EXT, 0, NULL},
};
-static field_t _RequestMessage[] = { /* CHOICE */
+static const struct field_t _RequestMessage[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
{FNAME("masterSlaveDetermination") SEQ, 0, 2, 2, STOP | EXT, 0, NULL},
{FNAME("terminalCapabilitySet") SEQ, 3, 5, 5, STOP | EXT, 0, NULL},
@@ -1372,7 +1372,7 @@ static field_t _RequestMessage[] = { /* CHOICE */
NULL},
};
-static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
+static const struct field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters[] = { /* CHOICE */
{FNAME("h222LogicalChannelParameters") SEQ, 3, 5, 5, SKIP | EXT, 0,
_H222LogicalChannelParameters},
{FNAME("h2250LogicalChannelParameters") SEQ, 10, 11, 14, DECODE | EXT,
@@ -1381,7 +1381,7 @@ static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexP
h2250LogicalChannelParameters), _H2250LogicalChannelParameters},
};
-static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = { /* SEQUENCE */
{FNAME("reverseLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
{FNAME("multiplexParameters") CHOICE, 0, 1, 2, DECODE | EXT | OPT,
@@ -1391,11 +1391,11 @@ static field_t _OpenLogicalChannelAck_reverseLogicalChannelParameters[] = { /* S
{FNAME("replacementFor") INT, WORD, 1, 0, SKIP | OPT, 0, NULL},
};
-static field_t _H2250LogicalChannelAckParameters_nonStandard[] = { /* SEQUENCE OF */
+static const struct field_t _H2250LogicalChannelAckParameters_nonStandard[] = { /* SEQUENCE OF */
{FNAME("item") SEQ, 0, 2, 2, SKIP, 0, _H245_NonStandardParameter},
};
-static field_t _H2250LogicalChannelAckParameters[] = { /* SEQUENCE */
+static const struct field_t _H2250LogicalChannelAckParameters[] = { /* SEQUENCE */
{FNAME("nonStandard") SEQOF, SEMI, 0, 0, SKIP | OPT, 0,
_H2250LogicalChannelAckParameters_nonStandard},
{FNAME("sessionID") INT, 8, 1, 0, SKIP | OPT, 0, NULL},
@@ -1410,14 +1410,14 @@ static field_t _H2250LogicalChannelAckParameters[] = { /* SEQUENCE */
{FNAME("portNumber") INT, WORD, 0, 0, SKIP | OPT, 0, NULL},
};
-static field_t _OpenLogicalChannelAck_forwardMultiplexAckParameters[] = { /* CHOICE */
+static const struct field_t _OpenLogicalChannelAck_forwardMultiplexAckParameters[] = { /* CHOICE */
{FNAME("h2250LogicalChannelAckParameters") SEQ, 5, 5, 7, DECODE | EXT,
offsetof(OpenLogicalChannelAck_forwardMultiplexAckParameters,
h2250LogicalChannelAckParameters),
_H2250LogicalChannelAckParameters},
};
-static field_t _OpenLogicalChannelAck[] = { /* SEQUENCE */
+static const struct field_t _OpenLogicalChannelAck[] = { /* SEQUENCE */
{FNAME("forwardLogicalChannelNumber") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("reverseLogicalChannelParameters") SEQ, 2, 3, 4,
DECODE | EXT | OPT, offsetof(OpenLogicalChannelAck,
@@ -1433,7 +1433,7 @@ static field_t _OpenLogicalChannelAck[] = { /* SEQUENCE */
{FNAME("encryptionSync") SEQ, 2, 4, 4, STOP | EXT | OPT, 0, NULL},
};
-static field_t _ResponseMessage[] = { /* CHOICE */
+static const struct field_t _ResponseMessage[] = { /* CHOICE */
{FNAME("nonStandard") SEQ, 0, 1, 1, STOP | EXT, 0, NULL},
{FNAME("masterSlaveDeterminationAck") SEQ, 0, 1, 1, STOP | EXT, 0,
NULL},
@@ -1469,7 +1469,7 @@ static field_t _ResponseMessage[] = { /* CHOICE */
{FNAME("logicalChannelRateReject") SEQ, 1, 4, 4, STOP | EXT, 0, NULL},
};
-static field_t _MultimediaSystemControlMessage[] = { /* CHOICE */
+static const struct field_t _MultimediaSystemControlMessage[] = { /* CHOICE */
{FNAME("request") CHOICE, 4, 11, 15, DECODE | EXT,
offsetof(MultimediaSystemControlMessage, request), _RequestMessage},
{FNAME("response") CHOICE, 5, 19, 24, DECODE | EXT,
@@ -1479,14 +1479,14 @@ static field_t _MultimediaSystemControlMessage[] = { /* CHOICE */
{FNAME("indication") CHOICE, 4, 14, 23, STOP | EXT, 0, NULL},
};
-static field_t _H323_UU_PDU_h245Control[] = { /* SEQUENCE OF */
+static const struct field_t _H323_UU_PDU_h245Control[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 2, 4, 4, DECODE | OPEN | EXT,
sizeof(MultimediaSystemControlMessage),
_MultimediaSystemControlMessage}
,
};
-static field_t _H323_UU_PDU[] = { /* SEQUENCE */
+static const struct field_t _H323_UU_PDU[] = { /* SEQUENCE */
{FNAME("h323-message-body") CHOICE, 3, 7, 13, DECODE | EXT,
offsetof(H323_UU_PDU, h323_message_body),
_H323_UU_PDU_h323_message_body},
@@ -1507,13 +1507,13 @@ static field_t _H323_UU_PDU[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _H323_UserInformation[] = { /* SEQUENCE */
+static const struct field_t _H323_UserInformation[] = { /* SEQUENCE */
{FNAME("h323-uu-pdu") SEQ, 1, 2, 11, DECODE | EXT,
offsetof(H323_UserInformation, h323_uu_pdu), _H323_UU_PDU},
{FNAME("user-data") SEQ, 0, 2, 2, STOP | EXT | OPT, 0, NULL},
};
-static field_t _GatekeeperRequest[] = { /* SEQUENCE */
+static const struct field_t _GatekeeperRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1537,7 +1537,7 @@ static field_t _GatekeeperRequest[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _GatekeeperConfirm[] = { /* SEQUENCE */
+static const struct field_t _GatekeeperConfirm[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1557,23 +1557,23 @@ static field_t _GatekeeperConfirm[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _RegistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _RegistrationRequest_rasAddress[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationRequest_rasAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _RegistrationRequest_terminalAlias[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationRequest_terminalAlias[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _RegistrationRequest[] = { /* SEQUENCE */
+static const struct field_t _RegistrationRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1621,17 +1621,17 @@ static field_t _RegistrationRequest[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _RegistrationConfirm_callSignalAddress[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationConfirm_callSignalAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _RegistrationConfirm_terminalAlias[] = { /* SEQUENCE OF */
+static const struct field_t _RegistrationConfirm_terminalAlias[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _RegistrationConfirm[] = { /* SEQUENCE */
+static const struct field_t _RegistrationConfirm[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("protocolIdentifier") OID, BYTE, 0, 0, SKIP, 0, NULL},
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
@@ -1667,13 +1667,13 @@ static field_t _RegistrationConfirm[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _UnregistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
+static const struct field_t _UnregistrationRequest_callSignalAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _UnregistrationRequest[] = { /* SEQUENCE */
+static const struct field_t _UnregistrationRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("callSignalAddress") SEQOF, SEMI, 0, 10, DECODE,
offsetof(UnregistrationRequest, callSignalAddress),
@@ -1694,24 +1694,24 @@ static field_t _UnregistrationRequest[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _CallModel[] = { /* CHOICE */
+static const struct field_t _CallModel[] = { /* CHOICE */
{FNAME("direct") NUL, FIXD, 0, 0, SKIP, 0, NULL},
{FNAME("gatekeeperRouted") NUL, FIXD, 0, 0, SKIP, 0, NULL},
};
-static field_t _AdmissionRequest_destinationInfo[] = { /* SEQUENCE OF */
+static const struct field_t _AdmissionRequest_destinationInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _AdmissionRequest_destExtraCallInfo[] = { /* SEQUENCE OF */
+static const struct field_t _AdmissionRequest_destExtraCallInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _AdmissionRequest_srcInfo[] = { /* SEQUENCE OF */
+static const struct field_t _AdmissionRequest_srcInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _AdmissionRequest[] = { /* SEQUENCE */
+static const struct field_t _AdmissionRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("callType") CHOICE, 2, 4, 4, SKIP | EXT, 0, _CallType},
{FNAME("callModel") CHOICE, 1, 2, 2, SKIP | EXT | OPT, 0, _CallModel},
@@ -1755,7 +1755,7 @@ static field_t _AdmissionRequest[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _AdmissionConfirm[] = { /* SEQUENCE */
+static const struct field_t _AdmissionConfirm[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("bandWidth") INT, CONS, 0, 0, SKIP, 0, NULL},
{FNAME("callModel") CHOICE, 1, 2, 2, SKIP | EXT, 0, _CallModel},
@@ -1790,11 +1790,11 @@ static field_t _AdmissionConfirm[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _LocationRequest_destinationInfo[] = { /* SEQUENCE OF */
+static const struct field_t _LocationRequest_destinationInfo[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 1, 2, 7, SKIP | EXT, 0, _AliasAddress},
};
-static field_t _LocationRequest[] = { /* SEQUENCE */
+static const struct field_t _LocationRequest[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("endpointIdentifier") BMPSTR, 7, 1, 0, SKIP | OPT, 0, NULL},
{FNAME("destinationInfo") SEQOF, SEMI, 0, 0, SKIP, 0,
@@ -1818,7 +1818,7 @@ static field_t _LocationRequest[] = { /* SEQUENCE */
{FNAME("circuitInfo") SEQ, 3, 3, 3, STOP | EXT | OPT, 0, NULL},
};
-static field_t _LocationConfirm[] = { /* SEQUENCE */
+static const struct field_t _LocationConfirm[] = { /* SEQUENCE */
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
{FNAME("callSignalAddress") CHOICE, 3, 7, 7, DECODE | EXT,
offsetof(LocationConfirm, callSignalAddress), _TransportAddress},
@@ -1844,13 +1844,13 @@ static field_t _LocationConfirm[] = { /* SEQUENCE */
{FNAME("serviceControl") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _InfoRequestResponse_callSignalAddress[] = { /* SEQUENCE OF */
+static const struct field_t _InfoRequestResponse_callSignalAddress[] = { /* SEQUENCE OF */
{FNAME("item") CHOICE, 3, 7, 7, DECODE | EXT,
sizeof(TransportAddress), _TransportAddress}
,
};
-static field_t _InfoRequestResponse[] = { /* SEQUENCE */
+static const struct field_t _InfoRequestResponse[] = { /* SEQUENCE */
{FNAME("nonStandardData") SEQ, 0, 2, 2, SKIP | OPT, 0,
_NonStandardParameter},
{FNAME("requestSeqNum") INT, WORD, 1, 0, SKIP, 0, NULL},
@@ -1873,7 +1873,7 @@ static field_t _InfoRequestResponse[] = { /* SEQUENCE */
{FNAME("genericData") SEQOF, SEMI, 0, 0, STOP | OPT, 0, NULL},
};
-static field_t _RasMessage[] = { /* CHOICE */
+static const struct field_t _RasMessage[] = { /* CHOICE */
{FNAME("gatekeeperRequest") SEQ, 4, 8, 18, DECODE | EXT,
offsetof(RasMessage, gatekeeperRequest), _GatekeeperRequest},
{FNAME("gatekeeperConfirm") SEQ, 2, 5, 14, DECODE | EXT,
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 96aa637c093..b1fd21cc1db 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -28,6 +28,7 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_extend.h>
+static DEFINE_MUTEX(nf_ct_helper_mutex);
static struct hlist_head *nf_ct_helper_hash __read_mostly;
static unsigned int nf_ct_helper_hsize __read_mostly;
static unsigned int nf_ct_helper_count __read_mostly;
@@ -54,42 +55,13 @@ __nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
return NULL;
h = helper_hash(tuple);
- hlist_for_each_entry(helper, n, &nf_ct_helper_hash[h], hnode) {
+ hlist_for_each_entry_rcu(helper, n, &nf_ct_helper_hash[h], hnode) {
if (nf_ct_tuple_src_mask_cmp(tuple, &helper->tuple, &mask))
return helper;
}
return NULL;
}
-
-struct nf_conntrack_helper *
-nf_ct_helper_find_get(const struct nf_conntrack_tuple *tuple)
-{
- struct nf_conntrack_helper *helper;
-
- /* need nf_conntrack_lock to assure that helper exists until
- * try_module_get() is called */
- read_lock_bh(&nf_conntrack_lock);
-
- helper = __nf_ct_helper_find(tuple);
- if (helper) {
- /* need to increase module usage count to assure helper will
- * not go away while the caller is e.g. busy putting a
- * conntrack in the hash that uses the helper */
- if (!try_module_get(helper->me))
- helper = NULL;
- }
-
- read_unlock_bh(&nf_conntrack_lock);
-
- return helper;
-}
-EXPORT_SYMBOL_GPL(nf_ct_helper_find_get);
-
-void nf_ct_helper_put(struct nf_conntrack_helper *helper)
-{
- module_put(helper->me);
-}
-EXPORT_SYMBOL_GPL(nf_ct_helper_put);
+EXPORT_SYMBOL_GPL(__nf_ct_helper_find);
struct nf_conntrack_helper *
__nf_conntrack_helper_find_byname(const char *name)
@@ -99,7 +71,7 @@ __nf_conntrack_helper_find_byname(const char *name)
unsigned int i;
for (i = 0; i < nf_ct_helper_hsize; i++) {
- hlist_for_each_entry(h, n, &nf_ct_helper_hash[i], hnode) {
+ hlist_for_each_entry_rcu(h, n, &nf_ct_helper_hash[i], hnode) {
if (!strcmp(h->name, name))
return h;
}
@@ -140,10 +112,10 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
BUG_ON(me->timeout == 0);
- write_lock_bh(&nf_conntrack_lock);
- hlist_add_head(&me->hnode, &nf_ct_helper_hash[h]);
+ mutex_lock(&nf_ct_helper_mutex);
+ hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
nf_ct_helper_count++;
- write_unlock_bh(&nf_conntrack_lock);
+ mutex_unlock(&nf_ct_helper_mutex);
return 0;
}
@@ -156,10 +128,17 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
struct hlist_node *n, *next;
unsigned int i;
- /* Need write lock here, to delete helper. */
- write_lock_bh(&nf_conntrack_lock);
- hlist_del(&me->hnode);
+ mutex_lock(&nf_ct_helper_mutex);
+ hlist_del_rcu(&me->hnode);
nf_ct_helper_count--;
+ mutex_unlock(&nf_ct_helper_mutex);
+
+ /* Make sure every nothing is still using the helper unless its a
+ * connection in the hash.
+ */
+ synchronize_rcu();
+
+ spin_lock_bh(&nf_conntrack_lock);
/* Get rid of expectations */
for (i = 0; i < nf_ct_expect_hsize; i++) {
@@ -181,10 +160,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
hlist_for_each_entry(h, n, &nf_conntrack_hash[i], hnode)
unhelp(h, me);
}
- write_unlock_bh(&nf_conntrack_lock);
-
- /* Someone could be still looking at the helper in a bh. */
- synchronize_net();
+ spin_unlock_bh(&nf_conntrack_lock);
}
EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index dfaed4ba83c..c336b07a0d4 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -23,7 +23,7 @@
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
-static int ports_c;
+static unsigned int ports_c;
static unsigned int max_dcc_channels = 8;
static unsigned int dcc_timeout __read_mostly = 300;
/* This is slow, but it's simple. --RR */
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 38141f104db..4a1b42b2b7a 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -491,11 +491,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
&& ctnetlink_dump_helpinfo(skb, ct) < 0)
goto nla_put_failure;
-#ifdef CONFIG_NF_CONNTRACK_MARK
- if ((events & IPCT_MARK || ct->mark)
- && ctnetlink_dump_mark(skb, ct) < 0)
- goto nla_put_failure;
-#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
if ((events & IPCT_SECMARK || ct->secmark)
&& ctnetlink_dump_secmark(skb, ct) < 0)
@@ -516,6 +511,12 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
goto nla_put_failure;
}
+#ifdef CONFIG_NF_CONNTRACK_MARK
+ if ((events & IPCT_MARK || ct->mark)
+ && ctnetlink_dump_mark(skb, ct) < 0)
+ goto nla_put_failure;
+#endif
+
nlh->nlmsg_len = skb->tail - b;
nfnetlink_send(skb, 0, group, 0);
return NOTIFY_DONE;
@@ -545,12 +546,12 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
u_int8_t l3proto = nfmsg->nfgen_family;
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
last = (struct nf_conn *)cb->args[1];
for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
restart:
- hlist_for_each_entry(h, n, &nf_conntrack_hash[cb->args[0]],
- hnode) {
+ hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[cb->args[0]],
+ hnode) {
if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
continue;
ct = nf_ct_tuplehash_to_ctrack(h);
@@ -568,7 +569,8 @@ restart:
cb->nlh->nlmsg_seq,
IPCTNL_MSG_CT_NEW,
1, ct) < 0) {
- nf_conntrack_get(&ct->ct_general);
+ if (!atomic_inc_not_zero(&ct->ct_general.use))
+ continue;
cb->args[1] = (unsigned long)ct;
goto out;
}
@@ -584,7 +586,7 @@ restart:
}
}
out:
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
if (last)
nf_ct_put(last);
@@ -1167,11 +1169,12 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
#endif
- helper = nf_ct_helper_find_get(rtuple);
+ rcu_read_lock();
+ helper = __nf_ct_helper_find(rtuple);
if (helper) {
help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
if (help == NULL) {
- nf_ct_helper_put(helper);
+ rcu_read_unlock();
err = -ENOMEM;
goto err;
}
@@ -1187,9 +1190,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
add_timer(&ct->timeout);
nf_conntrack_hash_insert(ct);
-
- if (helper)
- nf_ct_helper_put(helper);
+ rcu_read_unlock();
return 0;
@@ -1220,11 +1221,11 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err;
}
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
if (cda[CTA_TUPLE_ORIG])
- h = __nf_conntrack_find(&otuple, NULL);
+ h = __nf_conntrack_find(&otuple);
else if (cda[CTA_TUPLE_REPLY])
- h = __nf_conntrack_find(&rtuple, NULL);
+ h = __nf_conntrack_find(&rtuple);
if (h == NULL) {
struct nf_conntrack_tuple master;
@@ -1237,9 +1238,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
CTA_TUPLE_MASTER,
u3);
if (err < 0)
- return err;
+ goto out_unlock;
- master_h = __nf_conntrack_find(&master, NULL);
+ master_h = __nf_conntrack_find(&master);
if (master_h == NULL) {
err = -ENOENT;
goto out_unlock;
@@ -1248,7 +1249,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
atomic_inc(&master_ct->ct_general.use);
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE)
err = ctnetlink_create_conntrack(cda,
@@ -1281,7 +1282,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
}
out_unlock:
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return err;
}
@@ -1472,7 +1473,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct hlist_node *n;
u_int8_t l3proto = nfmsg->nfgen_family;
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
last = (struct nf_conntrack_expect *)cb->args[1];
for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
restart:
@@ -1489,7 +1490,8 @@ restart:
cb->nlh->nlmsg_seq,
IPCTNL_MSG_EXP_NEW,
1, exp) < 0) {
- atomic_inc(&exp->use);
+ if (!atomic_inc_not_zero(&exp->use))
+ continue;
cb->args[1] = (unsigned long)exp;
goto out;
}
@@ -1500,7 +1502,7 @@ restart:
}
}
out:
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
if (last)
nf_ct_expect_put(last);
@@ -1613,10 +1615,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
struct nf_conn_help *m_help;
/* delete all expectations for this helper */
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
h = __nf_conntrack_helper_find_byname(name);
if (!h) {
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return -EINVAL;
}
for (i = 0; i < nf_ct_expect_hsize; i++) {
@@ -1631,10 +1633,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
}
}
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
} else {
/* This basically means we have to flush everything*/
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
for (i = 0; i < nf_ct_expect_hsize; i++) {
hlist_for_each_entry_safe(exp, n, next,
&nf_ct_expect_hash[i],
@@ -1645,7 +1647,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
}
}
}
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
}
return 0;
@@ -1731,11 +1733,11 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
if (err < 0)
return err;
- write_lock_bh(&nf_conntrack_lock);
+ spin_lock_bh(&nf_conntrack_lock);
exp = __nf_ct_expect_find(&tuple);
if (!exp) {
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE)
err = ctnetlink_create_expect(cda, u3);
@@ -1745,7 +1747,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
err = -EEXIST;
if (!(nlh->nlmsg_flags & NLM_F_EXCL))
err = ctnetlink_change_expect(exp, cda);
- write_unlock_bh(&nf_conntrack_lock);
+ spin_unlock_bh(&nf_conntrack_lock);
return err;
}
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 099b6df3e2b..b5cb8e83123 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -67,7 +67,7 @@ EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
#ifdef DEBUG
/* PptpControlMessageType names */
-const char *pptp_msg_name[] = {
+const char *const pptp_msg_name[] = {
"UNKNOWN_MESSAGE",
"START_SESSION_REQUEST",
"START_SESSION_REPLY",
@@ -136,7 +136,7 @@ static void pptp_expectfn(struct nf_conn *ct,
static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
{
- struct nf_conntrack_tuple_hash *h;
+ const struct nf_conntrack_tuple_hash *h;
struct nf_conntrack_expect *exp;
struct nf_conn *sibling;
@@ -168,7 +168,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
/* timeout GRE data connections */
static void pptp_destroy_siblings(struct nf_conn *ct)
{
- struct nf_conn_help *help = nfct_help(ct);
+ const struct nf_conn_help *help = nfct_help(ct);
struct nf_conntrack_tuple t;
nf_ct_gre_keymap_destroy(ct);
@@ -497,9 +497,11 @@ conntrack_pptp_help(struct sk_buff *skb, unsigned int protoff,
{
int dir = CTINFO2DIR(ctinfo);
- struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info;
- struct tcphdr _tcph, *tcph;
- struct pptp_pkt_hdr _pptph, *pptph;
+ const struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info;
+ const struct tcphdr *tcph;
+ struct tcphdr _tcph;
+ const struct pptp_pkt_hdr *pptph;
+ struct pptp_pkt_hdr _pptph;
struct PptpControlHeader _ctlh, *ctlh;
union pptp_ctrl_union _pptpReq, *pptpReq;
unsigned int tcplen = skb->len - protoff;
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index 22c5dcb6306..55458915575 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -41,19 +41,19 @@ static int generic_print_tuple(struct seq_file *s,
}
/* Returns verdict for packet, or -1 for invalid. */
-static int packet(struct nf_conn *conntrack,
+static int packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
int pf,
unsigned int hooknum)
{
- nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_generic_timeout);
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_generic_timeout);
return NF_ACCEPT;
}
/* Called when a new connection for this protocol found. */
-static int new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int new(struct nf_conn *ct, const struct sk_buff *skb,
unsigned int dataoff)
{
return 1;
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 4a185f6aa65..e10024a1b66 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -161,9 +161,11 @@ static int gre_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct gre_hdr_pptp _pgrehdr, *pgrehdr;
+ const struct gre_hdr_pptp *pgrehdr;
+ struct gre_hdr_pptp _pgrehdr;
__be16 srckey;
- struct gre_hdr _grehdr, *grehdr;
+ const struct gre_hdr *grehdr;
+ struct gre_hdr _grehdr;
/* first only delinearize old RFC1701 GRE header */
grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr);
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 21d29e782ba..f9a08370dbb 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -25,7 +25,7 @@
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_ecache.h>
-/* Protects conntrack->proto.sctp */
+/* Protects ct->proto.sctp */
static DEFINE_RWLOCK(sctp_lock);
/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
@@ -624,7 +624,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
#endif
};
-int __init nf_conntrack_proto_sctp_init(void)
+static int __init nf_conntrack_proto_sctp_init(void)
{
int ret;
@@ -647,7 +647,7 @@ int __init nf_conntrack_proto_sctp_init(void)
return ret;
}
-void __exit nf_conntrack_proto_sctp_fini(void)
+static void __exit nf_conntrack_proto_sctp_fini(void)
{
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 64c9b910419..3e0cccae563 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -26,7 +26,7 @@
#include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_log.h>
-/* Protects conntrack->proto.tcp */
+/* Protects ct->proto.tcp */
static DEFINE_RWLOCK(tcp_lock);
/* "Be conservative in what you do,
@@ -46,7 +46,7 @@ static int nf_ct_tcp_max_retrans __read_mostly = 3;
/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
closely. They're more complex. --RR */
-static const char *tcp_conntrack_names[] = {
+static const char *const tcp_conntrack_names[] = {
"NONE",
"SYN_SENT",
"SYN_RECV",
@@ -261,7 +261,8 @@ static int tcp_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct tcphdr _hdr, *hp;
+ const struct tcphdr *hp;
+ struct tcphdr _hdr;
/* Actually only need first 8 bytes. */
hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
@@ -292,13 +293,12 @@ static int tcp_print_tuple(struct seq_file *s,
}
/* Print out the private part of the conntrack. */
-static int tcp_print_conntrack(struct seq_file *s,
- const struct nf_conn *conntrack)
+static int tcp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
{
enum tcp_conntrack state;
read_lock_bh(&tcp_lock);
- state = conntrack->proto.tcp.state;
+ state = ct->proto.tcp.state;
read_unlock_bh(&tcp_lock);
return seq_printf(s, "%s ", tcp_conntrack_names[state]);
@@ -344,7 +344,7 @@ static unsigned int get_conntrack_index(const struct tcphdr *tcph)
static inline __u32 segment_seq_plus_len(__u32 seq,
size_t len,
unsigned int dataoff,
- struct tcphdr *tcph)
+ const struct tcphdr *tcph)
{
/* XXX Should I use payload length field in IP/IPv6 header ?
* - YK */
@@ -363,11 +363,11 @@ static inline __u32 segment_seq_plus_len(__u32 seq,
*/
static void tcp_options(const struct sk_buff *skb,
unsigned int dataoff,
- struct tcphdr *tcph,
+ const struct tcphdr *tcph,
struct ip_ct_tcp_state *state)
{
unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
- unsigned char *ptr;
+ const unsigned char *ptr;
int length = (tcph->doff*4) - sizeof(struct tcphdr);
if (!length)
@@ -418,10 +418,10 @@ static void tcp_options(const struct sk_buff *skb,
}
static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
- struct tcphdr *tcph, __u32 *sack)
+ const struct tcphdr *tcph, __u32 *sack)
{
unsigned char buff[(15 * 4) - sizeof(struct tcphdr)];
- unsigned char *ptr;
+ const unsigned char *ptr;
int length = (tcph->doff*4) - sizeof(struct tcphdr);
__u32 tmp;
@@ -478,18 +478,18 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
}
}
-static int tcp_in_window(struct nf_conn *ct,
+static int tcp_in_window(const struct nf_conn *ct,
struct ip_ct_tcp *state,
enum ip_conntrack_dir dir,
unsigned int index,
const struct sk_buff *skb,
unsigned int dataoff,
- struct tcphdr *tcph,
+ const struct tcphdr *tcph,
int pf)
{
struct ip_ct_tcp_state *sender = &state->seen[dir];
struct ip_ct_tcp_state *receiver = &state->seen[!dir];
- struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
+ const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
__u32 seq, ack, sack, end, win, swin;
int res;
@@ -687,14 +687,14 @@ static int tcp_in_window(struct nf_conn *ct,
#ifdef CONFIG_NF_NAT_NEEDED
/* Update sender->td_end after NAT successfully mangled the packet */
/* Caller must linearize skb at tcp header. */
-void nf_conntrack_tcp_update(struct sk_buff *skb,
+void nf_conntrack_tcp_update(const struct sk_buff *skb,
unsigned int dataoff,
- struct nf_conn *conntrack,
+ struct nf_conn *ct,
int dir)
{
- struct tcphdr *tcph = (void *)skb->data + dataoff;
- struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[dir];
- struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[!dir];
+ const struct tcphdr *tcph = (const void *)skb->data + dataoff;
+ const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir];
+ const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[!dir];
__u32 end;
end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
@@ -703,9 +703,9 @@ void nf_conntrack_tcp_update(struct sk_buff *skb,
/*
* We have to worry for the ack in the reply packet only...
*/
- if (after(end, conntrack->proto.tcp.seen[dir].td_end))
- conntrack->proto.tcp.seen[dir].td_end = end;
- conntrack->proto.tcp.last_end = end;
+ if (after(end, ct->proto.tcp.seen[dir].td_end))
+ ct->proto.tcp.seen[dir].td_end = end;
+ ct->proto.tcp.last_end = end;
write_unlock_bh(&tcp_lock);
pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
@@ -727,7 +727,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
#define TH_CWR 0x80
/* table of valid flag combinations - PUSH, ECE and CWR are always valid */
-static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] =
+static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] =
{
[TH_SYN] = 1,
[TH_SYN|TH_URG] = 1,
@@ -747,7 +747,8 @@ static int tcp_error(struct sk_buff *skb,
int pf,
unsigned int hooknum)
{
- struct tcphdr _tcph, *th;
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
unsigned int tcplen = skb->len - dataoff;
u_int8_t tcpflags;
@@ -794,7 +795,7 @@ static int tcp_error(struct sk_buff *skb,
}
/* Returns verdict for packet, or -1 for invalid. */
-static int tcp_packet(struct nf_conn *conntrack,
+static int tcp_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
@@ -804,7 +805,8 @@ static int tcp_packet(struct nf_conn *conntrack,
struct nf_conntrack_tuple *tuple;
enum tcp_conntrack new_state, old_state;
enum ip_conntrack_dir dir;
- struct tcphdr *th, _tcph;
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
unsigned long timeout;
unsigned int index;
@@ -812,26 +814,24 @@ static int tcp_packet(struct nf_conn *conntrack,
BUG_ON(th == NULL);
write_lock_bh(&tcp_lock);
- old_state = conntrack->proto.tcp.state;
+ old_state = ct->proto.tcp.state;
dir = CTINFO2DIR(ctinfo);
index = get_conntrack_index(th);
new_state = tcp_conntracks[dir][index][old_state];
- tuple = &conntrack->tuplehash[dir].tuple;
+ tuple = &ct->tuplehash[dir].tuple;
switch (new_state) {
case TCP_CONNTRACK_SYN_SENT:
if (old_state < TCP_CONNTRACK_TIME_WAIT)
break;
- if ((conntrack->proto.tcp.seen[!dir].flags &
- IP_CT_TCP_FLAG_CLOSE_INIT)
- || (conntrack->proto.tcp.last_dir == dir
- && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+ if ((ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_CLOSE_INIT)
+ || (ct->proto.tcp.last_dir == dir
+ && ct->proto.tcp.last_index == TCP_RST_SET)) {
/* Attempt to reopen a closed/aborted connection.
* Delete this connection and look up again. */
write_unlock_bh(&tcp_lock);
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)
- conntrack);
+ if (del_timer(&ct->timeout))
+ ct->timeout.function((unsigned long)ct);
return -NF_REPEAT;
}
/* Fall through */
@@ -843,10 +843,9 @@ static int tcp_packet(struct nf_conn *conntrack,
* c) ACK in reply direction after initial SYN in original.
*/
if (index == TCP_SYNACK_SET
- && conntrack->proto.tcp.last_index == TCP_SYN_SET
- && conntrack->proto.tcp.last_dir != dir
- && ntohl(th->ack_seq) ==
- conntrack->proto.tcp.last_end) {
+ && ct->proto.tcp.last_index == TCP_SYN_SET
+ && ct->proto.tcp.last_dir != dir
+ && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
/* This SYN/ACK acknowledges a SYN that we earlier
* ignored as invalid. This means that the client and
* the server are both in sync, while the firewall is
@@ -858,15 +857,14 @@ static int tcp_packet(struct nf_conn *conntrack,
if (LOG_INVALID(IPPROTO_TCP))
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
"nf_ct_tcp: killing out of sync session ");
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)
- conntrack);
+ if (del_timer(&ct->timeout))
+ ct->timeout.function((unsigned long)ct);
return -NF_DROP;
}
- conntrack->proto.tcp.last_index = index;
- conntrack->proto.tcp.last_dir = dir;
- conntrack->proto.tcp.last_seq = ntohl(th->seq);
- conntrack->proto.tcp.last_end =
+ ct->proto.tcp.last_index = index;
+ ct->proto.tcp.last_dir = dir;
+ ct->proto.tcp.last_seq = ntohl(th->seq);
+ ct->proto.tcp.last_end =
segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
write_unlock_bh(&tcp_lock);
@@ -885,11 +883,11 @@ static int tcp_packet(struct nf_conn *conntrack,
return -NF_ACCEPT;
case TCP_CONNTRACK_CLOSE:
if (index == TCP_RST_SET
- && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
- && conntrack->proto.tcp.last_index == TCP_SYN_SET)
- || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
- && conntrack->proto.tcp.last_index == TCP_ACK_SET))
- && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
+ && ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status)
+ && ct->proto.tcp.last_index == TCP_SYN_SET)
+ || (!test_bit(IPS_ASSURED_BIT, &ct->status)
+ && ct->proto.tcp.last_index == TCP_ACK_SET))
+ && ntohl(th->ack_seq) == ct->proto.tcp.last_end) {
/* RST sent to invalid SYN or ACK we had let through
* at a) and c) above:
*
@@ -907,15 +905,15 @@ static int tcp_packet(struct nf_conn *conntrack,
break;
}
- if (!tcp_in_window(conntrack, &conntrack->proto.tcp, dir, index,
+ if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
skb, dataoff, th, pf)) {
write_unlock_bh(&tcp_lock);
return -NF_ACCEPT;
}
in_window:
/* From now on we have got in-window packets */
- conntrack->proto.tcp.last_index = index;
- conntrack->proto.tcp.last_dir = dir;
+ ct->proto.tcp.last_index = index;
+ ct->proto.tcp.last_dir = dir;
pr_debug("tcp_conntracks: ");
NF_CT_DUMP_TUPLE(tuple);
@@ -924,12 +922,12 @@ static int tcp_packet(struct nf_conn *conntrack,
(th->fin ? 1 : 0), (th->rst ? 1 : 0),
old_state, new_state);
- conntrack->proto.tcp.state = new_state;
+ ct->proto.tcp.state = new_state;
if (old_state != new_state
&& (new_state == TCP_CONNTRACK_FIN_WAIT
|| new_state == TCP_CONNTRACK_CLOSE))
- conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
- timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
+ ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
+ timeout = ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans
&& tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
? nf_ct_tcp_timeout_max_retrans : tcp_timeouts[new_state];
write_unlock_bh(&tcp_lock);
@@ -938,41 +936,41 @@ static int tcp_packet(struct nf_conn *conntrack,
if (new_state != old_state)
nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
- if (!test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
+ if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
/* If only reply is a RST, we can consider ourselves not to
have an established connection: this is a fairly common
problem case, so we can delete the conntrack
immediately. --RR */
if (th->rst) {
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)
- conntrack);
+ if (del_timer(&ct->timeout))
+ ct->timeout.function((unsigned long)ct);
return NF_ACCEPT;
}
- } else if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
+ } else if (!test_bit(IPS_ASSURED_BIT, &ct->status)
&& (old_state == TCP_CONNTRACK_SYN_RECV
|| old_state == TCP_CONNTRACK_ESTABLISHED)
&& new_state == TCP_CONNTRACK_ESTABLISHED) {
/* Set ASSURED if we see see valid ack in ESTABLISHED
after SYN_RECV or a valid answer for a picked up
connection. */
- set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ set_bit(IPS_ASSURED_BIT, &ct->status);
nf_conntrack_event_cache(IPCT_STATUS, skb);
}
- nf_ct_refresh_acct(conntrack, ctinfo, skb, timeout);
+ nf_ct_refresh_acct(ct, ctinfo, skb, timeout);
return NF_ACCEPT;
}
/* Called when a new connection for this protocol found. */
-static int tcp_new(struct nf_conn *conntrack,
+static int tcp_new(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff)
{
enum tcp_conntrack new_state;
- struct tcphdr *th, _tcph;
- struct ip_ct_tcp_state *sender = &conntrack->proto.tcp.seen[0];
- struct ip_ct_tcp_state *receiver = &conntrack->proto.tcp.seen[1];
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
+ const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[0];
+ const struct ip_ct_tcp_state *receiver = &ct->proto.tcp.seen[1];
th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
BUG_ON(th == NULL);
@@ -990,17 +988,17 @@ static int tcp_new(struct nf_conn *conntrack,
if (new_state == TCP_CONNTRACK_SYN_SENT) {
/* SYN packet */
- conntrack->proto.tcp.seen[0].td_end =
+ ct->proto.tcp.seen[0].td_end =
segment_seq_plus_len(ntohl(th->seq), skb->len,
dataoff, th);
- conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
- if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
- conntrack->proto.tcp.seen[0].td_maxwin = 1;
- conntrack->proto.tcp.seen[0].td_maxend =
- conntrack->proto.tcp.seen[0].td_end;
-
- tcp_options(skb, dataoff, th, &conntrack->proto.tcp.seen[0]);
- conntrack->proto.tcp.seen[1].flags = 0;
+ ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+ if (ct->proto.tcp.seen[0].td_maxwin == 0)
+ ct->proto.tcp.seen[0].td_maxwin = 1;
+ ct->proto.tcp.seen[0].td_maxend =
+ ct->proto.tcp.seen[0].td_end;
+
+ tcp_options(skb, dataoff, th, &ct->proto.tcp.seen[0]);
+ ct->proto.tcp.seen[1].flags = 0;
} else if (nf_ct_tcp_loose == 0) {
/* Don't try to pick up connections. */
return 0;
@@ -1010,32 +1008,32 @@ static int tcp_new(struct nf_conn *conntrack,
* its history is lost for us.
* Let's try to use the data from the packet.
*/
- conntrack->proto.tcp.seen[0].td_end =
+ ct->proto.tcp.seen[0].td_end =
segment_seq_plus_len(ntohl(th->seq), skb->len,
dataoff, th);
- conntrack->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
- if (conntrack->proto.tcp.seen[0].td_maxwin == 0)
- conntrack->proto.tcp.seen[0].td_maxwin = 1;
- conntrack->proto.tcp.seen[0].td_maxend =
- conntrack->proto.tcp.seen[0].td_end +
- conntrack->proto.tcp.seen[0].td_maxwin;
- conntrack->proto.tcp.seen[0].td_scale = 0;
+ ct->proto.tcp.seen[0].td_maxwin = ntohs(th->window);
+ if (ct->proto.tcp.seen[0].td_maxwin == 0)
+ ct->proto.tcp.seen[0].td_maxwin = 1;
+ ct->proto.tcp.seen[0].td_maxend =
+ ct->proto.tcp.seen[0].td_end +
+ ct->proto.tcp.seen[0].td_maxwin;
+ ct->proto.tcp.seen[0].td_scale = 0;
/* We assume SACK and liberal window checking to handle
* window scaling */
- conntrack->proto.tcp.seen[0].flags =
- conntrack->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
- IP_CT_TCP_FLAG_BE_LIBERAL;
+ ct->proto.tcp.seen[0].flags =
+ ct->proto.tcp.seen[1].flags = IP_CT_TCP_FLAG_SACK_PERM |
+ IP_CT_TCP_FLAG_BE_LIBERAL;
}
- conntrack->proto.tcp.seen[1].td_end = 0;
- conntrack->proto.tcp.seen[1].td_maxend = 0;
- conntrack->proto.tcp.seen[1].td_maxwin = 1;
- conntrack->proto.tcp.seen[1].td_scale = 0;
+ ct->proto.tcp.seen[1].td_end = 0;
+ ct->proto.tcp.seen[1].td_maxend = 0;
+ ct->proto.tcp.seen[1].td_maxwin = 1;
+ ct->proto.tcp.seen[1].td_scale = 0;
/* tcp_packet will set them */
- conntrack->proto.tcp.state = TCP_CONNTRACK_NONE;
- conntrack->proto.tcp.last_index = TCP_NONE_SET;
+ ct->proto.tcp.state = TCP_CONNTRACK_NONE;
+ ct->proto.tcp.last_index = TCP_NONE_SET;
pr_debug("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i "
"receiver end=%u maxend=%u maxwin=%u scale=%i\n",
@@ -1098,16 +1096,16 @@ static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = {
static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
{
- struct nlattr *attr = cda[CTA_PROTOINFO_TCP];
+ struct nlattr *pattr = cda[CTA_PROTOINFO_TCP];
struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
int err;
/* updates could not contain anything about the private
* protocol info, in that case skip the parsing */
- if (!attr)
+ if (!pattr)
return 0;
- err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr, tcp_nla_policy);
+ err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, pattr, tcp_nla_policy);
if (err < 0)
return err;
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 38487541108..b8a35cc0641 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -30,7 +30,8 @@ static int udp_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct udphdr _hdr, *hp;
+ const struct udphdr *hp;
+ struct udphdr _hdr;
/* Actually only need first 8 bytes. */
hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
@@ -61,7 +62,7 @@ static int udp_print_tuple(struct seq_file *s,
}
/* Returns verdict for packet, and may modify conntracktype */
-static int udp_packet(struct nf_conn *conntrack,
+static int udp_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
@@ -70,20 +71,19 @@ static int udp_packet(struct nf_conn *conntrack,
{
/* If we've seen traffic both ways, this is some kind of UDP
stream. Extend timeout. */
- if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
- nf_ct_refresh_acct(conntrack, ctinfo, skb,
- nf_ct_udp_timeout_stream);
+ if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout_stream);
/* Also, more likely to be important, and not a probe */
- if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
+ if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
nf_conntrack_event_cache(IPCT_STATUS, skb);
} else
- nf_ct_refresh_acct(conntrack, ctinfo, skb, nf_ct_udp_timeout);
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout);
return NF_ACCEPT;
}
/* Called when a new connection for this protocol found. */
-static int udp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int udp_new(struct nf_conn *ct, const struct sk_buff *skb,
unsigned int dataoff)
{
return 1;
@@ -95,7 +95,8 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
unsigned int hooknum)
{
unsigned int udplen = skb->len - dataoff;
- struct udphdr _hdr, *hdr;
+ const struct udphdr *hdr;
+ struct udphdr _hdr;
/* Header is too small? */
hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 070056d9bcd..9dd03c7aeac 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -31,7 +31,8 @@ static int udplite_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct nf_conntrack_tuple *tuple)
{
- struct udphdr _hdr, *hp;
+ const struct udphdr *hp;
+ struct udphdr _hdr;
hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
if (hp == NULL)
@@ -60,7 +61,7 @@ static int udplite_print_tuple(struct seq_file *s,
}
/* Returns verdict for packet, and may modify conntracktype */
-static int udplite_packet(struct nf_conn *conntrack,
+static int udplite_packet(struct nf_conn *ct,
const struct sk_buff *skb,
unsigned int dataoff,
enum ip_conntrack_info ctinfo,
@@ -69,21 +70,20 @@ static int udplite_packet(struct nf_conn *conntrack,
{
/* If we've seen traffic both ways, this is some kind of UDP
stream. Extend timeout. */
- if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
- nf_ct_refresh_acct(conntrack, ctinfo, skb,
+ if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
+ nf_ct_refresh_acct(ct, ctinfo, skb,
nf_ct_udplite_timeout_stream);
/* Also, more likely to be important, and not a probe */
- if (!test_and_set_bit(IPS_ASSURED_BIT, &conntrack->status))
+ if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
nf_conntrack_event_cache(IPCT_STATUS, skb);
} else
- nf_ct_refresh_acct(conntrack, ctinfo, skb,
- nf_ct_udplite_timeout);
+ nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout);
return NF_ACCEPT;
}
/* Called when a new connection for this protocol found. */
-static int udplite_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
unsigned int dataoff)
{
return 1;
@@ -95,7 +95,8 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
unsigned int hooknum)
{
unsigned int udplen = skb->len - dataoff;
- struct udphdr _hdr, *hdr;
+ const struct udphdr *hdr;
+ struct udphdr _hdr;
unsigned int cscov;
/* Header is too small? */
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index b5a16c6e21c..a70051d741a 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -62,8 +62,9 @@ static int help(struct sk_buff *skb,
enum ip_conntrack_info ctinfo)
{
unsigned int dataoff, datalen;
- struct tcphdr _tcph, *th;
- char *sb_ptr;
+ const struct tcphdr *th;
+ struct tcphdr _tcph;
+ void *sb_ptr;
int ret = NF_ACCEPT;
int dir = CTINFO2DIR(ctinfo);
struct nf_ct_sane_master *ct_sane_info;
@@ -99,7 +100,7 @@ static int help(struct sk_buff *skb,
if (datalen != sizeof(struct sane_request))
goto out;
- req = (struct sane_request *)sb_ptr;
+ req = sb_ptr;
if (req->RPC_code != htonl(SANE_NET_START)) {
/* Not an interesting command */
ct_sane_info->state = SANE_STATE_NORMAL;
@@ -123,7 +124,7 @@ static int help(struct sk_buff *skb,
goto out;
}
- reply = (struct sane_reply_net_start *)sb_ptr;
+ reply = sb_ptr;
if (reply->status != htonl(SANE_STATUS_SUCCESS)) {
/* saned refused the command */
pr_debug("nf_ct_sane: unsuccessful SANE_STATUS = %u\n",
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 47d8947cf26..c521c891d35 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -28,7 +28,7 @@ MODULE_ALIAS("ip_conntrack_sip");
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
-static int ports_c;
+static unsigned int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
MODULE_PARM_DESC(ports, "port numbers of SIP servers");
@@ -48,10 +48,10 @@ unsigned int (*nf_nat_sdp_hook)(struct sk_buff *skb,
const char *dptr) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_sdp_hook);
-static int digits_len(struct nf_conn *, const char *, const char *, int *);
-static int epaddr_len(struct nf_conn *, const char *, const char *, int *);
-static int skp_digits_len(struct nf_conn *, const char *, const char *, int *);
-static int skp_epaddr_len(struct nf_conn *, const char *, const char *, int *);
+static int digits_len(const struct nf_conn *, const char *, const char *, int *);
+static int epaddr_len(const struct nf_conn *, const char *, const char *, int *);
+static int skp_digits_len(const struct nf_conn *, const char *, const char *, int *);
+static int skp_epaddr_len(const struct nf_conn *, const char *, const char *, int *);
struct sip_header_nfo {
const char *lname;
@@ -61,7 +61,7 @@ struct sip_header_nfo {
size_t snlen;
size_t ln_strlen;
int case_sensitive;
- int (*match_len)(struct nf_conn *, const char *,
+ int (*match_len)(const struct nf_conn *, const char *,
const char *, int *);
};
@@ -225,7 +225,7 @@ const char *ct_sip_search(const char *needle, const char *haystack,
}
EXPORT_SYMBOL_GPL(ct_sip_search);
-static int digits_len(struct nf_conn *ct, const char *dptr,
+static int digits_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
{
int len = 0;
@@ -237,7 +237,7 @@ static int digits_len(struct nf_conn *ct, const char *dptr,
}
/* get digits length, skipping blank spaces. */
-static int skp_digits_len(struct nf_conn *ct, const char *dptr,
+static int skp_digits_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
{
for (; dptr <= limit && *dptr == ' '; dptr++)
@@ -246,8 +246,9 @@ static int skp_digits_len(struct nf_conn *ct, const char *dptr,
return digits_len(ct, dptr, limit, shift);
}
-static int parse_addr(struct nf_conn *ct, const char *cp, const char **endp,
- union nf_inet_addr *addr, const char *limit)
+static int parse_addr(const struct nf_conn *ct, const char *cp,
+ const char **endp, union nf_inet_addr *addr,
+ const char *limit)
{
const char *end;
int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
@@ -272,7 +273,7 @@ static int parse_addr(struct nf_conn *ct, const char *cp, const char **endp,
}
/* skip ip address. returns its length. */
-static int epaddr_len(struct nf_conn *ct, const char *dptr,
+static int epaddr_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
{
union nf_inet_addr addr;
@@ -292,7 +293,7 @@ static int epaddr_len(struct nf_conn *ct, const char *dptr,
}
/* get address length, skiping user info. */
-static int skp_epaddr_len(struct nf_conn *ct, const char *dptr,
+static int skp_epaddr_len(const struct nf_conn *ct, const char *dptr,
const char *limit, int *shift)
{
const char *start = dptr;
@@ -319,7 +320,7 @@ static int skp_epaddr_len(struct nf_conn *ct, const char *dptr,
}
/* Returns 0 if not found, -1 error parsing. */
-int ct_sip_get_info(struct nf_conn *ct,
+int ct_sip_get_info(const struct nf_conn *ct,
const char *dptr, size_t dlen,
unsigned int *matchoff,
unsigned int *matchlen,
@@ -407,7 +408,7 @@ static int sip_help(struct sk_buff *skb,
unsigned int dataoff, datalen;
const char *dptr;
int ret = NF_ACCEPT;
- int matchoff, matchlen;
+ unsigned int matchoff, matchlen;
u_int16_t port;
enum sip_header_pos pos;
typeof(nf_nat_sip_hook) nf_nat_sip;
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 696074a037c..e88e96af613 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -31,8 +31,8 @@ MODULE_LICENSE("GPL");
#ifdef CONFIG_PROC_FS
int
print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
- struct nf_conntrack_l3proto *l3proto,
- struct nf_conntrack_l4proto *l4proto)
+ const struct nf_conntrack_l3proto *l3proto,
+ const struct nf_conntrack_l4proto *l4proto)
{
return l3proto->print_tuple(s, tuple) || l4proto->print_tuple(s, tuple);
}
@@ -58,12 +58,14 @@ struct ct_iter_state {
static struct hlist_node *ct_get_first(struct seq_file *seq)
{
struct ct_iter_state *st = seq->private;
+ struct hlist_node *n;
for (st->bucket = 0;
st->bucket < nf_conntrack_htable_size;
st->bucket++) {
- if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
- return nf_conntrack_hash[st->bucket].first;
+ n = rcu_dereference(nf_conntrack_hash[st->bucket].first);
+ if (n)
+ return n;
}
return NULL;
}
@@ -73,11 +75,11 @@ static struct hlist_node *ct_get_next(struct seq_file *seq,
{
struct ct_iter_state *st = seq->private;
- head = head->next;
+ head = rcu_dereference(head->next);
while (head == NULL) {
if (++st->bucket >= nf_conntrack_htable_size)
return NULL;
- head = nf_conntrack_hash[st->bucket].first;
+ head = rcu_dereference(nf_conntrack_hash[st->bucket].first);
}
return head;
}
@@ -93,8 +95,9 @@ static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
}
static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
return ct_get_idx(seq, *pos);
}
@@ -105,79 +108,80 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void ct_seq_stop(struct seq_file *s, void *v)
+ __releases(RCU)
{
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
}
/* return 0 on success, 1 in case of error */
static int ct_seq_show(struct seq_file *s, void *v)
{
const struct nf_conntrack_tuple_hash *hash = v;
- const struct nf_conn *conntrack = nf_ct_tuplehash_to_ctrack(hash);
- struct nf_conntrack_l3proto *l3proto;
- struct nf_conntrack_l4proto *l4proto;
+ const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
+ const struct nf_conntrack_l3proto *l3proto;
+ const struct nf_conntrack_l4proto *l4proto;
- NF_CT_ASSERT(conntrack);
+ NF_CT_ASSERT(ct);
/* we only want to print DIR_ORIGINAL */
if (NF_CT_DIRECTION(hash))
return 0;
- l3proto = __nf_ct_l3proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.src.l3num);
NF_CT_ASSERT(l3proto);
- l4proto = __nf_ct_l4proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.src.l3num,
- conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+ ct->tuplehash[IP_CT_DIR_ORIGINAL]
.tuple.dst.protonum);
NF_CT_ASSERT(l4proto);
if (seq_printf(s, "%-8s %u %-8s %u %ld ",
l3proto->name,
- conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
l4proto->name,
- conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
- timer_pending(&conntrack->timeout)
- ? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0)
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
+ timer_pending(&ct->timeout)
+ ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
return -ENOSPC;
- if (l4proto->print_conntrack && l4proto->print_conntrack(s, conntrack))
+ if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct))
return -ENOSPC;
- if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+ if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
l3proto, l4proto))
return -ENOSPC;
- if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL]))
+ if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL]))
return -ENOSPC;
- if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
+ if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
if (seq_printf(s, "[UNREPLIED] "))
return -ENOSPC;
- if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
+ if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
l3proto, l4proto))
return -ENOSPC;
- if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY]))
+ if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY]))
return -ENOSPC;
- if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
+ if (test_bit(IPS_ASSURED_BIT, &ct->status))
if (seq_printf(s, "[ASSURED] "))
return -ENOSPC;
#if defined(CONFIG_NF_CONNTRACK_MARK)
- if (seq_printf(s, "mark=%u ", conntrack->mark))
+ if (seq_printf(s, "mark=%u ", ct->mark))
return -ENOSPC;
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
- if (seq_printf(s, "secmark=%u ", conntrack->secmark))
+ if (seq_printf(s, "secmark=%u ", ct->secmark))
return -ENOSPC;
#endif
- if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use)))
+ if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
return -ENOSPC;
return 0;
@@ -242,7 +246,7 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
static int ct_cpu_seq_show(struct seq_file *seq, void *v)
{
unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
- struct ip_conntrack_stat *st = v;
+ const struct ip_conntrack_stat *st = v;
if (v == SEQ_START_TOKEN) {
seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n");
@@ -380,7 +384,7 @@ static ctl_table nf_ct_netfilter_table[] = {
{ .ctl_name = 0 }
};
-struct ctl_path nf_ct_path[] = {
+static struct ctl_path nf_ct_path[] = {
{ .procname = "net", .ctl_name = CTL_NET, },
{ }
};
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index e894aa1ff3a..bd2e800f23c 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -25,7 +25,7 @@ MODULE_ALIAS("ip_conntrack_tftp");
#define MAX_PORTS 8
static unsigned short ports[MAX_PORTS];
-static int ports_c;
+static unsigned int ports_c;
module_param_array(ports, ushort, &ports_c, 0400);
MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
@@ -39,7 +39,8 @@ static int tftp_help(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{
- struct tftphdr _tftph, *tfh;
+ const struct tftphdr *tfh;
+ struct tftphdr _tftph;
struct nf_conntrack_expect *exp;
struct nf_conntrack_tuple *tuple;
unsigned int ret = NF_ACCEPT;
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 4f5f2885fca..cec9976aecb 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -103,6 +103,7 @@ EXPORT_SYMBOL(nf_log_packet);
#ifdef CONFIG_PROC_FS
static void *seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
{
rcu_read_lock();
@@ -123,6 +124,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void seq_stop(struct seq_file *s, void *v)
+ __releases(RCU)
{
rcu_read_unlock();
}
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 5013cb97ce2..7efa40d4739 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -467,7 +467,7 @@ __build_packet_message(struct nfulnl_instance *inst,
read_lock_bh(&skb->sk->sk_callback_lock);
if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
__be32 uid = htonl(skb->sk->sk_socket->file->f_uid);
- __be32 gid = htons(skb->sk->sk_socket->file->f_gid);
+ __be32 gid = htonl(skb->sk->sk_socket->file->f_gid);
/* need to unlock here since NLA_PUT may goto */
read_unlock_bh(&skb->sk->sk_callback_lock);
NLA_PUT_BE32(inst->skb, NFULA_UID, uid);
@@ -866,6 +866,7 @@ static struct hlist_node *get_idx(struct iter_state *st, loff_t pos)
}
static void *seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(instances_lock)
{
read_lock_bh(&instances_lock);
return get_idx(seq->private, *pos);
@@ -878,6 +879,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void seq_stop(struct seq_file *s, void *v)
+ __releases(instances_lock)
{
read_unlock_bh(&instances_lock);
}
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 51476f82bb5..a48b20fe9cd 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -360,7 +360,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
if (data_len) {
struct nlattr *nla;
- int size = nla_attr_size(data_len);
+ int sz = nla_attr_size(data_len);
if (skb_tailroom(skb) < nla_total_size(data_len)) {
printk(KERN_WARNING "nf_queue: no tailroom!\n");
@@ -369,7 +369,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
nla = (struct nlattr *)skb_put(skb, nla_total_size(data_len));
nla->nla_type = NFQA_PAYLOAD;
- nla->nla_len = size;
+ nla->nla_len = sz;
if (skb_copy_bits(entskb, 0, nla_data(nla), data_len))
BUG();
@@ -845,6 +845,7 @@ static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
}
static void *seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(instances_lock)
{
spin_lock(&instances_lock);
return get_idx(seq, *pos);
@@ -857,6 +858,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void seq_stop(struct seq_file *s, void *v)
+ __releases(instances_lock)
{
spin_unlock(&instances_lock);
}
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 8d4fca96a4a..a6792089fcf 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -44,7 +44,6 @@ struct xt_af {
struct mutex mutex;
struct list_head match;
struct list_head target;
- struct list_head tables;
#ifdef CONFIG_COMPAT
struct mutex compat_mutex;
struct compat_delta *compat_offsets;
@@ -59,12 +58,6 @@ static struct xt_af *xt;
#define duprintf(format, args...)
#endif
-enum {
- TABLE,
- TARGET,
- MATCH,
-};
-
static const char *xt_prefix[NPROTO] = {
[AF_INET] = "ip",
[AF_INET6] = "ip6",
@@ -400,7 +393,7 @@ int xt_compat_match_offset(struct xt_match *match)
EXPORT_SYMBOL_GPL(xt_compat_match_offset);
int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
- int *size)
+ unsigned int *size)
{
struct xt_match *match = m->u.kernel.match;
struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
@@ -427,7 +420,7 @@ int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr,
- int *size)
+ unsigned int *size)
{
struct xt_match *match = m->u.kernel.match;
struct compat_xt_entry_match __user *cm = *dstptr;
@@ -494,7 +487,7 @@ int xt_compat_target_offset(struct xt_target *target)
EXPORT_SYMBOL_GPL(xt_compat_target_offset);
void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
- int *size)
+ unsigned int *size)
{
struct xt_target *target = t->u.kernel.target;
struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
@@ -520,7 +513,7 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
EXPORT_SYMBOL_GPL(xt_compat_target_from_user);
int xt_compat_target_to_user(struct xt_entry_target *t, void __user **dstptr,
- int *size)
+ unsigned int *size)
{
struct xt_target *target = t->u.kernel.target;
struct compat_xt_entry_target __user *ct = *dstptr;
@@ -597,14 +590,14 @@ void xt_free_table_info(struct xt_table_info *info)
EXPORT_SYMBOL(xt_free_table_info);
/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
-struct xt_table *xt_find_table_lock(int af, const char *name)
+struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name)
{
struct xt_table *t;
if (mutex_lock_interruptible(&xt[af].mutex) != 0)
return ERR_PTR(-EINTR);
- list_for_each_entry(t, &xt[af].tables, list)
+ list_for_each_entry(t, &net->xt.tables[af], list)
if (strcmp(t->name, name) == 0 && try_module_get(t->me))
return t;
mutex_unlock(&xt[af].mutex);
@@ -660,20 +653,27 @@ xt_replace_table(struct xt_table *table,
}
EXPORT_SYMBOL_GPL(xt_replace_table);
-int xt_register_table(struct xt_table *table,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo)
+struct xt_table *xt_register_table(struct net *net, struct xt_table *table,
+ struct xt_table_info *bootstrap,
+ struct xt_table_info *newinfo)
{
int ret;
struct xt_table_info *private;
struct xt_table *t;
+ /* Don't add one object to multiple lists. */
+ table = kmemdup(table, sizeof(struct xt_table), GFP_KERNEL);
+ if (!table) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
ret = mutex_lock_interruptible(&xt[table->af].mutex);
if (ret != 0)
- return ret;
+ goto out_free;
/* Don't autoload: we'd eat our tail... */
- list_for_each_entry(t, &xt[table->af].tables, list) {
+ list_for_each_entry(t, &net->xt.tables[table->af], list) {
if (strcmp(t->name, table->name) == 0) {
ret = -EEXIST;
goto unlock;
@@ -692,12 +692,16 @@ int xt_register_table(struct xt_table *table,
/* save number of initial entries */
private->initial_entries = private->number;
- list_add(&table->list, &xt[table->af].tables);
+ list_add(&table->list, &net->xt.tables[table->af]);
+ mutex_unlock(&xt[table->af].mutex);
+ return table;
- ret = 0;
unlock:
mutex_unlock(&xt[table->af].mutex);
- return ret;
+out_free:
+ kfree(table);
+out:
+ return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(xt_register_table);
@@ -709,130 +713,204 @@ void *xt_unregister_table(struct xt_table *table)
private = table->private;
list_del(&table->list);
mutex_unlock(&xt[table->af].mutex);
+ kfree(table);
return private;
}
EXPORT_SYMBOL_GPL(xt_unregister_table);
#ifdef CONFIG_PROC_FS
-static struct list_head *xt_get_idx(struct list_head *list, struct seq_file *seq, loff_t pos)
+struct xt_names_priv {
+ struct seq_net_private p;
+ int af;
+};
+static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct list_head *head = list->next;
+ struct xt_names_priv *priv = seq->private;
+ struct net *net = priv->p.net;
+ int af = priv->af;
- if (!head || list_empty(list))
- return NULL;
+ mutex_lock(&xt[af].mutex);
+ return seq_list_start(&net->xt.tables[af], *pos);
+}
- while (pos && (head = head->next)) {
- if (head == list)
- return NULL;
- pos--;
- }
- return pos ? NULL : head;
-}
-
-static struct list_head *type2list(u_int16_t af, u_int16_t type)
-{
- struct list_head *list;
-
- switch (type) {
- case TARGET:
- list = &xt[af].target;
- break;
- case MATCH:
- list = &xt[af].match;
- break;
- case TABLE:
- list = &xt[af].tables;
- break;
- default:
- list = NULL;
- break;
- }
+static void *xt_table_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct xt_names_priv *priv = seq->private;
+ struct net *net = priv->p.net;
+ int af = priv->af;
- return list;
+ return seq_list_next(v, &net->xt.tables[af], pos);
}
-static void *xt_tgt_seq_start(struct seq_file *seq, loff_t *pos)
+static void xt_table_seq_stop(struct seq_file *seq, void *v)
{
- struct proc_dir_entry *pde = (struct proc_dir_entry *) seq->private;
- u_int16_t af = (unsigned long)pde->data & 0xffff;
- u_int16_t type = (unsigned long)pde->data >> 16;
- struct list_head *list;
+ struct xt_names_priv *priv = seq->private;
+ int af = priv->af;
- if (af >= NPROTO)
- return NULL;
+ mutex_unlock(&xt[af].mutex);
+}
- list = type2list(af, type);
- if (!list)
- return NULL;
+static int xt_table_seq_show(struct seq_file *seq, void *v)
+{
+ struct xt_table *table = list_entry(v, struct xt_table, list);
- if (mutex_lock_interruptible(&xt[af].mutex) != 0)
- return NULL;
+ if (strlen(table->name))
+ return seq_printf(seq, "%s\n", table->name);
+ else
+ return 0;
+}
+
+static const struct seq_operations xt_table_seq_ops = {
+ .start = xt_table_seq_start,
+ .next = xt_table_seq_next,
+ .stop = xt_table_seq_stop,
+ .show = xt_table_seq_show,
+};
- return xt_get_idx(list, seq, *pos);
+static int xt_table_open(struct inode *inode, struct file *file)
+{
+ int ret;
+ struct xt_names_priv *priv;
+
+ ret = seq_open_net(inode, file, &xt_table_seq_ops,
+ sizeof(struct xt_names_priv));
+ if (!ret) {
+ priv = ((struct seq_file *)file->private_data)->private;
+ priv->af = (unsigned long)PDE(inode)->data;
+ }
+ return ret;
}
-static void *xt_tgt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static const struct file_operations xt_table_ops = {
+ .owner = THIS_MODULE,
+ .open = xt_table_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static void *xt_match_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct proc_dir_entry *pde = seq->private;
- u_int16_t af = (unsigned long)pde->data & 0xffff;
- u_int16_t type = (unsigned long)pde->data >> 16;
- struct list_head *list;
+ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+ u_int16_t af = (unsigned long)pde->data;
- if (af >= NPROTO)
- return NULL;
+ mutex_lock(&xt[af].mutex);
+ return seq_list_start(&xt[af].match, *pos);
+}
- list = type2list(af, type);
- if (!list)
- return NULL;
+static void *xt_match_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+ u_int16_t af = (unsigned long)pde->data;
- (*pos)++;
- return xt_get_idx(list, seq, *pos);
+ return seq_list_next(v, &xt[af].match, pos);
}
-static void xt_tgt_seq_stop(struct seq_file *seq, void *v)
+static void xt_match_seq_stop(struct seq_file *seq, void *v)
{
struct proc_dir_entry *pde = seq->private;
- u_int16_t af = (unsigned long)pde->data & 0xffff;
+ u_int16_t af = (unsigned long)pde->data;
mutex_unlock(&xt[af].mutex);
}
-static int xt_name_seq_show(struct seq_file *seq, void *v)
+static int xt_match_seq_show(struct seq_file *seq, void *v)
{
- char *name = (char *)v + sizeof(struct list_head);
+ struct xt_match *match = list_entry(v, struct xt_match, list);
- if (strlen(name))
- return seq_printf(seq, "%s\n", name);
+ if (strlen(match->name))
+ return seq_printf(seq, "%s\n", match->name);
else
return 0;
}
-static const struct seq_operations xt_tgt_seq_ops = {
- .start = xt_tgt_seq_start,
- .next = xt_tgt_seq_next,
- .stop = xt_tgt_seq_stop,
- .show = xt_name_seq_show,
+static const struct seq_operations xt_match_seq_ops = {
+ .start = xt_match_seq_start,
+ .next = xt_match_seq_next,
+ .stop = xt_match_seq_stop,
+ .show = xt_match_seq_show,
};
-static int xt_tgt_open(struct inode *inode, struct file *file)
+static int xt_match_open(struct inode *inode, struct file *file)
{
int ret;
- ret = seq_open(file, &xt_tgt_seq_ops);
+ ret = seq_open(file, &xt_match_seq_ops);
if (!ret) {
struct seq_file *seq = file->private_data;
- struct proc_dir_entry *pde = PDE(inode);
- seq->private = pde;
+ seq->private = PDE(inode);
}
+ return ret;
+}
+
+static const struct file_operations xt_match_ops = {
+ .owner = THIS_MODULE,
+ .open = xt_match_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static void *xt_target_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+ u_int16_t af = (unsigned long)pde->data;
+
+ mutex_lock(&xt[af].mutex);
+ return seq_list_start(&xt[af].target, *pos);
+}
+
+static void *xt_target_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct proc_dir_entry *pde = (struct proc_dir_entry *)seq->private;
+ u_int16_t af = (unsigned long)pde->data;
+
+ return seq_list_next(v, &xt[af].target, pos);
+}
+
+static void xt_target_seq_stop(struct seq_file *seq, void *v)
+{
+ struct proc_dir_entry *pde = seq->private;
+ u_int16_t af = (unsigned long)pde->data;
+
+ mutex_unlock(&xt[af].mutex);
+}
+static int xt_target_seq_show(struct seq_file *seq, void *v)
+{
+ struct xt_target *target = list_entry(v, struct xt_target, list);
+
+ if (strlen(target->name))
+ return seq_printf(seq, "%s\n", target->name);
+ else
+ return 0;
+}
+
+static const struct seq_operations xt_target_seq_ops = {
+ .start = xt_target_seq_start,
+ .next = xt_target_seq_next,
+ .stop = xt_target_seq_stop,
+ .show = xt_target_seq_show,
+};
+
+static int xt_target_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ ret = seq_open(file, &xt_target_seq_ops);
+ if (!ret) {
+ struct seq_file *seq = file->private_data;
+
+ seq->private = PDE(inode);
+ }
return ret;
}
-static const struct file_operations xt_file_ops = {
+static const struct file_operations xt_target_ops = {
.owner = THIS_MODULE,
- .open = xt_tgt_open,
+ .open = xt_target_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
@@ -844,7 +922,7 @@ static const struct file_operations xt_file_ops = {
#endif /* CONFIG_PROC_FS */
-int xt_proto_init(int af)
+int xt_proto_init(struct net *net, int af)
{
#ifdef CONFIG_PROC_FS
char buf[XT_FUNCTION_MAXNAMELEN];
@@ -858,25 +936,25 @@ int xt_proto_init(int af)
#ifdef CONFIG_PROC_FS
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
- proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+ proc = proc_net_fops_create(net, buf, 0440, &xt_table_ops);
if (!proc)
goto out;
- proc->data = (void *) ((unsigned long) af | (TABLE << 16));
+ proc->data = (void *)(unsigned long)af;
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
- proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+ proc = proc_net_fops_create(net, buf, 0440, &xt_match_ops);
if (!proc)
goto out_remove_tables;
- proc->data = (void *) ((unsigned long) af | (MATCH << 16));
+ proc->data = (void *)(unsigned long)af;
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
- proc = proc_net_fops_create(&init_net, buf, 0440, &xt_file_ops);
+ proc = proc_net_fops_create(net, buf, 0440, &xt_target_ops);
if (!proc)
goto out_remove_matches;
- proc->data = (void *) ((unsigned long) af | (TARGET << 16));
+ proc->data = (void *)(unsigned long)af;
#endif
return 0;
@@ -885,42 +963,54 @@ int xt_proto_init(int af)
out_remove_matches:
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
out_remove_tables:
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
out:
return -1;
#endif
}
EXPORT_SYMBOL_GPL(xt_proto_init);
-void xt_proto_fini(int af)
+void xt_proto_fini(struct net *net, int af)
{
#ifdef CONFIG_PROC_FS
char buf[XT_FUNCTION_MAXNAMELEN];
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TABLES, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_TARGETS, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
strlcpy(buf, xt_prefix[af], sizeof(buf));
strlcat(buf, FORMAT_MATCHES, sizeof(buf));
- proc_net_remove(&init_net, buf);
+ proc_net_remove(net, buf);
#endif /*CONFIG_PROC_FS*/
}
EXPORT_SYMBOL_GPL(xt_proto_fini);
+static int __net_init xt_net_init(struct net *net)
+{
+ int i;
+
+ for (i = 0; i < NPROTO; i++)
+ INIT_LIST_HEAD(&net->xt.tables[i]);
+ return 0;
+}
+
+static struct pernet_operations xt_net_ops = {
+ .init = xt_net_init,
+};
static int __init xt_init(void)
{
- int i;
+ int i, rv;
xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL);
if (!xt)
@@ -934,13 +1024,16 @@ static int __init xt_init(void)
#endif
INIT_LIST_HEAD(&xt[i].target);
INIT_LIST_HEAD(&xt[i].match);
- INIT_LIST_HEAD(&xt[i].tables);
}
- return 0;
+ rv = register_pernet_subsys(&xt_net_ops);
+ if (rv < 0)
+ kfree(xt);
+ return rv;
}
static void __exit xt_fini(void)
{
+ unregister_pernet_subsys(&xt_net_ops);
kfree(xt);
}
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index 60e3767cc71..217e2b68632 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -13,7 +13,10 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/tcp.h>
+#include <net/dst.h>
+#include <net/flow.h>
#include <net/ipv6.h>
+#include <net/route.h>
#include <net/tcp.h>
#include <linux/netfilter_ipv4/ip_tables.h>
@@ -41,6 +44,7 @@ optlen(const u_int8_t *opt, unsigned int offset)
static int
tcpmss_mangle_packet(struct sk_buff *skb,
const struct xt_tcpmss_info *info,
+ unsigned int in_mtu,
unsigned int tcphoff,
unsigned int minlen)
{
@@ -76,7 +80,13 @@ tcpmss_mangle_packet(struct sk_buff *skb,
dst_mtu(skb->dst));
return -1;
}
- newmss = dst_mtu(skb->dst) - minlen;
+ if (in_mtu <= minlen) {
+ if (net_ratelimit())
+ printk(KERN_ERR "xt_TCPMSS: unknown or "
+ "invalid path-MTU (%u)\n", in_mtu);
+ return -1;
+ }
+ newmss = min(dst_mtu(skb->dst), in_mtu) - minlen;
} else
newmss = info->mss;
@@ -137,6 +147,28 @@ tcpmss_mangle_packet(struct sk_buff *skb,
return TCPOLEN_MSS;
}
+static u_int32_t tcpmss_reverse_mtu4(const struct iphdr *iph)
+{
+ struct flowi fl = {
+ .fl4_dst = iph->saddr,
+ };
+ const struct nf_afinfo *ai;
+ struct rtable *rt = NULL;
+ u_int32_t mtu = ~0U;
+
+ rcu_read_lock();
+ ai = nf_get_afinfo(AF_INET);
+ if (ai != NULL)
+ ai->route((struct dst_entry **)&rt, &fl);
+ rcu_read_unlock();
+
+ if (rt != NULL) {
+ mtu = dst_mtu(&rt->u.dst);
+ dst_release(&rt->u.dst);
+ }
+ return mtu;
+}
+
static unsigned int
tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
@@ -146,7 +178,8 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
__be16 newlen;
int ret;
- ret = tcpmss_mangle_packet(skb, targinfo, iph->ihl * 4,
+ ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu4(iph),
+ iph->ihl * 4,
sizeof(*iph) + sizeof(struct tcphdr));
if (ret < 0)
return NF_DROP;
@@ -160,6 +193,28 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
}
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+static u_int32_t tcpmss_reverse_mtu6(const struct ipv6hdr *iph)
+{
+ struct flowi fl = {
+ .fl6_dst = iph->saddr,
+ };
+ const struct nf_afinfo *ai;
+ struct rtable *rt = NULL;
+ u_int32_t mtu = ~0U;
+
+ rcu_read_lock();
+ ai = nf_get_afinfo(AF_INET6);
+ if (ai != NULL)
+ ai->route((struct dst_entry **)&rt, &fl);
+ rcu_read_unlock();
+
+ if (rt != NULL) {
+ mtu = dst_mtu(&rt->u.dst);
+ dst_release(&rt->u.dst);
+ }
+ return mtu;
+}
+
static unsigned int
tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
@@ -174,7 +229,8 @@ tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
if (tcphoff < 0)
return NF_DROP;
- ret = tcpmss_mangle_packet(skb, targinfo, tcphoff,
+ ret = tcpmss_mangle_packet(skb, targinfo, tcpmss_reverse_mtu6(ipv6h),
+ tcphoff,
sizeof(*ipv6h) + sizeof(struct tcphdr));
if (ret < 0)
return NF_DROP;
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index e00ecd974fa..3b0111933f6 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -120,11 +120,11 @@ static int count_them(struct xt_connlimit_data *data,
else
hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)];
- read_lock_bh(&nf_conntrack_lock);
+ rcu_read_lock();
/* check the saved connections */
list_for_each_entry_safe(conn, tmp, hash, list) {
- found = __nf_conntrack_find(&conn->tuple, NULL);
+ found = __nf_conntrack_find(&conn->tuple);
found_ct = NULL;
if (found != NULL)
@@ -163,7 +163,7 @@ static int count_them(struct xt_connlimit_data *data,
++matches;
}
- read_unlock_bh(&nf_conntrack_lock);
+ rcu_read_unlock();
if (addit) {
/* save the new connection in our list */
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index e92190eafcc..85330856a29 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -4,7 +4,6 @@
*
* (C) 2001 Marc Boucher (marc@mbsi.ca).
* Copyright © CC Computer Consultants GmbH, 2007 - 2008
- * Jan Engelhardt <jengelh@computergmbh.de>
*
* 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
@@ -20,6 +19,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("Xtables: connection tracking state match");
MODULE_ALIAS("ipt_conntrack");
MODULE_ALIAS("ip6t_conntrack");
@@ -166,6 +166,44 @@ conntrack_mt_repldst(const struct nf_conn *ct,
&info->repldst_addr, &info->repldst_mask, family);
}
+static inline bool
+ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
+ const struct nf_conn *ct)
+{
+ const struct nf_conntrack_tuple *tuple;
+
+ tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ if ((info->match_flags & XT_CONNTRACK_PROTO) &&
+ (tuple->dst.protonum == info->l4proto) ^
+ !(info->invert_flags & XT_CONNTRACK_PROTO))
+ return false;
+
+ /* Shortcut to match all recognized protocols by using ->src.all. */
+ if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) &&
+ (tuple->src.u.all == info->origsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT))
+ return false;
+
+ if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) &&
+ (tuple->dst.u.all == info->origdst_port) ^
+ !(info->invert_flags & XT_CONNTRACK_ORIGDST_PORT))
+ return false;
+
+ tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+
+ if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) &&
+ (tuple->src.u.all == info->replsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLSRC_PORT))
+ return false;
+
+ if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) &&
+ (tuple->dst.u.all == info->repldst_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLDST_PORT))
+ return false;
+
+ return true;
+}
+
static bool
conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
@@ -200,10 +238,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
if (ct == NULL)
return info->match_flags & XT_CONNTRACK_STATE;
-
- if ((info->match_flags & XT_CONNTRACK_PROTO) &&
- ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
- info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO)))
+ if ((info->match_flags & XT_CONNTRACK_DIRECTION) &&
+ (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^
+ !!(info->invert_flags & XT_CONNTRACK_DIRECTION))
return false;
if (info->match_flags & XT_CONNTRACK_ORIGSRC)
@@ -226,6 +263,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
!(info->invert_flags & XT_CONNTRACK_REPLDST))
return false;
+ if (!ct_proto_port_check(info, ct))
+ return false;
+
if ((info->match_flags & XT_CONNTRACK_STATUS) &&
(!!(info->status_mask & ct->status) ^
!(info->invert_flags & XT_CONNTRACK_STATUS)))
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index d479ca98011..744c7f2ab0b 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -1,9 +1,9 @@
-/* iptables match extension to limit the number of packets per second
- * seperately for each hashbucket (sourceip/sourceport/dstip/dstport)
+/*
+ * xt_hashlimit - Netfilter module to limit the number of packets per time
+ * seperately for each hashbucket (sourceip/sourceport/dstip/dstport)
*
- * (C) 2003-2004 by Harald Welte <laforge@netfilter.org>
- *
- * $Id: ipt_hashlimit.c 3244 2004-10-20 16:24:29Z laforge@netfilter.org $
+ * (C) 2003-2004 by Harald Welte <laforge@netfilter.org>
+ * Copyright © CC Computer Consultants GmbH, 2007 - 2008
*
* Development of this code was funded by Astaro AG, http://www.astaro.com/
*/
@@ -35,6 +35,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("Xtables: per hash-bucket rate-limit match");
MODULE_ALIAS("ipt_hashlimit");
MODULE_ALIAS("ip6t_hashlimit");
@@ -57,7 +58,7 @@ struct dsthash_dst {
__be32 dst[4];
} ip6;
#endif
- } addr;
+ };
__be16 src_port;
__be16 dst_port;
};
@@ -81,7 +82,7 @@ struct xt_hashlimit_htable {
atomic_t use;
int family;
- struct hashlimit_cfg cfg; /* config */
+ struct hashlimit_cfg1 cfg; /* config */
/* used internally */
spinlock_t lock; /* lock for list_head */
@@ -184,7 +185,7 @@ dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
}
static void htable_gc(unsigned long htlong);
-static int htable_create(struct xt_hashlimit_info *minfo, int family)
+static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
{
struct xt_hashlimit_htable *hinfo;
unsigned int size;
@@ -210,7 +211,18 @@ static int htable_create(struct xt_hashlimit_info *minfo, int family)
minfo->hinfo = hinfo;
/* copy match config into hashtable config */
- memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
+ hinfo->cfg.mode = minfo->cfg.mode;
+ hinfo->cfg.avg = minfo->cfg.avg;
+ hinfo->cfg.burst = minfo->cfg.burst;
+ hinfo->cfg.max = minfo->cfg.max;
+ hinfo->cfg.gc_interval = minfo->cfg.gc_interval;
+ hinfo->cfg.expire = minfo->cfg.expire;
+
+ if (family == AF_INET)
+ hinfo->cfg.srcmask = hinfo->cfg.dstmask = 32;
+ else
+ hinfo->cfg.srcmask = hinfo->cfg.dstmask = 128;
+
hinfo->cfg.size = size;
if (!hinfo->cfg.max)
hinfo->cfg.max = 8 * hinfo->cfg.size;
@@ -246,6 +258,70 @@ static int htable_create(struct xt_hashlimit_info *minfo, int family)
return 0;
}
+static int htable_create(struct xt_hashlimit_mtinfo1 *minfo,
+ unsigned int family)
+{
+ struct xt_hashlimit_htable *hinfo;
+ unsigned int size;
+ unsigned int i;
+
+ if (minfo->cfg.size) {
+ size = minfo->cfg.size;
+ } else {
+ size = (num_physpages << PAGE_SHIFT) / 16384 /
+ sizeof(struct list_head);
+ if (num_physpages > 1024 * 1024 * 1024 / PAGE_SIZE)
+ size = 8192;
+ if (size < 16)
+ size = 16;
+ }
+ /* FIXME: don't use vmalloc() here or anywhere else -HW */
+ hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) +
+ sizeof(struct list_head) * size);
+ if (hinfo == NULL) {
+ printk(KERN_ERR "xt_hashlimit: unable to create hashtable\n");
+ return -1;
+ }
+ minfo->hinfo = hinfo;
+
+ /* copy match config into hashtable config */
+ memcpy(&hinfo->cfg, &minfo->cfg, sizeof(hinfo->cfg));
+ hinfo->cfg.size = size;
+ if (hinfo->cfg.max == 0)
+ hinfo->cfg.max = 8 * hinfo->cfg.size;
+ else if (hinfo->cfg.max < hinfo->cfg.size)
+ hinfo->cfg.max = hinfo->cfg.size;
+
+ for (i = 0; i < hinfo->cfg.size; i++)
+ INIT_HLIST_HEAD(&hinfo->hash[i]);
+
+ atomic_set(&hinfo->use, 1);
+ hinfo->count = 0;
+ hinfo->family = family;
+ hinfo->rnd_initialized = 0;
+ spin_lock_init(&hinfo->lock);
+
+ hinfo->pde = create_proc_entry(minfo->name, 0,
+ family == AF_INET ? hashlimit_procdir4 :
+ hashlimit_procdir6);
+ if (hinfo->pde == NULL) {
+ vfree(hinfo);
+ return -1;
+ }
+ hinfo->pde->proc_fops = &dl_file_ops;
+ hinfo->pde->data = hinfo;
+
+ setup_timer(&hinfo->timer, htable_gc, (unsigned long)hinfo);
+ hinfo->timer.expires = jiffies + msecs_to_jiffies(hinfo->cfg.gc_interval);
+ add_timer(&hinfo->timer);
+
+ spin_lock_bh(&hashlimit_lock);
+ hlist_add_head(&hinfo->node, &hashlimit_htables);
+ spin_unlock_bh(&hashlimit_lock);
+
+ return 0;
+}
+
static bool select_all(const struct xt_hashlimit_htable *ht,
const struct dsthash_ent *he)
{
@@ -388,6 +464,48 @@ static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
dh->rateinfo.prev = now;
}
+static inline __be32 maskl(__be32 a, unsigned int l)
+{
+ return htonl(ntohl(a) & ~(~(u_int32_t)0 >> l));
+}
+
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+static void hashlimit_ipv6_mask(__be32 *i, unsigned int p)
+{
+ switch (p) {
+ case 0:
+ i[0] = i[1] = 0;
+ i[2] = i[3] = 0;
+ break;
+ case 1 ... 31:
+ i[0] = maskl(i[0], p);
+ i[1] = i[2] = i[3] = 0;
+ break;
+ case 32:
+ i[1] = i[2] = i[3] = 0;
+ break;
+ case 33 ... 63:
+ i[1] = maskl(i[1], p - 32);
+ i[2] = i[3] = 0;
+ break;
+ case 64:
+ i[2] = i[3] = 0;
+ break;
+ case 65 ... 95:
+ i[2] = maskl(i[2], p - 64);
+ i[3] = 0;
+ case 96:
+ i[3] = 0;
+ break;
+ case 97 ... 127:
+ i[3] = maskl(i[3], p - 96);
+ break;
+ case 128:
+ break;
+ }
+}
+#endif
+
static int
hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
struct dsthash_dst *dst,
@@ -401,9 +519,11 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
switch (hinfo->family) {
case AF_INET:
if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
- dst->addr.ip.dst = ip_hdr(skb)->daddr;
+ dst->ip.dst = maskl(ip_hdr(skb)->daddr,
+ hinfo->cfg.dstmask);
if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
- dst->addr.ip.src = ip_hdr(skb)->saddr;
+ dst->ip.src = maskl(ip_hdr(skb)->saddr,
+ hinfo->cfg.srcmask);
if (!(hinfo->cfg.mode &
(XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
@@ -412,12 +532,16 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
break;
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
case AF_INET6:
- if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
- memcpy(&dst->addr.ip6.dst, &ipv6_hdr(skb)->daddr,
- sizeof(dst->addr.ip6.dst));
- if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
- memcpy(&dst->addr.ip6.src, &ipv6_hdr(skb)->saddr,
- sizeof(dst->addr.ip6.src));
+ if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) {
+ memcpy(&dst->ip6.dst, &ipv6_hdr(skb)->daddr,
+ sizeof(dst->ip6.dst));
+ hashlimit_ipv6_mask(dst->ip6.dst, hinfo->cfg.dstmask);
+ }
+ if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP) {
+ memcpy(&dst->ip6.src, &ipv6_hdr(skb)->saddr,
+ sizeof(dst->ip6.src));
+ hashlimit_ipv6_mask(dst->ip6.src, hinfo->cfg.srcmask);
+ }
if (!(hinfo->cfg.mode &
(XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
@@ -457,10 +581,10 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
}
static bool
-hashlimit_mt(const struct sk_buff *skb, const struct net_device *in,
- const struct net_device *out, const struct xt_match *match,
- const void *matchinfo, int offset, unsigned int protoff,
- bool *hotdrop)
+hashlimit_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+ const struct net_device *out, const struct xt_match *match,
+ const void *matchinfo, int offset, unsigned int protoff,
+ bool *hotdrop)
{
const struct xt_hashlimit_info *r =
((const struct xt_hashlimit_info *)matchinfo)->u.master;
@@ -512,9 +636,62 @@ hotdrop:
}
static bool
-hashlimit_mt_check(const char *tablename, const void *inf,
- const struct xt_match *match, void *matchinfo,
- unsigned int hook_mask)
+hashlimit_mt(const struct sk_buff *skb, const struct net_device *in,
+ const struct net_device *out, const struct xt_match *match,
+ const void *matchinfo, int offset, unsigned int protoff,
+ bool *hotdrop)
+{
+ const struct xt_hashlimit_mtinfo1 *info = matchinfo;
+ struct xt_hashlimit_htable *hinfo = info->hinfo;
+ unsigned long now = jiffies;
+ struct dsthash_ent *dh;
+ struct dsthash_dst dst;
+
+ if (hashlimit_init_dst(hinfo, &dst, skb, protoff) < 0)
+ goto hotdrop;
+
+ spin_lock_bh(&hinfo->lock);
+ dh = dsthash_find(hinfo, &dst);
+ if (dh == NULL) {
+ dh = dsthash_alloc_init(hinfo, &dst);
+ if (dh == NULL) {
+ spin_unlock_bh(&hinfo->lock);
+ goto hotdrop;
+ }
+
+ dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
+ dh->rateinfo.prev = jiffies;
+ dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
+ hinfo->cfg.burst);
+ dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
+ hinfo->cfg.burst);
+ dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
+ } else {
+ /* update expiration timeout */
+ dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
+ rateinfo_recalc(dh, now);
+ }
+
+ if (dh->rateinfo.credit >= dh->rateinfo.cost) {
+ /* below the limit */
+ dh->rateinfo.credit -= dh->rateinfo.cost;
+ spin_unlock_bh(&hinfo->lock);
+ return !(info->cfg.mode & XT_HASHLIMIT_INVERT);
+ }
+
+ spin_unlock_bh(&hinfo->lock);
+ /* default match is underlimit - so over the limit, we need to invert */
+ return info->cfg.mode & XT_HASHLIMIT_INVERT;
+
+ hotdrop:
+ *hotdrop = true;
+ return false;
+}
+
+static bool
+hashlimit_mt_check_v0(const char *tablename, const void *inf,
+ const struct xt_match *match, void *matchinfo,
+ unsigned int hook_mask)
{
struct xt_hashlimit_info *r = matchinfo;
@@ -546,7 +723,7 @@ hashlimit_mt_check(const char *tablename, const void *inf,
* create duplicate proc files. -HW */
mutex_lock(&hlimit_mutex);
r->hinfo = htable_find_get(r->name, match->family);
- if (!r->hinfo && htable_create(r, match->family) != 0) {
+ if (!r->hinfo && htable_create_v0(r, match->family) != 0) {
mutex_unlock(&hlimit_mutex);
return false;
}
@@ -557,14 +734,68 @@ hashlimit_mt_check(const char *tablename, const void *inf,
return true;
}
+static bool
+hashlimit_mt_check(const char *tablename, const void *inf,
+ const struct xt_match *match, void *matchinfo,
+ unsigned int hook_mask)
+{
+ struct xt_hashlimit_mtinfo1 *info = matchinfo;
+
+ /* Check for overflow. */
+ if (info->cfg.burst == 0 ||
+ user2credits(info->cfg.avg * info->cfg.burst) <
+ user2credits(info->cfg.avg)) {
+ printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n",
+ info->cfg.avg, info->cfg.burst);
+ return false;
+ }
+ if (info->cfg.gc_interval == 0 || info->cfg.expire == 0)
+ return false;
+ if (info->name[sizeof(info->name)-1] != '\0')
+ return false;
+ if (match->family == AF_INET) {
+ if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32)
+ return false;
+ } else {
+ if (info->cfg.srcmask > 128 || info->cfg.dstmask > 128)
+ return false;
+ }
+
+ /* This is the best we've got: We cannot release and re-grab lock,
+ * since checkentry() is called before x_tables.c grabs xt_mutex.
+ * We also cannot grab the hashtable spinlock, since htable_create will
+ * call vmalloc, and that can sleep. And we cannot just re-search
+ * the list of htable's in htable_create(), since then we would
+ * create duplicate proc files. -HW */
+ mutex_lock(&hlimit_mutex);
+ info->hinfo = htable_find_get(info->name, match->family);
+ if (!info->hinfo && htable_create(info, match->family) != 0) {
+ mutex_unlock(&hlimit_mutex);
+ return false;
+ }
+ mutex_unlock(&hlimit_mutex);
+
+ /* Ugly hack: For SMP, we only want to use one set */
+ info->master = info;
+ return true;
+}
+
static void
-hashlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
+hashlimit_mt_destroy_v0(const struct xt_match *match, void *matchinfo)
{
const struct xt_hashlimit_info *r = matchinfo;
htable_put(r->hinfo);
}
+static void
+hashlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
+{
+ const struct xt_hashlimit_mtinfo1 *info = matchinfo;
+
+ htable_put(info->hinfo);
+}
+
#ifdef CONFIG_COMPAT
struct compat_xt_hashlimit_info {
char name[IFNAMSIZ];
@@ -592,38 +823,60 @@ static int hashlimit_mt_compat_to_user(void __user *dst, void *src)
static struct xt_match hashlimit_mt_reg[] __read_mostly = {
{
.name = "hashlimit",
+ .revision = 0,
.family = AF_INET,
- .match = hashlimit_mt,
+ .match = hashlimit_mt_v0,
.matchsize = sizeof(struct xt_hashlimit_info),
#ifdef CONFIG_COMPAT
.compatsize = sizeof(struct compat_xt_hashlimit_info),
.compat_from_user = hashlimit_mt_compat_from_user,
.compat_to_user = hashlimit_mt_compat_to_user,
#endif
- .checkentry = hashlimit_mt_check,
- .destroy = hashlimit_mt_destroy,
+ .checkentry = hashlimit_mt_check_v0,
+ .destroy = hashlimit_mt_destroy_v0,
.me = THIS_MODULE
},
+ {
+ .name = "hashlimit",
+ .revision = 1,
+ .family = AF_INET,
+ .match = hashlimit_mt,
+ .matchsize = sizeof(struct xt_hashlimit_mtinfo1),
+ .checkentry = hashlimit_mt_check,
+ .destroy = hashlimit_mt_destroy,
+ .me = THIS_MODULE,
+ },
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
{
.name = "hashlimit",
.family = AF_INET6,
- .match = hashlimit_mt,
+ .match = hashlimit_mt_v0,
.matchsize = sizeof(struct xt_hashlimit_info),
#ifdef CONFIG_COMPAT
.compatsize = sizeof(struct compat_xt_hashlimit_info),
.compat_from_user = hashlimit_mt_compat_from_user,
.compat_to_user = hashlimit_mt_compat_to_user,
#endif
- .checkentry = hashlimit_mt_check,
- .destroy = hashlimit_mt_destroy,
+ .checkentry = hashlimit_mt_check_v0,
+ .destroy = hashlimit_mt_destroy_v0,
.me = THIS_MODULE
},
+ {
+ .name = "hashlimit",
+ .revision = 1,
+ .family = AF_INET6,
+ .match = hashlimit_mt,
+ .matchsize = sizeof(struct xt_hashlimit_mtinfo1),
+ .checkentry = hashlimit_mt_check,
+ .destroy = hashlimit_mt_destroy,
+ .me = THIS_MODULE,
+ },
#endif
};
/* PROC stuff */
static void *dl_seq_start(struct seq_file *s, loff_t *pos)
+ __acquires(htable->lock)
{
struct proc_dir_entry *pde = s->private;
struct xt_hashlimit_htable *htable = pde->data;
@@ -656,6 +909,7 @@ static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
}
static void dl_seq_stop(struct seq_file *s, void *v)
+ __releases(htable->lock)
{
struct proc_dir_entry *pde = s->private;
struct xt_hashlimit_htable *htable = pde->data;
@@ -676,9 +930,9 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
return seq_printf(s, "%ld %u.%u.%u.%u:%u->"
"%u.%u.%u.%u:%u %u %u %u\n",
(long)(ent->expires - jiffies)/HZ,
- NIPQUAD(ent->dst.addr.ip.src),
+ NIPQUAD(ent->dst.ip.src),
ntohs(ent->dst.src_port),
- NIPQUAD(ent->dst.addr.ip.dst),
+ NIPQUAD(ent->dst.ip.dst),
ntohs(ent->dst.dst_port),
ent->rateinfo.credit, ent->rateinfo.credit_cap,
ent->rateinfo.cost);
@@ -687,9 +941,9 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
return seq_printf(s, "%ld " NIP6_FMT ":%u->"
NIP6_FMT ":%u %u %u %u\n",
(long)(ent->expires - jiffies)/HZ,
- NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.src),
+ NIP6(*(struct in6_addr *)&ent->dst.ip6.src),
ntohs(ent->dst.src_port),
- NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.dst),
+ NIP6(*(struct in6_addr *)&ent->dst.ip6.dst),
ntohs(ent->dst.dst_port),
ent->rateinfo.credit, ent->rateinfo.credit_cap,
ent->rateinfo.cost);
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index dbea0e0893f..01035fc0e14 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -101,7 +101,7 @@ iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b)
int r;
for (i = 0; i < 4; ++i) {
- r = a->s6_addr32[i] - b->s6_addr32[i];
+ r = (__force u32)a->s6_addr32[i] - (__force u32)b->s6_addr32[i];
if (r != 0)
return r;
}
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index d382f9cc38b..9059c16144c 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -4,8 +4,8 @@
*
* (C) 2000 Marc Boucher <marc@mbsi.ca>
*
- * Copyright © CC Computer Consultants GmbH, 2007
- * Contact: <jengelh@computergmbh.de>
+ * Copyright © CC Computer Consultants GmbH, 2007 - 2008
+ * <jengelh@computergmbh.de>
*
* 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
@@ -102,13 +102,15 @@ owner_mt(const struct sk_buff *skb, const struct net_device *in,
(XT_OWNER_UID | XT_OWNER_GID)) == 0;
if (info->match & XT_OWNER_UID)
- if ((filp->f_uid != info->uid) ^
- !!(info->invert & XT_OWNER_UID))
+ if ((filp->f_uid >= info->uid_min &&
+ filp->f_uid <= info->uid_max) ^
+ !(info->invert & XT_OWNER_UID))
return false;
if (info->match & XT_OWNER_GID)
- if ((filp->f_gid != info->gid) ^
- !!(info->invert & XT_OWNER_GID))
+ if ((filp->f_gid >= info->gid_min &&
+ filp->f_gid <= info->gid_max) ^
+ !(info->invert & XT_OWNER_GID))
return false;
return true;