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 48*889cd83cSYuval Mintz /* mfc_flags: 49*889cd83cSYuval Mintz * MFC_STATIC - the entry was added statically (not by a routing daemon) 50*889cd83cSYuval Mintz * MFC_OFFLOAD - the entry was offloaded to the hardware 51*889cd83cSYuval Mintz */ 52*889cd83cSYuval Mintz enum { 53*889cd83cSYuval Mintz MFC_STATIC = BIT(0), 54*889cd83cSYuval Mintz MFC_OFFLOAD = BIT(1), 55*889cd83cSYuval Mintz }; 56*889cd83cSYuval Mintz 57b70432f7SYuval Mintz /** 58494fff56SYuval Mintz * struct mr_mfc - common multicast routing entries 59494fff56SYuval Mintz * @mnode: rhashtable list 60494fff56SYuval Mintz * @mfc_parent: source interface (iif) 61494fff56SYuval Mintz * @mfc_flags: entry flags 62494fff56SYuval Mintz * @expires: unresolved entry expire time 63494fff56SYuval Mintz * @unresolved: unresolved cached skbs 64494fff56SYuval Mintz * @last_assert: time of last assert 65494fff56SYuval Mintz * @minvif: minimum VIF id 66494fff56SYuval Mintz * @maxvif: maximum VIF id 67494fff56SYuval Mintz * @bytes: bytes that have passed for this entry 68494fff56SYuval Mintz * @pkt: packets that have passed for this entry 69494fff56SYuval Mintz * @wrong_if: number of wrong source interface hits 70494fff56SYuval Mintz * @lastuse: time of last use of the group (traffic or update) 71494fff56SYuval Mintz * @ttls: OIF TTL threshold array 72494fff56SYuval Mintz * @refcount: reference count for this entry 73494fff56SYuval Mintz * @list: global entry list 74494fff56SYuval Mintz * @rcu: used for entry destruction 75494fff56SYuval Mintz */ 76494fff56SYuval Mintz struct mr_mfc { 77494fff56SYuval Mintz struct rhlist_head mnode; 78494fff56SYuval Mintz unsigned short mfc_parent; 79494fff56SYuval Mintz int mfc_flags; 80494fff56SYuval Mintz 81494fff56SYuval Mintz union { 82494fff56SYuval Mintz struct { 83494fff56SYuval Mintz unsigned long expires; 84494fff56SYuval Mintz struct sk_buff_head unresolved; 85494fff56SYuval Mintz } unres; 86494fff56SYuval Mintz struct { 87494fff56SYuval Mintz unsigned long last_assert; 88494fff56SYuval Mintz int minvif; 89494fff56SYuval Mintz int maxvif; 90494fff56SYuval Mintz unsigned long bytes; 91494fff56SYuval Mintz unsigned long pkt; 92494fff56SYuval Mintz unsigned long wrong_if; 93494fff56SYuval Mintz unsigned long lastuse; 94494fff56SYuval Mintz unsigned char ttls[MAXVIFS]; 95494fff56SYuval Mintz refcount_t refcount; 96494fff56SYuval Mintz } res; 97494fff56SYuval Mintz } mfc_un; 98494fff56SYuval Mintz struct list_head list; 99494fff56SYuval Mintz struct rcu_head rcu; 100494fff56SYuval Mintz }; 101494fff56SYuval Mintz 102845c9a7aSYuval Mintz struct mr_table; 103845c9a7aSYuval Mintz 104845c9a7aSYuval Mintz /** 105845c9a7aSYuval Mintz * struct mr_table_ops - callbacks and info for protocol-specific ops 106845c9a7aSYuval Mintz * @rht_params: parameters for accessing the MFC hash 107845c9a7aSYuval Mintz * @cmparg_any: a hash key to be used for matching on (*,*) routes 108845c9a7aSYuval Mintz */ 109845c9a7aSYuval Mintz struct mr_table_ops { 110845c9a7aSYuval Mintz const struct rhashtable_params *rht_params; 111845c9a7aSYuval Mintz void *cmparg_any; 112845c9a7aSYuval Mintz }; 113845c9a7aSYuval Mintz 114494fff56SYuval Mintz /** 115b70432f7SYuval Mintz * struct mr_table - a multicast routing table 116b70432f7SYuval Mintz * @list: entry within a list of multicast routing tables 117b70432f7SYuval Mintz * @net: net where this table belongs 118845c9a7aSYuval Mintz * @ops: protocol specific operations 119b70432f7SYuval Mintz * @id: identifier of the table 120b70432f7SYuval Mintz * @mroute_sk: socket associated with the table 121b70432f7SYuval Mintz * @ipmr_expire_timer: timer for handling unresolved routes 122b70432f7SYuval Mintz * @mfc_unres_queue: list of unresolved MFC entries 123b70432f7SYuval Mintz * @vif_table: array containing all possible vifs 124b70432f7SYuval Mintz * @mfc_hash: Hash table of all resolved routes for easy lookup 125b70432f7SYuval Mintz * @mfc_cache_list: list of resovled routes for possible traversal 126b70432f7SYuval Mintz * @maxvif: Identifier of highest value vif currently in use 127b70432f7SYuval Mintz * @cache_resolve_queue_len: current size of unresolved queue 128b70432f7SYuval Mintz * @mroute_do_assert: Whether to inform userspace on wrong ingress 129b70432f7SYuval Mintz * @mroute_do_pim: Whether to receive IGMP PIMv1 130b70432f7SYuval Mintz * @mroute_reg_vif_num: PIM-device vif index 131b70432f7SYuval Mintz */ 132b70432f7SYuval Mintz struct mr_table { 133b70432f7SYuval Mintz struct list_head list; 134b70432f7SYuval Mintz possible_net_t net; 135845c9a7aSYuval Mintz struct mr_table_ops ops; 136b70432f7SYuval Mintz u32 id; 137b70432f7SYuval Mintz struct sock __rcu *mroute_sk; 138b70432f7SYuval Mintz struct timer_list ipmr_expire_timer; 139b70432f7SYuval Mintz struct list_head mfc_unres_queue; 140b70432f7SYuval Mintz struct vif_device vif_table[MAXVIFS]; 141b70432f7SYuval Mintz struct rhltable mfc_hash; 142b70432f7SYuval Mintz struct list_head mfc_cache_list; 143b70432f7SYuval Mintz int maxvif; 144b70432f7SYuval Mintz atomic_t cache_resolve_queue_len; 145b70432f7SYuval Mintz bool mroute_do_assert; 146b70432f7SYuval Mintz bool mroute_do_pim; 147b70432f7SYuval Mintz int mroute_reg_vif_num; 148b70432f7SYuval Mintz }; 149b70432f7SYuval Mintz 1506853f21fSYuval Mintz #ifdef CONFIG_IP_MROUTE_COMMON 1516853f21fSYuval Mintz void vif_device_init(struct vif_device *v, 1526853f21fSYuval Mintz struct net_device *dev, 1536853f21fSYuval Mintz unsigned long rate_limit, 1546853f21fSYuval Mintz unsigned char threshold, 1556853f21fSYuval Mintz unsigned short flags, 1566853f21fSYuval Mintz unsigned short get_iflink_mask); 1570bbbf0e7SYuval Mintz 1580bbbf0e7SYuval Mintz struct mr_table * 1590bbbf0e7SYuval Mintz mr_table_alloc(struct net *net, u32 id, 160845c9a7aSYuval Mintz struct mr_table_ops *ops, 1610bbbf0e7SYuval Mintz void (*expire_func)(struct timer_list *t), 1620bbbf0e7SYuval Mintz void (*table_set)(struct mr_table *mrt, 1630bbbf0e7SYuval Mintz struct net *net)); 164845c9a7aSYuval Mintz 165845c9a7aSYuval Mintz /* These actually return 'struct mr_mfc *', but to avoid need for explicit 166845c9a7aSYuval Mintz * castings they simply return void. 167845c9a7aSYuval Mintz */ 168845c9a7aSYuval Mintz void *mr_mfc_find_parent(struct mr_table *mrt, 169845c9a7aSYuval Mintz void *hasharg, int parent); 170845c9a7aSYuval Mintz void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi); 171845c9a7aSYuval Mintz void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg); 172845c9a7aSYuval Mintz 1736853f21fSYuval Mintz #else 1746853f21fSYuval Mintz static inline void vif_device_init(struct vif_device *v, 1756853f21fSYuval Mintz struct net_device *dev, 1766853f21fSYuval Mintz unsigned long rate_limit, 1776853f21fSYuval Mintz unsigned char threshold, 1786853f21fSYuval Mintz unsigned short flags, 1796853f21fSYuval Mintz unsigned short get_iflink_mask) 1806853f21fSYuval Mintz { 1816853f21fSYuval Mintz } 1820bbbf0e7SYuval Mintz 183845c9a7aSYuval Mintz static inline void * 1840bbbf0e7SYuval Mintz mr_table_alloc(struct net *net, u32 id, 185845c9a7aSYuval Mintz struct mr_table_ops *ops, 1860bbbf0e7SYuval Mintz void (*expire_func)(struct timer_list *t), 1870bbbf0e7SYuval Mintz void (*table_set)(struct mr_table *mrt, 1880bbbf0e7SYuval Mintz struct net *net)) 1890bbbf0e7SYuval Mintz { 1900bbbf0e7SYuval Mintz return NULL; 1910bbbf0e7SYuval Mintz } 192845c9a7aSYuval Mintz 193845c9a7aSYuval Mintz static inline void *mr_mfc_find_parent(struct mr_table *mrt, 194845c9a7aSYuval Mintz void *hasharg, int parent) 195845c9a7aSYuval Mintz { 196845c9a7aSYuval Mintz return NULL; 197845c9a7aSYuval Mintz } 198845c9a7aSYuval Mintz 199845c9a7aSYuval Mintz static inline void *mr_mfc_find_any_parent(struct mr_table *mrt, 200845c9a7aSYuval Mintz int vifi) 201845c9a7aSYuval Mintz { 202845c9a7aSYuval Mintz return NULL; 203845c9a7aSYuval Mintz } 204845c9a7aSYuval Mintz 205845c9a7aSYuval Mintz static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt, 206845c9a7aSYuval Mintz int vifi, void *hasharg) 207845c9a7aSYuval Mintz { 208845c9a7aSYuval Mintz return NULL; 209845c9a7aSYuval Mintz } 2106853f21fSYuval Mintz #endif 211845c9a7aSYuval Mintz 212845c9a7aSYuval Mintz static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg) 213845c9a7aSYuval Mintz { 214845c9a7aSYuval Mintz return mr_mfc_find_parent(mrt, hasharg, -1); 215845c9a7aSYuval Mintz } 216c8d61968SYuval Mintz 217c8d61968SYuval Mintz #ifdef CONFIG_PROC_FS 2183feda6b4SYuval Mintz struct mr_vif_iter { 2193feda6b4SYuval Mintz struct seq_net_private p; 2203feda6b4SYuval Mintz struct mr_table *mrt; 2213feda6b4SYuval Mintz int ct; 2223feda6b4SYuval Mintz }; 2233feda6b4SYuval Mintz 224c8d61968SYuval Mintz struct mr_mfc_iter { 225c8d61968SYuval Mintz struct seq_net_private p; 226c8d61968SYuval Mintz struct mr_table *mrt; 227c8d61968SYuval Mintz struct list_head *cache; 228c8d61968SYuval Mintz 229c8d61968SYuval Mintz /* Lock protecting the mr_table's unresolved queue */ 230c8d61968SYuval Mintz spinlock_t *lock; 231c8d61968SYuval Mintz }; 232c8d61968SYuval Mintz 233c8d61968SYuval Mintz #ifdef CONFIG_IP_MROUTE_COMMON 2343feda6b4SYuval Mintz void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos); 2353feda6b4SYuval Mintz void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos); 2363feda6b4SYuval Mintz 2373feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 2383feda6b4SYuval Mintz { 2393feda6b4SYuval Mintz return *pos ? mr_vif_seq_idx(seq_file_net(seq), 2403feda6b4SYuval Mintz seq->private, *pos - 1) 2413feda6b4SYuval Mintz : SEQ_START_TOKEN; 2423feda6b4SYuval Mintz } 2433feda6b4SYuval Mintz 244c8d61968SYuval Mintz /* These actually return 'struct mr_mfc *', but to avoid need for explicit 245c8d61968SYuval Mintz * castings they simply return void. 246c8d61968SYuval Mintz */ 247c8d61968SYuval Mintz void *mr_mfc_seq_idx(struct net *net, 248c8d61968SYuval Mintz struct mr_mfc_iter *it, loff_t pos); 249c8d61968SYuval Mintz void *mr_mfc_seq_next(struct seq_file *seq, void *v, 250c8d61968SYuval Mintz loff_t *pos); 251c8d61968SYuval Mintz 252c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos, 253c8d61968SYuval Mintz struct mr_table *mrt, spinlock_t *lock) 254c8d61968SYuval Mintz { 255c8d61968SYuval Mintz struct mr_mfc_iter *it = seq->private; 256c8d61968SYuval Mintz 257c8d61968SYuval Mintz it->mrt = mrt; 258c8d61968SYuval Mintz it->cache = NULL; 259c8d61968SYuval Mintz it->lock = lock; 260c8d61968SYuval Mintz 261c8d61968SYuval Mintz return *pos ? mr_mfc_seq_idx(seq_file_net(seq), 262c8d61968SYuval Mintz seq->private, *pos - 1) 263c8d61968SYuval Mintz : SEQ_START_TOKEN; 264c8d61968SYuval Mintz } 265c8d61968SYuval Mintz 266c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v) 267c8d61968SYuval Mintz { 268c8d61968SYuval Mintz struct mr_mfc_iter *it = seq->private; 269c8d61968SYuval Mintz struct mr_table *mrt = it->mrt; 270c8d61968SYuval Mintz 271c8d61968SYuval Mintz if (it->cache == &mrt->mfc_unres_queue) 272c8d61968SYuval Mintz spin_unlock_bh(it->lock); 273c8d61968SYuval Mintz else if (it->cache == &mrt->mfc_cache_list) 274c8d61968SYuval Mintz rcu_read_unlock(); 275c8d61968SYuval Mintz } 276c8d61968SYuval Mintz #else 2773feda6b4SYuval Mintz static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, 2783feda6b4SYuval Mintz loff_t pos) 2793feda6b4SYuval Mintz { 2803feda6b4SYuval Mintz return NULL; 2813feda6b4SYuval Mintz } 2823feda6b4SYuval Mintz 2833feda6b4SYuval Mintz static inline void *mr_vif_seq_next(struct seq_file *seq, 2843feda6b4SYuval Mintz void *v, loff_t *pos) 2853feda6b4SYuval Mintz { 2863feda6b4SYuval Mintz return NULL; 2873feda6b4SYuval Mintz } 2883feda6b4SYuval Mintz 2893feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 2903feda6b4SYuval Mintz { 2913feda6b4SYuval Mintz return NULL; 2923feda6b4SYuval Mintz } 2933feda6b4SYuval Mintz 294c8d61968SYuval Mintz static inline void *mr_mfc_seq_idx(struct net *net, 295c8d61968SYuval Mintz struct mr_mfc_iter *it, loff_t pos) 296c8d61968SYuval Mintz { 297c8d61968SYuval Mintz return NULL; 298c8d61968SYuval Mintz } 299c8d61968SYuval Mintz 300c8d61968SYuval Mintz static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v, 301c8d61968SYuval Mintz loff_t *pos) 302c8d61968SYuval Mintz { 303c8d61968SYuval Mintz return NULL; 304c8d61968SYuval Mintz } 305c8d61968SYuval Mintz 306c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos, 307c8d61968SYuval Mintz struct mr_table *mrt, spinlock_t *lock) 308c8d61968SYuval Mintz { 309c8d61968SYuval Mintz return NULL; 310c8d61968SYuval Mintz } 311c8d61968SYuval Mintz 312c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v) 313c8d61968SYuval Mintz { 314c8d61968SYuval Mintz } 315c8d61968SYuval Mintz #endif 316c8d61968SYuval Mintz #endif 3176853f21fSYuval Mintz #endif 318