Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0516ef27 authored by Stephen Suryaputra's avatar Stephen Suryaputra Committed by Greg Kroah-Hartman
Browse files

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: default avatarStephen Suryaputra <ssuryaextr@gmail.com>
Reviewed-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 7243e352
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -648,7 +648,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
+3 −4
Original line number Diff line number Diff line
@@ -258,11 +258,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.
@@ -298,7 +297,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;
	}

@@ -354,7 +353,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);
+2 −2
Original line number Diff line number Diff line
@@ -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);