mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-20 19:34:46 +00:00
[NETNS][RAW]: Make ipv[46] raw sockets lookup namespaces aware.
This requires just to pass the appropriate struct net pointer into __raw_v[46]_lookup and skip sockets that do not belong to a needed namespace. The proper net is get from skb->dev in all the cases. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8d96544475
commit
be185884b3
|
@ -116,16 +116,15 @@ static void raw_v4_unhash(struct sock *sk)
|
||||||
raw_unhash_sk(sk, &raw_v4_hashinfo);
|
raw_unhash_sk(sk, &raw_v4_hashinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
|
static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
|
||||||
__be32 raddr, __be32 laddr,
|
unsigned short num, __be32 raddr, __be32 laddr, int dif)
|
||||||
int dif)
|
|
||||||
{
|
{
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
|
|
||||||
sk_for_each_from(sk, node) {
|
sk_for_each_from(sk, node) {
|
||||||
struct inet_sock *inet = inet_sk(sk);
|
struct inet_sock *inet = inet_sk(sk);
|
||||||
|
|
||||||
if (inet->num == num &&
|
if (sk->sk_net == net && inet->num == num &&
|
||||||
!(inet->daddr && inet->daddr != raddr) &&
|
!(inet->daddr && inet->daddr != raddr) &&
|
||||||
!(inet->rcv_saddr && inet->rcv_saddr != laddr) &&
|
!(inet->rcv_saddr && inet->rcv_saddr != laddr) &&
|
||||||
!(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
|
!(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
|
||||||
|
@ -169,12 +168,15 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct hlist_head *head;
|
struct hlist_head *head;
|
||||||
int delivered = 0;
|
int delivered = 0;
|
||||||
|
struct net *net;
|
||||||
|
|
||||||
read_lock(&raw_v4_hashinfo.lock);
|
read_lock(&raw_v4_hashinfo.lock);
|
||||||
head = &raw_v4_hashinfo.ht[hash];
|
head = &raw_v4_hashinfo.ht[hash];
|
||||||
if (hlist_empty(head))
|
if (hlist_empty(head))
|
||||||
goto out;
|
goto out;
|
||||||
sk = __raw_v4_lookup(__sk_head(head), iph->protocol,
|
|
||||||
|
net = skb->dev->nd_net;
|
||||||
|
sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
|
||||||
iph->saddr, iph->daddr,
|
iph->saddr, iph->daddr,
|
||||||
skb->dev->ifindex);
|
skb->dev->ifindex);
|
||||||
|
|
||||||
|
@ -187,7 +189,7 @@ static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
|
||||||
if (clone)
|
if (clone)
|
||||||
raw_rcv(sk, clone);
|
raw_rcv(sk, clone);
|
||||||
}
|
}
|
||||||
sk = __raw_v4_lookup(sk_next(sk), iph->protocol,
|
sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
|
||||||
iph->saddr, iph->daddr,
|
iph->saddr, iph->daddr,
|
||||||
skb->dev->ifindex);
|
skb->dev->ifindex);
|
||||||
}
|
}
|
||||||
|
@ -273,6 +275,7 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
|
||||||
int hash;
|
int hash;
|
||||||
struct sock *raw_sk;
|
struct sock *raw_sk;
|
||||||
struct iphdr *iph;
|
struct iphdr *iph;
|
||||||
|
struct net *net;
|
||||||
|
|
||||||
hash = protocol & (RAW_HTABLE_SIZE - 1);
|
hash = protocol & (RAW_HTABLE_SIZE - 1);
|
||||||
|
|
||||||
|
@ -280,8 +283,10 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
|
||||||
raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
|
raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
|
||||||
if (raw_sk != NULL) {
|
if (raw_sk != NULL) {
|
||||||
iph = (struct iphdr *)skb->data;
|
iph = (struct iphdr *)skb->data;
|
||||||
while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr,
|
net = skb->dev->nd_net;
|
||||||
iph->saddr,
|
|
||||||
|
while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
|
||||||
|
iph->daddr, iph->saddr,
|
||||||
skb->dev->ifindex)) != NULL) {
|
skb->dev->ifindex)) != NULL) {
|
||||||
raw_err(raw_sk, skb, info);
|
raw_err(raw_sk, skb, info);
|
||||||
raw_sk = sk_next(raw_sk);
|
raw_sk = sk_next(raw_sk);
|
||||||
|
|
|
@ -76,8 +76,9 @@ static void raw_v6_unhash(struct sock *sk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
|
static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
|
||||||
struct in6_addr *loc_addr, struct in6_addr *rmt_addr, int dif)
|
unsigned short num, struct in6_addr *loc_addr,
|
||||||
|
struct in6_addr *rmt_addr, int dif)
|
||||||
{
|
{
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
int is_multicast = ipv6_addr_is_multicast(loc_addr);
|
int is_multicast = ipv6_addr_is_multicast(loc_addr);
|
||||||
|
@ -86,6 +87,9 @@ static struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
|
||||||
if (inet_sk(sk)->num == num) {
|
if (inet_sk(sk)->num == num) {
|
||||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||||
|
|
||||||
|
if (sk->sk_net != net)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!ipv6_addr_any(&np->daddr) &&
|
if (!ipv6_addr_any(&np->daddr) &&
|
||||||
!ipv6_addr_equal(&np->daddr, rmt_addr))
|
!ipv6_addr_equal(&np->daddr, rmt_addr))
|
||||||
continue;
|
continue;
|
||||||
|
@ -165,6 +169,7 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
int delivered = 0;
|
int delivered = 0;
|
||||||
__u8 hash;
|
__u8 hash;
|
||||||
|
struct net *net;
|
||||||
|
|
||||||
saddr = &ipv6_hdr(skb)->saddr;
|
saddr = &ipv6_hdr(skb)->saddr;
|
||||||
daddr = saddr + 1;
|
daddr = saddr + 1;
|
||||||
|
@ -182,7 +187,8 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
|
||||||
if (sk == NULL)
|
if (sk == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif);
|
net = skb->dev->nd_net;
|
||||||
|
sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, IP6CB(skb)->iif);
|
||||||
|
|
||||||
while (sk) {
|
while (sk) {
|
||||||
int filtered;
|
int filtered;
|
||||||
|
@ -225,7 +231,7 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
|
||||||
rawv6_rcv(sk, clone);
|
rawv6_rcv(sk, clone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr,
|
sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr,
|
||||||
IP6CB(skb)->iif);
|
IP6CB(skb)->iif);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
@ -359,6 +365,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
int hash;
|
int hash;
|
||||||
struct in6_addr *saddr, *daddr;
|
struct in6_addr *saddr, *daddr;
|
||||||
|
struct net *net;
|
||||||
|
|
||||||
hash = nexthdr & (RAW_HTABLE_SIZE - 1);
|
hash = nexthdr & (RAW_HTABLE_SIZE - 1);
|
||||||
|
|
||||||
|
@ -367,8 +374,9 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
|
||||||
if (sk != NULL) {
|
if (sk != NULL) {
|
||||||
saddr = &ipv6_hdr(skb)->saddr;
|
saddr = &ipv6_hdr(skb)->saddr;
|
||||||
daddr = &ipv6_hdr(skb)->daddr;
|
daddr = &ipv6_hdr(skb)->daddr;
|
||||||
|
net = skb->dev->nd_net;
|
||||||
|
|
||||||
while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr,
|
while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
|
||||||
IP6CB(skb)->iif))) {
|
IP6CB(skb)->iif))) {
|
||||||
rawv6_err(sk, skb, NULL, type, code,
|
rawv6_err(sk, skb, NULL, type, code,
|
||||||
inner_offset, info);
|
inner_offset, info);
|
||||||
|
|
Loading…
Reference in a new issue