* Johannes Berg <[EMAIL PROTECTED]> 2006-08-22 15:52
> +static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
> +     [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
> +     [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
> +     [NL80211_ATTR_FLAGS] = { .type = NLA_U32 },
> +     [NL80211_ATTR_QUEUE] = { .type = NLA_U32 },
> +     [NL80211_ATTR_FRAME] = { .type = NLA_STRING, .len = 2500 },

Might want to put this in a header so userspace can see the limit.

> +     [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
> +};
> +
> +static int nl80211_get_commands(struct sk_buff *skb, struct genl_info *info)
> +{
> +     struct nl80211_registered_driver *drv;
> +     struct sk_buff *msg;
> +     void *hdr;
> +     int err;
> +     struct nlattr *start;
> +     u8 *data;
> +
> +     drv = nl80211_drv_from_info_with_locking(info);
> +     if (IS_ERR(drv))
> +             return PTR_ERR(drv);
> +
> +     hdr = nl80211msg_new(&msg, info->snd_pid, info->snd_seq, 0,
> +                          NL80211_CMD_GET_COMMANDS);

This isn't wrong in particular but usually we reverse the
meaning of the command when sending back answers, i.e. in
your case you'd define CMD_GET_COMMAND and CMD_NEW_COMMAND
with the following behaviour:

CMD_GET_COMMAND
   Search for command specified by the attributes and send
   back a CMD_NEW_COMMAND message.

CMD_GET_COMMAND with NLM_F_DUMP
   Iterate over all commands  and send back a CMD_NEW_COMMAND
   message for each command.

In your case I'd call it GET_CMDLIST and NEW_CMDLIST which
means you request a command list with GET_CMDLIST and
receive the answer with a CMD_NEWLIST message.


> +     start = nla_nest_start(msg, NL80211_ATTR_CMDS);
> +     if (!start)
> +             goto nla_nest_failure;
> +     data = nla_data(start);
> +
> +     /* unconditionally allow some common commands we handle centrally */
> +     skb_put(msg, 1);
> +     *data++ = NL80211_CMD_GET_COMMANDS;
> +     skb_put(msg, 1);
> +     *data++ = NL80211_CMD_GET_WIPHYS;
> +     skb_put(msg, 1);
> +     *data++ = NL80211_CMD_GET_INTERFACES;
> +
> +     CHECK_CMD(inject_packet, INJECT);
> +     CHECK_CMD(add_virtual_intf, ADD_VIRTUAL_INTERFACE);
> +     CHECK_CMD(del_virtual_intf, DEL_VIRTUAL_INTERFACE);
> +
> +     nla_nest_end(msg, start);

I'd just use the command id as attribute type:

        NLA_PUT_FLAG(msg, NL80211_CMD_GET_COMMANDS);
        NLA_PUT_FLAG(msg, NL80211_CMD_GET_WIPHYS);
        ....

This makes checking avaibility of a command as easy as
accessing an array for userspace.


> +     err = genlmsg_end(msg, hdr);
> +     if (err)
> +             goto msg_free;

genlmsg_end() can't fail, it just returns skb->len which
is only of importance while dumping to see if there is
still more to dump or not.

> +void *nl80211msg_new(struct sk_buff **skb, u32 pid, u32 seq, int flags, u8 
> cmd)
> +{
> +     void *hdr;
> +
> +     *skb = nlmsg_new(NLMSG_GOODSIZE);
> +     if (!*skb)
> +             return ERR_PTR(-ENOBUFS);
> +
> +     hdr = nl80211hdr_put(*skb, pid, seq, flags, cmd);
> +     if (!hdr) {
> +             nlmsg_free(*skb);
> +             /* what would be a good error here? */
> +             return ERR_PTR(-EINVAL);
> +     }

ENOBUFS


You might want to send out notifications for various events such as the
additiona and deletion of virtual interfaces etc.
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to