diff options
author | Deepak S <deepak.s@linux.intel.com> | 2017-04-17 23:02:53 -0700 |
---|---|---|
committer | Deepak S <deepak.s@linux.intel.com> | 2017-04-19 00:22:30 -0700 |
commit | 421bd97023e853a9e87d16e100b23bf3c60a9188 (patch) | |
tree | d277ba6943a0cb06fd7f717f2df588fe3039d739 | |
parent | 51cd08d9a3f2826088d122e2a5683315c77a2786 (diff) |
Adding script to auto build VNFs
Change-Id: I5af3301dceacb57499b92c543b912ed21f8b253d
Signed-off-by: Deepak S <deepak.s@linux.intel.com>
-rw-r--r-- | INSTALL.rst | 30 | ||||
-rw-r--r-- | RELEASE_NOTES.rst | 28 | ||||
-rw-r--r-- | patches/dpdk_custom_patch/i40e-fix-Rx-hang-when-disable-LLDP.patch | 49 | ||||
-rwxr-xr-x | patches/dpdk_custom_patch/i40e-fix-VF-bonded-device-link-down.patch | 251 | ||||
-rw-r--r-- | patches/dpdk_custom_patch/i40e-fix-link-management.patch | 169 | ||||
-rwxr-xr-x | patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch | 150 | ||||
-rw-r--r-- | patches/dpdk_custom_patch/rte_pipeline.patch | 88 | ||||
-rwxr-xr-x | tools/setenv.sh | 19 | ||||
-rwxr-xr-x | tools/vnf_build.sh | 317 |
9 files changed, 1101 insertions, 0 deletions
diff --git a/INSTALL.rst b/INSTALL.rst new file mode 100644 index 00000000..310bffe4 --- /dev/null +++ b/INSTALL.rst @@ -0,0 +1,30 @@ +.. this work is licensed under a creative commons attribution 4.0 international +.. license. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) opnfv, national center of scientific research "demokritos" and others. + +============================ +SAMPLEVNF Installation Guide +============================ + +Introduction +============ +This project provides a placeholder for various sample VNF (Virtual Network Function) +development which includes example reference architecture and optimization methods +related to VNF/Network service for high performance VNFs. + +The sample VNFs are Open Source approximations* of Telco grade VNF’s using +optimized VNF + NFVi Infrastructure libraries, with Performance Characterization +of Sample† Traffic Flows. +• * Not a commercial product. Encourage the community to contribute and close the feature gaps. +• † No Vendor/Proprietary Workloads + +VNF supported +============= + 1. CG-NAT (Carrier Grade Network Address Translation) VNF + 2. Firewall (vFW) VNF + 4. Access Control List (vACL) VNF + +Please refer docs folder for individual VNF Installation guide. + +Note:- Each VNF should include a installation document explain the process to install and run VNF. diff --git a/RELEASE_NOTES.rst b/RELEASE_NOTES.rst new file mode 100644 index 00000000..9dd4fef8 --- /dev/null +++ b/RELEASE_NOTES.rst @@ -0,0 +1,28 @@ +.. this work is licensed under a creative commons attribution 4.0 international +.. license. +.. http://creativecommons.org/licenses/by/4.0 +.. (c) opnfv, national center of scientific research "demokritos" and others. + +========================== +Sample VNF Release Notes +========================== + +Introduction +============ +This project provides a placeholder for various sample VNF (Virtual Network Function) +development which includes example reference architecture and optimization methods +related to VNF/Network service for high performance VNFs. + +The sample VNFs are Open Source approximations* of Telco grade VNF’s using +optimized VNF + NFVi Infrastructure libraries, with Performance Characterization +of Sample† Traffic Flows. +• * Not a commercial product. Encourage the community to contribute and close the feature gaps. +• † No Vendor/Proprietary Workloads + +VNF supported +============= + 1. CG-NAT (Carrier Grade Network Address Translation) VNF + 2. Firewall (vFW) VNF + 4. Access Control List (vACL) VNF + +Please refer docs folder for individual VNF release notes. diff --git a/patches/dpdk_custom_patch/i40e-fix-Rx-hang-when-disable-LLDP.patch b/patches/dpdk_custom_patch/i40e-fix-Rx-hang-when-disable-LLDP.patch new file mode 100644 index 00000000..7b0e5361 --- /dev/null +++ b/patches/dpdk_custom_patch/i40e-fix-Rx-hang-when-disable-LLDP.patch @@ -0,0 +1,49 @@ +From fcbd40d4327b36725c4de9f33f57809edc359f4a Mon Sep 17 00:00:00 2001 +From: Qi Zhang <qi.z.zhang@intel.com> +Date: Thu, 20 Oct 2016 04:40:13 +0800 +Subject: [PATCH] net/i40e: fix Rx hang when disable LLDP + +Remove stopping LLDP as a workaround for a known +errata which can cause Rx hang. + +Ref: Item #70 from +http://www.intel.com/content/www/us/en/embedded/products/networking/xl710-10-40-controller-spec-update.html + +Fixes: 4861cde46116 ("i40e: new poll mode driver") + +Signed-off-by: Qi Zhang <qi.z.zhang@intel.com> +Acked-by: Jingjing Wu <jingjing.wu@intel.com> +--- + drivers/net/i40e/i40e_ethdev.c | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c +index ca515dd..bb81b15 100644 +--- a/drivers/net/i40e/i40e_ethdev.c ++++ b/drivers/net/i40e/i40e_ethdev.c +@@ -1223,11 +1223,6 @@ eth_i40e_dev_uninit(struct rte_eth_dev *dev) + dev->rx_pkt_burst = NULL; + dev->tx_pkt_burst = NULL; + +- /* Disable LLDP */ +- ret = i40e_aq_stop_lldp(hw, true, NULL); +- if (ret != I40E_SUCCESS) /* Its failure can be ignored */ +- PMD_INIT_LOG(INFO, "Failed to stop lldp"); +- + /* Clear PXE mode */ + i40e_clear_pxe_mode(hw); + +@@ -9432,10 +9427,6 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb) + * LLDP MIB change event. + */ + if (sw_dcb == TRUE) { +- ret = i40e_aq_stop_lldp(hw, TRUE, NULL); +- if (ret != I40E_SUCCESS) +- PMD_INIT_LOG(DEBUG, "Failed to stop lldp"); +- + ret = i40e_init_dcb(hw); + /* if sw_dcb, lldp agent is stopped, the return from + * i40e_init_dcb we expect is failure with I40E_AQ_RC_EPERM +-- +2.7.4 + diff --git a/patches/dpdk_custom_patch/i40e-fix-VF-bonded-device-link-down.patch b/patches/dpdk_custom_patch/i40e-fix-VF-bonded-device-link-down.patch new file mode 100755 index 00000000..ef6fd58f --- /dev/null +++ b/patches/dpdk_custom_patch/i40e-fix-VF-bonded-device-link-down.patch @@ -0,0 +1,251 @@ +diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c +index 9c1f542..13060db 100644 +--- a/drivers/net/i40e/i40e_ethdev.c ++++ b/drivers/net/i40e/i40e_ethdev.c +@@ -5418,6 +5418,24 @@ i40e_dev_handle_vfr_event(struct rte_eth_dev *dev) + } + + static void ++i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev) ++{ ++ struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); ++ struct i40e_virtchnl_pf_event event; ++ int i; ++ ++ event.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE; ++ event.event_data.link_event.link_status = ++ dev->data->dev_link.link_status; ++ event.event_data.link_event.link_speed = ++ dev->data->dev_link.link_speed; ++ ++ for (i = 0; i < pf->vf_num; i++) ++ i40e_pf_host_send_msg_to_vf(&pf->vfs[i], I40E_VIRTCHNL_OP_EVENT, ++ I40E_SUCCESS, (uint8_t *)&event, sizeof(event)); ++} ++ ++static void + i40e_dev_handle_aq_msg(struct rte_eth_dev *dev) + { + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); +@@ -5455,9 +5473,11 @@ i40e_dev_handle_aq_msg(struct rte_eth_dev *dev) + break; + case i40e_aqc_opc_get_link_status: + ret = i40e_dev_link_update(dev, 0); +- if (!ret) ++ if (!ret) { ++ i40e_notify_all_vfs_link_status(dev); + _rte_eth_dev_callback_process(dev, + RTE_ETH_EVENT_INTR_LSC); ++ } + break; + default: + PMD_DRV_LOG(ERR, "Request %u is not supported yet", +diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h +index 92c8fad..61dfa93 100644 +--- a/drivers/net/i40e/i40e_ethdev.h ++++ b/drivers/net/i40e/i40e_ethdev.h +@@ -599,7 +599,9 @@ int i40e_hash_filter_inset_select(struct i40e_hw *hw, + struct rte_eth_input_set_conf *conf); + int i40e_fdir_filter_inset_select(struct i40e_pf *pf, + struct rte_eth_input_set_conf *conf); +- ++int i40e_pf_host_send_msg_to_vf(struct i40e_pf_vf *vf, uint32_t opcode, ++ uint32_t retval, uint8_t *msg, ++ uint16_t msglen); + void i40e_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, + struct rte_eth_rxq_info *qinfo); + void i40e_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, +diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c +index a616ae0..ba63a7f 100644 +--- a/drivers/net/i40e/i40e_ethdev_vf.c ++++ b/drivers/net/i40e/i40e_ethdev_vf.c +@@ -126,8 +126,6 @@ static void i40evf_dev_promiscuous_enable(struct rte_eth_dev *dev); + static void i40evf_dev_promiscuous_disable(struct rte_eth_dev *dev); + static void i40evf_dev_allmulticast_enable(struct rte_eth_dev *dev); + static void i40evf_dev_allmulticast_disable(struct rte_eth_dev *dev); +-static int i40evf_get_link_status(struct rte_eth_dev *dev, +- struct rte_eth_link *link); + static int i40evf_init_vlan(struct rte_eth_dev *dev); + static int i40evf_dev_rx_queue_start(struct rte_eth_dev *dev, + uint16_t rx_queue_id); +@@ -1084,31 +1082,6 @@ i40evf_del_vlan(struct rte_eth_dev *dev, uint16_t vlanid) + return err; + } + +-static int +-i40evf_get_link_status(struct rte_eth_dev *dev, struct rte_eth_link *link) +-{ +- struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); +- int err; +- struct vf_cmd_info args; +- struct rte_eth_link *new_link; +- +- args.ops = (enum i40e_virtchnl_ops)I40E_VIRTCHNL_OP_GET_LINK_STAT; +- args.in_args = NULL; +- args.in_args_size = 0; +- args.out_buffer = vf->aq_resp; +- args.out_size = I40E_AQ_BUF_SZ; +- err = i40evf_execute_vf_cmd(dev, &args); +- if (err) { +- PMD_DRV_LOG(ERR, "fail to execute command OP_GET_LINK_STAT"); +- return err; +- } +- +- new_link = (struct rte_eth_link *)args.out_buffer; +- (void)rte_memcpy(link, new_link, sizeof(*link)); +- +- return 0; +-} +- + static const struct rte_pci_id pci_id_i40evf_map[] = { + { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_VF) }, + { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_VF_HV) }, +@@ -2166,35 +2139,33 @@ i40evf_dev_link_update(struct rte_eth_dev *dev, + * DPDK pf host provide interfacet to acquire link status + * while Linux driver does not + */ +- if (vf->version_major == I40E_DPDK_VERSION_MAJOR) +- i40evf_get_link_status(dev, &new_link); +- else { +- /* Linux driver PF host */ +- switch (vf->link_speed) { +- case I40E_LINK_SPEED_100MB: +- new_link.link_speed = ETH_SPEED_NUM_100M; +- break; +- case I40E_LINK_SPEED_1GB: +- new_link.link_speed = ETH_SPEED_NUM_1G; +- break; +- case I40E_LINK_SPEED_10GB: +- new_link.link_speed = ETH_SPEED_NUM_10G; +- break; +- case I40E_LINK_SPEED_20GB: +- new_link.link_speed = ETH_SPEED_NUM_20G; +- break; +- case I40E_LINK_SPEED_40GB: +- new_link.link_speed = ETH_SPEED_NUM_40G; +- break; +- default: +- new_link.link_speed = ETH_SPEED_NUM_100M; +- break; +- } +- /* full duplex only */ +- new_link.link_duplex = ETH_LINK_FULL_DUPLEX; +- new_link.link_status = vf->link_up ? ETH_LINK_UP : +- ETH_LINK_DOWN; ++ ++ /* Linux driver PF host */ ++ switch (vf->link_speed) { ++ case I40E_LINK_SPEED_100MB: ++ new_link.link_speed = ETH_SPEED_NUM_100M; ++ break; ++ case I40E_LINK_SPEED_1GB: ++ new_link.link_speed = ETH_SPEED_NUM_1G; ++ break; ++ case I40E_LINK_SPEED_10GB: ++ new_link.link_speed = ETH_SPEED_NUM_10G; ++ break; ++ case I40E_LINK_SPEED_20GB: ++ new_link.link_speed = ETH_SPEED_NUM_20G; ++ break; ++ case I40E_LINK_SPEED_40GB: ++ new_link.link_speed = ETH_SPEED_NUM_40G; ++ break; ++ default: ++ new_link.link_speed = ETH_SPEED_NUM_100M; ++ break; + } ++ /* full duplex only */ ++ new_link.link_duplex = ETH_LINK_FULL_DUPLEX; ++ new_link.link_status = vf->link_up ? ETH_LINK_UP : ++ ETH_LINK_DOWN; ++ + i40evf_dev_atomic_write_link_status(dev, &new_link); + + return 0; +diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c +index d5b2d45..350f6a0 100644 +--- a/drivers/net/i40e/i40e_pf.c ++++ b/drivers/net/i40e/i40e_pf.c +@@ -250,7 +250,7 @@ i40e_pf_host_vf_reset(struct i40e_pf_vf *vf, bool do_hw_reset) + return ret; + } + +-static int ++int + i40e_pf_host_send_msg_to_vf(struct i40e_pf_vf *vf, + uint32_t opcode, + uint32_t retval, +@@ -847,18 +847,6 @@ i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf) + return I40E_SUCCESS; + } + +-static void +-i40e_pf_host_process_cmd_get_link_status(struct i40e_pf_vf *vf) +-{ +- struct rte_eth_dev *dev = I40E_VSI_TO_ETH_DEV(vf->pf->main_vsi); +- +- /* Update link status first to acquire latest link change */ +- i40e_dev_link_update(dev, 1); +- i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_LINK_STAT, +- I40E_SUCCESS, (uint8_t *)&dev->data->dev_link, +- sizeof(struct rte_eth_link)); +-} +- + static int + i40e_pf_host_process_cmd_cfg_vlan_offload( + struct i40e_pf_vf *vf, +@@ -909,6 +897,20 @@ send_msg: + return ret; + } + ++static void ++i40e_notify_vf_link_status(struct rte_eth_dev *dev, struct i40e_pf_vf *vf) ++{ ++ struct i40e_virtchnl_pf_event event; ++ ++ event.event = I40E_VIRTCHNL_EVENT_LINK_CHANGE; ++ event.event_data.link_event.link_status = ++ dev->data->dev_link.link_status; ++ event.event_data.link_event.link_speed = ++ dev->data->dev_link.link_speed; ++ i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_EVENT, ++ I40E_SUCCESS, (uint8_t *)&event, sizeof(event)); ++} ++ + void + i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev, + uint16_t abs_vf_id, uint32_t opcode, +@@ -964,6 +966,7 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev, + case I40E_VIRTCHNL_OP_ENABLE_QUEUES: + PMD_DRV_LOG(INFO, "OP_ENABLE_QUEUES received"); + i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen); ++ i40e_notify_vf_link_status(dev, vf); + break; + case I40E_VIRTCHNL_OP_DISABLE_QUEUES: + PMD_DRV_LOG(INFO, "OP_DISABLE_QUEUE received"); +@@ -993,10 +996,6 @@ i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev, + PMD_DRV_LOG(INFO, "OP_GET_STATS received"); + i40e_pf_host_process_cmd_get_stats(vf); + break; +- case I40E_VIRTCHNL_OP_GET_LINK_STAT: +- PMD_DRV_LOG(INFO, "OP_GET_LINK_STAT received"); +- i40e_pf_host_process_cmd_get_link_status(vf); +- break; + case I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD: + PMD_DRV_LOG(INFO, "OP_CFG_VLAN_OFFLOAD received"); + i40e_pf_host_process_cmd_cfg_vlan_offload(vf, msg, msglen); +diff --git a/drivers/net/i40e/i40e_pf.h b/drivers/net/i40e/i40e_pf.h +index 9c01829..cddc45c 100644 +--- a/drivers/net/i40e/i40e_pf.h ++++ b/drivers/net/i40e/i40e_pf.h +@@ -59,9 +59,8 @@ enum i40e_virtchnl_ops_dpdk { + * Keep some gap between Linux PF commands and + * DPDK PF extended commands. + */ +- I40E_VIRTCHNL_OP_GET_LINK_STAT = I40E_VIRTCHNL_OP_VERSION + ++ I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD = I40E_VIRTCHNL_OP_VERSION + + I40E_DPDK_OFFSET, +- I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD, + I40E_VIRTCHNL_OP_CFG_VLAN_PVID, + I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT, + }; diff --git a/patches/dpdk_custom_patch/i40e-fix-link-management.patch b/patches/dpdk_custom_patch/i40e-fix-link-management.patch new file mode 100644 index 00000000..af2c9a47 --- /dev/null +++ b/patches/dpdk_custom_patch/i40e-fix-link-management.patch @@ -0,0 +1,169 @@ +From ca7e599d4506f3d6b89dd846c901d09d46ea593c Mon Sep 17 00:00:00 2001 +From: Jingjing Wu <jingjing.wu@intel.com> +Date: Thu, 12 May 2016 15:21:04 +0800 +Subject: [PATCH] net/i40e: fix link management +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Previously, there was a known issue "On Intel® 40G Ethernet +Controller stopping the port does not really down the port link." + +There were two reasons why the port was always kept up. +1. Old firmware versions had issues when "Set PHY config command" + was used on 40G NICs. +2. The kernel i40e driver didn't call "Set PHY config command" when + ifconfig up/down was used, it assumes the link is always up. But + in DPDK, ports are forced down when an applications quits. So if + the port is then switched to being controlled by kernel the driver, + the port can not be brought up through "ifconfig <ethx> up". + +This patch fixes this issue by adding in "Set PHY config command" +into our driver. This is now possible because with newer firmware +there is no longer a problem using this command. + +With this fix, after DPDK quit, if the port is switched to being used +by the kernel driver, "ethtool -s <ethx> autoneg on" can be used to +turn on the auto negotiation, and then port can be brought up through +"ifconfig <ethx> up". +NOTE: requires kernel i40e driver version >= 1.4.X + +Fixes: 2f1e22817420 ("i40e: skip link control as firmware workaround") +Fixes: 16c979f9adf2 ("i40e: disable setting of PHY configuration") + +Signed-off-by: Jingjing Wu <jingjing.wu@intel.com> +--- + doc/guides/rel_notes/known_issues.rst | 19 --------- + drivers/net/i40e/i40e_ethdev.c | 72 +++++++++++++++++++++++++++++------ + 2 files changed, 60 insertions(+), 31 deletions(-) + +diff --git a/doc/guides/rel_notes/known_issues.rst b/doc/guides/rel_notes/known_issues.rst +index e464eca..5ec1987 100644 +--- a/doc/guides/rel_notes/known_issues.rst ++++ b/doc/guides/rel_notes/known_issues.rst +@@ -532,25 +532,6 @@ Cannot set link speed on Intel® 40G Ethernet controller + Poll Mode Driver (PMD). + + +-Stopping the port does not down the link on Intel® 40G Ethernet controller +--------------------------------------------------------------------------- +- +-**Description**: +- On Intel® 40G Ethernet Controller stopping the port does not really down the port link. +- +-**Implication**: +- The port link will be still up after stopping the port. +- +-**Resolution/Workaround**: +- None +- +-**Affected Environment/Platform**: +- All. +- +-**Driver/Module**: +- Poll Mode Driver (PMD). +- +- + Devices bound to igb_uio with VT-d enabled do not work on Linux kernel 3.15-3.17 + -------------------------------------------------------------------------------- + +diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c +index f94ad87..7a94663 100644 +--- a/drivers/net/i40e/i40e_ethdev.c ++++ b/drivers/net/i40e/i40e_ethdev.c +@@ -1407,15 +1407,58 @@ i40e_parse_link_speeds(uint16_t link_speeds) + } + + static int +-i40e_phy_conf_link(__rte_unused struct i40e_hw *hw, +- __rte_unused uint8_t abilities, +- __rte_unused uint8_t force_speed) +-{ +- /* Skip any phy config on both 10G and 40G interfaces, as a workaround +- * for the link control limitation of that all link control should be +- * handled by firmware. It should follow up if link control will be +- * opened to software driver in future firmware versions. +- */ ++i40e_phy_conf_link(struct i40e_hw *hw, ++ uint8_t abilities, ++ uint8_t force_speed) ++{ ++ enum i40e_status_code status; ++ struct i40e_aq_get_phy_abilities_resp phy_ab; ++ struct i40e_aq_set_phy_config phy_conf; ++ const uint8_t mask = I40E_AQ_PHY_FLAG_PAUSE_TX | ++ I40E_AQ_PHY_FLAG_PAUSE_RX | ++ I40E_AQ_PHY_FLAG_PAUSE_RX | ++ I40E_AQ_PHY_FLAG_LOW_POWER; ++ const uint8_t advt = I40E_LINK_SPEED_40GB | ++ I40E_LINK_SPEED_10GB | ++ I40E_LINK_SPEED_1GB | ++ I40E_LINK_SPEED_100MB; ++ int ret = -ENOTSUP; ++ ++ ++ status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_ab, ++ NULL); ++ if (status) ++ return ret; ++ ++ memset(&phy_conf, 0, sizeof(phy_conf)); ++ ++ /* bits 0-2 use the values from get_phy_abilities_resp */ ++ abilities &= ~mask; ++ abilities |= phy_ab.abilities & mask; ++ ++ /* update ablities and speed */ ++ if (abilities & I40E_AQ_PHY_AN_ENABLED) ++ phy_conf.link_speed = advt; ++ else ++ phy_conf.link_speed = force_speed; ++ ++ phy_conf.abilities = abilities; ++ ++ /* use get_phy_abilities_resp value for the rest */ ++ phy_conf.phy_type = phy_ab.phy_type; ++ phy_conf.eee_capability = phy_ab.eee_capability; ++ phy_conf.eeer = phy_ab.eeer_val; ++ phy_conf.low_power_ctrl = phy_ab.d3_lpan; ++ ++ PMD_DRV_LOG(DEBUG, "\tCurrent: abilities %x, link_speed %x", ++ phy_ab.abilities, phy_ab.link_speed); ++ PMD_DRV_LOG(DEBUG, "\tConfig: abilities %x, link_speed %x", ++ phy_conf.abilities, phy_conf.link_speed); ++ ++ status = i40e_aq_set_phy_config(hw, &phy_conf, NULL); ++ if (status) ++ return ret; ++ + return I40E_SUCCESS; + } + +@@ -1431,8 +1474,13 @@ i40e_apply_link_speed(struct rte_eth_dev *dev) + abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK; + if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED)) + abilities |= I40E_AQ_PHY_AN_ENABLED; +- else +- abilities |= I40E_AQ_PHY_LINK_ENABLED; ++ abilities |= I40E_AQ_PHY_LINK_ENABLED; ++ ++ /* Skip changing speed on 40G interfaces, FW does not support */ ++ if (i40e_is_40G_device(hw->device_id)) { ++ speed = I40E_LINK_SPEED_UNKNOWN; ++ abilities |= I40E_AQ_PHY_AN_ENABLED; ++ } + + return i40e_phy_conf_link(hw, abilities, speed); + } +@@ -1742,7 +1790,7 @@ i40e_dev_set_link_up(struct rte_eth_dev *dev) + * Set device link down. + */ + static int +-i40e_dev_set_link_down(__rte_unused struct rte_eth_dev *dev) ++i40e_dev_set_link_down(struct rte_eth_dev *dev) + { + uint8_t speed = I40E_LINK_SPEED_UNKNOWN; + uint8_t abilities = I40E_AQ_PHY_ENABLE_ATOMIC_LINK; +-- +2.7.4 + diff --git a/patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch b/patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch new file mode 100755 index 00000000..1510b36c --- /dev/null +++ b/patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch @@ -0,0 +1,150 @@ +diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c +index d0aeb70..9c1f542 100644 +--- a/drivers/net/i40e/i40e_ethdev.c ++++ b/drivers/net/i40e/i40e_ethdev.c +@@ -108,7 +108,6 @@ + I40E_PFINT_ICR0_ENA_GRST_MASK | \ + I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK | \ + I40E_PFINT_ICR0_ENA_STORM_DETECT_MASK | \ +- I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK | \ + I40E_PFINT_ICR0_ENA_HMC_ERR_MASK | \ + I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK | \ + I40E_PFINT_ICR0_ENA_VFLR_MASK | \ +@@ -1768,6 +1767,16 @@ i40e_dev_start(struct rte_eth_dev *dev) + if (dev->data->dev_conf.intr_conf.lsc != 0) + PMD_INIT_LOG(INFO, "lsc won't enable because of" + " no intr multiplex\n"); ++ } else if (dev->data->dev_conf.intr_conf.lsc != 0) { ++ ret = i40e_aq_set_phy_int_mask(hw, ++ ~(I40E_AQ_EVENT_LINK_UPDOWN | ++ I40E_AQ_EVENT_MODULE_QUAL_FAIL | ++ I40E_AQ_EVENT_MEDIA_NA), NULL); ++ if (ret != I40E_SUCCESS) ++ PMD_DRV_LOG(WARNING, "Fail to set phy mask"); ++ ++ /* Call get_link_info aq commond to enable LSE */ ++ i40e_dev_link_update(dev, 0); + } + + /* enable uio intr after callback register */ +@@ -1984,6 +1993,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev, + struct rte_eth_link link, old; + int status; + unsigned rep_cnt = MAX_REPEAT_TIME; ++ bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false; + + memset(&link, 0, sizeof(link)); + memset(&old, 0, sizeof(old)); +@@ -1992,7 +2002,8 @@ i40e_dev_link_update(struct rte_eth_dev *dev, + + do { + /* Get link status information from hardware */ +- status = i40e_aq_get_link_info(hw, false, &link_status, NULL); ++ status = i40e_aq_get_link_info(hw, enable_lse, ++ &link_status, NULL); + if (status != I40E_SUCCESS) { + link.link_speed = ETH_SPEED_NUM_100M; + link.link_duplex = ETH_LINK_FULL_DUPLEX; +@@ -5442,6 +5453,12 @@ i40e_dev_handle_aq_msg(struct rte_eth_dev *dev) + info.msg_buf, + info.msg_len); + break; ++ case i40e_aqc_opc_get_link_status: ++ ret = i40e_dev_link_update(dev, 0); ++ if (!ret) ++ _rte_eth_dev_callback_process(dev, ++ RTE_ETH_EVENT_INTR_LSC); ++ break; + default: + PMD_DRV_LOG(ERR, "Request %u is not supported yet", + opcode); +@@ -5451,57 +5468,6 @@ i40e_dev_handle_aq_msg(struct rte_eth_dev *dev) + rte_free(info.msg_buf); + } + +-/* +- * Interrupt handler is registered as the alarm callback for handling LSC +- * interrupt in a definite of time, in order to wait the NIC into a stable +- * state. Currently it waits 1 sec in i40e for the link up interrupt, and +- * no need for link down interrupt. +- */ +-static void +-i40e_dev_interrupt_delayed_handler(void *param) +-{ +- struct rte_eth_dev *dev = (struct rte_eth_dev *)param; +- struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); +- uint32_t icr0; +- +- /* read interrupt causes again */ +- icr0 = I40E_READ_REG(hw, I40E_PFINT_ICR0); +- +-#ifdef RTE_LIBRTE_I40E_DEBUG_DRIVER +- if (icr0 & I40E_PFINT_ICR0_ECC_ERR_MASK) +- PMD_DRV_LOG(ERR, "ICR0: unrecoverable ECC error\n"); +- if (icr0 & I40E_PFINT_ICR0_MAL_DETECT_MASK) +- PMD_DRV_LOG(ERR, "ICR0: malicious programming detected\n"); +- if (icr0 & I40E_PFINT_ICR0_GRST_MASK) +- PMD_DRV_LOG(INFO, "ICR0: global reset requested\n"); +- if (icr0 & I40E_PFINT_ICR0_PCI_EXCEPTION_MASK) +- PMD_DRV_LOG(INFO, "ICR0: PCI exception\n activated\n"); +- if (icr0 & I40E_PFINT_ICR0_STORM_DETECT_MASK) +- PMD_DRV_LOG(INFO, "ICR0: a change in the storm control " +- "state\n"); +- if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK) +- PMD_DRV_LOG(ERR, "ICR0: HMC error\n"); +- if (icr0 & I40E_PFINT_ICR0_PE_CRITERR_MASK) +- PMD_DRV_LOG(ERR, "ICR0: protocol engine critical error\n"); +-#endif /* RTE_LIBRTE_I40E_DEBUG_DRIVER */ +- +- if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) { +- PMD_DRV_LOG(INFO, "INT:VF reset detected\n"); +- i40e_dev_handle_vfr_event(dev); +- } +- if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) { +- PMD_DRV_LOG(INFO, "INT:ADMINQ event\n"); +- i40e_dev_handle_aq_msg(dev); +- } +- +- /* handle the link up interrupt in an alarm callback */ +- i40e_dev_link_update(dev, 0); +- _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC); +- +- i40e_pf_enable_irq0(hw); +- rte_intr_enable(&(dev->pci_dev->intr_handle)); +-} +- + /** + * Interrupt handler triggered by NIC for handling + * specific interrupt. +@@ -5558,31 +5524,6 @@ i40e_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle, + PMD_DRV_LOG(INFO, "ICR0: adminq event"); + i40e_dev_handle_aq_msg(dev); + } +- +- /* Link Status Change interrupt */ +- if (icr0 & I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK) { +-#define I40E_US_PER_SECOND 1000000 +- struct rte_eth_link link; +- +- PMD_DRV_LOG(INFO, "ICR0: link status changed\n"); +- memset(&link, 0, sizeof(link)); +- rte_i40e_dev_atomic_read_link_status(dev, &link); +- i40e_dev_link_update(dev, 0); +- +- /* +- * For link up interrupt, it needs to wait 1 second to let the +- * hardware be a stable state. Otherwise several consecutive +- * interrupts can be observed. +- * For link down interrupt, no need to wait. +- */ +- if (!link.link_status && rte_eal_alarm_set(I40E_US_PER_SECOND, +- i40e_dev_interrupt_delayed_handler, (void *)dev) >= 0) +- return; +- else +- _rte_eth_dev_callback_process(dev, +- RTE_ETH_EVENT_INTR_LSC); +- } +- + done: + /* Enable interrupt */ + i40e_pf_enable_irq0(hw); diff --git a/patches/dpdk_custom_patch/rte_pipeline.patch b/patches/dpdk_custom_patch/rte_pipeline.patch new file mode 100644 index 00000000..3f52d326 --- /dev/null +++ b/patches/dpdk_custom_patch/rte_pipeline.patch @@ -0,0 +1,88 @@ +--- lib/librte_pipeline/rte_pipeline.c 2016-08-10 21:50:46.625571187 +0530 ++++ lib/librte_pipeline/rte_pipeline.c 2016-08-10 21:51:02.333571628 +0530 +@@ -1241,6 +1241,85 @@ + } + } + ++void ++rte_pipeline_action_handler_port_ext(struct rte_pipeline *p, ++ uint64_t pkts_mask, ++ struct rte_pipeline_table_entry **entries); ++ ++void ++rte_pipeline_action_handler_port_ext(struct rte_pipeline *p, ++ uint64_t pkts_mask, ++ struct rte_pipeline_table_entry **entries) ++{ ++ p->pkts_mask = pkts_mask; ++ ++ if ((pkts_mask & (pkts_mask + 1)) == 0) { ++ uint64_t n_pkts = __builtin_popcountll(pkts_mask); ++ uint32_t i; ++ ++ for (i = 0; i < n_pkts; i++) { ++ struct rte_mbuf *pkt = p->pkts[i]; ++ uint32_t port_out_id = entries[i]->port_id; ++ struct rte_port_out *port_out = ++ &p->ports_out[port_out_id]; ++ ++ /* Output port user actions */ ++ if (port_out->f_action == NULL) /* Output port TX */ ++ port_out->ops.f_tx(port_out->h_port, pkt); ++ else { ++ uint64_t pkt_mask = 1LLU << i; ++ ++ port_out->f_action(p, ++ p->pkts, ++ pkt_mask, ++ port_out->arg_ah); ++ ++ RTE_PIPELINE_STATS_AH_DROP_READ(p, ++ port_out->n_pkts_dropped_by_ah); ++ ++ /* Output port TX */ ++ if (pkt_mask & p->pkts_mask) ++ port_out->ops.f_tx(port_out->h_port, ++ pkt); ++ } ++ } ++ } else { ++ uint32_t i; ++ ++ for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) { ++ uint64_t pkt_mask = 1LLU << i; ++ struct rte_mbuf *pkt; ++ struct rte_port_out *port_out; ++ uint32_t port_out_id; ++ ++ if ((pkt_mask & pkts_mask) == 0) ++ continue; ++ ++ pkt = p->pkts[i]; ++ port_out_id = entries[i]->port_id; ++ port_out = &p->ports_out[port_out_id]; ++ ++ /* Output port user actions */ ++ if (port_out->f_action == NULL) /* Output port TX */ ++ port_out->ops.f_tx(port_out->h_port, pkt); ++ else { ++ port_out->f_action(p, ++ p->pkts, ++ pkt_mask, ++ port_out->arg_ah); ++ ++ RTE_PIPELINE_STATS_AH_DROP_READ(p, ++ port_out->n_pkts_dropped_by_ah); ++ ++ /* Output port TX */ ++ if (pkt_mask & p->pkts_mask) ++ port_out->ops.f_tx(port_out->h_port, ++ pkt); ++ } ++ } ++ } ++} ++ + static inline void + rte_pipeline_action_handler_port_meta(struct rte_pipeline *p, + uint64_t pkts_mask) diff --git a/tools/setenv.sh b/tools/setenv.sh new file mode 100755 index 00000000..800168b8 --- /dev/null +++ b/tools/setenv.sh @@ -0,0 +1,19 @@ +#! /bin/bash +# +# Copyright (c) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +export VNF_CORE=$( cd "$( dirname "${BASH_SOURCE[0]}")/.." && pwd ) +export RTE_SDK=$( cd "$( dirname "${BASH_SOURCE[0]}")/.." && pwd )/dpdk +export RTE_TARGET=x86_64-native-linuxapp-gcc diff --git a/tools/vnf_build.sh b/tools/vnf_build.sh new file mode 100755 index 00000000..7c9265db --- /dev/null +++ b/tools/vnf_build.sh @@ -0,0 +1,317 @@ +#! /bin/bash +# +# Copyright (c) 2017 Intel Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +cd $(dirname ${BASH_SOURCE[0]})/.. +export VNF_CORE=$PWD +echo "------------------------------------------------------------------------------" +echo " VNF_CORE exported as $VNF_CORE" +echo "------------------------------------------------------------------------------" + +HUGEPGSZ=`cat /proc/meminfo | grep Hugepagesize | cut -d : -f 2 | tr -d ' '` +MODPROBE="/sbin/modprobe" +INSMOD="/sbin/insmod" +DPDK_DOWNLOAD="http://dpdk.org/browse/dpdk/snapshot/dpdk-16.04.zip" +DPDK_DIR=$VNF_CORE/dpdk + +# +# Sets QUIT variable so script will finish. +# +quit() +{ + QUIT=$1 +} + +# Shortcut for quit. +q() +{ + quit +} + +setup_http_proxy() +{ + while true; do + echo + read -p "Enter Proxy : " proxy + export http_proxy=$proxy + export https_proxy=$proxy + echo "Acquire::http::proxy \"$http_proxy\";" | sudo tee -a /etc/apt/apt.conf > /dev/null + echo "Acquire::https::proxy \"$http_proxy\";" | sudo tee -a /etc/apt/apt.conf > /dev/null + + wget -T 20 -t 3 --spider http://www.google.com > /dev/null 2>&1 + if [ "$?" != 0 ]; then + echo -e "No Internet connection. Proxy incorrect? Try again" + echo -e "eg: http://<proxy>:<port>" + exit 1 + fi + return + done + echo "Network connectivity successful." +} + +step_1() +{ + TITLE="Environment setup." + CONFIG_NUM=1 + TEXT[1]="Check OS and network connection" + FUNC[1]="setup_env" +} +setup_env() +{ + # a. Check for OS dependencies + source /etc/os-release + if [[ $VERSION_ID != "16.04" ]] ; then + echo "WARNING: It is recommended to use Ubuntu 16.04..Your version is "$VERSION_ID + else + echo "Ubuntu 16.04 OS requirement met..." + fi + echo + echo "Checking network connectivity..." + # b. Check for internet connections + wget -T 20 -t 3 --spider http://www.google.com > /dev/null 2>&1 + if [ "$?" != 0 ]; then + while true; do + read -p "No Internet connection. Are you behind a proxy (y/n)? " yn + case $yn in + [Yy]* ) $SETUP_PROXY ; return;; + [Nn]* ) echo "Please check your internet connection..." ; exit;; + * ) "Please answer yes or no.";; + esac + done + fi + echo "Network connectivity successful." +} + +step_2() +{ + TITLE="Download and Install" + CONFIG_NUM=1 + TEXT[1]="Agree to download" + FUNC[1]="get_agreement_download" + TEXT[2]="Download packages" + FUNC[2]="install_libs" + TEXT[3]="Download DPDK zip" + FUNC[3]="download_dpdk_zip" + TEXT[4]="Build and Install DPDK" + FUNC[4]="install_dpdk" + TEXT[5]="Setup hugepages" + FUNC[5]="setup_hugepages" +} +get_agreement_download() +{ + echo + echo "List of packages needed for VNFs build and installation:" + echo "-------------------------------------------------------" + echo "1. DPDK version 16.04" + echo "2. build-essential" + echo "3. linux-headers-generic" + echo "4. git" + echo "5. unzip" + echo "6. libpcap-dev" + echo "7. make" + echo "8. and other library dependencies" + while true; do + read -p "We need download above mentioned package. Press (y/n) to continue? " yn + case $yn in + [Yy]* ) + touch .agree + return;; + [Nn]* ) exit;; + * ) "Please answer yes or no.";; + esac + done +} + +install_libs() +{ + echo "Install libs needed to build and run VNFs..." + file_name=".agree" + if [ ! -e "$file_name" ]; then + echo "Please choose option '2.Agree to download' first" + return + fi + file_name=".download" + if [ -e "$file_name" ]; then + clear + return + fi + sudo apt-get update + sudo apt-get -y install build-essential linux-headers-$(uname -r) git unzip libpcap0.8-dev gcc \ + make libc6 libc6-dev g++-multilib libzmq3-dev libcurl4-openssl-dev + touch .download +} + +download_dpdk_zip() +{ + echo "Download DPDK zip" + file_name=".agree" + if [ ! -e "$file_name" ]; then + echo "Please choose option '2.Agree to download' first" + return + fi + rm -rf $DPDK_DIR + if [ ! -e ${DPDK_DOWNLOAD##*/} ] ; then + wget ${DPDK_DOWNLOAD} + fi + unzip -o ${DPDK_DOWNLOAD##*/} + mv $VNF_CORE/dpdk-16.04 $VNF_CORE/dpdk +} + +install_dpdk() +{ + echo "Build DPDK" + + if [ ! -d "$DPDK_DIR" ]; then + echo "Please choose option '4 Download DPDK zip'" + return + fi + + export RTE_TARGET=x86_64-native-linuxapp-gcc + + pushd $DPDK_DIR + echo "Apply dpdk custom patches..." + patch -p0 < $VNF_CORE/patches/dpdk_custom_patch/rte_pipeline.patch + patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-link-management.patch + patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-Rx-hang-when-disable-LLDP.patch + patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-link-status-change-interrupt.patch + patch -p1 < $VNF_CORE/patches/dpdk_custom_patch/i40e-fix-VF-bonded-device-link-down.patch + + make -j install T=$RTE_TARGET + if [ $? -ne 0 ] ; then + echo "Failed to build dpdk, please check the errors." + return + fi + sudo modinfo igb_uio + if [ $? -ne 0 ] ; then + sudo $MODPROBE -v uio + sudo $INSMOD $RTE_TARGET/kmod/igb_uio.ko + sudo cp -f $RTE_TARGET/kmod/igb_uio.ko /lib/modules/$(uname -r) + echo "uio" | sudo tee -a /etc/modules + echo "igb_uio" | sudo tee -a /etc/modules + sudo depmod + fi + popd +} + +setup_hugepages() +{ + #---- + Pages=16 + if [[ "$HUGEPGSZ" = "2048kB" ]] ; then + Pages=8192 + fi + if [ ! "`grep nr_hugepages /etc/sysctl.conf`" ] ; then + echo "vm.nr_hugepages=$Pages" | sudo tee /etc/sysctl.conf + fi + sudo sysctl -p + + sudo service procps start + + grep -s '/dev/hugepages' /proc/mounts + if [ $? -ne 0 ] ; then + echo "Creating /mnt/huge and mounting as hugetlbfs" + sudo mkdir -p /mnt/huge + sudo mount -t hugetlbfs nodev /mnt/huge + echo "nodev /mnt/huge hugetlbfs defaults 0 0" | sudo tee -a /etc/fstab > /dev/null + fi +} + +step_3() +{ + TITLE="Build VNFs" + CONFIG_NUM=1 + TEXT[1]="Build all VNFs (vACL, vCGNAPT, vFW)" + FUNC[1]="build_vnfs" +} + +build_vnfs() +{ + + if [ ! -d "$DPDK_DIR" ]; then + echo "Please choose option '4 Download DPDK zip'" + return + fi + + if [ ! -d "$DPDK_DIR/x86_64-native-linux-gcc" ]; then + echo "Please choose option '5 Build and Install DPDK'" + return + fi + + export RTE_SDK=$DPDK_DIR + export RTE_TARGET=x86_64-native-linuxapp-gcc + pushd $VNF_CORE + make clean + make || { echo -e "\nVNF: Make failed\n"; } + popd +} + +SETUP_PROXY="setup_http_proxy" +STEPS[1]="step_1" +STEPS[2]="step_2" +STEPS[3]="step_3" + +QUIT=0 + +clear + +echo -n "Checking for user permission.. " +sudo -n true +if [ $? -ne 0 ]; then + echo "Password-less sudo user must run this script" 1>&2 + exit 1 +fi +echo "Done" +clear + +while [ "$QUIT" == "0" ]; do + OPTION_NUM=1 + for s in $(seq ${#STEPS[@]}) ; do + ${STEPS[s]} + + echo "----------------------------------------------------------" + echo " Step $s: ${TITLE}" + echo "----------------------------------------------------------" + + for i in $(seq ${#TEXT[@]}) ; do + echo "[$OPTION_NUM] ${TEXT[i]}" + OPTIONS[$OPTION_NUM]=${FUNC[i]} + let "OPTION_NUM+=1" + done + + # Clear TEXT and FUNC arrays before next step + unset TEXT + unset FUNC + + echo "" + done + + echo "[$OPTION_NUM] Exit Script" + OPTIONS[$OPTION_NUM]="quit" + echo "" + echo -n "Option: " + read our_entry + echo "" + ${OPTIONS[our_entry]} ${our_entry} + + if [ "$QUIT" == "0" ] ; then + echo + echo -n "Press enter to continue ..."; read + clear + continue + exit + fi + echo "Installation successfully complete." +done |