LCOV - code coverage report
Current view: top level - include/net - ip6_fib.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 0 2 0.0 %
Date: 2021-04-22 12:43:58 Functions: 0 0 -

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0-or-later */
       2             : /*
       3             :  *      Linux INET6 implementation 
       4             :  *
       5             :  *      Authors:
       6             :  *      Pedro Roque             <roque@di.fc.ul.pt>       
       7             :  */
       8             : 
       9             : #ifndef _IP6_FIB_H
      10             : #define _IP6_FIB_H
      11             : 
      12             : #include <linux/ipv6_route.h>
      13             : #include <linux/rtnetlink.h>
      14             : #include <linux/spinlock.h>
      15             : #include <linux/notifier.h>
      16             : #include <net/dst.h>
      17             : #include <net/flow.h>
      18             : #include <net/ip_fib.h>
      19             : #include <net/netlink.h>
      20             : #include <net/inetpeer.h>
      21             : #include <net/fib_notifier.h>
      22             : #include <linux/indirect_call_wrapper.h>
      23             : 
      24             : #ifdef CONFIG_IPV6_MULTIPLE_TABLES
      25             : #define FIB6_TABLE_HASHSZ 256
      26             : #else
      27             : #define FIB6_TABLE_HASHSZ 1
      28             : #endif
      29             : 
      30             : #define RT6_DEBUG 2
      31             : 
      32             : #if RT6_DEBUG >= 3
      33             : #define RT6_TRACE(x...) pr_debug(x)
      34             : #else
      35             : #define RT6_TRACE(x...) do { ; } while (0)
      36             : #endif
      37             : 
      38             : struct rt6_info;
      39             : struct fib6_info;
      40             : 
      41             : struct fib6_config {
      42             :         u32             fc_table;
      43             :         u32             fc_metric;
      44             :         int             fc_dst_len;
      45             :         int             fc_src_len;
      46             :         int             fc_ifindex;
      47             :         u32             fc_flags;
      48             :         u32             fc_protocol;
      49             :         u16             fc_type;        /* only 8 bits are used */
      50             :         u16             fc_delete_all_nh : 1,
      51             :                         fc_ignore_dev_down:1,
      52             :                         __unused : 14;
      53             :         u32             fc_nh_id;
      54             : 
      55             :         struct in6_addr fc_dst;
      56             :         struct in6_addr fc_src;
      57             :         struct in6_addr fc_prefsrc;
      58             :         struct in6_addr fc_gateway;
      59             : 
      60             :         unsigned long   fc_expires;
      61             :         struct nlattr   *fc_mx;
      62             :         int             fc_mx_len;
      63             :         int             fc_mp_len;
      64             :         struct nlattr   *fc_mp;
      65             : 
      66             :         struct nl_info  fc_nlinfo;
      67             :         struct nlattr   *fc_encap;
      68             :         u16             fc_encap_type;
      69             :         bool            fc_is_fdb;
      70             : };
      71             : 
      72             : struct fib6_node {
      73             :         struct fib6_node __rcu  *parent;
      74             :         struct fib6_node __rcu  *left;
      75             :         struct fib6_node __rcu  *right;
      76             : #ifdef CONFIG_IPV6_SUBTREES
      77             :         struct fib6_node __rcu  *subtree;
      78             : #endif
      79             :         struct fib6_info __rcu  *leaf;
      80             : 
      81             :         __u16                   fn_bit;         /* bit key */
      82             :         __u16                   fn_flags;
      83             :         int                     fn_sernum;
      84             :         struct fib6_info __rcu  *rr_ptr;
      85             :         struct rcu_head         rcu;
      86             : };
      87             : 
      88             : struct fib6_gc_args {
      89             :         int                     timeout;
      90             :         int                     more;
      91             : };
      92             : 
      93             : #ifndef CONFIG_IPV6_SUBTREES
      94             : #define FIB6_SUBTREE(fn)        NULL
      95             : 
      96             : static inline bool fib6_routes_require_src(const struct net *net)
      97             : {
      98             :         return false;
      99             : }
     100             : 
     101             : static inline void fib6_routes_require_src_inc(struct net *net) {}
     102             : static inline void fib6_routes_require_src_dec(struct net *net) {}
     103             : 
     104             : #else
     105             : 
     106             : static inline bool fib6_routes_require_src(const struct net *net)
     107             : {
     108             :         return net->ipv6.fib6_routes_require_src > 0;
     109             : }
     110             : 
     111             : static inline void fib6_routes_require_src_inc(struct net *net)
     112             : {
     113             :         net->ipv6.fib6_routes_require_src++;
     114             : }
     115             : 
     116             : static inline void fib6_routes_require_src_dec(struct net *net)
     117             : {
     118             :         net->ipv6.fib6_routes_require_src--;
     119             : }
     120             : 
     121             : #define FIB6_SUBTREE(fn)        (rcu_dereference_protected((fn)->subtree, 1))
     122             : #endif
     123             : 
     124             : /*
     125             :  *      routing information
     126             :  *
     127             :  */
     128             : 
     129             : struct rt6key {
     130             :         struct in6_addr addr;
     131             :         int             plen;
     132             : };
     133             : 
     134             : struct fib6_table;
     135             : 
     136             : struct rt6_exception_bucket {
     137             :         struct hlist_head       chain;
     138             :         int                     depth;
     139             : };
     140             : 
     141             : struct rt6_exception {
     142             :         struct hlist_node       hlist;
     143             :         struct rt6_info         *rt6i;
     144             :         unsigned long           stamp;
     145             :         struct rcu_head         rcu;
     146             : };
     147             : 
     148             : #define FIB6_EXCEPTION_BUCKET_SIZE_SHIFT 10
     149             : #define FIB6_EXCEPTION_BUCKET_SIZE (1 << FIB6_EXCEPTION_BUCKET_SIZE_SHIFT)
     150             : #define FIB6_MAX_DEPTH 5
     151             : 
     152             : struct fib6_nh {
     153             :         struct fib_nh_common    nh_common;
     154             : 
     155             : #ifdef CONFIG_IPV6_ROUTER_PREF
     156             :         unsigned long           last_probe;
     157             : #endif
     158             : 
     159             :         struct rt6_info * __percpu *rt6i_pcpu;
     160             :         struct rt6_exception_bucket __rcu *rt6i_exception_bucket;
     161             : };
     162             : 
     163             : struct fib6_info {
     164             :         struct fib6_table               *fib6_table;
     165             :         struct fib6_info __rcu          *fib6_next;
     166             :         struct fib6_node __rcu          *fib6_node;
     167             : 
     168             :         /* Multipath routes:
     169             :          * siblings is a list of fib6_info that have the same metric/weight,
     170             :          * destination, but not the same gateway. nsiblings is just a cache
     171             :          * to speed up lookup.
     172             :          */
     173             :         union {
     174             :                 struct list_head        fib6_siblings;
     175             :                 struct list_head        nh_list;
     176             :         };
     177             :         unsigned int                    fib6_nsiblings;
     178             : 
     179             :         refcount_t                      fib6_ref;
     180             :         unsigned long                   expires;
     181             :         struct dst_metrics              *fib6_metrics;
     182             : #define fib6_pmtu               fib6_metrics->metrics[RTAX_MTU-1]
     183             : 
     184             :         struct rt6key                   fib6_dst;
     185             :         u32                             fib6_flags;
     186             :         struct rt6key                   fib6_src;
     187             :         struct rt6key                   fib6_prefsrc;
     188             : 
     189             :         u32                             fib6_metric;
     190             :         u8                              fib6_protocol;
     191             :         u8                              fib6_type;
     192             :         u8                              should_flush:1,
     193             :                                         dst_nocount:1,
     194             :                                         dst_nopolicy:1,
     195             :                                         fib6_destroying:1,
     196             :                                         offload:1,
     197             :                                         trap:1,
     198             :                                         offload_failed:1,
     199             :                                         unused:1;
     200             : 
     201             :         struct rcu_head                 rcu;
     202             :         struct nexthop                  *nh;
     203             :         struct fib6_nh                  fib6_nh[];
     204             : };
     205             : 
     206             : struct rt6_info {
     207             :         struct dst_entry                dst;
     208             :         struct fib6_info __rcu          *from;
     209             :         int                             sernum;
     210             : 
     211             :         struct rt6key                   rt6i_dst;
     212             :         struct rt6key                   rt6i_src;
     213             :         struct in6_addr                 rt6i_gateway;
     214             :         struct inet6_dev                *rt6i_idev;
     215             :         u32                             rt6i_flags;
     216             : 
     217             :         struct list_head                rt6i_uncached;
     218             :         struct uncached_list            *rt6i_uncached_list;
     219             : 
     220             :         /* more non-fragment space at head required */
     221             :         unsigned short                  rt6i_nfheader_len;
     222             : };
     223             : 
     224             : struct fib6_result {
     225             :         struct fib6_nh          *nh;
     226             :         struct fib6_info        *f6i;
     227             :         u32                     fib6_flags;
     228             :         u8                      fib6_type;
     229             :         struct rt6_info         *rt6;
     230             : };
     231             : 
     232             : #define for_each_fib6_node_rt_rcu(fn)                                   \
     233             :         for (rt = rcu_dereference((fn)->leaf); rt;                   \
     234             :              rt = rcu_dereference(rt->fib6_next))
     235             : 
     236             : #define for_each_fib6_walker_rt(w)                                      \
     237             :         for (rt = (w)->leaf; rt;                                     \
     238             :              rt = rcu_dereference_protected(rt->fib6_next, 1))
     239             : 
     240             : static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
     241             : {
     242             :         return ((struct rt6_info *)dst)->rt6i_idev;
     243             : }
     244             : 
     245             : static inline bool fib6_requires_src(const struct fib6_info *rt)
     246             : {
     247             :         return rt->fib6_src.plen > 0;
     248             : }
     249             : 
     250             : static inline void fib6_clean_expires(struct fib6_info *f6i)
     251             : {
     252             :         f6i->fib6_flags &= ~RTF_EXPIRES;
     253             :         f6i->expires = 0;
     254             : }
     255             : 
     256             : static inline void fib6_set_expires(struct fib6_info *f6i,
     257             :                                     unsigned long expires)
     258             : {
     259             :         f6i->expires = expires;
     260             :         f6i->fib6_flags |= RTF_EXPIRES;
     261             : }
     262             : 
     263             : static inline bool fib6_check_expired(const struct fib6_info *f6i)
     264             : {
     265             :         if (f6i->fib6_flags & RTF_EXPIRES)
     266             :                 return time_after(jiffies, f6i->expires);
     267             :         return false;
     268             : }
     269             : 
     270             : /* Function to safely get fn->sernum for passed in rt
     271             :  * and store result in passed in cookie.
     272             :  * Return true if we can get cookie safely
     273             :  * Return false if not
     274             :  */
     275             : static inline bool fib6_get_cookie_safe(const struct fib6_info *f6i,
     276             :                                         u32 *cookie)
     277             : {
     278             :         struct fib6_node *fn;
     279             :         bool status = false;
     280             : 
     281             :         fn = rcu_dereference(f6i->fib6_node);
     282             : 
     283             :         if (fn) {
     284             :                 *cookie = fn->fn_sernum;
     285             :                 /* pairs with smp_wmb() in fib6_update_sernum_upto_root() */
     286             :                 smp_rmb();
     287             :                 status = true;
     288             :         }
     289             : 
     290             :         return status;
     291             : }
     292             : 
     293             : static inline u32 rt6_get_cookie(const struct rt6_info *rt)
     294             : {
     295             :         struct fib6_info *from;
     296             :         u32 cookie = 0;
     297             : 
     298             :         if (rt->sernum)
     299             :                 return rt->sernum;
     300             : 
     301             :         rcu_read_lock();
     302             : 
     303             :         from = rcu_dereference(rt->from);
     304             :         if (from)
     305             :                 fib6_get_cookie_safe(from, &cookie);
     306             : 
     307             :         rcu_read_unlock();
     308             : 
     309             :         return cookie;
     310             : }
     311             : 
     312             : static inline void ip6_rt_put(struct rt6_info *rt)
     313             : {
     314             :         /* dst_release() accepts a NULL parameter.
     315             :          * We rely on dst being first structure in struct rt6_info
     316             :          */
     317             :         BUILD_BUG_ON(offsetof(struct rt6_info, dst) != 0);
     318             :         dst_release(&rt->dst);
     319             : }
     320             : 
     321             : struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh);
     322             : void fib6_info_destroy_rcu(struct rcu_head *head);
     323             : 
     324           0 : static inline void fib6_info_hold(struct fib6_info *f6i)
     325             : {
     326           0 :         refcount_inc(&f6i->fib6_ref);
     327             : }
     328             : 
     329             : static inline bool fib6_info_hold_safe(struct fib6_info *f6i)
     330             : {
     331             :         return refcount_inc_not_zero(&f6i->fib6_ref);
     332             : }
     333             : 
     334             : static inline void fib6_info_release(struct fib6_info *f6i)
     335             : {
     336             :         if (f6i && refcount_dec_and_test(&f6i->fib6_ref))
     337             :                 call_rcu(&f6i->rcu, fib6_info_destroy_rcu);
     338             : }
     339             : 
     340             : enum fib6_walk_state {
     341             : #ifdef CONFIG_IPV6_SUBTREES
     342             :         FWS_S,
     343             : #endif
     344             :         FWS_L,
     345             :         FWS_R,
     346             :         FWS_C,
     347             :         FWS_U
     348             : };
     349             : 
     350             : struct fib6_walker {
     351             :         struct list_head lh;
     352             :         struct fib6_node *root, *node;
     353             :         struct fib6_info *leaf;
     354             :         enum fib6_walk_state state;
     355             :         unsigned int skip;
     356             :         unsigned int count;
     357             :         unsigned int skip_in_node;
     358             :         int (*func)(struct fib6_walker *);
     359             :         void *args;
     360             : };
     361             : 
     362             : struct rt6_statistics {
     363             :         __u32           fib_nodes;              /* all fib6 nodes */
     364             :         __u32           fib_route_nodes;        /* intermediate nodes */
     365             :         __u32           fib_rt_entries;         /* rt entries in fib table */
     366             :         __u32           fib_rt_cache;           /* cached rt entries in exception table */
     367             :         __u32           fib_discarded_routes;   /* total number of routes delete */
     368             : 
     369             :         /* The following stats are not protected by any lock */
     370             :         atomic_t        fib_rt_alloc;           /* total number of routes alloced */
     371             :         atomic_t        fib_rt_uncache;         /* rt entries in uncached list */
     372             : };
     373             : 
     374             : #define RTN_TL_ROOT     0x0001
     375             : #define RTN_ROOT        0x0002          /* tree root node               */
     376             : #define RTN_RTINFO      0x0004          /* node with valid routing info */
     377             : 
     378             : /*
     379             :  *      priority levels (or metrics)
     380             :  *
     381             :  */
     382             : 
     383             : 
     384             : struct fib6_table {
     385             :         struct hlist_node       tb6_hlist;
     386             :         u32                     tb6_id;
     387             :         spinlock_t              tb6_lock;
     388             :         struct fib6_node        tb6_root;
     389             :         struct inet_peer_base   tb6_peers;
     390             :         unsigned int            flags;
     391             :         unsigned int            fib_seq;
     392             : #define RT6_TABLE_HAS_DFLT_ROUTER       BIT(0)
     393             : };
     394             : 
     395             : #define RT6_TABLE_UNSPEC        RT_TABLE_UNSPEC
     396             : #define RT6_TABLE_MAIN          RT_TABLE_MAIN
     397             : #define RT6_TABLE_DFLT          RT6_TABLE_MAIN
     398             : #define RT6_TABLE_INFO          RT6_TABLE_MAIN
     399             : #define RT6_TABLE_PREFIX        RT6_TABLE_MAIN
     400             : 
     401             : #ifdef CONFIG_IPV6_MULTIPLE_TABLES
     402             : #define FIB6_TABLE_MIN          1
     403             : #define FIB6_TABLE_MAX          RT_TABLE_MAX
     404             : #define RT6_TABLE_LOCAL         RT_TABLE_LOCAL
     405             : #else
     406             : #define FIB6_TABLE_MIN          RT_TABLE_MAIN
     407             : #define FIB6_TABLE_MAX          FIB6_TABLE_MIN
     408             : #define RT6_TABLE_LOCAL         RT6_TABLE_MAIN
     409             : #endif
     410             : 
     411             : typedef struct rt6_info *(*pol_lookup_t)(struct net *,
     412             :                                          struct fib6_table *,
     413             :                                          struct flowi6 *,
     414             :                                          const struct sk_buff *, int);
     415             : 
     416             : struct fib6_entry_notifier_info {
     417             :         struct fib_notifier_info info; /* must be first */
     418             :         struct fib6_info *rt;
     419             :         unsigned int nsiblings;
     420             : };
     421             : 
     422             : /*
     423             :  *      exported functions
     424             :  */
     425             : 
     426             : struct fib6_table *fib6_get_table(struct net *net, u32 id);
     427             : struct fib6_table *fib6_new_table(struct net *net, u32 id);
     428             : struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
     429             :                                    const struct sk_buff *skb,
     430             :                                    int flags, pol_lookup_t lookup);
     431             : 
     432             : /* called with rcu lock held; can return error pointer
     433             :  * caller needs to select path
     434             :  */
     435             : int fib6_lookup(struct net *net, int oif, struct flowi6 *fl6,
     436             :                 struct fib6_result *res, int flags);
     437             : 
     438             : /* called with rcu lock held; caller needs to select path */
     439             : int fib6_table_lookup(struct net *net, struct fib6_table *table,
     440             :                       int oif, struct flowi6 *fl6, struct fib6_result *res,
     441             :                       int strict);
     442             : 
     443             : void fib6_select_path(const struct net *net, struct fib6_result *res,
     444             :                       struct flowi6 *fl6, int oif, bool have_oif_match,
     445             :                       const struct sk_buff *skb, int strict);
     446             : struct fib6_node *fib6_node_lookup(struct fib6_node *root,
     447             :                                    const struct in6_addr *daddr,
     448             :                                    const struct in6_addr *saddr);
     449             : 
     450             : struct fib6_node *fib6_locate(struct fib6_node *root,
     451             :                               const struct in6_addr *daddr, int dst_len,
     452             :                               const struct in6_addr *saddr, int src_len,
     453             :                               bool exact_match);
     454             : 
     455             : void fib6_clean_all(struct net *net, int (*func)(struct fib6_info *, void *arg),
     456             :                     void *arg);
     457             : void fib6_clean_all_skip_notify(struct net *net,
     458             :                                 int (*func)(struct fib6_info *, void *arg),
     459             :                                 void *arg);
     460             : 
     461             : int fib6_add(struct fib6_node *root, struct fib6_info *rt,
     462             :              struct nl_info *info, struct netlink_ext_ack *extack);
     463             : int fib6_del(struct fib6_info *rt, struct nl_info *info);
     464             : 
     465             : static inline
     466             : void rt6_get_prefsrc(const struct rt6_info *rt, struct in6_addr *addr)
     467             : {
     468             :         const struct fib6_info *from;
     469             : 
     470             :         rcu_read_lock();
     471             : 
     472             :         from = rcu_dereference(rt->from);
     473             :         if (from) {
     474             :                 *addr = from->fib6_prefsrc.addr;
     475             :         } else {
     476             :                 struct in6_addr in6_zero = {};
     477             : 
     478             :                 *addr = in6_zero;
     479             :         }
     480             : 
     481             :         rcu_read_unlock();
     482             : }
     483             : 
     484             : int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
     485             :                  struct fib6_config *cfg, gfp_t gfp_flags,
     486             :                  struct netlink_ext_ack *extack);
     487             : void fib6_nh_release(struct fib6_nh *fib6_nh);
     488             : 
     489             : int call_fib6_entry_notifiers(struct net *net,
     490             :                               enum fib_event_type event_type,
     491             :                               struct fib6_info *rt,
     492             :                               struct netlink_ext_ack *extack);
     493             : int call_fib6_multipath_entry_notifiers(struct net *net,
     494             :                                         enum fib_event_type event_type,
     495             :                                         struct fib6_info *rt,
     496             :                                         unsigned int nsiblings,
     497             :                                         struct netlink_ext_ack *extack);
     498             : int call_fib6_entry_notifiers_replace(struct net *net, struct fib6_info *rt);
     499             : void fib6_rt_update(struct net *net, struct fib6_info *rt,
     500             :                     struct nl_info *info);
     501             : void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info,
     502             :                      unsigned int flags);
     503             : 
     504             : void fib6_run_gc(unsigned long expires, struct net *net, bool force);
     505             : 
     506             : void fib6_gc_cleanup(void);
     507             : 
     508             : int fib6_init(void);
     509             : 
     510             : struct ipv6_route_iter {
     511             :         struct seq_net_private p;
     512             :         struct fib6_walker w;
     513             :         loff_t skip;
     514             :         struct fib6_table *tbl;
     515             :         int sernum;
     516             : };
     517             : 
     518             : extern const struct seq_operations ipv6_route_seq_ops;
     519             : 
     520             : int call_fib6_notifier(struct notifier_block *nb,
     521             :                        enum fib_event_type event_type,
     522             :                        struct fib_notifier_info *info);
     523             : int call_fib6_notifiers(struct net *net, enum fib_event_type event_type,
     524             :                         struct fib_notifier_info *info);
     525             : 
     526             : int __net_init fib6_notifier_init(struct net *net);
     527             : void __net_exit fib6_notifier_exit(struct net *net);
     528             : 
     529             : unsigned int fib6_tables_seq_read(struct net *net);
     530             : int fib6_tables_dump(struct net *net, struct notifier_block *nb,
     531             :                      struct netlink_ext_ack *extack);
     532             : 
     533             : void fib6_update_sernum(struct net *net, struct fib6_info *rt);
     534             : void fib6_update_sernum_upto_root(struct net *net, struct fib6_info *rt);
     535             : void fib6_update_sernum_stub(struct net *net, struct fib6_info *f6i);
     536             : 
     537             : void fib6_metric_set(struct fib6_info *f6i, int metric, u32 val);
     538             : static inline bool fib6_metric_locked(struct fib6_info *f6i, int metric)
     539             : {
     540             :         return !!(f6i->fib6_metrics->metrics[RTAX_LOCK - 1] & (1 << metric));
     541             : }
     542             : void fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i,
     543             :                             bool offload, bool trap, bool offload_failed);
     544             : 
     545             : #if IS_BUILTIN(CONFIG_IPV6) && defined(CONFIG_BPF_SYSCALL)
     546             : struct bpf_iter__ipv6_route {
     547             :         __bpf_md_ptr(struct bpf_iter_meta *, meta);
     548             :         __bpf_md_ptr(struct fib6_info *, rt);
     549             : };
     550             : #endif
     551             : 
     552             : INDIRECT_CALLABLE_DECLARE(struct rt6_info *ip6_pol_route_output(struct net *net,
     553             :                                              struct fib6_table *table,
     554             :                                              struct flowi6 *fl6,
     555             :                                              const struct sk_buff *skb,
     556             :                                              int flags));
     557             : INDIRECT_CALLABLE_DECLARE(struct rt6_info *ip6_pol_route_input(struct net *net,
     558             :                                              struct fib6_table *table,
     559             :                                              struct flowi6 *fl6,
     560             :                                              const struct sk_buff *skb,
     561             :                                              int flags));
     562             : INDIRECT_CALLABLE_DECLARE(struct rt6_info *__ip6_route_redirect(struct net *net,
     563             :                                              struct fib6_table *table,
     564             :                                              struct flowi6 *fl6,
     565             :                                              const struct sk_buff *skb,
     566             :                                              int flags));
     567             : INDIRECT_CALLABLE_DECLARE(struct rt6_info *ip6_pol_route_lookup(struct net *net,
     568             :                                              struct fib6_table *table,
     569             :                                              struct flowi6 *fl6,
     570             :                                              const struct sk_buff *skb,
     571             :                                              int flags));
     572             : static inline struct rt6_info *pol_lookup_func(pol_lookup_t lookup,
     573             :                                                 struct net *net,
     574             :                                                 struct fib6_table *table,
     575             :                                                 struct flowi6 *fl6,
     576             :                                                 const struct sk_buff *skb,
     577             :                                                 int flags)
     578             : {
     579             :         return INDIRECT_CALL_4(lookup,
     580             :                                ip6_pol_route_output,
     581             :                                ip6_pol_route_input,
     582             :                                ip6_pol_route_lookup,
     583             :                                __ip6_route_redirect,
     584             :                                net, table, fl6, skb, flags);
     585             : }
     586             : 
     587             : #ifdef CONFIG_IPV6_MULTIPLE_TABLES
     588             : static inline bool fib6_has_custom_rules(const struct net *net)
     589             : {
     590             :         return net->ipv6.fib6_has_custom_rules;
     591             : }
     592             : 
     593             : int fib6_rules_init(void);
     594             : void fib6_rules_cleanup(void);
     595             : bool fib6_rule_default(const struct fib_rule *rule);
     596             : int fib6_rules_dump(struct net *net, struct notifier_block *nb,
     597             :                     struct netlink_ext_ack *extack);
     598             : unsigned int fib6_rules_seq_read(struct net *net);
     599             : 
     600             : static inline bool fib6_rules_early_flow_dissect(struct net *net,
     601             :                                                  struct sk_buff *skb,
     602             :                                                  struct flowi6 *fl6,
     603             :                                                  struct flow_keys *flkeys)
     604             : {
     605             :         unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP;
     606             : 
     607             :         if (!net->ipv6.fib6_rules_require_fldissect)
     608             :                 return false;
     609             : 
     610             :         skb_flow_dissect_flow_keys(skb, flkeys, flag);
     611             :         fl6->fl6_sport = flkeys->ports.src;
     612             :         fl6->fl6_dport = flkeys->ports.dst;
     613             :         fl6->flowi6_proto = flkeys->basic.ip_proto;
     614             : 
     615             :         return true;
     616             : }
     617             : #else
     618             : static inline bool fib6_has_custom_rules(const struct net *net)
     619             : {
     620             :         return false;
     621             : }
     622             : static inline int               fib6_rules_init(void)
     623             : {
     624             :         return 0;
     625             : }
     626             : static inline void              fib6_rules_cleanup(void)
     627             : {
     628             :         return ;
     629             : }
     630             : static inline bool fib6_rule_default(const struct fib_rule *rule)
     631             : {
     632             :         return true;
     633             : }
     634             : static inline int fib6_rules_dump(struct net *net, struct notifier_block *nb,
     635             :                                   struct netlink_ext_ack *extack)
     636             : {
     637             :         return 0;
     638             : }
     639             : static inline unsigned int fib6_rules_seq_read(struct net *net)
     640             : {
     641             :         return 0;
     642             : }
     643             : static inline bool fib6_rules_early_flow_dissect(struct net *net,
     644             :                                                  struct sk_buff *skb,
     645             :                                                  struct flowi6 *fl6,
     646             :                                                  struct flow_keys *flkeys)
     647             : {
     648             :         return false;
     649             : }
     650             : #endif
     651             : #endif

Generated by: LCOV version 1.14