LCOV - code coverage report
Current view: top level - include/net - l3mdev.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 12 20 60.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             :  * include/net/l3mdev.h - L3 master device API
       4             :  * Copyright (c) 2015 Cumulus Networks
       5             :  * Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com>
       6             :  */
       7             : #ifndef _NET_L3MDEV_H_
       8             : #define _NET_L3MDEV_H_
       9             : 
      10             : #include <net/dst.h>
      11             : #include <net/fib_rules.h>
      12             : 
      13             : enum l3mdev_type {
      14             :         L3MDEV_TYPE_UNSPEC,
      15             :         L3MDEV_TYPE_VRF,
      16             :         __L3MDEV_TYPE_MAX
      17             : };
      18             : 
      19             : #define L3MDEV_TYPE_MAX (__L3MDEV_TYPE_MAX - 1)
      20             : 
      21             : typedef int (*lookup_by_table_id_t)(struct net *net, u32 table_d);
      22             : 
      23             : /**
      24             :  * struct l3mdev_ops - l3mdev operations
      25             :  *
      26             :  * @l3mdev_fib_table: Get FIB table id to use for lookups
      27             :  *
      28             :  * @l3mdev_l3_rcv:    Hook in L3 receive path
      29             :  *
      30             :  * @l3mdev_l3_out:    Hook in L3 output path
      31             :  *
      32             :  * @l3mdev_link_scope_lookup: IPv6 lookup for linklocal and mcast destinations
      33             :  */
      34             : 
      35             : struct l3mdev_ops {
      36             :         u32             (*l3mdev_fib_table)(const struct net_device *dev);
      37             :         struct sk_buff * (*l3mdev_l3_rcv)(struct net_device *dev,
      38             :                                           struct sk_buff *skb, u16 proto);
      39             :         struct sk_buff * (*l3mdev_l3_out)(struct net_device *dev,
      40             :                                           struct sock *sk, struct sk_buff *skb,
      41             :                                           u16 proto);
      42             : 
      43             :         /* IPv6 ops */
      44             :         struct dst_entry * (*l3mdev_link_scope_lookup)(const struct net_device *dev,
      45             :                                                  struct flowi6 *fl6);
      46             : };
      47             : 
      48             : #ifdef CONFIG_NET_L3_MASTER_DEV
      49             : 
      50             : int l3mdev_table_lookup_register(enum l3mdev_type l3type,
      51             :                                  lookup_by_table_id_t fn);
      52             : 
      53             : void l3mdev_table_lookup_unregister(enum l3mdev_type l3type,
      54             :                                     lookup_by_table_id_t fn);
      55             : 
      56             : int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net,
      57             :                                       u32 table_id);
      58             : 
      59             : int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
      60             :                           struct fib_lookup_arg *arg);
      61             : 
      62             : void l3mdev_update_flow(struct net *net, struct flowi *fl);
      63             : 
      64             : int l3mdev_master_ifindex_rcu(const struct net_device *dev);
      65             : static inline int l3mdev_master_ifindex(struct net_device *dev)
      66             : {
      67             :         int ifindex;
      68             : 
      69             :         rcu_read_lock();
      70             :         ifindex = l3mdev_master_ifindex_rcu(dev);
      71             :         rcu_read_unlock();
      72             : 
      73             :         return ifindex;
      74             : }
      75             : 
      76             : static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
      77             : {
      78             :         struct net_device *dev;
      79             :         int rc = 0;
      80             : 
      81             :         if (likely(ifindex)) {
      82             :                 rcu_read_lock();
      83             : 
      84             :                 dev = dev_get_by_index_rcu(net, ifindex);
      85             :                 if (dev)
      86             :                         rc = l3mdev_master_ifindex_rcu(dev);
      87             : 
      88             :                 rcu_read_unlock();
      89             :         }
      90             : 
      91             :         return rc;
      92             : }
      93             : 
      94             : static inline
      95             : struct net_device *l3mdev_master_dev_rcu(const struct net_device *_dev)
      96             : {
      97             :         /* netdev_master_upper_dev_get_rcu calls
      98             :          * list_first_or_null_rcu to walk the upper dev list.
      99             :          * list_first_or_null_rcu does not handle a const arg. We aren't
     100             :          * making changes, just want the master device from that list so
     101             :          * typecast to remove the const
     102             :          */
     103             :         struct net_device *dev = (struct net_device *)_dev;
     104             :         struct net_device *master;
     105             : 
     106             :         if (!dev)
     107             :                 return NULL;
     108             : 
     109             :         if (netif_is_l3_master(dev))
     110             :                 master = dev;
     111             :         else if (netif_is_l3_slave(dev))
     112             :                 master = netdev_master_upper_dev_get_rcu(dev);
     113             :         else
     114             :                 master = NULL;
     115             : 
     116             :         return master;
     117             : }
     118             : 
     119             : int l3mdev_master_upper_ifindex_by_index_rcu(struct net *net, int ifindex);
     120             : static inline
     121             : int l3mdev_master_upper_ifindex_by_index(struct net *net, int ifindex)
     122             : {
     123             :         rcu_read_lock();
     124             :         ifindex = l3mdev_master_upper_ifindex_by_index_rcu(net, ifindex);
     125             :         rcu_read_unlock();
     126             : 
     127             :         return ifindex;
     128             : }
     129             : 
     130             : u32 l3mdev_fib_table_rcu(const struct net_device *dev);
     131             : u32 l3mdev_fib_table_by_index(struct net *net, int ifindex);
     132             : static inline u32 l3mdev_fib_table(const struct net_device *dev)
     133             : {
     134             :         u32 tb_id;
     135             : 
     136             :         rcu_read_lock();
     137             :         tb_id = l3mdev_fib_table_rcu(dev);
     138             :         rcu_read_unlock();
     139             : 
     140             :         return tb_id;
     141             : }
     142             : 
     143             : static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
     144             : {
     145             :         struct net_device *dev;
     146             :         bool rc = false;
     147             : 
     148             :         if (ifindex == 0)
     149             :                 return false;
     150             : 
     151             :         rcu_read_lock();
     152             : 
     153             :         dev = dev_get_by_index_rcu(net, ifindex);
     154             :         if (dev)
     155             :                 rc = netif_is_l3_master(dev);
     156             : 
     157             :         rcu_read_unlock();
     158             : 
     159             :         return rc;
     160             : }
     161             : 
     162             : struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6);
     163             : 
     164             : static inline
     165             : struct sk_buff *l3mdev_l3_rcv(struct sk_buff *skb, u16 proto)
     166             : {
     167             :         struct net_device *master = NULL;
     168             : 
     169             :         if (netif_is_l3_slave(skb->dev))
     170             :                 master = netdev_master_upper_dev_get_rcu(skb->dev);
     171             :         else if (netif_is_l3_master(skb->dev) ||
     172             :                  netif_has_l3_rx_handler(skb->dev))
     173             :                 master = skb->dev;
     174             : 
     175             :         if (master && master->l3mdev_ops->l3mdev_l3_rcv)
     176             :                 skb = master->l3mdev_ops->l3mdev_l3_rcv(master, skb, proto);
     177             : 
     178             :         return skb;
     179             : }
     180             : 
     181             : static inline
     182             : struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
     183             : {
     184             :         return l3mdev_l3_rcv(skb, AF_INET);
     185             : }
     186             : 
     187             : static inline
     188             : struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
     189             : {
     190             :         return l3mdev_l3_rcv(skb, AF_INET6);
     191             : }
     192             : 
     193             : static inline
     194             : struct sk_buff *l3mdev_l3_out(struct sock *sk, struct sk_buff *skb, u16 proto)
     195             : {
     196             :         struct net_device *dev = skb_dst(skb)->dev;
     197             : 
     198             :         if (netif_is_l3_slave(dev)) {
     199             :                 struct net_device *master;
     200             : 
     201             :                 master = netdev_master_upper_dev_get_rcu(dev);
     202             :                 if (master && master->l3mdev_ops->l3mdev_l3_out)
     203             :                         skb = master->l3mdev_ops->l3mdev_l3_out(master, sk,
     204             :                                                                 skb, proto);
     205             :         }
     206             : 
     207             :         return skb;
     208             : }
     209             : 
     210             : static inline
     211             : struct sk_buff *l3mdev_ip_out(struct sock *sk, struct sk_buff *skb)
     212             : {
     213             :         return l3mdev_l3_out(sk, skb, AF_INET);
     214             : }
     215             : 
     216             : static inline
     217             : struct sk_buff *l3mdev_ip6_out(struct sock *sk, struct sk_buff *skb)
     218             : {
     219             :         return l3mdev_l3_out(sk, skb, AF_INET6);
     220             : }
     221             : #else
     222             : 
     223           6 : static inline int l3mdev_master_ifindex_rcu(const struct net_device *dev)
     224             : {
     225           6 :         return 0;
     226             : }
     227           0 : static inline int l3mdev_master_ifindex(struct net_device *dev)
     228             : {
     229           0 :         return 0;
     230             : }
     231             : 
     232           0 : static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
     233             : {
     234           0 :         return 0;
     235             : }
     236             : 
     237             : static inline
     238             : int l3mdev_master_upper_ifindex_by_index_rcu(struct net *net, int ifindex)
     239             : {
     240             :         return 0;
     241             : }
     242             : static inline
     243             : int l3mdev_master_upper_ifindex_by_index(struct net *net, int ifindex)
     244             : {
     245             :         return 0;
     246             : }
     247             : 
     248             : static inline
     249           9 : struct net_device *l3mdev_master_dev_rcu(const struct net_device *dev)
     250             : {
     251           9 :         return NULL;
     252             : }
     253             : 
     254           0 : static inline u32 l3mdev_fib_table_rcu(const struct net_device *dev)
     255             : {
     256           0 :         return 0;
     257             : }
     258          14 : static inline u32 l3mdev_fib_table(const struct net_device *dev)
     259             : {
     260          14 :         return 0;
     261             : }
     262           5 : static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
     263             : {
     264           5 :         return 0;
     265             : }
     266             : 
     267             : static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
     268             : {
     269             :         return false;
     270             : }
     271             : 
     272             : static inline
     273             : struct dst_entry *l3mdev_link_scope_lookup(struct net *net, struct flowi6 *fl6)
     274             : {
     275             :         return NULL;
     276             : }
     277             : 
     278             : static inline
     279         454 : struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
     280             : {
     281         454 :         return skb;
     282             : }
     283             : 
     284             : static inline
     285             : struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
     286             : {
     287             :         return skb;
     288             : }
     289             : 
     290             : static inline
     291         444 : struct sk_buff *l3mdev_ip_out(struct sock *sk, struct sk_buff *skb)
     292             : {
     293         444 :         return skb;
     294             : }
     295             : 
     296             : static inline
     297           0 : struct sk_buff *l3mdev_ip6_out(struct sock *sk, struct sk_buff *skb)
     298             : {
     299           0 :         return skb;
     300             : }
     301             : 
     302             : static inline
     303             : int l3mdev_table_lookup_register(enum l3mdev_type l3type,
     304             :                                  lookup_by_table_id_t fn)
     305             : {
     306             :         return -EOPNOTSUPP;
     307             : }
     308             : 
     309             : static inline
     310             : void l3mdev_table_lookup_unregister(enum l3mdev_type l3type,
     311             :                                     lookup_by_table_id_t fn)
     312             : {
     313             : }
     314             : 
     315             : static inline
     316             : int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net,
     317             :                                       u32 table_id)
     318             : {
     319             :         return -ENODEV;
     320             : }
     321             : 
     322             : static inline
     323             : int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
     324             :                           struct fib_lookup_arg *arg)
     325             : {
     326             :         return 1;
     327             : }
     328             : static inline
     329             : void l3mdev_update_flow(struct net *net, struct flowi *fl)
     330             : {
     331             : }
     332             : #endif
     333             : 
     334             : #endif /* _NET_L3MDEV_H_ */

Generated by: LCOV version 1.14