summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Suryaputra <ssuryaextr@gmail.com>2019-04-01 09:17:32 -0400
committerDavid S. Miller <davem@davemloft.net>2019-04-01 13:44:58 -0400
commit8c83f2df9c6578ea4c5b940d8238ad8a41b87e9e (patch)
tree25b10b6f99295706111c3cbd972cac15a7e8ced1
parent8c1074f690bca6c6c8d79fc4a5752635cd0bfbe0 (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.h2
-rw-r--r--net/ipv4/ip_input.c7
-rw-r--r--net/ipv4/ip_options.c4
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);
678void ip_options_undo(struct ip_options *opt); 678void ip_options_undo(struct ip_options *opt);
679void ip_forward_options(struct sk_buff *skb); 679void ip_forward_options(struct sk_buff *skb);
680int ip_options_rcv_srr(struct sk_buff *skb); 680int 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
260static inline bool ip_rcv_options(struct sk_buff *skb) 260static 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
615int ip_options_rcv_srr(struct sk_buff *skb) 615int 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);