summaryrefslogtreecommitdiffstats
path: root/net/netlink/genetlink.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-23 16:49:31 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-23 16:49:31 -0700
commita4c12d6c5dde48c69464baf7c703e425ee511433 (patch)
tree73c375e41a353e2da0461ff30d744bff73958b08 /net/netlink/genetlink.c
parent73af07de3e32b9ac328c3d1417258bb98a9b0a9b (diff)
parent3b9f9a1c3903b64c38505f9fed3bb11e48dbc931 (diff)
downloadlinux-a4c12d6c5dde48c69464baf7c703e425ee511433.tar.gz
linux-a4c12d6c5dde48c69464baf7c703e425ee511433.tar.bz2
linux-a4c12d6c5dde48c69464baf7c703e425ee511433.zip
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (353 commits) [IPV6] ADDRCONF: Mobile IPv6 Home Address support. [IPV6] ADDRCONF: Allow non-DAD'able addresses. [IPV6] NDISC: Fix is_router flag setting. [IPV6] ADDRCONF: Convert addrconf_lock to RCU. [IPV6] NDISC: Add proxy_ndp sysctl. [IPV6] NDISC: Set per-entry is_router flag in Proxy NA. [IPV6] NDISC: Avoid updating neighbor cache for proxied address in receiving NA. [IPV6]: Don't forward packets to proxied link-local address. [IPV6] NDISC: Handle NDP messages to proxied addresses. [NETFILTER]: PPTP conntrack: fix another GRE keymap leak [NETFILTER]: PPTP conntrack: fix GRE keymap leak [NETFILTER]: PPTP conntrack: fix PPTP_IN_CALL message types [NETFILTER]: PPTP conntrack: check call ID before changing state [NETFILTER]: PPTP conntrack: clean up debugging cruft [NETFILTER]: PPTP conntrack: consolidate header parsing [NETFILTER]: PPTP conntrack: consolidate header size checks [NETFILTER]: PPTP conntrack: simplify expectation handling [NETFILTER]: PPTP conntrack: remove unnecessary cid/pcid header pointers [NETFILTER]: PPTP conntrack: fix header definitions [NETFILTER]: PPTP conntrack: remove more dead code ...
Diffstat (limited to 'net/netlink/genetlink.c')
-rw-r--r--net/netlink/genetlink.c54
1 files changed, 46 insertions, 8 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index a298f77cc3e3..49bc2db7982b 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -387,7 +387,10 @@ static void genl_rcv(struct sock *sk, int len)
static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
u32 flags, struct sk_buff *skb, u8 cmd)
{
+ struct nlattr *nla_ops;
+ struct genl_ops *ops;
void *hdr;
+ int idx = 1;
hdr = genlmsg_put(skb, pid, seq, GENL_ID_CTRL, 0, flags, cmd,
family->version);
@@ -396,6 +399,37 @@ static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name);
NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id);
+ NLA_PUT_U32(skb, CTRL_ATTR_VERSION, family->version);
+ NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize);
+ NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr);
+
+ nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS);
+ if (nla_ops == NULL)
+ goto nla_put_failure;
+
+ list_for_each_entry(ops, &family->ops_list, ops_list) {
+ struct nlattr *nest;
+
+ nest = nla_nest_start(skb, idx++);
+ if (nest == NULL)
+ goto nla_put_failure;
+
+ NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd);
+ NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags);
+
+ if (ops->policy)
+ NLA_PUT_FLAG(skb, CTRL_ATTR_OP_POLICY);
+
+ if (ops->doit)
+ NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DOIT);
+
+ if (ops->dumpit)
+ NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DUMPIT);
+
+ nla_nest_end(skb, nest);
+ }
+
+ nla_nest_end(skb, nla_ops);
return genlmsg_end(skb, hdr);
@@ -411,6 +445,9 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
int chains_to_skip = cb->args[0];
int fams_to_skip = cb->args[1];
+ if (chains_to_skip != 0)
+ genl_lock();
+
for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
if (i < chains_to_skip)
continue;
@@ -428,6 +465,9 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
}
errout:
+ if (chains_to_skip != 0)
+ genl_unlock();
+
cb->args[0] = i;
cb->args[1] = n;
@@ -440,7 +480,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
struct sk_buff *skb;
int err;
- skb = nlmsg_new(NLMSG_GOODSIZE);
+ skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (skb == NULL)
return ERR_PTR(-ENOBUFS);
@@ -455,7 +495,8 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = {
[CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
- [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING },
+ [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
+ .len = GENL_NAMSIZ - 1 },
};
static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
@@ -470,12 +511,9 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
}
if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
- char name[GENL_NAMSIZ];
-
- if (nla_strlcpy(name, info->attrs[CTRL_ATTR_FAMILY_NAME],
- GENL_NAMSIZ) >= GENL_NAMSIZ)
- goto errout;
+ char *name;
+ name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]);
res = genl_family_find_byname(name);
}
@@ -510,7 +548,7 @@ static int genl_ctrl_event(int event, void *data)
if (IS_ERR(msg))
return PTR_ERR(msg);
- genlmsg_multicast(msg, 0, GENL_ID_CTRL);
+ genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
break;
}