summaryrefslogtreecommitdiff
path: root/lib/ipf.c
diff options
context:
space:
mode:
authorwenxu <wenxu@ucloud.cn>2021-06-18 14:45:50 +0800
committerIlya Maximets <i.maximets@ovn.org>2021-09-15 22:01:25 +0200
commitebcbb534e192b47ce90ea5348843076eaa6a6842 (patch)
treef3406073013ce00cd7f94e2e68ad06b5fa2d7107 /lib/ipf.c
parent00d3d4a7d3750ab1d907d58894ad817febce1cf7 (diff)
downloadopenvswitch-ebcbb534e192b47ce90ea5348843076eaa6a6842.tar.gz
ipf: Fix only nat the first fragment in the reass process.
The ipf collect original fragment packets and reass a new pkt to do the conntrack logic. After finish the conntrack things copy the ct meta info to each original packet and modify the l4 header in the first fragment. It should modify the ip src/dst info for all the fragments. Fixes: 4ea96698f667 ("Userspace datapath: Add fragmentation handling.") Signed-off-by: wenxu <wenxu@ucloud.cn> Co-authored-by: luke.li <luke.li@ucloud.cn> Signed-off-by: luke.li <luke.li@ucloud.cn> Reviewed-by: wangze <wangze712@gmail.com> Acked-by: Aaron Conole <aconole@redhat.com> Acked-by: Paolo Valerio <pvalerio@redhat.com> Test case: Co-authored-by: Aaron Conole <aconole@redhat.com> Signed-off-by: Aaron Conole <aconole@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'lib/ipf.c')
-rw-r--r--lib/ipf.c80
1 files changed, 42 insertions, 38 deletions
diff --git a/lib/ipf.c b/lib/ipf.c
index d9f781147..665f40fef 100644
--- a/lib/ipf.c
+++ b/lib/ipf.c
@@ -1152,52 +1152,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 =
+ 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);