diff options
Diffstat (limited to 'net/ipv4')
57 files changed, 530 insertions, 1900 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index dc206f1f914..0a277453526 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1257,7 +1257,7 @@ out_unregister_udp_proto: goto out; } -module_init(inet_init); +fs_initcall(inet_init); /* ------------------------------------------------------------------------ */ diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 041dadde31a..4749d504c62 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -928,7 +928,8 @@ static void parp_redo(struct sk_buff *skb) * Receive an arp request from the device layer. */ -int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) +static int arp_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) { struct arphdr *arp; @@ -1417,7 +1418,6 @@ static int __init arp_proc_init(void) EXPORT_SYMBOL(arp_broken_ops); EXPORT_SYMBOL(arp_find); -EXPORT_SYMBOL(arp_rcv); EXPORT_SYMBOL(arp_create); EXPORT_SYMBOL(arp_xmit); EXPORT_SYMBOL(arp_send); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 81c2f788529..54419b27686 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1556,7 +1556,6 @@ void __init devinet_init(void) #endif } -EXPORT_SYMBOL(devinet_ioctl); EXPORT_SYMBOL(in_dev_finish_destroy); EXPORT_SYMBOL(inet_select_addr); EXPORT_SYMBOL(inetdev_by_index); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 4e3d3811dea..cdde9639096 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -666,4 +666,3 @@ void __init ip_fib_init(void) } EXPORT_SYMBOL(inet_addr_type); -EXPORT_SYMBOL(ip_rt_ioctl); diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index ccd3efc6a17..95a639f2e3d 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -50,7 +50,7 @@ * Patrick McHardy <kaber@trash.net> */ -#define VERSION "0.406" +#define VERSION "0.407" #include <linux/config.h> #include <asm/uaccess.h> @@ -314,11 +314,6 @@ static void __leaf_free_rcu(struct rcu_head *head) kfree(container_of(head, struct leaf, rcu)); } -static inline void free_leaf(struct leaf *leaf) -{ - call_rcu(&leaf->rcu, __leaf_free_rcu); -} - static void __leaf_info_free_rcu(struct rcu_head *head) { kfree(container_of(head, struct leaf_info, rcu)); @@ -357,7 +352,12 @@ static void __tnode_free_rcu(struct rcu_head *head) static inline void tnode_free(struct tnode *tn) { - call_rcu(&tn->rcu, __tnode_free_rcu); + if(IS_LEAF(tn)) { + struct leaf *l = (struct leaf *) tn; + call_rcu_bh(&l->rcu, __leaf_free_rcu); + } + else + call_rcu(&tn->rcu, __tnode_free_rcu); } static struct leaf *leaf_new(void) diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 9831fd2c73a..2a0455911ee 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -1107,7 +1107,7 @@ void __init icmp_init(struct net_proto_family *ops) struct inet_sock *inet; int i; - for_each_cpu(i) { + for_each_possible_cpu(i) { int err; 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 ef7366fc132..ee9b5515b9a 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, return tb; } -EXPORT_SYMBOL(inet_bind_bucket_create); - /* * Caller must hold hashbucket lock for this tb with local BH disabled */ @@ -64,8 +62,6 @@ void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, inet_csk(sk)->icsk_bind_hash = tb; } -EXPORT_SYMBOL(inet_bind_hash); - /* * Get rid of any references to a local port held by the given sock. */ diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 0923add122b..9f0bb529ab7 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -116,6 +116,7 @@ sr_failed: too_many_hops: /* Tell the sender its packet died... */ + IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); drop: kfree_skb(skb); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 2a8adda15e1..da734c43917 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -304,13 +304,17 @@ out: /* Creation primitives. */ -static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in) +static struct ipq *ip_frag_intern(struct ipq *qp_in) { struct ipq *qp; #ifdef CONFIG_SMP struct hlist_node *n; #endif + unsigned int hash; + write_lock(&ipfrag_lock); + hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr, + qp_in->protocol); #ifdef CONFIG_SMP /* With SMP race we have to recheck hash table, because * 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) } /* Add an entry to the 'ipq' queue for a newly received IP datagram. */ -static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) +static struct ipq *ip_frag_create(struct iphdr *iph, u32 user) { struct ipq *qp; @@ -371,7 +375,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user) spin_lock_init(&qp->lock); atomic_set(&qp->refcnt, 1); - return ip_frag_intern(hash, qp); + return ip_frag_intern(qp); out_nomem: 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) __u32 saddr = iph->saddr; __u32 daddr = iph->daddr; __u8 protocol = iph->protocol; - unsigned int hash = ipqhashfn(id, saddr, daddr, protocol); + unsigned int hash; struct ipq *qp; struct hlist_node *n; read_lock(&ipfrag_lock); + hash = ipqhashfn(id, saddr, daddr, protocol); hlist_for_each_entry(qp, n, &ipq_hash[hash], list) { if(qp->id == id && qp->saddr == saddr && @@ -405,7 +410,7 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user) } read_unlock(&ipfrag_lock); - return ip_frag_create(hash, iph, user); + return ip_frag_create(iph, user); } /* 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 9981dcd68f1..ab99bebdcdc 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) read_unlock(&ipgre_lock); return(0); } - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0); + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); drop: read_unlock(&ipgre_lock); diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 18d7fad474d..c9026dbf4c9 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -337,7 +337,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb) * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ - if (likely(skb->dst == NULL)) { + if (skb->dst == NULL) { int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, skb->dev); if (unlikely(err)) { diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 9bebad07bf2..cbcae654462 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -209,7 +209,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) void ip_options_fragment(struct sk_buff * skb) { - unsigned char * optptr = skb->nh.raw; + unsigned char * optptr = skb->nh.raw + sizeof(struct iphdr); struct ip_options * opt = &(IPCB(skb)->opt); int l = opt->optlen; int optlen; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index f75ff1d9655..cff9c3a72da 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -86,8 +86,6 @@ int sysctl_ip_default_ttl = IPDEFTTL; -static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)); - /* Generate a checksum for an outgoing IP datagram. */ __inline__ void ip_send_check(struct iphdr *iph) { @@ -421,7 +419,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) * single device frame, and queue such a frame for sending. */ -static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) +int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) { struct iphdr *iph; int raw = 0; @@ -673,6 +671,8 @@ fail: return err; } +EXPORT_SYMBOL(ip_fragment); + int ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) { @@ -904,7 +904,7 @@ alloc_new_skb: * because we have no idea what fragment will be * the last. */ - if (datalen == length) + if (datalen == length + fraggap) alloclen += rt->u.dst.trailer_len; if (transhdrlen) { diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 0a1d86a0f63..95278b22b66 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -210,7 +210,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info) skb->h.icmph->code != ICMP_FRAG_NEEDED) return; - spi = ntohl(ntohs(ipch->cpi)); + spi = htonl(ntohs(ipch->cpi)); x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET); if (!x) @@ -290,11 +290,8 @@ static void ipcomp_free_scratches(void) if (!scratches) return; - for_each_cpu(i) { - void *scratch = *per_cpu_ptr(scratches, i); - if (scratch) - vfree(scratch); - } + for_each_possible_cpu(i) + vfree(*per_cpu_ptr(scratches, i)); free_percpu(scratches); } @@ -313,7 +310,7 @@ static void **ipcomp_alloc_scratches(void) ipcomp_scratches = scratches; - for_each_cpu(i) { + for_each_possible_cpu(i) { void *scratch = vmalloc(IPCOMP_SCRATCH_SIZE); if (!scratch) return NULL; @@ -344,7 +341,7 @@ static void ipcomp_free_tfms(struct crypto_tfm **tfms) if (!tfms) return; - for_each_cpu(cpu) { + for_each_possible_cpu(cpu) { struct crypto_tfm *tfm = *per_cpu_ptr(tfms, cpu); crypto_free_tfm(tfm); } @@ -384,7 +381,7 @@ static struct crypto_tfm **ipcomp_alloc_tfms(const char *alg_name) if (!tfms) goto error; - for_each_cpu(cpu) { + for_each_possible_cpu(cpu) { struct crypto_tfm *tfm = crypto_alloc_tfm(alg_name, 0); if (!tfm) goto error; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index eef07b0916a..ea398ee43f2 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -474,9 +474,6 @@ static int ipip_rcv(struct sk_buff *skb) struct iphdr *iph; struct ip_tunnel *tunnel; - if (!pskb_may_pull(skb, sizeof(struct iphdr))) - goto out; - iph = skb->nh.iph; read_lock(&ipip_lock); @@ -508,7 +505,6 @@ static int ipip_rcv(struct sk_buff *skb) } read_unlock(&ipip_lock); -out: return -1; } diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index b5ad9ac2fbc..6a9e34b794b 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c @@ -133,7 +133,7 @@ struct ip_rt_info { u_int8_t tos; }; -static void queue_save(const struct sk_buff *skb, struct nf_info *info) +static void nf_ip_saveroute(const struct sk_buff *skb, struct nf_info *info) { struct ip_rt_info *rt_info = nf_info_reroute(info); @@ -146,7 +146,7 @@ static void queue_save(const struct sk_buff *skb, struct nf_info *info) } } -static int queue_reroute(struct sk_buff **pskb, const struct nf_info *info) +static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info) { const struct ip_rt_info *rt_info = nf_info_reroute(info); @@ -161,20 +161,54 @@ static int queue_reroute(struct sk_buff **pskb, const struct nf_info *info) return 0; } -static struct nf_queue_rerouter ip_reroute = { - .rer_size = sizeof(struct ip_rt_info), - .save = queue_save, - .reroute = queue_reroute, +unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook, + unsigned int dataoff, u_int8_t protocol) +{ + struct iphdr *iph = skb->nh.iph; + unsigned int csum = 0; + + switch (skb->ip_summed) { + case CHECKSUM_HW: + if (hook != NF_IP_PRE_ROUTING && hook != NF_IP_LOCAL_IN) + break; + if ((protocol == 0 && !(u16)csum_fold(skb->csum)) || + !csum_tcpudp_magic(iph->saddr, iph->daddr, + skb->len - dataoff, protocol, + skb->csum)) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + break; + } + /* fall through */ + case CHECKSUM_NONE: + if (protocol == 0) + skb->csum = 0; + else + skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, + skb->len - dataoff, + protocol, 0); + csum = __skb_checksum_complete(skb); + } + return csum; +} + +EXPORT_SYMBOL(nf_ip_checksum); + +static struct nf_afinfo nf_ip_afinfo = { + .family = AF_INET, + .checksum = nf_ip_checksum, + .saveroute = nf_ip_saveroute, + .reroute = nf_ip_reroute, + .route_key_size = sizeof(struct ip_rt_info), }; static int ipv4_netfilter_init(void) { - return nf_register_queue_rerouter(PF_INET, &ip_reroute); + return nf_register_afinfo(&nf_ip_afinfo); } static void ipv4_netfilter_fini(void) { - nf_unregister_queue_rerouter(PF_INET); + nf_unregister_afinfo(&nf_ip_afinfo); } module_init(ipv4_netfilter_init); diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 77855ccd6b4..d4072533da2 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -69,6 +69,7 @@ config IP_NF_CONNTRACK_NETLINK tristate 'Connection tracking netlink interface (EXPERIMENTAL)' depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m + depends on IP_NF_NAT=n || IP_NF_NAT help This option enables support for a netlink-based userspace interface @@ -169,8 +170,8 @@ config IP_NF_PPTP Documentation/modules.txt. If unsure, say `N'. config IP_NF_H323 - tristate 'H.323 protocol support' - depends on IP_NF_CONNTRACK + tristate 'H.323 protocol support (EXPERIMENTAL)' + depends on IP_NF_CONNTRACK && EXPERIMENTAL help H.323 is a VoIP signalling protocol from ITU-T. As one of the most important VoIP protocols, it is widely used by voice hardware and @@ -344,7 +345,7 @@ config IP_NF_TARGET_LOG To compile it as a module, choose M here. If unsure, say N. config IP_NF_TARGET_ULOG - tristate "ULOG target support (OBSOLETE)" + tristate "ULOG target support" depends on IP_NF_IPTABLES ---help--- diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index a44a5d73457..d0d19192026 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, } /* And one copy for every other CPU */ - for_each_cpu(i) { + for_each_possible_cpu(i) { if (newinfo->entries[i] && newinfo->entries[i] != entry0) memcpy(newinfo->entries[i], entry0, newinfo->size); } @@ -696,7 +696,7 @@ static void get_counters(const struct xt_table_info *t, counters, &i); - for_each_cpu(cpu) { + for_each_possible_cpu(cpu) { if (cpu == curcpu) continue; i = 0; @@ -948,7 +948,7 @@ static int do_add_counters(void __user *user, unsigned int len) write_lock_bh(&t->lock); private = t->private; - if (private->number != paddc->num_counters) { + if (private->number != tmp.num_counters) { ret = -EINVAL; goto unlock_up_free; } diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index d0d379c7df9..d7c472faa53 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[] = { static int __init arptable_filter_init(void) { - int ret, i; + int ret; /* Register table */ ret = arpt_register_table(&packet_filter, &initial_table.repl); if (ret < 0) return ret; - for (i = 0; i < ARRAY_SIZE(arpt_ops); i++) - if ((ret = nf_register_hook(&arpt_ops[i])) < 0) - goto cleanup_hooks; + ret = nf_register_hooks(arpt_ops, ARRAY_SIZE(arpt_ops)); + if (ret < 0) + goto cleanup_table; return ret; -cleanup_hooks: - while (--i >= 0) - nf_unregister_hook(&arpt_ops[i]); - +cleanup_table: arpt_unregister_table(&packet_filter); return ret; } static void __exit arptable_filter_fini(void) { - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(arpt_ops); i++) - nf_unregister_hook(&arpt_ops[i]); - + nf_unregister_hooks(arpt_ops, ARRAY_SIZE(arpt_ops)); arpt_unregister_table(&packet_filter); } diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index ceaabc18202..a297da7bbef 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) struct ip_conntrack_ecache *ecache; int cpu; - for_each_cpu(cpu) { + for_each_possible_cpu(cpu) { ecache = &per_cpu(ip_conntrack_ecache, cpu); if (ecache->ct) ip_conntrack_put(ecache->ct); @@ -1318,6 +1318,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) .tuple.dst.u.tcp.port; sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL] .tuple.dst.ip; + memset(sin.sin_zero, 0, sizeof(sin.sin_zero)); DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n", NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port)); diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c index daeb1395faa..518f581d39e 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c @@ -9,37 +9,6 @@ * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> * * For more information, please see http://nath323.sourceforge.net/ - * - * Changes: - * 2006-02-01 - initial version 0.1 - * - * 2006-02-20 - version 0.2 - * 1. Changed source format to follow kernel conventions - * 2. Deleted some unnecessary structures - * 3. Minor fixes - * - * 2006-03-10 - version 0.3 - * 1. Added support for multiple TPKTs in one packet (suggested by - * Patrick McHardy) - * 2. Avoid excessive stack usage (based on Patrick McHardy's patch) - * 3. Added support for non-linear skb (based on Patrick McHardy's patch) - * 4. Fixed missing H.245 module owner (Patrick McHardy) - * 5. Avoid long RAS expectation chains (Patrick McHardy) - * 6. Fixed incorrect __exit attribute (Patrick McHardy) - * 7. Eliminated unnecessary return code - * 8. Fixed incorrect use of NAT data from conntrack code (suggested by - * Patrick McHardy) - * 9. Fixed TTL calculation error in RCF - * 10. Added TTL support in RRQ - * 11. Better support for separate TPKT header and data - * - * 2006-03-15 - version 0.4 - * 1. Added support for T.120 channels - * 2. Added parameter gkrouted_only (suggested by Patrick McHardy) - * 3. Splitted ASN.1 code and data (suggested by Patrick McHardy) - * 4. Sort ASN.1 data to avoid forwarding declarations (suggested by - * Patrick McHardy) - * 5. Reset next TPKT data length in get_tpkt_data() */ #include <linux/config.h> @@ -54,8 +23,6 @@ #include <linux/netfilter_ipv4/ip_conntrack_h323.h> #include <linux/moduleparam.h> -#include "ip_conntrack_helper_h323_asn1.h" - #if 0 #define DEBUGP printk #else @@ -63,6 +30,10 @@ #endif /* Parameters */ +static unsigned int default_rrq_ttl = 300; +module_param(default_rrq_ttl, uint, 0600); +MODULE_PARM_DESC(default_rrq_ttl, "use this TTL if it's missing in RRQ"); + static int gkrouted_only = 1; module_param(gkrouted_only, int, 0600); MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper"); @@ -191,6 +162,8 @@ static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct, /* Validate TPKT length */ tpktlen = tpkt[2] * 256 + tpkt[3]; + if (tpktlen < 4) + goto clear_out; if (tpktlen > tcpdatalen) { if (tcpdatalen == 4) { /* Separate TPKT header */ /* Netmeeting sends TPKT header and data separately */ @@ -222,8 +195,8 @@ static int get_tpkt_data(struct sk_buff **pskb, struct ip_conntrack *ct, } /****************************************************************************/ -int get_h245_addr(unsigned char *data, H245_TransportAddress * addr, - u_int32_t * ip, u_int16_t * port) +static int get_h245_addr(unsigned char *data, H245_TransportAddress * addr, + u_int32_t * ip, u_int16_t * port) { unsigned char *p; @@ -1302,7 +1275,7 @@ static int process_rrq(struct sk_buff **pskb, struct ip_conntrack *ct, DEBUGP("ip_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive); info->timeout = rrq->timeToLive; } else - info->timeout = 0; + info->timeout = default_rrq_ttl; return 0; } @@ -1713,18 +1686,17 @@ static int __init init(void) module_init(init); module_exit(fini); -EXPORT_SYMBOL(get_h245_addr); -EXPORT_SYMBOL(get_h225_addr); -EXPORT_SYMBOL(ip_conntrack_h245_expect); -EXPORT_SYMBOL(ip_conntrack_q931_expect); -EXPORT_SYMBOL(set_h245_addr_hook); -EXPORT_SYMBOL(set_h225_addr_hook); -EXPORT_SYMBOL(set_sig_addr_hook); -EXPORT_SYMBOL(set_ras_addr_hook); -EXPORT_SYMBOL(nat_rtp_rtcp_hook); -EXPORT_SYMBOL(nat_t120_hook); -EXPORT_SYMBOL(nat_h245_hook); -EXPORT_SYMBOL(nat_q931_hook); +EXPORT_SYMBOL_GPL(get_h225_addr); +EXPORT_SYMBOL_GPL(ip_conntrack_h245_expect); +EXPORT_SYMBOL_GPL(ip_conntrack_q931_expect); +EXPORT_SYMBOL_GPL(set_h245_addr_hook); +EXPORT_SYMBOL_GPL(set_h225_addr_hook); +EXPORT_SYMBOL_GPL(set_sig_addr_hook); +EXPORT_SYMBOL_GPL(set_ras_addr_hook); +EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook); +EXPORT_SYMBOL_GPL(nat_t120_hook); +EXPORT_SYMBOL_GPL(nat_h245_hook); +EXPORT_SYMBOL_GPL(nat_q931_hook); MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>"); 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 afa525129b5..26dfecadb33 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c @@ -2,7 +2,7 @@ * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323 * conntrack/NAT module. * - * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@hotmail.com> + * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> * * This source code is licensed under General Public License version 2. * @@ -15,7 +15,7 @@ #else #include <stdio.h> #endif -#include "ip_conntrack_helper_h323_asn1.h" +#include <linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h> /* Trace Flag */ #ifndef H323_TRACE @@ -528,14 +528,15 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) /* Decode */ if ((err = (Decoders[son->type]) (bs, son, base, - level + 1)) > - H323_ERROR_STOP) + level + 1)) < + H323_ERROR_NONE) return err; bs->cur = beg + len; bs->bit = 0; } else if ((err = (Decoders[son->type]) (bs, son, base, - level + 1))) + level + 1)) < + H323_ERROR_NONE) return err; } @@ -554,7 +555,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) /* Decode the extension components */ for (opt = 0; opt < bmp2_len; opt++, i++, son++) { - if (son->attr & STOP) { + if (i < f->ub && son->attr & STOP) { PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", son->name); return H323_ERROR_STOP; @@ -584,8 +585,8 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level) beg = bs->cur; if ((err = (Decoders[son->type]) (bs, son, base, - level + 1)) > - H323_ERROR_STOP) + level + 1)) < + H323_ERROR_NONE) return err; bs->cur = beg + len; @@ -660,18 +661,20 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level) i < effective_count ? base : NULL, - level + 1)) > - H323_ERROR_STOP) + level + 1)) < + H323_ERROR_NONE) return err; bs->cur = beg + len; bs->bit = 0; } else - if ((err = (Decoders[son->type]) (bs, son, - i < effective_count ? - base : NULL, - level + 1))) - return err; + if ((err = (Decoders[son->type]) (bs, son, + i < + effective_count ? + base : NULL, + level + 1)) < + H323_ERROR_NONE) + return err; if (base) base += son->offset; @@ -703,6 +706,10 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level) type = get_bits(bs, f->sz); } + /* Write Type */ + if (base) + *(unsigned *) base = type; + /* Check Range */ if (type >= f->ub) { /* Newer version? */ BYTE_ALIGN(bs); @@ -712,10 +719,6 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level) return H323_ERROR_NONE; } - /* Write Type */ - if (base) - *(unsigned *) base = type; - /* Transfer to son level */ son = &f->fields[type]; if (son->attr & STOP) { @@ -735,13 +738,14 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level) } beg = bs->cur; - if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) > - H323_ERROR_STOP) + if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < + H323_ERROR_NONE) return err; bs->cur = beg + len; bs->bit = 0; - } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1))) + } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) < + H323_ERROR_NONE) return err; return H323_ERROR_NONE; 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 0bd828081c0..00000000000 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** - * ip_conntrack_helper_h323_asn1.h - BER and PER decoding library for H.323 - * conntrack/NAT module. - * - * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@hotmail.com> - * - * This source code is licensed under General Public License version 2. - * - * - * This library is based on H.225 version 4, H.235 version 2 and H.245 - * version 7. It is extremely optimized to decode only the absolutely - * necessary objects in a signal for Linux kernel NAT module use, so don't - * expect it to be a full ASN.1 library. - * - * Features: - * - * 1. Small. The total size of code plus data is less than 20 KB (IA32). - * 2. Fast. Decoding Netmeeting's Setup signal 1 million times on a PIII 866 - * takes only 3.9 seconds. - * 3. No memory allocation. It uses a static object. No need to initialize or - * cleanup. - * 4. Thread safe. - * 5. Support embedded architectures that has no misaligned memory access - * support. - * - * Limitations: - * - * 1. At most 30 faststart entries. Actually this is limited by ethernet's MTU. - * If a Setup signal contains more than 30 faststart, the packet size will - * very likely exceed the MTU size, then the TPKT will be fragmented. I - * don't know how to handle this in a Netfilter module. Anybody can help? - * Although I think 30 is enough for most of the cases. - * 2. IPv4 addresses only. - * - ****************************************************************************/ - -#ifndef _IP_CONNTRACK_HELPER_H323_ASN1_H_ -#define _IP_CONNTRACK_HELPER_H323_ASN1_H_ - -/***************************************************************************** - * H.323 Types - ****************************************************************************/ -#include "ip_conntrack_helper_h323_types.h" - -typedef struct { - enum { - Q931_NationalEscape = 0x00, - Q931_Alerting = 0x01, - Q931_CallProceeding = 0x02, - Q931_Connect = 0x07, - Q931_ConnectAck = 0x0F, - Q931_Progress = 0x03, - Q931_Setup = 0x05, - Q931_SetupAck = 0x0D, - Q931_Resume = 0x26, - Q931_ResumeAck = 0x2E, - Q931_ResumeReject = 0x22, - Q931_Suspend = 0x25, - Q931_SuspendAck = 0x2D, - Q931_SuspendReject = 0x21, - Q931_UserInformation = 0x20, - Q931_Disconnect = 0x45, - Q931_Release = 0x4D, - Q931_ReleaseComplete = 0x5A, - Q931_Restart = 0x46, - Q931_RestartAck = 0x4E, - Q931_Segment = 0x60, - Q931_CongestionCtrl = 0x79, - Q931_Information = 0x7B, - Q931_Notify = 0x6E, - Q931_Status = 0x7D, - Q931_StatusEnquiry = 0x75, - Q931_Facility = 0x62 - } MessageType; - H323_UserInformation UUIE; -} Q931; - -/***************************************************************************** - * Decode Functions Return Codes - ****************************************************************************/ - -#define H323_ERROR_NONE 0 /* Decoded successfully */ -#define H323_ERROR_STOP 1 /* Decoding stopped, not really an error */ -#define H323_ERROR_BOUND -1 -#define H323_ERROR_RANGE -2 - - -/***************************************************************************** - * Decode Functions - ****************************************************************************/ - -int DecodeRasMessage(unsigned char *buf, size_t sz, RasMessage * ras); -int DecodeQ931(unsigned char *buf, size_t sz, Q931 * q931); -int DecodeMultimediaSystemControlMessage(unsigned char *buf, size_t sz, - MultimediaSystemControlMessage * - mscm); - -#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 cc98f7aa5ab..00000000000 --- a/net/ipv4/netfilter/ip_conntrack_helper_h323_types.h +++ /dev/null @@ -1,938 +0,0 @@ -/* Generated by Jing Min Zhao's ASN.1 parser, Mar 15 2006 - * - * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net> - * - * This source code is licensed under General Public License version 2. - */ - -typedef struct TransportAddress_ipAddress { /* SEQUENCE */ - int options; /* No use */ - unsigned ip; -} TransportAddress_ipAddress; - -typedef struct TransportAddress { /* CHOICE */ - enum { - eTransportAddress_ipAddress, - eTransportAddress_ipSourceRoute, - eTransportAddress_ipxAddress, - eTransportAddress_ip6Address, - eTransportAddress_netBios, - eTransportAddress_nsap, - eTransportAddress_nonStandardAddress, - } choice; - union { - TransportAddress_ipAddress ipAddress; - }; -} TransportAddress; - -typedef struct DataProtocolCapability { /* CHOICE */ - enum { - eDataProtocolCapability_nonStandard, - eDataProtocolCapability_v14buffered, - eDataProtocolCapability_v42lapm, - eDataProtocolCapability_hdlcFrameTunnelling, - eDataProtocolCapability_h310SeparateVCStack, - eDataProtocolCapability_h310SingleVCStack, - eDataProtocolCapability_transparent, - eDataProtocolCapability_segmentationAndReassembly, - eDataProtocolCapability_hdlcFrameTunnelingwSAR, - eDataProtocolCapability_v120, - eDataProtocolCapability_separateLANStack, - eDataProtocolCapability_v76wCompression, - eDataProtocolCapability_tcp, - eDataProtocolCapability_udp, - } choice; -} DataProtocolCapability; - -typedef struct DataApplicationCapability_application { /* CHOICE */ - enum { - eDataApplicationCapability_application_nonStandard, - eDataApplicationCapability_application_t120, - eDataApplicationCapability_application_dsm_cc, - eDataApplicationCapability_application_userData, - eDataApplicationCapability_application_t84, - eDataApplicationCapability_application_t434, - eDataApplicationCapability_application_h224, - eDataApplicationCapability_application_nlpid, - eDataApplicationCapability_application_dsvdControl, - eDataApplicationCapability_application_h222DataPartitioning, - eDataApplicationCapability_application_t30fax, - eDataApplicationCapability_application_t140, - eDataApplicationCapability_application_t38fax, - eDataApplicationCapability_application_genericDataCapability, - } choice; - union { - DataProtocolCapability t120; - }; -} DataApplicationCapability_application; - -typedef struct DataApplicationCapability { /* SEQUENCE */ - int options; /* No use */ - DataApplicationCapability_application application; -} DataApplicationCapability; - -typedef struct DataType { /* CHOICE */ - enum { - eDataType_nonStandard, - eDataType_nullData, - eDataType_videoData, - eDataType_audioData, - eDataType_data, - eDataType_encryptionData, - eDataType_h235Control, - eDataType_h235Media, - eDataType_multiplexedStream, - } choice; - union { - DataApplicationCapability data; - }; -} DataType; - -typedef struct UnicastAddress_iPAddress { /* SEQUENCE */ - int options; /* No use */ - unsigned network; -} UnicastAddress_iPAddress; - -typedef struct UnicastAddress { /* CHOICE */ - enum { - eUnicastAddress_iPAddress, - eUnicastAddress_iPXAddress, - eUnicastAddress_iP6Address, - eUnicastAddress_netBios, - eUnicastAddress_iPSourceRouteAddress, - eUnicastAddress_nsap, - eUnicastAddress_nonStandardAddress, - } choice; - union { - UnicastAddress_iPAddress iPAddress; - }; -} UnicastAddress; - -typedef struct H245_TransportAddress { /* CHOICE */ - enum { - eH245_TransportAddress_unicastAddress, - eH245_TransportAddress_multicastAddress, - } choice; - union { - UnicastAddress unicastAddress; - }; -} H245_TransportAddress; - -typedef struct H2250LogicalChannelParameters { /* SEQUENCE */ - enum { - eH2250LogicalChannelParameters_nonStandard = (1 << 31), - eH2250LogicalChannelParameters_associatedSessionID = - (1 << 30), - eH2250LogicalChannelParameters_mediaChannel = (1 << 29), - eH2250LogicalChannelParameters_mediaGuaranteedDelivery = - (1 << 28), - eH2250LogicalChannelParameters_mediaControlChannel = - (1 << 27), - eH2250LogicalChannelParameters_mediaControlGuaranteedDelivery - = (1 << 26), - eH2250LogicalChannelParameters_silenceSuppression = (1 << 25), - eH2250LogicalChannelParameters_destination = (1 << 24), - eH2250LogicalChannelParameters_dynamicRTPPayloadType = - (1 << 23), - eH2250LogicalChannelParameters_mediaPacketization = (1 << 22), - eH2250LogicalChannelParameters_transportCapability = - (1 << 21), - eH2250LogicalChannelParameters_redundancyEncoding = (1 << 20), - eH2250LogicalChannelParameters_source = (1 << 19), - } options; - H245_TransportAddress mediaChannel; - H245_TransportAddress mediaControlChannel; -} H2250LogicalChannelParameters; - -typedef struct OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters { /* CHOICE */ - enum { - eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h222LogicalChannelParameters, - eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h223LogicalChannelParameters, - eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_v76LogicalChannelParameters, - eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters, - eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_none, - } choice; - union { - H2250LogicalChannelParameters h2250LogicalChannelParameters; - }; -} OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters; - -typedef struct OpenLogicalChannel_forwardLogicalChannelParameters { /* SEQUENCE */ - enum { - eOpenLogicalChannel_forwardLogicalChannelParameters_portNumber - = (1 << 31), - eOpenLogicalChannel_forwardLogicalChannelParameters_forwardLogicalChannelDependency - = (1 << 30), - eOpenLogicalChannel_forwardLogicalChannelParameters_replacementFor - = (1 << 29), - } options; - DataType dataType; - OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters - multiplexParameters; -} OpenLogicalChannel_forwardLogicalChannelParameters; - -typedef struct OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters { /* CHOICE */ - enum { - eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h223LogicalChannelParameters, - eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_v76LogicalChannelParameters, - eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters, - } choice; - union { - H2250LogicalChannelParameters h2250LogicalChannelParameters; - }; -} OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters; - -typedef struct OpenLogicalChannel_reverseLogicalChannelParameters { /* SEQUENCE */ - enum { - eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters - = (1 << 31), - eOpenLogicalChannel_reverseLogicalChannelParameters_reverseLogicalChannelDependency - = (1 << 30), - eOpenLogicalChannel_reverseLogicalChannelParameters_replacementFor - = (1 << 29), - } options; - OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters - multiplexParameters; -} OpenLogicalChannel_reverseLogicalChannelParameters; - -typedef struct NetworkAccessParameters_networkAddress { /* CHOICE */ - enum { - eNetworkAccessParameters_networkAddress_q2931Address, - eNetworkAccessParameters_networkAddress_e164Address, - eNetworkAccessParameters_networkAddress_localAreaAddress, - } choice; - union { - H245_TransportAddress localAreaAddress; - }; -} NetworkAccessParameters_networkAddress; - -typedef struct NetworkAccessParameters { /* SEQUENCE */ - enum { - eNetworkAccessParameters_distribution = (1 << 31), - eNetworkAccessParameters_externalReference = (1 << 30), - eNetworkAccessParameters_t120SetupProcedure = (1 << 29), - } options; - NetworkAccessParameters_networkAddress networkAddress; -} NetworkAccessParameters; - -typedef struct OpenLogicalChannel { /* SEQUENCE */ - enum { - eOpenLogicalChannel_reverseLogicalChannelParameters = - (1 << 31), - eOpenLogicalChannel_separateStack = (1 << 30), - eOpenLogicalChannel_encryptionSync = (1 << 29), - } options; - OpenLogicalChannel_forwardLogicalChannelParameters - forwardLogicalChannelParameters; - OpenLogicalChannel_reverseLogicalChannelParameters - reverseLogicalChannelParameters; - NetworkAccessParameters separateStack; -} OpenLogicalChannel; - -typedef struct Setup_UUIE_fastStart { /* SEQUENCE OF */ - int count; - OpenLogicalChannel item[30]; -} Setup_UUIE_fastStart; - -typedef struct Setup_UUIE { /* SEQUENCE */ - enum { - eSetup_UUIE_h245Address = (1 << 31), - eSetup_UUIE_sourceAddress = (1 << 30), - eSetup_UUIE_destinationAddress = (1 << 29), - eSetup_UUIE_destCallSignalAddress = (1 << 28), - eSetup_UUIE_destExtraCallInfo = (1 << 27), - eSetup_UUIE_destExtraCRV = (1 << 26), - eSetup_UUIE_callServices = (1 << 25), - eSetup_UUIE_sourceCallSignalAddress = (1 << 24), - eSetup_UUIE_remoteExtensionAddress = (1 << 23), - eSetup_UUIE_callIdentifier = (1 << 22), - eSetup_UUIE_h245SecurityCapability = (1 << 21), - eSetup_UUIE_tokens = (1 << 20), - eSetup_UUIE_cryptoTokens = (1 << 19), - eSetup_UUIE_fastStart = (1 << 18), - eSetup_UUIE_mediaWaitForConnect = (1 << 17), - eSetup_UUIE_canOverlapSend = (1 << 16), - eSetup_UUIE_endpointIdentifier = (1 << 15), - eSetup_UUIE_multipleCalls = (1 << 14), - eSetup_UUIE_maintainConnection = (1 << 13), - eSetup_UUIE_connectionParameters = (1 << 12), - eSetup_UUIE_language = (1 << 11), - eSetup_UUIE_presentationIndicator = (1 << 10), - eSetup_UUIE_screeningIndicator = (1 << 9), - eSetup_UUIE_serviceControl = (1 << 8), - eSetup_UUIE_symmetricOperationRequired = (1 << 7), - eSetup_UUIE_capacity = (1 << 6), - eSetup_UUIE_circuitInfo = (1 << 5), - eSetup_UUIE_desiredProtocols = (1 << 4), - eSetup_UUIE_neededFeatures = (1 << 3), - eSetup_UUIE_desiredFeatures = (1 << 2), - eSetup_UUIE_supportedFeatures = (1 << 1), - eSetup_UUIE_parallelH245Control = (1 << 0), - } options; - TransportAddress h245Address; - TransportAddress destCallSignalAddress; - TransportAddress sourceCallSignalAddress; - Setup_UUIE_fastStart fastStart; -} Setup_UUIE; - -typedef struct CallProceeding_UUIE_fastStart { /* SEQUENCE OF */ - int count; - OpenLogicalChannel item[30]; -} CallProceeding_UUIE_fastStart; - -typedef struct CallProceeding_UUIE { /* SEQUENCE */ - enum { - eCallProceeding_UUIE_h245Address = (1 << 31), - eCallProceeding_UUIE_callIdentifier = (1 << 30), - eCallProceeding_UUIE_h245SecurityMode = (1 << 29), - eCallProceeding_UUIE_tokens = (1 << 28), - eCallProceeding_UUIE_cryptoTokens = (1 << 27), - eCallProceeding_UUIE_fastStart = (1 << 26), - eCallProceeding_UUIE_multipleCalls = (1 << 25), - eCallProceeding_UUIE_maintainConnection = (1 << 24), - eCallProceeding_UUIE_fastConnectRefused = (1 << 23), - eCallProceeding_UUIE_featureSet = (1 << 22), - } options; - TransportAddress h245Address; - CallProceeding_UUIE_fastStart fastStart; -} CallProceeding_UUIE; - -typedef struct Connect_UUIE_fastStart { /* SEQUENCE OF */ - int count; - OpenLogicalChannel item[30]; -} Connect_UUIE_fastStart; - -typedef struct Connect_UUIE { /* SEQUENCE */ - enum { - eConnect_UUIE_h245Address = (1 << 31), - eConnect_UUIE_callIdentifier = (1 << 30), - eConnect_UUIE_h245SecurityMode = (1 << 29), - eConnect_UUIE_tokens = (1 << 28), - eConnect_UUIE_cryptoTokens = (1 << 27), - eConnect_UUIE_fastStart = (1 << 26), - eConnect_UUIE_multipleCalls = (1 << 25), - eConnect_UUIE_maintainConnection = (1 << 24), - eConnect_UUIE_language = (1 << 23), - eConnect_UUIE_connectedAddress = (1 << 22), - eConnect_UUIE_presentationIndicator = (1 << 21), - eConnect_UUIE_screeningIndicator = (1 << 20), - eConnect_UUIE_fastConnectRefused = (1 << 19), - eConnect_UUIE_serviceControl = (1 << 18), - eConnect_UUIE_capacity = (1 << 17), - eConnect_UUIE_featureSet = (1 << 16), - } options; - TransportAddress h245Address; - Connect_UUIE_fastStart fastStart; -} Connect_UUIE; - -typedef struct Alerting_UUIE_fastStart { /* SEQUENCE OF */ - int count; - OpenLogicalChannel item[30]; -} Alerting_UUIE_fastStart; - -typedef struct Alerting_UUIE { /* SEQUENCE */ - enum { - eAlerting_UUIE_h245Address = (1 << 31), - eAlerting_UUIE_callIdentifier = (1 << 30), - eAlerting_UUIE_h245SecurityMode = (1 << 29), - eAlerting_UUIE_tokens = (1 << 28), - eAlerting_UUIE_cryptoTokens = (1 << 27), - eAlerting_UUIE_fastStart = (1 << 26), - eAlerting_UUIE_multipleCalls = (1 << 25), - eAlerting_UUIE_maintainConnection = (1 << 24), - eAlerting_UUIE_alertingAddress = (1 << 23), - eAlerting_UUIE_presentationIndicator = (1 << 22), - eAlerting_UUIE_screeningIndicator = (1 << 21), - eAlerting_UUIE_fastConnectRefused = (1 << 20), - eAlerting_UUIE_serviceControl = (1 << 19), - eAlerting_UUIE_capacity = (1 << 18), - eAlerting_UUIE_featureSet = (1 << 17), - } options; - TransportAddress h245Address; - Alerting_UUIE_fastStart fastStart; -} Alerting_UUIE; - -typedef struct Information_UUIE_fastStart { /* SEQUENCE OF */ - int count; - OpenLogicalChannel item[30]; -} Information_UUIE_fastStart; - -typedef struct Information_UUIE { /* SEQUENCE */ - enum { - eInformation_UUIE_callIdentifier = (1 << 31), - eInformation_UUIE_tokens = (1 << 30), - eInformation_UUIE_cryptoTokens = (1 << 29), - eInformation_UUIE_fastStart = (1 << 28), - eInformation_UUIE_fastConnectRefused = (1 << 27), - eInformation_UUIE_circuitInfo = (1 << 26), - } options; - Information_UUIE_fastStart fastStart; -} Information_UUIE; - -typedef struct FacilityReason { /* CHOICE */ - enum { - eFacilityReason_routeCallToGatekeeper, - eFacilityReason_callForwarded, - eFacilityReason_routeCallToMC, - eFacilityReason_undefinedReason, - eFacilityReason_conferenceListChoice, - eFacilityReason_startH245, - eFacilityReason_noH245, - eFacilityReason_newTokens, - eFacilityReason_featureSetUpdate, - eFacilityReason_forwardedElements, - eFacilityReason_transportedInformation, - } choice; -} FacilityReason; - -typedef struct Facility_UUIE_fastStart { /* SEQUENCE OF */ - int count; - OpenLogicalChannel item[30]; -} Facility_UUIE_fastStart; - -typedef struct Facility_UUIE { /* SEQUENCE */ - enum { - eFacility_UUIE_alternativeAddress = (1 << 31), - eFacility_UUIE_alternativeAliasAddress = (1 << 30), - eFacility_UUIE_conferenceID = (1 << 29), - eFacility_UUIE_callIdentifier = (1 << 28), - eFacility_UUIE_destExtraCallInfo = (1 << 27), - eFacility_UUIE_remoteExtensionAddress = (1 << 26), - eFacility_UUIE_tokens = (1 << 25), - eFacility_UUIE_cryptoTokens = (1 << 24), - eFacility_UUIE_conferences = (1 << 23), - eFacility_UUIE_h245Address = (1 << 22), - eFacility_UUIE_fastStart = (1 << 21), - eFacility_UUIE_multipleCalls = (1 << 20), - eFacility_UUIE_maintainConnection = (1 << 19), - eFacility_UUIE_fastConnectRefused = (1 << 18), - eFacility_UUIE_serviceControl = (1 << 17), - eFacility_UUIE_circuitInfo = (1 << 16), - eFacility_UUIE_featureSet = (1 << 15), - eFacility_UUIE_destinationInfo = (1 << 14), - eFacility_UUIE_h245SecurityMode = (1 << 13), - } options; - FacilityReason reason; - TransportAddress h245Address; - Facility_UUIE_fastStart fastStart; -} Facility_UUIE; - -typedef struct Progress_UUIE_fastStart { /* SEQUENCE OF */ - int count; - OpenLogicalChannel item[30]; -} Progress_UUIE_fastStart; - -typedef struct Progress_UUIE { /* SEQUENCE */ - enum { - eProgress_UUIE_h245Address = (1 << 31), - eProgress_UUIE_h245SecurityMode = (1 << 30), - eProgress_UUIE_tokens = (1 << 29), - eProgress_UUIE_cryptoTokens = (1 << 28), - eProgress_UUIE_fastStart = (1 << 27), - eProgress_UUIE_multipleCalls = (1 << 26), - eProgress_UUIE_maintainConnection = (1 << 25), - eProgress_UUIE_fastConnectRefused = (1 << 24), - } options; - TransportAddress h245Address; - Progress_UUIE_fastStart fastStart; -} Progress_UUIE; - -typedef struct H323_UU_PDU_h323_message_body { /* CHOICE */ - enum { - eH323_UU_PDU_h323_message_body_setup, - eH323_UU_PDU_h323_message_body_callProceeding, - eH323_UU_PDU_h323_message_body_connect, - eH323_UU_PDU_h323_message_body_alerting, - eH323_UU_PDU_h323_message_body_information, - eH323_UU_PDU_h323_message_body_releaseComplete, - eH323_UU_PDU_h323_message_body_facility, - eH323_UU_PDU_h323_message_body_progress, - eH323_UU_PDU_h323_message_body_empty, - eH323_UU_PDU_h323_message_body_status, - eH323_UU_PDU_h323_message_body_statusInquiry, - eH323_UU_PDU_h323_message_body_setupAcknowledge, - eH323_UU_PDU_h323_message_body_notify, - } choice; - union { - Setup_UUIE setup; - CallProceeding_UUIE callProceeding; - Connect_UUIE connect; - Alerting_UUIE alerting; - Information_UUIE information; - Facility_UUIE facility; - Progress_UUIE progress; - }; -} H323_UU_PDU_h323_message_body; - -typedef struct RequestMessage { /* CHOICE */ - enum { - eRequestMessage_nonStandard, - eRequestMessage_masterSlaveDetermination, - eRequestMessage_terminalCapabilitySet, - eRequestMessage_openLogicalChannel, - eRequestMessage_closeLogicalChannel, - eRequestMessage_requestChannelClose, - eRequestMessage_multiplexEntrySend, - eRequestMessage_requestMultiplexEntry, - eRequestMessage_requestMode, - eRequestMessage_roundTripDelayRequest, - eRequestMessage_maintenanceLoopRequest, - eRequestMessage_communicationModeRequest, - eRequestMessage_conferenceRequest, - eRequestMessage_multilinkRequest, - eRequestMessage_logicalChannelRateRequest, - } choice; - union { - OpenLogicalChannel openLogicalChannel; - }; -} RequestMessage; - -typedef struct OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters { /* CHOICE */ - enum { - eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h222LogicalChannelParameters, - eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters, - } choice; - union { - H2250LogicalChannelParameters h2250LogicalChannelParameters; - }; -} OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters; - -typedef struct OpenLogicalChannelAck_reverseLogicalChannelParameters { /* SEQUENCE */ - enum { - eOpenLogicalChannelAck_reverseLogicalChannelParameters_portNumber - = (1 << 31), - eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters - = (1 << 30), - eOpenLogicalChannelAck_reverseLogicalChannelParameters_replacementFor - = (1 << 29), - } options; - OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters - multiplexParameters; -} OpenLogicalChannelAck_reverseLogicalChannelParameters; - -typedef struct H2250LogicalChannelAckParameters { /* SEQUENCE */ - enum { - eH2250LogicalChannelAckParameters_nonStandard = (1 << 31), - eH2250LogicalChannelAckParameters_sessionID = (1 << 30), - eH2250LogicalChannelAckParameters_mediaChannel = (1 << 29), - eH2250LogicalChannelAckParameters_mediaControlChannel = - (1 << 28), - eH2250LogicalChannelAckParameters_dynamicRTPPayloadType = - (1 << 27), - eH2250LogicalChannelAckParameters_flowControlToZero = - (1 << 26), - eH2250LogicalChannelAckParameters_portNumber = (1 << 25), - } options; - H245_TransportAddress mediaChannel; - H245_TransportAddress mediaControlChannel; -} H2250LogicalChannelAckParameters; - -typedef struct OpenLogicalChannelAck_forwardMultiplexAckParameters { /* CHOICE */ - enum { - eOpenLogicalChannelAck_forwardMultiplexAckParameters_h2250LogicalChannelAckParameters, - } choice; - union { - H2250LogicalChannelAckParameters - h2250LogicalChannelAckParameters; - }; -} OpenLogicalChannelAck_forwardMultiplexAckParameters; - -typedef struct OpenLogicalChannelAck { /* SEQUENCE */ - enum { - eOpenLogicalChannelAck_reverseLogicalChannelParameters = - (1 << 31), - eOpenLogicalChannelAck_separateStack = (1 << 30), - eOpenLogicalChannelAck_forwardMultiplexAckParameters = - (1 << 29), - eOpenLogicalChannelAck_encryptionSync = (1 << 28), - } options; - OpenLogicalChannelAck_reverseLogicalChannelParameters - reverseLogicalChannelParameters; - OpenLogicalChannelAck_forwardMultiplexAckParameters - forwardMultiplexAckParameters; -} OpenLogicalChannelAck; - -typedef struct ResponseMessage { /* CHOICE */ - enum { - eResponseMessage_nonStandard, - eResponseMessage_masterSlaveDeterminationAck, - eResponseMessage_masterSlaveDeterminationReject, - eResponseMessage_terminalCapabilitySetAck, - eResponseMessage_terminalCapabilitySetReject, - eResponseMessage_openLogicalChannelAck, - eResponseMessage_openLogicalChannelReject, - eResponseMessage_closeLogicalChannelAck, - eResponseMessage_requestChannelCloseAck, - eResponseMessage_requestChannelCloseReject, - eResponseMessage_multiplexEntrySendAck, - eResponseMessage_multiplexEntrySendReject, - eResponseMessage_requestMultiplexEntryAck, - eResponseMessage_requestMultiplexEntryReject, - eResponseMessage_requestModeAck, - eResponseMessage_requestModeReject, - eResponseMessage_roundTripDelayResponse, - eResponseMessage_maintenanceLoopAck, - eResponseMessage_maintenanceLoopReject, - eResponseMessage_communicationModeResponse, - eResponseMessage_conferenceResponse, - eResponseMessage_multilinkResponse, - eResponseMessage_logicalChannelRateAcknowledge, - eResponseMessage_logicalChannelRateReject, - } choice; - union { - OpenLogicalChannelAck openLogicalChannelAck; - }; -} ResponseMessage; - -typedef struct MultimediaSystemControlMessage { /* CHOICE */ - enum { - eMultimediaSystemControlMessage_request, - eMultimediaSystemControlMessage_response, - eMultimediaSystemControlMessage_command, - eMultimediaSystemControlMessage_indication, - } choice; - union { - RequestMessage request; - ResponseMessage response; - }; -} MultimediaSystemControlMessage; - -typedef struct H323_UU_PDU_h245Control { /* SEQUENCE OF */ - int count; - MultimediaSystemControlMessage item[4]; -} H323_UU_PDU_h245Control; - -typedef struct H323_UU_PDU { /* SEQUENCE */ - enum { - eH323_UU_PDU_nonStandardData = (1 << 31), - eH323_UU_PDU_h4501SupplementaryService = (1 << 30), - eH323_UU_PDU_h245Tunneling = (1 << 29), - eH323_UU_PDU_h245Control = (1 << 28), - eH323_UU_PDU_nonStandardControl = (1 << 27), - eH323_UU_PDU_callLinkage = (1 << 26), - eH323_UU_PDU_tunnelledSignallingMessage = (1 << 25), - eH323_UU_PDU_provisionalRespToH245Tunneling = (1 << 24), - eH323_UU_PDU_stimulusControl = (1 << 23), - eH323_UU_PDU_genericData = (1 << 22), - } options; - H323_UU_PDU_h323_message_body h323_message_body; - H323_UU_PDU_h245Control h245Control; -} H323_UU_PDU; - -typedef struct H323_UserInformation { /* SEQUENCE */ - enum { - eH323_UserInformation_user_data = (1 << 31), - } options; - H323_UU_PDU h323_uu_pdu; -} H323_UserInformation; - -typedef struct GatekeeperRequest { /* SEQUENCE */ - enum { - eGatekeeperRequest_nonStandardData = (1 << 31), - eGatekeeperRequest_gatekeeperIdentifier = (1 << 30), - eGatekeeperRequest_callServices = (1 << 29), - eGatekeeperRequest_endpointAlias = (1 << 28), - eGatekeeperRequest_alternateEndpoints = (1 << 27), - eGatekeeperRequest_tokens = (1 << 26), - eGatekeeperRequest_cryptoTokens = (1 << 25), - eGatekeeperRequest_authenticationCapability = (1 << 24), - eGatekeeperRequest_algorithmOIDs = (1 << 23), - eGatekeeperRequest_integrity = (1 << 22), - eGatekeeperRequest_integrityCheckValue = (1 << 21), - eGatekeeperRequest_supportsAltGK = (1 << 20), - eGatekeeperRequest_featureSet = (1 << 19), - eGatekeeperRequest_genericData = (1 << 18), - } options; - TransportAddress rasAddress; -} GatekeeperRequest; - -typedef struct GatekeeperConfirm { /* SEQUENCE */ - enum { - eGatekeeperConfirm_nonStandardData = (1 << 31), - eGatekeeperConfirm_gatekeeperIdentifier = (1 << 30), - eGatekeeperConfirm_alternateGatekeeper = (1 << 29), - eGatekeeperConfirm_authenticationMode = (1 << 28), - eGatekeeperConfirm_tokens = (1 << 27), - eGatekeeperConfirm_cryptoTokens = (1 << 26), - eGatekeeperConfirm_algorithmOID = (1 << 25), - eGatekeeperConfirm_integrity = (1 << 24), - eGatekeeperConfirm_integrityCheckValue = (1 << 23), - eGatekeeperConfirm_featureSet = (1 << 22), - eGatekeeperConfirm_genericData = (1 << 21), - } options; - TransportAddress rasAddress; -} GatekeeperConfirm; - -typedef struct RegistrationRequest_callSignalAddress { /* SEQUENCE OF */ - int count; - TransportAddress item[10]; -} RegistrationRequest_callSignalAddress; - -typedef struct RegistrationRequest_rasAddress { /* SEQUENCE OF */ - int count; - TransportAddress item[10]; -} RegistrationRequest_rasAddress; - -typedef struct RegistrationRequest { /* SEQUENCE */ - enum { - eRegistrationRequest_nonStandardData = (1 << 31), - eRegistrationRequest_terminalAlias = (1 << 30), - eRegistrationRequest_gatekeeperIdentifier = (1 << 29), - eRegistrationRequest_alternateEndpoints = (1 << 28), - eRegistrationRequest_timeToLive = (1 << 27), - eRegistrationRequest_tokens = (1 << 26), - eRegistrationRequest_cryptoTokens = (1 << 25), - eRegistrationRequest_integrityCheckValue = (1 << 24), - eRegistrationRequest_keepAlive = (1 << 23), - eRegistrationRequest_endpointIdentifier = (1 << 22), - eRegistrationRequest_willSupplyUUIEs = (1 << 21), - eRegistrationRequest_maintainConnection = (1 << 20), - eRegistrationRequest_alternateTransportAddresses = (1 << 19), - eRegistrationRequest_additiveRegistration = (1 << 18), - eRegistrationRequest_terminalAliasPattern = (1 << 17), - eRegistrationRequest_supportsAltGK = (1 << 16), - eRegistrationRequest_usageReportingCapability = (1 << 15), - eRegistrationRequest_multipleCalls = (1 << 14), - eRegistrationRequest_supportedH248Packages = (1 << 13), - eRegistrationRequest_callCreditCapability = (1 << 12), - eRegistrationRequest_capacityReportingCapability = (1 << 11), - eRegistrationRequest_capacity = (1 << 10), - eRegistrationRequest_featureSet = (1 << 9), - eRegistrationRequest_genericData = (1 << 8), - } options; - RegistrationRequest_callSignalAddress callSignalAddress; - RegistrationRequest_rasAddress rasAddress; - unsigned timeToLive; -} RegistrationRequest; - -typedef struct RegistrationConfirm_callSignalAddress { /* SEQUENCE OF */ - int count; - TransportAddress item[10]; -} RegistrationConfirm_callSignalAddress; - -typedef struct RegistrationConfirm { /* SEQUENCE */ - enum { - eRegistrationConfirm_nonStandardData = (1 << 31), - eRegistrationConfirm_terminalAlias = (1 << 30), - eRegistrationConfirm_gatekeeperIdentifier = (1 << 29), - eRegistrationConfirm_alternateGatekeeper = (1 << 28), - eRegistrationConfirm_timeToLive = (1 << 27), - eRegistrationConfirm_tokens = (1 << 26), - eRegistrationConfirm_cryptoTokens = (1 << 25), - eRegistrationConfirm_integrityCheckValue = (1 << 24), - eRegistrationConfirm_willRespondToIRR = (1 << 23), - eRegistrationConfirm_preGrantedARQ = (1 << 22), - eRegistrationConfirm_maintainConnection = (1 << 21), - eRegistrationConfirm_serviceControl = (1 << 20), - eRegistrationConfirm_supportsAdditiveRegistration = (1 << 19), - eRegistrationConfirm_terminalAliasPattern = (1 << 18), - eRegistrationConfirm_supportedPrefixes = (1 << 17), - eRegistrationConfirm_usageSpec = (1 << 16), - eRegistrationConfirm_featureServerAlias = (1 << 15), - eRegistrationConfirm_capacityReportingSpec = (1 << 14), - eRegistrationConfirm_featureSet = (1 << 13), - eRegistrationConfirm_genericData = (1 << 12), - } options; - RegistrationConfirm_callSignalAddress callSignalAddress; - unsigned timeToLive; -} RegistrationConfirm; - -typedef struct UnregistrationRequest_callSignalAddress { /* SEQUENCE OF */ - int count; - TransportAddress item[10]; -} UnregistrationRequest_callSignalAddress; - -typedef struct UnregistrationRequest { /* SEQUENCE */ - enum { - eUnregistrationRequest_endpointAlias = (1 << 31), - eUnregistrationRequest_nonStandardData = (1 << 30), - eUnregistrationRequest_endpointIdentifier = (1 << 29), - eUnregistrationRequest_alternateEndpoints = (1 << 28), - eUnregistrationRequest_gatekeeperIdentifier = (1 << 27), - eUnregistrationRequest_tokens = (1 << 26), - eUnregistrationRequest_cryptoTokens = (1 << 25), - eUnregistrationRequest_integrityCheckValue = (1 << 24), - eUnregistrationRequest_reason = (1 << 23), - eUnregistrationRequest_endpointAliasPattern = (1 << 22), - eUnregistrationRequest_supportedPrefixes = (1 << 21), - eUnregistrationRequest_alternateGatekeeper = (1 << 20), - eUnregistrationRequest_genericData = (1 << 19), - } options; - UnregistrationRequest_callSignalAddress callSignalAddress; -} UnregistrationRequest; - -typedef struct AdmissionRequest { /* SEQUENCE */ - enum { - eAdmissionRequest_callModel = (1 << 31), - eAdmissionRequest_destinationInfo = (1 << 30), - eAdmissionRequest_destCallSignalAddress = (1 << 29), - eAdmissionRequest_destExtraCallInfo = (1 << 28), - eAdmissionRequest_srcCallSignalAddress = (1 << 27), - eAdmissionRequest_nonStandardData = (1 << 26), - eAdmissionRequest_callServices = (1 << 25), - eAdmissionRequest_canMapAlias = (1 << 24), - eAdmissionRequest_callIdentifier = (1 << 23), - eAdmissionRequest_srcAlternatives = (1 << 22), - eAdmissionRequest_destAlternatives = (1 << 21), - eAdmissionRequest_gatekeeperIdentifier = (1 << 20), - eAdmissionRequest_tokens = (1 << 19), - eAdmissionRequest_cryptoTokens = (1 << 18), - eAdmissionRequest_integrityCheckValue = (1 << 17), - eAdmissionRequest_transportQOS = (1 << 16), - eAdmissionRequest_willSupplyUUIEs = (1 << 15), - eAdmissionRequest_callLinkage = (1 << 14), - eAdmissionRequest_gatewayDataRate = (1 << 13), - eAdmissionRequest_capacity = (1 << 12), - eAdmissionRequest_circuitInfo = (1 << 11), - eAdmissionRequest_desiredProtocols = (1 << 10), - eAdmissionRequest_desiredTunnelledProtocol = (1 << 9), - eAdmissionRequest_featureSet = (1 << 8), - eAdmissionRequest_genericData = (1 << 7), - } options; - TransportAddress destCallSignalAddress; - TransportAddress srcCallSignalAddress; -} AdmissionRequest; - -typedef struct AdmissionConfirm { /* SEQUENCE */ - enum { - eAdmissionConfirm_irrFrequency = (1 << 31), - eAdmissionConfirm_nonStandardData = (1 << 30), - eAdmissionConfirm_destinationInfo = (1 << 29), - eAdmissionConfirm_destExtraCallInfo = (1 << 28), - eAdmissionConfirm_destinationType = (1 << 27), - eAdmissionConfirm_remoteExtensionAddress = (1 << 26), - eAdmissionConfirm_alternateEndpoints = (1 << 25), - eAdmissionConfirm_tokens = (1 << 24), - eAdmissionConfirm_cryptoTokens = (1 << 23), - eAdmissionConfirm_integrityCheckValue = (1 << 22), - eAdmissionConfirm_transportQOS = (1 << 21), - eAdmissionConfirm_willRespondToIRR = (1 << 20), - eAdmissionConfirm_uuiesRequested = (1 << 19), - eAdmissionConfirm_language = (1 << 18), - eAdmissionConfirm_alternateTransportAddresses = (1 << 17), - eAdmissionConfirm_useSpecifiedTransport = (1 << 16), - eAdmissionConfirm_circuitInfo = (1 << 15), - eAdmissionConfirm_usageSpec = (1 << 14), - eAdmissionConfirm_supportedProtocols = (1 << 13), - eAdmissionConfirm_serviceControl = (1 << 12), - eAdmissionConfirm_multipleCalls = (1 << 11), - eAdmissionConfirm_featureSet = (1 << 10), - eAdmissionConfirm_genericData = (1 << 9), - } options; - TransportAddress destCallSignalAddress; -} AdmissionConfirm; - -typedef struct LocationRequest { /* SEQUENCE */ - enum { - eLocationRequest_endpointIdentifier = (1 << 31), - eLocationRequest_nonStandardData = (1 << 30), - eLocationRequest_sourceInfo = (1 << 29), - eLocationRequest_canMapAlias = (1 << 28), - eLocationRequest_gatekeeperIdentifier = (1 << 27), - eLocationRequest_tokens = (1 << 26), - eLocationRequest_cryptoTokens = (1 << 25), - eLocationRequest_integrityCheckValue = (1 << 24), - eLocationRequest_desiredProtocols = (1 << 23), - eLocationRequest_desiredTunnelledProtocol = (1 << 22), - eLocationRequest_featureSet = (1 << 21), - eLocationRequest_genericData = (1 << 20), - eLocationRequest_hopCount = (1 << 19), - eLocationRequest_circuitInfo = (1 << 18), - } options; - TransportAddress replyAddress; -} LocationRequest; - -typedef struct LocationConfirm { /* SEQUENCE */ - enum { - eLocationConfirm_nonStandardData = (1 << 31), - eLocationConfirm_destinationInfo = (1 << 30), - eLocationConfirm_destExtraCallInfo = (1 << 29), - eLocationConfirm_destinationType = (1 << 28), - eLocationConfirm_remoteExtensionAddress = (1 << 27), - eLocationConfirm_alternateEndpoints = (1 << 26), - eLocationConfirm_tokens = (1 << 25), - eLocationConfirm_cryptoTokens = (1 << 24), - eLocationConfirm_integrityCheckValue = (1 << 23), - eLocationConfirm_alternateTransportAddresses = (1 << 22), - eLocationConfirm_supportedProtocols = (1 << 21), - eLocationConfirm_multipleCalls = (1 << 20), - eLocationConfirm_featureSet = (1 << 19), - eLocationConfirm_genericData = (1 << 18), - eLocationConfirm_circuitInfo = (1 << 17), - eLocationConfirm_serviceControl = (1 << 16), - } options; - TransportAddress callSignalAddress; - TransportAddress rasAddress; -} LocationConfirm; - -typedef struct InfoRequestResponse_callSignalAddress { /* SEQUENCE OF */ - int count; - TransportAddress item[10]; -} InfoRequestResponse_callSignalAddress; - -typedef struct InfoRequestResponse { /* SEQUENCE */ - enum { - eInfoRequestResponse_nonStandardData = (1 << 31), - eInfoRequestResponse_endpointAlias = (1 << 30), - eInfoRequestResponse_perCallInfo = (1 << 29), - eInfoRequestResponse_tokens = (1 << 28), - eInfoRequestResponse_cryptoTokens = (1 << 27), - eInfoRequestResponse_integrityCheckValue = (1 << 26), - eInfoRequestResponse_needResponse = (1 << 25), - eInfoRequestResponse_capacity = (1 << 24), - eInfoRequestResponse_irrStatus = (1 << 23), - eInfoRequestResponse_unsolicited = (1 << 22), - eInfoRequestResponse_genericData = (1 << 21), - } options; - TransportAddress rasAddress; - InfoRequestResponse_callSignalAddress callSignalAddress; -} InfoRequestResponse; - -typedef struct RasMessage { /* CHOICE */ - enum { - eRasMessage_gatekeeperRequest, - eRasMessage_gatekeeperConfirm, - eRasMessage_gatekeeperReject, - eRasMessage_registrationRequest, - eRasMessage_registrationConfirm, - eRasMessage_registrationReject, - eRasMessage_unregistrationRequest, - eRasMessage_unregistrationConfirm, - eRasMessage_unregistrationReject, - eRasMessage_admissionRequest, - eRasMessage_admissionConfirm, - eRasMessage_admissionReject, - eRasMessage_bandwidthRequest, - eRasMessage_bandwidthConfirm, - eRasMessage_bandwidthReject, - eRasMessage_disengageRequest, - eRasMessage_disengageConfirm, - eRasMessage_disengageReject, - eRasMessage_locationRequest, - eRasMessage_locationConfirm, - eRasMessage_locationReject, - eRasMessage_infoRequest, - eRasMessage_infoRequestResponse, - eRasMessage_nonStandardMessage, - eRasMessage_unknownMessageResponse, - eRasMessage_requestInProgress, - eRasMessage_resourcesAvailableIndicate, - eRasMessage_resourcesAvailableConfirm, - eRasMessage_infoRequestAck, - eRasMessage_infoRequestNak, - eRasMessage_serviceControlIndication, - eRasMessage_serviceControlResponse, - } choice; - union { - GatekeeperRequest gatekeeperRequest; - GatekeeperConfirm gatekeeperConfirm; - RegistrationRequest registrationRequest; - RegistrationConfirm registrationConfirm; - UnregistrationRequest unregistrationRequest; - AdmissionRequest admissionRequest; - AdmissionConfirm admissionConfirm; - LocationRequest locationRequest; - LocationConfirm locationConfirm; - InfoRequestResponse infoRequestResponse; - }; -} RasMessage; diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c index 7d3ba4302e9..8ccfe17bb25 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c @@ -469,8 +469,8 @@ pptp_inbound_pkt(struct sk_buff **pskb, DEBUGP("%s but no session\n", pptp_msg_name[msg]); break; } - if (info->sstate != PPTP_CALL_IN_REP - && info->sstate != PPTP_CALL_IN_CONF) { + if (info->cstate != PPTP_CALL_IN_REP + && info->cstate != PPTP_CALL_IN_CONF) { DEBUGP("%s but never sent IN_CALL_REPLY\n", pptp_msg_name[msg]); break; diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c index 3021af0910f..d8b14a9010a 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, } /* See ip_conntrack_proto_tcp.c */ - if (hooknum != NF_IP_PRE_ROUTING) - goto checksum_skipped; - - switch (skb->ip_summed) { - case CHECKSUM_HW: - if (!(u16)csum_fold(skb->csum)) - break; - /* fall through */ - case CHECKSUM_NONE: - skb->csum = 0; - if (__skb_checksum_complete(skb)) { - if (LOG_INVALID(IPPROTO_ICMP)) - nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, - "ip_ct_icmp: bad ICMP checksum "); - return -NF_ACCEPT; - } + if (hooknum == NF_IP_PRE_ROUTING && + nf_ip_checksum(skb, hooknum, skb->nh.iph->ihl * 4, 0)) { + if (LOG_INVALID(IPPROTO_ICMP)) + nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, + "ip_ct_icmp: bad ICMP checksum "); + return -NF_ACCEPT; } -checksum_skipped: /* * 18 is the highest 'known' ICMP type. Anything else is a mystery * diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index 5259abd0fb4..0416073c560 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -235,12 +235,15 @@ static int do_basic_checks(struct ip_conntrack *conntrack, flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ - if ((sch->type == SCTP_CID_COOKIE_ACK + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ + if (((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count !=0) || !sch->length) { DEBUGP("Basic checks failed\n"); return 1; } diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index e0dc3706354..062b252b58a 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, * and moreover root might send raw packets. */ /* FIXME: Source route IP option packets --RR */ - if (hooknum == NF_IP_PRE_ROUTING - && skb->ip_summed != CHECKSUM_UNNECESSARY - && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, - skb->ip_summed == CHECKSUM_HW ? skb->csum - : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { + if (hooknum == NF_IP_PRE_ROUTING && + nf_ip_checksum(skb, hooknum, iph->ihl * 4, IPPROTO_TCP)) { if (LOG_INVALID(IPPROTO_TCP)) nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, "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 55b7d3210ad..70899868783 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, * because the semantic of CHECKSUM_HW is different there * and moreover root might send raw packets. * FIXME: Source route IP option packets --RR */ - if (hooknum == NF_IP_PRE_ROUTING - && skb->ip_summed != CHECKSUM_UNNECESSARY - && csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, - skb->ip_summed == CHECKSUM_HW ? skb->csum - : skb_checksum(skb, iph->ihl*4, udplen, 0))) { + if (hooknum == NF_IP_PRE_ROUTING && + nf_ip_checksum(skb, hooknum, iph->ihl * 4, IPPROTO_UDP)) { if (LOG_INVALID(IPPROTO_UDP)) nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, "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 52076026db3..929d61f7be9 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, /* Connection tracking may drop packets, but never alters them, so make it the first hook. */ -static struct nf_hook_ops ip_conntrack_defrag_ops = { - .hook = ip_conntrack_defrag, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_PRE_ROUTING, - .priority = NF_IP_PRI_CONNTRACK_DEFRAG, -}; - -static struct nf_hook_ops ip_conntrack_in_ops = { - .hook = ip_conntrack_in, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_PRE_ROUTING, - .priority = NF_IP_PRI_CONNTRACK, -}; - -static struct nf_hook_ops ip_conntrack_defrag_local_out_ops = { - .hook = ip_conntrack_defrag, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_OUT, - .priority = NF_IP_PRI_CONNTRACK_DEFRAG, -}; - -static struct nf_hook_ops ip_conntrack_local_out_ops = { - .hook = ip_conntrack_local, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_OUT, - .priority = NF_IP_PRI_CONNTRACK, -}; - -/* helpers */ -static struct nf_hook_ops ip_conntrack_helper_out_ops = { - .hook = ip_conntrack_help, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_POST_ROUTING, - .priority = NF_IP_PRI_CONNTRACK_HELPER, -}; - -static struct nf_hook_ops ip_conntrack_helper_in_ops = { - .hook = ip_conntrack_help, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_IN, - .priority = NF_IP_PRI_CONNTRACK_HELPER, -}; - -/* Refragmenter; last chance. */ -static struct nf_hook_ops ip_conntrack_out_ops = { - .hook = ip_confirm, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_POST_ROUTING, - .priority = NF_IP_PRI_CONNTRACK_CONFIRM, -}; - -static struct nf_hook_ops ip_conntrack_local_in_ops = { - .hook = ip_confirm, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_IN, - .priority = NF_IP_PRI_CONNTRACK_CONFIRM, +static struct nf_hook_ops ip_conntrack_ops[] = { + { + .hook = ip_conntrack_defrag, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_CONNTRACK_DEFRAG, + }, + { + .hook = ip_conntrack_in, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_CONNTRACK, + }, + { + .hook = ip_conntrack_defrag, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_CONNTRACK_DEFRAG, + }, + { + .hook = ip_conntrack_local, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_CONNTRACK, + }, + { + .hook = ip_conntrack_help, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_POST_ROUTING, + .priority = NF_IP_PRI_CONNTRACK_HELPER, + }, + { + .hook = ip_conntrack_help, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_IN, + .priority = NF_IP_PRI_CONNTRACK_HELPER, + }, + { + .hook = ip_confirm, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_POST_ROUTING, + .priority = NF_IP_PRI_CONNTRACK_CONFIRM, + }, + { + .hook = ip_confirm, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_IN, + .priority = NF_IP_PRI_CONNTRACK_CONFIRM, + }, }; /* Sysctl support */ @@ -783,18 +776,46 @@ static ctl_table ip_ct_net_table[] = { EXPORT_SYMBOL(ip_ct_log_invalid); #endif /* CONFIG_SYSCTL */ -static int init_or_cleanup(int init) +/* FIXME: Allow NULL functions and sub in pointers to generic for + them. --RR */ +int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) +{ + int ret = 0; + + write_lock_bh(&ip_conntrack_lock); + if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) { + ret = -EBUSY; + goto out; + } + ip_ct_protos[proto->proto] = proto; + out: + write_unlock_bh(&ip_conntrack_lock); + return ret; +} + +void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) +{ + write_lock_bh(&ip_conntrack_lock); + ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol; + write_unlock_bh(&ip_conntrack_lock); + + /* Somebody could be still looking at the proto in bh. */ + synchronize_net(); + + /* Remove all contrack entries for this protocol */ + ip_ct_iterate_cleanup(kill_proto, &proto->proto); +} + +static int __init ip_conntrack_standalone_init(void) { #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc, *proc_exp, *proc_stat; #endif int ret = 0; - if (!init) goto cleanup; - ret = ip_conntrack_init(); if (ret < 0) - goto cleanup_nothing; + return ret; #ifdef CONFIG_PROC_FS ret = -ENOMEM; @@ -813,78 +834,25 @@ static int init_or_cleanup(int init) proc_stat->owner = THIS_MODULE; #endif - ret = nf_register_hook(&ip_conntrack_defrag_ops); + ret = nf_register_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops)); if (ret < 0) { - printk("ip_conntrack: can't register pre-routing defrag hook.\n"); + printk("ip_conntrack: can't register hooks.\n"); goto cleanup_proc_stat; } - ret = nf_register_hook(&ip_conntrack_defrag_local_out_ops); - if (ret < 0) { - printk("ip_conntrack: can't register local_out defrag hook.\n"); - goto cleanup_defragops; - } - ret = nf_register_hook(&ip_conntrack_in_ops); - if (ret < 0) { - printk("ip_conntrack: can't register pre-routing hook.\n"); - goto cleanup_defraglocalops; - } - ret = nf_register_hook(&ip_conntrack_local_out_ops); - if (ret < 0) { - printk("ip_conntrack: can't register local out hook.\n"); - goto cleanup_inops; - } - ret = nf_register_hook(&ip_conntrack_helper_in_ops); - if (ret < 0) { - printk("ip_conntrack: can't register local in helper hook.\n"); - goto cleanup_inandlocalops; - } - ret = nf_register_hook(&ip_conntrack_helper_out_ops); - if (ret < 0) { - printk("ip_conntrack: can't register postrouting helper hook.\n"); - goto cleanup_helperinops; - } - ret = nf_register_hook(&ip_conntrack_out_ops); - if (ret < 0) { - printk("ip_conntrack: can't register post-routing hook.\n"); - goto cleanup_helperoutops; - } - ret = nf_register_hook(&ip_conntrack_local_in_ops); - if (ret < 0) { - printk("ip_conntrack: can't register local in hook.\n"); - goto cleanup_inoutandlocalops; - } #ifdef CONFIG_SYSCTL ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0); if (ip_ct_sysctl_header == NULL) { printk("ip_conntrack: can't register to sysctl.\n"); ret = -ENOMEM; - goto cleanup_localinops; + goto cleanup_hooks; } #endif - return ret; - cleanup: - synchronize_net(); #ifdef CONFIG_SYSCTL - unregister_sysctl_table(ip_ct_sysctl_header); - cleanup_localinops: + cleanup_hooks: + nf_unregister_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops)); #endif - nf_unregister_hook(&ip_conntrack_local_in_ops); - cleanup_inoutandlocalops: - nf_unregister_hook(&ip_conntrack_out_ops); - cleanup_helperoutops: - nf_unregister_hook(&ip_conntrack_helper_out_ops); - cleanup_helperinops: - nf_unregister_hook(&ip_conntrack_helper_in_ops); - cleanup_inandlocalops: - nf_unregister_hook(&ip_conntrack_local_out_ops); - cleanup_inops: - nf_unregister_hook(&ip_conntrack_in_ops); - cleanup_defraglocalops: - nf_unregister_hook(&ip_conntrack_defrag_local_out_ops); - cleanup_defragops: - nf_unregister_hook(&ip_conntrack_defrag_ops); cleanup_proc_stat: #ifdef CONFIG_PROC_FS remove_proc_entry("ip_conntrack", proc_net_stat); @@ -895,48 +863,22 @@ static int init_or_cleanup(int init) cleanup_init: #endif /* CONFIG_PROC_FS */ ip_conntrack_cleanup(); - cleanup_nothing: - return ret; -} - -/* FIXME: Allow NULL functions and sub in pointers to generic for - them. --RR */ -int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) -{ - int ret = 0; - - write_lock_bh(&ip_conntrack_lock); - if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) { - ret = -EBUSY; - goto out; - } - ip_ct_protos[proto->proto] = proto; - out: - write_unlock_bh(&ip_conntrack_lock); return ret; } -void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) -{ - write_lock_bh(&ip_conntrack_lock); - ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol; - write_unlock_bh(&ip_conntrack_lock); - - /* Somebody could be still looking at the proto in bh. */ - synchronize_net(); - - /* Remove all contrack entries for this protocol */ - ip_ct_iterate_cleanup(kill_proto, &proto->proto); -} - -static int __init ip_conntrack_standalone_init(void) -{ - return init_or_cleanup(1); -} - static void __exit ip_conntrack_standalone_fini(void) { - init_or_cleanup(0); + synchronize_net(); +#ifdef CONFIG_SYSCTL + unregister_sysctl_table(ip_ct_sysctl_header); +#endif + nf_unregister_hooks(ip_conntrack_ops, ARRAY_SIZE(ip_conntrack_ops)); +#ifdef CONFIG_PROC_FS + remove_proc_entry("ip_conntrack", proc_net_stat); + proc_net_remove("ip_conntrack_expect"); + proc_net_remove("ip_conntrack"); +#endif /* CONFIG_PROC_FS */ + ip_conntrack_cleanup(); } 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 a0bc883928c..d45663d137a 100644 --- a/net/ipv4/netfilter/ip_nat_helper_h323.c +++ b/net/ipv4/netfilter/ip_nat_helper_h323.c @@ -7,24 +7,6 @@ * * Based on the 'brute force' H.323 NAT module by * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> - * - * Changes: - * 2006-02-01 - initial version 0.1 - * - * 2006-02-20 - version 0.2 - * 1. Changed source format to follow kernel conventions - * 2. Deleted some unnecessary structures - * 3. Minor fixes - * - * 2006-03-10 - version 0.3 - * 1. Added support for multiple TPKTs in one packet (suggested by - * Patrick McHardy) - * 2. Added support for non-linear skb (based on Patrick McHardy's patch) - * 3. Eliminated unnecessary return code - * - * 2006-03-15 - version 0.4 - * 1. Added support for T.120 channels - * 2. Added parameter gkrouted_only (suggested by Patrick McHardy) */ #include <linux/module.h> @@ -41,65 +23,12 @@ #include <linux/netfilter_ipv4/ip_conntrack_h323.h> #include <linux/netfilter_ipv4/ip_conntrack_helper.h> -#include "ip_conntrack_helper_h323_asn1.h" - #if 0 #define DEBUGP printk #else #define DEBUGP(format, args...) #endif -extern int get_h245_addr(unsigned char *data, H245_TransportAddress * addr, - u_int32_t * ip, u_int16_t * port); -extern int get_h225_addr(unsigned char *data, TransportAddress * addr, - u_int32_t * ip, u_int16_t * port); -extern void ip_conntrack_h245_expect(struct ip_conntrack *new, - struct ip_conntrack_expect *this); -extern void ip_conntrack_q931_expect(struct ip_conntrack *new, - struct ip_conntrack_expect *this); -extern int (*set_h245_addr_hook) (struct sk_buff ** pskb, - unsigned char **data, int dataoff, - H245_TransportAddress * addr, - u_int32_t ip, u_int16_t port); -extern int (*set_h225_addr_hook) (struct sk_buff ** pskb, - unsigned char **data, int dataoff, - TransportAddress * addr, - u_int32_t ip, u_int16_t port); -extern int (*set_sig_addr_hook) (struct sk_buff ** pskb, - struct ip_conntrack * ct, - enum ip_conntrack_info ctinfo, - unsigned char **data, - TransportAddress * addr, int count); -extern int (*set_ras_addr_hook) (struct sk_buff ** pskb, - struct ip_conntrack * ct, - enum ip_conntrack_info ctinfo, - unsigned char **data, - TransportAddress * addr, int count); -extern int (*nat_rtp_rtcp_hook) (struct sk_buff ** pskb, - struct ip_conntrack * ct, - enum ip_conntrack_info ctinfo, - unsigned char **data, int dataoff, - H245_TransportAddress * addr, - u_int16_t port, u_int16_t rtp_port, - struct ip_conntrack_expect * rtp_exp, - struct ip_conntrack_expect * rtcp_exp); -extern int (*nat_t120_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, - enum ip_conntrack_info ctinfo, - unsigned char **data, int dataoff, - H245_TransportAddress * addr, u_int16_t port, - struct ip_conntrack_expect * exp); -extern int (*nat_h245_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, - enum ip_conntrack_info ctinfo, - unsigned char **data, int dataoff, - TransportAddress * addr, u_int16_t port, - struct ip_conntrack_expect * exp); -extern int (*nat_q931_hook) (struct sk_buff ** pskb, struct ip_conntrack * ct, - enum ip_conntrack_info ctinfo, - unsigned char **data, TransportAddress * addr, - int idx, u_int16_t port, - struct ip_conntrack_expect * exp); - - /****************************************************************************/ static int set_addr(struct sk_buff **pskb, unsigned char **data, int dataoff, diff --git a/net/ipv4/netfilter/ip_nat_proto_gre.c b/net/ipv4/netfilter/ip_nat_proto_gre.c index 6c4899d8046..96ceabaec40 100644 --- a/net/ipv4/netfilter/ip_nat_proto_gre.c +++ b/net/ipv4/netfilter/ip_nat_proto_gre.c @@ -49,15 +49,15 @@ gre_in_range(const struct ip_conntrack_tuple *tuple, const union ip_conntrack_manip_proto *min, const union ip_conntrack_manip_proto *max) { - u_int32_t key; + __be16 key; if (maniptype == IP_NAT_MANIP_SRC) key = tuple->src.u.gre.key; else key = tuple->dst.u.gre.key; - return ntohl(key) >= ntohl(min->gre.key) - && ntohl(key) <= ntohl(max->gre.key); + return ntohs(key) >= ntohs(min->gre.key) + && ntohs(key) <= ntohs(max->gre.key); } /* generate unique tuple ... */ @@ -81,14 +81,14 @@ gre_unique_tuple(struct ip_conntrack_tuple *tuple, min = 1; range_size = 0xffff; } else { - min = ntohl(range->min.gre.key); - range_size = ntohl(range->max.gre.key) - min + 1; + min = ntohs(range->min.gre.key); + range_size = ntohs(range->max.gre.key) - min + 1; } DEBUGP("min = %u, range_size = %u\n", min, range_size); for (i = 0; i < range_size; i++, key++) { - *keyptr = htonl(min + key % range_size); + *keyptr = htons(min + key % range_size); if (!ip_nat_used_tuple(tuple, conntrack)) return 1; } diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index efba8c4e42e..1aba926c1cb 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 = { .target = ipt_dnat_target, .targetsize = sizeof(struct ip_nat_multi_range_compat), .table = "nat", - .hooks = 1 << NF_IP_PRE_ROUTING, + .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT), .checkentry = ipt_dnat_checkentry, }; diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c index c6225384553..c33244263b9 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -768,6 +768,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, len *= sizeof(unsigned long); *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { + kfree(lp); kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); @@ -1003,12 +1004,12 @@ static unsigned char snmp_trap_decode(struct asn1_ctx *ctx, return 1; +err_addr_free: + kfree((unsigned long *)trap->ip_address); + err_id_free: kfree(trap->id); -err_addr_free: - kfree((unsigned long *)trap->ip_address); - return 0; } @@ -1126,11 +1127,10 @@ static int snmp_parse_mangle(unsigned char *msg, struct snmp_v1_trap trap; unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check); - /* Discard trap allocations regardless */ - kfree(trap.id); - kfree((unsigned long *)trap.ip_address); - - if (!ret) + if (ret) { + kfree(trap.id); + kfree((unsigned long *)trap.ip_address); + } else return ret; } else { diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 3505b0de2e0..67e676783da 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -219,8 +219,10 @@ ip_nat_out(unsigned int hooknum, const struct net_device *out, int (*okfn)(struct sk_buff *)) { +#ifdef CONFIG_XFRM struct ip_conntrack *ct; enum ip_conntrack_info ctinfo; +#endif unsigned int ret; /* root is playing with raw sockets. */ @@ -299,69 +301,63 @@ ip_nat_adjust(unsigned int hooknum, /* We must be after connection tracking and before packet filtering. */ -/* Before packet filtering, change destination */ -static struct nf_hook_ops ip_nat_in_ops = { - .hook = ip_nat_in, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_PRE_ROUTING, - .priority = NF_IP_PRI_NAT_DST, +static struct nf_hook_ops ip_nat_ops[] = { + /* Before packet filtering, change destination */ + { + .hook = ip_nat_in, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_NAT_DST, + }, + /* After packet filtering, change source */ + { + .hook = ip_nat_out, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_POST_ROUTING, + .priority = NF_IP_PRI_NAT_SRC, + }, + /* After conntrack, adjust sequence number */ + { + .hook = ip_nat_adjust, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_POST_ROUTING, + .priority = NF_IP_PRI_NAT_SEQ_ADJUST, + }, + /* Before packet filtering, change destination */ + { + .hook = ip_nat_local_fn, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_NAT_DST, + }, + /* After packet filtering, change source */ + { + .hook = ip_nat_fn, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_IN, + .priority = NF_IP_PRI_NAT_SRC, + }, + /* After conntrack, adjust sequence number */ + { + .hook = ip_nat_adjust, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_IN, + .priority = NF_IP_PRI_NAT_SEQ_ADJUST, + }, }; -/* After packet filtering, change source */ -static struct nf_hook_ops ip_nat_out_ops = { - .hook = ip_nat_out, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_POST_ROUTING, - .priority = NF_IP_PRI_NAT_SRC, -}; - -/* After conntrack, adjust sequence number */ -static struct nf_hook_ops ip_nat_adjust_out_ops = { - .hook = ip_nat_adjust, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_POST_ROUTING, - .priority = NF_IP_PRI_NAT_SEQ_ADJUST, -}; - -/* Before packet filtering, change destination */ -static struct nf_hook_ops ip_nat_local_out_ops = { - .hook = ip_nat_local_fn, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_OUT, - .priority = NF_IP_PRI_NAT_DST, -}; - -/* After packet filtering, change source for reply packets of LOCAL_OUT DNAT */ -static struct nf_hook_ops ip_nat_local_in_ops = { - .hook = ip_nat_fn, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_IN, - .priority = NF_IP_PRI_NAT_SRC, -}; - -/* After conntrack, adjust sequence number */ -static struct nf_hook_ops ip_nat_adjust_in_ops = { - .hook = ip_nat_adjust, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_IN, - .priority = NF_IP_PRI_NAT_SEQ_ADJUST, -}; - - -static int init_or_cleanup(int init) +static int __init ip_nat_standalone_init(void) { int ret = 0; need_conntrack(); - if (!init) goto cleanup; - #ifdef CONFIG_XFRM BUG_ON(ip_nat_decode_session != NULL); ip_nat_decode_session = nat_decode_session; @@ -371,50 +367,13 @@ static int init_or_cleanup(int init) printk("ip_nat_init: can't setup rules.\n"); goto cleanup_decode_session; } - ret = nf_register_hook(&ip_nat_in_ops); + ret = nf_register_hooks(ip_nat_ops, ARRAY_SIZE(ip_nat_ops)); if (ret < 0) { - printk("ip_nat_init: can't register in hook.\n"); + printk("ip_nat_init: can't register hooks.\n"); goto cleanup_rule_init; } - ret = nf_register_hook(&ip_nat_out_ops); - if (ret < 0) { - printk("ip_nat_init: can't register out hook.\n"); - goto cleanup_inops; - } - ret = nf_register_hook(&ip_nat_adjust_in_ops); - if (ret < 0) { - printk("ip_nat_init: can't register adjust in hook.\n"); - goto cleanup_outops; - } - ret = nf_register_hook(&ip_nat_adjust_out_ops); - if (ret < 0) { - printk("ip_nat_init: can't register adjust out hook.\n"); - goto cleanup_adjustin_ops; - } - ret = nf_register_hook(&ip_nat_local_out_ops); - if (ret < 0) { - printk("ip_nat_init: can't register local out hook.\n"); - goto cleanup_adjustout_ops; - } - ret = nf_register_hook(&ip_nat_local_in_ops); - if (ret < 0) { - printk("ip_nat_init: can't register local in hook.\n"); - goto cleanup_localoutops; - } return ret; - cleanup: - nf_unregister_hook(&ip_nat_local_in_ops); - cleanup_localoutops: - nf_unregister_hook(&ip_nat_local_out_ops); - cleanup_adjustout_ops: - nf_unregister_hook(&ip_nat_adjust_out_ops); - cleanup_adjustin_ops: - nf_unregister_hook(&ip_nat_adjust_in_ops); - cleanup_outops: - nf_unregister_hook(&ip_nat_out_ops); - cleanup_inops: - nf_unregister_hook(&ip_nat_in_ops); cleanup_rule_init: ip_nat_rule_cleanup(); cleanup_decode_session: @@ -425,14 +384,14 @@ static int init_or_cleanup(int init) return ret; } -static int __init ip_nat_standalone_init(void) -{ - return init_or_cleanup(1); -} - static void __exit ip_nat_standalone_fini(void) { - init_or_cleanup(0); + nf_unregister_hooks(ip_nat_ops, ARRAY_SIZE(ip_nat_ops)); + ip_nat_rule_cleanup(); +#ifdef CONFIG_XFRM + ip_nat_decode_session = NULL; + synchronize_net(); +#endif } module_init(ip_nat_standalone_init); diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 896a244f8f9..b93f0494362 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 = { .outfn = &ipq_enqueue_packet, }; -static int -init_or_cleanup(int init) +static int __init ip_queue_init(void) { int status = -ENOMEM; struct proc_dir_entry *proc; - if (!init) - goto cleanup; - netlink_register_notifier(&ipq_nl_notifier); ipqnl = netlink_kernel_create(NETLINK_FIREWALL, 0, ipq_rcv_sk, THIS_MODULE); @@ -697,11 +693,6 @@ init_or_cleanup(int init) } return status; -cleanup: - nf_unregister_queue_handlers(&nfqh); - synchronize_net(); - ipq_flush(NF_DROP); - cleanup_sysctl: unregister_sysctl_table(ipq_sysctl_header); unregister_netdevice_notifier(&ipq_dev_notifier); @@ -717,15 +708,21 @@ cleanup_netlink_notifier: return status; } -static int __init ip_queue_init(void) -{ - - return init_or_cleanup(1); -} - static void __exit ip_queue_fini(void) { - init_or_cleanup(0); + nf_unregister_queue_handlers(&nfqh); + synchronize_net(); + ipq_flush(NF_DROP); + + unregister_sysctl_table(ipq_sysctl_header); + unregister_netdevice_notifier(&ipq_dev_notifier); + proc_net_remove(IPQ_PROC_FS_NAME); + + sock_release(ipqnl->sk_socket); + mutex_lock(&ipqnl_mutex); + mutex_unlock(&ipqnl_mutex); + + netlink_unregister_notifier(&ipq_nl_notifier); } MODULE_DESCRIPTION("IPv4 packet queue handler"); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index d5b8cdd361c..cee3397ec27 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -735,7 +735,7 @@ translate_table(const char *name, } /* And one copy for every other CPU */ - for_each_cpu(i) { + for_each_possible_cpu(i) { if (newinfo->entries[i] && newinfo->entries[i] != entry0) memcpy(newinfo->entries[i], entry0, newinfo->size); } @@ -788,7 +788,7 @@ get_counters(const struct xt_table_info *t, counters, &i); - for_each_cpu(cpu) { + for_each_possible_cpu(cpu) { if (cpu == curcpu) continue; i = 0; @@ -956,15 +956,16 @@ struct compat_ipt_standard_target compat_int_t verdict; }; -#define IPT_ST_OFFSET (sizeof(struct ipt_standard_target) - \ - sizeof(struct compat_ipt_standard_target)) - struct compat_ipt_standard { struct compat_ipt_entry entry; struct compat_ipt_standard_target target; }; +#define IPT_ST_LEN XT_ALIGN(sizeof(struct ipt_standard_target)) +#define IPT_ST_COMPAT_LEN COMPAT_XT_ALIGN(sizeof(struct compat_ipt_standard_target)) +#define IPT_ST_OFFSET (IPT_ST_LEN - IPT_ST_COMPAT_LEN) + static int compat_ipt_standard_fn(void *target, void **dstptr, int *size, int convert) { @@ -975,35 +976,29 @@ static int compat_ipt_standard_fn(void *target, ret = 0; switch (convert) { case COMPAT_TO_USER: - pst = (struct ipt_standard_target *)target; + pst = target; memcpy(&compat_st.target, &pst->target, - sizeof(struct ipt_entry_target)); + sizeof(compat_st.target)); compat_st.verdict = pst->verdict; if (compat_st.verdict > 0) compat_st.verdict -= compat_calc_jump(compat_st.verdict); - compat_st.target.u.user.target_size = - sizeof(struct compat_ipt_standard_target); - if (__copy_to_user(*dstptr, &compat_st, - sizeof(struct compat_ipt_standard_target))) + compat_st.target.u.user.target_size = IPT_ST_COMPAT_LEN; + if (copy_to_user(*dstptr, &compat_st, IPT_ST_COMPAT_LEN)) ret = -EFAULT; *size -= IPT_ST_OFFSET; - *dstptr += sizeof(struct compat_ipt_standard_target); + *dstptr += IPT_ST_COMPAT_LEN; break; case COMPAT_FROM_USER: - pcompat_st = - (struct compat_ipt_standard_target *)target; - memcpy(&st.target, &pcompat_st->target, - sizeof(struct ipt_entry_target)); + pcompat_st = target; + memcpy(&st.target, &pcompat_st->target, IPT_ST_COMPAT_LEN); st.verdict = pcompat_st->verdict; if (st.verdict > 0) st.verdict += compat_calc_jump(st.verdict); - st.target.u.user.target_size = - sizeof(struct ipt_standard_target); - memcpy(*dstptr, &st, - sizeof(struct ipt_standard_target)); + st.target.u.user.target_size = IPT_ST_LEN; + memcpy(*dstptr, &st, IPT_ST_LEN); *size += IPT_ST_OFFSET; - *dstptr += sizeof(struct ipt_standard_target); + *dstptr += IPT_ST_LEN; break; case COMPAT_CALC_SIZE: *size += IPT_ST_OFFSET; @@ -1446,7 +1441,7 @@ static int compat_copy_entry_to_user(struct ipt_entry *e, ret = -EFAULT; origsize = *size; ce = (struct compat_ipt_entry __user *)*dstptr; - if (__copy_to_user(ce, e, sizeof(struct ipt_entry))) + if (copy_to_user(ce, e, sizeof(struct ipt_entry))) goto out; *dstptr += sizeof(struct compat_ipt_entry); @@ -1464,9 +1459,9 @@ static int compat_copy_entry_to_user(struct ipt_entry *e, goto out; ret = -EFAULT; next_offset = e->next_offset - (origsize - *size); - if (__put_user(target_offset, &ce->target_offset)) + if (put_user(target_offset, &ce->target_offset)) goto out; - if (__put_user(next_offset, &ce->next_offset)) + if (put_user(next_offset, &ce->next_offset)) goto out; return 0; out: diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index e4768a31718..aad9d28c8d7 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 = { #endif /* CONFIG_PROC_FS */ -static int init_or_cleanup(int fini) +static int __init ipt_clusterip_init(void) { int ret; - if (fini) - goto cleanup; - - if (ipt_register_target(&clusterip_tgt)) { - ret = -EINVAL; - goto cleanup_none; - } + ret = ipt_register_target(&clusterip_tgt); + if (ret < 0) + return ret; - if (nf_register_hook(&cip_arp_ops) < 0) { - ret = -EINVAL; + ret = nf_register_hook(&cip_arp_ops); + if (ret < 0) goto cleanup_target; - } #ifdef CONFIG_PROC_FS clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", proc_net); @@ -753,31 +748,24 @@ static int init_or_cleanup(int fini) printk(KERN_NOTICE "ClusterIP Version %s loaded successfully\n", CLUSTERIP_VERSION); - return 0; -cleanup: - printk(KERN_NOTICE "ClusterIP Version %s unloading\n", - CLUSTERIP_VERSION); -#ifdef CONFIG_PROC_FS - remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); -#endif cleanup_hook: nf_unregister_hook(&cip_arp_ops); cleanup_target: ipt_unregister_target(&clusterip_tgt); -cleanup_none: - return -EINVAL; -} - -static int __init ipt_clusterip_init(void) -{ - return init_or_cleanup(0); + return ret; } static void __exit ipt_clusterip_fini(void) { - init_or_cleanup(1); + printk(KERN_NOTICE "ClusterIP Version %s unloading\n", + CLUSTERIP_VERSION); +#ifdef CONFIG_PROC_FS + remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent); +#endif + nf_unregister_hook(&cip_arp_ops); + ipt_unregister_target(&clusterip_tgt); } module_init(ipt_clusterip_init); diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 39fd4c2a238..b98f7b08b08 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c @@ -428,7 +428,7 @@ ipt_log_target(struct sk_buff **pskb, if (loginfo->logflags & IPT_LOG_NFLOG) nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, - loginfo->prefix); + "%s", loginfo->prefix); else ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix); diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 4269a5440d4..0bba3c2bb78 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) struct rtable *rt; u_int16_t tmp_port; u_int32_t tmp_addr; - unsigned int tcplen; int needs_ack; int hh_len; @@ -124,13 +123,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) return; /* Check checksum */ - tcplen = oldskb->len - iph->ihl * 4; - if (((hook != NF_IP_LOCAL_IN && oldskb->ip_summed != CHECKSUM_HW) || - (hook == NF_IP_LOCAL_IN && - oldskb->ip_summed != CHECKSUM_UNNECESSARY)) && - csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, - oldskb->ip_summed == CHECKSUM_HW ? oldskb->csum : - skb_checksum(oldskb, iph->ihl * 4, tcplen, 0))) + if (nf_ip_checksum(oldskb, hook, iph->ihl * 4, IPPROTO_TCP)) return; if ((rt = route_reverse(oldskb, oth, hook)) == NULL) diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 14384328570..b847ee409ef 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c @@ -821,6 +821,7 @@ checkentry(const char *tablename, /* Create our proc 'status' entry. */ curr_table->status_proc = create_proc_entry(curr_table->name, ip_list_perms, proc_net_ipt_recent); if (!curr_table->status_proc) { + vfree(hold); printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for /proc entry.\n"); /* Destroy the created table */ spin_lock_bh(&recent_lock); @@ -845,7 +846,6 @@ checkentry(const char *tablename, spin_unlock_bh(&recent_lock); vfree(curr_table->time_info); vfree(curr_table->hash_table); - vfree(hold); vfree(curr_table->table); vfree(curr_table); return 0; diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c index 3d80aefe9cf..7f417484bfb 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) return ret; /* Register hooks */ - ret = nf_register_hook(&ipt_ops[0]); + ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); if (ret < 0) goto cleanup_table; - ret = nf_register_hook(&ipt_ops[1]); - if (ret < 0) - goto cleanup_hook0; - - ret = nf_register_hook(&ipt_ops[2]); - if (ret < 0) - goto cleanup_hook1; - return ret; - cleanup_hook1: - nf_unregister_hook(&ipt_ops[1]); - cleanup_hook0: - nf_unregister_hook(&ipt_ops[0]); cleanup_table: ipt_unregister_table(&packet_filter); - return ret; } static void __exit iptable_filter_fini(void) { - unsigned int i; - - for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) - nf_unregister_hook(&ipt_ops[i]); - + nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); ipt_unregister_table(&packet_filter); } diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c index 412fc96cc89..397b95cc026 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) return ret; /* Register hooks */ - ret = nf_register_hook(&ipt_ops[0]); + ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); if (ret < 0) goto cleanup_table; - ret = nf_register_hook(&ipt_ops[1]); - if (ret < 0) - goto cleanup_hook0; - - ret = nf_register_hook(&ipt_ops[2]); - if (ret < 0) - goto cleanup_hook1; - - ret = nf_register_hook(&ipt_ops[3]); - if (ret < 0) - goto cleanup_hook2; - - ret = nf_register_hook(&ipt_ops[4]); - if (ret < 0) - goto cleanup_hook3; - return ret; - cleanup_hook3: - nf_unregister_hook(&ipt_ops[3]); - cleanup_hook2: - nf_unregister_hook(&ipt_ops[2]); - cleanup_hook1: - nf_unregister_hook(&ipt_ops[1]); - cleanup_hook0: - nf_unregister_hook(&ipt_ops[0]); cleanup_table: ipt_unregister_table(&packet_mangler); - return ret; } static void __exit iptable_mangle_fini(void) { - unsigned int i; - - for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) - nf_unregister_hook(&ipt_ops[i]); - + nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); ipt_unregister_table(&packet_mangler); } diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 03cc79a6160..7912cce1e1b 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c @@ -101,18 +101,18 @@ ipt_hook(unsigned int hook, /* 'raw' is the very first table. */ static struct nf_hook_ops ipt_ops[] = { { - .hook = ipt_hook, - .pf = PF_INET, - .hooknum = NF_IP_PRE_ROUTING, - .priority = NF_IP_PRI_RAW, - .owner = THIS_MODULE, + .hook = ipt_hook, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_RAW, + .owner = THIS_MODULE, }, { - .hook = ipt_hook, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_OUT, - .priority = NF_IP_PRI_RAW, - .owner = THIS_MODULE, + .hook = ipt_hook, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_RAW, + .owner = THIS_MODULE, }, }; @@ -126,31 +126,20 @@ static int __init iptable_raw_init(void) return ret; /* Register hooks */ - ret = nf_register_hook(&ipt_ops[0]); + ret = nf_register_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); if (ret < 0) goto cleanup_table; - ret = nf_register_hook(&ipt_ops[1]); - if (ret < 0) - goto cleanup_hook0; - return ret; - cleanup_hook0: - nf_unregister_hook(&ipt_ops[0]); cleanup_table: ipt_unregister_table(&packet_raw); - return ret; } static void __exit iptable_raw_fini(void) { - unsigned int i; - - for (i = 0; i < sizeof(ipt_ops)/sizeof(struct nf_hook_ops); i++) - nf_unregister_hook(&ipt_ops[i]); - + nf_unregister_hooks(ipt_ops, ARRAY_SIZE(ipt_ops)); ipt_unregister_table(&packet_raw); } diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index 4afbc699d3b..77d974443c7 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, /* Connection tracking may drop packets, but never alters them, so make it the first hook. */ -static struct nf_hook_ops ipv4_conntrack_defrag_ops = { - .hook = ipv4_conntrack_defrag, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_PRE_ROUTING, - .priority = NF_IP_PRI_CONNTRACK_DEFRAG, -}; - -static struct nf_hook_ops ipv4_conntrack_in_ops = { - .hook = ipv4_conntrack_in, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_PRE_ROUTING, - .priority = NF_IP_PRI_CONNTRACK, -}; - -static struct nf_hook_ops ipv4_conntrack_defrag_local_out_ops = { - .hook = ipv4_conntrack_defrag, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_OUT, - .priority = NF_IP_PRI_CONNTRACK_DEFRAG, -}; - -static struct nf_hook_ops ipv4_conntrack_local_out_ops = { - .hook = ipv4_conntrack_local, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_OUT, - .priority = NF_IP_PRI_CONNTRACK, -}; - -/* helpers */ -static struct nf_hook_ops ipv4_conntrack_helper_out_ops = { - .hook = ipv4_conntrack_help, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_POST_ROUTING, - .priority = NF_IP_PRI_CONNTRACK_HELPER, -}; - -static struct nf_hook_ops ipv4_conntrack_helper_in_ops = { - .hook = ipv4_conntrack_help, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_IN, - .priority = NF_IP_PRI_CONNTRACK_HELPER, -}; - - -/* Refragmenter; last chance. */ -static struct nf_hook_ops ipv4_conntrack_out_ops = { - .hook = ipv4_confirm, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_POST_ROUTING, - .priority = NF_IP_PRI_CONNTRACK_CONFIRM, -}; - -static struct nf_hook_ops ipv4_conntrack_local_in_ops = { - .hook = ipv4_confirm, - .owner = THIS_MODULE, - .pf = PF_INET, - .hooknum = NF_IP_LOCAL_IN, - .priority = NF_IP_PRI_CONNTRACK_CONFIRM, +static struct nf_hook_ops ipv4_conntrack_ops[] = { + { + .hook = ipv4_conntrack_defrag, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_CONNTRACK_DEFRAG, + }, + { + .hook = ipv4_conntrack_in, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_PRE_ROUTING, + .priority = NF_IP_PRI_CONNTRACK, + }, + { + .hook = ipv4_conntrack_defrag, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_CONNTRACK_DEFRAG, + }, + { + .hook = ipv4_conntrack_local, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_OUT, + .priority = NF_IP_PRI_CONNTRACK, + }, + { + .hook = ipv4_conntrack_help, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_POST_ROUTING, + .priority = NF_IP_PRI_CONNTRACK_HELPER, + }, + { + .hook = ipv4_conntrack_help, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_IN, + .priority = NF_IP_PRI_CONNTRACK_HELPER, + }, + { + .hook = ipv4_confirm, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_POST_ROUTING, + .priority = NF_IP_PRI_CONNTRACK_CONFIRM, + }, + { + .hook = ipv4_confirm, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_IP_LOCAL_IN, + .priority = NF_IP_PRI_CONNTRACK_CONFIRM, + }, }; #ifdef CONFIG_SYSCTL @@ -356,6 +348,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len) .tuple.dst.u.tcp.port; sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL] .tuple.dst.u3.ip; + memset(sin.sin_zero, 0, sizeof(sin.sin_zero)); DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n", NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port)); @@ -440,16 +433,20 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = { extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4; extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4; extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp; -static int init_or_cleanup(int init) + +MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); +MODULE_LICENSE("GPL"); + +static int __init nf_conntrack_l3proto_ipv4_init(void) { int ret = 0; - if (!init) goto cleanup; + need_conntrack(); ret = nf_register_sockopt(&so_getorigdst); if (ret < 0) { printk(KERN_ERR "Unable to register netfilter socket option\n"); - goto cleanup_nothing; + return ret; } ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4); @@ -476,84 +473,26 @@ static int init_or_cleanup(int init) goto cleanup_icmp; } - ret = nf_register_hook(&ipv4_conntrack_defrag_ops); + ret = nf_register_hooks(ipv4_conntrack_ops, + ARRAY_SIZE(ipv4_conntrack_ops)); if (ret < 0) { - printk("nf_conntrack_ipv4: can't register pre-routing defrag hook.\n"); + printk("nf_conntrack_ipv4: can't register hooks.\n"); goto cleanup_ipv4; } - ret = nf_register_hook(&ipv4_conntrack_defrag_local_out_ops); - if (ret < 0) { - printk("nf_conntrack_ipv4: can't register local_out defrag hook.\n"); - goto cleanup_defragops; - } - - ret = nf_register_hook(&ipv4_conntrack_in_ops); - if (ret < 0) { - printk("nf_conntrack_ipv4: can't register pre-routing hook.\n"); - goto cleanup_defraglocalops; - } - - ret = nf_register_hook(&ipv4_conntrack_local_out_ops); - if (ret < 0) { - printk("nf_conntrack_ipv4: can't register local out hook.\n"); - goto cleanup_inops; - } - - ret = nf_register_hook(&ipv4_conntrack_helper_in_ops); - if (ret < 0) { - printk("nf_conntrack_ipv4: can't register local helper hook.\n"); - goto cleanup_inandlocalops; - } - - ret = nf_register_hook(&ipv4_conntrack_helper_out_ops); - if (ret < 0) { - printk("nf_conntrack_ipv4: can't register postrouting helper hook.\n"); - goto cleanup_helperinops; - } - - ret = nf_register_hook(&ipv4_conntrack_out_ops); - if (ret < 0) { - printk("nf_conntrack_ipv4: can't register post-routing hook.\n"); - goto cleanup_helperoutops; - } - - ret = nf_register_hook(&ipv4_conntrack_local_in_ops); - if (ret < 0) { - printk("nf_conntrack_ipv4: can't register local in hook.\n"); - goto cleanup_inoutandlocalops; - } - #ifdef CONFIG_SYSCTL nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); if (nf_ct_ipv4_sysctl_header == NULL) { printk("nf_conntrack: can't register to sysctl.\n"); ret = -ENOMEM; - goto cleanup_localinops; + goto cleanup_hooks; } #endif return ret; - cleanup: - synchronize_net(); #ifdef CONFIG_SYSCTL - unregister_sysctl_table(nf_ct_ipv4_sysctl_header); - cleanup_localinops: + cleanup_hooks: + nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); #endif - nf_unregister_hook(&ipv4_conntrack_local_in_ops); - cleanup_inoutandlocalops: - nf_unregister_hook(&ipv4_conntrack_out_ops); - cleanup_helperoutops: - nf_unregister_hook(&ipv4_conntrack_helper_out_ops); - cleanup_helperinops: - nf_unregister_hook(&ipv4_conntrack_helper_in_ops); - cleanup_inandlocalops: - nf_unregister_hook(&ipv4_conntrack_local_out_ops); - cleanup_inops: - nf_unregister_hook(&ipv4_conntrack_in_ops); - cleanup_defraglocalops: - nf_unregister_hook(&ipv4_conntrack_defrag_local_out_ops); - cleanup_defragops: - nf_unregister_hook(&ipv4_conntrack_defrag_ops); cleanup_ipv4: nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); cleanup_icmp: @@ -564,22 +503,21 @@ static int init_or_cleanup(int init) nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); cleanup_sockopt: nf_unregister_sockopt(&so_getorigdst); - cleanup_nothing: return ret; } -MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); -MODULE_LICENSE("GPL"); - -static int __init nf_conntrack_l3proto_ipv4_init(void) -{ - need_conntrack(); - return init_or_cleanup(1); -} - static void __exit nf_conntrack_l3proto_ipv4_fini(void) { - init_or_cleanup(0); + synchronize_net(); +#ifdef CONFIG_SYSCTL + unregister_sysctl_table(nf_ct_ipv4_sysctl_header); +#endif + nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); + nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); + nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp); + nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4); + nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); + nf_unregister_sockopt(&so_getorigdst); } 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 52dc175be39..4b0d361cc6e 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, } /* See ip_conntrack_proto_tcp.c */ - if (hooknum != NF_IP_PRE_ROUTING) - goto checksum_skipped; - - switch (skb->ip_summed) { - case CHECKSUM_HW: - if (!(u16)csum_fold(skb->csum)) - break; + if (hooknum == NF_IP_PRE_ROUTING && + nf_ip_checksum(skb, hooknum, dataoff, 0)) { if (LOG_INVALID(IPPROTO_ICMP)) nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, "nf_ct_icmp: bad HW ICMP checksum "); return -NF_ACCEPT; - case CHECKSUM_NONE: - if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0))) { - if (LOG_INVALID(IPPROTO_ICMP)) - nf_log_packet(PF_INET, 0, skb, NULL, NULL, - NULL, - "nf_ct_icmp: bad ICMP checksum "); - return -NF_ACCEPT; - } - default: - break; } -checksum_skipped: /* * 18 is the highest 'known' ICMP type. Anything else is a mystery * diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 1b167c4bb3b..d61e2a9d394 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -49,7 +49,7 @@ static int fold_prot_inuse(struct proto *proto) int res = 0; int cpu; - for_each_cpu(cpu) + for_each_possible_cpu(cpu) res += proto->stats[cpu].inuse; return res; @@ -91,7 +91,7 @@ fold_field(void *mib[], int offt) unsigned long res = 0; int i; - for_each_cpu(i) { + for_each_possible_cpu(i) { res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt); res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt); } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 94fcbc5e5a1..cc9423de731 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) /* Reserve room for dummy headers, this skb can pass through good chunk of routing engine. */ - skb->mac.raw = skb->data; + skb->mac.raw = skb->nh.raw = skb->data; + + /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */ + skb->nh.iph->protocol = IPPROTO_ICMP; skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); if (rta[RTA_SRC - 1]) @@ -3083,7 +3086,7 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset, memcpy(dst, src, length); /* Add the other cpus in, one int at a time */ - for_each_cpu(i) { + for_each_possible_cpu(i) { unsigned int j; src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 87f68e787d0..e2b7b805503 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1468,6 +1468,7 @@ void tcp_close(struct sock *sk, long timeout) { struct sk_buff *skb; int data_was_unread = 0; + int state; lock_sock(sk); sk->sk_shutdown = SHUTDOWN_MASK; @@ -1544,6 +1545,11 @@ void tcp_close(struct sock *sk, long timeout) sk_stream_wait_close(sk, timeout); adjudge_to_death: + state = sk->sk_state; + sock_hold(sk); + sock_orphan(sk); + atomic_inc(sk->sk_prot->orphan_count); + /* It is the last release_sock in its life. It will remove backlog. */ release_sock(sk); @@ -1555,8 +1561,9 @@ adjudge_to_death: bh_lock_sock(sk); BUG_TRAP(!sock_owned_by_user(sk)); - sock_hold(sk); - sock_orphan(sk); + /* Have we already been destroyed by a softirq or backlog? */ + if (state != TCP_CLOSE && sk->sk_state == TCP_CLOSE) + goto out; /* This is a (useful) BSD violating of the RFC. There is a * problem with TCP as specified in that the other end could @@ -1584,7 +1591,6 @@ adjudge_to_death: if (tmo > TCP_TIMEWAIT_LEN) { inet_csk_reset_keepalive_timer(sk, tcp_fin_time(sk)); } else { - atomic_inc(sk->sk_prot->orphan_count); tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); goto out; } @@ -1603,7 +1609,6 @@ adjudge_to_death: NET_INC_STATS_BH(LINUX_MIB_TCPABORTONMEMORY); } } - atomic_inc(sk->sk_prot->orphan_count); if (sk->sk_state == TCP_CLOSE) inet_csk_destroy_sock(sk); diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c index e0e9d1383c7..ba7c63ca5bb 100644 --- a/net/ipv4/tcp_highspeed.c +++ b/net/ipv4/tcp_highspeed.c @@ -135,10 +135,11 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt, /* Do additive increase */ if (tp->snd_cwnd < tp->snd_cwnd_clamp) { - tp->snd_cwnd_cnt += ca->ai; + /* cwnd = cwnd + a(w) / cwnd */ + tp->snd_cwnd_cnt += ca->ai + 1; if (tp->snd_cwnd_cnt >= tp->snd_cwnd) { - tp->snd_cwnd++; tp->snd_cwnd_cnt -= tp->snd_cwnd; + tp->snd_cwnd++; } } } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 195d8358455..b5521a9d3dc 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1649,7 +1649,7 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_sock *tp) * Hence, we can detect timed out packets during fast * retransmit without falling to slow start. */ - if (tcp_head_timedout(sk, tp)) { + if (!IsReno(tp) && tcp_head_timedout(sk, tp)) { struct sk_buff *skb; skb = tp->scoreboard_skb_hint ? tp->scoreboard_skb_hint @@ -4559,7 +4559,6 @@ discard: EXPORT_SYMBOL(sysctl_tcp_ecn); EXPORT_SYMBOL(sysctl_tcp_reordering); -EXPORT_SYMBOL(sysctl_tcp_abc); EXPORT_SYMBOL(tcp_parse_options); EXPORT_SYMBOL(tcp_rcv_established); EXPORT_SYMBOL(tcp_rcv_state_process); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9e85c041610..672950e54c4 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1859,5 +1859,4 @@ EXPORT_SYMBOL(tcp_proc_unregister); #endif EXPORT_SYMBOL(sysctl_local_port_range); EXPORT_SYMBOL(sysctl_tcp_low_latency); -EXPORT_SYMBOL(sysctl_tcp_tw_reuse); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 9d79546d384..f33c9dddaa1 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -59,9 +59,6 @@ int sysctl_tcp_tso_win_divisor = 3; int sysctl_tcp_mtu_probing = 0; int sysctl_tcp_base_mss = 512; -EXPORT_SYMBOL(sysctl_tcp_mtu_probing); -EXPORT_SYMBOL(sysctl_tcp_base_mss); - static void update_send_head(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb) { @@ -468,7 +465,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, TCP_INC_STATS(TCP_MIB_OUTSEGS); err = icsk->icsk_af_ops->queue_xmit(skb, 0); - if (unlikely(err <= 0)) + if (likely(err <= 0)) return err; tcp_enter_cwr(sk); @@ -536,6 +533,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *buff; int nsize, old_factor; + int nlen; u16 flags; BUG_ON(len > skb->len); @@ -554,7 +552,11 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); if (buff == NULL) return -ENOMEM; /* We'll just try again later. */ + sk_charge_skb(sk, buff); + nlen = skb->len - len - nsize; + buff->truesize += nlen; + skb->truesize -= nlen; /* Correct the sequence numbers. */ TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; @@ -640,7 +642,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss * eventually). The difference is that pulled data not copied, but * immediately discarded. */ -static unsigned char *__pskb_trim_head(struct sk_buff *skb, int len) +static void __pskb_trim_head(struct sk_buff *skb, int len) { int i, k, eat; @@ -665,7 +667,6 @@ static unsigned char *__pskb_trim_head(struct sk_buff *skb, int len) skb->tail = skb->data; skb->data_len -= len; skb->len = skb->data_len; - return skb->tail; } int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) @@ -674,12 +675,11 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) return -ENOMEM; - if (len <= skb_headlen(skb)) { + /* If len == headlen, we avoid __skb_pull to preserve alignment. */ + if (unlikely(len < skb_headlen(skb))) __skb_pull(skb, len); - } else { - if (__pskb_trim_head(skb, len-skb_headlen(skb)) == NULL) - return -ENOMEM; - } + else + __pskb_trim_head(skb, len - skb_headlen(skb)); TCP_SKB_CB(skb)->seq += len; skb->ip_summed = CHECKSUM_HW; @@ -1040,7 +1040,8 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len, if (unlikely(buff == NULL)) return -ENOMEM; - buff->truesize = nlen; + sk_charge_skb(sk, buff); + buff->truesize += nlen; skb->truesize -= nlen; /* Correct the sequence numbers. */ diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index 0d7d386dac2..8d30c48f090 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c @@ -8,6 +8,8 @@ #include <linux/mutex.h> #include <linux/netdevice.h> #include <linux/skbuff.h> +#include <net/icmp.h> +#include <net/ip.h> #include <net/protocol.h> #include <net/xfrm.h> @@ -70,10 +72,16 @@ static int tunnel4_rcv(struct sk_buff *skb) { struct xfrm_tunnel *handler; + if (!pskb_may_pull(skb, sizeof(struct iphdr))) + goto drop; + for (handler = tunnel4_handlers; handler; handler = handler->next) if (!handler->handler(skb)) return 0; + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); + +drop: kfree_skb(skb); return 0; } diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index e1b8f4b90d8..3e174c83bfe 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) { switch (nexthdr) { case IPPROTO_IPIP: - if (!pskb_may_pull(skb, sizeof(struct iphdr))) - return -EINVAL; *spi = skb->nh.iph->saddr; *seq = 0; return 0; @@ -90,7 +88,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) if (unlikely(x->km.state != XFRM_STATE_VALID)) goto drop_unlock; - if (x->encap->encap_type != encap_type) + if ((x->encap ? x->encap->encap_type : 0) != encap_type) goto drop_unlock; if (x->props.replay_window && xfrm_replay_check(x, seq)) diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 32ad229b4fe..4ef8efaf6a6 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c @@ -62,7 +62,7 @@ static void xfrm4_encap(struct sk_buff *skb) top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? 0 : (iph->frag_off & htons(IP_DF)); if (!top_iph->frag_off) - __ip_select_ident(top_iph, dst, 0); + __ip_select_ident(top_iph, dst->child, 0); top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index f285bbf296e..8604c747bca 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -221,7 +221,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl) if (pskb_may_pull(skb, xprth + 4 - skb->data)) { u16 *ipcomp_hdr = (u16 *)xprth; - fl->fl_ipsec_spi = ntohl(ntohs(ipcomp_hdr[1])); + fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); } break; default: |