fib_rules.h 5.4 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0 */
2 3 4 5
#ifndef __NET_FIB_RULES_H
#define __NET_FIB_RULES_H

#include <linux/types.h>
6
#include <linux/slab.h>
7 8
#include <linux/netdevice.h>
#include <linux/fib_rules.h>
9
#include <linux/refcount.h>
10
#include <net/flow.h>
11
#include <net/rtnetlink.h>
12
#include <net/fib_notifier.h>
13

14 15 16 17 18
struct fib_kuid_range {
	kuid_t start;
	kuid_t end;
};

E
Eric Dumazet 已提交
19
struct fib_rule {
20
	struct list_head	list;
21
	int			iifindex;
22
	int			oifindex;
23 24
	u32			mark;
	u32			mark_mask;
25 26 27
	u32			flags;
	u32			table;
	u8			action;
D
David Ahern 已提交
28
	u8			l3mdev;
29
	u8                      proto;
30
	u8			ip_proto;
T
Thomas Graf 已提交
31
	u32			target;
32
	__be64			tun_id;
E
Eric Dumazet 已提交
33
	struct fib_rule __rcu	*ctarget;
34 35
	struct net		*fr_net;

36
	refcount_t		refcnt;
37 38 39
	u32			pref;
	int			suppress_ifgroup;
	int			suppress_prefixlen;
40
	char			iifname[IFNAMSIZ];
41
	char			oifname[IFNAMSIZ];
42
	struct fib_kuid_range	uid_range;
43 44
	struct fib_rule_port_range	sport_range;
	struct fib_rule_port_range	dport_range;
45
	struct rcu_head		rcu;
46 47

	ALI_HOTFIX_RESERVE(1)
48 49
};

E
Eric Dumazet 已提交
50
struct fib_lookup_arg {
51
	void			*lookup_ptr;
D
David Ahern 已提交
52
	const void		*lookup_data;
53 54
	void			*result;
	struct fib_rule		*rule;
D
David Ahern 已提交
55
	u32			table;
E
Eric Dumazet 已提交
56
	int			flags;
57 58
#define FIB_LOOKUP_NOREF		1
#define FIB_LOOKUP_IGNORE_LINKSTATE	2
59 60
};

E
Eric Dumazet 已提交
61
struct fib_rules_ops {
62 63 64
	int			family;
	struct list_head	list;
	int			rule_size;
65
	int			addr_size;
T
Thomas Graf 已提交
66 67
	int			unresolved_rules;
	int			nr_goto_rules;
68
	unsigned int		fib_rules_seq;
69 70 71 72

	int			(*action)(struct fib_rule *,
					  struct flowi *, int,
					  struct fib_lookup_arg *);
73 74
	bool			(*suppress)(struct fib_rule *,
					    struct fib_lookup_arg *);
75 76 77 78 79
	int			(*match)(struct fib_rule *,
					 struct flowi *, int);
	int			(*configure)(struct fib_rule *,
					     struct sk_buff *,
					     struct fib_rule_hdr *,
80 81
					     struct nlattr **,
					     struct netlink_ext_ack *);
82
	int			(*delete)(struct fib_rule *);
83 84 85 86 87
	int			(*compare)(struct fib_rule *,
					   struct fib_rule_hdr *,
					   struct nlattr **);
	int			(*fill)(struct fib_rule *, struct sk_buff *,
					struct fib_rule_hdr *);
88
	size_t			(*nlmsg_payload)(struct fib_rule *);
89

90 91
	/* Called after modifications to the rules set, must flush
	 * the route cache if one exists. */
92
	void			(*flush_cache)(struct fib_rules_ops *ops);
93

94
	int			nlgroup;
95
	const struct nla_policy	*policy;
96
	struct list_head	rules_list;
97
	struct module		*owner;
98
	struct net		*fro_net;
99
	struct rcu_head		rcu;
100 101
};

102 103 104 105 106
struct fib_rule_notifier_info {
	struct fib_notifier_info info; /* must be first */
	struct fib_rule *rule;
};

107
#define FRA_GENERIC_POLICY \
108
	[FRA_IIFNAME]	= { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
109
	[FRA_OIFNAME]	= { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
110 111 112
	[FRA_PRIORITY]	= { .type = NLA_U32 }, \
	[FRA_FWMARK]	= { .type = NLA_U32 }, \
	[FRA_FWMASK]	= { .type = NLA_U32 }, \
T
Thomas Graf 已提交
113
	[FRA_TABLE]     = { .type = NLA_U32 }, \
114
	[FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \
115
	[FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \
D
David Ahern 已提交
116
	[FRA_GOTO]	= { .type = NLA_U32 }, \
117
	[FRA_L3MDEV]	= { .type = NLA_U8 }, \
118
	[FRA_UID_RANGE]	= { .len = sizeof(struct fib_rule_uid_range) }, \
119 120 121 122 123
	[FRA_PROTOCOL]  = { .type = NLA_U8 }, \
	[FRA_IP_PROTO]  = { .type = NLA_U8 }, \
	[FRA_SPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) }, \
	[FRA_DPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) }

124

125 126
static inline void fib_rule_get(struct fib_rule *rule)
{
127
	refcount_inc(&rule->refcnt);
128 129 130 131
}

static inline void fib_rule_put(struct fib_rule *rule)
{
132
	if (refcount_dec_and_test(&rule->refcnt))
133
		kfree_rcu(rule, rcu);
134 135
}

D
David Ahern 已提交
136 137 138 139 140 141 142 143 144 145 146 147 148 149
#ifdef CONFIG_NET_L3_MASTER_DEV
static inline u32 fib_rule_get_table(struct fib_rule *rule,
				     struct fib_lookup_arg *arg)
{
	return rule->l3mdev ? arg->table : rule->table;
}
#else
static inline u32 fib_rule_get_table(struct fib_rule *rule,
				     struct fib_lookup_arg *arg)
{
	return rule->table;
}
#endif

150 151 152 153 154 155 156
static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
{
	if (nla[FRA_TABLE])
		return nla_get_u32(nla[FRA_TABLE]);
	return frh->table;
}

157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
static inline bool fib_rule_port_range_set(const struct fib_rule_port_range *range)
{
	return range->start != 0 && range->end != 0;
}

static inline bool fib_rule_port_inrange(const struct fib_rule_port_range *a,
					 __be16 port)
{
	return ntohs(port) >= a->start &&
		ntohs(port) <= a->end;
}

static inline bool fib_rule_port_range_valid(const struct fib_rule_port_range *a)
{
	return a->start != 0 && a->end != 0 && a->end < 0xffff &&
		a->start <= a->end;
}

static inline bool fib_rule_port_range_compare(struct fib_rule_port_range *a,
					       struct fib_rule_port_range *b)
{
	return a->start == b->start &&
		a->end == b->end;
}

static inline bool fib_rule_requires_fldissect(struct fib_rule *rule)
{
	return rule->ip_proto ||
		fib_rule_port_range_set(&rule->sport_range) ||
		fib_rule_port_range_set(&rule->dport_range);
}

189 190 191
struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *,
					 struct net *);
void fib_rules_unregister(struct fib_rules_ops *);
192

193 194 195 196
int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags,
		     struct fib_lookup_arg *);
int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table,
			 u32 flags);
197
bool fib_rule_matchall(const struct fib_rule *rule);
198 199
int fib_rules_dump(struct net *net, struct notifier_block *nb, int family);
unsigned int fib_rules_seq_read(struct net *net, int family);
D
David Ahern 已提交
200

201 202 203 204
int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
		   struct netlink_ext_ack *extack);
int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
		   struct netlink_ext_ack *extack);
205
#endif