hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/include/net/ip_fib.h
....@@ -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
....@@ -6,11 +7,6 @@
67 * Definitions for the Forwarding Information Base.
78 *
89 * Authors: A.N.Kuznetsov, <kuznet@ms2.inr.ac.ru>
9
- *
10
- * This program is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU General Public License
12
- * as published by the Free Software Foundation; either version
13
- * 2 of the License, or (at your option) any later version.
1410 */
1511
1612 #ifndef _NET_IP_FIB_H
....@@ -32,14 +28,19 @@
3228 u8 fc_protocol;
3329 u8 fc_scope;
3430 u8 fc_type;
35
- /* 3 bytes unused */
31
+ u8 fc_gw_family;
32
+ /* 2 bytes unused */
3633 u32 fc_table;
3734 __be32 fc_dst;
38
- __be32 fc_gw;
35
+ union {
36
+ __be32 fc_gw4;
37
+ struct in6_addr fc_gw6;
38
+ };
3939 int fc_oif;
4040 u32 fc_flags;
4141 u32 fc_priority;
4242 __be32 fc_prefsrc;
43
+ u32 fc_nh_id;
4344 struct nlattr *fc_mx;
4445 struct rtnexthop *fc_mp;
4546 int fc_mx_len;
....@@ -76,36 +77,61 @@
7677 #define FNHE_HASH_SIZE (1 << FNHE_HASH_SHIFT)
7778 #define FNHE_RECLAIM_DEPTH 5
7879
80
+struct fib_nh_common {
81
+ struct net_device *nhc_dev;
82
+ int nhc_oif;
83
+ unsigned char nhc_scope;
84
+ u8 nhc_family;
85
+ u8 nhc_gw_family;
86
+ unsigned char nhc_flags;
87
+ struct lwtunnel_state *nhc_lwtstate;
88
+
89
+ union {
90
+ __be32 ipv4;
91
+ struct in6_addr ipv6;
92
+ } nhc_gw;
93
+
94
+ int nhc_weight;
95
+ atomic_t nhc_upper_bound;
96
+
97
+ /* v4 specific, but allows fib6_nh with v4 routes */
98
+ struct rtable __rcu * __percpu *nhc_pcpu_rth_output;
99
+ struct rtable __rcu *nhc_rth_input;
100
+ struct fnhe_hash_bucket __rcu *nhc_exceptions;
101
+};
102
+
79103 struct fib_nh {
80
- struct net_device *nh_dev;
104
+ struct fib_nh_common nh_common;
81105 struct hlist_node nh_hash;
82106 struct fib_info *nh_parent;
83
- unsigned int nh_flags;
84
- unsigned char nh_scope;
85
-#ifdef CONFIG_IP_ROUTE_MULTIPATH
86
- int nh_weight;
87
- atomic_t nh_upper_bound;
88
-#endif
89107 #ifdef CONFIG_IP_ROUTE_CLASSID
90108 __u32 nh_tclassid;
91109 #endif
92
- int nh_oif;
93
- __be32 nh_gw;
94110 __be32 nh_saddr;
95111 int nh_saddr_genid;
96
- struct rtable __rcu * __percpu *nh_pcpu_rth_output;
97
- struct rtable __rcu *nh_rth_input;
98
- struct fnhe_hash_bucket __rcu *nh_exceptions;
99
- struct lwtunnel_state *nh_lwtstate;
112
+#define fib_nh_family nh_common.nhc_family
113
+#define fib_nh_dev nh_common.nhc_dev
114
+#define fib_nh_oif nh_common.nhc_oif
115
+#define fib_nh_flags nh_common.nhc_flags
116
+#define fib_nh_lws nh_common.nhc_lwtstate
117
+#define fib_nh_scope nh_common.nhc_scope
118
+#define fib_nh_gw_family nh_common.nhc_gw_family
119
+#define fib_nh_gw4 nh_common.nhc_gw.ipv4
120
+#define fib_nh_gw6 nh_common.nhc_gw.ipv6
121
+#define fib_nh_weight nh_common.nhc_weight
122
+#define fib_nh_upper_bound nh_common.nhc_upper_bound
100123 };
101124
102125 /*
103126 * This structure contains data shared by many of routes.
104127 */
105128
129
+struct nexthop;
130
+
106131 struct fib_info {
107132 struct hlist_node fib_hash;
108133 struct hlist_node fib_lhash;
134
+ struct list_head nh_list;
109135 struct net *fib_net;
110136 int fib_treeref;
111137 refcount_t fib_clntref;
....@@ -123,9 +149,11 @@
123149 #define fib_rtt fib_metrics->metrics[RTAX_RTT-1]
124150 #define fib_advmss fib_metrics->metrics[RTAX_ADVMSS-1]
125151 int fib_nhs;
152
+ bool fib_nh_is_v6;
153
+ bool nh_updated;
154
+ struct nexthop *nh;
126155 struct rcu_head rcu;
127
- struct fib_nh fib_nh[0];
128
-#define fib_dev fib_nh[0].nh_dev
156
+ struct fib_nh fib_nh[];
129157 };
130158
131159
....@@ -135,15 +163,16 @@
135163
136164 struct fib_table;
137165 struct fib_result {
138
- __be32 prefix;
139
- unsigned char prefixlen;
140
- unsigned char nh_sel;
141
- unsigned char type;
142
- unsigned char scope;
143
- u32 tclassid;
144
- struct fib_info *fi;
145
- struct fib_table *table;
146
- struct hlist_head *fa_head;
166
+ __be32 prefix;
167
+ unsigned char prefixlen;
168
+ unsigned char nh_sel;
169
+ unsigned char type;
170
+ unsigned char scope;
171
+ u32 tclassid;
172
+ struct fib_nh_common *nhc;
173
+ struct fib_info *fi;
174
+ struct fib_table *table;
175
+ struct hlist_head *fa_head;
147176 };
148177
149178 struct fib_result_nl {
....@@ -161,31 +190,31 @@
161190 int err;
162191 };
163192
164
-#ifdef CONFIG_IP_ROUTE_MULTIPATH
165
-#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
166
-#else /* CONFIG_IP_ROUTE_MULTIPATH */
167
-#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
168
-#endif /* CONFIG_IP_ROUTE_MULTIPATH */
169
-
170193 #ifdef CONFIG_IP_MULTIPLE_TABLES
171194 #define FIB_TABLE_HASHSZ 256
172195 #else
173196 #define FIB_TABLE_HASHSZ 2
174197 #endif
175198
176
-__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
199
+__be32 fib_info_update_nhc_saddr(struct net *net, struct fib_nh_common *nhc,
200
+ unsigned char scope);
201
+__be32 fib_result_prefsrc(struct net *net, struct fib_result *res);
177202
178
-#define FIB_RES_SADDR(net, res) \
179
- ((FIB_RES_NH(res).nh_saddr_genid == \
180
- atomic_read(&(net)->ipv4.dev_addr_genid)) ? \
181
- FIB_RES_NH(res).nh_saddr : \
182
- fib_info_update_nh_saddr((net), &FIB_RES_NH(res)))
183
-#define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw)
184
-#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
185
-#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif)
203
+#define FIB_RES_NHC(res) ((res).nhc)
204
+#define FIB_RES_DEV(res) (FIB_RES_NHC(res)->nhc_dev)
205
+#define FIB_RES_OIF(res) (FIB_RES_NHC(res)->nhc_oif)
186206
187
-#define FIB_RES_PREFSRC(net, res) ((res).fi->fib_prefsrc ? : \
188
- FIB_RES_SADDR(net, res))
207
+struct fib_rt_info {
208
+ struct fib_info *fi;
209
+ u32 tb_id;
210
+ __be32 dst;
211
+ int dst_len;
212
+ u8 tos;
213
+ u8 type;
214
+ u8 offload:1,
215
+ trap:1,
216
+ unused:6;
217
+};
189218
190219 struct fib_entry_notifier_info {
191220 struct fib_notifier_info info; /* must be first */
....@@ -202,7 +231,7 @@
202231 struct fib_nh *fib_nh;
203232 };
204233
205
-int call_fib4_notifier(struct notifier_block *nb, struct net *net,
234
+int call_fib4_notifier(struct notifier_block *nb,
206235 enum fib_event_type event_type,
207236 struct fib_notifier_info *info);
208237 int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,
....@@ -211,7 +240,9 @@
211240 int __net_init fib4_notifier_init(struct net *net);
212241 void __net_exit fib4_notifier_exit(struct net *net);
213242
214
-void fib_notify(struct net *net, struct notifier_block *nb);
243
+void fib_info_notify_update(struct net *net, struct nl_info *info);
244
+int fib_notify(struct net *net, struct notifier_block *nb,
245
+ struct netlink_ext_ack *extack);
215246
216247 struct fib_table {
217248 struct hlist_node tb_hlist;
....@@ -219,7 +250,19 @@
219250 int tb_num_default;
220251 struct rcu_head rcu;
221252 unsigned long *tb_data;
222
- unsigned long __data[0];
253
+ unsigned long __data[];
254
+};
255
+
256
+struct fib_dump_filter {
257
+ u32 table_id;
258
+ /* filter_set is an optimization that an entry is set */
259
+ bool filter_set;
260
+ bool dump_routes;
261
+ bool dump_exceptions;
262
+ unsigned char protocol;
263
+ unsigned char rt_type;
264
+ unsigned int flags;
265
+ struct net_device *dev;
223266 };
224267
225268 int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
....@@ -229,7 +272,7 @@
229272 int fib_table_delete(struct net *, struct fib_table *, struct fib_config *,
230273 struct netlink_ext_ack *extack);
231274 int fib_table_dump(struct fib_table *table, struct sk_buff *skb,
232
- struct netlink_callback *cb);
275
+ struct netlink_callback *cb, struct fib_dump_filter *filter);
233276 int fib_table_flush(struct net *net, struct fib_table *table, bool flush_all);
234277 struct fib_table *fib_trie_unmerge(struct fib_table *main_tb);
235278 void fib_table_flush_external(struct fib_table *table);
....@@ -279,12 +322,18 @@
279322 return err;
280323 }
281324
325
+static inline bool fib4_has_custom_rules(const struct net *net)
326
+{
327
+ return false;
328
+}
329
+
282330 static inline bool fib4_rule_default(const struct fib_rule *rule)
283331 {
284332 return true;
285333 }
286334
287
-static inline int fib4_rules_dump(struct net *net, struct notifier_block *nb)
335
+static inline int fib4_rules_dump(struct net *net, struct notifier_block *nb,
336
+ struct netlink_ext_ack *extack)
288337 {
289338 return 0;
290339 }
....@@ -345,8 +394,14 @@
345394 return err;
346395 }
347396
397
+static inline bool fib4_has_custom_rules(const struct net *net)
398
+{
399
+ return net->ipv4.fib_has_custom_rules;
400
+}
401
+
348402 bool fib4_rule_default(const struct fib_rule *rule);
349
-int fib4_rules_dump(struct net *net, struct notifier_block *nb);
403
+int fib4_rules_dump(struct net *net, struct notifier_block *nb,
404
+ struct netlink_ext_ack *extack);
350405 unsigned int fib4_rules_seq_read(struct net *net);
351406
352407 static inline bool fib4_rules_early_flow_dissect(struct net *net,
....@@ -372,14 +427,17 @@
372427 /* Exported by fib_frontend.c */
373428 extern const struct nla_policy rtm_ipv4_policy[];
374429 void ip_fib_init(void);
430
+int fib_gw_from_via(struct fib_config *cfg, struct nlattr *nla,
431
+ struct netlink_ext_ack *extack);
375432 __be32 fib_compute_spec_dst(struct sk_buff *skb);
433
+bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev);
376434 int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
377435 u8 tos, int oif, struct net_device *dev,
378436 struct in_device *idev, u32 *itag);
379437 #ifdef CONFIG_IP_ROUTE_CLASSID
380438 static inline int fib_num_tclassid_users(struct net *net)
381439 {
382
- return net->ipv4.fib_num_tclassid_users;
440
+ return atomic_read(&net->ipv4.fib_num_tclassid_users);
383441 }
384442 #else
385443 static inline int fib_num_tclassid_users(struct net *net)
....@@ -389,32 +447,67 @@
389447 #endif
390448 int fib_unmerge(struct net *net);
391449
450
+static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc,
451
+const struct net_device *dev)
452
+{
453
+ if (nhc->nhc_dev == dev ||
454
+ l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex)
455
+ return true;
456
+
457
+ return false;
458
+}
459
+
392460 /* Exported by fib_semantics.c */
393461 int ip_fib_check_default(__be32 gw, struct net_device *dev);
394462 int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
395463 int fib_sync_down_addr(struct net_device *dev, __be32 local);
396
-int fib_sync_up(struct net_device *dev, unsigned int nh_flags);
464
+int fib_sync_up(struct net_device *dev, unsigned char nh_flags);
397465 void fib_sync_mtu(struct net_device *dev, u32 orig_mtu);
466
+void fib_nhc_update_mtu(struct fib_nh_common *nhc, u32 new, u32 orig);
398467
399468 #ifdef CONFIG_IP_ROUTE_MULTIPATH
400469 int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
401470 const struct sk_buff *skb, struct flow_keys *flkeys);
402471 #endif
472
+int fib_check_nh(struct net *net, struct fib_nh *nh, u32 table, u8 scope,
473
+ struct netlink_ext_ack *extack);
403474 void fib_select_multipath(struct fib_result *res, int hash);
404475 void fib_select_path(struct net *net, struct fib_result *res,
405476 struct flowi4 *fl4, const struct sk_buff *skb);
406477
478
+int fib_nh_init(struct net *net, struct fib_nh *fib_nh,
479
+ struct fib_config *cfg, int nh_weight,
480
+ struct netlink_ext_ack *extack);
481
+void fib_nh_release(struct net *net, struct fib_nh *fib_nh);
482
+int fib_nh_common_init(struct net *net, struct fib_nh_common *nhc,
483
+ struct nlattr *fc_encap, u16 fc_encap_type,
484
+ void *cfg, gfp_t gfp_flags,
485
+ struct netlink_ext_ack *extack);
486
+void fib_nh_common_release(struct fib_nh_common *nhc);
487
+
407488 /* Exported by fib_trie.c */
489
+void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri);
408490 void fib_trie_init(void);
409491 struct fib_table *fib_trie_table(u32 id, struct fib_table *alias);
492
+bool fib_lookup_good_nhc(const struct fib_nh_common *nhc, int fib_flags,
493
+ const struct flowi4 *flp);
410494
411495 static inline void fib_combine_itag(u32 *itag, const struct fib_result *res)
412496 {
413497 #ifdef CONFIG_IP_ROUTE_CLASSID
498
+ struct fib_nh_common *nhc = res->nhc;
414499 #ifdef CONFIG_IP_MULTIPLE_TABLES
415500 u32 rtag;
416501 #endif
417
- *itag = FIB_RES_NH(*res).nh_tclassid<<16;
502
+ if (nhc->nhc_family == AF_INET) {
503
+ struct fib_nh *nh;
504
+
505
+ nh = container_of(nhc, struct fib_nh, nh_common);
506
+ *itag = nh->nh_tclassid << 16;
507
+ } else {
508
+ *itag = 0;
509
+ }
510
+
418511 #ifdef CONFIG_IP_MULTIPLE_TABLES
419512 rtag = res->tclassid;
420513 if (*itag == 0)
....@@ -424,6 +517,7 @@
424517 #endif
425518 }
426519
520
+void fib_flush(struct net *net);
427521 void free_fib_info(struct fib_info *fi);
428522
429523 static inline void fib_info_hold(struct fib_info *fi)
....@@ -452,4 +546,12 @@
452546
453547 u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr);
454548
549
+int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
550
+ struct fib_dump_filter *filter,
551
+ struct netlink_callback *cb);
552
+
553
+int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nh,
554
+ u8 rt_family, unsigned char *flags, bool skip_oif);
555
+int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nh,
556
+ int nh_weight, u8 rt_family, u32 nh_tclassid);
455557 #endif /* _NET_FIB_H */