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