gre: Create common functions for transmit
Create common functions for both IPv4 and IPv6 GRE in transmit. These are put into gre.h. Common functions are for: - GRE checksum calculation. Move gre_checksum to gre.h. - Building a GRE header. Move GRE build_header and rename gre_build_header. Signed-off-by: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8eb30be035
commit
182a352d2d
@ -85,4 +85,48 @@ static inline __be16 gre_tnl_flags_to_gre_flags(__be16 tflags)
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline __sum16 gre_checksum(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
__wsum csum;
|
||||||
|
|
||||||
|
if (skb->ip_summed == CHECKSUM_PARTIAL)
|
||||||
|
csum = lco_csum(skb);
|
||||||
|
else
|
||||||
|
csum = skb_checksum(skb, 0, skb->len, 0);
|
||||||
|
return csum_fold(csum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gre_build_header(struct sk_buff *skb, int hdr_len,
|
||||||
|
__be16 flags, __be16 proto,
|
||||||
|
__be32 key, __be32 seq)
|
||||||
|
{
|
||||||
|
struct gre_base_hdr *greh;
|
||||||
|
|
||||||
|
skb_push(skb, hdr_len);
|
||||||
|
|
||||||
|
skb_reset_transport_header(skb);
|
||||||
|
greh = (struct gre_base_hdr *)skb->data;
|
||||||
|
greh->flags = gre_tnl_flags_to_gre_flags(flags);
|
||||||
|
greh->protocol = proto;
|
||||||
|
|
||||||
|
if (flags & (TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_SEQ)) {
|
||||||
|
__be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
|
||||||
|
|
||||||
|
if (flags & TUNNEL_SEQ) {
|
||||||
|
*ptr = seq;
|
||||||
|
ptr--;
|
||||||
|
}
|
||||||
|
if (flags & TUNNEL_KEY) {
|
||||||
|
*ptr = key;
|
||||||
|
ptr--;
|
||||||
|
}
|
||||||
|
if (flags & TUNNEL_CSUM &&
|
||||||
|
!(skb_shinfo(skb)->gso_type &
|
||||||
|
(SKB_GSO_GRE | SKB_GSO_GRE_CSUM))) {
|
||||||
|
*ptr = 0;
|
||||||
|
*(__sum16 *)ptr = gre_checksum(skb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -329,49 +329,6 @@ drop:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __sum16 gre_checksum(struct sk_buff *skb)
|
|
||||||
{
|
|
||||||
__wsum csum;
|
|
||||||
|
|
||||||
if (skb->ip_summed == CHECKSUM_PARTIAL)
|
|
||||||
csum = lco_csum(skb);
|
|
||||||
else
|
|
||||||
csum = skb_checksum(skb, 0, skb->len, 0);
|
|
||||||
return csum_fold(csum);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void build_header(struct sk_buff *skb, int hdr_len, __be16 flags,
|
|
||||||
__be16 proto, __be32 key, __be32 seq)
|
|
||||||
{
|
|
||||||
struct gre_base_hdr *greh;
|
|
||||||
|
|
||||||
skb_push(skb, hdr_len);
|
|
||||||
|
|
||||||
skb_reset_transport_header(skb);
|
|
||||||
greh = (struct gre_base_hdr *)skb->data;
|
|
||||||
greh->flags = gre_tnl_flags_to_gre_flags(flags);
|
|
||||||
greh->protocol = proto;
|
|
||||||
|
|
||||||
if (flags & (TUNNEL_KEY | TUNNEL_CSUM | TUNNEL_SEQ)) {
|
|
||||||
__be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
|
|
||||||
|
|
||||||
if (flags & TUNNEL_SEQ) {
|
|
||||||
*ptr = seq;
|
|
||||||
ptr--;
|
|
||||||
}
|
|
||||||
if (flags & TUNNEL_KEY) {
|
|
||||||
*ptr = key;
|
|
||||||
ptr--;
|
|
||||||
}
|
|
||||||
if (flags & TUNNEL_CSUM &&
|
|
||||||
!(skb_shinfo(skb)->gso_type &
|
|
||||||
(SKB_GSO_GRE | SKB_GSO_GRE_CSUM))) {
|
|
||||||
*ptr = 0;
|
|
||||||
*(__sum16 *)ptr = gre_checksum(skb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
|
static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||||
const struct iphdr *tnl_params,
|
const struct iphdr *tnl_params,
|
||||||
__be16 proto)
|
__be16 proto)
|
||||||
@ -382,8 +339,9 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev,
|
|||||||
tunnel->o_seqno++;
|
tunnel->o_seqno++;
|
||||||
|
|
||||||
/* Push GRE header. */
|
/* Push GRE header. */
|
||||||
build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
|
gre_build_header(skb, tunnel->tun_hlen,
|
||||||
proto, tunnel->parms.o_key, htonl(tunnel->o_seqno));
|
tunnel->parms.o_flags, proto, tunnel->parms.o_key,
|
||||||
|
htonl(tunnel->o_seqno));
|
||||||
|
|
||||||
skb_set_inner_protocol(skb, proto);
|
skb_set_inner_protocol(skb, proto);
|
||||||
ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
|
ip_tunnel_xmit(skb, dev, tnl_params, tnl_params->protocol);
|
||||||
@ -460,7 +418,7 @@ static void gre_fb_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
goto err_free_rt;
|
goto err_free_rt;
|
||||||
|
|
||||||
flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
|
flags = tun_info->key.tun_flags & (TUNNEL_CSUM | TUNNEL_KEY);
|
||||||
build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB),
|
gre_build_header(skb, tunnel_hlen, flags, htons(ETH_P_TEB),
|
||||||
tunnel_id_to_key(tun_info->key.tun_id), 0);
|
tunnel_id_to_key(tun_info->key.tun_id), 0);
|
||||||
|
|
||||||
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
|
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user