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