l3mdev.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * include/net/l3mdev.h - L3 master device API
  3. * Copyright (c) 2015 Cumulus Networks
  4. * Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. */
  11. #ifndef _NET_L3MDEV_H_
  12. #define _NET_L3MDEV_H_
  13. /**
  14. * struct l3mdev_ops - l3mdev operations
  15. *
  16. * @l3mdev_fib_table: Get FIB table id to use for lookups
  17. *
  18. * @l3mdev_get_rtable: Get cached IPv4 rtable (dst_entry) for device
  19. *
  20. * @l3mdev_get_saddr: Get source address for a flow
  21. *
  22. * @l3mdev_get_rt6_dst: Get cached IPv6 rt6_info (dst_entry) for device
  23. */
  24. struct l3mdev_ops {
  25. u32 (*l3mdev_fib_table)(const struct net_device *dev);
  26. /* IPv4 ops */
  27. struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev,
  28. const struct flowi4 *fl4);
  29. void (*l3mdev_get_saddr)(struct net_device *dev,
  30. struct flowi4 *fl4);
  31. /* IPv6 ops */
  32. struct dst_entry * (*l3mdev_get_rt6_dst)(const struct net_device *dev,
  33. const struct flowi6 *fl6);
  34. };
  35. #ifdef CONFIG_NET_L3_MASTER_DEV
  36. int l3mdev_master_ifindex_rcu(struct net_device *dev);
  37. static inline int l3mdev_master_ifindex(struct net_device *dev)
  38. {
  39. int ifindex;
  40. rcu_read_lock();
  41. ifindex = l3mdev_master_ifindex_rcu(dev);
  42. rcu_read_unlock();
  43. return ifindex;
  44. }
  45. /* get index of an interface to use for FIB lookups. For devices
  46. * enslaved to an L3 master device FIB lookups are based on the
  47. * master index
  48. */
  49. static inline int l3mdev_fib_oif_rcu(struct net_device *dev)
  50. {
  51. return l3mdev_master_ifindex_rcu(dev) ? : dev->ifindex;
  52. }
  53. static inline int l3mdev_fib_oif(struct net_device *dev)
  54. {
  55. int oif;
  56. rcu_read_lock();
  57. oif = l3mdev_fib_oif_rcu(dev);
  58. rcu_read_unlock();
  59. return oif;
  60. }
  61. u32 l3mdev_fib_table_rcu(const struct net_device *dev);
  62. u32 l3mdev_fib_table_by_index(struct net *net, int ifindex);
  63. static inline u32 l3mdev_fib_table(const struct net_device *dev)
  64. {
  65. u32 tb_id;
  66. rcu_read_lock();
  67. tb_id = l3mdev_fib_table_rcu(dev);
  68. rcu_read_unlock();
  69. return tb_id;
  70. }
  71. static inline struct rtable *l3mdev_get_rtable(const struct net_device *dev,
  72. const struct flowi4 *fl4)
  73. {
  74. if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rtable)
  75. return dev->l3mdev_ops->l3mdev_get_rtable(dev, fl4);
  76. return NULL;
  77. }
  78. static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
  79. {
  80. struct net_device *dev;
  81. bool rc = false;
  82. if (ifindex == 0)
  83. return false;
  84. rcu_read_lock();
  85. dev = dev_get_by_index_rcu(net, ifindex);
  86. if (dev)
  87. rc = netif_is_l3_master(dev);
  88. rcu_read_unlock();
  89. return rc;
  90. }
  91. static inline void l3mdev_get_saddr(struct net *net, int ifindex,
  92. struct flowi4 *fl4)
  93. {
  94. struct net_device *dev;
  95. if (ifindex) {
  96. rcu_read_lock();
  97. dev = dev_get_by_index_rcu(net, ifindex);
  98. if (dev && netif_is_l3_master(dev) &&
  99. dev->l3mdev_ops->l3mdev_get_saddr) {
  100. dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
  101. }
  102. rcu_read_unlock();
  103. }
  104. }
  105. static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
  106. const struct flowi6 *fl6)
  107. {
  108. if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rt6_dst)
  109. return dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
  110. return NULL;
  111. }
  112. static inline
  113. struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
  114. const struct flowi6 *fl6)
  115. {
  116. struct dst_entry *dst = NULL;
  117. struct net_device *dev;
  118. dev = dev_get_by_index(net, fl6->flowi6_oif);
  119. if (dev) {
  120. dst = l3mdev_get_rt6_dst(dev, fl6);
  121. dev_put(dev);
  122. }
  123. return dst;
  124. }
  125. #else
  126. static inline int l3mdev_master_ifindex_rcu(struct net_device *dev)
  127. {
  128. return 0;
  129. }
  130. static inline int l3mdev_master_ifindex(struct net_device *dev)
  131. {
  132. return 0;
  133. }
  134. static inline int l3mdev_fib_oif_rcu(struct net_device *dev)
  135. {
  136. return dev ? dev->ifindex : 0;
  137. }
  138. static inline int l3mdev_fib_oif(struct net_device *dev)
  139. {
  140. return dev ? dev->ifindex : 0;
  141. }
  142. static inline u32 l3mdev_fib_table_rcu(const struct net_device *dev)
  143. {
  144. return 0;
  145. }
  146. static inline u32 l3mdev_fib_table(const struct net_device *dev)
  147. {
  148. return 0;
  149. }
  150. static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
  151. {
  152. return 0;
  153. }
  154. static inline struct rtable *l3mdev_get_rtable(const struct net_device *dev,
  155. const struct flowi4 *fl4)
  156. {
  157. return NULL;
  158. }
  159. static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
  160. {
  161. return false;
  162. }
  163. static inline void l3mdev_get_saddr(struct net *net, int ifindex,
  164. struct flowi4 *fl4)
  165. {
  166. }
  167. static inline
  168. struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
  169. const struct flowi6 *fl6)
  170. {
  171. return NULL;
  172. }
  173. static inline
  174. struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
  175. const struct flowi6 *fl6)
  176. {
  177. return NULL;
  178. }
  179. #endif
  180. #endif /* _NET_L3MDEV_H_ */