hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/ipv4/fib_rules.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * INET An implementation of the TCP/IP protocol suite for the LINUX
34 * operating system. INET is implemented using the BSD Socket
....@@ -7,11 +8,6 @@
78 *
89 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
910 * Thomas Graf <tgraf@suug.ch>
10
- *
11
- * This program is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU General Public License
13
- * as published by the Free Software Foundation; either version
14
- * 2 of the License, or (at your option) any later version.
1511 *
1612 * Fixes:
1713 * Rani Assaf : local_rule cannot be deleted
....@@ -31,7 +27,9 @@
3127 #include <net/route.h>
3228 #include <net/tcp.h>
3329 #include <net/ip_fib.h>
30
+#include <net/nexthop.h>
3431 #include <net/fib_rules.h>
32
+#include <linux/indirect_call_wrapper.h>
3533
3634 struct fib4_rule {
3735 struct fib_rule common;
....@@ -68,9 +66,10 @@
6866 }
6967 EXPORT_SYMBOL_GPL(fib4_rule_default);
7068
71
-int fib4_rules_dump(struct net *net, struct notifier_block *nb)
69
+int fib4_rules_dump(struct net *net, struct notifier_block *nb,
70
+ struct netlink_ext_ack *extack)
7271 {
73
- return fib_rules_dump(net, nb, AF_INET);
72
+ return fib_rules_dump(net, nb, AF_INET, extack);
7473 }
7574
7675 unsigned int fib4_rules_seq_read(struct net *net)
....@@ -105,8 +104,9 @@
105104 }
106105 EXPORT_SYMBOL_GPL(__fib_lookup);
107106
108
-static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp,
109
- int flags, struct fib_lookup_arg *arg)
107
+INDIRECT_CALLABLE_SCOPE int fib4_rule_action(struct fib_rule *rule,
108
+ struct flowi *flp, int flags,
109
+ struct fib_lookup_arg *arg)
110110 {
111111 int err = -EAGAIN;
112112 struct fib_table *tbl;
....@@ -140,13 +140,18 @@
140140 return err;
141141 }
142142
143
-static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg)
143
+INDIRECT_CALLABLE_SCOPE bool fib4_rule_suppress(struct fib_rule *rule,
144
+ int flags,
145
+ struct fib_lookup_arg *arg)
144146 {
145147 struct fib_result *result = (struct fib_result *) arg->result;
146148 struct net_device *dev = NULL;
147149
148
- if (result->fi)
149
- dev = result->fi->fib_dev;
150
+ if (result->fi) {
151
+ struct fib_nh_common *nhc = fib_info_nhc(result->fi, 0);
152
+
153
+ dev = nhc->nhc_dev;
154
+ }
150155
151156 /* do not accept result if the route does
152157 * not meet the required prefix length
....@@ -168,7 +173,8 @@
168173 return true;
169174 }
170175
171
-static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
176
+INDIRECT_CALLABLE_SCOPE int fib4_rule_match(struct fib_rule *rule,
177
+ struct flowi *fl, int flags)
172178 {
173179 struct fib4_rule *r = (struct fib4_rule *) rule;
174180 struct flowi4 *fl4 = &fl->u.ip4;
....@@ -198,11 +204,15 @@
198204
199205 static struct fib_table *fib_empty_table(struct net *net)
200206 {
201
- u32 id;
207
+ u32 id = 1;
202208
203
- for (id = 1; id <= RT_TABLE_MAX; id++)
209
+ while (1) {
204210 if (!fib_get_table(net, id))
205211 return fib_new_table(net, id);
212
+
213
+ if (id++ == RT_TABLE_MAX)
214
+ break;
215
+ }
206216 return NULL;
207217 }
208218
....@@ -254,7 +264,7 @@
254264 if (tb[FRA_FLOW]) {
255265 rule4->tclassid = nla_get_u32(tb[FRA_FLOW]);
256266 if (rule4->tclassid)
257
- net->ipv4.fib_num_tclassid_users++;
267
+ atomic_inc(&net->ipv4.fib_num_tclassid_users);
258268 }
259269 #endif
260270
....@@ -286,7 +296,7 @@
286296
287297 #ifdef CONFIG_IP_ROUTE_CLASSID
288298 if (((struct fib4_rule *)rule)->tclassid)
289
- net->ipv4.fib_num_tclassid_users--;
299
+ atomic_dec(&net->ipv4.fib_num_tclassid_users);
290300 #endif
291301 net->ipv4.fib_has_custom_rules = true;
292302