l3mdev.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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. #include <net/fib_rules.h>
  14. /**
  15. * struct l3mdev_ops - l3mdev operations
  16. *
  17. * @l3mdev_fib_table: Get FIB table id to use for lookups
  18. *
  19. * @l3mdev_get_rtable: Get cached IPv4 rtable (dst_entry) for device
  20. *
  21. * @l3mdev_get_saddr: Get source address for a flow
  22. *
  23. * @l3mdev_get_rt6_dst: Get cached IPv6 rt6_info (dst_entry) for device
  24. */
  25. struct l3mdev_ops {
  26. u32 (*l3mdev_fib_table)(const struct net_device *dev);
  27. struct sk_buff * (*l3mdev_l3_rcv)(struct net_device *dev,
  28. struct sk_buff *skb, u16 proto);
  29. /* IPv4 ops */
  30. struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev,
  31. const struct flowi4 *fl4);
  32. int (*l3mdev_get_saddr)(struct net_device *dev,
  33. struct flowi4 *fl4);
  34. /* IPv6 ops */
  35. struct dst_entry * (*l3mdev_get_rt6_dst)(const struct net_device *dev,
  36. struct flowi6 *fl6);
  37. int (*l3mdev_get_saddr6)(struct net_device *dev,
  38. const struct sock *sk,
  39. struct flowi6 *fl6);
  40. };
  41. #ifdef CONFIG_NET_L3_MASTER_DEV
  42. int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
  43. struct fib_lookup_arg *arg);
  44. int l3mdev_master_ifindex_rcu(const struct net_device *dev);
  45. static inline int l3mdev_master_ifindex(struct net_device *dev)
  46. {
  47. int ifindex;
  48. rcu_read_lock();
  49. ifindex = l3mdev_master_ifindex_rcu(dev);
  50. rcu_read_unlock();
  51. return ifindex;
  52. }
  53. static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
  54. {
  55. struct net_device *dev;
  56. int rc = 0;
  57. if (likely(ifindex)) {
  58. rcu_read_lock();
  59. dev = dev_get_by_index_rcu(net, ifindex);
  60. if (dev)
  61. rc = l3mdev_master_ifindex_rcu(dev);
  62. rcu_read_unlock();
  63. }
  64. return rc;
  65. }
  66. static inline
  67. const struct net_device *l3mdev_master_dev_rcu(const struct net_device *_dev)
  68. {
  69. /* netdev_master_upper_dev_get_rcu calls
  70. * list_first_or_null_rcu to walk the upper dev list.
  71. * list_first_or_null_rcu does not handle a const arg. We aren't
  72. * making changes, just want the master device from that list so
  73. * typecast to remove the const
  74. */
  75. struct net_device *dev = (struct net_device *)_dev;
  76. const struct net_device *master;
  77. if (!dev)
  78. return NULL;
  79. if (netif_is_l3_master(dev))
  80. master = dev;
  81. else if (netif_is_l3_slave(dev))
  82. master = netdev_master_upper_dev_get_rcu(dev);
  83. else
  84. master = NULL;
  85. return master;
  86. }
  87. /* get index of an interface to use for FIB lookups. For devices
  88. * enslaved to an L3 master device FIB lookups are based on the
  89. * master index
  90. */
  91. static inline int l3mdev_fib_oif_rcu(struct net_device *dev)
  92. {
  93. return l3mdev_master_ifindex_rcu(dev) ? : dev->ifindex;
  94. }
  95. static inline int l3mdev_fib_oif(struct net_device *dev)
  96. {
  97. int oif;
  98. rcu_read_lock();
  99. oif = l3mdev_fib_oif_rcu(dev);
  100. rcu_read_unlock();
  101. return oif;
  102. }
  103. u32 l3mdev_fib_table_rcu(const struct net_device *dev);
  104. u32 l3mdev_fib_table_by_index(struct net *net, int ifindex);
  105. static inline u32 l3mdev_fib_table(const struct net_device *dev)
  106. {
  107. u32 tb_id;
  108. rcu_read_lock();
  109. tb_id = l3mdev_fib_table_rcu(dev);
  110. rcu_read_unlock();
  111. return tb_id;
  112. }
  113. static inline struct rtable *l3mdev_get_rtable(const struct net_device *dev,
  114. const struct flowi4 *fl4)
  115. {
  116. if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rtable)
  117. return dev->l3mdev_ops->l3mdev_get_rtable(dev, fl4);
  118. return NULL;
  119. }
  120. static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
  121. {
  122. struct net_device *dev;
  123. bool rc = false;
  124. if (ifindex == 0)
  125. return false;
  126. rcu_read_lock();
  127. dev = dev_get_by_index_rcu(net, ifindex);
  128. if (dev)
  129. rc = netif_is_l3_master(dev);
  130. rcu_read_unlock();
  131. return rc;
  132. }
  133. int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4);
  134. struct dst_entry *l3mdev_get_rt6_dst(struct net *net, struct flowi6 *fl6);
  135. int l3mdev_get_saddr6(struct net *net, const struct sock *sk,
  136. struct flowi6 *fl6);
  137. static inline
  138. struct sk_buff *l3mdev_l3_rcv(struct sk_buff *skb, u16 proto)
  139. {
  140. struct net_device *master = NULL;
  141. if (netif_is_l3_slave(skb->dev))
  142. master = netdev_master_upper_dev_get_rcu(skb->dev);
  143. else if (netif_is_l3_master(skb->dev))
  144. master = skb->dev;
  145. if (master && master->l3mdev_ops->l3mdev_l3_rcv)
  146. skb = master->l3mdev_ops->l3mdev_l3_rcv(master, skb, proto);
  147. return skb;
  148. }
  149. static inline
  150. struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
  151. {
  152. return l3mdev_l3_rcv(skb, AF_INET);
  153. }
  154. static inline
  155. struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
  156. {
  157. return l3mdev_l3_rcv(skb, AF_INET6);
  158. }
  159. #else
  160. static inline int l3mdev_master_ifindex_rcu(const struct net_device *dev)
  161. {
  162. return 0;
  163. }
  164. static inline int l3mdev_master_ifindex(struct net_device *dev)
  165. {
  166. return 0;
  167. }
  168. static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
  169. {
  170. return 0;
  171. }
  172. static inline
  173. const struct net_device *l3mdev_master_dev_rcu(const struct net_device *dev)
  174. {
  175. return NULL;
  176. }
  177. static inline int l3mdev_fib_oif_rcu(struct net_device *dev)
  178. {
  179. return dev ? dev->ifindex : 0;
  180. }
  181. static inline int l3mdev_fib_oif(struct net_device *dev)
  182. {
  183. return dev ? dev->ifindex : 0;
  184. }
  185. static inline u32 l3mdev_fib_table_rcu(const struct net_device *dev)
  186. {
  187. return 0;
  188. }
  189. static inline u32 l3mdev_fib_table(const struct net_device *dev)
  190. {
  191. return 0;
  192. }
  193. static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex)
  194. {
  195. return 0;
  196. }
  197. static inline struct rtable *l3mdev_get_rtable(const struct net_device *dev,
  198. const struct flowi4 *fl4)
  199. {
  200. return NULL;
  201. }
  202. static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
  203. {
  204. return false;
  205. }
  206. static inline int l3mdev_get_saddr(struct net *net, int ifindex,
  207. struct flowi4 *fl4)
  208. {
  209. return 0;
  210. }
  211. static inline
  212. struct dst_entry *l3mdev_get_rt6_dst(struct net *net, struct flowi6 *fl6)
  213. {
  214. return NULL;
  215. }
  216. static inline int l3mdev_get_saddr6(struct net *net, const struct sock *sk,
  217. struct flowi6 *fl6)
  218. {
  219. return 0;
  220. }
  221. static inline
  222. struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
  223. {
  224. return skb;
  225. }
  226. static inline
  227. struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
  228. {
  229. return skb;
  230. }
  231. static inline
  232. int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
  233. struct fib_lookup_arg *arg)
  234. {
  235. return 1;
  236. }
  237. #endif
  238. #endif /* _NET_L3MDEV_H_ */