If a output ipv6 packet match a ipsec rule and the dst be set to xfrm_output correct, but there is a netfilter mangle table rule also matched the rule which set the mark value to 0x01 , and then ,in ip6t_mangle_out ,when ip6t_do_table finished, the mark value changed, and the packet need routing by ip6_route_me_harder , the packet will be decode by ip6_route_me_harder—>xfrm_decode_session->_decode_session6 the function get nexthdr from cb , I found the cb only be set when it's a incoming packet, so in this case , I got a error nexthdr value. It's caused the xfrm_lookup failure,and the packet be sendout in plaintext. u8 nexthdr = nh[IP6CB(skb)->nhoff]; //in my case, the nexthdr is always 96
I found the root cause is IP6CB(skb)->nhoff not be set in this case,the below patch could resolve the problem. diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 98a262b..1d86b2d 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -64,7 +64,7 @@ int __ip6_local_out(struct sk_buff *skb) if (len > IPV6_MAXPLEN) len = 0; ipv6_hdr(skb)->payload_len = htons(len); - + IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev, dst_output); }
Please send patches to netdev@vger.kernel.org (See Documentation/SubmittingPatches) thanks.