diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-29 01:11:23 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-29 01:11:23 -0400 |
commit | 7b7e394185014e0f3bd8989cac937003f20ef9ce (patch) | |
tree | 3beda5f979bba0aa9822534e239cf1b45f3be69c /net/ipv4 | |
parent | ddc5d3414593e4d7ad7fbd33e7f7517fcc234544 (diff) | |
parent | 693f7d362055261882659475d2ef022e32edbff1 (diff) |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net/ipv4')
50 files changed, 1453 insertions, 2278 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index e16d8b42b953..e2e4771fa4c6 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c | |||
@@ -116,7 +116,7 @@ error: | |||
116 | return err; | 116 | return err; |
117 | } | 117 | } |
118 | 118 | ||
119 | static int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) | 119 | static int ah_input(struct xfrm_state *x, struct sk_buff *skb) |
120 | { | 120 | { |
121 | int ah_hlen; | 121 | int ah_hlen; |
122 | struct iphdr *iph; | 122 | struct iphdr *iph; |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 041dadde31af..4749d504c629 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -928,7 +928,8 @@ static void parp_redo(struct sk_buff *skb) | |||
928 | * Receive an arp request from the device layer. | 928 | * Receive an arp request from the device layer. |
929 | */ | 929 | */ |
930 | 930 | ||
931 | int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) | 931 | static int arp_rcv(struct sk_buff *skb, struct net_device *dev, |
932 | struct packet_type *pt, struct net_device *orig_dev) | ||
932 | { | 933 | { |
933 | struct arphdr *arp; | 934 | struct arphdr *arp; |
934 | 935 | ||
@@ -1417,7 +1418,6 @@ static int __init arp_proc_init(void) | |||
1417 | 1418 | ||
1418 | EXPORT_SYMBOL(arp_broken_ops); | 1419 | EXPORT_SYMBOL(arp_broken_ops); |
1419 | EXPORT_SYMBOL(arp_find); | 1420 | EXPORT_SYMBOL(arp_find); |
1420 | EXPORT_SYMBOL(arp_rcv); | ||
1421 | EXPORT_SYMBOL(arp_create); | 1421 | EXPORT_SYMBOL(arp_create); |
1422 | EXPORT_SYMBOL(arp_xmit); | 1422 | EXPORT_SYMBOL(arp_xmit); |
1423 | EXPORT_SYMBOL(arp_send); | 1423 | EXPORT_SYMBOL(arp_send); |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 81c2f7885292..54419b27686f 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1556,7 +1556,6 @@ void __init devinet_init(void) | |||
1556 | #endif | 1556 | #endif |
1557 | } | 1557 | } |
1558 | 1558 | ||
1559 | EXPORT_SYMBOL(devinet_ioctl); | ||
1560 | EXPORT_SYMBOL(in_dev_finish_destroy); | 1559 | EXPORT_SYMBOL(in_dev_finish_destroy); |
1561 | EXPORT_SYMBOL(inet_select_addr); | 1560 | EXPORT_SYMBOL(inet_select_addr); |
1562 | EXPORT_SYMBOL(inetdev_by_index); | 1561 | EXPORT_SYMBOL(inetdev_by_index); |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index bf88c620a954..9d1881c07a32 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -133,7 +133,7 @@ error: | |||
133 | * expensive, so we only support truncated data, which is the recommended | 133 | * expensive, so we only support truncated data, which is the recommended |
134 | * and common case. | 134 | * and common case. |
135 | */ | 135 | */ |
136 | static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) | 136 | static int esp_input(struct xfrm_state *x, struct sk_buff *skb) |
137 | { | 137 | { |
138 | struct iphdr *iph; | 138 | struct iphdr *iph; |
139 | struct ip_esp_hdr *esph; | 139 | struct ip_esp_hdr *esph; |
@@ -208,9 +208,6 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc | |||
208 | struct xfrm_encap_tmpl *encap = x->encap; | 208 | struct xfrm_encap_tmpl *encap = x->encap; |
209 | struct udphdr *uh; | 209 | struct udphdr *uh; |
210 | 210 | ||
211 | if (encap->encap_type != decap->decap_type) | ||
212 | goto out; | ||
213 | |||
214 | uh = (struct udphdr *)(iph + 1); | 211 | uh = (struct udphdr *)(iph + 1); |
215 | encap_len = (void*)esph - (void*)uh; | 212 | encap_len = (void*)esph - (void*)uh; |
216 | 213 | ||
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 4e3d3811dea2..cdde96390960 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -666,4 +666,3 @@ void __init ip_fib_init(void) | |||
666 | } | 666 | } |
667 | 667 | ||
668 | EXPORT_SYMBOL(inet_addr_type); | 668 | EXPORT_SYMBOL(inet_addr_type); |
669 | EXPORT_SYMBOL(ip_rt_ioctl); | ||
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index ccd3efc6a173..95a639f2e3db 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -50,7 +50,7 @@ | |||
50 | * Patrick McHardy <kaber@trash.net> | 50 | * Patrick McHardy <kaber@trash.net> |
51 | */ | 51 | */ |
52 | 52 | ||
53 | #define VERSION "0.406" | 53 | #define VERSION "0.407" |
54 | 54 | ||
55 | #include <linux/config.h> | 55 | #include <linux/config.h> |
56 | #include <asm/uaccess.h> | 56 | #include <asm/uaccess.h> |
@@ -314,11 +314,6 @@ static void __leaf_free_rcu(struct rcu_head *head) | |||
314 | kfree(container_of(head, struct leaf, rcu)); | 314 | kfree(container_of(head, struct leaf, rcu)); |
315 | } | 315 | } |
316 | 316 | ||
317 | static inline void free_leaf(struct leaf *leaf) | ||
318 | { | ||
319 | call_rcu(&leaf->rcu, __leaf_free_rcu); | ||
320 | } | ||
321 | |||
322 | static void __leaf_info_free_rcu(struct rcu_head *head) | 317 | static void __leaf_info_free_rcu(struct rcu_head *head) |
323 | { | 318 | { |
324 | kfree(container_of(head, struct leaf_info, rcu)); | 319 | kfree(container_of(head, struct leaf_info, rcu)); |
@@ -357,7 +352,12 @@ static void __tnode_free_rcu(struct rcu_head *head) | |||
357 | 352 | ||
358 | static inline void tnode_free(struct tnode *tn) | 353 | static inline void tnode_free(struct tnode *tn) |
359 | { | 354 | { |
360 | call_rcu(&tn->rcu, __tnode_free_rcu); | 355 | if(IS_LEAF(tn)) { |
356 | struct leaf *l = (struct leaf *) tn; | ||
357 | call_rcu_bh(&l->rcu, __leaf_free_rcu); | ||
358 | } | ||
359 | else | ||
360 | call_rcu(&tn->rcu, __tnode_free_rcu); | ||
361 | } | 361 | } |
362 | 362 | ||
363 | static struct leaf *leaf_new(void) | 363 | static struct leaf *leaf_new(void) |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 9831fd2c73a0..2a0455911ee0 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -1107,7 +1107,7 @@ void __init icmp_init(struct net_proto_family *ops) | |||
1107 | struct inet_sock *inet; | 1107 | struct inet_sock *inet; |
1108 | int i; | 1108 | int i; |
1109 | 1109 | ||
1110 | for_each_cpu(i) { | 1110 | for_each_possible_cpu(i) { |
1111 | int err; | 1111 | int err; |
1112 | 1112 | ||
1113 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, | 1113 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index ef7366fc132f..ee9b5515b9ae 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -43,8 +43,6 @@ struct inet_bind_bucket *inet_bind_bucket_create(kmem_cache_t *cachep, | |||
43 | return tb; | 43 | return tb; |
44 | } | 44 | } |
45 | 45 | ||
46 | EXPORT_SYMBOL(inet_bind_bucket_create); | ||
47 | |||
48 | /* | 46 | /* |
49 | * Caller must hold hashbucket lock for this tb with local BH disabled | 47 | * Caller must hold hashbucket lock for this tb with local BH disabled |
50 | */ | 48 | */ |
@@ -64,8 +62,6 @@ void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, | |||
64 | inet_csk(sk)->icsk_bind_hash = tb; | 62 | inet_csk(sk)->icsk_bind_hash = tb; |
65 | } | 63 | } |
66 | 64 | ||
67 | EXPORT_SYMBOL(inet_bind_hash); | ||
68 | |||
69 | /* | 65 | /* |
70 | * Get rid of any references to a local port held by the given sock. | 66 | * Get rid of any references to a local port held by the given sock. |
71 | */ | 67 | */ |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 2a8adda15e11..da734c439179 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -304,13 +304,17 @@ out: | |||
304 | 304 | ||
305 | /* Creation primitives. */ | 305 | /* Creation primitives. */ |
306 | 306 | ||
307 | static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) | 307 | static struct ipq *ip_frag_intern(struct ipq *qp_in) |
308 | { | 308 | { |
309 | struct ipq *qp; | 309 | struct ipq *qp; |
310 | #ifdef CONFIG_SMP | 310 | #ifdef CONFIG_SMP |
311 | struct hlist_node *n; | 311 | struct hlist_node *n; |
312 | #endif | 312 | #endif |
313 | unsigned int hash; | ||
314 | |||
313 | write_lock(&ipfrag_lock); | 315 | write_lock(&ipfrag_lock); |
316 | hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr, | ||
317 | qp_in->protocol); | ||
314 | #ifdef CONFIG_SMP | 318 | #ifdef CONFIG_SMP |
315 | /* With SMP race we have to recheck hash table, because | 319 | /* With SMP race we have to recheck hash table, because |
316 | * such entry could be created on other cpu, while we | 320 | * such entry could be created on other cpu, while we |
@@ -345,7 +349,7 @@ static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) | |||
345 | } | 349 | } |
346 | 350 | ||
347 | /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ | 351 | /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ |
348 | static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) | 352 | static struct ipq *ip_frag_create(struct iphdr *iph, u32 user) |
349 | { | 353 | { |
350 | struct ipq *qp; | 354 | struct ipq *qp; |
351 | 355 | ||
@@ -371,7 +375,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) | |||
371 | spin_lock_init(&qp->lock); | 375 | spin_lock_init(&qp->lock); |
372 | atomic_set(&qp->refcnt, 1); | 376 | atomic_set(&qp->refcnt, 1); |
373 | 377 | ||
374 | return ip_frag_intern(hash, qp); | 378 | return ip_frag_intern(qp); |
375 | 379 | ||
376 | out_nomem: | 380 | out_nomem: |
377 | LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); | 381 | LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); |
@@ -387,11 +391,12 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user) | |||
387 | __u32 saddr = iph->saddr; | 391 | __u32 saddr = iph->saddr; |
388 | __u32 daddr = iph->daddr; | 392 | __u32 daddr = iph->daddr; |
389 | __u8 protocol = iph->protocol; | 393 | __u8 protocol = iph->protocol; |
390 | unsigned int hash = ipqhashfn(id, saddr, daddr, protocol); | 394 | unsigned int hash; |
391 | struct ipq *qp; | 395 | struct ipq *qp; |
392 | struct hlist_node *n; | 396 | struct hlist_node *n; |
393 | 397 | ||
394 | read_lock(&ipfrag_lock); | 398 | read_lock(&ipfrag_lock); |
399 | hash = ipqhashfn(id, saddr, daddr, protocol); | ||
395 | hlist_for_each_entry(qp, n, &ipq_hash[hash], list) { | 400 | hlist_for_each_entry(qp, n, &ipq_hash[hash], list) { |
396 | if(qp->id == id && | 401 | if(qp->id == id && |
397 | qp->saddr == saddr && | 402 | qp->saddr == saddr && |
@@ -405,7 +410,7 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user) | |||
405 | } | 410 | } |
406 | read_unlock(&ipfrag_lock); | 411 | read_unlock(&ipfrag_lock); |
407 | 412 | ||
408 | return ip_frag_create(hash, iph, user); | 413 | return ip_frag_create(iph, user); |
409 | } | 414 | } |
410 | 415 | ||
411 | /* Is the fragment too far ahead to be part of ipq? */ | 416 | /* Is the fragment too far ahead to be part of ipq? */ |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 9981dcd68f11..ab99bebdcdc8 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -656,7 +656,7 @@ static int ipgre_rcv(struct sk_buff *skb) | |||
656 | read_unlock(&ipgre_lock); | 656 | read_unlock(&ipgre_lock); |
657 | return(0); | 657 | return(0); |
658 | } | 658 | } |
659 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); | 659 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); |
660 | 660 | ||
661 | drop: | 661 | drop: |
662 | read_unlock(&ipgre_lock); | 662 | read_unlock(&ipgre_lock); |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index f75ff1d96551..cff9c3a72daf 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -86,8 +86,6 @@ | |||
86 | 86 | ||
87 | int sysctl_ip_default_ttl = IPDEFTTL; | 87 | int sysctl_ip_default_ttl = IPDEFTTL; |
88 | 88 | ||
89 | static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)); | ||
90 | |||
91 | /* Generate a checksum for an outgoing IP datagram. */ | 89 | /* Generate a checksum for an outgoing IP datagram. */ |
92 | __inline__ void ip_send_check(struct iphdr *iph) | 90 | __inline__ void ip_send_check(struct iphdr *iph) |
93 | { | 91 | { |
@@ -421,7 +419,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
421 | * single device frame, and queue such a frame for sending. | 419 | * single device frame, and queue such a frame for sending. |
422 | */ | 420 | */ |
423 | 421 | ||
424 | static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | 422 | int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) |
425 | { | 423 | { |
426 | struct iphdr *iph; | 424 | struct iphdr *iph; |
427 | int raw = 0; | 425 | int raw = 0; |
@@ -673,6 +671,8 @@ fail: | |||
673 | return err; | 671 | return err; |
674 | } | 672 | } |
675 | 673 | ||
674 | EXPORT_SYMBOL(ip_fragment); | ||
675 | |||
676 | int | 676 | int |
677 | ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) | 677 | ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) |
678 | { | 678 | { |
@@ -904,7 +904,7 @@ alloc_new_skb: | |||
904 | * because we have no idea what fragment will be | 904 | * because we have no idea what fragment will be |
905 | * the last. | 905 | * the last. |
906 | */ | 906 | */ |
907 | if (datalen == length) | 907 | if (datalen == length + fraggap) |
908 | alloclen += rt->u.dst.trailer_len; | 908 | alloclen += rt->u.dst.trailer_len; |
909 | 909 | ||
910 | if (transhdrlen) { | 910 | if (transhdrlen) { |
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index c95020f7c81e..cd810f41af1a 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -81,8 +81,7 @@ out: | |||
81 | return err; | 81 | return err; |
82 | } | 82 | } |
83 | 83 | ||
84 | static int ipcomp_input(struct xfrm_state *x, | 84 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) |
85 | struct xfrm_decap_state *decap, struct sk_buff *skb) | ||
86 | { | 85 | { |
87 | u8 nexthdr; | 86 | u8 nexthdr; |
88 | int err = 0; | 87 | int err = 0; |
@@ -291,11 +290,8 @@ static void ipcomp_free_scratches(void) | |||
291 | if (!scratches) | 290 | if (!scratches) |
292 | return; | 291 | return; |
293 | 292 | ||
294 | for_each_cpu(i) { | 293 | for_each_possible_cpu(i) |
295 | void *scratch = *per_cpu_ptr(scratches, i); | 294 | vfree(*per_cpu_ptr(scratches, i)); |
296 | if (scratch) | ||
297 | vfree(scratch); | ||
298 | } | ||
299 | 295 | ||
300 | free_percpu(scratches); | 296 | free_percpu(scratches); |
301 | } | 297 | } |
@@ -314,7 +310,7 @@ static void **ipcomp_alloc_scratches(void) | |||
314 | 310 | ||
315 | ipcomp_scratches = scratches; | 311 | ipcomp_scratches = scratches; |
316 | 312 | ||
317 | for_each_cpu(i) { | 313 | for_each_possible_cpu(i) { |
318 | void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); | 314 | void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); |
319 | if (!scratch) | 315 | if (!scratch) |
320 | return NULL; | 316 | return NULL; |
@@ -345,7 +341,7 @@ static void ipcomp_free_tfms(struct crypto_tfm **tfms) | |||
345 | if (!tfms) | 341 | if (!tfms) |
346 | return; | 342 | return; |
347 | 343 | ||
348 | for_each_cpu(cpu) { | 344 | for_each_possible_cpu(cpu) { |
349 | struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); | 345 | struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); |
350 | crypto_free_tfm(tfm); | 346 | crypto_free_tfm(tfm); |
351 | } | 347 | } |
@@ -385,7 +381,7 @@ static struct crypto_tfm **ipcomp_alloc_tfms(const char *alg_name) | |||
385 | if (!tfms) | 381 | if (!tfms) |
386 | goto error; | 382 | goto error; |
387 | 383 | ||
388 | for_each_cpu(cpu) { | 384 | for_each_possible_cpu(cpu) { |
389 | struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); | 385 | struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); |
390 | if (!tfm) | 386 | if (!tfm) |
391 | goto error; | 387 | goto error; |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index eef07b0916a3..ea398ee43f28 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -474,9 +474,6 @@ static int ipip_rcv(struct sk_buff *skb) | |||
474 | struct iphdr *iph; | 474 | struct iphdr *iph; |
475 | struct ip_tunnel *tunnel; | 475 | struct ip_tunnel *tunnel; |
476 | 476 | ||
477 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
478 | goto out; | ||
479 | |||
480 | iph = skb->nh.iph; | 477 | iph = skb->nh.iph; |
481 | 478 | ||
482 | read_lock(&ipip_lock); | 479 | read_lock(&ipip_lock); |
@@ -508,7 +505,6 @@ static int ipip_rcv(struct sk_buff *skb) | |||
508 | } | 505 | } |
509 | read_unlock(&ipip_lock); | 506 | read_unlock(&ipip_lock); |
510 | 507 | ||
511 | out: | ||
512 | return -1; | 508 | return -1; |
513 | } | 509 | } |
514 | 510 | ||
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index b5ad9ac2fbcc..6a9e34b794bc 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
@@ -133,7 +133,7 @@ struct ip_rt_info { | |||
133 | u_int8_t tos; | 133 | u_int8_t tos; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static void queue_save(const struct sk_buff *skb, struct nf_info *info) | 136 | static void nf_ip_saveroute(const struct sk_buff *skb, struct nf_info *info) |
137 | { | 137 | { |
138 | struct ip_rt_info *rt_info = nf_info_reroute(info); | 138 | struct ip_rt_info *rt_info = nf_info_reroute(info); |
139 | 139 | ||
@@ -146,7 +146,7 @@ static void queue_save(const struct sk_buff *skb, struct nf_info *info) | |||
146 | } | 146 | } |
147 | } | 147 | } |
148 | 148 | ||
149 | static int queue_reroute(struct sk_buff **pskb, const struct nf_info *info) | 149 | static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info) |
150 | { | 150 | { |
151 | const struct ip_rt_info *rt_info = nf_info_reroute(info); | 151 | const struct ip_rt_info *rt_info = nf_info_reroute(info); |
152 | 152 | ||
@@ -161,20 +161,54 @@ static int queue_reroute(struct sk_buff **pskb, const struct nf_info *info) | |||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
164 | static struct nf_queue_rerouter ip_reroute = { | 164 | unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook, |
165 | .rer_size = sizeof(struct ip_rt_info), | 165 | unsigned int dataoff, u_int8_t protocol) |
166 | .save = queue_save, | 166 | { |
167 | .reroute = queue_reroute, | 167 | struct iphdr *iph = skb->nh.iph; |
168 | unsigned int csum = 0; | ||
169 | |||
170 | switch (skb->ip_summed) { | ||
171 | case CHECKSUM_HW: | ||
172 | if (hook != NF_IP_PRE_ROUTING && hook != NF_IP_LOCAL_IN) | ||
173 | break; | ||
174 | if ((protocol == 0 && !(u16)csum_fold(skb->csum)) || | ||
175 | !csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
176 | skb->len - dataoff, protocol, | ||
177 | skb->csum)) { | ||
178 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
179 | break; | ||
180 | } | ||
181 | /* fall through */ | ||
182 | case CHECKSUM_NONE: | ||
183 | if (protocol == 0) | ||
184 | skb->csum = 0; | ||
185 | else | ||
186 | skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, | ||
187 | skb->len - dataoff, | ||
188 | protocol, 0); | ||
189 | csum = __skb_checksum_complete(skb); | ||
190 | } | ||
191 | return csum; | ||
192 | } | ||
193 | |||
194 | EXPORT_SYMBOL(nf_ip_checksum); | ||
195 | |||
196 | static struct nf_afinfo nf_ip_afinfo = { | ||
197 | .family = AF_INET, | ||
198 | .checksum = nf_ip_checksum, | ||
199 | .saveroute = nf_ip_saveroute, | ||
200 | .reroute = nf_ip_reroute, | ||
201 | .route_key_size = sizeof(struct ip_rt_info), | ||
168 | }; | 202 | }; |
169 | 203 | ||
170 | static int ipv4_netfilter_init(void) | 204 | static int ipv4_netfilter_init(void) |
171 | { | 205 | { |
172 | return nf_register_queue_rerouter(PF_INET, &ip_reroute); | 206 | return nf_register_afinfo(&nf_ip_afinfo); |
173 | } | 207 | } |
174 | 208 | ||
175 | static void ipv4_netfilter_fini(void) | 209 | static void ipv4_netfilter_fini(void) |
176 | { | 210 | { |
177 | nf_unregister_queue_rerouter(PF_INET); | 211 | nf_unregister_afinfo(&nf_ip_afinfo); |
178 | } | 212 | } |
179 | 213 | ||
180 | module_init(ipv4_netfilter_init); | 214 | module_init(ipv4_netfilter_init); |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 882b842c25d4..3d560dec63ab 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -69,6 +69,7 @@ config IP_NF_CONNTRACK_NETLINK | |||
69 | tristate 'Connection tracking netlink interface (EXPERIMENTAL)' | 69 | tristate 'Connection tracking netlink interface (EXPERIMENTAL)' |
70 | depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK | 70 | depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK |
71 | depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m | 71 | depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m |
72 | depends on IP_NF_NAT=n || IP_NF_NAT | ||
72 | help | 73 | help |
73 | This option enables support for a netlink-based userspace interface | 74 | This option enables support for a netlink-based userspace interface |
74 | 75 | ||
@@ -221,16 +222,6 @@ config IP_NF_MATCH_IPRANGE | |||
221 | 222 | ||
222 | To compile it as a module, choose M here. If unsure, say N. | 223 | To compile it as a module, choose M here. If unsure, say N. |
223 | 224 | ||
224 | config IP_NF_MATCH_MULTIPORT | ||
225 | tristate "Multiple port match support" | ||
226 | depends on IP_NF_IPTABLES | ||
227 | help | ||
228 | Multiport matching allows you to match TCP or UDP packets based on | ||
229 | a series of source or destination ports: normally a rule can only | ||
230 | match a single range of ports. | ||
231 | |||
232 | To compile it as a module, choose M here. If unsure, say N. | ||
233 | |||
234 | config IP_NF_MATCH_TOS | 225 | config IP_NF_MATCH_TOS |
235 | tristate "TOS match support" | 226 | tristate "TOS match support" |
236 | depends on IP_NF_IPTABLES | 227 | depends on IP_NF_IPTABLES |
@@ -272,12 +263,12 @@ config IP_NF_MATCH_DSCP | |||
272 | 263 | ||
273 | To compile it as a module, choose M here. If unsure, say N. | 264 | To compile it as a module, choose M here. If unsure, say N. |
274 | 265 | ||
275 | config IP_NF_MATCH_AH_ESP | 266 | config IP_NF_MATCH_AH |
276 | tristate "AH/ESP match support" | 267 | tristate "AH match support" |
277 | depends on IP_NF_IPTABLES | 268 | depends on IP_NF_IPTABLES |
278 | help | 269 | help |
279 | These two match extensions (`ah' and `esp') allow you to match a | 270 | This match extension allows you to match a range of SPIs |
280 | range of SPIs inside AH or ESP headers of IPSec packets. | 271 | inside AH header of IPSec packets. |
281 | 272 | ||
282 | To compile it as a module, choose M here. If unsure, say N. | 273 | To compile it as a module, choose M here. If unsure, say N. |
283 | 274 | ||
@@ -354,7 +345,7 @@ config IP_NF_TARGET_LOG | |||
354 | To compile it as a module, choose M here. If unsure, say N. | 345 | To compile it as a module, choose M here. If unsure, say N. |
355 | 346 | ||
356 | config IP_NF_TARGET_ULOG | 347 | config IP_NF_TARGET_ULOG |
357 | tristate "ULOG target support (OBSOLETE)" | 348 | tristate "ULOG target support" |
358 | depends on IP_NF_IPTABLES | 349 | depends on IP_NF_IPTABLES |
359 | ---help--- | 350 | ---help--- |
360 | 351 | ||
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index f2cd9a6c5b91..461cb1eb5de7 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -53,13 +53,12 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o | |||
53 | # matches | 53 | # matches |
54 | obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o | 54 | obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o |
55 | obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o | 55 | obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o |
56 | obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o | ||
57 | obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o | 56 | obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o |
58 | obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o | 57 | obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o |
59 | obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o | 58 | obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o |
60 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o | 59 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o |
61 | obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o | 60 | obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o |
62 | obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o | 61 | obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o |
63 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o | 62 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o |
64 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 63 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
65 | 64 | ||
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index a44a5d73457d..c2d92f99a2b8 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -646,7 +646,7 @@ static int translate_table(const char *name, | |||
646 | } | 646 | } |
647 | 647 | ||
648 | /* And one copy for every other CPU */ | 648 | /* And one copy for every other CPU */ |
649 | for_each_cpu(i) { | 649 | for_each_possible_cpu(i) { |
650 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) | 650 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) |
651 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 651 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
652 | } | 652 | } |
@@ -696,7 +696,7 @@ static void get_counters(const struct xt_table_info *t, | |||
696 | counters, | 696 | counters, |
697 | &i); | 697 | &i); |
698 | 698 | ||
699 | for_each_cpu(cpu) { | 699 | for_each_possible_cpu(cpu) { |
700 | if (cpu == curcpu) | 700 | if (cpu == curcpu) |
701 | continue; | 701 | continue; |
702 | i = 0; | 702 | i = 0; |
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index d0d379c7df9a..d7c472faa53b 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c | |||
@@ -181,33 +181,26 @@ static struct nf_hook_ops arpt_ops[] = { | |||
181 | 181 | ||
182 | static int __init arptable_filter_init(void) | 182 | static int __init arptable_filter_init(void) |
183 | { | 183 | { |
184 | int ret, i; | 184 | int ret; |
185 | 185 | ||
186 | /* Register table */ | 186 | /* Register table */ |
187 | ret = arpt_register_table(&packet_filter, &initial_table.repl); | 187 | ret = arpt_register_table(&packet_filter, &initial_table.repl); |
188 | if (ret < 0) | 188 | if (ret < 0) |
189 | return ret; | 189 | return ret; |
190 | 190 | ||
191 | for (i = 0; i < ARRAY_SIZE(arpt_ops); i++) | 191 | ret = nf_register_hooks(arpt_ops, ARRAY_SIZE(arpt_ops)); |
192 | if ((ret = nf_register_hook(&arpt_ops[i])) < 0) | 192 | if (ret < 0) |
193 | goto cleanup_hooks; | 193 | goto cleanup_table; |
194 | return ret; | 194 | return ret; |
195 | 195 | ||
196 | cleanup_hooks: | 196 | cleanup_table: |
197 | while (--i >= 0) | ||
198 | nf_unregister_hook(&arpt_ops[i]); | ||
199 | |||
200 | arpt_unregister_table(&packet_filter); | 197 | arpt_unregister_table(&packet_filter); |
201 | return ret; | 198 | return ret; |
202 | } | 199 | } |
203 | 200 | ||
204 | static void __exit arptable_filter_fini(void) | 201 | static void __exit arptable_filter_fini(void) |
205 | { | 202 | { |
206 | unsigned int i; | 203 | nf_unregister_hooks(arpt_ops, ARRAY_SIZE(arpt_ops)); |
207 | |||
208 | for (i = 0; i < ARRAY_SIZE(arpt_ops); i++) | ||
209 | nf_unregister_hook(&arpt_ops[i]); | ||
210 | |||
211 | arpt_unregister_table(&packet_filter); | 204 | arpt_unregister_table(&packet_filter); |
212 | } | 205 | } |
213 | 206 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index ceaabc18202b..979a2eac6f00 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -133,7 +133,7 @@ static void ip_ct_event_cache_flush(void) | |||
133 | struct ip_conntrack_ecache *ecache; | 133 | struct ip_conntrack_ecache *ecache; |
134 | int cpu; | 134 | int cpu; |
135 | 135 | ||
136 | for_each_cpu(cpu) { | 136 | for_each_possible_cpu(cpu) { |
137 | ecache = &per_cpu(ip_conntrack_ecache, cpu); | 137 | ecache = &per_cpu(ip_conntrack_ecache, cpu); |
138 | if (ecache->ct) | 138 | if (ecache->ct) |
139 | ip_conntrack_put(ecache->ct); | 139 | ip_conntrack_put(ecache->ct); |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c index daeb1395faa4..2c2fb700d835 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c | |||
@@ -9,37 +9,6 @@ | |||
9 | * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 9 | * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> |
10 | * | 10 | * |
11 | * For more information, please see http://nath323.sourceforge.net/ | 11 | * For more information, please see http://nath323.sourceforge.net/ |
12 | * | ||
13 | * Changes: | ||
14 | * 2006-02-01 - initial version 0.1 | ||
15 | * | ||
16 | * 2006-02-20 - version 0.2 | ||
17 | * 1. Changed source format to follow kernel conventions | ||
18 | * 2. Deleted some unnecessary structures | ||
19 | * 3. Minor fixes | ||
20 | * | ||
21 | * 2006-03-10 - version 0.3 | ||
22 | * 1. Added support for multiple TPKTs in one packet (suggested by | ||
23 | * Patrick McHardy) | ||
24 | * 2. Avoid excessive stack usage (based on Patrick McHardy's patch) | ||
25 | * 3. Added support for non-linear skb (based on Patrick McHardy's patch) | ||
26 | * 4. Fixed missing H.245 module owner (Patrick McHardy) | ||
27 | * 5. Avoid long RAS expectation chains (Patrick McHardy) | ||
28 | * 6. Fixed incorrect __exit attribute (Patrick McHardy) | ||
29 | * 7. Eliminated unnecessary return code | ||
30 | * 8. Fixed incorrect use of NAT data from conntrack code (suggested by | ||
31 | * Patrick McHardy) | ||
32 | * 9. Fixed TTL calculation error in RCF | ||
33 | * 10. Added TTL support in RRQ | ||
34 | * 11. Better support for separate TPKT header and data | ||
35 | * | ||
36 | * 2006-03-15 - version 0.4 | ||
37 | * 1. Added support for T.120 channels | ||
38 | * 2. Added parameter gkrouted_only (suggested by Patrick McHardy) | ||
39 | * 3. Splitted ASN.1 code and data (suggested by Patrick McHardy) | ||
40 | * 4. Sort ASN.1 data to avoid forwarding declarations (suggested by | ||
41 | * Patrick McHardy) | ||
42 | * 5. Reset next TPKT data length in get_tpkt_data() | ||
43 | */ | 12 | */ |
44 | 13 | ||
45 | #include <linux/config.h> | 14 | #include <linux/config.h> |
@@ -54,8 +23,6 @@ | |||
54 | #include <linux/netfilter_ipv4/ip_conntrack_h323.h> | 23 | #include <linux/netfilter_ipv4/ip_conntrack_h323.h> |
55 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
56 | 25 | ||
57 | #include "ip_conntrack_helper_h323_asn1.h" | ||
58 | |||
59 | #if 0 | 26 | #if 0 |
60 | #define DEBUGP printk | 27 | #define DEBUGP printk |
61 | #else | 28 | #else |
@@ -63,6 +30,10 @@ | |||
63 | #endif | 30 | #endif |
64 | 31 | ||
65 | /* Parameters */ | 32 | /* Parameters */ |
33 | static unsigned int default_rrq_ttl = 300; | ||
34 | module_param(default_rrq_ttl, uint, 0600); | ||
35 | MODULE_PARM_DESC(default_rrq_ttl, "use this TTL if it's missing in RRQ"); | ||
36 | |||
66 | static int gkrouted_only = 1; | 37 | static int gkrouted_only = 1; |
67 | module_param(gkrouted_only, int, 0600); | 38 | module_param(gkrouted_only, int, 0600); |
68 | MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper"); | 39 | MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper"); |
@@ -222,8 +193,8 @@ static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct, | |||
222 | } | 193 | } |
223 | 194 | ||
224 | /****************************************************************************/ | 195 | /****************************************************************************/ |
225 | int get_h245_addr(unsigned char *data, H245_TransportAddress * addr, | 196 | static int get_h245_addr(unsigned char *data, H245_TransportAddress * addr, |
226 | u_int32_t * ip, u_int16_t * port) | 197 | u_int32_t * ip, u_int16_t * port) |
227 | { | 198 | { |
228 | unsigned char *p; | 199 | unsigned char *p; |
229 | 200 | ||
@@ -1302,7 +1273,7 @@ static int process_rrq(struct sk_buff **pskb, struct ip_conntrack *ct, | |||
1302 | DEBUGP("ip_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive); | 1273 | DEBUGP("ip_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive); |
1303 | info->timeout = rrq->timeToLive; | 1274 | info->timeout = rrq->timeToLive; |
1304 | } else | 1275 | } else |
1305 | info->timeout = 0; | 1276 | info->timeout = default_rrq_ttl; |
1306 | 1277 | ||
1307 | return 0; | 1278 | return 0; |
1308 | } | 1279 | } |
@@ -1713,18 +1684,17 @@ static int __init init(void) | |||
1713 | module_init(init); | 1684 | module_init(init); |
1714 | module_exit(fini); | 1685 | module_exit(fini); |
1715 | 1686 | ||
1716 | EXPORT_SYMBOL(get_h245_addr); | 1687 | EXPORT_SYMBOL_GPL(get_h225_addr); |
1717 | EXPORT_SYMBOL(get_h225_addr); | 1688 | EXPORT_SYMBOL_GPL(ip_conntrack_h245_expect); |
1718 | EXPORT_SYMBOL(ip_conntrack_h245_expect); | 1689 | EXPORT_SYMBOL_GPL(ip_conntrack_q931_expect); |
1719 | EXPORT_SYMBOL(ip_conntrack_q931_expect); | 1690 | EXPORT_SYMBOL_GPL(set_h245_addr_hook); |
1720 | EXPORT_SYMBOL(set_h245_addr_hook); | 1691 | EXPORT_SYMBOL_GPL(set_h225_addr_hook); |
1721 | EXPORT_SYMBOL(set_h225_addr_hook); | 1692 | EXPORT_SYMBOL_GPL(set_sig_addr_hook); |
1722 | EXPORT_SYMBOL(set_sig_addr_hook); | 1693 | EXPORT_SYMBOL_GPL(set_ras_addr_hook); |
1723 | EXPORT_SYMBOL(set_ras_addr_hook); | 1694 | EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook); |
1724 | EXPORT_SYMBOL(nat_rtp_rtcp_hook); | 1695 | EXPORT_SYMBOL_GPL(nat_t120_hook); |
1725 | EXPORT_SYMBOL(nat_t120_hook); | 1696 | EXPORT_SYMBOL_GPL(nat_h245_hook); |
1726 | EXPORT_SYMBOL(nat_h245_hook); | 1697 | EXPORT_SYMBOL_GPL(nat_q931_hook); |
1727 | EXPORT_SYMBOL(nat_q931_hook); | ||
1728 | 1698 | ||
1729 | MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>"); | 1699 | MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>"); |
1730 | MODULE_DESCRIPTION("H.323 connection tracking helper"); | 1700 | MODULE_DESCRIPTION("H.323 connection tracking helper"); |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c index afa525129b51..48078002e450 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #else | 15 | #else |
16 | #include <stdio.h> | 16 | #include <stdio.h> |
17 | #endif | 17 | #endif |
18 | #include "ip_conntrack_helper_h323_asn1.h" | 18 | #include <linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h> |
19 | 19 | ||
20 | /* Trace Flag */ | 20 | /* Trace Flag */ |
21 | #ifndef H323_TRACE | 21 | #ifndef H323_TRACE |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h deleted file mode 100644 index 0bd828081c0c..000000000000 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | /**************************************************************************** | ||
2 | * ip_conntrack_helper_h323_asn1.h - BER and PER decoding library for H.323 | ||
3 | * conntrack/NAT module. | ||
4 | * | ||
5 | * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@hotmail.com> | ||
6 | * | ||
7 | * This source code is licensed under General Public License version 2. | ||
8 | * | ||
9 | * | ||
10 | * This library is based on H.225 version 4, H.235 version 2 and H.245 | ||
11 | * version 7. It is extremely optimized to decode only the absolutely | ||
12 | * necessary objects in a signal for Linux kernel NAT module use, so don't | ||
13 | * expect it to be a full ASN.1 library. | ||
14 | * | ||
15 | * Features: | ||
16 | * | ||
17 | * 1. Small. The total size of code plus data is less than 20 KB (IA32). | ||
18 | * 2. Fast. Decoding Netmeeting's Setup signal 1 million times on a PIII 866 | ||
19 | * takes only 3.9 seconds. | ||
20 | * 3. No memory allocation. It uses a static object. No need to initialize or | ||
21 | * cleanup. | ||
22 | * 4. Thread safe. | ||
23 | * 5. Support embedded architectures that has no misaligned memory access | ||
24 | * support. | ||
25 | * | ||
26 | * Limitations: | ||
27 | * | ||
28 | * 1. At most 30 faststart entries. Actually this is limited by ethernet's MTU. | ||
29 | * If a Setup signal contains more than 30 faststart, the packet size will | ||
30 | * very likely exceed the MTU size, then the TPKT will be fragmented. I | ||
31 | * don't know how to handle this in a Netfilter module. Anybody can help? | ||
32 | * Although I think 30 is enough for most of the cases. | ||
33 | * 2. IPv4 addresses only. | ||
34 | * | ||
35 | ****************************************************************************/ | ||
36 | |||
37 | #ifndef _IP_CONNTRACK_HELPER_H323_ASN1_H_ | ||
38 | #define _IP_CONNTRACK_HELPER_H323_ASN1_H_ | ||
39 | |||
40 | /***************************************************************************** | ||
41 | * H.323 Types | ||
42 | ****************************************************************************/ | ||
43 | #include "ip_conntrack_helper_h323_types.h" | ||
44 | |||
45 | typedef struct { | ||
46 | enum { | ||
47 | Q931_NationalEscape = 0x00, | ||
48 | Q931_Alerting = 0x01, | ||
49 | Q931_CallProceeding = 0x02, | ||
50 | Q931_Connect = 0x07, | ||
51 | Q931_ConnectAck = 0x0F, | ||
52 | Q931_Progress = 0x03, | ||
53 | Q931_Setup = 0x05, | ||
54 | Q931_SetupAck = 0x0D, | ||
55 | Q931_Resume = 0x26, | ||
56 | Q931_ResumeAck = 0x2E, | ||
57 | Q931_ResumeReject = 0x22, | ||
58 | Q931_Suspend = 0x25, | ||
59 | Q931_SuspendAck = 0x2D, | ||
60 | Q931_SuspendReject = 0x21, | ||
61 | Q931_UserInformation = 0x20, | ||
62 | Q931_Disconnect = 0x45, | ||
63 | Q931_Release = 0x4D, | ||
64 | Q931_ReleaseComplete = 0x5A, | ||
65 | Q931_Restart = 0x46, | ||
66 | Q931_RestartAck = 0x4E, | ||
67 | Q931_Segment = 0x60, | ||
68 | Q931_CongestionCtrl = 0x79, | ||
69 | Q931_Information = 0x7B, | ||
70 | Q931_Notify = 0x6E, | ||
71 | Q931_Status = 0x7D, | ||
72 | Q931_StatusEnquiry = 0x75, | ||
73 | Q931_Facility = 0x62 | ||
74 | } MessageType; | ||
75 | H323_UserInformation UUIE; | ||
76 | } Q931; | ||
77 | |||
78 | /***************************************************************************** | ||
79 | * Decode Functions Return Codes | ||
80 | ****************************************************************************/ | ||
81 | |||
82 | #define H323_ERROR_NONE 0 /* Decoded successfully */ | ||
83 | #define H323_ERROR_STOP 1 /* Decoding stopped, not really an error */ | ||
84 | #define H323_ERROR_BOUND -1 | ||
85 | #define H323_ERROR_RANGE -2 | ||
86 | |||
87 | |||
88 | /***************************************************************************** | ||
89 | * Decode Functions | ||
90 | ****************************************************************************/ | ||
91 | |||
92 | int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras); | ||
93 | int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931); | ||
94 | int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz, | ||
95 | MultimediaSystemControlMessage * | ||
96 | mscm); | ||
97 | |||
98 | #endif | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_types.h b/net/ipv4/netfilter/ip_conntrack_helper_h323_types.h deleted file mode 100644 index cc98f7aa5abe..000000000000 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_types.h +++ /dev/null | |||
@@ -1,938 +0,0 @@ | |||
1 | /* Generated by Jing Min Zhao's ASN.1 parser, Mar 15 2006 | ||
2 | * | ||
3 | * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net> | ||
4 | * | ||
5 | * This source code is licensed under General Public License version 2. | ||
6 | */ | ||
7 | |||
8 | typedef struct TransportAddress_ipAddress { /* SEQUENCE */ | ||
9 | int options; /* No use */ | ||
10 | unsigned ip; | ||
11 | } TransportAddress_ipAddress; | ||
12 | |||
13 | typedef struct TransportAddress { /* CHOICE */ | ||
14 | enum { | ||
15 | eTransportAddress_ipAddress, | ||
16 | eTransportAddress_ipSourceRoute, | ||
17 | eTransportAddress_ipxAddress, | ||
18 | eTransportAddress_ip6Address, | ||
19 | eTransportAddress_netBios, | ||
20 | eTransportAddress_nsap, | ||
21 | eTransportAddress_nonStandardAddress, | ||
22 | } choice; | ||
23 | union { | ||
24 | TransportAddress_ipAddress ipAddress; | ||
25 | }; | ||
26 | } TransportAddress; | ||
27 | |||
28 | typedef struct DataProtocolCapability { /* CHOICE */ | ||
29 | enum { | ||
30 | eDataProtocolCapability_nonStandard, | ||
31 | eDataProtocolCapability_v14buffered, | ||
32 | eDataProtocolCapability_v42lapm, | ||
33 | eDataProtocolCapability_hdlcFrameTunnelling, | ||
34 | eDataProtocolCapability_h310SeparateVCStack, | ||
35 | eDataProtocolCapability_h310SingleVCStack, | ||
36 | eDataProtocolCapability_transparent, | ||
37 | eDataProtocolCapability_segmentationAndReassembly, | ||
38 | eDataProtocolCapability_hdlcFrameTunnelingwSAR, | ||
39 | eDataProtocolCapability_v120, | ||
40 | eDataProtocolCapability_separateLANStack, | ||
41 | eDataProtocolCapability_v76wCompression, | ||
42 | eDataProtocolCapability_tcp, | ||
43 | eDataProtocolCapability_udp, | ||
44 | } choice; | ||
45 | } DataProtocolCapability; | ||
46 | |||
47 | typedef struct DataApplicationCapability_application { /* CHOICE */ | ||
48 | enum { | ||
49 | eDataApplicationCapability_application_nonStandard, | ||
50 | eDataApplicationCapability_application_t120, | ||
51 | eDataApplicationCapability_application_dsm_cc, | ||
52 | eDataApplicationCapability_application_userData, | ||
53 | eDataApplicationCapability_application_t84, | ||
54 | eDataApplicationCapability_application_t434, | ||
55 | eDataApplicationCapability_application_h224, | ||
56 | eDataApplicationCapability_application_nlpid, | ||
57 | eDataApplicationCapability_application_dsvdControl, | ||
58 | eDataApplicationCapability_application_h222DataPartitioning, | ||
59 | eDataApplicationCapability_application_t30fax, | ||
60 | eDataApplicationCapability_application_t140, | ||
61 | eDataApplicationCapability_application_t38fax, | ||
62 | eDataApplicationCapability_application_genericDataCapability, | ||
63 | } choice; | ||
64 | union { | ||
65 | DataProtocolCapability t120; | ||
66 | }; | ||
67 | } DataApplicationCapability_application; | ||
68 | |||
69 | typedef struct DataApplicationCapability { /* SEQUENCE */ | ||
70 | int options; /* No use */ | ||
71 | DataApplicationCapability_application application; | ||
72 | } DataApplicationCapability; | ||
73 | |||
74 | typedef struct DataType { /* CHOICE */ | ||
75 | enum { | ||
76 | eDataType_nonStandard, | ||
77 | eDataType_nullData, | ||
78 | eDataType_videoData, | ||
79 | eDataType_audioData, | ||
80 | eDataType_data, | ||
81 | eDataType_encryptionData, | ||
82 | eDataType_h235Control, | ||
83 | eDataType_h235Media, | ||
84 | eDataType_multiplexedStream, | ||
85 | } choice; | ||
86 | union { | ||
87 | DataApplicationCapability data; | ||
88 | }; | ||
89 | } DataType; | ||
90 | |||
91 | typedef struct UnicastAddress_iPAddress { /* SEQUENCE */ | ||
92 | int options; /* No use */ | ||
93 | unsigned network; | ||
94 | } UnicastAddress_iPAddress; | ||
95 | |||
96 | typedef struct UnicastAddress { /* CHOICE */ | ||
97 | enum { | ||
98 | eUnicastAddress_iPAddress, | ||
99 | eUnicastAddress_iPXAddress, | ||
100 | eUnicastAddress_iP6Address, | ||
101 | eUnicastAddress_netBios, | ||
102 | eUnicastAddress_iPSourceRouteAddress, | ||
103 | eUnicastAddress_nsap, | ||
104 | eUnicastAddress_nonStandardAddress, | ||
105 | } choice; | ||
106 | union { | ||
107 | UnicastAddress_iPAddress iPAddress; | ||
108 | }; | ||
109 | } UnicastAddress; | ||
110 | |||
111 | typedef struct H245_TransportAddress { /* CHOICE */ | ||
112 | enum { | ||
113 | eH245_TransportAddress_unicastAddress, | ||
114 | eH245_TransportAddress_multicastAddress, | ||
115 | } choice; | ||
116 | union { | ||
117 | UnicastAddress unicastAddress; | ||
118 | }; | ||
119 | } H245_TransportAddress; | ||
120 | |||
121 | typedef struct H2250LogicalChannelParameters { /* SEQUENCE */ | ||
122 | enum { | ||
123 | eH2250LogicalChannelParameters_nonStandard = (1 << 31), | ||
124 | eH2250LogicalChannelParameters_associatedSessionID = | ||
125 | (1 << 30), | ||
126 | eH2250LogicalChannelParameters_mediaChannel = (1 << 29), | ||
127 | eH2250LogicalChannelParameters_mediaGuaranteedDelivery = | ||
128 | (1 << 28), | ||
129 | eH2250LogicalChannelParameters_mediaControlChannel = | ||
130 | (1 << 27), | ||
131 | eH2250LogicalChannelParameters_mediaControlGuaranteedDelivery | ||
132 | = (1 << 26), | ||
133 | eH2250LogicalChannelParameters_silenceSuppression = (1 << 25), | ||
134 | eH2250LogicalChannelParameters_destination = (1 << 24), | ||
135 | eH2250LogicalChannelParameters_dynamicRTPPayloadType = | ||
136 | (1 << 23), | ||
137 | eH2250LogicalChannelParameters_mediaPacketization = (1 << 22), | ||
138 | eH2250LogicalChannelParameters_transportCapability = | ||
139 | (1 << 21), | ||
140 | eH2250LogicalChannelParameters_redundancyEncoding = (1 << 20), | ||
141 | eH2250LogicalChannelParameters_source = (1 << 19), | ||
142 | } options; | ||
143 | H245_TransportAddress mediaChannel; | ||
144 | H245_TransportAddress mediaControlChannel; | ||
145 | } H2250LogicalChannelParameters; | ||
146 | |||
147 | typedef struct OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters { /* CHOICE */ | ||
148 | enum { | ||
149 | eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h222LogicalChannelParameters, | ||
150 | eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h223LogicalChannelParameters, | ||
151 | eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_v76LogicalChannelParameters, | ||
152 | eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters, | ||
153 | eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_none, | ||
154 | } choice; | ||
155 | union { | ||
156 | H2250LogicalChannelParameters h2250LogicalChannelParameters; | ||
157 | }; | ||
158 | } OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters; | ||
159 | |||
160 | typedef struct OpenLogicalChannel_forwardLogicalChannelParameters { /* SEQUENCE */ | ||
161 | enum { | ||
162 | eOpenLogicalChannel_forwardLogicalChannelParameters_portNumber | ||
163 | = (1 << 31), | ||
164 | eOpenLogicalChannel_forwardLogicalChannelParameters_forwardLogicalChannelDependency | ||
165 | = (1 << 30), | ||
166 | eOpenLogicalChannel_forwardLogicalChannelParameters_replacementFor | ||
167 | = (1 << 29), | ||
168 | } options; | ||
169 | DataType dataType; | ||
170 | OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters | ||
171 | multiplexParameters; | ||
172 | } OpenLogicalChannel_forwardLogicalChannelParameters; | ||
173 | |||
174 | typedef struct OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters { /* CHOICE */ | ||
175 | enum { | ||
176 | eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h223LogicalChannelParameters, | ||
177 | eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_v76LogicalChannelParameters, | ||
178 | eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters, | ||
179 | } choice; | ||
180 | union { | ||
181 | H2250LogicalChannelParameters h2250LogicalChannelParameters; | ||
182 | }; | ||
183 | } OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters; | ||
184 | |||
185 | typedef struct OpenLogicalChannel_reverseLogicalChannelParameters { /* SEQUENCE */ | ||
186 | enum { | ||
187 | eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters | ||
188 | = (1 << 31), | ||
189 | eOpenLogicalChannel_reverseLogicalChannelParameters_reverseLogicalChannelDependency | ||
190 | = (1 << 30), | ||
191 | eOpenLogicalChannel_reverseLogicalChannelParameters_replacementFor | ||
192 | = (1 << 29), | ||
193 | } options; | ||
194 | OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters | ||
195 | multiplexParameters; | ||
196 | } OpenLogicalChannel_reverseLogicalChannelParameters; | ||
197 | |||
198 | typedef struct NetworkAccessParameters_networkAddress { /* CHOICE */ | ||
199 | enum { | ||
200 | eNetworkAccessParameters_networkAddress_q2931Address, | ||
201 | eNetworkAccessParameters_networkAddress_e164Address, | ||
202 | eNetworkAccessParameters_networkAddress_localAreaAddress, | ||
203 | } choice; | ||
204 | union { | ||
205 | H245_TransportAddress localAreaAddress; | ||
206 | }; | ||
207 | } NetworkAccessParameters_networkAddress; | ||
208 | |||
209 | typedef struct NetworkAccessParameters { /* SEQUENCE */ | ||
210 | enum { | ||
211 | eNetworkAccessParameters_distribution = (1 << 31), | ||
212 | eNetworkAccessParameters_externalReference = (1 << 30), | ||
213 | eNetworkAccessParameters_t120SetupProcedure = (1 << 29), | ||
214 | } options; | ||
215 | NetworkAccessParameters_networkAddress networkAddress; | ||
216 | } NetworkAccessParameters; | ||
217 | |||
218 | typedef struct OpenLogicalChannel { /* SEQUENCE */ | ||
219 | enum { | ||
220 | eOpenLogicalChannel_reverseLogicalChannelParameters = | ||
221 | (1 << 31), | ||
222 | eOpenLogicalChannel_separateStack = (1 << 30), | ||
223 | eOpenLogicalChannel_encryptionSync = (1 << 29), | ||
224 | } options; | ||
225 | OpenLogicalChannel_forwardLogicalChannelParameters | ||
226 | forwardLogicalChannelParameters; | ||
227 | OpenLogicalChannel_reverseLogicalChannelParameters | ||
228 | reverseLogicalChannelParameters; | ||
229 | NetworkAccessParameters separateStack; | ||
230 | } OpenLogicalChannel; | ||
231 | |||
232 | typedef struct Setup_UUIE_fastStart { /* SEQUENCE OF */ | ||
233 | int count; | ||
234 | OpenLogicalChannel item[30]; | ||
235 | } Setup_UUIE_fastStart; | ||
236 | |||
237 | typedef struct Setup_UUIE { /* SEQUENCE */ | ||
238 | enum { | ||
239 | eSetup_UUIE_h245Address = (1 << 31), | ||
240 | eSetup_UUIE_sourceAddress = (1 << 30), | ||
241 | eSetup_UUIE_destinationAddress = (1 << 29), | ||
242 | eSetup_UUIE_destCallSignalAddress = (1 << 28), | ||
243 | eSetup_UUIE_destExtraCallInfo = (1 << 27), | ||
244 | eSetup_UUIE_destExtraCRV = (1 << 26), | ||
245 | eSetup_UUIE_callServices = (1 << 25), | ||
246 | eSetup_UUIE_sourceCallSignalAddress = (1 << 24), | ||
247 | eSetup_UUIE_remoteExtensionAddress = (1 << 23), | ||
248 | eSetup_UUIE_callIdentifier = (1 << 22), | ||
249 | eSetup_UUIE_h245SecurityCapability = (1 << 21), | ||
250 | eSetup_UUIE_tokens = (1 << 20), | ||
251 | eSetup_UUIE_cryptoTokens = (1 << 19), | ||
252 | eSetup_UUIE_fastStart = (1 << 18), | ||
253 | eSetup_UUIE_mediaWaitForConnect = (1 << 17), | ||
254 | eSetup_UUIE_canOverlapSend = (1 << 16), | ||
255 | eSetup_UUIE_endpointIdentifier = (1 << 15), | ||
256 | eSetup_UUIE_multipleCalls = (1 << 14), | ||
257 | eSetup_UUIE_maintainConnection = (1 << 13), | ||
258 | eSetup_UUIE_connectionParameters = (1 << 12), | ||
259 | eSetup_UUIE_language = (1 << 11), | ||
260 | eSetup_UUIE_presentationIndicator = (1 << 10), | ||
261 | eSetup_UUIE_screeningIndicator = (1 << 9), | ||
262 | eSetup_UUIE_serviceControl = (1 << 8), | ||
263 | eSetup_UUIE_symmetricOperationRequired = (1 << 7), | ||
264 | eSetup_UUIE_capacity = (1 << 6), | ||
265 | eSetup_UUIE_circuitInfo = (1 << 5), | ||
266 | eSetup_UUIE_desiredProtocols = (1 << 4), | ||
267 | eSetup_UUIE_neededFeatures = (1 << 3), | ||
268 | eSetup_UUIE_desiredFeatures = (1 << 2), | ||
269 | eSetup_UUIE_supportedFeatures = (1 << 1), | ||
270 | eSetup_UUIE_parallelH245Control = (1 << 0), | ||
271 | } options; | ||
272 | TransportAddress h245Address; | ||
273 | TransportAddress destCallSignalAddress; | ||
274 | TransportAddress sourceCallSignalAddress; | ||
275 | Setup_UUIE_fastStart fastStart; | ||
276 | } Setup_UUIE; | ||
277 | |||
278 | typedef struct CallProceeding_UUIE_fastStart { /* SEQUENCE OF */ | ||
279 | int count; | ||
280 | OpenLogicalChannel item[30]; | ||
281 | } CallProceeding_UUIE_fastStart; | ||
282 | |||
283 | typedef struct CallProceeding_UUIE { /* SEQUENCE */ | ||
284 | enum { | ||
285 | eCallProceeding_UUIE_h245Address = (1 << 31), | ||
286 | eCallProceeding_UUIE_callIdentifier = (1 << 30), | ||
287 | eCallProceeding_UUIE_h245SecurityMode = (1 << 29), | ||
288 | eCallProceeding_UUIE_tokens = (1 << 28), | ||
289 | eCallProceeding_UUIE_cryptoTokens = (1 << 27), | ||
290 | eCallProceeding_UUIE_fastStart = (1 << 26), | ||
291 | eCallProceeding_UUIE_multipleCalls = (1 << 25), | ||
292 | eCallProceeding_UUIE_maintainConnection = (1 << 24), | ||
293 | eCallProceeding_UUIE_fastConnectRefused = (1 << 23), | ||
294 | eCallProceeding_UUIE_featureSet = (1 << 22), | ||
295 | } options; | ||
296 | TransportAddress h245Address; | ||
297 | CallProceeding_UUIE_fastStart fastStart; | ||
298 | } CallProceeding_UUIE; | ||
299 | |||
300 | typedef struct Connect_UUIE_fastStart { /* SEQUENCE OF */ | ||
301 | int count; | ||
302 | OpenLogicalChannel item[30]; | ||
303 | } Connect_UUIE_fastStart; | ||
304 | |||
305 | typedef struct Connect_UUIE { /* SEQUENCE */ | ||
306 | enum { | ||
307 | eConnect_UUIE_h245Address = (1 << 31), | ||
308 | eConnect_UUIE_callIdentifier = (1 << 30), | ||
309 | eConnect_UUIE_h245SecurityMode = (1 << 29), | ||
310 | eConnect_UUIE_tokens = (1 << 28), | ||
311 | eConnect_UUIE_cryptoTokens = (1 << 27), | ||
312 | eConnect_UUIE_fastStart = (1 << 26), | ||
313 | eConnect_UUIE_multipleCalls = (1 << 25), | ||
314 | eConnect_UUIE_maintainConnection = (1 << 24), | ||
315 | eConnect_UUIE_language = (1 << 23), | ||
316 | eConnect_UUIE_connectedAddress = (1 << 22), | ||
317 | eConnect_UUIE_presentationIndicator = (1 << 21), | ||
318 | eConnect_UUIE_screeningIndicator = (1 << 20), | ||
319 | eConnect_UUIE_fastConnectRefused = (1 << 19), | ||
320 | eConnect_UUIE_serviceControl = (1 << 18), | ||
321 | eConnect_UUIE_capacity = (1 << 17), | ||
322 | eConnect_UUIE_featureSet = (1 << 16), | ||
323 | } options; | ||
324 | TransportAddress h245Address; | ||
325 | Connect_UUIE_fastStart fastStart; | ||
326 | } Connect_UUIE; | ||
327 | |||
328 | typedef struct Alerting_UUIE_fastStart { /* SEQUENCE OF */ | ||
329 | int count; | ||
330 | OpenLogicalChannel item[30]; | ||
331 | } Alerting_UUIE_fastStart; | ||
332 | |||
333 | typedef struct Alerting_UUIE { /* SEQUENCE */ | ||
334 | enum { | ||
335 | eAlerting_UUIE_h245Address = (1 << 31), | ||
336 | eAlerting_UUIE_callIdentifier = (1 << 30), | ||
337 | eAlerting_UUIE_h245SecurityMode = (1 << 29), | ||
338 | eAlerting_UUIE_tokens = (1 << 28), | ||
339 | eAlerting_UUIE_cryptoTokens = (1 << 27), | ||
340 | eAlerting_UUIE_fastStart = (1 << 26), | ||
341 | eAlerting_UUIE_multipleCalls = (1 << 25), | ||
342 | eAlerting_UUIE_maintainConnection = (1 << 24), | ||
343 | eAlerting_UUIE_alertingAddress = (1 << 23), | ||
344 | eAlerting_UUIE_presentationIndicator = (1 << 22), | ||
345 | eAlerting_UUIE_screeningIndicator = (1 << 21), | ||
346 | eAlerting_UUIE_fastConnectRefused = (1 << 20), | ||
347 | eAlerting_UUIE_serviceControl = (1 << 19), | ||
348 | eAlerting_UUIE_capacity = (1 << 18), | ||
349 | eAlerting_UUIE_featureSet = (1 << 17), | ||
350 | } options; | ||
351 | TransportAddress h245Address; | ||
352 | Alerting_UUIE_fastStart fastStart; | ||
353 | } Alerting_UUIE; | ||
354 | |||
355 | typedef struct Information_UUIE_fastStart { /* SEQUENCE OF */ | ||
356 | int count; | ||
357 | OpenLogicalChannel item[30]; | ||
358 | } Information_UUIE_fastStart; | ||
359 | |||
360 | typedef struct Information_UUIE { /* SEQUENCE */ | ||
361 | enum { | ||
362 | eInformation_UUIE_callIdentifier = (1 << 31), | ||
363 | eInformation_UUIE_tokens = (1 << 30), | ||
364 | eInformation_UUIE_cryptoTokens = (1 << 29), | ||
365 | eInformation_UUIE_fastStart = (1 << 28), | ||
366 | eInformation_UUIE_fastConnectRefused = (1 << 27), | ||
367 | eInformation_UUIE_circuitInfo = (1 << 26), | ||
368 | } options; | ||
369 | Information_UUIE_fastStart fastStart; | ||
370 | } Information_UUIE; | ||
371 | |||
372 | typedef struct FacilityReason { /* CHOICE */ | ||
373 | enum { | ||
374 | eFacilityReason_routeCallToGatekeeper, | ||
375 | eFacilityReason_callForwarded, | ||
376 | eFacilityReason_routeCallToMC, | ||
377 | eFacilityReason_undefinedReason, | ||
378 | eFacilityReason_conferenceListChoice, | ||
379 | eFacilityReason_startH245, | ||
380 | eFacilityReason_noH245, | ||
381 | eFacilityReason_newTokens, | ||
382 | eFacilityReason_featureSetUpdate, | ||
383 | eFacilityReason_forwardedElements, | ||
384 | eFacilityReason_transportedInformation, | ||
385 | } choice; | ||
386 | } FacilityReason; | ||
387 | |||
388 | typedef struct Facility_UUIE_fastStart { /* SEQUENCE OF */ | ||
389 | int count; | ||
390 | OpenLogicalChannel item[30]; | ||
391 | } Facility_UUIE_fastStart; | ||
392 | |||
393 | typedef struct Facility_UUIE { /* SEQUENCE */ | ||
394 | enum { | ||
395 | eFacility_UUIE_alternativeAddress = (1 << 31), | ||
396 | eFacility_UUIE_alternativeAliasAddress = (1 << 30), | ||
397 | eFacility_UUIE_conferenceID = (1 << 29), | ||
398 | eFacility_UUIE_callIdentifier = (1 << 28), | ||
399 | eFacility_UUIE_destExtraCallInfo = (1 << 27), | ||
400 | eFacility_UUIE_remoteExtensionAddress = (1 << 26), | ||
401 | eFacility_UUIE_tokens = (1 << 25), | ||
402 | eFacility_UUIE_cryptoTokens = (1 << 24), | ||
403 | eFacility_UUIE_conferences = (1 << 23), | ||
404 | eFacility_UUIE_h245Address = (1 << 22), | ||
405 | eFacility_UUIE_fastStart = (1 << 21), | ||
406 | eFacility_UUIE_multipleCalls = (1 << 20), | ||
407 | eFacility_UUIE_maintainConnection = (1 << 19), | ||
408 | eFacility_UUIE_fastConnectRefused = (1 << 18), | ||
409 | eFacility_UUIE_serviceControl = (1 << 17), | ||
410 | eFacility_UUIE_circuitInfo = (1 << 16), | ||
411 | eFacility_UUIE_featureSet = (1 << 15), | ||
412 | eFacility_UUIE_destinationInfo = (1 << 14), | ||
413 | eFacility_UUIE_h245SecurityMode = (1 << 13), | ||
414 | } options; | ||
415 | FacilityReason reason; | ||
416 | TransportAddress h245Address; | ||
417 | Facility_UUIE_fastStart fastStart; | ||
418 | } Facility_UUIE; | ||
419 | |||
420 | typedef struct Progress_UUIE_fastStart { /* SEQUENCE OF */ | ||
421 | int count; | ||
422 | OpenLogicalChannel item[30]; | ||
423 | } Progress_UUIE_fastStart; | ||
424 | |||
425 | typedef struct Progress_UUIE { /* SEQUENCE */ | ||
426 | enum { | ||
427 | eProgress_UUIE_h245Address = (1 << 31), | ||
428 | eProgress_UUIE_h245SecurityMode = (1 << 30), | ||
429 | eProgress_UUIE_tokens = (1 << 29), | ||
430 | eProgress_UUIE_cryptoTokens = (1 << 28), | ||
431 | eProgress_UUIE_fastStart = (1 << 27), | ||
432 | eProgress_UUIE_multipleCalls = (1 << 26), | ||
433 | eProgress_UUIE_maintainConnection = (1 << 25), | ||
434 | eProgress_UUIE_fastConnectRefused = (1 << 24), | ||
435 | } options; | ||
436 | TransportAddress h245Address; | ||
437 | Progress_UUIE_fastStart fastStart; | ||
438 | } Progress_UUIE; | ||
439 | |||
440 | typedef struct H323_UU_PDU_h323_message_body { /* CHOICE */ | ||
441 | enum { | ||
442 | eH323_UU_PDU_h323_message_body_setup, | ||
443 | eH323_UU_PDU_h323_message_body_callProceeding, | ||
444 | eH323_UU_PDU_h323_message_body_connect, | ||
445 | eH323_UU_PDU_h323_message_body_alerting, | ||
446 | eH323_UU_PDU_h323_message_body_information, | ||
447 | eH323_UU_PDU_h323_message_body_releaseComplete, | ||
448 | eH323_UU_PDU_h323_message_body_facility, | ||
449 | eH323_UU_PDU_h323_message_body_progress, | ||
450 | eH323_UU_PDU_h323_message_body_empty, | ||
451 | eH323_UU_PDU_h323_message_body_status, | ||
452 | eH323_UU_PDU_h323_message_body_statusInquiry, | ||
453 | eH323_UU_PDU_h323_message_body_setupAcknowledge, | ||
454 | eH323_UU_PDU_h323_message_body_notify, | ||
455 | } choice; | ||
456 | union { | ||
457 | Setup_UUIE setup; | ||
458 | CallProceeding_UUIE callProceeding; | ||
459 | Connect_UUIE connect; | ||
460 | Alerting_UUIE alerting; | ||
461 | Information_UUIE information; | ||
462 | Facility_UUIE facility; | ||
463 | Progress_UUIE progress; | ||
464 | }; | ||
465 | } H323_UU_PDU_h323_message_body; | ||
466 | |||
467 | typedef struct RequestMessage { /* CHOICE */ | ||
468 | enum { | ||
469 | eRequestMessage_nonStandard, | ||
470 | eRequestMessage_masterSlaveDetermination, | ||
471 | eRequestMessage_terminalCapabilitySet, | ||
472 | eRequestMessage_openLogicalChannel, | ||
473 | eRequestMessage_closeLogicalChannel, | ||
474 | eRequestMessage_requestChannelClose, | ||
475 | eRequestMessage_multiplexEntrySend, | ||
476 | eRequestMessage_requestMultiplexEntry, | ||
477 | eRequestMessage_requestMode, | ||
478 | eRequestMessage_roundTripDelayRequest, | ||
479 | eRequestMessage_maintenanceLoopRequest, | ||
480 | eRequestMessage_communicationModeRequest, | ||
481 | eRequestMessage_conferenceRequest, | ||
482 | eRequestMessage_multilinkRequest, | ||
483 | eRequestMessage_logicalChannelRateRequest, | ||
484 | } choice; | ||
485 | union { | ||
486 | OpenLogicalChannel openLogicalChannel; | ||
487 | }; | ||
488 | } RequestMessage; | ||
489 | |||
490 | typedef struct OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters { /* CHOICE */ | ||
491 | enum { | ||
492 | eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h222LogicalChannelParameters, | ||
493 | eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters, | ||
494 | } choice; | ||
495 | union { | ||
496 | H2250LogicalChannelParameters h2250LogicalChannelParameters; | ||
497 | }; | ||
498 | } OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters; | ||
499 | |||
500 | typedef struct OpenLogicalChannelAck_reverseLogicalChannelParameters { /* SEQUENCE */ | ||
501 | enum { | ||
502 | eOpenLogicalChannelAck_reverseLogicalChannelParameters_portNumber | ||
503 | = (1 << 31), | ||
504 | eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters | ||
505 | = (1 << 30), | ||
506 | eOpenLogicalChannelAck_reverseLogicalChannelParameters_replacementFor | ||
507 | = (1 << 29), | ||
508 | } options; | ||
509 | OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters | ||
510 | multiplexParameters; | ||
511 | } OpenLogicalChannelAck_reverseLogicalChannelParameters; | ||
512 | |||
513 | typedef struct H2250LogicalChannelAckParameters { /* SEQUENCE */ | ||
514 | enum { | ||
515 | eH2250LogicalChannelAckParameters_nonStandard = (1 << 31), | ||
516 | eH2250LogicalChannelAckParameters_sessionID = (1 << 30), | ||
517 | eH2250LogicalChannelAckParameters_mediaChannel = (1 << 29), | ||
518 | eH2250LogicalChannelAckParameters_mediaControlChannel = | ||
519 | (1 << 28), | ||
520 | eH2250LogicalChannelAckParameters_dynamicRTPPayloadType = | ||
521 | (1 << 27), | ||
522 | eH2250LogicalChannelAckParameters_flowControlToZero = | ||
523 | (1 << 26), | ||
524 | eH2250LogicalChannelAckParameters_portNumber = (1 << 25), | ||
525 | } options; | ||
526 | H245_TransportAddress mediaChannel; | ||
527 | H245_TransportAddress mediaControlChannel; | ||
528 | } H2250LogicalChannelAckParameters; | ||
529 | |||
530 | typedef struct OpenLogicalChannelAck_forwardMultiplexAckParameters { /* CHOICE */ | ||
531 | enum { | ||
532 | eOpenLogicalChannelAck_forwardMultiplexAckParameters_h2250LogicalChannelAckParameters, | ||
533 | } choice; | ||
534 | union { | ||
535 | H2250LogicalChannelAckParameters | ||
536 | h2250LogicalChannelAckParameters; | ||
537 | }; | ||
538 | } OpenLogicalChannelAck_forwardMultiplexAckParameters; | ||
539 | |||
540 | typedef struct OpenLogicalChannelAck { /* SEQUENCE */ | ||
541 | enum { | ||
542 | eOpenLogicalChannelAck_reverseLogicalChannelParameters = | ||
543 | (1 << 31), | ||
544 | eOpenLogicalChannelAck_separateStack = (1 << 30), | ||
545 | eOpenLogicalChannelAck_forwardMultiplexAckParameters = | ||
546 | (1 << 29), | ||
547 | eOpenLogicalChannelAck_encryptionSync = (1 << 28), | ||
548 | } options; | ||
549 | OpenLogicalChannelAck_reverseLogicalChannelParameters | ||
550 | reverseLogicalChannelParameters; | ||
551 | OpenLogicalChannelAck_forwardMultiplexAckParameters | ||
552 | forwardMultiplexAckParameters; | ||
553 | } OpenLogicalChannelAck; | ||
554 | |||
555 | typedef struct ResponseMessage { /* CHOICE */ | ||
556 | enum { | ||
557 | eResponseMessage_nonStandard, | ||
558 | eResponseMessage_masterSlaveDeterminationAck, | ||
559 | eResponseMessage_masterSlaveDeterminationReject, | ||
560 | eResponseMessage_terminalCapabilitySetAck, | ||
561 | eResponseMessage_terminalCapabilitySetReject, | ||
562 | eResponseMessage_openLogicalChannelAck, | ||
563 | eResponseMessage_openLogicalChannelReject, | ||
564 | eResponseMessage_closeLogicalChannelAck, | ||
565 | eResponseMessage_requestChannelCloseAck, | ||
566 | eResponseMessage_requestChannelCloseReject, | ||
567 | eResponseMessage_multiplexEntrySendAck, | ||
568 | eResponseMessage_multiplexEntrySendReject, | ||
569 | eResponseMessage_requestMultiplexEntryAck, | ||
570 | eResponseMessage_requestMultiplexEntryReject, | ||
571 | eResponseMessage_requestModeAck, | ||
572 | eResponseMessage_requestModeReject, | ||
573 | eResponseMessage_roundTripDelayResponse, | ||
574 | eResponseMessage_maintenanceLoopAck, | ||
575 | eResponseMessage_maintenanceLoopReject, | ||
576 | eResponseMessage_communicationModeResponse, | ||
577 | eResponseMessage_conferenceResponse, | ||
578 | eResponseMessage_multilinkResponse, | ||
579 | eResponseMessage_logicalChannelRateAcknowledge, | ||
580 | eResponseMessage_logicalChannelRateReject, | ||
581 | } choice; | ||
582 | union { | ||
583 | OpenLogicalChannelAck openLogicalChannelAck; | ||
584 | }; | ||
585 | } ResponseMessage; | ||
586 | |||
587 | typedef struct MultimediaSystemControlMessage { /* CHOICE */ | ||
588 | enum { | ||
589 | eMultimediaSystemControlMessage_request, | ||
590 | eMultimediaSystemControlMessage_response, | ||
591 | eMultimediaSystemControlMessage_command, | ||
592 | eMultimediaSystemControlMessage_indication, | ||
593 | } choice; | ||
594 | union { | ||
595 | RequestMessage request; | ||
596 | ResponseMessage response; | ||
597 | }; | ||
598 | } MultimediaSystemControlMessage; | ||
599 | |||
600 | typedef struct H323_UU_PDU_h245Control { /* SEQUENCE OF */ | ||
601 | int count; | ||
602 | MultimediaSystemControlMessage item[4]; | ||
603 | } H323_UU_PDU_h245Control; | ||
604 | |||
605 | typedef struct H323_UU_PDU { /* SEQUENCE */ | ||
606 | enum { | ||
607 | eH323_UU_PDU_nonStandardData = (1 << 31), | ||
608 | eH323_UU_PDU_h4501SupplementaryService = (1 << 30), | ||
609 | eH323_UU_PDU_h245Tunneling = (1 << 29), | ||
610 | eH323_UU_PDU_h245Control = (1 << 28), | ||
611 | eH323_UU_PDU_nonStandardControl = (1 << 27), | ||
612 | eH323_UU_PDU_callLinkage = (1 << 26), | ||
613 | eH323_UU_PDU_tunnelledSignallingMessage = (1 << 25), | ||
614 | eH323_UU_PDU_provisionalRespToH245Tunneling = (1 << 24), | ||
615 | eH323_UU_PDU_stimulusControl = (1 << 23), | ||
616 | eH323_UU_PDU_genericData = (1 << 22), | ||
617 | } options; | ||
618 | H323_UU_PDU_h323_message_body h323_message_body; | ||
619 | H323_UU_PDU_h245Control h245Control; | ||
620 | } H323_UU_PDU; | ||
621 | |||
622 | typedef struct H323_UserInformation { /* SEQUENCE */ | ||
623 | enum { | ||
624 | eH323_UserInformation_user_data = (1 << 31), | ||
625 | } options; | ||
626 | H323_UU_PDU h323_uu_pdu; | ||
627 | } H323_UserInformation; | ||
628 | |||
629 | typedef struct GatekeeperRequest { /* SEQUENCE */ | ||
630 | enum { | ||
631 | eGatekeeperRequest_nonStandardData = (1 << 31), | ||
632 | eGatekeeperRequest_gatekeeperIdentifier = (1 << 30), | ||
633 | eGatekeeperRequest_callServices = (1 << 29), | ||
634 | eGatekeeperRequest_endpointAlias = (1 << 28), | ||
635 | eGatekeeperRequest_alternateEndpoints = (1 << 27), | ||
636 | eGatekeeperRequest_tokens = (1 << 26), | ||
637 | eGatekeeperRequest_cryptoTokens = (1 << 25), | ||
638 | eGatekeeperRequest_authenticationCapability = (1 << 24), | ||
639 | eGatekeeperRequest_algorithmOIDs = (1 << 23), | ||
640 | eGatekeeperRequest_integrity = (1 << 22), | ||
641 | eGatekeeperRequest_integrityCheckValue = (1 << 21), | ||
642 | eGatekeeperRequest_supportsAltGK = (1 << 20), | ||
643 | eGatekeeperRequest_featureSet = (1 << 19), | ||
644 | eGatekeeperRequest_genericData = (1 << 18), | ||
645 | } options; | ||
646 | TransportAddress rasAddress; | ||
647 | } GatekeeperRequest; | ||
648 | |||
649 | typedef struct GatekeeperConfirm { /* SEQUENCE */ | ||
650 | enum { | ||
651 | eGatekeeperConfirm_nonStandardData = (1 << 31), | ||
652 | eGatekeeperConfirm_gatekeeperIdentifier = (1 << 30), | ||
653 | eGatekeeperConfirm_alternateGatekeeper = (1 << 29), | ||
654 | eGatekeeperConfirm_authenticationMode = (1 << 28), | ||
655 | eGatekeeperConfirm_tokens = (1 << 27), | ||
656 | eGatekeeperConfirm_cryptoTokens = (1 << 26), | ||
657 | eGatekeeperConfirm_algorithmOID = (1 << 25), | ||
658 | eGatekeeperConfirm_integrity = (1 << 24), | ||
659 | eGatekeeperConfirm_integrityCheckValue = (1 << 23), | ||
660 | eGatekeeperConfirm_featureSet = (1 << 22), | ||
661 | eGatekeeperConfirm_genericData = (1 << 21), | ||
662 | } options; | ||
663 | TransportAddress rasAddress; | ||
664 | } GatekeeperConfirm; | ||
665 | |||
666 | typedef struct RegistrationRequest_callSignalAddress { /* SEQUENCE OF */ | ||
667 | int count; | ||
668 | TransportAddress item[10]; | ||
669 | } RegistrationRequest_callSignalAddress; | ||
670 | |||
671 | typedef struct RegistrationRequest_rasAddress { /* SEQUENCE OF */ | ||
672 | int count; | ||
673 | TransportAddress item[10]; | ||
674 | } RegistrationRequest_rasAddress; | ||
675 | |||
676 | typedef struct RegistrationRequest { /* SEQUENCE */ | ||
677 | enum { | ||
678 | eRegistrationRequest_nonStandardData = (1 << 31), | ||
679 | eRegistrationRequest_terminalAlias = (1 << 30), | ||
680 | eRegistrationRequest_gatekeeperIdentifier = (1 << 29), | ||
681 | eRegistrationRequest_alternateEndpoints = (1 << 28), | ||
682 | eRegistrationRequest_timeToLive = (1 << 27), | ||
683 | eRegistrationRequest_tokens = (1 << 26), | ||
684 | eRegistrationRequest_cryptoTokens = (1 << 25), | ||
685 | eRegistrationRequest_integrityCheckValue = (1 << 24), | ||
686 | eRegistrationRequest_keepAlive = (1 << 23), | ||
687 | eRegistrationRequest_endpointIdentifier = (1 << 22), | ||
688 | eRegistrationRequest_willSupplyUUIEs = (1 << 21), | ||
689 | eRegistrationRequest_maintainConnection = (1 << 20), | ||
690 | eRegistrationRequest_alternateTransportAddresses = (1 << 19), | ||
691 | eRegistrationRequest_additiveRegistration = (1 << 18), | ||
692 | eRegistrationRequest_terminalAliasPattern = (1 << 17), | ||
693 | eRegistrationRequest_supportsAltGK = (1 << 16), | ||
694 | eRegistrationRequest_usageReportingCapability = (1 << 15), | ||
695 | eRegistrationRequest_multipleCalls = (1 << 14), | ||
696 | eRegistrationRequest_supportedH248Packages = (1 << 13), | ||
697 | eRegistrationRequest_callCreditCapability = (1 << 12), | ||
698 | eRegistrationRequest_capacityReportingCapability = (1 << 11), | ||
699 | eRegistrationRequest_capacity = (1 << 10), | ||
700 | eRegistrationRequest_featureSet = (1 << 9), | ||
701 | eRegistrationRequest_genericData = (1 << 8), | ||
702 | } options; | ||
703 | RegistrationRequest_callSignalAddress callSignalAddress; | ||
704 | RegistrationRequest_rasAddress rasAddress; | ||
705 | unsigned timeToLive; | ||
706 | } RegistrationRequest; | ||
707 | |||
708 | typedef struct RegistrationConfirm_callSignalAddress { /* SEQUENCE OF */ | ||
709 | int count; | ||
710 | TransportAddress item[10]; | ||
711 | } RegistrationConfirm_callSignalAddress; | ||
712 | |||
713 | typedef struct RegistrationConfirm { /* SEQUENCE */ | ||
714 | enum { | ||
715 | eRegistrationConfirm_nonStandardData = (1 << 31), | ||
716 | eRegistrationConfirm_terminalAlias = (1 << 30), | ||
717 | eRegistrationConfirm_gatekeeperIdentifier = (1 << 29), | ||
718 | eRegistrationConfirm_alternateGatekeeper = (1 << 28), | ||
719 | eRegistrationConfirm_timeToLive = (1 << 27), | ||
720 | eRegistrationConfirm_tokens = (1 << 26), | ||
721 | eRegistrationConfirm_cryptoTokens = (1 << 25), | ||
722 | eRegistrationConfirm_integrityCheckValue = (1 << 24), | ||
723 | eRegistrationConfirm_willRespondToIRR = (1 << 23), | ||
724 | eRegistrationConfirm_preGrantedARQ = (1 << 22), | ||
725 | eRegistrationConfirm_maintainConnection = (1 << 21), | ||
726 | eRegistrationConfirm_serviceControl = (1 << 20), | ||
727 | eRegistrationConfirm_supportsAdditiveRegistration = (1 << 19), | ||
728 | eRegistrationConfirm_terminalAliasPattern = (1 << 18), | ||
729 | eRegistrationConfirm_supportedPrefixes = (1 << 17), | ||
730 | eRegistrationConfirm_usageSpec = (1 << 16), | ||
731 | eRegistrationConfirm_featureServerAlias = (1 << 15), | ||
732 | eRegistrationConfirm_capacityReportingSpec = (1 << 14), | ||
733 | eRegistrationConfirm_featureSet = (1 << 13), | ||
734 | eRegistrationConfirm_genericData = (1 << 12), | ||
735 | } options; | ||
736 | RegistrationConfirm_callSignalAddress callSignalAddress; | ||
737 | unsigned timeToLive; | ||
738 | } RegistrationConfirm; | ||
739 | |||
740 | typedef struct UnregistrationRequest_callSignalAddress { /* SEQUENCE OF */ | ||
741 | int count; | ||
742 | TransportAddress item[10]; | ||
743 | } UnregistrationRequest_callSignalAddress; | ||
744 | |||
745 | typedef struct UnregistrationRequest { /* SEQUENCE */ | ||
746 | enum { | ||
747 | eUnregistrationRequest_endpointAlias = (1 << 31), | ||
748 | eUnregistrationRequest_nonStandardData = (1 << 30), | ||
749 | eUnregistrationRequest_endpointIdentifier = (1 << 29), | ||
750 | eUnregistrationRequest_alternateEndpoints = (1 << 28), | ||
751 | eUnregistrationRequest_gatekeeperIdentifier = (1 << 27), | ||
752 | eUnregistrationRequest_tokens = (1 << 26), | ||
753 | eUnregistrationRequest_cryptoTokens = (1 << 25), | ||
754 | eUnregistrationRequest_integrityCheckValue = (1 << 24), | ||
755 | eUnregistrationRequest_reason = (1 << 23), | ||
756 | eUnregistrationRequest_endpointAliasPattern = (1 << 22), | ||
757 | eUnregistrationRequest_supportedPrefixes = (1 << 21), | ||
758 | eUnregistrationRequest_alternateGatekeeper = (1 << 20), | ||
759 | eUnregistrationRequest_genericData = (1 << 19), | ||
760 | } options; | ||
761 | UnregistrationRequest_callSignalAddress callSignalAddress; | ||
762 | } UnregistrationRequest; | ||
763 | |||
764 | typedef struct AdmissionRequest { /* SEQUENCE */ | ||
765 | enum { | ||
766 | eAdmissionRequest_callModel = (1 << 31), | ||
767 | eAdmissionRequest_destinationInfo = (1 << 30), | ||
768 | eAdmissionRequest_destCallSignalAddress = (1 << 29), | ||
769 | eAdmissionRequest_destExtraCallInfo = (1 << 28), | ||
770 | eAdmissionRequest_srcCallSignalAddress = (1 << 27), | ||
771 | eAdmissionRequest_nonStandardData = (1 << 26), | ||
772 | eAdmissionRequest_callServices = (1 << 25), | ||
773 | eAdmissionRequest_canMapAlias = (1 << 24), | ||
774 | eAdmissionRequest_callIdentifier = (1 << 23), | ||
775 | eAdmissionRequest_srcAlternatives = (1 << 22), | ||
776 | eAdmissionRequest_destAlternatives = (1 << 21), | ||
777 | eAdmissionRequest_gatekeeperIdentifier = (1 << 20), | ||
778 | eAdmissionRequest_tokens = (1 << 19), | ||
779 | eAdmissionRequest_cryptoTokens = (1 << 18), | ||
780 | eAdmissionRequest_integrityCheckValue = (1 << 17), | ||
781 | eAdmissionRequest_transportQOS = (1 << 16), | ||
782 | eAdmissionRequest_willSupplyUUIEs = (1 << 15), | ||
783 | eAdmissionRequest_callLinkage = (1 << 14), | ||
784 | eAdmissionRequest_gatewayDataRate = (1 << 13), | ||
785 | eAdmissionRequest_capacity = (1 << 12), | ||
786 | eAdmissionRequest_circuitInfo = (1 << 11), | ||
787 | eAdmissionRequest_desiredProtocols = (1 << 10), | ||
788 | eAdmissionRequest_desiredTunnelledProtocol = (1 << 9), | ||
789 | eAdmissionRequest_featureSet = (1 << 8), | ||
790 | eAdmissionRequest_genericData = (1 << 7), | ||
791 | } options; | ||
792 | TransportAddress destCallSignalAddress; | ||
793 | TransportAddress srcCallSignalAddress; | ||
794 | } AdmissionRequest; | ||
795 | |||
796 | typedef struct AdmissionConfirm { /* SEQUENCE */ | ||
797 | enum { | ||
798 | eAdmissionConfirm_irrFrequency = (1 << 31), | ||
799 | eAdmissionConfirm_nonStandardData = (1 << 30), | ||
800 | eAdmissionConfirm_destinationInfo = (1 << 29), | ||
801 | eAdmissionConfirm_destExtraCallInfo = (1 << 28), | ||
802 | eAdmissionConfirm_destinationType = (1 << 27), | ||
803 | eAdmissionConfirm_remoteExtensionAddress = (1 << 26), | ||
804 | eAdmissionConfirm_alternateEndpoints = (1 << 25), | ||
805 | eAdmissionConfirm_tokens = (1 << 24), | ||
806 | eAdmissionConfirm_cryptoTokens = (1 << 23), | ||
807 | eAdmissionConfirm_integrityCheckValue = (1 << 22), | ||
808 | eAdmissionConfirm_transportQOS = (1 << 21), | ||
809 | eAdmissionConfirm_willRespondToIRR = (1 << 20), | ||
810 | eAdmissionConfirm_uuiesRequested = (1 << 19), | ||
811 | eAdmissionConfirm_language = (1 << 18), | ||
812 | eAdmissionConfirm_alternateTransportAddresses = (1 << 17), | ||
813 | eAdmissionConfirm_useSpecifiedTransport = (1 << 16), | ||
814 | eAdmissionConfirm_circuitInfo = (1 << 15), | ||
815 | eAdmissionConfirm_usageSpec = (1 << 14), | ||
816 | eAdmissionConfirm_supportedProtocols = (1 << 13), | ||
817 | eAdmissionConfirm_serviceControl = (1 << 12), | ||
818 | eAdmissionConfirm_multipleCalls = (1 << 11), | ||
819 | eAdmissionConfirm_featureSet = (1 << 10), | ||
820 | eAdmissionConfirm_genericData = (1 << 9), | ||
821 | } options; | ||
822 | TransportAddress destCallSignalAddress; | ||
823 | } AdmissionConfirm; | ||
824 | |||
825 | typedef struct LocationRequest { /* SEQUENCE */ | ||
826 | enum { | ||
827 | eLocationRequest_endpointIdentifier = (1 << 31), | ||
828 | eLocationRequest_nonStandardData = (1 << 30), | ||
829 | eLocationRequest_sourceInfo = (1 << 29), | ||
830 | eLocationRequest_canMapAlias = (1 << 28), | ||
831 | eLocationRequest_gatekeeperIdentifier = (1 << 27), | ||
832 | eLocationRequest_tokens = (1 << 26), | ||
833 | eLocationRequest_cryptoTokens = (1 << 25), | ||
834 | eLocationRequest_integrityCheckValue = (1 << 24), | ||
835 | eLocationRequest_desiredProtocols = (1 << 23), | ||
836 | eLocationRequest_desiredTunnelledProtocol = (1 << 22), | ||
837 | eLocationRequest_featureSet = (1 << 21), | ||
838 | eLocationRequest_genericData = (1 << 20), | ||
839 | eLocationRequest_hopCount = (1 << 19), | ||
840 | eLocationRequest_circuitInfo = (1 << 18), | ||
841 | } options; | ||
842 | TransportAddress replyAddress; | ||
843 | } LocationRequest; | ||
844 | |||
845 | typedef struct LocationConfirm { /* SEQUENCE */ | ||
846 | enum { | ||
847 | eLocationConfirm_nonStandardData = (1 << 31), | ||
848 | eLocationConfirm_destinationInfo = (1 << 30), | ||
849 | eLocationConfirm_destExtraCallInfo = (1 << 29), | ||
850 | eLocationConfirm_destinationType = (1 << 28), | ||
851 | eLocationConfirm_remoteExtensionAddress = (1 << 27), | ||
852 | eLocationConfirm_alternateEndpoints = (1 << 26), | ||
853 | eLocationConfirm_tokens = (1 << 25), | ||
854 | eLocationConfirm_cryptoTokens = (1 << 24), | ||
855 | eLocationConfirm_integrityCheckValue = (1 << 23), | ||
856 | eLocationConfirm_alternateTransportAddresses = (1 << 22), | ||
857 | eLocationConfirm_supportedProtocols = (1 << 21), | ||
858 | eLocationConfirm_multipleCalls = (1 << 20), | ||
859 | eLocationConfirm_featureSet = (1 << 19), | ||
860 | eLocationConfirm_genericData = (1 << 18), | ||
861 | eLocationConfirm_circuitInfo = (1 << 17), | ||
862 | eLocationConfirm_serviceControl = (1 << 16), | ||
863 | } options; | ||
864 | TransportAddress callSignalAddress; | ||
865 | TransportAddress rasAddress; | ||
866 | } LocationConfirm; | ||
867 | |||
868 | typedef struct InfoRequestResponse_callSignalAddress { /* SEQUENCE OF */ | ||
869 | int count; | ||
870 | TransportAddress item[10]; | ||
871 | } InfoRequestResponse_callSignalAddress; | ||
872 | |||
873 | typedef struct InfoRequestResponse { /* SEQUENCE */ | ||
874 | enum { | ||
875 | eInfoRequestResponse_nonStandardData = (1 << 31), | ||
876 | eInfoRequestResponse_endpointAlias = (1 << 30), | ||
877 | eInfoRequestResponse_perCallInfo = (1 << 29), | ||
878 | eInfoRequestResponse_tokens = (1 << 28), | ||
879 | eInfoRequestResponse_cryptoTokens = (1 << 27), | ||
880 | eInfoRequestResponse_integrityCheckValue = (1 << 26), | ||
881 | eInfoRequestResponse_needResponse = (1 << 25), | ||
882 | eInfoRequestResponse_capacity = (1 << 24), | ||
883 | eInfoRequestResponse_irrStatus = (1 << 23), | ||
884 | eInfoRequestResponse_unsolicited = (1 << 22), | ||
885 | eInfoRequestResponse_genericData = (1 << 21), | ||
886 | } options; | ||
887 | TransportAddress rasAddress; | ||
888 | InfoRequestResponse_callSignalAddress callSignalAddress; | ||
889 | } InfoRequestResponse; | ||
890 | |||
891 | typedef struct RasMessage { /* CHOICE */ | ||
892 | enum { | ||
893 | eRasMessage_gatekeeperRequest, | ||
894 | eRasMessage_gatekeeperConfirm, | ||
895 | eRasMessage_gatekeeperReject, | ||
896 | eRasMessage_registrationRequest, | ||
897 | eRasMessage_registrationConfirm, | ||
898 | eRasMessage_registrationReject, | ||
899 | eRasMessage_unregistrationRequest, | ||
900 | eRasMessage_unregistrationConfirm, | ||
901 | eRasMessage_unregistrationReject, | ||
902 | eRasMessage_admissionRequest, | ||
903 | eRasMessage_admissionConfirm, | ||
904 | eRasMessage_admissionReject, | ||
905 | eRasMessage_bandwidthRequest, | ||
906 | eRasMessage_bandwidthConfirm, | ||
907 | eRasMessage_bandwidthReject, | ||
908 | eRasMessage_disengageRequest, | ||
909 | eRasMessage_disengageConfirm, | ||
910 | eRasMessage_disengageReject, | ||
911 | eRasMessage_locationRequest, | ||
912 | eRasMessage_locationConfirm, | ||
913 | eRasMessage_locationReject, | ||
914 | eRasMessage_infoRequest, | ||
915 | eRasMessage_infoRequestResponse, | ||
916 | eRasMessage_nonStandardMessage, | ||
917 | eRasMessage_unknownMessageResponse, | ||
918 | eRasMessage_requestInProgress, | ||
919 | eRasMessage_resourcesAvailableIndicate, | ||
920 | eRasMessage_resourcesAvailableConfirm, | ||
921 | eRasMessage_infoRequestAck, | ||
922 | eRasMessage_infoRequestNak, | ||
923 | eRasMessage_serviceControlIndication, | ||
924 | eRasMessage_serviceControlResponse, | ||
925 | } choice; | ||
926 | union { | ||
927 | GatekeeperRequest gatekeeperRequest; | ||
928 | GatekeeperConfirm gatekeeperConfirm; | ||
929 | RegistrationRequest registrationRequest; | ||
930 | RegistrationConfirm registrationConfirm; | ||
931 | UnregistrationRequest unregistrationRequest; | ||
932 | AdmissionRequest admissionRequest; | ||
933 | AdmissionConfirm admissionConfirm; | ||
934 | LocationRequest locationRequest; | ||
935 | LocationConfirm locationConfirm; | ||
936 | InfoRequestResponse infoRequestResponse; | ||
937 | }; | ||
938 | } RasMessage; | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index 9b6e19bae90f..01bd7cab9367 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c | |||
@@ -1658,7 +1658,7 @@ static void __exit ctnetlink_exit(void) | |||
1658 | printk("ctnetlink: unregistering from nfnetlink.\n"); | 1658 | printk("ctnetlink: unregistering from nfnetlink.\n"); |
1659 | 1659 | ||
1660 | #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS | 1660 | #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS |
1661 | ip_conntrack_unregister_notifier(&ctnl_notifier_exp); | 1661 | ip_conntrack_expect_unregister_notifier(&ctnl_notifier_exp); |
1662 | ip_conntrack_unregister_notifier(&ctnl_notifier); | 1662 | ip_conntrack_unregister_notifier(&ctnl_notifier); |
1663 | #endif | 1663 | #endif |
1664 | 1664 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c index 3021af0910f1..d8b14a9010a6 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c | |||
@@ -224,25 +224,14 @@ icmp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, | |||
224 | } | 224 | } |
225 | 225 | ||
226 | /* See ip_conntrack_proto_tcp.c */ | 226 | /* See ip_conntrack_proto_tcp.c */ |
227 | if (hooknum != NF_IP_PRE_ROUTING) | 227 | if (hooknum == NF_IP_PRE_ROUTING && |
228 | goto checksum_skipped; | 228 | nf_ip_checksum(skb, hooknum, skb->nh.iph->ihl * 4, 0)) { |
229 | 229 | if (LOG_INVALID(IPPROTO_ICMP)) | |
230 | switch (skb->ip_summed) { | 230 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
231 | case CHECKSUM_HW: | 231 | "ip_ct_icmp: bad ICMP checksum "); |
232 | if (!(u16)csum_fold(skb->csum)) | 232 | return -NF_ACCEPT; |
233 | break; | ||
234 | /* fall through */ | ||
235 | case CHECKSUM_NONE: | ||
236 | skb->csum = 0; | ||
237 | if (__skb_checksum_complete(skb)) { | ||
238 | if (LOG_INVALID(IPPROTO_ICMP)) | ||
239 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | ||
240 | "ip_ct_icmp: bad ICMP checksum "); | ||
241 | return -NF_ACCEPT; | ||
242 | } | ||
243 | } | 233 | } |
244 | 234 | ||
245 | checksum_skipped: | ||
246 | /* | 235 | /* |
247 | * 18 is the highest 'known' ICMP type. Anything else is a mystery | 236 | * 18 is the highest 'known' ICMP type. Anything else is a mystery |
248 | * | 237 | * |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index e0dc37063545..062b252b58ad 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
@@ -870,11 +870,8 @@ static int tcp_error(struct sk_buff *skb, | |||
870 | * and moreover root might send raw packets. | 870 | * and moreover root might send raw packets. |
871 | */ | 871 | */ |
872 | /* FIXME: Source route IP option packets --RR */ | 872 | /* FIXME: Source route IP option packets --RR */ |
873 | if (hooknum == NF_IP_PRE_ROUTING | 873 | if (hooknum == NF_IP_PRE_ROUTING && |
874 | && skb->ip_summed != CHECKSUM_UNNECESSARY | 874 | nf_ip_checksum(skb, hooknum, iph->ihl * 4, IPPROTO_TCP)) { |
875 | && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, | ||
876 | skb->ip_summed == CHECKSUM_HW ? skb->csum | ||
877 | : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { | ||
878 | if (LOG_INVALID(IPPROTO_TCP)) | 875 | if (LOG_INVALID(IPPROTO_TCP)) |
879 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 876 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
880 | "ip_ct_tcp: bad TCP checksum "); | 877 | "ip_ct_tcp: bad TCP checksum "); |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c index 55b7d3210adf..70899868783b 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c | |||
@@ -120,11 +120,8 @@ static int udp_error(struct sk_buff *skb, enum ip_conntrack_info *ctinfo, | |||
120 | * because the semantic of CHECKSUM_HW is different there | 120 | * because the semantic of CHECKSUM_HW is different there |
121 | * and moreover root might send raw packets. | 121 | * and moreover root might send raw packets. |
122 | * FIXME: Source route IP option packets --RR */ | 122 | * FIXME: Source route IP option packets --RR */ |
123 | if (hooknum == NF_IP_PRE_ROUTING | 123 | if (hooknum == NF_IP_PRE_ROUTING && |
124 | && skb->ip_summed != CHECKSUM_UNNECESSARY | 124 | nf_ip_checksum(skb, hooknum, iph->ihl * 4, IPPROTO_UDP)) { |
125 | && csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, | ||
126 | skb->ip_summed == CHECKSUM_HW ? skb->csum | ||
127 | : skb_checksum(skb, iph->ihl*4, udplen, 0))) { | ||
128 | if (LOG_INVALID(IPPROTO_UDP)) | 125 | if (LOG_INVALID(IPPROTO_UDP)) |
129 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 126 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
130 | "ip_ct_udp: bad UDP checksum "); | 127 | "ip_ct_udp: bad UDP checksum "); |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 52076026db36..929d61f7be91 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
@@ -469,70 +469,63 @@ static unsigned int ip_conntrack_local(unsigned int hooknum, | |||
469 | 469 | ||
470 | /* Connection tracking may drop packets, but never alters them, so | 470 | /* Connection tracking may drop packets, but never alters them, so |
471 | make it the first hook. */ | 471 | make it the first hook. */ |
472 | static struct nf_hook_ops ip_conntrack_defrag_ops = { | 472 | static struct nf_hook_ops ip_conntrack_ops[] = { |
473 | .hook = ip_conntrack_defrag, | 473 | { |
474 | .owner = THIS_MODULE, | 474 | .hook = ip_conntrack_defrag, |
475 | .pf = PF_INET, | 475 | .owner = THIS_MODULE, |
476 | .hooknum = NF_IP_PRE_ROUTING, | 476 | .pf = PF_INET, |
477 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | 477 | .hooknum = NF_IP_PRE_ROUTING, |
478 | }; | 478 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, |
479 | 479 | }, | |
480 | static struct nf_hook_ops ip_conntrack_in_ops = { | 480 | { |
481 | .hook = ip_conntrack_in, | 481 | .hook = ip_conntrack_in, |
482 | .owner = THIS_MODULE, | 482 | .owner = THIS_MODULE, |
483 | .pf = PF_INET, | 483 | .pf = PF_INET, |
484 | .hooknum = NF_IP_PRE_ROUTING, | 484 | .hooknum = NF_IP_PRE_ROUTING, |
485 | .priority = NF_IP_PRI_CONNTRACK, | 485 | .priority = NF_IP_PRI_CONNTRACK, |
486 | }; | 486 | }, |
487 | 487 | { | |
488 | static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = { | 488 | .hook = ip_conntrack_defrag, |
489 | .hook = ip_conntrack_defrag, | 489 | .owner = THIS_MODULE, |
490 | .owner = THIS_MODULE, | 490 | .pf = PF_INET, |
491 | .pf = PF_INET, | 491 | .hooknum = NF_IP_LOCAL_OUT, |
492 | .hooknum = NF_IP_LOCAL_OUT, | 492 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, |
493 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | 493 | }, |
494 | }; | 494 | { |
495 | 495 | .hook = ip_conntrack_local, | |
496 | static struct nf_hook_ops ip_conntrack_local_out_ops = { | 496 | .owner = THIS_MODULE, |
497 | .hook = ip_conntrack_local, | 497 | .pf = PF_INET, |
498 | .owner = THIS_MODULE, | 498 | .hooknum = NF_IP_LOCAL_OUT, |
499 | .pf = PF_INET, | 499 | .priority = NF_IP_PRI_CONNTRACK, |
500 | .hooknum = NF_IP_LOCAL_OUT, | 500 | }, |
501 | .priority = NF_IP_PRI_CONNTRACK, | 501 | { |
502 | }; | 502 | .hook = ip_conntrack_help, |
503 | 503 | .owner = THIS_MODULE, | |
504 | /* helpers */ | 504 | .pf = PF_INET, |
505 | static struct nf_hook_ops ip_conntrack_helper_out_ops = { | 505 | .hooknum = NF_IP_POST_ROUTING, |
506 | .hook = ip_conntrack_help, | 506 | .priority = NF_IP_PRI_CONNTRACK_HELPER, |
507 | .owner = THIS_MODULE, | 507 | }, |
508 | .pf = PF_INET, | 508 | { |
509 | .hooknum = NF_IP_POST_ROUTING, | 509 | .hook = ip_conntrack_help, |
510 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | 510 | .owner = THIS_MODULE, |
511 | }; | 511 | .pf = PF_INET, |
512 | 512 | .hooknum = NF_IP_LOCAL_IN, | |
513 | static struct nf_hook_ops ip_conntrack_helper_in_ops = { | 513 | .priority = NF_IP_PRI_CONNTRACK_HELPER, |
514 | .hook = ip_conntrack_help, | 514 | }, |
515 | .owner = THIS_MODULE, | 515 | { |
516 | .pf = PF_INET, | 516 | .hook = ip_confirm, |
517 | .hooknum = NF_IP_LOCAL_IN, | 517 | .owner = THIS_MODULE, |
518 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | 518 | .pf = PF_INET, |
519 | }; | 519 | .hooknum = NF_IP_POST_ROUTING, |
520 | 520 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | |
521 | /* Refragmenter; last chance. */ | 521 | }, |
522 | static struct nf_hook_ops ip_conntrack_out_ops = { | 522 | { |
523 | .hook = ip_confirm, | 523 | .hook = ip_confirm, |
524 | .owner = THIS_MODULE, | 524 | .owner = THIS_MODULE, |
525 | .pf = PF_INET, | 525 | .pf = PF_INET, |
526 | .hooknum = NF_IP_POST_ROUTING, | 526 | .hooknum = NF_IP_LOCAL_IN, |
527 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | 527 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, |
528 | }; | 528 | }, |
529 | |||
530 | static struct nf_hook_ops ip_conntrack_local_in_ops = { | ||
531 | .hook = ip_confirm, | ||
532 | .owner = THIS_MODULE, | ||
533 | .pf = PF_INET, | ||
534 | .hooknum = NF_IP_LOCAL_IN, | ||
535 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | ||
536 | }; | 529 | }; |
537 | 530 | ||
538 | /* Sysctl support */ | 531 | /* Sysctl support */ |
@@ -783,18 +776,46 @@ static ctl_table ip_ct_net_table[] = { | |||
783 | EXPORT_SYMBOL(ip_ct_log_invalid); | 776 | EXPORT_SYMBOL(ip_ct_log_invalid); |
784 | #endif /* CONFIG_SYSCTL */ | 777 | #endif /* CONFIG_SYSCTL */ |
785 | 778 | ||
786 | static int init_or_cleanup(int init) | 779 | /* FIXME: Allow NULL functions and sub in pointers to generic for |
780 | them. --RR */ | ||
781 | int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) | ||
782 | { | ||
783 | int ret = 0; | ||
784 | |||
785 | write_lock_bh(&ip_conntrack_lock); | ||
786 | if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) { | ||
787 | ret = -EBUSY; | ||
788 | goto out; | ||
789 | } | ||
790 | ip_ct_protos[proto->proto] = proto; | ||
791 | out: | ||
792 | write_unlock_bh(&ip_conntrack_lock); | ||
793 | return ret; | ||
794 | } | ||
795 | |||
796 | void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) | ||
797 | { | ||
798 | write_lock_bh(&ip_conntrack_lock); | ||
799 | ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol; | ||
800 | write_unlock_bh(&ip_conntrack_lock); | ||
801 | |||
802 | /* Somebody could be still looking at the proto in bh. */ | ||
803 | synchronize_net(); | ||
804 | |||
805 | /* Remove all contrack entries for this protocol */ | ||
806 | ip_ct_iterate_cleanup(kill_proto, &proto->proto); | ||
807 | } | ||
808 | |||
809 | static int __init ip_conntrack_standalone_init(void) | ||
787 | { | 810 | { |
788 | #ifdef CONFIG_PROC_FS | 811 | #ifdef CONFIG_PROC_FS |
789 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; | 812 | struct proc_dir_entry *proc, *proc_exp, *proc_stat; |
790 | #endif | 813 | #endif |
791 | int ret = 0; | 814 | int ret = 0; |
792 | 815 | ||
793 | if (!init) goto cleanup; | ||
794 | |||
795 | ret = ip_conntrack_init(); | 816 | ret = ip_conntrack_init(); |
796 | if (ret < 0) | 817 | if (ret < 0) |
797 | goto cleanup_nothing; | 818 | return ret; |
798 | 819 | ||
799 | #ifdef CONFIG_PROC_FS | 820 | #ifdef CONFIG_PROC_FS |
800 | ret = -ENOMEM; | 821 | ret = -ENOMEM; |
@@ -813,78 +834,25 @@ static int init_or_cleanup(int init) | |||
813 | proc_stat->owner = THIS_MODULE; | 834 | proc_stat->owner = THIS_MODULE; |
814 | #endif | 835 | #endif |
815 | 836 | ||
816 | ret = nf_register_hook(&ip_conntrack_defrag_ops); | 837 | ret = nf_register_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops)); |
817 | if (ret < 0) { | 838 | if (ret < 0) { |
818 | printk("ip_conntrack: can't register pre-routing defrag hook.\n"); | 839 | printk("ip_conntrack: can't register hooks.\n"); |
819 | goto cleanup_proc_stat; | 840 | goto cleanup_proc_stat; |
820 | } | 841 | } |
821 | ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops); | ||
822 | if (ret < 0) { | ||
823 | printk("ip_conntrack: can't register local_out defrag hook.\n"); | ||
824 | goto cleanup_defragops; | ||
825 | } | ||
826 | ret = nf_register_hook(&ip_conntrack_in_ops); | ||
827 | if (ret < 0) { | ||
828 | printk("ip_conntrack: can't register pre-routing hook.\n"); | ||
829 | goto cleanup_defraglocalops; | ||
830 | } | ||
831 | ret = nf_register_hook(&ip_conntrack_local_out_ops); | ||
832 | if (ret < 0) { | ||
833 | printk("ip_conntrack: can't register local out hook.\n"); | ||
834 | goto cleanup_inops; | ||
835 | } | ||
836 | ret = nf_register_hook(&ip_conntrack_helper_in_ops); | ||
837 | if (ret < 0) { | ||
838 | printk("ip_conntrack: can't register local in helper hook.\n"); | ||
839 | goto cleanup_inandlocalops; | ||
840 | } | ||
841 | ret = nf_register_hook(&ip_conntrack_helper_out_ops); | ||
842 | if (ret < 0) { | ||
843 | printk("ip_conntrack: can't register postrouting helper hook.\n"); | ||
844 | goto cleanup_helperinops; | ||
845 | } | ||
846 | ret = nf_register_hook(&ip_conntrack_out_ops); | ||
847 | if (ret < 0) { | ||
848 | printk("ip_conntrack: can't register post-routing hook.\n"); | ||
849 | goto cleanup_helperoutops; | ||
850 | } | ||
851 | ret = nf_register_hook(&ip_conntrack_local_in_ops); | ||
852 | if (ret < 0) { | ||
853 | printk("ip_conntrack: can't register local in hook.\n"); | ||
854 | goto cleanup_inoutandlocalops; | ||
855 | } | ||
856 | #ifdef CONFIG_SYSCTL | 842 | #ifdef CONFIG_SYSCTL |
857 | ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0); | 843 | ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0); |
858 | if (ip_ct_sysctl_header == NULL) { | 844 | if (ip_ct_sysctl_header == NULL) { |
859 | printk("ip_conntrack: can't register to sysctl.\n"); | 845 | printk("ip_conntrack: can't register to sysctl.\n"); |
860 | ret = -ENOMEM; | 846 | ret = -ENOMEM; |
861 | goto cleanup_localinops; | 847 | goto cleanup_hooks; |
862 | } | 848 | } |
863 | #endif | 849 | #endif |
864 | |||
865 | return ret; | 850 | return ret; |
866 | 851 | ||
867 | cleanup: | ||
868 | synchronize_net(); | ||
869 | #ifdef CONFIG_SYSCTL | 852 | #ifdef CONFIG_SYSCTL |
870 | unregister_sysctl_table(ip_ct_sysctl_header); | 853 | cleanup_hooks: |
871 | cleanup_localinops: | 854 | nf_unregister_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops)); |
872 | #endif | 855 | #endif |
873 | nf_unregister_hook(&ip_conntrack_local_in_ops); | ||
874 | cleanup_inoutandlocalops: | ||
875 | nf_unregister_hook(&ip_conntrack_out_ops); | ||
876 | cleanup_helperoutops: | ||
877 | nf_unregister_hook(&ip_conntrack_helper_out_ops); | ||
878 | cleanup_helperinops: | ||
879 | nf_unregister_hook(&ip_conntrack_helper_in_ops); | ||
880 | cleanup_inandlocalops: | ||
881 | nf_unregister_hook(&ip_conntrack_local_out_ops); | ||
882 | cleanup_inops: | ||
883 | nf_unregister_hook(&ip_conntrack_in_ops); | ||
884 | cleanup_defraglocalops: | ||
885 | nf_unregister_hook(&ip_conntrack_defrag_local_out_ops); | ||
886 | cleanup_defragops: | ||
887 | nf_unregister_hook(&ip_conntrack_defrag_ops); | ||
888 | cleanup_proc_stat: | 856 | cleanup_proc_stat: |
889 | #ifdef CONFIG_PROC_FS | 857 | #ifdef CONFIG_PROC_FS |
890 | remove_proc_entry("ip_conntrack", proc_net_stat); | 858 | remove_proc_entry("ip_conntrack", proc_net_stat); |
@@ -895,48 +863,22 @@ static int init_or_cleanup(int init) | |||
895 | cleanup_init: | 863 | cleanup_init: |
896 | #endif /* CONFIG_PROC_FS */ | 864 | #endif /* CONFIG_PROC_FS */ |
897 | ip_conntrack_cleanup(); | 865 | ip_conntrack_cleanup(); |
898 | cleanup_nothing: | ||
899 | return ret; | ||
900 | } | ||
901 | |||
902 | /* FIXME: Allow NULL functions and sub in pointers to generic for | ||
903 | them. --RR */ | ||
904 | int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) | ||
905 | { | ||
906 | int ret = 0; | ||
907 | |||
908 | write_lock_bh(&ip_conntrack_lock); | ||
909 | if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) { | ||
910 | ret = -EBUSY; | ||
911 | goto out; | ||
912 | } | ||
913 | ip_ct_protos[proto->proto] = proto; | ||
914 | out: | ||
915 | write_unlock_bh(&ip_conntrack_lock); | ||
916 | return ret; | 866 | return ret; |
917 | } | 867 | } |
918 | 868 | ||
919 | void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) | ||
920 | { | ||
921 | write_lock_bh(&ip_conntrack_lock); | ||
922 | ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol; | ||
923 | write_unlock_bh(&ip_conntrack_lock); | ||
924 | |||
925 | /* Somebody could be still looking at the proto in bh. */ | ||
926 | synchronize_net(); | ||
927 | |||
928 | /* Remove all contrack entries for this protocol */ | ||
929 | ip_ct_iterate_cleanup(kill_proto, &proto->proto); | ||
930 | } | ||
931 | |||
932 | static int __init ip_conntrack_standalone_init(void) | ||
933 | { | ||
934 | return init_or_cleanup(1); | ||
935 | } | ||
936 | |||
937 | static void __exit ip_conntrack_standalone_fini(void) | 869 | static void __exit ip_conntrack_standalone_fini(void) |
938 | { | 870 | { |
939 | init_or_cleanup(0); | 871 | synchronize_net(); |
872 | #ifdef CONFIG_SYSCTL | ||
873 | unregister_sysctl_table(ip_ct_sysctl_header); | ||
874 | #endif | ||
875 | nf_unregister_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops)); | ||
876 | #ifdef CONFIG_PROC_FS | ||
877 | remove_proc_entry("ip_conntrack", proc_net_stat); | ||
878 | proc_net_remove("ip_conntrack_expect"); | ||
879 | proc_net_remove("ip_conntrack"); | ||
880 | #endif /* CONFIG_PROC_FS */ | ||
881 | ip_conntrack_cleanup(); | ||
940 | } | 882 | } |
941 | 883 | ||
942 | module_init(ip_conntrack_standalone_init); | 884 | module_init(ip_conntrack_standalone_init); |
diff --git a/net/ipv4/netfilter/ip_nat_helper_h323.c b/net/ipv4/netfilter/ip_nat_helper_h323.c index a0bc883928c0..d45663d137a7 100644 --- a/net/ipv4/netfilter/ip_nat_helper_h323.c +++ b/net/ipv4/netfilter/ip_nat_helper_h323.c | |||
@@ -7,24 +7,6 @@ | |||
7 | * | 7 | * |
8 | * Based on the 'brute force' H.323 NAT module by | 8 | * Based on the 'brute force' H.323 NAT module by |
9 | * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 9 | * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> |
10 | * | ||
11 | * Changes: | ||
12 | * 2006-02-01 - initial version 0.1 | ||
13 | * | ||
14 | * 2006-02-20 - version 0.2 | ||
15 | * 1. Changed source format to follow kernel conventions | ||
16 | * 2. Deleted some unnecessary structures | ||
17 | * 3. Minor fixes | ||
18 | * | ||
19 | * 2006-03-10 - version 0.3 | ||
20 | * 1. Added support for multiple TPKTs in one packet (suggested by | ||
21 | * Patrick McHardy) | ||
22 | * 2. Added support for non-linear skb (based on Patrick McHardy's patch) | ||
23 | * 3. Eliminated unnecessary return code | ||
24 | * | ||
25 | * 2006-03-15 - version 0.4 | ||
26 | * 1. Added support for T.120 channels | ||
27 | * 2. Added parameter gkrouted_only (suggested by Patrick McHardy) | ||
28 | */ | 10 | */ |
29 | 11 | ||
30 | #include <linux/module.h> | 12 | #include <linux/module.h> |
@@ -41,65 +23,12 @@ | |||
41 | #include <linux/netfilter_ipv4/ip_conntrack_h323.h> | 23 | #include <linux/netfilter_ipv4/ip_conntrack_h323.h> |
42 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | 24 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> |
43 | 25 | ||
44 | #include "ip_conntrack_helper_h323_asn1.h" | ||
45 | |||
46 | #if 0 | 26 | #if 0 |
47 | #define DEBUGP printk | 27 | #define DEBUGP printk |
48 | #else | 28 | #else |
49 | #define DEBUGP(format, args...) | 29 | #define DEBUGP(format, args...) |
50 | #endif | 30 | #endif |
51 | 31 | ||
52 | extern int get_h245_addr(unsigned char *data, H245_TransportAddress * addr, | ||
53 | u_int32_t * ip, u_int16_t * port); | ||
54 | extern int get_h225_addr(unsigned char *data, TransportAddress * addr, | ||
55 | u_int32_t * ip, u_int16_t * port); | ||
56 | extern void ip_conntrack_h245_expect(struct ip_conntrack *new, | ||
57 | struct ip_conntrack_expect *this); | ||
58 | extern void ip_conntrack_q931_expect(struct ip_conntrack *new, | ||
59 | struct ip_conntrack_expect *this); | ||
60 | extern int (*set_h245_addr_hook) (struct sk_buff ** pskb, | ||
61 | unsigned char **data, int dataoff, | ||
62 | H245_TransportAddress * addr, | ||
63 | u_int32_t ip, u_int16_t port); | ||
64 | extern int (*set_h225_addr_hook) (struct sk_buff ** pskb, | ||
65 | unsigned char **data, int dataoff, | ||
66 | TransportAddress * addr, | ||
67 | u_int32_t ip, u_int16_t port); | ||
68 | extern int (*set_sig_addr_hook) (struct sk_buff ** pskb, | ||
69 | struct ip_conntrack * ct, | ||
70 | enum ip_conntrack_info ctinfo, | ||
71 | unsigned char **data, | ||
72 | TransportAddress * addr, int count); | ||
73 | extern int (*set_ras_addr_hook) (struct sk_buff ** pskb, | ||
74 | struct ip_conntrack * ct, | ||
75 | enum ip_conntrack_info ctinfo, | ||
76 | unsigned char **data, | ||
77 | TransportAddress * addr, int count); | ||
78 | extern int (*nat_rtp_rtcp_hook) (struct sk_buff ** pskb, | ||
79 | struct ip_conntrack * ct, | ||
80 | enum ip_conntrack_info ctinfo, | ||
81 | unsigned char **data, int dataoff, | ||
82 | H245_TransportAddress * addr, | ||
83 | u_int16_t port, u_int16_t rtp_port, | ||
84 | struct ip_conntrack_expect * rtp_exp, | ||
85 | struct ip_conntrack_expect * rtcp_exp); | ||
86 | extern int (*nat_t120_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, | ||
87 | enum ip_conntrack_info ctinfo, | ||
88 | unsigned char **data, int dataoff, | ||
89 | H245_TransportAddress * addr, u_int16_t port, | ||
90 | struct ip_conntrack_expect * exp); | ||
91 | extern int (*nat_h245_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, | ||
92 | enum ip_conntrack_info ctinfo, | ||
93 | unsigned char **data, int dataoff, | ||
94 | TransportAddress * addr, u_int16_t port, | ||
95 | struct ip_conntrack_expect * exp); | ||
96 | extern int (*nat_q931_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, | ||
97 | enum ip_conntrack_info ctinfo, | ||
98 | unsigned char **data, TransportAddress * addr, | ||
99 | int idx, u_int16_t port, | ||
100 | struct ip_conntrack_expect * exp); | ||
101 | |||
102 | |||
103 | /****************************************************************************/ | 32 | /****************************************************************************/ |
104 | static int set_addr(struct sk_buff **pskb, | 33 | static int set_addr(struct sk_buff **pskb, |
105 | unsigned char **data, int dataoff, | 34 | unsigned char **data, int dataoff, |
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index efba8c4e42e0..1aba926c1cb0 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c | |||
@@ -279,7 +279,7 @@ static struct ipt_target ipt_dnat_reg = { | |||
279 | .target = ipt_dnat_target, | 279 | .target = ipt_dnat_target, |
280 | .targetsize = sizeof(struct ip_nat_multi_range_compat), | 280 | .targetsize = sizeof(struct ip_nat_multi_range_compat), |
281 | .table = "nat", | 281 | .table = "nat", |
282 | .hooks = 1 << NF_IP_PRE_ROUTING, | 282 | .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT), |
283 | .checkentry = ipt_dnat_checkentry, | 283 | .checkentry = ipt_dnat_checkentry, |
284 | }; | 284 | }; |
285 | 285 | ||
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 3505b0de2e04..8f760b28617e 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -299,69 +299,63 @@ ip_nat_adjust(unsigned int hooknum, | |||
299 | 299 | ||
300 | /* We must be after connection tracking and before packet filtering. */ | 300 | /* We must be after connection tracking and before packet filtering. */ |
301 | 301 | ||
302 | /* Before packet filtering, change destination */ | 302 | static struct nf_hook_ops ip_nat_ops[] = { |
303 | static struct nf_hook_ops ip_nat_in_ops = { | 303 | /* Before packet filtering, change destination */ |
304 | .hook = ip_nat_in, | 304 | { |
305 | .owner = THIS_MODULE, | 305 | .hook = ip_nat_in, |
306 | .pf = PF_INET, | 306 | .owner = THIS_MODULE, |
307 | .hooknum = NF_IP_PRE_ROUTING, | 307 | .pf = PF_INET, |
308 | .priority = NF_IP_PRI_NAT_DST, | 308 | .hooknum = NF_IP_PRE_ROUTING, |
309 | .priority = NF_IP_PRI_NAT_DST, | ||
310 | }, | ||
311 | /* After packet filtering, change source */ | ||
312 | { | ||
313 | .hook = ip_nat_out, | ||
314 | .owner = THIS_MODULE, | ||
315 | .pf = PF_INET, | ||
316 | .hooknum = NF_IP_POST_ROUTING, | ||
317 | .priority = NF_IP_PRI_NAT_SRC, | ||
318 | }, | ||
319 | /* After conntrack, adjust sequence number */ | ||
320 | { | ||
321 | .hook = ip_nat_adjust, | ||
322 | .owner = THIS_MODULE, | ||
323 | .pf = PF_INET, | ||
324 | .hooknum = NF_IP_POST_ROUTING, | ||
325 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
326 | }, | ||
327 | /* Before packet filtering, change destination */ | ||
328 | { | ||
329 | .hook = ip_nat_local_fn, | ||
330 | .owner = THIS_MODULE, | ||
331 | .pf = PF_INET, | ||
332 | .hooknum = NF_IP_LOCAL_OUT, | ||
333 | .priority = NF_IP_PRI_NAT_DST, | ||
334 | }, | ||
335 | /* After packet filtering, change source */ | ||
336 | { | ||
337 | .hook = ip_nat_fn, | ||
338 | .owner = THIS_MODULE, | ||
339 | .pf = PF_INET, | ||
340 | .hooknum = NF_IP_LOCAL_IN, | ||
341 | .priority = NF_IP_PRI_NAT_SRC, | ||
342 | }, | ||
343 | /* After conntrack, adjust sequence number */ | ||
344 | { | ||
345 | .hook = ip_nat_adjust, | ||
346 | .owner = THIS_MODULE, | ||
347 | .pf = PF_INET, | ||
348 | .hooknum = NF_IP_LOCAL_IN, | ||
349 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
350 | }, | ||
309 | }; | 351 | }; |
310 | 352 | ||
311 | /* After packet filtering, change source */ | 353 | static int __init ip_nat_standalone_init(void) |
312 | static struct nf_hook_ops ip_nat_out_ops = { | ||
313 | .hook = ip_nat_out, | ||
314 | .owner = THIS_MODULE, | ||
315 | .pf = PF_INET, | ||
316 | .hooknum = NF_IP_POST_ROUTING, | ||
317 | .priority = NF_IP_PRI_NAT_SRC, | ||
318 | }; | ||
319 | |||
320 | /* After conntrack, adjust sequence number */ | ||
321 | static struct nf_hook_ops ip_nat_adjust_out_ops = { | ||
322 | .hook = ip_nat_adjust, | ||
323 | .owner = THIS_MODULE, | ||
324 | .pf = PF_INET, | ||
325 | .hooknum = NF_IP_POST_ROUTING, | ||
326 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
327 | }; | ||
328 | |||
329 | /* Before packet filtering, change destination */ | ||
330 | static struct nf_hook_ops ip_nat_local_out_ops = { | ||
331 | .hook = ip_nat_local_fn, | ||
332 | .owner = THIS_MODULE, | ||
333 | .pf = PF_INET, | ||
334 | .hooknum = NF_IP_LOCAL_OUT, | ||
335 | .priority = NF_IP_PRI_NAT_DST, | ||
336 | }; | ||
337 | |||
338 | /* After packet filtering, change source for reply packets of LOCAL_OUT DNAT */ | ||
339 | static struct nf_hook_ops ip_nat_local_in_ops = { | ||
340 | .hook = ip_nat_fn, | ||
341 | .owner = THIS_MODULE, | ||
342 | .pf = PF_INET, | ||
343 | .hooknum = NF_IP_LOCAL_IN, | ||
344 | .priority = NF_IP_PRI_NAT_SRC, | ||
345 | }; | ||
346 | |||
347 | /* After conntrack, adjust sequence number */ | ||
348 | static struct nf_hook_ops ip_nat_adjust_in_ops = { | ||
349 | .hook = ip_nat_adjust, | ||
350 | .owner = THIS_MODULE, | ||
351 | .pf = PF_INET, | ||
352 | .hooknum = NF_IP_LOCAL_IN, | ||
353 | .priority = NF_IP_PRI_NAT_SEQ_ADJUST, | ||
354 | }; | ||
355 | |||
356 | |||
357 | static int init_or_cleanup(int init) | ||
358 | { | 354 | { |
359 | int ret = 0; | 355 | int ret = 0; |
360 | 356 | ||
361 | need_conntrack(); | 357 | need_conntrack(); |
362 | 358 | ||
363 | if (!init) goto cleanup; | ||
364 | |||
365 | #ifdef CONFIG_XFRM | 359 | #ifdef CONFIG_XFRM |
366 | BUG_ON(ip_nat_decode_session != NULL); | 360 | BUG_ON(ip_nat_decode_session != NULL); |
367 | ip_nat_decode_session = nat_decode_session; | 361 | ip_nat_decode_session = nat_decode_session; |
@@ -371,50 +365,13 @@ static int init_or_cleanup(int init) | |||
371 | printk("ip_nat_init: can't setup rules.\n"); | 365 | printk("ip_nat_init: can't setup rules.\n"); |
372 | goto cleanup_decode_session; | 366 | goto cleanup_decode_session; |
373 | } | 367 | } |
374 | ret = nf_register_hook(&ip_nat_in_ops); | 368 | ret = nf_register_hooks(ip_nat_ops, ARRAY_SIZE(ip_nat_ops)); |
375 | if (ret < 0) { | 369 | if (ret < 0) { |
376 | printk("ip_nat_init: can't register in hook.\n"); | 370 | printk("ip_nat_init: can't register hooks.\n"); |
377 | goto cleanup_rule_init; | 371 | goto cleanup_rule_init; |
378 | } | 372 | } |
379 | ret = nf_register_hook(&ip_nat_out_ops); | ||
380 | if (ret < 0) { | ||
381 | printk("ip_nat_init: can't register out hook.\n"); | ||
382 | goto cleanup_inops; | ||
383 | } | ||
384 | ret = nf_register_hook(&ip_nat_adjust_in_ops); | ||
385 | if (ret < 0) { | ||
386 | printk("ip_nat_init: can't register adjust in hook.\n"); | ||
387 | goto cleanup_outops; | ||
388 | } | ||
389 | ret = nf_register_hook(&ip_nat_adjust_out_ops); | ||
390 | if (ret < 0) { | ||
391 | printk("ip_nat_init: can't register adjust out hook.\n"); | ||
392 | goto cleanup_adjustin_ops; | ||
393 | } | ||
394 | ret = nf_register_hook(&ip_nat_local_out_ops); | ||
395 | if (ret < 0) { | ||
396 | printk("ip_nat_init: can't register local out hook.\n"); | ||
397 | goto cleanup_adjustout_ops; | ||
398 | } | ||
399 | ret = nf_register_hook(&ip_nat_local_in_ops); | ||
400 | if (ret < 0) { | ||
401 | printk("ip_nat_init: can't register local in hook.\n"); | ||
402 | goto cleanup_localoutops; | ||
403 | } | ||
404 | return ret; | 373 | return ret; |
405 | 374 | ||
406 | cleanup: | ||
407 | nf_unregister_hook(&ip_nat_local_in_ops); | ||
408 | cleanup_localoutops: | ||
409 | nf_unregister_hook(&ip_nat_local_out_ops); | ||
410 | cleanup_adjustout_ops: | ||
411 | nf_unregister_hook(&ip_nat_adjust_out_ops); | ||
412 | cleanup_adjustin_ops: | ||
413 | nf_unregister_hook(&ip_nat_adjust_in_ops); | ||
414 | cleanup_outops: | ||
415 | nf_unregister_hook(&ip_nat_out_ops); | ||
416 | cleanup_inops: | ||
417 | nf_unregister_hook(&ip_nat_in_ops); | ||
418 | cleanup_rule_init: | 375 | cleanup_rule_init: |
419 | ip_nat_rule_cleanup(); | 376 | ip_nat_rule_cleanup(); |
420 | cleanup_decode_session: | 377 | cleanup_decode_session: |
@@ -425,14 +382,14 @@ static int init_or_cleanup(int init) | |||
425 | return ret; | 382 | return ret; |
426 | } | 383 | } |
427 | 384 | ||
428 | static int __init ip_nat_standalone_init(void) | ||
429 | { | ||
430 | return init_or_cleanup(1); | ||
431 | } | ||
432 | |||
433 | static void __exit ip_nat_standalone_fini(void) | 385 | static void __exit ip_nat_standalone_fini(void) |
434 | { | 386 | { |
435 | init_or_cleanup(0); | 387 | nf_unregister_hooks(ip_nat_ops, ARRAY_SIZE(ip_nat_ops)); |
388 | ip_nat_rule_cleanup(); | ||
389 | #ifdef CONFIG_XFRM | ||
390 | ip_nat_decode_session = NULL; | ||
391 | synchronize_net(); | ||
392 | #endif | ||
436 | } | 393 | } |
437 | 394 | ||
438 | module_init(ip_nat_standalone_init); | 395 | module_init(ip_nat_standalone_init); |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 896a244f8f91..b93f0494362f 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -662,15 +662,11 @@ static struct nf_queue_handler nfqh = { | |||
662 | .outfn = &ipq_enqueue_packet, | 662 | .outfn = &ipq_enqueue_packet, |
663 | }; | 663 | }; |
664 | 664 | ||
665 | static int | 665 | static int __init ip_queue_init(void) |
666 | init_or_cleanup(int init) | ||
667 | { | 666 | { |
668 | int status = -ENOMEM; | 667 | int status = -ENOMEM; |
669 | struct proc_dir_entry *proc; | 668 | struct proc_dir_entry *proc; |
670 | 669 | ||
671 | if (!init) | ||
672 | goto cleanup; | ||
673 | |||
674 | netlink_register_notifier(&ipq_nl_notifier); | 670 | netlink_register_notifier(&ipq_nl_notifier); |
675 | ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk, | 671 | ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk, |
676 | THIS_MODULE); | 672 | THIS_MODULE); |
@@ -697,11 +693,6 @@ init_or_cleanup(int init) | |||
697 | } | 693 | } |
698 | return status; | 694 | return status; |
699 | 695 | ||
700 | cleanup: | ||
701 | nf_unregister_queue_handlers(&nfqh); | ||
702 | synchronize_net(); | ||
703 | ipq_flush(NF_DROP); | ||
704 | |||
705 | cleanup_sysctl: | 696 | cleanup_sysctl: |
706 | unregister_sysctl_table(ipq_sysctl_header); | 697 | unregister_sysctl_table(ipq_sysctl_header); |
707 | unregister_netdevice_notifier(&ipq_dev_notifier); | 698 | unregister_netdevice_notifier(&ipq_dev_notifier); |
@@ -717,15 +708,21 @@ cleanup_netlink_notifier: | |||
717 | return status; | 708 | return status; |
718 | } | 709 | } |
719 | 710 | ||
720 | static int __init ip_queue_init(void) | ||
721 | { | ||
722 | |||
723 | return init_or_cleanup(1); | ||
724 | } | ||
725 | |||
726 | static void __exit ip_queue_fini(void) | 711 | static void __exit ip_queue_fini(void) |
727 | { | 712 | { |
728 | init_or_cleanup(0); | 713 | nf_unregister_queue_handlers(&nfqh); |
714 | synchronize_net(); | ||
715 | ipq_flush(NF_DROP); | ||
716 | |||
717 | unregister_sysctl_table(ipq_sysctl_header); | ||
718 | unregister_netdevice_notifier(&ipq_dev_notifier); | ||
719 | proc_net_remove(IPQ_PROC_FS_NAME); | ||
720 | |||
721 | sock_release(ipqnl->sk_socket); | ||
722 | mutex_lock(&ipqnl_mutex); | ||
723 | mutex_unlock(&ipqnl_mutex); | ||
724 | |||
725 | netlink_unregister_notifier(&ipq_nl_notifier); | ||
729 | } | 726 | } |
730 | 727 | ||
731 | MODULE_DESCRIPTION("IPv4 packet queue handler"); | 728 | MODULE_DESCRIPTION("IPv4 packet queue handler"); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 460fd905fad0..d25ac8ba6eba 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/icmp.h> | 25 | #include <linux/icmp.h> |
26 | #include <net/ip.h> | 26 | #include <net/ip.h> |
27 | #include <net/compat.h> | ||
27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
28 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
29 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
@@ -734,7 +735,7 @@ translate_table(const char *name, | |||
734 | } | 735 | } |
735 | 736 | ||
736 | /* And one copy for every other CPU */ | 737 | /* And one copy for every other CPU */ |
737 | for_each_cpu(i) { | 738 | for_each_possible_cpu(i) { |
738 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) | 739 | if (newinfo->entries[i] && newinfo->entries[i] != entry0) |
739 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 740 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
740 | } | 741 | } |
@@ -787,7 +788,7 @@ get_counters(const struct xt_table_info *t, | |||
787 | counters, | 788 | counters, |
788 | &i); | 789 | &i); |
789 | 790 | ||
790 | for_each_cpu(cpu) { | 791 | for_each_possible_cpu(cpu) { |
791 | if (cpu == curcpu) | 792 | if (cpu == curcpu) |
792 | continue; | 793 | continue; |
793 | i = 0; | 794 | i = 0; |
@@ -799,17 +800,11 @@ get_counters(const struct xt_table_info *t, | |||
799 | } | 800 | } |
800 | } | 801 | } |
801 | 802 | ||
802 | static int | 803 | static inline struct xt_counters * alloc_counters(struct ipt_table *table) |
803 | copy_entries_to_user(unsigned int total_size, | ||
804 | struct ipt_table *table, | ||
805 | void __user *userptr) | ||
806 | { | 804 | { |
807 | unsigned int off, num, countersize; | 805 | unsigned int countersize; |
808 | struct ipt_entry *e; | ||
809 | struct xt_counters *counters; | 806 | struct xt_counters *counters; |
810 | struct xt_table_info *private = table->private; | 807 | struct xt_table_info *private = table->private; |
811 | int ret = 0; | ||
812 | void *loc_cpu_entry; | ||
813 | 808 | ||
814 | /* We need atomic snapshot of counters: rest doesn't change | 809 | /* We need atomic snapshot of counters: rest doesn't change |
815 | (other than comefrom, which userspace doesn't care | 810 | (other than comefrom, which userspace doesn't care |
@@ -818,13 +813,32 @@ copy_entries_to_user(unsigned int total_size, | |||
818 | counters = vmalloc_node(countersize, numa_node_id()); | 813 | counters = vmalloc_node(countersize, numa_node_id()); |
819 | 814 | ||
820 | if (counters == NULL) | 815 | if (counters == NULL) |
821 | return -ENOMEM; | 816 | return ERR_PTR(-ENOMEM); |
822 | 817 | ||
823 | /* First, sum counters... */ | 818 | /* First, sum counters... */ |
824 | write_lock_bh(&table->lock); | 819 | write_lock_bh(&table->lock); |
825 | get_counters(private, counters); | 820 | get_counters(private, counters); |
826 | write_unlock_bh(&table->lock); | 821 | write_unlock_bh(&table->lock); |
827 | 822 | ||
823 | return counters; | ||
824 | } | ||
825 | |||
826 | static int | ||
827 | copy_entries_to_user(unsigned int total_size, | ||
828 | struct ipt_table *table, | ||
829 | void __user *userptr) | ||
830 | { | ||
831 | unsigned int off, num; | ||
832 | struct ipt_entry *e; | ||
833 | struct xt_counters *counters; | ||
834 | struct xt_table_info *private = table->private; | ||
835 | int ret = 0; | ||
836 | void *loc_cpu_entry; | ||
837 | |||
838 | counters = alloc_counters(table); | ||
839 | if (IS_ERR(counters)) | ||
840 | return PTR_ERR(counters); | ||
841 | |||
828 | /* choose the copy that is on our node/cpu, ... | 842 | /* choose the copy that is on our node/cpu, ... |
829 | * This choice is lazy (because current thread is | 843 | * This choice is lazy (because current thread is |
830 | * allowed to migrate to another cpu) | 844 | * allowed to migrate to another cpu) |
@@ -884,25 +898,278 @@ copy_entries_to_user(unsigned int total_size, | |||
884 | return ret; | 898 | return ret; |
885 | } | 899 | } |
886 | 900 | ||
901 | #ifdef CONFIG_COMPAT | ||
902 | struct compat_delta { | ||
903 | struct compat_delta *next; | ||
904 | u_int16_t offset; | ||
905 | short delta; | ||
906 | }; | ||
907 | |||
908 | static struct compat_delta *compat_offsets = NULL; | ||
909 | |||
910 | static int compat_add_offset(u_int16_t offset, short delta) | ||
911 | { | ||
912 | struct compat_delta *tmp; | ||
913 | |||
914 | tmp = kmalloc(sizeof(struct compat_delta), GFP_KERNEL); | ||
915 | if (!tmp) | ||
916 | return -ENOMEM; | ||
917 | tmp->offset = offset; | ||
918 | tmp->delta = delta; | ||
919 | if (compat_offsets) { | ||
920 | tmp->next = compat_offsets->next; | ||
921 | compat_offsets->next = tmp; | ||
922 | } else { | ||
923 | compat_offsets = tmp; | ||
924 | tmp->next = NULL; | ||
925 | } | ||
926 | return 0; | ||
927 | } | ||
928 | |||
929 | static void compat_flush_offsets(void) | ||
930 | { | ||
931 | struct compat_delta *tmp, *next; | ||
932 | |||
933 | if (compat_offsets) { | ||
934 | for(tmp = compat_offsets; tmp; tmp = next) { | ||
935 | next = tmp->next; | ||
936 | kfree(tmp); | ||
937 | } | ||
938 | compat_offsets = NULL; | ||
939 | } | ||
940 | } | ||
941 | |||
942 | static short compat_calc_jump(u_int16_t offset) | ||
943 | { | ||
944 | struct compat_delta *tmp; | ||
945 | short delta; | ||
946 | |||
947 | for(tmp = compat_offsets, delta = 0; tmp; tmp = tmp->next) | ||
948 | if (tmp->offset < offset) | ||
949 | delta += tmp->delta; | ||
950 | return delta; | ||
951 | } | ||
952 | |||
953 | struct compat_ipt_standard_target | ||
954 | { | ||
955 | struct compat_xt_entry_target target; | ||
956 | compat_int_t verdict; | ||
957 | }; | ||
958 | |||
959 | #define IPT_ST_OFFSET (sizeof(struct ipt_standard_target) - \ | ||
960 | sizeof(struct compat_ipt_standard_target)) | ||
961 | |||
962 | struct compat_ipt_standard | ||
963 | { | ||
964 | struct compat_ipt_entry entry; | ||
965 | struct compat_ipt_standard_target target; | ||
966 | }; | ||
967 | |||
968 | static int compat_ipt_standard_fn(void *target, | ||
969 | void **dstptr, int *size, int convert) | ||
970 | { | ||
971 | struct compat_ipt_standard_target compat_st, *pcompat_st; | ||
972 | struct ipt_standard_target st, *pst; | ||
973 | int ret; | ||
974 | |||
975 | ret = 0; | ||
976 | switch (convert) { | ||
977 | case COMPAT_TO_USER: | ||
978 | pst = (struct ipt_standard_target *)target; | ||
979 | memcpy(&compat_st.target, &pst->target, | ||
980 | sizeof(struct ipt_entry_target)); | ||
981 | compat_st.verdict = pst->verdict; | ||
982 | if (compat_st.verdict > 0) | ||
983 | compat_st.verdict -= | ||
984 | compat_calc_jump(compat_st.verdict); | ||
985 | compat_st.target.u.user.target_size = | ||
986 | sizeof(struct compat_ipt_standard_target); | ||
987 | if (__copy_to_user(*dstptr, &compat_st, | ||
988 | sizeof(struct compat_ipt_standard_target))) | ||
989 | ret = -EFAULT; | ||
990 | *size -= IPT_ST_OFFSET; | ||
991 | *dstptr += sizeof(struct compat_ipt_standard_target); | ||
992 | break; | ||
993 | case COMPAT_FROM_USER: | ||
994 | pcompat_st = | ||
995 | (struct compat_ipt_standard_target *)target; | ||
996 | memcpy(&st.target, &pcompat_st->target, | ||
997 | sizeof(struct ipt_entry_target)); | ||
998 | st.verdict = pcompat_st->verdict; | ||
999 | if (st.verdict > 0) | ||
1000 | st.verdict += compat_calc_jump(st.verdict); | ||
1001 | st.target.u.user.target_size = | ||
1002 | sizeof(struct ipt_standard_target); | ||
1003 | memcpy(*dstptr, &st, | ||
1004 | sizeof(struct ipt_standard_target)); | ||
1005 | *size += IPT_ST_OFFSET; | ||
1006 | *dstptr += sizeof(struct ipt_standard_target); | ||
1007 | break; | ||
1008 | case COMPAT_CALC_SIZE: | ||
1009 | *size += IPT_ST_OFFSET; | ||
1010 | break; | ||
1011 | default: | ||
1012 | ret = -ENOPROTOOPT; | ||
1013 | break; | ||
1014 | } | ||
1015 | return ret; | ||
1016 | } | ||
1017 | |||
1018 | static inline int | ||
1019 | compat_calc_match(struct ipt_entry_match *m, int * size) | ||
1020 | { | ||
1021 | if (m->u.kernel.match->compat) | ||
1022 | m->u.kernel.match->compat(m, NULL, size, COMPAT_CALC_SIZE); | ||
1023 | else | ||
1024 | xt_compat_match(m, NULL, size, COMPAT_CALC_SIZE); | ||
1025 | return 0; | ||
1026 | } | ||
1027 | |||
1028 | static int compat_calc_entry(struct ipt_entry *e, struct xt_table_info *info, | ||
1029 | void *base, struct xt_table_info *newinfo) | ||
1030 | { | ||
1031 | struct ipt_entry_target *t; | ||
1032 | u_int16_t entry_offset; | ||
1033 | int off, i, ret; | ||
1034 | |||
1035 | off = 0; | ||
1036 | entry_offset = (void *)e - base; | ||
1037 | IPT_MATCH_ITERATE(e, compat_calc_match, &off); | ||
1038 | t = ipt_get_target(e); | ||
1039 | if (t->u.kernel.target->compat) | ||
1040 | t->u.kernel.target->compat(t, NULL, &off, COMPAT_CALC_SIZE); | ||
1041 | else | ||
1042 | xt_compat_target(t, NULL, &off, COMPAT_CALC_SIZE); | ||
1043 | newinfo->size -= off; | ||
1044 | ret = compat_add_offset(entry_offset, off); | ||
1045 | if (ret) | ||
1046 | return ret; | ||
1047 | |||
1048 | for (i = 0; i< NF_IP_NUMHOOKS; i++) { | ||
1049 | if (info->hook_entry[i] && (e < (struct ipt_entry *) | ||
1050 | (base + info->hook_entry[i]))) | ||
1051 | newinfo->hook_entry[i] -= off; | ||
1052 | if (info->underflow[i] && (e < (struct ipt_entry *) | ||
1053 | (base + info->underflow[i]))) | ||
1054 | newinfo->underflow[i] -= off; | ||
1055 | } | ||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | static int compat_table_info(struct xt_table_info *info, | ||
1060 | struct xt_table_info *newinfo) | ||
1061 | { | ||
1062 | void *loc_cpu_entry; | ||
1063 | int i; | ||
1064 | |||
1065 | if (!newinfo || !info) | ||
1066 | return -EINVAL; | ||
1067 | |||
1068 | memset(newinfo, 0, sizeof(struct xt_table_info)); | ||
1069 | newinfo->size = info->size; | ||
1070 | newinfo->number = info->number; | ||
1071 | for (i = 0; i < NF_IP_NUMHOOKS; i++) { | ||
1072 | newinfo->hook_entry[i] = info->hook_entry[i]; | ||
1073 | newinfo->underflow[i] = info->underflow[i]; | ||
1074 | } | ||
1075 | loc_cpu_entry = info->entries[raw_smp_processor_id()]; | ||
1076 | return IPT_ENTRY_ITERATE(loc_cpu_entry, info->size, | ||
1077 | compat_calc_entry, info, loc_cpu_entry, newinfo); | ||
1078 | } | ||
1079 | #endif | ||
1080 | |||
1081 | static int get_info(void __user *user, int *len, int compat) | ||
1082 | { | ||
1083 | char name[IPT_TABLE_MAXNAMELEN]; | ||
1084 | struct ipt_table *t; | ||
1085 | int ret; | ||
1086 | |||
1087 | if (*len != sizeof(struct ipt_getinfo)) { | ||
1088 | duprintf("length %u != %u\n", *len, | ||
1089 | (unsigned int)sizeof(struct ipt_getinfo)); | ||
1090 | return -EINVAL; | ||
1091 | } | ||
1092 | |||
1093 | if (copy_from_user(name, user, sizeof(name)) != 0) | ||
1094 | return -EFAULT; | ||
1095 | |||
1096 | name[IPT_TABLE_MAXNAMELEN-1] = '\0'; | ||
1097 | #ifdef CONFIG_COMPAT | ||
1098 | if (compat) | ||
1099 | xt_compat_lock(AF_INET); | ||
1100 | #endif | ||
1101 | t = try_then_request_module(xt_find_table_lock(AF_INET, name), | ||
1102 | "iptable_%s", name); | ||
1103 | if (t && !IS_ERR(t)) { | ||
1104 | struct ipt_getinfo info; | ||
1105 | struct xt_table_info *private = t->private; | ||
1106 | |||
1107 | #ifdef CONFIG_COMPAT | ||
1108 | if (compat) { | ||
1109 | struct xt_table_info tmp; | ||
1110 | ret = compat_table_info(private, &tmp); | ||
1111 | compat_flush_offsets(); | ||
1112 | private = &tmp; | ||
1113 | } | ||
1114 | #endif | ||
1115 | info.valid_hooks = t->valid_hooks; | ||
1116 | memcpy(info.hook_entry, private->hook_entry, | ||
1117 | sizeof(info.hook_entry)); | ||
1118 | memcpy(info.underflow, private->underflow, | ||
1119 | sizeof(info.underflow)); | ||
1120 | info.num_entries = private->number; | ||
1121 | info.size = private->size; | ||
1122 | strcpy(info.name, name); | ||
1123 | |||
1124 | if (copy_to_user(user, &info, *len) != 0) | ||
1125 | ret = -EFAULT; | ||
1126 | else | ||
1127 | ret = 0; | ||
1128 | |||
1129 | xt_table_unlock(t); | ||
1130 | module_put(t->me); | ||
1131 | } else | ||
1132 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
1133 | #ifdef CONFIG_COMPAT | ||
1134 | if (compat) | ||
1135 | xt_compat_unlock(AF_INET); | ||
1136 | #endif | ||
1137 | return ret; | ||
1138 | } | ||
1139 | |||
887 | static int | 1140 | static int |
888 | get_entries(const struct ipt_get_entries *entries, | 1141 | get_entries(struct ipt_get_entries __user *uptr, int *len) |
889 | struct ipt_get_entries __user *uptr) | ||
890 | { | 1142 | { |
891 | int ret; | 1143 | int ret; |
1144 | struct ipt_get_entries get; | ||
892 | struct ipt_table *t; | 1145 | struct ipt_table *t; |
893 | 1146 | ||
894 | t = xt_find_table_lock(AF_INET, entries->name); | 1147 | if (*len < sizeof(get)) { |
1148 | duprintf("get_entries: %u < %d\n", *len, | ||
1149 | (unsigned int)sizeof(get)); | ||
1150 | return -EINVAL; | ||
1151 | } | ||
1152 | if (copy_from_user(&get, uptr, sizeof(get)) != 0) | ||
1153 | return -EFAULT; | ||
1154 | if (*len != sizeof(struct ipt_get_entries) + get.size) { | ||
1155 | duprintf("get_entries: %u != %u\n", *len, | ||
1156 | (unsigned int)(sizeof(struct ipt_get_entries) + | ||
1157 | get.size)); | ||
1158 | return -EINVAL; | ||
1159 | } | ||
1160 | |||
1161 | t = xt_find_table_lock(AF_INET, get.name); | ||
895 | if (t && !IS_ERR(t)) { | 1162 | if (t && !IS_ERR(t)) { |
896 | struct xt_table_info *private = t->private; | 1163 | struct xt_table_info *private = t->private; |
897 | duprintf("t->private->number = %u\n", | 1164 | duprintf("t->private->number = %u\n", |
898 | private->number); | 1165 | private->number); |
899 | if (entries->size == private->size) | 1166 | if (get.size == private->size) |
900 | ret = copy_entries_to_user(private->size, | 1167 | ret = copy_entries_to_user(private->size, |
901 | t, uptr->entrytable); | 1168 | t, uptr->entrytable); |
902 | else { | 1169 | else { |
903 | duprintf("get_entries: I've got %u not %u!\n", | 1170 | duprintf("get_entries: I've got %u not %u!\n", |
904 | private->size, | 1171 | private->size, |
905 | entries->size); | 1172 | get.size); |
906 | ret = -EINVAL; | 1173 | ret = -EINVAL; |
907 | } | 1174 | } |
908 | module_put(t->me); | 1175 | module_put(t->me); |
@@ -914,79 +1181,47 @@ get_entries(const struct ipt_get_entries *entries, | |||
914 | } | 1181 | } |
915 | 1182 | ||
916 | static int | 1183 | static int |
917 | do_replace(void __user *user, unsigned int len) | 1184 | __do_replace(const char *name, unsigned int valid_hooks, |
1185 | struct xt_table_info *newinfo, unsigned int num_counters, | ||
1186 | void __user *counters_ptr) | ||
918 | { | 1187 | { |
919 | int ret; | 1188 | int ret; |
920 | struct ipt_replace tmp; | ||
921 | struct ipt_table *t; | 1189 | struct ipt_table *t; |
922 | struct xt_table_info *newinfo, *oldinfo; | 1190 | struct xt_table_info *oldinfo; |
923 | struct xt_counters *counters; | 1191 | struct xt_counters *counters; |
924 | void *loc_cpu_entry, *loc_cpu_old_entry; | 1192 | void *loc_cpu_old_entry; |
925 | 1193 | ||
926 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1194 | ret = 0; |
927 | return -EFAULT; | 1195 | counters = vmalloc(num_counters * sizeof(struct xt_counters)); |
928 | |||
929 | /* Hack: Causes ipchains to give correct error msg --RR */ | ||
930 | if (len != sizeof(tmp) + tmp.size) | ||
931 | return -ENOPROTOOPT; | ||
932 | |||
933 | /* overflow check */ | ||
934 | if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - | ||
935 | SMP_CACHE_BYTES) | ||
936 | return -ENOMEM; | ||
937 | if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) | ||
938 | return -ENOMEM; | ||
939 | |||
940 | newinfo = xt_alloc_table_info(tmp.size); | ||
941 | if (!newinfo) | ||
942 | return -ENOMEM; | ||
943 | |||
944 | /* choose the copy that is our node/cpu */ | ||
945 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | ||
946 | if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), | ||
947 | tmp.size) != 0) { | ||
948 | ret = -EFAULT; | ||
949 | goto free_newinfo; | ||
950 | } | ||
951 | |||
952 | counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters)); | ||
953 | if (!counters) { | 1196 | if (!counters) { |
954 | ret = -ENOMEM; | 1197 | ret = -ENOMEM; |
955 | goto free_newinfo; | 1198 | goto out; |
956 | } | 1199 | } |
957 | 1200 | ||
958 | ret = translate_table(tmp.name, tmp.valid_hooks, | 1201 | t = try_then_request_module(xt_find_table_lock(AF_INET, name), |
959 | newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, | 1202 | "iptable_%s", name); |
960 | tmp.hook_entry, tmp.underflow); | ||
961 | if (ret != 0) | ||
962 | goto free_newinfo_counters; | ||
963 | |||
964 | duprintf("ip_tables: Translated table\n"); | ||
965 | |||
966 | t = try_then_request_module(xt_find_table_lock(AF_INET, tmp.name), | ||
967 | "iptable_%s", tmp.name); | ||
968 | if (!t || IS_ERR(t)) { | 1203 | if (!t || IS_ERR(t)) { |
969 | ret = t ? PTR_ERR(t) : -ENOENT; | 1204 | ret = t ? PTR_ERR(t) : -ENOENT; |
970 | goto free_newinfo_counters_untrans; | 1205 | goto free_newinfo_counters_untrans; |
971 | } | 1206 | } |
972 | 1207 | ||
973 | /* You lied! */ | 1208 | /* You lied! */ |
974 | if (tmp.valid_hooks != t->valid_hooks) { | 1209 | if (valid_hooks != t->valid_hooks) { |
975 | duprintf("Valid hook crap: %08X vs %08X\n", | 1210 | duprintf("Valid hook crap: %08X vs %08X\n", |
976 | tmp.valid_hooks, t->valid_hooks); | 1211 | valid_hooks, t->valid_hooks); |
977 | ret = -EINVAL; | 1212 | ret = -EINVAL; |
978 | goto put_module; | 1213 | goto put_module; |
979 | } | 1214 | } |
980 | 1215 | ||
981 | oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret); | 1216 | oldinfo = xt_replace_table(t, num_counters, newinfo, &ret); |
982 | if (!oldinfo) | 1217 | if (!oldinfo) |
983 | goto put_module; | 1218 | goto put_module; |
984 | 1219 | ||
985 | /* Update module usage count based on number of rules */ | 1220 | /* Update module usage count based on number of rules */ |
986 | duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n", | 1221 | duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n", |
987 | oldinfo->number, oldinfo->initial_entries, newinfo->number); | 1222 | oldinfo->number, oldinfo->initial_entries, newinfo->number); |
988 | if ((oldinfo->number > oldinfo->initial_entries) || | 1223 | if ((oldinfo->number > oldinfo->initial_entries) || |
989 | (newinfo->number <= oldinfo->initial_entries)) | 1224 | (newinfo->number <= oldinfo->initial_entries)) |
990 | module_put(t->me); | 1225 | module_put(t->me); |
991 | if ((oldinfo->number > oldinfo->initial_entries) && | 1226 | if ((oldinfo->number > oldinfo->initial_entries) && |
992 | (newinfo->number <= oldinfo->initial_entries)) | 1227 | (newinfo->number <= oldinfo->initial_entries)) |
@@ -998,8 +1233,8 @@ do_replace(void __user *user, unsigned int len) | |||
998 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; | 1233 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
999 | IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); | 1234 | IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL); |
1000 | xt_free_table_info(oldinfo); | 1235 | xt_free_table_info(oldinfo); |
1001 | if (copy_to_user(tmp.counters, counters, | 1236 | if (copy_to_user(counters_ptr, counters, |
1002 | sizeof(struct xt_counters) * tmp.num_counters) != 0) | 1237 | sizeof(struct xt_counters) * num_counters) != 0) |
1003 | ret = -EFAULT; | 1238 | ret = -EFAULT; |
1004 | vfree(counters); | 1239 | vfree(counters); |
1005 | xt_table_unlock(t); | 1240 | xt_table_unlock(t); |
@@ -1009,9 +1244,62 @@ do_replace(void __user *user, unsigned int len) | |||
1009 | module_put(t->me); | 1244 | module_put(t->me); |
1010 | xt_table_unlock(t); | 1245 | xt_table_unlock(t); |
1011 | free_newinfo_counters_untrans: | 1246 | free_newinfo_counters_untrans: |
1012 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); | ||
1013 | free_newinfo_counters: | ||
1014 | vfree(counters); | 1247 | vfree(counters); |
1248 | out: | ||
1249 | return ret; | ||
1250 | } | ||
1251 | |||
1252 | static int | ||
1253 | do_replace(void __user *user, unsigned int len) | ||
1254 | { | ||
1255 | int ret; | ||
1256 | struct ipt_replace tmp; | ||
1257 | struct xt_table_info *newinfo; | ||
1258 | void *loc_cpu_entry; | ||
1259 | |||
1260 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | ||
1261 | return -EFAULT; | ||
1262 | |||
1263 | /* Hack: Causes ipchains to give correct error msg --RR */ | ||
1264 | if (len != sizeof(tmp) + tmp.size) | ||
1265 | return -ENOPROTOOPT; | ||
1266 | |||
1267 | /* overflow check */ | ||
1268 | if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - | ||
1269 | SMP_CACHE_BYTES) | ||
1270 | return -ENOMEM; | ||
1271 | if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) | ||
1272 | return -ENOMEM; | ||
1273 | |||
1274 | newinfo = xt_alloc_table_info(tmp.size); | ||
1275 | if (!newinfo) | ||
1276 | return -ENOMEM; | ||
1277 | |||
1278 | /* choose the copy that is our node/cpu */ | ||
1279 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | ||
1280 | if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), | ||
1281 | tmp.size) != 0) { | ||
1282 | ret = -EFAULT; | ||
1283 | goto free_newinfo; | ||
1284 | } | ||
1285 | |||
1286 | ret = translate_table(tmp.name, tmp.valid_hooks, | ||
1287 | newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, | ||
1288 | tmp.hook_entry, tmp.underflow); | ||
1289 | if (ret != 0) | ||
1290 | goto free_newinfo; | ||
1291 | |||
1292 | duprintf("ip_tables: Translated table\n"); | ||
1293 | |||
1294 | ret = __do_replace(tmp.name, tmp.valid_hooks, | ||
1295 | newinfo, tmp.num_counters, | ||
1296 | tmp.counters); | ||
1297 | if (ret) | ||
1298 | goto free_newinfo_untrans; | ||
1299 | return 0; | ||
1300 | |||
1301 | free_newinfo_untrans: | ||
1302 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); | ||
1015 | free_newinfo: | 1303 | free_newinfo: |
1016 | xt_free_table_info(newinfo); | 1304 | xt_free_table_info(newinfo); |
1017 | return ret; | 1305 | return ret; |
@@ -1040,31 +1328,59 @@ add_counter_to_entry(struct ipt_entry *e, | |||
1040 | } | 1328 | } |
1041 | 1329 | ||
1042 | static int | 1330 | static int |
1043 | do_add_counters(void __user *user, unsigned int len) | 1331 | do_add_counters(void __user *user, unsigned int len, int compat) |
1044 | { | 1332 | { |
1045 | unsigned int i; | 1333 | unsigned int i; |
1046 | struct xt_counters_info tmp, *paddc; | 1334 | struct xt_counters_info tmp; |
1335 | struct xt_counters *paddc; | ||
1336 | unsigned int num_counters; | ||
1337 | char *name; | ||
1338 | int size; | ||
1339 | void *ptmp; | ||
1047 | struct ipt_table *t; | 1340 | struct ipt_table *t; |
1048 | struct xt_table_info *private; | 1341 | struct xt_table_info *private; |
1049 | int ret = 0; | 1342 | int ret = 0; |
1050 | void *loc_cpu_entry; | 1343 | void *loc_cpu_entry; |
1344 | #ifdef CONFIG_COMPAT | ||
1345 | struct compat_xt_counters_info compat_tmp; | ||
1051 | 1346 | ||
1052 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1347 | if (compat) { |
1348 | ptmp = &compat_tmp; | ||
1349 | size = sizeof(struct compat_xt_counters_info); | ||
1350 | } else | ||
1351 | #endif | ||
1352 | { | ||
1353 | ptmp = &tmp; | ||
1354 | size = sizeof(struct xt_counters_info); | ||
1355 | } | ||
1356 | |||
1357 | if (copy_from_user(ptmp, user, size) != 0) | ||
1053 | return -EFAULT; | 1358 | return -EFAULT; |
1054 | 1359 | ||
1055 | if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters)) | 1360 | #ifdef CONFIG_COMPAT |
1361 | if (compat) { | ||
1362 | num_counters = compat_tmp.num_counters; | ||
1363 | name = compat_tmp.name; | ||
1364 | } else | ||
1365 | #endif | ||
1366 | { | ||
1367 | num_counters = tmp.num_counters; | ||
1368 | name = tmp.name; | ||
1369 | } | ||
1370 | |||
1371 | if (len != size + num_counters * sizeof(struct xt_counters)) | ||
1056 | return -EINVAL; | 1372 | return -EINVAL; |
1057 | 1373 | ||
1058 | paddc = vmalloc_node(len, numa_node_id()); | 1374 | paddc = vmalloc_node(len - size, numa_node_id()); |
1059 | if (!paddc) | 1375 | if (!paddc) |
1060 | return -ENOMEM; | 1376 | return -ENOMEM; |
1061 | 1377 | ||
1062 | if (copy_from_user(paddc, user, len) != 0) { | 1378 | if (copy_from_user(paddc, user + size, len - size) != 0) { |
1063 | ret = -EFAULT; | 1379 | ret = -EFAULT; |
1064 | goto free; | 1380 | goto free; |
1065 | } | 1381 | } |
1066 | 1382 | ||
1067 | t = xt_find_table_lock(AF_INET, tmp.name); | 1383 | t = xt_find_table_lock(AF_INET, name); |
1068 | if (!t || IS_ERR(t)) { | 1384 | if (!t || IS_ERR(t)) { |
1069 | ret = t ? PTR_ERR(t) : -ENOENT; | 1385 | ret = t ? PTR_ERR(t) : -ENOENT; |
1070 | goto free; | 1386 | goto free; |
@@ -1072,7 +1388,7 @@ do_add_counters(void __user *user, unsigned int len) | |||
1072 | 1388 | ||
1073 | write_lock_bh(&t->lock); | 1389 | write_lock_bh(&t->lock); |
1074 | private = t->private; | 1390 | private = t->private; |
1075 | if (private->number != paddc->num_counters) { | 1391 | if (private->number != num_counters) { |
1076 | ret = -EINVAL; | 1392 | ret = -EINVAL; |
1077 | goto unlock_up_free; | 1393 | goto unlock_up_free; |
1078 | } | 1394 | } |
@@ -1083,7 +1399,7 @@ do_add_counters(void __user *user, unsigned int len) | |||
1083 | IPT_ENTRY_ITERATE(loc_cpu_entry, | 1399 | IPT_ENTRY_ITERATE(loc_cpu_entry, |
1084 | private->size, | 1400 | private->size, |
1085 | add_counter_to_entry, | 1401 | add_counter_to_entry, |
1086 | paddc->counters, | 1402 | paddc, |
1087 | &i); | 1403 | &i); |
1088 | unlock_up_free: | 1404 | unlock_up_free: |
1089 | write_unlock_bh(&t->lock); | 1405 | write_unlock_bh(&t->lock); |
@@ -1095,8 +1411,438 @@ do_add_counters(void __user *user, unsigned int len) | |||
1095 | return ret; | 1411 | return ret; |
1096 | } | 1412 | } |
1097 | 1413 | ||
1414 | #ifdef CONFIG_COMPAT | ||
1415 | struct compat_ipt_replace { | ||
1416 | char name[IPT_TABLE_MAXNAMELEN]; | ||
1417 | u32 valid_hooks; | ||
1418 | u32 num_entries; | ||
1419 | u32 size; | ||
1420 | u32 hook_entry[NF_IP_NUMHOOKS]; | ||
1421 | u32 underflow[NF_IP_NUMHOOKS]; | ||
1422 | u32 num_counters; | ||
1423 | compat_uptr_t counters; /* struct ipt_counters * */ | ||
1424 | struct compat_ipt_entry entries[0]; | ||
1425 | }; | ||
1426 | |||
1427 | static inline int compat_copy_match_to_user(struct ipt_entry_match *m, | ||
1428 | void __user **dstptr, compat_uint_t *size) | ||
1429 | { | ||
1430 | if (m->u.kernel.match->compat) | ||
1431 | return m->u.kernel.match->compat(m, dstptr, size, | ||
1432 | COMPAT_TO_USER); | ||
1433 | else | ||
1434 | return xt_compat_match(m, dstptr, size, COMPAT_TO_USER); | ||
1435 | } | ||
1436 | |||
1437 | static int compat_copy_entry_to_user(struct ipt_entry *e, | ||
1438 | void __user **dstptr, compat_uint_t *size) | ||
1439 | { | ||
1440 | struct ipt_entry_target __user *t; | ||
1441 | struct compat_ipt_entry __user *ce; | ||
1442 | u_int16_t target_offset, next_offset; | ||
1443 | compat_uint_t origsize; | ||
1444 | int ret; | ||
1445 | |||
1446 | ret = -EFAULT; | ||
1447 | origsize = *size; | ||
1448 | ce = (struct compat_ipt_entry __user *)*dstptr; | ||
1449 | if (__copy_to_user(ce, e, sizeof(struct ipt_entry))) | ||
1450 | goto out; | ||
1451 | |||
1452 | *dstptr += sizeof(struct compat_ipt_entry); | ||
1453 | ret = IPT_MATCH_ITERATE(e, compat_copy_match_to_user, dstptr, size); | ||
1454 | target_offset = e->target_offset - (origsize - *size); | ||
1455 | if (ret) | ||
1456 | goto out; | ||
1457 | t = ipt_get_target(e); | ||
1458 | if (t->u.kernel.target->compat) | ||
1459 | ret = t->u.kernel.target->compat(t, dstptr, size, | ||
1460 | COMPAT_TO_USER); | ||
1461 | else | ||
1462 | ret = xt_compat_target(t, dstptr, size, COMPAT_TO_USER); | ||
1463 | if (ret) | ||
1464 | goto out; | ||
1465 | ret = -EFAULT; | ||
1466 | next_offset = e->next_offset - (origsize - *size); | ||
1467 | if (__put_user(target_offset, &ce->target_offset)) | ||
1468 | goto out; | ||
1469 | if (__put_user(next_offset, &ce->next_offset)) | ||
1470 | goto out; | ||
1471 | return 0; | ||
1472 | out: | ||
1473 | return ret; | ||
1474 | } | ||
1475 | |||
1476 | static inline int | ||
1477 | compat_check_calc_match(struct ipt_entry_match *m, | ||
1478 | const char *name, | ||
1479 | const struct ipt_ip *ip, | ||
1480 | unsigned int hookmask, | ||
1481 | int *size, int *i) | ||
1482 | { | ||
1483 | struct ipt_match *match; | ||
1484 | |||
1485 | match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name, | ||
1486 | m->u.user.revision), | ||
1487 | "ipt_%s", m->u.user.name); | ||
1488 | if (IS_ERR(match) || !match) { | ||
1489 | duprintf("compat_check_calc_match: `%s' not found\n", | ||
1490 | m->u.user.name); | ||
1491 | return match ? PTR_ERR(match) : -ENOENT; | ||
1492 | } | ||
1493 | m->u.kernel.match = match; | ||
1494 | |||
1495 | if (m->u.kernel.match->compat) | ||
1496 | m->u.kernel.match->compat(m, NULL, size, COMPAT_CALC_SIZE); | ||
1497 | else | ||
1498 | xt_compat_match(m, NULL, size, COMPAT_CALC_SIZE); | ||
1499 | |||
1500 | (*i)++; | ||
1501 | return 0; | ||
1502 | } | ||
1503 | |||
1504 | static inline int | ||
1505 | check_compat_entry_size_and_hooks(struct ipt_entry *e, | ||
1506 | struct xt_table_info *newinfo, | ||
1507 | unsigned int *size, | ||
1508 | unsigned char *base, | ||
1509 | unsigned char *limit, | ||
1510 | unsigned int *hook_entries, | ||
1511 | unsigned int *underflows, | ||
1512 | unsigned int *i, | ||
1513 | const char *name) | ||
1514 | { | ||
1515 | struct ipt_entry_target *t; | ||
1516 | struct ipt_target *target; | ||
1517 | u_int16_t entry_offset; | ||
1518 | int ret, off, h, j; | ||
1519 | |||
1520 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | ||
1521 | if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 | ||
1522 | || (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) { | ||
1523 | duprintf("Bad offset %p, limit = %p\n", e, limit); | ||
1524 | return -EINVAL; | ||
1525 | } | ||
1526 | |||
1527 | if (e->next_offset < sizeof(struct compat_ipt_entry) + | ||
1528 | sizeof(struct compat_xt_entry_target)) { | ||
1529 | duprintf("checking: element %p size %u\n", | ||
1530 | e, e->next_offset); | ||
1531 | return -EINVAL; | ||
1532 | } | ||
1533 | |||
1534 | if (!ip_checkentry(&e->ip)) { | ||
1535 | duprintf("ip_tables: ip check failed %p %s.\n", e, name); | ||
1536 | return -EINVAL; | ||
1537 | } | ||
1538 | |||
1539 | off = 0; | ||
1540 | entry_offset = (void *)e - (void *)base; | ||
1541 | j = 0; | ||
1542 | ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip, | ||
1543 | e->comefrom, &off, &j); | ||
1544 | if (ret != 0) | ||
1545 | goto out; | ||
1546 | |||
1547 | t = ipt_get_target(e); | ||
1548 | target = try_then_request_module(xt_find_target(AF_INET, | ||
1549 | t->u.user.name, | ||
1550 | t->u.user.revision), | ||
1551 | "ipt_%s", t->u.user.name); | ||
1552 | if (IS_ERR(target) || !target) { | ||
1553 | duprintf("check_entry: `%s' not found\n", t->u.user.name); | ||
1554 | ret = target ? PTR_ERR(target) : -ENOENT; | ||
1555 | goto out; | ||
1556 | } | ||
1557 | t->u.kernel.target = target; | ||
1558 | |||
1559 | if (t->u.kernel.target->compat) | ||
1560 | t->u.kernel.target->compat(t, NULL, &off, COMPAT_CALC_SIZE); | ||
1561 | else | ||
1562 | xt_compat_target(t, NULL, &off, COMPAT_CALC_SIZE); | ||
1563 | *size += off; | ||
1564 | ret = compat_add_offset(entry_offset, off); | ||
1565 | if (ret) | ||
1566 | goto out; | ||
1567 | |||
1568 | /* Check hooks & underflows */ | ||
1569 | for (h = 0; h < NF_IP_NUMHOOKS; h++) { | ||
1570 | if ((unsigned char *)e - base == hook_entries[h]) | ||
1571 | newinfo->hook_entry[h] = hook_entries[h]; | ||
1572 | if ((unsigned char *)e - base == underflows[h]) | ||
1573 | newinfo->underflow[h] = underflows[h]; | ||
1574 | } | ||
1575 | |||
1576 | /* Clear counters and comefrom */ | ||
1577 | e->counters = ((struct ipt_counters) { 0, 0 }); | ||
1578 | e->comefrom = 0; | ||
1579 | |||
1580 | (*i)++; | ||
1581 | return 0; | ||
1582 | out: | ||
1583 | IPT_MATCH_ITERATE(e, cleanup_match, &j); | ||
1584 | return ret; | ||
1585 | } | ||
1586 | |||
1587 | static inline int compat_copy_match_from_user(struct ipt_entry_match *m, | ||
1588 | void **dstptr, compat_uint_t *size, const char *name, | ||
1589 | const struct ipt_ip *ip, unsigned int hookmask) | ||
1590 | { | ||
1591 | struct ipt_entry_match *dm; | ||
1592 | struct ipt_match *match; | ||
1593 | int ret; | ||
1594 | |||
1595 | dm = (struct ipt_entry_match *)*dstptr; | ||
1596 | match = m->u.kernel.match; | ||
1597 | if (match->compat) | ||
1598 | match->compat(m, dstptr, size, COMPAT_FROM_USER); | ||
1599 | else | ||
1600 | xt_compat_match(m, dstptr, size, COMPAT_FROM_USER); | ||
1601 | |||
1602 | ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), | ||
1603 | name, hookmask, ip->proto, | ||
1604 | ip->invflags & IPT_INV_PROTO); | ||
1605 | if (ret) | ||
1606 | return ret; | ||
1607 | |||
1608 | if (m->u.kernel.match->checkentry | ||
1609 | && !m->u.kernel.match->checkentry(name, ip, match, dm->data, | ||
1610 | dm->u.match_size - sizeof(*dm), | ||
1611 | hookmask)) { | ||
1612 | duprintf("ip_tables: check failed for `%s'.\n", | ||
1613 | m->u.kernel.match->name); | ||
1614 | return -EINVAL; | ||
1615 | } | ||
1616 | return 0; | ||
1617 | } | ||
1618 | |||
1619 | static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | ||
1620 | unsigned int *size, const char *name, | ||
1621 | struct xt_table_info *newinfo, unsigned char *base) | ||
1622 | { | ||
1623 | struct ipt_entry_target *t; | ||
1624 | struct ipt_target *target; | ||
1625 | struct ipt_entry *de; | ||
1626 | unsigned int origsize; | ||
1627 | int ret, h; | ||
1628 | |||
1629 | ret = 0; | ||
1630 | origsize = *size; | ||
1631 | de = (struct ipt_entry *)*dstptr; | ||
1632 | memcpy(de, e, sizeof(struct ipt_entry)); | ||
1633 | |||
1634 | *dstptr += sizeof(struct compat_ipt_entry); | ||
1635 | ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, | ||
1636 | name, &de->ip, de->comefrom); | ||
1637 | if (ret) | ||
1638 | goto out; | ||
1639 | de->target_offset = e->target_offset - (origsize - *size); | ||
1640 | t = ipt_get_target(e); | ||
1641 | target = t->u.kernel.target; | ||
1642 | if (target->compat) | ||
1643 | target->compat(t, dstptr, size, COMPAT_FROM_USER); | ||
1644 | else | ||
1645 | xt_compat_target(t, dstptr, size, COMPAT_FROM_USER); | ||
1646 | |||
1647 | de->next_offset = e->next_offset - (origsize - *size); | ||
1648 | for (h = 0; h < NF_IP_NUMHOOKS; h++) { | ||
1649 | if ((unsigned char *)de - base < newinfo->hook_entry[h]) | ||
1650 | newinfo->hook_entry[h] -= origsize - *size; | ||
1651 | if ((unsigned char *)de - base < newinfo->underflow[h]) | ||
1652 | newinfo->underflow[h] -= origsize - *size; | ||
1653 | } | ||
1654 | |||
1655 | t = ipt_get_target(de); | ||
1656 | target = t->u.kernel.target; | ||
1657 | ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), | ||
1658 | name, e->comefrom, e->ip.proto, | ||
1659 | e->ip.invflags & IPT_INV_PROTO); | ||
1660 | if (ret) | ||
1661 | goto out; | ||
1662 | |||
1663 | ret = -EINVAL; | ||
1664 | if (t->u.kernel.target == &ipt_standard_target) { | ||
1665 | if (!standard_check(t, *size)) | ||
1666 | goto out; | ||
1667 | } else if (t->u.kernel.target->checkentry | ||
1668 | && !t->u.kernel.target->checkentry(name, de, target, | ||
1669 | t->data, t->u.target_size - sizeof(*t), | ||
1670 | de->comefrom)) { | ||
1671 | duprintf("ip_tables: compat: check failed for `%s'.\n", | ||
1672 | t->u.kernel.target->name); | ||
1673 | goto out; | ||
1674 | } | ||
1675 | ret = 0; | ||
1676 | out: | ||
1677 | return ret; | ||
1678 | } | ||
1679 | |||
1098 | static int | 1680 | static int |
1099 | do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | 1681 | translate_compat_table(const char *name, |
1682 | unsigned int valid_hooks, | ||
1683 | struct xt_table_info **pinfo, | ||
1684 | void **pentry0, | ||
1685 | unsigned int total_size, | ||
1686 | unsigned int number, | ||
1687 | unsigned int *hook_entries, | ||
1688 | unsigned int *underflows) | ||
1689 | { | ||
1690 | unsigned int i; | ||
1691 | struct xt_table_info *newinfo, *info; | ||
1692 | void *pos, *entry0, *entry1; | ||
1693 | unsigned int size; | ||
1694 | int ret; | ||
1695 | |||
1696 | info = *pinfo; | ||
1697 | entry0 = *pentry0; | ||
1698 | size = total_size; | ||
1699 | info->number = number; | ||
1700 | |||
1701 | /* Init all hooks to impossible value. */ | ||
1702 | for (i = 0; i < NF_IP_NUMHOOKS; i++) { | ||
1703 | info->hook_entry[i] = 0xFFFFFFFF; | ||
1704 | info->underflow[i] = 0xFFFFFFFF; | ||
1705 | } | ||
1706 | |||
1707 | duprintf("translate_compat_table: size %u\n", info->size); | ||
1708 | i = 0; | ||
1709 | xt_compat_lock(AF_INET); | ||
1710 | /* Walk through entries, checking offsets. */ | ||
1711 | ret = IPT_ENTRY_ITERATE(entry0, total_size, | ||
1712 | check_compat_entry_size_and_hooks, | ||
1713 | info, &size, entry0, | ||
1714 | entry0 + total_size, | ||
1715 | hook_entries, underflows, &i, name); | ||
1716 | if (ret != 0) | ||
1717 | goto out_unlock; | ||
1718 | |||
1719 | ret = -EINVAL; | ||
1720 | if (i != number) { | ||
1721 | duprintf("translate_compat_table: %u not %u entries\n", | ||
1722 | i, number); | ||
1723 | goto out_unlock; | ||
1724 | } | ||
1725 | |||
1726 | /* Check hooks all assigned */ | ||
1727 | for (i = 0; i < NF_IP_NUMHOOKS; i++) { | ||
1728 | /* Only hooks which are valid */ | ||
1729 | if (!(valid_hooks & (1 << i))) | ||
1730 | continue; | ||
1731 | if (info->hook_entry[i] == 0xFFFFFFFF) { | ||
1732 | duprintf("Invalid hook entry %u %u\n", | ||
1733 | i, hook_entries[i]); | ||
1734 | goto out_unlock; | ||
1735 | } | ||
1736 | if (info->underflow[i] == 0xFFFFFFFF) { | ||
1737 | duprintf("Invalid underflow %u %u\n", | ||
1738 | i, underflows[i]); | ||
1739 | goto out_unlock; | ||
1740 | } | ||
1741 | } | ||
1742 | |||
1743 | ret = -ENOMEM; | ||
1744 | newinfo = xt_alloc_table_info(size); | ||
1745 | if (!newinfo) | ||
1746 | goto out_unlock; | ||
1747 | |||
1748 | newinfo->number = number; | ||
1749 | for (i = 0; i < NF_IP_NUMHOOKS; i++) { | ||
1750 | newinfo->hook_entry[i] = info->hook_entry[i]; | ||
1751 | newinfo->underflow[i] = info->underflow[i]; | ||
1752 | } | ||
1753 | entry1 = newinfo->entries[raw_smp_processor_id()]; | ||
1754 | pos = entry1; | ||
1755 | size = total_size; | ||
1756 | ret = IPT_ENTRY_ITERATE(entry0, total_size, | ||
1757 | compat_copy_entry_from_user, &pos, &size, | ||
1758 | name, newinfo, entry1); | ||
1759 | compat_flush_offsets(); | ||
1760 | xt_compat_unlock(AF_INET); | ||
1761 | if (ret) | ||
1762 | goto free_newinfo; | ||
1763 | |||
1764 | ret = -ELOOP; | ||
1765 | if (!mark_source_chains(newinfo, valid_hooks, entry1)) | ||
1766 | goto free_newinfo; | ||
1767 | |||
1768 | /* And one copy for every other CPU */ | ||
1769 | for_each_cpu(i) | ||
1770 | if (newinfo->entries[i] && newinfo->entries[i] != entry1) | ||
1771 | memcpy(newinfo->entries[i], entry1, newinfo->size); | ||
1772 | |||
1773 | *pinfo = newinfo; | ||
1774 | *pentry0 = entry1; | ||
1775 | xt_free_table_info(info); | ||
1776 | return 0; | ||
1777 | |||
1778 | free_newinfo: | ||
1779 | xt_free_table_info(newinfo); | ||
1780 | out: | ||
1781 | return ret; | ||
1782 | out_unlock: | ||
1783 | xt_compat_unlock(AF_INET); | ||
1784 | goto out; | ||
1785 | } | ||
1786 | |||
1787 | static int | ||
1788 | compat_do_replace(void __user *user, unsigned int len) | ||
1789 | { | ||
1790 | int ret; | ||
1791 | struct compat_ipt_replace tmp; | ||
1792 | struct xt_table_info *newinfo; | ||
1793 | void *loc_cpu_entry; | ||
1794 | |||
1795 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | ||
1796 | return -EFAULT; | ||
1797 | |||
1798 | /* Hack: Causes ipchains to give correct error msg --RR */ | ||
1799 | if (len != sizeof(tmp) + tmp.size) | ||
1800 | return -ENOPROTOOPT; | ||
1801 | |||
1802 | /* overflow check */ | ||
1803 | if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - | ||
1804 | SMP_CACHE_BYTES) | ||
1805 | return -ENOMEM; | ||
1806 | if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) | ||
1807 | return -ENOMEM; | ||
1808 | |||
1809 | newinfo = xt_alloc_table_info(tmp.size); | ||
1810 | if (!newinfo) | ||
1811 | return -ENOMEM; | ||
1812 | |||
1813 | /* choose the copy that is our node/cpu */ | ||
1814 | loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; | ||
1815 | if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), | ||
1816 | tmp.size) != 0) { | ||
1817 | ret = -EFAULT; | ||
1818 | goto free_newinfo; | ||
1819 | } | ||
1820 | |||
1821 | ret = translate_compat_table(tmp.name, tmp.valid_hooks, | ||
1822 | &newinfo, &loc_cpu_entry, tmp.size, | ||
1823 | tmp.num_entries, tmp.hook_entry, tmp.underflow); | ||
1824 | if (ret != 0) | ||
1825 | goto free_newinfo; | ||
1826 | |||
1827 | duprintf("compat_do_replace: Translated table\n"); | ||
1828 | |||
1829 | ret = __do_replace(tmp.name, tmp.valid_hooks, | ||
1830 | newinfo, tmp.num_counters, | ||
1831 | compat_ptr(tmp.counters)); | ||
1832 | if (ret) | ||
1833 | goto free_newinfo_untrans; | ||
1834 | return 0; | ||
1835 | |||
1836 | free_newinfo_untrans: | ||
1837 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL); | ||
1838 | free_newinfo: | ||
1839 | xt_free_table_info(newinfo); | ||
1840 | return ret; | ||
1841 | } | ||
1842 | |||
1843 | static int | ||
1844 | compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, | ||
1845 | unsigned int len) | ||
1100 | { | 1846 | { |
1101 | int ret; | 1847 | int ret; |
1102 | 1848 | ||
@@ -1105,11 +1851,11 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | |||
1105 | 1851 | ||
1106 | switch (cmd) { | 1852 | switch (cmd) { |
1107 | case IPT_SO_SET_REPLACE: | 1853 | case IPT_SO_SET_REPLACE: |
1108 | ret = do_replace(user, len); | 1854 | ret = compat_do_replace(user, len); |
1109 | break; | 1855 | break; |
1110 | 1856 | ||
1111 | case IPT_SO_SET_ADD_COUNTERS: | 1857 | case IPT_SO_SET_ADD_COUNTERS: |
1112 | ret = do_add_counters(user, len); | 1858 | ret = do_add_counters(user, len, 1); |
1113 | break; | 1859 | break; |
1114 | 1860 | ||
1115 | default: | 1861 | default: |
@@ -1120,75 +1866,196 @@ do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | |||
1120 | return ret; | 1866 | return ret; |
1121 | } | 1867 | } |
1122 | 1868 | ||
1869 | struct compat_ipt_get_entries | ||
1870 | { | ||
1871 | char name[IPT_TABLE_MAXNAMELEN]; | ||
1872 | compat_uint_t size; | ||
1873 | struct compat_ipt_entry entrytable[0]; | ||
1874 | }; | ||
1875 | |||
1876 | static int compat_copy_entries_to_user(unsigned int total_size, | ||
1877 | struct ipt_table *table, void __user *userptr) | ||
1878 | { | ||
1879 | unsigned int off, num; | ||
1880 | struct compat_ipt_entry e; | ||
1881 | struct xt_counters *counters; | ||
1882 | struct xt_table_info *private = table->private; | ||
1883 | void __user *pos; | ||
1884 | unsigned int size; | ||
1885 | int ret = 0; | ||
1886 | void *loc_cpu_entry; | ||
1887 | |||
1888 | counters = alloc_counters(table); | ||
1889 | if (IS_ERR(counters)) | ||
1890 | return PTR_ERR(counters); | ||
1891 | |||
1892 | /* choose the copy that is on our node/cpu, ... | ||
1893 | * This choice is lazy (because current thread is | ||
1894 | * allowed to migrate to another cpu) | ||
1895 | */ | ||
1896 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; | ||
1897 | pos = userptr; | ||
1898 | size = total_size; | ||
1899 | ret = IPT_ENTRY_ITERATE(loc_cpu_entry, total_size, | ||
1900 | compat_copy_entry_to_user, &pos, &size); | ||
1901 | if (ret) | ||
1902 | goto free_counters; | ||
1903 | |||
1904 | /* ... then go back and fix counters and names */ | ||
1905 | for (off = 0, num = 0; off < size; off += e.next_offset, num++) { | ||
1906 | unsigned int i; | ||
1907 | struct ipt_entry_match m; | ||
1908 | struct ipt_entry_target t; | ||
1909 | |||
1910 | ret = -EFAULT; | ||
1911 | if (copy_from_user(&e, userptr + off, | ||
1912 | sizeof(struct compat_ipt_entry))) | ||
1913 | goto free_counters; | ||
1914 | if (copy_to_user(userptr + off + | ||
1915 | offsetof(struct compat_ipt_entry, counters), | ||
1916 | &counters[num], sizeof(counters[num]))) | ||
1917 | goto free_counters; | ||
1918 | |||
1919 | for (i = sizeof(struct compat_ipt_entry); | ||
1920 | i < e.target_offset; i += m.u.match_size) { | ||
1921 | if (copy_from_user(&m, userptr + off + i, | ||
1922 | sizeof(struct ipt_entry_match))) | ||
1923 | goto free_counters; | ||
1924 | if (copy_to_user(userptr + off + i + | ||
1925 | offsetof(struct ipt_entry_match, u.user.name), | ||
1926 | m.u.kernel.match->name, | ||
1927 | strlen(m.u.kernel.match->name) + 1)) | ||
1928 | goto free_counters; | ||
1929 | } | ||
1930 | |||
1931 | if (copy_from_user(&t, userptr + off + e.target_offset, | ||
1932 | sizeof(struct ipt_entry_target))) | ||
1933 | goto free_counters; | ||
1934 | if (copy_to_user(userptr + off + e.target_offset + | ||
1935 | offsetof(struct ipt_entry_target, u.user.name), | ||
1936 | t.u.kernel.target->name, | ||
1937 | strlen(t.u.kernel.target->name) + 1)) | ||
1938 | goto free_counters; | ||
1939 | } | ||
1940 | ret = 0; | ||
1941 | free_counters: | ||
1942 | vfree(counters); | ||
1943 | return ret; | ||
1944 | } | ||
1945 | |||
1123 | static int | 1946 | static int |
1124 | do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | 1947 | compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len) |
1125 | { | 1948 | { |
1126 | int ret; | 1949 | int ret; |
1950 | struct compat_ipt_get_entries get; | ||
1951 | struct ipt_table *t; | ||
1127 | 1952 | ||
1128 | if (!capable(CAP_NET_ADMIN)) | ||
1129 | return -EPERM; | ||
1130 | 1953 | ||
1131 | switch (cmd) { | 1954 | if (*len < sizeof(get)) { |
1132 | case IPT_SO_GET_INFO: { | 1955 | duprintf("compat_get_entries: %u < %u\n", |
1133 | char name[IPT_TABLE_MAXNAMELEN]; | 1956 | *len, (unsigned int)sizeof(get)); |
1134 | struct ipt_table *t; | 1957 | return -EINVAL; |
1958 | } | ||
1959 | |||
1960 | if (copy_from_user(&get, uptr, sizeof(get)) != 0) | ||
1961 | return -EFAULT; | ||
1962 | |||
1963 | if (*len != sizeof(struct compat_ipt_get_entries) + get.size) { | ||
1964 | duprintf("compat_get_entries: %u != %u\n", *len, | ||
1965 | (unsigned int)(sizeof(struct compat_ipt_get_entries) + | ||
1966 | get.size)); | ||
1967 | return -EINVAL; | ||
1968 | } | ||
1135 | 1969 | ||
1136 | if (*len != sizeof(struct ipt_getinfo)) { | 1970 | xt_compat_lock(AF_INET); |
1137 | duprintf("length %u != %u\n", *len, | 1971 | t = xt_find_table_lock(AF_INET, get.name); |
1138 | sizeof(struct ipt_getinfo)); | 1972 | if (t && !IS_ERR(t)) { |
1973 | struct xt_table_info *private = t->private; | ||
1974 | struct xt_table_info info; | ||
1975 | duprintf("t->private->number = %u\n", | ||
1976 | private->number); | ||
1977 | ret = compat_table_info(private, &info); | ||
1978 | if (!ret && get.size == info.size) { | ||
1979 | ret = compat_copy_entries_to_user(private->size, | ||
1980 | t, uptr->entrytable); | ||
1981 | } else if (!ret) { | ||
1982 | duprintf("compat_get_entries: I've got %u not %u!\n", | ||
1983 | private->size, | ||
1984 | get.size); | ||
1139 | ret = -EINVAL; | 1985 | ret = -EINVAL; |
1140 | break; | ||
1141 | } | 1986 | } |
1987 | compat_flush_offsets(); | ||
1988 | module_put(t->me); | ||
1989 | xt_table_unlock(t); | ||
1990 | } else | ||
1991 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
1142 | 1992 | ||
1143 | if (copy_from_user(name, user, sizeof(name)) != 0) { | 1993 | xt_compat_unlock(AF_INET); |
1144 | ret = -EFAULT; | 1994 | return ret; |
1145 | break; | 1995 | } |
1146 | } | 1996 | |
1147 | name[IPT_TABLE_MAXNAMELEN-1] = '\0'; | 1997 | static int |
1148 | 1998 | compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |
1149 | t = try_then_request_module(xt_find_table_lock(AF_INET, name), | 1999 | { |
1150 | "iptable_%s", name); | 2000 | int ret; |
1151 | if (t && !IS_ERR(t)) { | 2001 | |
1152 | struct ipt_getinfo info; | 2002 | switch (cmd) { |
1153 | struct xt_table_info *private = t->private; | 2003 | case IPT_SO_GET_INFO: |
1154 | 2004 | ret = get_info(user, len, 1); | |
1155 | info.valid_hooks = t->valid_hooks; | 2005 | break; |
1156 | memcpy(info.hook_entry, private->hook_entry, | 2006 | case IPT_SO_GET_ENTRIES: |
1157 | sizeof(info.hook_entry)); | 2007 | ret = compat_get_entries(user, len); |
1158 | memcpy(info.underflow, private->underflow, | 2008 | break; |
1159 | sizeof(info.underflow)); | 2009 | default: |
1160 | info.num_entries = private->number; | 2010 | duprintf("compat_do_ipt_get_ctl: unknown request %i\n", cmd); |
1161 | info.size = private->size; | 2011 | ret = -EINVAL; |
1162 | memcpy(info.name, name, sizeof(info.name)); | ||
1163 | |||
1164 | if (copy_to_user(user, &info, *len) != 0) | ||
1165 | ret = -EFAULT; | ||
1166 | else | ||
1167 | ret = 0; | ||
1168 | xt_table_unlock(t); | ||
1169 | module_put(t->me); | ||
1170 | } else | ||
1171 | ret = t ? PTR_ERR(t) : -ENOENT; | ||
1172 | } | 2012 | } |
1173 | break; | 2013 | return ret; |
2014 | } | ||
2015 | #endif | ||
1174 | 2016 | ||
1175 | case IPT_SO_GET_ENTRIES: { | 2017 | static int |
1176 | struct ipt_get_entries get; | 2018 | do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) |
2019 | { | ||
2020 | int ret; | ||
1177 | 2021 | ||
1178 | if (*len < sizeof(get)) { | 2022 | if (!capable(CAP_NET_ADMIN)) |
1179 | duprintf("get_entries: %u < %u\n", *len, sizeof(get)); | 2023 | return -EPERM; |
1180 | ret = -EINVAL; | 2024 | |
1181 | } else if (copy_from_user(&get, user, sizeof(get)) != 0) { | 2025 | switch (cmd) { |
1182 | ret = -EFAULT; | 2026 | case IPT_SO_SET_REPLACE: |
1183 | } else if (*len != sizeof(struct ipt_get_entries) + get.size) { | 2027 | ret = do_replace(user, len); |
1184 | duprintf("get_entries: %u != %u\n", *len, | ||
1185 | sizeof(struct ipt_get_entries) + get.size); | ||
1186 | ret = -EINVAL; | ||
1187 | } else | ||
1188 | ret = get_entries(&get, user); | ||
1189 | break; | 2028 | break; |
2029 | |||
2030 | case IPT_SO_SET_ADD_COUNTERS: | ||
2031 | ret = do_add_counters(user, len, 0); | ||
2032 | break; | ||
2033 | |||
2034 | default: | ||
2035 | duprintf("do_ipt_set_ctl: unknown request %i\n", cmd); | ||
2036 | ret = -EINVAL; | ||
1190 | } | 2037 | } |
1191 | 2038 | ||
2039 | return ret; | ||
2040 | } | ||
2041 | |||
2042 | static int | ||
2043 | do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | ||
2044 | { | ||
2045 | int ret; | ||
2046 | |||
2047 | if (!capable(CAP_NET_ADMIN)) | ||
2048 | return -EPERM; | ||
2049 | |||
2050 | switch (cmd) { | ||
2051 | case IPT_SO_GET_INFO: | ||
2052 | ret = get_info(user, len, 0); | ||
2053 | break; | ||
2054 | |||
2055 | case IPT_SO_GET_ENTRIES: | ||
2056 | ret = get_entries(user, len); | ||
2057 | break; | ||
2058 | |||
1192 | case IPT_SO_GET_REVISION_MATCH: | 2059 | case IPT_SO_GET_REVISION_MATCH: |
1193 | case IPT_SO_GET_REVISION_TARGET: { | 2060 | case IPT_SO_GET_REVISION_TARGET: { |
1194 | struct ipt_get_revision rev; | 2061 | struct ipt_get_revision rev; |
@@ -1336,6 +2203,9 @@ static struct ipt_target ipt_standard_target = { | |||
1336 | .name = IPT_STANDARD_TARGET, | 2203 | .name = IPT_STANDARD_TARGET, |
1337 | .targetsize = sizeof(int), | 2204 | .targetsize = sizeof(int), |
1338 | .family = AF_INET, | 2205 | .family = AF_INET, |
2206 | #ifdef CONFIG_COMPAT | ||
2207 | .compat = &compat_ipt_standard_fn, | ||
2208 | #endif | ||
1339 | }; | 2209 | }; |
1340 | 2210 | ||
1341 | static struct ipt_target ipt_error_target = { | 2211 | static struct ipt_target ipt_error_target = { |
@@ -1350,9 +2220,15 @@ static struct nf_sockopt_ops ipt_sockopts = { | |||
1350 | .set_optmin = IPT_BASE_CTL, | 2220 | .set_optmin = IPT_BASE_CTL, |
1351 | .set_optmax = IPT_SO_SET_MAX+1, | 2221 | .set_optmax = IPT_SO_SET_MAX+1, |
1352 | .set = do_ipt_set_ctl, | 2222 | .set = do_ipt_set_ctl, |
2223 | #ifdef CONFIG_COMPAT | ||
2224 | .compat_set = compat_do_ipt_set_ctl, | ||
2225 | #endif | ||
1353 | .get_optmin = IPT_BASE_CTL, | 2226 | .get_optmin = IPT_BASE_CTL, |
1354 | .get_optmax = IPT_SO_GET_MAX+1, | 2227 | .get_optmax = IPT_SO_GET_MAX+1, |
1355 | .get = do_ipt_get_ctl, | 2228 | .get = do_ipt_get_ctl, |
2229 | #ifdef CONFIG_COMPAT | ||
2230 | .compat_get = compat_do_ipt_get_ctl, | ||
2231 | #endif | ||
1356 | }; | 2232 | }; |
1357 | 2233 | ||
1358 | static struct ipt_match icmp_matchstruct = { | 2234 | static struct ipt_match icmp_matchstruct = { |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index e4768a31718b..aad9d28c8d71 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -725,22 +725,17 @@ static struct file_operations clusterip_proc_fops = { | |||
725 | 725 | ||
726 | #endif /* CONFIG_PROC_FS */ | 726 | #endif /* CONFIG_PROC_FS */ |
727 | 727 | ||
728 | static int init_or_cleanup(int fini) | 728 | static int __init ipt_clusterip_init(void) |
729 | { | 729 | { |
730 | int ret; | 730 | int ret; |
731 | 731 | ||
732 | if (fini) | 732 | ret = ipt_register_target(&clusterip_tgt); |
733 | goto cleanup; | 733 | if (ret < 0) |
734 | 734 | return ret; | |
735 | if (ipt_register_target(&clusterip_tgt)) { | ||
736 | ret = -EINVAL; | ||
737 | goto cleanup_none; | ||
738 | } | ||
739 | 735 | ||
740 | if (nf_register_hook(&cip_arp_ops) < 0) { | 736 | ret = nf_register_hook(&cip_arp_ops); |
741 | ret = -EINVAL; | 737 | if (ret < 0) |
742 | goto cleanup_target; | 738 | goto cleanup_target; |
743 | } | ||
744 | 739 | ||
745 | #ifdef CONFIG_PROC_FS | 740 | #ifdef CONFIG_PROC_FS |
746 | clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", proc_net); | 741 | clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", proc_net); |
@@ -753,31 +748,24 @@ static int init_or_cleanup(int fini) | |||
753 | 748 | ||
754 | printk(KERN_NOTICE "ClusterIP Version %s loaded successfully\n", | 749 | printk(KERN_NOTICE "ClusterIP Version %s loaded successfully\n", |
755 | CLUSTERIP_VERSION); | 750 | CLUSTERIP_VERSION); |
756 | |||
757 | return 0; | 751 | return 0; |
758 | 752 | ||
759 | cleanup: | ||
760 | printk(KERN_NOTICE "ClusterIP Version %s unloading\n", | ||
761 | CLUSTERIP_VERSION); | ||
762 | #ifdef CONFIG_PROC_FS | ||
763 | remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); | ||
764 | #endif | ||
765 | cleanup_hook: | 753 | cleanup_hook: |
766 | nf_unregister_hook(&cip_arp_ops); | 754 | nf_unregister_hook(&cip_arp_ops); |
767 | cleanup_target: | 755 | cleanup_target: |
768 | ipt_unregister_target(&clusterip_tgt); | 756 | ipt_unregister_target(&clusterip_tgt); |
769 | cleanup_none: | 757 | return ret; |
770 | return -EINVAL; | ||
771 | } | ||
772 | |||
773 | static int __init ipt_clusterip_init(void) | ||
774 | { | ||
775 | return init_or_cleanup(0); | ||
776 | } | 758 | } |
777 | 759 | ||
778 | static void __exit ipt_clusterip_fini(void) | 760 | static void __exit ipt_clusterip_fini(void) |
779 | { | 761 | { |
780 | init_or_cleanup(1); | 762 | printk(KERN_NOTICE "ClusterIP Version %s unloading\n", |
763 | CLUSTERIP_VERSION); | ||
764 | #ifdef CONFIG_PROC_FS | ||
765 | remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); | ||
766 | #endif | ||
767 | nf_unregister_hook(&cip_arp_ops); | ||
768 | ipt_unregister_target(&clusterip_tgt); | ||
781 | } | 769 | } |
782 | 770 | ||
783 | module_init(ipt_clusterip_init); | 771 | module_init(ipt_clusterip_init); |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 4269a5440d43..0bba3c2bb786 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -106,7 +106,6 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
106 | struct rtable *rt; | 106 | struct rtable *rt; |
107 | u_int16_t tmp_port; | 107 | u_int16_t tmp_port; |
108 | u_int32_t tmp_addr; | 108 | u_int32_t tmp_addr; |
109 | unsigned int tcplen; | ||
110 | int needs_ack; | 109 | int needs_ack; |
111 | int hh_len; | 110 | int hh_len; |
112 | 111 | ||
@@ -124,13 +123,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) | |||
124 | return; | 123 | return; |
125 | 124 | ||
126 | /* Check checksum */ | 125 | /* Check checksum */ |
127 | tcplen = oldskb->len - iph->ihl * 4; | 126 | if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP)) |
128 | if (((hook != NF_IP_LOCAL_IN && oldskb->ip_summed != CHECKSUM_HW) || | ||
129 | (hook == NF_IP_LOCAL_IN && | ||
130 | oldskb->ip_summed != CHECKSUM_UNNECESSARY)) && | ||
131 | csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, | ||
132 | oldskb->ip_summed == CHECKSUM_HW ? oldskb->csum : | ||
133 | skb_checksum(oldskb, iph->ihl * 4, tcplen, 0))) | ||
134 | return; | 127 | return; |
135 | 128 | ||
136 | if ((rt = route_reverse(oldskb, oth, hook)) == NULL) | 129 | if ((rt = route_reverse(oldskb, oth, hook)) == NULL) |
diff --git a/net/ipv4/netfilter/ipt_esp.c b/net/ipv4/netfilter/ipt_esp.c deleted file mode 100644 index 3840b417a3c5..000000000000 --- a/net/ipv4/netfilter/ipt_esp.c +++ /dev/null | |||
@@ -1,111 +0,0 @@ | |||
1 | /* Kernel module to match ESP parameters. */ | ||
2 | |||
3 | /* (C) 1999-2000 Yon Uriarte <yon@astaro.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/skbuff.h> | ||
12 | #include <linux/ip.h> | ||
13 | |||
14 | #include <linux/netfilter_ipv4/ipt_esp.h> | ||
15 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
16 | |||
17 | MODULE_LICENSE("GPL"); | ||
18 | MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>"); | ||
19 | MODULE_DESCRIPTION("iptables ESP SPI match module"); | ||
20 | |||
21 | #ifdef DEBUG_CONNTRACK | ||
22 | #define duprintf(format, args...) printk(format , ## args) | ||
23 | #else | ||
24 | #define duprintf(format, args...) | ||
25 | #endif | ||
26 | |||
27 | /* Returns 1 if the spi is matched by the range, 0 otherwise */ | ||
28 | static inline int | ||
29 | spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, int invert) | ||
30 | { | ||
31 | int r=0; | ||
32 | duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ', | ||
33 | min,spi,max); | ||
34 | r=(spi >= min && spi <= max) ^ invert; | ||
35 | duprintf(" result %s\n",r? "PASS" : "FAILED"); | ||
36 | return r; | ||
37 | } | ||
38 | |||
39 | static int | ||
40 | match(const struct sk_buff *skb, | ||
41 | const struct net_device *in, | ||
42 | const struct net_device *out, | ||
43 | const struct xt_match *match, | ||
44 | const void *matchinfo, | ||
45 | int offset, | ||
46 | unsigned int protoff, | ||
47 | int *hotdrop) | ||
48 | { | ||
49 | struct ip_esp_hdr _esp, *eh; | ||
50 | const struct ipt_esp *espinfo = matchinfo; | ||
51 | |||
52 | /* Must not be a fragment. */ | ||
53 | if (offset) | ||
54 | return 0; | ||
55 | |||
56 | eh = skb_header_pointer(skb, protoff, | ||
57 | sizeof(_esp), &_esp); | ||
58 | if (eh == NULL) { | ||
59 | /* We've been asked to examine this packet, and we | ||
60 | * can't. Hence, no choice but to drop. | ||
61 | */ | ||
62 | duprintf("Dropping evil ESP tinygram.\n"); | ||
63 | *hotdrop = 1; | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | return spi_match(espinfo->spis[0], espinfo->spis[1], | ||
68 | ntohl(eh->spi), | ||
69 | !!(espinfo->invflags & IPT_ESP_INV_SPI)); | ||
70 | } | ||
71 | |||
72 | /* Called when user tries to insert an entry of this type. */ | ||
73 | static int | ||
74 | checkentry(const char *tablename, | ||
75 | const void *ip_void, | ||
76 | const struct xt_match *match, | ||
77 | void *matchinfo, | ||
78 | unsigned int matchinfosize, | ||
79 | unsigned int hook_mask) | ||
80 | { | ||
81 | const struct ipt_esp *espinfo = matchinfo; | ||
82 | |||
83 | /* Must specify no unknown invflags */ | ||
84 | if (espinfo->invflags & ~IPT_ESP_INV_MASK) { | ||
85 | duprintf("ipt_esp: unknown flags %X\n", espinfo->invflags); | ||
86 | return 0; | ||
87 | } | ||
88 | return 1; | ||
89 | } | ||
90 | |||
91 | static struct ipt_match esp_match = { | ||
92 | .name = "esp", | ||
93 | .match = match, | ||
94 | .matchsize = sizeof(struct ipt_esp), | ||
95 | .proto = IPPROTO_ESP, | ||
96 | .checkentry = checkentry, | ||
97 | .me = THIS_MODULE, | ||
98 | }; | ||
99 | |||
100 | static int __init ipt_esp_init(void) | ||
101 | { | ||
102 | return ipt_register_match(&esp_match); | ||
103 | } | ||
104 | |||
105 | static void __exit ipt_esp_fini(void) | ||
106 | { | ||
107 | ipt_unregister_match(&esp_match); | ||
108 | } | ||
109 | |||
110 | module_init(ipt_esp_init); | ||
111 | module_exit(ipt_esp_fini); | ||
diff --git a/net/ipv4/netfilter/ipt_multiport.c b/net/ipv4/netfilter/ipt_multiport.c deleted file mode 100644 index ac95d8390bcc..000000000000 --- a/net/ipv4/netfilter/ipt_multiport.c +++ /dev/null | |||
@@ -1,195 +0,0 @@ | |||
1 | /* Kernel module to match one of a list of TCP/UDP ports: ports are in | ||
2 | the same place so we can treat them as equal. */ | ||
3 | |||
4 | /* (C) 1999-2001 Paul `Rusty' Russell | ||
5 | * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/udp.h> | ||
15 | #include <linux/skbuff.h> | ||
16 | |||
17 | #include <linux/netfilter_ipv4/ipt_multiport.h> | ||
18 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
19 | |||
20 | MODULE_LICENSE("GPL"); | ||
21 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | ||
22 | MODULE_DESCRIPTION("iptables multiple port match module"); | ||
23 | |||
24 | #if 0 | ||
25 | #define duprintf(format, args...) printk(format , ## args) | ||
26 | #else | ||
27 | #define duprintf(format, args...) | ||
28 | #endif | ||
29 | |||
30 | /* Returns 1 if the port is matched by the test, 0 otherwise. */ | ||
31 | static inline int | ||
32 | ports_match(const u_int16_t *portlist, enum ipt_multiport_flags flags, | ||
33 | u_int8_t count, u_int16_t src, u_int16_t dst) | ||
34 | { | ||
35 | unsigned int i; | ||
36 | for (i=0; i<count; i++) { | ||
37 | if (flags != IPT_MULTIPORT_DESTINATION | ||
38 | && portlist[i] == src) | ||
39 | return 1; | ||
40 | |||
41 | if (flags != IPT_MULTIPORT_SOURCE | ||
42 | && portlist[i] == dst) | ||
43 | return 1; | ||
44 | } | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | /* Returns 1 if the port is matched by the test, 0 otherwise. */ | ||
50 | static inline int | ||
51 | ports_match_v1(const struct ipt_multiport_v1 *minfo, | ||
52 | u_int16_t src, u_int16_t dst) | ||
53 | { | ||
54 | unsigned int i; | ||
55 | u_int16_t s, e; | ||
56 | |||
57 | for (i=0; i < minfo->count; i++) { | ||
58 | s = minfo->ports[i]; | ||
59 | |||
60 | if (minfo->pflags[i]) { | ||
61 | /* range port matching */ | ||
62 | e = minfo->ports[++i]; | ||
63 | duprintf("src or dst matches with %d-%d?\n", s, e); | ||
64 | |||
65 | if (minfo->flags == IPT_MULTIPORT_SOURCE | ||
66 | && src >= s && src <= e) | ||
67 | return 1 ^ minfo->invert; | ||
68 | if (minfo->flags == IPT_MULTIPORT_DESTINATION | ||
69 | && dst >= s && dst <= e) | ||
70 | return 1 ^ minfo->invert; | ||
71 | if (minfo->flags == IPT_MULTIPORT_EITHER | ||
72 | && ((dst >= s && dst <= e) | ||
73 | || (src >= s && src <= e))) | ||
74 | return 1 ^ minfo->invert; | ||
75 | } else { | ||
76 | /* exact port matching */ | ||
77 | duprintf("src or dst matches with %d?\n", s); | ||
78 | |||
79 | if (minfo->flags == IPT_MULTIPORT_SOURCE | ||
80 | && src == s) | ||
81 | return 1 ^ minfo->invert; | ||
82 | if (minfo->flags == IPT_MULTIPORT_DESTINATION | ||
83 | && dst == s) | ||
84 | return 1 ^ minfo->invert; | ||
85 | if (minfo->flags == IPT_MULTIPORT_EITHER | ||
86 | && (src == s || dst == s)) | ||
87 | return 1 ^ minfo->invert; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | return minfo->invert; | ||
92 | } | ||
93 | |||
94 | static int | ||
95 | match(const struct sk_buff *skb, | ||
96 | const struct net_device *in, | ||
97 | const struct net_device *out, | ||
98 | const struct xt_match *match, | ||
99 | const void *matchinfo, | ||
100 | int offset, | ||
101 | unsigned int protoff, | ||
102 | int *hotdrop) | ||
103 | { | ||
104 | u16 _ports[2], *pptr; | ||
105 | const struct ipt_multiport *multiinfo = matchinfo; | ||
106 | |||
107 | if (offset) | ||
108 | return 0; | ||
109 | |||
110 | pptr = skb_header_pointer(skb, protoff, | ||
111 | sizeof(_ports), _ports); | ||
112 | if (pptr == NULL) { | ||
113 | /* We've been asked to examine this packet, and we | ||
114 | * can't. Hence, no choice but to drop. | ||
115 | */ | ||
116 | duprintf("ipt_multiport:" | ||
117 | " Dropping evil offset=0 tinygram.\n"); | ||
118 | *hotdrop = 1; | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | return ports_match(multiinfo->ports, | ||
123 | multiinfo->flags, multiinfo->count, | ||
124 | ntohs(pptr[0]), ntohs(pptr[1])); | ||
125 | } | ||
126 | |||
127 | static int | ||
128 | match_v1(const struct sk_buff *skb, | ||
129 | const struct net_device *in, | ||
130 | const struct net_device *out, | ||
131 | const struct xt_match *match, | ||
132 | const void *matchinfo, | ||
133 | int offset, | ||
134 | unsigned int protoff, | ||
135 | int *hotdrop) | ||
136 | { | ||
137 | u16 _ports[2], *pptr; | ||
138 | const struct ipt_multiport_v1 *multiinfo = matchinfo; | ||
139 | |||
140 | if (offset) | ||
141 | return 0; | ||
142 | |||
143 | pptr = skb_header_pointer(skb, protoff, | ||
144 | sizeof(_ports), _ports); | ||
145 | if (pptr == NULL) { | ||
146 | /* We've been asked to examine this packet, and we | ||
147 | * can't. Hence, no choice but to drop. | ||
148 | */ | ||
149 | duprintf("ipt_multiport:" | ||
150 | " Dropping evil offset=0 tinygram.\n"); | ||
151 | *hotdrop = 1; | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | return ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1])); | ||
156 | } | ||
157 | |||
158 | static struct ipt_match multiport_match = { | ||
159 | .name = "multiport", | ||
160 | .revision = 0, | ||
161 | .match = match, | ||
162 | .matchsize = sizeof(struct ipt_multiport), | ||
163 | .me = THIS_MODULE, | ||
164 | }; | ||
165 | |||
166 | static struct ipt_match multiport_match_v1 = { | ||
167 | .name = "multiport", | ||
168 | .revision = 1, | ||
169 | .match = match_v1, | ||
170 | .matchsize = sizeof(struct ipt_multiport_v1), | ||
171 | .me = THIS_MODULE, | ||
172 | }; | ||
173 | |||
174 | static int __init ipt_multiport_init(void) | ||
175 | { | ||
176 | int err; | ||
177 | |||
178 | err = ipt_register_match(&multiport_match); | ||
179 | if (!err) { | ||
180 | err = ipt_register_match(&multiport_match_v1); | ||
181 | if (err) | ||
182 | ipt_unregister_match(&multiport_match); | ||
183 | } | ||
184 | |||
185 | return err; | ||
186 | } | ||
187 | |||
188 | static void __exit ipt_multiport_fini(void) | ||
189 | { | ||
190 | ipt_unregister_match(&multiport_match); | ||
191 | ipt_unregister_match(&multiport_match_v1); | ||
192 | } | ||
193 | |||
194 | module_init(ipt_multiport_init); | ||
195 | module_exit(ipt_multiport_fini); | ||
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 3d80aefe9cfa..7f417484bfbf 100644 --- a/net/ipv4/netfilter/iptable_filter.c +++ b/net/ipv4/netfilter/iptable_filter.c | |||
@@ -157,37 +157,20 @@ static int __init iptable_filter_init(void) | |||
157 | return ret; | 157 | return ret; |
158 | 158 | ||
159 | /* Register hooks */ | 159 | /* Register hooks */ |
160 | ret = nf_register_hook(&ipt_ops[0]); | 160 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
161 | if (ret < 0) | 161 | if (ret < 0) |
162 | goto cleanup_table; | 162 | goto cleanup_table; |
163 | 163 | ||
164 | ret = nf_register_hook(&ipt_ops[1]); | ||
165 | if (ret < 0) | ||
166 | goto cleanup_hook0; | ||
167 | |||
168 | ret = nf_register_hook(&ipt_ops[2]); | ||
169 | if (ret < 0) | ||
170 | goto cleanup_hook1; | ||
171 | |||
172 | return ret; | 164 | return ret; |
173 | 165 | ||
174 | cleanup_hook1: | ||
175 | nf_unregister_hook(&ipt_ops[1]); | ||
176 | cleanup_hook0: | ||
177 | nf_unregister_hook(&ipt_ops[0]); | ||
178 | cleanup_table: | 166 | cleanup_table: |
179 | ipt_unregister_table(&packet_filter); | 167 | ipt_unregister_table(&packet_filter); |
180 | |||
181 | return ret; | 168 | return ret; |
182 | } | 169 | } |
183 | 170 | ||
184 | static void __exit iptable_filter_fini(void) | 171 | static void __exit iptable_filter_fini(void) |
185 | { | 172 | { |
186 | unsigned int i; | 173 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
187 | |||
188 | for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) | ||
189 | nf_unregister_hook(&ipt_ops[i]); | ||
190 | |||
191 | ipt_unregister_table(&packet_filter); | 174 | ipt_unregister_table(&packet_filter); |
192 | } | 175 | } |
193 | 176 | ||
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 412fc96cc896..397b95cc026b 100644 --- a/net/ipv4/netfilter/iptable_mangle.c +++ b/net/ipv4/netfilter/iptable_mangle.c | |||
@@ -211,49 +211,20 @@ static int __init iptable_mangle_init(void) | |||
211 | return ret; | 211 | return ret; |
212 | 212 | ||
213 | /* Register hooks */ | 213 | /* Register hooks */ |
214 | ret = nf_register_hook(&ipt_ops[0]); | 214 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
215 | if (ret < 0) | 215 | if (ret < 0) |
216 | goto cleanup_table; | 216 | goto cleanup_table; |
217 | 217 | ||
218 | ret = nf_register_hook(&ipt_ops[1]); | ||
219 | if (ret < 0) | ||
220 | goto cleanup_hook0; | ||
221 | |||
222 | ret = nf_register_hook(&ipt_ops[2]); | ||
223 | if (ret < 0) | ||
224 | goto cleanup_hook1; | ||
225 | |||
226 | ret = nf_register_hook(&ipt_ops[3]); | ||
227 | if (ret < 0) | ||
228 | goto cleanup_hook2; | ||
229 | |||
230 | ret = nf_register_hook(&ipt_ops[4]); | ||
231 | if (ret < 0) | ||
232 | goto cleanup_hook3; | ||
233 | |||
234 | return ret; | 218 | return ret; |
235 | 219 | ||
236 | cleanup_hook3: | ||
237 | nf_unregister_hook(&ipt_ops[3]); | ||
238 | cleanup_hook2: | ||
239 | nf_unregister_hook(&ipt_ops[2]); | ||
240 | cleanup_hook1: | ||
241 | nf_unregister_hook(&ipt_ops[1]); | ||
242 | cleanup_hook0: | ||
243 | nf_unregister_hook(&ipt_ops[0]); | ||
244 | cleanup_table: | 220 | cleanup_table: |
245 | ipt_unregister_table(&packet_mangler); | 221 | ipt_unregister_table(&packet_mangler); |
246 | |||
247 | return ret; | 222 | return ret; |
248 | } | 223 | } |
249 | 224 | ||
250 | static void __exit iptable_mangle_fini(void) | 225 | static void __exit iptable_mangle_fini(void) |
251 | { | 226 | { |
252 | unsigned int i; | 227 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
253 | |||
254 | for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) | ||
255 | nf_unregister_hook(&ipt_ops[i]); | ||
256 | |||
257 | ipt_unregister_table(&packet_mangler); | 228 | ipt_unregister_table(&packet_mangler); |
258 | } | 229 | } |
259 | 230 | ||
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 03cc79a6160a..7912cce1e1b8 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c | |||
@@ -101,18 +101,18 @@ ipt_hook(unsigned int hook, | |||
101 | /* 'raw' is the very first table. */ | 101 | /* 'raw' is the very first table. */ |
102 | static struct nf_hook_ops ipt_ops[] = { | 102 | static struct nf_hook_ops ipt_ops[] = { |
103 | { | 103 | { |
104 | .hook = ipt_hook, | 104 | .hook = ipt_hook, |
105 | .pf = PF_INET, | 105 | .pf = PF_INET, |
106 | .hooknum = NF_IP_PRE_ROUTING, | 106 | .hooknum = NF_IP_PRE_ROUTING, |
107 | .priority = NF_IP_PRI_RAW, | 107 | .priority = NF_IP_PRI_RAW, |
108 | .owner = THIS_MODULE, | 108 | .owner = THIS_MODULE, |
109 | }, | 109 | }, |
110 | { | 110 | { |
111 | .hook = ipt_hook, | 111 | .hook = ipt_hook, |
112 | .pf = PF_INET, | 112 | .pf = PF_INET, |
113 | .hooknum = NF_IP_LOCAL_OUT, | 113 | .hooknum = NF_IP_LOCAL_OUT, |
114 | .priority = NF_IP_PRI_RAW, | 114 | .priority = NF_IP_PRI_RAW, |
115 | .owner = THIS_MODULE, | 115 | .owner = THIS_MODULE, |
116 | }, | 116 | }, |
117 | }; | 117 | }; |
118 | 118 | ||
@@ -126,31 +126,20 @@ static int __init iptable_raw_init(void) | |||
126 | return ret; | 126 | return ret; |
127 | 127 | ||
128 | /* Register hooks */ | 128 | /* Register hooks */ |
129 | ret = nf_register_hook(&ipt_ops[0]); | 129 | ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
130 | if (ret < 0) | 130 | if (ret < 0) |
131 | goto cleanup_table; | 131 | goto cleanup_table; |
132 | 132 | ||
133 | ret = nf_register_hook(&ipt_ops[1]); | ||
134 | if (ret < 0) | ||
135 | goto cleanup_hook0; | ||
136 | |||
137 | return ret; | 133 | return ret; |
138 | 134 | ||
139 | cleanup_hook0: | ||
140 | nf_unregister_hook(&ipt_ops[0]); | ||
141 | cleanup_table: | 135 | cleanup_table: |
142 | ipt_unregister_table(&packet_raw); | 136 | ipt_unregister_table(&packet_raw); |
143 | |||
144 | return ret; | 137 | return ret; |
145 | } | 138 | } |
146 | 139 | ||
147 | static void __exit iptable_raw_fini(void) | 140 | static void __exit iptable_raw_fini(void) |
148 | { | 141 | { |
149 | unsigned int i; | 142 | nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); |
150 | |||
151 | for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) | ||
152 | nf_unregister_hook(&ipt_ops[i]); | ||
153 | |||
154 | ipt_unregister_table(&packet_raw); | 143 | ipt_unregister_table(&packet_raw); |
155 | } | 144 | } |
156 | 145 | ||
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 4afbc699d3ba..5bc9f64d7b5b 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -210,71 +210,63 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum, | |||
210 | 210 | ||
211 | /* Connection tracking may drop packets, but never alters them, so | 211 | /* Connection tracking may drop packets, but never alters them, so |
212 | make it the first hook. */ | 212 | make it the first hook. */ |
213 | static struct nf_hook_ops ipv4_conntrack_defrag_ops = { | 213 | static struct nf_hook_ops ipv4_conntrack_ops[] = { |
214 | .hook = ipv4_conntrack_defrag, | 214 | { |
215 | .owner = THIS_MODULE, | 215 | .hook = ipv4_conntrack_defrag, |
216 | .pf = PF_INET, | 216 | .owner = THIS_MODULE, |
217 | .hooknum = NF_IP_PRE_ROUTING, | 217 | .pf = PF_INET, |
218 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | 218 | .hooknum = NF_IP_PRE_ROUTING, |
219 | }; | 219 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, |
220 | 220 | }, | |
221 | static struct nf_hook_ops ipv4_conntrack_in_ops = { | 221 | { |
222 | .hook = ipv4_conntrack_in, | 222 | .hook = ipv4_conntrack_in, |
223 | .owner = THIS_MODULE, | 223 | .owner = THIS_MODULE, |
224 | .pf = PF_INET, | 224 | .pf = PF_INET, |
225 | .hooknum = NF_IP_PRE_ROUTING, | 225 | .hooknum = NF_IP_PRE_ROUTING, |
226 | .priority = NF_IP_PRI_CONNTRACK, | 226 | .priority = NF_IP_PRI_CONNTRACK, |
227 | }; | 227 | }, |
228 | 228 | { | |
229 | static struct nf_hook_ops ipv4_conntrack_defrag_local_out_ops = { | 229 | .hook = ipv4_conntrack_defrag, |
230 | .hook = ipv4_conntrack_defrag, | 230 | .owner = THIS_MODULE, |
231 | .owner = THIS_MODULE, | 231 | .pf = PF_INET, |
232 | .pf = PF_INET, | 232 | .hooknum = NF_IP_LOCAL_OUT, |
233 | .hooknum = NF_IP_LOCAL_OUT, | 233 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, |
234 | .priority = NF_IP_PRI_CONNTRACK_DEFRAG, | 234 | }, |
235 | }; | 235 | { |
236 | 236 | .hook = ipv4_conntrack_local, | |
237 | static struct nf_hook_ops ipv4_conntrack_local_out_ops = { | 237 | .owner = THIS_MODULE, |
238 | .hook = ipv4_conntrack_local, | 238 | .pf = PF_INET, |
239 | .owner = THIS_MODULE, | 239 | .hooknum = NF_IP_LOCAL_OUT, |
240 | .pf = PF_INET, | 240 | .priority = NF_IP_PRI_CONNTRACK, |
241 | .hooknum = NF_IP_LOCAL_OUT, | 241 | }, |
242 | .priority = NF_IP_PRI_CONNTRACK, | 242 | { |
243 | }; | 243 | .hook = ipv4_conntrack_help, |
244 | 244 | .owner = THIS_MODULE, | |
245 | /* helpers */ | 245 | .pf = PF_INET, |
246 | static struct nf_hook_ops ipv4_conntrack_helper_out_ops = { | 246 | .hooknum = NF_IP_POST_ROUTING, |
247 | .hook = ipv4_conntrack_help, | 247 | .priority = NF_IP_PRI_CONNTRACK_HELPER, |
248 | .owner = THIS_MODULE, | 248 | }, |
249 | .pf = PF_INET, | 249 | { |
250 | .hooknum = NF_IP_POST_ROUTING, | 250 | .hook = ipv4_conntrack_help, |
251 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | 251 | .owner = THIS_MODULE, |
252 | }; | 252 | .pf = PF_INET, |
253 | 253 | .hooknum = NF_IP_LOCAL_IN, | |
254 | static struct nf_hook_ops ipv4_conntrack_helper_in_ops = { | 254 | .priority = NF_IP_PRI_CONNTRACK_HELPER, |
255 | .hook = ipv4_conntrack_help, | 255 | }, |
256 | .owner = THIS_MODULE, | 256 | { |
257 | .pf = PF_INET, | 257 | .hook = ipv4_confirm, |
258 | .hooknum = NF_IP_LOCAL_IN, | 258 | .owner = THIS_MODULE, |
259 | .priority = NF_IP_PRI_CONNTRACK_HELPER, | 259 | .pf = PF_INET, |
260 | }; | 260 | .hooknum = NF_IP_POST_ROUTING, |
261 | 261 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | |
262 | 262 | }, | |
263 | /* Refragmenter; last chance. */ | 263 | { |
264 | static struct nf_hook_ops ipv4_conntrack_out_ops = { | 264 | .hook = ipv4_confirm, |
265 | .hook = ipv4_confirm, | 265 | .owner = THIS_MODULE, |
266 | .owner = THIS_MODULE, | 266 | .pf = PF_INET, |
267 | .pf = PF_INET, | 267 | .hooknum = NF_IP_LOCAL_IN, |
268 | .hooknum = NF_IP_POST_ROUTING, | 268 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, |
269 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | 269 | }, |
270 | }; | ||
271 | |||
272 | static struct nf_hook_ops ipv4_conntrack_local_in_ops = { | ||
273 | .hook = ipv4_confirm, | ||
274 | .owner = THIS_MODULE, | ||
275 | .pf = PF_INET, | ||
276 | .hooknum = NF_IP_LOCAL_IN, | ||
277 | .priority = NF_IP_PRI_CONNTRACK_CONFIRM, | ||
278 | }; | 270 | }; |
279 | 271 | ||
280 | #ifdef CONFIG_SYSCTL | 272 | #ifdef CONFIG_SYSCTL |
@@ -440,16 +432,20 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = { | |||
440 | extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4; | 432 | extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4; |
441 | extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4; | 433 | extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4; |
442 | extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp; | 434 | extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp; |
443 | static int init_or_cleanup(int init) | 435 | |
436 | MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); | ||
437 | MODULE_LICENSE("GPL"); | ||
438 | |||
439 | static int __init nf_conntrack_l3proto_ipv4_init(void) | ||
444 | { | 440 | { |
445 | int ret = 0; | 441 | int ret = 0; |
446 | 442 | ||
447 | if (!init) goto cleanup; | 443 | need_conntrack(); |
448 | 444 | ||
449 | ret = nf_register_sockopt(&so_getorigdst); | 445 | ret = nf_register_sockopt(&so_getorigdst); |
450 | if (ret < 0) { | 446 | if (ret < 0) { |
451 | printk(KERN_ERR "Unable to register netfilter socket option\n"); | 447 | printk(KERN_ERR "Unable to register netfilter socket option\n"); |
452 | goto cleanup_nothing; | 448 | return ret; |
453 | } | 449 | } |
454 | 450 | ||
455 | ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4); | 451 | ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4); |
@@ -476,84 +472,26 @@ static int init_or_cleanup(int init) | |||
476 | goto cleanup_icmp; | 472 | goto cleanup_icmp; |
477 | } | 473 | } |
478 | 474 | ||
479 | ret = nf_register_hook(&ipv4_conntrack_defrag_ops); | 475 | ret = nf_register_hooks(ipv4_conntrack_ops, |
476 | ARRAY_SIZE(ipv4_conntrack_ops)); | ||
480 | if (ret < 0) { | 477 | if (ret < 0) { |
481 | printk("nf_conntrack_ipv4: can't register pre-routing defrag hook.\n"); | 478 | printk("nf_conntrack_ipv4: can't register hooks.\n"); |
482 | goto cleanup_ipv4; | 479 | goto cleanup_ipv4; |
483 | } | 480 | } |
484 | ret = nf_register_hook(&ipv4_conntrack_defrag_local_out_ops); | ||
485 | if (ret < 0) { | ||
486 | printk("nf_conntrack_ipv4: can't register local_out defrag hook.\n"); | ||
487 | goto cleanup_defragops; | ||
488 | } | ||
489 | |||
490 | ret = nf_register_hook(&ipv4_conntrack_in_ops); | ||
491 | if (ret < 0) { | ||
492 | printk("nf_conntrack_ipv4: can't register pre-routing hook.\n"); | ||
493 | goto cleanup_defraglocalops; | ||
494 | } | ||
495 | |||
496 | ret = nf_register_hook(&ipv4_conntrack_local_out_ops); | ||
497 | if (ret < 0) { | ||
498 | printk("nf_conntrack_ipv4: can't register local out hook.\n"); | ||
499 | goto cleanup_inops; | ||
500 | } | ||
501 | |||
502 | ret = nf_register_hook(&ipv4_conntrack_helper_in_ops); | ||
503 | if (ret < 0) { | ||
504 | printk("nf_conntrack_ipv4: can't register local helper hook.\n"); | ||
505 | goto cleanup_inandlocalops; | ||
506 | } | ||
507 | |||
508 | ret = nf_register_hook(&ipv4_conntrack_helper_out_ops); | ||
509 | if (ret < 0) { | ||
510 | printk("nf_conntrack_ipv4: can't register postrouting helper hook.\n"); | ||
511 | goto cleanup_helperinops; | ||
512 | } | ||
513 | |||
514 | ret = nf_register_hook(&ipv4_conntrack_out_ops); | ||
515 | if (ret < 0) { | ||
516 | printk("nf_conntrack_ipv4: can't register post-routing hook.\n"); | ||
517 | goto cleanup_helperoutops; | ||
518 | } | ||
519 | |||
520 | ret = nf_register_hook(&ipv4_conntrack_local_in_ops); | ||
521 | if (ret < 0) { | ||
522 | printk("nf_conntrack_ipv4: can't register local in hook.\n"); | ||
523 | goto cleanup_inoutandlocalops; | ||
524 | } | ||
525 | |||
526 | #ifdef CONFIG_SYSCTL | 481 | #ifdef CONFIG_SYSCTL |
527 | nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); | 482 | nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); |
528 | if (nf_ct_ipv4_sysctl_header == NULL) { | 483 | if (nf_ct_ipv4_sysctl_header == NULL) { |
529 | printk("nf_conntrack: can't register to sysctl.\n"); | 484 | printk("nf_conntrack: can't register to sysctl.\n"); |
530 | ret = -ENOMEM; | 485 | ret = -ENOMEM; |
531 | goto cleanup_localinops; | 486 | goto cleanup_hooks; |
532 | } | 487 | } |
533 | #endif | 488 | #endif |
534 | return ret; | 489 | return ret; |
535 | 490 | ||
536 | cleanup: | ||
537 | synchronize_net(); | ||
538 | #ifdef CONFIG_SYSCTL | 491 | #ifdef CONFIG_SYSCTL |
539 | unregister_sysctl_table(nf_ct_ipv4_sysctl_header); | 492 | cleanup_hooks: |
540 | cleanup_localinops: | 493 | nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); |
541 | #endif | 494 | #endif |
542 | nf_unregister_hook(&ipv4_conntrack_local_in_ops); | ||
543 | cleanup_inoutandlocalops: | ||
544 | nf_unregister_hook(&ipv4_conntrack_out_ops); | ||
545 | cleanup_helperoutops: | ||
546 | nf_unregister_hook(&ipv4_conntrack_helper_out_ops); | ||
547 | cleanup_helperinops: | ||
548 | nf_unregister_hook(&ipv4_conntrack_helper_in_ops); | ||
549 | cleanup_inandlocalops: | ||
550 | nf_unregister_hook(&ipv4_conntrack_local_out_ops); | ||
551 | cleanup_inops: | ||
552 | nf_unregister_hook(&ipv4_conntrack_in_ops); | ||
553 | cleanup_defraglocalops: | ||
554 | nf_unregister_hook(&ipv4_conntrack_defrag_local_out_ops); | ||
555 | cleanup_defragops: | ||
556 | nf_unregister_hook(&ipv4_conntrack_defrag_ops); | ||
557 | cleanup_ipv4: | 495 | cleanup_ipv4: |
558 | nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); | 496 | nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); |
559 | cleanup_icmp: | 497 | cleanup_icmp: |
@@ -564,22 +502,21 @@ static int init_or_cleanup(int init) | |||
564 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); | 502 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); |
565 | cleanup_sockopt: | 503 | cleanup_sockopt: |
566 | nf_unregister_sockopt(&so_getorigdst); | 504 | nf_unregister_sockopt(&so_getorigdst); |
567 | cleanup_nothing: | ||
568 | return ret; | 505 | return ret; |
569 | } | 506 | } |
570 | 507 | ||
571 | MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); | ||
572 | MODULE_LICENSE("GPL"); | ||
573 | |||
574 | static int __init nf_conntrack_l3proto_ipv4_init(void) | ||
575 | { | ||
576 | need_conntrack(); | ||
577 | return init_or_cleanup(1); | ||
578 | } | ||
579 | |||
580 | static void __exit nf_conntrack_l3proto_ipv4_fini(void) | 508 | static void __exit nf_conntrack_l3proto_ipv4_fini(void) |
581 | { | 509 | { |
582 | init_or_cleanup(0); | 510 | synchronize_net(); |
511 | #ifdef CONFIG_SYSCTL | ||
512 | unregister_sysctl_table(nf_ct_ipv4_sysctl_header); | ||
513 | #endif | ||
514 | nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); | ||
515 | nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); | ||
516 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp); | ||
517 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4); | ||
518 | nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); | ||
519 | nf_unregister_sockopt(&so_getorigdst); | ||
583 | } | 520 | } |
584 | 521 | ||
585 | module_init(nf_conntrack_l3proto_ipv4_init); | 522 | module_init(nf_conntrack_l3proto_ipv4_init); |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 52dc175be39a..4b0d361cc6e6 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
@@ -235,30 +235,14 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff, | |||
235 | } | 235 | } |
236 | 236 | ||
237 | /* See ip_conntrack_proto_tcp.c */ | 237 | /* See ip_conntrack_proto_tcp.c */ |
238 | if (hooknum != NF_IP_PRE_ROUTING) | 238 | if (hooknum == NF_IP_PRE_ROUTING && |
239 | goto checksum_skipped; | 239 | nf_ip_checksum(skb, hooknum, dataoff, 0)) { |
240 | |||
241 | switch (skb->ip_summed) { | ||
242 | case CHECKSUM_HW: | ||
243 | if (!(u16)csum_fold(skb->csum)) | ||
244 | break; | ||
245 | if (LOG_INVALID(IPPROTO_ICMP)) | 240 | if (LOG_INVALID(IPPROTO_ICMP)) |
246 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, | 241 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, |
247 | "nf_ct_icmp: bad HW ICMP checksum "); | 242 | "nf_ct_icmp: bad HW ICMP checksum "); |
248 | return -NF_ACCEPT; | 243 | return -NF_ACCEPT; |
249 | case CHECKSUM_NONE: | ||
250 | if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) { | ||
251 | if (LOG_INVALID(IPPROTO_ICMP)) | ||
252 | nf_log_packet(PF_INET, 0, skb, NULL, NULL, | ||
253 | NULL, | ||
254 | "nf_ct_icmp: bad ICMP checksum "); | ||
255 | return -NF_ACCEPT; | ||
256 | } | ||
257 | default: | ||
258 | break; | ||
259 | } | 244 | } |
260 | 245 | ||
261 | checksum_skipped: | ||
262 | /* | 246 | /* |
263 | * 18 is the highest 'known' ICMP type. Anything else is a mystery | 247 | * 18 is the highest 'known' ICMP type. Anything else is a mystery |
264 | * | 248 | * |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 1b167c4bb3be..d61e2a9d394d 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -49,7 +49,7 @@ static int fold_prot_inuse(struct proto *proto) | |||
49 | int res = 0; | 49 | int res = 0; |
50 | int cpu; | 50 | int cpu; |
51 | 51 | ||
52 | for_each_cpu(cpu) | 52 | for_each_possible_cpu(cpu) |
53 | res += proto->stats[cpu].inuse; | 53 | res += proto->stats[cpu].inuse; |
54 | 54 | ||
55 | return res; | 55 | return res; |
@@ -91,7 +91,7 @@ fold_field(void *mib[], int offt) | |||
91 | unsigned long res = 0; | 91 | unsigned long res = 0; |
92 | int i; | 92 | int i; |
93 | 93 | ||
94 | for_each_cpu(i) { | 94 | for_each_possible_cpu(i) { |
95 | res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt); | 95 | res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt); |
96 | res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt); | 96 | res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt); |
97 | } | 97 | } |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 94fcbc5e5a1b..cc9423de7311 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2741,7 +2741,10 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) | |||
2741 | /* Reserve room for dummy headers, this skb can pass | 2741 | /* Reserve room for dummy headers, this skb can pass |
2742 | through good chunk of routing engine. | 2742 | through good chunk of routing engine. |
2743 | */ | 2743 | */ |
2744 | skb->mac.raw = skb->data; | 2744 | skb->mac.raw = skb->nh.raw = skb->data; |
2745 | |||
2746 | /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */ | ||
2747 | skb->nh.iph->protocol = IPPROTO_ICMP; | ||
2745 | skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); | 2748 | skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); |
2746 | 2749 | ||
2747 | if (rta[RTA_SRC - 1]) | 2750 | if (rta[RTA_SRC - 1]) |
@@ -3083,7 +3086,7 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset, | |||
3083 | memcpy(dst, src, length); | 3086 | memcpy(dst, src, length); |
3084 | 3087 | ||
3085 | /* Add the other cpus in, one int at a time */ | 3088 | /* Add the other cpus in, one int at a time */ |
3086 | for_each_cpu(i) { | 3089 | for_each_possible_cpu(i) { |
3087 | unsigned int j; | 3090 | unsigned int j; |
3088 | 3091 | ||
3089 | src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset; | 3092 | src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 195d83584558..9f0cca4c4fae 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4559,7 +4559,6 @@ discard: | |||
4559 | 4559 | ||
4560 | EXPORT_SYMBOL(sysctl_tcp_ecn); | 4560 | EXPORT_SYMBOL(sysctl_tcp_ecn); |
4561 | EXPORT_SYMBOL(sysctl_tcp_reordering); | 4561 | EXPORT_SYMBOL(sysctl_tcp_reordering); |
4562 | EXPORT_SYMBOL(sysctl_tcp_abc); | ||
4563 | EXPORT_SYMBOL(tcp_parse_options); | 4562 | EXPORT_SYMBOL(tcp_parse_options); |
4564 | EXPORT_SYMBOL(tcp_rcv_established); | 4563 | EXPORT_SYMBOL(tcp_rcv_established); |
4565 | EXPORT_SYMBOL(tcp_rcv_state_process); | 4564 | EXPORT_SYMBOL(tcp_rcv_state_process); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9e85c0416109..672950e54c49 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1859,5 +1859,4 @@ EXPORT_SYMBOL(tcp_proc_unregister); | |||
1859 | #endif | 1859 | #endif |
1860 | EXPORT_SYMBOL(sysctl_local_port_range); | 1860 | EXPORT_SYMBOL(sysctl_local_port_range); |
1861 | EXPORT_SYMBOL(sysctl_tcp_low_latency); | 1861 | EXPORT_SYMBOL(sysctl_tcp_low_latency); |
1862 | EXPORT_SYMBOL(sysctl_tcp_tw_reuse); | ||
1863 | 1862 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 9d79546d384e..a28ae593b976 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -59,9 +59,6 @@ int sysctl_tcp_tso_win_divisor = 3; | |||
59 | int sysctl_tcp_mtu_probing = 0; | 59 | int sysctl_tcp_mtu_probing = 0; |
60 | int sysctl_tcp_base_mss = 512; | 60 | int sysctl_tcp_base_mss = 512; |
61 | 61 | ||
62 | EXPORT_SYMBOL(sysctl_tcp_mtu_probing); | ||
63 | EXPORT_SYMBOL(sysctl_tcp_base_mss); | ||
64 | |||
65 | static void update_send_head(struct sock *sk, struct tcp_sock *tp, | 62 | static void update_send_head(struct sock *sk, struct tcp_sock *tp, |
66 | struct sk_buff *skb) | 63 | struct sk_buff *skb) |
67 | { | 64 | { |
@@ -536,6 +533,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss | |||
536 | struct tcp_sock *tp = tcp_sk(sk); | 533 | struct tcp_sock *tp = tcp_sk(sk); |
537 | struct sk_buff *buff; | 534 | struct sk_buff *buff; |
538 | int nsize, old_factor; | 535 | int nsize, old_factor; |
536 | int nlen; | ||
539 | u16 flags; | 537 | u16 flags; |
540 | 538 | ||
541 | BUG_ON(len > skb->len); | 539 | BUG_ON(len > skb->len); |
@@ -554,7 +552,11 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss | |||
554 | buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); | 552 | buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); |
555 | if (buff == NULL) | 553 | if (buff == NULL) |
556 | return -ENOMEM; /* We'll just try again later. */ | 554 | return -ENOMEM; /* We'll just try again later. */ |
555 | |||
557 | sk_charge_skb(sk, buff); | 556 | sk_charge_skb(sk, buff); |
557 | nlen = skb->len - len - nsize; | ||
558 | buff->truesize += nlen; | ||
559 | skb->truesize -= nlen; | ||
558 | 560 | ||
559 | /* Correct the sequence numbers. */ | 561 | /* Correct the sequence numbers. */ |
560 | TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; | 562 | TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; |
@@ -1040,7 +1042,8 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len, | |||
1040 | if (unlikely(buff == NULL)) | 1042 | if (unlikely(buff == NULL)) |
1041 | return -ENOMEM; | 1043 | return -ENOMEM; |
1042 | 1044 | ||
1043 | buff->truesize = nlen; | 1045 | sk_charge_skb(sk, buff); |
1046 | buff->truesize += nlen; | ||
1044 | skb->truesize -= nlen; | 1047 | skb->truesize -= nlen; |
1045 | 1048 | ||
1046 | /* Correct the sequence numbers. */ | 1049 | /* Correct the sequence numbers. */ |
diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index 0d7d386dac22..8d30c48f090e 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <linux/mutex.h> | 8 | #include <linux/mutex.h> |
9 | #include <linux/netdevice.h> | 9 | #include <linux/netdevice.h> |
10 | #include <linux/skbuff.h> | 10 | #include <linux/skbuff.h> |
11 | #include <net/icmp.h> | ||
12 | #include <net/ip.h> | ||
11 | #include <net/protocol.h> | 13 | #include <net/protocol.h> |
12 | #include <net/xfrm.h> | 14 | #include <net/xfrm.h> |
13 | 15 | ||
@@ -70,10 +72,16 @@ static int tunnel4_rcv(struct sk_buff *skb) | |||
70 | { | 72 | { |
71 | struct xfrm_tunnel *handler; | 73 | struct xfrm_tunnel *handler; |
72 | 74 | ||
75 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
76 | goto drop; | ||
77 | |||
73 | for (handler = tunnel4_handlers; handler; handler = handler->next) | 78 | for (handler = tunnel4_handlers; handler; handler = handler->next) |
74 | if (!handler->handler(skb)) | 79 | if (!handler->handler(skb)) |
75 | return 0; | 80 | return 0; |
76 | 81 | ||
82 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); | ||
83 | |||
84 | drop: | ||
77 | kfree_skb(skb); | 85 | kfree_skb(skb); |
78 | return 0; | 86 | return 0; |
79 | } | 87 | } |
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index 850d919591d1..3e174c83bfe7 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -37,8 +37,6 @@ static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) | |||
37 | { | 37 | { |
38 | switch (nexthdr) { | 38 | switch (nexthdr) { |
39 | case IPPROTO_IPIP: | 39 | case IPPROTO_IPIP: |
40 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | ||
41 | return -EINVAL; | ||
42 | *spi = skb->nh.iph->saddr; | 40 | *spi = skb->nh.iph->saddr; |
43 | *seq = 0; | 41 | *seq = 0; |
44 | return 0; | 42 | return 0; |
@@ -68,7 +66,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
68 | { | 66 | { |
69 | int err; | 67 | int err; |
70 | u32 spi, seq; | 68 | u32 spi, seq; |
71 | struct sec_decap_state xfrm_vec[XFRM_MAX_DEPTH]; | 69 | struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; |
72 | struct xfrm_state *x; | 70 | struct xfrm_state *x; |
73 | int xfrm_nr = 0; | 71 | int xfrm_nr = 0; |
74 | int decaps = 0; | 72 | int decaps = 0; |
@@ -90,14 +88,16 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
90 | if (unlikely(x->km.state != XFRM_STATE_VALID)) | 88 | if (unlikely(x->km.state != XFRM_STATE_VALID)) |
91 | goto drop_unlock; | 89 | goto drop_unlock; |
92 | 90 | ||
91 | if ((x->encap ? x->encap->encap_type : 0) != encap_type) | ||
92 | goto drop_unlock; | ||
93 | |||
93 | if (x->props.replay_window && xfrm_replay_check(x, seq)) | 94 | if (x->props.replay_window && xfrm_replay_check(x, seq)) |
94 | goto drop_unlock; | 95 | goto drop_unlock; |
95 | 96 | ||
96 | if (xfrm_state_check_expire(x)) | 97 | if (xfrm_state_check_expire(x)) |
97 | goto drop_unlock; | 98 | goto drop_unlock; |
98 | 99 | ||
99 | xfrm_vec[xfrm_nr].decap.decap_type = encap_type; | 100 | if (x->type->input(x, skb)) |
100 | if (x->type->input(x, &(xfrm_vec[xfrm_nr].decap), skb)) | ||
101 | goto drop_unlock; | 101 | goto drop_unlock; |
102 | 102 | ||
103 | /* only the first xfrm gets the encap type */ | 103 | /* only the first xfrm gets the encap type */ |
@@ -111,7 +111,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
111 | 111 | ||
112 | spin_unlock(&x->lock); | 112 | spin_unlock(&x->lock); |
113 | 113 | ||
114 | xfrm_vec[xfrm_nr++].xvec = x; | 114 | xfrm_vec[xfrm_nr++] = x; |
115 | 115 | ||
116 | iph = skb->nh.iph; | 116 | iph = skb->nh.iph; |
117 | 117 | ||
@@ -153,7 +153,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) | |||
153 | if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) | 153 | if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH) |
154 | goto drop; | 154 | goto drop; |
155 | 155 | ||
156 | memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state)); | 156 | memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec, |
157 | xfrm_nr * sizeof(xfrm_vec[0])); | ||
157 | skb->sp->len += xfrm_nr; | 158 | skb->sp->len += xfrm_nr; |
158 | 159 | ||
159 | nf_reset(skb); | 160 | nf_reset(skb); |
@@ -184,7 +185,7 @@ drop_unlock: | |||
184 | xfrm_state_put(x); | 185 | xfrm_state_put(x); |
185 | drop: | 186 | drop: |
186 | while (--xfrm_nr >= 0) | 187 | while (--xfrm_nr >= 0) |
187 | xfrm_state_put(xfrm_vec[xfrm_nr].xvec); | 188 | xfrm_state_put(xfrm_vec[xfrm_nr]); |
188 | 189 | ||
189 | kfree_skb(skb); | 190 | kfree_skb(skb); |
190 | return 0; | 191 | return 0; |
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c index 2d670935c2b5..f8ceaa127c83 100644 --- a/net/ipv4/xfrm4_tunnel.c +++ b/net/ipv4/xfrm4_tunnel.c | |||
@@ -21,7 +21,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb) | |||
21 | return 0; | 21 | return 0; |
22 | } | 22 | } |
23 | 23 | ||
24 | static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) | 24 | static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb) |
25 | { | 25 | { |
26 | return 0; | 26 | return 0; |
27 | } | 27 | } |