0001 #ifndef __LINUX_MROUTE_BASE_H
0002 #define __LINUX_MROUTE_BASE_H
0003
0004 #include <linux/netdevice.h>
0005 #include <linux/rhashtable-types.h>
0006 #include <linux/spinlock.h>
0007 #include <net/net_namespace.h>
0008 #include <net/sock.h>
0009 #include <net/fib_notifier.h>
0010 #include <net/ip_fib.h>
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 struct vif_device {
0029 struct net_device __rcu *dev;
0030 netdevice_tracker dev_tracker;
0031 unsigned long bytes_in, bytes_out;
0032 unsigned long pkt_in, pkt_out;
0033 unsigned long rate_limit;
0034 unsigned char threshold;
0035 unsigned short flags;
0036 int link;
0037
0038
0039 struct netdev_phys_item_id dev_parent_id;
0040 __be32 local, remote;
0041 };
0042
0043 struct vif_entry_notifier_info {
0044 struct fib_notifier_info info;
0045 struct net_device *dev;
0046 unsigned short vif_index;
0047 unsigned short vif_flags;
0048 u32 tb_id;
0049 };
0050
0051 static inline int mr_call_vif_notifier(struct notifier_block *nb,
0052 unsigned short family,
0053 enum fib_event_type event_type,
0054 struct vif_device *vif,
0055 struct net_device *vif_dev,
0056 unsigned short vif_index, u32 tb_id,
0057 struct netlink_ext_ack *extack)
0058 {
0059 struct vif_entry_notifier_info info = {
0060 .info = {
0061 .family = family,
0062 .extack = extack,
0063 },
0064 .dev = vif_dev,
0065 .vif_index = vif_index,
0066 .vif_flags = vif->flags,
0067 .tb_id = tb_id,
0068 };
0069
0070 return call_fib_notifier(nb, event_type, &info.info);
0071 }
0072
0073 static inline int mr_call_vif_notifiers(struct net *net,
0074 unsigned short family,
0075 enum fib_event_type event_type,
0076 struct vif_device *vif,
0077 struct net_device *vif_dev,
0078 unsigned short vif_index, u32 tb_id,
0079 unsigned int *ipmr_seq)
0080 {
0081 struct vif_entry_notifier_info info = {
0082 .info = {
0083 .family = family,
0084 },
0085 .dev = vif_dev,
0086 .vif_index = vif_index,
0087 .vif_flags = vif->flags,
0088 .tb_id = tb_id,
0089 };
0090
0091 ASSERT_RTNL();
0092 (*ipmr_seq)++;
0093 return call_fib_notifiers(net, event_type, &info.info);
0094 }
0095
0096 #ifndef MAXVIFS
0097
0098
0099
0100 #define MAXVIFS 32
0101 #endif
0102
0103
0104 #define VIF_EXISTS(_mrt, _idx) (!!rcu_access_pointer((_mrt)->vif_table[_idx].dev))
0105
0106
0107
0108
0109
0110 enum {
0111 MFC_STATIC = BIT(0),
0112 MFC_OFFLOAD = BIT(1),
0113 };
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 struct mr_mfc {
0136 struct rhlist_head mnode;
0137 unsigned short mfc_parent;
0138 int mfc_flags;
0139
0140 union {
0141 struct {
0142 unsigned long expires;
0143 struct sk_buff_head unresolved;
0144 } unres;
0145 struct {
0146 unsigned long last_assert;
0147 int minvif;
0148 int maxvif;
0149 unsigned long bytes;
0150 unsigned long pkt;
0151 unsigned long wrong_if;
0152 unsigned long lastuse;
0153 unsigned char ttls[MAXVIFS];
0154 refcount_t refcount;
0155 } res;
0156 } mfc_un;
0157 struct list_head list;
0158 struct rcu_head rcu;
0159 void (*free)(struct rcu_head *head);
0160 };
0161
0162 static inline void mr_cache_put(struct mr_mfc *c)
0163 {
0164 if (refcount_dec_and_test(&c->mfc_un.res.refcount))
0165 call_rcu(&c->rcu, c->free);
0166 }
0167
0168 static inline void mr_cache_hold(struct mr_mfc *c)
0169 {
0170 refcount_inc(&c->mfc_un.res.refcount);
0171 }
0172
0173 struct mfc_entry_notifier_info {
0174 struct fib_notifier_info info;
0175 struct mr_mfc *mfc;
0176 u32 tb_id;
0177 };
0178
0179 static inline int mr_call_mfc_notifier(struct notifier_block *nb,
0180 unsigned short family,
0181 enum fib_event_type event_type,
0182 struct mr_mfc *mfc, u32 tb_id,
0183 struct netlink_ext_ack *extack)
0184 {
0185 struct mfc_entry_notifier_info info = {
0186 .info = {
0187 .family = family,
0188 .extack = extack,
0189 },
0190 .mfc = mfc,
0191 .tb_id = tb_id
0192 };
0193
0194 return call_fib_notifier(nb, event_type, &info.info);
0195 }
0196
0197 static inline int mr_call_mfc_notifiers(struct net *net,
0198 unsigned short family,
0199 enum fib_event_type event_type,
0200 struct mr_mfc *mfc, u32 tb_id,
0201 unsigned int *ipmr_seq)
0202 {
0203 struct mfc_entry_notifier_info info = {
0204 .info = {
0205 .family = family,
0206 },
0207 .mfc = mfc,
0208 .tb_id = tb_id
0209 };
0210
0211 ASSERT_RTNL();
0212 (*ipmr_seq)++;
0213 return call_fib_notifiers(net, event_type, &info.info);
0214 }
0215
0216 struct mr_table;
0217
0218
0219
0220
0221
0222
0223 struct mr_table_ops {
0224 const struct rhashtable_params *rht_params;
0225 void *cmparg_any;
0226 };
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246 struct mr_table {
0247 struct list_head list;
0248 possible_net_t net;
0249 struct mr_table_ops ops;
0250 u32 id;
0251 struct sock __rcu *mroute_sk;
0252 struct timer_list ipmr_expire_timer;
0253 struct list_head mfc_unres_queue;
0254 struct vif_device vif_table[MAXVIFS];
0255 struct rhltable mfc_hash;
0256 struct list_head mfc_cache_list;
0257 int maxvif;
0258 atomic_t cache_resolve_queue_len;
0259 bool mroute_do_assert;
0260 bool mroute_do_pim;
0261 bool mroute_do_wrvifwhole;
0262 int mroute_reg_vif_num;
0263 };
0264
0265 #ifdef CONFIG_IP_MROUTE_COMMON
0266 void vif_device_init(struct vif_device *v,
0267 struct net_device *dev,
0268 unsigned long rate_limit,
0269 unsigned char threshold,
0270 unsigned short flags,
0271 unsigned short get_iflink_mask);
0272
0273 struct mr_table *
0274 mr_table_alloc(struct net *net, u32 id,
0275 struct mr_table_ops *ops,
0276 void (*expire_func)(struct timer_list *t),
0277 void (*table_set)(struct mr_table *mrt,
0278 struct net *net));
0279
0280
0281
0282
0283 void *mr_mfc_find_parent(struct mr_table *mrt,
0284 void *hasharg, int parent);
0285 void *mr_mfc_find_any_parent(struct mr_table *mrt, int vifi);
0286 void *mr_mfc_find_any(struct mr_table *mrt, int vifi, void *hasharg);
0287
0288 int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
0289 struct mr_mfc *c, struct rtmsg *rtm);
0290 int mr_table_dump(struct mr_table *mrt, struct sk_buff *skb,
0291 struct netlink_callback *cb,
0292 int (*fill)(struct mr_table *mrt, struct sk_buff *skb,
0293 u32 portid, u32 seq, struct mr_mfc *c,
0294 int cmd, int flags),
0295 spinlock_t *lock, struct fib_dump_filter *filter);
0296 int mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
0297 struct mr_table *(*iter)(struct net *net,
0298 struct mr_table *mrt),
0299 int (*fill)(struct mr_table *mrt,
0300 struct sk_buff *skb,
0301 u32 portid, u32 seq, struct mr_mfc *c,
0302 int cmd, int flags),
0303 spinlock_t *lock, struct fib_dump_filter *filter);
0304
0305 int mr_dump(struct net *net, struct notifier_block *nb, unsigned short family,
0306 int (*rules_dump)(struct net *net,
0307 struct notifier_block *nb,
0308 struct netlink_ext_ack *extack),
0309 struct mr_table *(*mr_iter)(struct net *net,
0310 struct mr_table *mrt),
0311 struct netlink_ext_ack *extack);
0312 #else
0313 static inline void vif_device_init(struct vif_device *v,
0314 struct net_device *dev,
0315 unsigned long rate_limit,
0316 unsigned char threshold,
0317 unsigned short flags,
0318 unsigned short get_iflink_mask)
0319 {
0320 }
0321
0322 static inline void *mr_mfc_find_parent(struct mr_table *mrt,
0323 void *hasharg, int parent)
0324 {
0325 return NULL;
0326 }
0327
0328 static inline void *mr_mfc_find_any_parent(struct mr_table *mrt,
0329 int vifi)
0330 {
0331 return NULL;
0332 }
0333
0334 static inline struct mr_mfc *mr_mfc_find_any(struct mr_table *mrt,
0335 int vifi, void *hasharg)
0336 {
0337 return NULL;
0338 }
0339
0340 static inline int mr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
0341 struct mr_mfc *c, struct rtmsg *rtm)
0342 {
0343 return -EINVAL;
0344 }
0345
0346 static inline int
0347 mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb,
0348 struct mr_table *(*iter)(struct net *net,
0349 struct mr_table *mrt),
0350 int (*fill)(struct mr_table *mrt,
0351 struct sk_buff *skb,
0352 u32 portid, u32 seq, struct mr_mfc *c,
0353 int cmd, int flags),
0354 spinlock_t *lock, struct fib_dump_filter *filter)
0355 {
0356 return -EINVAL;
0357 }
0358
0359 static inline int mr_dump(struct net *net, struct notifier_block *nb,
0360 unsigned short family,
0361 int (*rules_dump)(struct net *net,
0362 struct notifier_block *nb,
0363 struct netlink_ext_ack *extack),
0364 struct mr_table *(*mr_iter)(struct net *net,
0365 struct mr_table *mrt),
0366 struct netlink_ext_ack *extack)
0367 {
0368 return -EINVAL;
0369 }
0370 #endif
0371
0372 static inline void *mr_mfc_find(struct mr_table *mrt, void *hasharg)
0373 {
0374 return mr_mfc_find_parent(mrt, hasharg, -1);
0375 }
0376
0377 #ifdef CONFIG_PROC_FS
0378 struct mr_vif_iter {
0379 struct seq_net_private p;
0380 struct mr_table *mrt;
0381 int ct;
0382 };
0383
0384 struct mr_mfc_iter {
0385 struct seq_net_private p;
0386 struct mr_table *mrt;
0387 struct list_head *cache;
0388
0389
0390 spinlock_t *lock;
0391 };
0392
0393 #ifdef CONFIG_IP_MROUTE_COMMON
0394 void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter, loff_t pos);
0395 void *mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos);
0396
0397 static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
0398 {
0399 return *pos ? mr_vif_seq_idx(seq_file_net(seq),
0400 seq->private, *pos - 1)
0401 : SEQ_START_TOKEN;
0402 }
0403
0404
0405
0406
0407 void *mr_mfc_seq_idx(struct net *net,
0408 struct mr_mfc_iter *it, loff_t pos);
0409 void *mr_mfc_seq_next(struct seq_file *seq, void *v,
0410 loff_t *pos);
0411
0412 static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
0413 struct mr_table *mrt, spinlock_t *lock)
0414 {
0415 struct mr_mfc_iter *it = seq->private;
0416
0417 it->mrt = mrt;
0418 it->cache = NULL;
0419 it->lock = lock;
0420
0421 return *pos ? mr_mfc_seq_idx(seq_file_net(seq),
0422 seq->private, *pos - 1)
0423 : SEQ_START_TOKEN;
0424 }
0425
0426 static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
0427 {
0428 struct mr_mfc_iter *it = seq->private;
0429 struct mr_table *mrt = it->mrt;
0430
0431 if (it->cache == &mrt->mfc_unres_queue)
0432 spin_unlock_bh(it->lock);
0433 else if (it->cache == &mrt->mfc_cache_list)
0434 rcu_read_unlock();
0435 }
0436 #else
0437 static inline void *mr_vif_seq_idx(struct net *net, struct mr_vif_iter *iter,
0438 loff_t pos)
0439 {
0440 return NULL;
0441 }
0442
0443 static inline void *mr_vif_seq_next(struct seq_file *seq,
0444 void *v, loff_t *pos)
0445 {
0446 return NULL;
0447 }
0448
0449 static inline void *mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
0450 {
0451 return NULL;
0452 }
0453
0454 static inline void *mr_mfc_seq_idx(struct net *net,
0455 struct mr_mfc_iter *it, loff_t pos)
0456 {
0457 return NULL;
0458 }
0459
0460 static inline void *mr_mfc_seq_next(struct seq_file *seq, void *v,
0461 loff_t *pos)
0462 {
0463 return NULL;
0464 }
0465
0466 static inline void *mr_mfc_seq_start(struct seq_file *seq, loff_t *pos,
0467 struct mr_table *mrt, spinlock_t *lock)
0468 {
0469 return NULL;
0470 }
0471
0472 static inline void mr_mfc_seq_stop(struct seq_file *seq, void *v)
0473 {
0474 }
0475 #endif
0476 #endif
0477 #endif