Skip to content

Commit 6735993

Browse files
dsaherndavem330
authored andcommitted
net: ipv4: 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: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 3fa6f61 commit 6735993

File tree

3 files changed

+13
-7
lines changed

3 files changed

+13
-7
lines changed

include/net/raw.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extern struct proto raw_prot;
2626
extern struct raw_hashinfo raw_v4_hashinfo;
2727
struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
2828
unsigned short num, __be32 raddr,
29-
__be32 laddr, int dif);
29+
__be32 laddr, int dif, int sdif);
3030

3131
int raw_abort(struct sock *sk, int err);
3232
void raw_icmp_error(struct sk_buff *, int, u32);

net/ipv4/raw.c

+11-5
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,17 @@ void raw_unhash_sk(struct sock *sk)
122122
EXPORT_SYMBOL_GPL(raw_unhash_sk);
123123

124124
struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
125-
unsigned short num, __be32 raddr, __be32 laddr, int dif)
125+
unsigned short num, __be32 raddr, __be32 laddr,
126+
int dif, int sdif)
126127
{
127128
sk_for_each_from(sk) {
128129
struct inet_sock *inet = inet_sk(sk);
129130

130131
if (net_eq(sock_net(sk), net) && inet->inet_num == num &&
131132
!(inet->inet_daddr && inet->inet_daddr != raddr) &&
132133
!(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
133-
!(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
134+
!(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
135+
sk->sk_bound_dev_if != sdif))
134136
goto found; /* gotcha */
135137
}
136138
sk = NULL;
@@ -171,6 +173,7 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
171173
*/
172174
static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
173175
{
176+
int sdif = inet_sdif(skb);
174177
struct sock *sk;
175178
struct hlist_head *head;
176179
int delivered = 0;
@@ -184,7 +187,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
184187
net = dev_net(skb->dev);
185188
sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
186189
iph->saddr, iph->daddr,
187-
skb->dev->ifindex);
190+
skb->dev->ifindex, sdif);
188191

189192
while (sk) {
190193
delivered = 1;
@@ -199,7 +202,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
199202
}
200203
sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
201204
iph->saddr, iph->daddr,
202-
skb->dev->ifindex);
205+
skb->dev->ifindex, sdif);
203206
}
204207
out:
205208
read_unlock(&raw_v4_hashinfo.lock);
@@ -297,12 +300,15 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
297300
read_lock(&raw_v4_hashinfo.lock);
298301
raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
299302
if (raw_sk) {
303+
int dif = skb->dev->ifindex;
304+
int sdif = inet_sdif(skb);
305+
300306
iph = (const struct iphdr *)skb->data;
301307
net = dev_net(skb->dev);
302308

303309
while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
304310
iph->daddr, iph->saddr,
305-
skb->dev->ifindex)) != NULL) {
311+
dif, sdif)) != NULL) {
306312
raw_err(raw_sk, skb, info);
307313
raw_sk = sk_next(raw_sk);
308314
iph = (const struct iphdr *)skb->data;

net/ipv4/raw_diag.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static struct sock *raw_lookup(struct net *net, struct sock *from,
4646
sk = __raw_v4_lookup(net, from, r->sdiag_raw_protocol,
4747
r->id.idiag_dst[0],
4848
r->id.idiag_src[0],
49-
r->id.idiag_if);
49+
r->id.idiag_if, 0);
5050
#if IS_ENABLED(CONFIG_IPV6)
5151
else
5252
sk = __raw_v6_lookup(net, from, r->sdiag_raw_protocol,

0 commit comments

Comments
 (0)