xref: /linux/include/net/fib_rules.h (revision 84a73014d86fd660822a20c032625e3afe99ca58)
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