114c0b97dSThomas Graf #ifndef __NET_FIB_RULES_H 214c0b97dSThomas Graf #define __NET_FIB_RULES_H 314c0b97dSThomas Graf 414c0b97dSThomas Graf #include <linux/types.h> 55a0e3ad6STejun Heo #include <linux/slab.h> 614c0b97dSThomas Graf #include <linux/netdevice.h> 714c0b97dSThomas Graf #include <linux/fib_rules.h> 814c0b97dSThomas Graf #include <net/flow.h> 99d9e6a58SThomas Graf #include <net/rtnetlink.h> 1014c0b97dSThomas Graf 11fd2c3ef7SEric Dumazet struct fib_rule { 1214c0b97dSThomas Graf struct list_head list; 13491deb24SPatrick McHardy int iifindex; 141b038a5eSPatrick McHardy int oifindex; 15b8964ed9SThomas Graf u32 mark; 16b8964ed9SThomas Graf u32 mark_mask; 1714c0b97dSThomas Graf u32 flags; 1814c0b97dSThomas Graf u32 table; 1914c0b97dSThomas Graf u8 action; 20fba3679dSEric Dumazet /* 3 bytes hole, try to use */ 210947c9feSThomas Graf u32 target; 22e7030878SThomas Graf __be64 tun_id; 237a2b03c5SEric Dumazet struct fib_rule __rcu *ctarget; 24fba3679dSEric Dumazet struct net *fr_net; 25fba3679dSEric Dumazet 26fba3679dSEric Dumazet atomic_t refcnt; 27fba3679dSEric Dumazet u32 pref; 28fba3679dSEric Dumazet int suppress_ifgroup; 29fba3679dSEric Dumazet int suppress_prefixlen; 30491deb24SPatrick McHardy char iifname[IFNAMSIZ]; 311b038a5eSPatrick McHardy char oifname[IFNAMSIZ]; 3214c0b97dSThomas Graf struct rcu_head rcu; 3314c0b97dSThomas Graf }; 3414c0b97dSThomas Graf 35fd2c3ef7SEric Dumazet struct fib_lookup_arg { 3614c0b97dSThomas Graf void *lookup_ptr; 3714c0b97dSThomas Graf void *result; 3814c0b97dSThomas Graf struct fib_rule *rule; 39ebc0ffaeSEric Dumazet int flags; 40ebc0ffaeSEric Dumazet #define FIB_LOOKUP_NOREF 1 410eeb075fSAndy Gospodarek #define FIB_LOOKUP_IGNORE_LINKSTATE 2 4214c0b97dSThomas Graf }; 4314c0b97dSThomas Graf 44fd2c3ef7SEric Dumazet struct fib_rules_ops { 4514c0b97dSThomas Graf int family; 4614c0b97dSThomas Graf struct list_head list; 4714c0b97dSThomas Graf int rule_size; 48e1701c68SThomas Graf int addr_size; 490947c9feSThomas Graf int unresolved_rules; 500947c9feSThomas Graf int nr_goto_rules; 5114c0b97dSThomas Graf 5214c0b97dSThomas Graf int (*action)(struct fib_rule *, 5314c0b97dSThomas Graf struct flowi *, int, 5414c0b97dSThomas Graf struct fib_lookup_arg *); 557764a45aSStefan Tomanek bool (*suppress)(struct fib_rule *, 567764a45aSStefan Tomanek struct fib_lookup_arg *); 5714c0b97dSThomas Graf int (*match)(struct fib_rule *, 5814c0b97dSThomas Graf struct flowi *, int); 5914c0b97dSThomas Graf int (*configure)(struct fib_rule *, 6014c0b97dSThomas Graf struct sk_buff *, 6114c0b97dSThomas Graf struct fib_rule_hdr *, 6214c0b97dSThomas Graf struct nlattr **); 630ddcf43dSAlexander Duyck int (*delete)(struct fib_rule *); 6414c0b97dSThomas Graf int (*compare)(struct fib_rule *, 6514c0b97dSThomas Graf struct fib_rule_hdr *, 6614c0b97dSThomas Graf struct nlattr **); 6714c0b97dSThomas Graf int (*fill)(struct fib_rule *, struct sk_buff *, 6814c0b97dSThomas Graf struct fib_rule_hdr *); 69339bf98fSThomas Graf size_t (*nlmsg_payload)(struct fib_rule *); 7014c0b97dSThomas Graf 7173417f61SThomas Graf /* Called after modifications to the rules set, must flush 7273417f61SThomas Graf * the route cache if one exists. */ 73ae299fc0SDenis V. Lunev void (*flush_cache)(struct fib_rules_ops *ops); 7473417f61SThomas Graf 7514c0b97dSThomas Graf int nlgroup; 76ef7c79edSPatrick McHardy const struct nla_policy *policy; 7776c72d4fSDenis V. Lunev struct list_head rules_list; 7814c0b97dSThomas Graf struct module *owner; 7903592383SDenis V. Lunev struct net *fro_net; 80e9c5158aSEric W. Biederman struct rcu_head rcu; 8114c0b97dSThomas Graf }; 8214c0b97dSThomas Graf 831f6c9557SThomas Graf #define FRA_GENERIC_POLICY \ 84491deb24SPatrick McHardy [FRA_IIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ 851b038a5eSPatrick McHardy [FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ 861f6c9557SThomas Graf [FRA_PRIORITY] = { .type = NLA_U32 }, \ 871f6c9557SThomas Graf [FRA_FWMARK] = { .type = NLA_U32 }, \ 881f6c9557SThomas Graf [FRA_FWMASK] = { .type = NLA_U32 }, \ 890947c9feSThomas Graf [FRA_TABLE] = { .type = NLA_U32 }, \ 9073f5698eSStefan Tomanek [FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \ 916ef94cfaSStefan Tomanek [FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \ 920947c9feSThomas Graf [FRA_GOTO] = { .type = NLA_U32 } 931f6c9557SThomas Graf 9414c0b97dSThomas Graf static inline void fib_rule_get(struct fib_rule *rule) 9514c0b97dSThomas Graf { 9614c0b97dSThomas Graf atomic_inc(&rule->refcnt); 9714c0b97dSThomas Graf } 9814c0b97dSThomas Graf 9914c0b97dSThomas Graf static inline void fib_rule_put(struct fib_rule *rule) 10014c0b97dSThomas Graf { 10114c0b97dSThomas Graf if (atomic_dec_and_test(&rule->refcnt)) 102efd7ef1cSEric W. Biederman kfree_rcu(rule, rcu); 10314c0b97dSThomas Graf } 10414c0b97dSThomas Graf 1059e762a4aSPatrick McHardy static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla) 1069e762a4aSPatrick McHardy { 1079e762a4aSPatrick McHardy if (nla[FRA_TABLE]) 1089e762a4aSPatrick McHardy return nla_get_u32(nla[FRA_TABLE]); 1099e762a4aSPatrick McHardy return frh->table; 1109e762a4aSPatrick McHardy } 1119e762a4aSPatrick McHardy 1128de6879fSJoe Perches struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *, 1138de6879fSJoe Perches struct net *); 1148de6879fSJoe Perches void fib_rules_unregister(struct fib_rules_ops *); 11514c0b97dSThomas Graf 1168de6879fSJoe Perches int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags, 11714c0b97dSThomas Graf struct fib_lookup_arg *); 1188de6879fSJoe Perches int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table, 1192994c638SDenis V. Lunev u32 flags); 12014c0b97dSThomas Graf #endif 121