diff options
author | Stephen Suryaputra <ssuryaextr@gmail.com> | 2019-04-01 09:17:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-01 13:44:58 -0400 |
commit | 8c83f2df9c6578ea4c5b940d8238ad8a41b87e9e (patch) | |
tree | 25b10b6f99295706111c3cbd972cac15a7e8ced1 | |
parent | 8c1074f690bca6c6c8d79fc4a5752635cd0bfbe0 (diff) |
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>
-rw-r--r-- | include/net/ip.h | 2 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 7 | ||||
-rw-r--r-- | net/ipv4/ip_options.c | 4 |
3 files changed, 6 insertions, 7 deletions
diff --git a/include/net/ip.h b/include/net/ip.h index be3cad9c2e4c..583526aad1d0 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -677,7 +677,7 @@ int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp, | |||
677 | unsigned char __user *data, int optlen); | 677 | unsigned char __user *data, int optlen); |
678 | void ip_options_undo(struct ip_options *opt); | 678 | void ip_options_undo(struct ip_options *opt); |
679 | void ip_forward_options(struct sk_buff *skb); | 679 | void ip_forward_options(struct sk_buff *skb); |
680 | int ip_options_rcv_srr(struct sk_buff *skb); | 680 | int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev); |
681 | 681 | ||
682 | /* | 682 | /* |
683 | * Functions provided by ip_sockglue.c | 683 | * Functions provided by ip_sockglue.c |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index ecce2dc78f17..1132d6d1796a 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -257,11 +257,10 @@ int ip_local_deliver(struct sk_buff *skb) | |||
257 | ip_local_deliver_finish); | 257 | ip_local_deliver_finish); |
258 | } | 258 | } |
259 | 259 | ||
260 | static inline bool ip_rcv_options(struct sk_buff *skb) | 260 | static inline bool ip_rcv_options(struct sk_buff *skb, struct net_device *dev) |
261 | { | 261 | { |
262 | struct ip_options *opt; | 262 | struct ip_options *opt; |
263 | const struct iphdr *iph; | 263 | const struct iphdr *iph; |
264 | struct net_device *dev = skb->dev; | ||
265 | 264 | ||
266 | /* It looks as overkill, because not all | 265 | /* It looks as overkill, because not all |
267 | IP options require packet mangling. | 266 | IP options require packet mangling. |
@@ -297,7 +296,7 @@ static inline bool ip_rcv_options(struct sk_buff *skb) | |||
297 | } | 296 | } |
298 | } | 297 | } |
299 | 298 | ||
300 | if (ip_options_rcv_srr(skb)) | 299 | if (ip_options_rcv_srr(skb, dev)) |
301 | goto drop; | 300 | goto drop; |
302 | } | 301 | } |
303 | 302 | ||
@@ -353,7 +352,7 @@ static int ip_rcv_finish_core(struct net *net, struct sock *sk, | |||
353 | } | 352 | } |
354 | #endif | 353 | #endif |
355 | 354 | ||
356 | if (iph->ihl > 5 && ip_rcv_options(skb)) | 355 | if (iph->ihl > 5 && ip_rcv_options(skb, dev)) |
357 | goto drop; | 356 | goto drop; |
358 | 357 | ||
359 | rt = skb_rtable(skb); | 358 | rt = skb_rtable(skb); |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 32a35043c9f5..3db31bb9df50 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
@@ -612,7 +612,7 @@ void ip_forward_options(struct sk_buff *skb) | |||
612 | } | 612 | } |
613 | } | 613 | } |
614 | 614 | ||
615 | int ip_options_rcv_srr(struct sk_buff *skb) | 615 | int ip_options_rcv_srr(struct sk_buff *skb, struct net_device *dev) |
616 | { | 616 | { |
617 | struct ip_options *opt = &(IPCB(skb)->opt); | 617 | struct ip_options *opt = &(IPCB(skb)->opt); |
618 | int srrspace, srrptr; | 618 | int srrspace, srrptr; |
@@ -647,7 +647,7 @@ int ip_options_rcv_srr(struct sk_buff *skb) | |||
647 | 647 | ||
648 | orefdst = skb->_skb_refdst; | 648 | orefdst = skb->_skb_refdst; |
649 | skb_dst_set(skb, NULL); | 649 | skb_dst_set(skb, NULL); |
650 | err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); | 650 | err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, dev); |
651 | rt2 = skb_rtable(skb); | 651 | rt2 = skb_rtable(skb); |
652 | if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { | 652 | if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { |
653 | skb_dst_drop(skb); | 653 | skb_dst_drop(skb); |