vrf: check accept_source_route on the original netdevice
authorStephen Suryaputra <ssuryaextr@gmail.com>
Mon, 1 Apr 2019 13:17:32 +0000 (09:17 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 1 Apr 2019 17:44:58 +0000 (10:44 -0700)
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>
include/net/ip.h
net/ipv4/ip_input.c
net/ipv4/ip_options.c

index be3cad9c2e4c37b282e5c2d0e2ef5f05a79b7438..583526aad1d0ac6ac3681cf9cf56d4496a221c3f 100644 (file)
@@ -677,7 +677,7 @@ int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp,
                             unsigned char __user *data, int optlen);
 void ip_options_undo(struct ip_options *opt);
 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
index ecce2dc78f17eb48d91f8f6638ef0a4e8076fedf..1132d6d1796a4f7c947da76b9b39e7fbe11d3399 100644 (file)
@@ -257,11 +257,10 @@ int ip_local_deliver(struct sk_buff *skb)
                       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;
        const struct iphdr *iph;
-       struct net_device *dev = skb->dev;
 
        /* It looks as overkill, because not all
           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;
        }
 
@@ -353,7 +352,7 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk,
        }
 #endif
 
-       if (iph->ihl > 5 && ip_rcv_options(skb))
+       if (iph->ihl > 5 && ip_rcv_options(skb, dev))
                goto drop;
 
        rt = skb_rtable(skb);
index 32a35043c9f590314b7fa354d5e948b59e665214..3db31bb9df50622f8c9ae961f4eabc566d1cb74a 100644 (file)
@@ -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);
        int srrspace, srrptr;
@@ -647,7 +647,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
 
                orefdst = skb->_skb_refdst;
                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);
                if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {
                        skb_dst_drop(skb);