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