netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Generic Netlink HOW-TO based on Jamal's original doc
@ 2006-11-10  6:08 Paul Moore
  2006-11-10  6:37 ` James Morris
                   ` (4 more replies)
  0 siblings, 5 replies; 35+ messages in thread
From: Paul Moore @ 2006-11-10  6:08 UTC (permalink / raw)
  To: hadi, tgraf; +Cc: netdev

A couple of months ago I promised Jamal and Thomas I would post some comments to
Jamal's original genetlink how-to.  However, as I started to work on the
document the diff from the original started to get a little ridiculous so
instead of posting a patch against Jamal's original how-to I'm just posting the
revised document in it's entirety.

In the document below I tried to summarize all of the things I learned while
developing NetLabel.  Some of it came from Jamal's document, some the kernel
code, and some from discussions with Thomas.  Hopefully this document will make
it much easier for others to use genetlink in the future.

If this text below is acceptable to everyone, should this be added to the
Documentation directory?


An Introduction To Using Generic Netlink
===============================================================================

Last Updated: November 10, 2006

Table of Contents

 1. Introduction
 1.1. Document Overview
 1.2. Netlink And Generic Netlink
 2. Architectural Overview
 3. Generic Netlink Families
    3.1. Family Overview
         3.1.1. The genl_family Structure
         3.1.2. The genl_ops Structure
    3.2. Registering A Family
 4. Generic Netlink Communications
    4.1. Generic Netlink Message Format
    4.2. Kernel Communication
         4.2.1. Sending Messages
         4.2.2. Receiving Messages
    4.3. Userspace Communication
 5. Recommendations
    5.1. Attributes And Message Payloads
    5.2. Operation Granularity
    5.3. Acknowledgment And Error Reporting


1. Introduction
------------------------------------------------------------------------------

1.1. Document Overview
------------------------------------------------------------------------------

This document gives is a brief introduction to Generic Netlink, some simple
examples on how to use it, and some recommendations on how to make the most of
the Generic Netlink communications interface.  While this document does not
require that the reader have a detailed understanding of what Netlink is
and how it works, some basic Netlink knowledge is assumed.  As usual, the
kernel source code is your best friend here.

While this document talks briefly about Generic Netlink from a userspace point
of view it's primary focus is on the kernel's Generic Netlink API.  It is
recommended that application developers who are interested in using Generic
Netlink make use of the libnl library[1].

[1] http://people.suug.ch/~tgr/libnl

1.2. Netlink And Generic Netlink
------------------------------------------------------------------------------

Netlink is a flexible, robust wire-format communications channel typically
used for kernel to user communication although it can also be used for
user to user and kernel to kernel communications.  Netlink communication
channels are associated with families or "busses", where each bus deals with a
specific service; for example, different Netlink busses exist for routing,
XFRM, netfilter, and several other kernel subsystems.  More information about
Netlink can be found in RFC 3549[1].

Over the years, Netlink has become very popular which has brought about a very
real concern that the number of Netlink family numbers may be exhausted in the
near future.  In response to this the Generic Netlink family was created which
acts as a Netlink multiplexer, allowing multiple service to use a single
Netlink bus.

[1] ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt

2. Architectural Overview
------------------------------------------------------------------------------

Figure #1 illustrates how the basic Generic Netlink architecture which is
composed of five different types of components.

 1) The Netlink subsystem which serves as the underlying transport layer for
    all of the Generic Netlink communications.

 2) The Generic Netlink bus which is implemented inside the kernel, but which
    is available to userspace through the socket API and inside the kernel via
    the normal Netlink and Generic Netlink APIs.

 3) The Generic Netlink users who communicate with each other over the Generic
    Netlink bus; users can exist both in kernel and user space.

 4) The Generic Netlink controller which is part of the kernel and is
    responsible for dynamically allocating Generic Netlink communication
    channels and other management tasks.  The Generic Netlink controller is
    implemented as a standard Generic Netlink user, however, it listens on a
    special, pre-allocated Generic Netlink channel.

 5) The kernel socket API.  Generic Netlink sockets are created with the
    PF_NETLINK domain and the NETLINK_GENERIC protocol values.

      +---------------------+      +---------------------+
      | (3) application "A" |      | (3) application "B" |
      +------+--------------+      +--------------+------+
             |                                    |
             \                                    /
              \                                  /
               |                                |
       +-------+--------------------------------+-------+
       |        :                               :       |   user-space
  =====+        :   (5)  Kernel socket API      :       +================
       |        :                               :       |   kernel-space
       +--------+-------------------------------+-------+
                |                               |
          +-----+-------------------------------+----+
          |        (1)  Netlink subsystem            |
          +---------------------+--------------------+
                                |
          +---------------------+--------------------+
          |       (2) Generic Netlink bus            |
          +--+--------------------------+-------+----+
             |                          |       |
     +-------+---------+                |       |
     |  (4) Controller |               /         \
     +-----------------+              /           \
                                      |           |
                   +------------------+--+     +--+------------------+
                   | (3) kernel user "X" |     | (3) kernel user "Y" |
                   +---------------------+     +---------------------+

  Figure 1: Generic Netlink Architecture

When looking at figure #1 it is important to note that any Generic Netlink
user can communicate with any other user over the bus using the same API
regardless of where the user resides in relation to the kernel/userspace
boundary.

Generic Netlink communications are essentially a series of different
communication channels which are multiplexed on a single Netlink family.
Communication channels are uniquely identified by channel numbers which are
dynamically allocated by the Generic Netlink controller.  The controller is a
special Generic Netlink user which listens on a fixed communication channel,
number 0x10, which is always present.  Kernel or userspace users which provide
services over the Generic Netlink bus establish new communication channels by
registering their services with the Generic Netlink controller.  Users who
want to use an existing service query the controller to see if it exists and
determine the correct channel number.

3. Generic Netlink Families
------------------------------------------------------------------------------

The Generic Netlink mechanism is based on a client-server model.  The Generic
Netlink servers register families, which are a collection of well defined
services, with the controller and the clients communicate with the server
through these service registrations.  This section explains how Generic Netlink
families are defined, created and registered.

3.1. Family Overview
------------------------------------------------------------------------------

Generic Netlink family service registrations are defined by two structures,
genl_family and genl_ops.  The genl_family structure defines the family and
it's associated communication channel.  The genl_ops structure defines
an individual service or operation which the family provides to other Generic
Netlink users.

This section focuses on Generic Netlink families as they are represented in
the kernel.  A similar API exists for userspace applications using the libnl
library[1].

[1] http://people.suug.ch/~tgr/libnl

3.1.2. The genl_family Structure

Generic Netlink services are defined by the genl_family structure, which is
shown below:

  struct genl_family
  {
        unsigned int            id;
        unsigned int            hdrsize;
        char                    name[GENL_NAMSIZ];
        unsigned int            version;
        unsigned int            maxattr;
        struct nlattr **        attrbuf;
        struct list_head        ops_list;
        struct list_head        family_list;
  };

  Figure 2: The genl_family structure

The genl_family structure fields are used in the following manner:

 * unsigned int id

   This is the dynamically allocated channel number.  A value of 0x0 signifies
   that the channel number should be assigned by the controller and the 0x10
   value is reserved for use by the controller.  Users should always use
   value 0x0 when registering a new family.

 * unsigned int hdrsize

   If the family makes use of a family specific header, it's size is stored
   here.  If there is no family specific header this value should be zero.

 * char name[GENL_NAMSIZ]

   This string should be unique to the family as it is the key that the
   controller uses to lookup channel numbers when requested.

 * unsigned int version

   Family specific version number.

 * unsigned int maxattr

   Generic Netlink makes use of the standard Netlink attributes, this value
   holds the maximum number of attributes defined for the Generic Netlink
   family.

 * struct nlattr **attrbuf
 * struct list_head ops_list
 * struct list_head family_list

   These are private fields and should not be modified.

3.1.2. The genl_ops Structure

  struct genl_ops
  {
        u8                      cmd;
        unsigned int            flags;
        struct nla_policy       *policy;
        int                     (*doit)(struct sk_buff *skb,
                                        struct genl_info *info);
        int                     (*dumpit)(struct sk_buff *skb,
                                          struct netlink_callback *cb);
        struct list_head        ops_list;
  };

  Figure 3: The genl_ops structure

The genl_ops structure fields are used in the following manner:

 * u8 cmd

   This value is unique across the corresponding Generic Netlink family and is
   used to reference the operation.

 * unsigned int flags

   This field is used to specify any special attributes of the operation.  The
   following flags may be used, multiple flags can be OR'd together:

   - GENL_ADMIN_PERM

     The operation requires the CAP_NET_ADMIN privilege

 * struct nla_policy policy

   This field defines the Netlink attribute policy for the operation request
   message.  If specified, the Generic Netlink mechanism uses this policy to
   verify all of the attributes in a operation request message before calling
   the operation handler.

   The attribute policy is defined as an array of nla_policy structures indexed
   by the attribute number.  The nla_policy structure is defined in figure #4.

     struct nla_policy
     {
        u16             type;
        u16             len;
     };

     Figure 4: The nla_policy structure

   The fields are used in the following manner:

   - u16 type

     This specifies the type of the attribute, presently the following types
     are defined for general use:

     o NLA_UNSPEC

       Undefined type

     o NLA_U8

       A 8 bit unsigned integer

     o NLA_U16

       A 16 bit unsigned integer

     o NLA_U32

       A 32 bit unsigned integer

     o NLA_U64

       A 64 bit unsigned integer

     o NLA_FLAG

       A simple boolean flag

     o NLA_MSECS

       A 64 bit time value in msecs

     o NLA_STRING

       A variable length string

     o NLA_NUL_STRING

       A variable length NULL terminated string

     o NLA_NESTED

       A stream of attributes

   - u16 len

     When the attribute type is one of the string types then this field should
     be set to the maximum length of the string, not including the terminal
     NULL byte.  If the attribute type is unknown or NLA_UNSPEC then this field
     should be set to the exact length of the attribute's payload.

     Unless the attribute type is one of the fixed length types above, a value
     of zero indicates that no validation of the attribute should be performed.

 * int (*doit)(struct skbuff *skb, struct genl_info *info)

   This callback is similar in use to the standard Netlink 'doit' callback, the
   primary difference being the change in parameters.

   The 'doit' handler receives two parameters, the first if the message buffer
   which triggered the handler and the second is a Generic Netlink genl_info
   structure which is defined in figure #5.

     struct genl_ops
     {
        u32                     snd_seq;
        u32                     snd_pid;
        struct nlmsghdr *       nlhdr;
        struct genlmsghdr *     genlhdr;
        void *                  userhdr;
        struct nlattr **        attrs;
     };

     Figure 5: The genl_info structure

   The fields are populated in the following manner:

   - u32 snd_seq

     This is the Netlink sequence number of the request.

   - u32 snd_pid

     This is the PID of the client which issued the request.

   - struct nlmsghdr *nlhdr

     This is set to point to the Netlink message header of the request.

   - struct genlmsghdr *genlhdr

     This is set to point to the Generic Netlink message header of the request.

   - void *userhdr

     If the Generic Netlink family makes use of a family specific header, this
     pointer will be set to point to the start of the family specific header.

   - struct nlattr **attrs

     The parsed Netlink attributes from the request, if the Generic Netlink
     family definition specified a Netlink attribute policy then the
     attributes will have already been validated.

   The 'doit' handler should do whatever processing is necessary and return
   zero on success, or a negative value on failure.  Negative return values
   will cause a NLMSG_ERROR message to be sent while a zero return value will
   only cause a NLMSG_ERROR message to be sent if the request is received with
   the NLM_F_ACK flag set.

 * int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb)

   This callback is similar in use to the standard Netlink 'dumpit' callback.
   The 'dumpit' callback is invoked when a Generic Netlink message is received
   with the NLM_F_DUMP flag set.

   The main difference between a 'dumpit' handler and a 'doit' handler is
   that a 'dumpit' handler does not allocate a message buffer for a response;
   a pre-allocated sk_buff is passed to the 'dumpit' handler as the first
   parameter.  The 'dumpit' handler should fill the message buffer with the
   appropriate response message and return the size of the sk_buff,
   i.e. sk_buff->len, and the message buffer will automatically be sent to the
   Generic Netlink client that initiated the request.  As long as the 'dumpit'
   handler returns a value greater than zero it will be called again with a
   newly allocated message buffer to fill, when the handler has no more data
   to send it should return zero; error conditions are indicated by returning
   a negative value.  If necessary, state can be preserved in the
   netlink_callback parameter which is passed to the 'dumpit' handler; the
   netlink_callback parameter values will be preserved across handler calls
   for a single request.

 * struct list_head ops_list

   This is a private field and should not be modified.

3.2. Registering A Family
------------------------------------------------------------------------------

Registering a Generic Netlink family is a simple four step process: define the
family, define the operations, register the family, register the operations.
In order to help demonstrate these steps below is a simple example broken down
and explained in detail.

The first step is to define the family itself, which we do by creating an
instance of the genl_family structure which we explained in section 3.1.1..
In our simple example we are going to create a new Generic Netlink family
named "DOC_EXMPL".

  /* attributes */
  enum {
        DOC_EXMPL_A_UNSPEC,
        DOC_EXMPL_A_MSG,
        __DOC_EXMPL_A_MAX,
  };
  #define DOC_EXMPL_A_MAX (__DOC_EXMPL_A_MAX - 1)

  /* attribute policy */
  static struct nla_policy doc_exmpl_genl_policy = [DOC_EXMPL_A_MAX + 1] = {
        [DOC_EXMPL_A_MSG] = { .type = NLA_NUL_STRING },
  }

  /* family definition */
  static struct genl_family doc_exmpl_gnl_family = {
        .id = GENL_ID_GENERATE,
        .hdrsize = 0,
        .name = "DOC_EXMPL",
        .version = 1,
        .maxattr = DOC_EXMPL_A_MAX,

  };

  Figure 6: The DOC_EXMPL family, attributes, and policy

You can see above that we defined a new family and the family recognizes a
single attribute, DOC_EXMPL_A_ECHO, which is a NULL terminated string.  The
GENL_ID_GENERATE macro/constant is really just the value 0x0 and it signifies
that we want the Generic Netlink controller to assign the channel number when
we register the family.

The second step is to define the operations for the family, which we do by
creating at least one instance of the genl_ops structure which we explained in
section 3.1.2..  In this example we are only going to define one operation but
you can define up to 255 unique operations for each family.

  /* handler */
  int doc_exmpl_echo(struct sk_buff *skb, struct genl_info *info)
  {
        /* message handling code goes here; return 0 on success, negative
         * values on failure */
  }

  /* commands */
  enum {
        DOC_EXMPL_C_UNSPEC,
        DOC_EXMPL_C_ECHO,
        __DOC_EXMPL_C_ECHO,
  };
  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)

  /* operation definition */
  struct genl_ops doc_exmpl_gnl_ops_echo = {
        .cmd = DOC_EXMPL_C_ECHO,
        .flags = 0,
        .policy = doc_exmpl_genl_policy,
	.doit = doc_exmpl_echo,
	.dumpit = NULL,
  }

  Figure 7: The DOC_EXMPL_C_ECHO operation

Here we have defined a single operation, DOC_EXMPL_C_ECHO, which uses the
Netlink attribute policy we defined above.  Once registered, this particular
operation would call the doc_exmpl_echo() function whenever a
DOC_EXMPL_C_ECHO message is sent to the DOC_EXMPL family over the Generic
Netlink bus.

The third step it to register the DOC_EXMPL family with the Generic Netlink
operation.  We do this with a single function call:

  genl_register_family(&doc_exmpl_gnl_family);

This call registers the new family name with the Generic Netlink mechanism and
requests a new channel number which is stored in the genl_family struct,
replacing the GENL_ID_GENERATE value.  It is important to remember to
unregister Generic Netlink families when done as the kernel does allocate
resources for each registered family.

The fourth and final step is to register the operations for the family.  Once
again this is a simple function call:

  genl_register_ops(&doc_exmpl_gnl_family, &doc_exmpl_gnl_ops_echo);

This call registers the DOC_EXMPL_C_ECHO operation in association with the
DOC_EXMPL family.  The process is now complete, other Generic Netlink users can
now issue DOC_EXMPL_C_ECHO commands and they will be handled as desired.

4.  Generic Netlink Communications
------------------------------------------------------------------------------

This section deals with the Generic Netlink messages themselves and how to
send and receive messages.

4.1. Generic Netlink Message Format
------------------------------------------------------------------------------

Generic Netlink uses the standard Netlink subsystem as a transport layer which
means that the foundation of the Generic Netlink message is the standard
Netlink message format, the only difference is the inclusion of a Generic
Netlink message header.  The format of the message is defined below:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                Netlink message header (nlmsghdr)              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           Generic Netlink message header (genlmsghdr)         |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |             Optional user specific message header             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           Optional Generic Netlink message payload            |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  Figure 8: Generic Netlink message format

Figure #8 is included only to give you a rough idea of how Generic Netlink
messages are formatted and sent on the "wire".  In practice the Netlink and
Generic Netlink API should insulate most users from the details of the message
format and the Netlink message headers.

4.2 Kernel Communication
------------------------------------------------------------------------------

The kernel provides two sets of interfaces for sending, receiving, and
processing Generic Netlink messages.  The majority of the API consists of the
general purpose Netlink interfaces, however, there are a small number of
interfaces specific to Generic Netlink.  The following two include files
define the Netlink and Generic Netlink API for the kernel.

 * include/net/netlink.h
 * include/net/genetlink.h

4.2.1. Sending Messages

Sending Generic Netlink messages is a three step process: allocate memory for
the message buffer, create the message, send the message.  In order to help
demonstrate these steps below is a simple example using the DOC_EXMPL family
shown in section 3.

The first step is to allocate a Netlink message buffer, the easiest way to do
this is with the nlsmsg_new() function.

  struct sk_buff *skb;

  skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  if (skb == NULL)
      goto failure;

  Figure 9: Allocating a Generic Netlink message buffer

The NLMSG_GOODSIZE macro/constant is a good value to use when you do not know
the size of the message buffer at the time of allocation.  Don't forget that
the message buffer needs to be big enough to hold the message payload and both
the Netlink and Generic Netlink message headers.

The second step is to actually create the message payload.  This is obviously
something which is very specific to each use service, but a simple example is
shown below.

  int rc;
  void *msg_head;

  /* create the message headers */
  msg_head = genlmsg_put(skb, pid, seq, type, 0, flags, DOC_EXMPL_C_ECHO, 1);
  if (msg_head == NULL) {
      rc = -ENOMEM;
      goto failure;
  }
  /* add a DOC_EXMPL_A_MSG attribute */
  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Generic Netlink Rocks");
  if (rc != 0)
      goto failure;
  /* finalize the message */
  genlmsg_end(skb, msg_head);

  Figure 10: Creating a Generic Netlink message payload

The genlmsg_put() function creates the required Netlink and Generic Netlink
message headers, populating them with the given values; see the Generic
Netlink header file for a description of the parameters.  The nla_put_string()
function is a standard Netlink attribute function which adds a string
attribute to the end of the Netlink message; see the Netlink header file for a
description of the parameters.  The genlmsg_end() function updates the Netlink
message header once the message payload has been finalized, this function
should be called before sending the message.

The third and final step is to send the Generic Netlink message which can be
done with a single function call.  The example below is for a unicast send,
but interfaces exist for doing a multicast send of Generic Netlink message.

  int rc;

  rc = genlmsg_unicast(skb, pid);
  if (rc != 0)
      goto failure;

  Figure 11: Sending Generic Netlink messages

4.2.2. Receiving Messages

Typically, the kernel acts a Generic Netlink server which means that the act of
receiving messages is handled automatically by the Generic Netlink bus.  Once
the bus receives the message and determines the correct routing, the message
is passed directly to the family specific operation callback for processing.
If the kernel is acting as a Generic Netlink client, server response messages
can be received over the Generic Netlink socket using standard kernel socket
interfaces.

4.3. Userspace Communication
------------------------------------------------------------------------------

While Generic Netlink messages can be sent and received using the standard
socket API it is recommended that user space applications use the libnl
library[1].  The libnl library insulates applications from many of the low
level Netlink tasks and uses an API which is very similar to the kernel API
shown above.

[1] http://people.suug.ch/~tgr/libnl

5. Recommendations
------------------------------------------------------------------------------

The Generic Netlink mechanism is a very flexible communications mechanism and
as a result there are many different ways it can be used.  The following
recommendations are based on conventions within the Linux kernel and should be
followed whenever possible.  While not all existing kernel code follows the
recommendations outlined here all new code should consider these
recommendations as requirements.

5.1. Attributes And Message Payloads
------------------------------------------------------------------------------

When defining new Generic Netlink message formats you must make use of the
Netlink attributes wherever possible.  The Netlink attribute mechanism has
been carefully designed to allow for future message expansion while preserving
backward compatibility.  There are also additional benefits to using Netlink
attributes which include developer familiarity and basic input checking.

Most common data structures can be represented with Netlink attributes:

 * scalar values

   Most scalar values already have well defined attribute types, see section 3
   for details

 * structures

   Structures can be represented using a nested attribute with the structure
   fields represented as attributes in the payload of the container attribute

 * arrays

   Arrays can be represented by using a single nested attribute as a container
   with several of the same attribute type inside each representing a spot in
   the array

