xref: /linux/include/linux/mroute_base.h (revision 3feda6b46f734704840685a62b645cbe4efb810c)
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