1  #ifndef __LINUX_MROUTE_BASE_H
2  #define __LINUX_MROUTE_BASE_H
3  
4  #include <linux/netdevice.h>
5  #include <linux/rhashtable-types.h>
6  #include <linux/spinlock.h>
7  #include <net/net_namespace.h>
8  #include <net/sock.h>
9  #include <net/fib_notifier.h>
10  #include <net/ip_fib.h>
11  
12  /**
13   * struct vif_device - interface representor for multicast routing
14   * @dev: network device being used
15   * @dev_tracker: refcount tracker for @dev reference
16   * @bytes_in: statistic; bytes ingressing
17   * @bytes_out: statistic; bytes egresing
18   * @pkt_in: statistic; packets ingressing
19   * @pkt_out: statistic; packets egressing
20   * @rate_limit: Traffic shaping (NI)
21   * @threshold: TTL threshold
22   * @flags: Control flags
23   * @link: Physical interface index
24   * @dev_parent_id: device parent id
25   * @local: Local address
26   * @remote: Remote address for tunnels
27   */
28  struct vif_device {
29  	struct net_device __rcu *dev;
30  	netdevice_tracker dev_tracker;
31  	unsigned long bytes_in, bytes_out;
32  	unsigned long pkt_in, pkt_out;
33  	unsigned long rate_limit;
34  	unsigned char threshold;
35  	unsigned short flags;
36  	int link;
37  
38  	/* Currently only used by ipmr */
39  	struct netdev_phys_item_id dev_parent_id;
40  	__be32 local, remote;
41  };
42  
43  struct vif_entry_notifier_info {
44  	struct fib_notifier_info info;
45  	struct net_device *dev;
46  	unsigned short vif_index;
47  	unsigned short vif_flags;
48  	u32 tb_id;
49  };
50  
mr_call_vif_notifier(struct notifier_block * nb,unsigned short family,enum fib_event_type event_type,struct vif_device * vif,struct net_device * vif_dev,unsigned short vif_index,u32 tb_id,struct netlink_ext_ack * extack)51  static inline int mr_call_vif_notifier(struct notifier_block *nb,
52  				       unsigned short family,
53  				       enum fib_event_type event_type,
54  				       struct vif_device *vif,
55  				       struct net_device *vif_dev,
56  				       unsigned short vif_index, u32 tb_id,
57  				       struct netlink_ext_ack *extack)
58  {
59  	struct vif_entry_notifier_info info = {
60  		.info = {
61  			.family = family,
62  			.extack = extack,
63  		},
64  		.dev = vif_dev,
65  		.vif_index = vif_index,
66  		.vif_flags = vif->flags,
67  		.tb_id = tb_id,
68  	};
69  
70  	return call_fib_notifier(nb, event_type, &info.info);
71  }
72  
mr_call_vif_notifiers(struct net * net,unsigned short family,enum fib_event_type event_type,struct vif_device * vif,struct net_device * vif_dev,unsigned short vif_index,u32 tb_id,unsigned int * ipmr_seq)73  static inline int mr_call_vif_notifiers(struct net *net,
74  					unsigned short family,
75  					enum fib_event_type event_type,
76  					struct vif_device *vif,
77  					struct net_device *vif_dev,
78  					unsigned short vif_index, u32 tb_id,
79  					unsigned int *ipmr_seq)
80  {
81  	struct vif_entry_notifier_info info = {
82  		.info = {
83  			.family = family,
84  		},
85  		.dev = vif_dev,
86  		.vif_index = vif_index,
87  		.vif_flags = vif->flags,
88  		.tb_id = tb_id,
89  	};
90  
91  	ASSERT_RTNL();
92  	(*ipmr_seq)++;
93  	return call_fib_notifiers(net, event_type, &info.info);
94  }
95  
96  #ifndef MAXVIFS
97  /* This one is nasty; value is defined in uapi using different symbols for
98   * mroute and morute6 but both map into same 32.
99   */
100  #define MAXVIFS	32
101  #endif
102  
103  /* Note: This helper is deprecated. */
104  #define VIF_EXISTS(_mrt, _idx) (!!rcu_access_pointer((_mrt)->vif_table[_idx].dev))
105  
106  /* mfc_flags:
107   * MFC_STATIC - the entry was added statically (not by a routing daemon)
108   * MFC_OFFLOAD - the entry was offloaded to the hardware
109   */
110  enum {
111  	MFC_STATIC = BIT(0),
112  	MFC_OFFLOAD = BIT(1),
113  };
114  
115  /**
116   * struct mr_mfc - common multicast routing entries
117   * @mnode: rhashtable list
118   * @mfc_parent: source interface (iif)
119   * @mfc_flags: entry flags
120   * @expires: unresolved entry expire time
121   * @unresolved: unresolved cached skbs
122   * @last_assert: time of last assert
123   * @minvif: minimum VIF id
124   * @maxvif: maximum VIF id
125   * @bytes: bytes that have passed for this entry
126   * @pkt: packets that have passed for this entry
127   * @wrong_if: number of wrong source interface hits
128   * @lastuse: time of last use of the group (traffic or update)
129   * @ttls: OIF TTL threshold array
130   * @refcount: reference count for this entry
131   * @list: global entry list
132   * @rcu: used for entry destruction
133   * @free: Operation used for freeing an entry under RCU
134   */
135  struct mr_mfc {
136  	struct rhlist_head mnode;
137  	unsigned short mfc_parent;
138  	int mfc_flags;
139  
140  	union {
141  		struct {
142  			unsigned long expires;
143  			struct sk_buff_head unresolved;
144  		} unres;
145  		struct {
146  			unsigned long last_assert;
147  			int minvif;
148  			int maxvif;
149  			unsigned long bytes;
150  			unsigned long pkt;
151  			unsigned long wrong_if;
152  			unsigned long lastuse;
153  			unsigned char ttls[MAXVIFS];
154  			refcount_t refcount;
155  		} res;
156  	} mfc_un;
157  	struct list_head list;
158  	struct rcu_head	rcu;
159  	void (*free)(struct rcu_head *head);
160  };
161  
mr_cache_put(struct mr_mfc * c)162  static inline void mr_cache_put(struct mr_mfc *c)
163  {
164  	if (refcount_dec_and_test(&c->mfc_un.res.refcount))
165  		call_rcu(&c->rcu, c->free);
166  }
167  
mr_cache_hold(struct mr_mfc * c)168  static inline void mr_cache_hold(struct mr_mfc *c)
169  {
170  	refcount_inc(&c->mfc_un.res.refcount);
171  }
172  
173  struct mfc_entry_notifier_info {
174  	struct fib_notifier_info info;
175  	struct mr_mfc *mfc;
176  	u32 tb_id;
177  };
178  
mr_call_mfc_notifier(struct notifier_block * nb,unsigned short family,enum fib_event_type event_type,struct mr_mfc * mfc,u32 tb_id,struct netlink_ext_ack * extack)179  static inline int mr_call_mfc_notifier(struct notifier_block *nb,
180  				       unsigned short family,
181  				       enum fib_event_type event_type,
182  				       struct mr_mfc *mfc, u32 tb_id,
183  				       struct netlink_ext_ack *extack)
184  {
185  	struct mfc_entry_notifier_info info = {
186  		.info = {
187  			.family = family,
188  			.extack = extack,
189  		},
190  		.mfc = mfc,
191  		.tb_id = tb_id
192  	};
193  
194  	return call_fib_notifier(nb, event_type, &info.info);
195  }
196  
mr_call_mfc_notifiers(struct net * net,unsigned short family,enum fib_event_type event_type,struct mr_mfc * mfc,u32 tb_id,unsigned int * ipmr_seq)197  static inline int mr_call_mfc_notifiers(struct net *net,
198  					unsigned short family,
199  					enum fib_event_type event_type,
200  					struct mr_mfc *mfc, u32 tb_id,
201  					unsigned int *ipmr_seq)
202  {
203  	struct mfc_entry_notifier_info info = {
204  		.info = {
205  			.family = family,
206  		},
207  		.mfc = mfc,
208  		.tb_id = tb_id
209  	};
210  
211  	ASSERT_RTNL();
212  	(*ipmr_seq)++;
213  	return call_fib_notifiers(net, event_type, &info.info);
214  }
215  
216  struct mr_table;
217  
218  /**
219   * struct mr_table_ops - callbacks and info for protocol-specific ops
220   * @rht_params: parameters for accessing the MFC hash
221   * @cmparg_any: a hash key to be used for matching on (*,*) routes
222   */
223  struct mr_table_ops {
224  	const struct rhashtable_params *rht_params;
225  	void *cmparg_any;
226  };
227  
228  /**
229   * struct mr_table - a multicast routing table
230   * @list: entry within a list of multicast routing tables
231   * @net: net where this table belongs
232   * @ops: protocol specific operations
233   * @id: identifier of the table
234   * @mroute_sk: socket associated with the table
235   * @ipmr_expire_timer: timer for handling unresolved routes
236   * @mfc_unres_queue: list of unresolved MFC entries
237   * @vif_table: array containing all possible vifs
238   * @mfc_hash: Hash table of all resolved routes for easy lookup
239   * @mfc_cache_list: list of resovled routes for possible traversal
240   * @maxvif: Identifier of highest value vif currently in use
241   * @cache_resolve_queue_len: current size of unresolved queue
242   * @mroute_do_assert: Whether to inform userspace on wrong ingress
243   * @mroute_do_pim: Whether to receive IGMP PIMv1
244   * @mroute_reg_vif_num: PIM-device vif index
245   */
246  struct mr_table {
247  	struct list_head	list;
248  	possible_net_t		net;
249  	struct mr_table_ops	ops;
250  	u32			id;
251  	struct sock __rcu	*mroute_sk;
252  	struct timer_list	ipmr_expire_timer;
253  	struct list_head	mfc_unres_queue;
254  	struct vif_device	vif_table[MAXVIFS];
255  	struct rhltable		mfc_hash;
256  	struct list_head	mfc_cache_list;
257  	int			maxvif;
258  	atomic_t		cache_resolve_queue_len;
259  	bool			mroute_do_assert;
260  	bool			mroute_do_pim;
261  	bool			mroute_do_wrvifwhole;
262  	int			mroute_reg_vif_num;
263  };
264  
265  #ifdef CONFIG_IP_MROUTE_COMMON
266  void vif_device_init(struct vif_device *v,
267  		     struct net_device *dev,
268  		     unsigned long rate_limit,
269  		     unsigned char threshold,
270  		     unsigned short flags,
271  		     unsigned short get_iflink_mask);
272  
273  struct mr_table *
274  mr_table_alloc(struct net *net, u32 id,
275  	       struct mr_table_ops *ops,
276  	       void (*expire_func)(struct timer_list *t),
277  	       void (*table_set)(struct mr_table *mrt,
278  				 struct net *net));
279  
280  /* These actually return 'struct mr_mfc *', but to avoid need for explicit
281   * castings they simply return void.
282   */
283  void *mr_mfc_find_parent(struct mr_table *mrt,
284  			 void *hasharg, int parent);
285  void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi);
286  void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg);
287  
288  int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
289  		   struct mr_mfc *c, struct rtmsg *rtm);
290  int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb,
291  		  struct netlink_callback *cb,
292  		  int (*fill)(struct mr_table *mrt, struct sk_buff *skb,
293  			      u32 portid, u32 seq, struct mr_mfc *c,
294  			      int cmd, int flags),
295  		  spinlock_t *lock, struct fib_dump_filter *filter);
296  int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
297  		     struct mr_table *(*iter)(struct net *net,
298  					      struct mr_table *mrt),
299  		     int (*fill)(struct mr_table *mrt,
300  				 struct sk_buff *skb,
301  				 u32 portid, u32 seq, struct mr_mfc *c,
302  				 int cmd, int flags),
303  		     spinlock_t *lock, struct fib_dump_filter *filter);
304  
305  int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family,
306  	    int (*rules_dump)(struct net *net,
307  			      struct notifier_block *nb,
308  			      struct netlink_ext_ack *extack),
309  	    struct mr_table *(*mr_iter)(struct net *net,
310  					struct mr_table *mrt),
311  	    struct netlink_ext_ack *extack);
312  #else
vif_device_init(struct vif_device * v,struct net_device * dev,unsigned long rate_limit,unsigned char threshold,unsigned short flags,unsigned short get_iflink_mask)313  static inline void vif_device_init(struct vif_device *v,
314  				   struct net_device *dev,
315  				   unsigned long rate_limit,
316  				   unsigned char threshold,
317  				   unsigned short flags,
318  				   unsigned short get_iflink_mask)
319  {
320  }
321  
mr_mfc_find_parent(struct mr_table * mrt,void * hasharg,int parent)322  static inline void *mr_mfc_find_parent(struct mr_table *mrt,
323  				       void *hasharg, int parent)
324  {
325  	return NULL;
326  }
327  
mr_mfc_find_any_parent(struct mr_table * mrt,int vifi)328  static inline void *mr_mfc_find_any_parent(struct mr_table *mrt,
329  					   int vifi)
330  {
331  	return NULL;
332  }
333  
mr_mfc_find_any(struct mr_table * mrt,int vifi,void * hasharg)334  static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt,
335  					     int vifi, void *hasharg)
336  {
337  	return NULL;
338  }
339  
mr_fill_mroute(struct mr_table * mrt,struct sk_buff * skb,struct mr_mfc * c,struct rtmsg * rtm)340  static inline int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
341  				 struct mr_mfc *c, struct rtmsg *rtm)
342  {
343  	return -EINVAL;
344  }
345  
346  static inline int
mr_rtm_dumproute(struct sk_buff * skb,struct netlink_callback * cb,struct mr_table * (* iter)(struct net * net,struct mr_table * mrt),int (* fill)(struct mr_table * mrt,struct sk_buff * skb,u32 portid,u32 seq,struct mr_mfc * c,int cmd,int flags),spinlock_t * lock,struct fib_dump_filter * filter)347  mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
348  		 struct mr_table *(*iter)(struct net *net,
349  					  struct mr_table *mrt),
350  		 int (*fill)(struct mr_table *mrt,
351  			     struct sk_buff *skb,
352  			     u32 portid, u32 seq, struct mr_mfc *c,
353  			     int cmd, int flags),
354  		 spinlock_t *lock, struct fib_dump_filter *filter)
355  {
356  	return -EINVAL;
357  }
358  
mr_dump(struct net * net,struct notifier_block * nb,unsigned short family,int (* rules_dump)(struct net * net,struct notifier_block * nb,struct netlink_ext_ack * extack),struct mr_table * (* mr_iter)(struct net * net,struct mr_table * mrt),struct netlink_ext_ack * extack)359  static inline int mr_dump(struct net *net, struct notifier_block *nb,
360  			  unsigned short family,
361  			  int (*rules_dump)(struct net *net,
362  					    struct notifier_block *nb,
363  					    struct netlink_ext_ack *extack),
364  			  struct mr_table *(*mr_iter)(struct net *net,
365  						      struct mr_table *mrt),
366  			  struct netlink_ext_ack *extack)
367  {
368  	return -EINVAL;
369  }
370  #endif
371  
mr_mfc_find(struct mr_table * mrt,void * hasharg)372  static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg)
373  {
374  	return mr_mfc_find_parent(mrt, hasharg, -1);
375  }
376  
377  #ifdef CONFIG_PROC_FS
378  struct mr_vif_iter {
379  	struct seq_net_private p;
380  	struct mr_table *mrt;
381  	int ct;
382  };
383  
384  struct mr_mfc_iter {
385  	struct seq_net_private p;
386  	struct mr_table *mrt;
387  	struct list_head *cache;
388  
389  	/* Lock protecting the mr_table's unresolved queue */
390  	spinlock_t *lock;
391  };
392  
393  #ifdef CONFIG_IP_MROUTE_COMMON
394  void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos);
395  void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos);
396  
mr_vif_seq_start(struct seq_file * seq,loff_t * pos)397  static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
398  {
399  	return *pos ? mr_vif_seq_idx(seq_file_net(seq),
400  				     seq->private, *pos - 1)
401  		    : SEQ_START_TOKEN;
402  }
403  
404  /* These actually return 'struct mr_mfc *', but to avoid need for explicit
405   * castings they simply return void.
406   */
407  void *mr_mfc_seq_idx(struct net *net,
408  		     struct mr_mfc_iter *it, loff_t pos);
409  void *mr_mfc_seq_next(struct seq_file *seq, void *v,
410  		      loff_t *pos);
411  
mr_mfc_seq_start(struct seq_file * seq,loff_t * pos,struct mr_table * mrt,spinlock_t * lock)412  static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
413  				     struct mr_table *mrt, spinlock_t *lock)
414  {
415  	struct mr_mfc_iter *it = seq->private;
416  
417  	it->mrt = mrt;
418  	it->cache = NULL;
419  	it->lock = lock;
420  
421  	return *pos ? mr_mfc_seq_idx(seq_file_net(seq),
422  				     seq->private, *pos - 1)
423  		    : SEQ_START_TOKEN;
424  }
425  
mr_mfc_seq_stop(struct seq_file * seq,void * v)426  static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
427  {
428  	struct mr_mfc_iter *it = seq->private;
429  	struct mr_table *mrt = it->mrt;
430  
431  	if (it->cache == &mrt->mfc_unres_queue)
432  		spin_unlock_bh(it->lock);
433  	else if (it->cache == &mrt->mfc_cache_list)
434  		rcu_read_unlock();
435  }
436  #else
mr_vif_seq_idx(struct net * net,struct mr_vif_iter * iter,loff_t pos)437  static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter,
438  				   loff_t pos)
439  {
440  	return NULL;
441  }
442  
mr_vif_seq_next(struct seq_file * seq,void * v,loff_t * pos)443  static inline void *mr_vif_seq_next(struct seq_file *seq,
444  				    void *v, loff_t *pos)
445  {
446  	return NULL;
447  }
448  
mr_vif_seq_start(struct seq_file * seq,loff_t * pos)449  static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
450  {
451  	return NULL;
452  }
453  
mr_mfc_seq_idx(struct net * net,struct mr_mfc_iter * it,loff_t pos)454  static inline void *mr_mfc_seq_idx(struct net *net,
455  				   struct mr_mfc_iter *it, loff_t pos)
456  {
457  	return NULL;
458  }
459  
mr_mfc_seq_next(struct seq_file * seq,void * v,loff_t * pos)460  static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v,
461  				    loff_t *pos)
462  {
463  	return NULL;
464  }
465  
mr_mfc_seq_start(struct seq_file * seq,loff_t * pos,struct mr_table * mrt,spinlock_t * lock)466  static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
467  				     struct mr_table *mrt, spinlock_t *lock)
468  {
469  	return NULL;
470  }
471  
mr_mfc_seq_stop(struct seq_file * seq,void * v)472  static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
473  {
474  }
475  #endif
476  #endif
477  #endif
478