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

Commit 5108ab4b authored by David Ahern's avatar David Ahern Committed by David S. Miller
Browse files

net: ipv6: add second dif to raw socket lookups



Add a second device index, sdif, to raw socket lookups. sdif is the
index for ingress devices enslaved to an l3mdev. It allows the lookups
to consider the enslaved device as well as the L3 domain when searching
for a socket.

Signed-off-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4297a0ef
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
extern struct raw_hashinfo raw_v6_hashinfo;
struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
			     unsigned short num, const struct in6_addr *loc_addr,
			     const struct in6_addr *rmt_addr, int dif);
			     const struct in6_addr *rmt_addr, int dif, int sdif);

int raw_abort(struct sock *sk, int err);

+1 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ static struct sock *raw_lookup(struct net *net, struct sock *from,
		sk = __raw_v6_lookup(net, from, r->sdiag_raw_protocol,
				     (const struct in6_addr *)r->id.idiag_src,
				     (const struct in6_addr *)r->id.idiag_dst,
				     r->id.idiag_if);
				     r->id.idiag_if, 0);
#endif
	return sk;
}
+8 −5
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ EXPORT_SYMBOL_GPL(raw_v6_hashinfo);

struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
		unsigned short num, const struct in6_addr *loc_addr,
		const struct in6_addr *rmt_addr, int dif)
		const struct in6_addr *rmt_addr, int dif, int sdif)
{
	bool is_multicast = ipv6_addr_is_multicast(loc_addr);

@@ -86,7 +86,9 @@ struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
			    !ipv6_addr_equal(&sk->sk_v6_daddr, rmt_addr))
				continue;

			if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)
			if (sk->sk_bound_dev_if &&
			    sk->sk_bound_dev_if != dif &&
			    sk->sk_bound_dev_if != sdif)
				continue;

			if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
@@ -178,7 +180,8 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
		goto out;

	net = dev_net(skb->dev);
	sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, inet6_iif(skb));
	sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr,
			     inet6_iif(skb), inet6_sdif(skb));

	while (sk) {
		int filtered;
@@ -222,7 +225,7 @@ static bool ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
			}
		}
		sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr,
				     inet6_iif(skb));
				     inet6_iif(skb), inet6_sdif(skb));
	}
out:
	read_unlock(&raw_v6_hashinfo.lock);
@@ -378,7 +381,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
		net = dev_net(skb->dev);

		while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
						inet6_iif(skb)))) {
					     inet6_iif(skb), inet6_iif(skb)))) {
			rawv6_err(sk, skb, NULL, type, code,
					inner_offset, info);
			sk = sk_next(sk);