lwtunnel.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __NET_LWTUNNEL_H
  3. #define __NET_LWTUNNEL_H 1
  4. #include <linux/lwtunnel.h>
  5. #include <linux/netdevice.h>
  6. #include <linux/skbuff.h>
  7. #include <linux/types.h>
  8. #include <net/route.h>
  9. #define LWTUNNEL_HASH_BITS 7
  10. #define LWTUNNEL_HASH_SIZE (1 << LWTUNNEL_HASH_BITS)
  11. /* lw tunnel state flags */
  12. #define LWTUNNEL_STATE_OUTPUT_REDIRECT BIT(0)
  13. #define LWTUNNEL_STATE_INPUT_REDIRECT BIT(1)
  14. #define LWTUNNEL_STATE_XMIT_REDIRECT BIT(2)
  15. /* LWTUNNEL_XMIT_CONTINUE should be distinguishable from dst_output return
  16. * values (NET_XMIT_xxx and NETDEV_TX_xxx in linux/netdevice.h) for safety.
  17. */
  18. enum {
  19. LWTUNNEL_XMIT_DONE,
  20. LWTUNNEL_XMIT_CONTINUE = 0x100,
  21. };
  22. struct lwtunnel_state {
  23. __u16 type;
  24. __u16 flags;
  25. __u16 headroom;
  26. atomic_t refcnt;
  27. int (*orig_output)(struct net *net, struct sock *sk, struct sk_buff *skb);
  28. int (*orig_input)(struct sk_buff *);
  29. struct rcu_head rcu;
  30. __u8 data[];
  31. };
  32. struct lwtunnel_encap_ops {
  33. int (*build_state)(struct net *net, struct nlattr *encap,
  34. unsigned int family, const void *cfg,
  35. struct lwtunnel_state **ts,
  36. struct netlink_ext_ack *extack);
  37. void (*destroy_state)(struct lwtunnel_state *lws);
  38. int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
  39. int (*input)(struct sk_buff *skb);
  40. int (*fill_encap)(struct sk_buff *skb,
  41. struct lwtunnel_state *lwtstate);
  42. int (*get_encap_size)(struct lwtunnel_state *lwtstate);
  43. int (*cmp_encap)(struct lwtunnel_state *a, struct lwtunnel_state *b);
  44. int (*xmit)(struct sk_buff *skb);
  45. struct module *owner;
  46. };
  47. #ifdef CONFIG_LWTUNNEL
  48. DECLARE_STATIC_KEY_FALSE(nf_hooks_lwtunnel_enabled);
  49. void lwtstate_free(struct lwtunnel_state *lws);
  50. static inline struct lwtunnel_state *
  51. lwtstate_get(struct lwtunnel_state *lws)
  52. {
  53. if (lws)
  54. atomic_inc(&lws->refcnt);
  55. return lws;
  56. }
  57. static inline void lwtstate_put(struct lwtunnel_state *lws)
  58. {
  59. if (!lws)
  60. return;
  61. if (atomic_dec_and_test(&lws->refcnt))
  62. lwtstate_free(lws);
  63. }
  64. static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
  65. {
  66. if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_OUTPUT_REDIRECT))
  67. return true;
  68. return false;
  69. }
  70. static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
  71. {
  72. if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_INPUT_REDIRECT))
  73. return true;
  74. return false;
  75. }
  76. static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
  77. {
  78. if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_XMIT_REDIRECT))
  79. return true;
  80. return false;
  81. }
  82. static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
  83. unsigned int mtu)
  84. {
  85. if ((lwtunnel_xmit_redirect(lwtstate) ||
  86. lwtunnel_output_redirect(lwtstate)) && lwtstate->headroom < mtu)
  87. return lwtstate->headroom;
  88. return 0;
  89. }
  90. int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
  91. unsigned int num);
  92. int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
  93. unsigned int num);
  94. int lwtunnel_valid_encap_type(u16 encap_type,
  95. struct netlink_ext_ack *extack);
  96. int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
  97. struct netlink_ext_ack *extack);
  98. int lwtunnel_build_state(struct net *net, u16 encap_type,
  99. struct nlattr *encap,
  100. unsigned int family, const void *cfg,
  101. struct lwtunnel_state **lws,
  102. struct netlink_ext_ack *extack);
  103. int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate,
  104. int encap_attr, int encap_type_attr);
  105. int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
  106. struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len);
  107. int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b);
  108. int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb);
  109. int lwtunnel_input(struct sk_buff *skb);
  110. int lwtunnel_xmit(struct sk_buff *skb);
  111. int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len,
  112. bool ingress);
  113. static inline void lwtunnel_set_redirect(struct dst_entry *dst)
  114. {
  115. if (lwtunnel_output_redirect(dst->lwtstate)) {
  116. dst->lwtstate->orig_output = dst->output;
  117. dst->output = lwtunnel_output;
  118. }
  119. if (lwtunnel_input_redirect(dst->lwtstate)) {
  120. dst->lwtstate->orig_input = dst->input;
  121. dst->input = lwtunnel_input;
  122. }
  123. }
  124. #else
  125. static inline void lwtstate_free(struct lwtunnel_state *lws)
  126. {
  127. }
  128. static inline struct lwtunnel_state *
  129. lwtstate_get(struct lwtunnel_state *lws)
  130. {
  131. return lws;
  132. }
  133. static inline void lwtstate_put(struct lwtunnel_state *lws)
  134. {
  135. }
  136. static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate)
  137. {
  138. return false;
  139. }
  140. static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate)
  141. {
  142. return false;
  143. }
  144. static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
  145. {
  146. return false;
  147. }
  148. static inline void lwtunnel_set_redirect(struct dst_entry *dst)
  149. {
  150. }
  151. static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
  152. unsigned int mtu)
  153. {
  154. return 0;
  155. }
  156. static inline int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
  157. unsigned int num)
  158. {
  159. return -EOPNOTSUPP;
  160. }
  161. static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
  162. unsigned int num)
  163. {
  164. return -EOPNOTSUPP;
  165. }
  166. static inline int lwtunnel_valid_encap_type(u16 encap_type,
  167. struct netlink_ext_ack *extack)
  168. {
  169. NL_SET_ERR_MSG(extack, "CONFIG_LWTUNNEL is not enabled in this kernel");
  170. return -EOPNOTSUPP;
  171. }
  172. static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len,
  173. struct netlink_ext_ack *extack)
  174. {
  175. /* return 0 since we are not walking attr looking for
  176. * RTA_ENCAP_TYPE attribute on nexthops.
  177. */
  178. return 0;
  179. }
  180. static inline int lwtunnel_build_state(struct net *net, u16 encap_type,
  181. struct nlattr *encap,
  182. unsigned int family, const void *cfg,
  183. struct lwtunnel_state **lws,
  184. struct netlink_ext_ack *extack)
  185. {
  186. return -EOPNOTSUPP;
  187. }
  188. static inline int lwtunnel_fill_encap(struct sk_buff *skb,
  189. struct lwtunnel_state *lwtstate,
  190. int encap_attr, int encap_type_attr)
  191. {
  192. return 0;
  193. }
  194. static inline int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate)
  195. {
  196. return 0;
  197. }
  198. static inline struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len)
  199. {
  200. return NULL;
  201. }
  202. static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a,
  203. struct lwtunnel_state *b)
  204. {
  205. return 0;
  206. }
  207. static inline int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
  208. {
  209. return -EOPNOTSUPP;
  210. }
  211. static inline int lwtunnel_input(struct sk_buff *skb)
  212. {
  213. return -EOPNOTSUPP;
  214. }
  215. static inline int lwtunnel_xmit(struct sk_buff *skb)
  216. {
  217. return -EOPNOTSUPP;
  218. }
  219. #endif /* CONFIG_LWTUNNEL */
  220. #define MODULE_ALIAS_RTNL_LWT(encap_type) MODULE_ALIAS("rtnl-lwt-" __stringify(encap_type))
  221. #endif /* __NET_LWTUNNEL_H */