| From 5cde3719ed617f010b2860e7dc9b78b27182f378 Mon Sep 17 00:00:00 2001 |
| From: Stephen Suryaputra <ssuryaextr@gmail.com> |
| Date: Mon, 1 Apr 2019 09:17:32 -0400 |
| Subject: vrf: check accept_source_route on the original netdevice |
| |
| [ Upstream commit 8c83f2df9c6578ea4c5b940d8238ad8a41b87e9e ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/net/ip.h | 2 +- |
| net/ipv4/ip_input.c | 7 +++---- |
| 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, |
| 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 |
| diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c |
| index 1f4737b77067..ccf0d31b6ce5 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) |
| 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); |
| 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) |
| } |
| } |
| |
| -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); |
| -- |
| 2.19.1 |
| |