X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetlink.h;h=f9234da1b9daf28616c0657371932679d65504de;hb=HEAD;hp=5aa06a3ffa2a7dfafeeeab817e75b4f70426b8d5;hpb=b18fcf8edd07d7832c16e96f29d44a2961c1e5aa;p=sliver-openvswitch.git diff --git a/lib/netlink.h b/lib/netlink.h index 5aa06a3ff..f9234da1b 100644 --- a/lib/netlink.h +++ b/lib/netlink.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. + * Copyright (c) 2008, 2009, 2010, 2011, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,7 @@ struct genlmsghdr *nl_msg_genlmsghdr(const struct ofpbuf *); bool nl_msg_nlmsgerr(const struct ofpbuf *, int *error); void nl_msg_reserve(struct ofpbuf *, size_t); -/* Appending headers and raw data. */ +/* Appending and prepending headers and raw data. */ void nl_msg_put_nlmsghdr(struct ofpbuf *, size_t expected_payload, uint32_t type, uint32_t flags); void nl_msg_put_genlmsghdr(struct ofpbuf *, size_t expected_payload, @@ -54,9 +54,12 @@ void nl_msg_put_genlmsghdr(struct ofpbuf *, size_t expected_payload, uint8_t cmd, uint8_t version); void nl_msg_put(struct ofpbuf *, const void *, size_t); void *nl_msg_put_uninit(struct ofpbuf *, size_t); +void nl_msg_push(struct ofpbuf *, const void *, size_t); +void *nl_msg_push_uninit(struct ofpbuf *, size_t); /* Appending attributes. */ void *nl_msg_put_unspec_uninit(struct ofpbuf *, uint16_t type, size_t); +void *nl_msg_put_unspec_zero(struct ofpbuf *, uint16_t type, size_t); void nl_msg_put_unspec(struct ofpbuf *, uint16_t type, const void *, size_t); void nl_msg_put_flag(struct ofpbuf *, uint16_t type); void nl_msg_put_u8(struct ofpbuf *, uint16_t type, uint8_t value); @@ -66,6 +69,7 @@ void nl_msg_put_u64(struct ofpbuf *, uint16_t type, uint64_t value); void nl_msg_put_be16(struct ofpbuf *, uint16_t type, ovs_be16 value); void nl_msg_put_be32(struct ofpbuf *, uint16_t type, ovs_be32 value); void nl_msg_put_be64(struct ofpbuf *, uint16_t type, ovs_be64 value); +void nl_msg_put_odp_port(struct ofpbuf *, uint16_t type, odp_port_t value); void nl_msg_put_string(struct ofpbuf *, uint16_t type, const char *value); size_t nl_msg_start_nested(struct ofpbuf *, uint16_t type); @@ -73,8 +77,35 @@ void nl_msg_end_nested(struct ofpbuf *, size_t offset); void nl_msg_put_nested(struct ofpbuf *, uint16_t type, const void *data, size_t size); +/* Prepending attributes. */ +void *nl_msg_push_unspec_uninit(struct ofpbuf *, uint16_t type, size_t); +void nl_msg_push_unspec(struct ofpbuf *, uint16_t type, const void *, size_t); +void nl_msg_push_flag(struct ofpbuf *, uint16_t type); +void nl_msg_push_u8(struct ofpbuf *, uint16_t type, uint8_t value); +void nl_msg_push_u16(struct ofpbuf *, uint16_t type, uint16_t value); +void nl_msg_push_u32(struct ofpbuf *, uint16_t type, uint32_t value); +void nl_msg_push_u64(struct ofpbuf *, uint16_t type, uint64_t value); +void nl_msg_push_be16(struct ofpbuf *, uint16_t type, ovs_be16 value); +void nl_msg_push_be32(struct ofpbuf *, uint16_t type, ovs_be32 value); +void nl_msg_push_be64(struct ofpbuf *, uint16_t type, ovs_be64 value); +void nl_msg_push_string(struct ofpbuf *, uint16_t type, const char *value); + /* Separating buffers into individual messages. */ struct nlmsghdr *nl_msg_next(struct ofpbuf *buffer, struct ofpbuf *msg); + +/* Sizes of various attribute types, in bytes, including the attribute header + * and padding. */ +#define NL_ATTR_SIZE(PAYLOAD_SIZE) (NLA_HDRLEN + NLA_ALIGN(PAYLOAD_SIZE)) +#define NL_A_U8_SIZE NL_ATTR_SIZE(sizeof(uint8_t)) +#define NL_A_U16_SIZE NL_ATTR_SIZE(sizeof(uint16_t)) +#define NL_A_U32_SIZE NL_ATTR_SIZE(sizeof(uint32_t)) +#define NL_A_U64_SIZE NL_ATTR_SIZE(sizeof(uint64_t)) +#define NL_A_BE16_SIZE NL_ATTR_SIZE(sizeof(ovs_be16)) +#define NL_A_BE32_SIZE NL_ATTR_SIZE(sizeof(ovs_be32)) +#define NL_A_BE64_SIZE NL_ATTR_SIZE(sizeof(ovs_be64)) +#define NL_A_FLAG_SIZE NL_ATTR_SIZE(0) + +bool nl_attr_oversized(size_t payload_size); /* Netlink attribute types. */ enum nl_attr_type @@ -83,8 +114,11 @@ enum nl_attr_type NL_A_UNSPEC, NL_A_U8, NL_A_U16, + NL_A_BE16 = NL_A_U16, NL_A_U32, + NL_A_BE32 = NL_A_U32, NL_A_U64, + NL_A_BE64 = NL_A_U64, NL_A_STRING, NL_A_FLAG, NL_A_NESTED, @@ -95,7 +129,7 @@ enum nl_attr_type static inline struct nlattr * nl_attr_next(const struct nlattr *nla) { - return (struct nlattr *) ((uint8_t *) nla + NLA_ALIGN(nla->nla_len)); + return (void *) ((uint8_t *) nla + NLA_ALIGN(nla->nla_len)); } static inline bool @@ -103,14 +137,22 @@ nl_attr_is_valid(const struct nlattr *nla, size_t maxlen) { return (maxlen >= sizeof *nla && nla->nla_len >= sizeof *nla - && NLA_ALIGN(nla->nla_len) <= maxlen); + && nla->nla_len <= maxlen); +} + +static inline size_t +nl_attr_len_pad(const struct nlattr *nla, size_t maxlen) +{ + size_t len = NLA_ALIGN(nla->nla_len); + + return len <= maxlen ? len : nla->nla_len; } /* This macro is careful to check for attributes with bad lengths. */ #define NL_ATTR_FOR_EACH(ITER, LEFT, ATTRS, ATTRS_LEN) \ for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ nl_attr_is_valid(ITER, LEFT); \ - (LEFT) -= NLA_ALIGN((ITER)->nla_len), (ITER) = nl_attr_next(ITER)) + (LEFT) -= nl_attr_len_pad(ITER, LEFT), (ITER) = nl_attr_next(ITER)) /* This macro does not check for attributes with bad lengths. It should only @@ -119,7 +161,13 @@ nl_attr_is_valid(const struct nlattr *nla, size_t maxlen) #define NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, ATTRS, ATTRS_LEN) \ for ((ITER) = (ATTRS), (LEFT) = (ATTRS_LEN); \ (LEFT) > 0; \ - (LEFT) -= NLA_ALIGN((ITER)->nla_len), (ITER) = nl_attr_next(ITER)) + (LEFT) -= nl_attr_len_pad(ITER, LEFT), (ITER) = nl_attr_next(ITER)) + +/* These variants are convenient for iterating nested attributes. */ +#define NL_NESTED_FOR_EACH(ITER, LEFT, A) \ + NL_ATTR_FOR_EACH(ITER, LEFT, nl_attr_get(A), nl_attr_get_size(A)) +#define NL_NESTED_FOR_EACH_UNSAFE(ITER, LEFT, A) \ + NL_ATTR_FOR_EACH_UNSAFE(ITER, LEFT, nl_attr_get(A), nl_attr_get_size(A)) /* Netlink attribute parsing. */ int nl_attr_type(const struct nlattr *); @@ -134,6 +182,7 @@ uint64_t nl_attr_get_u64(const struct nlattr *); ovs_be16 nl_attr_get_be16(const struct nlattr *); ovs_be32 nl_attr_get_be32(const struct nlattr *); ovs_be64 nl_attr_get_be64(const struct nlattr *); +odp_port_t nl_attr_get_odp_port(const struct nlattr *); const char *nl_attr_get_string(const struct nlattr *); void nl_attr_get_nested(const struct nlattr *, struct ofpbuf *); @@ -148,6 +197,11 @@ struct nl_policy bool optional; }; +#define NL_POLICY_FOR(TYPE) \ + .type = NL_A_UNSPEC, .min_len = sizeof(TYPE), .max_len = sizeof(TYPE) + +bool nl_attr_validate(const struct nlattr *, const struct nl_policy *); + bool nl_policy_parse(const struct ofpbuf *, size_t offset, const struct nl_policy[], struct nlattr *[], size_t n_attrs); @@ -157,5 +211,7 @@ bool nl_parse_nested(const struct nlattr *, const struct nl_policy[], 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); +const struct nlattr *nl_attr_find__(const struct nlattr *attrs, size_t size, + uint16_t type); #endif /* netlink.h */