linux/include/linux/mroute_base.h
<<
>>
Prefs
   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 */
  27struct 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
  41struct 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
  49static 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        struct vif_entry_notifier_info info = {
  57                .info = {
  58                        .family = family,
  59                        .extack = extack,
  60                },
  61                .dev = vif->dev,
  62                .vif_index = vif_index,
  63                .vif_flags = vif->flags,
  64                .tb_id = tb_id,
  65        };
  66
  67        return call_fib_notifier(nb, event_type, &info.info);
  68}
  69
  70static 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        struct vif_entry_notifier_info info = {
  78                .info = {
  79                        .family = family,
  80                },
  81                .dev = vif->dev,
  82                .vif_index = vif_index,
  83                .vif_flags = vif->flags,
  84                .tb_id = tb_id,
  85        };
  86
  87        ASSERT_RTNL();
  88        (*ipmr_seq)++;
  89        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 */
 105enum {
 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 */
 130struct 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
 157static inline void mr_cache_put(struct mr_mfc *c)
 158{
 159        if (refcount_dec_and_test(&c->mfc_un.res.refcount))
 160                call_rcu(&c->rcu, c->free);
 161}
 162
 163static inline void mr_cache_hold(struct mr_mfc *c)
 164{
 165        refcount_inc(&c->mfc_un.res.refcount);
 166}
 167
 168struct mfc_entry_notifier_info {
 169        struct fib_notifier_info info;
 170        struct mr_mfc *mfc;
 171        u32 tb_id;
 172};
 173
 174static 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        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        return call_fib_notifier(nb, event_type, &info.info);
 190}
 191
 192static 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        struct mfc_entry_notifier_info info = {
 199                .info = {
 200                        .family = family,
 201                },
 202                .mfc = mfc,
 203                .tb_id = tb_id
 204        };
 205
 206        ASSERT_RTNL();
 207        (*ipmr_seq)++;
 208        return call_fib_notifiers(net, event_type, &info.info);
 209}
 210
 211struct 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 */
 218struct 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 */
 241struct 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
 261void 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
 268struct mr_table *
 269mr_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 */
 278void *mr_mfc_find_parent(struct mr_table *mrt,
 279                         void *hasharg, int parent);
 280void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi);
 281void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg);
 282
 283int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
 284                   struct mr_mfc *c, struct rtmsg *rtm);
 285int 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);
 291int 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
 300int 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
 308static 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
 317static inline void *mr_mfc_find_parent(struct mr_table *mrt,
 318                                       void *hasharg, int parent)
 319{
 320        return NULL;
 321}
 322
 323static inline void *mr_mfc_find_any_parent(struct mr_table *mrt,
 324                                           int vifi)
 325{
 326        return NULL;
 327}
 328
 329static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt,
 330                                             int vifi, void *hasharg)
 331{
 332        return NULL;
 333}
 334
 335static 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
 341static inline int
 342mr_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
 354static 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
 367static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg)
 368{
 369        return mr_mfc_find_parent(mrt, hasharg, -1);
 370}
 371
 372#ifdef CONFIG_PROC_FS
 373struct mr_vif_iter {
 374        struct seq_net_private p;
 375        struct mr_table *mrt;
 376        int ct;
 377};
 378
 379struct 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
 389void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos);
 390void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos);
 391
 392static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
 393{
 394        return *pos ? mr_vif_seq_idx(seq_file_net(seq),
 395                                     seq->private, *pos - 1)
 396                    : 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 */
 402void *mr_mfc_seq_idx(struct net *net,
 403                     struct mr_mfc_iter *it, loff_t pos);
 404void *mr_mfc_seq_next(struct seq_file *seq, void *v,
 405                      loff_t *pos);
 406
 407static 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
 421static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
 422{
 423        struct mr_mfc_iter *it = seq->private;
 424        struct mr_table *mrt = it->mrt;
 425
 426        if (it->cache == &mrt->mfc_unres_queue)
 427                spin_unlock_bh(it->lock);
 428        else if (it->cache == &mrt->mfc_cache_list)
 429                rcu_read_unlock();
 430}
 431#else
 432static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter,
 433                                   loff_t pos)
 434{
 435        return NULL;
 436}
 437
 438static inline void *mr_vif_seq_next(struct seq_file *seq,
 439                                    void *v, loff_t *pos)
 440{
 441        return NULL;
 442}
 443
 444static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
 445{
 446        return NULL;
 447}
 448
 449static inline void *mr_mfc_seq_idx(struct net *net,
 450                                   struct mr_mfc_iter *it, loff_t pos)
 451{
 452        return NULL;
 453}
 454
 455static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v,
 456                                    loff_t *pos)
 457{
 458        return NULL;
 459}
 460
 461static 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
 467static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
 468{
 469}
 470#endif
 471#endif
 472#endif
 473