It is also important to use unique attributes as much as possible.  This helps
make the most of the Netlink attribute mechanisms and provides for easy changes
to the message format in the future.

5.2. Operation Granularity
------------------------------------------------------------------------------

While it may be tempting to register a single operation for a Generic Netlink
family and multiplex multiple sub-commands on the single operation this
is strongly discouraged for security reasons.  Combining multiple behaviors
into one operation makes it difficult to restrict the operations using the
existing Linux kernel security mechanisms.

5.3. Acknowledgment and Error Reporting
------------------------------------------------------------------------------

It is often necessary for Generic Netlink services to return an ACK or error
code to the client.  It is not necessary to implement an explicit
acknowledgment message as Netlink already provides a flexible acknowledgment
and error reporting message type called NLMSG_ERROR.  When an error occurs a
NLMSG_ERROR message is returned to the client with the error code returned by
the Generic Netlink operation handler.  Clients can also request a NLMSG_ERROR
message when no error has occurred by setting the NLM_F_ACK flag on requests.

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10  6:08 Generic Netlink HOW-TO based on Jamal's original doc Paul Moore
@ 2006-11-10  6:37 ` James Morris
  2006-11-10  6:45   ` Paul Moore
  2006-11-10  9:48 ` Thomas Graf
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 35+ messages in thread
From: James Morris @ 2006-11-10  6:37 UTC (permalink / raw)
  To: Paul Moore; +Cc: hadi, tgraf, netdev


> An Introduction To Using Generic Netlink
> ===============================================================================

Wow, this is great!


-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10  6:37 ` James Morris
@ 2006-11-10  6:45   ` Paul Moore
  2006-11-10 14:34     ` jamal
  0 siblings, 1 reply; 35+ messages in thread
From: Paul Moore @ 2006-11-10  6:45 UTC (permalink / raw)
  To: James Morris; +Cc: hadi, tgraf, netdev

James Morris wrote:
>>An Introduction To Using Generic Netlink
>>===============================================================================
> 
> 
> Wow, this is great!

Thanks.  I consider it an act of penance for all of the evil things I did
with Netlink on my first few iterations of NetLabel ;)

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10  6:08 Generic Netlink HOW-TO based on Jamal's original doc Paul Moore
  2006-11-10  6:37 ` James Morris
@ 2006-11-10  9:48 ` Thomas Graf
  2006-11-10 16:08   ` Paul Moore
  2006-11-10 13:24 ` Jarek Poplawski
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 35+ messages in thread
From: Thomas Graf @ 2006-11-10  9:48 UTC (permalink / raw)
  To: Paul Moore; +Cc: hadi, netdev

* Paul Moore <paul.moore@hp.com> 2006-11-10 01:08

Excellent!

>    - u32 snd_pid
> 
>      This is the PID of the client which issued the request.

In order to avoid confusion it might be better to call it
"netlink PID" as it is not equal to the process ID.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10  6:08 Generic Netlink HOW-TO based on Jamal's original doc Paul Moore
  2006-11-10  6:37 ` James Morris
  2006-11-10  9:48 ` Thomas Graf
@ 2006-11-10 13:24 ` Jarek Poplawski
  2006-11-10 16:10   ` Paul Moore
  2006-11-10 17:36   ` Thomas Graf
  2006-11-10 15:49 ` Stephen Hemminger
  2006-11-10 18:23 ` Randy Dunlap
  4 siblings, 2 replies; 35+ messages in thread
From: Jarek Poplawski @ 2006-11-10 13:24 UTC (permalink / raw)
  To: Paul Moore; +Cc: netdev

On 10-11-2006 07:08, Paul Moore wrote:
... 
> An Introduction To Using Generic Netlink
> ===============================================================================
...

Here is a proposal of small adjustments.
Maybe some of them will be useful.

Best regards,
Jarek P.
---

--- netlink.txt-	2006-11-10 10:53:50.000000000 +0100
+++ netlink.txt	2006-11-10 14:08:25.000000000 +0100
@@ -32,7 +32,7 @@
 1.1. Document Overview
 ------------------------------------------------------------------------------
 
-This document gives is a brief introduction to Generic Netlink, some simple
+This document gives a brief introduction to Generic Netlink, some simple
 examples on how to use it, and some recommendations on how to make the most of
 the Generic Netlink communications interface.  While this document does not
 require that the reader have a detailed understanding of what Netlink is
@@ -55,21 +55,21 @@
 channels are associated with families or "busses", where each bus deals with a
 specific service; for example, different Netlink busses exist for routing,
 XFRM, netfilter, and several other kernel subsystems.  More information about
-Netlink can be found in RFC 3549[1].
+Netlink can be found in RFC 3549[2].
 
 Over the years, Netlink has become very popular which has brought about a very
 real concern that the number of Netlink family numbers may be exhausted in the
 near future.  In response to this the Generic Netlink family was created which
-acts as a Netlink multiplexer, allowing multiple service to use a single
+acts as a Netlink multiplexer, allowing multiple services to use a single
 Netlink bus.
 
-[1] ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt
+[2] ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt
 
 2. Architectural Overview
 ------------------------------------------------------------------------------
 
-Figure #1 illustrates how the basic Generic Netlink architecture which is
-composed of five different types of components.
+Figure #1 illustrates the basic Generic Netlink architecture which is
+composed of five different types of components:
 
  1) The Netlink subsystem which serves as the underlying transport layer for
     all of the Generic Netlink communications.
@@ -99,7 +99,7 @@
                |                                |
        +-------+--------------------------------+-------+
        |        :                               :       |   user-space
-  =====+        :   (5)  Kernel socket API      :       +================
+  =====+        :   (5)  kernel socket API      :       +================
        |        :                               :       |   kernel-space
        +--------+-------------------------------+-------+
                 |                               |
@@ -112,7 +112,7 @@
           +--+--------------------------+-------+----+
              |                          |       |
      +-------+---------+                |       |
-     |  (4) Controller |               /         \
+     |  (4) controller |               /         \
      +-----------------+              /           \
                                       |           |
                    +------------------+--+     +--+------------------+
@@ -149,7 +149,7 @@
 3.1. Family Overview
 ------------------------------------------------------------------------------
 
-Generic Netlink family service registrations are defined by two structures,
+Generic Netlink family service registrations are defined by two structures:
 genl_family and genl_ops.  The genl_family structure defines the family and
 it's associated communication channel.  The genl_ops structure defines
 an individual service or operation which the family provides to other Generic
@@ -161,7 +161,7 @@
 
 [1] http://people.suug.ch/~tgr/libnl
 
-3.1.2. The genl_family Structure
+3.1.1. The genl_family Structure
 
 Generic Netlink services are defined by the genl_family structure, which is
 shown below:
@@ -241,7 +241,7 @@
  * unsigned int flags
 
    This field is used to specify any special attributes of the operation.  The
-   following flags may be used, multiple flags can be OR'd together:
+   following flags may be used (multiple flags can be OR'd together):
 
    - GENL_ADMIN_PERM
 
@@ -251,11 +251,12 @@
 
    This field defines the Netlink attribute policy for the operation request
    message.  If specified, the Generic Netlink mechanism uses this policy to
-   verify all of the attributes in a operation request message before calling
+   verify all of the attributes in an operation request message before calling
    the operation handler.
 
    The attribute policy is defined as an array of nla_policy structures indexed
-   by the attribute number.  The nla_policy structure is defined in figure #4.
+   by the attribute number.  The nla_policy structure is defined as shown in
+   figure #4.
 
      struct nla_policy
      {
@@ -269,7 +270,7 @@
 
    - u16 type
 
-     This specifies the type of the attribute, presently the following types
+     This specifies the type of the attribute; presently the following types
      are defined for general use:
 
      o NLA_UNSPEC
@@ -278,7 +279,7 @@
 
      o NLA_U8
 
-       A 8 bit unsigned integer
+       An 8 bit unsigned integer
 
      o NLA_U16
 
@@ -327,11 +328,11 @@
    This callback is similar in use to the standard Netlink 'doit' callback, the
    primary difference being the change in parameters.
 
-   The 'doit' handler receives two parameters, the first if the message buffer
+   The 'doit' handler receives two parameters: the first is the message buffer
    which triggered the handler and the second is a Generic Netlink genl_info
-   structure which is defined in figure #5.
+   structure which is defined as shown in figure #5.
 
-     struct genl_ops
+     struct genl_info
      {
         u32                     snd_seq;
         u32                     snd_pid;
@@ -368,12 +369,12 @@
 
    - struct nlattr **attrs
 
-     The parsed Netlink attributes from the request, if the Generic Netlink
+     The parsed Netlink attributes from the request; if the Generic Netlink
      family definition specified a Netlink attribute policy then the
-     attributes will have already been validated.
+     attributes would have already been validated.
 
    The 'doit' handler should do whatever processing is necessary and return
-   zero on success, or a negative value on failure.  Negative return values
+   zero on success or a negative value on failure.  Negative return values
    will cause a NLMSG_ERROR message to be sent while a zero return value will
    only cause a NLMSG_ERROR message to be sent if the request is received with
    the NLM_F_ACK flag set.
@@ -392,7 +393,7 @@
    i.e. sk_buff->len, and the message buffer will automatically be sent to the
    Generic Netlink client that initiated the request.  As long as the 'dumpit'
    handler returns a value greater than zero it will be called again with a
-   newly allocated message buffer to fill, when the handler has no more data
+   newly allocated message buffer to fill.  When the handler has no more data
    to send it should return zero; error conditions are indicated by returning
    a negative value.  If necessary, state can be preserved in the
    netlink_callback parameter which is passed to the 'dumpit' handler; the
@@ -412,7 +413,7 @@
 and explained in detail.
 
 The first step is to define the family itself, which we do by creating an
-instance of the genl_family structure which we explained in section 3.1.1..
+instance of the genl_family structure which we explained in section 3.1.1.
 In our simple example we are going to create a new Generic Netlink family
 named "DOC_EXMPL".
 
@@ -436,7 +437,6 @@
         .name = "DOC_EXMPL",
         .version = 1,
         .maxattr = DOC_EXMPL_A_MAX,
-
   };
 
   Figure 6: The DOC_EXMPL family, attributes, and policy
@@ -449,7 +449,7 @@
 
 The second step is to define the operations for the family, which we do by
 creating at least one instance of the genl_ops structure which we explained in
-section 3.1.2..  In this example we are only going to define one operation but
+section 3.1.2.  In this example we are only going to define one operation but
 you can define up to 255 unique operations for each family.
 
   /* handler */
@@ -465,7 +465,7 @@
         DOC_EXMPL_C_ECHO,
         __DOC_EXMPL_C_ECHO,
   };
-  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)
+  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_ECHO - 1)
 
   /* operation definition */
   struct genl_ops doc_exmpl_gnl_ops_echo = {
@@ -492,7 +492,7 @@
 This call registers the new family name with the Generic Netlink mechanism and
 requests a new channel number which is stored in the genl_family struct,
 replacing the GENL_ID_GENERATE value.  It is important to remember to
-unregister Generic Netlink families when done as the kernel does allocate
+unregister Generic Netlink families when done, as the kernel does allocate
 resources for each registered family.
 
 The fourth and final step is to register the operations for the family.  Once
@@ -501,7 +501,7 @@
   genl_register_ops(&doc_exmpl_gnl_family, &doc_exmpl_gnl_ops_echo);
 
 This call registers the DOC_EXMPL_C_ECHO operation in association with the
-DOC_EXMPL family.  The process is now complete, other Generic Netlink users can
+DOC_EXMPL family.  The process is now complete.  Other Generic Netlink users can
 now issue DOC_EXMPL_C_ECHO commands and they will be handled as desired.
 
 4.  Generic Netlink Communications
@@ -515,8 +515,8 @@
 
 Generic Netlink uses the standard Netlink subsystem as a transport layer which
 means that the foundation of the Generic Netlink message is the standard
-Netlink message format, the only difference is the inclusion of a Generic
-Netlink message header.  The format of the message is defined below:
+Netlink message format - the only difference is the inclusion of a Generic
+Netlink message header.  The format of the message is defined as shown below:
 
    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -540,11 +540,11 @@
 4.2 Kernel Communication
 ------------------------------------------------------------------------------
 
-The kernel provides two sets of interfaces for sending, receiving, and
+The kernel provides two sets of interfaces for sending, receiving and
 processing Generic Netlink messages.  The majority of the API consists of the
 general purpose Netlink interfaces, however, there are a small number of
-interfaces specific to Generic Netlink.  The following two include files
-define the Netlink and Generic Netlink API for the kernel.
+interfaces specific to Generic Netlink.  The following two 'include' files
+define the Netlink and Generic Netlink API for the kernel:
 
  * include/net/netlink.h
  * include/net/genetlink.h
@@ -556,7 +556,7 @@
 demonstrate these steps below is a simple example using the DOC_EXMPL family
 shown in section 3.
 
-The first step is to allocate a Netlink message buffer, the easiest way to do
+The first step is to allocate a Netlink message buffer; the easiest way to do
 this is with the nlsmsg_new() function.
 
   struct sk_buff *skb;
@@ -573,7 +573,7 @@
 the Netlink and Generic Netlink message headers.
 
 The second step is to actually create the message payload.  This is obviously
-something which is very specific to each use service, but a simple example is
+something which is very specific to each used service, but a simple example is
 shown below.
 
   int rc;
@@ -643,7 +643,7 @@
 as a result there are many different ways it can be used.  The following
 recommendations are based on conventions within the Linux kernel and should be
 followed whenever possible.  While not all existing kernel code follows the
-recommendations outlined here all new code should consider these
+recommendations outlined here, all new code should consider these
 recommendations as requirements.
 
 5.1. Attributes And Message Payloads
@@ -681,7 +681,7 @@
 ------------------------------------------------------------------------------
 
 While it may be tempting to register a single operation for a Generic Netlink
-family and multiplex multiple sub-commands on the single operation this
+family and multiplex multiple sub-commands on the single operation, this
 is strongly discouraged for security reasons.  Combining multiple behaviors
 into one operation makes it difficult to restrict the operations using the
 existing Linux kernel security mechanisms.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10  6:45   ` Paul Moore
@ 2006-11-10 14:34     ` jamal
  2006-11-10 16:17       ` Paul Moore
  0 siblings, 1 reply; 35+ messages in thread
From: jamal @ 2006-11-10 14:34 UTC (permalink / raw)
  To: Paul Moore
  Cc: Randy.Dunlap, Balbir Singh, Shailabh Nagar, James Morris, tgraf,
	netdev

On Fri, 2006-10-11 at 01:45 -0500, Paul Moore wrote:
> James Morris wrote:
> >>An Introduction To Using Generic Netlink
> >>===============================================================================
> > 
> > 
> > Wow, this is great!
> 
> Thanks.  I consider it an act of penance for all of the evil things I did
> with Netlink on my first few iterations of NetLabel ;)

Hey, theres more than one way to pay for your sins ;->
For example: Do you wanna take over maintainance of the doc? ;->
i.e it would make a lot of sense to finally submit it for inclusion.
Thanks for the effort.

I havent read it - dont have the time till this weekend. I would like
to have input as well from the other folks who have opined in the past
(on CC list - they seemed to have strong opinions of what should be in
the doc).

This is also timely because this weekend i was going to work on a
presentation on this stuff for a conference ;-> So i will actually
have to read what you put together. I will have more comments later when
i am done reading.

cheers,
jamal


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10  6:08 Generic Netlink HOW-TO based on Jamal's original doc Paul Moore
                   ` (2 preceding siblings ...)
  2006-11-10 13:24 ` Jarek Poplawski
@ 2006-11-10 15:49 ` Stephen Hemminger
  2006-11-10 16:20   ` Paul Moore
  2006-11-10 18:23 ` Randy Dunlap
  4 siblings, 1 reply; 35+ messages in thread
From: Stephen Hemminger @ 2006-11-10 15:49 UTC (permalink / raw)
  To: Paul Moore; +Cc: hadi, tgraf, netdev

Paul Moore wrote:
> A couple of months ago I promised Jamal and Thomas I would post some comments to
> Jamal's original genetlink how-to.  However, as I started to work on the
> document the diff from the original started to get a little ridiculous so
> instead of posting a patch against Jamal's original how-to I'm just posting the
> revised document in it's entirety.
>
> In the document below I tried to summarize all of the things I learned while
> developing NetLabel.  Some of it came from Jamal's document, some the kernel
> code, and some from discussions with Thomas.  Hopefully this document will make
> it much easier for others to use genetlink in the future.
>
> If this text below is acceptable to everyone, should this be added to the
> Documentation directory?
>   
Mind if we put a wikified version on http://linux-net.osdl.org?

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10  9:48 ` Thomas Graf
@ 2006-11-10 16:08   ` Paul Moore
  0 siblings, 0 replies; 35+ messages in thread
From: Paul Moore @ 2006-11-10 16:08 UTC (permalink / raw)
  To: Thomas Graf; +Cc: hadi, netdev

Thomas Graf wrote:
> * Paul Moore <paul.moore@hp.com> 2006-11-10 01:08
> 
> Excellent!

Thanks.

>>   - u32 snd_pid
>>
>>     This is the PID of the client which issued the request.
> 
> In order to avoid confusion it might be better to call it
> "netlink PID" as it is not equal to the process ID.

Good point, I just made the change.  I'll push out another rev of the document
once the rest of the group has had a chance to review the doc.

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 13:24 ` Jarek Poplawski
@ 2006-11-10 16:10   ` Paul Moore
  2006-11-10 17:36   ` Thomas Graf
  1 sibling, 0 replies; 35+ messages in thread
From: Paul Moore @ 2006-11-10 16:10 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: netdev

Jarek Poplawski wrote:
> On 10-11-2006 07:08, Paul Moore wrote:
> ... 
> 
>>An Introduction To Using Generic Netlink
>>===============================================================================
> 
> ...
> 
> Here is a proposal of small adjustments.
> Maybe some of them will be useful.

They all look very useful to me, thank you very much.  I'm going to merge your
patch and I'll put out an updated rev of the document once Jamal and some others
have had a chance to review the document.

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 14:34     ` jamal
@ 2006-11-10 16:17       ` Paul Moore
  2006-11-10 16:59         ` Randy Dunlap
  0 siblings, 1 reply; 35+ messages in thread
From: Paul Moore @ 2006-11-10 16:17 UTC (permalink / raw)
  To: hadi
  Cc: Randy.Dunlap, Balbir Singh, Shailabh Nagar, James Morris, tgraf,
	netdev

jamal wrote:
> On Fri, 2006-10-11 at 01:45 -0500, Paul Moore wrote:
> 
>>James Morris wrote:
>>
>>>>An Introduction To Using Generic Netlink
>>>>===============================================================================
>>>
>>>
>>>Wow, this is great!
>>
>>Thanks.  I consider it an act of penance for all of the evil things I did
>>with Netlink on my first few iterations of NetLabel ;)
> 
> 
> Hey, theres more than one way to pay for your sins ;->
> For example: Do you wanna take over maintainance of the doc? ;->

There is a sucker born every minute. right? :)

I'll make you a deal: I'll take over maintainance of the document as long as you
promise to send me your feedback by Monday.

> i.e it would make a lot of sense to finally submit it for inclusion.
> Thanks for the effort.

I think so too, I'm glad I was able to help out.

> I havent read it - dont have the time till this weekend. I would like
> to have input as well from the other folks who have opined in the past
> (on CC list - they seemed to have strong opinions of what should be in
> the doc).
> 
> This is also timely because this weekend i was going to work on a
> presentation on this stuff for a conference ;-> So i will actually
> have to read what you put together. I will have more comments later when
> i am done reading.

Okay, I've already made some changes based on other comments in this thread but
I'll refrain from pushing out an updated version until early next week.  I'll
also make the next version of the document a patch against net-2.6.20.

Thanks.

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 15:49 ` Stephen Hemminger
@ 2006-11-10 16:20   ` Paul Moore
  0 siblings, 0 replies; 35+ messages in thread
From: Paul Moore @ 2006-11-10 16:20 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: hadi, tgraf, netdev

Stephen Hemminger wrote:
> Paul Moore wrote:
> 
>>A couple of months ago I promised Jamal and Thomas I would post some comments to
>>Jamal's original genetlink how-to.  However, as I started to work on the
>>document the diff from the original started to get a little ridiculous so
>>instead of posting a patch against Jamal's original how-to I'm just posting the
>>revised document in it's entirety.
>>
>>In the document below I tried to summarize all of the things I learned while
>>developing NetLabel.  Some of it came from Jamal's document, some the kernel
>>code, and some from discussions with Thomas.  Hopefully this document will make
>>it much easier for others to use genetlink in the future.
>>
>>If this text below is acceptable to everyone, should this be added to the
>>Documentation directory?
>>  
> 
> Mind if we put a wikified version on http://linux-net.osdl.org?

That sounds fine to me, although can we hold off for a little bit so I can
collect some more comments?  Is the wiki open to anyone, i.e. can I add the
document directly, or am I better off just letting you do it?

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 16:17       ` Paul Moore
@ 2006-11-10 16:59         ` Randy Dunlap
  0 siblings, 0 replies; 35+ messages in thread
From: Randy Dunlap @ 2006-11-10 16:59 UTC (permalink / raw)
  To: Paul Moore
  Cc: hadi, Randy.Dunlap, Balbir Singh, Shailabh Nagar, James Morris,
	tgraf, netdev

On Fri, 10 Nov 2006 11:17:11 -0500 Paul Moore wrote:

> jamal wrote:
> > On Fri, 2006-10-11 at 01:45 -0500, Paul Moore wrote:
> > 
> >>James Morris wrote:
> >>
> >>>>An Introduction To Using Generic Netlink
> >>>>===============================================================================
> >>>
> >>>
> >>>Wow, this is great!
> >>
> >>Thanks.  I consider it an act of penance for all of the evil things I did
> >>with Netlink on my first few iterations of NetLabel ;)
> > 
> > 
> > Hey, theres more than one way to pay for your sins ;->
> > For example: Do you wanna take over maintainance of the doc? ;->
> 
> There is a sucker born every minute. right? :)
> 
> I'll make you a deal: I'll take over maintainance of the document as long as you
> promise to send me your feedback by Monday.

Jamal,
Were my patches ever merged into your document?


> > i.e it would make a lot of sense to finally submit it for inclusion.
> > Thanks for the effort.
> 
> I think so too, I'm glad I was able to help out.
> 
> > I havent read it - dont have the time till this weekend. I would like
> > to have input as well from the other folks who have opined in the past
> > (on CC list - they seemed to have strong opinions of what should be in
> > the doc).
> > 
> > This is also timely because this weekend i was going to work on a
> > presentation on this stuff for a conference ;-> So i will actually
> > have to read what you put together. I will have more comments later when
> > i am done reading.
> 
> Okay, I've already made some changes based on other comments in this thread but
> I'll refrain from pushing out an updated version until early next week.  I'll
> also make the next version of the document a patch against net-2.6.20.


---
~Randy

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 13:24 ` Jarek Poplawski
  2006-11-10 16:10   ` Paul Moore
@ 2006-11-10 17:36   ` Thomas Graf
  2006-11-13  7:05     ` Jarek Poplawski
  2006-11-13  7:23     ` Jarek Poplawski
  1 sibling, 2 replies; 35+ messages in thread
