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> 9bc67a0daSYuval Mintz #include <net/fib_notifier.h> 106853f21fSYuval Mintz 116853f21fSYuval Mintz /** 126853f21fSYuval Mintz * struct vif_device - interface representor for multicast routing 136853f21fSYuval Mintz * @dev: network device being used 146853f21fSYuval Mintz * @bytes_in: statistic; bytes ingressing 156853f21fSYuval Mintz * @bytes_out: statistic; bytes egresing 166853f21fSYuval Mintz * @pkt_in: statistic; packets ingressing 176853f21fSYuval Mintz * @pkt_out: statistic; packets egressing 186853f21fSYuval Mintz * @rate_limit: Traffic shaping (NI) 196853f21fSYuval Mintz * @threshold: TTL threshold 206853f21fSYuval Mintz * @flags: Control flags 216853f21fSYuval Mintz * @link: Physical interface index 226853f21fSYuval Mintz * @dev_parent_id: device parent id 236853f21fSYuval Mintz * @local: Local address 246853f21fSYuval Mintz * @remote: Remote address for tunnels 256853f21fSYuval Mintz */ 266853f21fSYuval Mintz struct vif_device { 276853f21fSYuval Mintz struct net_device *dev; 286853f21fSYuval Mintz unsigned long bytes_in, bytes_out; 296853f21fSYuval Mintz unsigned long pkt_in, pkt_out; 306853f21fSYuval Mintz unsigned long rate_limit; 316853f21fSYuval Mintz unsigned char threshold; 326853f21fSYuval Mintz unsigned short flags; 336853f21fSYuval Mintz int link; 346853f21fSYuval Mintz 356853f21fSYuval Mintz /* Currently only used by ipmr */ 366853f21fSYuval Mintz struct netdev_phys_item_id dev_parent_id; 376853f21fSYuval Mintz __be32 local, remote; 386853f21fSYuval Mintz }; 396853f21fSYuval Mintz 40bc67a0daSYuval Mintz struct vif_entry_notifier_info { 41bc67a0daSYuval Mintz struct fib_notifier_info info; 42bc67a0daSYuval Mintz struct net_device *dev; 43bc67a0daSYuval Mintz unsigned short vif_index; 44bc67a0daSYuval Mintz unsigned short vif_flags; 45bc67a0daSYuval Mintz u32 tb_id; 46bc67a0daSYuval Mintz }; 47bc67a0daSYuval Mintz 48bc67a0daSYuval Mintz static inline int mr_call_vif_notifier(struct notifier_block *nb, 49bc67a0daSYuval Mintz struct net *net, 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 .net = net, 59bc67a0daSYuval Mintz }, 60bc67a0daSYuval Mintz .dev = vif->dev, 61bc67a0daSYuval Mintz .vif_index = vif_index, 62bc67a0daSYuval Mintz .vif_flags = vif->flags, 63bc67a0daSYuval Mintz .tb_id = tb_id, 64bc67a0daSYuval Mintz }; 65bc67a0daSYuval Mintz 66bc67a0daSYuval Mintz return call_fib_notifier(nb, net, event_type, &info.info); 67bc67a0daSYuval Mintz } 68bc67a0daSYuval Mintz 69bc67a0daSYuval Mintz static inline int mr_call_vif_notifiers(struct net *net, 70bc67a0daSYuval Mintz unsigned short family, 71bc67a0daSYuval Mintz enum fib_event_type event_type, 72bc67a0daSYuval Mintz struct vif_device *vif, 73bc67a0daSYuval Mintz unsigned short vif_index, u32 tb_id, 74bc67a0daSYuval Mintz unsigned int *ipmr_seq) 75bc67a0daSYuval Mintz { 76bc67a0daSYuval Mintz struct vif_entry_notifier_info info = { 77bc67a0daSYuval Mintz .info = { 78bc67a0daSYuval Mintz .family = family, 79bc67a0daSYuval Mintz .net = net, 80bc67a0daSYuval Mintz }, 81bc67a0daSYuval Mintz .dev = vif->dev, 82bc67a0daSYuval Mintz .vif_index = vif_index, 83bc67a0daSYuval Mintz .vif_flags = vif->flags, 84bc67a0daSYuval Mintz .tb_id = tb_id, 85bc67a0daSYuval Mintz }; 86bc67a0daSYuval Mintz 87bc67a0daSYuval Mintz ASSERT_RTNL(); 88bc67a0daSYuval Mintz (*ipmr_seq)++; 89bc67a0daSYuval Mintz return call_fib_notifiers(net, event_type, &info.info); 90bc67a0daSYuval Mintz } 91bc67a0daSYuval Mintz 92b70432f7SYuval Mintz #ifndef MAXVIFS 93b70432f7SYuval Mintz /* This one is nasty; value is defined in uapi using different symbols for 94b70432f7SYuval Mintz * mroute and morute6 but both map into same 32. 95b70432f7SYuval Mintz */ 96b70432f7SYuval Mintz #define MAXVIFS 32 97b70432f7SYuval Mintz #endif 98b70432f7SYuval Mintz 99b70432f7SYuval Mintz #define VIF_EXISTS(_mrt, _idx) (!!((_mrt)->vif_table[_idx].dev)) 100b70432f7SYuval Mintz 101889cd83cSYuval Mintz /* mfc_flags: 102889cd83cSYuval Mintz * MFC_STATIC - the entry was added statically (not by a routing daemon) 103889cd83cSYuval Mintz * MFC_OFFLOAD - the entry was offloaded to the hardware 104889cd83cSYuval Mintz */ 105889cd83cSYuval Mintz enum { 106889cd83cSYuval Mintz MFC_STATIC = BIT(0), 107889cd83cSYuval Mintz MFC_OFFLOAD = BIT(1), 108889cd83cSYuval Mintz }; 109889cd83cSYuval Mintz 110b70432f7SYuval Mintz /** 111494fff56SYuval Mintz * struct mr_mfc - common multicast routing entries 112494fff56SYuval Mintz * @mnode: rhashtable list 113494fff56SYuval Mintz * @mfc_parent: source interface (iif) 114494fff56SYuval Mintz * @mfc_flags: entry flags 115494fff56SYuval Mintz * @expires: unresolved entry expire time 116494fff56SYuval Mintz * @unresolved: unresolved cached skbs 117494fff56SYuval Mintz * @last_assert: time of last assert 118494fff56SYuval Mintz * @minvif: minimum VIF id 119494fff56SYuval Mintz * @maxvif: maximum VIF id 120494fff56SYuval Mintz * @bytes: bytes that have passed for this entry 121494fff56SYuval Mintz * @pkt: packets that have passed for this entry 122494fff56SYuval Mintz * @wrong_if: number of wrong source interface hits 123494fff56SYuval Mintz * @lastuse: time of last use of the group (traffic or update) 124494fff56SYuval Mintz * @ttls: OIF TTL threshold array 125494fff56SYuval Mintz * @refcount: reference count for this entry 126494fff56SYuval Mintz * @list: global entry list 127494fff56SYuval Mintz * @rcu: used for entry destruction 128494fff56SYuval Mintz */ 129494fff56SYuval Mintz struct mr_mfc { 130494fff56SYuval Mintz struct rhlist_head mnode; 131494fff56SYuval Mintz unsigned short mfc_parent; 132494fff56SYuval Mintz int mfc_flags; 133494fff56SYuval Mintz 134494fff56SYuval Mintz union { 135494fff56SYuval Mintz struct { 136494fff56SYuval Mintz unsigned long expires; 137494fff56SYuval Mintz struct sk_buff_head unresolved; 138494fff56SYuval Mintz } unres; 139494fff56SYuval Mintz struct { 140494fff56SYuval Mintz unsigned long last_assert; 141494fff56SYuval Mintz int minvif; 142494fff56SYuval Mintz int maxvif; 143494fff56SYuval Mintz unsigned long bytes; 144494fff56SYuval Mintz unsigned long pkt; 145494fff56SYuval Mintz unsigned long wrong_if; 146494fff56SYuval Mintz unsigned long lastuse; 147494fff56SYuval Mintz unsigned char ttls[MAXVIFS]; 148494fff56SYuval Mintz refcount_t refcount; 149494fff56SYuval Mintz } res; 150494fff56SYuval Mintz } mfc_un; 151494fff56SYuval Mintz struct list_head list; 152494fff56SYuval Mintz struct rcu_head rcu; 153494fff56SYuval Mintz }; 154494fff56SYuval Mintz 155*54c4cad9SYuval Mintz struct mfc_entry_notifier_info { 156*54c4cad9SYuval Mintz struct fib_notifier_info info; 157*54c4cad9SYuval Mintz struct mr_mfc *mfc; 158*54c4cad9SYuval Mintz u32 tb_id; 159*54c4cad9SYuval Mintz }; 160*54c4cad9SYuval Mintz 161*54c4cad9SYuval Mintz static inline int mr_call_mfc_notifier(struct notifier_block *nb, 162*54c4cad9SYuval Mintz struct net *net, 163*54c4cad9SYuval Mintz unsigned short family, 164*54c4cad9SYuval Mintz enum fib_event_type event_type, 165*54c4cad9SYuval Mintz struct mr_mfc *mfc, u32 tb_id) 166*54c4cad9SYuval Mintz { 167*54c4cad9SYuval Mintz struct mfc_entry_notifier_info info = { 168*54c4cad9SYuval Mintz .info = { 169*54c4cad9SYuval Mintz .family = family, 170*54c4cad9SYuval Mintz .net = net, 171*54c4cad9SYuval Mintz }, 172*54c4cad9SYuval Mintz .mfc = mfc, 173*54c4cad9SYuval Mintz .tb_id = tb_id 174*54c4cad9SYuval Mintz }; 175*54c4cad9SYuval Mintz 176*54c4cad9SYuval Mintz return call_fib_notifier(nb, net, event_type, &info.info); 177*54c4cad9SYuval Mintz } 178*54c4cad9SYuval Mintz 179*54c4cad9SYuval Mintz static inline int mr_call_mfc_notifiers(struct net *net, 180*54c4cad9SYuval Mintz unsigned short family, 181*54c4cad9SYuval Mintz enum fib_event_type event_type, 182*54c4cad9SYuval Mintz struct mr_mfc *mfc, u32 tb_id, 183*54c4cad9SYuval Mintz unsigned int *ipmr_seq) 184*54c4cad9SYuval Mintz { 185*54c4cad9SYuval Mintz struct mfc_entry_notifier_info info = { 186*54c4cad9SYuval Mintz .info = { 187*54c4cad9SYuval Mintz .family = family, 188*54c4cad9SYuval Mintz .net = net, 189*54c4cad9SYuval Mintz }, 190*54c4cad9SYuval Mintz .mfc = mfc, 191*54c4cad9SYuval Mintz .tb_id = tb_id 192*54c4cad9SYuval Mintz }; 193*54c4cad9SYuval Mintz 194*54c4cad9SYuval Mintz ASSERT_RTNL(); 195*54c4cad9SYuval Mintz (*ipmr_seq)++; 196*54c4cad9SYuval Mintz return call_fib_notifiers(net, event_type, &info.info); 197*54c4cad9SYuval Mintz } 198*54c4cad9SYuval Mintz 199845c9a7aSYuval Mintz struct mr_table; 200845c9a7aSYuval Mintz 201845c9a7aSYuval Mintz /** 202845c9a7aSYuval Mintz * struct mr_table_ops - callbacks and info for protocol-specific ops 203845c9a7aSYuval Mintz * @rht_params: parameters for accessing the MFC hash 204845c9a7aSYuval Mintz * @cmparg_any: a hash key to be used for matching on (*,*) routes 205845c9a7aSYuval Mintz */ 206845c9a7aSYuval Mintz struct mr_table_ops { 207845c9a7aSYuval Mintz const struct rhashtable_params *rht_params; 208845c9a7aSYuval Mintz void *cmparg_any; 209845c9a7aSYuval Mintz }; 210845c9a7aSYuval Mintz 211494fff56SYuval Mintz /** 212b70432f7SYuval Mintz * struct mr_table - a multicast routing table 213b70432f7SYuval Mintz * @list: entry within a list of multicast routing tables 214b70432f7SYuval Mintz * @net: net where this table belongs 215845c9a7aSYuval Mintz * @ops: protocol specific operations 216b70432f7SYuval Mintz * @id: identifier of the table 217b70432f7SYuval Mintz * @mroute_sk: socket associated with the table 218b70432f7SYuval Mintz * @ipmr_expire_timer: timer for handling unresolved routes 219b70432f7SYuval Mintz * @mfc_unres_queue: list of unresolved MFC entries 220b70432f7SYuval Mintz * @vif_table: array containing all possible vifs 221b70432f7SYuval Mintz * @mfc_hash: Hash table of all resolved routes for easy lookup 222b70432f7SYuval Mintz * @mfc_cache_list: list of resovled routes for possible traversal 223b70432f7SYuval Mintz * @maxvif: Identifier of highest value vif currently in use 224b70432f7SYuval Mintz * @cache_resolve_queue_len: current size of unresolved queue 225b70432f7SYuval Mintz * @mroute_do_assert: Whether to inform userspace on wrong ingress 226b70432f7SYuval Mintz * @mroute_do_pim: Whether to receive IGMP PIMv1 227b70432f7SYuval Mintz * @mroute_reg_vif_num: PIM-device vif index 228b70432f7SYuval Mintz */ 229b70432f7SYuval Mintz struct mr_table { 230b70432f7SYuval Mintz struct list_head list; 231b70432f7SYuval Mintz possible_net_t net; 232845c9a7aSYuval Mintz struct mr_table_ops ops; 233b70432f7SYuval Mintz u32 id; 234b70432f7SYuval Mintz struct sock __rcu *mroute_sk; 235b70432f7SYuval Mintz struct timer_list ipmr_expire_timer; 236b70432f7SYuval Mintz struct list_head mfc_unres_queue; 237b70432f7SYuval Mintz struct vif_device vif_table[MAXVIFS]; 238b70432f7SYuval Mintz struct rhltable mfc_hash; 239b70432f7SYuval Mintz struct list_head mfc_cache_list; 240b70432f7SYuval Mintz int maxvif; 241b70432f7SYuval Mintz atomic_t cache_resolve_queue_len; 242b70432f7SYuval Mintz bool mroute_do_assert; 243b70432f7SYuval Mintz bool mroute_do_pim; 244b70432f7SYuval Mintz int mroute_reg_vif_num; 245b70432f7SYuval Mintz }; 246b70432f7SYuval Mintz 2476853f21fSYuval Mintz #ifdef CONFIG_IP_MROUTE_COMMON 2486853f21fSYuval Mintz void vif_device_init(struct vif_device *v, 2496853f21fSYuval Mintz struct net_device *dev, 2506853f21fSYuval Mintz unsigned long rate_limit, 2516853f21fSYuval Mintz unsigned char threshold, 2526853f21fSYuval Mintz unsigned short flags, 2536853f21fSYuval Mintz unsigned short get_iflink_mask); 2540bbbf0e7SYuval Mintz 2550bbbf0e7SYuval Mintz struct mr_table * 2560bbbf0e7SYuval Mintz mr_table_alloc(struct net *net, u32 id, 257845c9a7aSYuval Mintz struct mr_table_ops *ops, 2580bbbf0e7SYuval Mintz void (*expire_func)(struct timer_list *t), 2590bbbf0e7SYuval Mintz void (*table_set)(struct mr_table *mrt, 2600bbbf0e7SYuval Mintz struct net *net)); 261845c9a7aSYuval Mintz 262845c9a7aSYuval Mintz /* These actually return 'struct mr_mfc *', but to avoid need for explicit 263845c9a7aSYuval Mintz * castings they simply return void. 264845c9a7aSYuval Mintz */ 265845c9a7aSYuval Mintz void *mr_mfc_find_parent(struct mr_table *mrt, 266845c9a7aSYuval Mintz void *hasharg, int parent); 267845c9a7aSYuval Mintz void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi); 268845c9a7aSYuval Mintz void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg); 269845c9a7aSYuval Mintz 2707b0db857SYuval Mintz int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, 2717b0db857SYuval Mintz struct mr_mfc *c, struct rtmsg *rtm); 2727b0db857SYuval Mintz int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb, 2737b0db857SYuval Mintz struct mr_table *(*iter)(struct net *net, 2747b0db857SYuval Mintz struct mr_table *mrt), 2757b0db857SYuval Mintz int (*fill)(struct mr_table *mrt, 2767b0db857SYuval Mintz struct sk_buff *skb, 2777b0db857SYuval Mintz u32 portid, u32 seq, struct mr_mfc *c, 2787b0db857SYuval Mintz int cmd, int flags), 2797b0db857SYuval Mintz spinlock_t *lock); 2806853f21fSYuval Mintz #else 2816853f21fSYuval Mintz static inline void vif_device_init(struct vif_device *v, 2826853f21fSYuval Mintz struct net_device *dev, 2836853f21fSYuval Mintz unsigned long rate_limit, 2846853f21fSYuval Mintz unsigned char threshold, 2856853f21fSYuval Mintz unsigned short flags, 2866853f21fSYuval Mintz unsigned short get_iflink_mask) 2876853f21fSYuval Mintz { 2886853f21fSYuval Mintz } 2890bbbf0e7SYuval Mintz 290845c9a7aSYuval Mintz static inline void * 2910bbbf0e7SYuval Mintz mr_table_alloc(struct net *net, u32 id, 292845c9a7aSYuval Mintz struct mr_table_ops *ops, 2930bbbf0e7SYuval Mintz void (*expire_func)(struct timer_list *t), 2940bbbf0e7SYuval Mintz void (*table_set)(struct mr_table *mrt, 2950bbbf0e7SYuval Mintz struct net *net)) 2960bbbf0e7SYuval Mintz { 2970bbbf0e7SYuval Mintz return NULL; 2980bbbf0e7SYuval Mintz } 299845c9a7aSYuval Mintz 300845c9a7aSYuval Mintz static inline void *mr_mfc_find_parent(struct mr_table *mrt, 301845c9a7aSYuval Mintz void *hasharg, int parent) 302845c9a7aSYuval Mintz { 303845c9a7aSYuval Mintz return NULL; 304845c9a7aSYuval Mintz } 305845c9a7aSYuval Mintz 306845c9a7aSYuval Mintz static inline void *mr_mfc_find_any_parent(struct mr_table *mrt, 307845c9a7aSYuval Mintz int vifi) 308845c9a7aSYuval Mintz { 309845c9a7aSYuval Mintz return NULL; 310845c9a7aSYuval Mintz } 311845c9a7aSYuval Mintz 312845c9a7aSYuval Mintz static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt, 313845c9a7aSYuval Mintz int vifi, void *hasharg) 314845c9a7aSYuval Mintz { 315845c9a7aSYuval Mintz return NULL; 316845c9a7aSYuval Mintz } 3177b0db857SYuval Mintz 3187b0db857SYuval Mintz static inline int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, 3197b0db857SYuval Mintz struct mr_mfc *c, struct rtmsg *rtm) 3207b0db857SYuval Mintz { 3217b0db857SYuval Mintz return -EINVAL; 3227b0db857SYuval Mintz } 3237b0db857SYuval Mintz 3247b0db857SYuval Mintz static inline int 3257b0db857SYuval Mintz mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb, 3267b0db857SYuval Mintz struct mr_table *(*iter)(struct net *net, 3277b0db857SYuval Mintz struct mr_table *mrt), 3287b0db857SYuval Mintz int (*fill)(struct mr_table *mrt, 3297b0db857SYuval Mintz struct sk_buff *skb, 3307b0db857SYuval Mintz u32 portid, u32 seq, struct mr_mfc *c, 3317b0db857SYuval Mintz int cmd, int flags), 3327b0db857SYuval Mintz spinlock_t *lock) 3337b0db857SYuval Mintz { 3347b0db857SYuval Mintz return -EINVAL; 3357b0db857SYuval Mintz } 3366853f21fSYuval Mintz #endif 337845c9a7aSYuval Mintz 338845c9a7aSYuval Mintz static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg) 339845c9a7aSYuval Mintz { 340845c9a7aSYuval Mintz return mr_mfc_find_parent(mrt, hasharg, -1); 341845c9a7aSYuval Mintz } 342c8d61968SYuval Mintz 343c8d61968SYuval Mintz #ifdef CONFIG_PROC_FS 3443feda6b4SYuval Mintz struct mr_vif_iter { 3453feda6b4SYuval Mintz struct seq_net_private p; 3463feda6b4SYuval Mintz struct mr_table *mrt; 3473feda6b4SYuval Mintz int ct; 3483feda6b4SYuval Mintz }; 3493feda6b4SYuval Mintz 350c8d61968SYuval Mintz struct mr_mfc_iter { 351c8d61968SYuval Mintz struct seq_net_private p; 352c8d61968SYuval Mintz struct mr_table *mrt; 353c8d61968SYuval Mintz struct list_head *cache; 354c8d61968SYuval Mintz 355c8d61968SYuval Mintz /* Lock protecting the mr_table's unresolved queue */ 356c8d61968SYuval Mintz spinlock_t *lock; 357c8d61968SYuval Mintz }; 358c8d61968SYuval Mintz 359c8d61968SYuval Mintz #ifdef CONFIG_IP_MROUTE_COMMON 3603feda6b4SYuval Mintz void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos); 3613feda6b4SYuval Mintz void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos); 3623feda6b4SYuval Mintz 3633feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 3643feda6b4SYuval Mintz { 3653feda6b4SYuval Mintz return *pos ? mr_vif_seq_idx(seq_file_net(seq), 3663feda6b4SYuval Mintz seq->private, *pos - 1) 3673feda6b4SYuval Mintz : SEQ_START_TOKEN; 3683feda6b4SYuval Mintz } 3693feda6b4SYuval Mintz 370c8d61968SYuval Mintz /* These actually return 'struct mr_mfc *', but to avoid need for explicit 371c8d61968SYuval Mintz * castings they simply return void. 372c8d61968SYuval Mintz */ 373c8d61968SYuval Mintz void *mr_mfc_seq_idx(struct net *net, 374c8d61968SYuval Mintz struct mr_mfc_iter *it, loff_t pos); 375c8d61968SYuval Mintz void *mr_mfc_seq_next(struct seq_file *seq, void *v, 376c8d61968SYuval Mintz loff_t *pos); 377c8d61968SYuval Mintz 378c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos, 379c8d61968SYuval Mintz struct mr_table *mrt, spinlock_t *lock) 380c8d61968SYuval Mintz { 381c8d61968SYuval Mintz struct mr_mfc_iter *it = seq->private; 382c8d61968SYuval Mintz 383c8d61968SYuval Mintz it->mrt = mrt; 384c8d61968SYuval Mintz it->cache = NULL; 385c8d61968SYuval Mintz it->lock = lock; 386c8d61968SYuval Mintz 387c8d61968SYuval Mintz return *pos ? mr_mfc_seq_idx(seq_file_net(seq), 388c8d61968SYuval Mintz seq->private, *pos - 1) 389c8d61968SYuval Mintz : SEQ_START_TOKEN; 390c8d61968SYuval Mintz } 391c8d61968SYuval Mintz 392c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v) 393c8d61968SYuval Mintz { 394c8d61968SYuval Mintz struct mr_mfc_iter *it = seq->private; 395c8d61968SYuval Mintz struct mr_table *mrt = it->mrt; 396c8d61968SYuval Mintz 397c8d61968SYuval Mintz if (it->cache == &mrt->mfc_unres_queue) 398c8d61968SYuval Mintz spin_unlock_bh(it->lock); 399c8d61968SYuval Mintz else if (it->cache == &mrt->mfc_cache_list) 400c8d61968SYuval Mintz rcu_read_unlock(); 401c8d61968SYuval Mintz } 402c8d61968SYuval Mintz #else 4033feda6b4SYuval Mintz static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, 4043feda6b4SYuval Mintz loff_t pos) 4053feda6b4SYuval Mintz { 4063feda6b4SYuval Mintz return NULL; 4073feda6b4SYuval Mintz } 4083feda6b4SYuval Mintz 4093feda6b4SYuval Mintz static inline void *mr_vif_seq_next(struct seq_file *seq, 4103feda6b4SYuval Mintz void *v, loff_t *pos) 4113feda6b4SYuval Mintz { 4123feda6b4SYuval Mintz return NULL; 4133feda6b4SYuval Mintz } 4143feda6b4SYuval Mintz 4153feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 4163feda6b4SYuval Mintz { 4173feda6b4SYuval Mintz return NULL; 4183feda6b4SYuval Mintz } 4193feda6b4SYuval Mintz 420c8d61968SYuval Mintz static inline void *mr_mfc_seq_idx(struct net *net, 421c8d61968SYuval Mintz struct mr_mfc_iter *it, loff_t pos) 422c8d61968SYuval Mintz { 423c8d61968SYuval Mintz return NULL; 424c8d61968SYuval Mintz } 425c8d61968SYuval Mintz 426c8d61968SYuval Mintz static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v, 427c8d61968SYuval Mintz loff_t *pos) 428c8d61968SYuval Mintz { 429c8d61968SYuval Mintz return NULL; 430c8d61968SYuval Mintz } 431c8d61968SYuval Mintz 432c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos, 433c8d61968SYuval Mintz struct mr_table *mrt, spinlock_t *lock) 434c8d61968SYuval Mintz { 435c8d61968SYuval Mintz return NULL; 436c8d61968SYuval Mintz } 437c8d61968SYuval Mintz 438c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v) 439c8d61968SYuval Mintz { 440c8d61968SYuval Mintz } 441c8d61968SYuval Mintz #endif 442c8d61968SYuval Mintz #endif 4436853f21fSYuval Mintz #endif 444