1
2#ifndef __LIBNETLINK_H__
3#define __LIBNETLINK_H__ 1
4
5#include <stdio.h>
6#include <string.h>
7#include <asm/types.h>
8#include <linux/netlink.h>
9#include <linux/rtnetlink.h>
10#include <linux/if_link.h>
11#include <linux/if_addr.h>
12#include <linux/neighbour.h>
13#include <linux/netconf.h>
14#include <arpa/inet.h>
15
16struct rtnl_handle {
17 int fd;
18 struct sockaddr_nl local;
19 struct sockaddr_nl peer;
20 __u32 seq;
21 __u32 dump;
22 int proto;
23 FILE *dump_fp;
24#define RTNL_HANDLE_F_LISTEN_ALL_NSID 0x01
25#define RTNL_HANDLE_F_SUPPRESS_NLERR 0x02
26#define RTNL_HANDLE_F_STRICT_CHK 0x04
27 int flags;
28};
29
30struct nlmsg_list {
31 struct nlmsg_list *next;
32 struct nlmsghdr h;
33};
34
35struct nlmsg_chain {
36 struct nlmsg_list *head;
37 struct nlmsg_list *tail;
38};
39
40extern int rcvbuf;
41
42int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions)
43 __attribute__((warn_unused_result));
44
45int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions,
46 int protocol)
47 __attribute__((warn_unused_result));
48int rtnl_add_nl_group(struct rtnl_handle *rth, unsigned int group)
49 __attribute__((warn_unused_result));
50void rtnl_close(struct rtnl_handle *rth);
51void rtnl_set_strict_dump(struct rtnl_handle *rth);
52
53typedef int (*req_filter_fn_t)(struct nlmsghdr *nlh, int reqlen);
54
55int rtnl_addrdump_req(struct rtnl_handle *rth, int family,
56 req_filter_fn_t filter_fn)
57 __attribute__((warn_unused_result));
58int rtnl_addrlbldump_req(struct rtnl_handle *rth, int family)
59 __attribute__((warn_unused_result));
60int rtnl_routedump_req(struct rtnl_handle *rth, int family,
61 req_filter_fn_t filter_fn)
62 __attribute__((warn_unused_result));
63int rtnl_ruledump_req(struct rtnl_handle *rth, int family)
64 __attribute__((warn_unused_result));
65int rtnl_neighdump_req(struct rtnl_handle *rth, int family,
66 req_filter_fn_t filter_fn)
67 __attribute__((warn_unused_result));
68int rtnl_neightbldump_req(struct rtnl_handle *rth, int family)
69 __attribute__((warn_unused_result));
70int rtnl_mdbdump_req(struct rtnl_handle *rth, int family)
71 __attribute__((warn_unused_result));
72int rtnl_brvlandump_req(struct rtnl_handle *rth, int family, __u32 dump_flags)
73 __attribute__((warn_unused_result));
74int rtnl_netconfdump_req(struct rtnl_handle *rth, int family)
75 __attribute__((warn_unused_result));
76
77int rtnl_linkdump_req(struct rtnl_handle *rth, int fam)
78 __attribute__((warn_unused_result));
79int rtnl_linkdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask)
80 __attribute__((warn_unused_result));
81
82int rtnl_linkdump_req_filter_fn(struct rtnl_handle *rth, int fam,
83 req_filter_fn_t fn)
84 __attribute__((warn_unused_result));
85int rtnl_fdb_linkdump_req_filter_fn(struct rtnl_handle *rth,
86 req_filter_fn_t filter_fn)
87 __attribute__((warn_unused_result));
88int rtnl_nsiddump_req_filter_fn(struct rtnl_handle *rth, int family,
89 req_filter_fn_t filter_fn)
90 __attribute__((warn_unused_result));
91int rtnl_statsdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask)
92 __attribute__((warn_unused_result));
93int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req,
94 int len)
95 __attribute__((warn_unused_result));
96int rtnl_dump_request_n(struct rtnl_handle *rth, struct nlmsghdr *n)
97 __attribute__((warn_unused_result));
98
99int rtnl_nexthopdump_req(struct rtnl_handle *rth, int family,
100 req_filter_fn_t filter_fn)
101 __attribute__((warn_unused_result));
102int rtnl_nexthop_bucket_dump_req(struct rtnl_handle *rth, int family,
103 req_filter_fn_t filter_fn)
104 __attribute__((warn_unused_result));
105
106struct rtnl_ctrl_data {
107 int nsid;
108};
109
110typedef int (*rtnl_filter_t)(struct nlmsghdr *n, void *);
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127#define RTNL_LET_NLERR 0x01
128#define RTNL_SUPPRESS_NLMSG_DONE_NLERR 0x02
129#define RTNL_SUPPRESS_NLMSG_ERROR_NLERR 0x04
130#define RTNL_SUPPRESS_NLERR 0x06
131typedef int (*rtnl_err_hndlr_t)(struct nlmsghdr *n, void *);
132
133typedef int (*rtnl_listen_filter_t)(struct rtnl_ctrl_data *,
134 struct nlmsghdr *n, void *);
135
136typedef int (*nl_ext_ack_fn_t)(const char *errmsg, uint32_t off,
137 const struct nlmsghdr *inner_nlh);
138
139struct rtnl_dump_filter_arg {
140 rtnl_filter_t filter;
141 void *arg1;
142 rtnl_err_hndlr_t errhndlr;
143 void *arg2;
144 __u16 nc_flags;
145};
146
147int rtnl_dump_filter_nc(struct rtnl_handle *rth,
148 rtnl_filter_t filter,
149 void *arg, __u16 nc_flags);
150#define rtnl_dump_filter(rth, filter, arg) \
151 rtnl_dump_filter_nc(rth, filter, arg, 0)
152int rtnl_dump_filter_errhndlr_nc(struct rtnl_handle *rth,
153 rtnl_filter_t filter,
154 void *arg1,
155 rtnl_err_hndlr_t errhndlr,
156 void *arg2,
157 __u16 nc_flags);
158#define rtnl_dump_filter_errhndlr(rth, filter, farg, errhndlr, earg) \
159 rtnl_dump_filter_errhndlr_nc(rth, filter, farg, errhndlr, earg, 0)
160
161int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
162 struct nlmsghdr **answer)
163 __attribute__((warn_unused_result));
164int rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iovec, size_t iovlen,
165 struct nlmsghdr **answer)
166 __attribute__((warn_unused_result));
167int rtnl_talk_suppress_rtnl_errmsg(struct rtnl_handle *rtnl, struct nlmsghdr *n,
168 struct nlmsghdr **answer)
169 __attribute__((warn_unused_result));
170int rtnl_send(struct rtnl_handle *rth, const void *buf, int)
171 __attribute__((warn_unused_result));
172int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int)
173 __attribute__((warn_unused_result));
174int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn);
175int nl_dump_ext_ack_done(const struct nlmsghdr *nlh, int error);
176
177int addattr(struct nlmsghdr *n, int maxlen, int type);
178int addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data);
179int addattr16(struct nlmsghdr *n, int maxlen, int type, __u16 data);
180int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data);
181int addattr64(struct nlmsghdr *n, int maxlen, int type, __u64 data);
182int addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *data);
183
184int addattr_l(struct nlmsghdr *n, int maxlen, int type,
185 const void *data, int alen);
186int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len);
187struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type);
188int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest);
189struct rtattr *addattr_nest_compat(struct nlmsghdr *n, int maxlen, int type,
190 const void *data, int len);
191int addattr_nest_compat_end(struct nlmsghdr *n, struct rtattr *nest);
192int rta_addattr8(struct rtattr *rta, int maxlen, int type, __u8 data);
193int rta_addattr16(struct rtattr *rta, int maxlen, int type, __u16 data);
194int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data);
195int rta_addattr64(struct rtattr *rta, int maxlen, int type, __u64 data);
196int rta_addattr_l(struct rtattr *rta, int maxlen, int type,
197 const void *data, int alen);
198
199int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
200int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta,
201 int len, unsigned short flags);
202struct rtattr *parse_rtattr_one(int type, struct rtattr *rta, int len);
203int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, int len);
204
205struct rtattr *rta_nest(struct rtattr *rta, int maxlen, int type);
206int rta_nest_end(struct rtattr *rta, struct rtattr *nest);
207
208#define RTA_TAIL(rta) \
209 ((struct rtattr *) (((void *) (rta)) + \
210 RTA_ALIGN((rta)->rta_len)))
211
212#define parse_rtattr_nested(tb, max, rta) \
213 (parse_rtattr_flags((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta), \
214 NLA_F_NESTED))
215
216#define parse_rtattr_one_nested(type, rta) \
217 (parse_rtattr_one(type, RTA_DATA(rta), RTA_PAYLOAD(rta)))
218
219#define parse_rtattr_nested_compat(tb, max, rta, data, len) \
220 ({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
221 __parse_rtattr_nested_compat(tb, max, rta, len); })
222
223static inline __u8 rta_getattr_u8(const struct rtattr *rta)
224{
225 return *(__u8 *)RTA_DATA(rta);
226}
227static inline __u16 rta_getattr_u16(const struct rtattr *rta)
228{
229 return *(__u16 *)RTA_DATA(rta);
230}
231static inline __be16 rta_getattr_be16(const struct rtattr *rta)
232{
233 return ntohs(rta_getattr_u16(rta));
234}
235static inline __u32 rta_getattr_u32(const struct rtattr *rta)
236{
237 return *(__u32 *)RTA_DATA(rta);
238}
239static inline __be32 rta_getattr_be32(const struct rtattr *rta)
240{
241 return ntohl(rta_getattr_u32(rta));
242}
243static inline __u64 rta_getattr_u64(const struct rtattr *rta)
244{
245 __u64 tmp;
246
247 memcpy(&tmp, RTA_DATA(rta), sizeof(__u64));
248 return tmp;
249}
250static inline __s32 rta_getattr_s32(const struct rtattr *rta)
251{
252 return *(__s32 *)RTA_DATA(rta);
253}
254static inline __s64 rta_getattr_s64(const struct rtattr *rta)
255{
256 __s64 tmp;
257
258 memcpy(&tmp, RTA_DATA(rta), sizeof(tmp));
259 return tmp;
260}
261static inline const char *rta_getattr_str(const struct rtattr *rta)
262{
263 return (const char *)RTA_DATA(rta);
264}
265
266int rtnl_listen_all_nsid(struct rtnl_handle *);
267int rtnl_listen(struct rtnl_handle *, rtnl_listen_filter_t handler,
268 void *jarg);
269int rtnl_from_file(FILE *, rtnl_listen_filter_t handler,
270 void *jarg);
271
272#define NLMSG_TAIL(nmsg) \
273 ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
274
275#ifndef IFA_RTA
276#define IFA_RTA(r) \
277 ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
278#endif
279#ifndef IFA_PAYLOAD
280#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg))
281#endif
282
283#ifndef IFLA_RTA
284#define IFLA_RTA(r) \
285 ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
286#endif
287#ifndef IFLA_PAYLOAD
288#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg))
289#endif
290
291#ifndef NDA_RTA
292#define NDA_RTA(r) \
293 ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
294#endif
295#ifndef NDA_PAYLOAD
296#define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ndmsg))
297#endif
298
299#ifndef NDTA_RTA
300#define NDTA_RTA(r) \
301 ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndtmsg))))
302#endif
303#ifndef NDTA_PAYLOAD
304#define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ndtmsg))
305#endif
306
307#ifndef NETNS_RTA
308#define NETNS_RTA(r) \
309 ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))))
310#endif
311#ifndef NETNS_PAYLOAD
312#define NETNS_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct rtgenmsg))
313#endif
314
315#ifndef IFLA_STATS_RTA
316#define IFLA_STATS_RTA(r) \
317 ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct if_stats_msg))))
318#endif
319
320#ifndef BRVLAN_RTA
321#define BRVLAN_RTA(r) \
322 ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct br_vlan_msg))))
323#endif
324
325
326
327#define NLMSG_TSTAMP 15
328
329#define rtattr_for_each_nested(attr, nest) \
330 for ((attr) = (void *)RTA_DATA(nest); \
331 RTA_OK(attr, RTA_PAYLOAD(nest) - ((char *)(attr) - (char *)RTA_DATA((nest)))); \
332 (attr) = RTA_TAIL((attr)))
333
334void nl_print_policy(const struct rtattr *attr, FILE *fp);
335
336#endif
337