13#include <netlink-private/netlink.h> 
   14#include <netlink/netlink.h> 
   15#include <netlink/utils.h> 
   16#include <netlink/route/rtnl.h> 
   17#include <netlink/route/rule.h> 
   19#include <linux/fib_rules.h> 
   22#define RULE_ATTR_FAMILY        0x000001 
   23#define RULE_ATTR_TABLE         0x000002 
   24#define RULE_ATTR_ACTION        0x000004 
   25#define RULE_ATTR_FLAGS         0x000008 
   26#define RULE_ATTR_IIFNAME       0x000010 
   27#define RULE_ATTR_OIFNAME       0x000020 
   28#define RULE_ATTR_PRIO          0x000040 
   29#define RULE_ATTR_MARK          0x000080 
   30#define RULE_ATTR_MASK          0x000100 
   31#define RULE_ATTR_GOTO          0x000200 
   32#define RULE_ATTR_SRC           0x000400 
   33#define RULE_ATTR_DST           0x000800 
   34#define RULE_ATTR_DSFIELD       0x001000 
   35#define RULE_ATTR_FLOW          0x002000 
   36#define RULE_ATTR_L3MDEV        0x004000 
   37#define RULE_ATTR_PROTOCOL      0x008000 
   38#define RULE_ATTR_IP_PROTO      0x010000 
   39#define RULE_ATTR_SPORT         0x020000 
   40#define RULE_ATTR_DPORT         0x040000 
   42static struct nl_cache_ops rtnl_rule_ops;
 
   43static struct nl_object_ops rule_obj_ops;
 
   46static void rule_free_data(
struct nl_object *c)
 
   48        struct rtnl_rule *rule = nl_object_priv(c);
 
   57static int rule_clone(
struct nl_object *_dst, 
struct nl_object *_src)
 
   59        struct rtnl_rule *dst = nl_object_priv(_dst);
 
   60        struct rtnl_rule *src = nl_object_priv(_src);
 
   76static struct nla_policy rule_policy[FRA_MAX+1] = {
 
   78        [FRA_IIFNAME]   = { .type = 
NLA_STRING, .maxlen = IFNAMSIZ },
 
   79        [FRA_OIFNAME]   = { .type = 
NLA_STRING, .maxlen = IFNAMSIZ },
 
   80        [FRA_PRIORITY]  = { .type = 
NLA_U32 },
 
   81        [FRA_FWMARK]    = { .type = 
NLA_U32 },
 
   82        [FRA_FWMASK]    = { .type = 
NLA_U32 },
 
   83        [FRA_GOTO]      = { .type = 
NLA_U32 },
 
   84        [FRA_FLOW]      = { .type = 
NLA_U32 },
 
   85        [FRA_L3MDEV]    = { .type = 
NLA_U8 },
 
   86        [FRA_PROTOCOL]  = { .type = 
NLA_U8 },
 
   87        [FRA_IP_PROTO]  = { .type = 
NLA_U8 },
 
   88        [FRA_SPORT_RANGE] = { .minlen = 
sizeof(
struct fib_rule_port_range),
 
   89                              .maxlen = 
sizeof(
struct fib_rule_port_range) },
 
   90        [FRA_DPORT_RANGE] = { .minlen = 
sizeof(
struct fib_rule_port_range),
 
   91                              .maxlen = 
sizeof(
struct fib_rule_port_range) },
 
   94static int rule_msg_parser(
struct nl_cache_ops *ops, 
struct sockaddr_nl *who,
 
   95                           struct nlmsghdr *n, 
struct nl_parser_param *pp)
 
   97        struct rtnl_rule *rule;
 
   98        struct fib_rule_hdr *frh;
 
   99        struct nlattr *tb[FRA_MAX+1];
 
  102        rule = rtnl_rule_alloc();
 
  108        rule->ce_msgtype = n->nlmsg_type;
 
  111        err = 
nlmsg_parse(n, 
sizeof(*frh), tb, FRA_MAX, rule_policy);
 
  115        rule->r_family = family = frh->family;
 
  116        rule->r_table = frh->table;
 
  117        rule->r_action = frh->action;
 
  118        rule->r_flags = frh->flags;
 
  120        rule->ce_mask = (RULE_ATTR_FAMILY | RULE_ATTR_ACTION | RULE_ATTR_FLAGS);
 
  122                rule->ce_mask |= RULE_ATTR_TABLE;
 
  126                rule->r_dsfield = frh->tos;
 
  127                rule->ce_mask |= RULE_ATTR_DSFIELD;
 
  133                        rule->ce_mask |= RULE_ATTR_TABLE;
 
  136        if (tb[FRA_IIFNAME]) {
 
  137                nla_strlcpy(rule->r_iifname, tb[FRA_IIFNAME], IFNAMSIZ);
 
  138                rule->ce_mask |= RULE_ATTR_IIFNAME;
 
  141        if (tb[FRA_OIFNAME]) {
 
  142                nla_strlcpy(rule->r_oifname, tb[FRA_OIFNAME], IFNAMSIZ);
 
  143                rule->ce_mask |= RULE_ATTR_OIFNAME;
 
  146        if (tb[FRA_PRIORITY]) {
 
  148                rule->ce_mask |= RULE_ATTR_PRIO;
 
  151        if (tb[FRA_FWMARK]) {
 
  153                rule->ce_mask |= RULE_ATTR_MARK;
 
  156        if (tb[FRA_FWMASK]) {
 
  158                rule->ce_mask |= RULE_ATTR_MASK;
 
  163                rule->ce_mask |= RULE_ATTR_GOTO;
 
  171                rule->ce_mask |= RULE_ATTR_SRC;
 
  178                rule->ce_mask |= RULE_ATTR_DST;
 
  184                rule->ce_mask |= RULE_ATTR_FLOW;
 
  187        if (tb[FRA_L3MDEV]) {
 
  189                rule->ce_mask |= RULE_ATTR_L3MDEV;
 
  192        if (tb[FRA_PROTOCOL]) {
 
  193                rule->r_protocol = 
nla_get_u8(tb[FRA_PROTOCOL]);
 
  194                rule->ce_mask |= RULE_ATTR_PROTOCOL;
 
  197        if (tb[FRA_IP_PROTO]) {
 
  198                rule->r_ip_proto = 
nla_get_u8(tb[FRA_IP_PROTO]);
 
  199                rule->ce_mask |= RULE_ATTR_IP_PROTO;
 
  202        if (tb[FRA_SPORT_RANGE]) {
 
  203                struct fib_rule_port_range *pr;
 
  207                rule->ce_mask |= RULE_ATTR_SPORT;
 
  210        if (tb[FRA_DPORT_RANGE]) {
 
  211                struct fib_rule_port_range *pr;
 
  215                rule->ce_mask |= RULE_ATTR_DPORT;
 
  218        err = pp->pp_cb((
struct nl_object *) rule, pp);
 
  228static int rule_request_update(
struct nl_cache *c, 
struct nl_sock *h)
 
  233static void rule_dump_line(
struct nl_object *o, 
struct nl_dump_params *p)
 
  235        struct rtnl_rule *r = (
struct rtnl_rule *) o;
 
  238        nl_dump_line(p, 
"%8d ", (r->ce_mask & RULE_ATTR_PRIO) ? r->r_prio : 0);
 
  239        nl_dump(p, 
"%s ", nl_af2str(r->r_family, buf, 
sizeof(buf)));
 
  241        if (r->ce_mask & RULE_ATTR_SRC)
 
  245        if (r->ce_mask & RULE_ATTR_DST)
 
  249        if (r->ce_mask & RULE_ATTR_DSFIELD)
 
  250                nl_dump(p, 
"tos %u ", r->r_dsfield);
 
  252        if (r->ce_mask & (RULE_ATTR_MARK | RULE_ATTR_MASK))
 
  253                nl_dump(p, 
"mark %#x/%#x", r->r_mark, r->r_mask);
 
  255        if (r->ce_mask & RULE_ATTR_IIFNAME)
 
  256                nl_dump(p, 
"iif %s ", r->r_iifname);
 
  258        if (r->ce_mask & RULE_ATTR_OIFNAME)
 
  259                nl_dump(p, 
"oif %s ", r->r_oifname);
 
  261        if (r->ce_mask & RULE_ATTR_TABLE)
 
  263                        rtnl_route_table2str(r->r_table, buf, 
sizeof(buf)));
 
  265        if (r->ce_mask & RULE_ATTR_L3MDEV)
 
  266                nl_dump(p, 
"lookup [l3mdev-table] ");
 
  268        if (r->ce_mask & RULE_ATTR_IP_PROTO)
 
  270                        nl_ip_proto2str(r->r_ip_proto, buf, 
sizeof(buf)));
 
  272        if (r->ce_mask & RULE_ATTR_SPORT) {
 
  273                if (r->r_sport.start == r->r_sport.end)
 
  274                        nl_dump(p, 
"sport %u ", r->r_sport.start);
 
  277                                r->r_sport.start, r->r_sport.end);
 
  280        if (r->ce_mask & RULE_ATTR_DPORT) {
 
  281                if (r->r_dport.start == r->r_dport.end)
 
  282                        nl_dump(p, 
"dport %u ", r->r_dport.start);
 
  285                                r->r_dport.start, r->r_dport.end);
 
  288        if (r->ce_mask & RULE_ATTR_PROTOCOL)
 
  290                        rtnl_route_proto2str(r->r_protocol, buf, 
sizeof(buf)));
 
  292        if (r->ce_mask & RULE_ATTR_FLOW)
 
  294                        rtnl_realms2str(r->r_flow, buf, 
sizeof(buf)));
 
  296        if (r->ce_mask & RULE_ATTR_GOTO)
 
  297                nl_dump(p, 
"goto %u ", r->r_goto);
 
  299        if (r->ce_mask & RULE_ATTR_ACTION)
 
  301                        nl_rtntype2str(r->r_action, buf, 
sizeof(buf)));
 
  306static void rule_dump_details(
struct nl_object *obj, 
struct nl_dump_params *p)
 
  308        rule_dump_line(obj, p);
 
  311static void rule_dump_stats(
struct nl_object *obj, 
struct nl_dump_params *p)
 
  313        rule_dump_details(obj, p);
 
  316static uint64_t rule_compare(
struct nl_object *_a, 
struct nl_object *_b,
 
  317                             uint64_t attrs, 
int flags)
 
  319        struct rtnl_rule *a = (
struct rtnl_rule *) _a;
 
  320        struct rtnl_rule *b = (
struct rtnl_rule *) _b;
 
  323#define RULE_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, RULE_ATTR_##ATTR, a, b, EXPR) 
  325        diff |= RULE_DIFF(FAMILY,       a->r_family != b->r_family);
 
  326        diff |= RULE_DIFF(TABLE,        a->r_table != b->r_table);
 
  327        diff |= RULE_DIFF(ACTION,       a->r_action != b->r_action);
 
  328        diff |= RULE_DIFF(IIFNAME,      strcmp(a->r_iifname, b->r_iifname));
 
  329        diff |= RULE_DIFF(OIFNAME,      strcmp(a->r_oifname, b->r_oifname));
 
  330        diff |= RULE_DIFF(PRIO,         a->r_prio != b->r_prio);
 
  331        diff |= RULE_DIFF(MARK,         a->r_mark != b->r_mark);
 
  332        diff |= RULE_DIFF(MASK,         a->r_mask != b->r_mask);
 
  333        diff |= RULE_DIFF(GOTO,         a->r_goto != b->r_goto);
 
  334        diff |= RULE_DIFF(SRC,          
nl_addr_cmp(a->r_src, b->r_src));
 
  335        diff |= RULE_DIFF(DST,          
nl_addr_cmp(a->r_dst, b->r_dst));
 
  336        diff |= RULE_DIFF(DSFIELD,      a->r_dsfield != b->r_dsfield);
 
  337        diff |= RULE_DIFF(FLOW,         a->r_flow != b->r_flow);
 
  344static const struct trans_tbl rule_attrs[] = {
 
  345        __ADD(RULE_ATTR_FAMILY, family),
 
  346        __ADD(RULE_ATTR_TABLE, table),
 
  347        __ADD(RULE_ATTR_ACTION, action),
 
  348        __ADD(RULE_ATTR_IIFNAME, iifname),
 
  349        __ADD(RULE_ATTR_OIFNAME, oifname),
 
  350        __ADD(RULE_ATTR_PRIO, prio),
 
  351        __ADD(RULE_ATTR_MARK, mark),
 
  352        __ADD(RULE_ATTR_MASK, mask),
 
  353        __ADD(RULE_ATTR_GOTO, 
goto),
 
  354        __ADD(RULE_ATTR_SRC, src),
 
  355        __ADD(RULE_ATTR_DST, dst),
 
  356        __ADD(RULE_ATTR_DSFIELD, dsfield),
 
  357        __ADD(RULE_ATTR_FLOW, flow),
 
  360static char *rule_attrs2str(
int attrs, 
char *buf, 
size_t len)
 
  362        return __flags2str(attrs, buf, len, rule_attrs,
 
  363                           ARRAY_SIZE(rule_attrs));
 
  371struct rtnl_rule *rtnl_rule_alloc(
void)
 
  376void rtnl_rule_put(
struct rtnl_rule *rule)
 
  400                          struct nl_cache **result)
 
  402        struct nl_cache * cache;
 
  408        cache->c_iarg1 = family;
 
  426static int build_rule_msg(
struct rtnl_rule *tmpl, 
int cmd, 
int flags,
 
  427                          struct nl_msg **result)
 
  430        struct fib_rule_hdr frh = {
 
  431                .family = tmpl->r_family,
 
  432                .table = tmpl->r_table,
 
  433                .action = tmpl->r_action,
 
  434                .flags = tmpl->r_flags,
 
  435                .tos = tmpl->r_dsfield,
 
  438        if (!(tmpl->ce_mask & RULE_ATTR_FAMILY))
 
  439                return -NLE_MISSING_ATTR;
 
  445        if (tmpl->ce_mask & RULE_ATTR_SRC) 
 
  448        if (tmpl->ce_mask & RULE_ATTR_DST)
 
  451        if (
nlmsg_append(msg, &frh, 
sizeof(frh), NLMSG_ALIGNTO) < 0)
 
  452                goto nla_put_failure;
 
  458        if (tmpl->ce_mask & RULE_ATTR_SRC)
 
  461        if (tmpl->ce_mask & RULE_ATTR_DST) 
 
  464        if (tmpl->ce_mask & RULE_ATTR_IIFNAME)
 
  467        if (tmpl->ce_mask & RULE_ATTR_OIFNAME)
 
  470        if (tmpl->ce_mask & RULE_ATTR_PRIO)
 
  473        if (tmpl->ce_mask & RULE_ATTR_MARK)
 
  476        if (tmpl->ce_mask & RULE_ATTR_MASK)
 
  479        if (tmpl->ce_mask & RULE_ATTR_GOTO)
 
  482        if (tmpl->ce_mask & RULE_ATTR_FLOW)
 
  485        if (tmpl->ce_mask & RULE_ATTR_L3MDEV)
 
  488        if (tmpl->ce_mask & RULE_ATTR_IP_PROTO)
 
  489                NLA_PUT_U8(msg, FRA_IP_PROTO, tmpl->r_ip_proto);
 
  491        if (tmpl->ce_mask & RULE_ATTR_SPORT)
 
  492                NLA_PUT(msg, FRA_SPORT_RANGE, 
sizeof(tmpl->r_sport),
 
  495        if (tmpl->ce_mask & RULE_ATTR_DPORT)
 
  496                NLA_PUT(msg, FRA_DPORT_RANGE, 
sizeof(tmpl->r_dport),
 
  499        if (tmpl->ce_mask & RULE_ATTR_PROTOCOL)
 
  500                NLA_PUT_U8(msg, FRA_PROTOCOL, tmpl->r_protocol);
 
  525                                struct nl_msg **result)
 
  527        return build_rule_msg(tmpl, RTM_NEWRULE, NLM_F_CREATE | flags,
 
  556        return wait_for_ack(sk);
 
  581                                   struct nl_msg **result)
 
  583        return build_rule_msg(rule, RTM_DELRULE, flags, result);
 
  611        return wait_for_ack(sk);
 
  621void rtnl_rule_set_family(
struct rtnl_rule *rule, 
int family)
 
  623        rule->r_family = family;
 
  624        rule->ce_mask |= RULE_ATTR_FAMILY;
 
  627int rtnl_rule_get_family(
struct rtnl_rule *rule)
 
  629        if (rule->ce_mask & RULE_ATTR_FAMILY)
 
  630                return rule->r_family;
 
  635void rtnl_rule_set_prio(
struct rtnl_rule *rule, uint32_t prio)
 
  638        rule->ce_mask |= RULE_ATTR_PRIO;
 
  641uint32_t rtnl_rule_get_prio(
struct rtnl_rule *rule)
 
  646void rtnl_rule_set_mark(
struct rtnl_rule *rule, uint32_t mark)
 
  649        rule->ce_mask |= RULE_ATTR_MARK;
 
  652uint32_t rtnl_rule_get_mark(
struct rtnl_rule *rule)
 
  657void rtnl_rule_set_mask(
struct rtnl_rule *rule, uint32_t mask)
 
  660        rule->ce_mask |= RULE_ATTR_MASK;
 
  663uint32_t rtnl_rule_get_mask(
struct rtnl_rule *rule)
 
  668void rtnl_rule_set_table(
struct rtnl_rule *rule, uint32_t table)
 
  670        rule->r_table = table;
 
  671        rule->ce_mask |= RULE_ATTR_TABLE;
 
  674uint32_t rtnl_rule_get_table(
struct rtnl_rule *rule)
 
  676        return rule->r_table;
 
  679void rtnl_rule_set_dsfield(
struct rtnl_rule *rule, uint8_t dsfield)
 
  681        rule->r_dsfield = dsfield;
 
  682        rule->ce_mask |= RULE_ATTR_DSFIELD;
 
  685uint8_t rtnl_rule_get_dsfield(
struct rtnl_rule *rule)
 
  687        return rule->r_dsfield;
 
  690static inline int __assign_addr(
struct rtnl_rule *rule, 
struct nl_addr **pos,
 
  691                                struct nl_addr *
new, 
int flag)
 
  693        if (rule->ce_mask & RULE_ATTR_FAMILY) {
 
  694                if (new->a_family != rule->r_family)
 
  695                        return -NLE_AF_MISMATCH;
 
  697                rule->r_family = 
new->a_family;
 
  705        rule->ce_mask |= (flag | RULE_ATTR_FAMILY);
 
  710int rtnl_rule_set_src(
struct rtnl_rule *rule, 
struct nl_addr *src)
 
  712        return __assign_addr(rule, &rule->r_src, src, RULE_ATTR_SRC);
 
  715struct nl_addr *rtnl_rule_get_src(
struct rtnl_rule *rule)
 
  720int rtnl_rule_set_dst(
struct rtnl_rule *rule, 
struct nl_addr *dst)
 
  722        return __assign_addr(rule, &rule->r_dst, dst, RULE_ATTR_DST);
 
  725struct nl_addr *rtnl_rule_get_dst(
struct rtnl_rule *rule)
 
  730int rtnl_rule_set_iif(
struct rtnl_rule *rule, 
const char *dev)
 
  732        if (strlen(dev) > IFNAMSIZ-1)
 
  735        strcpy(rule->r_iifname, dev);
 
  736        rule->ce_mask |= RULE_ATTR_IIFNAME;
 
  740char *rtnl_rule_get_iif(
struct rtnl_rule *rule)
 
  742        if (rule->ce_mask & RULE_ATTR_IIFNAME)
 
  743                return rule->r_iifname;
 
  748int rtnl_rule_set_oif(
struct rtnl_rule *rule, 
const char *dev)
 
  750        if (strlen(dev) > IFNAMSIZ-1)
 
  753        strcpy(rule->r_oifname, dev);
 
  754        rule->ce_mask |= RULE_ATTR_OIFNAME;
 
  758char *rtnl_rule_get_oif(
struct rtnl_rule *rule)
 
  760        if (rule->ce_mask & RULE_ATTR_OIFNAME)
 
  761                return rule->r_oifname;
 
  766void rtnl_rule_set_action(
struct rtnl_rule *rule, uint8_t action)
 
  768        rule->r_action = action;
 
  769        rule->ce_mask |= RULE_ATTR_ACTION;
 
  772uint8_t rtnl_rule_get_action(
struct rtnl_rule *rule)
 
  774        return rule->r_action;
 
  789                rule->r_l3mdev = (uint8_t) value;
 
  790                rule->ce_mask |= RULE_ATTR_L3MDEV;
 
  793                rule->ce_mask &= ~((uint32_t) RULE_ATTR_L3MDEV);
 
  810        if (!(rule->ce_mask & RULE_ATTR_L3MDEV))
 
  811                return -NLE_MISSING_ATTR;
 
  812        return rule->r_l3mdev;
 
  815int rtnl_rule_set_protocol(
struct rtnl_rule *rule, uint8_t protocol)
 
  818                rule->r_protocol = protocol;
 
  819                rule->ce_mask |= RULE_ATTR_PROTOCOL;
 
  821                rule->r_protocol = 0;
 
  822                rule->ce_mask &= ~((uint32_t) RULE_ATTR_PROTOCOL);
 
  827int rtnl_rule_get_protocol(
struct rtnl_rule *rule, uint8_t *protocol)
 
  829        if (!(rule->ce_mask & RULE_ATTR_PROTOCOL))
 
  832        *protocol = rule->r_protocol;
 
  836int rtnl_rule_set_ipproto(
struct rtnl_rule *rule, uint8_t ip_proto)
 
  839                rule->r_ip_proto = ip_proto;
 
  840                rule->ce_mask |= RULE_ATTR_IP_PROTO;
 
  842                rule->r_ip_proto = 0;
 
  843                rule->ce_mask &= ~((uint32_t) RULE_ATTR_IP_PROTO);
 
  848int rtnl_rule_get_ipproto(
struct rtnl_rule *rule, uint8_t *ip_proto)
 
  850        if (!(rule->ce_mask & RULE_ATTR_IP_PROTO))
 
  853        *ip_proto = rule->r_ip_proto;
 
  857static int __rtnl_rule_set_port(
struct fib_rule_port_range *prange,
 
  858                                uint16_t start, uint16_t end,
 
  859                                uint64_t attr, uint64_t *mask)
 
  861        if ((start && end < start) || (end && !start))
 
  865                prange->start = start;
 
  877int rtnl_rule_set_sport(
struct rtnl_rule *rule, uint16_t sport)
 
  879        return __rtnl_rule_set_port(&rule->r_sport, sport, sport,
 
  880                                    RULE_ATTR_SPORT, &rule->ce_mask);
 
  883int rtnl_rule_set_sport_range(
struct rtnl_rule *rule, uint16_t start,
 
  886        return __rtnl_rule_set_port(&rule->r_sport, start, end,
 
  887                                    RULE_ATTR_SPORT, &rule->ce_mask);
 
  890int rtnl_rule_get_sport(
struct rtnl_rule *rule, uint16_t *start, uint16_t *end)
 
  892        if (!(rule->ce_mask & RULE_ATTR_SPORT))
 
  895        *start = rule->r_sport.start;
 
  896        *end = rule->r_sport.end;
 
  900int rtnl_rule_set_dport(
struct rtnl_rule *rule, uint16_t dport)
 
  902        return __rtnl_rule_set_port(&rule->r_dport, dport, dport,
 
  903                                    RULE_ATTR_DPORT, &rule->ce_mask);
 
  906int rtnl_rule_set_dport_range(
struct rtnl_rule *rule, uint16_t start,
 
  909        return __rtnl_rule_set_port(&rule->r_dport, start, end,
 
  910                                    RULE_ATTR_DPORT, &rule->ce_mask);
 
  913int rtnl_rule_get_dport(
struct rtnl_rule *rule, uint16_t *start, uint16_t *end)
 
  915        if (!(rule->ce_mask & RULE_ATTR_DPORT))
 
  918        *start = rule->r_dport.start;
 
  919        *end = rule->r_dport.end;
 
  923void rtnl_rule_set_realms(
struct rtnl_rule *rule, uint32_t realms)
 
  925        rule->r_flow = realms;
 
  926        rule->ce_mask |= RULE_ATTR_FLOW;
 
  929uint32_t rtnl_rule_get_realms(
struct rtnl_rule *rule)
 
  934void rtnl_rule_set_goto(
struct rtnl_rule *rule, uint32_t ref)
 
  937        rule->ce_mask |= RULE_ATTR_GOTO;
 
  940uint32_t rtnl_rule_get_goto(
struct rtnl_rule *rule)
 
  947static struct nl_object_ops rule_obj_ops = {
 
  948        .oo_name                = 
"route/rule",
 
  949        .oo_size                = 
sizeof(
struct rtnl_rule),
 
  950        .oo_free_data           = rule_free_data,
 
  951        .oo_clone               = rule_clone,
 
  957        .oo_compare             = rule_compare,
 
  958        .oo_attrs2str           = rule_attrs2str,
 
  962static struct nl_af_group rule_groups[] = {
 
  963        { AF_INET,      RTNLGRP_IPV4_RULE },
 
  964        { AF_INET6,     RTNLGRP_IPV6_RULE },
 
  965        { END_OF_GROUP_LIST },
 
  968static struct nl_cache_ops rtnl_rule_ops = {
 
  969        .co_name                = 
"route/rule",
 
  970        .co_hdrsize             = 
sizeof(
struct fib_rule_hdr),
 
  972                                        { RTM_NEWRULE, NL_ACT_NEW, 
"new" },
 
  973                                        { RTM_DELRULE, NL_ACT_DEL, 
"del" },
 
  974                                        { RTM_GETRULE, NL_ACT_GET, 
"get" },
 
  975                                        END_OF_MSGTYPES_LIST,
 
  977        .co_protocol            = NETLINK_ROUTE,
 
  978        .co_request_update      = rule_request_update,
 
  979        .co_msg_parser          = rule_msg_parser,
 
  980        .co_obj_ops             = &rule_obj_ops,
 
  981        .co_groups              = rule_groups,
 
  984static void __init rule_init(
void)
 
  989static void __exit rule_exit(
void)
 
void nl_addr_set_prefixlen(struct nl_addr *addr, int prefixlen)
Set the prefix length of an abstract address.
 
struct nl_addr * nl_addr_get(struct nl_addr *addr)
Increase the reference counter of an abstract address.
 
struct nl_addr * nl_addr_alloc_attr(const struct nlattr *nla, int family)
Allocate abstract address based on Netlink attribute.
 
int nl_addr_cmp(const struct nl_addr *a, const struct nl_addr *b)
Compare abstract addresses.
 
struct nl_addr * nl_addr_clone(const struct nl_addr *addr)
Clone existing abstract address object.
 
char * nl_addr2str(const struct nl_addr *addr, char *buf, size_t size)
Convert abstract address object to character string.
 
unsigned int nl_addr_get_prefixlen(const struct nl_addr *addr)
Return prefix length of abstract address object.
 
void nl_addr_put(struct nl_addr *addr)
Decrease the reference counter of an abstract address.
 
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
 
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
 
#define NLA_PUT_ADDR(msg, attrtype, addr)
Add address attribute to netlink message.
 
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
 
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
 
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
 
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
 
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
Copy string attribute payload to a buffer.
 
#define NLA_PUT_STRING(msg, attrtype, value)
Add string attribute to netlink message.
 
@ NLA_STRING
NUL terminated character string.
 
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
Unregister a set of cache operations.
 
int nl_cache_mngt_register(struct nl_cache_ops *ops)
Register a set of cache operations.
 
int nl_cache_refill(struct nl_sock *sk, struct nl_cache *cache)
(Re)fill a cache with the contents in the kernel.
 
struct nl_cache * nl_cache_alloc(struct nl_cache_ops *ops)
Allocate new cache.
 
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
 
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
 
void nlmsg_free(struct nl_msg *msg)
Release a reference from an netlink message.
 
int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy)
parse attributes of a netlink message
 
int nlmsg_append(struct nl_msg *n, void *data, size_t len, int pad)
Append data to tail of a netlink message.
 
void nl_object_put(struct nl_object *obj)
Release a reference from an object.
 
struct nl_object * nl_object_alloc(struct nl_object_ops *ops)
Allocate a new object of kind specified by the operations handle.
 
int nl_rtgen_request(struct nl_sock *sk, int type, int family, int flags)
Send routing netlink request message.
 
int rtnl_rule_delete(struct nl_sock *sk, struct rtnl_rule *rule, int flags)
Delete a rule.
 
int rtnl_rule_build_delete_request(struct rtnl_rule *rule, int flags, struct nl_msg **result)
Build a netlink request message to delete a rule.
 
int rtnl_rule_alloc_cache(struct nl_sock *sock, int family, struct nl_cache **result)
Build a rule cache including all rules currently configured in the kernel.
 
int rtnl_rule_get_l3mdev(struct rtnl_rule *rule)
Get l3mdev value of the rule (FRA_L3MDEV)
 
void rtnl_rule_set_l3mdev(struct rtnl_rule *rule, int value)
Set l3mdev value of the rule (FRA_L3MDEV)
 
int rtnl_rule_build_add_request(struct rtnl_rule *tmpl, int flags, struct nl_msg **result)
Build netlink request message to add a new rule.
 
int rtnl_rule_add(struct nl_sock *sk, struct rtnl_rule *tmpl, int flags)
Add a new rule.
 
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
 
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
 
@ NL_DUMP_STATS
Dump all attributes including statistics.
 
@ NL_DUMP_LINE
Dump object briefly on one line.
 
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
 
Attribute validation policy.
 
uint16_t type
Type of attribute or NLA_UNSPEC.