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