Re: [iovisor-dev] How to update the csum of a trimmed UDP packet?
On 01/11/2017 05:32 PM, Daniel Borkmann wrote: On 01/11/2017 10:51 PM, Mauricio Vasquez wrote: Hi Daniel, On 01/10/2017 04:49 AM, Daniel Borkmann wrote: On 01/09/2017 04:48 PM, Mauricio Vasquez via iovisor-dev wrote: Hello, I am trying to implement an eBPF program that trims an UDP packet to a predefined length. I am able to trim the packet (using the bpf_change_tail helper) and also to update the ip->len and udp->length fields. After changing the those fields I update the checksums using the bpf_[l3,l4]_csum_replace helpers. Due to the fact that the UDP checksum also covers the data itself, it is necessary to update it. I tried to use the bpf_csum_diff together with the bpf_l4_csum_replace helpers, however I found that is not possible to pass a variable size to the bpf_csum_diff as it is marked as "ARG_CONST_STACK_SIZE_OR_ZER" in the function prototype. This limitation makes it impossible to update the checksum on different packets size as the quantity of bytes to be trimmed depends on the length of the packet. The code is available at [1] (please note that it is based on hover). The error that I get when I tried to load the program is: 31: (61) r9 = *(u32 *)(r6 +48) 32: (61) r2 = *(u32 *)(r6 +0) 33: (07) r2 += -100 34: (67) r2 <<= 32 35: (77) r2 >>= 32 36: (b7) r8 = 0 37: (b7) r3 = 0 38: (b7) r4 = 0 39: (b7) r5 = 0 40: (85) call 28 R2 type=inv expected=imm My questions are. 1. Am I missing another way to update the UDP checksum? 2. In case 1 is false, how could it be implemented? I think having a function to trim the packet without having a way to update the checksum is, in some way, useless. What's your specific use-case on this? Reason why I'm asking is that the helper needs to linearize skb and is thus only suitable for slow path [1]. We are implementing a DHCP server, DHCP messages are quite unusual so slow path helpers are not a problem in this case. F.e. we use it for rewriting an skb as time exceeded reply [2]. How far from the header start are you trimming? Perhaps it's feasible to to calc the csum up to the point of trimming via bpf_csum_diff()? Thanks to it I realized that I was doing the difficult way, I was trying to "remove" the trimmed bytes from the checksum. I am trying to implement it in a way similar to [2], calculating the checksum from scratch. [...] /* calculate checksum of the new udp packet */ u32 src_ip = bpf_htonl(ip->src); u32 dst_ip = bpf_htonl(ip->dst); u32 len_udp_n = ((u32)ip->nextp<<8) | (bpf_htons(ip->tlen)<<16); On just a very quick glance, don't you need UDP length here (aka UDP header and data)? You got it!!, It is working now. Thanks! int csum = bpf_csum_diff(NULL, 0, data + sizeof(struct ethernet_t) + sizeof(struct ip_t), udp_len, 0); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _udp_n, 4, csum); bpf_trace_printk("[dhcp] csum: %x\n", csum); err = bpf_l4_csum_replace(skb, UDP_CRC_OFF, 0, csum, BPF_F_PSEUDO_HDR); [...] The full code of this test is available at [1]. I am calculating the csum of the udp packet itself, for that reason I skip the ethernet and ip headers on the first call to bpf_csum_diff. Then, as the UDP checksum includes a IPV4 pseudo header [2], I update the csum including those fields. This code compiles and passes verification, however it is not calculating the checksum correctly. According to wireshark there is always a difference of 0x14 between the calculated and the expected checksums. I am pretty sure that I am missing something about checksums, but I cannot figure it out. Can you spot some mistake on that code? Thank you very much, Mauricio V. [1] https://gist.github.com/mvbpolito/9697247eba1c412cd4a6c8efe6fab55d [2] https://www.ietf.org/rfc/rfc768.txt Did you check whether [3] could help in that? [1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5293efe62df81908f2e90c9820c7edcc8e61f5e9 [2] https://github.com/cilium/cilium/blob/master/bpf/lib/icmp6.h [3] https://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/?id=06c1c049721a995dee2829ad13b24aaf5d7c5cce Thanks in advance. Mauricio V. [1] https://gist.github.com/mvbpolito/77edb3b4e65cc03c92862b3f17452286 ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev
Re: [iovisor-dev] How to update the csum of a trimmed UDP packet?
On 01/11/2017 05:08 PM, Fulvio Risso wrote: Mauricio, is the UDP checksum needed? It seems to me that the checksum, in case of UDP frames, is optional. You are right Fulvio, it is optional in IPv4, however I wanted to know I was failing to calculate it. We can then discuss about if it makes sense or not to calculate it in the DHCP case. fulvio On 11/01/2017 22:51, Mauricio Vasquez via iovisor-dev wrote: Hi Daniel, On 01/10/2017 04:49 AM, Daniel Borkmann wrote: On 01/09/2017 04:48 PM, Mauricio Vasquez via iovisor-dev wrote: Hello, I am trying to implement an eBPF program that trims an UDP packet to a predefined length. I am able to trim the packet (using the bpf_change_tail helper) and also to update the ip->len and udp->length fields. After changing the those fields I update the checksums using the bpf_[l3,l4]_csum_replace helpers. Due to the fact that the UDP checksum also covers the data itself, it is necessary to update it. I tried to use the bpf_csum_diff together with the bpf_l4_csum_replace helpers, however I found that is not possible to pass a variable size to the bpf_csum_diff as it is marked as "ARG_CONST_STACK_SIZE_OR_ZER" in the function prototype. This limitation makes it impossible to update the checksum on different packets size as the quantity of bytes to be trimmed depends on the length of the packet. The code is available at [1] (please note that it is based on hover). The error that I get when I tried to load the program is: 31: (61) r9 = *(u32 *)(r6 +48) 32: (61) r2 = *(u32 *)(r6 +0) 33: (07) r2 += -100 34: (67) r2 <<= 32 35: (77) r2 >>= 32 36: (b7) r8 = 0 37: (b7) r3 = 0 38: (b7) r4 = 0 39: (b7) r5 = 0 40: (85) call 28 R2 type=inv expected=imm My questions are. 1. Am I missing another way to update the UDP checksum? 2. In case 1 is false, how could it be implemented? I think having a function to trim the packet without having a way to update the checksum is, in some way, useless. What's your specific use-case on this? Reason why I'm asking is that the helper needs to linearize skb and is thus only suitable for slow path [1]. We are implementing a DHCP server, DHCP messages are quite unusual so slow path helpers are not a problem in this case. F.e. we use it for rewriting an skb as time exceeded reply [2]. How far from the header start are you trimming? Perhaps it's feasible to to calc the csum up to the point of trimming via bpf_csum_diff()? Thanks to it I realized that I was doing the difficult way, I was trying to "remove" the trimmed bytes from the checksum. I am trying to implement it in a way similar to [2], calculating the checksum from scratch. [...] /* calculate checksum of the new udp packet */ u32 src_ip = bpf_htonl(ip->src); u32 dst_ip = bpf_htonl(ip->dst); u32 len_udp_n = ((u32)ip->nextp<<8) | (bpf_htons(ip->tlen)<<16); int csum = bpf_csum_diff(NULL, 0, data + sizeof(struct ethernet_t) + sizeof(struct ip_t), udp_len, 0); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _udp_n, 4, csum); bpf_trace_printk("[dhcp] csum: %x\n", csum); err = bpf_l4_csum_replace(skb, UDP_CRC_OFF, 0, csum, BPF_F_PSEUDO_HDR); [...] The full code of this test is available at [1]. I am calculating the csum of the udp packet itself, for that reason I skip the ethernet and ip headers on the first call to bpf_csum_diff. Then, as the UDP checksum includes a IPV4 pseudo header [2], I update the csum including those fields. This code compiles and passes verification, however it is not calculating the checksum correctly. According to wireshark there is always a difference of 0x14 between the calculated and the expected checksums. I am pretty sure that I am missing something about checksums, but I cannot figure it out. Can you spot some mistake on that code? Thank you very much, Mauricio V. [1] https://gist.github.com/mvbpolito/9697247eba1c412cd4a6c8efe6fab55d [2] https://www.ietf.org/rfc/rfc768.txt Did you check whether [3] could help in that? [1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5293efe62df81908f2e90c9820c7edcc8e61f5e9 [2] https://github.com/cilium/cilium/blob/master/bpf/lib/icmp6.h [3] https://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/?id=06c1c049721a995dee2829ad13b24aaf5d7c5cce Thanks in advance. Mauricio V. [1] https://gist.github.com/mvbpolito/77edb3b4e65cc03c92862b3f17452286 ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev
Re: [iovisor-dev] How to update the csum of a trimmed UDP packet?
On 01/11/2017 10:51 PM, Mauricio Vasquez wrote: Hi Daniel, On 01/10/2017 04:49 AM, Daniel Borkmann wrote: On 01/09/2017 04:48 PM, Mauricio Vasquez via iovisor-dev wrote: Hello, I am trying to implement an eBPF program that trims an UDP packet to a predefined length. I am able to trim the packet (using the bpf_change_tail helper) and also to update the ip->len and udp->length fields. After changing the those fields I update the checksums using the bpf_[l3,l4]_csum_replace helpers. Due to the fact that the UDP checksum also covers the data itself, it is necessary to update it. I tried to use the bpf_csum_diff together with the bpf_l4_csum_replace helpers, however I found that is not possible to pass a variable size to the bpf_csum_diff as it is marked as "ARG_CONST_STACK_SIZE_OR_ZER" in the function prototype. This limitation makes it impossible to update the checksum on different packets size as the quantity of bytes to be trimmed depends on the length of the packet. The code is available at [1] (please note that it is based on hover). The error that I get when I tried to load the program is: 31: (61) r9 = *(u32 *)(r6 +48) 32: (61) r2 = *(u32 *)(r6 +0) 33: (07) r2 += -100 34: (67) r2 <<= 32 35: (77) r2 >>= 32 36: (b7) r8 = 0 37: (b7) r3 = 0 38: (b7) r4 = 0 39: (b7) r5 = 0 40: (85) call 28 R2 type=inv expected=imm My questions are. 1. Am I missing another way to update the UDP checksum? 2. In case 1 is false, how could it be implemented? I think having a function to trim the packet without having a way to update the checksum is, in some way, useless. What's your specific use-case on this? Reason why I'm asking is that the helper needs to linearize skb and is thus only suitable for slow path [1]. We are implementing a DHCP server, DHCP messages are quite unusual so slow path helpers are not a problem in this case. F.e. we use it for rewriting an skb as time exceeded reply [2]. How far from the header start are you trimming? Perhaps it's feasible to to calc the csum up to the point of trimming via bpf_csum_diff()? Thanks to it I realized that I was doing the difficult way, I was trying to "remove" the trimmed bytes from the checksum. I am trying to implement it in a way similar to [2], calculating the checksum from scratch. [...] /* calculate checksum of the new udp packet */ u32 src_ip = bpf_htonl(ip->src); u32 dst_ip = bpf_htonl(ip->dst); u32 len_udp_n = ((u32)ip->nextp<<8) | (bpf_htons(ip->tlen)<<16); On just a very quick glance, don't you need UDP length here (aka UDP header and data)? int csum = bpf_csum_diff(NULL, 0, data + sizeof(struct ethernet_t) + sizeof(struct ip_t), udp_len, 0); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _udp_n, 4, csum); bpf_trace_printk("[dhcp] csum: %x\n", csum); err = bpf_l4_csum_replace(skb, UDP_CRC_OFF, 0, csum, BPF_F_PSEUDO_HDR); [...] The full code of this test is available at [1]. I am calculating the csum of the udp packet itself, for that reason I skip the ethernet and ip headers on the first call to bpf_csum_diff. Then, as the UDP checksum includes a IPV4 pseudo header [2], I update the csum including those fields. This code compiles and passes verification, however it is not calculating the checksum correctly. According to wireshark there is always a difference of 0x14 between the calculated and the expected checksums. I am pretty sure that I am missing something about checksums, but I cannot figure it out. Can you spot some mistake on that code? Thank you very much, Mauricio V. [1] https://gist.github.com/mvbpolito/9697247eba1c412cd4a6c8efe6fab55d [2] https://www.ietf.org/rfc/rfc768.txt Did you check whether [3] could help in that? [1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5293efe62df81908f2e90c9820c7edcc8e61f5e9 [2] https://github.com/cilium/cilium/blob/master/bpf/lib/icmp6.h [3] https://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/?id=06c1c049721a995dee2829ad13b24aaf5d7c5cce Thanks in advance. Mauricio V. [1] https://gist.github.com/mvbpolito/77edb3b4e65cc03c92862b3f17452286 ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev
Re: [iovisor-dev] How to update the csum of a trimmed UDP packet?
Mauricio, is the UDP checksum needed? It seems to me that the checksum, in case of UDP frames, is optional. fulvio On 11/01/2017 22:51, Mauricio Vasquez via iovisor-dev wrote: Hi Daniel, On 01/10/2017 04:49 AM, Daniel Borkmann wrote: On 01/09/2017 04:48 PM, Mauricio Vasquez via iovisor-dev wrote: Hello, I am trying to implement an eBPF program that trims an UDP packet to a predefined length. I am able to trim the packet (using the bpf_change_tail helper) and also to update the ip->len and udp->length fields. After changing the those fields I update the checksums using the bpf_[l3,l4]_csum_replace helpers. Due to the fact that the UDP checksum also covers the data itself, it is necessary to update it. I tried to use the bpf_csum_diff together with the bpf_l4_csum_replace helpers, however I found that is not possible to pass a variable size to the bpf_csum_diff as it is marked as "ARG_CONST_STACK_SIZE_OR_ZER" in the function prototype. This limitation makes it impossible to update the checksum on different packets size as the quantity of bytes to be trimmed depends on the length of the packet. The code is available at [1] (please note that it is based on hover). The error that I get when I tried to load the program is: 31: (61) r9 = *(u32 *)(r6 +48) 32: (61) r2 = *(u32 *)(r6 +0) 33: (07) r2 += -100 34: (67) r2 <<= 32 35: (77) r2 >>= 32 36: (b7) r8 = 0 37: (b7) r3 = 0 38: (b7) r4 = 0 39: (b7) r5 = 0 40: (85) call 28 R2 type=inv expected=imm My questions are. 1. Am I missing another way to update the UDP checksum? 2. In case 1 is false, how could it be implemented? I think having a function to trim the packet without having a way to update the checksum is, in some way, useless. What's your specific use-case on this? Reason why I'm asking is that the helper needs to linearize skb and is thus only suitable for slow path [1]. We are implementing a DHCP server, DHCP messages are quite unusual so slow path helpers are not a problem in this case. F.e. we use it for rewriting an skb as time exceeded reply [2]. How far from the header start are you trimming? Perhaps it's feasible to to calc the csum up to the point of trimming via bpf_csum_diff()? Thanks to it I realized that I was doing the difficult way, I was trying to "remove" the trimmed bytes from the checksum. I am trying to implement it in a way similar to [2], calculating the checksum from scratch. [...] /* calculate checksum of the new udp packet */ u32 src_ip = bpf_htonl(ip->src); u32 dst_ip = bpf_htonl(ip->dst); u32 len_udp_n = ((u32)ip->nextp<<8) | (bpf_htons(ip->tlen)<<16); int csum = bpf_csum_diff(NULL, 0, data + sizeof(struct ethernet_t) + sizeof(struct ip_t), udp_len, 0); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _udp_n, 4, csum); bpf_trace_printk("[dhcp] csum: %x\n", csum); err = bpf_l4_csum_replace(skb, UDP_CRC_OFF, 0, csum, BPF_F_PSEUDO_HDR); [...] The full code of this test is available at [1]. I am calculating the csum of the udp packet itself, for that reason I skip the ethernet and ip headers on the first call to bpf_csum_diff. Then, as the UDP checksum includes a IPV4 pseudo header [2], I update the csum including those fields. This code compiles and passes verification, however it is not calculating the checksum correctly. According to wireshark there is always a difference of 0x14 between the calculated and the expected checksums. I am pretty sure that I am missing something about checksums, but I cannot figure it out. Can you spot some mistake on that code? Thank you very much, Mauricio V. [1] https://gist.github.com/mvbpolito/9697247eba1c412cd4a6c8efe6fab55d [2] https://www.ietf.org/rfc/rfc768.txt Did you check whether [3] could help in that? [1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5293efe62df81908f2e90c9820c7edcc8e61f5e9 [2] https://github.com/cilium/cilium/blob/master/bpf/lib/icmp6.h [3] https://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/?id=06c1c049721a995dee2829ad13b24aaf5d7c5cce Thanks in advance. Mauricio V. [1] https://gist.github.com/mvbpolito/77edb3b4e65cc03c92862b3f17452286 ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev
Re: [iovisor-dev] How to update the csum of a trimmed UDP packet?
Hi Daniel, On 01/10/2017 04:49 AM, Daniel Borkmann wrote: On 01/09/2017 04:48 PM, Mauricio Vasquez via iovisor-dev wrote: Hello, I am trying to implement an eBPF program that trims an UDP packet to a predefined length. I am able to trim the packet (using the bpf_change_tail helper) and also to update the ip->len and udp->length fields. After changing the those fields I update the checksums using the bpf_[l3,l4]_csum_replace helpers. Due to the fact that the UDP checksum also covers the data itself, it is necessary to update it. I tried to use the bpf_csum_diff together with the bpf_l4_csum_replace helpers, however I found that is not possible to pass a variable size to the bpf_csum_diff as it is marked as "ARG_CONST_STACK_SIZE_OR_ZER" in the function prototype. This limitation makes it impossible to update the checksum on different packets size as the quantity of bytes to be trimmed depends on the length of the packet. The code is available at [1] (please note that it is based on hover). The error that I get when I tried to load the program is: 31: (61) r9 = *(u32 *)(r6 +48) 32: (61) r2 = *(u32 *)(r6 +0) 33: (07) r2 += -100 34: (67) r2 <<= 32 35: (77) r2 >>= 32 36: (b7) r8 = 0 37: (b7) r3 = 0 38: (b7) r4 = 0 39: (b7) r5 = 0 40: (85) call 28 R2 type=inv expected=imm My questions are. 1. Am I missing another way to update the UDP checksum? 2. In case 1 is false, how could it be implemented? I think having a function to trim the packet without having a way to update the checksum is, in some way, useless. What's your specific use-case on this? Reason why I'm asking is that the helper needs to linearize skb and is thus only suitable for slow path [1]. We are implementing a DHCP server, DHCP messages are quite unusual so slow path helpers are not a problem in this case. F.e. we use it for rewriting an skb as time exceeded reply [2]. How far from the header start are you trimming? Perhaps it's feasible to to calc the csum up to the point of trimming via bpf_csum_diff()? Thanks to it I realized that I was doing the difficult way, I was trying to "remove" the trimmed bytes from the checksum. I am trying to implement it in a way similar to [2], calculating the checksum from scratch. [...] /* calculate checksum of the new udp packet */ u32 src_ip = bpf_htonl(ip->src); u32 dst_ip = bpf_htonl(ip->dst); u32 len_udp_n = ((u32)ip->nextp<<8) | (bpf_htons(ip->tlen)<<16); int csum = bpf_csum_diff(NULL, 0, data + sizeof(struct ethernet_t) + sizeof(struct ip_t), udp_len, 0); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _ip, 4, csum); csum = bpf_csum_diff (NULL, 0, _udp_n, 4, csum); bpf_trace_printk("[dhcp] csum: %x\n", csum); err = bpf_l4_csum_replace(skb, UDP_CRC_OFF, 0, csum, BPF_F_PSEUDO_HDR); [...] The full code of this test is available at [1]. I am calculating the csum of the udp packet itself, for that reason I skip the ethernet and ip headers on the first call to bpf_csum_diff. Then, as the UDP checksum includes a IPV4 pseudo header [2], I update the csum including those fields. This code compiles and passes verification, however it is not calculating the checksum correctly. According to wireshark there is always a difference of 0x14 between the calculated and the expected checksums. I am pretty sure that I am missing something about checksums, but I cannot figure it out. Can you spot some mistake on that code? Thank you very much, Mauricio V. [1] https://gist.github.com/mvbpolito/9697247eba1c412cd4a6c8efe6fab55d [2] https://www.ietf.org/rfc/rfc768.txt Did you check whether [3] could help in that? [1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5293efe62df81908f2e90c9820c7edcc8e61f5e9 [2] https://github.com/cilium/cilium/blob/master/bpf/lib/icmp6.h [3] https://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/?id=06c1c049721a995dee2829ad13b24aaf5d7c5cce Thanks in advance. Mauricio V. [1] https://gist.github.com/mvbpolito/77edb3b4e65cc03c92862b3f17452286 ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev
Re: [iovisor-dev] How to update the csum of a trimmed UDP packet?
On 01/09/2017 04:48 PM, Mauricio Vasquez via iovisor-dev wrote: Hello, I am trying to implement an eBPF program that trims an UDP packet to a predefined length. I am able to trim the packet (using the bpf_change_tail helper) and also to update the ip->len and udp->length fields. After changing the those fields I update the checksums using the bpf_[l3,l4]_csum_replace helpers. Due to the fact that the UDP checksum also covers the data itself, it is necessary to update it. I tried to use the bpf_csum_diff together with the bpf_l4_csum_replace helpers, however I found that is not possible to pass a variable size to the bpf_csum_diff as it is marked as "ARG_CONST_STACK_SIZE_OR_ZER" in the function prototype. This limitation makes it impossible to update the checksum on different packets size as the quantity of bytes to be trimmed depends on the length of the packet. The code is available at [1] (please note that it is based on hover). The error that I get when I tried to load the program is: 31: (61) r9 = *(u32 *)(r6 +48) 32: (61) r2 = *(u32 *)(r6 +0) 33: (07) r2 += -100 34: (67) r2 <<= 32 35: (77) r2 >>= 32 36: (b7) r8 = 0 37: (b7) r3 = 0 38: (b7) r4 = 0 39: (b7) r5 = 0 40: (85) call 28 R2 type=inv expected=imm My questions are. 1. Am I missing another way to update the UDP checksum? 2. In case 1 is false, how could it be implemented? I think having a function to trim the packet without having a way to update the checksum is, in some way, useless. What's your specific use-case on this? Reason why I'm asking is that the helper needs to linearize skb and is thus only suitable for slow path [1]. F.e. we use it for rewriting an skb as time exceeded reply [2]. How far from the header start are you trimming? Perhaps it's feasible to to calc the csum up to the point of trimming via bpf_csum_diff()? Did you check whether [3] could help in that? [1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5293efe62df81908f2e90c9820c7edcc8e61f5e9 [2] https://github.com/cilium/cilium/blob/master/bpf/lib/icmp6.h [3] https://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/?id=06c1c049721a995dee2829ad13b24aaf5d7c5cce Thanks in advance. Mauricio V. [1] https://gist.github.com/mvbpolito/77edb3b4e65cc03c92862b3f17452286 ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev
[iovisor-dev] How to update the csum of a trimmed UDP packet?
Hello, I am trying to implement an eBPF program that trims an UDP packet to a predefined length. I am able to trim the packet (using the bpf_change_tail helper) and also to update the ip->len and udp->length fields. After changing the those fields I update the checksums using the bpf_[l3,l4]_csum_replace helpers. Due to the fact that the UDP checksum also covers the data itself, it is necessary to update it. I tried to use the bpf_csum_diff together with the bpf_l4_csum_replace helpers, however I found that is not possible to pass a variable size to the bpf_csum_diff as it is marked as "ARG_CONST_STACK_SIZE_OR_ZER" in the function prototype. This limitation makes it impossible to update the checksum on different packets size as the quantity of bytes to be trimmed depends on the length of the packet. The code is available at [1] (please note that it is based on hover). The error that I get when I tried to load the program is: 31: (61) r9 = *(u32 *)(r6 +48) 32: (61) r2 = *(u32 *)(r6 +0) 33: (07) r2 += -100 34: (67) r2 <<= 32 35: (77) r2 >>= 32 36: (b7) r8 = 0 37: (b7) r3 = 0 38: (b7) r4 = 0 39: (b7) r5 = 0 40: (85) call 28 R2 type=inv expected=imm My questions are. 1. Am I missing another way to update the UDP checksum? 2. In case 1 is false, how could it be implemented? I think having a function to trim the packet without having a way to update the checksum is, in some way, useless. Thanks in advance. Mauricio V. [1] https://gist.github.com/mvbpolito/77edb3b4e65cc03c92862b3f17452286 ___ iovisor-dev mailing list iovisor-dev@lists.iovisor.org https://lists.iovisor.org/mailman/listinfo/iovisor-dev