: Reinject packet instead of calling netfilter directly on input
Subsystems (4)
cover : Reinject packet instead of calling netfilter directly on input
Herbert,
This is a simplified version of one of your earlier patches that never made it in. I liked it so much that i reduced it to this and infact given the cycles today, tested it (with transport and tunnel mode only;->).
We re-inject a decrypted ipsec (other than tunnel mode) back and let it bubble up the network stack. This improves debugability (since sniffers like tcpdump can see the packet) and usability since ingress tc filters can act on it.
Ive broken it down into two: IPv4 and IPV6. If you want to go through the xfrm reinject() method, then I am gonna need more time to resubmit or you be my guest and go for it and i will test it.
cheers,
jamal
Herbert Xu
maintainerQuoted 6 lines · jamal
Herbert,
This is a simplified version of one of your earlier patches that never made it in. I liked it so much that i reduced it to this and infact given the cycles today, tested it (with transport and tunnel mode only;->).
Sorry for the late response Jamal. I've been too busy to give this issue proper thought. It's still in my mailbox so I will respond to it once things quiten down a little.
Cheers,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtQuoted 3 lines · Herbert Xu
Sorry for the late response Jamal. I've been too busy to give this issue proper thought. It's still in my mailbox so I will respond to it once things quiten down a little.
I totaly empathize - take your time.
The point brought up on v6 extensions needs to be addressed. I thought about it a little - and it is valid as well for ipv4 options; they will be processed twice.
To build up on what Patrick said, I noticed a bit still available in the bag right after skb->nf_trace that i could use to signal "options/extensions already processed".
If people think think this is a sane use of that very lonely bit, I will post patches.
CCing Yoshfuji.
cheers,
jamal
Quoted 8 lines · jamal
The point brought up on v6 extensions needs to be addressed. I thought about it a little - and it is valid as well for ipv4 options; they will be processed twice.
To build up on what Patrick said, I noticed a bit still available in the bag right afterskb->nf_tracethat i could use to signal "options/extensions already processed".
If people think think this is a sane use of that very lonely bit, I will post patches.
And the patch included demonstrates the thought (I thought i had sent it to the list on monday; seems only to Yoshfuji). Note, blah is not a proper name, just an emphasis.
cheers,
jama
include/linux/skbuff.h +2 -1
@@ -288,7 +288,8 @@ struct sk_buff { __u8 pkt_type:3, fclone:2, ipvs_property:1, - nf_trace:1; + nf_trace:1, + blah:1;__be16 protocol;void (*destructor)(struct sk_buff *skb);
net/core/skbuff.c +1 -0
@@ -437,6 +437,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->tc_verd = old->tc_verd;#endif #endif + new->blah = old->blah;skb_copy_secmark (new, old); }
net/ipv4/ip_input.c +2 -1
@@ -348,9 +348,10 @@ static int ip_rcv_finish(struct sk_buff *skb) }#endif -if (iph->ihl >5 &&ip_rcv_options (skb)) +if (iph->ihl >5 || (!skb->blah &&ip_rcv_options (skb))) goto drop; + skb->blah =1 ; rt = (struct rtable *)skb->dst;if (rt->rt_type ==RTN_MULTICAST )IP_INC_STATS_BH (IPSTATS_MIB_INMCASTPKTS );
net/ipv4/xfrm4_input.c +14 -9
@@ -50,20 +50,25 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async) iph->protocol =XFRM_MODE_SKB_CB (skb)->protocol; -#ifdef CONFIG_NETFILTER +if (async) +return xfrm4_rcv_encap_finish (skb); +__skb_push (skb, skb->data -skb_network_header (skb)); iph->tot_len =htons (skb->len);ip_send_check (iph); -NF_HOOK (PF_INET ,NF_INET_PRE_ROUTING , skb, skb->dev,NULL , - xfrm4_rcv_encap_finish); -return 0 ; -#else -if (async) -return xfrm4_rcv_encap_finish (skb); +dst_release (skb->dst); + skb->dst =NULL ; + { +/* make some packet-sock user (eg tcpdump) happy */ +const unsigned char *old_mac; + old_mac =skb_mac_header (skb); +skb_set_mac_header (skb, -skb->mac_len); +memmove (skb_mac_header (skb), old_mac, skb->mac_len); + } -return -iph->protocol; -#endif +netif_rx (skb); +return 0 ; }/* If it's a keepalive packet, then just eat it.
net/ipv6/ip6_input.c +6 -0
@@ -158,6 +158,9 @@ static int ip6_input_finish(struct sk_buff *skb)u8 hash;struct inet6_dev *idev; +if (skb->blah) + goto ext_parse_done; +/* * Parse extension headers */
@@ -215,6 +218,9 @@ resubmit:kfree_skb (skb); }rcu_read_unlock (); + + skb->blah =1 ; +ext_parse_done:return 0 ; discard:
net/ipv6/xfrm6_input.c +14 -9
@@ -33,19 +33,24 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)skb_network_header (skb)[IP6CB (skb)->nhoff] =XFRM_MODE_SKB_CB (skb)->protocol; -#ifdef CONFIG_NETFILTER +if (async) +return ip6_rcv_finish (skb); +ipv6_hdr (skb)->payload_len =htons (skb->len);__skb_push (skb, skb->data -skb_network_header (skb)); -NF_HOOK (PF_INET6 ,NF_INET_PRE_ROUTING , skb, skb->dev,NULL , - ip6_rcv_finish); -return -1 ; -#else -if (async) -return ip6_rcv_finish (skb); +dst_release (skb->dst); + skb->dst =NULL ; + { +/* make some packet-sock user (eg tcpdump) happy */ +const unsigned char *old_mac; + old_mac =skb_mac_header (skb); +skb_set_mac_header (skb, -skb->mac_len); +memmove (skb_mac_header (skb), old_mac, skb->mac_len); + } -return 1 ; -#endif +netif_rx (skb); +return 0 ; }int xfrm6_rcv (struct sk_buff *skb)