[ovs-dev] [PATCH v2] ipf: fix only nat the first fragment in the reass process
Aaron Conole
aconole at redhat.com
Thu Jul 8 20:11:12 UTC 2021
wenxu at ucloud.cn writes:
> From: wenxu <wenxu at ucloud.cn>
>
> The ipf collect original fragment packets and reass a new pkt
> to do the conntrack logic. After finsh the conntrack things
> copy the ct meta info to each orignal packet and modify the
> l4 header in the first fragment. It should modify the ip src/
> dst info for all the fragments.
>
> Signed-off-by: wenxu <wenxu at ucloud.cn>
> Co-authored-by: luke.li <luke.li at ucloud.cn>
> Signed-off-by: luke.li <luke.li at ucloud.cn>
> ---
This looks okay. Please post a set of sample packets that showcase the
issue. I will write a test case that can demonstrate it that we can
check in with this fix.
Alternately, please add such a test case.
> lib/ipf.c | 82 +++++++++++++++++++++++++++++++++------------------------------
> 1 file changed, 43 insertions(+), 39 deletions(-)
>
> diff --git a/lib/ipf.c b/lib/ipf.c
> index 9c83f19..795e801 100644
> --- a/lib/ipf.c
> +++ b/lib/ipf.c
> @@ -1149,52 +1149,56 @@ ipf_post_execute_reass_pkts(struct ipf *ipf,
> * NETDEV_MAX_BURST. */
> DP_PACKET_BATCH_REFILL_FOR_EACH (pb_idx, pb_cnt, pkt, pb) {
> if (rp && pkt == rp->list->reass_execute_ctx) {
> + const struct ipf_frag *frag_0 = &rp->list->frag_list[0];
> + void *l4_frag = dp_packet_l4(frag_0->pkt);
> + void *l4_reass = dp_packet_l4(pkt);
> + memcpy(l4_frag, l4_reass, dp_packet_l4_size(frag_0->pkt));
> +
> for (int i = 0; i <= rp->list->last_inuse_idx; i++) {
> - rp->list->frag_list[i].pkt->md.ct_label = pkt->md.ct_label;
> - rp->list->frag_list[i].pkt->md.ct_mark = pkt->md.ct_mark;
> - rp->list->frag_list[i].pkt->md.ct_state = pkt->md.ct_state;
> - rp->list->frag_list[i].pkt->md.ct_zone = pkt->md.ct_zone;
> - rp->list->frag_list[i].pkt->md.ct_orig_tuple_ipv6 =
> - pkt->md.ct_orig_tuple_ipv6;
> + const struct ipf_frag *frag_i = &rp->list->frag_list[i];
> +
> + frag_i->pkt->md.ct_label = pkt->md.ct_label;
> + frag_i->pkt->md.ct_mark = pkt->md.ct_mark;
> + frag_i->pkt->md.ct_state = pkt->md.ct_state;
> + frag_i->pkt->md.ct_zone = pkt->md.ct_zone;
> + frag_i->pkt->md.ct_orig_tuple_ipv6 =
> + pkt->md.ct_orig_tuple_ipv6;
> if (pkt->md.ct_orig_tuple_ipv6) {
> - rp->list->frag_list[i].pkt->md.ct_orig_tuple.ipv6 =
> + frag_i->pkt->md.ct_orig_tuple.ipv6 =
> pkt->md.ct_orig_tuple.ipv6;
> } else {
> - rp->list->frag_list[i].pkt->md.ct_orig_tuple.ipv4 =
> + frag_i->pkt->md.ct_orig_tuple.ipv4 =
> pkt->md.ct_orig_tuple.ipv4;
> }
> - }
> -
> - const struct ipf_frag *frag_0 = &rp->list->frag_list[0];
> - void *l4_frag = dp_packet_l4(frag_0->pkt);
> - void *l4_reass = dp_packet_l4(pkt);
> - memcpy(l4_frag, l4_reass, dp_packet_l4_size(frag_0->pkt));
> -
> - if (v6) {
> - struct ovs_16aligned_ip6_hdr *l3_frag
> - = dp_packet_l3(frag_0->pkt);
> - struct ovs_16aligned_ip6_hdr *l3_reass = dp_packet_l3(pkt);
> - l3_frag->ip6_src = l3_reass->ip6_src;
> - l3_frag->ip6_dst = l3_reass->ip6_dst;
> - } else {
> - struct ip_header *l3_frag = dp_packet_l3(frag_0->pkt);
> - struct ip_header *l3_reass = dp_packet_l3(pkt);
> - if (!dp_packet_hwol_is_ipv4(frag_0->pkt)) {
> - ovs_be32 reass_ip =
> - get_16aligned_be32(&l3_reass->ip_src);
> - ovs_be32 frag_ip =
> - get_16aligned_be32(&l3_frag->ip_src);
> -
> - l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum,
> - frag_ip, reass_ip);
> - reass_ip = get_16aligned_be32(&l3_reass->ip_dst);
> - frag_ip = get_16aligned_be32(&l3_frag->ip_dst);
> - l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum,
> - frag_ip, reass_ip);
> + if (v6) {
> + struct ovs_16aligned_ip6_hdr *l3_frag
> + = dp_packet_l3(frag_i->pkt);
> + struct ovs_16aligned_ip6_hdr *l3_reass
> + = dp_packet_l3(pkt);
> + l3_frag->ip6_src = l3_reass->ip6_src;
> + l3_frag->ip6_dst = l3_reass->ip6_dst;
> + } else {
> + struct ip_header *l3_frag = dp_packet_l3(frag_i->pkt);
> + struct ip_header *l3_reass = dp_packet_l3(pkt);
> + if (!dp_packet_hwol_is_ipv4(frag_i->pkt)) {
> + ovs_be32 reass_ip =
> + get_16aligned_be32(&l3_reass->ip_src);
> + ovs_be32 frag_ip =
> + get_16aligned_be32(&l3_frag->ip_src);
> +
> + l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum,
> + frag_ip,
> + reass_ip);
> + reass_ip = get_16aligned_be32(&l3_reass->ip_dst);
> + frag_ip = get_16aligned_be32(&l3_frag->ip_dst);
> + l3_frag->ip_csum = recalc_csum32(l3_frag->ip_csum,
> + frag_ip,
> + reass_ip);
> + }
> +
> + l3_frag->ip_src = l3_reass->ip_src;
> + l3_frag->ip_dst = l3_reass->ip_dst;
> }
> -
> - l3_frag->ip_src = l3_reass->ip_src;
> - l3_frag->ip_dst = l3_reass->ip_dst;
> }
>
> ipf_completed_list_add(&ipf->frag_complete_list, rp->list);
More information about the dev
mailing list