xref: /aosp_15_r20/external/libnl/python/netlink/capi.i (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker %module capi
2*4dc78e53SAndroid Build Coastguard Worker %{
3*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
4*4dc78e53SAndroid Build Coastguard Worker #include <netlink/types.h>
5*4dc78e53SAndroid Build Coastguard Worker #include <netlink/socket.h>
6*4dc78e53SAndroid Build Coastguard Worker #include <netlink/msg.h>
7*4dc78e53SAndroid Build Coastguard Worker #include <netlink/object.h>
8*4dc78e53SAndroid Build Coastguard Worker #include <netlink/cache.h>
9*4dc78e53SAndroid Build Coastguard Worker #include <netlink/attr.h>
10*4dc78e53SAndroid Build Coastguard Worker #include <net/if.h>
11*4dc78e53SAndroid Build Coastguard Worker 
12*4dc78e53SAndroid Build Coastguard Worker /* enable define below to get swig api debug messages */
13*4dc78e53SAndroid Build Coastguard Worker /*#define DEBUG*/
14*4dc78e53SAndroid Build Coastguard Worker #include "utils.h"
15*4dc78e53SAndroid Build Coastguard Worker %}
16*4dc78e53SAndroid Build Coastguard Worker 
17*4dc78e53SAndroid Build Coastguard Worker %include <stdint.i>
18*4dc78e53SAndroid Build Coastguard Worker %include <cstring.i>
19*4dc78e53SAndroid Build Coastguard Worker %include <cpointer.i>
20*4dc78e53SAndroid Build Coastguard Worker %include <exception.i>
21*4dc78e53SAndroid Build Coastguard Worker 
22*4dc78e53SAndroid Build Coastguard Worker %inline %{
alloc_dump_params(void)23*4dc78e53SAndroid Build Coastguard Worker         struct nl_dump_params *alloc_dump_params(void)
24*4dc78e53SAndroid Build Coastguard Worker         {
25*4dc78e53SAndroid Build Coastguard Worker                 struct nl_dump_params *dp;
26*4dc78e53SAndroid Build Coastguard Worker                 if (!(dp = calloc(1, sizeof(*dp))))
27*4dc78e53SAndroid Build Coastguard Worker                         return NULL;
28*4dc78e53SAndroid Build Coastguard Worker                 dp->dp_fd = stdout;
29*4dc78e53SAndroid Build Coastguard Worker                 return dp;
30*4dc78e53SAndroid Build Coastguard Worker         }
31*4dc78e53SAndroid Build Coastguard Worker 
free_dump_params(struct nl_dump_params * dp)32*4dc78e53SAndroid Build Coastguard Worker         void free_dump_params(struct nl_dump_params *dp)
33*4dc78e53SAndroid Build Coastguard Worker         {
34*4dc78e53SAndroid Build Coastguard Worker                 free(dp);
35*4dc78e53SAndroid Build Coastguard Worker         }
36*4dc78e53SAndroid Build Coastguard Worker %};
37*4dc78e53SAndroid Build Coastguard Worker 
38*4dc78e53SAndroid Build Coastguard Worker /* <netlink/types.h> */
39*4dc78e53SAndroid Build Coastguard Worker 
40*4dc78e53SAndroid Build Coastguard Worker enum nl_dump_type {
41*4dc78e53SAndroid Build Coastguard Worker 	NL_DUMP_LINE,		/**< Dump object briefly on one line */
42*4dc78e53SAndroid Build Coastguard Worker 	NL_DUMP_DETAILS,	/**< Dump all attributes but no statistics */
43*4dc78e53SAndroid Build Coastguard Worker 	NL_DUMP_STATS,		/**< Dump all attributes including statistics */
44*4dc78e53SAndroid Build Coastguard Worker 	__NL_DUMP_MAX,
45*4dc78e53SAndroid Build Coastguard Worker };
46*4dc78e53SAndroid Build Coastguard Worker 
47*4dc78e53SAndroid Build Coastguard Worker struct nl_dump_params
48*4dc78e53SAndroid Build Coastguard Worker {
49*4dc78e53SAndroid Build Coastguard Worker 	/**
50*4dc78e53SAndroid Build Coastguard Worker 	 * Specifies the type of dump that is requested.
51*4dc78e53SAndroid Build Coastguard Worker 	 */
52*4dc78e53SAndroid Build Coastguard Worker 	enum nl_dump_type	dp_type;
53*4dc78e53SAndroid Build Coastguard Worker 
54*4dc78e53SAndroid Build Coastguard Worker 	/**
55*4dc78e53SAndroid Build Coastguard Worker 	 * Specifies the number of whitespaces to be put in front
56*4dc78e53SAndroid Build Coastguard Worker 	 * of every new line (indentation).
57*4dc78e53SAndroid Build Coastguard Worker 	 */
58*4dc78e53SAndroid Build Coastguard Worker 	int			dp_prefix;
59*4dc78e53SAndroid Build Coastguard Worker 
60*4dc78e53SAndroid Build Coastguard Worker 	/**
61*4dc78e53SAndroid Build Coastguard Worker 	 * Causes the cache index to be printed for each element.
62*4dc78e53SAndroid Build Coastguard Worker 	 */
63*4dc78e53SAndroid Build Coastguard Worker 	int			dp_print_index;
64*4dc78e53SAndroid Build Coastguard Worker 
65*4dc78e53SAndroid Build Coastguard Worker 	/**
66*4dc78e53SAndroid Build Coastguard Worker 	 * Causes each element to be prefixed with the message type.
67*4dc78e53SAndroid Build Coastguard Worker 	 */
68*4dc78e53SAndroid Build Coastguard Worker 	int			dp_dump_msgtype;
69*4dc78e53SAndroid Build Coastguard Worker 
70*4dc78e53SAndroid Build Coastguard Worker 	/**
71*4dc78e53SAndroid Build Coastguard Worker 	 * A callback invoked for output
72*4dc78e53SAndroid Build Coastguard Worker 	 *
73*4dc78e53SAndroid Build Coastguard Worker 	 * Passed arguments are:
74*4dc78e53SAndroid Build Coastguard Worker 	 *  - dumping parameters
75*4dc78e53SAndroid Build Coastguard Worker 	 *  - string to append to the output
76*4dc78e53SAndroid Build Coastguard Worker 	 */
77*4dc78e53SAndroid Build Coastguard Worker 	void			(*dp_cb)(struct nl_dump_params *, char *);
78*4dc78e53SAndroid Build Coastguard Worker 
79*4dc78e53SAndroid Build Coastguard Worker 	/**
80*4dc78e53SAndroid Build Coastguard Worker 	 * A callback invoked for every new line, can be used to
81*4dc78e53SAndroid Build Coastguard Worker 	 * customize the indentation.
82*4dc78e53SAndroid Build Coastguard Worker 	 *
83*4dc78e53SAndroid Build Coastguard Worker 	 * Passed arguments are:
84*4dc78e53SAndroid Build Coastguard Worker 	 *  - dumping parameters
85*4dc78e53SAndroid Build Coastguard Worker 	 *  - line number starting from 0
86*4dc78e53SAndroid Build Coastguard Worker 	 */
87*4dc78e53SAndroid Build Coastguard Worker 	void			(*dp_nl_cb)(struct nl_dump_params *, int);
88*4dc78e53SAndroid Build Coastguard Worker 
89*4dc78e53SAndroid Build Coastguard Worker 	/**
90*4dc78e53SAndroid Build Coastguard Worker 	 * User data pointer, can be used to pass data to callbacks.
91*4dc78e53SAndroid Build Coastguard Worker 	 */
92*4dc78e53SAndroid Build Coastguard Worker 	void			*dp_data;
93*4dc78e53SAndroid Build Coastguard Worker 
94*4dc78e53SAndroid Build Coastguard Worker 	/**
95*4dc78e53SAndroid Build Coastguard Worker 	 * File descriptor the dumping output should go to
96*4dc78e53SAndroid Build Coastguard Worker 	 */
97*4dc78e53SAndroid Build Coastguard Worker 	FILE *			dp_fd;
98*4dc78e53SAndroid Build Coastguard Worker 
99*4dc78e53SAndroid Build Coastguard Worker 	/**
100*4dc78e53SAndroid Build Coastguard Worker 	 * Alternatively the output may be redirected into a buffer
101*4dc78e53SAndroid Build Coastguard Worker 	 */
102*4dc78e53SAndroid Build Coastguard Worker 	char *			dp_buf;
103*4dc78e53SAndroid Build Coastguard Worker 
104*4dc78e53SAndroid Build Coastguard Worker 	/**
105*4dc78e53SAndroid Build Coastguard Worker 	 * Length of the buffer dp_buf
106*4dc78e53SAndroid Build Coastguard Worker 	 */
107*4dc78e53SAndroid Build Coastguard Worker 	size_t			dp_buflen;
108*4dc78e53SAndroid Build Coastguard Worker 
109*4dc78e53SAndroid Build Coastguard Worker 	/**
110*4dc78e53SAndroid Build Coastguard Worker 	 * PRIVATE
111*4dc78e53SAndroid Build Coastguard Worker 	 * Set if a dump was performed prior to the actual dump handler.
112*4dc78e53SAndroid Build Coastguard Worker 	 */
113*4dc78e53SAndroid Build Coastguard Worker 	int			dp_pre_dump;
114*4dc78e53SAndroid Build Coastguard Worker 
115*4dc78e53SAndroid Build Coastguard Worker 	/**
116*4dc78e53SAndroid Build Coastguard Worker 	 * PRIVATE
117*4dc78e53SAndroid Build Coastguard Worker 	 * Owned by the current caller
118*4dc78e53SAndroid Build Coastguard Worker 	 */
119*4dc78e53SAndroid Build Coastguard Worker 	int			dp_ivar;
120*4dc78e53SAndroid Build Coastguard Worker 
121*4dc78e53SAndroid Build Coastguard Worker 	unsigned int		dp_line;
122*4dc78e53SAndroid Build Coastguard Worker };
123*4dc78e53SAndroid Build Coastguard Worker 
124*4dc78e53SAndroid Build Coastguard Worker /* <net/if.h> */
125*4dc78e53SAndroid Build Coastguard Worker extern unsigned int if_nametoindex(const char *ifname);
126*4dc78e53SAndroid Build Coastguard Worker 
127*4dc78e53SAndroid Build Coastguard Worker /* <netlink/errno.h> */
128*4dc78e53SAndroid Build Coastguard Worker extern const char *nl_geterror(int);
129*4dc78e53SAndroid Build Coastguard Worker 
130*4dc78e53SAndroid Build Coastguard Worker /* <netlink/utils.h> */
131*4dc78e53SAndroid Build Coastguard Worker 
132*4dc78e53SAndroid Build Coastguard Worker extern double nl_cancel_down_bytes(unsigned long long, char **);
133*4dc78e53SAndroid Build Coastguard Worker extern double nl_cancel_down_bits(unsigned long long, char **);
134*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
135*4dc78e53SAndroid Build Coastguard Worker extern int nl_rate2str(unsigned long long rate, int type, char *buf, size_t len);
136*4dc78e53SAndroid Build Coastguard Worker extern double nl_cancel_down_us(uint32_t, char **);
137*4dc78e53SAndroid Build Coastguard Worker 
138*4dc78e53SAndroid Build Coastguard Worker extern long nl_size2int(const char *);
139*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, const size_t len)
140*4dc78e53SAndroid Build Coastguard Worker extern char *nl_size2str(const size_t, char *buf, const size_t len);
141*4dc78e53SAndroid Build Coastguard Worker extern long nl_prob2int(const char *);
142*4dc78e53SAndroid Build Coastguard Worker 
143*4dc78e53SAndroid Build Coastguard Worker extern int nl_get_user_hz(void);
144*4dc78e53SAndroid Build Coastguard Worker extern uint32_t nl_us2ticks(uint32_t);
145*4dc78e53SAndroid Build Coastguard Worker extern uint32_t nl_ticks2us(uint32_t);
146*4dc78e53SAndroid Build Coastguard Worker extern int nl_str2msec(const char *, uint64_t *);
147*4dc78e53SAndroid Build Coastguard Worker 
148*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
149*4dc78e53SAndroid Build Coastguard Worker extern char *nl_msec2str(uint64_t, char *buf, size_t len);
150*4dc78e53SAndroid Build Coastguard Worker 
151*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
152*4dc78e53SAndroid Build Coastguard Worker extern char *nl_llproto2str(int, char *buf, size_t len);
153*4dc78e53SAndroid Build Coastguard Worker extern int nl_str2llproto(const char *);
154*4dc78e53SAndroid Build Coastguard Worker 
155*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
156*4dc78e53SAndroid Build Coastguard Worker extern char *nl_ether_proto2str(int, char *buf, size_t len);
157*4dc78e53SAndroid Build Coastguard Worker extern int nl_str2ether_proto(const char *);
158*4dc78e53SAndroid Build Coastguard Worker 
159*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
160*4dc78e53SAndroid Build Coastguard Worker extern char *nl_ip_proto2str(int, char *buf, size_t len);
161*4dc78e53SAndroid Build Coastguard Worker extern int nl_str2ip_proto(const char *);
162*4dc78e53SAndroid Build Coastguard Worker 
163*4dc78e53SAndroid Build Coastguard Worker extern void nl_new_line(struct nl_dump_params *);
164*4dc78e53SAndroid Build Coastguard Worker extern void nl_dump(struct nl_dump_params *, const char *, ...);
165*4dc78e53SAndroid Build Coastguard Worker extern void nl_dump_line(struct nl_dump_params *, const char *, ...);
166*4dc78e53SAndroid Build Coastguard Worker 
167*4dc78e53SAndroid Build Coastguard Worker /* <netlink/netlink.h> */
168*4dc78e53SAndroid Build Coastguard Worker extern struct nl_dump_params *alloc_dump_params(void);
169*4dc78e53SAndroid Build Coastguard Worker extern void free_dump_params(struct nl_dump_params *);
170*4dc78e53SAndroid Build Coastguard Worker 
171*4dc78e53SAndroid Build Coastguard Worker extern int nl_connect(struct nl_sock *, int);
172*4dc78e53SAndroid Build Coastguard Worker extern void nl_close(struct nl_sock *);
173*4dc78e53SAndroid Build Coastguard Worker 
174*4dc78e53SAndroid Build Coastguard Worker /* <netlink/socket.h> */
175*4dc78e53SAndroid Build Coastguard Worker extern struct nl_sock *nl_socket_alloc(void);
176*4dc78e53SAndroid Build Coastguard Worker extern struct nl_sock *nl_socket_alloc_cb(struct nl_cb *);
177*4dc78e53SAndroid Build Coastguard Worker extern void nl_socket_free(struct nl_sock *);
178*4dc78e53SAndroid Build Coastguard Worker 
179*4dc78e53SAndroid Build Coastguard Worker extern uint32_t nl_socket_get_local_port(const struct nl_sock *);
180*4dc78e53SAndroid Build Coastguard Worker extern void nl_socket_set_local_port(struct nl_sock *, uint32_t);
181*4dc78e53SAndroid Build Coastguard Worker 
182*4dc78e53SAndroid Build Coastguard Worker extern uint32_t nl_socket_get_peer_port(const struct nl_sock *);
183*4dc78e53SAndroid Build Coastguard Worker extern void nl_socket_set_peer_port(struct nl_sock *, uint32_t);
184*4dc78e53SAndroid Build Coastguard Worker 
185*4dc78e53SAndroid Build Coastguard Worker extern uint32_t nl_socket_get_peer_groups(const struct nl_sock *sk);
186*4dc78e53SAndroid Build Coastguard Worker extern void  nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups);
187*4dc78e53SAndroid Build Coastguard Worker 
188*4dc78e53SAndroid Build Coastguard Worker extern int nl_socket_set_buffer_size(struct nl_sock *, int, int);
189*4dc78e53SAndroid Build Coastguard Worker extern void nl_socket_set_cb(struct nl_sock *, struct nl_cb *);
190*4dc78e53SAndroid Build Coastguard Worker 
191*4dc78e53SAndroid Build Coastguard Worker extern int nl_socket_add_membership(struct nl_sock *, int);
192*4dc78e53SAndroid Build Coastguard Worker extern int nl_socket_drop_membership(struct nl_sock *, int);
193*4dc78e53SAndroid Build Coastguard Worker 
194*4dc78e53SAndroid Build Coastguard Worker extern int nl_send_auto_complete(struct nl_sock *, struct nl_msg *);
195*4dc78e53SAndroid Build Coastguard Worker extern int nl_recvmsgs(struct nl_sock *, struct nl_cb *);
196*4dc78e53SAndroid Build Coastguard Worker 
197*4dc78e53SAndroid Build Coastguard Worker /* <netlink/msg.h> */
198*4dc78e53SAndroid Build Coastguard Worker extern int			nlmsg_size(int);
199*4dc78e53SAndroid Build Coastguard Worker extern int			nlmsg_total_size(int);
200*4dc78e53SAndroid Build Coastguard Worker extern int			nlmsg_padlen(int);
201*4dc78e53SAndroid Build Coastguard Worker 
202*4dc78e53SAndroid Build Coastguard Worker extern void *			nlmsg_data(const struct nlmsghdr *);
203*4dc78e53SAndroid Build Coastguard Worker extern int			nlmsg_datalen(const struct nlmsghdr *);
204*4dc78e53SAndroid Build Coastguard Worker extern void *			nlmsg_tail(const struct nlmsghdr *);
205*4dc78e53SAndroid Build Coastguard Worker 
206*4dc78e53SAndroid Build Coastguard Worker /* attribute access */
207*4dc78e53SAndroid Build Coastguard Worker extern struct nlattr *	  nlmsg_attrdata(const struct nlmsghdr *, int);
208*4dc78e53SAndroid Build Coastguard Worker extern int		  nlmsg_attrlen(const struct nlmsghdr *, int);
209*4dc78e53SAndroid Build Coastguard Worker 
210*4dc78e53SAndroid Build Coastguard Worker /* message parsing */
211*4dc78e53SAndroid Build Coastguard Worker extern int		  nlmsg_valid_hdr(const struct nlmsghdr *, int);
212*4dc78e53SAndroid Build Coastguard Worker extern int		  nlmsg_ok(const struct nlmsghdr *, int);
213*4dc78e53SAndroid Build Coastguard Worker extern struct nlmsghdr *  nlmsg_next(struct nlmsghdr *, int *);
214*4dc78e53SAndroid Build Coastguard Worker extern int		  nlmsg_parse(struct nlmsghdr *, int, struct nlattr **,
215*4dc78e53SAndroid Build Coastguard Worker 				      int, struct nla_policy *);
216*4dc78e53SAndroid Build Coastguard Worker extern struct nlattr *	  nlmsg_find_attr(struct nlmsghdr *, int, int);
217*4dc78e53SAndroid Build Coastguard Worker extern int		  nlmsg_validate(struct nlmsghdr *, int, int,
218*4dc78e53SAndroid Build Coastguard Worker 					 struct nla_policy *);
219*4dc78e53SAndroid Build Coastguard Worker 
220*4dc78e53SAndroid Build Coastguard Worker extern struct nl_msg *	  nlmsg_alloc(void);
221*4dc78e53SAndroid Build Coastguard Worker extern struct nl_msg *	  nlmsg_alloc_size(size_t);
222*4dc78e53SAndroid Build Coastguard Worker extern struct nl_msg *	  nlmsg_alloc_simple(int, int);
223*4dc78e53SAndroid Build Coastguard Worker extern void		  nlmsg_set_default_size(size_t);
224*4dc78e53SAndroid Build Coastguard Worker extern struct nl_msg *	  nlmsg_inherit(struct nlmsghdr *);
225*4dc78e53SAndroid Build Coastguard Worker extern struct nl_msg *	  nlmsg_convert(struct nlmsghdr *);
226*4dc78e53SAndroid Build Coastguard Worker extern void *		  nlmsg_reserve(struct nl_msg *, size_t, int);
227*4dc78e53SAndroid Build Coastguard Worker extern int		  nlmsg_append(struct nl_msg *, void *, size_t, int);
228*4dc78e53SAndroid Build Coastguard Worker extern int		  nlmsg_expand(struct nl_msg *, size_t);
229*4dc78e53SAndroid Build Coastguard Worker 
230*4dc78e53SAndroid Build Coastguard Worker extern struct nlmsghdr *  nlmsg_put(struct nl_msg *, uint32_t, uint32_t,
231*4dc78e53SAndroid Build Coastguard Worker 				    int, int, int);
232*4dc78e53SAndroid Build Coastguard Worker extern struct nlmsghdr *  nlmsg_hdr(struct nl_msg *);
233*4dc78e53SAndroid Build Coastguard Worker extern void		  nlmsg_get(struct nl_msg *);
234*4dc78e53SAndroid Build Coastguard Worker extern void		  nlmsg_free(struct nl_msg *);
235*4dc78e53SAndroid Build Coastguard Worker 
236*4dc78e53SAndroid Build Coastguard Worker /* attribute modification */
237*4dc78e53SAndroid Build Coastguard Worker extern void		  nlmsg_set_proto(struct nl_msg *, int);
238*4dc78e53SAndroid Build Coastguard Worker extern int		  nlmsg_get_proto(struct nl_msg *);
239*4dc78e53SAndroid Build Coastguard Worker extern size_t		  nlmsg_get_max_size(struct nl_msg *);
240*4dc78e53SAndroid Build Coastguard Worker extern void		  nlmsg_set_src(struct nl_msg *, struct sockaddr_nl *);
241*4dc78e53SAndroid Build Coastguard Worker extern struct sockaddr_nl *nlmsg_get_src(struct nl_msg *);
242*4dc78e53SAndroid Build Coastguard Worker extern void		  nlmsg_set_dst(struct nl_msg *, struct sockaddr_nl *);
243*4dc78e53SAndroid Build Coastguard Worker extern struct sockaddr_nl *nlmsg_get_dst(struct nl_msg *);
244*4dc78e53SAndroid Build Coastguard Worker extern void		  nlmsg_set_creds(struct nl_msg *, struct ucred *);
245*4dc78e53SAndroid Build Coastguard Worker extern struct ucred *	  nlmsg_get_creds(struct nl_msg *);
246*4dc78e53SAndroid Build Coastguard Worker 
247*4dc78e53SAndroid Build Coastguard Worker extern char *		  nl_nlmsgtype2str(int, char *, size_t);
248*4dc78e53SAndroid Build Coastguard Worker extern int		  nl_str2nlmsgtype(const char *);
249*4dc78e53SAndroid Build Coastguard Worker 
250*4dc78e53SAndroid Build Coastguard Worker extern char *		  nl_nlmsg_flags2str(int, char *, size_t);
251*4dc78e53SAndroid Build Coastguard Worker 
252*4dc78e53SAndroid Build Coastguard Worker extern int		  nl_msg_parse(struct nl_msg *,
253*4dc78e53SAndroid Build Coastguard Worker 				       void (*cb)(struct nl_object *, void *),
254*4dc78e53SAndroid Build Coastguard Worker 				       void *);
255*4dc78e53SAndroid Build Coastguard Worker 
256*4dc78e53SAndroid Build Coastguard Worker extern void		nl_msg_dump(struct nl_msg *, FILE *);
257*4dc78e53SAndroid Build Coastguard Worker 
258*4dc78e53SAndroid Build Coastguard Worker %inline %{
cast_obj(void * obj)259*4dc78e53SAndroid Build Coastguard Worker 	struct nl_object *cast_obj(void *obj)
260*4dc78e53SAndroid Build Coastguard Worker         {
261*4dc78e53SAndroid Build Coastguard Worker                 return (struct nl_object *) obj;
262*4dc78e53SAndroid Build Coastguard Worker         }
263*4dc78e53SAndroid Build Coastguard Worker 
object_alloc_name(const char * name)264*4dc78e53SAndroid Build Coastguard Worker         struct nl_object *object_alloc_name(const char *name)
265*4dc78e53SAndroid Build Coastguard Worker         {
266*4dc78e53SAndroid Build Coastguard Worker                 struct nl_object *obj;
267*4dc78e53SAndroid Build Coastguard Worker 
268*4dc78e53SAndroid Build Coastguard Worker                 if (nl_object_alloc_name(name, &obj) < 0)
269*4dc78e53SAndroid Build Coastguard Worker                         return NULL;
270*4dc78e53SAndroid Build Coastguard Worker 
271*4dc78e53SAndroid Build Coastguard Worker                 return obj;
272*4dc78e53SAndroid Build Coastguard Worker         }
273*4dc78e53SAndroid Build Coastguard Worker %};
274*4dc78e53SAndroid Build Coastguard Worker 
275*4dc78e53SAndroid Build Coastguard Worker extern struct nl_object *nl_object_alloc(struct nl_object_ops *);
276*4dc78e53SAndroid Build Coastguard Worker extern void nl_object_free(struct nl_object *);
277*4dc78e53SAndroid Build Coastguard Worker extern struct nl_object *nl_object_clone(struct nl_object *);
278*4dc78e53SAndroid Build Coastguard Worker extern void nl_object_get(struct nl_object *);
279*4dc78e53SAndroid Build Coastguard Worker extern void nl_object_put(struct nl_object *);
280*4dc78e53SAndroid Build Coastguard Worker extern int nl_object_shared(struct nl_object *);
281*4dc78e53SAndroid Build Coastguard Worker 
282*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
283*4dc78e53SAndroid Build Coastguard Worker extern void nl_object_dump_buf(struct nl_object *, char *buf, size_t len);
284*4dc78e53SAndroid Build Coastguard Worker 
285*4dc78e53SAndroid Build Coastguard Worker extern void nl_object_dump(struct nl_object *, struct nl_dump_params *);
286*4dc78e53SAndroid Build Coastguard Worker 
287*4dc78e53SAndroid Build Coastguard Worker extern int nl_object_identical(struct nl_object *, struct nl_object *);
288*4dc78e53SAndroid Build Coastguard Worker extern uint32_t nl_object_diff(struct nl_object *, struct nl_object *);
289*4dc78e53SAndroid Build Coastguard Worker extern int nl_object_match_filter(struct nl_object *, struct nl_object *);
290*4dc78e53SAndroid Build Coastguard Worker 
291*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
292*4dc78e53SAndroid Build Coastguard Worker extern char *nl_object_attrs2str(struct nl_object *, uint32_t, char *buf, size_t len);
293*4dc78e53SAndroid Build Coastguard Worker 
294*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
295*4dc78e53SAndroid Build Coastguard Worker extern char *nl_object_attr_list(struct nl_object *, char *buf, size_t len);
296*4dc78e53SAndroid Build Coastguard Worker 
297*4dc78e53SAndroid Build Coastguard Worker extern void nl_object_mark(struct nl_object *);
298*4dc78e53SAndroid Build Coastguard Worker extern void nl_object_unmark(struct nl_object *);
299*4dc78e53SAndroid Build Coastguard Worker extern int nl_object_is_marked(struct nl_object *);
300*4dc78e53SAndroid Build Coastguard Worker 
301*4dc78e53SAndroid Build Coastguard Worker extern int nl_object_get_refcnt(struct nl_object *);
302*4dc78e53SAndroid Build Coastguard Worker 
303*4dc78e53SAndroid Build Coastguard Worker /* <netlink/cache.h> */
304*4dc78e53SAndroid Build Coastguard Worker 
305*4dc78e53SAndroid Build Coastguard Worker typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int, void *);
306*4dc78e53SAndroid Build Coastguard Worker 
307*4dc78e53SAndroid Build Coastguard Worker %inline %{
alloc_cache_name(const char * name)308*4dc78e53SAndroid Build Coastguard Worker         struct nl_cache *alloc_cache_name(const char *name)
309*4dc78e53SAndroid Build Coastguard Worker         {
310*4dc78e53SAndroid Build Coastguard Worker                 struct nl_cache *c;
311*4dc78e53SAndroid Build Coastguard Worker                 if (nl_cache_alloc_name(name, &c) < 0)
312*4dc78e53SAndroid Build Coastguard Worker                         return NULL;
313*4dc78e53SAndroid Build Coastguard Worker                 return c;
314*4dc78e53SAndroid Build Coastguard Worker         }
315*4dc78e53SAndroid Build Coastguard Worker 
alloc_cache_mngr(struct nl_sock * sock,int protocol,int flags)316*4dc78e53SAndroid Build Coastguard Worker         struct nl_cache_mngr *alloc_cache_mngr(struct nl_sock *sock,
317*4dc78e53SAndroid Build Coastguard Worker                                                int protocol, int flags)
318*4dc78e53SAndroid Build Coastguard Worker         {
319*4dc78e53SAndroid Build Coastguard Worker                 struct nl_cache_mngr *mngr;
320*4dc78e53SAndroid Build Coastguard Worker 
321*4dc78e53SAndroid Build Coastguard Worker                 if (nl_cache_mngr_alloc(sock, protocol, flags, &mngr) < 0)
322*4dc78e53SAndroid Build Coastguard Worker                         return NULL;
323*4dc78e53SAndroid Build Coastguard Worker 
324*4dc78e53SAndroid Build Coastguard Worker                 return mngr;
325*4dc78e53SAndroid Build Coastguard Worker         }
326*4dc78e53SAndroid Build Coastguard Worker 
cache_mngr_add(struct nl_cache_mngr * mngr,const char * name,change_func_t func,void * arg)327*4dc78e53SAndroid Build Coastguard Worker         struct nl_cache *cache_mngr_add(struct nl_cache_mngr *mngr,
328*4dc78e53SAndroid Build Coastguard Worker                                         const char *name, change_func_t func,
329*4dc78e53SAndroid Build Coastguard Worker                                         void *arg)
330*4dc78e53SAndroid Build Coastguard Worker         {
331*4dc78e53SAndroid Build Coastguard Worker                 struct nl_cache *cache;
332*4dc78e53SAndroid Build Coastguard Worker 
333*4dc78e53SAndroid Build Coastguard Worker                 if (nl_cache_mngr_add(mngr, name, func, arg, &cache) < 0)
334*4dc78e53SAndroid Build Coastguard Worker                         return NULL;
335*4dc78e53SAndroid Build Coastguard Worker 
336*4dc78e53SAndroid Build Coastguard Worker                 return cache;
337*4dc78e53SAndroid Build Coastguard Worker         }
338*4dc78e53SAndroid Build Coastguard Worker %}
339*4dc78e53SAndroid Build Coastguard Worker 
340*4dc78e53SAndroid Build Coastguard Worker /* Access Functions */
341*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_nitems(struct nl_cache *);
342*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_nitems_filter(struct nl_cache *,
343*4dc78e53SAndroid Build Coastguard Worker 						       struct nl_object *);
344*4dc78e53SAndroid Build Coastguard Worker extern struct nl_cache_ops *	nl_cache_get_ops(struct nl_cache *);
345*4dc78e53SAndroid Build Coastguard Worker extern struct nl_object *	nl_cache_get_first(struct nl_cache *);
346*4dc78e53SAndroid Build Coastguard Worker extern struct nl_object *	nl_cache_get_last(struct nl_cache *);
347*4dc78e53SAndroid Build Coastguard Worker extern struct nl_object *	nl_cache_get_next(struct nl_object *);
348*4dc78e53SAndroid Build Coastguard Worker extern struct nl_object *	nl_cache_get_prev(struct nl_object *);
349*4dc78e53SAndroid Build Coastguard Worker 
350*4dc78e53SAndroid Build Coastguard Worker extern struct nl_cache *	nl_cache_alloc(struct nl_cache_ops *);
351*4dc78e53SAndroid Build Coastguard Worker extern struct nl_cache *	nl_cache_subset(struct nl_cache *,
352*4dc78e53SAndroid Build Coastguard Worker 						struct nl_object *);
353*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_clear(struct nl_cache *);
354*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_free(struct nl_cache *);
355*4dc78e53SAndroid Build Coastguard Worker 
356*4dc78e53SAndroid Build Coastguard Worker /* Cache modification */
357*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_add(struct nl_cache *,
358*4dc78e53SAndroid Build Coastguard Worker 					     struct nl_object *);
359*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_parse_and_add(struct nl_cache *,
360*4dc78e53SAndroid Build Coastguard Worker 						       struct nl_msg *);
361*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_remove(struct nl_object *);
362*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_refill(struct nl_sock *,
363*4dc78e53SAndroid Build Coastguard Worker 						struct nl_cache *);
364*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_pickup(struct nl_sock *,
365*4dc78e53SAndroid Build Coastguard Worker 						struct nl_cache *);
366*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_resync(struct nl_sock *,
367*4dc78e53SAndroid Build Coastguard Worker 						struct nl_cache *,
368*4dc78e53SAndroid Build Coastguard Worker 						change_func_t,
369*4dc78e53SAndroid Build Coastguard Worker 						void *);
370*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_include(struct nl_cache *,
371*4dc78e53SAndroid Build Coastguard Worker 						 struct nl_object *,
372*4dc78e53SAndroid Build Coastguard Worker 						 change_func_t,
373*4dc78e53SAndroid Build Coastguard Worker 						 void *);
374*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_set_arg1(struct nl_cache *, int);
375*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_set_arg2(struct nl_cache *, int);
376*4dc78e53SAndroid Build Coastguard Worker 
377*4dc78e53SAndroid Build Coastguard Worker /* General */
378*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_is_empty(struct nl_cache *);
379*4dc78e53SAndroid Build Coastguard Worker extern struct nl_object *	nl_cache_search(struct nl_cache *,
380*4dc78e53SAndroid Build Coastguard Worker 						struct nl_object *);
381*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_mark_all(struct nl_cache *);
382*4dc78e53SAndroid Build Coastguard Worker 
383*4dc78e53SAndroid Build Coastguard Worker /* Dumping */
384*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_dump(struct nl_cache *,
385*4dc78e53SAndroid Build Coastguard Worker 					      struct nl_dump_params *);
386*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_dump_filter(struct nl_cache *,
387*4dc78e53SAndroid Build Coastguard Worker 						     struct nl_dump_params *,
388*4dc78e53SAndroid Build Coastguard Worker 						     struct nl_object *);
389*4dc78e53SAndroid Build Coastguard Worker 
390*4dc78e53SAndroid Build Coastguard Worker /* Iterators */
391*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_foreach(struct nl_cache *,
392*4dc78e53SAndroid Build Coastguard Worker 						 void (*cb)(struct nl_object *,
393*4dc78e53SAndroid Build Coastguard Worker 							    void *),
394*4dc78e53SAndroid Build Coastguard Worker 						 void *arg);
395*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_foreach_filter(struct nl_cache *,
396*4dc78e53SAndroid Build Coastguard Worker 							struct nl_object *,
397*4dc78e53SAndroid Build Coastguard Worker 							void (*cb)(struct
398*4dc78e53SAndroid Build Coastguard Worker 								   nl_object *,
399*4dc78e53SAndroid Build Coastguard Worker 								   void *),
400*4dc78e53SAndroid Build Coastguard Worker 							void *arg);
401*4dc78e53SAndroid Build Coastguard Worker 
402*4dc78e53SAndroid Build Coastguard Worker /* --- cache management --- */
403*4dc78e53SAndroid Build Coastguard Worker 
404*4dc78e53SAndroid Build Coastguard Worker /* Cache type management */
405*4dc78e53SAndroid Build Coastguard Worker extern struct nl_cache_ops *	nl_cache_ops_lookup(const char *);
406*4dc78e53SAndroid Build Coastguard Worker extern struct nl_cache_ops *	nl_cache_ops_associate(int, int);
407*4dc78e53SAndroid Build Coastguard Worker extern struct nl_msgtype *	nl_msgtype_lookup(struct nl_cache_ops *, int);
408*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *);
409*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_mngt_register(struct nl_cache_ops *);
410*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_mngt_unregister(struct nl_cache_ops *);
411*4dc78e53SAndroid Build Coastguard Worker 
412*4dc78e53SAndroid Build Coastguard Worker /* Global cache provisioning/requiring */
413*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_mngt_provide(struct nl_cache *);
414*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_mngt_unprovide(struct nl_cache *);
415*4dc78e53SAndroid Build Coastguard Worker extern struct nl_cache *	nl_cache_mngt_require(const char *);
416*4dc78e53SAndroid Build Coastguard Worker 
417*4dc78e53SAndroid Build Coastguard Worker struct nl_cache_mngr;
418*4dc78e53SAndroid Build Coastguard Worker 
419*4dc78e53SAndroid Build Coastguard Worker #define NL_AUTO_PROVIDE		1
420*4dc78e53SAndroid Build Coastguard Worker 
421*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_mngr_get_fd(struct nl_cache_mngr *);
422*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_mngr_poll(struct nl_cache_mngr *,
423*4dc78e53SAndroid Build Coastguard Worker 						   int);
424*4dc78e53SAndroid Build Coastguard Worker extern int			nl_cache_mngr_data_ready(struct nl_cache_mngr *);
425*4dc78e53SAndroid Build Coastguard Worker extern void			nl_cache_mngr_free(struct nl_cache_mngr *);
426*4dc78e53SAndroid Build Coastguard Worker 
427*4dc78e53SAndroid Build Coastguard Worker /* <netlink/addr.h> */
428*4dc78e53SAndroid Build Coastguard Worker %inline %{
addr_parse(const char * addr,int guess)429*4dc78e53SAndroid Build Coastguard Worker         struct nl_addr *addr_parse(const char *addr, int guess)
430*4dc78e53SAndroid Build Coastguard Worker         {
431*4dc78e53SAndroid Build Coastguard Worker                 struct nl_addr *result;
432*4dc78e53SAndroid Build Coastguard Worker 
433*4dc78e53SAndroid Build Coastguard Worker                 if (nl_addr_parse(addr, guess, &result) < 0)
434*4dc78e53SAndroid Build Coastguard Worker                         return NULL;
435*4dc78e53SAndroid Build Coastguard Worker 
436*4dc78e53SAndroid Build Coastguard Worker                 return result;
437*4dc78e53SAndroid Build Coastguard Worker         }
438*4dc78e53SAndroid Build Coastguard Worker %};
439*4dc78e53SAndroid Build Coastguard Worker 
440*4dc78e53SAndroid Build Coastguard Worker extern struct nl_addr *nl_addr_alloc(size_t);
441*4dc78e53SAndroid Build Coastguard Worker extern struct nl_addr *nl_addr_alloc_attr(struct nlattr *, int);
442*4dc78e53SAndroid Build Coastguard Worker extern struct nl_addr *nl_addr_build(int, void *, size_t);
443*4dc78e53SAndroid Build Coastguard Worker extern struct nl_addr *nl_addr_clone(struct nl_addr *);
444*4dc78e53SAndroid Build Coastguard Worker 
445*4dc78e53SAndroid Build Coastguard Worker extern struct nl_addr *nl_addr_get(struct nl_addr *);
446*4dc78e53SAndroid Build Coastguard Worker extern void nl_addr_put(struct nl_addr *);
447*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_shared(struct nl_addr *);
448*4dc78e53SAndroid Build Coastguard Worker 
449*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_cmp(struct nl_addr *, struct nl_addr *);
450*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_cmp_prefix(struct nl_addr *, struct nl_addr *);
451*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_iszero(struct nl_addr *);
452*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_valid(char *, int);
453*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_guess_family(struct nl_addr *);
454*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_fill_sockaddr(struct nl_addr *, struct sockaddr *, socklen_t *);
455*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_info(struct nl_addr *, struct addrinfo **);
456*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen);
457*4dc78e53SAndroid Build Coastguard Worker 
458*4dc78e53SAndroid Build Coastguard Worker extern void nl_addr_set_family(struct nl_addr *, int);
459*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_get_family(struct nl_addr *);
460*4dc78e53SAndroid Build Coastguard Worker extern int nl_addr_set_binary_addr(struct nl_addr *, void *, size_t);
461*4dc78e53SAndroid Build Coastguard Worker 
462*4dc78e53SAndroid Build Coastguard Worker extern void *nl_addr_get_binary_addr(struct nl_addr *);
463*4dc78e53SAndroid Build Coastguard Worker extern unsigned int nl_addr_get_len(struct nl_addr *);
464*4dc78e53SAndroid Build Coastguard Worker extern void nl_addr_set_prefixlen(struct nl_addr *, int);
465*4dc78e53SAndroid Build Coastguard Worker extern unsigned int nl_addr_get_prefixlen(struct nl_addr *);
466*4dc78e53SAndroid Build Coastguard Worker 
467*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
468*4dc78e53SAndroid Build Coastguard Worker extern char *nl_af2str(int, char *buf, size_t len);
469*4dc78e53SAndroid Build Coastguard Worker extern int nl_str2af(const char *);
470*4dc78e53SAndroid Build Coastguard Worker 
471*4dc78e53SAndroid Build Coastguard Worker %cstring_output_maxsize(char *buf, size_t len)
472*4dc78e53SAndroid Build Coastguard Worker extern char *nl_addr2str(struct nl_addr *, char *buf, size_t len);
473*4dc78e53SAndroid Build Coastguard Worker 
474*4dc78e53SAndroid Build Coastguard Worker /* Message Handlers <netlink/handlers.h> */
475*4dc78e53SAndroid Build Coastguard Worker /**
476*4dc78e53SAndroid Build Coastguard Worker  * Callback actions
477*4dc78e53SAndroid Build Coastguard Worker  * @ingroup cb
478*4dc78e53SAndroid Build Coastguard Worker  */
479*4dc78e53SAndroid Build Coastguard Worker enum nl_cb_action {
480*4dc78e53SAndroid Build Coastguard Worker 	/** Proceed with wathever would come next */
481*4dc78e53SAndroid Build Coastguard Worker 	NL_OK,
482*4dc78e53SAndroid Build Coastguard Worker 	/** Skip this message */
483*4dc78e53SAndroid Build Coastguard Worker 	NL_SKIP,
484*4dc78e53SAndroid Build Coastguard Worker 	/** Stop parsing altogether and discard remaining messages */
485*4dc78e53SAndroid Build Coastguard Worker 	NL_STOP,
486*4dc78e53SAndroid Build Coastguard Worker };
487*4dc78e53SAndroid Build Coastguard Worker 
488*4dc78e53SAndroid Build Coastguard Worker /**
489*4dc78e53SAndroid Build Coastguard Worker  * Callback kinds
490*4dc78e53SAndroid Build Coastguard Worker  * @ingroup cb
491*4dc78e53SAndroid Build Coastguard Worker  */
492*4dc78e53SAndroid Build Coastguard Worker enum nl_cb_kind {
493*4dc78e53SAndroid Build Coastguard Worker 	/** Default handlers (quiet) */
494*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_DEFAULT,
495*4dc78e53SAndroid Build Coastguard Worker 	/** Verbose default handlers (error messages printed) */
496*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_VERBOSE,
497*4dc78e53SAndroid Build Coastguard Worker 	/** Debug handlers for debugging */
498*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_DEBUG,
499*4dc78e53SAndroid Build Coastguard Worker 	/** Customized handler specified by the user */
500*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_CUSTOM,
501*4dc78e53SAndroid Build Coastguard Worker 	__NL_CB_KIND_MAX,
502*4dc78e53SAndroid Build Coastguard Worker };
503*4dc78e53SAndroid Build Coastguard Worker 
504*4dc78e53SAndroid Build Coastguard Worker #define NL_CB_KIND_MAX (__NL_CB_KIND_MAX - 1)
505*4dc78e53SAndroid Build Coastguard Worker 
506*4dc78e53SAndroid Build Coastguard Worker /**
507*4dc78e53SAndroid Build Coastguard Worker  * Callback types
508*4dc78e53SAndroid Build Coastguard Worker  * @ingroup cb
509*4dc78e53SAndroid Build Coastguard Worker  */
510*4dc78e53SAndroid Build Coastguard Worker enum nl_cb_type {
511*4dc78e53SAndroid Build Coastguard Worker 	/** Message is valid */
512*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_VALID,
513*4dc78e53SAndroid Build Coastguard Worker 	/** Last message in a series of multi part messages received */
514*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_FINISH,
515*4dc78e53SAndroid Build Coastguard Worker 	/** Report received that data was lost */
516*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_OVERRUN,
517*4dc78e53SAndroid Build Coastguard Worker 	/** Message wants to be skipped */
518*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_SKIPPED,
519*4dc78e53SAndroid Build Coastguard Worker 	/** Message is an acknowledge */
520*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_ACK,
521*4dc78e53SAndroid Build Coastguard Worker 	/** Called for every message received */
522*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_MSG_IN,
523*4dc78e53SAndroid Build Coastguard Worker 	/** Called for every message sent out except for nl_sendto() */
524*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_MSG_OUT,
525*4dc78e53SAndroid Build Coastguard Worker 	/** Message is malformed and invalid */
526*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_INVALID,
527*4dc78e53SAndroid Build Coastguard Worker 	/** Called instead of internal sequence number checking */
528*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_SEQ_CHECK,
529*4dc78e53SAndroid Build Coastguard Worker 	/** Sending of an acknowledge message has been requested */
530*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_SEND_ACK,
531*4dc78e53SAndroid Build Coastguard Worker 	/** Flag NLM_F_DUMP_INTR is set in message */
532*4dc78e53SAndroid Build Coastguard Worker 	NL_CB_DUMP_INTR,
533*4dc78e53SAndroid Build Coastguard Worker 	__NL_CB_TYPE_MAX,
534*4dc78e53SAndroid Build Coastguard Worker };
535*4dc78e53SAndroid Build Coastguard Worker 
536*4dc78e53SAndroid Build Coastguard Worker #define NL_CB_TYPE_MAX (__NL_CB_TYPE_MAX - 1)
537*4dc78e53SAndroid Build Coastguard Worker 
538*4dc78e53SAndroid Build Coastguard Worker extern struct nl_cb *nl_cb_alloc(enum nl_cb_kind);
539*4dc78e53SAndroid Build Coastguard Worker extern struct nl_cb *nl_cb_clone(struct nl_cb *);
540*4dc78e53SAndroid Build Coastguard Worker 
541*4dc78e53SAndroid Build Coastguard Worker struct nlmsgerr {
542*4dc78e53SAndroid Build Coastguard Worker 	int error;
543*4dc78e53SAndroid Build Coastguard Worker };
544*4dc78e53SAndroid Build Coastguard Worker 
545*4dc78e53SAndroid Build Coastguard Worker %{
546*4dc78e53SAndroid Build Coastguard Worker 
547*4dc78e53SAndroid Build Coastguard Worker struct pynl_callback {
548*4dc78e53SAndroid Build Coastguard Worker 	PyObject *cbf;
549*4dc78e53SAndroid Build Coastguard Worker 	PyObject *cba;
550*4dc78e53SAndroid Build Coastguard Worker };
551*4dc78e53SAndroid Build Coastguard Worker 
552*4dc78e53SAndroid Build Coastguard Worker struct pynl_cbinfo {
553*4dc78e53SAndroid Build Coastguard Worker 	struct nl_cb *cb;
554*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_callback cbtype[NL_CB_TYPE_MAX+1];
555*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_callback cberr;
556*4dc78e53SAndroid Build Coastguard Worker 	struct list_head list;
557*4dc78e53SAndroid Build Coastguard Worker };
558*4dc78e53SAndroid Build Coastguard Worker 
559*4dc78e53SAndroid Build Coastguard Worker LIST_HEAD(callback_list);
560*4dc78e53SAndroid Build Coastguard Worker 
pynl_find_cbinfo(struct nl_cb * cb,int unlink)561*4dc78e53SAndroid Build Coastguard Worker static struct pynl_cbinfo *pynl_find_cbinfo(struct nl_cb *cb, int unlink)
562*4dc78e53SAndroid Build Coastguard Worker {
563*4dc78e53SAndroid Build Coastguard Worker 	struct list_head *pos, *prev;
564*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_cbinfo *info;
565*4dc78e53SAndroid Build Coastguard Worker 
566*4dc78e53SAndroid Build Coastguard Worker 	list_for_each_safe(pos, prev, &callback_list) {
567*4dc78e53SAndroid Build Coastguard Worker 		info = container_of(pos, struct pynl_cbinfo, list);
568*4dc78e53SAndroid Build Coastguard Worker 		if (info->cb == cb) {
569*4dc78e53SAndroid Build Coastguard Worker 			if (unlink)
570*4dc78e53SAndroid Build Coastguard Worker 				list_del(pos, prev);
571*4dc78e53SAndroid Build Coastguard Worker 			pynl_dbg("cb=%p: found=%p\n", cb, info);
572*4dc78e53SAndroid Build Coastguard Worker 			return info;
573*4dc78e53SAndroid Build Coastguard Worker 		}
574*4dc78e53SAndroid Build Coastguard Worker 	}
575*4dc78e53SAndroid Build Coastguard Worker 	pynl_dbg("cb=%p: not found\n", cb);
576*4dc78e53SAndroid Build Coastguard Worker 	return NULL;
577*4dc78e53SAndroid Build Coastguard Worker }
578*4dc78e53SAndroid Build Coastguard Worker 
pynl_get_cbinfo(struct nl_cb * cb,int unlink)579*4dc78e53SAndroid Build Coastguard Worker static struct pynl_cbinfo *pynl_get_cbinfo(struct nl_cb *cb, int unlink)
580*4dc78e53SAndroid Build Coastguard Worker {
581*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_cbinfo *info;
582*4dc78e53SAndroid Build Coastguard Worker 
583*4dc78e53SAndroid Build Coastguard Worker 	info = pynl_find_cbinfo(cb, unlink);
584*4dc78e53SAndroid Build Coastguard Worker 
585*4dc78e53SAndroid Build Coastguard Worker 	if (info || unlink) {
586*4dc78e53SAndroid Build Coastguard Worker 		/* found or no need to allocate a new one */
587*4dc78e53SAndroid Build Coastguard Worker 		pynl_dbg("cb=%p: done\n", cb);
588*4dc78e53SAndroid Build Coastguard Worker 		return info;
589*4dc78e53SAndroid Build Coastguard Worker 	}
590*4dc78e53SAndroid Build Coastguard Worker 
591*4dc78e53SAndroid Build Coastguard Worker 	info = calloc(1, sizeof(*info));
592*4dc78e53SAndroid Build Coastguard Worker 	info->cb = cb;
593*4dc78e53SAndroid Build Coastguard Worker 	list_add(&info->list, &callback_list);
594*4dc78e53SAndroid Build Coastguard Worker 	pynl_dbg("cb=%p: added %p\n", cb, info);
595*4dc78e53SAndroid Build Coastguard Worker 	return info;
596*4dc78e53SAndroid Build Coastguard Worker }
597*4dc78e53SAndroid Build Coastguard Worker 
nl_recv_msg_handler(struct nl_msg * msg,void * arg)598*4dc78e53SAndroid Build Coastguard Worker static int nl_recv_msg_handler(struct nl_msg *msg, void *arg)
599*4dc78e53SAndroid Build Coastguard Worker {
600*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_callback *cbd = arg;
601*4dc78e53SAndroid Build Coastguard Worker 	PyObject *msgobj;
602*4dc78e53SAndroid Build Coastguard Worker 	PyObject *cbparobj;
603*4dc78e53SAndroid Build Coastguard Worker 	PyObject *resobj;
604*4dc78e53SAndroid Build Coastguard Worker 	PyObject *funcobj;
605*4dc78e53SAndroid Build Coastguard Worker 	int result;
606*4dc78e53SAndroid Build Coastguard Worker 
607*4dc78e53SAndroid Build Coastguard Worker 	if (!cbd) {
608*4dc78e53SAndroid Build Coastguard Worker 		result = NL_STOP;
609*4dc78e53SAndroid Build Coastguard Worker 		goto done;
610*4dc78e53SAndroid Build Coastguard Worker 	}
611*4dc78e53SAndroid Build Coastguard Worker 	msgobj = SWIG_NewPointerObj(SWIG_as_voidptr(msg),
612*4dc78e53SAndroid Build Coastguard Worker 				    SWIGTYPE_p_nl_msg, 0 |  0 );
613*4dc78e53SAndroid Build Coastguard Worker 	/* add selfobj if callback is a method */
614*4dc78e53SAndroid Build Coastguard Worker 	if (cbd->cbf && PyMethod_Check(cbd->cbf)) {
615*4dc78e53SAndroid Build Coastguard Worker 		PyObject *selfobj = PyMethod_Self(cbd->cbf);
616*4dc78e53SAndroid Build Coastguard Worker 		cbparobj = Py_BuildValue("(OOO)", selfobj ? selfobj : cbd->cba,
617*4dc78e53SAndroid Build Coastguard Worker 					 msgobj, cbd->cba);
618*4dc78e53SAndroid Build Coastguard Worker 		funcobj = PyMethod_Function(cbd->cbf);
619*4dc78e53SAndroid Build Coastguard Worker 		pynl_dbg("callback %sbounded instance method %p\n",
620*4dc78e53SAndroid Build Coastguard Worker 			 selfobj ? "" : "un", funcobj);
621*4dc78e53SAndroid Build Coastguard Worker 	} else {
622*4dc78e53SAndroid Build Coastguard Worker 		cbparobj = Py_BuildValue("(OO)", msgobj, cbd->cba);
623*4dc78e53SAndroid Build Coastguard Worker 		funcobj = cbd->cbf;
624*4dc78e53SAndroid Build Coastguard Worker 		pynl_dbg("callback function %p\n", funcobj);
625*4dc78e53SAndroid Build Coastguard Worker 	}
626*4dc78e53SAndroid Build Coastguard Worker 	resobj = PyObject_CallObject(funcobj, cbparobj);
627*4dc78e53SAndroid Build Coastguard Worker 	Py_DECREF(cbparobj);
628*4dc78e53SAndroid Build Coastguard Worker 	if (resobj && PyInt_Check(resobj))
629*4dc78e53SAndroid Build Coastguard Worker 		result = (int)PyInt_AsLong(resobj);
630*4dc78e53SAndroid Build Coastguard Worker 	else
631*4dc78e53SAndroid Build Coastguard Worker 		result = NL_STOP;
632*4dc78e53SAndroid Build Coastguard Worker 	Py_XDECREF(resobj);
633*4dc78e53SAndroid Build Coastguard Worker done:
634*4dc78e53SAndroid Build Coastguard Worker 	pynl_dbg("result=%d\n", result);
635*4dc78e53SAndroid Build Coastguard Worker 	return result;
636*4dc78e53SAndroid Build Coastguard Worker }
637*4dc78e53SAndroid Build Coastguard Worker 
nl_recv_err_handler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)638*4dc78e53SAndroid Build Coastguard Worker static int nl_recv_err_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
639*4dc78e53SAndroid Build Coastguard Worker 			       void *arg)
640*4dc78e53SAndroid Build Coastguard Worker {
641*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_callback *cbd = arg;
642*4dc78e53SAndroid Build Coastguard Worker 	PyObject *errobj;
643*4dc78e53SAndroid Build Coastguard Worker 	PyObject *cbparobj;
644*4dc78e53SAndroid Build Coastguard Worker 	PyObject *resobj;
645*4dc78e53SAndroid Build Coastguard Worker 	PyObject *funcobj;
646*4dc78e53SAndroid Build Coastguard Worker 	int result;
647*4dc78e53SAndroid Build Coastguard Worker 
648*4dc78e53SAndroid Build Coastguard Worker 	if (!cbd)
649*4dc78e53SAndroid Build Coastguard Worker 		return NL_STOP;
650*4dc78e53SAndroid Build Coastguard Worker 	errobj = SWIG_NewPointerObj(SWIG_as_voidptr(err),
651*4dc78e53SAndroid Build Coastguard Worker 				    SWIGTYPE_p_nlmsgerr, 0 |  0 );
652*4dc78e53SAndroid Build Coastguard Worker 	/* add selfobj if callback is a method */
653*4dc78e53SAndroid Build Coastguard Worker 	if (cbd->cbf && PyMethod_Check(cbd->cbf)) {
654*4dc78e53SAndroid Build Coastguard Worker 		PyObject *selfobj = PyMethod_Self(cbd->cbf);
655*4dc78e53SAndroid Build Coastguard Worker 		cbparobj = Py_BuildValue("(OOO)", selfobj ? selfobj : cbd->cba,
656*4dc78e53SAndroid Build Coastguard Worker 					 errobj, cbd->cba);
657*4dc78e53SAndroid Build Coastguard Worker 		funcobj = PyMethod_Function(cbd->cbf);
658*4dc78e53SAndroid Build Coastguard Worker 	} else {
659*4dc78e53SAndroid Build Coastguard Worker 		cbparobj = Py_BuildValue("(OO)", errobj, cbd->cba);
660*4dc78e53SAndroid Build Coastguard Worker 		funcobj = cbd->cbf;
661*4dc78e53SAndroid Build Coastguard Worker 	}
662*4dc78e53SAndroid Build Coastguard Worker 	resobj = PyObject_CallObject(funcobj, cbparobj);
663*4dc78e53SAndroid Build Coastguard Worker 	Py_DECREF(cbparobj);
664*4dc78e53SAndroid Build Coastguard Worker 	if (resobj && PyInt_Check(resobj))
665*4dc78e53SAndroid Build Coastguard Worker 		result = (int)PyInt_AsLong(resobj);
666*4dc78e53SAndroid Build Coastguard Worker 	else
667*4dc78e53SAndroid Build Coastguard Worker 		result = NL_STOP;
668*4dc78e53SAndroid Build Coastguard Worker 	Py_XDECREF(resobj);
669*4dc78e53SAndroid Build Coastguard Worker 	pynl_dbg("error: err=%d ret=%d\n", err->error, result);
670*4dc78e53SAndroid Build Coastguard Worker 	return result;
671*4dc78e53SAndroid Build Coastguard Worker }
672*4dc78e53SAndroid Build Coastguard Worker 
673*4dc78e53SAndroid Build Coastguard Worker %}
674*4dc78e53SAndroid Build Coastguard Worker %inline %{
py_nl_cb_clone(struct nl_cb * cb)675*4dc78e53SAndroid Build Coastguard Worker struct nl_cb *py_nl_cb_clone(struct nl_cb *cb)
676*4dc78e53SAndroid Build Coastguard Worker {
677*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_cbinfo *info, *clone_info;
678*4dc78e53SAndroid Build Coastguard Worker 	struct nl_cb *clone;
679*4dc78e53SAndroid Build Coastguard Worker 	int i;
680*4dc78e53SAndroid Build Coastguard Worker 
681*4dc78e53SAndroid Build Coastguard Worker 	clone = nl_cb_clone(cb);
682*4dc78e53SAndroid Build Coastguard Worker 	info = pynl_find_cbinfo(cb, 0);
683*4dc78e53SAndroid Build Coastguard Worker 	if (info) {
684*4dc78e53SAndroid Build Coastguard Worker 		clone_info = pynl_get_cbinfo(clone, 0);
685*4dc78e53SAndroid Build Coastguard Worker 		/* increase refcnt to callback parameters and copy them */
686*4dc78e53SAndroid Build Coastguard Worker 		for (i = 0; info && i <= NL_CB_TYPE_MAX; i++) {
687*4dc78e53SAndroid Build Coastguard Worker 			Py_XINCREF(info->cbtype[i].cbf);
688*4dc78e53SAndroid Build Coastguard Worker 			Py_XINCREF(info->cbtype[i].cba);
689*4dc78e53SAndroid Build Coastguard Worker 			clone_info->cbtype[i].cbf = info->cbtype[i].cbf;
690*4dc78e53SAndroid Build Coastguard Worker 			clone_info->cbtype[i].cba = info->cbtype[i].cba;
691*4dc78e53SAndroid Build Coastguard Worker 		}
692*4dc78e53SAndroid Build Coastguard Worker 		Py_XINCREF(info->cberr.cbf);
693*4dc78e53SAndroid Build Coastguard Worker 		Py_XINCREF(info->cberr.cba);
694*4dc78e53SAndroid Build Coastguard Worker 		clone_info->cberr.cbf = info->cberr.cbf;
695*4dc78e53SAndroid Build Coastguard Worker 		clone_info->cberr.cba = info->cberr.cba;
696*4dc78e53SAndroid Build Coastguard Worker 	}
697*4dc78e53SAndroid Build Coastguard Worker 	return clone;
698*4dc78e53SAndroid Build Coastguard Worker }
699*4dc78e53SAndroid Build Coastguard Worker 
py_nl_cb_put(struct nl_cb * cb)700*4dc78e53SAndroid Build Coastguard Worker void py_nl_cb_put(struct nl_cb *cb)
701*4dc78e53SAndroid Build Coastguard Worker {
702*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_cbinfo *info;
703*4dc78e53SAndroid Build Coastguard Worker 	int i;
704*4dc78e53SAndroid Build Coastguard Worker 
705*4dc78e53SAndroid Build Coastguard Worker 	/* obtain callback info (and unlink) */
706*4dc78e53SAndroid Build Coastguard Worker 	info = pynl_get_cbinfo(cb, 1);
707*4dc78e53SAndroid Build Coastguard Worker 	pynl_dbg("cb=%p, info=%p\n", cb, info);
708*4dc78e53SAndroid Build Coastguard Worker 	/* decrease refcnt for callback type handlers */
709*4dc78e53SAndroid Build Coastguard Worker 	for (i = 0; info && i <= NL_CB_TYPE_MAX; i++) {
710*4dc78e53SAndroid Build Coastguard Worker 		Py_XDECREF(info->cbtype[i].cbf);
711*4dc78e53SAndroid Build Coastguard Worker 		Py_XDECREF(info->cbtype[i].cba);
712*4dc78e53SAndroid Build Coastguard Worker 	}
713*4dc78e53SAndroid Build Coastguard Worker 	/* decrease refcnt for error handler and free callback info */
714*4dc78e53SAndroid Build Coastguard Worker 	if (info) {
715*4dc78e53SAndroid Build Coastguard Worker 		Py_XDECREF(info->cberr.cbf);
716*4dc78e53SAndroid Build Coastguard Worker 		Py_XDECREF(info->cberr.cba);
717*4dc78e53SAndroid Build Coastguard Worker 		free(info);
718*4dc78e53SAndroid Build Coastguard Worker 	}
719*4dc78e53SAndroid Build Coastguard Worker 	nl_cb_put(cb);
720*4dc78e53SAndroid Build Coastguard Worker }
721*4dc78e53SAndroid Build Coastguard Worker 
py_nl_cb_set(struct nl_cb * cb,enum nl_cb_type t,enum nl_cb_kind k,PyObject * func,PyObject * a)722*4dc78e53SAndroid Build Coastguard Worker int py_nl_cb_set(struct nl_cb *cb, enum nl_cb_type t, enum nl_cb_kind k,
723*4dc78e53SAndroid Build Coastguard Worker 		PyObject *func, PyObject *a)
724*4dc78e53SAndroid Build Coastguard Worker {
725*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_cbinfo *info;
726*4dc78e53SAndroid Build Coastguard Worker 
727*4dc78e53SAndroid Build Coastguard Worker 	/* obtain callback info */
728*4dc78e53SAndroid Build Coastguard Worker 	info = pynl_get_cbinfo(cb, 0);
729*4dc78e53SAndroid Build Coastguard Worker 
730*4dc78e53SAndroid Build Coastguard Worker 	/* clear existing handlers (if any) */
731*4dc78e53SAndroid Build Coastguard Worker 	Py_XDECREF(info->cbtype[t].cbf);
732*4dc78e53SAndroid Build Coastguard Worker 	Py_XDECREF(info->cbtype[t].cba);
733*4dc78e53SAndroid Build Coastguard Worker 	info->cbtype[t].cbf = NULL;
734*4dc78e53SAndroid Build Coastguard Worker 	info->cbtype[t].cba = NULL;
735*4dc78e53SAndroid Build Coastguard Worker 	pynl_dbg("cb=%p, info=%p, type=%d, kind=%d\n", cb, info, t, k);
736*4dc78e53SAndroid Build Coastguard Worker 	/* handle custom callback */
737*4dc78e53SAndroid Build Coastguard Worker 	if (k == NL_CB_CUSTOM) {
738*4dc78e53SAndroid Build Coastguard Worker 		Py_XINCREF(func);
739*4dc78e53SAndroid Build Coastguard Worker 		Py_XINCREF(a);
740*4dc78e53SAndroid Build Coastguard Worker 		info->cbtype[t].cbf = func;
741*4dc78e53SAndroid Build Coastguard Worker 		info->cbtype[t].cba = a;
742*4dc78e53SAndroid Build Coastguard Worker 		return nl_cb_set(cb, t, k,
743*4dc78e53SAndroid Build Coastguard Worker 				 nl_recv_msg_handler, &info->cbtype[t]);
744*4dc78e53SAndroid Build Coastguard Worker 	}
745*4dc78e53SAndroid Build Coastguard Worker 	return nl_cb_set(cb, t, k,  NULL, NULL);
746*4dc78e53SAndroid Build Coastguard Worker }
747*4dc78e53SAndroid Build Coastguard Worker 
py_nl_cb_set_all(struct nl_cb * cb,enum nl_cb_kind k,PyObject * func,PyObject * a)748*4dc78e53SAndroid Build Coastguard Worker int py_nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind k,
749*4dc78e53SAndroid Build Coastguard Worker 		    PyObject *func , PyObject *a)
750*4dc78e53SAndroid Build Coastguard Worker {
751*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_cbinfo *info;
752*4dc78e53SAndroid Build Coastguard Worker 	int t;
753*4dc78e53SAndroid Build Coastguard Worker 
754*4dc78e53SAndroid Build Coastguard Worker 	info = pynl_get_cbinfo(cb, 0);
755*4dc78e53SAndroid Build Coastguard Worker 	pynl_dbg("cb=%p, info=%p, kind=%d\n", cb, info, k);
756*4dc78e53SAndroid Build Coastguard Worker 	for (t = 0; t <= NL_CB_TYPE_MAX; t++) {
757*4dc78e53SAndroid Build Coastguard Worker 		/* (possibly) free existing handler */
758*4dc78e53SAndroid Build Coastguard Worker 		Py_XDECREF(info->cbtype[t].cbf);
759*4dc78e53SAndroid Build Coastguard Worker 		Py_XDECREF(info->cbtype[t].cba);
760*4dc78e53SAndroid Build Coastguard Worker 		info->cbtype[t].cbf = NULL;
761*4dc78e53SAndroid Build Coastguard Worker 		info->cbtype[t].cba = NULL;
762*4dc78e53SAndroid Build Coastguard Worker 		if (k == NL_CB_CUSTOM) {
763*4dc78e53SAndroid Build Coastguard Worker 			Py_XINCREF(func);
764*4dc78e53SAndroid Build Coastguard Worker 			Py_XINCREF(a);
765*4dc78e53SAndroid Build Coastguard Worker 			info->cbtype[t].cbf = func;
766*4dc78e53SAndroid Build Coastguard Worker 			info->cbtype[t].cba = a;
767*4dc78e53SAndroid Build Coastguard Worker 		}
768*4dc78e53SAndroid Build Coastguard Worker 	}
769*4dc78e53SAndroid Build Coastguard Worker 	if (k == NL_CB_CUSTOM)
770*4dc78e53SAndroid Build Coastguard Worker 		/* callback argument is same for all so using idx 0 here */
771*4dc78e53SAndroid Build Coastguard Worker 		return nl_cb_set_all(cb, k, nl_recv_msg_handler,
772*4dc78e53SAndroid Build Coastguard Worker 				     &info->cbtype[0]);
773*4dc78e53SAndroid Build Coastguard Worker 	else
774*4dc78e53SAndroid Build Coastguard Worker 		return nl_cb_set_all(cb, k, NULL, NULL);
775*4dc78e53SAndroid Build Coastguard Worker }
776*4dc78e53SAndroid Build Coastguard Worker 
py_nl_cb_err(struct nl_cb * cb,enum nl_cb_kind k,PyObject * func,PyObject * a)777*4dc78e53SAndroid Build Coastguard Worker int py_nl_cb_err(struct nl_cb *cb, enum nl_cb_kind k,
778*4dc78e53SAndroid Build Coastguard Worker 		PyObject *func, PyObject *a)
779*4dc78e53SAndroid Build Coastguard Worker {
780*4dc78e53SAndroid Build Coastguard Worker 	struct pynl_cbinfo *info;
781*4dc78e53SAndroid Build Coastguard Worker 
782*4dc78e53SAndroid Build Coastguard Worker 	/* obtain callback info */
783*4dc78e53SAndroid Build Coastguard Worker 	info = pynl_get_cbinfo(cb, 0);
784*4dc78e53SAndroid Build Coastguard Worker 	pynl_dbg("cb=%p, info=%p, kind=%d\n", cb, info, k);
785*4dc78e53SAndroid Build Coastguard Worker 	/* clear existing handlers (if any) */
786*4dc78e53SAndroid Build Coastguard Worker 	Py_XDECREF(info->cberr.cbf);
787*4dc78e53SAndroid Build Coastguard Worker 	Py_XDECREF(info->cberr.cba);
788*4dc78e53SAndroid Build Coastguard Worker 	info->cberr.cbf = NULL;
789*4dc78e53SAndroid Build Coastguard Worker 	info->cberr.cba = NULL;
790*4dc78e53SAndroid Build Coastguard Worker 
791*4dc78e53SAndroid Build Coastguard Worker 	/* handle custom callback */
792*4dc78e53SAndroid Build Coastguard Worker 	if (k == NL_CB_CUSTOM) {
793*4dc78e53SAndroid Build Coastguard Worker 		Py_XINCREF(func);
794*4dc78e53SAndroid Build Coastguard Worker 		Py_XINCREF(a);
795*4dc78e53SAndroid Build Coastguard Worker 		info->cberr.cbf = func;
796*4dc78e53SAndroid Build Coastguard Worker 		info->cberr.cba = a;
797*4dc78e53SAndroid Build Coastguard Worker 		return nl_cb_err(cb, k,
798*4dc78e53SAndroid Build Coastguard Worker 				 nl_recv_err_handler, &info->cberr);
799*4dc78e53SAndroid Build Coastguard Worker 	}
800*4dc78e53SAndroid Build Coastguard Worker 	return nl_cb_err(cb, k,  NULL, NULL);
801*4dc78e53SAndroid Build Coastguard Worker }
802*4dc78e53SAndroid Build Coastguard Worker %}
803*4dc78e53SAndroid Build Coastguard Worker 
804*4dc78e53SAndroid Build Coastguard Worker /* Attributes <netlink/attr.h> */
805*4dc78e53SAndroid Build Coastguard Worker /*
806*4dc78e53SAndroid Build Coastguard Worker  * This typemap is a bit tricky as it uses arg1, which is knowledge about
807*4dc78e53SAndroid Build Coastguard Worker  * the SWIGged wrapper output.
808*4dc78e53SAndroid Build Coastguard Worker  */
809*4dc78e53SAndroid Build Coastguard Worker %typemap(out) void * {
810*4dc78e53SAndroid Build Coastguard Worker 	$result = PyByteArray_FromStringAndSize($1, nla_len(arg1));
811*4dc78e53SAndroid Build Coastguard Worker }
812*4dc78e53SAndroid Build Coastguard Worker extern void *nla_data(struct nlattr *);
813*4dc78e53SAndroid Build Coastguard Worker %typemap(out) void *;
814*4dc78e53SAndroid Build Coastguard Worker extern int		nla_type(const struct nlattr *);
815*4dc78e53SAndroid Build Coastguard Worker 
816*4dc78e53SAndroid Build Coastguard Worker %typemap(in) (int, const void *) {
817*4dc78e53SAndroid Build Coastguard Worker 	$1 = Py_SIZE($input);
818*4dc78e53SAndroid Build Coastguard Worker 	if (PyByteArray_Check($input)) {
819*4dc78e53SAndroid Build Coastguard Worker 		$2 = ($2_ltype)PyByteArray_AsString($input);
820*4dc78e53SAndroid Build Coastguard Worker 	} else if (PyString_Check($input)) {
821*4dc78e53SAndroid Build Coastguard Worker 		$2 = ($2_ltype)PyString_AsString($input);
822*4dc78e53SAndroid Build Coastguard Worker 	} else
823*4dc78e53SAndroid Build Coastguard Worker 		SWIG_exception(SWIG_TypeError,
824*4dc78e53SAndroid Build Coastguard Worker 			       "pointer must be bytearray or string.");
825*4dc78e53SAndroid Build Coastguard Worker }
826*4dc78e53SAndroid Build Coastguard Worker extern int              nla_put(struct nl_msg *, int, int, const void *);
827*4dc78e53SAndroid Build Coastguard Worker %typemap(in) const void *;
828*4dc78e53SAndroid Build Coastguard Worker 
829*4dc78e53SAndroid Build Coastguard Worker /* Integer attribute */
830*4dc78e53SAndroid Build Coastguard Worker extern uint8_t		nla_get_u8(struct nlattr *);
831*4dc78e53SAndroid Build Coastguard Worker extern int		nla_put_u8(struct nl_msg *, int, uint8_t);
832*4dc78e53SAndroid Build Coastguard Worker extern uint16_t		nla_get_u16(struct nlattr *);
833*4dc78e53SAndroid Build Coastguard Worker extern int		nla_put_u16(struct nl_msg *, int, uint16_t);
834*4dc78e53SAndroid Build Coastguard Worker extern uint32_t		nla_get_u32(struct nlattr *);
835*4dc78e53SAndroid Build Coastguard Worker extern int		nla_put_u32(struct nl_msg *, int, uint32_t);
836*4dc78e53SAndroid Build Coastguard Worker extern uint64_t		nla_get_u64(struct nlattr *);
837*4dc78e53SAndroid Build Coastguard Worker extern int		nla_put_u64(struct nl_msg *, int, uint64_t);
838*4dc78e53SAndroid Build Coastguard Worker 
839*4dc78e53SAndroid Build Coastguard Worker /* String attribute */
840*4dc78e53SAndroid Build Coastguard Worker extern char *		nla_get_string(struct nlattr *);
841*4dc78e53SAndroid Build Coastguard Worker extern char *		nla_strdup(struct nlattr *);
842*4dc78e53SAndroid Build Coastguard Worker extern int		nla_put_string(struct nl_msg *, int, const char *);
843*4dc78e53SAndroid Build Coastguard Worker 
844*4dc78e53SAndroid Build Coastguard Worker /* Flag attribute */
845*4dc78e53SAndroid Build Coastguard Worker extern int		nla_get_flag(struct nlattr *);
846*4dc78e53SAndroid Build Coastguard Worker extern int		nla_put_flag(struct nl_msg *, int);
847*4dc78e53SAndroid Build Coastguard Worker 
848*4dc78e53SAndroid Build Coastguard Worker /* Msec attribute */
849*4dc78e53SAndroid Build Coastguard Worker extern unsigned long	nla_get_msecs(struct nlattr *);
850*4dc78e53SAndroid Build Coastguard Worker extern int		nla_put_msecs(struct nl_msg *, int, unsigned long);
851*4dc78e53SAndroid Build Coastguard Worker 
852*4dc78e53SAndroid Build Coastguard Worker /* Attribute nesting */
853*4dc78e53SAndroid Build Coastguard Worker extern int		nla_put_nested(struct nl_msg *, int, struct nl_msg *);
854*4dc78e53SAndroid Build Coastguard Worker extern struct nlattr *	nla_nest_start(struct nl_msg *, int);
855*4dc78e53SAndroid Build Coastguard Worker extern int		nla_nest_end(struct nl_msg *, struct nlattr *);
856*4dc78e53SAndroid Build Coastguard Worker %inline %{
py_nla_parse_nested(int max,struct nlattr * nest_attr,PyObject * p)857*4dc78e53SAndroid Build Coastguard Worker PyObject *py_nla_parse_nested(int max, struct nlattr *nest_attr, PyObject *p)
858*4dc78e53SAndroid Build Coastguard Worker {
859*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *tb_msg[max + 1];
860*4dc78e53SAndroid Build Coastguard Worker 	struct nla_policy *policy = NULL;
861*4dc78e53SAndroid Build Coastguard Worker 	void *pol;
862*4dc78e53SAndroid Build Coastguard Worker 	PyObject *attrs = Py_None;
863*4dc78e53SAndroid Build Coastguard Worker 	PyObject *k;
864*4dc78e53SAndroid Build Coastguard Worker 	PyObject *v;
865*4dc78e53SAndroid Build Coastguard Worker 	PyObject *resobj;
866*4dc78e53SAndroid Build Coastguard Worker 	int err;
867*4dc78e53SAndroid Build Coastguard Worker 	int i;
868*4dc78e53SAndroid Build Coastguard Worker 
869*4dc78e53SAndroid Build Coastguard Worker 	if (p != Py_None) {
870*4dc78e53SAndroid Build Coastguard Worker 		PyObject *pobj;
871*4dc78e53SAndroid Build Coastguard Worker 
872*4dc78e53SAndroid Build Coastguard Worker 		if (!PyList_Check(p)) {
873*4dc78e53SAndroid Build Coastguard Worker 			fprintf(stderr, "expected list object\n");
874*4dc78e53SAndroid Build Coastguard Worker 			err = -1;
875*4dc78e53SAndroid Build Coastguard Worker 			goto fail;
876*4dc78e53SAndroid Build Coastguard Worker 		}
877*4dc78e53SAndroid Build Coastguard Worker 		pobj = PyList_GetItem(p, 0);
878*4dc78e53SAndroid Build Coastguard Worker 		err = SWIG_ConvertPtr(pobj, &pol, SWIGTYPE_p_nla_policy, 0 |  0 );
879*4dc78e53SAndroid Build Coastguard Worker 		if (!SWIG_IsOK(err))
880*4dc78e53SAndroid Build Coastguard Worker 			goto fail;
881*4dc78e53SAndroid Build Coastguard Worker 		policy = pol;
882*4dc78e53SAndroid Build Coastguard Worker 	}
883*4dc78e53SAndroid Build Coastguard Worker 	err = nla_parse_nested(tb_msg, max, nest_attr, policy);
884*4dc78e53SAndroid Build Coastguard Worker 	if (err < 0) {
885*4dc78e53SAndroid Build Coastguard Worker 		fprintf(stderr, "Failed to parse response message\n");
886*4dc78e53SAndroid Build Coastguard Worker 	} else {
887*4dc78e53SAndroid Build Coastguard Worker 		attrs = PyDict_New();
888*4dc78e53SAndroid Build Coastguard Worker 		for (i = 0; i <= max; i++)
889*4dc78e53SAndroid Build Coastguard Worker 			if (tb_msg[i]) {
890*4dc78e53SAndroid Build Coastguard Worker 				k = PyInt_FromLong((long)i);
891*4dc78e53SAndroid Build Coastguard Worker 				v = SWIG_NewPointerObj(SWIG_as_voidptr(tb_msg[i]), SWIGTYPE_p_nlattr, 0 |  0 );
892*4dc78e53SAndroid Build Coastguard Worker 				PyDict_SetItem(attrs, k, v);
893*4dc78e53SAndroid Build Coastguard Worker 			}
894*4dc78e53SAndroid Build Coastguard Worker 	}
895*4dc78e53SAndroid Build Coastguard Worker fail:
896*4dc78e53SAndroid Build Coastguard Worker 	if (attrs == Py_None)
897*4dc78e53SAndroid Build Coastguard Worker 		Py_INCREF(attrs);
898*4dc78e53SAndroid Build Coastguard Worker 	resobj = Py_BuildValue("(iO)", err, attrs);
899*4dc78e53SAndroid Build Coastguard Worker 	return resobj;
900*4dc78e53SAndroid Build Coastguard Worker }
901*4dc78e53SAndroid Build Coastguard Worker 
902*4dc78e53SAndroid Build Coastguard Worker /*
903*4dc78e53SAndroid Build Coastguard Worker  * nla_get_nested() - get list of nested attributes.
904*4dc78e53SAndroid Build Coastguard Worker  *
905*4dc78e53SAndroid Build Coastguard Worker  * nla_for_each_<nested|attr>() is a macro construct that needs another approach
906*4dc78e53SAndroid Build Coastguard Worker  * for Python. Create and return list of nested attributes.
907*4dc78e53SAndroid Build Coastguard Worker  */
nla_get_nested(struct nlattr * nest_attr)908*4dc78e53SAndroid Build Coastguard Worker PyObject *nla_get_nested(struct nlattr *nest_attr)
909*4dc78e53SAndroid Build Coastguard Worker {
910*4dc78e53SAndroid Build Coastguard Worker 	PyObject *listobj;
911*4dc78e53SAndroid Build Coastguard Worker 	PyObject *nestattrobj;
912*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *pos;
913*4dc78e53SAndroid Build Coastguard Worker 	int rem;
914*4dc78e53SAndroid Build Coastguard Worker 
915*4dc78e53SAndroid Build Coastguard Worker 	listobj = PyList_New(0);
916*4dc78e53SAndroid Build Coastguard Worker 	nla_for_each_nested(pos, nest_attr, rem) {
917*4dc78e53SAndroid Build Coastguard Worker 		nestattrobj = SWIG_NewPointerObj(SWIG_as_voidptr(pos),
918*4dc78e53SAndroid Build Coastguard Worker 						 SWIGTYPE_p_nlattr, 0 |  0 );
919*4dc78e53SAndroid Build Coastguard Worker 		PyList_Append(listobj, nestattrobj);
920*4dc78e53SAndroid Build Coastguard Worker 	}
921*4dc78e53SAndroid Build Coastguard Worker 	return listobj;
922*4dc78e53SAndroid Build Coastguard Worker }
923*4dc78e53SAndroid Build Coastguard Worker %}
924*4dc78e53SAndroid Build Coastguard Worker 
925*4dc78e53SAndroid Build Coastguard Worker  /**
926*4dc78e53SAndroid Build Coastguard Worker   * @ingroup attr
927*4dc78e53SAndroid Build Coastguard Worker   * Basic attribute data types
928*4dc78e53SAndroid Build Coastguard Worker   *
929*4dc78e53SAndroid Build Coastguard Worker   * See \ref attr_datatypes for more details.
930*4dc78e53SAndroid Build Coastguard Worker   */
931*4dc78e53SAndroid Build Coastguard Worker enum {
932*4dc78e53SAndroid Build Coastguard Worker 	NLA_UNSPEC,	/**< Unspecified type, binary data chunk */
933*4dc78e53SAndroid Build Coastguard Worker 	NLA_U8,		/**< 8 bit integer */
934*4dc78e53SAndroid Build Coastguard Worker 	NLA_U16,	/**< 16 bit integer */
935*4dc78e53SAndroid Build Coastguard Worker 	NLA_U32,	/**< 32 bit integer */
936*4dc78e53SAndroid Build Coastguard Worker 	NLA_U64,	/**< 64 bit integer */
937*4dc78e53SAndroid Build Coastguard Worker 	NLA_STRING,	/**< NUL terminated character string */
938*4dc78e53SAndroid Build Coastguard Worker 	NLA_FLAG,	/**< Flag */
939*4dc78e53SAndroid Build Coastguard Worker 	NLA_MSECS,	/**< Micro seconds (64bit) */
940*4dc78e53SAndroid Build Coastguard Worker 	NLA_NESTED,	/**< Nested attributes */
941*4dc78e53SAndroid Build Coastguard Worker 	__NLA_TYPE_MAX,
942*4dc78e53SAndroid Build Coastguard Worker };
943*4dc78e53SAndroid Build Coastguard Worker 
944*4dc78e53SAndroid Build Coastguard Worker #define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
945*4dc78e53SAndroid Build Coastguard Worker 
946*4dc78e53SAndroid Build Coastguard Worker /** @} */
947*4dc78e53SAndroid Build Coastguard Worker 
948*4dc78e53SAndroid Build Coastguard Worker /**
949*4dc78e53SAndroid Build Coastguard Worker  * @ingroup attr
950*4dc78e53SAndroid Build Coastguard Worker  * Attribute validation policy.
951*4dc78e53SAndroid Build Coastguard Worker  *
952*4dc78e53SAndroid Build Coastguard Worker  * See \ref attr_datatypes for more details.
953*4dc78e53SAndroid Build Coastguard Worker  */
954*4dc78e53SAndroid Build Coastguard Worker struct nla_policy {
955*4dc78e53SAndroid Build Coastguard Worker 	/** Type of attribute or NLA_UNSPEC */
956*4dc78e53SAndroid Build Coastguard Worker 	uint16_t	type;
957*4dc78e53SAndroid Build Coastguard Worker 
958*4dc78e53SAndroid Build Coastguard Worker 	/** Minimal length of payload required */
959*4dc78e53SAndroid Build Coastguard Worker 	uint16_t	minlen;
960*4dc78e53SAndroid Build Coastguard Worker 
961*4dc78e53SAndroid Build Coastguard Worker 	/** Maximal length of payload allowed */
962*4dc78e53SAndroid Build Coastguard Worker 	uint16_t	maxlen;
963*4dc78e53SAndroid Build Coastguard Worker };
964*4dc78e53SAndroid Build Coastguard Worker 
965*4dc78e53SAndroid Build Coastguard Worker %inline %{
nla_policy_array(int n_items)966*4dc78e53SAndroid Build Coastguard Worker PyObject *nla_policy_array(int n_items)
967*4dc78e53SAndroid Build Coastguard Worker {
968*4dc78e53SAndroid Build Coastguard Worker 	struct nla_policy *policies;
969*4dc78e53SAndroid Build Coastguard Worker 	PyObject *listobj;
970*4dc78e53SAndroid Build Coastguard Worker 	PyObject *polobj;
971*4dc78e53SAndroid Build Coastguard Worker 	int i;
972*4dc78e53SAndroid Build Coastguard Worker 
973*4dc78e53SAndroid Build Coastguard Worker 	policies = calloc(n_items, sizeof(*policies));
974*4dc78e53SAndroid Build Coastguard Worker 	listobj = PyList_New(n_items);
975*4dc78e53SAndroid Build Coastguard Worker 	for (i = 0; i < n_items; i++) {
976*4dc78e53SAndroid Build Coastguard Worker 		polobj = SWIG_NewPointerObj(SWIG_as_voidptr(&policies[i]),
977*4dc78e53SAndroid Build Coastguard Worker 					    SWIGTYPE_p_nla_policy, 0 |  0 );
978*4dc78e53SAndroid Build Coastguard Worker 		PyList_SetItem(listobj, i, polobj);
979*4dc78e53SAndroid Build Coastguard Worker 	}
980*4dc78e53SAndroid Build Coastguard Worker 	return listobj;
981*4dc78e53SAndroid Build Coastguard Worker }
982*4dc78e53SAndroid Build Coastguard Worker %}
983