From b18fcf8edd07d7832c16e96f29d44a2961c1e5aa Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 13 Jan 2011 12:36:06 -0800 Subject: [PATCH] netlink: New functions for finding a specific attribute. These functions are useful in the occasional case where a piece of code only cares about one or a few attributes, probably knows that the format is correct, and doesn't want to go to the trouble of doing a full parse. Upcoming commits will add a user. Reviewed by Justin Pettit. --- lib/netlink.c | 38 +++++++++++++++++++++++++++++++++++++- lib/netlink.h | 8 ++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/lib/netlink.c b/lib/netlink.c index f1234ad48..48a52ee34 100644 --- a/lib/netlink.c +++ b/lib/netlink.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -608,3 +608,39 @@ nl_parse_nested(const struct nlattr *nla, const struct nl_policy policy[], nl_attr_get_nested(nla, &buf); return nl_policy_parse(&buf, 0, policy, attrs, n_attrs); } + +static const struct nlattr * +nl_attr_find__(const struct nlattr *attrs, size_t size, uint16_t type) +{ + const struct nlattr *nla; + size_t left; + + NL_ATTR_FOR_EACH (nla, left, attrs, size) { + if (nl_attr_type (nla) == type) { + return nla; + } + } + return NULL; +} + +/* Returns the first Netlink attribute within 'buf' with the specified 'type', + * skipping a header of 'hdr_len' bytes at the beginning of 'buf'. + * + * This function does not validate the attribute's length. */ +const struct nlattr * +nl_attr_find(const struct ofpbuf *buf, size_t hdr_len, uint16_t type) +{ + const uint8_t *start = (const uint8_t *) buf->data + hdr_len; + return nl_attr_find__((const struct nlattr *) start, buf->size - hdr_len, + type); +} + +/* Returns the first Netlink attribute within 'nla' with the specified + * 'type'. + * + * This function does not validate the attribute's length. */ +const struct nlattr * +nl_attr_find_nested(const struct nlattr *nla, uint16_t type) +{ + return nl_attr_find__(nl_attr_get(nla), nl_attr_get_size(nla), type); +} diff --git a/lib/netlink.h b/lib/netlink.h index 383681c33..5aa06a3ff 100644 --- a/lib/netlink.h +++ b/lib/netlink.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,7 +115,7 @@ nl_attr_is_valid(const struct nlattr *nla, size_t maxlen) /* This macro does not check for attributes with bad lengths. It should only * be used with messages from trusted sources or with messages that have - * already been validates (e.g. with NL_ATTR_FOR_EACH). */ + * already been validated (e.g. with NL_ATTR_FOR_EACH). */ #define NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, ATTRS, ATTRS_LEN) \ for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ (LEFT) > 0; \ @@ -154,4 +154,8 @@ bool nl_policy_parse(const struct ofpbuf *, size_t offset, bool nl_parse_nested(const struct nlattr *, const struct nl_policy[], struct nlattr *[], size_t n_attrs); +const struct nlattr *nl_attr_find(const struct ofpbuf *, size_t hdr_len, + uint16_t type); +const struct nlattr *nl_attr_find_nested(const struct nlattr *, uint16_t type); + #endif /* netlink.h */ -- 2.43.0