From: Thomas Graf @ 2006-11-10 17:36 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: Paul Moore, netdev

* Jarek Poplawski <jarkao2@o2.pl> 2006-11-10 14:24
> @@ -449,7 +449,7 @@
>  
>  The second step is to define the operations for the family, which we do by
>  creating at least one instance of the genl_ops structure which we explained in
> -section 3.1.2..  In this example we are only going to define one operation but
> +section 3.1.2.  In this example we are only going to define one operation but
>  you can define up to 255 unique operations for each family.
>  
>    /* handler */
> @@ -465,7 +465,7 @@
>          DOC_EXMPL_C_ECHO,
>          __DOC_EXMPL_C_ECHO,

Careful, the typo is here, not below.

>    };
> -  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)
> +  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_ECHO - 1)
>  
>    /* operation definition */
>    struct genl_ops doc_exmpl_gnl_ops_echo = {

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10  6:08 Generic Netlink HOW-TO based on Jamal's original doc Paul Moore
                   ` (3 preceding siblings ...)
  2006-11-10 15:49 ` Stephen Hemminger
@ 2006-11-10 18:23 ` Randy Dunlap
  2006-11-10 19:50   ` Paul Moore
  2006-11-10 22:12   ` Thomas Graf
  4 siblings, 2 replies; 35+ messages in thread
From: Randy Dunlap @ 2006-11-10 18:23 UTC (permalink / raw)
  To: Paul Moore; +Cc: hadi, tgraf, netdev

[-- Attachment #1: Type: text/plain, Size: 885 bytes --]

On Fri, 10 Nov 2006 01:08:23 -0500 Paul Moore wrote:

> An Introduction To Using Generic Netlink
> ===============================================================================
> 3.1.2. The genl_family Structure
> 
> Generic Netlink services are defined by the genl_family structure, which is
> shown below:
> 
>   struct genl_family
>   {
>         unsigned int            id;
>         unsigned int            hdrsize;
>         char                    name[GENL_NAMSIZ];
>         unsigned int            version;
>         unsigned int            maxattr;
>         struct nlattr **        attrbuf;
>         struct list_head        ops_list;
>         struct list_head        family_list;
>   };

Any alignment/packing concerns here?  or that is already
handled, just not presented here?

and same questions for other structs below (deleted).


Typo patch attached.

---
~Randy

[-- Attachment #2: generic-netlink-howto.diff --]
[-- Type: text/x-patch, Size: 5033 bytes --]

--- generic-netlink-howto.txt.~1~	2006-11-10 09:35:03.000000000 -0800
+++ generic-netlink-howto.txt	2006-11-10 10:21:10.000000000 -0800
@@ -40,7 +40,7 @@
 kernel source code is your best friend here.
 
 While this document talks briefly about Generic Netlink from a userspace point
-of view it's primary focus is on the kernel's Generic Netlink API.  It is
+of view, its primary focus is on the kernel's Generic Netlink API.  It is
 recommended that application developers who are interested in using Generic
 Netlink make use of the libnl library[1].
 
@@ -141,17 +141,17 @@
 ------------------------------------------------------------------------------
 
 The Generic Netlink mechanism is based on a client-server model.  The Generic
-Netlink servers register families, which are a collection of well defined
+Netlink servers register families, which are a collection of well-defined
 services, with the controller and the clients communicate with the server
 through these service registrations.  This section explains how Generic Netlink
-families are defined, created and registered.
+families are defined, created, and registered.
 
 3.1. Family Overview
 ------------------------------------------------------------------------------
 
 Generic Netlink family service registrations are defined by two structures,
 genl_family and genl_ops.  The genl_family structure defines the family and
-it's associated communication channel.  The genl_ops structure defines
+its associated communication channel.  The genl_ops structure defines
 an individual service or operation which the family provides to other Generic
 Netlink users.
 
@@ -191,7 +191,7 @@
 
  * unsigned int hdrsize
 
-   If the family makes use of a family specific header, it's size is stored
+   If the family makes use of a family specific header, its size is stored
    here.  If there is no family specific header this value should be zero.
 
  * char name[GENL_NAMSIZ]
@@ -278,19 +278,19 @@
 
      o NLA_U8
 
-       A 8 bit unsigned integer
+       A 8-bit unsigned integer
 
      o NLA_U16
 
-       A 16 bit unsigned integer
+       A 16-bit unsigned integer
 
      o NLA_U32
 
-       A 32 bit unsigned integer
+       A 32-bit unsigned integer
 
      o NLA_U64
 
-       A 64 bit unsigned integer
+       A 64-bit unsigned integer
 
      o NLA_FLAG
 
@@ -298,7 +298,7 @@
 
      o NLA_MSECS
 
-       A 64 bit time value in msecs
+       A 64-bit time value in msecs
 
      o NLA_STRING
 
@@ -319,7 +319,7 @@
      NULL byte.  If the attribute type is unknown or NLA_UNSPEC then this field
      should be set to the exact length of the attribute's payload.
 
-     Unless the attribute type is one of the fixed length types above, a value
+     Unless the attribute type is one of the fixed-length types above, a value
      of zero indicates that no validation of the attribute should be performed.
 
  * int (*doit)(struct skbuff *skb, struct genl_info *info)
@@ -331,7 +331,7 @@
    which triggered the handler and the second is a Generic Netlink genl_info
    structure which is defined in figure #5.
 
-     struct genl_ops
+     struct genl_info
      {
         u32                     snd_seq;
         u32                     snd_pid;
@@ -449,7 +449,7 @@
 
 The second step is to define the operations for the family, which we do by
 creating at least one instance of the genl_ops structure which we explained in
-section 3.1.2..  In this example we are only going to define one operation but
+section 3.1.2.  In this example we are only going to define one operation but
 you can define up to 255 unique operations for each family.
 
   /* handler */
@@ -659,19 +659,19 @@
 
  * scalar values
 
-   Most scalar values already have well defined attribute types, see section 3
-   for details
+   Most scalar values already have well-defined attribute types; see section 3
+   for details.
 
  * structures
 
    Structures can be represented using a nested attribute with the structure
-   fields represented as attributes in the payload of the container attribute
+   fields represented as attributes in the payload of the container attribute.
 
  * arrays
 
    Arrays can be represented by using a single nested attribute as a container
    with several of the same attribute type inside each representing a spot in
-   the array
+   the array.
 
 It is also important to use unique attributes as much as possible.  This helps
 make the most of the Netlink attribute mechanisms and provides for easy changes
@@ -681,7 +681,7 @@
 ------------------------------------------------------------------------------
 
 While it may be tempting to register a single operation for a Generic Netlink
-family and multiplex multiple sub-commands on the single operation this
+family and multiplex multiple sub-commands on the single operation, this
 is strongly discouraged for security reasons.  Combining multiple behaviors
 into one operation makes it difficult to restrict the operations using the
 existing Linux kernel security mechanisms.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 18:23 ` Randy Dunlap
@ 2006-11-10 19:50   ` Paul Moore
  2006-11-10 22:12   ` Thomas Graf
  1 sibling, 0 replies; 35+ messages in thread
From: Paul Moore @ 2006-11-10 19:50 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: hadi, tgraf, netdev

Randy Dunlap wrote:
> On Fri, 10 Nov 2006 01:08:23 -0500 Paul Moore wrote:
> 
>>An Introduction To Using Generic Netlink
>>===============================================================================
>>3.1.2. The genl_family Structure
>>
>>Generic Netlink services are defined by the genl_family structure, which is
>>shown below:
>>
>>  struct genl_family
>>  {
>>        unsigned int            id;
>>        unsigned int            hdrsize;
>>        char                    name[GENL_NAMSIZ];
>>        unsigned int            version;
>>        unsigned int            maxattr;
>>        struct nlattr **        attrbuf;
>>        struct list_head        ops_list;
>>        struct list_head        family_list;
>>  };
> 
> Any alignment/packing concerns here?  or that is already
> handled, just not presented here?
> 
> and same questions for other structs below (deleted).

These structure contents/layout were taken straight from the code.

> Typo patch attached.

Applied, thanks.

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 18:23 ` Randy Dunlap
  2006-11-10 19:50   ` Paul Moore
@ 2006-11-10 22:12   ` Thomas Graf
  2006-11-10 22:49     ` Randy Dunlap
  1 sibling, 1 reply; 35+ messages in thread
From: Thomas Graf @ 2006-11-10 22:12 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: Paul Moore, hadi, netdev, Arnaldo Carvalho de Melo

* Randy Dunlap <randy.dunlap@oracle.com> 2006-11-10 10:23
> On Fri, 10 Nov 2006 01:08:23 -0500 Paul Moore wrote:
> 
> > An Introduction To Using Generic Netlink
> > ===============================================================================
> > 3.1.2. The genl_family Structure
> > 
> > Generic Netlink services are defined by the genl_family structure, which is
> > shown below:
> > 
> >   struct genl_family
> >   {
> >         unsigned int            id;
> >         unsigned int            hdrsize;
> >         char                    name[GENL_NAMSIZ];
> >         unsigned int            version;
> >         unsigned int            maxattr;
> >         struct nlattr **        attrbuf;
> >         struct list_head        ops_list;
> >         struct list_head        family_list;
> >   };
> 
> Any alignment/packing concerns here?  or that is already
> handled, just not presented here?

I thought I chose GENL_NAMESIZ wisely but to be sure I checked
with Mr. Alignment himself, Arnaldo:

struct genl_family {
        unsigned int               id;                   /* 0(0)     4 */
        unsigned int               hdrsize;              /* 4(0)     4 */
        char                       name[16];             /* 8(0)    16 */
        unsigned int               version;              /* 24(0)     4 */
        unsigned int               maxattr;              /* 28(0)     4 */
        /* ---------- cacheline 1 boundary ---------- */
        struct nlattr * *          attrbuf;              /* 32(0)     4 */
        struct list_head           ops_list;             /* 36(0)     8 */
        struct list_head           family_list;          /* 44(0)     8 */
}; /* size: 52 */

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 22:12   ` Thomas Graf
@ 2006-11-10 22:49     ` Randy Dunlap
  2006-11-10 22:56       ` Thomas Graf
  0 siblings, 1 reply; 35+ messages in thread
From: Randy Dunlap @ 2006-11-10 22:49 UTC (permalink / raw)
  To: Thomas Graf; +Cc: Paul Moore, hadi, netdev, Arnaldo Carvalho de Melo

Thomas Graf wrote:
> * Randy Dunlap <randy.dunlap@oracle.com> 2006-11-10 10:23
>> On Fri, 10 Nov 2006 01:08:23 -0500 Paul Moore wrote:
>>
>>> An Introduction To Using Generic Netlink
>>> ===============================================================================
>>> 3.1.2. The genl_family Structure
>>>
>>> Generic Netlink services are defined by the genl_family structure, which is
>>> shown below:
>>>
>>>   struct genl_family
>>>   {
>>>         unsigned int            id;
>>>         unsigned int            hdrsize;
>>>         char                    name[GENL_NAMSIZ];
>>>         unsigned int            version;
>>>         unsigned int            maxattr;
>>>         struct nlattr **        attrbuf;
>>>         struct list_head        ops_list;
>>>         struct list_head        family_list;
>>>   };
>> Any alignment/packing concerns here?  or that is already
>> handled, just not presented here?
> 
> I thought I chose GENL_NAMESIZ wisely but to be sure I checked
> with Mr. Alignment himself, Arnaldo:

Hm, looks OK to me.  Am I missing something?

> struct genl_family {
>         unsigned int               id;                   /* 0(0)     4 */
>         unsigned int               hdrsize;              /* 4(0)     4 */
>         char                       name[16];             /* 8(0)    16 */
>         unsigned int               version;              /* 24(0)     4 */
>         unsigned int               maxattr;              /* 28(0)     4 */
>         /* ---------- cacheline 1 boundary ---------- */
>         struct nlattr * *          attrbuf;              /* 32(0)     4 */
>         struct list_head           ops_list;             /* 36(0)     8 */
>         struct list_head           family_list;          /* 44(0)     8 */
> }; /* size: 52 */

How about field size issues?  Usually for int's etc. that are in
userspace interfaces, we use __u32 etc.

-- 
~Randy

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 22:49     ` Randy Dunlap
@ 2006-11-10 22:56       ` Thomas Graf
  2006-11-10 23:17         ` Randy Dunlap
  0 siblings, 1 reply; 35+ messages in thread
From: Thomas Graf @ 2006-11-10 22:56 UTC (permalink / raw)
  To: Randy Dunlap; +Cc: Paul Moore, hadi, netdev, Arnaldo Carvalho de Melo

* Randy Dunlap <randy.dunlap@oracle.com> 2006-11-10 14:49
> >I thought I chose GENL_NAMESIZ wisely but to be sure I checked
> >with Mr. Alignment himself, Arnaldo:
> 
> Hm, looks OK to me.  Am I missing something?

It is OK, I was merely trying to prove it :-)

> >struct genl_family {
> >        unsigned int               id;                   /* 0(0)     4 */
> >        unsigned int               hdrsize;              /* 4(0)     4 */
> >        char                       name[16];             /* 8(0)    16 */
> >        unsigned int               version;              /* 24(0)     4 */
> >        unsigned int               maxattr;              /* 28(0)     4 */
> >        /* ---------- cacheline 1 boundary ---------- */
> >        struct nlattr * *          attrbuf;              /* 32(0)     4 */
> >        struct list_head           ops_list;             /* 36(0)     8 */
> >        struct list_head           family_list;          /* 44(0)     8 */
> >}; /* size: 52 */
> 
> How about field size issues?  Usually for int's etc. that are in
> userspace interfaces, we use __u32 etc.

This is kernel side only, struct genl_family lives in net/genetlink.h
and is not exported to userspace.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 22:56       ` Thomas Graf
@ 2006-11-10 23:17         ` Randy Dunlap
  0 siblings, 0 replies; 35+ messages in thread
From: Randy Dunlap @ 2006-11-10 23:17 UTC (permalink / raw)
  To: Thomas Graf; +Cc: Paul Moore, hadi, netdev, Arnaldo Carvalho de Melo

Thomas Graf wrote:
> * Randy Dunlap <randy.dunlap@oracle.com> 2006-11-10 14:49
>>> I thought I chose GENL_NAMESIZ wisely but to be sure I checked
>>> with Mr. Alignment himself, Arnaldo:
>> Hm, looks OK to me.  Am I missing something?
> 
> It is OK, I was merely trying to prove it :-)
> 
>>> struct genl_family {
>>>        unsigned int               id;                   /* 0(0)     4 */
>>>        unsigned int               hdrsize;              /* 4(0)     4 */
>>>        char                       name[16];             /* 8(0)    16 */
>>>        unsigned int               version;              /* 24(0)     4 */
>>>        unsigned int               maxattr;              /* 28(0)     4 */
>>>        /* ---------- cacheline 1 boundary ---------- */
>>>        struct nlattr * *          attrbuf;              /* 32(0)     4 */
>>>        struct list_head           ops_list;             /* 36(0)     8 */
>>>        struct list_head           family_list;          /* 44(0)     8 */
>>> }; /* size: 52 */
>> How about field size issues?  Usually for int's etc. that are in
>> userspace interfaces, we use __u32 etc.
> 
> This is kernel side only, struct genl_family lives in net/genetlink.h
> and is not exported to userspace.

OK, thanks for the clarifications.

