diff options
Diffstat (limited to 'net/netfilter')
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; |