16853f21fSYuval Mintz #ifndef __LINUX_MROUTE_BASE_H 26853f21fSYuval Mintz #define __LINUX_MROUTE_BASE_H 36853f21fSYuval Mintz 46853f21fSYuval Mintz #include <linux/netdevice.h> 50eb71a9dSNeilBrown #include <linux/rhashtable-types.h> 6c8d61968SYuval Mintz #include <linux/spinlock.h> 7b70432f7SYuval Mintz #include <net/net_namespace.h> 8b70432f7SYuval Mintz #include <net/sock.h> 9bc67a0daSYuval Mintz #include <net/fib_notifier.h> 10cb167893SDavid Ahern #include <net/ip_fib.h> 116853f21fSYuval Mintz 126853f21fSYuval Mintz /** 136853f21fSYuval Mintz * struct vif_device - interface representor for multicast routing 146853f21fSYuval Mintz * @dev: network device being used 156853f21fSYuval Mintz * @bytes_in: statistic; bytes ingressing 166853f21fSYuval Mintz * @bytes_out: statistic; bytes egresing 176853f21fSYuval Mintz * @pkt_in: statistic; packets ingressing 186853f21fSYuval Mintz * @pkt_out: statistic; packets egressing 196853f21fSYuval Mintz * @rate_limit: Traffic shaping (NI) 206853f21fSYuval Mintz * @threshold: TTL threshold 216853f21fSYuval Mintz * @flags: Control flags 226853f21fSYuval Mintz * @link: Physical interface index 236853f21fSYuval Mintz * @dev_parent_id: device parent id 246853f21fSYuval Mintz * @local: Local address 256853f21fSYuval Mintz * @remote: Remote address for tunnels 266853f21fSYuval Mintz */ 276853f21fSYuval Mintz struct vif_device { 286853f21fSYuval Mintz struct net_device *dev; 296853f21fSYuval Mintz unsigned long bytes_in, bytes_out; 306853f21fSYuval Mintz unsigned long pkt_in, pkt_out; 316853f21fSYuval Mintz unsigned long rate_limit; 326853f21fSYuval Mintz unsigned char threshold; 336853f21fSYuval Mintz unsigned short flags; 346853f21fSYuval Mintz int link; 356853f21fSYuval Mintz 366853f21fSYuval Mintz /* Currently only used by ipmr */ 376853f21fSYuval Mintz struct netdev_phys_item_id dev_parent_id; 386853f21fSYuval Mintz __be32 local, remote; 396853f21fSYuval Mintz }; 406853f21fSYuval Mintz 41bc67a0daSYuval Mintz struct vif_entry_notifier_info { 42bc67a0daSYuval Mintz struct fib_notifier_info info; 43bc67a0daSYuval Mintz struct net_device *dev; 44bc67a0daSYuval Mintz unsigned short vif_index; 45bc67a0daSYuval Mintz unsigned short vif_flags; 46bc67a0daSYuval Mintz u32 tb_id; 47bc67a0daSYuval Mintz }; 48bc67a0daSYuval Mintz 49bc67a0daSYuval Mintz static inline int mr_call_vif_notifier(struct notifier_block *nb, 50bc67a0daSYuval Mintz unsigned short family, 51bc67a0daSYuval Mintz enum fib_event_type event_type, 52bc67a0daSYuval Mintz struct vif_device *vif, 53bc67a0daSYuval Mintz unsigned short vif_index, u32 tb_id) 54bc67a0daSYuval Mintz { 55bc67a0daSYuval Mintz struct vif_entry_notifier_info info = { 56bc67a0daSYuval Mintz .info = { 57bc67a0daSYuval Mintz .family = family, 58bc67a0daSYuval Mintz }, 59bc67a0daSYuval Mintz .dev = vif->dev, 60bc67a0daSYuval Mintz .vif_index = vif_index, 61bc67a0daSYuval Mintz .vif_flags = vif->flags, 62bc67a0daSYuval Mintz .tb_id = tb_id, 63bc67a0daSYuval Mintz }; 64bc67a0daSYuval Mintz 65*7c550dafSJiri Pirko return call_fib_notifier(nb, event_type, &info.info); 66bc67a0daSYuval Mintz } 67bc67a0daSYuval Mintz 68bc67a0daSYuval Mintz static inline int mr_call_vif_notifiers(struct net *net, 69bc67a0daSYuval Mintz unsigned short family, 70bc67a0daSYuval Mintz enum fib_event_type event_type, 71bc67a0daSYuval Mintz struct vif_device *vif, 72bc67a0daSYuval Mintz unsigned short vif_index, u32 tb_id, 73bc67a0daSYuval Mintz unsigned int *ipmr_seq) 74bc67a0daSYuval Mintz { 75bc67a0daSYuval Mintz struct vif_entry_notifier_info info = { 76bc67a0daSYuval Mintz .info = { 77bc67a0daSYuval Mintz .family = family, 78bc67a0daSYuval Mintz }, 79bc67a0daSYuval Mintz .dev = vif->dev, 80bc67a0daSYuval Mintz .vif_index = vif_index, 81bc67a0daSYuval Mintz .vif_flags = vif->flags, 82bc67a0daSYuval Mintz .tb_id = tb_id, 83bc67a0daSYuval Mintz }; 84bc67a0daSYuval Mintz 85bc67a0daSYuval Mintz ASSERT_RTNL(); 86bc67a0daSYuval Mintz (*ipmr_seq)++; 87bc67a0daSYuval Mintz return call_fib_notifiers(net, event_type, &info.info); 88bc67a0daSYuval Mintz } 89bc67a0daSYuval Mintz 90b70432f7SYuval Mintz #ifndef MAXVIFS 91b70432f7SYuval Mintz /* This one is nasty; value is defined in uapi using different symbols for 92b70432f7SYuval Mintz * mroute and morute6 but both map into same 32. 93b70432f7SYuval Mintz */ 94b70432f7SYuval Mintz #define MAXVIFS 32 95b70432f7SYuval Mintz #endif 96b70432f7SYuval Mintz 97b70432f7SYuval Mintz #define VIF_EXISTS(_mrt, _idx) (!!((_mrt)->vif_table[_idx].dev)) 98b70432f7SYuval Mintz 99889cd83cSYuval Mintz /* mfc_flags: 100889cd83cSYuval Mintz * MFC_STATIC - the entry was added statically (not by a routing daemon) 101889cd83cSYuval Mintz * MFC_OFFLOAD - the entry was offloaded to the hardware 102889cd83cSYuval Mintz */ 103889cd83cSYuval Mintz enum { 104889cd83cSYuval Mintz MFC_STATIC = BIT(0), 105889cd83cSYuval Mintz MFC_OFFLOAD = BIT(1), 106889cd83cSYuval Mintz }; 107889cd83cSYuval Mintz 108b70432f7SYuval Mintz /** 109494fff56SYuval Mintz * struct mr_mfc - common multicast routing entries 110494fff56SYuval Mintz * @mnode: rhashtable list 111494fff56SYuval Mintz * @mfc_parent: source interface (iif) 112494fff56SYuval Mintz * @mfc_flags: entry flags 113494fff56SYuval Mintz * @expires: unresolved entry expire time 114494fff56SYuval Mintz * @unresolved: unresolved cached skbs 115494fff56SYuval Mintz * @last_assert: time of last assert 116494fff56SYuval Mintz * @minvif: minimum VIF id 117494fff56SYuval Mintz * @maxvif: maximum VIF id 118494fff56SYuval Mintz * @bytes: bytes that have passed for this entry 119494fff56SYuval Mintz * @pkt: packets that have passed for this entry 120494fff56SYuval Mintz * @wrong_if: number of wrong source interface hits 121494fff56SYuval Mintz * @lastuse: time of last use of the group (traffic or update) 122494fff56SYuval Mintz * @ttls: OIF TTL threshold array 123494fff56SYuval Mintz * @refcount: reference count for this entry 124494fff56SYuval Mintz * @list: global entry list 125494fff56SYuval Mintz * @rcu: used for entry destruction 1268c13af2aSYuval Mintz * @free: Operation used for freeing an entry under RCU 127494fff56SYuval Mintz */ 128494fff56SYuval Mintz struct mr_mfc { 129494fff56SYuval Mintz struct rhlist_head mnode; 130494fff56SYuval Mintz unsigned short mfc_parent; 131494fff56SYuval Mintz int mfc_flags; 132494fff56SYuval Mintz 133494fff56SYuval Mintz union { 134494fff56SYuval Mintz struct { 135494fff56SYuval Mintz unsigned long expires; 136494fff56SYuval Mintz struct sk_buff_head unresolved; 137494fff56SYuval Mintz } unres; 138494fff56SYuval Mintz struct { 139494fff56SYuval Mintz unsigned long last_assert; 140494fff56SYuval Mintz int minvif; 141494fff56SYuval Mintz int maxvif; 142494fff56SYuval Mintz unsigned long bytes; 143494fff56SYuval Mintz unsigned long pkt; 144494fff56SYuval Mintz unsigned long wrong_if; 145494fff56SYuval Mintz unsigned long lastuse; 146494fff56SYuval Mintz unsigned char ttls[MAXVIFS]; 147494fff56SYuval Mintz refcount_t refcount; 148494fff56SYuval Mintz } res; 149494fff56SYuval Mintz } mfc_un; 150494fff56SYuval Mintz struct list_head list; 151494fff56SYuval Mintz struct rcu_head rcu; 1528c13af2aSYuval Mintz void (*free)(struct rcu_head *head); 153494fff56SYuval Mintz }; 154494fff56SYuval Mintz 1558c13af2aSYuval Mintz static inline void mr_cache_put(struct mr_mfc *c) 1568c13af2aSYuval Mintz { 1578c13af2aSYuval Mintz if (refcount_dec_and_test(&c->mfc_un.res.refcount)) 1588c13af2aSYuval Mintz call_rcu(&c->rcu, c->free); 1598c13af2aSYuval Mintz } 1608c13af2aSYuval Mintz 1618c13af2aSYuval Mintz static inline void mr_cache_hold(struct mr_mfc *c) 1628c13af2aSYuval Mintz { 1638c13af2aSYuval Mintz refcount_inc(&c->mfc_un.res.refcount); 1648c13af2aSYuval Mintz } 1658c13af2aSYuval Mintz 16654c4cad9SYuval Mintz struct mfc_entry_notifier_info { 16754c4cad9SYuval Mintz struct fib_notifier_info info; 16854c4cad9SYuval Mintz struct mr_mfc *mfc; 16954c4cad9SYuval Mintz u32 tb_id; 17054c4cad9SYuval Mintz }; 17154c4cad9SYuval Mintz 17254c4cad9SYuval Mintz static inline int mr_call_mfc_notifier(struct notifier_block *nb, 17354c4cad9SYuval Mintz unsigned short family, 17454c4cad9SYuval Mintz enum fib_event_type event_type, 17554c4cad9SYuval Mintz struct mr_mfc *mfc, u32 tb_id) 17654c4cad9SYuval Mintz { 17754c4cad9SYuval Mintz struct mfc_entry_notifier_info info = { 17854c4cad9SYuval Mintz .info = { 17954c4cad9SYuval Mintz .family = family, 18054c4cad9SYuval Mintz }, 18154c4cad9SYuval Mintz .mfc = mfc, 18254c4cad9SYuval Mintz .tb_id = tb_id 18354c4cad9SYuval Mintz }; 18454c4cad9SYuval Mintz 185*7c550dafSJiri Pirko return call_fib_notifier(nb, event_type, &info.info); 18654c4cad9SYuval Mintz } 18754c4cad9SYuval Mintz 18854c4cad9SYuval Mintz static inline int mr_call_mfc_notifiers(struct net *net, 18954c4cad9SYuval Mintz unsigned short family, 19054c4cad9SYuval Mintz enum fib_event_type event_type, 19154c4cad9SYuval Mintz struct mr_mfc *mfc, u32 tb_id, 19254c4cad9SYuval Mintz unsigned int *ipmr_seq) 19354c4cad9SYuval Mintz { 19454c4cad9SYuval Mintz struct mfc_entry_notifier_info info = { 19554c4cad9SYuval Mintz .info = { 19654c4cad9SYuval Mintz .family = family, 19754c4cad9SYuval Mintz }, 19854c4cad9SYuval Mintz .mfc = mfc, 19954c4cad9SYuval Mintz .tb_id = tb_id 20054c4cad9SYuval Mintz }; 20154c4cad9SYuval Mintz 20254c4cad9SYuval Mintz ASSERT_RTNL(); 20354c4cad9SYuval Mintz (*ipmr_seq)++; 20454c4cad9SYuval Mintz return call_fib_notifiers(net, event_type, &info.info); 20554c4cad9SYuval Mintz } 20654c4cad9SYuval Mintz 207845c9a7aSYuval Mintz struct mr_table; 208845c9a7aSYuval Mintz 209845c9a7aSYuval Mintz /** 210845c9a7aSYuval Mintz * struct mr_table_ops - callbacks and info for protocol-specific ops 211845c9a7aSYuval Mintz * @rht_params: parameters for accessing the MFC hash 212845c9a7aSYuval Mintz * @cmparg_any: a hash key to be used for matching on (*,*) routes 213845c9a7aSYuval Mintz */ 214845c9a7aSYuval Mintz struct mr_table_ops { 215845c9a7aSYuval Mintz const struct rhashtable_params *rht_params; 216845c9a7aSYuval Mintz void *cmparg_any; 217845c9a7aSYuval Mintz }; 218845c9a7aSYuval Mintz 219494fff56SYuval Mintz /** 220b70432f7SYuval Mintz * struct mr_table - a multicast routing table 221b70432f7SYuval Mintz * @list: entry within a list of multicast routing tables 222b70432f7SYuval Mintz * @net: net where this table belongs 223845c9a7aSYuval Mintz * @ops: protocol specific operations 224b70432f7SYuval Mintz * @id: identifier of the table 225b70432f7SYuval Mintz * @mroute_sk: socket associated with the table 226b70432f7SYuval Mintz * @ipmr_expire_timer: timer for handling unresolved routes 227b70432f7SYuval Mintz * @mfc_unres_queue: list of unresolved MFC entries 228b70432f7SYuval Mintz * @vif_table: array containing all possible vifs 229b70432f7SYuval Mintz * @mfc_hash: Hash table of all resolved routes for easy lookup 230b70432f7SYuval Mintz * @mfc_cache_list: list of resovled routes for possible traversal 231b70432f7SYuval Mintz * @maxvif: Identifier of highest value vif currently in use 232b70432f7SYuval Mintz * @cache_resolve_queue_len: current size of unresolved queue 233b70432f7SYuval Mintz * @mroute_do_assert: Whether to inform userspace on wrong ingress 234b70432f7SYuval Mintz * @mroute_do_pim: Whether to receive IGMP PIMv1 235b70432f7SYuval Mintz * @mroute_reg_vif_num: PIM-device vif index 236b70432f7SYuval Mintz */ 237b70432f7SYuval Mintz struct mr_table { 238b70432f7SYuval Mintz struct list_head list; 239b70432f7SYuval Mintz possible_net_t net; 240845c9a7aSYuval Mintz struct mr_table_ops ops; 241b70432f7SYuval Mintz u32 id; 242b70432f7SYuval Mintz struct sock __rcu *mroute_sk; 243b70432f7SYuval Mintz struct timer_list ipmr_expire_timer; 244b70432f7SYuval Mintz struct list_head mfc_unres_queue; 245b70432f7SYuval Mintz struct vif_device vif_table[MAXVIFS]; 246b70432f7SYuval Mintz struct rhltable mfc_hash; 247b70432f7SYuval Mintz struct list_head mfc_cache_list; 248b70432f7SYuval Mintz int maxvif; 249b70432f7SYuval Mintz atomic_t cache_resolve_queue_len; 250b70432f7SYuval Mintz bool mroute_do_assert; 251b70432f7SYuval Mintz bool mroute_do_pim; 252c921c207SNikolay Aleksandrov bool mroute_do_wrvifwhole; 253b70432f7SYuval Mintz int mroute_reg_vif_num; 254b70432f7SYuval Mintz }; 255b70432f7SYuval Mintz 2566853f21fSYuval Mintz #ifdef CONFIG_IP_MROUTE_COMMON 2576853f21fSYuval Mintz void vif_device_init(struct vif_device *v, 2586853f21fSYuval Mintz struct net_device *dev, 2596853f21fSYuval Mintz unsigned long rate_limit, 2606853f21fSYuval Mintz unsigned char threshold, 2616853f21fSYuval Mintz unsigned short flags, 2626853f21fSYuval Mintz unsigned short get_iflink_mask); 2630bbbf0e7SYuval Mintz 2640bbbf0e7SYuval Mintz struct mr_table * 2650bbbf0e7SYuval Mintz mr_table_alloc(struct net *net, u32 id, 266845c9a7aSYuval Mintz struct mr_table_ops *ops, 2670bbbf0e7SYuval Mintz void (*expire_func)(struct timer_list *t), 2680bbbf0e7SYuval Mintz void (*table_set)(struct mr_table *mrt, 2690bbbf0e7SYuval Mintz struct net *net)); 270845c9a7aSYuval Mintz 271845c9a7aSYuval Mintz /* These actually return 'struct mr_mfc *', but to avoid need for explicit 272845c9a7aSYuval Mintz * castings they simply return void. 273845c9a7aSYuval Mintz */ 274845c9a7aSYuval Mintz void *mr_mfc_find_parent(struct mr_table *mrt, 275845c9a7aSYuval Mintz void *hasharg, int parent); 276845c9a7aSYuval Mintz void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi); 277845c9a7aSYuval Mintz void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg); 278845c9a7aSYuval Mintz 2797b0db857SYuval Mintz int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, 2807b0db857SYuval Mintz struct mr_mfc *c, struct rtmsg *rtm); 281e1cedae1SDavid Ahern int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb, 282e1cedae1SDavid Ahern struct netlink_callback *cb, 283e1cedae1SDavid Ahern int (*fill)(struct mr_table *mrt, struct sk_buff *skb, 284e1cedae1SDavid Ahern u32 portid, u32 seq, struct mr_mfc *c, 285e1cedae1SDavid Ahern int cmd, int flags), 286cb167893SDavid Ahern spinlock_t *lock, struct fib_dump_filter *filter); 2877b0db857SYuval Mintz int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb, 2887b0db857SYuval Mintz struct mr_table *(*iter)(struct net *net, 2897b0db857SYuval Mintz struct mr_table *mrt), 2907b0db857SYuval Mintz int (*fill)(struct mr_table *mrt, 2917b0db857SYuval Mintz struct sk_buff *skb, 2927b0db857SYuval Mintz u32 portid, u32 seq, struct mr_mfc *c, 2937b0db857SYuval Mintz int cmd, int flags), 294cb167893SDavid Ahern spinlock_t *lock, struct fib_dump_filter *filter); 295cdc9f944SYuval Mintz 296cdc9f944SYuval Mintz int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family, 297cdc9f944SYuval Mintz int (*rules_dump)(struct net *net, 298cdc9f944SYuval Mintz struct notifier_block *nb), 299cdc9f944SYuval Mintz struct mr_table *(*mr_iter)(struct net *net, 300cdc9f944SYuval Mintz struct mr_table *mrt), 301cdc9f944SYuval Mintz rwlock_t *mrt_lock); 3026853f21fSYuval Mintz #else 3036853f21fSYuval Mintz static inline void vif_device_init(struct vif_device *v, 3046853f21fSYuval Mintz struct net_device *dev, 3056853f21fSYuval Mintz unsigned long rate_limit, 3066853f21fSYuval Mintz unsigned char threshold, 3076853f21fSYuval Mintz unsigned short flags, 3086853f21fSYuval Mintz unsigned short get_iflink_mask) 3096853f21fSYuval Mintz { 3106853f21fSYuval Mintz } 3110bbbf0e7SYuval Mintz 312845c9a7aSYuval Mintz static inline void *mr_mfc_find_parent(struct mr_table *mrt, 313845c9a7aSYuval Mintz void *hasharg, int parent) 314845c9a7aSYuval Mintz { 315845c9a7aSYuval Mintz return NULL; 316845c9a7aSYuval Mintz } 317845c9a7aSYuval Mintz 318845c9a7aSYuval Mintz static inline void *mr_mfc_find_any_parent(struct mr_table *mrt, 319845c9a7aSYuval Mintz int vifi) 320845c9a7aSYuval Mintz { 321845c9a7aSYuval Mintz return NULL; 322845c9a7aSYuval Mintz } 323845c9a7aSYuval Mintz 324845c9a7aSYuval Mintz static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt, 325845c9a7aSYuval Mintz int vifi, void *hasharg) 326845c9a7aSYuval Mintz { 327845c9a7aSYuval Mintz return NULL; 328845c9a7aSYuval Mintz } 3297b0db857SYuval Mintz 3307b0db857SYuval Mintz static inline int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, 3317b0db857SYuval Mintz struct mr_mfc *c, struct rtmsg *rtm) 3327b0db857SYuval Mintz { 3337b0db857SYuval Mintz return -EINVAL; 3347b0db857SYuval Mintz } 3357b0db857SYuval Mintz 3367b0db857SYuval Mintz static inline int 3377b0db857SYuval Mintz mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb, 3387b0db857SYuval Mintz struct mr_table *(*iter)(struct net *net, 3397b0db857SYuval Mintz struct mr_table *mrt), 3407b0db857SYuval Mintz int (*fill)(struct mr_table *mrt, 3417b0db857SYuval Mintz struct sk_buff *skb, 3427b0db857SYuval Mintz u32 portid, u32 seq, struct mr_mfc *c, 3437b0db857SYuval Mintz int cmd, int flags), 344cb167893SDavid Ahern spinlock_t *lock, struct fib_dump_filter *filter) 3457b0db857SYuval Mintz { 3467b0db857SYuval Mintz return -EINVAL; 3477b0db857SYuval Mintz } 348cdc9f944SYuval Mintz 349cdc9f944SYuval Mintz static inline int mr_dump(struct net *net, struct notifier_block *nb, 350cdc9f944SYuval Mintz unsigned short family, 351cdc9f944SYuval Mintz int (*rules_dump)(struct net *net, 352cdc9f944SYuval Mintz struct notifier_block *nb), 353cdc9f944SYuval Mintz struct mr_table *(*mr_iter)(struct net *net, 354cdc9f944SYuval Mintz struct mr_table *mrt), 355cdc9f944SYuval Mintz rwlock_t *mrt_lock) 356cdc9f944SYuval Mintz { 357cdc9f944SYuval Mintz return -EINVAL; 358cdc9f944SYuval Mintz } 3596853f21fSYuval Mintz #endif 360845c9a7aSYuval Mintz 361845c9a7aSYuval Mintz static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg) 362845c9a7aSYuval Mintz { 363845c9a7aSYuval Mintz return mr_mfc_find_parent(mrt, hasharg, -1); 364845c9a7aSYuval Mintz } 365c8d61968SYuval Mintz 366c8d61968SYuval Mintz #ifdef CONFIG_PROC_FS 3673feda6b4SYuval Mintz struct mr_vif_iter { 3683feda6b4SYuval Mintz struct seq_net_private p; 3693feda6b4SYuval Mintz struct mr_table *mrt; 3703feda6b4SYuval Mintz int ct; 3713feda6b4SYuval Mintz }; 3723feda6b4SYuval Mintz 373c8d61968SYuval Mintz struct mr_mfc_iter { 374c8d61968SYuval Mintz struct seq_net_private p; 375c8d61968SYuval Mintz struct mr_table *mrt; 376c8d61968SYuval Mintz struct list_head *cache; 377c8d61968SYuval Mintz 378c8d61968SYuval Mintz /* Lock protecting the mr_table's unresolved queue */ 379c8d61968SYuval Mintz spinlock_t *lock; 380c8d61968SYuval Mintz }; 381c8d61968SYuval Mintz 382c8d61968SYuval Mintz #ifdef CONFIG_IP_MROUTE_COMMON 3833feda6b4SYuval Mintz void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos); 3843feda6b4SYuval Mintz void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos); 3853feda6b4SYuval Mintz 3863feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 3873feda6b4SYuval Mintz { 3883feda6b4SYuval Mintz return *pos ? mr_vif_seq_idx(seq_file_net(seq), 3893feda6b4SYuval Mintz seq->private, *pos - 1) 3903feda6b4SYuval Mintz : SEQ_START_TOKEN; 3913feda6b4SYuval Mintz } 3923feda6b4SYuval Mintz 393c8d61968SYuval Mintz /* These actually return 'struct mr_mfc *', but to avoid need for explicit 394c8d61968SYuval Mintz * castings they simply return void. 395c8d61968SYuval Mintz */ 396c8d61968SYuval Mintz void *mr_mfc_seq_idx(struct net *net, 397c8d61968SYuval Mintz struct mr_mfc_iter *it, loff_t pos); 398c8d61968SYuval Mintz void *mr_mfc_seq_next(struct seq_file *seq, void *v, 399c8d61968SYuval Mintz loff_t *pos); 400c8d61968SYuval Mintz 401c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos, 402c8d61968SYuval Mintz struct mr_table *mrt, spinlock_t *lock) 403c8d61968SYuval Mintz { 404c8d61968SYuval Mintz struct mr_mfc_iter *it = seq->private; 405c8d61968SYuval Mintz 406c8d61968SYuval Mintz it->mrt = mrt; 407c8d61968SYuval Mintz it->cache = NULL; 408c8d61968SYuval Mintz it->lock = lock; 409c8d61968SYuval Mintz 410c8d61968SYuval Mintz return *pos ? mr_mfc_seq_idx(seq_file_net(seq), 411c8d61968SYuval Mintz seq->private, *pos - 1) 412c8d61968SYuval Mintz : SEQ_START_TOKEN; 413c8d61968SYuval Mintz } 414c8d61968SYuval Mintz 415c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v) 416c8d61968SYuval Mintz { 417c8d61968SYuval Mintz struct mr_mfc_iter *it = seq->private; 418c8d61968SYuval Mintz struct mr_table *mrt = it->mrt; 419c8d61968SYuval Mintz 420c8d61968SYuval Mintz if (it->cache == &mrt->mfc_unres_queue) 421c8d61968SYuval Mintz spin_unlock_bh(it->lock); 422c8d61968SYuval Mintz else if (it->cache == &mrt->mfc_cache_list) 423c8d61968SYuval Mintz rcu_read_unlock(); 424c8d61968SYuval Mintz } 425c8d61968SYuval Mintz #else 4263feda6b4SYuval Mintz static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, 4273feda6b4SYuval Mintz loff_t pos) 4283feda6b4SYuval Mintz { 4293feda6b4SYuval Mintz return NULL; 4303feda6b4SYuval Mintz } 4313feda6b4SYuval Mintz 4323feda6b4SYuval Mintz static inline void *mr_vif_seq_next(struct seq_file *seq, 4333feda6b4SYuval Mintz void *v, loff_t *pos) 4343feda6b4SYuval Mintz { 4353feda6b4SYuval Mintz return NULL; 4363feda6b4SYuval Mintz } 4373feda6b4SYuval Mintz 4383feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 4393feda6b4SYuval Mintz { 4403feda6b4SYuval Mintz return NULL; 4413feda6b4SYuval Mintz } 4423feda6b4SYuval Mintz 443c8d61968SYuval Mintz static inline void *mr_mfc_seq_idx(struct net *net, 444c8d61968SYuval Mintz struct mr_mfc_iter *it, loff_t pos) 445c8d61968SYuval Mintz { 446c8d61968SYuval Mintz return NULL; 447c8d61968SYuval Mintz } 448c8d61968SYuval Mintz 449c8d61968SYuval Mintz static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v, 450c8d61968SYuval Mintz loff_t *pos) 451c8d61968SYuval Mintz { 452c8d61968SYuval Mintz return NULL; 453c8d61968SYuval Mintz } 454c8d61968SYuval Mintz 455c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos, 456c8d61968SYuval Mintz struct mr_table *mrt, spinlock_t *lock) 457c8d61968SYuval Mintz { 458c8d61968SYuval Mintz return NULL; 459c8d61968SYuval Mintz } 460c8d61968SYuval Mintz 461c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v) 462c8d61968SYuval Mintz { 463c8d61968SYuval Mintz } 464c8d61968SYuval Mintz #endif 465c8d61968SYuval Mintz #endif 4666853f21fSYuval Mintz #endif 467