-- 
~Randy

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 17:36   ` Thomas Graf
@ 2006-11-13  7:05     ` Jarek Poplawski
  2006-11-13  7:23     ` Jarek Poplawski
  1 sibling, 0 replies; 35+ messages in thread
From: Jarek Poplawski @ 2006-11-13  7:05 UTC (permalink / raw)
  To: Thomas Graf; +Cc: Paul Moore, netdev

On Fri, Nov 10, 2006 at 06:36:42PM +0100, Thomas Graf wrote:
> * Jarek Poplawski <jarkao2@o2.pl> 2006-11-10 14:24
> > @@ -449,7 +449,7 @@
> >  
> >  The second step is to define the operations for the family, which we do by
> >  creating at least one instance of the genl_ops structure which we explained in
> > -section 3.1.2..  In this example we are only going to define one operation but
> > +section 3.1.2.  In this example we are only going to define one operation but
> >  you can define up to 255 unique operations for each family.
> >  
> >    /* handler */
> > @@ -465,7 +465,7 @@
> >          DOC_EXMPL_C_ECHO,
> >          __DOC_EXMPL_C_ECHO,
> 
> Careful, the typo is here, not below.
> 
> >    };
> > -  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)
> > +  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_ECHO - 1)
> >  
> >    /* operation definition */
> >    struct genl_ops doc_exmpl_gnl_ops_echo = {
> 

But there is more...

Jarek P.

PS: It is added to my first patch because I don't know
what is the current version. 
---

--- netlink.txt-	2006-11-10 10:53:50.000000000 +0100
+++ netlink.txt	2006-11-13 07:53:41.000000000 +0100
@@ -32,7 +32,7 @@
 1.1. Document Overview
 ------------------------------------------------------------------------------
 
-This document gives is a brief introduction to Generic Netlink, some simple
+This document gives a brief introduction to Generic Netlink, some simple
 examples on how to use it, and some recommendations on how to make the most of
 the Generic Netlink communications interface.  While this document does not
 require that the reader have a detailed understanding of what Netlink is
@@ -55,21 +55,21 @@
 channels are associated with families or "busses", where each bus deals with a
 specific service; for example, different Netlink busses exist for routing,
 XFRM, netfilter, and several other kernel subsystems.  More information about
-Netlink can be found in RFC 3549[1].
+Netlink can be found in RFC 3549[2].
 
 Over the years, Netlink has become very popular which has brought about a very
 real concern that the number of Netlink family numbers may be exhausted in the
 near future.  In response to this the Generic Netlink family was created which
-acts as a Netlink multiplexer, allowing multiple service to use a single
+acts as a Netlink multiplexer, allowing multiple services to use a single
 Netlink bus.
 
-[1] ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt
+[2] ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt
 
 2. Architectural Overview
 ------------------------------------------------------------------------------
 
-Figure #1 illustrates how the basic Generic Netlink architecture which is
-composed of five different types of components.
+Figure #1 illustrates the basic Generic Netlink architecture which is
+composed of five different types of components:
 
  1) The Netlink subsystem which serves as the underlying transport layer for
     all of the Generic Netlink communications.
@@ -99,7 +99,7 @@
                |                                |
        +-------+--------------------------------+-------+
        |        :                               :       |   user-space
-  =====+        :   (5)  Kernel socket API      :       +================
+  =====+        :   (5)  kernel socket API      :       +================
        |        :                               :       |   kernel-space
        +--------+-------------------------------+-------+
                 |                               |
@@ -112,7 +112,7 @@
           +--+--------------------------+-------+----+
              |                          |       |
      +-------+---------+                |       |
-     |  (4) Controller |               /         \
+     |  (4) controller |               /         \
      +-----------------+              /           \
                                       |           |
                    +------------------+--+     +--+------------------+
@@ -141,15 +141,15 @@
 ------------------------------------------------------------------------------
 
 The Generic Netlink mechanism is based on a client-server model.  The Generic
-Netlink servers register families, which are a collection of well defined
-services, with the controller and the clients communicate with the server
+Netlink servers register with the controller families, which are a collection
+of well defined services, and the clients communicate with the servers
 through these service registrations.  This section explains how Generic Netlink
 families are defined, created and registered.
 
 3.1. Family Overview
 ------------------------------------------------------------------------------
 
-Generic Netlink family service registrations are defined by two structures,
+Generic Netlink family service registrations are defined by two structures:
 genl_family and genl_ops.  The genl_family structure defines the family and
 it's associated communication channel.  The genl_ops structure defines
 an individual service or operation which the family provides to other Generic
@@ -161,7 +161,7 @@
 
 [1] http://people.suug.ch/~tgr/libnl
 
-3.1.2. The genl_family Structure
+3.1.1. The genl_family Structure
 
 Generic Netlink services are defined by the genl_family structure, which is
 shown below:
@@ -187,7 +187,7 @@
    This is the dynamically allocated channel number.  A value of 0x0 signifies
    that the channel number should be assigned by the controller and the 0x10
    value is reserved for use by the controller.  Users should always use
-   value 0x0 when registering a new family.
+   GENL_ID_GENERATE macro/constant (value 0x0) when registering a new family.
 
  * unsigned int hdrsize
 
@@ -241,7 +241,7 @@
  * unsigned int flags
 
    This field is used to specify any special attributes of the operation.  The
-   following flags may be used, multiple flags can be OR'd together:
+   following flags may be used (multiple flags can be OR-ed together):
 
    - GENL_ADMIN_PERM
 
@@ -251,11 +251,12 @@
 
    This field defines the Netlink attribute policy for the operation request
    message.  If specified, the Generic Netlink mechanism uses this policy to
-   verify all of the attributes in a operation request message before calling
+   verify all of the attributes in an operation request message before calling
    the operation handler.
 
    The attribute policy is defined as an array of nla_policy structures indexed
-   by the attribute number.  The nla_policy structure is defined in figure #4.
+   by the attribute number.  The nla_policy structure is defined as shown in
+   figure #4.
 
      struct nla_policy
      {
@@ -269,7 +270,7 @@
 
    - u16 type
 
-     This specifies the type of the attribute, presently the following types
+     This specifies the type of the attribute; presently the following types
      are defined for general use:
 
      o NLA_UNSPEC
@@ -278,7 +279,7 @@
 
      o NLA_U8
 
-       A 8 bit unsigned integer
+       An 8 bit unsigned integer
 
      o NLA_U16
 
@@ -327,11 +328,11 @@
    This callback is similar in use to the standard Netlink 'doit' callback, the
    primary difference being the change in parameters.
 
-   The 'doit' handler receives two parameters, the first if the message buffer
+   The 'doit' handler receives two parameters: the first is the message buffer
    which triggered the handler and the second is a Generic Netlink genl_info
-   structure which is defined in figure #5.
+   structure which is defined as shown in figure #5.
 
-     struct genl_ops
+     struct genl_info
      {
         u32                     snd_seq;
         u32                     snd_pid;
@@ -368,12 +369,12 @@
 
    - struct nlattr **attrs
 
-     The parsed Netlink attributes from the request, if the Generic Netlink
+     The parsed Netlink attributes from the request; if the Generic Netlink
      family definition specified a Netlink attribute policy then the
-     attributes will have already been validated.
+     attributes would have already been validated.
 
    The 'doit' handler should do whatever processing is necessary and return
-   zero on success, or a negative value on failure.  Negative return values
+   zero on success or a negative value on failure.  Negative return values
    will cause a NLMSG_ERROR message to be sent while a zero return value will
    only cause a NLMSG_ERROR message to be sent if the request is received with
    the NLM_F_ACK flag set.
@@ -384,15 +385,15 @@
    The 'dumpit' callback is invoked when a Generic Netlink message is received
    with the NLM_F_DUMP flag set.
 
-   The main difference between a 'dumpit' handler and a 'doit' handler is
-   that a 'dumpit' handler does not allocate a message buffer for a response;
+   The main difference between the 'dumpit' handler and the 'doit' handler is
+   that the 'dumpit' handler does not allocate a message buffer for a response;
    a pre-allocated sk_buff is passed to the 'dumpit' handler as the first
    parameter.  The 'dumpit' handler should fill the message buffer with the
    appropriate response message and return the size of the sk_buff,
    i.e. sk_buff->len, and the message buffer will automatically be sent to the
    Generic Netlink client that initiated the request.  As long as the 'dumpit'
    handler returns a value greater than zero it will be called again with a
-   newly allocated message buffer to fill, when the handler has no more data
+   newly allocated message buffer to fill.  When the handler has no more data
    to send it should return zero; error conditions are indicated by returning
    a negative value.  If necessary, state can be preserved in the
    netlink_callback parameter which is passed to the 'dumpit' handler; the
@@ -412,7 +413,7 @@
 and explained in detail.
 
 The first step is to define the family itself, which we do by creating an
-instance of the genl_family structure which we explained in section 3.1.1..
+instance of the genl_family structure which we explained in section 3.1.1.
 In our simple example we are going to create a new Generic Netlink family
 named "DOC_EXMPL".
 
@@ -425,9 +426,9 @@
   #define DOC_EXMPL_A_MAX (__DOC_EXMPL_A_MAX - 1)
 
   /* attribute policy */
-  static struct nla_policy doc_exmpl_genl_policy = [DOC_EXMPL_A_MAX + 1] = {
+  static struct nla_policy doc_exmpl_genl_policy[DOC_EXMPL_A_MAX + 1] = {
         [DOC_EXMPL_A_MSG] = { .type = NLA_NUL_STRING },
-  }
+  };
 
   /* family definition */
   static struct genl_family doc_exmpl_gnl_family = {
@@ -436,20 +437,19 @@
         .name = "DOC_EXMPL",
         .version = 1,
         .maxattr = DOC_EXMPL_A_MAX,
-
   };
 
-  Figure 6: The DOC_EXMPL family, attributes, and policy
+  Figure 6: The DOC_EXMPL family, attributes and policy
 
 You can see above that we defined a new family and the family recognizes a
-single attribute, DOC_EXMPL_A_ECHO, which is a NULL terminated string.  The
+single attribute, DOC_EXMPL_A_MAX, which is a NULL terminated string.  The
 GENL_ID_GENERATE macro/constant is really just the value 0x0 and it signifies
 that we want the Generic Netlink controller to assign the channel number when
 we register the family.
 
 The second step is to define the operations for the family, which we do by
 creating at least one instance of the genl_ops structure which we explained in
-section 3.1.2..  In this example we are only going to define one operation but
+section 3.1.2.  In this example we are only going to define one operation but
 you can define up to 255 unique operations for each family.
 
   /* handler */
@@ -463,7 +463,7 @@
   enum {
         DOC_EXMPL_C_UNSPEC,
         DOC_EXMPL_C_ECHO,
-        __DOC_EXMPL_C_ECHO,
+        __DOC_EXMPL_C_MAX,
   };
   #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)
 
@@ -474,7 +474,7 @@
         .policy = doc_exmpl_genl_policy,
 	.doit = doc_exmpl_echo,
 	.dumpit = NULL,
-  }
+  };
 
   Figure 7: The DOC_EXMPL_C_ECHO operation
 
@@ -492,7 +492,7 @@
 This call registers the new family name with the Generic Netlink mechanism and
 requests a new channel number which is stored in the genl_family struct,
 replacing the GENL_ID_GENERATE value.  It is important to remember to
-unregister Generic Netlink families when done as the kernel does allocate
+unregister Generic Netlink families when done, as the kernel does allocate
 resources for each registered family.
 
 The fourth and final step is to register the operations for the family.  Once
@@ -501,7 +501,7 @@
   genl_register_ops(&doc_exmpl_gnl_family, &doc_exmpl_gnl_ops_echo);
 
 This call registers the DOC_EXMPL_C_ECHO operation in association with the
-DOC_EXMPL family.  The process is now complete, other Generic Netlink users can
+DOC_EXMPL family.  The process is now complete.  Other Generic Netlink users can
 now issue DOC_EXMPL_C_ECHO commands and they will be handled as desired.
 
 4.  Generic Netlink Communications
@@ -515,8 +515,8 @@
 
 Generic Netlink uses the standard Netlink subsystem as a transport layer which
 means that the foundation of the Generic Netlink message is the standard
-Netlink message format, the only difference is the inclusion of a Generic
-Netlink message header.  The format of the message is defined below:
+Netlink message format - the only difference is the inclusion of a Generic
+Netlink message header.  The format of the message is defined as shown below:
 
    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -537,14 +537,14 @@
 Generic Netlink API should insulate most users from the details of the message
 format and the Netlink message headers.
 
-4.2 Kernel Communication
+4.2. Kernel Communication
 ------------------------------------------------------------------------------
 
-The kernel provides two sets of interfaces for sending, receiving, and
+The kernel provides two sets of interfaces for sending, receiving and
 processing Generic Netlink messages.  The majority of the API consists of the
 general purpose Netlink interfaces, however, there are a small number of
-interfaces specific to Generic Netlink.  The following two include files
-define the Netlink and Generic Netlink API for the kernel.
+interfaces specific to Generic Netlink.  The following two 'include' files
+define the Netlink and Generic Netlink API for the kernel:
 
  * include/net/netlink.h
  * include/net/genetlink.h
@@ -556,7 +556,7 @@
 demonstrate these steps below is a simple example using the DOC_EXMPL family
 shown in section 3.
 
-The first step is to allocate a Netlink message buffer, the easiest way to do
+The first step is to allocate a Netlink message buffer; the easiest way to do
 this is with the nlsmsg_new() function.
 
   struct sk_buff *skb;
@@ -573,7 +573,7 @@
 the Netlink and Generic Netlink message headers.
 
 The second step is to actually create the message payload.  This is obviously
-something which is very specific to each use service, but a simple example is
+something which is very specific to each used service, but a simple example is
 shown below.
 
   int rc;
@@ -586,7 +586,7 @@
       goto failure;
   }
   /* add a DOC_EXMPL_A_MSG attribute */
-  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Generic Netlink Rocks");
+  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Justin Timberlake rocks");
   if (rc != 0)
       goto failure;
   /* finalize the message */
@@ -617,7 +617,7 @@
 
 4.2.2. Receiving Messages
 
-Typically, the kernel acts a Generic Netlink server which means that the act of
+Typically, the kernel acts as Generic Netlink server which means that the act of
 receiving messages is handled automatically by the Generic Netlink bus.  Once
 the bus receives the message and determines the correct routing, the message
 is passed directly to the family specific operation callback for processing.
@@ -643,7 +643,7 @@
 as a result there are many different ways it can be used.  The following
 recommendations are based on conventions within the Linux kernel and should be
 followed whenever possible.  While not all existing kernel code follows the
-recommendations outlined here all new code should consider these
+recommendations outlined here, all new code should consider these
 recommendations as requirements.
 
 5.1. Attributes And Message Payloads
@@ -652,7 +652,7 @@
 When defining new Generic Netlink message formats you must make use of the
 Netlink attributes wherever possible.  The Netlink attribute mechanism has
 been carefully designed to allow for future message expansion while preserving
-backward compatibility.  There are also additional benefits to using Netlink
+backward compatibility.  There are also additional benefits from using Netlink
 attributes which include developer familiarity and basic input checking.
 
 Most common data structures can be represented with Netlink attributes:
@@ -681,7 +681,7 @@
 ------------------------------------------------------------------------------
 
 While it may be tempting to register a single operation for a Generic Netlink
-family and multiplex multiple sub-commands on the single operation this
+family and multiplex multiple sub-commands on the single operation, this
 is strongly discouraged for security reasons.  Combining multiple behaviors
 into one operation makes it difficult to restrict the operations using the
 existing Linux kernel security mechanisms.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-10 17:36   ` Thomas Graf
  2006-11-13  7:05     ` Jarek Poplawski
@ 2006-11-13  7:23     ` Jarek Poplawski
  2006-11-13 14:08       ` Paul Moore
  2006-11-13 19:58       ` Paul Moore
  1 sibling, 2 replies; 35+ messages in thread
From: Jarek Poplawski @ 2006-11-13  7:23 UTC (permalink / raw)
  To: Thomas Graf; +Cc: Paul Moore, netdev

On Fri, Nov 10, 2006 at 06:36:42PM +0100, Thomas Graf wrote:
> * Jarek Poplawski <jarkao2@o2.pl> 2006-11-10 14:24
> > @@ -449,7 +449,7 @@
> >  
> >  The second step is to define the operations for the family, which we do by
> >  creating at least one instance of the genl_ops structure which we explained in
> > -section 3.1.2..  In this example we are only going to define one operation but
> > +section 3.1.2.  In this example we are only going to define one operation but
> >  you can define up to 255 unique operations for each family.
> >  
> >    /* handler */
> > @@ -465,7 +465,7 @@
> >          DOC_EXMPL_C_ECHO,
> >          __DOC_EXMPL_C_ECHO,
> 
> Careful, the typo is here, not below.
> 
> >    };
> > -  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)
> > +  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_ECHO - 1)
> >  
> >    /* operation definition */
> >    struct genl_ops doc_exmpl_gnl_ops_echo = {
> 

Sorry! Typo in @@ -436,20 part. Forget the earlier message. 

So there is more...

Jarek P.

PS: It is added to my first patch because I don't know
what is the current version. 
---

--- netlink.txt-	2006-11-10 10:53:50.000000000 +0100
+++ netlink.txt	2006-11-13 07:53:41.000000000 +0100
@@ -32,7 +32,7 @@
 1.1. Document Overview
 ------------------------------------------------------------------------------
 
-This document gives is a brief introduction to Generic Netlink, some simple
+This document gives a brief introduction to Generic Netlink, some simple
 examples on how to use it, and some recommendations on how to make the most of
 the Generic Netlink communications interface.  While this document does not
 require that the reader have a detailed understanding of what Netlink is
@@ -55,21 +55,21 @@
 channels are associated with families or "busses", where each bus deals with a
 specific service; for example, different Netlink busses exist for routing,
 XFRM, netfilter, and several other kernel subsystems.  More information about
-Netlink can be found in RFC 3549[1].
+Netlink can be found in RFC 3549[2].
 
 Over the years, Netlink has become very popular which has brought about a very
 real concern that the number of Netlink family numbers may be exhausted in the
 near future.  In response to this the Generic Netlink family was created which
-acts as a Netlink multiplexer, allowing multiple service to use a single
+acts as a Netlink multiplexer, allowing multiple services to use a single
 Netlink bus.
 
-[1] ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt
+[2] ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt
 
 2. Architectural Overview
 ------------------------------------------------------------------------------
 
-Figure #1 illustrates how the basic Generic Netlink architecture which is
-composed of five different types of components.
+Figure #1 illustrates the basic Generic Netlink architecture which is
+composed of five different types of components:
 
  1) The Netlink subsystem which serves as the underlying transport layer for
     all of the Generic Netlink communications.
@@ -99,7 +99,7 @@
                |                                |
        +-------+--------------------------------+-------+
        |        :                               :       |   user-space
-  =====+        :   (5)  Kernel socket API      :       +================
+  =====+        :   (5)  kernel socket API      :       +================
        |        :                               :       |   kernel-space
        +--------+-------------------------------+-------+
                 |                               |
@@ -112,7 +112,7 @@
           +--+--------------------------+-------+----+
              |                          |       |
      +-------+---------+                |       |
-     |  (4) Controller |               /         \
+     |  (4) controller |               /         \
      +-----------------+              /           \
                                       |           |
                    +------------------+--+     +--+------------------+
@@ -141,15 +141,15 @@
 ------------------------------------------------------------------------------
 
 The Generic Netlink mechanism is based on a client-server model.  The Generic
-Netlink servers register families, which are a collection of well defined
-services, with the controller and the clients communicate with the server
+Netlink servers register with the controller families, which are a collection
+of well defined services, and the clients communicate with the servers
 through these service registrations.  This section explains how Generic Netlink
 families are defined, created and registered.
 
 3.1. Family Overview
 ------------------------------------------------------------------------------
 
-Generic Netlink family service registrations are defined by two structures,
+Generic Netlink family service registrations are defined by two structures:
 genl_family and genl_ops.  The genl_family structure defines the family and
 it's associated communication channel.  The genl_ops structure defines
 an individual service or operation which the family provides to other Generic
@@ -161,7 +161,7 @@
 
 [1] http://people.suug.ch/~tgr/libnl
 
-3.1.2. The genl_family Structure
+3.1.1. The genl_family Structure
 
 Generic Netlink services are defined by the genl_family structure, which is
 shown below:
@@ -187,7 +187,7 @@
    This is the dynamically allocated channel number.  A value of 0x0 signifies
    that the channel number should be assigned by the controller and the 0x10
    value is reserved for use by the controller.  Users should always use
-   value 0x0 when registering a new family.
+   GENL_ID_GENERATE macro/constant (value 0x0) when registering a new family.
 
  * unsigned int hdrsize
 
@@ -241,7 +241,7 @@
  * unsigned int flags
 
    This field is used to specify any special attributes of the operation.  The
-   following flags may be used, multiple flags can be OR'd together:
+   following flags may be used (multiple flags can be OR-ed together):
 
    - GENL_ADMIN_PERM
 
@@ -251,11 +251,12 @@
 
    This field defines the Netlink attribute policy for the operation request
    message.  If specified, the Generic Netlink mechanism uses this policy to
-   verify all of the attributes in a operation request message before calling
+   verify all of the attributes in an operation request message before calling
    the operation handler.
 
    The attribute policy is defined as an array of nla_policy structures indexed
-   by the attribute number.  The nla_policy structure is defined in figure #4.
+   by the attribute number.  The nla_policy structure is defined as shown in
+   figure #4.
 
      struct nla_policy
      {
@@ -269,7 +270,7 @@
 
    - u16 type
 
-     This specifies the type of the attribute, presently the following types
+     This specifies the type of the attribute; presently the following types
      are defined for general use:
 
      o NLA_UNSPEC
@@ -278,7 +279,7 @@
 
      o NLA_U8
 
-       A 8 bit unsigned integer
+       An 8 bit unsigned integer
 
      o NLA_U16
 
@@ -327,11 +328,11 @@
    This callback is similar in use to the standard Netlink 'doit' callback, the
    primary difference being the change in parameters.
 
-   The 'doit' handler receives two parameters, the first if the message buffer
+   The 'doit' handler receives two parameters: the first is the message buffer
    which triggered the handler and the second is a Generic Netlink genl_info
-   structure which is defined in figure #5.
+   structure which is defined as shown in figure #5.
 
-     struct genl_ops
+     struct genl_info
      {
         u32                     snd_seq;
         u32                     snd_pid;
@@ -368,12 +369,12 @@
 
    - struct nlattr **attrs
 
-     The parsed Netlink attributes from the request, if the Generic Netlink
+     The parsed Netlink attributes from the request; if the Generic Netlink
      family definition specified a Netlink attribute policy then the
-     attributes will have already been validated.
+     attributes would have already been validated.
 
    The 'doit' handler should do whatever processing is necessary and return
-   zero on success, or a negative value on failure.  Negative return values
+   zero on success or a negative value on failure.  Negative return values
    will cause a NLMSG_ERROR message to be sent while a zero return value will
    only cause a NLMSG_ERROR message to be sent if the request is received with
    the NLM_F_ACK flag set.
@@ -384,15 +385,15 @@
    The 'dumpit' callback is invoked when a Generic Netlink message is received
    with the NLM_F_DUMP flag set.
 
-   The main difference between a 'dumpit' handler and a 'doit' handler is
-   that a 'dumpit' handler does not allocate a message buffer for a response;
+   The main difference between the 'dumpit' handler and the 'doit' handler is
+   that the 'dumpit' handler does not allocate a message buffer for a response;
    a pre-allocated sk_buff is passed to the 'dumpit' handler as the first
    parameter.  The 'dumpit' handler should fill the message buffer with the
    appropriate response message and return the size of the sk_buff,
    i.e. sk_buff->len, and the message buffer will automatically be sent to the
    Generic Netlink client that initiated the request.  As long as the 'dumpit'
    handler returns a value greater than zero it will be called again with a
-   newly allocated message buffer to fill, when the handler has no more data
+   newly allocated message buffer to fill.  When the handler has no more data
    to send it should return zero; error conditions are indicated by returning
    a negative value.  If necessary, state can be preserved in the
    netlink_callback parameter which is passed to the 'dumpit' handler; the
@@ -412,7 +413,7 @@
 and explained in detail.
 
 The first step is to define the family itself, which we do by creating an
-instance of the genl_family structure which we explained in section 3.1.1..
+instance of the genl_family structure which we explained in section 3.1.1.
 In our simple example we are going to create a new Generic Netlink family
 named "DOC_EXMPL".
 
@@ -425,9 +426,9 @@
   #define DOC_EXMPL_A_MAX (__DOC_EXMPL_A_MAX - 1)
 
   /* attribute policy */
-  static struct nla_policy doc_exmpl_genl_policy = [DOC_EXMPL_A_MAX + 1] = {
+  static struct nla_policy doc_exmpl_genl_policy[DOC_EXMPL_A_MAX + 1] = {
         [DOC_EXMPL_A_MSG] = { .type = NLA_NUL_STRING },
-  }
+  };
 
   /* family definition */
   static struct genl_family doc_exmpl_gnl_family = {
@@ -436,20 +437,19 @@
         .name = "DOC_EXMPL",
         .version = 1,
         .maxattr = DOC_EXMPL_A_MAX,
-
   };
 
-  Figure 6: The DOC_EXMPL family, attributes, and policy
+  Figure 6: The DOC_EXMPL family, attributes and policy
 
 You can see above that we defined a new family and the family recognizes a
-single attribute, DOC_EXMPL_A_ECHO, which is a NULL terminated string.  The
+single attribute, DOC_EXMPL_A_MSG, which is a NULL terminated string.  The
 GENL_ID_GENERATE macro/constant is really just the value 0x0 and it signifies
 that we want the Generic Netlink controller to assign the channel number when
 we register the family.
 
 The second step is to define the operations for the family, which we do by
 creating at least one instance of the genl_ops structure which we explained in
-section 3.1.2..  In this example we are only going to define one operation but
+section 3.1.2.  In this example we are only going to define one operation but
 you can define up to 255 unique operations for each family.
 
   /* handler */
@@ -463,7 +463,7 @@
   enum {
         DOC_EXMPL_C_UNSPEC,
         DOC_EXMPL_C_ECHO,
-        __DOC_EXMPL_C_ECHO,
+        __DOC_EXMPL_C_MAX,
   };
   #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)
 
@@ -474,7 +474,7 @@
         .policy = doc_exmpl_genl_policy,
 	.doit = doc_exmpl_echo,
 	.dumpit = NULL,
-  }
+  };
 
   Figure 7: The DOC_EXMPL_C_ECHO operation
 
