On Thu, Nov 22, 2012 at 7:57 AM, Pravin B Shelar <[email protected]> wrote:
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index 585aca7..a23df86 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -422,6 +424,7 @@ struct sk_buff {
> __u16 csum_offset;
> };
> };
> + __u16 tunnel_hlen;
Is it possible to use those new inner header pointers that were added here?
> diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
> index c256008..1ce522a 100644
> --- a/net/ipv4/udp.c
> +++ b/net/ipv4/udp.c
> @@ -2246,31 +2246,79 @@ void __init udp_init(void)
>
> int udp4_ufo_send_check(struct sk_buff *skb)
> {
> - const struct iphdr *iph;
> - struct udphdr *uh;
> -
> - if (!pskb_may_pull(skb, sizeof(*uh)))
> + if (!pskb_may_pull(skb, sizeof(struct udphdr)))
> return -EINVAL;
>
> - iph = ip_hdr(skb);
> - uh = udp_hdr(skb);
> + if (!skb->tunnel_hlen) {
Don't we have to pass this down to the encapsulated protocol below
since that's the checksum that we really care about?
> +static struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
> + netdev_features_t features)
> +{
> + struct sk_buff *segs = ERR_PTR(-EINVAL);
> + int mac_len = skb->mac_len;
> + unsigned char *mac = skb_mac_header(skb);
> + int hlen = sizeof(struct udphdr) + skb->tunnel_hlen;
> + int doffset;
> + int network_hlen = skb_network_header_len(skb);
> +
> + skb->tunnel_hlen = 0;
> + if (unlikely(!pskb_may_pull(skb, hlen)))
> + goto out;
> +
> + __skb_pull(skb, hlen);
> + skb_reset_mac_header(skb);
> + skb_set_network_header(skb, skb->mac_len);
> + doffset = skb_mac_header(skb) - mac;
> +
> + /* segment inner packet. */
> + segs = skb_gso_segment(skb, 0);
> + if (!segs || IS_ERR(segs))
> + goto out;
I have similar questions here as with GRE about whether it is safe to
reuse skb->mac_len and if we can avoid the loop with memcpy() by
calling directly into the next layer for segmentation.
> diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
> index 8234c1d..e02a65a 100644
> --- a/net/ipv6/ip6_offload.c
> +++ b/net/ipv6/ip6_offload.c
> @@ -100,6 +100,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff
> *skb,
> SKB_GSO_DODGY |
> SKB_GSO_TCP_ECN |
> SKB_GSO_GRE |
> + SKB_GSO_UDP_TUNNEL |
> SKB_GSO_TCPV6 |
> 0)))
> goto out;
Do we need to do the check to avoid fragmenting UDP for IPv6 as well?
> diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
> index cf05cf0..8530d57 100644
> --- a/net/ipv6/udp_offload.c
> +++ b/net/ipv6/udp_offload.c
> @@ -21,6 +21,9 @@ static int udp6_ufo_send_check(struct sk_buff *skb)
> const struct ipv6hdr *ipv6h;
> struct udphdr *uh;
>
> + if (skb->tunnel_hlen)
> + return -EINVAL;
Can't we support IPv6 fairly easily as well?
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev