Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 74520
b: refs/heads/master
c: d523a32
h: refs/heads/master
v: v3
  • Loading branch information
Herbert Xu committed Dec 3, 2007
1 parent a1452df commit f1fa3ef
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2b1e300a9dfc3196ccddf6f1d74b91b7af55e416
refs/heads/master: d523a328fb0271e1a763e985a21f2488fd816e7e
67 changes: 46 additions & 21 deletions trunk/net/ipv4/inet_diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,29 @@ static struct sock *idiagnl;
#define INET_DIAG_PUT(skb, attrtype, attrlen) \
RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))

static DEFINE_MUTEX(inet_diag_table_mutex);

static const struct inet_diag_handler *inet_diag_lock_handler(int type)
{
#ifdef CONFIG_KMOD
if (!inet_diag_table[type])
request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
NETLINK_INET_DIAG, type);
#endif

mutex_lock(&inet_diag_table_mutex);
if (!inet_diag_table[type])
return ERR_PTR(-ENOENT);

return inet_diag_table[type];
}

static inline void inet_diag_unlock_handler(
const struct inet_diag_handler *handler)
{
mutex_unlock(&inet_diag_table_mutex);
}

static int inet_csk_diag_fill(struct sock *sk,
struct sk_buff *skb,
int ext, u32 pid, u32 seq, u16 nlmsg_flags,
Expand Down Expand Up @@ -235,9 +258,12 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
struct inet_hashinfo *hashinfo;
const struct inet_diag_handler *handler;

handler = inet_diag_table[nlh->nlmsg_type];
BUG_ON(handler == NULL);
handler = inet_diag_lock_handler(nlh->nlmsg_type);
if (!handler)
return -ENOENT;

hashinfo = handler->idiag_hashinfo;
err = -EINVAL;

if (req->idiag_family == AF_INET) {
sk = inet_lookup(hashinfo, req->id.idiag_dst[0],
Expand All @@ -255,11 +281,12 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
}
#endif
else {
return -EINVAL;
goto unlock;
}

err = -ENOENT;
if (sk == NULL)
return -ENOENT;
goto unlock;

err = -ESTALE;
if ((req->id.idiag_cookie[0] != INET_DIAG_NOCOOKIE ||
Expand Down Expand Up @@ -296,6 +323,8 @@ static int inet_diag_get_exact(struct sk_buff *in_skb,
else
sock_put(sk);
}
unlock:
inet_diag_unlock_handler(handler);
return err;
}

Expand Down Expand Up @@ -678,8 +707,10 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
const struct inet_diag_handler *handler;
struct inet_hashinfo *hashinfo;

handler = inet_diag_table[cb->nlh->nlmsg_type];
BUG_ON(handler == NULL);
handler = inet_diag_lock_handler(cb->nlh->nlmsg_type);
if (!handler)
goto no_handler;

hashinfo = handler->idiag_hashinfo;

s_i = cb->args[1];
Expand Down Expand Up @@ -743,7 +774,7 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
}

if (!(r->idiag_states & ~(TCPF_LISTEN | TCPF_SYN_RECV)))
return skb->len;
goto unlock;

for (i = s_i; i < hashinfo->ehash_size; i++) {
struct inet_ehash_bucket *head = &hashinfo->ehash[i];
Expand Down Expand Up @@ -805,6 +836,9 @@ static int inet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
done:
cb->args[1] = i;
cb->args[2] = num;
unlock:
inet_diag_unlock_handler(handler);
no_handler:
return skb->len;
}

Expand All @@ -816,15 +850,6 @@ static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
nlmsg_len(nlh) < hdrlen)
return -EINVAL;

#ifdef CONFIG_KMOD
if (inet_diag_table[nlh->nlmsg_type] == NULL)
request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
NETLINK_INET_DIAG, nlh->nlmsg_type);
#endif

if (inet_diag_table[nlh->nlmsg_type] == NULL)
return -ENOENT;

if (nlh->nlmsg_flags & NLM_F_DUMP) {
if (nlmsg_attrlen(nlh, hdrlen)) {
struct nlattr *attr;
Expand Down Expand Up @@ -861,13 +886,13 @@ int inet_diag_register(const struct inet_diag_handler *h)
if (type >= INET_DIAG_GETSOCK_MAX)
goto out;

mutex_lock(&inet_diag_mutex);
mutex_lock(&inet_diag_table_mutex);
err = -EEXIST;
if (inet_diag_table[type] == NULL) {
inet_diag_table[type] = h;
err = 0;
}
mutex_unlock(&inet_diag_mutex);
mutex_unlock(&inet_diag_table_mutex);
out:
return err;
}
Expand All @@ -880,9 +905,9 @@ void inet_diag_unregister(const struct inet_diag_handler *h)
if (type >= INET_DIAG_GETSOCK_MAX)
return;

mutex_lock(&inet_diag_mutex);
mutex_lock(&inet_diag_table_mutex);
inet_diag_table[type] = NULL;
mutex_unlock(&inet_diag_mutex);
mutex_unlock(&inet_diag_table_mutex);
}
EXPORT_SYMBOL_GPL(inet_diag_unregister);

Expand All @@ -897,7 +922,7 @@ static int __init inet_diag_init(void)
goto out;

idiagnl = netlink_kernel_create(&init_net, NETLINK_INET_DIAG, 0,
inet_diag_rcv, &inet_diag_mutex, THIS_MODULE);
inet_diag_rcv, NULL, THIS_MODULE);
if (idiagnl == NULL)
goto out_free_table;
err = 0;
Expand Down

0 comments on commit f1fa3ef

Please sign in to comment.