@@ -492,7 +492,7 @@
 This call registers the new family name with the Generic Netlink mechanism and
 requests a new channel number which is stored in the genl_family struct,
 replacing the GENL_ID_GENERATE value.  It is important to remember to
-unregister Generic Netlink families when done as the kernel does allocate
+unregister Generic Netlink families when done, as the kernel does allocate
 resources for each registered family.
 
 The fourth and final step is to register the operations for the family.  Once
@@ -501,7 +501,7 @@
   genl_register_ops(&doc_exmpl_gnl_family, &doc_exmpl_gnl_ops_echo);
 
 This call registers the DOC_EXMPL_C_ECHO operation in association with the
-DOC_EXMPL family.  The process is now complete, other Generic Netlink users can
+DOC_EXMPL family.  The process is now complete.  Other Generic Netlink users can
 now issue DOC_EXMPL_C_ECHO commands and they will be handled as desired.
 
 4.  Generic Netlink Communications
@@ -515,8 +515,8 @@
 
 Generic Netlink uses the standard Netlink subsystem as a transport layer which
 means that the foundation of the Generic Netlink message is the standard
-Netlink message format, the only difference is the inclusion of a Generic
-Netlink message header.  The format of the message is defined below:
+Netlink message format - the only difference is the inclusion of a Generic
+Netlink message header.  The format of the message is defined as shown below:
 
    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -537,14 +537,14 @@
 Generic Netlink API should insulate most users from the details of the message
 format and the Netlink message headers.
 
-4.2 Kernel Communication
+4.2. Kernel Communication
 ------------------------------------------------------------------------------
 
-The kernel provides two sets of interfaces for sending, receiving, and
+The kernel provides two sets of interfaces for sending, receiving and
 processing Generic Netlink messages.  The majority of the API consists of the
 general purpose Netlink interfaces, however, there are a small number of
-interfaces specific to Generic Netlink.  The following two include files
-define the Netlink and Generic Netlink API for the kernel.
+interfaces specific to Generic Netlink.  The following two 'include' files
+define the Netlink and Generic Netlink API for the kernel:
 
  * include/net/netlink.h
  * include/net/genetlink.h
@@ -556,7 +556,7 @@
 demonstrate these steps below is a simple example using the DOC_EXMPL family
 shown in section 3.
 
-The first step is to allocate a Netlink message buffer, the easiest way to do
+The first step is to allocate a Netlink message buffer; the easiest way to do
 this is with the nlsmsg_new() function.
 
   struct sk_buff *skb;
@@ -573,7 +573,7 @@
 the Netlink and Generic Netlink message headers.
 
 The second step is to actually create the message payload.  This is obviously
-something which is very specific to each use service, but a simple example is
+something which is very specific to each used service, but a simple example is
 shown below.
 
   int rc;
@@ -586,7 +586,7 @@
       goto failure;
   }
   /* add a DOC_EXMPL_A_MSG attribute */
-  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Generic Netlink Rocks");
+  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Justin Timberlake rocks");
   if (rc != 0)
       goto failure;
   /* finalize the message */
@@ -617,7 +617,7 @@
 
 4.2.2. Receiving Messages
 
-Typically, the kernel acts a Generic Netlink server which means that the act of
+Typically, the kernel acts as Generic Netlink server which means that the act of
 receiving messages is handled automatically by the Generic Netlink bus.  Once
 the bus receives the message and determines the correct routing, the message
 is passed directly to the family specific operation callback for processing.
@@ -643,7 +643,7 @@
 as a result there are many different ways it can be used.  The following
 recommendations are based on conventions within the Linux kernel and should be
 followed whenever possible.  While not all existing kernel code follows the
-recommendations outlined here all new code should consider these
+recommendations outlined here, all new code should consider these
 recommendations as requirements.
 
 5.1. Attributes And Message Payloads
@@ -652,7 +652,7 @@
 When defining new Generic Netlink message formats you must make use of the
 Netlink attributes wherever possible.  The Netlink attribute mechanism has
 been carefully designed to allow for future message expansion while preserving
-backward compatibility.  There are also additional benefits to using Netlink
+backward compatibility.  There are also additional benefits from using Netlink
 attributes which include developer familiarity and basic input checking.
 
 Most common data structures can be represented with Netlink attributes:
@@ -681,7 +681,7 @@
 ------------------------------------------------------------------------------
 
 While it may be tempting to register a single operation for a Generic Netlink
-family and multiplex multiple sub-commands on the single operation this
+family and multiplex multiple sub-commands on the single operation, this
 is strongly discouraged for security reasons.  Combining multiple behaviors
 into one operation makes it difficult to restrict the operations using the
 existing Linux kernel security mechanisms.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-13  7:23     ` Jarek Poplawski
@ 2006-11-13 14:08       ` Paul Moore
  2006-11-13 14:17         ` jamal
  2006-11-13 19:58       ` Paul Moore
  1 sibling, 1 reply; 35+ messages in thread
From: Paul Moore @ 2006-11-13 14:08 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: Thomas Graf, netdev

On Monday 13 November 2006 2:23 am, Jarek Poplawski wrote:
> Sorry! Typo in @@ -436,20 part. Forget the earlier message.

No problem, my first draft was full of typos too ;)

> So there is more...
>
> Jarek P.
>
> PS: It is added to my first patch because I don't know
> what is the current version.

Thanks.  I'm going to mail out the latest version (my first draft with 
everybody's patches) later today - I want to give Jamal a little bit longer 
to reply.

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-13 14:08       ` Paul Moore
@ 2006-11-13 14:17         ` jamal
  2006-11-13 20:06           ` Paul Moore
  0 siblings, 1 reply; 35+ messages in thread
From: jamal @ 2006-11-13 14:17 UTC (permalink / raw)
  To: Paul Moore; +Cc: Jarek Poplawski, Thomas Graf, netdev

On Mon, 2006-13-11 at 09:08 -0500, Paul Moore wrote:

> I want to give Jamal a little bit longer 
> to reply.

Sorry, family emergency - still ongoing today, so havent looked at
anything (including presentation that was supposed to be done) ;-<

Give me a day or two (I know i at least have to do the presentation or
iam fscked ;->).

cheers,
jamal


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-13  7:23     ` Jarek Poplawski
  2006-11-13 14:08       ` Paul Moore
@ 2006-11-13 19:58       ` Paul Moore
  2006-11-14  6:53         ` Jarek Poplawski
  1 sibling, 1 reply; 35+ messages in thread
From: Paul Moore @ 2006-11-13 19:58 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: Thomas Graf, netdev

Jarek Poplawski wrote:
> @@ -586,7 +586,7 @@
>        goto failure;
>    }
>    /* add a DOC_EXMPL_A_MSG attribute */
> -  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Generic Netlink Rocks");
> +  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Justin Timberlake rocks");
>    if (rc != 0)
>        goto failure;
>    /* finalize the message */

So here I am applying this patch by hand because the diffs are a bit off and I
come across this ... I think I might have to nix this change on the basis of
rudimentary quality standards :)

Besides, *I* brought sexy back.

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-13 14:17         ` jamal
@ 2006-11-13 20:06           ` Paul Moore
  2006-11-17 13:05             ` jamal
  0 siblings, 1 reply; 35+ messages in thread
From: Paul Moore @ 2006-11-13 20:06 UTC (permalink / raw)
  To: hadi; +Cc: Jarek Poplawski, Thomas Graf, netdev

jamal wrote:
> On Mon, 2006-13-11 at 09:08 -0500, Paul Moore wrote:
> 
>>I want to give Jamal a little bit longer to reply.
> 
> Sorry, family emergency - still ongoing today, so havent looked at
> anything (including presentation that was supposed to be done) ;-<
> 
> Give me a day or two (I know i at least have to do the presentation or
> iam fscked ;->).

No problem, life has a tendency to surprise us once in a while, hopefully it is
nothing to terrible.

For those of you who have been sending feedback, here is an updated copy to look
over.  I've taken pretty much everything but if there is still something awry
feel free to send patches ...

An Introduction To Using Generic Netlink
===============================================================================

Last Updated: November 13, 2006

Table of Contents

 1. Introduction
 1.1. Document Overview
 1.2. Netlink And Generic Netlink
 2. Architectural Overview
 3. Generic Netlink Families
    3.1. Family Overview
         3.1.1. The genl_family Structure
         3.1.2. The genl_ops Structure
    3.2. Registering A Family
 4. Generic Netlink Communications
    4.1. Generic Netlink Message Format
    4.2. Kernel Communication
         4.2.1. Sending Messages
         4.2.2. Receiving Messages
    4.3. Userspace Communication
 5. Recommendations
    5.1. Attributes And Message Payloads
    5.2. Operation Granularity
    5.3. Acknowledgment And Error Reporting


1. Introduction
------------------------------------------------------------------------------

1.1. Document Overview
------------------------------------------------------------------------------

This document gives a brief introduction to Generic Netlink, some simple
examples on how to use it, and some recommendations on how to make the most of
the Generic Netlink communications interface.  While this document does not
require that the reader have a detailed understanding of what Netlink is
and how it works, some basic Netlink knowledge is assumed.  As usual, the
kernel source code is your best friend here.

While this document talks briefly about Generic Netlink from a userspace point
of view, its primary focus is on the kernel's Generic Netlink API.  It is
recommended that application developers who are interested in using Generic
Netlink make use of the libnl library[1].

[1] http://people.suug.ch/~tgr/libnl

1.2. Netlink And Generic Netlink
------------------------------------------------------------------------------

Netlink is a flexible, robust wire-format communications channel typically
used for kernel to user communication although it can also be used for
user to user and kernel to kernel communications.  Netlink communication
channels are associated with families or "busses", where each bus deals with a
specific service; for example, different Netlink busses exist for routing,
XFRM, netfilter, and several other kernel subsystems.  More information about
Netlink can be found in RFC 3549[2].

Over the years, Netlink has become very popular which has brought about a very
real concern that the number of Netlink family numbers may be exhausted in the
near future.  In response to this the Generic Netlink family was created which
acts as a Netlink multiplexer, allowing multiple services to use a single
Netlink bus.

[2] ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt

2. Architectural Overview
------------------------------------------------------------------------------

Figure #1 illustrates the basic Generic Netlink architecture which is
composed of five different types of components:

 1) The Netlink subsystem which serves as the underlying transport layer for
    all of the Generic Netlink communications.

 2) The Generic Netlink bus which is implemented inside the kernel, but which
    is available to userspace through the socket API and inside the kernel via
    the normal Netlink and Generic Netlink APIs.

 3) The Generic Netlink users who communicate with each other over the Generic
    Netlink bus; users can exist both in kernel and user space.

 4) The Generic Netlink controller which is part of the kernel and is
    responsible for dynamically allocating Generic Netlink communication
    channels and other management tasks.  The Generic Netlink controller is
    implemented as a standard Generic Netlink user, however, it listens on a
    special, pre-allocated Generic Netlink channel.

 5) The kernel socket API.  Generic Netlink sockets are created with the
    PF_NETLINK domain and the NETLINK_GENERIC protocol values.

      +---------------------+      +---------------------+
      | (3) application "A" |      | (3) application "B" |
      +------+--------------+      +--------------+------+
             |                                    |
             \                                    /
              \                                  /
               |                                |
       +-------+--------------------------------+-------+
       |        :                               :       |   user-space
  =====+        :   (5)  kernel socket API      :       +================
       |        :                               :       |   kernel-space
       +--------+-------------------------------+-------+
                |                               |
          +-----+-------------------------------+----+
          |        (1)  Netlink subsystem            |
          +---------------------+--------------------+
                                |
          +---------------------+--------------------+
          |       (2) Generic Netlink bus            |
          +--+--------------------------+-------+----+
             |                          |       |
     +-------+---------+                |       |
     |  (4) controller |               /         \
     +-----------------+              /           \
                                      |           |
                   +------------------+--+     +--+------------------+
                   | (3) kernel user "X" |     | (3) kernel user "Y" |
                   +---------------------+     +---------------------+

  Figure 1: Generic Netlink Architecture

When looking at figure #1 it is important to note that any Generic Netlink
user can communicate with any other user over the bus using the same API
regardless of where the user resides in relation to the kernel/userspace
boundary.

Generic Netlink communications are essentially a series of different
communication channels which are multiplexed on a single Netlink family.
Communication channels are uniquely identified by channel numbers which are
dynamically allocated by the Generic Netlink controller.  The controller is a
special Generic Netlink user which listens on a fixed communication channel,
number 0x10, which is always present.  Kernel or userspace users which provide
services over the Generic Netlink bus establish new communication channels by
registering their services with the Generic Netlink controller.  Users who
want to use an existing service query the controller to see if it exists and
determine the correct channel number.

3. Generic Netlink Families
------------------------------------------------------------------------------

The Generic Netlink mechanism is based on a client-server model.  The Generic
Netlink servers register families, which are a collection of well-defined
services, with the controller and the clients communicate with the servers
through these service registrations.  This section explains how Generic Netlink
families are defined, created, and registered.

3.1. Family Overview
------------------------------------------------------------------------------

Generic Netlink family service registrations are defined by two structures:
genl_family and genl_ops.  The genl_family structure defines the family and
its associated communication channel.  The genl_ops structure defines
an individual service or operation which the family provides to other Generic
Netlink users.

This section focuses on Generic Netlink families as they are represented in
the kernel.  A similar API exists for userspace applications using the libnl
library[3].

[3] http://people.suug.ch/~tgr/libnl

3.1.1. The genl_family Structure

Generic Netlink services are defined by the genl_family structure, which is
shown below:

  struct genl_family
  {
        unsigned int            id;
        unsigned int            hdrsize;
        char                    name[GENL_NAMSIZ];
        unsigned int            version;
        unsigned int            maxattr;
        struct nlattr **        attrbuf;
        struct list_head        ops_list;
        struct list_head        family_list;
  };

  Figure 2: The genl_family structure

The genl_family structure fields are used in the following manner:

 * unsigned int id

   This is the dynamically allocated channel number.  A value of 0x0 signifies
   that the channel number should be assigned by the controller and the 0x10
   value is reserved for use by the controller.  Users should always use
   GENL_ID_GENERATE macro/constant (value 0x0) when registering a new family.

 * unsigned int hdrsize

   If the family makes use of a family specific header, its size is stored
   here.  If there is no family specific header this value should be zero.

 * char name[GENL_NAMSIZ]

   This string should be unique to the family as it is the key that the
   controller uses to lookup channel numbers when requested.

 * unsigned int version

   Family specific version number.

 * unsigned int maxattr

   Generic Netlink makes use of the standard Netlink attributes, this value
   holds the maximum number of attributes defined for the Generic Netlink
   family.

 * struct nlattr **attrbuf
 * struct list_head ops_list
 * struct list_head family_list

   These are private fields and should not be modified.

3.1.2. The genl_ops Structure

  struct genl_ops
  {
        u8                      cmd;
        unsigned int            flags;
        struct nla_policy       *policy;
        int                     (*doit)(struct sk_buff *skb,
                                        struct genl_info *info);
        int                     (*dumpit)(struct sk_buff *skb,
                                          struct netlink_callback *cb);
        struct list_head        ops_list;
  };

  Figure 3: The genl_ops structure

The genl_ops structure fields are used in the following manner:

 * u8 cmd

   This value is unique across the corresponding Generic Netlink family and is
   used to reference the operation.

 * unsigned int flags

   This field is used to specify any special attributes of the operation.  The
   following flags may be used (multiple flags can be OR'd together):

   - GENL_ADMIN_PERM

     The operation requires the CAP_NET_ADMIN privilege

 * struct nla_policy policy

   This field defines the Netlink attribute policy for the operation request
   message.  If specified, the Generic Netlink mechanism uses this policy to
   verify all of the attributes in an operation request message before calling
   the operation handler.

   The attribute policy is defined as an array of nla_policy structures indexed
   by the attribute number.  The nla_policy structure is defined as shown in
   figure #4.

     struct nla_policy
     {
        u16             type;
        u16             len;
     };

     Figure 4: The nla_policy structure

   The fields are used in the following manner:

   - u16 type

     This specifies the type of the attribute; presently the following types
     are defined for general use:

     o NLA_UNSPEC

       Undefined type

     o NLA_U8

       An 8-bit unsigned integer

     o NLA_U16

       A 16-bit unsigned integer

     o NLA_U32

       A 32-bit unsigned integer

     o NLA_U64

       A 64-bit unsigned integer

     o NLA_FLAG

       A simple boolean flag

     o NLA_MSECS

       A 64-bit time value in msecs

     o NLA_STRING

       A variable length string

     o NLA_NUL_STRING

       A variable length NULL terminated string

     o NLA_NESTED

       A stream of attributes

   - u16 len

     When the attribute type is one of the string types then this field should
     be set to the maximum length of the string, not including the terminal
     NULL byte.  If the attribute type is unknown or NLA_UNSPEC then this field
     should be set to the exact length of the attribute's payload.

     Unless the attribute type is one of the fixed-length types above, a value
     of zero indicates that no validation of the attribute should be performed.

 * int (*doit)(struct skbuff *skb, struct genl_info *info)

   This callback is similar in use to the standard Netlink 'doit' callback, the
   primary difference being the change in parameters.

   The 'doit' handler receives two parameters: the first is the message buffer
   which triggered the handler and the second is a Generic Netlink genl_info
   structure which is defined as shown in figure #5.

     struct genl_info
     {
        u32                     snd_seq;
        u32                     snd_pid;
        struct nlmsghdr *       nlhdr;
        struct genlmsghdr *     genlhdr;
        void *                  userhdr;
        struct nlattr **        attrs;
     };

     Figure 5: The genl_info structure

   The fields are populated in the following manner:

   - u32 snd_seq

     This is the Netlink sequence number of the request.

   - u32 snd_pid

     This is the Netlink PID of the client which issued the request, it is
     important to note that the Netlink PID is not the same as the standard
     kernel PID.

   - struct nlmsghdr *nlhdr

     This is set to point to the Netlink message header of the request.

   - struct genlmsghdr *genlhdr

     This is set to point to the Generic Netlink message header of the request.

   - void *userhdr

     If the Generic Netlink family makes use of a family specific header, this
     pointer will be set to point to the start of the family specific header.

   - struct nlattr **attrs

     The parsed Netlink attributes from the request; if the Generic Netlink
     family definition specified a Netlink attribute policy then the
     attributes would have already been validated.

   The 'doit' handler should do whatever processing is necessary and return
   zero on success or a negative value on failure.  Negative return values
   will cause a NLMSG_ERROR message to be sent while a zero return value will
   only cause a NLMSG_ERROR message to be sent if the request is received with
   the NLM_F_ACK flag set.

 * int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb)

   This callback is similar in use to the standard Netlink 'dumpit' callback.
   The 'dumpit' callback is invoked when a Generic Netlink message is received
   with the NLM_F_DUMP flag set.

   The main difference between the 'dumpit' handler and the 'doit' handler is
   that the 'dumpit' handler does not allocate a message buffer for a response;
   a pre-allocated sk_buff is passed to the 'dumpit' handler as the first
   parameter.  The 'dumpit' handler should fill the message buffer with the
   appropriate response message and return the size of the sk_buff,
   i.e. sk_buff->len, and the message buffer will automatically be sent to the
   Generic Netlink client that initiated the request.  As long as the 'dumpit'
   handler returns a value greater than zero it will be called again with a
   newly allocated message buffer to fill.  When the handler has no more data
   to send it should return zero; error conditions are indicated by returning
   a negative value.  If necessary, state can be preserved in the
   netlink_callback parameter which is passed to the 'dumpit' handler; the
   netlink_callback parameter values will be preserved across handler calls
   for a single request.

 * struct list_head ops_list

   This is a private field and should not be modified.

