[ovs-dev] [PATCH] ipf.c: Fix userspace datapath crash caused by IP fragments
Aaron Conole
aconole at redhat.com
Thu Apr 15 12:55:16 UTC 2021
王亮 Liang Wang <wangliangrt at didiglobal.com> writes:
> Hi, Conole. Thank you for pointing out the mistakes in my last patch. Yes, I did missed some something important.
> The correct and complete way to fix this problem is like the following patch. In fact, we have found and fixed this
> crash problem one year ago; and this patch has worked very well in our production environment for 11 months.
>
> From 7e13a39cdbdfb484d4cb6b074f08471dc16d22b7 Mon Sep 17 00:00:00 2001
> From: Wang Liang <wangliangrt at didiglobal.com>
> Date: Thu, 15 Apr 2021 13:52:01 +0800
> Subject: [PATCH] Fix userspace datapath crash caused by IP fragments
>
> The ovs userspace datapath will crash on openflow packet-out message
> with IP packet largger than MTU. This patch will fix the problem.
> When pre-processing the IP fragments, clone the packet if it has
> 'dnsteal' flag set.
>
> Signed-off-by: Wang Liang <wangliangrt at didiglobal.com>
> ---
> lib/ipf.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/lib/ipf.c b/lib/ipf.c
> index c20bcc0b3..176140afb 100644
> --- a/lib/ipf.c
> +++ b/lib/ipf.c
> @@ -811,7 +811,7 @@ ipf_process_frag(struct ipf *ipf, struct ipf_list *ipf_list,
> * recommend not setting the mempool number of buffers too low
> * and also clamp the number of fragments. */
> struct ipf_frag *frag = &ipf_list->frag_list[last_inuse_idx + 1];
> - frag->pkt = pkt;
> + frag->pkt = dnsteal ? dp_packet_clone(pkt) : pkt;
> frag->start_data_byte = start_data_byte;
> frag->end_data_byte = end_data_byte;
> frag->dnsteal = dnsteal;
> @@ -1338,9 +1338,7 @@ ipf_destroy(struct ipf *ipf)
> while (ipf_list->last_sent_idx < ipf_list->last_inuse_idx) {
> struct dp_packet *pkt
> = ipf_list->frag_list[ipf_list->last_sent_idx + 1].pkt;
> - if (!ipf_list->frag_list[ipf_list->last_sent_idx + 1].dnsteal) {
> - dp_packet_delete(pkt);
> - }
> + dp_packet_delete(pkt);
This looks better.
There are no more uses of (struct ipf_frag *)->dnsteal - so I think we should
remove it from the struct as well.
I know you wrote that you've been running this in production for a year,
and I think the change looks correct, but is it possible to have a test
case (maybe even a pcap that we can extract) to go along with it?
> atomic_count_dec(&ipf->nfrag);
> ipf_list->last_sent_idx++;
> }
More information about the dev
mailing list