cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mroute_base.h (12548B)


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