3.2. Registering A Family
------------------------------------------------------------------------------

Registering a Generic Netlink family is a simple four step process: define the
family, define the operations, register the family, register the operations.
In order to help demonstrate these steps below is a simple example broken down
and explained in detail.

The first step is to define the family itself, which we do by creating an
instance of the genl_family structure which we explained in section 3.1.1.
In our simple example we are going to create a new Generic Netlink family
named "DOC_EXMPL".

  /* attributes */
  enum {
        DOC_EXMPL_A_UNSPEC,
        DOC_EXMPL_A_MSG,
        __DOC_EXMPL_A_MAX,
  };
  #define DOC_EXMPL_A_MAX (__DOC_EXMPL_A_MAX - 1)

  /* attribute policy */
  static struct nla_policy doc_exmpl_genl_policy[DOC_EXMPL_A_MAX + 1] = {
        [DOC_EXMPL_A_MSG] = { .type = NLA_NUL_STRING },
  };

  /* family definition */
  static struct genl_family doc_exmpl_gnl_family = {
        .id = GENL_ID_GENERATE,
        .hdrsize = 0,
        .name = "DOC_EXMPL",
        .version = 1,
        .maxattr = DOC_EXMPL_A_MAX,
  };

  Figure 6: The DOC_EXMPL family, attributes and policy

You can see above that we defined a new family and the family recognizes a
single attribute, DOC_EXMPL_A_MSG, which is a NULL terminated string.  The
GENL_ID_GENERATE macro/constant is really just the value 0x0 and it signifies
that we want the Generic Netlink controller to assign the channel number when
we register the family.

The second step is to define the operations for the family, which we do by
creating at least one instance of the genl_ops structure which we explained in
section 3.1.2.  In this example we are only going to define one operation but
you can define up to 255 unique operations for each family.

  /* handler */
  int doc_exmpl_echo(struct sk_buff *skb, struct genl_info *info)
  {
        /* message handling code goes here; return 0 on success, negative
         * values on failure */
  }

  /* commands */
  enum {
        DOC_EXMPL_C_UNSPEC,
        DOC_EXMPL_C_ECHO,
        __DOC_EXMPL_C_MAX,
  };
  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)

  /* operation definition */
  struct genl_ops doc_exmpl_gnl_ops_echo = {
        .cmd = DOC_EXMPL_C_ECHO,
        .flags = 0,
        .policy = doc_exmpl_genl_policy,
	.doit = doc_exmpl_echo,
	.dumpit = NULL,
  };

  Figure 7: The DOC_EXMPL_C_ECHO operation

Here we have defined a single operation, DOC_EXMPL_C_ECHO, which uses the
Netlink attribute policy we defined above.  Once registered, this particular
operation would call the doc_exmpl_echo() function whenever a
DOC_EXMPL_C_ECHO message is sent to the DOC_EXMPL family over the Generic
Netlink bus.

The third step it to register the DOC_EXMPL family with the Generic Netlink
operation.  We do this with a single function call:

  genl_register_family(&doc_exmpl_gnl_family);

This call registers the new family name with the Generic Netlink mechanism and
requests a new channel number which is stored in the genl_family struct,
replacing the GENL_ID_GENERATE value.  It is important to remember to
unregister Generic Netlink families when done as the kernel does allocate
resources for each registered family.

The fourth and final step is to register the operations for the family.  Once
again this is a simple function call:

  genl_register_ops(&doc_exmpl_gnl_family, &doc_exmpl_gnl_ops_echo);

This call registers the DOC_EXMPL_C_ECHO operation in association with the
DOC_EXMPL family.  The process is now complete.  Other Generic Netlink users can
now issue DOC_EXMPL_C_ECHO commands and they will be handled as desired.

4.  Generic Netlink Communications
------------------------------------------------------------------------------

This section deals with the Generic Netlink messages themselves and how to
send and receive messages.

4.1. Generic Netlink Message Format
------------------------------------------------------------------------------

Generic Netlink uses the standard Netlink subsystem as a transport layer which
means that the foundation of the Generic Netlink message is the standard
Netlink message format - the only difference is the inclusion of a Generic
Netlink message header.  The format of the message is defined as shown below:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                Netlink message header (nlmsghdr)              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           Generic Netlink message header (genlmsghdr)         |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |             Optional user specific message header             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           Optional Generic Netlink message payload            |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  Figure 8: Generic Netlink message format

Figure #8 is included only to give you a rough idea of how Generic Netlink
messages are formatted and sent on the "wire".  In practice the Netlink and
Generic Netlink API should insulate most users from the details of the message
format and the Netlink message headers.

4.2. Kernel Communication
------------------------------------------------------------------------------

The kernel provides two sets of interfaces for sending, receiving and
processing Generic Netlink messages.  The majority of the API consists of the
general purpose Netlink interfaces, however, there are a small number of
interfaces specific to Generic Netlink.  The following two 'include' files
define the Netlink and Generic Netlink API for the kernel:

 * include/net/netlink.h
 * include/net/genetlink.h

4.2.1. Sending Messages

Sending Generic Netlink messages is a three step process: allocate memory for
the message buffer, create the message, send the message.  In order to help
demonstrate these steps below is a simple example using the DOC_EXMPL family
shown in section 3.

The first step is to allocate a Netlink message buffer; the easiest way to do
this is with the nlsmsg_new() function.

  struct sk_buff *skb;

  skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  if (skb == NULL)
      goto failure;

  Figure 9: Allocating a Generic Netlink message buffer

The NLMSG_GOODSIZE macro/constant is a good value to use when you do not know
the size of the message buffer at the time of allocation.  Don't forget that
the message buffer needs to be big enough to hold the message payload and both
the Netlink and Generic Netlink message headers.

The second step is to actually create the message payload.  This is obviously
something which is very specific to each service, but a simple example is
shown below.

  int rc;
  void *msg_head;

  /* create the message headers */
  msg_head = genlmsg_put(skb, pid, seq, type, 0, flags, DOC_EXMPL_C_ECHO, 1);
  if (msg_head == NULL) {
      rc = -ENOMEM;
      goto failure;
  }
  /* add a DOC_EXMPL_A_MSG attribute */
  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Generic Netlink Rocks");
  if (rc != 0)
      goto failure;
  /* finalize the message */
  genlmsg_end(skb, msg_head);

  Figure 10: Creating a Generic Netlink message payload

The genlmsg_put() function creates the required Netlink and Generic Netlink
message headers, populating them with the given values; see the Generic
Netlink header file for a description of the parameters.  The nla_put_string()
function is a standard Netlink attribute function which adds a string
attribute to the end of the Netlink message; see the Netlink header file for a
description of the parameters.  The genlmsg_end() function updates the Netlink
message header once the message payload has been finalized, this function
should be called before sending the message.

The third and final step is to send the Generic Netlink message which can be
done with a single function call.  The example below is for a unicast send,
but interfaces exist for doing a multicast send of Generic Netlink message.

  int rc;

  rc = genlmsg_unicast(skb, pid);
  if (rc != 0)
      goto failure;

  Figure 11: Sending Generic Netlink messages

4.2.2. Receiving Messages

Typically, kernel modules act as Generic Netlink servers which means that the
act of receiving messages is handled automatically by the Generic Netlink bus.
Once the bus receives the message and determines the correct routing, the
message is passed directly to the family specific operation callback for
processing.  If the kernel is acting as a Generic Netlink client, server
response messages can be received over the Generic Netlink socket using
standard kernel socket interfaces.

4.3. Userspace Communication
------------------------------------------------------------------------------

While Generic Netlink messages can be sent and received using the standard
socket API it is recommended that user space applications use the libnl
library[4].  The libnl library insulates applications from many of the low
level Netlink tasks and uses an API which is very similar to the kernel API
shown above.

[4] http://people.suug.ch/~tgr/libnl

5. Recommendations
------------------------------------------------------------------------------

The Generic Netlink mechanism is a very flexible communications mechanism and
as a result there are many different ways it can be used.  The following
recommendations are based on conventions within the Linux kernel and should be
followed whenever possible.  While not all existing kernel code follows the
recommendations outlined here, all new code should consider these
recommendations as requirements.

5.1. Attributes And Message Payloads
------------------------------------------------------------------------------

When defining new Generic Netlink message formats you must make use of the
Netlink attributes wherever possible.  The Netlink attribute mechanism has
been carefully designed to allow for future message expansion while preserving
backward compatibility.  There are also additional benefits from using Netlink
attributes which include developer familiarity and basic input checking.

Most common data structures can be represented with Netlink attributes:

 * scalar values

   Most scalar values already have well-defined attribute types; see section 3
   for details.

 * structures

   Structures can be represented using a nested attribute with the structure
   fields represented as attributes in the payload of the container attribute.

 * arrays

   Arrays can be represented by using a single nested attribute as a container
   with several of the same attribute type inside each representing a spot in
   the array.

It is also important to use unique attributes as much as possible.  This helps
make the most of the Netlink attribute mechanisms and provides for easy changes
to the message format in the future.

5.2. Operation Granularity
------------------------------------------------------------------------------

While it may be tempting to register a single operation for a Generic Netlink
family and multiplex multiple sub-commands on the single operation, this
is strongly discouraged for security reasons.  Combining multiple behaviors
into one operation makes it difficult to restrict the operations using the
existing Linux kernel security mechanisms.

5.3. Acknowledgment and Error Reporting
------------------------------------------------------------------------------

It is often necessary for Generic Netlink services to return an ACK or error
code to the client.  It is not necessary to implement an explicit
acknowledgment message as Netlink already provides a flexible acknowledgment
and error reporting message type called NLMSG_ERROR.  When an error occurs a
NLMSG_ERROR message is returned to the client with the error code returned by
the Generic Netlink operation handler.  Clients can also request a NLMSG_ERROR
message when no error has occurred by setting the NLM_F_ACK flag on requests.

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-13 19:58       ` Paul Moore
@ 2006-11-14  6:53         ` Jarek Poplawski
  0 siblings, 0 replies; 35+ messages in thread
From: Jarek Poplawski @ 2006-11-14  6:53 UTC (permalink / raw)
  To: Paul Moore; +Cc: Thomas Graf, netdev

On Mon, Nov 13, 2006 at 02:58:17PM -0500, Paul Moore wrote:
> Jarek Poplawski wrote:
> > @@ -586,7 +586,7 @@
> >        goto failure;
> >    }
> >    /* add a DOC_EXMPL_A_MSG attribute */
> > -  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Generic Netlink Rocks");
> > +  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Justin Timberlake rocks");
> >    if (rc != 0)
> >        goto failure;
> >    /* finalize the message */
> 
> So here I am applying this patch by hand because the diffs are a bit off and I
> come across this ... I think I might have to nix this change on the basis of
> rudimentary quality standards :)
> 
> Besides, *I* brought sexy back.

It's too late!

"My Love" (clip) nixed all possible standards
so you'll have to update it soon anyway...

Jarek P.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-13 20:06           ` Paul Moore
@ 2006-11-17 13:05             ` jamal
  2006-11-17 19:47               ` jamal
  0 siblings, 1 reply; 35+ messages in thread
From: jamal @ 2006-11-17 13:05 UTC (permalink / raw)
  To: Paul Moore; +Cc: Jarek Poplawski, Thomas Graf, netdev

On Mon, 2006-13-11 at 15:06 -0500, Paul Moore wrote:
> jamal wrote:
> > On Mon, 2006-13-11 at 09:08 -0500, Paul Moore wrote:
> > 
> >>I want to give Jamal a little bit longer to reply.
> > 
> > Sorry, family emergency - still ongoing today, so havent looked at
> > anything (including presentation that was supposed to be done) ;-<
> > 
> > Give me a day or two (I know i at least have to do the presentation or
> > iam fscked ;->).
> 
> No problem, life has a tendency to surprise us once in a while, hopefully it is
> nothing to terrible.
> 

Sorry, this was certainly more than 2 days; however, I am back (kinda).
[Chasing something that is driving me nuts for the last hour or so for
an iproute2 with ipsec with hope to introduce aevents.]
i will review the doc as soon as i am done with that.

cheers,
jamal



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-17 13:05             ` jamal
@ 2006-11-17 19:47               ` jamal
  2006-11-17 23:53                 ` Paul Moore
  0 siblings, 1 reply; 35+ messages in thread
From: jamal @ 2006-11-17 19:47 UTC (permalink / raw)
  To: Paul Moore; +Cc: netdev, Thomas Graf, Jarek Poplawski

On Fri, 2006-17-11 at 08:05 -0500, jamal wrote:

> i will review the doc as soon as i am done with that.

I glanced at the doc over lunch. I will give you high level views first
and later on today or tomorrow i will give you a lot more pointed
opinions.

#1. I think the content layout has improved over the previous doc. So
good stuff.
Something still bothers me though; whether there is too much theory or
verbosity (not that this long email has any of those
characteristics;->). I am wondering if that affects usability. As a
litmus test, what would be the answer to the question:
"If i didnt know anything about generic netlink, how long do i need to
spend and immediately start programming?"
I dont think it is 5 minutes. Can we make it a 5 minute effort?

I think this is partially my fault because thats how i laid out the
original doc (and always is my style) - but you added more;->

Heres a thought:

** lay it out is to have two sections:

I. A LinuxWay section (others call it genetic programming!)

a) "heres an example for the kernel and heres the controller from user
space"
b) "heres what all different fields mean"

II. Here are all the nitty gritty details your mother never told you.

What this means is someone can immediately jump to Ia) do it the
LinuxWay(tm). When in doubt will read Ib) and when in further doubt will
read II.
[Actually Andrew Morton contented that nobody needs more than section I
when i first posted the doc].

I know this is a big change, so it will depend on how much time you
have. I also think people may be happy with it in its current form. It
would be nice to get feedback from someone who has used it.

2) Hey - you got rid of foobar[1] and googah ;-> I love those terms.
No big deal - you own the doc now, so you can get away with things like
that ;->

3) Why not create a references section at the end and move all the
references you have scattered every there instead? 

4) Terminology is still confusing even to me. We most definetely need
such a section. For example, I dont like the term "family" to descrive
those boxes that sit in the kernel. But i dont know what else to call
them. Also looking closely at Thomas' introduction of the thing called
nla_policy - it really oughta have been called attribute "property".
To add to this chaos - you introduced something you call a "channel". A
little confusing although sounds right ;-> I think the previous doc had
attempted something like a section on terms introduced by Balbir. But
you may have gotten rid of it.

5) For registration of commands and families, you dont show the user
handling return codes which could be errors. If this doc becomes
scripture it could mean trouble. Just a cutnpaste from the original doc
should suffice. 

6) There is still a lot of "content" for theory mostly that is missing.
I noticed you dont have async events, discovery etc. And there are still
a few ideas i would like to discuss with Thomas and send patches for
later.
So keep me as a coauthor - it will keep me on the hook for now; i will
bail out the moment i think it is complete.

hope this helps. 

cheers,
jamal

[1] http://en.wikipedia.org/wiki/Foobar


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-17 19:47               ` jamal
@ 2006-11-17 23:53                 ` Paul Moore
  2006-11-18 17:06                   ` jamal
  2006-11-20  7:26                   ` Jarek Poplawski
  0 siblings, 2 replies; 35+ messages in thread
From: Paul Moore @ 2006-11-17 23:53 UTC (permalink / raw)
  To: hadi; +Cc: netdev, Thomas Graf, Jarek Poplawski

jamal wrote:
> #1. I think the content layout has improved over the previous doc. So
> good stuff.
> Something still bothers me though; whether there is too much theory or
> verbosity (not that this long email has any of those
> characteristics;->). I am wondering if that affects usability. As a
> litmus test, what would be the answer to the question:
> "If i didnt know anything about generic netlink, how long do i need to
> spend and immediately start programming?"
> I dont think it is 5 minutes. Can we make it a 5 minute effort?
> 
> I think this is partially my fault because thats how i laid out the
> original doc (and always is my style) - but you added more;->
> 
> Heres a thought:
> 
> ** lay it out is to have two sections:
> 
> I. A LinuxWay section (others call it genetic programming!)
> 
> a) "heres an example for the kernel and heres the controller from user
> space"
> b) "heres what all different fields mean"

I think we are best off punting on the userspace as there a multiple ways to do
it: use good ole fashioned socket calls, the libnl library, or some other way
that hasn't been written yet.  Besides, Thomas already has some pretty good
userspace documentation written for libnl; no sense in duplicating that effort.

That said, there is a kernel space example and a field breakdown; did that look
okay?  If the content is good but the layout is off we can always move it up
closer to the top of the document.  If the content needs work lets deal with
that first ...

> II. Here are all the nitty gritty details your mother never told you.
> 
> What this means is someone can immediately jump to Ia) do it the
> LinuxWay(tm). When in doubt will read Ib) and when in further doubt will
> read II.
> [Actually Andrew Morton contented that nobody needs more than section I
> when i first posted the doc].

Well, if we are talking about *needs* then nobody really needs more than the
source code.  IMHO the main reason for documentation is to help speed along the
understanding of the code so it becomes more accessibile.  I can see their being
value for including both section I and section II material in the document.

> I know this is a big change, so it will depend on how much time you
> have. I also think people may be happy with it in its current form. It
> would be nice to get feedback from someone who has used it.

Well, it's Friday night and I've got a big football game to watch tommorrow so
I'm probably not going to devote much time to this until Monday.  Let's see what
 other people have to say in the meantime.  We can always just submit/post it
and play with it as time permits.

One of the main reasons I wanted to post my changes is because I found your
original document helpful when writing NetLabel but I didn't know about when I
started because it wasn't located in the usual places (I had to pick it out of
the mailing list archives).  I think having a Generic Netlink document in
Documentation/ and/or on the OSDL network wiki is a good thing - even if it
isn't perfect.

> 2) Hey - you got rid of foobar[1] and googah ;-> I love those terms.
> No big deal - you own the doc now, so you can get away with things like
> that ;->

Don't take it personally, it's just step one in my master plan to remove all
references too "googah" from the english language.  Muwahahaha!

> 3) Why not create a references section at the end and move all the
> references you have scattered every there instead? 

I tend to like the actual references closer to the referring text (I dislike
scrolling) but I'm not too hung up on this, I can move it.

> 4) Terminology is still confusing even to me. We most definetely need
> such a section. For example, I dont like the term "family" to descrive
> those boxes that sit in the kernel. But i dont know what else to call
> them. Also looking closely at Thomas' introduction of the thing called
> nla_policy - it really oughta have been called attribute "property".
> To add to this chaos - you introduced something you call a "channel". A
> little confusing although sounds right ;-> I think the previous doc had
> attempted something like a section on terms introduced by Balbir. But
> you may have gotten rid of it.

Yeah, I stuggled with that the entire time I was writing that draft.  I'm still
not entirely happy with it either but I decided that I was tired of worrying
about it so I just sent it out.

I don't remember a section on terminology in your original doc, but I'll go back
and check.

> 5) For registration of commands and families, you dont show the user
> handling return codes which could be errors. If this doc becomes
> scripture it could mean trouble. Just a cutnpaste from the original doc
> should suffice. 

Good point, I included it in the other examples but not that one - I'll fix it.

> 6) There is still a lot of "content" for theory mostly that is missing.
> I noticed you dont have async events, discovery etc. And there are still
> a few ideas i would like to discuss with Thomas and send patches for
> later.

Yep, I was trying to get it fairly small so people wouldn't be afraid by the
length of the document.  However, if we try to partition the document into two
sections then it's probably won't be too bad.

> So keep me as a coauthor - it will keep me on the hook for now; i will
> bail out the moment i think it is complete.

Hey, anybody who sends me text that doesn't include the phrase "Justin
Timberlake Rocks" gets to be a {co}author.  I'm just trying to keep the document
alive.

> [1] http://en.wikipedia.org/wiki/Foobar

