2 * lib/route/rule.c Routing Rules
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
9 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
14 * @defgroup rule Routing Rules
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>
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
41 static struct nl_cache_ops rtnl_rule_ops;
44 static void rule_free_data(struct nl_object *c)
46 struct rtnl_rule *rule = nl_object_priv(c);
51 nl_addr_put(rule->r_src);
52 nl_addr_put(rule->r_dst);
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, },
63 static int rule_msg_parser(struct sockaddr_nl *who, struct nlmsghdr *n,
66 struct rtnl_rule *rule;
68 struct nlattr *tb[RTA_MAX+1];
69 struct nl_parser_param *pp = arg;
72 rule = rtnl_rule_alloc();
74 err = nl_errno(ENOMEM);
78 rule->ce_msgtype = n->nlmsg_type;
81 err = nlmsg_parse(n, sizeof(*r), tb, RTA_MAX, rule_policy);
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);
94 if (tb[RTA_PRIORITY]) {
95 rule->r_prio = nla_get_u32(tb[RTA_PRIORITY]);
96 rule->r_mask |= RULE_ATTR_PRIO;
100 rule->r_src = nla_get_addr(tb[RTA_SRC], r->rtm_family);
102 err = nl_errno(ENOMEM);
105 nl_addr_set_prefixlen(rule->r_src, r->rtm_src_len);
106 rule->r_mask |= RULE_ATTR_SRC;
110 rule->r_dst = nla_get_addr(tb[RTA_DST], r->rtm_family);
112 err = nl_errno(ENOMEM);
115 nl_addr_set_prefixlen(rule->r_dst, r->rtm_dst_len);
116 rule->r_mask |= RULE_ATTR_DST;
119 if (tb[RTA_PROTOINFO]) {
120 rule->r_fwmark = nla_get_u32(tb[RTA_PROTOINFO]);
121 rule->r_mask |= RULE_ATTR_FWMARK;
125 nla_strlcpy(rule->r_iif, tb[RTA_IIF], IFNAMSIZ);
126 rule->r_mask |= RULE_ATTR_IIF;
130 rule->r_realms = nla_get_u32(tb[RTA_FLOW]);
131 rule->r_mask |= RULE_ATTR_REALMS;
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);
140 rule->r_mask |= RULE_ATTR_SRCMAP;
143 err = pp->pp_cb((struct nl_object *) rule, pp);
154 static int rule_request_update(struct nl_cache *c, struct nl_handle *h)
156 return nl_rtgen_request(h, RTM_GETRULE, AF_UNSPEC, NLM_F_DUMP);
159 static int rule_dump_brief(struct nl_object *o, struct nl_dump_params *p)
161 struct rtnl_rule *r = (struct rtnl_rule *) o;
164 if (r->r_mask & RULE_ATTR_PRIO)
165 dp_dump(p, "%d:\t", r->r_prio);
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);
175 if (r->r_mask & RULE_ATTR_DST)
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);
181 if (r->r_mask & RULE_ATTR_DSFIELD && r->r_dsfield)
182 dp_dump(p, "tos %d ", r->r_dsfield);
184 if (r->r_mask & RULE_ATTR_FWMARK)
185 dp_dump(p, "fwmark %" PRIx64 , r->r_fwmark);
187 if (r->r_mask & RULE_ATTR_IIF)
188 dp_dump(p, "iif %s ", r->r_iif);
190 if (r->r_mask & RULE_ATTR_TABLE)
191 dp_dump(p, "lookup %s ",
192 rtnl_route_table2str(r->r_table, buf, sizeof(buf)));
194 if (r->r_mask & RULE_ATTR_REALMS)
195 dp_dump(p, "realms %s ",
196 rtnl_realms2str(r->r_realms, buf, sizeof(buf)));
198 dp_dump(p, "action %s\n",
199 nl_rtntype2str(r->r_type, buf, sizeof(buf)));
204 static int rule_dump_full(struct nl_object *obj, struct nl_dump_params *p)
206 struct rtnl_rule *rule = (struct rtnl_rule *) obj;
210 line = rule_dump_brief(obj, p);
212 dp_dump_line(p, line++, " family %s",
213 nl_af2str(rule->r_family, buf, sizeof(buf)));
215 if (rule->r_mask & RULE_ATTR_SRCMAP)
216 dp_dump(p, " srcmap %s",
217 nl_addr2str(rule->r_srcmap, buf, sizeof(buf)));
224 static int rule_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
226 return rule_dump_full(obj, p);
229 static int rule_dump_xml(struct nl_object *obj, struct nl_dump_params *p)
231 struct rtnl_rule *rule = (struct rtnl_rule *) obj;
235 dp_dump_line(p, line++, "<rule>\n");
237 dp_dump_line(p, line++, " <priority>%u</priority>\n",
239 dp_dump_line(p, line++, " <family>%s</family>\n",
240 nl_af2str(rule->r_family, buf, sizeof(buf)));
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)));
246 if (rule->r_mask & RULE_ATTR_DST_LEN)
247 dp_dump_line(p, line++, " <dstlen>%u</dstlen>\n",
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)));
254 if (rule->r_mask & RULE_ATTR_SRC_LEN)
255 dp_dump_line(p, line++, " <srclen>%u</srclen>\n",
258 if (rule->r_mask & RULE_ATTR_IIF)
259 dp_dump_line(p, line++, " <iif>%s</iif>\n", rule->r_iif);
261 if (rule->r_mask & RULE_ATTR_TABLE)
262 dp_dump_line(p, line++, " <table>%u</table>\n",
265 if (rule->r_mask & RULE_ATTR_REALMS)
266 dp_dump_line(p, line++, " <realms>%u</realms>\n",
269 if (rule->r_mask & RULE_ATTR_FWMARK)
270 dp_dump_line(p, line++, " <fwmark>%" PRIx64 "</fwmark>\n",
273 if (rule->r_mask & RULE_ATTR_DSFIELD)
274 dp_dump_line(p, line++, " <dsfield>%u</dsfield>\n",
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)));
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)));
285 dp_dump_line(p, line++, "</rule>\n");
290 static int rule_dump_env(struct nl_object *obj, struct nl_dump_params *p)
292 struct rtnl_rule *rule = (struct rtnl_rule *) obj;
296 dp_dump_line(p, line++, "RULE_PRIORITY=%u\n",
298 dp_dump_line(p, line++, "RULE_FAMILY=%s\n",
299 nl_af2str(rule->r_family, buf, sizeof(buf)));
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)));
305 if (rule->r_mask & RULE_ATTR_DST_LEN)
306 dp_dump_line(p, line++, "RULE_DSTLEN=%u\n",
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)));
313 if (rule->r_mask & RULE_ATTR_SRC_LEN)
314 dp_dump_line(p, line++, "RULE_SRCLEN=%u\n",
317 if (rule->r_mask & RULE_ATTR_IIF)
318 dp_dump_line(p, line++, "RULE_IIF=%s\n", rule->r_iif);
320 if (rule->r_mask & RULE_ATTR_TABLE)
321 dp_dump_line(p, line++, "RULE_TABLE=%u\n",
324 if (rule->r_mask & RULE_ATTR_REALMS)
325 dp_dump_line(p, line++, "RULE_REALM=%u\n",
328 if (rule->r_mask & RULE_ATTR_FWMARK)
329 dp_dump_line(p, line++, "RULE_FWMARK=0x%" PRIx64 "\n",
332 if (rule->r_mask & RULE_ATTR_DSFIELD)
333 dp_dump_line(p, line++, "RULE_DSFIELD=%u\n",
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)));
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)));
348 static int rule_filter(struct nl_object *obj, struct nl_object *filter)
350 struct rtnl_rule *o = (struct rtnl_rule *) obj;
351 struct rtnl_rule *f = (struct rtnl_rule *) filter;
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) ||
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)))
379 * @name Routing Rule Object Allocation/Freeage
384 * Allocate a new rule object
385 * @return New rule object
387 struct rtnl_rule *rtnl_rule_alloc(void)
389 return (struct rtnl_rule *) nl_object_alloc_from_ops(&rtnl_rule_ops);
393 * Give back reference on routing rule object.
394 * @arg rule Routing rule object to be given back.
396 * Decrements the reference counter and frees the object if the
397 * last reference has been released.
399 void rtnl_rule_put(struct rtnl_rule *rule)
401 nl_object_put((struct nl_object *) rule);
404 * Free routing rule object.
405 * @arg rule Routing rule object to be freed.
407 * @note Always use rtnl_rule_put() unless you're absolutely sure
408 * that no other user may have a reference on this object.
410 void rtnl_rule_free(struct rtnl_rule *rule)
412 nl_object_free((struct nl_object *) rule);
418 * @name Routing Rule Cache Management
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
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.
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.
435 struct nl_cache * rtnl_rule_alloc_cache_by_family(struct nl_handle *handle,
438 struct nl_cache * cache = nl_cache_alloc_from_ops(&rtnl_rule_ops);
443 /* XXX RULE_CACHE_FAMILY(cache) = family; */
445 if (nl_cache_update(handle, cache) < 0) {
454 * Build a rule cache including all rules currently configured in the kernel.
455 * @arg handle netlink handle
457 * Allocates a new rule cache, initializes it properly and updates it
458 * to include all rules currently configured in the kernel.
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.
464 struct nl_cache * rtnl_rule_alloc_cache(struct nl_handle *handle)
466 return rtnl_rule_alloc_cache_by_family(handle, AF_UNSPEC);
472 * @name Rule Addition
476 static struct nl_msg *build_rule_msg(struct rtnl_rule *tmpl, int cmd, int flags)
480 .rtm_type = RTN_UNSPEC
483 if (cmd == RTM_NEWRULE)
484 rtm.rtm_type = RTN_UNICAST;
486 if (tmpl->r_mask & RULE_ATTR_FAMILY)
487 rtm.rtm_family = tmpl->r_family;
489 if (tmpl->r_mask & RULE_ATTR_TABLE)
490 rtm.rtm_table = tmpl->r_table;
492 if (tmpl->r_mask & RULE_ATTR_DSFIELD)
493 rtm.rtm_tos = tmpl->r_dsfield;
495 if (tmpl->r_mask & RULE_ATTR_TYPE)
496 rtm.rtm_type = tmpl->r_type;
498 if (tmpl->r_mask & RULE_ATTR_SRC_LEN)
499 rtm.rtm_src_len = tmpl->r_src_len;
501 if (tmpl->r_mask & RULE_ATTR_DST_LEN)
502 rtm.rtm_dst_len = tmpl->r_dst_len;
504 msg = nlmsg_build_simple(cmd, flags);
506 goto nla_put_failure;
508 if (nlmsg_append(msg, &rtm, sizeof(rtm), 1) < 0)
509 goto nla_put_failure;
511 if (tmpl->r_mask & RULE_ATTR_SRC)
512 NLA_PUT_ADDR(msg, RTA_SRC, tmpl->r_src);
514 if (tmpl->r_mask & RULE_ATTR_DST)
515 NLA_PUT_ADDR(msg, RTA_DST, tmpl->r_dst);
517 if (tmpl->r_mask & RULE_ATTR_PRIO)
518 NLA_PUT_U32(msg, RTA_PRIORITY, tmpl->r_prio);
520 if (tmpl->r_mask & RULE_ATTR_FWMARK)
521 NLA_PUT_U32(msg, RTA_PROTOINFO, tmpl->r_fwmark);
523 if (tmpl->r_mask & RULE_ATTR_REALMS)
524 NLA_PUT_U32(msg, RTA_FLOW, tmpl->r_realms);
526 if (tmpl->r_mask & RULE_ATTR_IIF)
527 NLA_PUT_STRING(msg, RTA_IIF, tmpl->r_iif);
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
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.
547 * @return The netlink message
549 struct nl_msg *rtnl_rule_build_add_request(struct rtnl_rule *tmpl, int flags)
551 return build_rule_msg(tmpl, RTM_NEWRULE, NLM_F_CREATE | flags);
556 * @arg handle netlink handle
557 * @arg tmpl template with requested changes
558 * @arg flags additional netlink message flags
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.
564 * @return 0 on sucess or a negative error if an error occured.
566 int rtnl_rule_add(struct nl_handle *handle, struct rtnl_rule *tmpl, int flags)
571 msg = rtnl_rule_build_add_request(tmpl, flags);
573 return nl_errno(ENOMEM);
575 err = nl_send_auto_complete(handle, msg);
580 return nl_wait_for_ack(handle);
586 * @name Rule Deletion
591 * Build a netlink request message to delete a rule
592 * @arg rule rule to delete
593 * @arg flags additional netlink message flags
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
601 * @return The netlink message
603 struct nl_msg *rtnl_rule_build_delete_request(struct rtnl_rule *rule, int flags)
605 return build_rule_msg(rule, RTM_DELRULE, flags);
610 * @arg handle netlink handle
611 * @arg rule rule to delete
612 * @arg flags additional netlink message flags
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.
618 * @return 0 on sucess or a negative error if an error occured.
620 int rtnl_rule_delete(struct nl_handle *handle, struct rtnl_rule *rule,
626 msg = rtnl_rule_build_delete_request(rule, flags);
628 return nl_errno(ENOMEM);
630 err = nl_send_auto_complete(handle, msg);
635 return nl_wait_for_ack(handle);
641 * @name Attribute Modification
646 * Set the address family of a rule to the specified value
647 * @arg rule rule to change
648 * @arg family new address family
650 void rtnl_rule_set_family(struct rtnl_rule *rule, int family)
652 rule->r_family = family;
653 rule->r_mask |= RULE_ATTR_FAMILY;
657 * Get the address family of a rule
658 * @arg rule rule handle
659 * @return Address family or AF_UNSPEC if not set
661 int rtnl_rule_get_family(struct rtnl_rule *rule)
663 if (rule->r_mask & RULE_ATTR_FAMILY)
664 return rule->r_family;
670 * Set the priority of a rule to the specified value
671 * @arg rule rule to change
672 * @arg prio new priority
674 void rtnl_rule_set_prio(struct rtnl_rule *rule, int prio)
677 rule->r_mask |= RULE_ATTR_PRIO;
681 * Get the priority of a rule
682 * @arg rule rule handle
683 * @return Priority or -1 if not set
685 int rtnl_rule_get_prio(struct rtnl_rule *rule)
687 if (rule->r_mask & RULE_ATTR_PRIO)
694 * Set the firewall mark of a rule to the specified value
695 * @arg rule rule to change
696 * @arg fwmark new firewall mark
698 void rtnl_rule_set_fwmark(struct rtnl_rule *rule, uint64_t fwmark)
700 rule->r_fwmark = fwmark;
701 rule->r_mask |= RULE_ATTR_FWMARK;
705 * Get the firewall mark of a rule
706 * @arg rule rule handle
707 * @return Firewall mark or UINT_LEAST64_MAX if not set
709 uint64_t rtnl_rule_get_fwmark(struct rtnl_rule *rule)
711 if (rule->r_mask & RULE_ATTR_FWMARK)
712 return rule->r_fwmark;
714 return UINT_LEAST64_MAX;
718 * Set the table index of a rule to the specified value
719 * @arg rule rule to change
720 * @arg table new table
722 void rtnl_rule_set_table(struct rtnl_rule *rule, int table)
724 rule->r_table = table;
725 rule->r_mask |= RULE_ATTR_TABLE;
729 * Get the table index of a rule
730 * @arg rule rule handle
731 * @return Table index or -1 if not set
733 int rtnl_rule_get_table(struct rtnl_rule *rule)
735 if (rule->r_mask & RULE_ATTR_TABLE)
736 return rule->r_table;
742 * Set the dsfield of a rule to the specified value
743 * @arg rule rule to change
744 * @arg dsfield new dsfield value
746 void rtnl_rule_set_dsfield(struct rtnl_rule *rule, int dsfield)
748 rule->r_dsfield = dsfield;
749 rule->r_mask |= RULE_ATTR_DSFIELD;
753 * Get the dsfield of a rule
754 * @arg rule rule handle
755 * @return dsfield or -1 if not set
757 int rtnl_rule_get_dsfield(struct rtnl_rule *rule)
759 if (rule->r_mask & RULE_ATTR_DSFIELD)
760 return rule->r_dsfield;
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
770 void rtnl_rule_set_src_len(struct rtnl_rule *rule, int len)
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;
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
783 int rtnl_rule_get_src_len(struct rtnl_rule *rule)
785 if (rule->r_mask & RULE_ATTR_SRC_LEN)
786 return rule->r_src_len;
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
796 void rtnl_rule_set_dst_len(struct rtnl_rule *rule, int len)
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;
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
809 int rtnl_rule_get_dst_len(struct rtnl_rule *rule)
811 if (rule->r_mask & RULE_ATTR_DST_LEN)
812 return rule->r_dst_len;
817 static inline int __assign_addr(struct rtnl_rule *rule, struct nl_addr **pos,
818 struct nl_addr *new, uint8_t *len, int flag)
820 if (rule->r_mask & RULE_ATTR_FAMILY) {
821 if (new->a_family != rule->r_family)
822 return nl_error(EINVAL, "Address family mismatch");
824 rule->r_family = new->a_family;
831 *len = nl_addr_get_prefixlen(new);
833 rule->r_mask |= (flag | RULE_ATTR_FAMILY);
838 * Set the source address of a rule
839 * @arg rule rule to change
840 * @arg src new source address
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.
849 * @return 0 on success or a negative error code.
851 int rtnl_rule_set_src(struct rtnl_rule *rule, struct nl_addr *src)
853 return __assign_addr(rule, &rule->r_src, src, &rule->r_src_len,
854 RULE_ATTR_SRC | RULE_ATTR_SRC_LEN);
858 * Get the source address of a rule
859 * @arg rule rule handle
860 * @return Source address or NULL if not set
862 struct nl_addr *rtnl_rule_get_src(struct rtnl_rule *rule)
864 if (rule->r_mask & RULE_ATTR_SRC)
871 * Set the destination address of a rule
872 * @arg rule rule to change
873 * @arg dst new destination address
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.
882 * @return 0 on success or a negative error code.
884 int rtnl_rule_set_dst(struct rtnl_rule *rule, struct nl_addr *dst)
886 return __assign_addr(rule, &rule->r_dst, dst, &rule->r_dst_len,
887 RULE_ATTR_DST | RULE_ATTR_DST_LEN);
891 * Get the destination address of a rule
892 * @arg rule rule handle
893 * @return Destination address or NULL if not set
895 struct nl_addr *rtnl_rule_get_dst(struct rtnl_rule *rule)
897 if (rule->r_mask & RULE_ATTR_DST)
904 * Set incoming interface of routing rule object.
905 * @arg rule Routing rule object to be modified.
906 * @arg dev Name of incoming interface.
908 * @return 0 on success or a negative error code.
910 int rtnl_rule_set_iif(struct rtnl_rule *rule, const char *dev)
912 if (strlen(dev) > IFNAMSIZ-1)
913 return nl_errno(ERANGE);
915 strcpy(rule->r_iif, dev);
916 rule->r_mask |= RULE_ATTR_IIF;
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.
925 char *rtnl_rule_get_iif(struct rtnl_rule *rule)
927 if (rule->r_mask & RULE_ATTR_IIF)
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.
938 void rtnl_rule_set_action(struct rtnl_rule *rule, int type)
941 rule->r_mask |= RULE_ATTR_TYPE;
945 * Get action of routing rule object.
946 * @arg rule Routing rule object.
947 * @return Routing type or a negative error code.
949 int rtnl_rule_get_action(struct rtnl_rule *rule)
951 if (rule->r_mask & RULE_ATTR_TYPE)
954 return nl_errno(ENOENT);
958 * Set realms of routing rule object.
959 * @arg rule Routing rule object to be modified.
960 * @arg realms New realms value.
962 void rtnl_rule_set_realms(struct rtnl_rule *rule, realm_t realms)
964 rule->r_realms = realms;
965 rule->r_mask |= RULE_ATTR_REALMS;
969 * Get realms of routing rule object.
970 * @arg rule Routing rule object.
971 * @return Realms value or 0 if not set.
973 realm_t rtnl_rule_get_realms(struct rtnl_rule *rule)
975 if (rule->r_mask & RULE_ATTR_REALMS)
976 return rule->r_realms;
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),
988 { RTM_NEWRULE, "new" },
989 { RTM_DELRULE, "delete" },
990 { RTM_GETRULE, "get" },
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,
1005 static void __init rule_init(void)
1007 nl_cache_mngt_register(&rtnl_rule_ops);
1010 static void __exit rule_exit(void)
1012 nl_cache_mngt_unregister(&rtnl_rule_ops);