On Mon, Nov 5, 2012 at 1:13 PM, Ansis Atteka <aatt...@nicira.com> wrote:

> On Mon, Nov 5, 2012 at 8:58 PM, Jesse Gross <je...@nicira.com> wrote:
> > On Sun, Nov 4, 2012 at 7:44 AM, Ansis Atteka <aatt...@nicira.com> wrote:
> >> On Tue, Oct 30, 2012 at 1:11 AM, Jesse Gross <je...@nicira.com> wrote:
> >>> On Sun, Oct 28, 2012 at 2:21 PM, Ansis Atteka <aatt...@nicira.com>
> wrote:
> >>>> diff --git a/datapath/actions.c b/datapath/actions.c
> >>>> index ec9b595..7e60b0f 100644
> >>>> --- a/datapath/actions.c
> >>>> +++ b/datapath/actions.c
> >>>> +static void set_ipv6_addr(struct sk_buff *skb, struct ipv6hdr *nh,
> >>>> +                         __be32 addr[4], const __be32 new_addr[4])
> >>>> +{
> >>>> +       int transport_len = skb->len - skb_transport_offset(skb);
> >>>> +
> >>>> +       if (nh->nexthdr == IPPROTO_TCP) {
> >>>> +               if (likely(transport_len >= sizeof(struct tcphdr)))
> >>>> +
> inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb,
> >>>> +                                                 addr, new_addr, 1);
> >>>> +       } else if (nh->nexthdr == IPPROTO_UDP) {
> >>>> +               if (likely(transport_len >= sizeof(struct udphdr))) {
> >>>> +                       struct udphdr *uh = udp_hdr(skb);
> >>>> +
> >>>> +                       if (uh->check ||
> >>>> +                           get_ip_summed(skb) == OVS_CSUM_PARTIAL) {
> >>>> +                               inet_proto_csum_replace16(&uh->check,
> skb,
> >>>> +                                                         addr,
> new_addr, 1);
> >>>> +                               if (!uh->check)
> >>>> +                                       uh->check = CSUM_MANGLED_0;
> >>>> +                       }
> >>>> +               }
> >>>> +       }
> >>>
> >>> IPv6 has an extra little twist when it comes to checksums compared to
> >>> IPv4: routing headers.  In an IPv6 packet, the destination IP address
> >>> used for the purposes of checksum calculation in the pseudo header is
> >>> the final destination address.  This means that if you have a routing
> >>> header then it is that address that matters and not one in the IP
> >>> header.  This is likely to be a pretty rare case but we should handle
> >>> it.
> >> There could be a chain of ipv6 extension headers. And the Routing
> >> Header could be in the middle of that chain. Can you confirm, if
> >> ipv6_find_hdr() function is good enough to get the routing header?
> >
> > Yes, it seems to be basically fine.  Two things that come to mind are:
> > what happens if there are multiple routing headers (is this legal?)
> RFC3542 has implication "When multiple Routing headers are received
> ...". This makes me think that multiple routing headers are legal.
>
> This means that L4 checksum shouldn't be updated, if there exists at
> least one routing header, where segments_left > 0. Otherwise, we have
> to update L4 checksums.
>

That sounds right to me.


> > and ipv6_find_hdr() is in the ip6_tables module so using it will
> > create a dependency, which we don't want.  We probably should move it
> > somewhere else.
> This ipv6_find_hdr() function seems to be able to handle only single
> routing header. Perhaps I will write my own function that will iterate
> over all extension headers and tell the caller, whether the
> ipv6hdr->daddr is the final destination address.


That sounds fine although if possible we should try to modify the existing
function to do what we want rather than adding a new one.


> >
> > You might want to look to see how IPv6 NAT handles this case currently.
> Either I am overlooking that IPv6 NAT code or it does not handle
> routing headers and checksums as I would have expected.
>
> The nf_nat_ipv6_csum_update() is called, for example, from
> tcp_manip_pkt(). And it seems that it always updates L4 checksums
> without taking into account routing headers. Will check it tomorrow
> morning one more time.


I agree, it looks like those functions don't handle this case.  We should
still try to get it right regardless though.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to