From 21ebb413b35fc34e8b84d1173a1eacb15cb898b1 Mon Sep 17 00:00:00 2001 From: Raja Sivaramakrishnan Date: Tue, 1 Sep 2015 11:13:35 -0700 Subject: [PATCH] - Use the right vlan and vrf when flushing fragments after the first fragment arrives - Fix error with using && for bitwise AND - Avoid blocking interrupts when handling fragments as dev_queue_xmit requires that interrupts should not be blocked when packets are transmitted. Change-Id: I1d627bb230ddd9068ef36626754a7656905efb08 Closes-bug: #1489719 --- dp-core/vr_fragment.c | 6 ++++-- dp-core/vr_proto_ip.c | 2 +- linux/vr_fragment_assembler.c | 10 ++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dp-core/vr_fragment.c b/dp-core/vr_fragment.c index 364d9fe9f..0bb284725 100644 --- a/dp-core/vr_fragment.c +++ b/dp-core/vr_fragment.c @@ -299,7 +299,7 @@ vr_fragment_assembler(struct vr_fragment **head_p, } if (vr_ip_fragment_tail(ip)) { - frag->f_expected = ((ntohs(ip->ip_frag_off) && 0x1FFF) * 8) + + frag->f_expected = ((ntohs(ip->ip_frag_off) & 0x1FFF) * 8) + ntohs(ip->ip_len) - (ip->ip_hl * 4) ; } frag->f_received += (ntohs(ip->ip_len) - (ip->ip_hl * 4)); @@ -349,8 +349,10 @@ vr_fragment_assembler(struct vr_fragment **head_p, if (frag->f_port_info_valid) { while ((fqe = frag->f_qe)) { - memset(&fmd, 0, sizeof(fmd)); + vr_init_forwarding_md(&fmd); pnode = &fqe->fqe_pnode; + fmd.fmd_vlan = pnode->pl_vlan; + fmd.fmd_dvrf = pnode->pl_vrf; vr_flow_flush_pnode(router, pnode, NULL, &fmd); frag->f_qe = fqe->fqe_next; vr_fragment_queue_element_free(fqe, VP_DROP_CLONED_ORIGINAL); diff --git a/dp-core/vr_proto_ip.c b/dp-core/vr_proto_ip.c index f400d450c..b990006a1 100644 --- a/dp-core/vr_proto_ip.c +++ b/dp-core/vr_proto_ip.c @@ -820,7 +820,7 @@ vr_inet_fragment_flow(struct vrouter *router, unsigned short vrf, frag->f_received += (ntohs(ip->ip_len) - (ip->ip_hl * 4)); if (vr_ip_fragment_tail(ip)) { - frag->f_expected = ((ntohs(ip->ip_frag_off) && 0x1FFF) * 8) + + frag->f_expected = ((ntohs(ip->ip_frag_off) & 0x1FFF) * 8) + ntohs(ip->ip_len) - (ip->ip_hl * 4) ; } diff --git a/linux/vr_fragment_assembler.c b/linux/vr_fragment_assembler.c index f920afd0b..acc5bff66 100644 --- a/linux/vr_fragment_assembler.c +++ b/linux/vr_fragment_assembler.c @@ -53,7 +53,6 @@ static void vr_linux_fragment_assembler(struct work_struct *work) { uint32_t hash, index; - unsigned long flags; struct vr_packet *pkt; struct vr_linux_fragment_bucket *vfb; @@ -89,9 +88,9 @@ vr_linux_fragment_assembler(struct work_struct *work) index = (hash % VR_LINUX_ASSEMBLER_BUCKETS); vfb = &vr_linux_assembler_table[index]; - spin_lock_irqsave(&vfb->vfb_lock, flags); + spin_lock_bh(&vfb->vfb_lock); vr_fragment_assembler(&vfb->vfb_frag_list, tail); - spin_unlock_irqrestore(&vfb->vfb_lock, flags); + spin_unlock_bh(&vfb->vfb_lock); } tail = tail_n; @@ -126,17 +125,16 @@ static void vr_linux_assembler_table_scan(void *arg) { unsigned int i, j, scanned = 0; - unsigned long flags; struct vr_linux_fragment_bucket *vfb; i = vr_linux_assembler_scan_index; for (j = 0; j < VR_LINUX_ASSEMBLER_BUCKETS; j++) { vfb = &vr_linux_assembler_table[(i + j) % VR_LINUX_ASSEMBLER_BUCKETS]; - spin_lock_irqsave(&vfb->vfb_lock, flags); + spin_lock_bh(&vfb->vfb_lock); if (vfb->vfb_frag_list) scanned += vr_assembler_table_scan(&vfb->vfb_frag_list); - spin_unlock_irqrestore(&vfb->vfb_lock, flags); + spin_unlock_bh(&vfb->vfb_lock); if (scanned > vr_linux_assembler_scan_thresh) { j++; break;