aboutsummaryrefslogtreecommitdiffstats
path: root/dpdk/dpdk-16.04_patches/0021-net-enic-fix-crash-when-releasing-queues.patch
blob: 56d2c677e1bd9f35ebf5f27734ff950cae712b6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
From 38e154305ee5fd2ee454c19218ca144ffd1535f1 Mon Sep 17 00:00:00 2001
From: John Daley <johndale@cisco.com>
Date: Sat, 11 Jun 2016 10:27:04 -0700
Subject: [PATCH 21/25] net/enic: fix crash when releasing queues

If device configuration failed due to a lack of resources, such as
if more queues are requested than are available, the queue release
functions are called with NULL pointers which were being dereferenced.

Skip releasing queues if they are NULL pointers.

Fixes: fefed3d1e62c ("enic: new driver")

Signed-off-by: John Daley <johndale@cisco.com>
---
 drivers/net/enic/enic_main.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 56ec96e..4e5594f 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -462,9 +462,15 @@ int enic_alloc_intr_resources(struct enic *enic)
 
 void enic_free_rq(void *rxq)
 {
-	struct vnic_rq *rq_sop = (struct vnic_rq *)rxq;
-	struct enic *enic = vnic_dev_priv(rq_sop->vdev);
-	struct vnic_rq *rq_data = &enic->rq[rq_sop->data_queue_idx];
+	struct vnic_rq *rq_sop, *rq_data;
+	struct enic *enic;
+
+	if (rxq == NULL)
+		return;
+
+	rq_sop = (struct vnic_rq *)rxq;
+	enic = vnic_dev_priv(rq_sop->vdev);
+	rq_data = &enic->rq[rq_sop->data_queue_idx];
 
 	enic_rxmbuf_queue_release(enic, rq_sop);
 	if (rq_data->in_use)
@@ -657,9 +663,14 @@ err_exit:
 
 void enic_free_wq(void *txq)
 {
-	struct vnic_wq *wq = (struct vnic_wq *)txq;
-	struct enic *enic = vnic_dev_priv(wq->vdev);
+	struct vnic_wq *wq;
+	struct enic *enic;
+
+	if (txq == NULL)
+		return;
 
+	wq = (struct vnic_wq *)txq;
+	enic = vnic_dev_priv(wq->vdev);
 	rte_memzone_free(wq->cqmsg_rz);
 	vnic_wq_free(wq);
 	vnic_cq_free(&enic->cq[enic->rq_count + wq->index]);
-- 
2.7.0
"ch">#!/usr/bin/env python """CRUD tests of APIs (Create, Read, Update, Delete) HLD: - interface up/down/add/delete - interface type: - pg (TBD) - loopback - vhostuser (TBD) - af_packet (TBD) - netmap (TBD) - tuntap (root privileges needed) - vxlan (TBD) """ import unittest from scapy.layers.inet import IP, ICMP from scapy.layers.l2 import Ether from framework import VppTestCase, VppTestRunner class TestLoopbackInterfaceCRUD(VppTestCase): """CRUD Loopback """ @classmethod def setUpClass(cls): super(TestLoopbackInterfaceCRUD, cls).setUpClass() try: cls.create_pg_interfaces(range(1)) for i in cls.pg_interfaces: i.config_ip4() i.resolve_arp() except: cls.tearDownClass() raise @classmethod def tearDownClass(cls): super(TestLoopbackInterfaceCRUD, cls).tearDownClass() @staticmethod def create_icmp_stream(src_if, dst_ifs): """ :param VppInterface src_if: Packets are send to this interface, using this interfaces remote host. :param list dst_ifs: IPv4 ICMP requests are send to interfaces addresses. :return: List of generated packets. """ pkts = [] for i in dst_ifs: p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) / IP(src=src_if.remote_ip4, dst=i.local_ip4) / ICMP(id=i.sw_if_index, type='echo-request')) pkts.append(p) return pkts def verify_icmp(self, capture, request_src_if, dst_ifs): """ :param capture: Capture to verify. :param VppInterface request_src_if: Interface where was send packets. :param list dst_ifs: Interfaces where was generated IPv4 ICMP requests. """ rcvd_icmp_pkts = [] for pkt in capture: try: ip = pkt[IP] icmp = pkt[ICMP] except IndexError: pass else: info = (ip.src, ip.dst, icmp.type, icmp.id) rcvd_icmp_pkts.append(info) for i in dst_ifs: # 0 - icmp echo response info = (i.local_ip4, request_src_if.remote_ip4, 0, i.sw_if_index) self.assertIn(info, rcvd_icmp_pkts) def test_crud(self): # create loopbacks = self.create_loopback_interfaces(20) for i in loopbacks: i.local_ip4_prefix_len = 32 i.config_ip4() i.admin_up() # read (check sw if dump, ip4 fib, ip6 fib) if_dump = self.vapi.sw_interface_dump() fib4_dump = self.vapi.ip_route_dump(0) for i in loopbacks: self.assertTrue(i.is_interface_config_in_dump(if_dump)) self.assertTrue(i.is_ip4_entry_in_fib_dump(fib4_dump)) # check ping stream = self.create_icmp_stream(self.pg0, loopbacks) self.pg0.add_stream(stream) self.pg_enable_capture(self.pg_interfaces) self.pg_start() capture = self.pg0.get_capture(expected_count=len(stream)) self.verify_icmp(capture, self.pg0, loopbacks) # delete for i in loopbacks: i.remove_vpp_config() # read (check not in sw if dump, ip4 fib, ip6 fib) if_dump = self.vapi.sw_interface_dump() fib4_dump = self.vapi.ip_route_dump(0) for i in loopbacks: self.assertFalse(i.is_interface_config_in_dump(if_dump)) self.assertFalse(i.is_ip4_entry_in_fib_dump(fib4_dump)) # check not ping stream = self.create_icmp_stream(self.pg0, loopbacks) self.pg0.add_stream(stream) self.pg_enable_capture(self.pg_interfaces) self.pg_start() self.pg0.assert_nothing_captured() def test_down(self): # create loopbacks = self.create_loopback_interfaces(20) for i in loopbacks: i.local_ip4_prefix_len = 32 i.config_ip4() i.admin_up() # disable for i in loopbacks: i.admin_down() i.unconfig_ip4() # read (check not in sw if dump, ip4 fib, ip6 fib) if_dump = self.vapi.sw_interface_dump() fib4_dump = self.vapi.ip_route_dump(0) for i in loopbacks: self.assertTrue(i.is_interface_config_in_dump(if_dump)) self.assertFalse(i.is_ip4_entry_in_fib_dump(fib4_dump)) # check not ping stream = self.create_icmp_stream(self.pg0, loopbacks) self.pg0.add_stream(stream) self.pg_enable_capture(self.pg_interfaces) self.pg_start() self.pg0.assert_nothing_captured() class TestInterfaceDumpApiLocalOnly(VppTestCase): """test_interface_crud.TestInterfaceDumpApiLocalOnly""" def test_sw_if_index_0(self): rv = self.vapi.sw_interface_dump(sw_if_index=0) self.assertEqual(rv[0].sw_if_index, 0) def test_sw_if_index_twiddle0(self): rv = self.vapi.sw_interface_dump(sw_if_index=0xffffffff) self.assertEqual(rv[0].sw_if_index, 0) def test_sw_if_index_1_not_existing(self): rv = self.vapi.sw_interface_dump(sw_if_index=1) self.assertEqual(len(rv), 0, 'expected no records.') class TestInterfaceDumpApi(VppTestCase): """test_interface_crud.TestInterfaceDumpApi""" def test_sw_if_index_1(self): self.vapi.create_loopback_instance(is_specified=1, user_instance=10) self.vapi.create_loopback_instance(is_specified=1, user_instance=5) # Can I get back the specified record? rv = self.vapi.sw_interface_dump(sw_if_index=1) self.assertEqual(rv[0].sw_if_index, 1, rv) # verify 3 interfaces rv = self.vapi.sw_interface_dump(sw_if_index=0xffffffff) self.assertEqual(len(rv), 3, 'Expected 3 interfaces.') if __name__ == '__main__': unittest.main(testRunner=VppTestRunner)