xref: /linux/include/linux/mroute_base.h (revision cdc9f9443b5c3a61c7cec807965054ee1fd29acf)
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 
15554c4cad9SYuval Mintz struct mfc_entry_notifier_info {
15654c4cad9SYuval Mintz 	struct fib_notifier_info info;
15754c4cad9SYuval Mintz 	struct mr_mfc *mfc;
15854c4cad9SYuval Mintz 	u32 tb_id;
15954c4cad9SYuval Mintz };
16054c4cad9SYuval Mintz 
16154c4cad9SYuval Mintz static inline int mr_call_mfc_notifier(struct notifier_block *nb,
16254c4cad9SYuval Mintz 				       struct net *net,
16354c4cad9SYuval Mintz 				       unsigned short family,
16454c4cad9SYuval Mintz 				       enum fib_event_type event_type,
16554c4cad9SYuval Mintz 				       struct mr_mfc *mfc, u32 tb_id)
16654c4cad9SYuval Mintz {
16754c4cad9SYuval Mintz 	struct mfc_entry_notifier_info info = {
16854c4cad9SYuval Mintz 		.info = {
16954c4cad9SYuval Mintz 			.family = family,
17054c4cad9SYuval Mintz 			.net = net,
17154c4cad9SYuval Mintz 		},
17254c4cad9SYuval Mintz 		.mfc = mfc,
17354c4cad9SYuval Mintz 		.tb_id = tb_id
17454c4cad9SYuval Mintz 	};
17554c4cad9SYuval Mintz 
17654c4cad9SYuval Mintz 	return call_fib_notifier(nb, net, event_type, &info.info);
17754c4cad9SYuval Mintz }
17854c4cad9SYuval Mintz 
17954c4cad9SYuval Mintz static inline int mr_call_mfc_notifiers(struct net *net,
18054c4cad9SYuval Mintz 					unsigned short family,
18154c4cad9SYuval Mintz 					enum fib_event_type event_type,
18254c4cad9SYuval Mintz 					struct mr_mfc *mfc, u32 tb_id,
18354c4cad9SYuval Mintz 					unsigned int *ipmr_seq)
18454c4cad9SYuval Mintz {
18554c4cad9SYuval Mintz 	struct mfc_entry_notifier_info info = {
18654c4cad9SYuval Mintz 		.info = {
18754c4cad9SYuval Mintz 			.family = family,
18854c4cad9SYuval Mintz 			.net = net,
18954c4cad9SYuval Mintz 		},
19054c4cad9SYuval Mintz 		.mfc = mfc,
19154c4cad9SYuval Mintz 		.tb_id = tb_id
19254c4cad9SYuval Mintz 	};
19354c4cad9SYuval Mintz 
19454c4cad9SYuval Mintz 	ASSERT_RTNL();
19554c4cad9SYuval Mintz 	(*ipmr_seq)++;
19654c4cad9SYuval Mintz 	return call_fib_notifiers(net, event_type, &info.info);
19754c4cad9SYuval Mintz }
19854c4cad9SYuval 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);
280*cdc9f944SYuval Mintz 
281*cdc9f944SYuval Mintz int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family,
282*cdc9f944SYuval Mintz 	    int (*rules_dump)(struct net *net,
283*cdc9f944SYuval Mintz 			      struct notifier_block *nb),
284*cdc9f944SYuval Mintz 	    struct mr_table *(*mr_iter)(struct net *net,
285*cdc9f944SYuval Mintz 					struct mr_table *mrt),
286*cdc9f944SYuval Mintz 	    rwlock_t *mrt_lock);
2876853f21fSYuval Mintz #else
2886853f21fSYuval Mintz static inline void vif_device_init(struct vif_device *v,
2896853f21fSYuval Mintz 				   struct net_device *dev,
2906853f21fSYuval Mintz 				   unsigned long rate_limit,
2916853f21fSYuval Mintz 				   unsigned char threshold,
2926853f21fSYuval Mintz 				   unsigned short flags,
2936853f21fSYuval Mintz 				   unsigned short get_iflink_mask)
2946853f21fSYuval Mintz {
2956853f21fSYuval Mintz }
2960bbbf0e7SYuval Mintz 
297845c9a7aSYuval Mintz static inline void *
2980bbbf0e7SYuval Mintz mr_table_alloc(struct net *net, u32 id,
299845c9a7aSYuval Mintz 	       struct mr_table_ops *ops,
3000bbbf0e7SYuval Mintz 	       void (*expire_func)(struct timer_list *t),
3010bbbf0e7SYuval Mintz 	       void (*table_set)(struct mr_table *mrt,
3020bbbf0e7SYuval Mintz 				 struct net *net))
3030bbbf0e7SYuval Mintz {
3040bbbf0e7SYuval Mintz 	return NULL;
3050bbbf0e7SYuval Mintz }
306845c9a7aSYuval Mintz 
307845c9a7aSYuval Mintz static inline void *mr_mfc_find_parent(struct mr_table *mrt,
308845c9a7aSYuval Mintz 				       void *hasharg, int parent)
309845c9a7aSYuval Mintz {
310845c9a7aSYuval Mintz 	return NULL;
311845c9a7aSYuval Mintz }
312845c9a7aSYuval Mintz 
313845c9a7aSYuval Mintz static inline void *mr_mfc_find_any_parent(struct mr_table *mrt,
314845c9a7aSYuval Mintz 					   int vifi)
315845c9a7aSYuval Mintz {
316845c9a7aSYuval Mintz 	return NULL;
317845c9a7aSYuval Mintz }
318845c9a7aSYuval Mintz 
319845c9a7aSYuval Mintz static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt,
320845c9a7aSYuval Mintz 					     int vifi, void *hasharg)
321845c9a7aSYuval Mintz {
322845c9a7aSYuval Mintz 	return NULL;
323845c9a7aSYuval Mintz }
3247b0db857SYuval Mintz 
3257b0db857SYuval Mintz static inline int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
3267b0db857SYuval Mintz 				 struct mr_mfc *c, struct rtmsg *rtm)
3277b0db857SYuval Mintz {
3287b0db857SYuval Mintz 	return -EINVAL;
3297b0db857SYuval Mintz }
3307b0db857SYuval Mintz 
3317b0db857SYuval Mintz static inline int
3327b0db857SYuval Mintz mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
3337b0db857SYuval Mintz 		 struct mr_table *(*iter)(struct net *net,
3347b0db857SYuval Mintz 					  struct mr_table *mrt),
3357b0db857SYuval Mintz 		 int (*fill)(struct mr_table *mrt,
3367b0db857SYuval Mintz 			     struct sk_buff *skb,
3377b0db857SYuval Mintz 			     u32 portid, u32 seq, struct mr_mfc *c,
3387b0db857SYuval Mintz 			     int cmd, int flags),
3397b0db857SYuval Mintz 		 spinlock_t *lock)
3407b0db857SYuval Mintz {
3417b0db857SYuval Mintz 	return -EINVAL;
3427b0db857SYuval Mintz }
343*cdc9f944SYuval Mintz 
344*cdc9f944SYuval Mintz static inline int mr_dump(struct net *net, struct notifier_block *nb,
345*cdc9f944SYuval Mintz 			  unsigned short family,
346*cdc9f944SYuval Mintz 			  int (*rules_dump)(struct net *net,
347*cdc9f944SYuval Mintz 					    struct notifier_block *nb),
348*cdc9f944SYuval Mintz 			  struct mr_table *(*mr_iter)(struct net *net,
349*cdc9f944SYuval Mintz 						      struct mr_table *mrt),
350*cdc9f944SYuval Mintz 			  rwlock_t *mrt_lock)
351*cdc9f944SYuval Mintz {
352*cdc9f944SYuval Mintz 	return -EINVAL;
353*cdc9f944SYuval Mintz }
3546853f21fSYuval Mintz #endif
355845c9a7aSYuval Mintz 
356845c9a7aSYuval Mintz static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg)
357845c9a7aSYuval Mintz {
358845c9a7aSYuval Mintz 	return mr_mfc_find_parent(mrt, hasharg, -1);
359845c9a7aSYuval Mintz }
360c8d61968SYuval Mintz 
361c8d61968SYuval Mintz #ifdef CONFIG_PROC_FS
3623feda6b4SYuval Mintz struct mr_vif_iter {
3633feda6b4SYuval Mintz 	struct seq_net_private p;
3643feda6b4SYuval Mintz 	struct mr_table *mrt;
3653feda6b4SYuval Mintz 	int ct;
3663feda6b4SYuval Mintz };
3673feda6b4SYuval Mintz 
368c8d61968SYuval Mintz struct mr_mfc_iter {
369c8d61968SYuval Mintz 	struct seq_net_private p;
370c8d61968SYuval Mintz 	struct mr_table *mrt;
371c8d61968SYuval Mintz 	struct list_head *cache;
372c8d61968SYuval Mintz 
373c8d61968SYuval Mintz 	/* Lock protecting the mr_table's unresolved queue */
374c8d61968SYuval Mintz 	spinlock_t *lock;
375c8d61968SYuval Mintz };
376c8d61968SYuval Mintz 
377c8d61968SYuval Mintz #ifdef CONFIG_IP_MROUTE_COMMON
3783feda6b4SYuval Mintz void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos);
3793feda6b4SYuval Mintz void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos);
3803feda6b4SYuval Mintz 
3813feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
3823feda6b4SYuval Mintz {
3833feda6b4SYuval Mintz 	return *pos ? mr_vif_seq_idx(seq_file_net(seq),
3843feda6b4SYuval Mintz 				     seq->private, *pos - 1)
3853feda6b4SYuval Mintz 		    : SEQ_START_TOKEN;
3863feda6b4SYuval Mintz }
3873feda6b4SYuval Mintz 
388c8d61968SYuval Mintz /* These actually return 'struct mr_mfc *', but to avoid need for explicit
389c8d61968SYuval Mintz  * castings they simply return void.
390c8d61968SYuval Mintz  */
391c8d61968SYuval Mintz void *mr_mfc_seq_idx(struct net *net,
392c8d61968SYuval Mintz 		     struct mr_mfc_iter *it, loff_t pos);
393c8d61968SYuval Mintz void *mr_mfc_seq_next(struct seq_file *seq, void *v,
394c8d61968SYuval Mintz 		      loff_t *pos);
395c8d61968SYuval Mintz 
396c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
397c8d61968SYuval Mintz 				     struct mr_table *mrt, spinlock_t *lock)
398c8d61968SYuval Mintz {
399c8d61968SYuval Mintz 	struct mr_mfc_iter *it = seq->private;
400c8d61968SYuval Mintz 
401c8d61968SYuval Mintz 	it->mrt = mrt;
402c8d61968SYuval Mintz 	it->cache = NULL;
403c8d61968SYuval Mintz 	it->lock = lock;
404c8d61968SYuval Mintz 
405c8d61968SYuval Mintz 	return *pos ? mr_mfc_seq_idx(seq_file_net(seq),
406c8d61968SYuval Mintz 				     seq->private, *pos - 1)
407c8d61968SYuval Mintz 		    : SEQ_START_TOKEN;
408c8d61968SYuval Mintz }
409c8d61968SYuval Mintz 
410c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
411c8d61968SYuval Mintz {
412c8d61968SYuval Mintz 	struct mr_mfc_iter *it = seq->private;
413c8d61968SYuval Mintz 	struct mr_table *mrt = it->mrt;
414c8d61968SYuval Mintz 
415c8d61968SYuval Mintz 	if (it->cache == &mrt->mfc_unres_queue)
416c8d61968SYuval Mintz 		spin_unlock_bh(it->lock);
417c8d61968SYuval Mintz 	else if (it->cache == &mrt->mfc_cache_list)
418c8d61968SYuval Mintz 		rcu_read_unlock();
419c8d61968SYuval Mintz }
420c8d61968SYuval Mintz #else
4213feda6b4SYuval Mintz static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter,
4223feda6b4SYuval Mintz 				   loff_t pos)
4233feda6b4SYuval Mintz {
4243feda6b4SYuval Mintz 	return NULL;
4253feda6b4SYuval Mintz }
4263feda6b4SYuval Mintz 
4273feda6b4SYuval Mintz static inline void *mr_vif_seq_next(struct seq_file *seq,
4283feda6b4SYuval Mintz 				    void *v, loff_t *pos)
4293feda6b4SYuval Mintz {
4303feda6b4SYuval Mintz 	return NULL;
4313feda6b4SYuval Mintz }
4323feda6b4SYuval Mintz 
4333feda6b4SYuval Mintz static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
4343feda6b4SYuval Mintz {
4353feda6b4SYuval Mintz 	return NULL;
4363feda6b4SYuval Mintz }
4373feda6b4SYuval Mintz 
438c8d61968SYuval Mintz static inline void *mr_mfc_seq_idx(struct net *net,
439c8d61968SYuval Mintz 				   struct mr_mfc_iter *it, loff_t pos)
440c8d61968SYuval Mintz {
441c8d61968SYuval Mintz 	return NULL;
442c8d61968SYuval Mintz }
443c8d61968SYuval Mintz 
444c8d61968SYuval Mintz static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v,
445c8d61968SYuval Mintz 				    loff_t *pos)
446c8d61968SYuval Mintz {
447c8d61968SYuval Mintz 	return NULL;
448c8d61968SYuval Mintz }
449c8d61968SYuval Mintz 
450c8d61968SYuval Mintz static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
451c8d61968SYuval Mintz 				     struct mr_table *mrt, spinlock_t *lock)
452c8d61968SYuval Mintz {
453c8d61968SYuval Mintz 	return NULL;
454c8d61968SYuval Mintz }
455c8d61968SYuval Mintz 
456c8d61968SYuval Mintz static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
457c8d61968SYuval Mintz {
458c8d61968SYuval Mintz }
459c8d61968SYuval Mintz #endif
460c8d61968SYuval Mintz #endif
4616853f21fSYuval Mintz #endif
462