]>
Commit | Line | Data |
---|---|---|
1 | /* SPDX-License-Identifier: GPL-2.0 */ | |
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 | ||
16 | struct 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 | int flags; | |
27 | }; | |
28 | ||
29 | struct nlmsg_list { | |
30 | struct nlmsg_list *next; | |
31 | struct nlmsghdr h; | |
32 | }; | |
33 | ||
34 | struct nlmsg_chain { | |
35 | struct nlmsg_list *head; | |
36 | struct nlmsg_list *tail; | |
37 | }; | |
38 | ||
39 | extern int rcvbuf; | |
40 | ||
41 | int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions) | |
42 | __attribute__((warn_unused_result)); | |
43 | ||
44 | int rtnl_open_byproto(struct rtnl_handle *rth, unsigned int subscriptions, | |
45 | int protocol) | |
46 | __attribute__((warn_unused_result)); | |
47 | ||
48 | void rtnl_close(struct rtnl_handle *rth); | |
49 | ||
50 | int rtnl_addrdump_req(struct rtnl_handle *rth, int family) | |
51 | __attribute__((warn_unused_result)); | |
52 | int rtnl_addrlbldump_req(struct rtnl_handle *rth, int family) | |
53 | __attribute__((warn_unused_result)); | |
54 | int rtnl_routedump_req(struct rtnl_handle *rth, int family) | |
55 | __attribute__((warn_unused_result)); | |
56 | int rtnl_ruledump_req(struct rtnl_handle *rth, int family) | |
57 | __attribute__((warn_unused_result)); | |
58 | int rtnl_neighdump_req(struct rtnl_handle *rth, int family) | |
59 | __attribute__((warn_unused_result)); | |
60 | int rtnl_neightbldump_req(struct rtnl_handle *rth, int family) | |
61 | __attribute__((warn_unused_result)); | |
62 | int rtnl_mdbdump_req(struct rtnl_handle *rth, int family) | |
63 | __attribute__((warn_unused_result)); | |
64 | int rtnl_netconfdump_req(struct rtnl_handle *rth, int family) | |
65 | __attribute__((warn_unused_result)); | |
66 | int rtnl_nsiddump_req(struct rtnl_handle *rth, int family) | |
67 | __attribute__((warn_unused_result)); | |
68 | ||
69 | int rtnl_linkdump_req(struct rtnl_handle *rth, int fam) | |
70 | __attribute__((warn_unused_result)); | |
71 | int rtnl_linkdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask) | |
72 | __attribute__((warn_unused_result)); | |
73 | ||
74 | typedef int (*req_filter_fn_t)(struct nlmsghdr *nlh, int reqlen); | |
75 | ||
76 | int rtnl_linkdump_req_filter_fn(struct rtnl_handle *rth, int fam, | |
77 | req_filter_fn_t fn) | |
78 | __attribute__((warn_unused_result)); | |
79 | int rtnl_wilddump_stats_req_filter(struct rtnl_handle *rth, int fam, int type, | |
80 | __u32 filt_mask) | |
81 | __attribute__((warn_unused_result)); | |
82 | int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, | |
83 | int len) | |
84 | __attribute__((warn_unused_result)); | |
85 | int rtnl_dump_request_n(struct rtnl_handle *rth, struct nlmsghdr *n) | |
86 | __attribute__((warn_unused_result)); | |
87 | ||
88 | struct rtnl_ctrl_data { | |
89 | int nsid; | |
90 | }; | |
91 | ||
92 | typedef int (*rtnl_filter_t)(const struct sockaddr_nl *, | |
93 | struct nlmsghdr *n, void *); | |
94 | ||
95 | typedef int (*rtnl_listen_filter_t)(const struct sockaddr_nl *, | |
96 | struct rtnl_ctrl_data *, | |
97 | struct nlmsghdr *n, void *); | |
98 | ||
99 | typedef int (*nl_ext_ack_fn_t)(const char *errmsg, uint32_t off, | |
100 | const struct nlmsghdr *inner_nlh); | |
101 | ||
102 | struct rtnl_dump_filter_arg { | |
103 | rtnl_filter_t filter; | |
104 | void *arg1; | |
105 | __u16 nc_flags; | |
106 | }; | |
107 | ||
108 | int rtnl_dump_filter_l(struct rtnl_handle *rth, | |
109 | const struct rtnl_dump_filter_arg *arg); | |
110 | int rtnl_dump_filter_nc(struct rtnl_handle *rth, | |
111 | rtnl_filter_t filter, | |
112 | void *arg, __u16 nc_flags); | |
113 | #define rtnl_dump_filter(rth, filter, arg) \ | |
114 | rtnl_dump_filter_nc(rth, filter, arg, 0) | |
115 | int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, | |
116 | struct nlmsghdr **answer) | |
117 | __attribute__((warn_unused_result)); | |
118 | int rtnl_talk_iov(struct rtnl_handle *rtnl, struct iovec *iovec, size_t iovlen, | |
119 | struct nlmsghdr **answer) | |
120 | __attribute__((warn_unused_result)); | |
121 | int rtnl_talk_extack(struct rtnl_handle *rtnl, struct nlmsghdr *n, | |
122 | struct nlmsghdr **answer, nl_ext_ack_fn_t errfn) | |
123 | __attribute__((warn_unused_result)); | |
124 | int rtnl_talk_suppress_rtnl_errmsg(struct rtnl_handle *rtnl, struct nlmsghdr *n, | |
125 | struct nlmsghdr **answer) | |
126 | __attribute__((warn_unused_result)); | |
127 | int rtnl_send(struct rtnl_handle *rth, const void *buf, int) | |
128 | __attribute__((warn_unused_result)); | |
129 | int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int) | |
130 | __attribute__((warn_unused_result)); | |
131 | int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn); | |
132 | ||
133 | int addattr(struct nlmsghdr *n, int maxlen, int type); | |
134 | int addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data); | |
135 | int addattr16(struct nlmsghdr *n, int maxlen, int type, __u16 data); | |
136 | int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data); | |
137 | int addattr64(struct nlmsghdr *n, int maxlen, int type, __u64 data); | |
138 | int addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *data); | |
139 | ||
140 | int addattr_l(struct nlmsghdr *n, int maxlen, int type, | |
141 | const void *data, int alen); | |
142 | int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len); | |
143 | struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type); | |
144 | int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest); | |
145 | struct rtattr *addattr_nest_compat(struct nlmsghdr *n, int maxlen, int type, | |
146 | const void *data, int len); | |
147 | int addattr_nest_compat_end(struct nlmsghdr *n, struct rtattr *nest); | |
148 | int rta_addattr8(struct rtattr *rta, int maxlen, int type, __u8 data); | |
149 | int rta_addattr16(struct rtattr *rta, int maxlen, int type, __u16 data); | |
150 | int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data); | |
151 | int rta_addattr64(struct rtattr *rta, int maxlen, int type, __u64 data); | |
152 | int rta_addattr_l(struct rtattr *rta, int maxlen, int type, | |
153 | const void *data, int alen); | |
154 | ||
155 | int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len); | |
156 | int parse_rtattr_flags(struct rtattr *tb[], int max, struct rtattr *rta, | |
157 | int len, unsigned short flags); | |
158 | int parse_rtattr_byindex(struct rtattr *tb[], int max, | |
159 | struct rtattr *rta, int len); | |
160 | struct rtattr *parse_rtattr_one(int type, struct rtattr *rta, int len); | |
161 | int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rta, int len); | |
162 | ||
163 | struct rtattr *rta_nest(struct rtattr *rta, int maxlen, int type); | |
164 | int rta_nest_end(struct rtattr *rta, struct rtattr *nest); | |
165 | ||
166 | #define RTA_TAIL(rta) \ | |
167 | ((struct rtattr *) (((void *) (rta)) + \ | |
168 | RTA_ALIGN((rta)->rta_len))) | |
169 | ||
170 | #define parse_rtattr_nested(tb, max, rta) \ | |
171 | (parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))) | |
172 | ||
173 | #define parse_rtattr_one_nested(type, rta) \ | |
174 | (parse_rtattr_one(type, RTA_DATA(rta), RTA_PAYLOAD(rta))) | |
175 | ||
176 | #define parse_rtattr_nested_compat(tb, max, rta, data, len) \ | |
177 | ({ data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \ | |
178 | __parse_rtattr_nested_compat(tb, max, rta, len); }) | |
179 | ||
180 | static inline __u8 rta_getattr_u8(const struct rtattr *rta) | |
181 | { | |
182 | return *(__u8 *)RTA_DATA(rta); | |
183 | } | |
184 | static inline __u16 rta_getattr_u16(const struct rtattr *rta) | |
185 | { | |
186 | return *(__u16 *)RTA_DATA(rta); | |
187 | } | |
188 | static inline __be16 rta_getattr_be16(const struct rtattr *rta) | |
189 | { | |
190 | return ntohs(rta_getattr_u16(rta)); | |
191 | } | |
192 | static inline __u32 rta_getattr_u32(const struct rtattr *rta) | |
193 | { | |
194 | return *(__u32 *)RTA_DATA(rta); | |
195 | } | |
196 | static inline __be32 rta_getattr_be32(const struct rtattr *rta) | |
197 | { | |
198 | return ntohl(rta_getattr_u32(rta)); | |
199 | } | |
200 | static inline __u64 rta_getattr_u64(const struct rtattr *rta) | |
201 | { | |
202 | __u64 tmp; | |
203 | ||
204 | memcpy(&tmp, RTA_DATA(rta), sizeof(__u64)); | |
205 | return tmp; | |
206 | } | |
207 | static inline const char *rta_getattr_str(const struct rtattr *rta) | |
208 | { | |
209 | return (const char *)RTA_DATA(rta); | |
210 | } | |
211 | ||
212 | int rtnl_listen_all_nsid(struct rtnl_handle *); | |
213 | int rtnl_listen(struct rtnl_handle *, rtnl_listen_filter_t handler, | |
214 | void *jarg); | |
215 | int rtnl_from_file(FILE *, rtnl_listen_filter_t handler, | |
216 | void *jarg); | |
217 | ||
218 | #define NLMSG_TAIL(nmsg) \ | |
219 | ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) | |
220 | ||
221 | #ifndef IFA_RTA | |
222 | #define IFA_RTA(r) \ | |
223 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)))) | |
224 | #endif | |
225 | #ifndef IFA_PAYLOAD | |
226 | #define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ifaddrmsg)) | |
227 | #endif | |
228 | ||
229 | #ifndef IFLA_RTA | |
230 | #define IFLA_RTA(r) \ | |
231 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg)))) | |
232 | #endif | |
233 | #ifndef IFLA_PAYLOAD | |
234 | #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg)) | |
235 | #endif | |
236 | ||
237 | #ifndef NDA_RTA | |
238 | #define NDA_RTA(r) \ | |
239 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) | |
240 | #endif | |
241 | #ifndef NDA_PAYLOAD | |
242 | #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ndmsg)) | |
243 | #endif | |
244 | ||
245 | #ifndef NDTA_RTA | |
246 | #define NDTA_RTA(r) \ | |
247 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct ndtmsg)))) | |
248 | #endif | |
249 | #ifndef NDTA_PAYLOAD | |
250 | #define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct ndtmsg)) | |
251 | #endif | |
252 | ||
253 | #ifndef NETNS_RTA | |
254 | #define NETNS_RTA(r) \ | |
255 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct rtgenmsg)))) | |
256 | #endif | |
257 | #ifndef NETNS_PAYLOAD | |
258 | #define NETNS_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct rtgenmsg)) | |
259 | #endif | |
260 | ||
261 | #ifndef IFLA_STATS_RTA | |
262 | #define IFLA_STATS_RTA(r) \ | |
263 | ((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct if_stats_msg)))) | |
264 | #endif | |
265 | ||
266 | /* User defined nlmsg_type which is used mostly for logging netlink | |
267 | * messages from dump file */ | |
268 | #define NLMSG_TSTAMP 15 | |
269 | ||
270 | #endif /* __LIBNETLINK_H__ */ |