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 atomic_t refcnt; 28 int (*orig_output)(struct net *net, struct sock *sk, struct sk_buff *skb); 29 int (*orig_input)(struct sk_buff *); 30 int len; 31 __u16 headroom; 32 __u8 data[0]; 33 }; 34 35 struct lwtunnel_encap_ops { 36 int (*build_state)(struct net_device *dev, struct nlattr *encap, 37 unsigned int family, const void *cfg, 38 struct lwtunnel_state **ts); 39 int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb); 40 int (*input)(struct sk_buff *skb); 41 int (*fill_encap)(struct sk_buff *skb, 42 struct lwtunnel_state *lwtstate); 43 int (*get_encap_size)(struct lwtunnel_state *lwtstate); 44 int (*cmp_encap)(struct lwtunnel_state *a, struct lwtunnel_state *b); 45 int (*xmit)(struct sk_buff *skb); 46 }; 47 48 #ifdef CONFIG_LWTUNNEL 49 static inline void lwtstate_free(struct lwtunnel_state *lws) 50 { 51 kfree(lws); 52 } 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) && lwtstate->headroom < mtu) 100 return lwtstate->headroom; 101 102 return 0; 103 } 104 105 int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op, 106 unsigned int num); 107 int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op, 108 unsigned int num); 109 int lwtunnel_build_state(struct net_device *dev, u16 encap_type, 110 struct nlattr *encap, 111 unsigned int family, const void *cfg, 112 struct lwtunnel_state **lws); 113 int lwtunnel_fill_encap(struct sk_buff *skb, 114 struct lwtunnel_state *lwtstate); 115 int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate); 116 struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len); 117 int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b); 118 int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb); 119 int lwtunnel_input(struct sk_buff *skb); 120 int lwtunnel_xmit(struct sk_buff *skb); 121 122 #else 123 124 static inline void lwtstate_free(struct lwtunnel_state *lws) 125 { 126 } 127 128 static inline struct lwtunnel_state * 129 lwtstate_get(struct lwtunnel_state *lws) 130 { 131 return lws; 132 } 133 134 static inline void lwtstate_put(struct lwtunnel_state *lws) 135 { 136 } 137 138 static inline bool lwtunnel_output_redirect(struct lwtunnel_state *lwtstate) 139 { 140 return false; 141 } 142 143 static inline bool lwtunnel_input_redirect(struct lwtunnel_state *lwtstate) 144 { 145 return false; 146 } 147 148 static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate) 149 { 150 return false; 151 } 152 153 static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate, 154 unsigned int mtu) 155 { 156 return 0; 157 } 158 159 static inline int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op, 160 unsigned int num) 161 { 162 return -EOPNOTSUPP; 163 164 } 165 166 static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op, 167 unsigned int num) 168 { 169 return -EOPNOTSUPP; 170 } 171 172 static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type, 173 struct nlattr *encap, 174 unsigned int family, const void *cfg, 175 struct lwtunnel_state **lws) 176 { 177 return -EOPNOTSUPP; 178 } 179 180 static inline int lwtunnel_fill_encap(struct sk_buff *skb, 181 struct lwtunnel_state *lwtstate) 182 { 183 return 0; 184 } 185 186 static inline int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate) 187 { 188 return 0; 189 } 190 191 static inline struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len) 192 { 193 return NULL; 194 } 195 196 static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a, 197 struct lwtunnel_state *b) 198 { 199 return 0; 200 } 201 202 static inline int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb) 203 { 204 return -EOPNOTSUPP; 205 } 206 207 static inline int lwtunnel_input(struct sk_buff *skb) 208 { 209 return -EOPNOTSUPP; 210 } 211 212 static inline int lwtunnel_xmit(struct sk_buff *skb) 213 { 214 return -EOPNOTSUPP; 215 } 216 217 #endif /* CONFIG_LWTUNNEL */ 218 219 #define MODULE_ALIAS_RTNL_LWT(encap_type) MODULE_ALIAS("rtnl-lwt-" __stringify(encap_type)) 220 221 #endif /* __NET_LWTUNNEL_H */ 222