LCOV - code coverage report
Current view: top level - include/linux - mroute_base.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 38 0.0 %
Date: 2022-04-01 14:35:51 Functions: 0 4 0.0 %
Branches: 0 16 0.0 %

           Branch data     Line data    Source code
       1                 :            : #ifndef __LINUX_MROUTE_BASE_H
       2                 :            : #define __LINUX_MROUTE_BASE_H
       3                 :            : 
       4                 :            : #include <linux/netdevice.h>
       5                 :            : #include <linux/rhashtable-types.h>
       6                 :            : #include <linux/spinlock.h>
       7                 :            : #include <net/net_namespace.h>
       8                 :            : #include <net/sock.h>
       9                 :            : #include <net/fib_notifier.h>
      10                 :            : #include <net/ip_fib.h>
      11                 :            : 
      12                 :            : /**
      13                 :            :  * struct vif_device - interface representor for multicast routing
      14                 :            :  * @dev: network device being used
      15                 :            :  * @bytes_in: statistic; bytes ingressing
      16                 :            :  * @bytes_out: statistic; bytes egresing
      17                 :            :  * @pkt_in: statistic; packets ingressing
      18                 :            :  * @pkt_out: statistic; packets egressing
      19                 :            :  * @rate_limit: Traffic shaping (NI)
      20                 :            :  * @threshold: TTL threshold
      21                 :            :  * @flags: Control flags
      22                 :            :  * @link: Physical interface index
      23                 :            :  * @dev_parent_id: device parent id
      24                 :            :  * @local: Local address
      25                 :            :  * @remote: Remote address for tunnels
      26                 :            :  */
      27                 :            : struct vif_device {
      28                 :            :         struct net_device *dev;
      29                 :            :         unsigned long bytes_in, bytes_out;
      30                 :            :         unsigned long pkt_in, pkt_out;
      31                 :            :         unsigned long rate_limit;
      32                 :            :         unsigned char threshold;
      33                 :            :         unsigned short flags;
      34                 :            :         int link;
      35                 :            : 
      36                 :            :         /* Currently only used by ipmr */
      37                 :            :         struct netdev_phys_item_id dev_parent_id;
      38                 :            :         __be32 local, remote;
      39                 :            : };
      40                 :            : 
      41                 :            : struct vif_entry_notifier_info {
      42                 :            :         struct fib_notifier_info info;
      43                 :            :         struct net_device *dev;
      44                 :            :         unsigned short vif_index;
      45                 :            :         unsigned short vif_flags;
      46                 :            :         u32 tb_id;
      47                 :            : };
      48                 :            : 
      49                 :          0 : static inline int mr_call_vif_notifier(struct notifier_block *nb,
      50                 :            :                                        unsigned short family,
      51                 :            :                                        enum fib_event_type event_type,
      52                 :            :                                        struct vif_device *vif,
      53                 :            :                                        unsigned short vif_index, u32 tb_id,
      54                 :            :                                        struct netlink_ext_ack *extack)
      55                 :            : {
      56                 :          0 :         struct vif_entry_notifier_info info = {
      57                 :            :                 .info = {
      58                 :            :                         .family = family,
      59                 :            :                         .extack = extack,
      60                 :            :                 },
      61                 :          0 :                 .dev = vif->dev,
      62                 :            :                 .vif_index = vif_index,
      63                 :          0 :                 .vif_flags = vif->flags,
      64                 :            :                 .tb_id = tb_id,
      65                 :            :         };
      66                 :            : 
      67                 :          0 :         return call_fib_notifier(nb, event_type, &info.info);
      68                 :            : }
      69                 :            : 
      70                 :          0 : static inline int mr_call_vif_notifiers(struct net *net,
      71                 :            :                                         unsigned short family,
      72                 :            :                                         enum fib_event_type event_type,
      73                 :            :                                         struct vif_device *vif,
      74                 :            :                                         unsigned short vif_index, u32 tb_id,
      75                 :            :                                         unsigned int *ipmr_seq)
      76                 :            : {
      77                 :          0 :         struct vif_entry_notifier_info info = {
      78                 :            :                 .info = {
      79                 :            :                         .family = family,
      80                 :            :                 },
      81                 :          0 :                 .dev = vif->dev,
      82                 :            :                 .vif_index = vif_index,
      83                 :          0 :                 .vif_flags = vif->flags,
      84                 :            :                 .tb_id = tb_id,
      85                 :            :         };
      86                 :            : 
      87   [ #  #  #  # ]:          0 :         ASSERT_RTNL();
      88                 :          0 :         (*ipmr_seq)++;
      89                 :          0 :         return call_fib_notifiers(net, event_type, &info.info);
      90                 :            : }
      91                 :            : 
      92                 :            : #ifndef MAXVIFS
      93                 :            : /* This one is nasty; value is defined in uapi using different symbols for
      94                 :            :  * mroute and morute6 but both map into same 32.
      95                 :            :  */
      96                 :            : #define MAXVIFS 32
      97                 :            : #endif
      98                 :            : 
      99                 :            : #define VIF_EXISTS(_mrt, _idx) (!!((_mrt)->vif_table[_idx].dev))
     100                 :            : 
     101                 :            : /* mfc_flags:
     102                 :            :  * MFC_STATIC - the entry was added statically (not by a routing daemon)
     103                 :            :  * MFC_OFFLOAD - the entry was offloaded to the hardware
     104                 :            :  */
     105                 :            : enum {
     106                 :            :         MFC_STATIC = BIT(0),
     107                 :            :         MFC_OFFLOAD = BIT(1),
     108                 :            : };
     109                 :            : 
     110                 :            : /**
     111                 :            :  * struct mr_mfc - common multicast routing entries
     112                 :            :  * @mnode: rhashtable list
     113                 :            :  * @mfc_parent: source interface (iif)
     114                 :            :  * @mfc_flags: entry flags
     115                 :            :  * @expires: unresolved entry expire time
     116                 :            :  * @unresolved: unresolved cached skbs
     117                 :            :  * @last_assert: time of last assert
     118                 :            :  * @minvif: minimum VIF id
     119                 :            :  * @maxvif: maximum VIF id
     120                 :            :  * @bytes: bytes that have passed for this entry
     121                 :            :  * @pkt: packets that have passed for this entry
     122                 :            :  * @wrong_if: number of wrong source interface hits
     123                 :            :  * @lastuse: time of last use of the group (traffic or update)
     124                 :            :  * @ttls: OIF TTL threshold array
     125                 :            :  * @refcount: reference count for this entry
     126                 :            :  * @list: global entry list
     127                 :            :  * @rcu: used for entry destruction
     128                 :            :  * @free: Operation used for freeing an entry under RCU
     129                 :            :  */
     130                 :            : struct mr_mfc {
     131                 :            :         struct rhlist_head mnode;
     132                 :            :         unsigned short mfc_parent;
     133                 :            :         int mfc_flags;
     134                 :            : 
     135                 :            :         union {
     136                 :            :                 struct {
     137                 :            :                         unsigned long expires;
     138                 :            :                         struct sk_buff_head unresolved;
     139                 :            :                 } unres;
     140                 :            :                 struct {
     141                 :            :                         unsigned long last_assert;
     142                 :            :                         int minvif;
     143                 :            :                         int maxvif;
     144                 :            :                         unsigned long bytes;
     145                 :            :                         unsigned long pkt;
     146                 :            :                         unsigned long wrong_if;
     147                 :            :                         unsigned long lastuse;
     148                 :            :                         unsigned char ttls[MAXVIFS];
     149                 :            :                         refcount_t refcount;
     150                 :            :                 } res;
     151                 :            :         } mfc_un;
     152                 :            :         struct list_head list;
     153                 :            :         struct rcu_head rcu;
     154                 :            :         void (*free)(struct rcu_head *head);
     155                 :            : };
     156                 :            : 
     157                 :          0 : static inline void mr_cache_put(struct mr_mfc *c)
     158                 :            : {
     159         [ #  # ]:          0 :         if (refcount_dec_and_test(&c->mfc_un.res.refcount))
     160                 :          0 :                 call_rcu(&c->rcu, c->free);
     161                 :          0 : }
     162                 :            : 
     163                 :            : static inline void mr_cache_hold(struct mr_mfc *c)
     164                 :            : {
     165                 :            :         refcount_inc(&c->mfc_un.res.refcount);
     166                 :            : }
     167                 :            : 
     168                 :            : struct mfc_entry_notifier_info {
     169                 :            :         struct fib_notifier_info info;
     170                 :            :         struct mr_mfc *mfc;
     171                 :            :         u32 tb_id;
     172                 :            : };
     173                 :            : 
     174                 :          0 : static inline int mr_call_mfc_notifier(struct notifier_block *nb,
     175                 :            :                                        unsigned short family,
     176                 :            :                                        enum fib_event_type event_type,
     177                 :            :                                        struct mr_mfc *mfc, u32 tb_id,
     178                 :            :                                        struct netlink_ext_ack *extack)
     179                 :            : {
     180                 :          0 :         struct mfc_entry_notifier_info info = {
     181                 :            :                 .info = {
     182                 :            :                         .family = family,
     183                 :            :                         .extack = extack,
     184                 :            :                 },
     185                 :            :                 .mfc = mfc,
     186                 :            :                 .tb_id = tb_id
     187                 :            :         };
     188                 :            : 
     189                 :          0 :         return call_fib_notifier(nb, event_type, &info.info);
     190                 :            : }
     191                 :            : 
     192                 :          0 : static inline int mr_call_mfc_notifiers(struct net *net,
     193                 :            :                                         unsigned short family,
     194                 :            :                                         enum fib_event_type event_type,
     195                 :            :                                         struct mr_mfc *mfc, u32 tb_id,
     196                 :            :                                         unsigned int *ipmr_seq)
     197                 :            : {
     198                 :          0 :         struct mfc_entry_notifier_info info = {
     199                 :            :                 .info = {
     200                 :            :                         .family = family,
     201                 :            :                 },
     202                 :            :                 .mfc = mfc,
     203                 :            :                 .tb_id = tb_id
     204                 :            :         };
     205                 :            : 
     206   [ #  #  #  # ]:          0 :         ASSERT_RTNL();
     207                 :          0 :         (*ipmr_seq)++;
     208                 :          0 :         return call_fib_notifiers(net, event_type, &info.info);
     209                 :            : }
     210                 :            : 
     211                 :            : struct mr_table;
     212                 :            : 
     213                 :            : /**
     214                 :            :  * struct mr_table_ops - callbacks and info for protocol-specific ops
     215                 :            :  * @rht_params: parameters for accessing the MFC hash
     216                 :            :  * @cmparg_any: a hash key to be used for matching on (*,*) routes
     217                 :            :  */
     218                 :            : struct mr_table_ops {
     219                 :            :         const struct rhashtable_params *rht_params;
     220                 :            :         void *cmparg_any;
     221                 :            : };
     222                 :            : 
     223                 :            : /**
     224                 :            :  * struct mr_table - a multicast routing table
     225                 :            :  * @list: entry within a list of multicast routing tables
     226                 :            :  * @net: net where this table belongs
     227                 :            :  * @ops: protocol specific operations
     228                 :            :  * @id: identifier of the table
     229                 :            :  * @mroute_sk: socket associated with the table
     230                 :            :  * @ipmr_expire_timer: timer for handling unresolved routes
     231                 :            :  * @mfc_unres_queue: list of unresolved MFC entries
     232                 :            :  * @vif_table: array containing all possible vifs
     233                 :            :  * @mfc_hash: Hash table of all resolved routes for easy lookup
     234                 :            :  * @mfc_cache_list: list of resovled routes for possible traversal
     235                 :            :  * @maxvif: Identifier of highest value vif currently in use
     236                 :            :  * @cache_resolve_queue_len: current size of unresolved queue
     237                 :            :  * @mroute_do_assert: Whether to inform userspace on wrong ingress
     238                 :            :  * @mroute_do_pim: Whether to receive IGMP PIMv1
     239                 :            :  * @mroute_reg_vif_num: PIM-device vif index
     240                 :            :  */
     241                 :            : struct mr_table {
     242                 :            :         struct list_head        list;
     243                 :            :         possible_net_t          net;
     244                 :            :         struct mr_table_ops     ops;
     245                 :            :         u32                     id;
     246                 :            :         struct sock __rcu       *mroute_sk;
     247                 :            :         struct timer_list       ipmr_expire_timer;
     248                 :            :         struct list_head        mfc_unres_queue;
     249                 :            :         struct vif_device       vif_table[MAXVIFS];
     250                 :            :         struct rhltable         mfc_hash;
     251                 :            :         struct list_head        mfc_cache_list;
     252                 :            :         int                     maxvif;
     253                 :            :         atomic_t                cache_resolve_queue_len;
     254                 :            :         bool                    mroute_do_assert;
     255                 :            :         bool                    mroute_do_pim;
     256                 :            :         bool                    mroute_do_wrvifwhole;
     257                 :            :         int                     mroute_reg_vif_num;
     258                 :            : };
     259                 :            : 
     260                 :            : #ifdef CONFIG_IP_MROUTE_COMMON
     261                 :            : void vif_device_init(struct vif_device *v,
     262                 :            :                      struct net_device *dev,
     263                 :            :                      unsigned long rate_limit,
     264                 :            :                      unsigned char threshold,
     265                 :            :                      unsigned short flags,
     266                 :            :                      unsigned short get_iflink_mask);
     267                 :            : 
     268                 :            : struct mr_table *
     269                 :            : mr_table_alloc(struct net *net, u32 id,
     270                 :            :                struct mr_table_ops *ops,
     271                 :            :                void (*expire_func)(struct timer_list *t),
     272                 :            :                void (*table_set)(struct mr_table *mrt,
     273                 :            :                                  struct net *net));
     274                 :            : 
     275                 :            : /* These actually return 'struct mr_mfc *', but to avoid need for explicit
     276                 :            :  * castings they simply return void.
     277                 :            :  */
     278                 :            : void *mr_mfc_find_parent(struct mr_table *mrt,
     279                 :            :                          void *hasharg, int parent);
     280                 :            : void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi);
     281                 :            : void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg);
     282                 :            : 
     283                 :            : int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
     284                 :            :                    struct mr_mfc *c, struct rtmsg *rtm);
     285                 :            : int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb,
     286                 :            :                   struct netlink_callback *cb,
     287                 :            :                   int (*fill)(struct mr_table *mrt, struct sk_buff *skb,
     288                 :            :                               u32 portid, u32 seq, struct mr_mfc *c,
     289                 :            :                               int cmd, int flags),
     290                 :            :                   spinlock_t *lock, struct fib_dump_filter *filter);
     291                 :            : int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
     292                 :            :                      struct mr_table *(*iter)(struct net *net,
     293                 :            :                                               struct mr_table *mrt),
     294                 :            :                      int (*fill)(struct mr_table *mrt,
     295                 :            :                                  struct sk_buff *skb,
     296                 :            :                                  u32 portid, u32 seq, struct mr_mfc *c,
     297                 :            :                                  int cmd, int flags),
     298                 :            :                      spinlock_t *lock, struct fib_dump_filter *filter);
     299                 :            : 
     300                 :            : int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family,
     301                 :            :             int (*rules_dump)(struct net *net,
     302                 :            :                               struct notifier_block *nb,
     303                 :            :                               struct netlink_ext_ack *extack),
     304                 :            :             struct mr_table *(*mr_iter)(struct net *net,
     305                 :            :                                         struct mr_table *mrt),
     306                 :            :             rwlock_t *mrt_lock, struct netlink_ext_ack *extack);
     307                 :            : #else
     308                 :            : static inline void vif_device_init(struct vif_device *v,
     309                 :            :                                    struct net_device *dev,
     310                 :            :                                    unsigned long rate_limit,
     311                 :            :                                    unsigned char threshold,
     312                 :            :                                    unsigned short flags,
     313                 :            :                                    unsigned short get_iflink_mask)
     314                 :            : {
     315                 :            : }
     316                 :            : 
     317                 :            : static inline void *mr_mfc_find_parent(struct mr_table *mrt,
     318                 :            :                                        void *hasharg, int parent)
     319                 :            : {
     320                 :            :         return NULL;
     321                 :            : }
     322                 :            : 
     323                 :            : static inline void *mr_mfc_find_any_parent(struct mr_table *mrt,
     324                 :            :                                            int vifi)
     325                 :            : {
     326                 :            :         return NULL;
     327                 :            : }
     328                 :            : 
     329                 :            : static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt,
     330                 :            :                                              int vifi, void *hasharg)
     331                 :            : {
     332                 :            :         return NULL;
     333                 :            : }
     334                 :            : 
     335                 :            : static inline int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
     336                 :            :                                  struct mr_mfc *c, struct rtmsg *rtm)
     337                 :            : {
     338                 :            :         return -EINVAL;
     339                 :            : }
     340                 :            : 
     341                 :            : static inline int
     342                 :            : mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
     343                 :            :                  struct mr_table *(*iter)(struct net *net,
     344                 :            :                                           struct mr_table *mrt),
     345                 :            :                  int (*fill)(struct mr_table *mrt,
     346                 :            :                              struct sk_buff *skb,
     347                 :            :                              u32 portid, u32 seq, struct mr_mfc *c,
     348                 :            :                              int cmd, int flags),
     349                 :            :                  spinlock_t *lock, struct fib_dump_filter *filter)
     350                 :            : {
     351                 :            :         return -EINVAL;
     352                 :            : }
     353                 :            : 
     354                 :            : static inline int mr_dump(struct net *net, struct notifier_block *nb,
     355                 :            :                           unsigned short family,
     356                 :            :                           int (*rules_dump)(struct net *net,
     357                 :            :                                             struct notifier_block *nb,
     358                 :            :                                             struct netlink_ext_ack *extack),
     359                 :            :                           struct mr_table *(*mr_iter)(struct net *net,
     360                 :            :                                                       struct mr_table *mrt),
     361                 :            :                           rwlock_t *mrt_lock, struct netlink_ext_ack *extack)
     362                 :            : {
     363                 :            :         return -EINVAL;
     364                 :            : }
     365                 :            : #endif
     366                 :            : 
     367                 :          0 : static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg)
     368                 :            : {
     369                 :          0 :         return mr_mfc_find_parent(mrt, hasharg, -1);
     370                 :            : }
     371                 :            : 
     372                 :            : #ifdef CONFIG_PROC_FS
     373                 :            : struct mr_vif_iter {
     374                 :            :         struct seq_net_private p;
     375                 :            :         struct mr_table *mrt;
     376                 :            :         int ct;
     377                 :            : };
     378                 :            : 
     379                 :            : struct mr_mfc_iter {
     380                 :            :         struct seq_net_private p;
     381                 :            :         struct mr_table *mrt;
     382                 :            :         struct list_head *cache;
     383                 :            : 
     384                 :            :         /* Lock protecting the mr_table's unresolved queue */
     385                 :            :         spinlock_t *lock;
     386                 :            : };
     387                 :            : 
     388                 :            : #ifdef CONFIG_IP_MROUTE_COMMON
     389                 :            : void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos);
     390                 :            : void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos);
     391                 :            : 
     392                 :          0 : static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
     393                 :            : {
     394                 :          0 :         return *pos ? mr_vif_seq_idx(seq_file_net(seq),
     395                 :          0 :                                      seq->private, *pos - 1)
     396         [ #  # ]:          0 :                     : SEQ_START_TOKEN;
     397                 :            : }
     398                 :            : 
     399                 :            : /* These actually return 'struct mr_mfc *', but to avoid need for explicit
     400                 :            :  * castings they simply return void.
     401                 :            :  */
     402                 :            : void *mr_mfc_seq_idx(struct net *net,
     403                 :            :                      struct mr_mfc_iter *it, loff_t pos);
     404                 :            : void *mr_mfc_seq_next(struct seq_file *seq, void *v,
     405                 :            :                       loff_t *pos);
     406                 :            : 
     407                 :            : static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
     408                 :            :                                      struct mr_table *mrt, spinlock_t *lock)
     409                 :            : {
     410                 :            :         struct mr_mfc_iter *it = seq->private;
     411                 :            : 
     412                 :            :         it->mrt = mrt;
     413                 :            :         it->cache = NULL;
     414                 :            :         it->lock = lock;
     415                 :            : 
     416                 :            :         return *pos ? mr_mfc_seq_idx(seq_file_net(seq),
     417                 :            :                                      seq->private, *pos - 1)
     418                 :            :                     : SEQ_START_TOKEN;
     419                 :            : }
     420                 :            : 
     421                 :          0 : static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
     422                 :            : {
     423                 :          0 :         struct mr_mfc_iter *it = seq->private;
     424                 :          0 :         struct mr_table *mrt = it->mrt;
     425                 :            : 
     426         [ #  # ]:          0 :         if (it->cache == &mrt->mfc_unres_queue)
     427                 :          0 :                 spin_unlock_bh(it->lock);
     428         [ #  # ]:          0 :         else if (it->cache == &mrt->mfc_cache_list)
     429                 :          0 :                 rcu_read_unlock();
     430                 :          0 : }
     431                 :            : #else
     432                 :            : static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter,
     433                 :            :                                    loff_t pos)
     434                 :            : {
     435                 :            :         return NULL;
     436                 :            : }
     437                 :            : 
     438                 :            : static inline void *mr_vif_seq_next(struct seq_file *seq,
     439                 :            :                                     void *v, loff_t *pos)
     440                 :            : {
     441                 :            :         return NULL;
     442                 :            : }
     443                 :            : 
     444                 :            : static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
     445                 :            : {
     446                 :            :         return NULL;
     447                 :            : }
     448                 :            : 
     449                 :            : static inline void *mr_mfc_seq_idx(struct net *net,
     450                 :            :                                    struct mr_mfc_iter *it, loff_t pos)
     451                 :            : {
     452                 :            :         return NULL;
     453                 :            : }
     454                 :            : 
     455                 :            : static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v,
     456                 :            :                                     loff_t *pos)
     457                 :            : {
     458                 :            :         return NULL;
     459                 :            : }
     460                 :            : 
     461                 :            : static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
     462                 :            :                                      struct mr_table *mrt, spinlock_t *lock)
     463                 :            : {
     464                 :            :         return NULL;
     465                 :            : }
     466                 :            : 
     467                 :            : static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
     468                 :            : {
     469                 :            : }
     470                 :            : #endif
     471                 :            : #endif
     472                 :            : #endif

Generated by: LCOV version 1.14