Netlink message handling in Shill.


1.0 INTRODUCTION.

Shill uses netlink sockets (described in RFC 3549) to communicate with
software in kernel space.  Messages that are passed across netlink sockets take
a specific format that includes a netlink header, a sub-domain-specific header,
and attributes.

Shill defines a NetlinkManager class for dealing with the netlink sockets and
NetlinkMessage (and its children such as ControlNetlinkMessage and
Nl80211Message) and NetlinkAttribute (and its children) classes for dealing
with the messages passed across the netlink sockets.


2.0 SENDING A MESSAGE.

This section describes how to send a netlink message in Shill.  The steps,
described below, are:

  o Create a message.
  o Make Response and Error Handlers.
  o Send the Message.


2.1 Create the message.

Start by declaring a message object.  This will be a message-specific child
class of the NetlinkMessage type.  For example:

  TriggerScanMessage trigger_scan;

2.1.1 Add attributes to the message.

You'll want to set values for all the message's attributes.  The message
object should have all of its legal attributes pre-instantiated so all
you should have to do is set their values (if an attribute is optional,
don't set the value -- only the attibutes that have been explicitly
set will be sent in the message).

A message's attributes are accessed through the message's |attributes|
or |const_attributes| methods.


2.1.1.1 Regular attributes.

Netlink attributes are typed (e.g., String, U32, etc.).  In order to
set the value of an attribute you use the SetXxxAttributeValue method
(where Xxx is the type of the attribute.  For example, you may want
to set the value of the NL80211_ATTR_IFINDEX attribute:

  if (trigger_scan.attributes()->SetU32AttributeValue(
         NL80211_ATTR_IFINDEX, wifi_interface_index_)) {
    // ...

If the message hasn't pre-instantiated the attribute you want to use, the
'SetXxxAttributeValue' call will return false.  This can be for one of
three reasons:

  a) a message of this type may not be expecting this kind of attribute,
  b) the data type of the attribute may not agree with the setter you
     used, or
  c) the definition of the specific message class is incomplete (that
     is, the attribute hasn't been, but should be, added to the message
     type).

You can check the kernel code to determine the attributes each message is
expecting and the type of those attributes.

  a) Find the command (NL80211_CMD_TRIGGER_SCAN, in the case of
     TriggerScanMessage) in the |nl80211_ops| array in the kernel sources
     (.../src/third_party/kernel/files/net/wireless/nl80211.c in the ChromeOS
     sources).
  b) Find the name of the command handler (in the |.doit| structure member)
     in that structure.  Find that handler.  In the case of
     NL80211_CMD_TRIGGER_SCAN, the handler is |nl80211_trigtger_scan|.
  c) Look for handling of the attribute in question.  It will be an offset
     into the |info->attrs[]| array.  You can also see the data type expected
     for the attribute.

If the kernel expects the attribute, modify the message's constructor
(probably in one of the message handling source files, like
nl80211_message.cc) to create the attribute:

  attributes()->CreateAttribute(
      NL80211_ATTR_IFINDEX, Bind(&NetlinkAttribute::NewNl80211AttributeFromId));


2.1.1.2  Nested attributes.

So, this is all fun and games until someone needs a nested attribute.
A nested attribute contains a number of other attributes (like a structure)
or a list of identically-typed attributes (like an array).  To set a nested
attribute, declare an AttributeListRefPtr, and fill it with the attribute
in question:

  AttributeListRefPtr nested;
  if (!trigger_scan.attributes()->GetNestedAttributeList(
      NL80211_ATTR_SCAN_FREQUENCIES, &nested) || !nested) {
    LOG(FATAL) << "Couldn't get NL80211_ATTR_SCAN_FREQUENCIES.";
  }

Set the 'has a value' trait of the nested attribute:

  trigger_scan.attributes()->SetNestedAttributeHasAValue(
      NL80211_ATTR_SCAN_FREQUENCIES);

Now, create and set the nested attributes within AttributeList.  You can
create an array:

  int i = 0;
  for (const auto freq : scan_frequencies) {
    nested->CreateU32Attribute(i, StringPrintf("Frequency-%d", i).c_str());
    nested->SetU32AttributeValue(i, freq);
    ++i;
  }

Or you can just create and add ordinary named attributes:

  nested->CreateStringAttribute(type, kSsidString);
  nested->SetStringAttributeValue(type, "Foo");

You can even nest nested attributes inside nested attributes:

  nested->CreateNestedAttribute(type, kRatesString);
  AttributeListRefPtr nested_nested;
  if (!nested->GetNestedAttributeList(type, &nested_nested) ||
      !nested_nested) {
    LOG(ERROR) << "Couldn't get attribute " << attribute_name
               << " which we just created.";
    return;
  }
  for (size_t i = 0; i < payload_bytes; ++i) {
    string rate_name = StringPrintf("Rate-%zu", i);
    nested_nested->CreateU8Attribute(i, rate_name.c_str());
    nested_nested->SetU8AttributeValue(i, payload[i]);
  }
  nested->SetNestedAttributeHasAValue(type);


2.2 Make Response and Error Handlers.

