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