My favorite wikipedia page -> http://en.wikipedia.org/wiki/Mad_Scientist

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-17 23:53                 ` Paul Moore
@ 2006-11-18 17:06                   ` jamal
  2006-11-20  7:39                     ` Jarek Poplawski
  2006-11-21 22:24                     ` Paul Moore
  2006-11-20  7:26                   ` Jarek Poplawski
  1 sibling, 2 replies; 35+ messages in thread
From: jamal @ 2006-11-18 17:06 UTC (permalink / raw)
  To: Paul Moore; +Cc: netdev, Thomas Graf, Jarek Poplawski

On Fri, 2006-17-11 at 18:53 -0500, Paul Moore wrote:
> jamal wrote:

> I think we are best off punting on the userspace as there a multiple ways to do
> it: use good ole fashioned socket calls, the libnl library, or some other way
> that hasn't been written yet.  Besides, Thomas already has some pretty good
> userspace documentation written for libnl; no sense in duplicating that effort.
> 

That has been my thinking as well. Looking at just the comments in the
code for the attribute stuff I think Thomas has done an excellent job in
documenting.
I havent looked at libnl in many moons (and dont have time at the
moment) - but it would be the right thing for a newbie/usability
approach.
In my tutorial I am not going to use it mostly because of lack of time
to figure out things (have to get out about 100 slides done by monday).
I already know how to use libnetlink and i have already added patches to
iproute2 for genetlink - so i am going to use those.
I will send you the tutorial so you can see what i mean.

> That said, there is a kernel space example and a field breakdown; did that look
> okay?  

It did. Just the little nitpicks i mentioned (like error checks etc). I
will stare at it some more later.

> If the content is good but the layout is off we can always move it up
> closer to the top of the document.  If the content needs work lets deal with
> that first ...
> 

I think moving it up first may make it more usable. If i find this doc,
cutnpaste, change variable names, load it, refine it further to do what
i want ... that would be ideal.

> Well, if we are talking about *needs* then nobody really needs more than the
> source code.  

I am not entirely sure i buy that anymore these days.
[The shock i had at some point is that the majority of linux users are
not subscribers to "the code is the message" philosophy. This was a
shock to me because the crowd i typically associate with always delivers
that message "Look at the source and you shall be healed"].

> IMHO the main reason for documentation is to help speed along the
> understanding of the code so it becomes more accessibile.  I can see their being
> value for including both section I and section II material in the document.
> 

sure, sure.
And in the complex case, source is useless if you dont know what is
being coded. 
  
> > I know this is a big change, so it will depend on how much time you
> > have. I also think people may be happy with it in its current form. It
> > would be nice to get feedback from someone who has used it.
> 
> Well, it's Friday night and I've got a big football game to watch tommorrow so
> I'm probably not going to devote much time to this until Monday.  

Take it easy, no rush.

> Let's see what
>  other people have to say in the meantime.  We can always just submit/post it
> and play with it as time permits.
> 

indeed.

> One of the main reasons I wanted to post my changes is because I found your
> original document helpful when writing NetLabel but I didn't know about when I
> started because it wasn't located in the usual places (I had to pick it out of
> the mailing list archives).  I think having a Generic Netlink document in
> Documentation/ and/or on the OSDL network wiki is a good thing - even if it
> isn't perfect.
> 

I tend to be conservative when pushing to the kernel(you should see the
patches i am sitting on;->). But if you are brave, go ahead and submit
it. Perhaps you can put the doc somewhere, and send a url patch to the
kernel and then keep updating the web version.

> Don't take it personally, it's just step one in my master plan to remove all
> references too "googah" from the english language.  Muwahahaha!
> 

hehe. That would be hard unless you get rid of certain cartoon
characters ;->

> I tend to like the actual references closer to the referring text (I dislike
> scrolling) but I'm not too hung up on this, I can move it.

Your mileage may vary. Your call - The formal way is you have them at
the end.

> Yeah, I stuggled with that the entire time I was writing that draft.  I'm still
> not entirely happy with it either but I decided that I was tired of worrying
> about it so I just sent it out.
> 
> I don't remember a section on terminology in your original doc, but I'll go back
> and check.
> 

If it is not there, I suggest just adding it in II.

> Hey, anybody who sends me text that doesn't include the phrase "Justin
> Timberlake Rocks" gets to be a {co}author.  

[Is Justin Timberlake the fella who got the FCC involved in Janet
Jacksons mammary glands? If, yes, he rocks!]

> I'm just trying to keep the document
> alive.
> 

A noble effort. And i dont want to stress you with more work - As it is
it is not bad, it could just be better ;-> (famous last words?)


> > [1] http://en.wikipedia.org/wiki/Foobar
> 
> My favorite wikipedia page -> http://en.wikipedia.org/wiki/Mad_Scientist

Hey, how did my picture get there? ;->

cheers,
jamal


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-17 23:53                 ` Paul Moore
  2006-11-18 17:06                   ` jamal
@ 2006-11-20  7:26                   ` Jarek Poplawski
  1 sibling, 0 replies; 35+ messages in thread
From: Jarek Poplawski @ 2006-11-20  7:26 UTC (permalink / raw)
  To: Paul Moore; +Cc: hadi, netdev, Thomas Graf

On Fri, Nov 17, 2006 at 06:53:11PM -0500, Paul Moore wrote:
...
> Hey, anybody who sends me text that doesn't include the phrase "Justin
> Timberlake Rocks" gets to be a {co}author.

So, according to law, you should add "for dummies" warning in the title. 
 
> My favorite wikipedia page -> http://en.wikipedia.org/wiki/Mad_Scientist

Scientists suck! Homer Simpson rocks!

Jarek P.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-18 17:06                   ` jamal
@ 2006-11-20  7:39                     ` Jarek Poplawski
  2006-11-21 22:24                     ` Paul Moore
  1 sibling, 0 replies; 35+ messages in thread
From: Jarek Poplawski @ 2006-11-20  7:39 UTC (permalink / raw)
  To: jamal; +Cc: Paul Moore, netdev, Thomas Graf

On Sat, Nov 18, 2006 at 12:06:59PM -0500, jamal wrote:
... 
> Hey, how did my picture get there? ;->

Which one? If you mean this with moustache, I like you!

Jarek P. 

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-18 17:06                   ` jamal
  2006-11-20  7:39                     ` Jarek Poplawski
@ 2006-11-21 22:24                     ` Paul Moore
  2006-11-22 12:27                       ` Jarek Poplawski
  1 sibling, 1 reply; 35+ messages in thread
From: Paul Moore @ 2006-11-21 22:24 UTC (permalink / raw)
  To: netdev; +Cc: hadi, Thomas Graf, Jarek Poplawski

Based on the discussion with Jamal I moved some things around in the doc so that
the examples were closer to the top and the details were towards the bottom.
There are some other minor changes as well, mostly changes already discussed in
the thread.

I think it may be a good idea to renew the discussion about where this document
should live.  My first thought was in Documentation/ but both Jamal and Stephen
Hemminger have suggested the OSDL networking wiki (we could always put a pointer
in Documentation/ if we went this route).  In order to eliminate the out-of-sync
problem I'd like to keep only one copy around; do people have a preference?

An Introduction To Using Generic Netlink
===============================================================================

Last Updated: November 21, 2006

Table of Contents

 1. Introduction
 1.1. Document Overview
 1.2. Netlink And Generic Netlink
 2. Generic Netlink By Example
    2.1. Registering A Family
    2.2. Kernel Communication
         2.2.1. Sending Messages
         2.2.2. Receiving Messages
    2.4. Userspace Communication
 3. Architectural Overview
 4. Implementation Details
    4.1. Message Format
    4.2. Data Structures
         4.2.1. The genl_family Structure
         4.2.2. The genl_ops Structure
 5. Recommendations
    5.1. Attributes And Message Payloads
    5.2. Operation Granularity
    5.3. Acknowledgment And Error Reporting
 6. References


1. Introduction
------------------------------------------------------------------------------

1.1. Document Overview
------------------------------------------------------------------------------

This document gives a brief introduction to Generic Netlink, some simple
examples on how to use it, and some recommendations on how to make the most of
the Generic Netlink communications interface.  While this document does not
require that the reader have a detailed understanding of what Netlink is
and how it works, some basic Netlink knowledge is assumed.  As usual, the
kernel source code is your best friend here.

While this document talks briefly about Generic Netlink from a userspace point
of view, its primary focus is on the kernel's Generic Netlink API.  It is
recommended that application developers who are interested in using Generic
Netlink make use of the libnl library[1].

1.2. Netlink And Generic Netlink
------------------------------------------------------------------------------

Netlink is a flexible, robust wire-format communications channel typically
used for kernel to user communication although it can also be used for
user to user and kernel to kernel communications.  Netlink communication
channels are associated with families or "busses", where each bus deals with a
specific service; for example, different Netlink busses exist for routing,
XFRM, netfilter, and several other kernel subsystems.  More information about
Netlink can be found in RFC 3549[2].

Over the years, Netlink has become very popular which has brought about a very
real concern that the number of Netlink family numbers may be exhausted in the
near future.  In response to this the Generic Netlink family was created which
acts as a Netlink multiplexer, allowing multiple services to use a single
Netlink bus.

2. Generic Netlink By Example
------------------------------------------------------------------------------

This section deals with the Generic Netlink subsystem in the Linux kernel and
provides a simple example of how in-kernel users can make use of the Generic
Netlink API.  Don't forget to review section #5, "Recommendations", before
writing any code as it could save you, and the people who review your code,
lots of time!

The first section explains how to register a Generic Netlink family which is
required for Generic Netlink users who wish to act as servers, listening over
the Generic Netlink "bus".  The second section explains how to send and receive
Generic Netlink messages in the kernel.  Finally, the third section provides
a brief introduction to using Generic Netlink in userspace.

2.1. Registering A Family
------------------------------------------------------------------------------

Registering a Generic Netlink family is a simple four step process: define the
family, define the operations, register the family, register the operations.
In order to help demonstrate these steps below is a simple example broken down
and explained in detail.

The first step is to define the family itself, which we do by creating an
instance of the genl_family structure.  In our simple example we are going to
create a new Generic Netlink family named "DOC_EXMPL".

  /* attributes */
  enum {
        DOC_EXMPL_A_UNSPEC,
        DOC_EXMPL_A_MSG,
        __DOC_EXMPL_A_MAX,
  };
  #define DOC_EXMPL_A_MAX (__DOC_EXMPL_A_MAX - 1)

  /* attribute policy */
  static struct nla_policy doc_exmpl_genl_policy[DOC_EXMPL_A_MAX + 1] = {
        [DOC_EXMPL_A_MSG] = { .type = NLA_NUL_STRING },
  };

  /* family definition */
  static struct genl_family doc_exmpl_gnl_family = {
        .id = GENL_ID_GENERATE,
        .hdrsize = 0,
        .name = "DOC_EXMPL",
        .version = 1,
        .maxattr = DOC_EXMPL_A_MAX,
  };

  Figure 1: The DOC_EXMPL family, attributes and policy

You can see above that we defined a new family and the family recognizes a
single attribute, DOC_EXMPL_A_MSG, which is a NULL terminated string.  The
GENL_ID_GENERATE macro/constant is really just the value 0x0 and it signifies
that we want the Generic Netlink controller to assign the channel number when
we register the family.

The second step is to define the operations for the family, which we do by
creating at least one instance of the genl_ops structure.  In this example we
are only going to define one operation but you can define up to 255 unique
operations for each family.

  /* handler */
  int doc_exmpl_echo(struct sk_buff *skb, struct genl_info *info)
  {
        /* message handling code goes here; return 0 on success, negative
         * values on failure */
  }

  /* commands */
  enum {
        DOC_EXMPL_C_UNSPEC,
        DOC_EXMPL_C_ECHO,
        __DOC_EXMPL_C_MAX,
  };
  #define DOC_EXMPL_C_MAX (__DOC_EXMPL_C_MAX - 1)

  /* operation definition */
  struct genl_ops doc_exmpl_gnl_ops_echo = {
        .cmd = DOC_EXMPL_C_ECHO,
        .flags = 0,
        .policy = doc_exmpl_genl_policy,
	.doit = doc_exmpl_echo,
	.dumpit = NULL,
  };

  Figure 2: The DOC_EXMPL_C_ECHO operation

Here we have defined a single operation, DOC_EXMPL_C_ECHO, which uses the
Netlink attribute policy we defined above.  Once registered, this particular
operation would call the doc_exmpl_echo() function whenever a
DOC_EXMPL_C_ECHO message is sent to the DOC_EXMPL family over the Generic
Netlink bus.

The third step it to register the DOC_EXMPL family with the Generic Netlink
operation.  We do this with a single function call:

  int rc;

  rc = genl_register_family(&doc_exmpl_gnl_family);
  if (rc != 0)
      goto failure;

This call registers the new family name with the Generic Netlink mechanism and
requests a new channel number which is stored in the genl_family struct,
replacing the GENL_ID_GENERATE value.  It is important to remember to
unregister Generic Netlink families when done as the kernel does allocate
resources for each registered family.

The fourth and final step is to register the operations for the family.  Once
again this is a simple function call:

  int rc;

  rc = genl_register_ops(&doc_exmpl_gnl_family, &doc_exmpl_gnl_ops_echo);
  if (rc != 0)
      goto failure;

This call registers the DOC_EXMPL_C_ECHO operation in association with the
DOC_EXMPL family.  The process is now complete.  Other Generic Netlink users
can now issue DOC_EXMPL_C_ECHO commands and they will be handled as desired.

2.2. Kernel Communication
------------------------------------------------------------------------------

The kernel provides two sets of interfaces for sending, receiving and
processing Generic Netlink messages.  The majority of the API consists of the
general purpose Netlink interfaces, however, there are a small number of
interfaces specific to Generic Netlink.  The following two 'include' files
define the Netlink and Generic Netlink API for the kernel:

 * include/net/netlink.h
 * include/net/genetlink.h

2.2.1. Sending Messages

Sending Generic Netlink messages is a three step process: allocate memory for
the message buffer, create the message, send the message.  In order to help
demonstrate these steps below is a simple example using the DOC_EXMPL family.

The first step is to allocate a Netlink message buffer; the easiest way to do
this is with the nlsmsg_new() function.

  struct sk_buff *skb;

  skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
  if (skb == NULL)
      goto failure;

  Figure 3: Allocating a Generic Netlink message buffer

The NLMSG_GOODSIZE macro/constant is a good value to use when you do not know
the size of the message buffer at the time of allocation.  Don't forget that
the genlmsg_new() function automatically adds space for the Netlink and Generic
Netlink message headers.

The second step is to actually create the message payload.  This is obviously
something which is very specific to each service, but a simple example is
shown below.

  int rc;
  void *msg_head;

  /* create the message headers */
  msg_head = genlmsg_put(skb, pid, seq, type, 0, flags, DOC_EXMPL_C_ECHO, 1);
  if (msg_head == NULL) {
      rc = -ENOMEM;
      goto failure;
  }
  /* add a DOC_EXMPL_A_MSG attribute */
  rc = nla_put_string(skb, DOC_EXMPL_A_MSG, "Generic Netlink Rocks");
  if (rc != 0)
      goto failure;
  /* finalize the message */
  genlmsg_end(skb, msg_head);

  Figure 4: Creating a Generic Netlink message payload

The genlmsg_put() function creates the required Netlink and Generic Netlink
message headers, populating them with the given values; see the Generic
Netlink header file for a description of the parameters.  The nla_put_string()
function is a standard Netlink attribute function which adds a string
attribute to the end of the Netlink message; see the Netlink header file for a
description of the parameters.  The genlmsg_end() function updates the Netlink
message header once the message payload has been finalized, this function
should be called before sending the message.

The third and final step is to send the Generic Netlink message which can be
done with a single function call.  The example below is for a unicast send,
but interfaces exist for doing a multicast send of Generic Netlink message.

  int rc;

  rc = genlmsg_unicast(skb, pid);
  if (rc != 0)
      goto failure;

  Figure 5: Sending Generic Netlink messages

2.2.2. Receiving Messages

Typically, kernel modules act as Generic Netlink servers which means that the
act of receiving messages is handled automatically by the Generic Netlink bus.
Once the bus receives the message and determines the correct routing, the
message is passed directly to the family specific operation callback for
processing.  If the kernel is acting as a Generic Netlink client, server
response messages can be received over the Generic Netlink socket using
standard kernel socket interfaces.

2.3. Userspace Communication
------------------------------------------------------------------------------

While Generic Netlink messages can be sent and received using the standard
socket API it is recommended that user space applications use the libnl
library[1].  The libnl library insulates applications from many of the low
level Netlink tasks and uses an API which is very similar to the kernel API
shown above.

3. Architectural Overview
------------------------------------------------------------------------------

Figure #6 illustrates the basic Generic Netlink architecture which is
composed of five different types of components:

 1) The Netlink subsystem which serves as the underlying transport layer for
    all of the Generic Netlink communications.

 2) The Generic Netlink bus which is implemented inside the kernel, but which
    is available to userspace through the socket API and inside the kernel via
    the normal Netlink and Generic Netlink APIs.

 3) The Generic Netlink users who communicate with each other over the Generic
    Netlink bus; users can exist both in kernel and user space.

 4) The Generic Netlink controller which is part of the kernel and is
    responsible for dynamically allocating Generic Netlink communication
    channels and other management tasks.  The Generic Netlink controller is
    implemented as a standard Generic Netlink user, however, it listens on a
    special, pre-allocated Generic Netlink channel.

 5) The kernel socket API.  Generic Netlink sockets are created with the
    PF_NETLINK domain and the NETLINK_GENERIC protocol values.

      +---------------------+      +---------------------+
      | (3) application "A" |      | (3) application "B" |
      +------+--------------+      +--------------+------+
             |                                    |
             \                                    /
              \                                  /
               |                                |
       +-------+--------------------------------+-------+
       |        :                               :       |   user-space
  =====+        :   (5)  kernel socket API      :       +================
       |        :                               :       |   kernel-space
       +--------+-------------------------------+-------+
                |                               |
          +-----+-------------------------------+----+
          |        (1)  Netlink subsystem            |
          +---------------------+--------------------+
                                |
          +---------------------+--------------------+
          |       (2) Generic Netlink bus            |
          +--+--------------------------+-------+----+
             |                          |       |
     +-------+---------+                |       |
     |  (4) controller |               /         \
     +-----------------+              /           \
                                      |           |
                   +------------------+--+     +--+------------------+
                   | (3) kernel user "X" |     | (3) kernel user "Y" |
                   +---------------------+     +---------------------+

  Figure 6: Generic Netlink Architecture

When looking at figure #6 it is important to note that any Generic Netlink
user can communicate with any other user over the bus using the same API
regardless of where the user resides in relation to the kernel/userspace
boundary.

Generic Netlink communications are essentially a series of different
communication channels which are multiplexed on a single Netlink family.
Communication channels are uniquely identified by channel numbers which are
dynamically allocated by the Generic Netlink controller.  The controller is a
special Generic Netlink user which listens on a fixed communication channel,
number 0x10, which is always present.  Kernel or userspace users which provide
services over the Generic Netlink bus establish new communication channels by
registering their services with the Generic Netlink controller.  Users who
want to use an existing service query the controller to see if it exists and
determine the correct channel number.

4. Implementation Details
------------------------------------------------------------------------------

This section provides a more in depth explanation of the Generic Netlink
message formats and data structures.

4.1. Message Format
------------------------------------------------------------------------------

Generic Netlink uses the standard Netlink subsystem as a transport layer which
means that the foundation of the Generic Netlink message is the standard
Netlink message format - the only difference is the inclusion of a Generic
Netlink message header.  The format of the message is defined as shown below:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                Netlink message header (nlmsghdr)              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           Generic Netlink message header (genlmsghdr)         |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |             Optional user specific message header             |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           Optional Generic Netlink message payload            |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  Figure 7: Generic Netlink message format

Figure #7 is included only to give you a rough idea of how Generic Netlink
messages are formatted and sent on the "wire".  In practice the Netlink and
Generic Netlink API should insulate most users from the details of the message
format and the Netlink message headers.


4.2. Data Structures
------------------------------------------------------------------------------

This section focuses on the Generic Netlink data structures as they are defined
in the kernel.  A similar API exists for userspace applications using the libnl
library[1].

4.2.1. The genl_family Structure

Generic Netlink families are defined by the genl_family structure, which is
shown below:

  struct genl_family
  {
        unsigned int            id;
        unsigned int            hdrsize;
        char                    name[GENL_NAMSIZ];
        unsigned int            version;
        unsigned int            maxattr;
        struct nlattr **        attrbuf;
        struct list_head        ops_list;
        struct list_head        family_list;
  };

  Figure 8: The genl_family structure

The genl_family structure fields are used in the following manner:

 * unsigned int id

   This is the dynamically allocated channel number.  A value of 0x0 signifies
   that the channel number should be assigned by the controller and the 0x10
   value is reserved for use by the controller.  Users should always use
   GENL_ID_GENERATE macro/constant (value 0x0) when registering a new family.

 * unsigned int hdrsize

   If the family makes use of a family specific header, its size is stored
   here.  If there is no family specific header this value should be zero.

 * char name[GENL_NAMSIZ]

   This string should be unique to the family as it is the key that the
   controller uses to lookup channel numbers when requested.

 * unsigned int version

   Family specific version number.

 * unsigned int maxattr

   Generic Netlink makes use of the standard Netlink attributes, this value
   holds the maximum number of attributes defined for the Generic Netlink
   family.

 * struct nlattr **attrbuf
 * struct list_head ops_list
 * struct list_head family_list

   These are private fields and should not be modified.

4.2.2. The genl_ops Structure

Generic Netlink operations are defined by the genl_ops structure, which is
shown below:

  struct genl_ops
  {
        u8                      cmd;
        unsigned int            flags;
        struct nla_policy       *policy;
        int                     (*doit)(struct sk_buff *skb,
                                        struct genl_info *info);
        int                     (*dumpit)(struct sk_buff *skb,
                                          struct netlink_callback *cb);
        struct list_head        ops_list;
  };

  Figure 9: The genl_ops structure

The genl_ops structure fields are used in the following manner:

 * u8 cmd

   This value is unique across the corresponding Generic Netlink family and is
   used to reference the operation.

 * unsigned int flags

   This field is used to specify any special attributes of the operation.  The
   following flags may be used (multiple flags can be OR'd together):

   - GENL_ADMIN_PERM

     The operation requires the CAP_NET_ADMIN privilege

 * struct nla_policy policy

   This field defines the Netlink attribute policy for the operation request
   message.  If specified, the Generic Netlink mechanism uses this policy to
   verify all of the attributes in an operation request message before calling
   the operation handler.

   The attribute policy is defined as an array of nla_policy structures indexed
   by the attribute number.  The nla_policy structure is defined as shown in
   figure #10.

     struct nla_policy
     {
        u16             type;
        u16             len;
     };

     Figure 10: The nla_policy structure

   The fields are used in the following manner:

   - u16 type

     This specifies the type of the attribute; presently the following types
     are defined for general use:

     o NLA_UNSPEC

       Undefined type

     o NLA_U8

       An 8-bit unsigned integer

     o NLA_U16

       A 16-bit unsigned integer

     o NLA_U32

       A 32-bit unsigned integer

     o NLA_U64

       A 64-bit unsigned integer

     o NLA_FLAG

       A simple boolean flag

     o NLA_MSECS

       A 64-bit time value in msecs

     o NLA_STRING

       A variable length string

     o NLA_NUL_STRING

       A variable length NULL terminated string

     o NLA_NESTED

       A stream of attributes

   - u16 len

     When the attribute type is one of the string types then this field should
     be set to the maximum length of the string, not including the terminal
     NULL byte.  If the attribute type is unknown or NLA_UNSPEC then this field
     should be set to the exact length of the attribute's payload.

     Unless the attribute type is one of the fixed-length types above, a value
     of zero indicates that no validation of the attribute should be performed.

 * int (*doit)(struct skbuff *skb, struct genl_info *info)

   This callback is similar in use to the standard Netlink 'doit' callback, the
   primary difference being the change in parameters.

   The 'doit' handler receives two parameters: the first is the message buffer
   which triggered the handler and the second is a Generic Netlink genl_info
   structure which is defined as shown in figure #11.

     struct genl_info
     {
        u32                     snd_seq;
        u32                     snd_pid;
        struct nlmsghdr *       nlhdr;
        struct genlmsghdr *     genlhdr;
        void *                  userhdr;
        struct nlattr **        attrs;
     };

     Figure 11: The genl_info structure

   The fields are populated in the following manner:

   - u32 snd_seq

     This is the Netlink sequence number of the request.

   - u32 snd_pid

     This is the Netlink PID of the client which issued the request, it is
     important to note that the Netlink PID is not the same as the standard
     kernel PID.

   - struct nlmsghdr *nlhdr

     This is set to point to the Netlink message header of the request.

   - struct genlmsghdr *genlhdr

     This is set to point to the Generic Netlink message header of the request.

   - void *userhdr

     If the Generic Netlink family makes use of a family specific header, this
     pointer will be set to point to the start of the family specific header.

   - struct nlattr **attrs

     The parsed Netlink attributes from the request; if the Generic Netlink
     family definition specified a Netlink attribute policy then the
     attributes would have already been validated.

   The 'doit' handler should do whatever processing is necessary and return
   zero on success or a negative value on failure.  Negative return values
   will cause a NLMSG_ERROR message to be sent while a zero return value will
   only cause a NLMSG_ERROR message to be sent if the request is received with
   the NLM_F_ACK flag set.

 * int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb)

   This callback is similar in use to the standard Netlink 'dumpit' callback.
   The 'dumpit' callback is invoked when a Generic Netlink message is received
   with the NLM_F_DUMP flag set.

   The main difference between the 'dumpit' handler and the 'doit' handler is
   that the 'dumpit' handler does not allocate a message buffer for a response;
   a pre-allocated sk_buff is passed to the 'dumpit' handler as the first
   parameter.  The 'dumpit' handler should fill the message buffer with the
   appropriate response message and return the size of the sk_buff,
   i.e. sk_buff->len, and the message buffer will automatically be sent to the
   Generic Netlink client that initiated the request.  As long as the 'dumpit'
   handler returns a value greater than zero it will be called again with a
   newly allocated message buffer to fill.  When the handler has no more data
   to send it should return zero; error conditions are indicated by returning
   a negative value.  If necessary, state can be preserved in the
   netlink_callback parameter which is passed to the 'dumpit' handler; the
   netlink_callback parameter values will be preserved across handler calls
   for a single request.

 * struct list_head ops_list

   This is a private field and should not be modified.

5. Recommendations
------------------------------------------------------------------------------

The Generic Netlink mechanism is a very flexible communications mechanism and
as a result there are many different ways it can be used.  The following
recommendations are based on conventions within the Linux kernel and should be
followed whenever possible.  While not all existing kernel code follows the
recommendations outlined here, all new code should consider these
recommendations as requirements.

5.1. Attributes And Message Payloads
------------------------------------------------------------------------------

When defining new Generic Netlink message formats you must make use of the
Netlink attributes wherever possible.  The Netlink attribute mechanism has
been carefully designed to allow for future message expansion while preserving
backward compatibility.  There are also additional benefits from using Netlink
attributes which include developer familiarity and basic input checking.

Most common data structures can be represented with Netlink attributes:

 * scalar values

   Most scalar values already have well-defined attribute types; see section 4
   for details.

 * structures

   Structures can be represented using a nested attribute with the structure
   fields represented as attributes in the payload of the container attribute.

 * arrays

   Arrays can be represented by using a single nested attribute as a container
   with several of the same attribute type inside each representing a spot in
   the array.

It is also important to use unique attributes as much as possible.  This helps
make the most of the Netlink attribute mechanisms and provides for easy changes
to the message format in the future.

5.2. Operation Granularity
------------------------------------------------------------------------------

While it may be tempting to register a single operation for a Generic Netlink
family and multiplex multiple sub-commands on the single operation, this
is strongly discouraged for security reasons.  Combining multiple behaviors
into one operation makes it difficult to restrict the operations using the
existing Linux kernel security mechanisms.

5.3. Acknowledgment and Error Reporting
------------------------------------------------------------------------------

It is often necessary for Generic Netlink services to return an ACK or error
code to the client.  It is not necessary to implement an explicit
acknowledgment message as Netlink already provides a flexible acknowledgment
and error reporting message type called NLMSG_ERROR.  When an error occurs a
NLMSG_ERROR message is returned to the client with the error code returned by
the Generic Netlink operation handler.  Clients can also request a NLMSG_ERROR
message when no error has occurred by setting the NLM_F_ACK flag on requests.

6. References
------------------------------------------------------------------------------

[1] http://people.suug.ch/~tgr/libnl
[2] ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-21 22:24                     ` Paul Moore
@ 2006-11-22 12:27                       ` Jarek Poplawski
  2006-11-22 21:38                         ` Paul Moore
  0 siblings, 1 reply; 35+ messages in thread
