Skip to content

Commit

Permalink
Merge branch 'seg6-fix-skb-checksum-for-srh-encapsulation-insertion'
Browse files Browse the repository at this point in the history
Andrea Mayer says:

====================
seg6: fix skb checksum for SRH encapsulation/insertion

The Linux kernel supports Segment Routing Header (SRH)
encapsulation/insertion operations by providing the capability to: i)
encapsulate a packet in an outer IPv6 header with a specified SRH; ii)
insert a specified SRH directly after the IPv6 header of the packet.
Note that the insertion operation is also referred to as 'injection'.

The two operations are respectively supported by seg6_do_srh_encap() and
seg6_do_srh_inline(), which operate on the skb associated to the packet as
needed (e.g. adding the necessary headers and initializing them, while
taking care to recalculate the skb checksum).

seg6_do_srh_encap() and seg6_do_srh_inline() do not initialize the payload
length of the IPv6 header, which is carried out by the caller functions.
However, this approach causes the corruption of the skb checksum which
needs to be updated only after initialization of headers is completed
(thanks to Paolo Abeni for detecting this issue).

The patchset fixes the skb checksum corruption by moving the IPv6 header
payload length initialization from the callers of seg6_do_srh_encap() and
seg6_do_srh_inline() directly into these functions.

This patchset is organized as follows:
 - patch 1/3, seg6: fix skb checksum evaluation in SRH
   encapsulation/insertion;
    (* SRH encapsulation/insertion available since v4.10)

 - patch 2/3, seg6: fix skb checksum in SRv6 End.B6 and End.B6.Encaps
   behaviors;
    (* SRv6 End.B6 and End.B6.Encaps behaviors available since v4.14)

 - patch 3/3, seg6: bpf: fix skb checksum in bpf_push_seg6_encap();
    (* bpf IPv6 Segment Routing helpers available since v4.18)

====================

Link: https://lore.kernel.org/r/20220712175837.16267-1-andrea.mayer@uniroma2.it
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Paolo Abeni committed Jul 14, 2022
2 parents f46a5a9 + 4889fbd commit cc91b09
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 4 deletions.
1 change: 0 additions & 1 deletion net/core/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -6158,7 +6158,6 @@ static int bpf_push_seg6_encap(struct sk_buff *skb, u32 type, void *hdr, u32 len
if (err)
return err;

ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
skb_set_transport_header(skb, sizeof(struct ipv6hdr));

return seg6_lookup_nexthop(skb, NULL, 0);
Expand Down
5 changes: 4 additions & 1 deletion net/ipv6/seg6_iptunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
}
#endif

hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));

skb_postpush_rcsum(skb, hdr, tot_len);

return 0;
Expand Down Expand Up @@ -241,6 +243,8 @@ int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh)
}
#endif

hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));

skb_postpush_rcsum(skb, hdr, sizeof(struct ipv6hdr) + hdrlen);

return 0;
Expand Down Expand Up @@ -302,7 +306,6 @@ static int seg6_do_srh(struct sk_buff *skb)
break;
}

ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
nf_reset_ct(skb);

Expand Down
2 changes: 0 additions & 2 deletions net/ipv6/seg6_local.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,6 @@ static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt)
if (err)
goto drop;

ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
skb_set_transport_header(skb, sizeof(struct ipv6hdr));

seg6_lookup_nexthop(skb, NULL, 0);
Expand Down Expand Up @@ -858,7 +857,6 @@ static int input_action_end_b6_encap(struct sk_buff *skb,
if (err)
goto drop;

ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
skb_set_transport_header(skb, sizeof(struct ipv6hdr));

seg6_lookup_nexthop(skb, NULL, 0);
Expand Down

0 comments on commit cc91b09

Please sign in to comment.