History

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) ====================

Paolo Abeni committed 4 years ago

Commit cc91b092 parents f46a5a9 4889fbd3 files · +4 −4Browse files

Unified · Split

3 files
  1. net/core/filter.c +0 −1
  2. net/ipv6/seg6_iptunnel.c +4 −1
  3. net/ipv6/seg6_local.c +0 −2
net/core/filter.c+0−1
@@ -6158,7 +6158,6 @@ static int bpf_push_seg6_encap(struct sk_buff *skb, u32 type, void *hdr, u32 len · 6157 unmodified lines
6158 if (err)6158 if (err)
6159 return err;6159 return err;
6160 6160
6161 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
6162 skb_set_transport_header(skb, sizeof(struct ipv6hdr));6161 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
6163 6162
6164 return seg6_lookup_nexthop(skb, NULL, 0);6163 return seg6_lookup_nexthop(skb, NULL, 0);
net/ipv6/seg6_iptunnel.c+4−1
@@ -189,6 +189,8 @@ int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto) · 188 unmodified lines
189 }189 }
190#endif190#endif
191 191
192 hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
193
192 skb_postpush_rcsum(skb, hdr, tot_len);194 skb_postpush_rcsum(skb, hdr, tot_len);
193 195
194 return 0;196 return 0;
@@ -241,6 +243,8 @@ int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh) · 46 unmodified lines
241 }243 }
242#endif244#endif
243 245
246 hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
247
244 skb_postpush_rcsum(skb, hdr, sizeof(struct ipv6hdr) + hdrlen);248 skb_postpush_rcsum(skb, hdr, sizeof(struct ipv6hdr) + hdrlen);
245 249
246 return 0;250 return 0;
@@ -302,7 +306,6 @@ static int seg6_do_srh(struct sk_buff *skb) · 55 unmodified lines
302 break;306 break;
303 }307 }
304 308
305 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
306 skb_set_transport_header(skb, sizeof(struct ipv6hdr));309 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
307 nf_reset_ct(skb);310 nf_reset_ct(skb);
308 311
net/ipv6/seg6_local.c+0−2
@@ -826,7 +826,6 @@ static int input_action_end_b6(struct sk_buff *skb, struct seg6_local_lwt *slwt) · 825 unmodified lines
826 if (err)826 if (err)
827 goto drop;827 goto drop;
828 828
829 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
830 skb_set_transport_header(skb, sizeof(struct ipv6hdr));829 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
831 830
832 seg6_lookup_nexthop(skb, NULL, 0);831 seg6_lookup_nexthop(skb, NULL, 0);
@@ -858,7 +857,6 @@ static int input_action_end_b6_encap(struct sk_buff *skb, · 25 unmodified lines
858 if (err)857 if (err)
859 goto drop;858 goto drop;
860 859
861 ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
862 skb_set_transport_header(skb, sizeof(struct ipv6hdr));860 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
863 861
864 seg6_lookup_nexthop(skb, NULL, 0);862 seg6_lookup_nexthop(skb, NULL, 0);