This commit was generated by cvs2svn to compensate for changes in r786,
[libnl.git] / lib / route / rule.c
1 /*
2  * lib/route/rule.c          Routing Rules
3  *
4  *      This library is free software; you can redistribute it and/or
5  *      modify it under the terms of the GNU Lesser General Public
6  *      License as published by the Free Software Foundation version 2.1
7  *      of the License.
8  *
9  * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
10  */
11
12 /**
13  * @ingroup rtnl
14  * @defgroup rule Routing Rules
15  * @brief
16  * @{
17  */
18
19 #include <netlink-local.h>
20 #include <netlink/netlink.h>
21 #include <netlink/utils.h>
22 #include <netlink/route/rtnl.h>
23 #include <netlink/route/rule.h>
24 #include <inttypes.h>
25
26 /** @cond SKIP */
27 #define RULE_ATTR_FAMILY  0x0001
28 #define RULE_ATTR_PRIO    0x0002
29 #define RULE_ATTR_FWMARK  0x0004
30 #define RULE_ATTR_IIF     0x0008
31 #define RULE_ATTR_REALMS  0x0010
32 #define RULE_ATTR_SRC     0x0020
33 #define RULE_ATTR_DST     0x0040
34 #define RULE_ATTR_DSFIELD 0x0080
35 #define RULE_ATTR_TABLE   0x0100
36 #define RULE_ATTR_TYPE    0x0200
37 #define RULE_ATTR_SRC_LEN 0x0400
38 #define RULE_ATTR_DST_LEN 0x0800
39 #define RULE_ATTR_SRCMAP  0x1000
40
41 static struct nl_cache_ops rtnl_rule_ops;
42 /** @endcond */
43
44 static void rule_free_data(struct nl_object *c)
45 {
46         struct rtnl_rule *rule = nl_object_priv(c);
47
48         if (!rule)
49                 return;
50
51         nl_addr_put(rule->r_src);
52         nl_addr_put(rule->r_dst);
53 }
54
55 static struct nla_policy rule_policy[RTA_MAX+1] = {
56         [RTA_PRIORITY]  = { .type = NLA_U32 },
57         [RTA_FLOW]      = { .type = NLA_U32 },
58         [RTA_PROTOINFO] = { .type = NLA_U32 },
59         [RTA_IIF]       = { .type = NLA_STRING,
60                             .maxlen = IFNAMSIZ, },
61 };
62
63 static int rule_msg_parser(struct sockaddr_nl *who, struct nlmsghdr *n,
64                            void *arg)
65 {
66         struct rtnl_rule *rule;
67         struct rtmsg *r;
68         struct nlattr *tb[RTA_MAX+1];
69         struct nl_parser_param *pp = arg;
70         int err = 1;
71
72         rule = rtnl_rule_alloc();
73         if (!rule) {
74                 err = nl_errno(ENOMEM);
75                 goto errout;
76         }
77
78         rule->ce_msgtype = n->nlmsg_type;
79         r = nlmsg_data(n);
80
81         err = nlmsg_parse(n, sizeof(*r), tb, RTA_MAX, rule_policy);
82         if (err < 0)
83                 goto errout;
84
85         rule->r_family = r->rtm_family;
86         rule->r_type = r->rtm_type;
87         rule->r_dsfield = r->rtm_tos;
88         rule->r_src_len = r->rtm_src_len;
89         rule->r_dst_len = r->rtm_dst_len;
90         rule->r_table = r->rtm_table;
91         rule->r_mask = (RULE_ATTR_FAMILY | RULE_ATTR_TYPE | RULE_ATTR_DSFIELD |
92                         RULE_ATTR_SRC_LEN | RULE_ATTR_DST_LEN | RULE_ATTR_TYPE);
93
94         if (tb[RTA_PRIORITY]) {
95                 rule->r_prio = nla_get_u32(tb[RTA_PRIORITY]);
96                 rule->r_mask |= RULE_ATTR_PRIO;
97         }
98
99         if (tb[RTA_SRC]) {
100                 rule->r_src = nla_get_addr(tb[RTA_SRC], r->rtm_family);
101                 if (!rule->r_src) {
102                         err = nl_errno(ENOMEM);
103                         goto errout;
104                 }
105                 nl_addr_set_prefixlen(rule->r_src, r->rtm_src_len);
106                 rule->r_mask |= RULE_ATTR_SRC;
107         }
108
109         if (tb[RTA_DST]) {
110                 rule->r_dst = nla_get_addr(tb[RTA_DST], r->rtm_family);
111                 if (!rule->r_dst) {
112                         err = nl_errno(ENOMEM);
113                         goto errout;
114                 }
115                 nl_addr_set_prefixlen(rule->r_dst, r->rtm_dst_len);
116                 rule->r_mask |= RULE_ATTR_DST;
117         }
118
119         if (tb[RTA_PROTOINFO]) {
120                 rule->r_fwmark = nla_get_u32(tb[RTA_PROTOINFO]);
121                 rule->r_mask |= RULE_ATTR_FWMARK;
122         }
123
124         if (tb[RTA_IIF]) {
125                 nla_strlcpy(rule->r_iif, tb[RTA_IIF], IFNAMSIZ);
126                 rule->r_mask |= RULE_ATTR_IIF;
127         }
128
129         if (tb[RTA_FLOW]) {
130                 rule->r_realms = nla_get_u32(tb[RTA_FLOW]);
131                 rule->r_mask |= RULE_ATTR_REALMS;
132         }
133
134         if (tb[RTA_GATEWAY]) {
135                 rule->r_srcmap = nla_get_addr(tb[RTA_GATEWAY], r->rtm_family);
136                 if (!rule->r_srcmap) {
137                         err = nl_errno(ENOMEM);
138                         goto errout;
139                 }
140                 rule->r_mask |= RULE_ATTR_SRCMAP;
141         }
142
143         err = pp->pp_cb((struct nl_object *) rule, pp);
144         if (err < 0)
145                 goto errout;
146
147         return P_ACCEPT;
148
149 errout:
150         rtnl_rule_put(rule);
151         return err;
152 }
153
154 static int rule_request_update(struct nl_cache *c, struct nl_handle *h)
155 {
156         return nl_rtgen_request(h, RTM_GETRULE, AF_UNSPEC, NLM_F_DUMP);
157 }
158
159 static int rule_dump_brief(struct nl_object *o, struct nl_dump_params *p)
160 {
161         struct rtnl_rule *r = (struct rtnl_rule *) o;
162         char buf[128];
163
164         if (r->r_mask & RULE_ATTR_PRIO)
165                 dp_dump(p, "%d:\t", r->r_prio);
166         else
167                 dp_dump(p, "0:\t");
168
169         if (r->r_mask & RULE_ATTR_SRC)
170                 dp_dump(p, "from %s ",
171                         nl_addr2str(r->r_src, buf, sizeof(buf)));
172         else if (r->r_mask & RULE_ATTR_SRC_LEN && r->r_src_len)
173                 dp_dump(p, "from 0/%d ", r->r_src_len);
174
175         if (r->r_mask & RULE_ATTR_DST)
176                 dp_dump(p, "to %s ",
177                         nl_addr2str(r->r_dst, buf, sizeof(buf)));
178         else if (r->r_mask & RULE_ATTR_DST_LEN && r->r_dst_len)
179                 dp_dump(p, "to 0/%d ", r->r_dst_len);
180
181         if (r->r_mask & RULE_ATTR_DSFIELD && r->r_dsfield)
182                 dp_dump(p, "tos %d ", r->r_dsfield);
183
184         if (r->r_mask & RULE_ATTR_FWMARK)
185                 dp_dump(p, "fwmark %" PRIx64 , r->r_fwmark);
186
187         if (r->r_mask & RULE_ATTR_IIF)
188                 dp_dump(p, "iif %s ", r->r_iif);
189
190         if (r->r_mask & RULE_ATTR_TABLE)
191                 dp_dump(p, "lookup %s ",
192                         rtnl_route_table2str(r->r_table, buf, sizeof(buf)));
193
194         if (r->r_mask & RULE_ATTR_REALMS)
195                 dp_dump(p, "realms %s ",
196                         rtnl_realms2str(r->r_realms, buf, sizeof(buf)));
197
198         dp_dump(p, "action %s\n",
199                 nl_rtntype2str(r->r_type, buf, sizeof(buf)));
200
201         return 1;
202 }
203
204 static int rule_dump_full(struct nl_object *obj, struct nl_dump_params *p)
205 {
206         struct rtnl_rule *rule = (struct rtnl_rule *) obj;
207         char buf[128];
208         int line;
209
210         line = rule_dump_brief(obj, p);
211
212         dp_dump_line(p, line++, "  family %s",
213                      nl_af2str(rule->r_family, buf, sizeof(buf)));
214
215         if (rule->r_mask & RULE_ATTR_SRCMAP)
216                 dp_dump(p, " srcmap %s",
217                         nl_addr2str(rule->r_srcmap, buf, sizeof(buf)));
218
219         dp_dump(p, "\n");
220
221         return line;
222 }
223
224 static int rule_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
225 {
226         return rule_dump_full(obj, p);
227 }
228
229 static int rule_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
230 {
231         struct rtnl_rule *rule = (struct rtnl_rule *) obj;
232         char buf[128];
233         int line = 0;
234         
235         dp_dump_line(p, line++, "<rule>\n");
236
237         dp_dump_line(p, line++, "  <priority>%u</priority>\n",
238                      rule->r_prio);
239         dp_dump_line(p, line++, "  <family>%s</family>\n",
240                      nl_af2str(rule->r_family, buf, sizeof(buf)));
241
242         if (rule->r_mask & RULE_ATTR_DST)
243                 dp_dump_line(p, line++, "  <dst>%s</dst>\n",
244                              nl_addr2str(rule->r_dst, buf, sizeof(buf)));
245
246         if (rule->r_mask & RULE_ATTR_DST_LEN)
247                 dp_dump_line(p, line++, "  <dstlen>%u</dstlen>\n",
248                              rule->r_dst_len);
249
250         if (rule->r_mask & RULE_ATTR_SRC)
251                 dp_dump_line(p, line++, "  <src>%s</src>\n",
252                              nl_addr2str(rule->r_src, buf, sizeof(buf)));
253
254         if (rule->r_mask & RULE_ATTR_SRC_LEN)
255                 dp_dump_line(p, line++, "  <srclen>%u</srclen>\n",
256                              rule->r_src_len);
257
258         if (rule->r_mask & RULE_ATTR_IIF)
259                 dp_dump_line(p, line++, "  <iif>%s</iif>\n", rule->r_iif);
260
261         if (rule->r_mask & RULE_ATTR_TABLE)
262                 dp_dump_line(p, line++, "  <table>%u</table>\n",
263                              rule->r_table);
264
265         if (rule->r_mask & RULE_ATTR_REALMS)
266                 dp_dump_line(p, line++, "  <realms>%u</realms>\n",
267                              rule->r_realms);
268
269         if (rule->r_mask & RULE_ATTR_FWMARK)
270                 dp_dump_line(p, line++, "  <fwmark>%" PRIx64 "</fwmark>\n",
271                              rule->r_fwmark);
272
273         if (rule->r_mask & RULE_ATTR_DSFIELD)
274                 dp_dump_line(p, line++, "  <dsfield>%u</dsfield>\n",
275                              rule->r_dsfield);
276
277         if (rule->r_mask & RULE_ATTR_TYPE)
278                 dp_dump_line(p, line++, "<type>%s</type>\n",
279                              nl_rtntype2str(rule->r_type, buf, sizeof(buf)));
280
281         if (rule->r_mask & RULE_ATTR_SRCMAP)
282                 dp_dump_line(p, line++, "<srcmap>%s</srcmap>\n",
283                              nl_addr2str(rule->r_srcmap, buf, sizeof(buf)));
284
285         dp_dump_line(p, line++, "</rule>\n");
286
287         return line;
288 }
289
290 static int rule_dump_env(struct nl_object *obj, struct nl_dump_params *p)
291 {
292         struct rtnl_rule *rule = (struct rtnl_rule *) obj;
293         char buf[128];
294         int line = 0;
295
296         dp_dump_line(p, line++, "RULE_PRIORITY=%u\n",
297                      rule->r_prio);
298         dp_dump_line(p, line++, "RULE_FAMILY=%s\n",
299                      nl_af2str(rule->r_family, buf, sizeof(buf)));
300
301         if (rule->r_mask & RULE_ATTR_DST)
302                 dp_dump_line(p, line++, "RULE_DST=%s\n",
303                              nl_addr2str(rule->r_dst, buf, sizeof(buf)));
304
305         if (rule->r_mask & RULE_ATTR_DST_LEN)
306                 dp_dump_line(p, line++, "RULE_DSTLEN=%u\n",
307                              rule->r_dst_len);
308
309         if (rule->r_mask & RULE_ATTR_SRC)
310                 dp_dump_line(p, line++, "RULE_SRC=%s\n",
311                              nl_addr2str(rule->r_src, buf, sizeof(buf)));
312
313         if (rule->r_mask & RULE_ATTR_SRC_LEN)
314                 dp_dump_line(p, line++, "RULE_SRCLEN=%u\n",
315                              rule->r_src_len);
316
317         if (rule->r_mask & RULE_ATTR_IIF)
318                 dp_dump_line(p, line++, "RULE_IIF=%s\n", rule->r_iif);
319
320         if (rule->r_mask & RULE_ATTR_TABLE)
321                 dp_dump_line(p, line++, "RULE_TABLE=%u\n",
322                              rule->r_table);
323
324         if (rule->r_mask & RULE_ATTR_REALMS)
325                 dp_dump_line(p, line++, "RULE_REALM=%u\n",
326                              rule->r_realms);
327
328         if (rule->r_mask & RULE_ATTR_FWMARK)
329                 dp_dump_line(p, line++, "RULE_FWMARK=0x%" PRIx64 "\n",
330                              rule->r_fwmark);
331
332         if (rule->r_mask & RULE_ATTR_DSFIELD)
333                 dp_dump_line(p, line++, "RULE_DSFIELD=%u\n",
334                              rule->r_dsfield);
335
336         if (rule->r_mask & RULE_ATTR_TYPE)
337                 dp_dump_line(p, line++, "RULE_TYPE=%s\n",
338                              nl_rtntype2str(rule->r_type, buf, sizeof(buf)));
339
340         if (rule->r_mask & RULE_ATTR_SRCMAP)
341                 dp_dump_line(p, line++, "RULE_SRCMAP=%s\n",
342                              nl_addr2str(rule->r_srcmap, buf, sizeof(buf)));
343
344         return line;
345 }
346
347
348 static int rule_filter(struct nl_object *obj, struct nl_object *filter)
349 {
350         struct rtnl_rule *o = (struct rtnl_rule *) obj;
351         struct rtnl_rule *f = (struct rtnl_rule *) filter;
352
353 #define REQ(F) (f->r_mask & RULE_ATTR_##F)
354 #define AVAIL(F) (o->r_mask & RULE_ATTR_##F)
355 #define _O(F, EXPR) (REQ(F) && (!AVAIL(F) || (EXPR)))
356 #define _C(F, N) (REQ(F) && (!AVAIL(F) || (o->N != f->N)))
357         if (_C(FAMILY,  r_family)                                       ||
358             _C(TABLE,   r_table)                                        ||
359             _C(REALMS,  r_realms)                                       ||
360             _C(DSFIELD, r_dsfield)                                      ||
361             _C(TYPE,    r_type)                                         ||
362             _C(PRIO,    r_prio)                                         ||
363             _C(FWMARK,  r_fwmark)                                       ||
364             _C(SRC_LEN, r_src_len)                                      ||
365             _C(DST_LEN, r_dst_len)                                      ||
366             _O(SRC,     nl_addr_cmp(o->r_src, f->r_src))                ||
367             _O(DST,     nl_addr_cmp(o->r_dst, f->r_dst))                ||
368             _O(IIF,     strcmp(o->r_iif, f->r_iif)))
369                 return 0;
370 #undef REQ
371 #undef AVAIL
372 #undef _O
373 #undef _C
374
375         return 1;
376 }
377
378 /**
379  * @name Routing Rule Object Allocation/Freeage
380  * @{
381  */
382
383 /**
384  * Allocate a new rule object
385  * @return New rule object
386  */
387 struct rtnl_rule *rtnl_rule_alloc(void)
388 {
389         return (struct rtnl_rule *) nl_object_alloc_from_ops(&rtnl_rule_ops);
390 }
391
392 /**
393  * Give back reference on routing rule object.
394  * @arg rule            Routing rule object to be given back.
395  *
396  * Decrements the reference counter and frees the object if the
397  * last reference has been released.
398  */
399 void rtnl_rule_put(struct rtnl_rule *rule)
400 {
401         nl_object_put((struct nl_object *) rule);
402 }
403 /**
404  * Free routing rule object.
405  * @arg rule            Routing rule object to be freed.
406  *
407  * @note Always use rtnl_rule_put() unless you're absolutely sure
408  *       that no other user may have a reference on this object.
409  */
410 void rtnl_rule_free(struct rtnl_rule *rule)
411 {
412         nl_object_free((struct nl_object *) rule);
413 }
414
415 /** @} */
416
417 /**
418  * @name Routing Rule Cache Management
419  * @{
420  */
421
422 /**
423  * Build a rule cache including all rules of the specified family currently configured in the kernel.
424  * @arg handle          netlink handle
425  * @arg family          address family
426  *
427  * Allocates a new rule cache, initializes it properly and updates it
428  * to include all rules of the specified address family currently
429  * configured in the kernel.
430  *
431  * @note The caller is responsible for destroying and freeing the
432  *       cache after using it. (nl_cache_destroy_and_free())
433  * @return The new cache or NULL if an error occured.
434  */
435 struct nl_cache * rtnl_rule_alloc_cache_by_family(struct nl_handle *handle,
436                                                   int family)
437 {
438         struct nl_cache * cache = nl_cache_alloc_from_ops(&rtnl_rule_ops);
439
440         if (cache == NULL)
441                 return NULL;
442
443         /* XXX RULE_CACHE_FAMILY(cache) = family; */
444
445         if (nl_cache_update(handle, cache) < 0) {
446                 free(cache);
447                 return NULL;
448         }
449
450         return cache;
451 }
452
453 /**
454  * Build a rule cache including all rules currently configured in the kernel.
455  * @arg handle          netlink handle
456  *
457  * Allocates a new rule cache, initializes it properly and updates it
458  * to include all rules currently configured in the kernel.
459  *
460  * @note The caller is responsible for destroying and freeing the
461  *       cache after using it. (nl_cache_destroy_and_free())
462  * @return The new cache or NULL if an error occured.
463  */
464 struct nl_cache * rtnl_rule_alloc_cache(struct nl_handle *handle)
465 {
466         return rtnl_rule_alloc_cache_by_family(handle, AF_UNSPEC);
467 }
468
469 /** @} */
470
471 /**
472  * @name Rule Addition
473  * @{
474  */
475
476 static struct nl_msg *build_rule_msg(struct rtnl_rule *tmpl, int cmd, int flags)
477 {
478         struct nl_msg *msg;
479         struct rtmsg rtm = {
480                 .rtm_type = RTN_UNSPEC
481         };
482
483         if (cmd == RTM_NEWRULE)
484                 rtm.rtm_type = RTN_UNICAST;
485                 
486         if (tmpl->r_mask & RULE_ATTR_FAMILY)
487                 rtm.rtm_family = tmpl->r_family;
488
489         if (tmpl->r_mask & RULE_ATTR_TABLE)
490                 rtm.rtm_table = tmpl->r_table;
491
492         if (tmpl->r_mask & RULE_ATTR_DSFIELD)
493                 rtm.rtm_tos = tmpl->r_dsfield;
494
495         if (tmpl->r_mask & RULE_ATTR_TYPE)
496                 rtm.rtm_type = tmpl->r_type;
497
498         if (tmpl->r_mask & RULE_ATTR_SRC_LEN)
499                 rtm.rtm_src_len = tmpl->r_src_len;
500
501         if (tmpl->r_mask & RULE_ATTR_DST_LEN)
502                 rtm.rtm_dst_len = tmpl->r_dst_len;
503
504         msg = nlmsg_build_simple(cmd, flags);
505         if (!msg)
506                 goto nla_put_failure;
507
508         if (nlmsg_append(msg, &rtm, sizeof(rtm), 1) < 0)
509                 goto nla_put_failure;
510
511         if (tmpl->r_mask & RULE_ATTR_SRC)
512                 NLA_PUT_ADDR(msg, RTA_SRC, tmpl->r_src);
513
514         if (tmpl->r_mask & RULE_ATTR_DST)
515                 NLA_PUT_ADDR(msg, RTA_DST, tmpl->r_dst);
516
517         if (tmpl->r_mask & RULE_ATTR_PRIO)
518                 NLA_PUT_U32(msg, RTA_PRIORITY, tmpl->r_prio);
519
520         if (tmpl->r_mask & RULE_ATTR_FWMARK)
521                 NLA_PUT_U32(msg, RTA_PROTOINFO, tmpl->r_fwmark);
522
523         if (tmpl->r_mask & RULE_ATTR_REALMS)
524                 NLA_PUT_U32(msg, RTA_FLOW, tmpl->r_realms);
525
526         if (tmpl->r_mask & RULE_ATTR_IIF)
527                 NLA_PUT_STRING(msg, RTA_IIF, tmpl->r_iif);
528
529         return msg;
530
531 nla_put_failure:
532         nlmsg_free(msg);
533         return NULL;
534 }
535
536 /**
537  * Build netlink request message to add a new rule
538  * @arg tmpl            template with data of new rule
539  * @arg flags           additional netlink message flags
540  *
541  * Builds a new netlink message requesting a addition of a new
542  * rule. The netlink message header isn't fully equipped with
543  * all relevant fields and must thus be sent out via nl_send_auto_complete()
544  * or supplemented as needed. \a tmpl must contain the attributes of the new
545  * address set via \c rtnl_rule_set_* functions.
546  * 
547  * @return The netlink message
548  */
549 struct nl_msg *rtnl_rule_build_add_request(struct rtnl_rule *tmpl, int flags)
550 {
551         return build_rule_msg(tmpl, RTM_NEWRULE, NLM_F_CREATE | flags);
552 }
553
554 /**
555  * Add a new rule
556  * @arg handle          netlink handle
557  * @arg tmpl            template with requested changes
558  * @arg flags           additional netlink message flags
559  *
560  * Builds a netlink message by calling rtnl_rule_build_add_request(),
561  * sends the request to the kernel and waits for the next ACK to be
562  * received and thus blocks until the request has been fullfilled.
563  *
564  * @return 0 on sucess or a negative error if an error occured.
565  */
566 int rtnl_rule_add(struct nl_handle *handle, struct rtnl_rule *tmpl, int flags)
567 {
568         int err;
569         struct nl_msg *msg;
570         
571         msg = rtnl_rule_build_add_request(tmpl, flags);
572         if (!msg)
573                 return nl_errno(ENOMEM);
574
575         err = nl_send_auto_complete(handle, msg);
576         if (err < 0)
577                 return err;
578
579         nlmsg_free(msg);
580         return nl_wait_for_ack(handle);
581 }
582
583 /** @} */
584
585 /**
586  * @name Rule Deletion
587  * @{
588  */
589
590 /**
591  * Build a netlink request message to delete a rule
592  * @arg rule            rule to delete
593  * @arg flags           additional netlink message flags
594  *
595  * Builds a new netlink message requesting a deletion of a rule.
596  * The netlink message header isn't fully equipped with all relevant
597  * fields and must thus be sent out via nl_send_auto_complete()
598  * or supplemented as needed. \a rule must point to an existing
599  * address.
600  *
601  * @return The netlink message
602  */
603 struct nl_msg *rtnl_rule_build_delete_request(struct rtnl_rule *rule, int flags)
604 {
605         return build_rule_msg(rule, RTM_DELRULE, flags);
606 }
607
608 /**
609  * Delete a rule
610  * @arg handle          netlink handle
611  * @arg rule            rule to delete
612  * @arg flags           additional netlink message flags
613  *
614  * Builds a netlink message by calling rtnl_rule_build_delete_request(),
615  * sends the request to the kernel and waits for the next ACK to be
616  * received and thus blocks until the request has been fullfilled.
617  *
618  * @return 0 on sucess or a negative error if an error occured.
619  */
620 int rtnl_rule_delete(struct nl_handle *handle, struct rtnl_rule *rule,
621                      int flags)
622 {
623         int err;
624         struct nl_msg *msg;
625         
626         msg = rtnl_rule_build_delete_request(rule, flags);
627         if (!msg)
628                 return nl_errno(ENOMEM);
629
630         err = nl_send_auto_complete(handle, msg);
631         if (err < 0)
632                 return err;
633
634         nlmsg_free(msg);
635         return nl_wait_for_ack(handle);
636 }
637
638 /** @} */
639
640 /**
641  * @name Attribute Modification
642  * @{
643  */
644
645 /**
646  * Set the address family of a rule to the specified value
647  * @arg rule            rule to change
648  * @arg family          new address family
649  */
650 void rtnl_rule_set_family(struct rtnl_rule *rule, int family)
651 {
652         rule->r_family = family;
653         rule->r_mask |= RULE_ATTR_FAMILY;
654 }
655
656 /**
657  * Get the address family of a rule
658  * @arg rule            rule handle
659  * @return Address family or AF_UNSPEC if not set
660  */
661 int rtnl_rule_get_family(struct rtnl_rule *rule)
662 {
663         if (rule->r_mask & RULE_ATTR_FAMILY)
664                 return rule->r_family;
665         else
666                 return AF_UNSPEC;
667 }
668
669 /**
670  * Set the priority of a rule to the specified value
671  * @arg rule            rule to change
672  * @arg prio            new priority
673  */
674 void rtnl_rule_set_prio(struct rtnl_rule *rule, int prio)
675 {
676         rule->r_prio = prio;
677         rule->r_mask |= RULE_ATTR_PRIO;
678 }
679
680 /**
681  * Get the priority of a rule
682  * @arg rule            rule handle
683  * @return Priority or -1 if not set
684  */
685 int rtnl_rule_get_prio(struct rtnl_rule *rule)
686 {
687         if (rule->r_mask & RULE_ATTR_PRIO)
688                 return rule->r_prio;
689         else
690                 return -1;
691 }
692
693 /**
694  * Set the firewall mark of a rule to the specified value
695  * @arg rule            rule to change
696  * @arg fwmark          new firewall mark
697  */
698 void rtnl_rule_set_fwmark(struct rtnl_rule *rule, uint64_t fwmark)
699 {
700         rule->r_fwmark = fwmark;
701         rule->r_mask |= RULE_ATTR_FWMARK;
702 }
703
704 /**
705  * Get the firewall mark of a rule
706  * @arg rule            rule handle
707  * @return Firewall mark or UINT_LEAST64_MAX if not set
708  */
709 uint64_t rtnl_rule_get_fwmark(struct rtnl_rule *rule)
710 {
711         if (rule->r_mask & RULE_ATTR_FWMARK)
712                 return rule->r_fwmark;
713         else
714                 return UINT_LEAST64_MAX;
715 }
716
717 /**
718  * Set the table index of a rule to the specified value
719  * @arg rule            rule to change
720  * @arg table           new table
721  */
722 void rtnl_rule_set_table(struct rtnl_rule *rule, int table)
723 {
724         rule->r_table = table;
725         rule->r_mask |= RULE_ATTR_TABLE;
726 }
727
728 /**
729  * Get the table index of a rule
730  * @arg rule            rule handle
731  * @return Table index or -1 if not set
732  */
733 int rtnl_rule_get_table(struct rtnl_rule *rule)
734 {
735         if (rule->r_mask & RULE_ATTR_TABLE)
736                 return rule->r_table;
737         else
738                 return -1;
739 }
740
741 /**
742  * Set the dsfield of a rule to the specified value
743  * @arg rule            rule to change
744  * @arg dsfield         new dsfield value
745  */
746 void rtnl_rule_set_dsfield(struct rtnl_rule *rule, int dsfield)
747 {
748         rule->r_dsfield = dsfield;
749         rule->r_mask |= RULE_ATTR_DSFIELD;
750 }
751
752 /**
753  * Get the dsfield of a rule
754  * @arg rule            rule handle
755  * @return dsfield or -1 if not set
756  */
757 int rtnl_rule_get_dsfield(struct rtnl_rule *rule)
758 {
759         if (rule->r_mask & RULE_ATTR_DSFIELD)
760                 return rule->r_dsfield;
761         else
762                 return -1;
763 }
764
765 /**
766  * Set the source address prefix length of a rule to the specified value
767  * @arg rule            rule to change
768  * @arg len             new source address length
769  */
770 void rtnl_rule_set_src_len(struct rtnl_rule *rule, int len)
771 {
772         rule->r_src_len = len;
773         if (rule->r_mask & RULE_ATTR_SRC)
774                 nl_addr_set_prefixlen(rule->r_src, len);
775         rule->r_mask |= RULE_ATTR_SRC_LEN;
776 }
777
778 /**
779  * Get the source address prefix length of a rule
780  * @arg rule            rule handle
781  * @return Prefix length of source address or -1 if not set
782  */
783 int rtnl_rule_get_src_len(struct rtnl_rule *rule)
784 {
785         if (rule->r_mask & RULE_ATTR_SRC_LEN)
786                 return rule->r_src_len;
787         else
788                 return -1;
789 }
790
791 /**
792  * Set the destination address prefix length of a rule to the specified value
793  * @arg rule            rule to change
794  * @arg len             new destination address length
795  */
796 void rtnl_rule_set_dst_len(struct rtnl_rule *rule, int len)
797 {
798         rule->r_dst_len = len;
799         if (rule->r_mask & RULE_ATTR_DST)
800                 nl_addr_set_prefixlen(rule->r_dst, len);
801         rule->r_mask |= RULE_ATTR_DST_LEN;
802 }
803
804 /**
805  * Get the destination address prefix length of a rule
806  * @arg rule            rule handle
807  * @return Prefix length of destination address or -1 if not set
808  */
809 int rtnl_rule_get_dst_len(struct rtnl_rule *rule)
810 {
811         if (rule->r_mask & RULE_ATTR_DST_LEN)
812                 return rule->r_dst_len;
813         else
814                 return -1;
815 }
816
817 static inline int __assign_addr(struct rtnl_rule *rule, struct nl_addr **pos,
818                                 struct nl_addr *new, uint8_t *len, int flag)
819 {
820         if (rule->r_mask & RULE_ATTR_FAMILY) {
821                 if (new->a_family != rule->r_family)
822                         return nl_error(EINVAL, "Address family mismatch");
823         } else
824                 rule->r_family = new->a_family;
825
826         if (*pos)
827                 nl_addr_put(*pos);
828
829         nl_addr_get(new);
830         *pos = new;
831         *len = nl_addr_get_prefixlen(new);
832
833         rule->r_mask |= (flag | RULE_ATTR_FAMILY);
834
835         return 0;
836 }
837 /**
838  * Set the source address of a rule
839  * @arg rule            rule to change
840  * @arg src             new source address
841  *
842  * Assigns the new source address to the specified rule handle. The
843  * address is validated against the address family if set already via
844  * either rtnl_rule_set_family() or by setting one of the other addresses.
845  * The assignment fails if the address families mismatch. In case the
846  * address family has not been specified yet, the address family of this
847  * new address is elected to be the requirement.
848  * 
849  * @return 0 on success or a negative error code.
850  */
851 int rtnl_rule_set_src(struct rtnl_rule *rule, struct nl_addr *src)
852 {
853         return __assign_addr(rule, &rule->r_src, src, &rule->r_src_len,
854                              RULE_ATTR_SRC | RULE_ATTR_SRC_LEN);
855 }
856
857 /**
858  * Get the source address of a rule
859  * @arg rule            rule handle
860  * @return Source address or NULL if not set
861  */
862 struct nl_addr *rtnl_rule_get_src(struct rtnl_rule *rule)
863 {
864         if (rule->r_mask & RULE_ATTR_SRC)
865                 return rule->r_src;
866         else
867                 return NULL;
868 }
869
870 /**
871  * Set the destination address of a rule
872  * @arg rule            rule to change
873  * @arg dst             new destination address
874  *
875  * Assigns the new destination address to the specified rule handle. The
876  * address is validated against the address family if set already via
877  * either rtnl_rule_set_family() or by setting one of the other addresses.
878  * The assignment fails if the address families mismatch. In case the
879  * address family has not been specified yet, the address family of this
880  * new address is elected to be the requirement.
881  * 
882  * @return 0 on success or a negative error code.
883  */
884 int rtnl_rule_set_dst(struct rtnl_rule *rule, struct nl_addr *dst)
885 {
886         return __assign_addr(rule, &rule->r_dst, dst, &rule->r_dst_len,
887                              RULE_ATTR_DST | RULE_ATTR_DST_LEN);
888 }
889
890 /**
891  * Get the destination address of a rule
892  * @arg rule            rule handle
893  * @return Destination address or NULL if not set
894  */
895 struct nl_addr *rtnl_rule_get_dst(struct rtnl_rule *rule)
896 {
897         if (rule->r_mask & RULE_ATTR_DST)
898                 return rule->r_dst;
899         else
900                 return NULL;
901 }
902
903 /**
904  * Set incoming interface of routing rule object.
905  * @arg rule            Routing rule object to be modified.
906  * @arg dev             Name of incoming interface.
907  *
908  * @return 0 on success or a negative error code.
909  */
910 int rtnl_rule_set_iif(struct rtnl_rule *rule, const char *dev)
911 {
912         if (strlen(dev) > IFNAMSIZ-1)
913                 return nl_errno(ERANGE);
914
915         strcpy(rule->r_iif, dev);
916         rule->r_mask |= RULE_ATTR_IIF;
917         return 0;
918 }
919
920 /**
921  * Get incoming interface of routing rule object.
922  * @arg rule            Routing rule object.
923  * @return Name of incoming interface or NULL if not available.
924  */
925 char *rtnl_rule_get_iif(struct rtnl_rule *rule)
926 {
927         if (rule->r_mask & RULE_ATTR_IIF)
928                 return rule->r_iif;
929         else
930                 return NULL;
931 }
932
933 /**
934  * Set action of routing rule object.
935  * @arg rule            Routing rule object to be modified.
936  * @arg type            New routing type specifying an action.
937  */
938 void rtnl_rule_set_action(struct rtnl_rule *rule, int type)
939 {
940         rule->r_type = type;
941         rule->r_mask |= RULE_ATTR_TYPE;
942 }
943
944 /**
945  * Get action of routing rule object.
946  * @arg rule            Routing rule object.
947  * @return Routing type or a negative error code.
948  */
949 int rtnl_rule_get_action(struct rtnl_rule *rule)
950 {
951         if (rule->r_mask & RULE_ATTR_TYPE)
952                 return rule->r_type;
953         else
954                 return nl_errno(ENOENT);
955 }
956
957 /**
958  * Set realms of routing rule object.
959  * @arg rule            Routing rule object to be modified.
960  * @arg realms          New realms value.
961  */
962 void rtnl_rule_set_realms(struct rtnl_rule *rule, realm_t realms)
963 {
964         rule->r_realms = realms;
965         rule->r_mask |= RULE_ATTR_REALMS;
966 }
967
968 /**
969  * Get realms of routing rule object.
970  * @arg rule            Routing rule object.
971  * @return Realms value or 0 if not set.
972  */
973 realm_t rtnl_rule_get_realms(struct rtnl_rule *rule)
974 {
975         if (rule->r_mask & RULE_ATTR_REALMS)
976                 return rule->r_realms;
977         else
978                 return 0;
979 }
980
981 /** @} */
982
983 static struct nl_cache_ops rtnl_rule_ops = {
984         .co_name                = "route/rule",
985         .co_size                = sizeof(struct rtnl_rule),
986         .co_hdrsize             = sizeof(struct rtmsg),
987         .co_msgtypes            = {
988                                         { RTM_NEWRULE, "new" },
989                                         { RTM_DELRULE, "delete" },
990                                         { RTM_GETRULE, "get" },
991                                         { -1, NULL },
992                                   },
993         .co_protocol            = NETLINK_ROUTE,
994         .co_request_update      = rule_request_update,
995         .co_msg_parser          = rule_msg_parser,
996         .co_free_data           = rule_free_data,
997         .co_dump[NL_DUMP_BRIEF] = rule_dump_brief,
998         .co_dump[NL_DUMP_FULL]  = rule_dump_full,
999         .co_dump[NL_DUMP_STATS] = rule_dump_stats,
1000         .co_dump[NL_DUMP_XML]   = rule_dump_xml,
1001         .co_dump[NL_DUMP_ENV]   = rule_dump_env,
1002         .co_filter              = rule_filter,
1003 };
1004
1005 static void __init rule_init(void)
1006 {
1007         nl_cache_mngt_register(&rtnl_rule_ops);
1008 }
1009
1010 static void __exit rule_exit(void)
1011 {
1012         nl_cache_mngt_unregister(&rtnl_rule_ops);
1013 }
1014
1015 /** @} */