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