Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e3850e9 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NETFILTER]: Fix xfrm lookup in ip_route_me_harder/ip6_route_me_harder



ip_route_me_harder doesn't use the port numbers of the xfrm lookup and
uses ip_route_input for non-local addresses which doesn't do a xfrm
lookup, ip6_route_me_harder doesn't do a xfrm lookup at all.

Use xfrm_decode_session and do the lookup manually, make sure both
only do the lookup if the packet hasn't been transformed already.

Makeing sure the lookup only happens once needs a new field in the
IP6CB, which exceeds the size of skb->cb. The size of skb->cb is
increased to 48b. Apparently the IPv6 mobile extensions need some
more room anyway.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8cdfab8a
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -192,6 +192,9 @@ struct inet6_skb_parm {
	__u16			dst1;
	__u16			dst1;
	__u16			lastopt;
	__u16			lastopt;
	__u32			nhoff;
	__u32			nhoff;
	__u16			flags;

#define IP6SKB_XFRM_TRANSFORMED	1
};
};


#define IP6CB(skb)	((struct inet6_skb_parm*)((skb)->cb))
#define IP6CB(skb)	((struct inet6_skb_parm*)((skb)->cb))
+1 −1
Original line number Original line Diff line number Diff line
@@ -251,7 +251,7 @@ struct sk_buff {
	 * want to keep them across layers you have to do a skb_clone()
	 * want to keep them across layers you have to do a skb_clone()
	 * first. This is owned by whoever has the skb queued ATM.
	 * first. This is owned by whoever has the skb queued ATM.
	 */
	 */
	char			cb[40];
	char			cb[48];


	unsigned int		len,
	unsigned int		len,
				data_len,
				data_len,
+2 −1
Original line number Original line Diff line number Diff line
@@ -39,7 +39,8 @@ struct inet_skb_parm


#define IPSKB_FORWARDED		1
#define IPSKB_FORWARDED		1
#define IPSKB_XFRM_TUNNEL_SIZE	2
#define IPSKB_XFRM_TUNNEL_SIZE	2
#define IPSKB_FRAG_COMPLETE	4
#define IPSKB_XFRM_TRANSFORMED	4
#define IPSKB_FRAG_COMPLETE	8
};
};


struct ipcm_cookie
struct ipcm_cookie
+1 −1
Original line number Original line Diff line number Diff line
@@ -668,7 +668,7 @@ static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *s
	return xfrm_policy_check(sk, dir, skb, AF_INET6);
	return xfrm_policy_check(sk, dir, skb, AF_INET6);
}
}



extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family);
extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);


static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
+1 −1
Original line number Original line Diff line number Diff line
@@ -832,7 +832,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
	skb->h.raw = skb->nh.raw;
	skb->h.raw = skb->nh.raw;
	skb->nh.raw = skb_push(skb, gre_hlen);
	skb->nh.raw = skb_push(skb, gre_hlen);
	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
	IPCB(skb)->flags &= ~IPSKB_XFRM_TUNNEL_SIZE;
	IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED);
	dst_release(skb->dst);
	dst_release(skb->dst);
	skb->dst = &rt->u.dst;
	skb->dst = &rt->u.dst;


Loading