brintos

brintos / linux-shallow public Read only

0
0
Text · 12.3 KiB · 9dd4bf1 Raw
478 lines · c
1#ifndef __LINUX_MROUTE_BASE_H2#define __LINUX_MROUTE_BASE_H3 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 routing14 * @dev: network device being used15 * @dev_tracker: refcount tracker for @dev reference16 * @bytes_in: statistic; bytes ingressing17 * @bytes_out: statistic; bytes egresing18 * @pkt_in: statistic; packets ingressing19 * @pkt_out: statistic; packets egressing20 * @rate_limit: Traffic shaping (NI)21 * @threshold: TTL threshold22 * @flags: Control flags23 * @link: Physical interface index24 * @dev_parent_id: device parent id25 * @local: Local address26 * @remote: Remote address for tunnels27 */28struct 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 43struct 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 51static 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 73static 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 MAXVIFS97/* This one is nasty; value is defined in uapi using different symbols for98 * mroute and morute6 but both map into same 32.99 */100#define MAXVIFS	32101#endif102 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 hardware109 */110enum {111	MFC_STATIC = BIT(0),112	MFC_OFFLOAD = BIT(1),113};114 115/**116 * struct mr_mfc - common multicast routing entries117 * @mnode: rhashtable list118 * @mfc_parent: source interface (iif)119 * @mfc_flags: entry flags120 * @expires: unresolved entry expire time121 * @unresolved: unresolved cached skbs122 * @last_assert: time of last assert123 * @minvif: minimum VIF id124 * @maxvif: maximum VIF id125 * @bytes: bytes that have passed for this entry126 * @pkt: packets that have passed for this entry127 * @wrong_if: number of wrong source interface hits128 * @lastuse: time of last use of the group (traffic or update)129 * @ttls: OIF TTL threshold array130 * @refcount: reference count for this entry131 * @list: global entry list132 * @rcu: used for entry destruction133 * @free: Operation used for freeing an entry under RCU134 */135struct 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 162static 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 168static inline void mr_cache_hold(struct mr_mfc *c)169{170	refcount_inc(&c->mfc_un.res.refcount);171}172 173struct mfc_entry_notifier_info {174	struct fib_notifier_info info;175	struct mr_mfc *mfc;176	u32 tb_id;177};178 179static 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_id192	};193 194	return call_fib_notifier(nb, event_type, &info.info);195}196 197static 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_id209	};210 211	ASSERT_RTNL();212	(*ipmr_seq)++;213	return call_fib_notifiers(net, event_type, &info.info);214}215 216struct mr_table;217 218/**219 * struct mr_table_ops - callbacks and info for protocol-specific ops220 * @rht_params: parameters for accessing the MFC hash221 * @cmparg_any: a hash key to be used for matching on (*,*) routes222 */223struct mr_table_ops {224	const struct rhashtable_params *rht_params;225	void *cmparg_any;226};227 228/**229 * struct mr_table - a multicast routing table230 * @list: entry within a list of multicast routing tables231 * @net: net where this table belongs232 * @ops: protocol specific operations233 * @id: identifier of the table234 * @mroute_sk: socket associated with the table235 * @ipmr_expire_timer: timer for handling unresolved routes236 * @mfc_unres_queue: list of unresolved MFC entries237 * @vif_table: array containing all possible vifs238 * @mfc_hash: Hash table of all resolved routes for easy lookup239 * @mfc_cache_list: list of resovled routes for possible traversal240 * @maxvif: Identifier of highest value vif currently in use241 * @cache_resolve_queue_len: current size of unresolved queue242 * @mroute_do_assert: Whether to inform userspace on wrong ingress243 * @mroute_do_pim: Whether to receive IGMP PIMv1244 * @mroute_reg_vif_num: PIM-device vif index245 */246struct 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_COMMON266void 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 273struct mr_table *274mr_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 explicit281 * castings they simply return void.282 */283void *mr_mfc_find_parent(struct mr_table *mrt,284			 void *hasharg, int parent);285void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi);286void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg);287 288int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,289		   struct mr_mfc *c, struct rtmsg *rtm);290int 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);296int 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 305int 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#else313static 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 322static inline void *mr_mfc_find_parent(struct mr_table *mrt,323				       void *hasharg, int parent)324{325	return NULL;326}327 328static inline void *mr_mfc_find_any_parent(struct mr_table *mrt,329					   int vifi)330{331	return NULL;332}333 334static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt,335					     int vifi, void *hasharg)336{337	return NULL;338}339 340static 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 346static inline int347mr_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 359static 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#endif371 372static 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_FS378struct mr_vif_iter {379	struct seq_net_private p;380	struct mr_table *mrt;381	int ct;382};383 384struct 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_COMMON394void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos);395void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos);396 397static 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 explicit405 * castings they simply return void.406 */407void *mr_mfc_seq_idx(struct net *net,408		     struct mr_mfc_iter *it, loff_t pos);409void *mr_mfc_seq_next(struct seq_file *seq, void *v,410		      loff_t *pos);411 412static 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 426static 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#else437static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter,438				   loff_t pos)439{440	return NULL;441}442 443static inline void *mr_vif_seq_next(struct seq_file *seq,444				    void *v, loff_t *pos)445{446	return NULL;447}448 449static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)450{451	return NULL;452}453 454static inline void *mr_mfc_seq_idx(struct net *net,455				   struct mr_mfc_iter *it, loff_t pos)456{457	return NULL;458}459 460static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v,461				    loff_t *pos)462{463	return NULL;464}465 466static 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 472static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)473{474}475#endif476#endif477#endif478