1
2#ifndef __NET_FIB_RULES_H
3#define __NET_FIB_RULES_H
4
5#include <linux/types.h>
6#include <linux/slab.h>
7#include <linux/netdevice.h>
8#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#include <linux/rh_kabi.h>
15
16struct fib_kuid_range {
17 kuid_t start;
18 kuid_t end;
19};
20
21struct fib_rule {
22 struct list_head list;
23 int iifindex;
24 int oifindex;
25 u32 mark;
26 u32 mark_mask;
27 u32 flags;
28 u32 table;
29 u8 action;
30 u8 l3mdev;
31 u8 proto;
32 u8 ip_proto;
33 u32 target;
34 __be64 tun_id;
35 struct fib_rule __rcu *ctarget;
36 struct net *fr_net;
37
38 refcount_t refcnt;
39 u32 pref;
40 int suppress_ifgroup;
41 int suppress_prefixlen;
42 char iifname[IFNAMSIZ];
43 char oifname[IFNAMSIZ];
44 struct fib_kuid_range uid_range;
45 struct fib_rule_port_range sport_range;
46 struct fib_rule_port_range dport_range;
47 struct rcu_head rcu;
48
49 RH_KABI_RESERVE(1)
50 RH_KABI_RESERVE(2)
51 RH_KABI_RESERVE(3)
52 RH_KABI_RESERVE(4)
53 RH_KABI_RESERVE(5)
54 RH_KABI_RESERVE(6)
55 RH_KABI_RESERVE(7)
56 RH_KABI_RESERVE(8)
57};
58
59struct fib_lookup_arg {
60 void *lookup_ptr;
61 const void *lookup_data;
62 void *result;
63 struct fib_rule *rule;
64 u32 table;
65 int flags;
66#define FIB_LOOKUP_NOREF 1
67#define FIB_LOOKUP_IGNORE_LINKSTATE 2
68};
69
70struct fib_rules_ops {
71 int family;
72 struct list_head list;
73 int rule_size;
74 int addr_size;
75 int unresolved_rules;
76 int nr_goto_rules;
77 unsigned int fib_rules_seq;
78
79 int (*action)(struct fib_rule *,
80 struct flowi *, int,
81 struct fib_lookup_arg *);
82 bool (*suppress)(struct fib_rule *,
83 struct fib_lookup_arg *);
84 int (*match)(struct fib_rule *,
85 struct flowi *, int);
86 int (*configure)(struct fib_rule *,
87 struct sk_buff *,
88 struct fib_rule_hdr *,
89 struct nlattr **,
90 struct netlink_ext_ack *);
91 int (*delete)(struct fib_rule *);
92 int (*compare)(struct fib_rule *,
93 struct fib_rule_hdr *,
94 struct nlattr **);
95 int (*fill)(struct fib_rule *, struct sk_buff *,
96 struct fib_rule_hdr *);
97 size_t (*nlmsg_payload)(struct fib_rule *);
98
99
100
101 void (*flush_cache)(struct fib_rules_ops *ops);
102
103 int nlgroup;
104 const struct nla_policy *policy;
105 struct list_head rules_list;
106 struct module *owner;
107 struct net *fro_net;
108 struct rcu_head rcu;
109};
110
111struct fib_rule_notifier_info {
112 struct fib_notifier_info info;
113 struct fib_rule *rule;
114};
115
116#define FRA_GENERIC_POLICY \
117 [FRA_IIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
118 [FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
119 [FRA_PRIORITY] = { .type = NLA_U32 }, \
120 [FRA_FWMARK] = { .type = NLA_U32 }, \
121 [FRA_TUN_ID] = { .type = NLA_U64 }, \
122 [FRA_FWMASK] = { .type = NLA_U32 }, \
123 [FRA_TABLE] = { .type = NLA_U32 }, \
124 [FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \
125 [FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \
126 [FRA_GOTO] = { .type = NLA_U32 }, \
127 [FRA_L3MDEV] = { .type = NLA_U8 }, \
128 [FRA_UID_RANGE] = { .len = sizeof(struct fib_rule_uid_range) }, \
129 [FRA_PROTOCOL] = { .type = NLA_U8 }, \
130 [FRA_IP_PROTO] = { .type = NLA_U8 }, \
131 [FRA_SPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) }, \
132 [FRA_DPORT_RANGE] = { .len = sizeof(struct fib_rule_port_range) }
133
134
135static inline void fib_rule_get(struct fib_rule *rule)
136{
137 refcount_inc(&rule->refcnt);
138}
139
140static inline void fib_rule_put(struct fib_rule *rule)
141{
142 if (refcount_dec_and_test(&rule->refcnt))
143 kfree_rcu(rule, rcu);
144}
145
146#ifdef CONFIG_NET_L3_MASTER_DEV
147static inline u32 fib_rule_get_table(struct fib_rule *rule,
148 struct fib_lookup_arg *arg)
149{
150 return rule->l3mdev ? arg->table : rule->table;
151}
152#else
153static inline u32 fib_rule_get_table(struct fib_rule *rule,
154 struct fib_lookup_arg *arg)
155{
156 return rule->table;
157}
158#endif
159
160static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
161{
162 if (nla[FRA_TABLE])
163 return nla_get_u32(nla[FRA_TABLE]);
164 return frh->table;
165}
166
167static inline bool fib_rule_port_range_set(const struct fib_rule_port_range *range)
168{
169 return range->start != 0 && range->end != 0;
170}
171
172static inline bool fib_rule_port_inrange(const struct fib_rule_port_range *a,
173 __be16 port)
174{
175 return ntohs(port) >= a->start &&
176 ntohs(port) <= a->end;
177}
178
179static inline bool fib_rule_port_range_valid(const struct fib_rule_port_range *a)
180{
181 return a->start != 0 && a->end != 0 && a->end < 0xffff &&
182 a->start <= a->end;
183}
184
185static inline bool fib_rule_port_range_compare(struct fib_rule_port_range *a,
186 struct fib_rule_port_range *b)
187{
188 return a->start == b->start &&
189 a->end == b->end;
190}
191
192static inline bool fib_rule_requires_fldissect(struct fib_rule *rule)
193{
194 return rule->ip_proto ||
195 fib_rule_port_range_set(&rule->sport_range) ||
196 fib_rule_port_range_set(&rule->dport_range);
197}
198
199struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *,
200 struct net *);
201void fib_rules_unregister(struct fib_rules_ops *);
202
203int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags,
204 struct fib_lookup_arg *);
205int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table,
206 u32 flags);
207bool fib_rule_matchall(const struct fib_rule *rule);
208int fib_rules_dump(struct net *net, struct notifier_block *nb, int family,
209 struct netlink_ext_ack *extack);
210unsigned int fib_rules_seq_read(struct net *net, int family);
211
212int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh,
213 struct netlink_ext_ack *extack);
214int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh,
215 struct netlink_ext_ack *extack);
216#endif
217