hc
2024-05-10 ee930fffee469d076998274a2ca55e13dc1efb67
kernel/include/net/ip6_fib.h
....@@ -1,13 +1,9 @@
1
+/* SPDX-License-Identifier: GPL-2.0-or-later */
12 /*
23 * Linux INET6 implementation
34 *
45 * Authors:
56 * Pedro Roque <roque@di.fc.ul.pt>
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version
10
- * 2 of the License, or (at your option) any later version.
117 */
128
139 #ifndef _IP6_FIB_H
....@@ -17,11 +13,14 @@
1713 #include <linux/rtnetlink.h>
1814 #include <linux/spinlock.h>
1915 #include <linux/notifier.h>
16
+#include <linux/android_kabi.h>
2017 #include <net/dst.h>
2118 #include <net/flow.h>
19
+#include <net/ip_fib.h>
2220 #include <net/netlink.h>
2321 #include <net/inetpeer.h>
2422 #include <net/fib_notifier.h>
23
+#include <linux/indirect_call_wrapper.h>
2524
2625 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
2726 #define FIB6_TABLE_HASHSZ 256
....@@ -50,7 +49,9 @@
5049 u32 fc_protocol;
5150 u16 fc_type; /* only 8 bits are used */
5251 u16 fc_delete_all_nh : 1,
53
- __unused : 15;
52
+ fc_ignore_dev_down:1,
53
+ __unused : 14;
54
+ u32 fc_nh_id;
5455
5556 struct in6_addr fc_dst;
5657 struct in6_addr fc_src;
....@@ -66,6 +67,9 @@
6667 struct nl_info fc_nlinfo;
6768 struct nlattr *fc_encap;
6869 u16 fc_encap_type;
70
+ bool fc_is_fdb;
71
+
72
+ ANDROID_KABI_RESERVE(1);
6973 };
7074
7175 struct fib6_node {
....@@ -82,6 +86,8 @@
8286 int fn_sernum;
8387 struct fib6_info __rcu *rr_ptr;
8488 struct rcu_head rcu;
89
+
90
+ ANDROID_KABI_RESERVE(1);
8591 };
8692
8793 struct fib6_gc_args {
....@@ -91,7 +97,32 @@
9197
9298 #ifndef CONFIG_IPV6_SUBTREES
9399 #define FIB6_SUBTREE(fn) NULL
100
+
101
+static inline bool fib6_routes_require_src(const struct net *net)
102
+{
103
+ return false;
104
+}
105
+
106
+static inline void fib6_routes_require_src_inc(struct net *net) {}
107
+static inline void fib6_routes_require_src_dec(struct net *net) {}
108
+
94109 #else
110
+
111
+static inline bool fib6_routes_require_src(const struct net *net)
112
+{
113
+ return net->ipv6.fib6_routes_require_src > 0;
114
+}
115
+
116
+static inline void fib6_routes_require_src_inc(struct net *net)
117
+{
118
+ net->ipv6.fib6_routes_require_src++;
119
+}
120
+
121
+static inline void fib6_routes_require_src_dec(struct net *net)
122
+{
123
+ net->ipv6.fib6_routes_require_src--;
124
+}
125
+
95126 #define FIB6_SUBTREE(fn) (rcu_dereference_protected((fn)->subtree, 1))
96127 #endif
97128
....@@ -124,13 +155,14 @@
124155 #define FIB6_MAX_DEPTH 5
125156
126157 struct fib6_nh {
127
- struct in6_addr nh_gw;
128
- struct net_device *nh_dev;
129
- struct lwtunnel_state *nh_lwtstate;
158
+ struct fib_nh_common nh_common;
130159
131
- unsigned int nh_flags;
132
- atomic_t nh_upper_bound;
133
- int nh_weight;
160
+#ifdef CONFIG_IPV6_ROUTER_PREF
161
+ unsigned long last_probe;
162
+#endif
163
+
164
+ struct rt6_info * __percpu *rt6i_pcpu;
165
+ struct rt6_exception_bucket __rcu *rt6i_exception_bucket;
134166 };
135167
136168 struct fib6_info {
....@@ -139,14 +171,17 @@
139171 struct fib6_node __rcu *fib6_node;
140172
141173 /* Multipath routes:
142
- * siblings is a list of fib6_info that have the the same metric/weight,
174
+ * siblings is a list of fib6_info that have the same metric/weight,
143175 * destination, but not the same gateway. nsiblings is just a cache
144176 * to speed up lookup.
145177 */
146
- struct list_head fib6_siblings;
178
+ union {
179
+ struct list_head fib6_siblings;
180
+ struct list_head nh_list;
181
+ };
147182 unsigned int fib6_nsiblings;
148183
149
- atomic_t fib6_ref;
184
+ refcount_t fib6_ref;
150185 unsigned long expires;
151186 struct dst_metrics *fib6_metrics;
152187 #define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1]
....@@ -156,44 +191,51 @@
156191 struct rt6key fib6_src;
157192 struct rt6key fib6_prefsrc;
158193
159
- struct rt6_info * __percpu *rt6i_pcpu;
160
- struct rt6_exception_bucket __rcu *rt6i_exception_bucket;
161
-
162
-#ifdef CONFIG_IPV6_ROUTER_PREF
163
- unsigned long last_probe;
164
-#endif
165
-
166194 u32 fib6_metric;
167195 u8 fib6_protocol;
168196 u8 fib6_type;
169
- u8 exception_bucket_flushed:1,
170
- should_flush:1,
197
+ u8 should_flush:1,
171198 dst_nocount:1,
172199 dst_nopolicy:1,
173
- dst_host:1,
174200 fib6_destroying:1,
201
+ offload:1,
202
+ trap:1,
175203 unused:2;
176204
177
- struct fib6_nh fib6_nh;
178205 struct rcu_head rcu;
206
+ struct nexthop *nh;
207
+
208
+ ANDROID_KABI_RESERVE(1);
209
+
210
+ struct fib6_nh fib6_nh[];
179211 };
180212
181213 struct rt6_info {
182214 struct dst_entry dst;
183215 struct fib6_info __rcu *from;
216
+ int sernum;
184217
185218 struct rt6key rt6i_dst;
186219 struct rt6key rt6i_src;
187220 struct in6_addr rt6i_gateway;
188221 struct inet6_dev *rt6i_idev;
189222 u32 rt6i_flags;
190
- struct rt6key rt6i_prefsrc;
191223
192224 struct list_head rt6i_uncached;
193225 struct uncached_list *rt6i_uncached_list;
194226
195227 /* more non-fragment space at head required */
196228 unsigned short rt6i_nfheader_len;
229
+
230
+ ANDROID_KABI_RESERVE(1);
231
+};
232
+
233
+struct fib6_result {
234
+ struct fib6_nh *nh;
235
+ struct fib6_info *f6i;
236
+ u32 fib6_flags;
237
+ u8 fib6_type;
238
+ struct rt6_info *rt6;
197239 };
198240
199241 #define for_each_fib6_node_rt_rcu(fn) \
....@@ -207,6 +249,11 @@
207249 static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
208250 {
209251 return ((struct rt6_info *)dst)->rt6i_idev;
252
+}
253
+
254
+static inline bool fib6_requires_src(const struct fib6_info *rt)
255
+{
256
+ return rt->fib6_src.plen > 0;
210257 }
211258
212259 static inline void fib6_clean_expires(struct fib6_info *f6i)
....@@ -257,6 +304,9 @@
257304 struct fib6_info *from;
258305 u32 cookie = 0;
259306
307
+ if (rt->sernum)
308
+ return rt->sernum;
309
+
260310 rcu_read_lock();
261311
262312 from = rcu_dereference(rt->from);
....@@ -277,23 +327,30 @@
277327 dst_release(&rt->dst);
278328 }
279329
280
-struct fib6_info *fib6_info_alloc(gfp_t gfp_flags);
330
+struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh);
281331 void fib6_info_destroy_rcu(struct rcu_head *head);
282332
283333 static inline void fib6_info_hold(struct fib6_info *f6i)
284334 {
285
- atomic_inc(&f6i->fib6_ref);
335
+ refcount_inc(&f6i->fib6_ref);
286336 }
287337
288338 static inline bool fib6_info_hold_safe(struct fib6_info *f6i)
289339 {
290
- return atomic_inc_not_zero(&f6i->fib6_ref);
340
+ return refcount_inc_not_zero(&f6i->fib6_ref);
291341 }
292342
293343 static inline void fib6_info_release(struct fib6_info *f6i)
294344 {
295
- if (f6i && atomic_dec_and_test(&f6i->fib6_ref))
345
+ if (f6i && refcount_dec_and_test(&f6i->fib6_ref))
296346 call_rcu(&f6i->rcu, fib6_info_destroy_rcu);
347
+}
348
+
349
+static inline void fib6_info_hw_flags_set(struct fib6_info *f6i, bool offload,
350
+ bool trap)
351
+{
352
+ f6i->offload = offload;
353
+ f6i->trap = trap;
297354 }
298355
299356 enum fib6_walk_state {
....@@ -313,6 +370,7 @@
313370 enum fib6_walk_state state;
314371 unsigned int skip;
315372 unsigned int count;
373
+ unsigned int skip_in_node;
316374 int (*func)(struct fib6_walker *);
317375 void *args;
318376 };
....@@ -374,6 +432,7 @@
374432 struct fib6_entry_notifier_info {
375433 struct fib_notifier_info info; /* must be first */
376434 struct fib6_info *rt;
435
+ unsigned int nsiblings;
377436 };
378437
379438 /*
....@@ -389,18 +448,17 @@
389448 /* called with rcu lock held; can return error pointer
390449 * caller needs to select path
391450 */
392
-struct fib6_info *fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
393
- int flags);
451
+int fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
452
+ struct fib6_result *res, int flags);
394453
395454 /* called with rcu lock held; caller needs to select path */
396
-struct fib6_info *fib6_table_lookup(struct net *net, struct fib6_table *table,
397
- int oif, struct flowi6 *fl6, int strict);
455
+int fib6_table_lookup(struct net *net, struct fib6_table *table,
456
+ int oif, struct flowi6 *fl6, struct fib6_result *res,
457
+ int strict);
398458
399
-struct fib6_info *fib6_multipath_select(const struct net *net,
400
- struct fib6_info *match,
401
- struct flowi6 *fl6, int oif,
402
- const struct sk_buff *skb, int strict);
403
-
459
+void fib6_select_path(const struct net *net, struct fib6_result *res,
460
+ struct flowi6 *fl6, int oif, bool have_oif_match,
461
+ const struct sk_buff *skb, int strict);
404462 struct fib6_node *fib6_node_lookup(struct fib6_node *root,
405463 const struct in6_addr *daddr,
406464 const struct in6_addr *saddr);
....@@ -412,22 +470,50 @@
412470
413471 void fib6_clean_all(struct net *net, int (*func)(struct fib6_info *, void *arg),
414472 void *arg);
473
+void fib6_clean_all_skip_notify(struct net *net,
474
+ int (*func)(struct fib6_info *, void *arg),
475
+ void *arg);
415476
416477 int fib6_add(struct fib6_node *root, struct fib6_info *rt,
417478 struct nl_info *info, struct netlink_ext_ack *extack);
418479 int fib6_del(struct fib6_info *rt, struct nl_info *info);
419480
420
-static inline struct net_device *fib6_info_nh_dev(const struct fib6_info *f6i)
421
-{
422
- return f6i->fib6_nh.nh_dev;
423
-}
424
-
425481 static inline
426
-struct lwtunnel_state *fib6_info_nh_lwt(const struct fib6_info *f6i)
482
+void rt6_get_prefsrc(const struct rt6_info *rt, struct in6_addr *addr)
427483 {
428
- return f6i->fib6_nh.nh_lwtstate;
484
+ const struct fib6_info *from;
485
+
486
+ rcu_read_lock();
487
+
488
+ from = rcu_dereference(rt->from);
489
+ if (from) {
490
+ *addr = from->fib6_prefsrc.addr;
491
+ } else {
492
+ struct in6_addr in6_zero = {};
493
+
494
+ *addr = in6_zero;
495
+ }
496
+
497
+ rcu_read_unlock();
429498 }
430499
500
+int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
501
+ struct fib6_config *cfg, gfp_t gfp_flags,
502
+ struct netlink_ext_ack *extack);
503
+void fib6_nh_release(struct fib6_nh *fib6_nh);
504
+
505
+int call_fib6_entry_notifiers(struct net *net,
506
+ enum fib_event_type event_type,
507
+ struct fib6_info *rt,
508
+ struct netlink_ext_ack *extack);
509
+int call_fib6_multipath_entry_notifiers(struct net *net,
510
+ enum fib_event_type event_type,
511
+ struct fib6_info *rt,
512
+ unsigned int nsiblings,
513
+ struct netlink_ext_ack *extack);
514
+int call_fib6_entry_notifiers_replace(struct net *net, struct fib6_info *rt);
515
+void fib6_rt_update(struct net *net, struct fib6_info *rt,
516
+ struct nl_info *info);
431517 void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info,
432518 unsigned int flags);
433519
....@@ -447,7 +533,7 @@
447533
448534 extern const struct seq_operations ipv6_route_seq_ops;
449535
450
-int call_fib6_notifier(struct notifier_block *nb, struct net *net,
536
+int call_fib6_notifier(struct notifier_block *nb,
451537 enum fib_event_type event_type,
452538 struct fib_notifier_info *info);
453539 int call_fib6_notifiers(struct net *net, enum fib_event_type event_type,
....@@ -457,10 +543,12 @@
457543 void __net_exit fib6_notifier_exit(struct net *net);
458544
459545 unsigned int fib6_tables_seq_read(struct net *net);
460
-int fib6_tables_dump(struct net *net, struct notifier_block *nb);
546
+int fib6_tables_dump(struct net *net, struct notifier_block *nb,
547
+ struct netlink_ext_ack *extack);
461548
462549 void fib6_update_sernum(struct net *net, struct fib6_info *rt);
463550 void fib6_update_sernum_upto_root(struct net *net, struct fib6_info *rt);
551
+void fib6_update_sernum_stub(struct net *net, struct fib6_info *f6i);
464552
465553 void fib6_metric_set(struct fib6_info *f6i, int metric, u32 val);
466554 static inline bool fib6_metric_locked(struct fib6_info *f6i, int metric)
....@@ -468,11 +556,59 @@
468556 return !!(f6i->fib6_metrics->metrics[RTAX_LOCK - 1] & (1 << metric));
469557 }
470558
559
+#if IS_BUILTIN(CONFIG_IPV6) && defined(CONFIG_BPF_SYSCALL)
560
+struct bpf_iter__ipv6_route {
561
+ __bpf_md_ptr(struct bpf_iter_meta *, meta);
562
+ __bpf_md_ptr(struct fib6_info *, rt);
563
+};
564
+#endif
565
+
566
+INDIRECT_CALLABLE_DECLARE(struct rt6_info *ip6_pol_route_output(struct net *net,
567
+ struct fib6_table *table,
568
+ struct flowi6 *fl6,
569
+ const struct sk_buff *skb,
570
+ int flags));
571
+INDIRECT_CALLABLE_DECLARE(struct rt6_info *ip6_pol_route_input(struct net *net,
572
+ struct fib6_table *table,
573
+ struct flowi6 *fl6,
574
+ const struct sk_buff *skb,
575
+ int flags));
576
+INDIRECT_CALLABLE_DECLARE(struct rt6_info *__ip6_route_redirect(struct net *net,
577
+ struct fib6_table *table,
578
+ struct flowi6 *fl6,
579
+ const struct sk_buff *skb,
580
+ int flags));
581
+INDIRECT_CALLABLE_DECLARE(struct rt6_info *ip6_pol_route_lookup(struct net *net,
582
+ struct fib6_table *table,
583
+ struct flowi6 *fl6,
584
+ const struct sk_buff *skb,
585
+ int flags));
586
+static inline struct rt6_info *pol_lookup_func(pol_lookup_t lookup,
587
+ struct net *net,
588
+ struct fib6_table *table,
589
+ struct flowi6 *fl6,
590
+ const struct sk_buff *skb,
591
+ int flags)
592
+{
593
+ return INDIRECT_CALL_4(lookup,
594
+ ip6_pol_route_output,
595
+ ip6_pol_route_input,
596
+ ip6_pol_route_lookup,
597
+ __ip6_route_redirect,
598
+ net, table, fl6, skb, flags);
599
+}
600
+
471601 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
602
+static inline bool fib6_has_custom_rules(const struct net *net)
603
+{
604
+ return net->ipv6.fib6_has_custom_rules;
605
+}
606
+
472607 int fib6_rules_init(void);
473608 void fib6_rules_cleanup(void);
474609 bool fib6_rule_default(const struct fib_rule *rule);
475
-int fib6_rules_dump(struct net *net, struct notifier_block *nb);
610
+int fib6_rules_dump(struct net *net, struct notifier_block *nb,
611
+ struct netlink_ext_ack *extack);
476612 unsigned int fib6_rules_seq_read(struct net *net);
477613
478614 static inline bool fib6_rules_early_flow_dissect(struct net *net,
....@@ -493,6 +629,10 @@
493629 return true;
494630 }
495631 #else
632
+static inline bool fib6_has_custom_rules(const struct net *net)
633
+{
634
+ return false;
635
+}
496636 static inline int fib6_rules_init(void)
497637 {
498638 return 0;
....@@ -505,7 +645,8 @@
505645 {
506646 return true;
507647 }
508
-static inline int fib6_rules_dump(struct net *net, struct notifier_block *nb)
648
+static inline int fib6_rules_dump(struct net *net, struct notifier_block *nb,
649
+ struct netlink_ext_ack *extack)
509650 {
510651 return 0;
511652 }