Make some sort of handler for the response message.

  class Foo {
   // ...
   private:
    // More on this, later.
    void OnTriggerScanResponse(const Nl80211Message &response) {
      // Do whatever you want with the response.
      return;
    }

    void OnTriggerScanErrorResponse(
        NetlinkManager::AuxilliaryMessageType type,
        const NetlinkMessage *netlink_message) {
      switch (type) {
        case NetlinkManager::kErrorFromKernel: {
            if (!netlink_message) {
              LOG(ERROR) << __func__ << ": Message failed: NetlinkManager Error.";
              break;
            }
            if (netlink_message->message_type() !=
                ErrorAckMessage::GetMessageType()) {
              LOG(ERROR) << __func__ << ": Message failed: Not an error.";
              break;
            }
            const ErrorAckMessage *error_ack_message =
                dynamic_cast<const ErrorAckMessage *>(netlink_message);
            if (error_ack_message->error()) {
              LOG(ERROR) << __func__ << ": Message failed: "
                         << error_ack_message->ToString();
            } else {
              SLOG(WiFi, 6) << __func__ << ": Message ACKed";
            }
          }
          break;

        case NetlinkManager::kUnexpectedResponseType:
          LOG(ERROR) << "Message not handled by regular message handler:";
          if (netlink_message) {
            netlink_message->Print(0, 0);
          }
          found_error_ = true;
          on_scan_failed_.Run();
          break;

        case NetlinkManager::kTimeoutWaitingForResponse:
          // Handle this one.
          break;

        default:
          LOG(ERROR) << "Unexpected auxiliary message type: " << type;
          found_error_ = true;
          on_scan_failed_.Run();
          break;
      }
    }
  }


2.3 Send the Message.

Send the message with the handlers for the various cases.

  NetlinkManager::GetInstance()->SendNl80211Message(
      &trigger_scan,
      Bind(&Foo::OnTriggerScanResponse,
           weak_ptr_factory_.GetWeakPtr()),
      Bind(&Foo::OnTriggerScanErrorResponse,
           weak_ptr_factory_.GetWeakPtr()));


3.0 RECEIVING A NETLINK MESSAGE.

3.1 Build a Message Handler (to which I've alluded, above).

The message handler should take a single parameter of the type of message you
want to handle.  For example:

  void NetlinkManager::OnNewFamilyMessage(const ControlNetlinkMessage &message) {

You'll probably want to look for some attributes:

  uint16_t family_id;
  if (!message.const_attributes()->GetU16AttributeValue(CTRL_ATTR_FAMILY_ID,
                                                         &family_id)) {
    LOG(ERROR) << __func__ << ": Couldn't get family_id attribute";
    return;
  }

  string family_name;
  if (!message.const_attributes()->GetStringAttributeValue(
      CTRL_ATTR_FAMILY_NAME, &family_name)) {
    LOG(ERROR) << __func__ << ": Couldn't get family_name attribute";
    return;
  }

And, some of these attributes may be nested.  In this example, we've got an
array of structures that looks sort-of like (this isn't the way the data is
stored, it just _logically_ looks like this):

  struct {
    u32 ignored;  // CTRL_ATTR_MCAST_GRP_UNSPEC;
    string group_name;  // CTRL_ATTR_MCAST_GRP_NAME;
    u32 group_id;  // CTRL_ATTR_MCAST_GRP_ID;
  } multicast_groups[];

But the actual code for reading this array is as follows:

  AttributeListConstRefPtr multicast_groups;
  if (message.const_attributes()->ConstGetNestedAttributeList(
      CTRL_ATTR_MCAST_GROUPS, &multicast_groups)) {
    AttributeListConstRefPtr current_group;

    for (int i = 1;
         multicast_groups->ConstGetNestedAttributeList(i, &current_group);
         ++i) {

      string group_name;
      if (!current_group->GetStringAttributeValue(CTRL_ATTR_MCAST_GRP_NAME,
                                                  &group_name)) {
        LOG(WARNING) << "Expected CTRL_ATTR_MCAST_GRP_NAME, found none";
        continue;
      }

      uint32_t group_id;
      if (!current_group->GetU32AttributeValue(CTRL_ATTR_MCAST_GRP_ID,
                                               &group_id)) {
        LOG(WARNING) << "Expected CTRL_ATTR_MCAST_GRP_ID, found none";
        continue;
      }

      SLOG(WiFi, 3) << "  Adding group '" << group_name << "' = " << group_id;
      message_types_[family_name].groups[group_name] = group_id;
    }
  }


3.2 Install the Message Handler.

The message you're handling can either be a broadcast message or a response
(I've not seen a case where the kernel sends a message directly to us but, I'd
imagine it's possible.  This case could be handled as a broadcast message
followed by a hasty name change fot that method).

3.2.1 Install a Broadcast Message Handler.

Broadcast handlers are installed to the NetlinkManager as follows:

  NetlinkManager::GetInstance()->AddBroadcastHandler(handler);

Where 'handler' is the handler described, above.  Broadcast messaes just
handle generic NetlinkMessages rather than a specific kind.

3.2.2 Install a Unicast (i.e., a Response) Message Handler.

Otherwise, the handler is installed as the response handler for a message.
For example:

  ControlNetlinkMessage message;
  // Build the message.

  NetlinkManager::GetInstance()->SendControlMessage(&message,
                                                    &message_handler,
						    &error_handler);

