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 void lwtstate_free(struct lwtunnel_state *lws); 55 56 static inline struct lwtunnel_state * 57 lwtstate_get(struct lwtunnel_state *lws) 58 { 59 if (lws) 60 atomic_inc(&lws->refcnt); 61 62 return lws; 63 } 64 65 static inline void lwtstate_put(struct lwtunnel_state *lws) 66 { 67 if (!lws) 68 return; 69 70 if (atomic_dec_and_test(&lws->refcnt)) 71 lwtstate_free(lws); 72 } 73 74 static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate) 75 { 76 if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_OUTPUT_REDIRECT)) 77 return true; 78 79 return false; 80 } 81 82 static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate) 83 { 84 if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_INPUT_REDIRECT)) 85 return true; 86 87 return false; 88 } 89 90 static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate) 91 { 92 if (lwtstate && (lwtstate->flags & LWTUNNEL_STATE_XMIT_REDIRECT)) 93 return true; 94 95 return false; 96 } 97 98 static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate, 99 unsigned int mtu) 100 { 101 if ((lwtunnel_xmit_redirect(lwtstate) || 102 lwtunnel_output_redirect(lwtstate)) && lwtstate->headroom < mtu) 103 return lwtstate->headroom; 104 105 return 0; 106 } 107 108 int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op, 109 unsigned int num); 110 int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op, 111 unsigned int num); 112 int lwtunnel_valid_encap_type(u16 encap_type, 113 struct netlink_ext_ack *extack); 114 int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len, 115 struct netlink_ext_ack *extack); 116 int lwtunnel_build_state(struct net *net, u16 encap_type, 117 struct nlattr *encap, 118 unsigned int family, const void *cfg, 119 struct lwtunnel_state **lws, 120 struct netlink_ext_ack *extack); 121 int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate, 122 int encap_attr, int encap_type_attr); 123 int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate); 124 struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len); 125 int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b); 126 int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb); 127 int lwtunnel_input(struct sk_buff *skb); 128 int lwtunnel_xmit(struct sk_buff *skb); 129 int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len, 130 bool ingress); 131 132 static inline void lwtunnel_set_redirect(struct dst_entry *dst) 133 { 134 if (lwtunnel_output_redirect(dst->lwtstate)) { 135 dst->lwtstate->orig_output = dst->output; 136 dst->output = lwtunnel_output; 137 } 138 if (lwtunnel_input_redirect(dst->lwtstate)) { 139 dst->lwtstate->orig_input = dst->input; 140 dst->input = lwtunnel_input; 141 } 142 } 143 #else 144 145 static inline void lwtstate_free(struct lwtunnel_state *lws) 146 { 147 } 148 149 static inline struct lwtunnel_state * 150 lwtstate_get(struct lwtunnel_state *lws) 151 { 152 return lws; 153 } 154 155 static inline void lwtstate_put(struct lwtunnel_state *lws) 156 { 157 } 158 159 static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate) 160 { 161 return false; 162 } 163 164 static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate) 165 { 166 return false; 167 } 168 169 static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate) 170 { 171 return false; 172 } 173 174 static inline void lwtunnel_set_redirect(struct dst_entry *dst) 175 { 176 } 177 178 static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate, 179 unsigned int mtu) 180 { 181 return 0; 182 } 183 184 static inline int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op, 185 unsigned int num) 186 { 187 return -EOPNOTSUPP; 188 189 } 190 191 static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op, 192 unsigned int num) 193 { 194 return -EOPNOTSUPP; 195 } 196 197 static inline int lwtunnel_valid_encap_type(u16 encap_type, 198 struct netlink_ext_ack *extack) 199 { 200 NL_SET_ERR_MSG(extack, "CONFIG_LWTUNNEL is not enabled in this kernel"); 201 return -EOPNOTSUPP; 202 } 203 static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len, 204 struct netlink_ext_ack *extack) 205 { 206 /* return 0 since we are not walking attr looking for 207 * RTA_ENCAP_TYPE attribute on nexthops. 208 */ 209 return 0; 210 } 211 212 static inline int lwtunnel_build_state(struct net *net, u16 encap_type, 213 struct nlattr *encap, 214 unsigned int family, const void *cfg, 215 struct lwtunnel_state **lws, 216 struct netlink_ext_ack *extack) 217 { 218 return -EOPNOTSUPP; 219 } 220 221 static inline int lwtunnel_fill_encap(struct sk_buff *skb, 222 struct lwtunnel_state *lwtstate, 223 int encap_attr, int encap_type_attr) 224 { 225 return 0; 226 } 227 228 static inline int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate) 229 { 230 return 0; 231 } 232 233 static inline struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len) 234 { 235 return NULL; 236 } 237 238 static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a, 239 struct lwtunnel_state *b) 240 { 241 return 0; 242 } 243 244 static inline int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb) 245 { 246 return -EOPNOTSUPP; 247 } 248 249 static inline int lwtunnel_input(struct sk_buff *skb) 250 { 251 return -EOPNOTSUPP; 252 } 253 254 static inline int lwtunnel_xmit(struct sk_buff *skb) 255 { 256 return -EOPNOTSUPP; 257 } 258 259 #endif /* CONFIG_LWTUNNEL */ 260 261 #define MODULE_ALIAS_RTNL_LWT(encap_type) MODULE_ALIAS("rtnl-lwt-" __stringify(encap_type)) 262 263 #endif /* __NET_LWTUNNEL_H */ 264