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