vrf: check accept_source_route on the original netdevice
Configuration check to accept source route IP options should be made on the incoming netdevice when the skb->dev is an l3mdev master. The route lookup for the source route next hop also needs the incoming netdev. v2->v3: - Simplify by passing the original netdevice down the stack (per David Ahern). Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com> Reviewed-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8c1074f690
commit
8c83f2df9c
|
@ -677,7 +677,7 @@ int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp,
|
||||||
unsigned char __user *data, int optlen);
|
unsigned char __user *data, int optlen);
|
||||||
void ip_options_undo(struct ip_options *opt);
|
void ip_options_undo(struct ip_options *opt);
|
||||||
void ip_forward_options(struct sk_buff *skb);
|
void ip_forward_options(struct sk_buff *skb);
|
||||||
int ip_options_rcv_srr(struct sk_buff *skb);
|
int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions provided by ip_sockglue.c
|
* Functions provided by ip_sockglue.c
|
||||||
|
|
|
@ -257,11 +257,10 @@ int ip_local_deliver(struct sk_buff *skb)
|
||||||
ip_local_deliver_finish);
|
ip_local_deliver_finish);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ip_rcv_options(struct sk_buff *skb)
|
static inline bool ip_rcv_options(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ip_options *opt;
|
struct ip_options *opt;
|
||||||
const struct iphdr *iph;
|
const struct iphdr *iph;
|
||||||
struct net_device *dev = skb->dev;
|
|
||||||
|
|
||||||
/* It looks as overkill, because not all
|
/* It looks as overkill, because not all
|
||||||
IP options require packet mangling.
|
IP options require packet mangling.
|
||||||
|
@ -297,7 +296,7 @@ static inline bool ip_rcv_options(struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip_options_rcv_srr(skb))
|
if (ip_options_rcv_srr(skb, dev))
|
||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +352,7 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (iph->ihl > 5 && ip_rcv_options(skb))
|
if (iph->ihl > 5 && ip_rcv_options(skb, dev))
|
||||||
goto drop;
|
goto drop;
|
||||||
|
|
||||||
rt = skb_rtable(skb);
|
rt = skb_rtable(skb);
|
||||||
|
|
|
@ -612,7 +612,7 @@ void ip_forward_options(struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ip_options_rcv_srr(struct sk_buff *skb)
|
int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ip_options *opt = &(IPCB(skb)->opt);
|
struct ip_options *opt = &(IPCB(skb)->opt);
|
||||||
int srrspace, srrptr;
|
int srrspace, srrptr;
|
||||||
|
@ -647,7 +647,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
|
||||||
|
|
||||||
orefdst = skb->_skb_refdst;
|
orefdst = skb->_skb_refdst;
|
||||||
skb_dst_set(skb, NULL);
|
skb_dst_set(skb, NULL);
|
||||||
err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev);
|
err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, dev);
|
||||||
rt2 = skb_rtable(skb);
|
rt2 = skb_rtable(skb);
|
||||||
if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {
|
if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {
|
||||||
skb_dst_drop(skb);
|
skb_dst_drop(skb);
|
||||||
|
|
Loading…
Reference in New Issue