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