Skip to content

Commit

Permalink
[GENL]: Provide more information to userspace about registered genl f…
Browse files Browse the repository at this point in the history
…amilies

Additionaly exports the following information when providing
the list of registered generic netlink families:
  - protocol version
  - header size
  - maximum number of attributes
  - list of available operations including
      - id
      - flags
      - avaiability of policy and doit/dumpit function

libnl HEAD provides a utility to read this new information:

	0x0010 nlctrl version 1
	    hdrsize 0 maxattr 6
	      op GETFAMILY (0x03) [POLICY,DOIT,DUMPIT]
	0x0011 NLBL_MGMT version 1
	    hdrsize 0 maxattr 0
	      op unknown (0x02) [DOIT]
	      op unknown (0x03) [DOIT]
	      ....

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Thomas Graf authored and David S. Miller committed Sep 22, 2006
1 parent 78e5b89 commit eb32811
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
18 changes: 18 additions & 0 deletions include/linux/genetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ struct genlmsghdr {

#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))

#define GENL_ADMIN_PERM 0x01

/*
* List of reserved static generic netlink identifiers:
*/
Expand Down Expand Up @@ -43,9 +45,25 @@ enum {
CTRL_ATTR_UNSPEC,
CTRL_ATTR_FAMILY_ID,
CTRL_ATTR_FAMILY_NAME,
CTRL_ATTR_VERSION,
CTRL_ATTR_HDRSIZE,
CTRL_ATTR_MAXATTR,
CTRL_ATTR_OPS,
__CTRL_ATTR_MAX,
};

#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)

enum {
CTRL_ATTR_OP_UNSPEC,
CTRL_ATTR_OP_ID,
CTRL_ATTR_OP_FLAGS,
CTRL_ATTR_OP_POLICY,
CTRL_ATTR_OP_DOIT,
CTRL_ATTR_OP_DUMPIT,
__CTRL_ATTR_OP_MAX,
};

#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1)

#endif /* __LINUX_GENERIC_NETLINK_H */
2 changes: 0 additions & 2 deletions include/net/genetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ struct genl_family
struct list_head family_list; /* private */
};

#define GENL_ADMIN_PERM 0x01

/**
* struct genl_info - receiving information
* @snd_seq: sending sequence number
Expand Down
40 changes: 40 additions & 0 deletions net/netlink/genetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);

Expand All @@ -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;
Expand All @@ -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;

Expand Down

0 comments on commit eb32811

Please sign in to comment.