aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/virtio
AgeCommit message (Collapse)AuthorFilesLines
2018-02-19virtio: add missing tx lock when running multithreadedDamjan Marion2-0/+6
Change-Id: I373f429c53c6f66ad38322addcfaccddb7761392 Signed-off-by: Damjan Marion <damarion@cisco.com>
2018-02-08virtio: reset vnet header on txDamjan Marion1-0/+3
Change-Id: Ib04a8787038fb536470a04d99fdc165102edfb5a Signed-off-by: Damjan Marion <damarion@cisco.com>
2018-02-08vhostuser: Fix vhostuser file descriptor leakHaiyang Tan1-4/+13
In the case that vhostuser server accepted more than one client connection, 'vui->clib_file_index' will be overwritten directly without release the possible existed resource, so file descriptor leak occurs Change-Id: I89d08133dae31a12a815df2631334dbf0aefeb1e Signed-off-by: Haiyang Tan <haiyang.tan.dev@gmail.com>
2018-02-07vhost: Added ARMV8 NEON version of function map_guest_mem()Nitin Saxena1-0/+69
(VPP-1085) The NEON implementation searches particular address in VHOST_MEMORY_MAX_NREGIONS regions. Searching two regions at a time. Change-Id: Icc3c6746bc98e3a1fa71424e51b64f62efbfdc74 Signed-off-by: Nitin Saxena <nitin.saxena@cavium.com>
2018-02-06vlib: epoll on worker threadsDamjan Marion2-0/+4
This patch teaches worer threads to sleep and to be waken up by kernel if there is activity on file desctiptors assigned to that thread. It also adds counters to epoll file descriptors and new debug cli 'show unix file'. Change-Id: Iaf67869f4aa88ff5b0a08982e1c08474013107c4 Signed-off-by: Damjan Marion <damarion@cisco.com>
2018-02-05vhost_user: code cleanupHaiyang Tan1-4/+4
1. Replace the magic number '-1' with MAP_FAILED 2. On x86 platform, QEMU uses vhostuser required the memory back-end is file based, the file could be tmpfs(4K page size) or hugetlbfs(2M or 1G page size) Change-Id: If1818cb6833728d641f68e4d4a3bc645e70f2ee6 Signed-off-by: Haiyang Tan <haiyang.tan.dev@gmail.com>
2018-01-30VPP-899: Run VPP under SELinuxBilly McFall1-13/+17
Add an SELinux profile such that VPP can run under SELinux on RPM based platforms. The SELinux Policy is currently only implemented for RPM packages, specifically, Fedora, CentOS and RHEL. Doxygen User Documentation has been included (selinux_doc.md). Once some discussion on file locations has completed (see vpp-devlist), updates to the Debug CLI documentation will also need to be updated. Additional changes: Patch Set 2: - Rework selinux_doc.md such that each line is only 80 characters instead of each sentence on a line. Made additonal minor chnages to the text. - Update vHost Debug CLI documentation to reflex new socket location. Cleaned up some text from when I originally wrote it, to better reflex proper use. - Update exec Debug CLI documentation to be more inline with suggested helptext, added text regarding recommended script file location. - For Debian builds, create the /var/log/vpp/ directory. I don't use Debian very much, so please pay extra attention to build-data/platforms.mk and build-root/deb/debian/.gitignore. - Per discussion on VPP call, changed the default log location to /var/log/vpp/vpp.log. - Changed the socket location for vHost in AutoConfig to /var/run/vpp/. Patch Set 3: - Update selinux_doc.md based on comments. Change-Id: I400520dc33f1ca51012d09ef8fe5a7b7b96c631e Signed-off-by: Billy McFall <bmcfall@redhat.com>
2018-01-23VPPAPIGEN: vppapigen replacement in Python PLY.Ole Troan1-1/+1
This is a version of the VPP API generator in Python PLY. It supports the existing language, and has a plugin architecture for generators. Currently C and JSON are supported. Changes: - vl_api_version to option version = "major.minor.patch" - enum support - Added error checking and reporting - import support (removed the C pre-processor) - services (tying request/reply together) Version: option version = "1.0.0"; Enum: enum colours { RED, BLUE = 50, }; define foo { vl_api_colours_t colours; }; Services: service { rpc foo returns foo_reply; rpc foo_dump returns stream foo_details; rpc want_stats returns want_stats_reply events ip4_counters, ip6_counters; }; Future planned features: - unions - bool, text - array support (including length) - proto3 output plugin - Refactor C/C++ generator as a plugin - Refactor Java generator as a plugin Change-Id: Ifa289966c790e1b1a8e2938a91e69331e3a58bdf Signed-off-by: Ole Troan <ot@cisco.com>
2018-01-21vhost_user: 'nregions' saves the actual number of mapped guest physical ↵Haiyang Tan1-1/+2
address area This patch fixed the VMA leak that if mapping one of guest physical address area get failed. Change-Id: I07b0b9a932209561d6ff2b2dd08a111ea5db2209 Signed-off-by: Haiyang Tan <haiyang.tan.dev@gmail.com>
2018-01-18vlib: add vlib_buffer_alloc_to_ring APIDamjan Marion2-11/+4
Change-Id: I4e2804754b443f5f41fb25eed8334908c4a70f84 Signed-off-by: Damjan Marion <damarion@cisco.com>
2018-01-16tapv2: deleting tap interface may leak buffers (VPP-1124)Steven3-9/+32
Buffers may be allocated for indirect descriptors by tx thread and they are freed when tx thread is invoked in the next invocation. This is to allow the recipient (kernel) to have a chance to process them. But if the tap interface is deleted, the tx thread may not yet be called to clean up the indirect descriptors' buffers. In that case, we need to remove them without waiting for the tx thread to be called. Failure to do so may cause buffers leak when the tap interface is deleted. For the RX ring, leakage also exists for vring->buffers when the interface is removed. Change-Id: I3df313a0e60334776b19daf51a9f5bf20dfdc489 Signed-off-by: Steven <sluong@cisco.com> (cherry picked from commit d8a998e74b815dd3725dfcd80080e4e540940236)
2018-01-11api: remove transport specific code from handlersFlorin Coras1-11/+12
This does not update api client code. In other words, if the client assumes the transport is shmem based, this patch does not change that. Furthermore, code that checks queue size, for tail dropping, is not updated. Done for the following apis: Plugins - acl - gtpu - memif - nat - pppoe VNET - bfd - bier - tapv2 - vhost user - dhcp - flow - geneve - ip - punt - ipsec/ipsec-gre - l2 - l2tp - lisp-cp/one-cp - lisp-gpe - map - mpls - policer - session - span - udp - tap - vxlan/vxlan-gpe - interface VPP - api/api.c OAM - oam_api.c Stats - stats.c Change-Id: I0e33ecefb2bdab0295698c0add948068a5a83345 Signed-off-by: Florin Coras <fcoras@cisco.com>
2018-01-09api: refactor vlibmemoryFlorin Coras1-6/+4
- separate client/server code for both memory and socket apis - separate memory api code from generic vlib api code - move unix_shared_memory_fifo to svm and rename to svm_fifo_t - overall declutter Change-Id: I90cdd98ff74d0787d58825b914b0f1eafcfa4dc2 Signed-off-by: Florin Coras <fcoras@cisco.com>
2017-12-14tap_v2: include host-side parameters in the dump binary APIMilan Lenco4-0/+15
Change-Id: I097a738b96a304621520f1842dcac7dbf61a8e3f Signed-off-by: Milan Lenco <milan.lenco@pantheon.tech>
2017-12-08tapv2: multiple improvementsDamjan Marion2-2/+3
- change interface naming scheme - rework netlink code - add option to set link address, namespace Change-Id: Icf667babb3077a07617b0b87c45c957e345cb4d1 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-12-04tap_v2: move code to vnet/devices/tapDamjan Marion5-1068/+0
virtio backend stays in vnet/devices/virtio Change-Id: Idbf04f1c645a809ed408670ba330662859fe9309 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-12-04tap_v2: coverity strikes, again!Steven1-2/+3
fd is not close when IOCTL encounters an error which causes resource leak. The fix is to initialize fd to -1. At return, close fd if it has a valid value. Change-Id: I53c4f5c71ca0f556fb6586f5849e7cb622632d8f Signed-off-by: Steven <sluong@cisco.com>
2017-12-04virtio: zero data structs in virtio_vring_initDamjan Marion1-3/+3
Change-Id: I877cf1abb062a90f428c3ec0cab5c6e9dad0ca82 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-12-02tap_v2: multiple improvementsDamjan Marion5-60/+168
- add support for assigning tap interface to the bridge - add support for assigning tap interface host side ip4 and ip6 address - host namespace can be specified as PID (pid:12345) or full path to file - automatically bring linux interface up Change-Id: I1cf7c3cad9a740e430cc1b9c2bb0aad0ba4cc8d8 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-12-01virtio: fix coverity warningsSteven1-1/+1
Fix 3 coverity warnings 1. api_format.c: init net_ns = 0 and remove its corresponding vec_add and vec_free 2. netlink.c (reported in tap.c before the code was removed): resource leaked due to fd is not close 3. tap.c: subtract 1 for size when calling strncpy to accommodate the terminated NULL character Change-Id: Iff4e66604862f0c06dac227b8cfd48d3979e41a5 Signed-off-by: Steven <sluong@cisco.com>
2017-11-30tap_v2: move netlink code to separate fileDamjan Marion1-76/+2
Change-Id: Ib091875f77ea99421aec0947fd17833c4e6d2ec2 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-11-30virtio: fast TAP interfaces with vhost-net backendDamjan Marion9-0/+1953
Change-Id: Ided667356d5c6fb9648eb34685aabd6b16a598b7 Signed-off-by: Damjan Marion <damarion@cisco.com> Signed-off-by: Steven Luong <sluong@cisco.com>
2017-10-14vhost: crash under heavy traffic condition due to memory corruption (VPP-1016)Steven1-2/+33
With heavy traffic, tx code path may crash due to memory corruption Thread 5 "vpp_wk_2" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7fff3995c700 (LWP 2505)] 0x00007ffff73675e8 in vhost_user_if_input (vm=0x7fffb5f5bf9c, vum=0x7ffff7882a40 <vhost_user_main>, vui=0x7fffb65570c4, qid=0, node=0x7fffb6577dac, mode=VNET_HW_INTERFACE_RX_MODE_POLLING) at /home/sluong/vpp-master/vpp/build-data/../src/vnet/devices/virtio/vhost-user.c:1610 1610 bi_current = (vum->cpus[thread_index].rx_buffers) [vum->cpus[thread_index].rx_buffers_len]; (gdb) p vum->cpus[thread_index].rx_buffers_len $2 = 793212607 (gdb) Apparently, some code accidentally wrote the bad value in rx_buffers_len. rx_buffers_len should never be greater than 1024 since that is how many buffers we request each time. After debugging many hours, I discovered that the memory corruption happens in the tx code path right here on line 2176. { vhost_copy_t *cpy = &vum->cpus[thread_index].copy[copy_len]; copy_len++; cpy->len = bytes_left; cpy->len = (cpy->len > buffer_len) ? buffer_len : cpy->len; cpy->dst = buffer_map_addr; cpy->src = (uword) vlib_buffer_get_current (current_b0) + current_b0->current_length - bytes_left; (gdb) p cpy $3 = (vhost_copy_t *) 0x7fffb554077c (gdb) p copy_len $4 = 1025 (gdb) p &vum->cpus[3].rx_buffers_len $8 = (u32 *) 0x7fffb5540784 copy_len is picking up the index entry 1024 before it was incremented. copy array has only 1024 members (0 - 1023 are valid). The assignment here in cpy surely causes memory corruption. It is only discovered later when the memory location that it corrupted is used. The condition for the crash is to transmit jumbo frames under heavy volume. Since ring size is 1024, with one packet taking up one index for frame size (less 2048), it does not cause overflow. With jumbo frames, it requires multiple indices for one packet, it can cause the overflow under heavy traffic. The fix is to do copy out when we have 1000 entries in the array to avoid overflow. Change-Id: Iefbc739b8e80470f1cf13123113f8331ffcd0eb2 Signed-off-by: Steven <sluong@cisco.com>
2017-10-09vppapigen: support per-file (major,minor,patch) version stampsDave Barach1-0/+2
Add one of these statements to foo.api: vl_api_version 1.2.3 to generate a version tuple stanza in foo.api.h: /****** Version tuple *****/ vl_api_version_tuple(foo, 1, 2, 3) Change-Id: Ic514439e4677999daa8463a94f948f76b132ff15 Signed-off-by: Dave Barach <dave@barachs.net> Signed-off-by: Ole Troan <ot@cisco.com>
2017-10-09fix buffer allocation for sparse jumbo frames in vhostPierre Pfister1-1/+3
A bug was reported where a jumbo packet would stay in vhost queue forever or until a large enough number of other packets arrived in the queue too. This is due to a bug in vhost input node buffer allocation. The fix is to make sure that vhost always allocates at least enough buffers for one single big packet. '40' is used to account for 65kB frames. Change-Id: I1d293028854165083e30cd798fab9d4140230b78 Signed-off-by: Pierre Pfister <ppfister@cisco.com> (cherry picked from commit 67700d41169ac37d21c400949a316750eabad969)
2017-10-04[aarch64] Fixes CLI crashes on dpaa2 platform.Christophe Fontaine1-1/+1
- always use 'va_args' as pointer in all format_* functions - u32 for all 'indent' params as it's declaration was inconsistent Change-Id: Ic5799309a6b104c9b50fec309cba789c8da99e79 Signed-off-by: Christophe Fontaine <christophe.fontaine@enea.com>
2017-09-22vhost-user: fix link-up statusYoann Desmouceaux1-1/+1
When changing the admin state of a vhost-user interface, do not put it in link-up mode if the interface is not actually ready. Change-Id: Idbc631a7126efa79d199909f9e7656d21bd412ca Signed-off-by: Yoann Desmouceaux <ydesmouc@cisco.com>
2017-09-09move unix_file_* code to vppinfraDamjan Marion2-32/+32
This will allow us to use this code in client libraries without vlib. Change-Id: I8557b752496841ba588aa36b6082cbe2cd1867fe Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-08-31vhost: Disallow interrupt mode config if driver opts out interrupt supportSteven2-3/+9
According to the spec, supporting interrupt mode from the driver is optional, not a must. When interrupt mode is configured on the interface, we should check to make sure that the driver didn't opt out for the kickfd support and reject the configuration if it did. Change-Id: I7d3dbaddde65458e1a6a802754a3768ae8685a0e Signed-off-by: Steven <sluong@cisco.com>
2017-08-30vhost: Cache qsz_mask instead of qsz in vhost_user_vring_tSteven2-32/+28
In the data path, we grab qsz from vhost_user_vring_t to compute qsz_mask and store it in a stack variable to use on many occasions. We never use qsz for any meaningful purpose. It is more useful to cache qsz_mask in vhost_user_vring_t to avoid the needless computation in the data path. Change-Id: Idf4d94a9754d5c75c899f1f4f59602275b9904a6 Signed-off-by: Steven <sluong@cisco.com>
2017-08-28vhost: Remove operation mode in the APISteven1-6/+0
create/delete/modify vhost_user APIs no longer support the operation mode (polling/interrupt/adaptive). They are now done via the generic interface. Change-Id: I9e9bd503f9b56c953ecd2b271b3e2007da20c72a Signed-off-by: Steven <sluong@cisco.com>
2017-08-18Use correct msg ID in the sw-interface-event from TAP and VHOSTNeale Ranns1-1/+1
Change-Id: I0124fa264f7f390fc7cd9722da59be03116831c5 Signed-off-by: Neale Ranns <nranns@cisco.com>
2017-08-11Dedicated SW Interface EventNeale Ranns1-3/+3
Change-Id: I06a10a4291e61aec3f1396d2514ed6fe3901897a Signed-off-by: Neale Ranns <neale.ranns@cisco.com> Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
2017-07-27vhost: debug vhost-user command needs better error checking on the syntax ↵Steven1-5/+26
(VPP-916) The syntax for debug vhost-user is debug vhost-user <on | off> However, currently the code does not reject the invalid command such as below debug vhost-user debug vhost-user on blah debug vhost-user off blah The fix is to enforece the correct syntax and reject the command when invalid option is entered. Change-Id: I1a04ae8ddb6dd299aa6d15b043362964e685ddde Signed-off-by: Steven <sluong@cisco.com> (cherry picked from commit 6a4de2764d9e6cadf36af824dddb3f33c2d6dc7e)
2017-06-02vhost: add debug vhost-user on | off CLISteven2-20/+59
Add runtime debug vhost-user on | off CLI to facilitate troubleshooting. This feature is needed to avoid recompiling the code to debug vhost issues. The debugging messages should not be on the data path to avoid performance hit. Change-Id: I4c40f65dbb222557cba3fb8706fa3b7b62eec95f Signed-off-by: Steven <sluong@cisco.com>
2017-05-22vhost: migrate to use device infra for worker thread assignment, rx-mode.Steven3-484/+316
and add adaptive mode support to receive queue - Migrate vhost to use device infra which does the interface/queue to worker thread assignment. - Retire vhost thread CLI and corresponding code which assigns interface/queue to worker thread. set interface placement should be used instead to customize the interface/queue to worker thread assignment. - Retire vhost interrupt/polling option when creating vhost-user interface. Instead, set interface rx-mode should be used. - Add code in vnet_device_input_unassign_thread to change the node state to interrupt if the last polling interface has left the worker thread for the device of the corresponding interface/queue. - Add adaptive mode support. The node state is set to interrupt initially. When the scheduler detects a burst of traffic, it switches the input node to polling. Then we inform the device that we don't need interrupt notification. When the traffic subsides, the scheduler switches the input node back to interrupt. Then we immediately tell the driver that we want interrupt notification again. - Remove some duplicate code in vlib/main.c Change-Id: Id19bb1b9e50e6521c6464f470f5825c26924d3a8 Signed-off-by: Steven <sluong@cisco.com>
2017-05-20vhost: buffers leak and interface disable upon vring descriptor out of mmapSteven1-16/+9
When processing a vring descriptor which is outside of mmap, we disable the interface and spit a message to shut/no shut the interface. This is not practical as application using vhost cannot constantly checking the logs and do the recovery. The proposed fix is to log an error, like other errors that we encounter. The other bug is buffer leak in the function rewind. At the end of the while loop when b_current != b_head, we still have to give back 1 more buffer or add 1 to rx_buffers_len. Change-Id: I68c0b24f070e644cd8878f42272a7b518f14393f Signed-off-by: Steven <sluong@cisco.com>
2017-05-17vhost: bad packet assembled from descriptor chainingSteven1-1/+2
When the descriptor is chained via multiple parts, vhost is supposed to reassemble the different parts to form a packet prior to passing the packet to the next input node. However, bad packet was seen, having bad ethertype, source, and destination mac addresses. The problem was due to the destination pointer not being incremented as each chain is processed. THe result was the first chain is copied to the beginning of the buffer, the next chain is copied, then the last chain is also copied to the beginning of the buffer. As a result, the ethertype, source and destination mac, etc, are being overwritten by the very last chain of the descriptor. Change-Id: I78f9a91de68c85574047912576dcc311d7597e21 Signed-off-by: Steven <sluong@cisco.com>
2017-05-09Fix remaining 32-bit compile issuesDamjan Marion1-1/+1
Change-Id: I9664214652229b663c3e3ba7406b4ede96bfb123 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-04-28vhost: Disallow duplicate path name for vhost interfaceSteven2-1/+37
When creating or modifying a vhost interface, verify if the path name already existed and reject the command. Change-Id: I8b2d33b77c847f774492874f7d194fa72c488479 Signed-off-by: Steven <sluong@cisco.com>
2017-04-26vhost: Fix mmap size calculationPierre Pfister1-3/+3
I had a bug where a requested size of 1G was resulting in an aligned size of '1G + 2M', resulting in an OOM error. Previous code was adding one huge page size when memory is already aligned. Change-Id: Idd3aa0e9b893fb3efccba6ae1c7161e26d3f9456 Signed-off-by: Pierre Pfister <ppfister@cisco.com>
2017-04-26vhost: core dump on quit with worker threadsSteven1-0/+2
Patch 6347 removed the socket file when the interface is deleted and when VPP process is exitting. The CLI for deleting the interface has builtin vlib_worker_thread_barrier_sync to prevent the worker threads from running. Unfortunately, the CLI quit does not have the builtin vlib_worker_thread_barrier_sync. As a result, it may cause the worker thread to crash. The fix is to add the vlib_worker_thread_barrier_sync in vhost_user_exit. Change-Id: I1eff81170e131098f1799662f0ab48d6fca3def7 Signed-off-by: Steven <sluong@cisco.com>
2017-04-25"autoreply" flag: autogenerate standard xxx_reply_t messagesDave Barach1-22/+2
Change-Id: I72298aaae7d172082ece3a8edea4217c11b28d79 Signed-off-by: Dave Barach <dave@barachs.net>
2017-04-24vhost: remove socket linked file when deleting vhost interfaceSteven1-9/+18
- Unlink the file created for the socket when deleting vhost interface if we are the server mode. - Remove all vhost interfaces when VPP process is exitting. Change-Id: Id9b676cd027bbd67b473bbd01901d1ecc4d8e6cb Signed-off-by: Steven <sluong@cisco.com>
2017-04-11vhost: interrupt mode enhancementsSteven2-34/+26
- Add cpu index to the vring structure for quick lookup - Reduce the code that needs to be protected by vlib_worker_thread_barrier_sync - Set minimum timer no less than 1 ms Change-Id: Iafef4bf6879a8efb350abf4e0f517e38f7ff7a8b Signed-off-by: Steven <sluong@cisco.com>
2017-04-06Use thread local storage for thread indexDamjan Marion1-62/+65
This patch deprecates stack-based thread identification, Also removes requirement that thread stacks are adjacent. Finally, possibly annoying for some folks, it renames all occurences of cpu_index and cpu_number with thread index. Using word "cpu" is misleading here as thread can be migrated ti different CPU, and also it is not related to linux cpu index. Change-Id: I68cdaf661e701d2336fc953dcb9978d10a70f7c1 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-03-29vhost: vhost-user component may become unusable with too many open files ↵Steven1-9/+20
(VPP-668) When the number of open files is reached in the system, vhost may encounter a failure in socket call and return from vhost-user-process. The return terminates all attempts of incoming socket connections in the future, even if the condition is reconciled. The fix is to not return from vhost-user-process, record the error in the interface, spit out the error, and retry the connection every 3 seconds. Change-Id: I806baedf13e8c9b73e7c7820c094240f39949950 Signed-off-by: Steven <sluong@cisco.com>
2017-03-26Rename "show interfaces" -> "show interface"Dave Barach1-1/+1
To line up with "show interface placement," recently added. Otherwise, "show int" refers only to "show interface placement," which tends to annoy the cash customers... Change-Id: Iea9e3681aeb051e2b0e1ecbf06706d98af9a3abf Signed-off-by: Dave Barach <dave@barachs.net>
2017-03-22vhost: support interrupt modeSteven2-22/+322
vhost currently supports only polling mode. This patch is to add interrupt mode. When the interface is configured for interrupt mode, our input node does not get called unless there is a packet in the vring. If a particular CPU has one interface configured for polling mode and another in interrupt, the input node is set to polling for that CPU. This diffs also includes two crashes in vlib's dispatch_node. One is included in https://gerrit.fd.io/r/#/c/5516. The other crash is in the ASSERT. The ASSERT can become true when the caller of dispatch_node is in a loop. The first call converted the node to polling. The second call thereafter will hit the ASSERT. Change-Id: If17b6d48b20d7d8605c6a161459828637173cd32 Signed-off-by: Steven <sluong@cisco.com>
2017-03-16vhost: wrong value return for VHOST_USER_VRING_GET_BASESteven1-4/+11
When the VM is migrated, the driver sends VHOST_USER_VRING_GET_BASE message to the device to get the vring offset. The device is supposed to shut down the vring, and return the current vring offset. What the code did was to shutdown the vring, initialize the vring, and return 0 to the driver. The fix is to first store last_avail_idx in the message and then close the vring. Change-Id: I432e9f50f36d89fe53a45e050edcf5e1218caf7a Signed-off-by: Steven <sluong@cisco.com>