16853f21fSYuval Mintz #ifndef __LINUX_MROUTE_BASE_H 26853f21fSYuval Mintz #define __LINUX_MROUTE_BASE_H 36853f21fSYuval Mintz 46853f21fSYuval Mintz #include <linux/netdevice.h> 5b70432f7SYuval Mintz #include <linux/rhashtable.h> 6c8d61968SYuval Mintz #include <linux/spinlock.h> 7b70432f7SYuval Mintz #include <net/net_namespace.h> 8b70432f7SYuval Mintz #include <net/sock.h> 96853f21fSYuval Mintz 106853f21fSYuval Mintz /** 116853f21fSYuval Mintz * struct vif_device - interface representor for multicast routing 126853f21fSYuval Mintz * @dev: network device being used 136853f21fSYuval Mintz * @bytes_in: statistic; bytes ingressing 146853f21fSYuval Mintz * @bytes_out: statistic; bytes egresing 156853f21fSYuval Mintz * @pkt_in: statistic; packets ingressing 166853f21fSYuval Mintz * @pkt_out: statistic; packets egressing 176853f21fSYuval Mintz * @rate_limit: Traffic shaping (NI) 186853f21fSYuval Mintz * @threshold: TTL threshold 196853f21fSYuval Mintz * @flags: Control flags 206853f21fSYuval Mintz * @link: Physical interface index 216853f21fSYuval Mintz * @dev_parent_id: device parent id 226853f21fSYuval Mintz * @local: Local address 236853f21fSYuval Mintz * @remote: Remote address for tunnels 246853f21fSYuval Mintz */ 256853f21fSYuval Mintz struct vif_device { 266853f21fSYuval Mintz struct net_device *dev; 276853f21fSYuval Mintz unsigned long bytes_in, bytes_out; 286853f21fSYuval Mintz unsigned long pkt_in, pkt_out; 296853f21fSYuval Mintz unsigned long rate_limit; 306853f21fSYuval Mintz unsigned char threshold; 316853f21fSYuval Mintz unsigned short flags; 326853f21fSYuval Mintz int link; 336853f21fSYuval Mintz 346853f21fSYuval Mintz /* Currently only used by ipmr */ 356853f21fSYuval Mintz struct netdev_phys_item_id dev_parent_id; 366853f21fSYuval Mintz __be32 local, remote; 376853f21fSYuval Mintz }; 386853f21fSYuval Mintz 39b70432f7SYuval Mintz #ifndef MAXVIFS 40b70432f7SYuval Mintz /* This one is nasty; value is defined in uapi using different symbols for 41b70432f7SYuval Mintz * mroute and morute6 but both map into same 32. 42b70432f7SYuval Mintz */ 43b70432f7SYuval Mintz #define MAXVIFS 32 44b70432f7SYuval Mintz #endif 45b70432f7SYuval Mintz 46b70432f7SYuval Mintz #define VIF_EXISTS(_mrt, _idx) (!!((_mrt)->vif_table[_idx].dev)) 47b70432f7SYuval Mintz 48b70432f7SYuval Mintz /** 49494fff56SYuval Mintz * struct mr_mfc - common multicast routing entries 50494fff56SYuval Mintz * @mnode: rhashtable list 51494fff56SYuval Mintz * @mfc_parent: source interface (iif) 52494fff56SYuval Mintz * @mfc_flags: entry flags 53494fff56SYuval Mintz * @expires: unresolved entry expire time 54494fff56SYuval Mintz * @unresolved: unresolved cached skbs 55494fff56SYuval Mintz * @last_assert: time of last assert 56494fff56SYuval Mintz * @minvif: minimum VIF id 57494fff56SYuval Mintz * @maxvif: maximum VIF id 58494fff56SYuval Mintz * @bytes: bytes that have passed for this entry 59494fff56SYuval Mintz * @pkt: packets that have passed for this entry 60494fff56SYuval Mintz * @wrong_if: number of wrong source interface hits 61494fff56SYuval Mintz * @lastuse: time of last use of the group (traffic or update) 62494fff56SYuval Mintz * @ttls: OIF TTL threshold array 63494fff56SYuval Mintz * @refcount: reference count for this entry 64494fff56SYuval Mintz * @list: global entry list 65494fff56SYuval Mintz * @rcu: used for entry destruction 66494fff56SYuval Mintz */ 67494fff56SYuval Mintz struct mr_mfc { 68494fff56SYuval Mintz struct rhlist_head mnode; 69494fff56SYuval Mintz unsigned short mfc_parent; 70494fff56SYuval Mintz int mfc_flags; 71494fff56SYuval Mintz 72494fff56SYuval Mintz union { 73494fff56SYuval Mintz struct { 74494fff56SYuval Mintz unsigned long expires; 75494fff56SYuval Mintz struct sk_buff_head unresolved; 76494fff56SYuval Mintz } unres; 77494fff56SYuval Mintz struct { 78494fff56SYuval Mintz unsigned long last_assert; 79494fff56SYuval Mintz int minvif; 80494fff56SYuval Mintz int maxvif; 81494fff56SYuval Mintz unsigned long bytes; 82494fff56SYuval Mintz unsigned long pkt; 83494fff56SYuval Mintz unsigned long wrong_if; 84494fff56SYuval Mintz unsigned long lastuse; 85494fff56SYuval Mintz unsigned char ttls[MAXVIFS]; 86494fff56SYuval Mintz refcount_t refcount; 87494fff56SYuval Mintz } res; 88494fff56SYuval Mintz } mfc_un; 89494fff56SYuval Mintz struct list_head list; 90494fff56SYuval Mintz struct rcu_head rcu; 91494fff56SYuval Mintz }; 92494fff56SYuval Mintz 93845c9a7aSYuval Mintz struct mr_table; 94845c9a7aSYuval Mintz 95845c9a7aSYuval Mintz /** 96845c9a7aSYuval Mintz * struct mr_table_ops - callbacks and info for protocol-specific ops 97845c9a7aSYuval Mintz * @rht_params: parameters for accessing the MFC hash 98845c9a7aSYuval Mintz * @cmparg_any: a hash key to be used for matching on (*,*) routes 99845c9a7aSYuval Mintz */ 100845c9a7aSYuval Mintz struct mr_table_ops { 101845c9a7aSYuval Mintz const struct rhashtable_params *rht_params; 102845c9a7aSYuval Mintz void *cmparg_any; 103845c9a7aSYuval Mintz }; 104845c9a7aSYuval Mintz 105494fff56SYuval Mintz /** 106b70432f7SYuval Mintz * struct mr_table - a multicast routing table 107b70432f7SYuval Mintz * @list: entry within a list of multicast routing tables 108b70432f7SYuval Mintz * @net: net where this table belongs 109845c9a7aSYuval Mintz * @ops: protocol specific operations 110b70432f7SYuval Mintz * @id: identifier of the table 111b70432f7SYuval Mintz * @mroute_sk: socket associated with the table 112b70432f7SYuval Mintz * @ipmr_expire_timer: timer for handling unresolved routes 113b70432f7SYuval Mintz * @mfc_unres_queue: list of unresolved MFC entries 114b70432f7SYuval Mintz * @vif_table: array containing all possible vifs 115b70432f7SYuval Mintz * @mfc_hash: Hash table of all resolved routes for easy lookup 116b70432f7SYuval Mintz * @mfc_cache_list: list of resovled routes for possible traversal 117b70432f7SYuval Mintz * @maxvif: Identifier of highest value vif currently in use 118b70432f7SYuval Mintz * @cache_resolve_queue_len: current size of unresolved queue 119b70432f7SYuval Mintz * @mroute_do_assert: Whether to inform userspace on wrong ingress 120b70432f7SYuval Mintz * @mroute_do_pim: Whether to receive IGMP PIMv1 121b70432f7SYuval Mintz * @mroute_reg_vif_num: PIM-device vif index 122b70432f7SYuval Mintz */ 123b70432f7SYuval Mintz struct mr_table { 124b70432f7SYuval Mintz struct list_head list; 125b70432f7SYuval Mintz possible_net_t net; 126845c9a7aSYuval Mintz struct mr_table_ops ops; 127b70432f7SYuval Mintz u32 id; 128b70432f7SYuval Mintz struct sock __rcu *mroute_sk; 129b70432f7SYuval Mintz struct timer_list ipmr_expire_timer; 130b70432f7SYuval Mintz struct list_head mfc_unres_queue; 131b70432f7SYuval Mintz struct vif_device vif_table[MAXVIFS]; 132b70432f7SYuval Mintz struct rhltable mfc_hash; 133b70432f7SYuval Mintz struct list_head mfc_cache_list; 134b70432f7SYuval Mintz int maxvif; 135b70432f7SYuval Mintz atomic_t cache_resolve_queue_len; 136b70432f7SYuval Mintz bool mroute_do_assert; 137b70432f7SYuval Mintz bool mroute_do_pim; 138b70432f7SYuval Mintz int mroute_reg_vif_num; 139b70432f7SYuval Mintz }; 140b70432f7SYuval Mintz 1416853f21fSYuval Mintz #ifdef CONFIG_IP_MROUTE_COMMON 1426853f21fSYuval Mintz void vif_device_init(struct vif_device *v, 1436853f21fSYuval Mintz struct net_device *dev, 1446853f21fSYuval Mintz unsigned long rate_limit, 1456853f21fSYuval Mintz unsigned char threshold, 1466853f21fSYuval Mintz unsigned short flags, 1476853f21fSYuval Mintz unsigned short get_iflink_mask); 1480bbbf0e7SYuval Mintz 1490bbbf0e7SYuval Mintz struct mr_table * 1500bbbf0e7SYuval Mintz mr_table_alloc(struct net *net, u32 id, 151845c9a7aSYuval Mintz struct mr_table_ops *ops, 1520bbbf0e7SYuval Mintz void (*expire_func)(struct timer_list *t), 1530bbbf0e7SYuval Mintz void (*table_set)(struct mr_table *mrt, 1540bbbf0e7SYuval Mintz struct net *net)); 155845c9a7aSYuval Mintz 156845c9a7aSYuval Mintz /* These actually return 'struct mr_mfc *', but to avoid need for explicit 157845c9a7aSYuval Mintz * castings they simply return void. 158845c9a7aSYuval Mintz */ 159845c9a7aSYuval Mintz void *mr_mfc_find_parent(struct mr_table *mrt, 160845c9a7aSYuval Mintz void *hasharg, int parent); 161845c9a7aSYuval Mintz void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi); 162845c9a7aSYuval Mintz void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg); 163845c9a7aSYuval Mintz 1646853f21fSYuval Mintz #else 1656853f21fSYuval Mintz static inline void vif_device_init(struct vif_device *v, 1666853f21fSYuval Mintz struct net_device *dev, 1676853f21fSYuval Mintz unsigned long rate_limit, 1686853f21fSYuval Mintz unsigned char threshold, 1696853f21fSYuval Mintz unsigned short flags, 1706853f21fSYuval Mintz unsigned short get_iflink_mask) 1716853f21fSYuval Mintz { 1726853f21fSYuval Mintz } 1730bbbf0e7SYuval Mintz 174845c9a7aSYuval Mintz static inline void * 1750bbbf0e7SYuval Mintz mr_table_alloc(struct net *net, u32 id, 176845c9a7aSYuval Mintz struct mr_table_ops *ops, 1770bbbf0e7SYuval Mintz void (*expire_func)(struct timer_list *t), 1780bbbf0e7SYuval Mintz void (*table_set)(struct mr_table *mrt, 1790bbbf0e7SYuval Mintz struct net *net)) 1800bbbf0e7SYuval Mintz { 1810bbbf0e7SYuval Mintz return NULL; 1820bbbf0e7SYuval Mintz } 183845c9a7aSYuval Mintz 184845c9a7aSYuval Mintz static inline void *mr_mfc_find_parent(struct mr_table *mrt, 185845c9a7aSYuval Mintz void *hasharg, int parent) 186845c9a7aSYuval Mintz { 187845c9a7aSYuval Mintz return NULL; 188845c9a7aSYuval Mintz } 189845c9a7aSYuval Mintz 190845c9a7aSYuval Mintz static inline void *mr_mfc_find_any_parent(struct mr_table *mrt, 191845c9a7aSYuval Mintz int vifi) 192845c9a7aSYuval Mintz { 193845c9a7aSYuval Mintz return NULL; 194845c9a7aSYuval Mintz } 195845c9a7aSYuval Mintz 196845c9a7aSYuval Mintz static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt, 197845c9a7aSYuval Mintz int vifi, void *hasharg) 198845c9a7aSYuval Mintz { 199845c9a7aSYuval Mintz return NULL; 200845c9a7aSYuval Mintz } 2016853f21fSYuval Mintz #endif 202845c9a7aSYuval Mintz 203845c9a7aSYuval Mintz static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg) 204845c9a7aSYuval Mintz { 205845c9a7aSYuval Mintz return mr_mfc_find_parent(mrt, hasharg, -1); 206845c9a7aSYuval Mintz } 207c8d61968SYuval Mintz 208c8d61968SYuval Mintz #ifdef CONFIG_PROC_FS 209*3feda6b4SYuval Mintz struct mr_vif_iter { 210*3feda6b4SYuval Mintz struct seq_net_private p; 211*3feda6b4SYuval Mintz struct mr_table *mrt; 212*3feda6b4SYuval Mintz int ct; 213*3feda6b4SYuval Mintz }; 214*3feda6b4SYuval Mintz 215c8d61968SYuval Mintz struct mr_mfc_iter { 216c8d61968SYuval Mintz struct seq_net_private p; 217c8d61968SYuval Mintz struct mr_table *mrt; 218c8d61968SYuval Mintz struct list_head *cache; 219c8d61968SYuval Mintz 220c8d61968SYuval Mintz /* Lock protecting the mr_table's unresolved queue */ 221c8d61968SYuval Mintz spinlock_t *lock; 222c8d61968SYuval Mintz }; 223c8d61968SYuval Mintz 224c8d61968SYuval Mintz #ifdef CONFIG_IP_MROUTE_COMMON 225*3feda6b4SYuval Mintz void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos); 226*3feda6b4SYuval Mintz void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos); 227*3feda6b4SYuval Mintz 228*3feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 229*3feda6b4SYuval Mintz { 230*3feda6b4SYuval Mintz return *pos ? mr_vif_seq_idx(seq_file_net(seq), 231*3feda6b4SYuval Mintz seq->private, *pos - 1) 232*3feda6b4SYuval Mintz : SEQ_START_TOKEN; 233*3feda6b4SYuval Mintz } 234*3feda6b4SYuval Mintz 235c8d61968SYuval Mintz /* These actually return 'struct mr_mfc *', but to avoid need for explicit 236c8d61968SYuval Mintz * castings they simply return void. 237c8d61968SYuval Mintz */ 238c8d61968SYuval Mintz void *mr_mfc_seq_idx(struct net *net, 239c8d61968SYuval Mintz struct mr_mfc_iter *it, loff_t pos); 240c8d61968SYuval Mintz void *mr_mfc_seq_next(struct seq_file *seq, void *v, 241c8d61968SYuval Mintz loff_t *pos); 242c8d61968SYuval Mintz 243c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos, 244c8d61968SYuval Mintz struct mr_table *mrt, spinlock_t *lock) 245c8d61968SYuval Mintz { 246c8d61968SYuval Mintz struct mr_mfc_iter *it = seq->private; 247c8d61968SYuval Mintz 248c8d61968SYuval Mintz it->mrt = mrt; 249c8d61968SYuval Mintz it->cache = NULL; 250c8d61968SYuval Mintz it->lock = lock; 251c8d61968SYuval Mintz 252c8d61968SYuval Mintz return *pos ? mr_mfc_seq_idx(seq_file_net(seq), 253c8d61968SYuval Mintz seq->private, *pos - 1) 254c8d61968SYuval Mintz : SEQ_START_TOKEN; 255c8d61968SYuval Mintz } 256c8d61968SYuval Mintz 257c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v) 258c8d61968SYuval Mintz { 259c8d61968SYuval Mintz struct mr_mfc_iter *it = seq->private; 260c8d61968SYuval Mintz struct mr_table *mrt = it->mrt; 261c8d61968SYuval Mintz 262c8d61968SYuval Mintz if (it->cache == &mrt->mfc_unres_queue) 263c8d61968SYuval Mintz spin_unlock_bh(it->lock); 264c8d61968SYuval Mintz else if (it->cache == &mrt->mfc_cache_list) 265c8d61968SYuval Mintz rcu_read_unlock(); 266c8d61968SYuval Mintz } 267c8d61968SYuval Mintz #else 268*3feda6b4SYuval Mintz static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, 269*3feda6b4SYuval Mintz loff_t pos) 270*3feda6b4SYuval Mintz { 271*3feda6b4SYuval Mintz return NULL; 272*3feda6b4SYuval Mintz } 273*3feda6b4SYuval Mintz 274*3feda6b4SYuval Mintz static inline void *mr_vif_seq_next(struct seq_file *seq, 275*3feda6b4SYuval Mintz void *v, loff_t *pos) 276*3feda6b4SYuval Mintz { 277*3feda6b4SYuval Mintz return NULL; 278*3feda6b4SYuval Mintz } 279*3feda6b4SYuval Mintz 280*3feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 281*3feda6b4SYuval Mintz { 282*3feda6b4SYuval Mintz return NULL; 283*3feda6b4SYuval Mintz } 284*3feda6b4SYuval Mintz 285c8d61968SYuval Mintz static inline void *mr_mfc_seq_idx(struct net *net, 286c8d61968SYuval Mintz struct mr_mfc_iter *it, loff_t pos) 287c8d61968SYuval Mintz { 288c8d61968SYuval Mintz return NULL; 289c8d61968SYuval Mintz } 290c8d61968SYuval Mintz 291c8d61968SYuval Mintz static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v, 292c8d61968SYuval Mintz loff_t *pos) 293c8d61968SYuval Mintz { 294c8d61968SYuval Mintz return NULL; 295c8d61968SYuval Mintz } 296c8d61968SYuval Mintz 297c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos, 298c8d61968SYuval Mintz struct mr_table *mrt, spinlock_t *lock) 299c8d61968SYuval Mintz { 300c8d61968SYuval Mintz return NULL; 301c8d61968SYuval Mintz } 302c8d61968SYuval Mintz 303c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v) 304c8d61968SYuval Mintz { 305c8d61968SYuval Mintz } 306c8d61968SYuval Mintz #endif 307c8d61968SYuval Mintz #endif 3086853f21fSYuval Mintz #endif 309