|
@@ -70,17 +70,28 @@ static struct xfrm_if *xfrmi_lookup(struct net *net, struct xfrm_state *x)
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static struct xfrm_if *xfrmi_decode_session(struct sk_buff *skb)
|
|
|
|
|
|
|
+static struct xfrm_if *xfrmi_decode_session(struct sk_buff *skb,
|
|
|
|
|
+ unsigned short family)
|
|
|
{
|
|
{
|
|
|
struct xfrmi_net *xfrmn;
|
|
struct xfrmi_net *xfrmn;
|
|
|
- int ifindex;
|
|
|
|
|
struct xfrm_if *xi;
|
|
struct xfrm_if *xi;
|
|
|
|
|
+ int ifindex = 0;
|
|
|
|
|
|
|
|
if (!secpath_exists(skb) || !skb->dev)
|
|
if (!secpath_exists(skb) || !skb->dev)
|
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
+ switch (family) {
|
|
|
|
|
+ case AF_INET6:
|
|
|
|
|
+ ifindex = inet6_sdif(skb);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case AF_INET:
|
|
|
|
|
+ ifindex = inet_sdif(skb);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!ifindex)
|
|
|
|
|
+ ifindex = skb->dev->ifindex;
|
|
|
|
|
+
|
|
|
xfrmn = net_generic(xs_net(xfrm_input_state(skb)), xfrmi_net_id);
|
|
xfrmn = net_generic(xs_net(xfrm_input_state(skb)), xfrmi_net_id);
|
|
|
- ifindex = skb->dev->ifindex;
|
|
|
|
|
|
|
|
|
|
for_each_xfrmi_rcu(xfrmn->xfrmi[0], xi) {
|
|
for_each_xfrmi_rcu(xfrmn->xfrmi[0], xi) {
|
|
|
if (ifindex == xi->dev->ifindex &&
|
|
if (ifindex == xi->dev->ifindex &&
|