]>
Commit | Line | Data |
---|---|---|
6054c1eb | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
aba5acdf SH |
2 | #ifndef __LIBNETLINK_H__ |
3 | #define __LIBNETLINK_H__ 1 | |
4 | ||
5bd9dd49 | 5 | #include <stdio.h> |
f5b830dc | 6 | #include <string.h> |
aba5acdf SH |
7 | #include <asm/types.h> |
8 | #include <linux/netlink.h> | |
9 | #include <linux/rtnetlink.h> | |
ead2ba70 SH |
10 | #include <linux/if_link.h> |
11 | #include <linux/if_addr.h> | |
12 | #include <linux/neighbour.h> | |
9d0efc10 | 13 | #include <linux/netconf.h> |
aab0f610 | 14 | #include <arpa/inet.h> |
aba5acdf | 15 | |
e9e9365b | 16 | struct rtnl_handle { |
aba5acdf SH |
17 | int fd; |
18 | struct sockaddr_nl local; | |
19 | struct sockaddr_nl peer; | |
20 | __u32 seq; | |
21 | __u32 dump; | |
8a4025f6 | 22 | int proto; |
486ccd99 | 23 | FILE *dump_fp; |
449b824a | 24 | #define RTNL_HANDLE_F_LISTEN_ALL_NSID 0x01 |
3ad6d176 | 25 | #define RTNL_HANDLE_F_SUPPRESS_NLERR 0x02 |
285033bf | 26 | #define RTNL_HANDLE_F_STRICT_CHK 0x04 |
449b824a | 27 | int flags; |
aba5acdf SH |
28 | }; |
29 | ||
4ad87594 DA |
30 | struct nlmsg_list { |
31 | struct nlmsg_list *next; | |
32 | struct nlmsghdr h; | |
33 | }; | |
34 | ||
35 | struct nlmsg_chain { | |
36 | struct nlmsg_list *head; | |
37 | struct nlmsg_list *tail; | |
38 | }; | |
39 | ||
7f03191f PM |
40 | extern int rcvbuf; |
41 | ||
e9e9365b | 42 | int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions) |
d2468da0 SH |
43 | __attribute__((warn_unused_result)); |
44 | ||
e9e9365b | 45 | int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions, |
d2468da0 SH |
46 | int protocol) |
47 | __attribute__((warn_unused_result)); | |
9860becf DA |
48 | int rtnl_add_nl_group(struct rtnl_handle *rth, unsigned int group) |
49 | __attribute__((warn_unused_result)); | |
892e2124 | 50 | void rtnl_close(struct rtnl_handle *rth); |
aea41afc | 51 | void rtnl_set_strict_dump(struct rtnl_handle *rth); |
46917d08 | 52 | |
43fd93ae DA |
53 | typedef int (*req_filter_fn_t)(struct nlmsghdr *nlh, int reqlen); |
54 | ||
88470978 DA |
55 | int rtnl_addrdump_req(struct rtnl_handle *rth, int family, |
56 | req_filter_fn_t filter_fn) | |
46917d08 | 57 | __attribute__((warn_unused_result)); |
39360023 DA |
58 | int rtnl_addrlbldump_req(struct rtnl_handle *rth, int family) |
59 | __attribute__((warn_unused_result)); | |
43fd93ae DA |
60 | int rtnl_routedump_req(struct rtnl_handle *rth, int family, |
61 | req_filter_fn_t filter_fn) | |
bfb27dfa | 62 | __attribute__((warn_unused_result)); |
b05d9a3d DA |
63 | int rtnl_ruledump_req(struct rtnl_handle *rth, int family) |
64 | __attribute__((warn_unused_result)); | |
f255ab12 DA |
65 | int rtnl_neighdump_req(struct rtnl_handle *rth, int family, |
66 | req_filter_fn_t filter_fn) | |
9e0ab19c | 67 | __attribute__((warn_unused_result)); |
ff41db8a DA |
68 | int rtnl_neightbldump_req(struct rtnl_handle *rth, int family) |
69 | __attribute__((warn_unused_result)); | |
9dbe6df4 DA |
70 | int rtnl_mdbdump_req(struct rtnl_handle *rth, int family) |
71 | __attribute__((warn_unused_result)); | |
ddee16bc DA |
72 | int rtnl_netconfdump_req(struct rtnl_handle *rth, int family) |
73 | __attribute__((warn_unused_result)); | |
46917d08 | 74 | |
31ae2912 | 75 | int rtnl_linkdump_req(struct rtnl_handle *rth, int fam) |
d2468da0 | 76 | __attribute__((warn_unused_result)); |
31ae2912 | 77 | int rtnl_linkdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask) |
d2468da0 | 78 | __attribute__((warn_unused_result)); |
b0a4ce62 | 79 | |
31ae2912 | 80 | int rtnl_linkdump_req_filter_fn(struct rtnl_handle *rth, int fam, |
b0a4ce62 DA |
81 | req_filter_fn_t fn) |
82 | __attribute__((warn_unused_result)); | |
264be1d8 IS |
83 | int rtnl_fdb_linkdump_req_filter_fn(struct rtnl_handle *rth, |
84 | req_filter_fn_t filter_fn) | |
85 | __attribute__((warn_unused_result)); | |
eaefb078 ND |
86 | int rtnl_nsiddump_req_filter_fn(struct rtnl_handle *rth, int family, |
87 | req_filter_fn_t filter_fn) | |
88 | __attribute__((warn_unused_result)); | |
56eeeda9 | 89 | int rtnl_statsdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask) |
7abf5de6 | 90 | __attribute__((warn_unused_result)); |
892e2124 | 91 | int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, |
d2468da0 SH |
92 | int len) |
93 | __attribute__((warn_unused_result)); | |
0d238ca2 DA |
94 | int rtnl_dump_request_n(struct rtnl_handle *rth, struct nlmsghdr *n) |
95 | __attribute__((warn_unused_result)); | |
6dc9f016 | 96 | |
74829ca7 DA |
97 | int rtnl_nexthopdump_req(struct rtnl_handle *rth, int family, |
98 | req_filter_fn_t filter_fn) | |
99 | __attribute__((warn_unused_result)); | |
100 | ||
0628cddd | 101 | struct rtnl_ctrl_data { |
449b824a | 102 | int nsid; |
0628cddd ND |
103 | }; |
104 | ||
cd554f2c | 105 | typedef int (*rtnl_filter_t)(struct nlmsghdr *n, void *); |
b49240ec | 106 | |
cd554f2c | 107 | typedef int (*rtnl_listen_filter_t)(struct rtnl_ctrl_data *, |
0628cddd ND |
108 | struct nlmsghdr *n, void *); |
109 | ||
b6432e68 SH |
110 | typedef int (*nl_ext_ack_fn_t)(const char *errmsg, uint32_t off, |
111 | const struct nlmsghdr *inner_nlh); | |
112 | ||
e9e9365b | 113 | struct rtnl_dump_filter_arg { |
b49240ec SH |
114 | rtnl_filter_t filter; |
115 | void *arg1; | |
8e72880f | 116 | __u16 nc_flags; |
b49240ec SH |
117 | }; |
118 | ||
8e72880f PS |
119 | int rtnl_dump_filter_nc(struct rtnl_handle *rth, |
120 | rtnl_filter_t filter, | |
121 | void *arg, __u16 nc_flags); | |
122 | #define rtnl_dump_filter(rth, filter, arg) \ | |
123 | rtnl_dump_filter_nc(rth, filter, arg, 0) | |
892e2124 | 124 | int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, |
86bf43c7 | 125 | struct nlmsghdr **answer) |
d2468da0 | 126 | __attribute__((warn_unused_result)); |
72a2ff39 CM |
127 | int rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iovec, size_t iovlen, |
128 | struct nlmsghdr **answer) | |
129 | __attribute__((warn_unused_result)); | |
463d9efa | 130 | int rtnl_talk_suppress_rtnl_errmsg(struct rtnl_handle *rtnl, struct nlmsghdr *n, |
86bf43c7 | 131 | struct nlmsghdr **answer) |
463d9efa | 132 | __attribute__((warn_unused_result)); |
892e2124 | 133 | int rtnl_send(struct rtnl_handle *rth, const void *buf, int) |
d2468da0 | 134 | __attribute__((warn_unused_result)); |
892e2124 | 135 | int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int) |
d2468da0 | 136 | __attribute__((warn_unused_result)); |
049c5853 | 137 | int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn); |
c934da8a | 138 | int nl_dump_ext_ack_done(const struct nlmsghdr *nlh, int error); |
aba5acdf | 139 | |
892e2124 SH |
140 | int addattr(struct nlmsghdr *n, int maxlen, int type); |
141 | int addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data); | |
142 | int addattr16(struct nlmsghdr *n, int maxlen, int type, __u16 data); | |
143 | int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data); | |
144 | int addattr64(struct nlmsghdr *n, int maxlen, int type, __u64 data); | |
145 | int addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *data); | |
146 | ||
147 | int addattr_l(struct nlmsghdr *n, int maxlen, int type, | |
148 | const void *data, int alen); | |
149 | int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len); | |
150 | struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type); | |
151 | int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest); | |
152 | struct rtattr *addattr_nest_compat(struct nlmsghdr *n, int maxlen, int type, | |
153 | const void *data, int len); | |
154 | int addattr_nest_compat_end(struct nlmsghdr *n, struct rtattr *nest); | |
303cc9cb RP |
155 | int rta_addattr8(struct rtattr *rta, int maxlen, int type, __u8 data); |
156 | int rta_addattr16(struct rtattr *rta, int maxlen, int type, __u16 data); | |
892e2124 | 157 | int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data); |
303cc9cb | 158 | int rta_addattr64(struct rtattr *rta, int maxlen, int type, __u64 data); |
892e2124 SH |
159 | int rta_addattr_l(struct rtattr *rta, int maxlen, int type, |
160 | const void *data, int alen); | |
161 | ||
162 | int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len); | |
163 | int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, | |
b1b7ce0f | 164 | int len, unsigned short flags); |
892e2124 SH |
165 | struct rtattr *parse_rtattr_one(int type, struct rtattr *rta, int len); |
166 | int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, int len); | |
aba5acdf | 167 | |
303cc9cb RP |
168 | struct rtattr *rta_nest(struct rtattr *rta, int maxlen, int type); |
169 | int rta_nest_end(struct rtattr *rta, struct rtattr *nest); | |
170 | ||
171 | #define RTA_TAIL(rta) \ | |
172 | ((struct rtattr *) (((void *) (rta)) + \ | |
173 | RTA_ALIGN((rta)->rta_len))) | |
174 | ||
753fca4f | 175 | #define parse_rtattr_nested(tb, max, rta) \ |
0da4cfaa PM |
176 | (parse_rtattr_flags((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta), \ |
177 | NLA_F_NESTED)) | |
753fca4f | 178 | |
decbb437 JP |
179 | #define parse_rtattr_one_nested(type, rta) \ |
180 | (parse_rtattr_one(type, RTA_DATA(rta), RTA_PAYLOAD(rta))) | |
181 | ||
2f90c9c0 | 182 | #define parse_rtattr_nested_compat(tb, max, rta, data, len) \ |
cd70f3f5 SH |
183 | ({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \ |
184 | __parse_rtattr_nested_compat(tb, max, rta, len); }) | |
2f90c9c0 | 185 | |
7dd03712 SH |
186 | static inline __u8 rta_getattr_u8(const struct rtattr *rta) |
187 | { | |
188 | return *(__u8 *)RTA_DATA(rta); | |
189 | } | |
46c5d64d SH |
190 | static inline __u16 rta_getattr_u16(const struct rtattr *rta) |
191 | { | |
192 | return *(__u16 *)RTA_DATA(rta); | |
193 | } | |
aab0f610 AV |
194 | static inline __be16 rta_getattr_be16(const struct rtattr *rta) |
195 | { | |
196 | return ntohs(rta_getattr_u16(rta)); | |
197 | } | |
7dd03712 | 198 | static inline __u32 rta_getattr_u32(const struct rtattr *rta) |
46c5d64d SH |
199 | { |
200 | return *(__u32 *)RTA_DATA(rta); | |
201 | } | |
aab0f610 AV |
202 | static inline __be32 rta_getattr_be32(const struct rtattr *rta) |
203 | { | |
204 | return ntohl(rta_getattr_u32(rta)); | |
205 | } | |
46c5d64d SH |
206 | static inline __u64 rta_getattr_u64(const struct rtattr *rta) |
207 | { | |
208 | __u64 tmp; | |
e9e9365b | 209 | |
46c5d64d SH |
210 | memcpy(&tmp, RTA_DATA(rta), sizeof(__u64)); |
211 | return tmp; | |
212 | } | |
d791f3ad JSP |
213 | static inline __s32 rta_getattr_s32(const struct rtattr *rta) |
214 | { | |
215 | return *(__s32 *)RTA_DATA(rta); | |
216 | } | |
de63cd90 VCG |
217 | static inline __s64 rta_getattr_s64(const struct rtattr *rta) |
218 | { | |
219 | __s64 tmp; | |
220 | ||
221 | memcpy(&tmp, RTA_DATA(rta), sizeof(tmp)); | |
222 | return tmp; | |
223 | } | |
46c5d64d SH |
224 | static inline const char *rta_getattr_str(const struct rtattr *rta) |
225 | { | |
cfd2cbd1 | 226 | return (const char *)RTA_DATA(rta); |
46c5d64d SH |
227 | } |
228 | ||
892e2124 SH |
229 | int rtnl_listen_all_nsid(struct rtnl_handle *); |
230 | int rtnl_listen(struct rtnl_handle *, rtnl_listen_filter_t handler, | |
231 | void *jarg); | |
232 | int rtnl_from_file(FILE *, rtnl_listen_filter_t handler, | |
233 | void *jarg); | |
aba5acdf | 234 | |
370d67ba | 235 | #define NLMSG_TAIL(nmsg) \ |
236 | ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) | |
237 | ||
ead2ba70 SH |
238 | #ifndef IFA_RTA |
239 | #define IFA_RTA(r) \ | |
e9e9365b | 240 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) |
ead2ba70 SH |
241 | #endif |
242 | #ifndef IFA_PAYLOAD | |
e9e9365b | 243 | #define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg)) |
ead2ba70 SH |
244 | #endif |
245 | ||
246 | #ifndef IFLA_RTA | |
247 | #define IFLA_RTA(r) \ | |
e9e9365b | 248 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) |
ead2ba70 SH |
249 | #endif |
250 | #ifndef IFLA_PAYLOAD | |
e9e9365b | 251 | #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg)) |
ead2ba70 SH |
252 | #endif |
253 | ||
254 | #ifndef NDA_RTA | |
255 | #define NDA_RTA(r) \ | |
e9e9365b | 256 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) |
ead2ba70 SH |
257 | #endif |
258 | #ifndef NDA_PAYLOAD | |
e9e9365b | 259 | #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ndmsg)) |
ead2ba70 SH |
260 | #endif |
261 | ||
262 | #ifndef NDTA_RTA | |
263 | #define NDTA_RTA(r) \ | |
e9e9365b | 264 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndtmsg)))) |
ead2ba70 SH |
265 | #endif |
266 | #ifndef NDTA_PAYLOAD | |
e9e9365b | 267 | #define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ndtmsg)) |
ead2ba70 SH |
268 | #endif |
269 | ||
d182ee13 ND |
270 | #ifndef NETNS_RTA |
271 | #define NETNS_RTA(r) \ | |
e9e9365b | 272 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct rtgenmsg)))) |
d182ee13 ND |
273 | #endif |
274 | #ifndef NETNS_PAYLOAD | |
e9e9365b | 275 | #define NETNS_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct rtgenmsg)) |
d182ee13 ND |
276 | #endif |
277 | ||
7abf5de6 NA |
278 | #ifndef IFLA_STATS_RTA |
279 | #define IFLA_STATS_RTA(r) \ | |
280 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct if_stats_msg)))) | |
281 | #endif | |
282 | ||
27b14f2e VK |
283 | /* User defined nlmsg_type which is used mostly for logging netlink |
284 | * messages from dump file */ | |
285 | #define NLMSG_TSTAMP 15 | |
286 | ||
784fa9f6 JB |
287 | #define rtattr_for_each_nested(attr, nest) \ |
288 | for ((attr) = (void *)RTA_DATA(nest); \ | |
289 | RTA_OK(attr, RTA_PAYLOAD(nest) - ((char *)(attr) - (char *)RTA_DATA((nest)))); \ | |
290 | (attr) = RTA_TAIL((attr))) | |
291 | ||
aba5acdf | 292 | #endif /* __LIBNETLINK_H__ */ |