message attribute mismatch

Sergiy Lozovsky sergiy.lozovsky at gmail.com
Fri Jun 5 12:53:29 PDT 2015


Hi Thoms,

thanks for the response. It's bad that libnl attribute types don't
match kernel and other packages attribute types. It is the core idea
of Netlink for all endpoints to have consistent API. IMHO

At the same time after some digging, I figured out that it's not
really critical. I thought that types are transmitted within the
message. I was wrong. Attribute types are used for type verification
and deserialization only.

That means that although other endpoints (kernel, Python, etc.) use
NLA_NUL_STRING and NLA_BINARY. It's ok to use NLA_STRING and
NLA_UNSPEC in application using libnl. This mismatch looks ugly from
software support point of view, but it will work.

NLA_BINARY means that content is not checked and can have variable
length. NLA_UNSPEC is exactly the same.

NLA_STRING - will deserialize attribute encoded as NLA_NUL_STRING just
fine. It will not verify trailing zero and minimal length (1) (as
kernel does), but other than that there are no problems.

I may later work on the patch to add NLA_NUL_STRING and NLA_BINARY to libnl.

There is other problem with libnl - it doesn't directly support server
side of Netlink. It is still possible to implement it, but
nl_recvmsgs_default() will return NLE_SEQ_MISMATCH as server doesn't
know what sequence number will be sent by a client. It's easy to just
ignore these errors and use NL_CB_MSG_IN callback skipping all
nl_recvmsgs verifications though.

Thanks,

Sergiy.




On Thu, Jun 4, 2015 at 10:50 PM, Thomas Haller <thaller at redhat.com> wrote:
> On Mo, 2015-06-01 at 17:58 -0700, Sergiy Lozovsky wrote:
>> Hi,
>>
>> it looks like libnl-3.2.25 doesn't support following attribute types:
>> NLA_NUL_STRING and NLA_BINARY. These types are supported by kernel,
>> Python Netlink packages, etc.
>>
>> We have a kernel module and Python scripts that use these types. Is
>> there any workaround? What is the best way to handle that?
>
> Hi Sergiy,
>
>
> Usually, you can use libnl to create libnl objects of certain known
> types. For example libnl3-route can create 'struct rtnl_route' objects
> via:
>   rtnl_route_parse().
> Obviously, as libnl doesn't know about these attributes, none of its
> known types will make use of those attributes. I.e. there is no libnl
> object for your the objects from your kernel module.
>
>
>
> In your case, you would anyway parse your messages generically with:
>
>     int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
>                     int maxtype, struct nla_policy *policy);
>     int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
>                   struct nla_policy *policy);
>
> if you now try to pass a policy argument like:
>
> struct nla_policy my_type_policy[IFLA_MY_TYPE_MAX + 1] = {
>     [IFLA_MY_TYPE_DATA] = { .type = NLA_BINARY },
> };
>
> libnl will barf on the unknown type. But the @policy argument is only there to validate
> the message. You can pass %NULL and it will do no validation at all. Obviously, you must then
> somehow validate the message youself.
>
>
> You could still use nlmsg_parse() to fill the @tb argument without
> validation. Afterwards, you validate the message yourself by
> reimplementing validate_nla() to support the new message types:
>   https://github.com/thom311/libnl/blob/e206c255d8fff8b51938945c8f57575
> 0c418a95e/lib/attr.c#L188
>
>
>
> Not very satisfying. Patches very welcome!! ;-)
>
>
> Thomas



More information about the libnl mailing list