From: Jarek Poplawski @ 2006-11-22 12:27 UTC (permalink / raw)
  To: Paul Moore; +Cc: netdev, hadi, Thomas Graf

On Tue, Nov 21, 2006 at 05:24:15PM -0500, Paul Moore wrote:
> Based on the discussion with Jamal I moved some things around in the doc so that
> the examples were closer to the top and the details were towards the bottom.
> There are some other minor changes as well, mostly changes already discussed in
> the thread.
...

And here is some (over)adJustin'.

Jarek P.


--- netlink4.txt-	2006-11-22 09:26:47.000000000 +0100
+++ netlink4.txt	2006-11-22 12:57:12.000000000 +0100
@@ -1,5 +1,5 @@
 An Introduction To Using Generic Netlink
-===============================================================================
+==============================================================================
 
 Last Updated: November 21, 2006
 
@@ -13,7 +13,7 @@
     2.2. Kernel Communication
          2.2.1. Sending Messages
          2.2.2. Receiving Messages
-    2.4. Userspace Communication
+    2.3. Userspace Communication
  3. Architectural Overview
  4. Implementation Details
     4.1. Message Format
@@ -34,9 +34,9 @@
 ------------------------------------------------------------------------------
 
 This document gives a brief introduction to Generic Netlink, some simple
-examples on how to use it, and some recommendations on how to make the most of
+examples on how to use it and some recommendations on how to make the most of
 the Generic Netlink communications interface.  While this document does not
-require that the reader have a detailed understanding of what Netlink is
+require that the reader has a detailed understanding of what Netlink is
 and how it works, some basic Netlink knowledge is assumed.  As usual, the
 kernel source code is your best friend here.
 
@@ -48,12 +48,12 @@
 1.2. Netlink And Generic Netlink
 ------------------------------------------------------------------------------
 
-Netlink is a flexible, robust wire-format communications channel typically
+Netlink is a flexible, robust, wire-format communications channel typically
 used for kernel to user communication although it can also be used for
 user to user and kernel to kernel communications.  Netlink communication
 channels are associated with families or "busses", where each bus deals with a
 specific service; for example, different Netlink busses exist for routing,
-XFRM, netfilter, and several other kernel subsystems.  More information about
+XFRM, netfilter and several other kernel subsystems.  More information about
 Netlink can be found in RFC 3549[2].
 
 Over the years, Netlink has become very popular which has brought about a very
@@ -68,14 +68,14 @@
 This section deals with the Generic Netlink subsystem in the Linux kernel and
 provides a simple example of how in-kernel users can make use of the Generic
 Netlink API.  Don't forget to review section #5, "Recommendations", before
-writing any code as it could save you, and the people who review your code,
+writing any code as it can save you, and the people who review your code,
 lots of time!
 
 The first section explains how to register a Generic Netlink family which is
 required for Generic Netlink users who wish to act as servers, listening over
-the Generic Netlink "bus".  The second section explains how to send and receive
-Generic Netlink messages in the kernel.  Finally, the third section provides
-a brief introduction to using Generic Netlink in userspace.
+the Generic Netlink bus.  The second section explains how to send and
+receive Generic Netlink messages in the kernel.  Finally, the third section
+provides a brief introduction to using Generic Netlink in userspace.
 
 2.1. Registering A Family
 ------------------------------------------------------------------------------
@@ -190,7 +190,7 @@
 The kernel provides two sets of interfaces for sending, receiving and
 processing Generic Netlink messages.  The majority of the API consists of the
 general purpose Netlink interfaces, however, there are a small number of
-interfaces specific to Generic Netlink.  The following two 'include' files
+interfaces specific to Generic Netlink.  The following two "include" files
 define the Netlink and Generic Netlink API for the kernel:
 
  * include/net/netlink.h
@@ -215,8 +215,8 @@
 
 The NLMSG_GOODSIZE macro/constant is a good value to use when you do not know
 the size of the message buffer at the time of allocation.  Don't forget that
-the genlmsg_new() function automatically adds space for the Netlink and Generic
-Netlink message headers.
+the genlmsg_new() function automatically adds space for the Netlink and
+Generic Netlink message headers.
 
 The second step is to actually create the message payload.  This is obviously
 something which is very specific to each service, but a simple example is
@@ -246,7 +246,7 @@
 function is a standard Netlink attribute function which adds a string
 attribute to the end of the Netlink message; see the Netlink header file for a
 description of the parameters.  The genlmsg_end() function updates the Netlink
-message header once the message payload has been finalized, this function
+message header once the message payload has been finalized.  This function
 should be called before sending the message.
 
 The third and final step is to send the Generic Netlink message which can be
@@ -349,13 +349,13 @@
 number 0x10, which is always present.  Kernel or userspace users which provide
 services over the Generic Netlink bus establish new communication channels by
 registering their services with the Generic Netlink controller.  Users who
-want to use an existing service query the controller to see if it exists and
-determine the correct channel number.
+want to use a service query the controller to see if the service exists and
+to determine the correct channel number.
 
 4. Implementation Details
 ------------------------------------------------------------------------------
 
-This section provides a more in depth explanation of the Generic Netlink
+This section provides a more in-depth explanation of the Generic Netlink
 message formats and data structures.
 
 4.1. Message Format
@@ -381,7 +381,7 @@
   Figure 7: Generic Netlink message format
 
 Figure #7 is included only to give you a rough idea of how Generic Netlink
-messages are formatted and sent on the "wire".  In practice the Netlink and
+messages are formatted and sent "on the wire".  In practice the Netlink and
 Generic Netlink API should insulate most users from the details of the message
 format and the Netlink message headers.
 
@@ -389,9 +389,9 @@
 4.2. Data Structures
 ------------------------------------------------------------------------------
 
-This section focuses on the Generic Netlink data structures as they are defined
-in the kernel.  A similar API exists for userspace applications using the libnl
-library[1].
+This section focuses on the Generic Netlink data structures as they are
+defined in the kernel.  A similar API exists for userspace applications using
+the libnl library[1].
 
 4.2.1. The genl_family Structure
 
@@ -437,7 +437,7 @@
 
  * unsigned int maxattr
 
-   Generic Netlink makes use of the standard Netlink attributes, this value
+   Generic Netlink makes use of the standard Netlink attributes; this value
    holds the maximum number of attributes defined for the Generic Netlink
    family.
 
@@ -486,12 +486,12 @@
 
    This field defines the Netlink attribute policy for the operation request
    message.  If specified, the Generic Netlink mechanism uses this policy to
-   verify all of the attributes in an operation request message before calling
-   the operation handler.
+   verify all of the attributes in the operation request message before
+   calling the operation handler.
 
-   The attribute policy is defined as an array of nla_policy structures indexed
-   by the attribute number.  The nla_policy structure is defined as shown in
-   figure #10.
+   The attribute policy is defined as an array of nla_policy structures
+   indexed by the attribute number.  The nla_policy structure is defined as
+   shown in figure #10.
 
      struct nla_policy
      {
@@ -552,18 +552,19 @@
 
      When the attribute type is one of the string types then this field should
      be set to the maximum length of the string, not including the terminal
-     NULL byte.  If the attribute type is unknown or NLA_UNSPEC then this field
-     should be set to the exact length of the attribute's payload.
+     NULL byte.  If the attribute type is unknown or NLA_UNSPEC then this
+     field should be set to the exact length of the attribute's payload.
 
      Unless the attribute type is one of the fixed-length types above, a value
-     of zero indicates that no validation of the attribute should be performed.
+     of zero indicates that no validation of the attribute should be
+     performed.
 
  * int (*doit)(struct skbuff *skb, struct genl_info *info)
 
-   This callback is similar in use to the standard Netlink 'doit' callback, the
-   primary difference being the change in parameters.
+   This callback is similar in use to the standard Netlink doit() callback,
+   the primary difference being the change in parameters.
 
-   The 'doit' handler receives two parameters: the first is the message buffer
+   The doit() handler receives two parameters: the first is the message buffer
    which triggered the handler and the second is a Generic Netlink genl_info
    structure which is defined as shown in figure #11.
 
@@ -587,7 +588,7 @@
 
    - u32 snd_pid
 
-     This is the Netlink PID of the client which issued the request, it is
+     This is the Netlink PID of the client which issued the request; it is
      important to note that the Netlink PID is not the same as the standard
      kernel PID.
 
@@ -597,7 +598,8 @@
 
    - struct genlmsghdr *genlhdr
 
-     This is set to point to the Generic Netlink message header of the request.
+     This is set to point to the Generic Netlink message header of the
+     request.
 
    - void *userhdr
 
@@ -610,30 +612,30 @@
      family definition specified a Netlink attribute policy then the
      attributes would have already been validated.
 
-   The 'doit' handler should do whatever processing is necessary and return
+   The doit() handler should do whatever processing is necessary and return
    zero on success or a negative value on failure.  Negative return values
-   will cause a NLMSG_ERROR message to be sent while a zero return value will
-   only cause a NLMSG_ERROR message to be sent if the request is received with
-   the NLM_F_ACK flag set.
+   will cause an NLMSG_ERROR message to be sent while a zero return value will
+   only cause the NLMSG_ERROR message to be sent if the request is received
+   with the NLM_F_ACK flag set.
 
  * int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb)
 
-   This callback is similar in use to the standard Netlink 'dumpit' callback.
-   The 'dumpit' callback is invoked when a Generic Netlink message is received
-   with the NLM_F_DUMP flag set.
-
-   The main difference between the 'dumpit' handler and the 'doit' handler is
-   that the 'dumpit' handler does not allocate a message buffer for a response;
-   a pre-allocated sk_buff is passed to the 'dumpit' handler as the first
-   parameter.  The 'dumpit' handler should fill the message buffer with the
-   appropriate response message and return the size of the sk_buff,
+   This callback is similar in use to the standard Netlink dumpit() callback.
+   The dumpit() callback is invoked when the Generic Netlink message is
+   received with the NLM_F_DUMP flag set.
+
+   The main difference between the dumpit() handler and the doit() handler is
+   that the dumpit() handler does not allocate a message buffer for a
+   response; a pre-allocated sk_buff is passed to the dumpit() handler as the
+   first parameter.  The dumpit() handler should fill the message buffer with
+   the appropriate response message and return the size of the sk_buff,
    i.e. sk_buff->len, and the message buffer will automatically be sent to the
-   Generic Netlink client that initiated the request.  As long as the 'dumpit'
+   Generic Netlink client that initiated the request.  As long as the dumpit()
    handler returns a value greater than zero it will be called again with a
    newly allocated message buffer to fill.  When the handler has no more data
    to send it should return zero; error conditions are indicated by returning
    a negative value.  If necessary, state can be preserved in the
-   netlink_callback parameter which is passed to the 'dumpit' handler; the
+   netlink_callback parameter which is passed to the dumpit() handler; the
    netlink_callback parameter values will be preserved across handler calls
    for a single request.
 
@@ -679,8 +681,8 @@
    the array.
 
 It is also important to use unique attributes as much as possible.  This helps
-make the most of the Netlink attribute mechanisms and provides for easy changes
-to the message format in the future.
+make the most of the Netlink attribute mechanisms and provides for easy
+changes to the message format in the future.
 
 5.2. Operation Granularity
 ------------------------------------------------------------------------------
@@ -697,10 +699,11 @@
 It is often necessary for Generic Netlink services to return an ACK or error
 code to the client.  It is not necessary to implement an explicit
 acknowledgment message as Netlink already provides a flexible acknowledgment
-and error reporting message type called NLMSG_ERROR.  When an error occurs a
+and error reporting message type called NLMSG_ERROR.  When an error occurs an
 NLMSG_ERROR message is returned to the client with the error code returned by
-the Generic Netlink operation handler.  Clients can also request a NLMSG_ERROR
-message when no error has occurred by setting the NLM_F_ACK flag on requests.
+the Generic Netlink operation handler.  Clients can also request the
+NLMSG_ERROR message when no error has occurred by setting the NLM_F_ACK flag
+on requests.
 
 6. References
 ------------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: Generic Netlink HOW-TO based on Jamal's original doc
  2006-11-22 12:27                       ` Jarek Poplawski
@ 2006-11-22 21:38                         ` Paul Moore
  0 siblings, 0 replies; 35+ messages in thread
From: Paul Moore @ 2006-11-22 21:38 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: netdev, hadi, Thomas Graf

Jarek Poplawski wrote:
> On Tue, Nov 21, 2006 at 05:24:15PM -0500, Paul Moore wrote:
> 
>>Based on the discussion with Jamal I moved some things around in the doc so that
>>the examples were closer to the top and the details were towards the bottom.
>>There are some other minor changes as well, mostly changes already discussed in
>>the thread.
> 
> ...
> 
> And here is some (over)adJustin'.
> 
> Jarek P.

Applied ... despite the covert Justin reference :P

-- 
paul moore
linux security @ hp

^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2006-11-22 21:39 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-10  6:08 Generic Netlink HOW-TO based on Jamal's original doc Paul Moore
2006-11-10  6:37 ` James Morris
2006-11-10  6:45   ` Paul Moore
2006-11-10 14:34     ` jamal
2006-11-10 16:17       ` Paul Moore
2006-11-10 16:59         ` Randy Dunlap
2006-11-10  9:48 ` Thomas Graf
2006-11-10 16:08   ` Paul Moore
2006-11-10 13:24 ` Jarek Poplawski
2006-11-10 16:10   ` Paul Moore
2006-11-10 17:36   ` Thomas Graf
2006-11-13  7:05     ` Jarek Poplawski
2006-11-13  7:23     ` Jarek Poplawski
2006-11-13 14:08       ` Paul Moore
2006-11-13 14:17         ` jamal
2006-11-13 20:06           ` Paul Moore
2006-11-17 13:05             ` jamal
2006-11-17 19:47               ` jamal
2006-11-17 23:53                 ` Paul Moore
2006-11-18 17:06                   ` jamal
2006-11-20  7:39                     ` Jarek Poplawski
2006-11-21 22:24                     ` Paul Moore
2006-11-22 12:27                       ` Jarek Poplawski
2006-11-22 21:38                         ` Paul Moore
2006-11-20  7:26                   ` Jarek Poplawski
2006-11-13 19:58       ` Paul Moore
2006-11-14  6:53         ` Jarek Poplawski
2006-11-10 15:49 ` Stephen Hemminger
2006-11-10 16:20   ` Paul Moore
2006-11-10 18:23 ` Randy Dunlap
2006-11-10 19:50   ` Paul Moore
2006-11-10 22:12   ` Thomas Graf
2006-11-10 22:49     ` Randy Dunlap
2006-11-10 22:56       ` Thomas Graf
2006-11-10 23:17         ` Randy Dunlap

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).