diff mbox series

[net,v2] vrf: check accept_source_route on the original netdevice

Message ID 20190327195848.7080-1-ssuryaextr@gmail.com
State Changes Requested
Delegated to: David Miller
Headers show
Series [net,v2] vrf: check accept_source_route on the original netdevice | expand

Commit Message

Stephen Suryaputra March 27, 2019, 7:58 p.m. UTC
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.

Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
---
 net/ipv4/ip_input.c   | 3 +++
 net/ipv4/ip_options.c | 6 +++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

Comments

David Miller March 29, 2019, 6:12 p.m. UTC | #1
From: Stephen Suryaputra <ssuryaextr@gmail.com>
Date: Wed, 27 Mar 2019 15:58:48 -0400

> 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.
> 
> Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>

David, please review.
David Miller March 31, 2019, 8:57 p.m. UTC | #2
From: Stephen Suryaputra <ssuryaextr@gmail.com>
Date: Wed, 27 Mar 2019 15:58:48 -0400

> 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.
> 
> Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>

David, please review this.

Thanks.
David Ahern April 1, 2019, 12:04 a.m. UTC | #3
On 3/27/19 1:58 PM, Stephen Suryaputra wrote:
> 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.
> 
> Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
> ---
>  net/ipv4/ip_input.c   | 3 +++
>  net/ipv4/ip_options.c | 6 +++++-
>  2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
> index ecce2dc78f17..754176222ef6 100644
> --- a/net/ipv4/ip_input.c
> +++ b/net/ipv4/ip_input.c
> @@ -263,6 +263,9 @@ static inline bool ip_rcv_options(struct sk_buff *skb)
>  	const struct iphdr *iph;
>  	struct net_device *dev = skb->dev;
>  
> +	if (netif_is_l3_master(dev))
> +		dev = __dev_get_by_index(dev_net(dev), IPCB(skb)->iif);

ip_rcv_options is called from ip_rcv_finish_core which already has this
dev. Passing it as an arg saves the lookup. I believe you can always use
dev as the input argument vs skb->dev.

> +
>  	/* It looks as overkill, because not all
>  	   IP options require packet mangling.
>  	   But it is the easiest for now, especially taking
> diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
> index 32a35043c9f5..99f37591d7c1 100644
> --- a/net/ipv4/ip_options.c
> +++ b/net/ipv4/ip_options.c
> @@ -620,6 +620,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
>  	struct iphdr *iph = ip_hdr(skb);
>  	unsigned char *optptr = skb_network_header(skb) + opt->srr;
>  	struct rtable *rt = skb_rtable(skb);
> +	struct net_device *dev = skb->dev;
>  	struct rtable *rt2;
>  	unsigned long orefdst;
>  	int err;
> @@ -638,6 +639,9 @@ int ip_options_rcv_srr(struct sk_buff *skb)
>  	if (rt->rt_type != RTN_LOCAL)
>  		return -EINVAL;
>  
> +	if (netif_is_l3_master(dev))
> +		dev = __dev_get_by_index(dev_net(dev), IPCB(skb)->iif);

same here - just pass net_device from ip_rcv_options
> +
>  	for (srrptr = optptr[2], srrspace = optptr[1]; srrptr <= srrspace; srrptr += 4) {
>  		if (srrptr + 3 > srrspace) {
>  			icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl((opt->srr+2)<<24));
> @@ -647,7 +651,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);
>
David Ahern April 1, 2019, 12:06 a.m. UTC | #4
On 3/31/19 2:57 PM, David Miller wrote:
> From: Stephen Suryaputra <ssuryaextr@gmail.com>
> Date: Wed, 27 Mar 2019 15:58:48 -0400
> 
>> 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.
>>
>> Signed-off-by: Stephen Suryaputra <ssuryaextr@gmail.com>
> 
> David, please review this.
> 
> Thanks.
> 

now that my heart rate is back to normal following the Auburn game ...

The change can be much simpler by passing the device down the stack from
where it is saved before the skb->dev switch.
diff mbox series

Patch

diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index ecce2dc78f17..754176222ef6 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -263,6 +263,9 @@  static inline bool ip_rcv_options(struct sk_buff *skb)
 	const struct iphdr *iph;
 	struct net_device *dev = skb->dev;
 
+	if (netif_is_l3_master(dev))
+		dev = __dev_get_by_index(dev_net(dev), IPCB(skb)->iif);
+
 	/* It looks as overkill, because not all
 	   IP options require packet mangling.
 	   But it is the easiest for now, especially taking
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 32a35043c9f5..99f37591d7c1 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -620,6 +620,7 @@  int ip_options_rcv_srr(struct sk_buff *skb)
 	struct iphdr *iph = ip_hdr(skb);
 	unsigned char *optptr = skb_network_header(skb) + opt->srr;
 	struct rtable *rt = skb_rtable(skb);
+	struct net_device *dev = skb->dev;
 	struct rtable *rt2;
 	unsigned long orefdst;
 	int err;
@@ -638,6 +639,9 @@  int ip_options_rcv_srr(struct sk_buff *skb)
 	if (rt->rt_type != RTN_LOCAL)
 		return -EINVAL;
 
+	if (netif_is_l3_master(dev))
+		dev = __dev_get_by_index(dev_net(dev), IPCB(skb)->iif);
+
 	for (srrptr = optptr[2], srrspace = optptr[1]; srrptr <= srrspace; srrptr += 4) {
 		if (srrptr + 3 > srrspace) {
 			icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl((opt->srr+2)<<24));
@@ -647,7 +651,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);