l3mdev.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. int (*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 int l3mdev_get_saddr(struct net *net, int ifindex,
  92. struct flowi4 *fl4)
  93. {
  94. struct net_device *dev;
  95. int rc = 0;
  96. if (ifindex) {
  97. rcu_read_lock();
  98. dev = dev_get_by_index_rcu(net, ifindex);
  99. if (dev && netif_is_l3_master(dev) &&
  100. dev->l3mdev_ops->l3mdev_get_saddr) {
  101. rc = dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4);
  102. }
  103. rcu_read_unlock();
  104. }
  105. return rc;
  106. }
  107. static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
  108. const struct flowi6 *fl6)
  109. {
  110. if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rt6_dst)
  111. return dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6);
  112. return NULL;
  113. }
  114. static inline
  115. struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
  116. const struct flowi6 *fl6)
  117. {
  118. struct dst_entry *dst = NULL;
  119. struct net_device *dev;
  120. dev = dev_get_by_index(net, fl6->flowi6_oif);
  121. if (dev) {
  122. dst = l3mdev_get_rt6_dst(dev, fl6);
  123. dev_put(dev);
  124. }
  125. return dst;
  126. }
  127. #else
  128. static inline int l3mdev_master_ifindex_rcu(struct net_device *dev)
  129. {
  130. return 0;
  131. }
  132. static inline int l3mdev_master_ifindex(struct net_device *dev)
  133. {
  134. return 0;
  135. }
  136. static inline int l3mdev_fib_oif_rcu(struct net_device *dev)
  137. {
  138. return dev ? dev->ifindex : 0;
  139. }
  140. static inline int l3mdev_fib_oif(struct net_device *dev)
  141. {
  142. return dev ? dev->ifindex : 0;
  143. }
  144. static inline u32 l3mdev_fib_table_rcu(const struct net_device *dev)
  145. {
  146. return 0;
  147. }
  148. static inline u32 l3mdev_fib_table(const struct net_device *dev)
  149. {
  150. return 0;
  151. }
  152. static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
  153. {
  154. return 0;
  155. }
  156. static inline struct rtable *l3mdev_get_rtable(const struct net_device *dev,
  157. const struct flowi4 *fl4)
  158. {
  159. return NULL;
  160. }
  161. static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
  162. {
  163. return false;
  164. }
  165. static inline int l3mdev_get_saddr(struct net *net, int ifindex,
  166. struct flowi4 *fl4)
  167. {
  168. return 0;
  169. }
  170. static inline
  171. struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev,
  172. const struct flowi6 *fl6)
  173. {
  174. return NULL;
  175. }
  176. static inline
  177. struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net,
  178. const struct flowi6 *fl6)
  179. {
  180. return NULL;
  181. }
  182. #endif
  183. #endif /* _NET_L3MDEV_H_ */