From 4bf05eceecf2efb4c883e9e9b17825682e7330dd Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 27 Feb 2006 13:00:01 -0800 Subject: [PATCH 1/9] [IPSEC] esp: Kill unnecessary block and indentation We used to keep sg on the stack which is why the extra block was useful. We've long since stopped doing that so let's kill the block and save some indentation. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/esp4.c | 101 ++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 73bfcae8af9c..3f47419cb9c5 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -150,6 +150,10 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; int nfrags; int encap_len = 0; + u8 nexthdr[2]; + struct scatterlist *sg; + u8 workbuf[60]; + int padlen; if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) goto out; @@ -185,60 +189,55 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc if (esp->conf.ivlen) crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm)); - { - u8 nexthdr[2]; - struct scatterlist *sg = &esp->sgbuf[0]; - u8 workbuf[60]; - int padlen; + sg = &esp->sgbuf[0]; - if (unlikely(nfrags > ESP_NUM_FAST_SG)) { - sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); - if (!sg) - goto out; - } - skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen); - crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); - if (unlikely(sg != &esp->sgbuf[0])) - kfree(sg); - - if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) - BUG(); - - padlen = nexthdr[0]; - if (padlen+2 >= elen) + if (unlikely(nfrags > ESP_NUM_FAST_SG)) { + sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); + if (!sg) goto out; - - /* ... check padding bits here. Silly. :-) */ - - if (x->encap && decap && decap->decap_type) { - struct esp_decap_data *encap_data; - struct udphdr *uh = (struct udphdr *) (iph+1); - - encap_data = (struct esp_decap_data *) (decap->decap_data); - encap_data->proto = 0; - - switch (decap->decap_type) { - case UDP_ENCAP_ESPINUDP: - case UDP_ENCAP_ESPINUDP_NON_IKE: - encap_data->proto = AF_INET; - encap_data->saddr.a4 = iph->saddr; - encap_data->sport = uh->source; - encap_len = (void*)esph - (void*)uh; - break; - - default: - goto out; - } - } - - iph->protocol = nexthdr[1]; - pskb_trim(skb, skb->len - alen - padlen - 2); - memcpy(workbuf, skb->nh.raw, iph->ihl*4); - skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen); - skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen; - memcpy(skb->nh.raw, workbuf, iph->ihl*4); - skb->nh.iph->tot_len = htons(skb->len); } + skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen); + crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); + if (unlikely(sg != &esp->sgbuf[0])) + kfree(sg); + + if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) + BUG(); + + padlen = nexthdr[0]; + if (padlen+2 >= elen) + goto out; + + /* ... check padding bits here. Silly. :-) */ + + if (x->encap && decap && decap->decap_type) { + struct esp_decap_data *encap_data; + struct udphdr *uh = (struct udphdr *) (iph+1); + + encap_data = (struct esp_decap_data *) (decap->decap_data); + encap_data->proto = 0; + + switch (decap->decap_type) { + case UDP_ENCAP_ESPINUDP: + case UDP_ENCAP_ESPINUDP_NON_IKE: + encap_data->proto = AF_INET; + encap_data->saddr.a4 = iph->saddr; + encap_data->sport = uh->source; + encap_len = (void*)esph - (void*)uh; + break; + + default: + goto out; + } + } + + iph->protocol = nexthdr[1]; + pskb_trim(skb, skb->len - alen - padlen - 2); + memcpy(workbuf, skb->nh.raw, iph->ihl*4); + skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen); + skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen; + memcpy(skb->nh.raw, workbuf, iph->ihl*4); + skb->nh.iph->tot_len = htons(skb->len); return 0; From 752c1f4c78fe86d0fd6497387f763306b0d8fc53 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 27 Feb 2006 13:00:40 -0800 Subject: [PATCH 2/9] [IPSEC]: Kill post_input hook and do NAT-T in esp_input directly The only reason post_input exists at all is that it gives us the potential to adjust the checksums incrementally in future which we ought to do. However, after thinking about it for a bit we can adjust the checksums without using this post_input stuff at all. The crucial point is that only the inner-most NAT-T SA needs to be considered when adjusting checksums. What's more, the checksum adjustment comes down to a single u32 due to the linearity of IP checksums. We just happen to have a spare u32 lying around in our skb structure :) When ip_summed is set to CHECKSUM_NONE on input, the value of skb->csum is currently unused. All we have to do is to make that the checksum adjustment and voila, there goes all the post_input and decap structures! I've left in the decap data structures for now since it's intricately woven into the sec_path stuff. We can kill them later too. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/net/xfrm.h | 1 - net/ipv4/esp4.c | 128 ++++++++++++----------------------------- net/xfrm/xfrm_policy.c | 7 --- 3 files changed, 38 insertions(+), 98 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 004e645f3e18..8d362c49b8a9 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -233,7 +233,6 @@ struct xfrm_type int (*init_state)(struct xfrm_state *x); void (*destructor)(struct xfrm_state *); int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); - int (*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); int (*output)(struct xfrm_state *, struct sk_buff *pskb); /* Estimate maximal size of result of transformation of a dgram */ u32 (*get_max_size)(struct xfrm_state *, int size); diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 3f47419cb9c5..09590f356086 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -12,13 +12,6 @@ #include #include -/* decapsulation data for use when post-processing */ -struct esp_decap_data { - xfrm_address_t saddr; - __u16 sport; - __u8 proto; -}; - static int esp_output(struct xfrm_state *x, struct sk_buff *skb) { int err; @@ -210,25 +203,47 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc /* ... check padding bits here. Silly. :-) */ - if (x->encap && decap && decap->decap_type) { - struct esp_decap_data *encap_data; - struct udphdr *uh = (struct udphdr *) (iph+1); + if (x->encap) { + struct xfrm_encap_tmpl *encap = x->encap; + struct udphdr *uh; - encap_data = (struct esp_decap_data *) (decap->decap_data); - encap_data->proto = 0; - - switch (decap->decap_type) { - case UDP_ENCAP_ESPINUDP: - case UDP_ENCAP_ESPINUDP_NON_IKE: - encap_data->proto = AF_INET; - encap_data->saddr.a4 = iph->saddr; - encap_data->sport = uh->source; - encap_len = (void*)esph - (void*)uh; - break; - - default: + if (encap->encap_type != decap->decap_type) goto out; + + uh = (struct udphdr *)(iph + 1); + encap_len = (void*)esph - (void*)uh; + + /* + * 1) if the NAT-T peer's IP or port changed then + * advertize the change to the keying daemon. + * This is an inbound SA, so just compare + * SRC ports. + */ + if (iph->saddr != x->props.saddr.a4 || + uh->source != encap->encap_sport) { + xfrm_address_t ipaddr; + + ipaddr.a4 = iph->saddr; + km_new_mapping(x, &ipaddr, uh->source); + + /* XXX: perhaps add an extra + * policy check here, to see + * if we should allow or + * reject a packet from a + * different source + * address/port. + */ } + + /* + * 2) ignore UDP/TCP checksums in case + * of NAT-T in Transport Mode, or + * perform other post-processing fixes + * as per draft-ietf-ipsec-udp-encaps-06, + * section 3.1.2 + */ + if (!x->props.mode) + skb->ip_summed = CHECKSUM_UNNECESSARY; } iph->protocol = nexthdr[1]; @@ -245,63 +260,6 @@ out: return -EINVAL; } -static int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) -{ - - if (x->encap) { - struct xfrm_encap_tmpl *encap; - struct esp_decap_data *decap_data; - - encap = x->encap; - decap_data = (struct esp_decap_data *)(decap->decap_data); - - /* first, make sure that the decap type == the encap type */ - if (encap->encap_type != decap->decap_type) - return -EINVAL; - - switch (encap->encap_type) { - default: - case UDP_ENCAP_ESPINUDP: - case UDP_ENCAP_ESPINUDP_NON_IKE: - /* - * 1) if the NAT-T peer's IP or port changed then - * advertize the change to the keying daemon. - * This is an inbound SA, so just compare - * SRC ports. - */ - if (decap_data->proto == AF_INET && - (decap_data->saddr.a4 != x->props.saddr.a4 || - decap_data->sport != encap->encap_sport)) { - xfrm_address_t ipaddr; - - ipaddr.a4 = decap_data->saddr.a4; - km_new_mapping(x, &ipaddr, decap_data->sport); - - /* XXX: perhaps add an extra - * policy check here, to see - * if we should allow or - * reject a packet from a - * different source - * address/port. - */ - } - - /* - * 2) ignore UDP/TCP checksums in case - * of NAT-T in Transport Mode, or - * perform other post-processing fixes - * as per * draft-ietf-ipsec-udp-encaps-06, - * section 3.1.2 - */ - if (!x->props.mode) - skb->ip_summed = CHECKSUM_UNNECESSARY; - - break; - } - } - return 0; -} - static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) { struct esp_data *esp = x->data; @@ -457,7 +415,6 @@ static struct xfrm_type esp_type = .destructor = esp_destroy, .get_max_size = esp4_get_max_size, .input = esp_input, - .post_input = esp_post_input, .output = esp_output }; @@ -469,15 +426,6 @@ static struct net_protocol esp4_protocol = { static int __init esp4_init(void) { - struct xfrm_decap_state decap; - - if (sizeof(struct esp_decap_data) > - sizeof(decap.decap_data)) { - extern void decap_data_too_small(void); - - decap_data_too_small(); - } - if (xfrm_register_type(&esp_type, AF_INET) < 0) { printk(KERN_INFO "ip esp init: can't add xfrm type\n"); return -EAGAIN; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8206025d8e46..ae62054a9fc4 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -996,13 +996,6 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, struct sec_decap_state *xvec = &(skb->sp->x[i]); if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family)) return 0; - - /* If there is a post_input processor, try running it */ - if (xvec->xvec->type->post_input && - (xvec->xvec->type->post_input)(xvec->xvec, - &(xvec->decap), - skb) != 0) - return 0; } } From e02f7d1603c955126e88cc08149509d00be25cb9 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 27 Feb 2006 13:02:52 -0800 Subject: [PATCH 3/9] [NETFILTER]: nf_queue: don't copy registered rerouter data Use the registered data structure instead of copying it. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_queue.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index d3a4f30a7f22..24ad41e6601b 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -16,7 +16,7 @@ * for queueing and must reinject all packets it receives, no matter what. */ static struct nf_queue_handler *queue_handler[NPROTO]; -static struct nf_queue_rerouter *queue_rerouter; +static struct nf_queue_rerouter *queue_rerouter[NPROTO]; static DEFINE_RWLOCK(queue_handler_lock); @@ -64,7 +64,7 @@ int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer) return -EINVAL; write_lock_bh(&queue_handler_lock); - memcpy(&queue_rerouter[pf], rer, sizeof(queue_rerouter[pf])); + queue_rerouter[pf] = rer; write_unlock_bh(&queue_handler_lock); return 0; @@ -77,7 +77,7 @@ int nf_unregister_queue_rerouter(int pf) return -EINVAL; write_lock_bh(&queue_handler_lock); - memset(&queue_rerouter[pf], 0, sizeof(queue_rerouter[pf])); + queue_rerouter[pf] = NULL; write_unlock_bh(&queue_handler_lock); return 0; } @@ -123,7 +123,7 @@ int nf_queue(struct sk_buff **skb, return 1; } - info = kmalloc(sizeof(*info)+queue_rerouter[pf].rer_size, GFP_ATOMIC); + info = kmalloc(sizeof(*info)+queue_rerouter[pf]->rer_size, GFP_ATOMIC); if (!info) { if (net_ratelimit()) printk(KERN_ERR "OOM queueing packet %p\n", @@ -155,14 +155,14 @@ int nf_queue(struct sk_buff **skb, if (physoutdev) dev_hold(physoutdev); } #endif - if (queue_rerouter[pf].save) - queue_rerouter[pf].save(*skb, info); + if (queue_rerouter[pf]->save) + queue_rerouter[pf]->save(*skb, info); status = queue_handler[pf]->outfn(*skb, info, queuenum, queue_handler[pf]->data); - if (status >= 0 && queue_rerouter[pf].reroute) - status = queue_rerouter[pf].reroute(skb, info); + if (status >= 0 && queue_rerouter[pf]->reroute) + status = queue_rerouter[pf]->reroute(skb, info); read_unlock(&queue_handler_lock); @@ -322,22 +322,12 @@ int __init netfilter_queue_init(void) { #ifdef CONFIG_PROC_FS struct proc_dir_entry *pde; -#endif - queue_rerouter = kmalloc(NPROTO * sizeof(struct nf_queue_rerouter), - GFP_KERNEL); - if (!queue_rerouter) - return -ENOMEM; -#ifdef CONFIG_PROC_FS pde = create_proc_entry("nf_queue", S_IRUGO, proc_net_netfilter); - if (!pde) { - kfree(queue_rerouter); + if (!pde) return -1; - } pde->proc_fops = &nfqueue_file_ops; #endif - memset(queue_rerouter, 0, NPROTO * sizeof(struct nf_queue_rerouter)); - return 0; } From f92f871989c97a24d284ac60b0f880222ddf87ac Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 27 Feb 2006 13:03:10 -0800 Subject: [PATCH 4/9] [NETFILTER]: nf_queue: check if rerouter is present before using it Every rerouter needs to provide a save and a reroute function, we don't need to check for them. But we do need to check if a rerouter is registered at all for the current family, with bridging for example packets of unregistered families can hit nf_queue. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 24ad41e6601b..1fc7152fba8f 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -155,13 +155,13 @@ int nf_queue(struct sk_buff **skb, if (physoutdev) dev_hold(physoutdev); } #endif - if (queue_rerouter[pf]->save) + if (queue_rerouter[pf]) queue_rerouter[pf]->save(*skb, info); status = queue_handler[pf]->outfn(*skb, info, queuenum, queue_handler[pf]->data); - if (status >= 0 && queue_rerouter[pf]->reroute) + if (status >= 0 && queue_rerouter[pf]) status = queue_rerouter[pf]->reroute(skb, info); read_unlock(&queue_handler_lock); From 7a11b9848ae27e571f219fab5541bd84700f0d68 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 27 Feb 2006 13:03:24 -0800 Subject: [PATCH 5/9] [NETFILTER]: nf_queue: fix rerouting after packet mangling Packets should be rerouted when they come back from userspace, not before. Also move the queue_rerouters to RCU to avoid taking the queue_handler_lock for each reinjected packet. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_queue.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 1fc7152fba8f..c61f7237237f 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "nf_internals.h" @@ -64,7 +65,7 @@ int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer) return -EINVAL; write_lock_bh(&queue_handler_lock); - queue_rerouter[pf] = rer; + rcu_assign_pointer(queue_rerouter[pf], rer); write_unlock_bh(&queue_handler_lock); return 0; @@ -77,8 +78,9 @@ int nf_unregister_queue_rerouter(int pf) return -EINVAL; write_lock_bh(&queue_handler_lock); - queue_rerouter[pf] = NULL; + rcu_assign_pointer(queue_rerouter[pf], NULL); write_unlock_bh(&queue_handler_lock); + synchronize_rcu(); return 0; } EXPORT_SYMBOL_GPL(nf_unregister_queue_rerouter); @@ -114,6 +116,7 @@ int nf_queue(struct sk_buff **skb, struct net_device *physindev = NULL; struct net_device *physoutdev = NULL; #endif + struct nf_queue_rerouter *rerouter; /* QUEUE == DROP if noone is waiting, to be safe. */ read_lock(&queue_handler_lock); @@ -155,15 +158,13 @@ int nf_queue(struct sk_buff **skb, if (physoutdev) dev_hold(physoutdev); } #endif - if (queue_rerouter[pf]) - queue_rerouter[pf]->save(*skb, info); + rerouter = rcu_dereference(queue_rerouter[pf]); + if (rerouter) + rerouter->save(*skb, info); status = queue_handler[pf]->outfn(*skb, info, queuenum, queue_handler[pf]->data); - if (status >= 0 && queue_rerouter[pf]) - status = queue_rerouter[pf]->reroute(skb, info); - read_unlock(&queue_handler_lock); if (status < 0) { @@ -189,6 +190,7 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, { struct list_head *elem = &info->elem->list; struct list_head *i; + struct nf_queue_rerouter *rerouter; rcu_read_lock(); @@ -225,6 +227,12 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, verdict = NF_ACCEPT; } + if (verdict == NF_ACCEPT) { + rerouter = rcu_dereference(queue_rerouter[info->pf]); + if (rerouter && rerouter->reroute(&skb, info) < 0) + verdict = NF_DROP; + } + if (verdict == NF_ACCEPT) { next_hook: verdict = nf_iterate(&nf_hooks[info->pf][info->hook], From e121e9ecb08c3a9843243f461290869ff08be900 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 27 Feb 2006 13:03:39 -0800 Subject: [PATCH 6/9] [NETFILTER]: nf_queue: remove unnecessary check for outfn The only point of registering a queue handler is to provide an outfn, so there is no need to check for it. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index c61f7237237f..913df7dcbada 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -120,7 +120,7 @@ int nf_queue(struct sk_buff **skb, /* QUEUE == DROP if noone is waiting, to be safe. */ read_lock(&queue_handler_lock); - if (!queue_handler[pf] || !queue_handler[pf]->outfn) { + if (!queue_handler[pf]) { read_unlock(&queue_handler_lock); kfree_skb(*skb); return 1; From 45fe4dc08cbf9510074b97a16606366c1d405f4d Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 27 Feb 2006 13:03:55 -0800 Subject: [PATCH 7/9] [NETFILTER]: nf_queue: fix end-of-list check The comparison wants to find out if the last list iteration reached the end of the list. It needs to compare the iterator with the list head to do this, not the element it is looking for. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 913df7dcbada..d9f0d7ef103b 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -214,7 +214,7 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, break; } - if (elem == &nf_hooks[info->pf][info->hook]) { + if (i == &nf_hooks[info->pf][info->hook]) { /* The module which sent it to userspace is gone. */ NFDEBUG("%s: module disappeared, dropping packet.\n", __FUNCTION__); From bafac2a512bf4fd2ce7520f3976ce8aab4435f74 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 27 Feb 2006 13:04:17 -0800 Subject: [PATCH 8/9] [NETFILTER]: Restore {ipt,ip6t,ebt}_LOG compatibility The nfnetlink_log infrastructure changes broke compatiblity of the LOG targets. They currently use whatever log backend was registered first, which means that if ipt_ULOG was loaded first, no messages will be printed to the ring buffer anymore. Restore compatiblity by using the old log functions by default and only use the nf_log backend if the user explicitly said so. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter_bridge/ebt_log.h | 1 + include/linux/netfilter_ipv4/ipt_LOG.h | 3 ++- include/linux/netfilter_ipv6/ip6t_LOG.h | 3 ++- net/bridge/netfilter/ebt_log.c | 7 ++++++- net/ipv4/netfilter/ipt_LOG.c | 7 ++++++- net/ipv6/netfilter/ip6t_LOG.c | 7 ++++++- 6 files changed, 23 insertions(+), 5 deletions(-) diff --git a/include/linux/netfilter_bridge/ebt_log.h b/include/linux/netfilter_bridge/ebt_log.h index 358fbc84fb59..96e231ae7554 100644 --- a/include/linux/netfilter_bridge/ebt_log.h +++ b/include/linux/netfilter_bridge/ebt_log.h @@ -3,6 +3,7 @@ #define EBT_LOG_IP 0x01 /* if the frame is made by ip, log the ip information */ #define EBT_LOG_ARP 0x02 +#define EBT_LOG_NFLOG 0x04 #define EBT_LOG_MASK (EBT_LOG_IP | EBT_LOG_ARP) #define EBT_LOG_PREFIX_SIZE 30 #define EBT_LOG_WATCHER "log" diff --git a/include/linux/netfilter_ipv4/ipt_LOG.h b/include/linux/netfilter_ipv4/ipt_LOG.h index 22d16177319b..892f9a33fea8 100644 --- a/include/linux/netfilter_ipv4/ipt_LOG.h +++ b/include/linux/netfilter_ipv4/ipt_LOG.h @@ -6,7 +6,8 @@ #define IPT_LOG_TCPOPT 0x02 /* Log TCP options */ #define IPT_LOG_IPOPT 0x04 /* Log IP options */ #define IPT_LOG_UID 0x08 /* Log UID owning local socket */ -#define IPT_LOG_MASK 0x0f +#define IPT_LOG_NFLOG 0x10 /* Log using nf_log backend */ +#define IPT_LOG_MASK 0x1f struct ipt_log_info { unsigned char level; diff --git a/include/linux/netfilter_ipv6/ip6t_LOG.h b/include/linux/netfilter_ipv6/ip6t_LOG.h index 9008ff5c40ae..060c1a1c6c60 100644 --- a/include/linux/netfilter_ipv6/ip6t_LOG.h +++ b/include/linux/netfilter_ipv6/ip6t_LOG.h @@ -6,7 +6,8 @@ #define IP6T_LOG_TCPOPT 0x02 /* Log TCP options */ #define IP6T_LOG_IPOPT 0x04 /* Log IP options */ #define IP6T_LOG_UID 0x08 /* Log UID owning local socket */ -#define IP6T_LOG_MASK 0x0f +#define IP6T_LOG_NFLOG 0x10 /* Log using nf_log backend */ +#define IP6T_LOG_MASK 0x1f struct ip6t_log_info { unsigned char level; diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 0128fbbe2328..288ff1d4ccc4 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c @@ -166,7 +166,12 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, li.u.log.level = info->loglevel; li.u.log.logflags = info->bitmask; - nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix); + if (info->bitmask & EBT_LOG_NFLOG) + nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, + info->prefix); + else + ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, + info->prefix); } static struct ebt_watcher log = diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 6606ddb66a29..cc27545ff97f 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c @@ -425,7 +425,12 @@ ipt_log_target(struct sk_buff **pskb, li.u.log.level = loginfo->level; li.u.log.logflags = loginfo->logflags; - nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix); + if (loginfo->logflags & IPT_LOG_NFLOG) + nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, + loginfo->prefix); + else + ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li, + loginfo->prefix); return IPT_CONTINUE; } diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index 77c725832dec..6b930efa9fb9 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c @@ -436,7 +436,12 @@ ip6t_log_target(struct sk_buff **pskb, li.u.log.level = loginfo->level; li.u.log.logflags = loginfo->logflags; - nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, loginfo->prefix); + if (loginfo->logflags & IP6T_LOG_NFLOG) + nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, + loginfo->prefix); + else + ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, + loginfo->prefix); return IP6T_CONTINUE; } From ba13c98405ba44d37d148376c6615e6c8babbfdc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 27 Feb 2006 13:30:43 -0800 Subject: [PATCH 9/9] [REQSK]: Don't reset rskq_defer_accept in reqsk_queue_alloc In 295f7324ff8d9ea58b4d3ec93b1aaa1d80e048a9 I moved defer_accept from tcp_sock to request_queue and mistakingly reset it at reqsl_queue_alloc, causing calls to setsockopt(TCP_DEFER_ACCEPT ) to be lost after bind, the fix is to remove the zeroing of rskq_defer_accept from reqsl_queue_alloc. Thanks to Alexandra N. Kossovsky for reporting and testing the suggested fix. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/core/request_sock.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/core/request_sock.c b/net/core/request_sock.c index b8203de5ff07..98f0fc923f91 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c @@ -52,7 +52,6 @@ int reqsk_queue_alloc(struct request_sock_queue *queue, get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd)); rwlock_init(&queue->syn_wait_lock); queue->rskq_accept_head = queue->rskq_accept_head = NULL; - queue->rskq_defer_accept = 0; lopt->nr_table_entries = nr_table_entries; write_lock_bh(&queue->syn_wait_lock);