Skip to content

Commit cc91b09

Browse files
author
Paolo Abeni
committed
Merge branch 'seg6-fix-skb-checksum-for-srh-encapsulation-insertion'
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/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents f46a5a9 + 4889fbd commit cc91b09

File tree

3 files changed

+4
-4
lines changed

3 files changed

+4
-4
lines changed

net/core/filter.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6158,7 +6158,6 @@ static int bpf_push_seg6_encap(struct sk_buff *skb, u32 type, void *hdr, u32 len
61586158
if (err)
61596159
return err;
61606160

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

61646163
return seg6_lookup_nexthop(skb, NULL, 0);

net/ipv6/seg6_iptunnel.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
189189
}
190190
#endif
191191

192+
hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
193+
192194
skb_postpush_rcsum(skb, hdr, tot_len);
193195

194196
return 0;
@@ -241,6 +243,8 @@ int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh)
241243
}
242244
#endif
243245

246+
hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
247+
244248
skb_postpush_rcsum(skb, hdr, sizeof(struct ipv6hdr) + hdrlen);
245249

246250
return 0;
@@ -302,7 +306,6 @@ static int seg6_do_srh(struct sk_buff *skb)
302306
break;
303307
}
304308

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

net/ipv6/seg6_local.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,6 @@ static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt)
826826
if (err)
827827
goto drop;
828828

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

832831
seg6_lookup_nexthop(skb, NULL, 0);
@@ -858,7 +857,6 @@ static int input_action_end_b6_encap(struct sk_buff *skb,
858857
if (err)
859858
goto drop;
860859

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

864862
seg6_lookup_nexthop(skb, NULL, 0);

0 commit comments

Comments
 (0)