Back to home page

OSCL-LXR

 
 

    


0001 #ifndef __LINUX_MROUTE_BASE_H
0002 #define __LINUX_MROUTE_BASE_H
0003 
0004 #include <linux/netdevice.h>
0005 #include <linux/rhashtable-types.h>
0006 #include <linux/spinlock.h>
0007 #include <net/net_namespace.h>
0008 #include <net/sock.h>
0009 #include <net/fib_notifier.h>
0010 #include <net/ip_fib.h>
0011 
0012 /**
0013  * struct vif_device - interface representor for multicast routing
0014  * @dev: network device being used
0015  * @dev_tracker: refcount tracker for @dev reference
0016  * @bytes_in: statistic; bytes ingressing
0017  * @bytes_out: statistic; bytes egresing
0018  * @pkt_in: statistic; packets ingressing
0019  * @pkt_out: statistic; packets egressing
0020  * @rate_limit: Traffic shaping (NI)
0021  * @threshold: TTL threshold
0022  * @flags: Control flags
0023  * @link: Physical interface index
0024  * @dev_parent_id: device parent id
0025  * @local: Local address
0026  * @remote: Remote address for tunnels
0027  */
0028 struct vif_device {
0029     struct net_device __rcu *dev;
0030     netdevice_tracker dev_tracker;
0031     unsigned long bytes_in, bytes_out;
0032     unsigned long pkt_in, pkt_out;
0033     unsigned long rate_limit;
0034     unsigned char threshold;
0035     unsigned short flags;
0036     int link;
0037 
0038     /* Currently only used by ipmr */
0039     struct netdev_phys_item_id dev_parent_id;
0040     __be32 local, remote;
0041 };
0042 
0043 struct vif_entry_notifier_info {
0044     struct fib_notifier_info info;
0045     struct net_device *dev;
0046     unsigned short vif_index;
0047     unsigned short vif_flags;
0048     u32 tb_id;
0049 };
0050 
0051 static inline int mr_call_vif_notifier(struct notifier_block *nb,
0052                        unsigned short family,
0053                        enum fib_event_type event_type,
0054                        struct vif_device *vif,
0055                        struct net_device *vif_dev,
0056                        unsigned short vif_index, u32 tb_id,
0057                        struct netlink_ext_ack *extack)
0058 {
0059     struct vif_entry_notifier_info info = {
0060         .info = {
0061             .family = family,
0062             .extack = extack,
0063         },
0064         .dev = vif_dev,
0065         .vif_index = vif_index,
0066         .vif_flags = vif->flags,
0067         .tb_id = tb_id,
0068     };
0069 
0070     return call_fib_notifier(nb, event_type, &info.info);
0071 }
0072 
0073 static inline int mr_call_vif_notifiers(struct net *net,
0074                     unsigned short family,
0075                     enum fib_event_type event_type,
0076                     struct vif_device *vif,
0077                     struct net_device *vif_dev,
0078                     unsigned short vif_index, u32 tb_id,
0079                     unsigned int *ipmr_seq)
0080 {
0081     struct vif_entry_notifier_info info = {
0082         .info = {
0083             .family = family,
0084         },
0085         .dev = vif_dev,
0086         .vif_index = vif_index,
0087         .vif_flags = vif->flags,
0088         .tb_id = tb_id,
0089     };
0090 
0091     ASSERT_RTNL();
0092     (*ipmr_seq)++;
0093     return call_fib_notifiers(net, event_type, &info.info);
0094 }
0095 
0096 #ifndef MAXVIFS
0097 /* This one is nasty; value is defined in uapi using different symbols for
0098  * mroute and morute6 but both map into same 32.
0099  */
0100 #define MAXVIFS 32
0101 #endif
0102 
0103 /* Note: This helper is deprecated. */
0104 #define VIF_EXISTS(_mrt, _idx) (!!rcu_access_pointer((_mrt)->vif_table[_idx].dev))
0105 
0106 /* mfc_flags:
0107  * MFC_STATIC - the entry was added statically (not by a routing daemon)
0108  * MFC_OFFLOAD - the entry was offloaded to the hardware
0109  */
0110 enum {
0111     MFC_STATIC = BIT(0),
0112     MFC_OFFLOAD = BIT(1),
0113 };
0114 
0115 /**
0116  * struct mr_mfc - common multicast routing entries
0117  * @mnode: rhashtable list
0118  * @mfc_parent: source interface (iif)
0119  * @mfc_flags: entry flags
0120  * @expires: unresolved entry expire time
0121  * @unresolved: unresolved cached skbs
0122  * @last_assert: time of last assert
0123  * @minvif: minimum VIF id
0124  * @maxvif: maximum VIF id
0125  * @bytes: bytes that have passed for this entry
0126  * @pkt: packets that have passed for this entry
0127  * @wrong_if: number of wrong source interface hits
0128  * @lastuse: time of last use of the group (traffic or update)
0129  * @ttls: OIF TTL threshold array
0130  * @refcount: reference count for this entry
0131  * @list: global entry list
0132  * @rcu: used for entry destruction
0133  * @free: Operation used for freeing an entry under RCU
0134  */
0135 struct mr_mfc {
0136     struct rhlist_head mnode;
0137     unsigned short mfc_parent;
0138     int mfc_flags;
0139 
0140     union {
0141         struct {
0142             unsigned long expires;
0143             struct sk_buff_head unresolved;
0144         } unres;
0145         struct {
0146             unsigned long last_assert;
0147             int minvif;
0148             int maxvif;
0149             unsigned long bytes;
0150             unsigned long pkt;
0151             unsigned long wrong_if;
0152             unsigned long lastuse;
0153             unsigned char ttls[MAXVIFS];
0154             refcount_t refcount;
0155         } res;
0156     } mfc_un;
0157     struct list_head list;
0158     struct rcu_head rcu;
0159     void (*free)(struct rcu_head *head);
0160 };
0161 
0162 static inline void mr_cache_put(struct mr_mfc *c)
0163 {
0164     if (refcount_dec_and_test(&c->mfc_un.res.refcount))
0165         call_rcu(&c->rcu, c->free);
0166 }
0167 
0168 static inline void mr_cache_hold(struct mr_mfc *c)
0169 {
0170     refcount_inc(&c->mfc_un.res.refcount);
0171 }
0172 
0173 struct mfc_entry_notifier_info {
0174     struct fib_notifier_info info;
0175     struct mr_mfc *mfc;
0176     u32 tb_id;
0177 };
0178 
0179 static inline int mr_call_mfc_notifier(struct notifier_block *nb,
0180                        unsigned short family,
0181                        enum fib_event_type event_type,
0182                        struct mr_mfc *mfc, u32 tb_id,
0183                        struct netlink_ext_ack *extack)
0184 {
0185     struct mfc_entry_notifier_info info = {
0186         .info = {
0187             .family = family,
0188             .extack = extack,
0189         },
0190         .mfc = mfc,
0191         .tb_id = tb_id
0192     };
0193 
0194     return call_fib_notifier(nb, event_type, &info.info);
0195 }
0196 
0197 static inline int mr_call_mfc_notifiers(struct net *net,
0198                     unsigned short family,
0199                     enum fib_event_type event_type,
0200                     struct mr_mfc *mfc, u32 tb_id,
0201                     unsigned int *ipmr_seq)
0202 {
0203     struct mfc_entry_notifier_info info = {
0204         .info = {
0205             .family = family,
0206         },
0207         .mfc = mfc,
0208         .tb_id = tb_id
0209     };
0210 
0211     ASSERT_RTNL();
0212     (*ipmr_seq)++;
0213     return call_fib_notifiers(net, event_type, &info.info);
0214 }
0215 
0216 struct mr_table;
0217 
0218 /**
0219  * struct mr_table_ops - callbacks and info for protocol-specific ops
0220  * @rht_params: parameters for accessing the MFC hash
0221  * @cmparg_any: a hash key to be used for matching on (*,*) routes
0222  */
0223 struct mr_table_ops {
0224     const struct rhashtable_params *rht_params;
0225     void *cmparg_any;
0226 };
0227 
0228 /**
0229  * struct mr_table - a multicast routing table
0230  * @list: entry within a list of multicast routing tables
0231  * @net: net where this table belongs
0232  * @ops: protocol specific operations
0233  * @id: identifier of the table
0234  * @mroute_sk: socket associated with the table
0235  * @ipmr_expire_timer: timer for handling unresolved routes
0236  * @mfc_unres_queue: list of unresolved MFC entries
0237  * @vif_table: array containing all possible vifs
0238  * @mfc_hash: Hash table of all resolved routes for easy lookup
0239  * @mfc_cache_list: list of resovled routes for possible traversal
0240  * @maxvif: Identifier of highest value vif currently in use
0241  * @cache_resolve_queue_len: current size of unresolved queue
0242  * @mroute_do_assert: Whether to inform userspace on wrong ingress
0243  * @mroute_do_pim: Whether to receive IGMP PIMv1
0244  * @mroute_reg_vif_num: PIM-device vif index
0245  */
0246 struct mr_table {
0247     struct list_head    list;
0248     possible_net_t      net;
0249     struct mr_table_ops ops;
0250     u32         id;
0251     struct sock __rcu   *mroute_sk;
0252     struct timer_list   ipmr_expire_timer;
0253     struct list_head    mfc_unres_queue;
0254     struct vif_device   vif_table[MAXVIFS];
0255     struct rhltable     mfc_hash;
0256     struct list_head    mfc_cache_list;
0257     int         maxvif;
0258     atomic_t        cache_resolve_queue_len;
0259     bool            mroute_do_assert;
0260     bool            mroute_do_pim;
0261     bool            mroute_do_wrvifwhole;
0262     int         mroute_reg_vif_num;
0263 };
0264 
0265 #ifdef CONFIG_IP_MROUTE_COMMON
0266 void vif_device_init(struct vif_device *v,
0267              struct net_device *dev,
0268              unsigned long rate_limit,
0269              unsigned char threshold,
0270              unsigned short flags,
0271              unsigned short get_iflink_mask);
0272 
0273 struct mr_table *
0274 mr_table_alloc(struct net *net, u32 id,
0275            struct mr_table_ops *ops,
0276            void (*expire_func)(struct timer_list *t),
0277            void (*table_set)(struct mr_table *mrt,
0278                  struct net *net));
0279 
0280 /* These actually return 'struct mr_mfc *', but to avoid need for explicit
0281  * castings they simply return void.
0282  */
0283 void *mr_mfc_find_parent(struct mr_table *mrt,
0284              void *hasharg, int parent);
0285 void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi);
0286 void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg);
0287 
0288 int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
0289            struct mr_mfc *c, struct rtmsg *rtm);
0290 int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb,
0291           struct netlink_callback *cb,
0292           int (*fill)(struct mr_table *mrt, struct sk_buff *skb,
0293                   u32 portid, u32 seq, struct mr_mfc *c,
0294                   int cmd, int flags),
0295           spinlock_t *lock, struct fib_dump_filter *filter);
0296 int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
0297              struct mr_table *(*iter)(struct net *net,
0298                           struct mr_table *mrt),
0299              int (*fill)(struct mr_table *mrt,
0300                  struct sk_buff *skb,
0301                  u32 portid, u32 seq, struct mr_mfc *c,
0302                  int cmd, int flags),
0303              spinlock_t *lock, struct fib_dump_filter *filter);
0304 
0305 int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family,
0306         int (*rules_dump)(struct net *net,
0307                   struct notifier_block *nb,
0308                   struct netlink_ext_ack *extack),
0309         struct mr_table *(*mr_iter)(struct net *net,
0310                     struct mr_table *mrt),
0311         struct netlink_ext_ack *extack);
0312 #else
0313 static inline void vif_device_init(struct vif_device *v,
0314                    struct net_device *dev,
0315                    unsigned long rate_limit,
0316                    unsigned char threshold,
0317                    unsigned short flags,
0318                    unsigned short get_iflink_mask)
0319 {
0320 }
0321 
0322 static inline void *mr_mfc_find_parent(struct mr_table *mrt,
0323                        void *hasharg, int parent)
0324 {
0325     return NULL;
0326 }
0327 
0328 static inline void *mr_mfc_find_any_parent(struct mr_table *mrt,
0329                        int vifi)
0330 {
0331     return NULL;
0332 }
0333 
0334 static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt,
0335                          int vifi, void *hasharg)
0336 {
0337     return NULL;
0338 }
0339 
0340 static inline int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
0341                  struct mr_mfc *c, struct rtmsg *rtm)
0342 {
0343     return -EINVAL;
0344 }
0345 
0346 static inline int
0347 mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
0348          struct mr_table *(*iter)(struct net *net,
0349                       struct mr_table *mrt),
0350          int (*fill)(struct mr_table *mrt,
0351                  struct sk_buff *skb,
0352                  u32 portid, u32 seq, struct mr_mfc *c,
0353                  int cmd, int flags),
0354          spinlock_t *lock, struct fib_dump_filter *filter)
0355 {
0356     return -EINVAL;
0357 }
0358 
0359 static inline int mr_dump(struct net *net, struct notifier_block *nb,
0360               unsigned short family,
0361               int (*rules_dump)(struct net *net,
0362                         struct notifier_block *nb,
0363                         struct netlink_ext_ack *extack),
0364               struct mr_table *(*mr_iter)(struct net *net,
0365                               struct mr_table *mrt),
0366               struct netlink_ext_ack *extack)
0367 {
0368     return -EINVAL;
0369 }
0370 #endif
0371 
0372 static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg)
0373 {
0374     return mr_mfc_find_parent(mrt, hasharg, -1);
0375 }
0376 
0377 #ifdef CONFIG_PROC_FS
0378 struct mr_vif_iter {
0379     struct seq_net_private p;
0380     struct mr_table *mrt;
0381     int ct;
0382 };
0383 
0384 struct mr_mfc_iter {
0385     struct seq_net_private p;
0386     struct mr_table *mrt;
0387     struct list_head *cache;
0388 
0389     /* Lock protecting the mr_table's unresolved queue */
0390     spinlock_t *lock;
0391 };
0392 
0393 #ifdef CONFIG_IP_MROUTE_COMMON
0394 void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos);
0395 void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos);
0396 
0397 static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
0398 {
0399     return *pos ? mr_vif_seq_idx(seq_file_net(seq),
0400                      seq->private, *pos - 1)
0401             : SEQ_START_TOKEN;
0402 }
0403 
0404 /* These actually return 'struct mr_mfc *', but to avoid need for explicit
0405  * castings they simply return void.
0406  */
0407 void *mr_mfc_seq_idx(struct net *net,
0408              struct mr_mfc_iter *it, loff_t pos);
0409 void *mr_mfc_seq_next(struct seq_file *seq, void *v,
0410               loff_t *pos);
0411 
0412 static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
0413                      struct mr_table *mrt, spinlock_t *lock)
0414 {
0415     struct mr_mfc_iter *it = seq->private;
0416 
0417     it->mrt = mrt;
0418     it->cache = NULL;
0419     it->lock = lock;
0420 
0421     return *pos ? mr_mfc_seq_idx(seq_file_net(seq),
0422                      seq->private, *pos - 1)
0423             : SEQ_START_TOKEN;
0424 }
0425 
0426 static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
0427 {
0428     struct mr_mfc_iter *it = seq->private;
0429     struct mr_table *mrt = it->mrt;
0430 
0431     if (it->cache == &mrt->mfc_unres_queue)
0432         spin_unlock_bh(it->lock);
0433     else if (it->cache == &mrt->mfc_cache_list)
0434         rcu_read_unlock();
0435 }
0436 #else
0437 static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter,
0438                    loff_t pos)
0439 {
0440     return NULL;
0441 }
0442 
0443 static inline void *mr_vif_seq_next(struct seq_file *seq,
0444                     void *v, loff_t *pos)
0445 {
0446     return NULL;
0447 }
0448 
0449 static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
0450 {
0451     return NULL;
0452 }
0453 
0454 static inline void *mr_mfc_seq_idx(struct net *net,
0455                    struct mr_mfc_iter *it, loff_t pos)
0456 {
0457     return NULL;
0458 }
0459 
0460 static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v,
0461                     loff_t *pos)
0462 {
0463     return NULL;
0464 }
0465 
0466 static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
0467                      struct mr_table *mrt, spinlock_t *lock)
0468 {
0469     return NULL;
0470 }
0471 
0472 static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
0473 {
0474 }
0475 #endif
0476 #endif
0477 #endif