Mention branches and keyring.
[releases.git] / bpf / nlattr.h
1 /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
2
3 /*
4  * NETLINK      Netlink attributes
5  *
6  * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
7  */
8
9 #ifndef __LIBBPF_NLATTR_H
10 #define __LIBBPF_NLATTR_H
11
12 #include <stdint.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <linux/netlink.h>
16 #include <linux/rtnetlink.h>
17 #include <linux/genetlink.h>
18
19 /* avoid multiple definition of netlink features */
20 #define __LINUX_NETLINK_H
21
22 /**
23  * Standard attribute types to specify validation policy
24  */
25 enum {
26         LIBBPF_NLA_UNSPEC,      /**< Unspecified type, binary data chunk */
27         LIBBPF_NLA_U8,          /**< 8 bit integer */
28         LIBBPF_NLA_U16,         /**< 16 bit integer */
29         LIBBPF_NLA_U32,         /**< 32 bit integer */
30         LIBBPF_NLA_U64,         /**< 64 bit integer */
31         LIBBPF_NLA_STRING,      /**< NUL terminated character string */
32         LIBBPF_NLA_FLAG,        /**< Flag */
33         LIBBPF_NLA_MSECS,       /**< Micro seconds (64bit) */
34         LIBBPF_NLA_NESTED,      /**< Nested attributes */
35         __LIBBPF_NLA_TYPE_MAX,
36 };
37
38 #define LIBBPF_NLA_TYPE_MAX (__LIBBPF_NLA_TYPE_MAX - 1)
39
40 /**
41  * @ingroup attr
42  * Attribute validation policy.
43  *
44  * See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
45  */
46 struct libbpf_nla_policy {
47         /** Type of attribute or LIBBPF_NLA_UNSPEC */
48         uint16_t        type;
49
50         /** Minimal length of payload required */
51         uint16_t        minlen;
52
53         /** Maximal length of payload allowed */
54         uint16_t        maxlen;
55 };
56
57 struct libbpf_nla_req {
58         struct nlmsghdr nh;
59         union {
60                 struct ifinfomsg ifinfo;
61                 struct tcmsg tc;
62                 struct genlmsghdr gnl;
63         };
64         char buf[128];
65 };
66
67 /**
68  * @ingroup attr
69  * Iterate over a stream of attributes
70  * @arg pos     loop counter, set to current attribute
71  * @arg head    head of attribute stream
72  * @arg len     length of attribute stream
73  * @arg rem     initialized to len, holds bytes currently remaining in stream
74  */
75 #define libbpf_nla_for_each_attr(pos, head, len, rem) \
76         for (pos = head, rem = len; \
77              nla_ok(pos, rem); \
78              pos = nla_next(pos, &(rem)))
79
80 /**
81  * libbpf_nla_data - head of payload
82  * @nla: netlink attribute
83  */
84 static inline void *libbpf_nla_data(const struct nlattr *nla)
85 {
86         return (void *)nla + NLA_HDRLEN;
87 }
88
89 static inline uint8_t libbpf_nla_getattr_u8(const struct nlattr *nla)
90 {
91         return *(uint8_t *)libbpf_nla_data(nla);
92 }
93
94 static inline uint16_t libbpf_nla_getattr_u16(const struct nlattr *nla)
95 {
96         return *(uint16_t *)libbpf_nla_data(nla);
97 }
98
99 static inline uint32_t libbpf_nla_getattr_u32(const struct nlattr *nla)
100 {
101         return *(uint32_t *)libbpf_nla_data(nla);
102 }
103
104 static inline uint64_t libbpf_nla_getattr_u64(const struct nlattr *nla)
105 {
106         return *(uint64_t *)libbpf_nla_data(nla);
107 }
108
109 static inline const char *libbpf_nla_getattr_str(const struct nlattr *nla)
110 {
111         return (const char *)libbpf_nla_data(nla);
112 }
113
114 /**
115  * libbpf_nla_len - length of payload
116  * @nla: netlink attribute
117  */
118 static inline int libbpf_nla_len(const struct nlattr *nla)
119 {
120         return nla->nla_len - NLA_HDRLEN;
121 }
122
123 int libbpf_nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head,
124                      int len, struct libbpf_nla_policy *policy);
125 int libbpf_nla_parse_nested(struct nlattr *tb[], int maxtype,
126                             struct nlattr *nla,
127                             struct libbpf_nla_policy *policy);
128
129 int libbpf_nla_dump_errormsg(struct nlmsghdr *nlh);
130
131 static inline struct nlattr *nla_data(struct nlattr *nla)
132 {
133         return (struct nlattr *)((void *)nla + NLA_HDRLEN);
134 }
135
136 static inline struct nlattr *req_tail(struct libbpf_nla_req *req)
137 {
138         return (struct nlattr *)((void *)req + NLMSG_ALIGN(req->nh.nlmsg_len));
139 }
140
141 static inline int nlattr_add(struct libbpf_nla_req *req, int type,
142                              const void *data, int len)
143 {
144         struct nlattr *nla;
145
146         if (NLMSG_ALIGN(req->nh.nlmsg_len) + NLA_ALIGN(NLA_HDRLEN + len) > sizeof(*req))
147                 return -EMSGSIZE;
148         if (!!data != !!len)
149                 return -EINVAL;
150
151         nla = req_tail(req);
152         nla->nla_type = type;
153         nla->nla_len = NLA_HDRLEN + len;
154         if (data)
155                 memcpy(nla_data(nla), data, len);
156         req->nh.nlmsg_len = NLMSG_ALIGN(req->nh.nlmsg_len) + NLA_ALIGN(nla->nla_len);
157         return 0;
158 }
159
160 static inline struct nlattr *nlattr_begin_nested(struct libbpf_nla_req *req, int type)
161 {
162         struct nlattr *tail;
163
164         tail = req_tail(req);
165         if (nlattr_add(req, type | NLA_F_NESTED, NULL, 0))
166                 return NULL;
167         return tail;
168 }
169
170 static inline void nlattr_end_nested(struct libbpf_nla_req *req,
171                                      struct nlattr *tail)
172 {
173         tail->nla_len = (void *)req_tail(req) - (void *)tail;
174 }
175
176 #endif /* __LIBBPF_NLATTR_H */