[net-next 06/12] i40e: allow look-up of MAC address from Open Firmware or IDPROM
From: Jacob Keller Look up the MAC address from the eth_get_platform_mac_address() function first before checking what the firmware provides. We already handle the case of re-writing the MAC-VLAN filter, so there is no need to add extra code for this. However, update the comment where we do this to indicate that it does impact the Open Firmware MAC address case. Change-ID: I73e59fbe0b0e7e6f3ee9f5170d0bd3a4d5faf4db Signed-off-by: Jacob Keller Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 29 - 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 22831a4a9099..2111f120865a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -9326,10 +9326,15 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) if (vsi->type == I40E_VSI_MAIN) { SET_NETDEV_DEV(netdev, &pf->pdev->dev); ether_addr_copy(mac_addr, hw->mac.perm_addr); - /* The following steps are necessary to properly keep track of -* MAC-VLAN filters loaded into firmware - first we remove -* filter that is automatically generated by firmware and then -* add new filter both to the driver hash table and firmware. + /* The following steps are necessary for two reasons. First, +* some older NVM configurations load a default MAC-VLAN +* filter that will accept any tagged packet, and we want to +* replace this with a normal filter. Additionally, it is +* possible our MAC address was provided by the platform using +* Open Firmware or similar. +* +* Thus, we need to remove the default filter and install one +* specific to the MAC address. */ i40e_rm_default_mac_filter(vsi, mac_addr); spin_lock_bh(&vsi->mac_filter_hash_lock); @@ -10834,20 +10839,18 @@ static void i40e_print_features(struct i40e_pf *pf) /** * i40e_get_platform_mac_addr - get platform-specific MAC address - * * @pdev: PCI device information struct * @pf: board private structure * - * Look up the MAC address in Open Firmware on systems that support it, - * and use IDPROM on SPARC if no OF address is found. On return, the - * I40E_FLAG_PF_MAC will be wset in pf->flags if a platform-specific value - * has been selected. + * Look up the MAC address for the device. First we'll try + * eth_platform_get_mac_address, which will check Open Firmware, or arch + * specific fallback. Otherwise, we'll default to the stored value in + * firmware. **/ static void i40e_get_platform_mac_addr(struct pci_dev *pdev, struct i40e_pf *pf) { - pf->flags &= ~I40E_FLAG_PF_MAC; - if (!eth_platform_get_mac_address(&pdev->dev, pf->hw.mac.addr)) - pf->flags |= I40E_FLAG_PF_MAC; + if (eth_platform_get_mac_address(&pdev->dev, pf->hw.mac.addr)) + i40e_get_mac_addr(&pf->hw, pf->hw.mac.addr); } /** @@ -11061,9 +11064,9 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) i40e_aq_stop_lldp(hw, true, NULL); } - i40e_get_mac_addr(hw, hw->mac.addr); /* allow a platform config to override the HW addr */ i40e_get_platform_mac_addr(pdev, pf); + if (!is_valid_ether_addr(hw->mac.addr)) { dev_info(&pdev->dev, "invalid MAC address %pM\n", hw->mac.addr); err = -EIO; -- 2.12.2
[net-next 02/12] i40e: update error message when trying to add invalid filters
From: Jacob Keller Re-word the error message displayed when adding a filter with an invalid flow type. Additionally, report a distinct error message when the IPv4 protocol is at fault. Change-ID: Iba3d85b87f8d383c97c8bdd180df34a6adf3ee67 Signed-off-by: Jacob Keller Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index ebffca0cefac..d45f48c84ff7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -533,14 +533,15 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi, break; default: /* We cannot support masking based on protocol */ - goto unsupported_flow; + dev_info(&pf->pdev->dev, "Unsupported IPv4 protocol 0x%02x\n", +input->ip4_proto); + return -EINVAL; } break; default: -unsupported_flow: - dev_info(&pf->pdev->dev, "Could not specify spec type %d\n", + dev_info(&pf->pdev->dev, "Unsupported flow type 0x%02x\n", input->flow_type); - ret = -EINVAL; + return -EINVAL; } /* The buffer allocated here will be normally be freed by -- 2.12.2
[net-next 03/12] i40e: Swap use of pf->flags and pf->hw_disabled_flags for ATR Eviction
From: Alexander Duyck This is a minor cleanup so that we are always updating pf->flags when we make a change to the private flags instead of updating a mix of either pf->flags and/or pf->hw_disabled_flags. In addition I went through and cleaned out all the spots where we were using the X722 define in regards to this flag. Lastly since we changed the logic I went through and flushed out any redundancy and cleaned up the handling of the flags in the Tx path. Change-ID: I79ff95a7272bb2533251ff11ef91e89ccb80b610 Signed-off-by: Alexander Duyck Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index d45f48c84ff7..a9a97dd2c0a5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2263,8 +2263,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb, /* Due to lack of space, no more new filters can be programmed */ if (th->syn && (pf->hw_disabled_flags & I40E_FLAG_FD_ATR_ENABLED)) return; - if ((pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) && - (!(pf->hw_disabled_flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE))) { + if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) { /* HW ATR eviction will take care of removing filters on FIN * and RST packets. */ @@ -2326,8 +2325,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb, I40E_TXD_FLTR_QW1_CNTINDEX_SHIFT) & I40E_TXD_FLTR_QW1_CNTINDEX_MASK; - if ((pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) && - (!(pf->hw_disabled_flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE))) + if (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE) dtype_cmd |= I40E_TXD_FLTR_QW1_ATR_MASK; fdir_desc->qindex_flex_ptype_vsi = cpu_to_le32(flex_ptype); -- 2.12.2
[net-next 07/12] i40e: remove extraneous loop in i40e_vsi_wait_queues_disabled
From: Jacob Keller We can simply check both Tx and Rx queues in a single loop, rather than repeating the loop twice. Change-ID: Ic06f26b0e3c2620e0e33c1a2999edda488e647ad Signed-off-by: Jacob Keller Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 2111f120865a..0e1240b704ef 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -4440,7 +4440,7 @@ static void i40e_pf_unquiesce_all_vsi(struct i40e_pf *pf) * i40e_vsi_wait_queues_disabled - Wait for VSI's queues to be disabled * @vsi: the VSI being configured * - * This function waits for the given VSI's queues to be disabled. + * Wait until all queues on a given VSI have been disabled. **/ static int i40e_vsi_wait_queues_disabled(struct i40e_vsi *vsi) { @@ -4449,7 +4449,7 @@ static int i40e_vsi_wait_queues_disabled(struct i40e_vsi *vsi) pf_q = vsi->base_queue; for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { - /* Check and wait for the disable status of the queue */ + /* Check and wait for the Tx queue */ ret = i40e_pf_txq_wait(pf, pf_q, false); if (ret) { dev_info(&pf->pdev->dev, @@ -4457,11 +4457,7 @@ static int i40e_vsi_wait_queues_disabled(struct i40e_vsi *vsi) vsi->seid, pf_q); return ret; } - } - - pf_q = vsi->base_queue; - for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { - /* Check and wait for the disable status of the queue */ + /* Check and wait for the Tx queue */ ret = i40e_pf_rxq_wait(pf, pf_q, false); if (ret) { dev_info(&pf->pdev->dev, -- 2.12.2
[net-next 05/12] i40e: Simplify i40e_detect_recover_hung_queue logic
From: Alan Brady This patch greatly reduces the unneeded complexity in the i40e_detect_recover_hung_queue code path. The previous implementation set a 'hung bit' which would then get cleared while polling. If the detection routine was called a second time with the bit already set, we would issue a software interrupt. This patch makes it such that if interrupts are disabled and we have pending TX descriptors, we trigger a software interrupt since in, the worst case, queues are already clean and we have an extra interrupt. Additionally this patch removes the workaround for lost interrupts as calling napi_reschedule in this context can cause software interrupts to fire on the wrong CPU. Change-ID: Iae108582a3ceb6229ed1d22e4ed6e69cf97aad8d Signed-off-by: Alan Brady Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 4 -- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 1 - drivers/net/ethernet/intel/i40e/i40e_main.c| 59 +- drivers/net/ethernet/intel/i40e/i40e_txrx.c| 12 ++ drivers/net/ethernet/intel/i40e/i40e_txrx.h| 3 +- 5 files changed, 15 insertions(+), 64 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 686327c031fa..110ef4204306 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -617,7 +617,6 @@ struct i40e_vsi { u32 tx_busy; u64 tx_linearize; u64 tx_force_wb; - u64 tx_lost_interrupt; u32 rx_buf_failed; u32 rx_page_failed; @@ -703,9 +702,6 @@ struct i40e_q_vector { u8 num_ringpairs; /* total number of ring pairs in vector */ -#define I40E_Q_VECTOR_HUNG_DETECT 0 /* Bit Index for hung detection logic */ - unsigned long hung_detected; /* Set/Reset for hung_detection logic */ - cpumask_t affinity_mask; struct irq_affinity_notify affinity_notify; diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 68c0f204f93e..10325b5a9805 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -89,7 +89,6 @@ static const struct i40e_stats i40e_gstrings_misc_stats[] = { I40E_VSI_STAT("rx_unknown_protocol", eth_stats.rx_unknown_protocol), I40E_VSI_STAT("tx_linearize", tx_linearize), I40E_VSI_STAT("tx_force_wb", tx_force_wb), - I40E_VSI_STAT("tx_lost_interrupt", tx_lost_interrupt), I40E_VSI_STAT("rx_alloc_fail", rx_buf_failed), I40E_VSI_STAT("rx_pg_alloc_fail", rx_page_failed), }; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 8181647f512e..22831a4a9099 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -737,7 +737,6 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) struct i40e_eth_stats *oes; struct i40e_eth_stats *es; /* device's eth stats */ u32 tx_restart, tx_busy; - u64 tx_lost_interrupt; struct i40e_ring *p; u32 rx_page, rx_buf; u64 bytes, packets; @@ -763,7 +762,6 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) rx_b = rx_p = 0; tx_b = tx_p = 0; tx_restart = tx_busy = tx_linearize = tx_force_wb = 0; - tx_lost_interrupt = 0; rx_page = 0; rx_buf = 0; rcu_read_lock(); @@ -782,7 +780,6 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) tx_busy += p->tx_stats.tx_busy; tx_linearize += p->tx_stats.tx_linearize; tx_force_wb += p->tx_stats.tx_force_wb; - tx_lost_interrupt += p->tx_stats.tx_lost_interrupt; /* Rx queue is part of the same block as Tx queue */ p = &p[1]; @@ -801,7 +798,6 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi) vsi->tx_busy = tx_busy; vsi->tx_linearize = tx_linearize; vsi->tx_force_wb = tx_force_wb; - vsi->tx_lost_interrupt = tx_lost_interrupt; vsi->rx_page_failed = rx_page; vsi->rx_buf_failed = rx_buf; @@ -4508,16 +4504,15 @@ static int i40e_pf_wait_queues_disabled(struct i40e_pf *pf) * @vsi: Pointer to VSI struct * * This function checks specified queue for given VSI. Detects hung condition. - * Sets hung bit since it is two step process. Before next run of service task - * if napi_poll runs, it reset 'hung' bit for respective q_vector. If not, - * hung condition remain unchanged and during subsequent run, this function - * issues SW interrupt to recover from hung condition. + * We proactively detect hung TX queues by checking if interrupts are disabled + * but there are pending descriptors. If it appears hung, attempt to recover + * by triggering a SW interrupt. **/ static void i40e_detect_recover_hung_queue(
[net-next 04/12] i40e: Decrease the scope of rtnl lock
From: Maciej Sosin Previously rtnl lock was held during whole reset procedure that was stopping other PFs running their reset procedures. In the result reset was not handled properly and host reset was the only way to recover. Change-ID: I23c0771c0303caaa7bd64badbf0c667e25142954 Signed-off-by: Maciej Sosin Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 2 +- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 6 +- drivers/net/ethernet/intel/i40e/i40e_main.c| 138 + 3 files changed, 101 insertions(+), 45 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 421ea57128d3..686327c031fa 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -837,7 +837,7 @@ void i40e_down(struct i40e_vsi *vsi); extern const char i40e_driver_name[]; extern const char i40e_driver_version_str[]; void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags); -void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags); +void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags, bool lock_acquired); int i40e_config_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size); int i40e_get_rss(struct i40e_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size); void i40e_fill_rss_lut(struct i40e_pf *pf, u8 *lut, diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index c0c1a0cdaa5b..68c0f204f93e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1852,7 +1852,7 @@ static void i40e_diag_test(struct net_device *netdev, * link then the following link test would have * to be moved to before the reset */ - i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED)); + i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED), true); if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK])) eth_test->flags |= ETH_TEST_FL_FAILED; @@ -1868,7 +1868,7 @@ static void i40e_diag_test(struct net_device *netdev, eth_test->flags |= ETH_TEST_FL_FAILED; clear_bit(__I40E_TESTING, &pf->state); - i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED)); + i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED), true); if (if_running) i40e_open(netdev); @@ -4099,7 +4099,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags) */ if ((changed_flags & I40E_FLAG_VEB_STATS_ENABLED) || ((changed_flags & I40E_FLAG_LEGACY_RX) && netif_running(dev))) - i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED)); + i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED), true); return 0; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 1ee2759c38f7..8181647f512e 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -50,13 +50,16 @@ static const char i40e_copyright[] = "Copyright (c) 2013 - 2014 Intel Corporatio /* a bit of forward declarations */ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi); -static void i40e_handle_reset_warning(struct i40e_pf *pf); +static void i40e_handle_reset_warning(struct i40e_pf *pf, bool lock_acquired); static int i40e_add_vsi(struct i40e_vsi *vsi); static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi); static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit); static int i40e_setup_misc_vector(struct i40e_pf *pf); static void i40e_determine_queue_usage(struct i40e_pf *pf); static int i40e_setup_pf_filter_control(struct i40e_pf *pf); +static void i40e_prep_for_reset(struct i40e_pf *pf, bool lock_acquired); +static int i40e_reset(struct i40e_pf *pf); +static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired); static void i40e_fdir_sb_setup(struct i40e_pf *pf); static int i40e_veb_get_bw_info(struct i40e_veb *veb); @@ -5537,6 +5540,8 @@ int i40e_open(struct net_device *netdev) * Finish initialization of the VSI. * * Returns 0 on success, negative value on failure + * + * Note: expects to be called while under rtnl_lock() **/ int i40e_vsi_open(struct i40e_vsi *vsi) { @@ -5600,7 +5605,7 @@ int i40e_vsi_open(struct i40e_vsi *vsi) err_setup_tx: i40e_vsi_free_tx_resources(vsi); if (vsi == pf->vsi[pf->lan_vsi]) - i40e_do_reset(pf, BIT_ULL(__I40E_PF_RESET_REQUESTED)); + i40e_do_reset(pf, BIT_ULL(__I40E_PF_RESET_REQUESTED), true); return err; } @@ -5686,12 +5691,14 @@ int i40e_close(struct net_device *netdev) * i40e_do_reset - Start a PF or Core Reset sequence * @pf: board private structure * @r
[net-next 01/12] i40e: only register client on iWarp-capable devices
From: Mitch Williams The client interface is only intended for use on devices that support iWarp. Only register with the client if this is the case. This fixes a panic when loading i40iw on X710 devices. Signed-off-by: Mitch Williams Reported-by: Stefan Assmann Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index d83430faaa41..1ee2759c38f7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -11245,10 +11245,12 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) round_jiffies(jiffies + pf->service_timer_period)); /* add this PF to client device list and launch a client service task */ - err = i40e_lan_add_device(pf); - if (err) - dev_info(&pdev->dev, "Failed to add PF to client API service list: %d\n", -err); + if (pf->flags & I40E_FLAG_IWARP_ENABLED) { + err = i40e_lan_add_device(pf); + if (err) + dev_info(&pdev->dev, "Failed to add PF to client API service list: %d\n", +err); + } #define PCI_SPEED_SIZE 8 #define PCI_WIDTH_SIZE 8 @@ -11426,10 +11428,11 @@ static void i40e_remove(struct pci_dev *pdev) i40e_vsi_release(pf->vsi[pf->lan_vsi]); /* remove attached clients */ - ret_code = i40e_lan_del_device(pf); - if (ret_code) { - dev_warn(&pdev->dev, "Failed to delete client device: %d\n", -ret_code); + if (pf->flags & I40E_FLAG_IWARP_ENABLED) { + ret_code = i40e_lan_del_device(pf); + if (ret_code) + dev_warn(&pdev->dev, "Failed to delete client device: %d\n", +ret_code); } /* shutdown and destroy the HMC */ -- 2.12.2
[net-next 00/12][pull request] 40GbE Intel Wired LAN Driver Updates 2017-04-08
This series contains updates to i40e and i40evf only. Mitch fixes an issue where the client driver (i40iw) was attempting to load on x710 devices (which do not support iWARP), so only register with the client if iWARP is supported. Jake fixes up error messages to better clarify to the user when adding a invalid flow type. Updates the driver to look up the MAC address from eth_get_platform_mac_address() first before checking what the firmware provides. Cleans up code so we are not repeating a duplicate loop, by checking both transmit and receive queues in a single loop. Also cleans up flags never used, so remove the definitions. Alex does cleanup so that we are always updating pf->flags when a change is made to the private flags. Adds support for 3K buffers to the receive path so that we can provide the additional padding needed in the event of NET_IP_ALIGN being non-zero or a cache line being greater than 64. Adds support for build_skb() to i40e/i40evf. Maciej adjusts the scope of the rtnl lock held during reset because it was stopping other PFs from running their reset procedures. Alan reduces code complexity in i40e_detect_recover_hung_queue(). The following are changes since commit 3a9024f52c2e92a143195db43d2abbd5d0792c06: net: thunderx: Enable TSO and checksum offloads for ipv6 and are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue 40GbE Alan Brady (1): i40e: Simplify i40e_detect_recover_hung_queue logic Alexander Duyck (4): i40e: Swap use of pf->flags and pf->hw_disabled_flags for ATR Eviction i40e/i40evf: Add support for using order 1 pages with a 3K buffer i40e/i40evf: Add support for padding start of frames i40e/i40evf: Use build_skb to build frames Alice Michael (1): i40e: remove I40E_FLAG_NEED_LINK_UPDATE Jacob Keller (4): i40e: update error message when trying to add invalid filters i40e: allow look-up of MAC address from Open Firmware or IDPROM i40e: remove extraneous loop in i40e_vsi_wait_queues_disabled i40e: clean up historic deprecated flag definitions Maciej Sosin (1): i40e: Decrease the scope of rtnl lock Mitch Williams (1): i40e: only register client on iWarp-capable devices drivers/net/ethernet/intel/i40e/i40e.h | 10 +- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 7 +- drivers/net/ethernet/intel/i40e/i40e_main.c | 268 +--- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 116 +++--- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 85 +++- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 89 ++-- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 82 +++- drivers/net/ethernet/intel/i40evf/i40evf.h | 1 - drivers/net/ethernet/intel/i40evf/i40evf_main.c | 14 +- 9 files changed, 486 insertions(+), 186 deletions(-) -- 2.12.2
[net-next 09/12] i40e: clean up historic deprecated flag definitions
From: Jacob Keller Since an early commit a few flags have no longer been used. Remove these definitions to reduce code clutter. Change-ID: I3589be4622574e747013cd4dc403e18b039f4965 Signed-off-by: Jacob Keller Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index ef64dc60f857..e987503f8517 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -390,11 +390,8 @@ struct i40e_pf { #define I40E_FLAG_RSS_ENABLED BIT_ULL(6) #define I40E_FLAG_VMDQ_ENABLED BIT_ULL(7) #define I40E_FLAG_IWARP_ENABLEDBIT_ULL(10) -#define I40E_FLAG_CLEAN_ADMINQ BIT_ULL(14) #define I40E_FLAG_FILTER_SYNC BIT_ULL(15) #define I40E_FLAG_SERVICE_CLIENT_REQUESTED BIT_ULL(16) -#define I40E_FLAG_PROCESS_MDD_EVENTBIT_ULL(17) -#define I40E_FLAG_PROCESS_VFLR_EVENT BIT_ULL(18) #define I40E_FLAG_SRIOV_ENABLEDBIT_ULL(19) #define I40E_FLAG_DCB_ENABLED BIT_ULL(20) #define I40E_FLAG_FD_SB_ENABLEDBIT_ULL(21) -- 2.12.2
[net-next 10/12] i40e/i40evf: Add support for using order 1 pages with a 3K buffer
From: Alexander Duyck There are situations where adding padding to the front and back of an Rx buffer will require that we add additional padding. Specifically if NET_IP_ALIGN is non-zero, or the MTU size is larger than 7.5K we would need to use 2K buffers which leaves us with no room for the padding. To preemptively address these cases I am adding support for 3K buffers to the Rx path so that we can provide the additional padding needed in the event of NET_IP_ALIGN being non-zero or a cache line being greater than 64. Change-ID: I938bc1ba611285428df39a613cd66f98e60b55c7 Signed-off-by: Alexander Duyck Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 3 ++- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 27 + drivers/net/ethernet/intel/i40e/i40e_txrx.h | 12 +++ drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 27 + drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 12 +++ drivers/net/ethernet/intel/i40evf/i40evf_main.c | 6 ++ 6 files changed, 60 insertions(+), 27 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 3b1dab7a7cc9..97489d69029a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3085,7 +3085,8 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi) #endif } else { vsi->max_frame = I40E_MAX_RXBUFFER; - vsi->rx_buf_len = I40E_RXBUFFER_2048; + vsi->rx_buf_len = (PAGE_SIZE < 8192) ? I40E_RXBUFFER_3072 : + I40E_RXBUFFER_2048; } /* set up individual rings */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index e95428c7aba0..bee16726c104 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1138,14 +1138,15 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring) dma_sync_single_range_for_cpu(rx_ring->dev, rx_bi->dma, rx_bi->page_offset, - I40E_RXBUFFER_2048, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); /* free resources associated with mapping */ dma_unmap_page_attrs(rx_ring->dev, rx_bi->dma, -PAGE_SIZE, +i40e_rx_pg_size(rx_ring), DMA_FROM_DEVICE, I40E_RX_DMA_ATTR); + __page_frag_cache_drain(rx_bi->page, rx_bi->pagecnt_bias); rx_bi->page = NULL; @@ -1267,7 +1268,7 @@ static bool i40e_alloc_mapped_page(struct i40e_ring *rx_ring, } /* alloc new page for storage */ - page = dev_alloc_page(); + page = dev_alloc_pages(i40e_rx_pg_order(rx_ring)); if (unlikely(!page)) { rx_ring->rx_stats.alloc_page_failed++; return false; @@ -1275,7 +1276,7 @@ static bool i40e_alloc_mapped_page(struct i40e_ring *rx_ring, /* map page for use */ dma = dma_map_page_attrs(rx_ring->dev, page, 0, -PAGE_SIZE, +i40e_rx_pg_size(rx_ring), DMA_FROM_DEVICE, I40E_RX_DMA_ATTR); @@ -1283,7 +1284,7 @@ static bool i40e_alloc_mapped_page(struct i40e_ring *rx_ring, * there isn't much point in holding memory we can't use */ if (dma_mapping_error(rx_ring->dev, dma)) { - __free_pages(page, 0); + __free_pages(page, i40e_rx_pg_order(rx_ring)); rx_ring->rx_stats.alloc_page_failed++; return false; } @@ -1343,7 +1344,7 @@ bool i40e_alloc_rx_buffers(struct i40e_ring *rx_ring, u16 cleaned_count) /* sync the buffer for use by the device */ dma_sync_single_range_for_device(rx_ring->dev, bi->dma, bi->page_offset, -I40E_RXBUFFER_2048, +rx_ring->rx_buf_len, DMA_FROM_DEVICE); /* Refresh the desc even if buffer_addrs didn't change @@ -1645,9 +1646,6 @@ static inline bool i40e_page_is_reusable(struct page *page) **/ static bool i40e_can_reuse_rx_page(struct i40e_rx_buffer *rx_buffer) { -#if (PAGE_SIZE >= 8192) - unsigned int last_offset = PAGE_SIZE - I40E_RXBUFFER_2048; -#endif unsigned int pagecnt_bias = rx_buffer->pagecnt_bias; stru
[net-next 11/12] i40e/i40evf: Add support for padding start of frames
From: Alexander Duyck This patch adds padding to the start of frames to make room for headroom for us to eventually start using build_skb. Right now we guarantee at least NET_SKB_PAD + NET_IP_ALIGN, however we allocate more space if more is available. For example on x86 the headroom should be 192 bytes. On systems that have too large of a cache line size to support storing 1.5K padding and shared info we default to using 3K buffers and reserve everything that isn't used for skb_shared_info or the data buffer for headroom. Change-ID: I33c641c9a1ea10cf7cc484c2d20985368d2d709a Signed-off-by: Alexander Duyck Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 9 +++- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 15 +- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 70 - drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 15 +- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 70 - drivers/net/ethernet/intel/i40evf/i40evf_main.c | 8 ++- 6 files changed, 179 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 97489d69029a..b6ec9beeebff 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3038,6 +3038,12 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) return -ENOMEM; } + /* configure Rx buffer alignment */ + if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) + clear_ring_build_skb_enabled(ring); + else + set_ring_build_skb_enabled(ring); + /* cache tail for quicker writes, and clear the reg before use */ ring->tail = hw->hw_addr + I40E_QRX_TAIL(pf_q); writel(0, ring->tail); @@ -3079,7 +3085,8 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi) vsi->max_frame = I40E_MAX_RXBUFFER; vsi->rx_buf_len = I40E_RXBUFFER_2048; #if (PAGE_SIZE < 8192) - } else if (vsi->netdev->mtu <= ETH_DATA_LEN) { + } else if (!I40E_2K_TOO_SMALL_WITH_PADDING && + (vsi->netdev->mtu <= ETH_DATA_LEN)) { vsi->max_frame = I40E_RXBUFFER_1536 - NET_IP_ALIGN; vsi->rx_buf_len = I40E_RXBUFFER_1536 - NET_IP_ALIGN; #endif diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index bee16726c104..f15e1bcf3555 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1248,6 +1248,17 @@ static inline void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val) } /** + * i40e_rx_offset - Return expected offset into page to access data + * @rx_ring: Ring we are requesting offset of + * + * Returns the offset value for ring into the data buffer. + */ +static inline unsigned int i40e_rx_offset(struct i40e_ring *rx_ring) +{ + return ring_uses_build_skb(rx_ring) ? I40E_SKB_PAD : 0; +} + +/** * i40e_alloc_mapped_page - recycle or make a new page * @rx_ring: ring to use * @bi: rx_buffer struct to modify @@ -1291,7 +1302,7 @@ static bool i40e_alloc_mapped_page(struct i40e_ring *rx_ring, bi->dma = dma; bi->page = page; - bi->page_offset = 0; + bi->page_offset = i40e_rx_offset(rx_ring); /* initialize pagecnt_bias to 1 representing we fully own page */ bi->pagecnt_bias = 1; @@ -1696,7 +1707,7 @@ static void i40e_add_rx_frag(struct i40e_ring *rx_ring, #if (PAGE_SIZE < 8192) unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2; #else - unsigned int truesize = SKB_DATA_ALIGN(size); + unsigned int truesize = SKB_DATA_ALIGN(size + i40e_rx_offset(rx_ring)); #endif skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page, diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index 2f618539a436..f5de51124cae 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -135,6 +135,58 @@ enum i40e_dyn_idx_t { #define I40E_RX_DMA_ATTR \ (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING) +/* Attempt to maximize the headroom available for incoming frames. We + * use a 2K buffer for receives and need 1536/1534 to store the data for + * the frame. This leaves us with 512 bytes of room. From that we need + * to deduct the space needed for the shared info and the padding needed + * to IP align the frame. + * + * Note: For cache line sizes 256 or larger this value is going to end + * up negative. In these cases we should fall back to the legacy + * receive path. + */ +#if (PAGE_SIZE < 8192) +#define I40E_2K_TOO_SMALL_WITH_PADDING \ +((NET_SKB_PAD + I40E_RXBUFFER_1536) > SKB_WITH_OVERHEAD(I40E_RXBUFFER_2048)) + +static inline int i40e_compute_pad(int rx_buf_len) +{ +
[net-next 08/12] i40e: remove I40E_FLAG_NEED_LINK_UPDATE
From: Alice Michael The I40E_FLAG_NEED_LINK_UPDATE was never used. Remove the flag definitions. Change-ID: If59d0c6b4af85ca27281f3183c54b055adb439a4 Signed-off-by: Jacob Keller Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e.h | 1 - drivers/net/ethernet/intel/i40e/i40e_main.c | 1 - drivers/net/ethernet/intel/i40evf/i40evf.h | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 110ef4204306..ef64dc60f857 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -389,7 +389,6 @@ struct i40e_pf { #define I40E_FLAG_MSIX_ENABLED BIT_ULL(3) #define I40E_FLAG_RSS_ENABLED BIT_ULL(6) #define I40E_FLAG_VMDQ_ENABLED BIT_ULL(7) -#define I40E_FLAG_NEED_LINK_UPDATE BIT_ULL(9) #define I40E_FLAG_IWARP_ENABLEDBIT_ULL(10) #define I40E_FLAG_CLEAN_ADMINQ BIT_ULL(14) #define I40E_FLAG_FILTER_SYNC BIT_ULL(15) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 0e1240b704ef..3b1dab7a7cc9 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -11091,7 +11091,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) INIT_WORK(&pf->service_task, i40e_service_task); clear_bit(__I40E_SERVICE_SCHED, &pf->state); - pf->flags |= I40E_FLAG_NEED_LINK_UPDATE; /* NVM bit on means WoL disabled for the port */ i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits); diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h index d61ecf655091..35ded19e9cc2 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf.h +++ b/drivers/net/ethernet/intel/i40evf/i40evf.h @@ -205,7 +205,6 @@ struct i40evf_adapter { #define I40EVF_FLAG_IN_NETPOLL BIT(4) #define I40EVF_FLAG_IMIR_ENABLED BIT(5) #define I40EVF_FLAG_MQ_CAPABLE BIT(6) -#define I40EVF_FLAG_NEED_LINK_UPDATE BIT(7) #define I40EVF_FLAG_PF_COMMS_FAILEDBIT(8) #define I40EVF_FLAG_RESET_PENDING BIT(9) #define I40EVF_FLAG_RESET_NEEDED BIT(10) -- 2.12.2
[net-next 12/12] i40e/i40evf: Use build_skb to build frames
From: Alexander Duyck This patch is meant to improve the performance of the Rx path. Specifically by using build_skb we have several distinct advantages. In the case of small frames we were previously using a copy-break approach. This means that we were allocating a page fragment to use for skb->head, and were having to copy the packet into that region. Both of those calls are now avoided since we just build the skb around the data. In the case of large frames the gains are much more significant. Specifically we were having to allocate skb->head, and copy the headers as before. However in addition we were having to parse the header using eth_get_headlen which could be quite expensive. All of this is avoided by building the frame around the data. I have seen gains as high as 30% when using VXLAN for instance due to just header pulling overhead. Finally with all this in place it also sets us up to start looking at enabling XDP. Specifically we now have a path in which the data is in the page and the frame is built around it. So if we parse it with XDP before we call build_skb we can take care of any necessary processing there. Change-ID: Id4bdd618e94473d41f892417e5d8019639e421e3 Signed-off-by: Alexander Duyck Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 47 +++ drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 47 +++ 2 files changed, 94 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index f15e1bcf3555..20691d2bf113 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1816,6 +1816,51 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring, } /** + * i40e_build_skb - Build skb around an existing buffer + * @rx_ring: Rx descriptor ring to transact packets on + * @rx_buffer: Rx buffer to pull data from + * @size: size of buffer to add to skb + * + * This function builds an skb around an existing Rx buffer, taking care + * to set up the skb correctly and avoid any memcpy overhead. + */ +static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring, + struct i40e_rx_buffer *rx_buffer, + unsigned int size) +{ + void *va = page_address(rx_buffer->page) + rx_buffer->page_offset; +#if (PAGE_SIZE < 8192) + unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2; +#else + unsigned int truesize = SKB_DATA_ALIGN(size); +#endif + struct sk_buff *skb; + + /* prefetch first cache line of first page */ + prefetch(va); +#if L1_CACHE_BYTES < 128 + prefetch(va + L1_CACHE_BYTES); +#endif + /* build an skb around the page buffer */ + skb = build_skb(va - I40E_SKB_PAD, truesize); + if (unlikely(!skb)) + return NULL; + + /* update pointers within the skb to store the data */ + skb_reserve(skb, I40E_SKB_PAD); + __skb_put(skb, size); + + /* buffer is used by skb, update page_offset */ +#if (PAGE_SIZE < 8192) + rx_buffer->page_offset ^= truesize; +#else + rx_buffer->page_offset += truesize; +#endif + + return skb; +} + +/** * i40e_put_rx_buffer - Clean up used buffer and either recycle or free * @rx_ring: rx descriptor ring to transact packets on * @rx_buffer: rx buffer to pull data from @@ -1939,6 +1984,8 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) /* retrieve a buffer from the ring */ if (skb) i40e_add_rx_frag(rx_ring, rx_buffer, skb, size); + else if (ring_uses_build_skb(rx_ring)) + skb = i40e_build_skb(rx_ring, rx_buffer, size); else skb = i40e_construct_skb(rx_ring, rx_buffer, size); diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index a71f81a9291f..460171edc412 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c @@ -1177,6 +1177,51 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring, } /** + * i40e_build_skb - Build skb around an existing buffer + * @rx_ring: Rx descriptor ring to transact packets on + * @rx_buffer: Rx buffer to pull data from + * @size: size of buffer to add to skb + * + * This function builds an skb around an existing Rx buffer, taking care + * to set up the skb correctly and avoid any memcpy overhead. + */ +static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring, + struct i40e_rx_buffer *rx_buffer, + unsigned int size) +{ + void *va = page_address(rx_buffer->page) + rx_buffer->page_offset; +#if (PAGE_SIZE < 8192) + unsigned int truesize = i40e_rx_pg_size(rx_ring)
Re: [regression v4.11] 617f01211baf ("8139too: use napi_complete_done()")
David Miller : [...] > One theory is that the interrupt masking isn't working properly > and interrupts are still arriving and hitting the NAPI state even > when we are actively polling NAPI. > > And this problem was masked by the locking done here. Yes. Ville, can you rule out irq sharing between the 8139 and some other device ? It's a candidate for unexpected interrupt handler invocation with older pc, even with properly working hardware. -- Ueimor
[PATCH net v2 1/2] bridge: implement missing ndo_uninit()
From: Ido Schimmel While the bridge driver implements an ndo_init(), it was missing a symmetric ndo_uninit(), causing the different de-initialization operations to be scattered around its dellink() and destructor(). Implement a symmetric ndo_uninit() and remove the overlapping operations from its dellink() and destructor(). This is a prerequisite for the next patch, as it allows us to have a proper cleanup upon changelink() failure during the bridge's newlink(). Fixes: b6677449dff6 ("bridge: netlink: call br_changelink() during br_dev_newlink()") Signed-off-by: Nikolay Aleksandrov Signed-off-by: Ido Schimmel --- net/bridge/br_device.c| 13 ++--- net/bridge/br_if.c| 1 - net/bridge/br_multicast.c | 7 +-- net/bridge/br_private.h | 5 + 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index ea71513..607210f 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -119,6 +119,15 @@ static int br_dev_init(struct net_device *dev) return err; } +static void br_dev_uninit(struct net_device *dev) +{ + struct net_bridge *br = netdev_priv(dev); + + br_multicast_uninit_stats(br); + br_vlan_flush(br); + free_percpu(br->stats); +} + static int br_dev_open(struct net_device *dev) { struct net_bridge *br = netdev_priv(dev); @@ -332,6 +341,7 @@ static const struct net_device_ops br_netdev_ops = { .ndo_open= br_dev_open, .ndo_stop= br_dev_stop, .ndo_init= br_dev_init, + .ndo_uninit = br_dev_uninit, .ndo_start_xmit = br_dev_xmit, .ndo_get_stats64 = br_get_stats64, .ndo_set_mac_address = br_set_mac_address, @@ -358,9 +368,6 @@ static const struct net_device_ops br_netdev_ops = { static void br_dev_free(struct net_device *dev) { - struct net_bridge *br = netdev_priv(dev); - - free_percpu(br->stats); free_netdev(dev); } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 8ac1770..56a2a72 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -311,7 +311,6 @@ void br_dev_delete(struct net_device *dev, struct list_head *head) br_fdb_delete_by_port(br, NULL, 0, 1); - br_vlan_flush(br); br_multicast_dev_del(br); cancel_delayed_work_sync(&br->gc_work); diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index b760f26..faa7261 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -2031,8 +2031,6 @@ void br_multicast_dev_del(struct net_bridge *br) out: spin_unlock_bh(&br->multicast_lock); - - free_percpu(br->mcast_stats); } int br_multicast_set_router(struct net_bridge *br, unsigned long val) @@ -2531,6 +2529,11 @@ int br_multicast_init_stats(struct net_bridge *br) return 0; } +void br_multicast_uninit_stats(struct net_bridge *br) +{ + free_percpu(br->mcast_stats); +} + static void mcast_stats_add_dir(u64 *dst, u64 *src) { dst[BR_MCAST_DIR_RX] += src[BR_MCAST_DIR_RX]; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 6136818..0d17728 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -620,6 +620,7 @@ void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, void br_multicast_count(struct net_bridge *br, const struct net_bridge_port *p, const struct sk_buff *skb, u8 type, u8 dir); int br_multicast_init_stats(struct net_bridge *br); +void br_multicast_uninit_stats(struct net_bridge *br); void br_multicast_get_stats(const struct net_bridge *br, const struct net_bridge_port *p, struct br_mcast_stats *dest); @@ -760,6 +761,10 @@ static inline int br_multicast_init_stats(struct net_bridge *br) return 0; } +static inline void br_multicast_uninit_stats(struct net_bridge *br) +{ +} + static inline int br_multicast_igmp_type(const struct sk_buff *skb) { return 0; -- 2.9.3
[PATCH net v2 2/2] bridge: netlink: register netdevice before executing changelink
From: Ido Schimmel Peter reported a kernel oops when executing the following command: $ ip link add name test type bridge vlan_default_pvid 1 [13634.939408] BUG: unable to handle kernel NULL pointer dereference at 0190 [13634.939436] IP: __vlan_add+0x73/0x5f0 [...] [13634.939783] Call Trace: [13634.939791] ? pcpu_next_unpop+0x3b/0x50 [13634.939801] ? pcpu_alloc+0x3d2/0x680 [13634.939810] ? br_vlan_add+0x135/0x1b0 [13634.939820] ? __br_vlan_set_default_pvid.part.28+0x204/0x2b0 [13634.939834] ? br_changelink+0x120/0x4e0 [13634.939844] ? br_dev_newlink+0x50/0x70 [13634.939854] ? rtnl_newlink+0x5f5/0x8a0 [13634.939864] ? rtnl_newlink+0x176/0x8a0 [13634.939874] ? mem_cgroup_commit_charge+0x7c/0x4e0 [13634.939886] ? rtnetlink_rcv_msg+0xe1/0x220 [13634.939896] ? lookup_fast+0x52/0x370 [13634.939905] ? rtnl_newlink+0x8a0/0x8a0 [13634.939915] ? netlink_rcv_skb+0xa1/0xc0 [13634.939925] ? rtnetlink_rcv+0x24/0x30 [13634.939934] ? netlink_unicast+0x177/0x220 [13634.939944] ? netlink_sendmsg+0x2fe/0x3b0 [13634.939954] ? _copy_from_user+0x39/0x40 [13634.939964] ? sock_sendmsg+0x30/0x40 [13634.940159] ? ___sys_sendmsg+0x29d/0x2b0 [13634.940326] ? __alloc_pages_nodemask+0xdf/0x230 [13634.940478] ? mem_cgroup_commit_charge+0x7c/0x4e0 [13634.940592] ? mem_cgroup_try_charge+0x76/0x1a0 [13634.940701] ? __handle_mm_fault+0xdb9/0x10b0 [13634.940809] ? __sys_sendmsg+0x51/0x90 [13634.940917] ? entry_SYSCALL_64_fastpath+0x1e/0xad The problem is that the bridge's VLAN group is created after setting the default PVID, when registering the netdevice and executing its ndo_init(). Fix this by changing the order of both operations, so that br_changelink() is only processed after the netdevice is registered, when the VLAN group is already initialized. Fixes: b6677449dff6 ("bridge: netlink: call br_changelink() during br_dev_newlink()") Signed-off-by: Nikolay Aleksandrov Signed-off-by: Ido Schimmel Reported-by: Peter V. Saveliev --- net/bridge/br_netlink.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index a8f6acd..c38104e 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -1165,11 +1165,19 @@ static int br_dev_newlink(struct net *src_net, struct net_device *dev, spin_unlock_bh(&br->lock); } - err = br_changelink(dev, tb, data); + err = register_netdevice(dev); if (err) return err; - return register_netdevice(dev); + err = br_changelink(dev, tb, data); + if (err) + goto unregister; + + return 0; + +unregister: + unregister_netdevice(dev); + return err; } static size_t br_get_size(const struct net_device *brdev) -- 2.9.3
[PATCH net v2 0/2] bridge: Fix kernel oops during bridge creation
From: Ido Schimmel First patch adds a missing ndo_uninit() in the bridge driver, which is a prerequisite for the second patch that actually fixes the oops. First version was rejected for being "half baked", but given the amount of changes in this version and that three stable kernels need to be patched, a better approach might be to simply revert the patch in the Fixes line and have this patchset go through net-next. Ido Schimmel (2): bridge: implement missing ndo_uninit() bridge: netlink: register netdevice before executing changelink net/bridge/br_device.c| 13 ++--- net/bridge/br_if.c| 1 - net/bridge/br_multicast.c | 7 +-- net/bridge/br_netlink.c | 12 ++-- net/bridge/br_private.h | 5 + 5 files changed, 30 insertions(+), 8 deletions(-) -- 2.9.3
Re: [PATCH 06/12] audit: Use timespec64 to represent audit timestamps
On Fri, Apr 7, 2017 at 8:57 PM, Deepa Dinamani wrote: > struct timespec is not y2038 safe. > Audit timestamps are recorded in string format into > an audit buffer for a given context. > These mark the entry timestamps for the syscalls. > Use y2038 safe struct timespec64 to represent the times. > The log strings can handle this transition as strings can > hold upto 1024 characters. > > Signed-off-by: Deepa Dinamani > Reviewed-by: Arnd Bergmann > Acked-by: Paul Moore > Acked-by: Richard Guy Briggs > --- > include/linux/audit.h | 4 ++-- > kernel/audit.c| 10 +- > kernel/audit.h| 2 +- > kernel/auditsc.c | 6 +++--- > 4 files changed, 11 insertions(+), 11 deletions(-) I have no problem merging this patch into audit/next for v4.12, would you prefer me to do that so at least this patch is merged? It would probably make life a small bit easier for us in the audit world too as it would reduce the potential merge conflict. However, that's a relatively small thing to worry about. > diff --git a/include/linux/audit.h b/include/linux/audit.h > index 6fdfefc..f830508 100644 > --- a/include/linux/audit.h > +++ b/include/linux/audit.h > @@ -332,7 +332,7 @@ static inline void audit_ptrace(struct task_struct *t) > /* Private API (for audit.c only) */ > extern unsigned int audit_serial(void); > extern int auditsc_get_stamp(struct audit_context *ctx, > - struct timespec *t, unsigned int *serial); > + struct timespec64 *t, unsigned int *serial); > extern int audit_set_loginuid(kuid_t loginuid); > > static inline kuid_t audit_get_loginuid(struct task_struct *tsk) > @@ -511,7 +511,7 @@ static inline void __audit_seccomp(unsigned long syscall, > long signr, int code) > static inline void audit_seccomp(unsigned long syscall, long signr, int code) > { } > static inline int auditsc_get_stamp(struct audit_context *ctx, > - struct timespec *t, unsigned int *serial) > + struct timespec64 *t, unsigned int *serial) > { > return 0; > } > diff --git a/kernel/audit.c b/kernel/audit.c > index 2f4964c..fcbf377 100644 > --- a/kernel/audit.c > +++ b/kernel/audit.c > @@ -1625,10 +1625,10 @@ unsigned int audit_serial(void) > } > > static inline void audit_get_stamp(struct audit_context *ctx, > - struct timespec *t, unsigned int *serial) > + struct timespec64 *t, unsigned int *serial) > { > if (!ctx || !auditsc_get_stamp(ctx, t, serial)) { > - *t = CURRENT_TIME; > + ktime_get_real_ts64(t); > *serial = audit_serial(); > } > } > @@ -1652,7 +1652,7 @@ struct audit_buffer *audit_log_start(struct > audit_context *ctx, gfp_t gfp_mask, > int type) > { > struct audit_buffer *ab; > - struct timespec t; > + struct timespec64 t; > unsigned int uninitialized_var(serial); > > if (audit_initialized != AUDIT_INITIALIZED) > @@ -1705,8 +1705,8 @@ struct audit_buffer *audit_log_start(struct > audit_context *ctx, gfp_t gfp_mask, > } > > audit_get_stamp(ab->ctx, &t, &serial); > - audit_log_format(ab, "audit(%lu.%03lu:%u): ", > -t.tv_sec, t.tv_nsec/100, serial); > + audit_log_format(ab, "audit(%llu.%03lu:%u): ", > +(unsigned long long)t.tv_sec, t.tv_nsec/100, > serial); > > return ab; > } > diff --git a/kernel/audit.h b/kernel/audit.h > index 0f1cf6d..cdf96f4 100644 > --- a/kernel/audit.h > +++ b/kernel/audit.h > @@ -112,7 +112,7 @@ struct audit_context { > enum audit_statestate, current_state; > unsigned intserial; /* serial number for record */ > int major; /* syscall number */ > - struct timespec ctime; /* time of syscall entry */ > + struct timespec64 ctime; /* time of syscall entry */ > unsigned long argv[4];/* syscall arguments */ > longreturn_code;/* syscall return code */ > u64 prio; > diff --git a/kernel/auditsc.c b/kernel/auditsc.c > index e59ffc7..a2d9217 100644 > --- a/kernel/auditsc.c > +++ b/kernel/auditsc.c > @@ -1532,7 +1532,7 @@ void __audit_syscall_entry(int major, unsigned long a1, > unsigned long a2, > return; > > context->serial = 0; > - context->ctime = CURRENT_TIME; > + ktime_get_real_ts64(&context->ctime); > context->in_syscall = 1; > context->current_state = state; > context->ppid = 0; > @@ -1941,13 +1941,13 @@ EXPORT_SYMBOL_GPL(__audit_inode_child); > /** > * auditsc_get_stamp - get local copies of audit_context values > * @ctx: audit_context for the task > - * @t: timespec to store time recorded in the audit_cont
Re: [PATCH] net: mvpp2: sleeping function called from invalid context
Hello, Thanks for your patch! However, it is badly line wrapped, you should consider sending your patch with "git send-email". On Sat, 8 Apr 2017 15:07:14 +0200, Gerald Guillaume wrote: > --- linux-3.18/drivers/net/ethernet/marvell/mvpp2.c 2017-04-03 > 10:29:31.863264347 +0200 > +++ linux-3.x/drivers/net/ethernet/marvell/mvpp2.c 2017-04-03 > 10:45:23.008339453 +0200 > @@ -2997,7 +2997,7 @@ > struct mvpp2_prs_entry *pe; > int tid; > > - pe = kzalloc(sizeof(*pe), GFP_KERNEL); > + pe = kzalloc(sizeof(*pe), GFP_ATOMIC); > if (!pe) > return NULL; > mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC); > @@ -3059,7 +3059,7 @@ > if (tid < 0) > return tid; > > - pe = kzalloc(sizeof(*pe), GFP_KERNEL); > + pe = kzalloc(sizeof(*pe), GFP_ATOMIC); > if (!pe) > return -1; > mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_MAC); I am wondering if doing a GFP_ATOMIC allocation for this is the right solution. Should it be pre-allocated instead? I would have to look at how other drivers typically do this. Perhaps allocating on the stack is reasonable? After all, sizeof(struct mvpp2_prs_entry) is only: 4 + 6 * 4 + 4 * 4 = 44 bytes. It's allocated at the beginning of the function, and freed at the end, so it really calls for a local variable. Anyway, I think it's worth investigating a different solution than blindly converting to a GFP_ATOMIC allocation. Best regards, Thomas -- Thomas Petazzoni, CTO, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com
Re: [pull request][net-next 0/7] Mellanox mlx5 updates 2017-04-16
From: Saeed Mahameed Date: Fri, 7 Apr 2017 21:26:49 +0300 > The following changes provide some small features and updates to the mlx5 > driver. > > For more information please see below. > > Please pull and let me know if there's any problem. Pulled, thanks.
Re: [PATCH net v2 1/2] bridge: implement missing ndo_uninit()
On Sat, 8 Apr 2017 14:41:58 +0300 wrote: > static void br_dev_free(struct net_device *dev) > { > - struct net_bridge *br = netdev_priv(dev); > - > - free_percpu(br->stats); > free_netdev(dev); > } > Since the only thing left is free_netdev, you can now just set dev->destructor to be free_netdev.
Re: [PATCH net v2 2/2] bridge: netlink: register netdevice before executing changelink
On Sat, 8 Apr 2017 14:41:59 +0300 wrote: > + err = br_changelink(dev, tb, data); > + if (err) > + goto unregister; > + > + return 0; > + > +unregister: > + unregister_netdevice(dev); > + return err; > } Why use a goto? just do: err = br_changelink(dev, tb, data); if (err) unregister_netdevice(dev) return err; } The goto looks ugly
Re: [PATCH net v2 1/2] bridge: implement missing ndo_uninit()
On Sat, Apr 08, 2017 at 09:30:42AM -0400, Stephen Hemminger wrote: > On Sat, 8 Apr 2017 14:41:58 +0300 > wrote: > > > static void br_dev_free(struct net_device *dev) > > { > > - struct net_bridge *br = netdev_priv(dev); > > - > > - free_percpu(br->stats); > > free_netdev(dev); > > } > > > > Since the only thing left is free_netdev, you can now just set dev->destructor > to be free_netdev. Fine. Beside stylistic issues, I would appreciate comments on how this should be handled. Are we reverting the patch in the Fixes line or applying this patchset? I prefer the first option. Then after net is merged into net-next I can re-post this patchset with the requested changes.
Re: [PATCH] net: davinci_mdio: add GPIO reset logic
From: Roger Quadros Date: Wed, 5 Apr 2017 11:33:57 +0300 > Some boards [1] leave the PHYs at an invalid state > during system power-up or reset thus causing unreliability > issues with the PHY like not being detected by the mdio bus > or link not functional. To work around these boards have > a GPIO connected to the PHY's reset pin. > > Implement GPIO reset handling for such cases. > > [1] - am572x-idk, am571x-idk, a437x-idk. > > Signed-off-by: Roger Quadros > Signed-off-by: Sekhar Nori I have not seen a resolution in this discussion. My understanding is that there are several cases (single MDIO bus whose reset does a reset on all that MDIO bus's PHYs, etc.) and it's unclear how to handle all such cases cleanly.
Re: [PATCH net v2 1/2] bridge: implement missing ndo_uninit()
On 08/04/17 16:49, Ido Schimmel wrote: > On Sat, Apr 08, 2017 at 09:30:42AM -0400, Stephen Hemminger wrote: >> On Sat, 8 Apr 2017 14:41:58 +0300 >> wrote: >> >>> static void br_dev_free(struct net_device *dev) >>> { >>> - struct net_bridge *br = netdev_priv(dev); >>> - >>> - free_percpu(br->stats); >>> free_netdev(dev); >>> } >>> >> >> Since the only thing left is free_netdev, you can now just set >> dev->destructor >> to be free_netdev. > > Fine. > > Beside stylistic issues, I would appreciate comments on how this should > be handled. Are we reverting the patch in the Fixes line or applying > this patchset? > > I prefer the first option. Then after net is merged into net-next I can > re-post this patchset with the requested changes. > +1
Re: [PATCH net v2 1/2] bridge: implement missing ndo_uninit()
On Sat, 8 Apr 2017 17:05:48 +0300 Nikolay Aleksandrov wrote: > On 08/04/17 16:49, Ido Schimmel wrote: > > On Sat, Apr 08, 2017 at 09:30:42AM -0400, Stephen Hemminger wrote: > >> On Sat, 8 Apr 2017 14:41:58 +0300 > >> wrote: > >> > >>> static void br_dev_free(struct net_device *dev) > >>> { > >>> - struct net_bridge *br = netdev_priv(dev); > >>> - > >>> - free_percpu(br->stats); > >>> free_netdev(dev); > >>> } > >>> > >> > >> Since the only thing left is free_netdev, you can now just set > >> dev->destructor > >> to be free_netdev. > > > > Fine. > > > > Beside stylistic issues, I would appreciate comments on how this should > > be handled. Are we reverting the patch in the Fixes line or applying > > this patchset? > > > > I prefer the first option. Then after net is merged into net-next I can > > re-post this patchset with the requested changes. > > > > +1 > > If this fixes the issue, then the one fix should go to stable, net and net-next. There is no good reason to have two versions.
Re: [PATCH net v2 1/2] bridge: implement missing ndo_uninit()
2017-04-08 16:14 GMT+02:00 Stephen Hemminger : > On Sat, 8 Apr 2017 17:05:48 +0300 > Nikolay Aleksandrov wrote: > >> On 08/04/17 16:49, Ido Schimmel wrote: >> > On Sat, Apr 08, 2017 at 09:30:42AM -0400, Stephen Hemminger wrote: >> >> On Sat, 8 Apr 2017 14:41:58 +0300 >> >> wrote: >> >> >> >>> static void br_dev_free(struct net_device *dev) >> >>> { >> >>> - struct net_bridge *br = netdev_priv(dev); >> >>> - >> >>> - free_percpu(br->stats); >> >>> free_netdev(dev); >> >>> } >> >>> >> >> >> >> Since the only thing left is free_netdev, you can now just set >> >> dev->destructor >> >> to be free_netdev. >> > >> > Fine. >> > >> > Beside stylistic issues, I would appreciate comments on how this should >> > be handled. Are we reverting the patch in the Fixes line or applying >> > this patchset? >> > >> > I prefer the first option. Then after net is merged into net-next I can >> > re-post this patchset with the requested changes. >> > >> >> +1 >> >> > > If this fixes the issue, then the one fix should go to stable, net and > net-next. > There is no good reason to have two versions. > +1
[PATCH net] tcp: clear saved_syn in tcp_disconnect()
From: Eric Dumazet In the (very unlikely) case a passive socket becomes a listener, we do not want to duplicate its saved SYN headers. This would lead to double frees, use after free, and please hackers and various fuzzers Tested: 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, IPPROTO_TCP, TCP_SAVE_SYN, [1], 4) = 0 +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 +0 bind(3, ..., ...) = 0 +0 listen(3, 5) = 0 +0 < S 0:0(0) win 32972 +0 > S. 0:0(0) ack 1 <...> +.1 < . 1:1(0) ack 1 win 257 +0 accept(3, ..., ...) = 4 +0 connect(4, AF_UNSPEC, ...) = 0 +0 close(3) = 0 +0 bind(4, ..., ...) = 0 +0 listen(4, 5) = 0 +0 < S 0:0(0) win 32972 +0 > S. 0:0(0) ack 1 <...> +.1 < . 1:1(0) ack 1 win 257 Fixes: cd8ae85299d5 ("tcp: provide SYN headers for passive connections") Signed-off-by: Eric Dumazet --- net/ipv4/tcp.c |1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 94f0b5b50e0d728c3edab175aee9d769cd80907f..04843ae77b9ecacb3e4f2e81096f11d35ae1915e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2322,6 +2322,7 @@ int tcp_disconnect(struct sock *sk, int flags) tcp_init_send_head(sk); memset(&tp->rx_opt, 0, sizeof(tp->rx_opt)); __sk_dst_reset(sk); + tcp_saved_syn_free(tp); /* Clean up fastopen related fields */ tcp_free_fastopen_req(tp);
Re: [PATCH net-next 0/2] New getsockopt option to retrieve socket cookie
From: Chenbo Feng Date: Wed, 5 Apr 2017 19:00:54 -0700 > In the current kernel socket cookie implementation, there is no simple > and direct way to retrieve the socket cookie based on file descriptor. A > process mat need to get it from sock fd if it want to correlate with > sock_diag output or use a bpf map with new socket cookie function. > > If userspace wants to receive the socket cookie for a given socket fd, > it must send a SOCK_DIAG_BY_FAMILY dump request and look for the 5-tuple. > This is slow and can be ambiguous in the case of sockets that have the > same 5-tuple (e.g., tproxy / transparent sockets, SO_REUSEPORT sockets, > etc.). > > As shown in the example program. The xt_eBPF program is using socket cookie > to record the network traffics statistics and with the socket cookie > retrieved by getsockopt. The program can directly access to a specific > socket data without scanning the whole bpf map. Series applied, thank you.
Re: [PATCH] net: davinci_mdio: add GPIO reset logic
On Sat, Apr 08, 2017 at 06:55:45AM -0700, David Miller wrote: > From: Roger Quadros > Date: Wed, 5 Apr 2017 11:33:57 +0300 > > > Some boards [1] leave the PHYs at an invalid state > > during system power-up or reset thus causing unreliability > > issues with the PHY like not being detected by the mdio bus > > or link not functional. To work around these boards have > > a GPIO connected to the PHY's reset pin. > > > > Implement GPIO reset handling for such cases. > > > > [1] - am572x-idk, am571x-idk, a437x-idk. > > > > Signed-off-by: Roger Quadros > > Signed-off-by: Sekhar Nori > > I have not seen a resolution in this discussion. > > My understanding is that there are several cases (single MDIO bus whose > reset does a reset on all that MDIO bus's PHYs, etc.) and it's unclear > how to handle all such cases cleanly. I see it falling into two cases. 1) We have a GPIO which resets one PHY. In this case, the GPIO is a PHY property, it should be documented in Documentation/devicetree/bindings/net/phy.txt. Hopefully there is nothing PHY driver specific here, so all the handling can be placed in the core PHY code. 2) We have one or more GPIOs which reset more than one PHY. In this case, the GPIOs are MDIO bus properties. Again, there should not be anything which is MDIO bus driver specific, so all the handling can be placed in the core MDIO bus code. Andrew
Re: [PATCH][-next] nfp: don't dereference a null nn->eth_port to print a warning
From: Colin King Date: Thu, 6 Apr 2017 13:54:35 +0100 > From: Colin Ian King > > On the case where nn->eth_port is null the warning message > is printing the port by dereferencing this null pointer. > Remove the deference to avoid a crash when printing the > warning message. > > Detected by CoverityScan, CID#1426198 ("Dereference after null check") > > Fixes: ce22f5a2cbe3c627 ("nfp: separate high level and low level NSP headers") > Signed-off-by: Colin Ian King Applied, thanks.
Re: [PATCH] net: davinci_mdio: add GPIO reset logic
On 04/08/2017 08:10 AM, Andrew Lunn wrote: > On Sat, Apr 08, 2017 at 06:55:45AM -0700, David Miller wrote: >> From: Roger Quadros >> Date: Wed, 5 Apr 2017 11:33:57 +0300 >> >>> Some boards [1] leave the PHYs at an invalid state >>> during system power-up or reset thus causing unreliability >>> issues with the PHY like not being detected by the mdio bus >>> or link not functional. To work around these boards have >>> a GPIO connected to the PHY's reset pin. >>> >>> Implement GPIO reset handling for such cases. >>> >>> [1] - am572x-idk, am571x-idk, a437x-idk. >>> >>> Signed-off-by: Roger Quadros >>> Signed-off-by: Sekhar Nori >> >> I have not seen a resolution in this discussion. >> >> My understanding is that there are several cases (single MDIO bus whose >> reset does a reset on all that MDIO bus's PHYs, etc.) and it's unclear >> how to handle all such cases cleanly. > > I see it falling into two cases. > > 1) We have a GPIO which resets one PHY. In this case, the GPIO is a > PHY property, it should be documented in > Documentation/devicetree/bindings/net/phy.txt. Hopefully there is > nothing PHY driver specific here, so all the handling can be placed in > the core PHY code. I suspect we would have to release the PHY GPIO reset line within a mii_bus::reset callback, which occurs before the PHY registers are read. There is this chicken and egg problem where you can't probe for a PHY unless you can successfully read from it, and you can't do the PHY reset in the PHY drivers' probe function unless you were able to find a PHY device. NB: you can work around that by using an Ethernet PHY device compatible string in Device Tree that already has the PHY OUI specified, although that usually does not scale to many different boards/designs. > > 2) We have one or more GPIOs which reset more than one PHY. In this > case, the GPIOs are MDIO bus properties. Again, there should not be > anything which is MDIO bus driver specific, so all the handling can be > placed in the core MDIO bus code. Agreed. I would do something like: - if the MDIO bus node has a "gpio" reset property, use it and release the device from reset - for each available child node: - if the PHY/MDIO device's node have a "gpio" reset property use it and release the PHYs from reset. All of this should probably be placed somewhere in drivers/of/of_mdio.c and deal with conditional GPIO/RESET controller support. -- Florian
Re: [PATCH] netlink: uapi: use hex numbers for NLM_F_* flags
From: Johannes Berg Date: Thu, 6 Apr 2017 16:10:42 +0200 > From: Johannes Berg > > It's rather confusing that the netlink message flags are > numbered 1, 2, 4, 8, 16, 32, , 0x100. Make that > more understandable by numbering the lower ones with hex > constants as well. > > Signed-off-by: Johannes Berg This is fine, applied, thanks.
Re: [RFC] netlink: send exterr cookie on success
On Fri, 7 Apr 2017 21:44:02 +0200, Johannes Berg wrote: > @@ -67,6 +67,8 @@ struct netlink_ext_err { > u32 ext_code; > u32 msg_offset; > u16 attr; > + const u8 *cookie; > + u8 cookie_len; > }; Perhaps the structure should be named just "netlink_ext" or so? It seems it'll pick up some non-error related usage, such as the cookies here or, in the future, flags indicating how the message should be parsed. Thanks, Jiri
Re: [PATCH net 0/2] l2tp: fix error handling of PPPoL2TP socket options
From: Guillaume Nault Date: Thu, 6 Apr 2017 18:31:18 +0200 > Fix pppol2tp_[gs]etsockopt() so that they don't ignore errors returned > by their helper functions. Series applied, thanks.
Re: [PATCH net v2 1/1] net: tcp: Increase TCP_MIB_OUTRSTS even though fail to alloc skb
From: gfree.w...@foxmail.com Date: Thu, 6 Apr 2017 23:05:49 +0800 > From: Gao Feng > > Because TCP_MIB_OUTRSTS is an important count, so always increase it > whatever send it successfully or not. > > Now move the increment of TCP_MIB_OUTRSTS to the top of > tcp_send_active_reset to make sure it is increased always even though > fail to alloc skb. > > Signed-off-by: Gao Feng Applied, thank you.
Re: [PATCH net-next v2] net: dsa: mv88e6xxx: Make SMI c22/c45 read/write functions static
From: Florian Fainelli Date: Thu, 6 Apr 2017 12:42:16 -0700 > The SMI clause 22 & 45 read/write operations are local to the global2.c file, > so make them static. This eliminates the following warning: ... > Suggested-by: Andrew Lunn > Signed-off-by: Florian Fainelli Applied, thanks Florian.
Re: [PATCH net-next 1/1] netvsc: Initialize all channel related state prior to opening the channel
From: k...@exchange.microsoft.com Date: Thu, 6 Apr 2017 14:59:21 -0700 > From: K. Y. Srinivasan > > Prior to opening the channel we should have all the state setup to handle > interrupts. The current code does not do that; fix the bug. This bug > can result in faults in the interrupt path. > > Signed-off-by: K. Y. Srinivasan Applied, thanks.
Re: [PATCH net-next] liquidio: fix VF incorrectly indicating that it successfully set its VLAN
From: Felix Manlunas Date: Thu, 6 Apr 2017 19:22:22 -0700 > For security reasons, NIC firmware does not allow VF to set its VLAN if PF > set it already. Firmware allows VF to set its VLAN if PF did not set it. > After the VF instructs the firmware to set the VLAN, VF always indicates > (via return 0) that the operation is successful--even for the times when it > isn't. > > Put in a mechanism for the VF's set VLAN function to receive the firmware > response code, then make that function return -EPERM if the firmware > forbids the operation. > > Make that mechanism available for other functions that may, in the future, > be interested in receiving the response code from the firmware. That > mechanism involves adding new fields to struct octnic_ctrl_pkt, so make all > users of struct octnic_ctrl_pkt initialize the struct to zero before using > it; otherwise, the mechanism might act on uninitialized garbage. > > Signed-off-by: Felix Manlunas > Signed-off-by: Derek Chickles Applied, thanks.
[PATCH] net: ipv6: Remove unneccessary comments
This comments are obsolete and should go, as there are no set of rules per CPU anymore. Signed-off-by: Arushi Singhal --- net/ipv6/netfilter/ip6_tables.c | 9 - 1 file changed, 9 deletions(-) diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 1e15c54fd5e2..e52234a111d6 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -51,15 +51,6 @@ void *ip6t_alloc_initial_table(const struct xt_table *info) } EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table); -/* - We keep a set of rules for each CPU, so we can avoid write-locking - them in the softirq when updating the counters and therefore - only need to read-lock in the softirq; doing a write_lock_bh() in user - context stops packets coming through and allows user context to read - the counters or update the rules. - - Hence the start of any table is given by get_table() below. */ - /* Returns whether matches rule or not. */ /* Performance critical - called for every packet */ static inline bool -- 2.11.0
Re: [RFC] netlink: send exterr cookie on success
On Sat, 2017-04-08 at 11:28 -0400, Jiri Benc wrote: > Perhaps the structure should be named just "netlink_ext" or so? It > seems it'll pick up some non-error related usage, such as the cookies > here or, in the future, flags indicating how the message should be > parsed. Fair point, I'll call it netlink_ext_ack. johannes
[PATCH net-next] net: dsa: mt7530: Include gpio/consumer.h for GPIO functions
Fixes build errors seen with CONFIG_GPIOLIB disabled and warnings enabled: drivers/net/dsa/mt7530.c: In function 'mt7530_setup': drivers/net/dsa/mt7530.c:948:3: error: implicit declaration of function 'gpiod_set_value_cansleep' [-Werror=implicit-function-declaration] gpiod_set_value_cansleep(priv->reset, 0); ^~~~ drivers/net/dsa/mt7530.c: In function 'mt7530_probe': drivers/net/dsa/mt7530.c:1068:17: error: implicit declaration of function 'devm_gpiod_get_optional' [-Werror=implicit-function-declaration] priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset", ^~~ drivers/net/dsa/mt7530.c:1069:13: error: 'GPIOD_OUT_LOW' undeclared (first use in this function) GPIOD_OUT_LOW); ^ drivers/net/dsa/mt7530.c:1069:13: Fixes: b8f126a8d543 ("net-next: dsa: add dsa support for Mediatek MT7530 switch") Signed-off-by: Florian Fainelli --- drivers/net/dsa/mt7530.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index a4f3b0b8c28e..b070c167e70f 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include -- 2.9.3
[PATCH net-next v2 1/3] net: dsa: Do not check for NULL dst in tag parsers
dsa_switch_rcv() already tests for dst == NULL, so there is no need to duplicate the same check within the tag receive functions. Signed-off-by: Florian Fainelli --- net/dsa/tag_brcm.c| 3 --- net/dsa/tag_dsa.c | 3 --- net/dsa/tag_edsa.c| 3 --- net/dsa/tag_mtk.c | 3 --- net/dsa/tag_qca.c | 3 --- net/dsa/tag_trailer.c | 2 -- 6 files changed, 17 deletions(-) diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index e2ed6cf68261..68d4feef96d4 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -100,9 +100,6 @@ static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, int source_port; u8 *brcm_tag; - if (unlikely(dst == NULL)) - goto out_drop; - ds = dst->cpu_switch; skb = skb_unshare(skb, GFP_ATOMIC); diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index e42ba906100c..377569c0e4f7 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -77,9 +77,6 @@ static int dsa_rcv(struct sk_buff *skb, struct net_device *dev, int source_device; int source_port; - if (unlikely(dst == NULL)) - goto out_drop; - skb = skb_unshare(skb, GFP_ATOMIC); if (skb == NULL) goto out; diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c index 6a9b7a9e4e15..30520ff9c9a2 100644 --- a/net/dsa/tag_edsa.c +++ b/net/dsa/tag_edsa.c @@ -90,9 +90,6 @@ static int edsa_rcv(struct sk_buff *skb, struct net_device *dev, int source_device; int source_port; - if (unlikely(dst == NULL)) - goto out_drop; - skb = skb_unshare(skb, GFP_ATOMIC); if (skb == NULL) goto out; diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c index 44ae6353a521..836c311a3c38 100644 --- a/net/dsa/tag_mtk.c +++ b/net/dsa/tag_mtk.c @@ -55,9 +55,6 @@ static int mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, int port; __be16 *phdr, hdr; - if (unlikely(!dst)) - goto out_drop; - skb = skb_unshare(skb, GFP_ATOMIC); if (!skb) goto out; diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c index 4e0dad759d04..6579d6db1bc6 100644 --- a/net/dsa/tag_qca.c +++ b/net/dsa/tag_qca.c @@ -75,9 +75,6 @@ static int qca_tag_rcv(struct sk_buff *skb, struct net_device *dev, int port; __be16 *phdr, hdr; - if (unlikely(!dst)) - goto out_drop; - skb = skb_unshare(skb, GFP_ATOMIC); if (!skb) goto out; diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c index 74c948512550..f5c764ee2968 100644 --- a/net/dsa/tag_trailer.c +++ b/net/dsa/tag_trailer.c @@ -66,8 +66,6 @@ static int trailer_rcv(struct sk_buff *skb, struct net_device *dev, u8 *trailer; int source_port; - if (unlikely(dst == NULL)) - goto out_drop; ds = dst->cpu_switch; skb = skb_unshare(skb, GFP_ATOMIC); -- 2.9.3
[PATCH net-next v2 0/3] net: dsa: Receive path simplifications
Hi all, This patch series does factor the common code found in all tag implementations into dsa_switch_rcv(). The original motivation was to add GRO support, but this may be a lot of work with unclear benefits at this point. Changes in v2: - take care of tag_mtk.c in the process Florian Fainelli (3): net: dsa: Do not check for NULL dst in tag parsers net: dsa: Move skb_unshare() to dsa_switch_rcv() net: dsa: Factor bottom tag receive functions include/net/dsa.h | 2 +- net/dsa/dsa.c | 24 +++- net/dsa/dsa_priv.h| 5 +++-- net/dsa/tag_brcm.c| 26 +- net/dsa/tag_dsa.c | 26 +- net/dsa/tag_edsa.c| 26 +- net/dsa/tag_mtk.c | 28 +--- net/dsa/tag_qca.c | 26 +- net/dsa/tag_trailer.c | 25 + 9 files changed, 57 insertions(+), 131 deletions(-) -- 2.9.3
[PATCH net-next v2 2/3] net: dsa: Move skb_unshare() to dsa_switch_rcv()
All DSA tag receive functions need to unshare the skb before mangling it, move this to the generic dsa_switch_rcv() function which will allow us to make the tag receive function return their mangled skb without caring about freeing a NULL skb. Signed-off-by: Florian Fainelli --- net/dsa/dsa.c | 4 net/dsa/tag_brcm.c| 5 - net/dsa/tag_dsa.c | 5 - net/dsa/tag_edsa.c| 5 - net/dsa/tag_mtk.c | 5 - net/dsa/tag_qca.c | 5 - net/dsa/tag_trailer.c | 5 - 7 files changed, 4 insertions(+), 30 deletions(-) diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 6cad15da5892..d370c8bfa372 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -906,6 +906,10 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, return 0; } + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) + return 0; + return dst->rcv(skb, dev, pt, orig_dev); } diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index 68d4feef96d4..263941769c88 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -102,10 +102,6 @@ static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, ds = dst->cpu_switch; - skb = skb_unshare(skb, GFP_ATOMIC); - if (skb == NULL) - goto out; - if (unlikely(!pskb_may_pull(skb, BRCM_TAG_LEN))) goto out_drop; @@ -151,7 +147,6 @@ static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, out_drop: kfree_skb(skb); -out: return 0; } diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index 377569c0e4f7..b7032699eaad 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -77,10 +77,6 @@ static int dsa_rcv(struct sk_buff *skb, struct net_device *dev, int source_device; int source_port; - skb = skb_unshare(skb, GFP_ATOMIC); - if (skb == NULL) - goto out; - if (unlikely(!pskb_may_pull(skb, DSA_HLEN))) goto out_drop; @@ -175,7 +171,6 @@ static int dsa_rcv(struct sk_buff *skb, struct net_device *dev, out_drop: kfree_skb(skb); -out: return 0; } diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c index 30520ff9c9a2..b87009672b40 100644 --- a/net/dsa/tag_edsa.c +++ b/net/dsa/tag_edsa.c @@ -90,10 +90,6 @@ static int edsa_rcv(struct sk_buff *skb, struct net_device *dev, int source_device; int source_port; - skb = skb_unshare(skb, GFP_ATOMIC); - if (skb == NULL) - goto out; - if (unlikely(!pskb_may_pull(skb, EDSA_HLEN))) goto out_drop; @@ -194,7 +190,6 @@ static int edsa_rcv(struct sk_buff *skb, struct net_device *dev, out_drop: kfree_skb(skb); -out: return 0; } diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c index 836c311a3c38..d0a477084870 100644 --- a/net/dsa/tag_mtk.c +++ b/net/dsa/tag_mtk.c @@ -55,10 +55,6 @@ static int mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, int port; __be16 *phdr, hdr; - skb = skb_unshare(skb, GFP_ATOMIC); - if (!skb) - goto out; - if (unlikely(!pskb_may_pull(skb, MTK_HDR_LEN))) goto out_drop; @@ -105,7 +101,6 @@ static int mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, out_drop: kfree_skb(skb); -out: return 0; } diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c index 6579d6db1bc6..d1324649808c 100644 --- a/net/dsa/tag_qca.c +++ b/net/dsa/tag_qca.c @@ -75,10 +75,6 @@ static int qca_tag_rcv(struct sk_buff *skb, struct net_device *dev, int port; __be16 *phdr, hdr; - skb = skb_unshare(skb, GFP_ATOMIC); - if (!skb) - goto out; - if (unlikely(!pskb_may_pull(skb, QCA_HDR_LEN))) goto out_drop; @@ -126,7 +122,6 @@ static int qca_tag_rcv(struct sk_buff *skb, struct net_device *dev, out_drop: kfree_skb(skb); -out: return 0; } diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c index f5c764ee2968..1fc0b221a70f 100644 --- a/net/dsa/tag_trailer.c +++ b/net/dsa/tag_trailer.c @@ -68,10 +68,6 @@ static int trailer_rcv(struct sk_buff *skb, struct net_device *dev, ds = dst->cpu_switch; - skb = skb_unshare(skb, GFP_ATOMIC); - if (skb == NULL) - goto out; - if (skb_linearize(skb)) goto out_drop; @@ -100,7 +96,6 @@ static int trailer_rcv(struct sk_buff *skb, struct net_device *dev, out_drop: kfree_skb(skb); -out: return 0; } -- 2.9.3
[PATCH net-next v2 3/3] net: dsa: Factor bottom tag receive functions
All DSA tag receive functions do strictly the same thing after they have located the originating source port from their tag specific protocol: - push ETH_HLEN bytes - set pkt_type to PACKET_HOST - call eth_type_trans() - bump up counters - call netif_receive_skb() Factor all of that into dsa_switch_rcv(). This also makes us return a pointer to a sk_buff, which makes us symetric with the xmit function. Signed-off-by: Florian Fainelli --- include/net/dsa.h | 2 +- net/dsa/dsa.c | 20 +++- net/dsa/dsa_priv.h| 5 +++-- net/dsa/tag_brcm.c| 18 +- net/dsa/tag_dsa.c | 18 +- net/dsa/tag_edsa.c| 18 +- net/dsa/tag_mtk.c | 20 +--- net/dsa/tag_qca.c | 18 +- net/dsa/tag_trailer.c | 18 +- 9 files changed, 53 insertions(+), 84 deletions(-) diff --git a/include/net/dsa.h b/include/net/dsa.h index 7ba9b1fb565c..9b1c1eb4147a 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -124,7 +124,7 @@ struct dsa_switch_tree { * protocol to use. */ struct net_device *master_netdev; - int (*rcv)(struct sk_buff *skb, + struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev); diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index d370c8bfa372..1fb9cf7aaaf4 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "dsa_priv.h" @@ -900,6 +901,7 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { struct dsa_switch_tree *dst = dev->dsa_ptr; + struct sk_buff *nskb = NULL; if (unlikely(dst == NULL)) { kfree_skb(skb); @@ -910,7 +912,23 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, if (!skb) return 0; - return dst->rcv(skb, dev, pt, orig_dev); + nskb = dst->rcv(skb, dev, pt, orig_dev); + if (!nskb) { + kfree_skb(skb); + return 0; + } + + skb = nskb; + skb_push(skb, ETH_HLEN); + skb->pkt_type = PACKET_HOST; + skb->protocol = eth_type_trans(skb, skb->dev); + + skb->dev->stats.rx_packets++; + skb->dev->stats.rx_bytes += skb->len; + + netif_receive_skb(skb); + + return 0; } static struct packet_type dsa_pack_type __read_mostly = { diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 2a3139921811..107138a55bd8 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -17,8 +17,9 @@ struct dsa_device_ops { struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev); - int (*rcv)(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev); + struct sk_buff *(*rcv)(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, + struct net_device *orig_dev); }; struct dsa_slave_priv { diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index 263941769c88..2a9b52c5af86 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -92,8 +92,9 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev return NULL; } -static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) +static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, + struct net_device *orig_dev) { struct dsa_switch_tree *dst = dev->dsa_ptr; struct dsa_switch *ds; @@ -133,21 +134,12 @@ static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, skb->data - ETH_HLEN - BRCM_TAG_LEN, 2 * ETH_ALEN); - skb_push(skb, ETH_HLEN); - skb->pkt_type = PACKET_HOST; skb->dev = ds->ports[source_port].netdev; - skb->protocol = eth_type_trans(skb, skb->dev); - skb->dev->stats.rx_packets++; - skb->dev->stats.rx_bytes += skb->len; - - netif_receive_skb(skb); - - return 0; + return skb; out_drop: - kfree_skb(skb); - return 0; + return NULL; } const struct dsa_device_ops brcm_netdev_ops = { diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index b7032699eaad..1c6633f0de01 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -68,8 +68,9 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev) return NULL; } -static int dsa_rcv(struct sk_buff *skb, str
[PATCH 00/22] staging: rtl87232bs: Fix errors and warnings detected by Smatch
A number of routines have indenting, off by one, and possible usage while null warnings or errors listed by Smatch. This set of patches fix all but one of these, and it is in code that will be removed in a subsequent patch. Signed-off-by: Larry Finger Larry Finger (22): staging: rtl8723bs: Fix indenting warning in os_dep/xmit_linux.c staging: rtl8723bs: Fix indenting warning in os_dep/rtw_proc.c staging: rtl8723bs: Fix dereference before check warning in os_dep/recv_linux.c staging: rtl8723bs: Fix indenting warning in os_dep/os_intfs.c staging: rtl8723bs: Fix indenting mistake in os_dep/mlme_linux.c staging: rtl8723bs: Fix various errors in os_dep/ioctl_cfg80211.c staging: rtl8723bs: Fix potential usage while NULL error in hal/rtl8723b_hal_init.c staging: rtl8723bs: Fix indenting problems in hal/HalHWImg8723B_BB.c staging: rtl8723bs: Fix indening problem in hal/hal_com_phycfg.c staging: rtl8723bs: Fix indenting problem for hal/hal_com.c staging: rtl8723bs: Fix indenting problems in core/rtw_xmit.c staging: rtl8723bs: Fix possible usage of NULL pointer in core/rtw_debug.c staging: rtl8723bs: Fix indenting mistake in core/rtw_ap.c staging: rtl8723bs: Fix indenting mistakes in core/rtw_ieee80211.c staging: rtl8723bs: Fix indenting mistakes in core/rtw_mlme.c staging: rtl8723bs: Fix some indenting problems and a potential data overrun staging: rtl8723bs: Fix indenting problem in core/rtw_sta_mgt.c staging: rtl8723bs: Fix some white-space errors in core/rtw_security.c staging: rtl8723bs: Fix white-space errors in core/rtw_recv.c staging rtl8723bs: Fix indenting errors and an off-by-one mistake in core/rtw_mlme_ext.c staging: rtl8723bs: Fix indenting problems in core/rtw_odm.c staging: rtlwifi: Fix indenting error in core/rtw_pwrctrl.c drivers/staging/rtl8723bs/core/rtw_ap.c | 99 +++-- drivers/staging/rtl8723bs/core/rtw_debug.c| 1 - drivers/staging/rtl8723bs/core/rtw_ieee80211.c| 13 +- drivers/staging/rtl8723bs/core/rtw_mlme.c | 37 +- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 25 +- drivers/staging/rtl8723bs/core/rtw_odm.c | 10 +- drivers/staging/rtl8723bs/core/rtw_pwrctrl.c | 2 +- drivers/staging/rtl8723bs/core/rtw_recv.c | 21 +- drivers/staging/rtl8723bs/core/rtw_security.c | 469 +++--- drivers/staging/rtl8723bs/core/rtw_sta_mgt.c | 2 +- drivers/staging/rtl8723bs/core/rtw_wlan_util.c| 10 +- drivers/staging/rtl8723bs/core/rtw_xmit.c | 10 +- drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c | 6 +- drivers/staging/rtl8723bs/hal/hal_com.c | 10 +- drivers/staging/rtl8723bs/hal/hal_com_phycfg.c| 2 +- drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c | 13 +- drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 38 +- drivers/staging/rtl8723bs/os_dep/ioctl_linux.c| 2 +- drivers/staging/rtl8723bs/os_dep/mlme_linux.c | 4 +- drivers/staging/rtl8723bs/os_dep/os_intfs.c | 2 +- drivers/staging/rtl8723bs/os_dep/recv_linux.c | 3 +- drivers/staging/rtl8723bs/os_dep/rtw_proc.c | 3 +- drivers/staging/rtl8723bs/os_dep/xmit_linux.c | 2 +- 23 files changed, 375 insertions(+), 409 deletions(-) -- 2.12.0
[PATCH 02/22] staging: rtl8723bs: Fix indenting warning in os_dep/rtw_proc.c
Smatch lists the following warning: CHECK drivers/staging/rtl8723bs/os_dep/rtw_proc.c drivers/staging/rtl8723bs/os_dep/rtw_proc.c:102 rtw_drv_proc_open() warn: inconsistent indenting This warning is fixed with a simple change in the white space. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/os_dep/rtw_proc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/os_dep/rtw_proc.c b/drivers/staging/rtl8723bs/os_dep/rtw_proc.c index 4088381dff35..a2011e06d719 100644 --- a/drivers/staging/rtl8723bs/os_dep/rtw_proc.c +++ b/drivers/staging/rtl8723bs/os_dep/rtw_proc.c @@ -99,7 +99,8 @@ static int rtw_drv_proc_open(struct inode *inode, struct file *file) /* struct net_device *dev = proc_get_parent_data(inode); */ ssize_t index = (ssize_t)PDE_DATA(inode); const struct rtw_proc_hdl *hdl = drv_proc_hdls+index; - return single_open(file, hdl->show, NULL); + + return single_open(file, hdl->show, NULL); } static ssize_t rtw_drv_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos) -- 2.12.0
[PATCH 03/22] staging: rtl8723bs: Fix dereference before check warning in os_dep/recv_linux.c
Smatch lists the following warning: CHECK drivers/staging/rtl8723bs/os_dep/recv_linux.c drivers/staging/rtl8723bs/os_dep/recv_linux.c:353 rtw_recv_indicatepkt() warn: variable dereferenced before check 'precv_frame' (see line 312) This warning is fixed by removing the test at line 353. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/os_dep/recv_linux.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723bs/os_dep/recv_linux.c b/drivers/staging/rtl8723bs/os_dep/recv_linux.c index c677a5216b54..e731ab4e2bd7 100644 --- a/drivers/staging/rtl8723bs/os_dep/recv_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/recv_linux.c @@ -350,8 +350,7 @@ int rtw_recv_indicatepkt(struct adapter *padapter, union recv_frame *precv_frame _recv_indicatepkt_drop: /* enqueue back to free_recv_queue */ -if (precv_frame) -rtw_free_recvframe(precv_frame, pfree_recv_queue); +rtw_free_recvframe(precv_frame, pfree_recv_queue); DBG_COUNTER(padapter->rx_logs.os_indicate_err); return _FAIL; -- 2.12.0
[PATCH 04/22] staging: rtl8723bs: Fix indenting warning in os_dep/os_intfs.c
Smatch logs the following warning: CHECK drivers/staging/rtl8723bs/os_dep/os_intfs.c drivers/staging/rtl8723bs/os_dep/os_intfs.c:1082 ips_netdrv_open() warn: inconsistent indenting A simple change in the white space handles this warning. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/os_dep/os_intfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c index 2ed3067b4af0..843be2cc6c10 100644 --- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c @@ -1079,7 +1079,7 @@ static int ips_netdrv_open(struct adapter *padapter) _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000); -return _SUCCESS; + return _SUCCESS; netdev_open_error: /* padapter->bup = false; */ -- 2.12.0
[PATCH 01/22] staging: rtl8723bs: Fix indenting warning in os_dep/xmit_linux.c
Smatch issues the warning CHECK drivers/staging/rtl8723bs/os_dep/xmit_linux.c drivers/staging/rtl8723bs/os_dep/xmit_linux.c:42 _rtw_pktfile_read() warn: inconsistent indenting A simple indent changes fixes this. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/os_dep/xmit_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/os_dep/xmit_linux.c b/drivers/staging/rtl8723bs/os_dep/xmit_linux.c index 5ede3b6fbdec..66dfec18f770 100644 --- a/drivers/staging/rtl8723bs/os_dep/xmit_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/xmit_linux.c @@ -39,7 +39,7 @@ uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen) len = rtw_remainder_len(pfile); len = (rlen > len)? len: rlen; - if (rmem) + if (rmem) skb_copy_bits(pfile->pkt, pfile->buf_len-pfile->pkt_len, rmem, len); pfile->cur_addr += len; -- 2.12.0
[PATCH 08/22] staging: rtl8723bs: Fix indenting problems in hal/HalHWImg8723B_BB.c
Smatch lists the following: CHECK drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c:314 ODM_ReadAndConfig_MP_8723B_AGC_TAB() warn: for statement not indented drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c:583 ODM_ReadAndConfig_MP_8723B_PHY_REG() warn: for statement not indented drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c:586 ODM_ReadAndConfig_MP_8723B_PHY_REG() warn: inconsistent indenting These were all fixed with white-space changes. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c index b42f06076f93..51d4219177d3 100644 --- a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c +++ b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c @@ -312,7 +312,7 @@ void ODM_ReadAndConfig_MP_8723B_AGC_TAB(PDM_ODM_T pDM_Odm) * Discard the following (offset, data) pairs. */ while (v1 < 0x4000 && i < ArrayLen-2) - READ_NEXT_PAIR(v1, v2, i); + READ_NEXT_PAIR(v1, v2, i); i -= 2; /* prevent from for-loop += 2 */ } else { @@ -581,9 +581,9 @@ void ODM_ReadAndConfig_MP_8723B_PHY_REG(PDM_ODM_T pDM_Odm) * Discard the following (offset, data) pairs. */ while (v1 < 0x4000 && i < ArrayLen-2) - READ_NEXT_PAIR(v1, v2, i); + READ_NEXT_PAIR(v1, v2, i); - i -= 2; /* prevent from for-loop += 2 */ + i -= 2; /* prevent from for-loop += 2 */ } else { /* Configure matched pairs and skip to end of if-else. */ while (v1 < 0x4000 && i < ArrayLen-2) { odm_ConfigBB_PHY_8723B(pDM_Odm, v1, bMaskDWord, v2); -- 2.12.0
[PATCH 11/22] staging: rtl8723bs: Fix indenting problems in core/rtw_xmit.c
Smatch logs the following: CHECK drivers/staging/rtl8723bs/core/rtw_xmit.c drivers/staging/rtl8723bs/core/rtw_xmit.c:277 _rtw_init_xmit_priv() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_xmit.c:294 _rtw_free_xmit_priv() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_xmit.c:295 _rtw_free_xmit_priv() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_xmit.c:946 xmitframe_addmic() warn: inconsistent indenting These are fixed with white-space changes. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_xmit.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 60585540069a..8f2c9a6658bf 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -274,7 +274,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) rtw_alloc_hwxmits(padapter); rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); - for (i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { pxmitpriv->wmm_para_seq[i] = i; } @@ -290,8 +290,8 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv) { - int i; - struct adapter *padapter = pxmitpriv->adapter; + int i; + struct adapter *padapter = pxmitpriv->adapter; struct xmit_frame *pxmitframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf; struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; @@ -942,8 +942,8 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr } - /* if (pqospriv->qos_option == 1) */ - if (pattrib->qos_en) + /* if (pqospriv->qos_option == 1) */ + if (pattrib->qos_en) priority[0] = (u8)pxmitframe->attrib.priority; -- 2.12.0
[PATCH 05/22] staging: rtl8723bs: Fix indenting mistake in os_dep/mlme_linux.c
Smatch reports the following warning: CHECK drivers/staging/rtl8723bs/os_dep/mlme_linux.c drivers/staging/rtl8723bs/os_dep/mlme_linux.c:149 rtw_os_indicate_disconnect() warn: inconsistent indenting Again, a simple change in the white space fixes this problem. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/os_dep/mlme_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723bs/os_dep/mlme_linux.c b/drivers/staging/rtl8723bs/os_dep/mlme_linux.c index aa1793389797..46315d1a82f7 100644 --- a/drivers/staging/rtl8723bs/os_dep/mlme_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/mlme_linux.c @@ -145,8 +145,8 @@ void rtw_os_indicate_disconnect(struct adapter *adapter) rtw_indicate_wx_disassoc_event(adapter); -/* modify for CONFIG_IEEE80211W, none 11w also can use the same command */ -rtw_reset_securitypriv_cmd(adapter); + /* modify for CONFIG_IEEE80211W, none 11w also can use the same command */ + rtw_reset_securitypriv_cmd(adapter); } void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) -- 2.12.0
[PATCH 12/22] staging: rtl8723bs: Fix possible usage of NULL pointer in core/rtw_debug.c
Smatch reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_debug.c drivers/staging/rtl8723bs/core/rtw_debug.c:454 proc_get_survey_info() error: we previously assumed 'phead' could be null (see line 453) drivers/staging/rtl8723bs/core/rtw_debug.c:455 proc_get_survey_info() warn: variable dereferenced before check 'phead' (see line 454) In the code, there are two successive calls to get_head(). The second is removed. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_debug.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_debug.c b/drivers/staging/rtl8723bs/core/rtw_debug.c index d34747b29309..51cef55d3f76 100644 --- a/drivers/staging/rtl8723bs/core/rtw_debug.c +++ b/drivers/staging/rtl8723bs/core/rtw_debug.c @@ -451,7 +451,6 @@ int proc_get_survey_info(struct seq_file *m, void *v) spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); phead = get_list_head(queue); plist = phead ? get_next(phead) : NULL; - plist = get_next(phead); if ((!phead) || (!plist)) { spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); return 0; -- 2.12.0
[PATCH 06/22] staging: rtl8723bs: Fix various errors in os_dep/ioctl_cfg80211.c
Smatch lists the following: CHECK drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:470 rtw_cfg80211_ibss_indicate_connect() error: we previously assumed 'scanned' could be null (see line 466) drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:942 rtw_cfg80211_set_encryption() warn: inconsistent indenting drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:955 rtw_cfg80211_set_encryption() error: buffer overflow 'psecuritypriv->dot11DefKey' 4 <= 4 drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:1017 rtw_cfg80211_set_encryption() error: buffer overflow 'padapter->securitypriv.dot118021XGrpKey' 5 <= 5 drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:1216 cfg80211_rtw_set_default_key() warn: inconsistent indenting drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2498 rtw_cfg80211_monitor_if_xmit_entry() error: we previously assumed 'skb' could be null (see line 2495) drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2850 cfg80211_rtw_start_ap() warn: if statement not indented drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:2860 cfg80211_rtw_start_ap() warn: if statement not indented drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:3417 rtw_cfg80211_preinit_wiphy() warn: inconsistent indenting drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c:3547 rtw_wdev_alloc() info: ignoring unreachable code. The indenting warnings were fixed by simple white space changes. The section where 'scanned' could be null required an immediate exit from the routine at that point. A similar fix was required where 'skb' could be null. The two buffer overflow errors were caused by off-by-one errors. While locating these problems, another one was found in os_dep/ioctl_linux.c. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c | 38 +-- drivers/staging/rtl8723bs/os_dep/ioctl_linux.c| 2 +- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index ce7cca68ff7a..d2c66041a561 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -463,9 +463,10 @@ void rtw_cfg80211_ibss_indicate_connect(struct adapter *padapter) } else { - if (scanned == NULL) + if (scanned == NULL) { rtw_warn_on(1); - + return; + } if (!memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(struct ndis_802_11_ssid)) && !memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) ) { @@ -906,7 +907,7 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { if (param->u.crypt.idx >= WEP_KEYS - && param->u.crypt.idx > BIP_MAX_KEYID + || param->u.crypt.idx >= BIP_MAX_KEYID ) { ret = -EINVAL; @@ -927,7 +928,7 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param wep_key_idx = param->u.crypt.idx; wep_key_len = param->u.crypt.key_len; - if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) + if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) { ret = -EINVAL; goto exit; @@ -939,7 +940,7 @@ static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param wep_key_len = wep_key_len <= 5 ? 5 : 13; - psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; + psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled; psecuritypriv->dot11PrivacyAlgrthm = _WEP40_; psecuritypriv->dot118021XGrpPrivacy = _WEP40_; @@ -1213,11 +1214,8 @@ static int cfg80211_rtw_set_default_key(struct wiphy *wiphy, struct adapter *padapter = (struct adapter *)rtw_netdev_priv(ndev); struct security_priv *psecuritypriv = &padapter->securitypriv; - DBG_871X(FUNC_NDEV_FMT" key_index =%d" - ", unicast =%d, multicast =%d" - ".\n", FUNC_NDEV_ARG(ndev), key_index - , unicast, multicast - ); + DBG_871X(FUNC_NDEV_FMT" key_index =%d, unicast =%d, multicast =%d\n", +FUNC_NDEV_ARG(ndev), key_index, unicast, multicast); if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) /* set wep default key */
[PATCH 09/22] staging: rtl8723bs: Fix indening problem in hal/hal_com_phycfg.c
Smatch reports the following: CHECK drivers/staging/rtl8723bs/hal/hal_com_phycfg.c drivers/staging/rtl8723bs/hal/hal_com_phycfg.c:2090 Hal_ChannelPlanToRegulation() warn: inconsistent indenting This warning is fixed with a white-space change. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/hal/hal_com_phycfg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c index 95fff20e9c4b..566b6f0997da 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c @@ -2087,7 +2087,7 @@ void Hal_ChannelPlanToRegulation(struct adapter *Adapter, u16 ChannelPlan) case RT_CHANNEL_DOMAIN_WORLD_FCC2: pHalData->Regulation2_4G = TXPWR_LMT_FCC; pHalData->Regulation5G = TXPWR_LMT_FCC; - break; + break; case RT_CHANNEL_DOMAIN_WORLD_FCC3: pHalData->Regulation2_4G = TXPWR_LMT_FCC; pHalData->Regulation5G = TXPWR_LMT_FCC; -- 2.12.0
[PATCH 07/22] staging: rtl8723bs: Fix potential usage while NULL error in hal/rtl8723b_hal_init.c
Smatch logs the following: CHECK drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c:518 rtl8723b_FirmwareDownload() error: we previously assumed 'pFirmware' could be null (see line 382) Fixing this error required a rewrite of the error exits from this routine. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c index b7f6dc7ce318..d40ad03e99a3 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c @@ -377,13 +377,13 @@ s32 rtl8723b_FirmwareDownload(struct adapter *padapter, bool bUsedWoWLANFw) RT_TRACE(_module_hal_init_c_, _drv_notice_, ("+%s, bUsedWoWLANFw:%d\n", __func__, bUsedWoWLANFw)); #endif pFirmware = kzalloc(sizeof(struct rt_firmware), GFP_KERNEL); + if (!pFirmware) + return _FAIL; pBTFirmware = kzalloc(sizeof(struct rt_firmware), GFP_KERNEL); - - if (!pFirmware || !pBTFirmware) { - rtStatus = _FAIL; - goto exit; + if (!pBTFirmware) { + kfree(pFirmware); + return _FAIL; } - tmp_ps = rtw_read8(padapter, 0xa3); tmp_ps &= 0xf8; tmp_ps |= 0x02; @@ -441,7 +441,7 @@ s32 rtl8723b_FirmwareDownload(struct adapter *padapter, bool bUsedWoWLANFw) if (pFirmware->ulFwLength > FW_8723B_SIZE) { rtStatus = _FAIL; DBG_871X_LEVEL(_drv_emerg_, "Firmware size:%u exceed %u\n", pFirmware->ulFwLength, FW_8723B_SIZE); - goto exit; + goto release_fw1; } pFirmwareBuf = pFirmware->szFwBuffer; @@ -517,6 +517,7 @@ s32 rtl8723b_FirmwareDownload(struct adapter *padapter, bool bUsedWoWLANFw) exit: kfree(pFirmware->szFwBuffer); kfree(pFirmware); +release_fw1: kfree(pBTFirmware); DBG_871X(" <=== rtl8723b_FirmwareDownload()\n"); return rtStatus; -- 2.12.0
[PATCH 10/22] staging: rtl8723bs: Fix indenting problem for hal/hal_com.c
Smatch lists the following: CHECK drivers/staging/rtl8723bs/hal/hal_com_phycfg.c drivers/staging/rtl8723bs/hal/hal_com_phycfg.c:2090 Hal_ChannelPlanToRegulation() warn: inconsistent indenting Fixed by changing the white space. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/hal/hal_com.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8723bs/hal/hal_com.c b/drivers/staging/rtl8723bs/hal/hal_com.c index 093978d8f2a4..1880d4140bee 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com.c +++ b/drivers/staging/rtl8723bs/hal/hal_com.c @@ -1731,11 +1731,11 @@ void rtw_bb_rf_gain_offset(struct adapter *padapter) for (i = 0; i < ArrayLen; i += 2) { v1 = Array[i]; v2 = Array[i+1]; -if (v1 == padapter->eeprompriv.EEPROMRFGainVal) { - DBG_871X("Offset RF Gain. got v1 = 0x%x , v2 = 0x%x\n", v1, v2); - target = v2; - break; -} + if (v1 == padapter->eeprompriv.EEPROMRFGainVal) { + DBG_871X("Offset RF Gain. got v1 = 0x%x , v2 = 0x%x\n", v1, v2); + target = v2; + break; + } } DBG_871X("padapter->eeprompriv.EEPROMRFGainVal = 0x%x , Gain offset Target Value = 0x%x\n", padapter->eeprompriv.EEPROMRFGainVal, target); PHY_SetRFReg(padapter, RF_PATH_A, REG_RF_BB_GAIN_OFFSET, BIT18|BIT17|BIT16|BIT15, target); -- 2.12.0
[PATCH 14/22] staging: rtl8723bs: Fix indenting mistakes in core/rtw_ieee80211.c
Smatch reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_ieee80211.c drivers/staging/rtl8723bs/core/rtw_ieee80211.c:83 rtw_is_cckrates_included() warn: if statement not indented drivers/staging/rtl8723bs/core/rtw_ieee80211.c:98 rtw_is_cckratesonly_included() warn: if statement not indented These warnings are fixed with white-space changes. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_ieee80211.c | 13 + 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c index af44a8cd26f8..4670e72368e5 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c @@ -81,8 +81,8 @@ uint rtw_is_cckrates_included(u8 *rate) while (rate[i] != 0) { if rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || - (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) - return true; +(((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) + return true; i++; } @@ -95,16 +95,13 @@ uintrtw_is_cckratesonly_included(u8 *rate) while (rate[i] != 0) { - if rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && - (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) - + if rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && +(((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) return false; - - i++; + i++; } return true; - } int rtw_check_network_type(unsigned char *rate, int ratelen, int channel) -- 2.12.0
[PATCH 22/22] staging: rtl8723bs: Fix indenting error in core/rtw_pwrctrl.c
Smatch reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_pwrctrl.c drivers/staging/rtl8723bs/core/rtw_pwrctrl.c:641 LeaveAllPowerSaveModeDirect() warn: inconsistent indenting Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_pwrctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c index c5dd794dac4b..f708dbf5bfd4 100644 --- a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c @@ -638,7 +638,7 @@ void LeaveAllPowerSaveModeDirect(struct adapter *Adapter) rtw_set_rpwm(Adapter, PS_STATE_S4); - up(&pwrpriv->lock); + up(&pwrpriv->lock); rtw_lps_ctrl_wk_cmd(pri_padapter, LPS_CTRL_LEAVE, 0); } else{ -- 2.12.0
[PATCH 18/22] staging: rtl8723bs: Fix some white-space errors in core/rtw_security.c
Smatch reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_security.c drivers/staging/rtl8723bs/core/rtw_security.c:266 rtw_wep_encrypt() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:433 rtw_seccalctkipmic() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:749 rtw_tkip_encrypt() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:865 rtw_tkip_decrypt() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:1383 aes_cipher() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:1415 aes_cipher() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:1430 aes_cipher() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:1582 rtw_aes_encrypt() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:1651 aes_decipher() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:1739 aes_decipher() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_security.c:1792 aes_decipher() warn: curly braces intended? drivers/staging/rtl8723bs/core/rtw_security.c:1809 aes_decipher() warn: inconsistent indenting All of the above are fixed with white-space changes. A few unneeded blank lines are deleted. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_security.c | 469 +- 1 file changed, 229 insertions(+), 240 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c index 698e11e5d0a9..e832f16997b7 100644 --- a/drivers/staging/rtl8723bs/core/rtw_security.c +++ b/drivers/staging/rtl8723bs/core/rtw_security.c @@ -262,17 +262,15 @@ void rtw_wep_encrypt(struct adapter *padapter, u8 *pxmitframe) arcfour_encrypt(&mycontext, payload+length, crc, 4); } else{ - length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len; + length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len; *((__le32 *)crc) = getcrc32(payload, length); arcfour_init(&mycontext, wepkey, 3+keylength); arcfour_encrypt(&mycontext, payload, payload, length); arcfour_encrypt(&mycontext, payload+length, crc, 4); - pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((SIZE_PTR)(pframe)); - + pframe += pxmitpriv->frag_len; + pframe = (u8 *)RND4((SIZE_PTR)(pframe)); } - } WEP_SW_ENC_CNT_INC(psecuritypriv, pattrib->ra); @@ -429,7 +427,7 @@ void rtw_seccalctkipmic(u8 *key, u8 *header, u8 *data, u32 data_len, u8 *mic_cod /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */ if (header[1]&1) { /* ToDS == 1 */ - rtw_secmicappend(&micdata, &header[16], 6); /* DA */ + rtw_secmicappend(&micdata, &header[16], 6); /* DA */ if (header[1]&2) /* From Ds == 1 */ rtw_secmicappend(&micdata, &header[24], 6); else @@ -746,9 +744,8 @@ u32 rtw_tkip_encrypt(struct adapter *padapter, u8 *pxmitframe) arcfour_encrypt(&mycontext, payload, payload, length); arcfour_encrypt(&mycontext, payload+length, crc, 4); - pframe += pxmitpriv->frag_len; - pframe = (u8 *)RND4((SIZE_PTR)(pframe)); - + pframe += pxmitpriv->frag_len; + pframe = (u8 *)RND4((SIZE_PTR)(pframe)); } } @@ -791,10 +788,8 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe) /* 4 start to decrypt recvframe */ if (prxattrib->encrypt == _TKIP_) { - stainfo = rtw_get_stainfo(&padapter->stapriv, &prxattrib->ta[0]); if (stainfo != NULL) { - if (IS_MCAST(prxattrib->ra)) { static unsigned long start = 0; static u32 no_gkey_bc_cnt = 0; @@ -860,8 +855,9 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe) *((u32 *)crc) = le32_to_cpu(getcrc32(payload, length-4)); if (crc[3] != payload[length-1] || crc[2] != payload[length-2] || crc[1] != payload[length-3] || crc[0] != payload[length-4]) { - RT_TRACE(_module_rtl871x_security_c_, _drv_err_, ("rtw_wep_decrypt:icv error crc[3](%x)!=payload[length-1](%x) || crc[2](%x)!=payload[length-2](
[PATCH 16/22] staging: rtl8723bs: Fix some indenting problems and a potential data overrun
Smatch reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_wlan_util.c drivers/staging/rtl8723bs/core/rtw_wlan_util.c:67 cckrates_included() warn: if statement not indented drivers/staging/rtl8723bs/core/rtw_wlan_util.c:81 cckratesonly_included() warn: if statement not indented drivers/staging/rtl8723bs/core/rtw_wlan_util.c:815 rtw_camid_alloc() warn: should '1 << (cam_id)' be a 64 bit type? The first two are fixed with white-space changes. The third is fixed by restricting cam_id to be less than 32. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c index c966241df2ea..f485f541e36d 100644 --- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c @@ -65,8 +65,8 @@ int cckrates_included(unsigned char *rate, int ratelen) for (i = 0; i < ratelen; i++) { if rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) || - (((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) - return true; +(((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22)) + return true; } return false; @@ -79,8 +79,8 @@ int cckratesonly_included(unsigned char *rate, int ratelen) for (i = 0; i < ratelen; i++) { if rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) && - (((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) - return false; +(((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22)) + return false; } return true; @@ -811,7 +811,7 @@ s16 rtw_camid_alloc(struct adapter *adapter, struct sta_info *sta, u8 kid) } bitmap_handle: - if (cam_id >= 0) + if (cam_id >= 0 && cam_id < 32) cam_ctl->bitmap |= BIT(cam_id); spin_unlock_bh(&cam_ctl->lock); -- 2.12.0
[PATCH 17/22] staging: rtl8723bs: Fix indenting problem in core/rtw_sta_mgt.c
Sparse reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_sta_mgt.c drivers/staging/rtl8723bs/core/rtw_sta_mgt.c:25 _rtw_init_stainfo() warn: inconsistent indenting This problem is fixed with a white-spcae change. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_sta_mgt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c index d7eee6dd7e3b..cb43ec90a648 100644 --- a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c @@ -22,7 +22,7 @@ void _rtw_init_stainfo(struct sta_info *psta) { memset((u8 *)psta, 0, sizeof(struct sta_info)); -spin_lock_init(&psta->lock); + spin_lock_init(&psta->lock); INIT_LIST_HEAD(&psta->list); INIT_LIST_HEAD(&psta->hash_list); /* INIT_LIST_HEAD(&psta->asoc_list); */ -- 2.12.0
[PATCH 21/22] staging: rtl8723bs: Fix indenting problems in core/rtw_odm.c
Smatch reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_odm.c drivers/staging/rtl8723bs/core/rtw_odm.c:109 rtw_odm_dbg_comp_msg() warn: if statement not indented drivers/staging/rtl8723bs/core/rtw_odm.c:146 rtw_odm_ability_msg() warn: if statement not indented Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_odm.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_odm.c b/drivers/staging/rtl8723bs/core/rtw_odm.c index 5bc573386ad1..3144e8ec2fa2 100644 --- a/drivers/staging/rtl8723bs/core/rtw_odm.c +++ b/drivers/staging/rtl8723bs/core/rtw_odm.c @@ -107,8 +107,9 @@ void rtw_odm_dbg_comp_msg(void *sel, struct adapter *adapter) DBG_871X_SEL_NL(sel, "odm.DebugComponents = 0x%016llx\n", dbg_comp); for (i = 0; i < RTW_ODM_COMP_MAX; i++) { if (odm_comp_str[i]) - DBG_871X_SEL_NL(sel, "%cBIT%-2d %s\n", - (BIT0 << i) & dbg_comp ? '+' : ' ', i, odm_comp_str[i]); + DBG_871X_SEL_NL(sel, "%cBIT%-2d %s\n", + (BIT0 << i) & dbg_comp ? '+' : ' ', + i, odm_comp_str[i]); } } @@ -144,8 +145,9 @@ void rtw_odm_ability_msg(void *sel, struct adapter *adapter) DBG_871X_SEL_NL(sel, "odm.SupportAbility = 0x%08x\n", ability); for (i = 0; i < RTW_ODM_ABILITY_MAX; i++) { if (odm_ability_str[i]) - DBG_871X_SEL_NL(sel, "%cBIT%-2d %s\n", - (BIT0 << i) & ability ? '+' : ' ', i, odm_ability_str[i]); + DBG_871X_SEL_NL(sel, "%cBIT%-2d %s\n", + (BIT0 << i) & ability ? '+' : ' ', i, + odm_ability_str[i]); } } -- 2.12.0
[PATCH 15/22] staging: rtl8723bs: Fix indenting mistakes in core/rtw_mlme.c
Smatch reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_mlme.c drivers/staging/rtl8723bs/core/rtw_mlme.c:862 rtw_survey_event_callback() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_mlme.c:1102 rtw_free_assoc_resources() warn: if statement not indented drivers/staging/rtl8723bs/core/rtw_mlme.c:1165 rtw_indicate_disconnect() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_mlme.c:2830 rtw_restructure_ht_ie() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_mlme.c:2991 rtw_update_ht_cap() warn: inconsistent indenting All of there are simple white-space errors. A typo is also fixed. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_mlme.c | 37 +++ 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index c95e0626b522..53755e5b97a6 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -856,7 +856,7 @@ void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) /* lock pmlmepriv->lock when you accessing network_q */ if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == false) { - if (pnetwork->Ssid.Ssid[0] == 0) { + if (pnetwork->Ssid.Ssid[0] == 0) { pnetwork->Ssid.SsidLength = 0; } rtw_add_network(adapter, pnetwork); @@ -1100,8 +1100,7 @@ void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue) } if (lock_scanned_queue) - - adapter->securitypriv.key_mask = 0; + adapter->securitypriv.key_mask = 0; rtw_reset_rx_info(pdbgpriv); } @@ -1162,7 +1161,7 @@ void rtw_indicate_disconnect(struct adapter *padapter) /* set ips_deny_time to avoid enter IPS before LPS leave */ rtw_set_ips_deny(padapter, 3000); - _clr_fwstate_(pmlmepriv, _FW_LINKED); + _clr_fwstate_(pmlmepriv, _FW_LINKED); rtw_clear_scan_deny(padapter); } @@ -2826,8 +2825,8 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ if (stbc_rx_enable) ht_capie.cap_info |= cpu_to_le16(IEEE80211_HT_CAP_RX_STBC_1R);/* RX STBC One spatial stream */ - set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_1R); - break; + set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_1R); + break; case RF_2T2R: case RF_1T2R: @@ -2984,22 +2983,22 @@ void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len, u8 channe #else /* CONFIG_DISABLE_MCS13TO15 */ set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R); #endif /* CONFIG_DISABLE_MCS13TO15 */ - } + } - /* switch to the 40M Hz mode accoring to the AP */ - /* pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; */ - switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) { - case EXTCHNL_OFFSET_UPPER: - pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; - break; + /* switch to the 40M Hz mode according to the AP */ + /* pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; */ + switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) { + case EXTCHNL_OFFSET_UPPER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; + break; - case EXTCHNL_OFFSET_LOWER: - pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; - break; + case EXTCHNL_OFFSET_LOWER: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; + break; - default: - pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - break; + default: + pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + break; } } -- 2.12.0
[PATCH 19/22] staging: rtl8723bs: Fix white-space errors in core/rtw_recv.c
Smart reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_recv.c drivers/staging/rtl8723bs/core/rtw_recv.c:598 portctrl() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_recv.c:838 sta2sta_data_frame() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_recv.c:1547 validate_recv_frame() warn: inconsistent indenting Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_recv.c | 21 - 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c index 864538e8299d..6e98a1bd3e77 100644 --- a/drivers/staging/rtl8723bs/core/rtw_recv.c +++ b/drivers/staging/rtl8723bs/core/rtw_recv.c @@ -595,7 +595,7 @@ union recv_frame *portctrl(struct adapter *adapter, union recv_frame *precv_fram memcpy(&be_tmp, ptr, 2); ether_type = ntohs(be_tmp); - if (ether_type == eapol_type) + if (ether_type == eapol_type) prtnframe = precv_frame; else { /* free this frame */ @@ -827,17 +827,14 @@ sint sta2sta_data_frame( sta_addr = pattrib->src; } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { - { - /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */ - if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) { - RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("bssid != TA under STATION_MODE; drop pkt\n")); - ret = _FAIL; - goto exit; - } - - sta_addr = pattrib->bssid; + /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */ + if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) { + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("bssid != TA under STATION_MODE; drop pkt\n")); + ret = _FAIL; + goto exit; } + sta_addr = pattrib->bssid; } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) { if (bmcast) { /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */ @@ -1517,6 +1514,7 @@ sint validate_recv_frame(struct adapter *adapter, union recv_frame *precv_frame) u8 type; u8 subtype; sint retval = _SUCCESS; + u8 bDumpRxPkt; struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; @@ -1544,8 +1542,6 @@ sint validate_recv_frame(struct adapter *adapter, union recv_frame *precv_frame) pattrib->mdata = GetMData(ptr); pattrib->privacy = GetPrivacy(ptr); pattrib->order = GetOrder(ptr); -{ - u8 bDumpRxPkt; rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt)); if (bDumpRxPkt == 1) /* dump all rx packets */ dump_rx_packet(ptr); @@ -1553,7 +1549,6 @@ sint validate_recv_frame(struct adapter *adapter, union recv_frame *precv_frame) dump_rx_packet(ptr); else if ((bDumpRxPkt == 3) && (type == WIFI_DATA_TYPE)) dump_rx_packet(ptr); -} switch (type) { case WIFI_MGT_TYPE: /* mgnt */ -- 2.12.0
[PATCH 13/22] staging: rtl8723bs: Fix indenting mistake in core/rtw_ap.c
Smatch reports the following: CHECK drivers/staging/rtl8723bs/core/rtw_ap.c drivers/staging/rtl8723bs/core/rtw_ap.c:382 expire_timeout_chk() warn: inconsistent indenting Fixing this requires changing the indentatikon of a long for loop. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_ap.c | 99 - 1 file changed, 47 insertions(+), 52 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_ap.c b/drivers/staging/rtl8723bs/core/rtw_ap.c index 9c71692a3a05..68b750275dff 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ap.c +++ b/drivers/staging/rtl8723bs/core/rtw_ap.c @@ -379,70 +379,65 @@ void expire_timeout_chk(struct adapter *padapter) spin_unlock_bh(&pstapriv->asoc_list_lock); -if (chk_alive_num) { + if (chk_alive_num) { + u8 backup_oper_channel = 0; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + + /* switch to correct channel of current network before issue keep-alive frames */ + if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { + backup_oper_channel = rtw_get_oper_ch(padapter); + SelectChannel(padapter, pmlmeext->cur_channel); + } - u8 backup_oper_channel = 0; - struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - /* switch to correct channel of current network before issue keep-alive frames */ - if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) { - backup_oper_channel = rtw_get_oper_ch(padapter); - SelectChannel(padapter, pmlmeext->cur_channel); - } + /* issue null data to check sta alive*/ + for (i = 0; i < chk_alive_num; i++) { + int ret = _FAIL; - /* issue null data to check sta alive*/ - for (i = 0; i < chk_alive_num; i++) { - int ret = _FAIL; + psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); + if (!(psta->state & _FW_LINKED)) + continue; - psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); - if (!(psta->state & _FW_LINKED)) - continue; + if (psta->state & WIFI_SLEEP_STATE) + ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50); + else + ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50); - if (psta->state & WIFI_SLEEP_STATE) - ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50); - else - ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50); + psta->keep_alive_trycnt++; + if (ret == _SUCCESS) { + DBG_871X( + "asoc check, sta(" MAC_FMT ") is alive\n", + MAC_ARG(psta->hwaddr) + ); + psta->expire_to = pstapriv->expire_to; + psta->keep_alive_trycnt = 0; + continue; + } else if (psta->keep_alive_trycnt <= 3) { - psta->keep_alive_trycnt++; - if (ret == _SUCCESS) { + DBG_871X( + "ack check for asoc expire, keep_alive_trycnt =%d\n", + psta->keep_alive_trycnt); + psta->expire_to = 1; + continue; + } - DBG_871X( - "asoc check, sta(" MAC_FMT ") is alive\n", - MAC_ARG(psta->hwaddr) - ); - psta->expire_to = pstapriv->expire_to; psta->keep_alive_trycnt = 0; - continue; - } else if (psta->keep_alive_trycnt <= 3) { - - DBG_871X( - "ack check for asoc expire, keep_alive_trycnt =%d\n", - psta->keep_alive_trycnt - ); - psta->expire_to = 1; - continue; - } - - psta->keep_alive_trycnt = 0; - DBG_871X( - "asoc expire "MAC_FMT", state = 0x%x\n", - MAC_ARG(psta->hwaddr), - psta->state - ); - spin_lock_bh(&pstapriv->asoc_list_lock); - if (list_empty(&psta->asoc_list) == false) { - list_del_init(&psta->asoc_list); - pstapriv->asoc_list_cnt--; - updated = ap_free_st
[PATCH 20/22] staging rtl8723bs: Fix indenting errors and an off-by-one mistake in core/rtw_mlme_ext.c
Smatch lists the following: CHECK drivers/staging/rtl8723bs/core/rtw_mlme_ext.c drivers/staging/rtl8723bs/core/rtw_mlme_ext.c:525 _mgt_dispatcher() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_mlme_ext.c:1595 OnAssocReq() error: buffer overflow 'pstapriv->sta_aid' 32 <= 32 drivers/staging/rtl8723bs/core/rtw_mlme_ext.c:2391 dump_mgntframe_and_wait() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_mlme_ext.c:2420 dump_mgntframe_and_wait_ack() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_mlme_ext.c:4969 process_80211d() error: testing array offset 'i' after use. drivers/staging/rtl8723bs/core/rtw_mlme_ext.c:5738 linked_status_chk() warn: inconsistent indenting drivers/staging/rtl8723bs/core/rtw_mlme_ext.c:6459 sitesurvey_cmd_hdl() warn: inconsistent indenting The indenting problems were fixed with white-space changes. The error at line 1595 was the result of an off-by-one error in a for loop. The error at line 4969 was not fixed as that code lies inside a block of code that only is needed for 5G channels. This chip only works at 2.4 GHz. Signed-off-by: Larry Finger --- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 25 - 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index e0a3cd64777f..18e78d5198c3 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -522,15 +522,14 @@ static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptabl u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; u8 *pframe = precv_frame->u.hdr.rx_data; - if (ptable->func) { -/* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ - if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && - memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) - return; - - ptable->func(padapter, precv_frame); - } + if (ptable->func) { + /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ + if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && + memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) + return; + ptable->func(padapter, precv_frame); + } } void mgt_dispatcher(struct adapter *padapter, union recv_frame *precv_frame) @@ -1575,7 +1574,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) if (pstat->aid > 0) { DBG_871X(" old AID %d\n", pstat->aid); } else { - for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) + for (pstat->aid = 1; pstat->aid < NUM_STA; pstat->aid++) if (pstapriv->sta_aid[pstat->aid - 1] == NULL) break; @@ -2388,7 +2387,7 @@ s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntfr pxmitbuf->sctx = NULL; spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL); -return ret; + return ret; } s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe) @@ -2417,7 +2416,7 @@ s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmg mutex_unlock(&pxmitpriv->ack_tx_mutex); } -return ret; + return ret; } static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) @@ -5735,7 +5734,7 @@ void linked_status_chk(struct adapter *padapter) #else rx_chk_limit = 8; #endif - link_count_limit = 7; /* 16 sec */ + link_count_limit = 7; /* 16 sec */ /* Marked by Kurt 20130715 */ /* For WiDi 3.5 and latered on, they don't ask WiDi sink to do roaming, so we could not check rx limit that strictly. */ @@ -6456,7 +6455,7 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); /* config the initial gain under scaning, need to write the BB registers */ - initialgain = 0x1e; + initialgain = 0x1e; rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); -- 2.12.0
Re: pull-request: can 2017-04-04,Re: pull-request: can 2017-04-04
From: Marc Kleine-Budde Date: Fri, 7 Apr 2017 11:00:20 +0200 > Sorry. The "tag" some git lost, here it is: ... > git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git > tags/linux-can-fixes-for-4.12-20170404 Thanks, and pulled, but you probably meant to name this linux-can-fixes-for-4.11-something... not 4.12-something...
[PATCH] net: netfilter: ipvs: Replace explicit NULL comparison
Replace explicit NULL comparison to simplify code. Signed-off-by: Arushi Singhal --- net/netfilter/ipvs/ip_vs_ctl.c | 40 net/netfilter/ipvs/ip_vs_proto.c | 22 +++--- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 5aeb0dde6ccc..481dcfa5f2c6 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -436,7 +436,7 @@ ip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol svc = __ip_vs_service_find(ipvs, af, protocol, vaddr, FTPPORT); } - if (svc == NULL + if (!svc && atomic_read(&ipvs->nullsvc_counter)) { /* * Check if the catch-all port (port zero) exists @@ -910,7 +910,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest, } dest = kzalloc(sizeof(struct ip_vs_dest), GFP_KERNEL); - if (dest == NULL) + if (!dest) return -ENOMEM; dest->stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); @@ -983,7 +983,7 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) dest = ip_vs_lookup_dest(svc, udest->af, &daddr, dport); rcu_read_unlock(); - if (dest != NULL) { + if (dest) { IP_VS_DBG(1, "%s(): dest already exists\n", __func__); return -EEXIST; } @@ -994,7 +994,7 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) */ dest = ip_vs_trash_get_dest(svc, udest->af, &daddr, dport); - if (dest != NULL) { + if (dest) { IP_VS_DBG_BUF(3, "Get destination %s:%u from trash, " "dest->refcnt=%d, service %u/%s:%u\n", IP_VS_DBG_ADDR(udest->af, &daddr), ntohs(dport), @@ -1047,7 +1047,7 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) dest = ip_vs_lookup_dest(svc, udest->af, &daddr, dport); rcu_read_unlock(); - if (dest == NULL) { + if (!dest) { IP_VS_DBG(1, "%s(): dest doesn't exist\n", __func__); return -ENOENT; } @@ -1129,7 +1129,7 @@ ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) dest = ip_vs_lookup_dest(svc, udest->af, &udest->addr, dport); rcu_read_unlock(); - if (dest == NULL) { + if (!dest) { IP_VS_DBG(1, "%s(): destination not found!\n", __func__); return -ENOENT; } @@ -1208,7 +1208,7 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, if (u->pe_name && *u->pe_name) { pe = ip_vs_pe_getbyname(u->pe_name); - if (pe == NULL) { + if (!pe) { pr_info("persistence engine module ip_vs_pe_%s " "not found\n", u->pe_name); ret = -ENOENT; @@ -1228,7 +1228,7 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, #endif svc = kzalloc(sizeof(struct ip_vs_service), GFP_KERNEL); - if (svc == NULL) { + if (!svc) { IP_VS_DBG(1, "%s(): no memory\n", __func__); ret = -ENOMEM; goto out_err; @@ -1299,7 +1299,7 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, out_err: - if (svc != NULL) { + if (svc) { ip_vs_unbind_scheduler(svc, sched); ip_vs_service_free(svc); } @@ -1339,7 +1339,7 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) if (u->pe_name && *u->pe_name) { pe = ip_vs_pe_getbyname(u->pe_name); - if (pe == NULL) { + if (!pe) { pr_info("persistence engine module ip_vs_pe_%s " "not found\n", u->pe_name); ret = -ENOENT; @@ -1476,7 +1476,7 @@ static void ip_vs_unlink_service(struct ip_vs_service *svc, bool cleanup) */ static int ip_vs_del_service(struct ip_vs_service *svc) { - if (svc == NULL) + if (!svc) return -EEXIST; ip_vs_unlink_service(svc, false); @@ -2446,14 +2446,14 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) rcu_read_unlock(); if (cmd != IP_VS_SO_SET_ADD - && (svc == NULL || svc->protocol != usvc.protocol)) { + && (!svc || svc->protocol != usvc.protocol)) { ret = -ESRCH; goto out_unlock; } switch (cmd) { case IP_VS_SO_SET_ADD: - if (svc != NULL) + if (svc) ret = -EEXIST; else
[PATCH] net: netfilter: Replace explicit NULL comparisons
Replace explicit NULL comparison with ! operator to simplify code. Signed-off-by: Arushi Singhal --- net/netfilter/nf_conntrack_broadcast.c | 2 +- net/netfilter/nf_conntrack_core.c | 2 +- net/netfilter/nf_conntrack_ecache.c| 4 +-- net/netfilter/nf_conntrack_helper.c| 4 +-- net/netfilter/nf_conntrack_proto.c | 4 +-- net/netfilter/nf_log.c | 2 +- net/netfilter/nf_nat_redirect.c| 2 +- net/netfilter/nf_tables_api.c | 62 +- net/netfilter/nfnetlink_log.c | 6 ++-- net/netfilter/nfnetlink_queue.c| 8 ++--- net/netfilter/nft_compat.c | 4 +-- net/netfilter/nft_ct.c | 10 +++--- net/netfilter/nft_dynset.c | 14 net/netfilter/nft_log.c| 14 net/netfilter/nft_lookup.c | 2 +- net/netfilter/nft_payload.c| 4 +-- net/netfilter/nft_set_hash.c | 4 +-- net/netfilter/x_tables.c | 8 ++--- net/netfilter/xt_TCPMSS.c | 4 +-- net/netfilter/xt_addrtype.c| 2 +- net/netfilter/xt_connlimit.c | 2 +- net/netfilter/xt_conntrack.c | 2 +- net/netfilter/xt_hashlimit.c | 4 +-- net/netfilter/xt_recent.c | 6 ++-- 24 files changed, 88 insertions(+), 88 deletions(-) diff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c index 4e99cca61612..a016d47e5a80 100644 --- a/net/netfilter/nf_conntrack_broadcast.c +++ b/net/netfilter/nf_conntrack_broadcast.c @@ -42,7 +42,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, rcu_read_lock(); in_dev = __in_dev_get_rcu(rt->dst.dev); - if (in_dev != NULL) { + if (in_dev) { for_primary_ifa(in_dev) { if (ifa->ifa_broadcast == iph->daddr) { mask = ifa->ifa_mask; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index ffb78e5f7b70..282d7ec1acba 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1345,7 +1345,7 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, /* It may be an special packet, error, unclean... * inverse of the return code tells to the netfilter * core what to do with the packet. */ - if (l4proto->error != NULL) { + if (l4proto->error) { ret = l4proto->error(net, tmpl, skb, dataoff, pf, hooknum); if (ret <= 0) { NF_CT_STAT_INC_ATOMIC(net, error); diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c index da9df2d56e66..11184cae5329 100644 --- a/net/netfilter/nf_conntrack_ecache.c +++ b/net/netfilter/nf_conntrack_ecache.c @@ -266,7 +266,7 @@ int nf_conntrack_register_notifier(struct net *net, mutex_lock(&nf_ct_ecache_mutex); notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb, lockdep_is_held(&nf_ct_ecache_mutex)); - if (notify != NULL) { + if (notify) { ret = -EBUSY; goto out_unlock; } @@ -302,7 +302,7 @@ int nf_ct_expect_register_notifier(struct net *net, mutex_lock(&nf_ct_ecache_mutex); notify = rcu_dereference_protected(net->ct.nf_expect_event_cb, lockdep_is_held(&nf_ct_ecache_mutex)); - if (notify != NULL) { + if (notify) { ret = -EBUSY; goto out_unlock; } diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 6dc44d9b4190..fda6348a88e5 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c @@ -224,9 +224,9 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, if (test_bit(IPS_HELPER_BIT, &ct->status)) return 0; - if (tmpl != NULL) { + if (tmpl) { help = nfct_help(tmpl); - if (help != NULL) { + if (help) { helper = help->helper; set_bit(IPS_HELPER_BIT, &ct->status); } diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 2d6ee1803415..cb1e1593fc82 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -307,7 +307,7 @@ int nf_ct_l4proto_register_sysctl(struct net *net, int err = 0; #ifdef CONFIG_SYSCTL - if (pn->ctl_table != NULL) { + if (pn->ctl_table) { err = nf_ct_register_sysctl(net, &pn->ctl_table_header, "net/netfilter", @@ -329,7 +329,7 @@ void nf_ct_l4proto_unregister_sysctl(struct net *net, struct
Re: [PATCH net-next v2] can: initial support for network namespaces
Hello Mario, unfortunately Marc pushed this patch before I finally was able to review it ... :-( Some questions: On 02/21/2017 12:19 PM, Mario Kicherer wrote: This patch adds initial support for network namespaces. The changes only enable support in the CAN raw, proc and af_can code. GW and BCM still have their checks that ensure that they are used only from the main namespace. The patch boils down to moving the global structures, i.e. the global filter list and their /proc stats, into a per-namespace structure and passing around the corresponding "struct net" in a lot of different places. (..) diff --git a/include/net/netns/can.h b/include/net/netns/can.h new file mode 100644 index 000..e8beba7 --- /dev/null +++ b/include/net/netns/can.h @@ -0,0 +1,31 @@ +/* + * can in net namespaces + */ + +#ifndef __NETNS_CAN_H__ +#define __NETNS_CAN_H__ + +#include + +struct dev_rcv_lists; + +struct netns_can { +#if IS_ENABLED(CONFIG_PROC_FS) + struct proc_dir_entry *proc_dir; + struct proc_dir_entry *pde_version; + struct proc_dir_entry *pde_stats; + struct proc_dir_entry *pde_reset_stats; + struct proc_dir_entry *pde_rcvlist_all; + struct proc_dir_entry *pde_rcvlist_fil; + struct proc_dir_entry *pde_rcvlist_inv; + struct proc_dir_entry *pde_rcvlist_sff; + struct proc_dir_entry *pde_rcvlist_eff; + struct proc_dir_entry *pde_rcvlist_err; +#endif + + /* receive filters subscribed for 'all' CAN devices */ + struct dev_rcv_lists *can_rx_alldev_list; + spinlock_t can_rcvlists_lock; You didn't include the statistics here: + struct s_stats *can_stats; /* packet statistics */ + struct s_pstats *can_pstats;/* receive list statistics */ which need to be per-net too, right? (..) @@ -877,6 +871,41 @@ static int can_notifier(struct notifier_block *nb, unsigned long msg, return NOTIFY_DONE; } +int can_pernet_init(struct net *net) +{ + net->can.can_rcvlists_lock = + __SPIN_LOCK_UNLOCKED(net->can.can_rcvlists_lock); + net->can.can_rx_alldev_list = + kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL); + memset(net->can.can_rx_alldev_list, 0, sizeof(struct dev_rcv_lists)); + + if (IS_ENABLED(CONFIG_PROC_FS)) + can_init_proc(net); + + return 0; +} + +void can_pernet_exit(struct net *net) +{ + struct net_device *dev; + + if (IS_ENABLED(CONFIG_PROC_FS)) + can_remove_proc(net); + + /* remove created dev_rcv_lists from still registered CAN devices */ + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->type == ARPHRD_CAN && dev->ml_priv) { + struct dev_rcv_lists *d = dev->ml_priv; + + BUG_ON(d->entries); + kfree(d); + dev->ml_priv = NULL; + } + } + rcu_read_unlock(); You do a kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL) in can_pernet_init(). Doesn't it need a kfree(net->can.can_rx_alldev_list) then?? Regards, Oliver
[PATCH 3/5] netlink: allow sending extended ACK with cookie on success
From: Johannes Berg Now that we have extended error reporting and a new message format for netlink ACK messages, also extend this to be able to return arbitrary cookie data on success. This will allow, for example, nl80211 to not send an extra message for cookies identifying newly created objects, but return those directly in the ACK message. The cookie data size is currently limited to 32 bytes (since Jamal talked about using SHA1 for identifiers.) Signed-off-by: Johannes Berg --- include/linux/netlink.h | 3 +++ include/uapi/linux/netlink.h | 4 net/netlink/af_netlink.c | 38 -- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 47562e940e9c..2133353b9a30 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -62,6 +62,9 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg) return __netlink_kernel_create(net, unit, THIS_MODULE, cfg); } +/* this can be increased when necessary - don't expose to userland */ +#define NETLINK_MAX_COOKIE_LEN 32 + /** * struct netlink_ext_ack - netlink extended ACK report struct * @_msg: message string to report - don't access directly, use diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h index d1564557d645..7892095b1a16 100644 --- a/include/uapi/linux/netlink.h +++ b/include/uapi/linux/netlink.h @@ -118,12 +118,16 @@ struct nlmsgerr { * @NLMSGERR_ATTR_OFFS: error offset in the original message (u32) * @NLMSGERR_ATTR_ATTR: top-level attribute that caused the error * (or is missing, u16) + * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to + * be used - in the success case - to identify a created + * object or operation or similar (binary) */ enum nlmsgerr_attrs { NLMSGERR_ATTR_UNUSED, NLMSGERR_ATTR_MSG, NLMSGERR_ATTR_OFFS, NLMSGERR_ATTR_ATTR, + NLMSGERR_ATTR_COOKIE, }; #define NETLINK_ADD_MEMBERSHIP 1 diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 02cffb0a3904..bc1c9e8dd7ef 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2312,6 +2312,9 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, (extack->missing_attr || extack->bad_attr)) acksize += nla_total_size(sizeof(u16)); } + } else if (nlk->flags & NETLINK_F_EXT_ACK) { + if (extack && extack->cookie_len) + acksize += nla_total_size(extack->cookie_len); } skb = nlmsg_new(acksize, GFP_KERNEL); @@ -2337,20 +2340,27 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, !(nlk->flags & NETLINK_F_CAP_ACK) ? nlh->nlmsg_len : sizeof(*nlh)); - if (err && nlk->flags & NETLINK_F_EXT_ACK) { - if (extack && extack->_msg) - WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, - extack->_msg)); - if (extack && extack->bad_attr && - !WARN_ON((u8 *)extack->bad_attr < in_skb->data || -(u8 *)extack->bad_attr >= in_skb->data + - in_skb->len)) - WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, - (u8 *)extack->bad_attr - - in_skb->data)); - if (extack && extack->missing_attr) - WARN_ON(nla_put_u16(skb, NLMSGERR_ATTR_ATTR, - extack->missing_attr)); + if (nlk->flags & NETLINK_F_EXT_ACK) { + if (err) { + if (extack && extack->_msg) + WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, + extack->_msg)); + if (extack && extack->bad_attr && + !WARN_ON((u8 *)extack->bad_attr < in_skb->data || +(u8 *)extack->bad_attr >= in_skb->data + + in_skb->len)) + WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, + (u8 *)extack->bad_attr - + in_skb->data)); + if (extack && extack->missing_attr) + WARN_ON(nla_put_u16(skb, NLMSGERR_ATTR_ATTR, + extack->missing_attr)); + } else { + if (extack && extack->cookie_len) + WARN_ON(nla_put(skb, NLMSGERR_ATTR_COOKIE, +
[PATCH 1/5] netlink: extended ACK reporting
From: Johannes Berg Add the base infrastructure and UAPI for netlink extended ACK reporting. All "manual" calls to netlink_ack() pass NULL for now and thus don't get extended ACK reporting. Signed-off-by: Johannes Berg --- crypto/crypto_user.c | 3 +- drivers/infiniband/core/netlink.c | 5 +-- drivers/scsi/scsi_netlink.c | 2 +- include/linux/netlink.h | 32 - include/net/netlink.h | 3 +- include/uapi/linux/netlink.h | 24 + kernel/audit.c| 2 +- net/core/rtnetlink.c | 3 +- net/core/sock_diag.c | 3 +- net/hsr/hsr_netlink.c | 4 +-- net/netfilter/ipset/ip_set_core.c | 2 +- net/netfilter/nfnetlink.c | 22 ++-- net/netlink/af_netlink.c | 72 ++- net/netlink/af_netlink.h | 1 + net/netlink/genetlink.c | 3 +- net/xfrm/xfrm_user.c | 3 +- 16 files changed, 151 insertions(+), 33 deletions(-) diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index a90404a0c5ff..4a44830741c1 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -483,7 +483,8 @@ static const struct crypto_link { [CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = { .doit = crypto_del_rng }, }; -static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) { struct nlattr *attrs[CRYPTOCFGA_MAX+1]; const struct crypto_link *link; diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c index 10469b0088b5..b784055423c8 100644 --- a/drivers/infiniband/core/netlink.c +++ b/drivers/infiniband/core/netlink.c @@ -146,7 +146,8 @@ int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh, } EXPORT_SYMBOL(ibnl_put_attr); -static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) { struct ibnl_client *client; int type = nlh->nlmsg_type; @@ -209,7 +210,7 @@ static void ibnl_rcv_reply_skb(struct sk_buff *skb) if (nlh->nlmsg_flags & NLM_F_REQUEST) return; - ibnl_rcv_msg(skb, nlh); + ibnl_rcv_msg(skb, nlh, NULL); msglen = NLMSG_ALIGN(nlh->nlmsg_len); if (msglen > skb->len) diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index 109802f776ed..50e624fb8307 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c @@ -111,7 +111,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) next_msg: if ((err) || (nlh->nlmsg_flags & NLM_F_ACK)) - netlink_ack(skb, nlh, err); + netlink_ack(skb, nlh, err, NULL); skb_pull(skb, rlen); } diff --git a/include/linux/netlink.h b/include/linux/netlink.h index da14ab61f363..47562e940e9c 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -62,11 +62,41 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg) return __netlink_kernel_create(net, unit, THIS_MODULE, cfg); } +/** + * struct netlink_ext_ack - netlink extended ACK report struct + * @_msg: message string to report - don't access directly, use + * %NL_SET_ERR_MSG + * @bad_attr: attribute with error + * @missing_attr: number of missing attr (or 0) + * @cookie: cookie data to return to userspace (for success) + * @cookie_len: actual cookie data length + */ +struct netlink_ext_ack { + const char *_msg; + const struct nlattr *bad_attr; + u16 missing_attr; + u8 cookie[NETLINK_MAX_COOKIE_LEN]; + u8 cookie_len; +}; + +/* Always use this macro, this allows later putting the + * message into a separate section or such for things + * like translation or listing all possible messages. + * Currently string formatting is not supported (due + * to the lack of an output buffer.) + */ +#define NL_SET_ERR_MSG(extack, msg) do { \ + static const char *_msg = (msg);\ + \ + (extack)->_msg = _msg; \ +} while (0) + extern void netlink_kernel_release(struct sock *sk); extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups); extern int netlink_change_ngroups(struct sock *sk, unsigned int groups); extern void __netlink_clear_multicast_users(struct sock *sk, unsigned int group); -extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err); +extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, + const struct netlink_ext_ack *extack); extern int netlink_has_listeners(struct sock *sk, unsigned int group); extern int net
[PATCH 4/5] netlink: pass extended ACK struct to parsing functions
From: Johannes Berg Pass the new extended ACK reporting struct to all of the generic netlink parsing functions. For now, pass NULL in almost all callers (except for some in the core.) Signed-off-by: Johannes Berg --- crypto/crypto_user.c | 2 +- drivers/block/drbd/drbd_nla.c | 2 +- drivers/infiniband/core/addr.c| 2 +- drivers/infiniband/core/iwpm_util.c | 6 +- drivers/infiniband/core/sa_query.c| 4 +- drivers/net/macsec.c | 10 +-- drivers/net/team/team.c | 2 +- drivers/net/veth.c| 3 +- drivers/net/wireless/ath/ath10k/testmode.c| 4 +- drivers/net/wireless/ath/ath6kl/testmode.c| 4 +- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +- drivers/net/wireless/mac80211_hwsim.c | 4 +- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 4 +- drivers/net/wireless/ti/wlcore/testmode.c | 3 +- drivers/net/wireless/ti/wlcore/vendor_cmd.c | 4 +- include/net/genetlink.h | 8 ++- include/net/netlink.h | 33 +++--- include/net/rtnetlink.h | 3 +- lib/nlattr.c | 28 +--- net/8021q/vlan_netlink.c | 3 +- net/bridge/br_mdb.c | 3 +- net/bridge/br_netlink.c | 4 +- net/bridge/br_netlink_tunnel.c| 4 +- net/can/gw.c | 2 +- net/core/fib_rules.c | 4 +- net/core/lwt_bpf.c| 5 +- net/core/neighbour.c | 8 +-- net/core/net_namespace.c | 4 +- net/core/rtnetlink.c | 47 -- net/dcb/dcbnl.c | 57 - net/decnet/dn_dev.c | 4 +- net/decnet/dn_fib.c | 6 +- net/decnet/dn_route.c | 2 +- net/ieee802154/nl802154.c | 29 - net/ipv4/devinet.c| 12 ++-- net/ipv4/fib_frontend.c | 3 +- net/ipv4/ip_tunnel_core.c | 5 +- net/ipv4/ipmr.c | 3 +- net/ipv4/route.c | 3 +- net/ipv6/addrconf.c | 16 +++-- net/ipv6/addrlabel.c | 4 +- net/ipv6/ila/ila_lwt.c| 3 +- net/ipv6/route.c | 6 +- net/ipv6/seg6_iptunnel.c | 2 +- net/mpls/af_mpls.c| 5 +- net/mpls/mpls_iptunnel.c | 2 +- net/netfilter/ipset/ip_set_core.c | 27 net/netfilter/ipvs/ip_vs_ctl.c| 12 ++-- net/netfilter/nf_conntrack_netlink.c | 27 net/netfilter/nf_conntrack_proto_dccp.c | 2 +- net/netfilter/nf_conntrack_proto_sctp.c | 6 +- net/netfilter/nf_conntrack_proto_tcp.c| 3 +- net/netfilter/nf_nat_core.c | 5 +- net/netfilter/nf_tables_api.c | 27 net/netfilter/nfnetlink.c | 11 ++-- net/netfilter/nfnetlink_acct.c| 3 +- net/netfilter/nfnetlink_cthelper.c| 12 ++-- net/netfilter/nfnetlink_cttimeout.c | 3 +- net/netfilter/nfnetlink_queue.c | 2 +- net/netfilter/nft_compat.c| 2 +- net/netlabel/netlabel_cipso_v4.c | 19 +++--- net/netlink/genetlink.c | 2 +- net/nfc/netlink.c | 5 +- net/openvswitch/datapath.c| 2 +- net/openvswitch/flow_netlink.c| 4 +- net/openvswitch/vport-vxlan.c | 3 +- net/phonet/pn_netlink.c | 6 +- net/qrtr/qrtr.c | 2 +- net/sched/act_api.c | 20 +++--- net/sched/act_bpf.c | 2 +- net/sched/act_connmark.c | 3 +- net/sched/act_csum.c | 2 +- net/sched/act_gact.c | 2 +- net/sched/act_ife.c | 4 +- net/sched/act_ipt.c | 2 +- net/sched/act_mirred.c| 2 +- net/sched/act_nat.c | 2 +- net/sched/act_pedit.c | 4 +- net/sched/act_police.c| 2 +- net/sched/act_sample.c
[PATCH 0/5] extended netlink ACK reporting
Hi, After testing and fixing the ack message length calculation, this now works. The UAPI changes are like before - the ACK message format becomes [nlmsg header] [ack header] [request nlmsg header] [request nlmsg body (already optional) - length aligned] [extended ACK TLVs - this is NEW] The extended ACK TLVs currently are: For the error case: * MSG - string message * OFFS - offset of problem (e.g. malformed attribute) in the request message * ATTR - missing attribute ID For the success case: * COOKIE - arbitrary per-subsystem cookie to identify the newly created object or similar The whole behaviour can be enabled/disabled/queried using a new socket option NETLINK_EXT_ACK. johannes
[PATCH 2/5] genetlink: pass extended ACK report down
From: Johannes Berg Pass the extended ACK reporting struct down from generic netlink to the families, using the existing struct genl_info for simplicity. Also add support to set the extended ACK information from generic netlink users. Signed-off-by: Johannes Berg --- include/net/genetlink.h | 20 net/netlink/genetlink.c | 6 -- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/net/genetlink.h b/include/net/genetlink.h index a34275be3600..b81a4979e1db 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -84,6 +84,7 @@ struct nlattr **genl_family_attrbuf(const struct genl_family *family); * @attrs: netlink attributes * @_net: network namespace * @user_ptr: user pointers + * @extack: extended ACK report struct */ struct genl_info { u32 snd_seq; @@ -94,6 +95,7 @@ struct genl_info { struct nlattr **attrs; possible_net_t _net; void * user_ptr[2]; + struct netlink_ext_ack *extack; }; static inline struct net *genl_info_net(struct genl_info *info) @@ -106,6 +108,24 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net) write_pnet(&info->_net, net); } +#define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg) + +static inline int genl_err_attr(struct genl_info *info, int err, + struct nlattr *attr) +{ + info->extack->bad_attr = attr; + + return err; +} + +static inline int genl_err_attr_missing(struct genl_info *info, int err, + u16 attr) +{ + info->extack->missing_attr = attr; + + return err; +} + /** * struct genl_ops - generic netlink operations * @cmd: command identifier diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 57b2e3648bc0..4b598a5999a2 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -497,7 +497,8 @@ static int genl_lock_done(struct netlink_callback *cb) static int genl_family_rcv_msg(const struct genl_family *family, struct sk_buff *skb, - struct nlmsghdr *nlh) + struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) { const struct genl_ops *ops; struct net *net = sock_net(skb->sk); @@ -584,6 +585,7 @@ static int genl_family_rcv_msg(const struct genl_family *family, info.genlhdr = nlmsg_data(nlh); info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; info.attrs = attrbuf; + info.extack = extack; genl_info_net_set(&info, net); memset(&info.user_ptr, 0, sizeof(info.user_ptr)); @@ -618,7 +620,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, if (!family->parallel_ops) genl_lock(); - err = genl_family_rcv_msg(family, skb, nlh); + err = genl_family_rcv_msg(family, skb, nlh, extack); if (!family->parallel_ops) genl_unlock(); -- 2.11.0
[PATCH 5/5] netlink: pass extended ACK struct where available
From: Johannes Berg This is an add-on to the previous patch that passes the extended ACK structure where it's already available by existing genl_info or extack function arguments. This was done with this spatch (with some manual adjustment of indentation): @@ expression A, B, C, D, E; identifier fn, info; @@ fn(..., struct genl_info *info, ...) { ... -nlmsg_parse(A, B, C, D, E, NULL) +nlmsg_parse(A, B, C, D, E, info->extack) ... } @@ expression A, B, C, D, E; identifier fn, info; @@ fn(..., struct genl_info *info, ...) { <... -nla_parse_nested(A, B, C, D, NULL) +nla_parse_nested(A, B, C, D, info->extack) ...> } @@ expression A, B, C, D, E; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nlmsg_parse(A, B, C, D, E, NULL) +nlmsg_parse(A, B, C, D, E, extack) ...> } @@ expression A, B, C, D, E; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nla_parse(A, B, C, D, E, NULL) +nla_parse(A, B, C, D, E, extack) ...> } @@ expression A, B, C, D, E; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { ... -nlmsg_parse(A, B, C, D, E, NULL) +nlmsg_parse(A, B, C, D, E, extack) ... } @@ expression A, B, C, D; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nla_parse_nested(A, B, C, D, NULL) +nla_parse_nested(A, B, C, D, extack) ...> } @@ expression A, B, C, D; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nlmsg_validate(A, B, C, D, NULL) +nlmsg_validate(A, B, C, D, extack) ...> } @@ expression A, B, C, D; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nla_validate(A, B, C, D, NULL) +nla_validate(A, B, C, D, extack) ...> } @@ expression A, B, C; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nla_validate_nested(A, B, C, NULL) +nla_validate_nested(A, B, C, extack) ...> } Signed-off-by: Johannes Berg --- crypto/crypto_user.c | 2 +- drivers/net/team/team.c| 3 ++- net/ieee802154/nl802154.c | 10 +- net/netfilter/ipvs/ip_vs_ctl.c | 2 +- net/netfilter/nfnetlink.c | 2 +- net/netlink/genetlink.c| 2 +- net/nfc/netlink.c | 2 +- net/tipc/bearer.c | 14 +++--- net/tipc/net.c | 2 +- net/tipc/node.c| 8 net/wireless/nl80211.c | 33 ++--- net/xfrm/xfrm_user.c | 2 +- 12 files changed, 43 insertions(+), 39 deletions(-) diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index fc79906c1fe7..b5758768920b 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -523,7 +523,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, } err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX, - crypto_policy, NULL); + crypto_policy, extack); if (err < 0) return err; diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 86f227124ba1..65c056e2f705 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -2471,7 +2471,8 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) goto team_put; } err = nla_parse_nested(opt_attrs, TEAM_ATTR_OPTION_MAX, - nl_option, team_nl_option_policy, NULL); + nl_option, team_nl_option_policy, + info->extack); if (err) goto team_put; if (!opt_attrs[TEAM_ATTR_OPTION_NAME] || diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index d6b1a1b21909..99f6c254ea77 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -1564,7 +1564,7 @@ static int nl802154_add_llsec_key(struct sk_buff *skb, struct genl_info *info) if (nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], -nl802154_key_policy, NULL)) +nl802154_key_policy, info->extack)) return -EINVAL; if (!attrs[NL802154_KEY_ATTR_USAGE_FRAMES] || @@ -1614,7 +1614,7 @@ static int nl802154_del_llsec_key(struct sk_buff *skb, struct genl_info *info) if (nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], -nl802154_key_policy, NULL)) +nl802154_key_policy, info->extack)) return -EINVAL; if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0) @@ -1782,7 +1782,7 @@ static int nl802154_del_llsec_dev(struct sk_buff *skb, struct genl_info *info) if (nla_parse_nested(attrs, NL802154_DEV_ATTR_MAX,
Re: [PATCH 06/12] audit: Use timespec64 to represent audit timestamps
> I have no problem merging this patch into audit/next for v4.12, would > you prefer me to do that so at least this patch is merged? This would be fine. But, I think whoever takes the last 2 deletion patches should also take them. I'm not sure how that part works out. > It would probably make life a small bit easier for us in the audit > world too as it would reduce the potential merge conflict. However, > that's a relatively small thing to worry about. -Deepa
Re: [PATCH net-next 1/8] rtnetlink: Do not generate notifications for MTU events
On 4/7/17, 2:25 PM, David Ahern wrote: > Changing MTU on a link currently causes 3 messages to be sent to userspace: > > [LINK]11: dummy1: mtu 1490 qdisc noqueue state > UNKNOWN group default event PRE_CHANGE_MTU > link/ether f2:52:5c:6d:21:f3 brd ff:ff:ff:ff:ff:ff > > [LINK]11: dummy1: mtu 1500 qdisc noqueue state > UNKNOWN group default event CHANGE_MTU > link/ether f2:52:5c:6d:21:f3 brd ff:ff:ff:ff:ff:ff > > [LINK]11: dummy1: mtu 1500 qdisc noqueue state > UNKNOWN group default > link/ether f2:52:5c:6d:21:f3 brd ff:ff:ff:ff:ff:ff > > Remove the PRE_CHANGE_MTU and CHANGE_MTU messages. > > This change is good... multiple notifications for the same event does not help in large scale links setups. However, this reverts what vlad was trying to do with his patchset. Vlad's patch-set relies on the rtnl notifications generated from notifiers (rtnetlink_event) to add specific event (IFLA_EVENT) in notifications. The third notification in your example above is the correct one and is an aggregate notification for a set of changes, but it cannot really fill in all types of events in the single IFLA_EVENT attribute as it stands today. IFLA_EVENT should be a bitmask to include all events in this case (i had indicated this in vlads first version).
Re: [PATCH net-next v2] can: initial support for network namespaces
Hi Mario, I started to convert the statistics ... but there's some code adaption missing in proc.c Is this the right way to start? diff --git a/include/net/netns/can.h b/include/net/netns/can.h index e8beba772f1a..a8866ae1788f 100644 --- a/include/net/netns/can.h +++ b/include/net/netns/can.h @@ -8,6 +8,8 @@ #include struct dev_rcv_lists; +struct s_stats; +struct s_pstats; struct netns_can { #if IS_ENABLED(CONFIG_PROC_FS) @@ -26,6 +28,8 @@ struct netns_can { /* receive filters subscribed for 'all' CAN devices */ struct dev_rcv_lists *can_rx_alldev_list; spinlock_t can_rcvlists_lock; + struct s_stats *can_stats; /* packet statistics */ + struct s_pstats *can_pstats;/* receive list statistics */ }; #endif /* __NETNS_CAN_H__ */ diff --git a/net/can/af_can.c b/net/can/af_can.c index abf7d854a94d..db35d6a5ac26 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -84,8 +84,6 @@ static const struct can_proto *proto_tab[CAN_NPROTO] __read_mostly; static DEFINE_MUTEX(proto_tab_lock); struct timer_list can_stattimer; /* timer for statistics update */ -struct s_statscan_stats; /* packet statistics */ -struct s_pstats can_pstats; /* receive list statistics */ static atomic_t skbcounter = ATOMIC_INIT(0); @@ -223,6 +221,7 @@ int can_send(struct sk_buff *skb, int loop) { struct sk_buff *newskb = NULL; struct canfd_frame *cfd = (struct canfd_frame *)skb->data; + struct net *net = dev_net(skb->dev); int err = -EINVAL; if (skb->len == CAN_MTU) { @@ -311,8 +310,8 @@ int can_send(struct sk_buff *skb, int loop) netif_rx_ni(newskb); /* update statistics */ - can_stats.tx_frames++; - can_stats.tx_frames_delta++; + net->can.can_stats->tx_frames++; + net->can.can_stats->tx_frames_delta++; return 0; @@ -501,9 +500,9 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id, hlist_add_head_rcu(&r->list, rl); d->entries++; - can_pstats.rcv_entries++; - if (can_pstats.rcv_entries_max < can_pstats.rcv_entries) - can_pstats.rcv_entries_max = can_pstats.rcv_entries; + net->can.can_pstats->rcv_entries++; + if (net->can.can_pstats->rcv_entries_max < net->can.can_pstats->rcv_entries) + net->can.can_pstats->rcv_entries_max = net->can.can_pstats->rcv_entries; } else { kmem_cache_free(rcv_cache, r); err = -ENODEV; @@ -591,8 +590,8 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id, hlist_del_rcu(&r->list); d->entries--; - if (can_pstats.rcv_entries > 0) - can_pstats.rcv_entries--; + if (net->can.can_pstats->rcv_entries > 0) + net->can.can_pstats->rcv_entries--; /* remove device structure requested by NETDEV_UNREGISTER */ if (d->remove_on_zero_entries && !d->entries) { @@ -686,11 +685,12 @@ static int can_rcv_filter(struct dev_rcv_lists *d, struct sk_buff *skb) static void can_receive(struct sk_buff *skb, struct net_device *dev) { struct dev_rcv_lists *d; + struct net *net = dev_net(dev); int matches; /* update statistics */ - can_stats.rx_frames++; - can_stats.rx_frames_delta++; + net->can.can_stats->rx_frames++; + net->can.can_stats->rx_frames_delta++; /* create non-zero unique skb identifier together with *skb */ while (!(can_skb_prv(skb)->skbcnt)) @@ -699,10 +699,10 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev) rcu_read_lock(); /* deliver the packet to sockets listening on all devices */ - matches = can_rcv_filter(dev_net(dev)->can.can_rx_alldev_list, skb); + matches = can_rcv_filter(net->can.can_rx_alldev_list, skb); /* find receive list for this device */ - d = find_dev_rcv_lists(dev_net(dev), dev); + d = find_dev_rcv_lists(net, dev); if (d) matches += can_rcv_filter(d, skb); @@ -712,8 +712,8 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev) consume_skb(skb); if (matches > 0) { - can_stats.matches++; - can_stats.matches_delta++; + net->can.can_stats->matches++; + net->can.can_stats->matches_delta++; } } @@ -878,6 +878,9 @@ static int can_pernet_init(struct net *net) net->can.can_rx_alldev_list = kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL); + net->can.can_stats = kzalloc(sizeof(struct s_stats), GFP_KERNEL); + net->can.can_pstats = kzalloc(sizeof(struct s_pstats), GFP_KERNEL); + if (IS_ENABLED(CONFIG_PROC_FS)) can_init_proc(net); diff --git a/net/can/af_can.h b/net/can/af_can.h index f273c9d9b129..10d46bd2e9ea 100644 --
Re: [PATCH net-next 1/8] rtnetlink: Do not generate notifications for MTU events
On 4/8/17 2:06 PM, Roopa Prabhu wrote: > On 4/7/17, 2:25 PM, David Ahern wrote: >> Changing MTU on a link currently causes 3 messages to be sent to userspace: >> >> [LINK]11: dummy1: mtu 1490 qdisc noqueue state >> UNKNOWN group default event PRE_CHANGE_MTU >> link/ether f2:52:5c:6d:21:f3 brd ff:ff:ff:ff:ff:ff >> >> [LINK]11: dummy1: mtu 1500 qdisc noqueue state >> UNKNOWN group default event CHANGE_MTU >> link/ether f2:52:5c:6d:21:f3 brd ff:ff:ff:ff:ff:ff >> >> [LINK]11: dummy1: mtu 1500 qdisc noqueue state >> UNKNOWN group default >> link/ether f2:52:5c:6d:21:f3 brd ff:ff:ff:ff:ff:ff >> >> Remove the PRE_CHANGE_MTU and CHANGE_MTU messages. >> >> > > This change is good... multiple notifications for the same event does not > help in large scale links setups. However, this > reverts what vlad was trying to do with his patchset. Vlad's patch-set relies > on the rtnl notifications generated from > notifiers (rtnetlink_event) to add specific event (IFLA_EVENT) in > notifications. > > The third notification in your example above is the correct one and is an > aggregate notification for a set of changes, but > it cannot really fill in all types of events in the single IFLA_EVENT > attribute as it stands today. IFLA_EVENT should be > a bitmask to include all events in this case (i had indicated this in vlads > first version). > Agreed. I think it would be best to revert def12888c161 before the UAPI goes out. The change can instead add the IFLA_EVENT as a bitmask mentioned here to note the changes in a setlink. On top of that, remove the notifications for the events I mentioned in this set to reduce the overhead on userspace.
Re: [PATCH net-next 1/8] rtnetlink: Do not generate notifications for MTU events
On 4/8/17, 11:13 AM, David Ahern wrote: > On 4/8/17 2:06 PM, Roopa Prabhu wrote: >> On 4/7/17, 2:25 PM, David Ahern wrote: >>> Changing MTU on a link currently causes 3 messages to be sent to userspace: >>> >>> [LINK]11: dummy1: mtu 1490 qdisc noqueue >>> state UNKNOWN group default event PRE_CHANGE_MTU >>> link/ether f2:52:5c:6d:21:f3 brd ff:ff:ff:ff:ff:ff >>> >>> [LINK]11: dummy1: mtu 1500 qdisc noqueue >>> state UNKNOWN group default event CHANGE_MTU >>> link/ether f2:52:5c:6d:21:f3 brd ff:ff:ff:ff:ff:ff >>> >>> [LINK]11: dummy1: mtu 1500 qdisc noqueue >>> state UNKNOWN group default >>> link/ether f2:52:5c:6d:21:f3 brd ff:ff:ff:ff:ff:ff >>> >>> Remove the PRE_CHANGE_MTU and CHANGE_MTU messages. >>> >>> >> This change is good... multiple notifications for the same event does not >> help in large scale links setups. However, this >> reverts what vlad was trying to do with his patchset. Vlad's patch-set >> relies on the rtnl notifications generated from >> notifiers (rtnetlink_event) to add specific event (IFLA_EVENT) in >> notifications. >> >> The third notification in your example above is the correct one and is an >> aggregate notification for a set of changes, but >> it cannot really fill in all types of events in the single IFLA_EVENT >> attribute as it stands today. IFLA_EVENT should be >> a bitmask to include all events in this case (i had indicated this in vlads >> first version). >> > Agreed. I think it would be best to revert def12888c161 before the UAPI > goes out. > > The change can instead add the IFLA_EVENT as a bitmask mentioned here to > note the changes in a setlink. On top of that, remove the notifications > for the events I mentioned in this set to reduce the overhead on userspace. ack
Re: [PATCH] net: netfilter: Replace explicit NULL comparisons
On Saturday 2017-04-08 19:21, Arushi Singhal wrote: >Replace explicit NULL comparison with ! operator to simplify code. I still wouldn't do this, for the same reason as before. Comparing to NULL explicitly more or less gave an extra guarantee that the other operand was also a pointer.
Re: [PATCH 1/5] netlink: extended ACK reporting
On 4/8/17 1:48 PM, Johannes Berg wrote: > @@ -2267,21 +2284,37 @@ int __netlink_dump_start(struct sock *ssk, struct > sk_buff *skb, > } > EXPORT_SYMBOL(__netlink_dump_start); > > -void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) > +void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, > + const struct netlink_ext_ack *extack) > { > struct sk_buff *skb; > struct nlmsghdr *rep; > struct nlmsgerr *errmsg; > size_t payload = sizeof(*errmsg); > + size_t acksize = sizeof(*errmsg); > struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk); > > /* Error messages get the original request appened, unless the user > - * requests to cap the error message. > + * requests to cap the error message, and get extra error data if > + * requested. >*/ > - if (!(nlk->flags & NETLINK_F_CAP_ACK) && err) > - payload += nlmsg_len(nlh); > + if (err) { > + if (!(nlk->flags & NETLINK_F_CAP_ACK)) > + payload += nlmsg_len(nlh); > + acksize = payload; > + if (nlk->flags & NETLINK_F_EXT_ACK) { > + if (extack && extack->_msg) > + acksize += > + nla_total_size(strlen(extack->_msg) + > 1); > + if (extack && extack->bad_attr) > + acksize += nla_total_size(sizeof(u32)); > + if (extack && > + (extack->missing_attr || extack->bad_attr)) > + acksize += nla_total_size(sizeof(u16)); If you create a v3, the extack check can by pulled up to the (flags & NETLINK_F_EXT_ACK) check. > + } > + } > > - skb = nlmsg_new(payload, GFP_KERNEL); > + skb = nlmsg_new(acksize, GFP_KERNEL); > if (!skb) { > struct sock *sk; > > @@ -2300,14 +2333,35 @@ void netlink_ack(struct sk_buff *in_skb, struct > nlmsghdr *nlh, int err) > NLMSG_ERROR, payload, 0); > errmsg = nlmsg_data(rep); > errmsg->error = err; > - memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : > sizeof(*nlh)); > + memcpy(&errmsg->msg, nlh, > +!(nlk->flags & NETLINK_F_CAP_ACK) ? nlh->nlmsg_len > + : sizeof(*nlh)); > + > + if (err && nlk->flags & NETLINK_F_EXT_ACK) { > + if (extack && extack->_msg) > + WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, > +extack->_msg)); > + if (extack && extack->bad_attr && > + !WARN_ON((u8 *)extack->bad_attr < in_skb->data || > + (u8 *)extack->bad_attr >= in_skb->data + > +in_skb->len)) > + WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, > + (u8 *)extack->bad_attr - > + in_skb->data)); > + if (extack && extack->missing_attr) > + WARN_ON(nla_put_u16(skb, NLMSGERR_ATTR_ATTR, > + extack->missing_attr)); same here
Re: [PATCH 1/5] netlink: extended ACK reporting
Sat, Apr 08, 2017 at 07:48:56PM CEST, johan...@sipsolutions.net wrote: >From: Johannes Berg > >Add the base infrastructure and UAPI for netlink >extended ACK reporting. All "manual" calls to >netlink_ack() pass NULL for now and thus don't >get extended ACK reporting. Why so narrow? :) > >Signed-off-by: Johannes Berg >--- [...] >diff --git a/include/linux/netlink.h b/include/linux/netlink.h >index da14ab61f363..47562e940e9c 100644 >--- a/include/linux/netlink.h >+++ b/include/linux/netlink.h >@@ -62,11 +62,41 @@ netlink_kernel_create(struct net *net, int unit, struct >netlink_kernel_cfg *cfg) > return __netlink_kernel_create(net, unit, THIS_MODULE, cfg); > } > >+/** >+ * struct netlink_ext_ack - netlink extended ACK report struct >+ * @_msg: message string to report - don't access directly, use >+ *%NL_SET_ERR_MSG >+ * @bad_attr: attribute with error >+ * @missing_attr: number of missing attr (or 0) >+ * @cookie: cookie data to return to userspace (for success) >+ * @cookie_len: actual cookie data length >+ */ >+struct netlink_ext_ack { >+ const char *_msg; >+ const struct nlattr *bad_attr; >+ u16 missing_attr; >+ u8 cookie[NETLINK_MAX_COOKIE_LEN]; >+ u8 cookie_len; >+}; >+ >+/* Always use this macro, this allows later putting the >+ * message into a separate section or such for things >+ * like translation or listing all possible messages. >+ * Currently string formatting is not supported (due >+ * to the lack of an output buffer.) Please use 80 cols. [...] >@@ -2267,21 +2284,37 @@ int __netlink_dump_start(struct sock *ssk, struct >sk_buff *skb, > } > EXPORT_SYMBOL(__netlink_dump_start); > >-void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) >+void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, >+ const struct netlink_ext_ack *extack) > { > struct sk_buff *skb; > struct nlmsghdr *rep; > struct nlmsgerr *errmsg; > size_t payload = sizeof(*errmsg); >+ size_t acksize = sizeof(*errmsg); > struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk); > > /* Error messages get the original request appened, unless the user >- * requests to cap the error message. >+ * requests to cap the error message, and get extra error data if >+ * requested. >*/ >- if (!(nlk->flags & NETLINK_F_CAP_ACK) && err) >- payload += nlmsg_len(nlh); >+ if (err) { >+ if (!(nlk->flags & NETLINK_F_CAP_ACK)) >+ payload += nlmsg_len(nlh); >+ acksize = payload; >+ if (nlk->flags & NETLINK_F_EXT_ACK) { >+ if (extack && extack->_msg) >+ acksize += >+ nla_total_size(strlen(extack->_msg) + >1); >+ if (extack && extack->bad_attr) >+ acksize += nla_total_size(sizeof(u32)); >+ if (extack && >+ (extack->missing_attr || extack->bad_attr)) Attr could be 0, right? I know that on the most of the places 0 is UNSPEC, but I'm pretty sure not everywhere. >+ acksize += nla_total_size(sizeof(u16)); >+ } >+ } > >- skb = nlmsg_new(payload, GFP_KERNEL); >+ skb = nlmsg_new(acksize, GFP_KERNEL); > if (!skb) { > struct sock *sk; > [...] Look very good. Thanks for taking care of this!
[PATCH v2 3/5] netlink: allow sending extended ACK with cookie on success
From: Johannes Berg Now that we have extended error reporting and a new message format for netlink ACK messages, also extend this to be able to return arbitrary cookie data on success. This will allow, for example, nl80211 to not send an extra message for cookies identifying newly created objects, but return those directly in the ACK message. The cookie data size is currently limited to 32 bytes (since Jamal talked about using SHA1 for identifiers.) Thanks to Jamal Hadi Salim for bringing up this idea during the discussions. Signed-off-by: Johannes Berg --- include/linux/netlink.h | 3 +++ include/uapi/linux/netlink.h | 4 net/netlink/af_netlink.c | 38 -- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 47562e940e9c..2133353b9a30 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -62,6 +62,9 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg) return __netlink_kernel_create(net, unit, THIS_MODULE, cfg); } +/* this can be increased when necessary - don't expose to userland */ +#define NETLINK_MAX_COOKIE_LEN 32 + /** * struct netlink_ext_ack - netlink extended ACK report struct * @_msg: message string to report - don't access directly, use diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h index d1564557d645..7892095b1a16 100644 --- a/include/uapi/linux/netlink.h +++ b/include/uapi/linux/netlink.h @@ -118,12 +118,16 @@ struct nlmsgerr { * @NLMSGERR_ATTR_OFFS: error offset in the original message (u32) * @NLMSGERR_ATTR_ATTR: top-level attribute that caused the error * (or is missing, u16) + * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to + * be used - in the success case - to identify a created + * object or operation or similar (binary) */ enum nlmsgerr_attrs { NLMSGERR_ATTR_UNUSED, NLMSGERR_ATTR_MSG, NLMSGERR_ATTR_OFFS, NLMSGERR_ATTR_ATTR, + NLMSGERR_ATTR_COOKIE, }; #define NETLINK_ADD_MEMBERSHIP 1 diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index c74f56a4fcf1..98e55a59c97e 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2311,6 +2311,9 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, if (extack->missing_attr) acksize += nla_total_size(sizeof(u16)); } + } else if (nlk->flags & NETLINK_F_EXT_ACK) { + if (extack && extack->cookie_len) + acksize += nla_total_size(extack->cookie_len); } skb = nlmsg_new(acksize, GFP_KERNEL); @@ -2336,20 +2339,27 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, !(nlk->flags & NETLINK_F_CAP_ACK) ? nlh->nlmsg_len : sizeof(*nlh)); - if (err && nlk->flags & NETLINK_F_EXT_ACK && extack) { - if (extack->_msg) - WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, - extack->_msg)); - if (extack->bad_attr && - !WARN_ON((u8 *)extack->bad_attr < in_skb->data || -(u8 *)extack->bad_attr >= in_skb->data + - in_skb->len)) - WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, - (u8 *)extack->bad_attr - - in_skb->data)); - if (extack->missing_attr) - WARN_ON(nla_put_u16(skb, NLMSGERR_ATTR_ATTR, - extack->missing_attr)); + if (nlk->flags & NETLINK_F_EXT_ACK) { + if (err && extack) { + if (extack->_msg) + WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG, + extack->_msg)); + if (extack->bad_attr && + !WARN_ON((u8 *)extack->bad_attr < in_skb->data || +(u8 *)extack->bad_attr >= in_skb->data + + in_skb->len)) + WARN_ON(nla_put_u32(skb, NLMSGERR_ATTR_OFFS, + (u8 *)extack->bad_attr - + in_skb->data)); + if (extack->missing_attr) + WARN_ON(nla_put_u16(skb, NLMSGERR_ATTR_ATTR, + extack->missing_attr)); + } else if (!err && extack) { + if (extack->cookie_len) + WARN_ON(nla_put(skb, NLMSGERR_ATT
[PATCH v2 0/5]
Changes since v1: * credit Pablo and Jamal * incorporate suggestion from David Ahern * fix compilation in decnet
[PATCH v2 5/5] netlink: pass extended ACK struct where available
From: Johannes Berg This is an add-on to the previous patch that passes the extended ACK structure where it's already available by existing genl_info or extack function arguments. This was done with this spatch (with some manual adjustment of indentation): @@ expression A, B, C, D, E; identifier fn, info; @@ fn(..., struct genl_info *info, ...) { ... -nlmsg_parse(A, B, C, D, E, NULL) +nlmsg_parse(A, B, C, D, E, info->extack) ... } @@ expression A, B, C, D, E; identifier fn, info; @@ fn(..., struct genl_info *info, ...) { <... -nla_parse_nested(A, B, C, D, NULL) +nla_parse_nested(A, B, C, D, info->extack) ...> } @@ expression A, B, C, D, E; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nlmsg_parse(A, B, C, D, E, NULL) +nlmsg_parse(A, B, C, D, E, extack) ...> } @@ expression A, B, C, D, E; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nla_parse(A, B, C, D, E, NULL) +nla_parse(A, B, C, D, E, extack) ...> } @@ expression A, B, C, D, E; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { ... -nlmsg_parse(A, B, C, D, E, NULL) +nlmsg_parse(A, B, C, D, E, extack) ... } @@ expression A, B, C, D; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nla_parse_nested(A, B, C, D, NULL) +nla_parse_nested(A, B, C, D, extack) ...> } @@ expression A, B, C, D; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nlmsg_validate(A, B, C, D, NULL) +nlmsg_validate(A, B, C, D, extack) ...> } @@ expression A, B, C, D; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nla_validate(A, B, C, D, NULL) +nla_validate(A, B, C, D, extack) ...> } @@ expression A, B, C; identifier fn, extack; @@ fn(..., struct netlink_ext_ack *extack, ...) { <... -nla_validate_nested(A, B, C, NULL) +nla_validate_nested(A, B, C, extack) ...> } Signed-off-by: Johannes Berg --- crypto/crypto_user.c | 2 +- drivers/net/team/team.c| 3 ++- net/ieee802154/nl802154.c | 10 +- net/netfilter/ipvs/ip_vs_ctl.c | 2 +- net/netfilter/nfnetlink.c | 2 +- net/netlink/genetlink.c| 2 +- net/nfc/netlink.c | 2 +- net/tipc/bearer.c | 14 +++--- net/tipc/net.c | 2 +- net/tipc/node.c| 8 net/wireless/nl80211.c | 33 ++--- net/xfrm/xfrm_user.c | 2 +- 12 files changed, 43 insertions(+), 39 deletions(-) diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index fc79906c1fe7..b5758768920b 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -523,7 +523,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, } err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX, - crypto_policy, NULL); + crypto_policy, extack); if (err < 0) return err; diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 86f227124ba1..65c056e2f705 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -2471,7 +2471,8 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) goto team_put; } err = nla_parse_nested(opt_attrs, TEAM_ATTR_OPTION_MAX, - nl_option, team_nl_option_policy, NULL); + nl_option, team_nl_option_policy, + info->extack); if (err) goto team_put; if (!opt_attrs[TEAM_ATTR_OPTION_NAME] || diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index d6b1a1b21909..99f6c254ea77 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -1564,7 +1564,7 @@ static int nl802154_add_llsec_key(struct sk_buff *skb, struct genl_info *info) if (nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], -nl802154_key_policy, NULL)) +nl802154_key_policy, info->extack)) return -EINVAL; if (!attrs[NL802154_KEY_ATTR_USAGE_FRAMES] || @@ -1614,7 +1614,7 @@ static int nl802154_del_llsec_key(struct sk_buff *skb, struct genl_info *info) if (nla_parse_nested(attrs, NL802154_KEY_ATTR_MAX, info->attrs[NL802154_ATTR_SEC_KEY], -nl802154_key_policy, NULL)) +nl802154_key_policy, info->extack)) return -EINVAL; if (ieee802154_llsec_parse_key_id(attrs[NL802154_KEY_ATTR_ID], &id) < 0) @@ -1782,7 +1782,7 @@ static int nl802154_del_llsec_dev(struct sk_buff *skb, struct genl_info *info) if (nla_parse_nested(attrs, NL802154_DEV_ATTR_MAX,
[PATCH v2 1/5] netlink: extended ACK reporting
From: Johannes Berg Add the base infrastructure and UAPI for netlink extended ACK reporting. All "manual" calls to netlink_ack() pass NULL for now and thus don't get extended ACK reporting. Big thanks goes to Pablo Neira Ayuso for not only bringing up the whole topic at netconf (again) but also coming up with the nlattr passing trick and various other ideads. Signed-off-by: Johannes Berg --- crypto/crypto_user.c | 3 +- drivers/infiniband/core/netlink.c | 5 +-- drivers/scsi/scsi_netlink.c | 2 +- include/linux/netlink.h | 32 +- include/net/netlink.h | 3 +- include/uapi/linux/netlink.h | 24 + kernel/audit.c| 2 +- net/core/rtnetlink.c | 3 +- net/core/sock_diag.c | 3 +- net/decnet/netfilter/dn_rtmsg.c | 2 +- net/hsr/hsr_netlink.c | 4 +-- net/netfilter/ipset/ip_set_core.c | 2 +- net/netfilter/nfnetlink.c | 22 ++-- net/netlink/af_netlink.c | 71 ++- net/netlink/af_netlink.h | 1 + net/netlink/genetlink.c | 3 +- net/xfrm/xfrm_user.c | 3 +- 17 files changed, 151 insertions(+), 34 deletions(-) diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index a90404a0c5ff..4a44830741c1 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -483,7 +483,8 @@ static const struct crypto_link { [CRYPTO_MSG_DELRNG - CRYPTO_MSG_BASE] = { .doit = crypto_del_rng }, }; -static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) { struct nlattr *attrs[CRYPTOCFGA_MAX+1]; const struct crypto_link *link; diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c index 10469b0088b5..b784055423c8 100644 --- a/drivers/infiniband/core/netlink.c +++ b/drivers/infiniband/core/netlink.c @@ -146,7 +146,8 @@ int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh, } EXPORT_SYMBOL(ibnl_put_attr); -static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) { struct ibnl_client *client; int type = nlh->nlmsg_type; @@ -209,7 +210,7 @@ static void ibnl_rcv_reply_skb(struct sk_buff *skb) if (nlh->nlmsg_flags & NLM_F_REQUEST) return; - ibnl_rcv_msg(skb, nlh); + ibnl_rcv_msg(skb, nlh, NULL); msglen = NLMSG_ALIGN(nlh->nlmsg_len); if (msglen > skb->len) diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index 109802f776ed..50e624fb8307 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c @@ -111,7 +111,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) next_msg: if ((err) || (nlh->nlmsg_flags & NLM_F_ACK)) - netlink_ack(skb, nlh, err); + netlink_ack(skb, nlh, err, NULL); skb_pull(skb, rlen); } diff --git a/include/linux/netlink.h b/include/linux/netlink.h index da14ab61f363..47562e940e9c 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -62,11 +62,41 @@ netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg) return __netlink_kernel_create(net, unit, THIS_MODULE, cfg); } +/** + * struct netlink_ext_ack - netlink extended ACK report struct + * @_msg: message string to report - don't access directly, use + * %NL_SET_ERR_MSG + * @bad_attr: attribute with error + * @missing_attr: number of missing attr (or 0) + * @cookie: cookie data to return to userspace (for success) + * @cookie_len: actual cookie data length + */ +struct netlink_ext_ack { + const char *_msg; + const struct nlattr *bad_attr; + u16 missing_attr; + u8 cookie[NETLINK_MAX_COOKIE_LEN]; + u8 cookie_len; +}; + +/* Always use this macro, this allows later putting the + * message into a separate section or such for things + * like translation or listing all possible messages. + * Currently string formatting is not supported (due + * to the lack of an output buffer.) + */ +#define NL_SET_ERR_MSG(extack, msg) do { \ + static const char *_msg = (msg);\ + \ + (extack)->_msg = _msg; \ +} while (0) + extern void netlink_kernel_release(struct sock *sk); extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups); extern int netlink_change_ngroups(struct sock *sk, unsigned int groups); extern void __netlink_clear_multicast_users(struct sock *sk, unsigned int group); -extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err); +extern void ne
[PATCH v2 2/5] genetlink: pass extended ACK report down
From: Johannes Berg Pass the extended ACK reporting struct down from generic netlink to the families, using the existing struct genl_info for simplicity. Also add support to set the extended ACK information from generic netlink users. Signed-off-by: Johannes Berg --- include/net/genetlink.h | 20 net/netlink/genetlink.c | 6 -- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/include/net/genetlink.h b/include/net/genetlink.h index a34275be3600..b81a4979e1db 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -84,6 +84,7 @@ struct nlattr **genl_family_attrbuf(const struct genl_family *family); * @attrs: netlink attributes * @_net: network namespace * @user_ptr: user pointers + * @extack: extended ACK report struct */ struct genl_info { u32 snd_seq; @@ -94,6 +95,7 @@ struct genl_info { struct nlattr **attrs; possible_net_t _net; void * user_ptr[2]; + struct netlink_ext_ack *extack; }; static inline struct net *genl_info_net(struct genl_info *info) @@ -106,6 +108,24 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net) write_pnet(&info->_net, net); } +#define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg) + +static inline int genl_err_attr(struct genl_info *info, int err, + struct nlattr *attr) +{ + info->extack->bad_attr = attr; + + return err; +} + +static inline int genl_err_attr_missing(struct genl_info *info, int err, + u16 attr) +{ + info->extack->missing_attr = attr; + + return err; +} + /** * struct genl_ops - generic netlink operations * @cmd: command identifier diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 57b2e3648bc0..4b598a5999a2 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -497,7 +497,8 @@ static int genl_lock_done(struct netlink_callback *cb) static int genl_family_rcv_msg(const struct genl_family *family, struct sk_buff *skb, - struct nlmsghdr *nlh) + struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) { const struct genl_ops *ops; struct net *net = sock_net(skb->sk); @@ -584,6 +585,7 @@ static int genl_family_rcv_msg(const struct genl_family *family, info.genlhdr = nlmsg_data(nlh); info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; info.attrs = attrbuf; + info.extack = extack; genl_info_net_set(&info, net); memset(&info.user_ptr, 0, sizeof(info.user_ptr)); @@ -618,7 +620,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, if (!family->parallel_ops) genl_lock(); - err = genl_family_rcv_msg(family, skb, nlh); + err = genl_family_rcv_msg(family, skb, nlh, extack); if (!family->parallel_ops) genl_unlock(); -- 2.11.0
[PATCH v2 4/5] netlink: pass extended ACK struct to parsing functions
From: Johannes Berg Pass the new extended ACK reporting struct to all of the generic netlink parsing functions. For now, pass NULL in almost all callers (except for some in the core.) Signed-off-by: Johannes Berg --- crypto/crypto_user.c | 2 +- drivers/block/drbd/drbd_nla.c | 2 +- drivers/infiniband/core/addr.c| 2 +- drivers/infiniband/core/iwpm_util.c | 6 +- drivers/infiniband/core/sa_query.c| 4 +- drivers/net/macsec.c | 10 +-- drivers/net/team/team.c | 2 +- drivers/net/veth.c| 3 +- drivers/net/wireless/ath/ath10k/testmode.c| 4 +- drivers/net/wireless/ath/ath6kl/testmode.c| 4 +- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +- drivers/net/wireless/mac80211_hwsim.c | 4 +- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 4 +- drivers/net/wireless/ti/wlcore/testmode.c | 3 +- drivers/net/wireless/ti/wlcore/vendor_cmd.c | 4 +- include/net/genetlink.h | 8 ++- include/net/netlink.h | 33 +++--- include/net/rtnetlink.h | 3 +- lib/nlattr.c | 28 +--- net/8021q/vlan_netlink.c | 3 +- net/bridge/br_mdb.c | 3 +- net/bridge/br_netlink.c | 4 +- net/bridge/br_netlink_tunnel.c| 4 +- net/can/gw.c | 2 +- net/core/fib_rules.c | 4 +- net/core/lwt_bpf.c| 5 +- net/core/neighbour.c | 8 +-- net/core/net_namespace.c | 4 +- net/core/rtnetlink.c | 47 -- net/dcb/dcbnl.c | 57 - net/decnet/dn_dev.c | 4 +- net/decnet/dn_fib.c | 6 +- net/decnet/dn_route.c | 2 +- net/ieee802154/nl802154.c | 29 - net/ipv4/devinet.c| 12 ++-- net/ipv4/fib_frontend.c | 3 +- net/ipv4/ip_tunnel_core.c | 5 +- net/ipv4/ipmr.c | 3 +- net/ipv4/route.c | 3 +- net/ipv6/addrconf.c | 16 +++-- net/ipv6/addrlabel.c | 4 +- net/ipv6/ila/ila_lwt.c| 3 +- net/ipv6/route.c | 6 +- net/ipv6/seg6_iptunnel.c | 2 +- net/mpls/af_mpls.c| 5 +- net/mpls/mpls_iptunnel.c | 2 +- net/netfilter/ipset/ip_set_core.c | 27 net/netfilter/ipvs/ip_vs_ctl.c| 12 ++-- net/netfilter/nf_conntrack_netlink.c | 27 net/netfilter/nf_conntrack_proto_dccp.c | 2 +- net/netfilter/nf_conntrack_proto_sctp.c | 6 +- net/netfilter/nf_conntrack_proto_tcp.c| 3 +- net/netfilter/nf_nat_core.c | 5 +- net/netfilter/nf_tables_api.c | 27 net/netfilter/nfnetlink.c | 11 ++-- net/netfilter/nfnetlink_acct.c| 3 +- net/netfilter/nfnetlink_cthelper.c| 12 ++-- net/netfilter/nfnetlink_cttimeout.c | 3 +- net/netfilter/nfnetlink_queue.c | 2 +- net/netfilter/nft_compat.c| 2 +- net/netlabel/netlabel_cipso_v4.c | 19 +++--- net/netlink/genetlink.c | 2 +- net/nfc/netlink.c | 5 +- net/openvswitch/datapath.c| 2 +- net/openvswitch/flow_netlink.c| 4 +- net/openvswitch/vport-vxlan.c | 3 +- net/phonet/pn_netlink.c | 6 +- net/qrtr/qrtr.c | 2 +- net/sched/act_api.c | 20 +++--- net/sched/act_bpf.c | 2 +- net/sched/act_connmark.c | 3 +- net/sched/act_csum.c | 2 +- net/sched/act_gact.c | 2 +- net/sched/act_ife.c | 4 +- net/sched/act_ipt.c | 2 +- net/sched/act_mirred.c| 2 +- net/sched/act_nat.c | 2 +- net/sched/act_pedit.c | 4 +- net/sched/act_police.c| 2 +- net/sched/act_sample.c
[PATCH net-next 0/1 v2] skbuff: Extend gso_type to unsigned int
We need a GSO type for IPsec ESP to be able to integrate the IPsec hardware offloading infrastructure. Unfortunately, all gso_type flags are currently in use. This change extends gso_type from 'unsigned short' to 'unsigned int'. Changes from v1: - Place the remaining two byte hole in front, suggested by Eric Dumazet. - Skipping the memset of the two byte hole is unnecessary as it does not matter if we memset two or four bytes more, suggested by Alexander Duyck.
Re: [PATCH 1/5] netlink: extended ACK reporting
On 4/8/17 1:48 PM, Johannes Berg wrote: > diff --git a/include/linux/netlink.h b/include/linux/netlink.h > index da14ab61f363..47562e940e9c 100644 > --- a/include/linux/netlink.h > +++ b/include/linux/netlink.h > @@ -62,11 +62,41 @@ netlink_kernel_create(struct net *net, int unit, struct > netlink_kernel_cfg *cfg) > return __netlink_kernel_create(net, unit, THIS_MODULE, cfg); > } > > +/** > + * struct netlink_ext_ack - netlink extended ACK report struct > + * @_msg: message string to report - don't access directly, use > + * %NL_SET_ERR_MSG > + * @bad_attr: attribute with error > + * @missing_attr: number of missing attr (or 0) > + * @cookie: cookie data to return to userspace (for success) > + * @cookie_len: actual cookie data length > + */ > +struct netlink_ext_ack { > + const char *_msg; > + const struct nlattr *bad_attr; > + u16 missing_attr; > + u8 cookie[NETLINK_MAX_COOKIE_LEN]; > + u8 cookie_len; > +}; > + I think v3 is in your future ... /home/dsa/kernel-4.git/include/linux/netlink.h:78:12: error: ‘NETLINK_MAX_COOKIE_LEN’ undeclared here (not in a function) u8 cookie[NETLINK_MAX_COOKIE_LEN]; ^ it's defined in patch 3; needed in patch 1
[PATCH net-next 0/1 v2] skbuff: Extend gso_type to unsigned int.
All available gso_type flags are currently in use, so extend gso_type from 'unsigned short' to 'unsigned int' to be able to add further flags. We reorder the struct skb_shared_info to use two bytes of the four byte hole before dataref. All fields before dataref are cleared, i.e. four bytes more than before the change. The remaining two byte hole is moved to the beginning of the structure, this protects us from immediate overwites on out of bound writes to the sk_buff head. Structure layout on x86-64 before the change: struct skb_shared_info { unsigned char nr_frags; /* 0 1 */ __u8 tx_flags; /* 1 1 */ short unsigned int gso_size; /* 2 2 */ short unsigned int gso_segs; /* 4 2 */ short unsigned int gso_type; /* 6 2 */ struct sk_buff * frag_list;/* 8 8 */ struct skb_shared_hwtstamps hwtstamps; /*16 8 */ u32tskey;/*24 4 */ __be32 ip6_frag_id; /*28 4 */ atomic_t dataref; /*32 4 */ /* XXX 4 bytes hole, try to pack */ void * destructor_arg; /*40 8 */ skb_frag_t frags[17];/*48 272 */ /* --- cacheline 5 boundary (320 bytes) --- */ /* size: 320, cachelines: 5, members: 12 */ /* sum members: 316, holes: 1, sum holes: 4 */ }; Structure layout on x86-64 after the change: struct skb_shared_info { short unsigned int _unused; /* 0 2 */ unsigned char nr_frags; /* 2 1 */ __u8 tx_flags; /* 3 1 */ short unsigned int gso_size; /* 4 2 */ short unsigned int gso_segs; /* 6 2 */ struct sk_buff * frag_list;/* 8 8 */ struct skb_shared_hwtstamps hwtstamps; /*16 8 */ unsigned int gso_type; /*24 4 */ u32tskey;/*28 4 */ __be32 ip6_frag_id; /*32 4 */ atomic_t dataref; /*36 4 */ void * destructor_arg; /*40 8 */ skb_frag_t frags[17];/*48 272 */ /* --- cacheline 5 boundary (320 bytes) --- */ /* size: 320, cachelines: 5, members: 13 */ }; Signed-off-by: Steffen Klassert --- include/linux/skbuff.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index c776abd..741d75c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -413,14 +413,15 @@ struct ubuf_info { * the end of the header data, ie. at skb->end. */ struct skb_shared_info { + unsigned short _unused; unsigned char nr_frags; __u8tx_flags; unsigned short gso_size; /* Warning: this field is not always filled in (UFO)! */ unsigned short gso_segs; - unsigned short gso_type; struct sk_buff *frag_list; struct skb_shared_hwtstamps hwtstamps; + unsigned intgso_type; u32 tskey; __be32 ip6_frag_id; -- 2.7.4
Re: [PATCH 1/5] netlink: extended ACK reporting
On Sat, 2017-04-08 at 20:34 +0200, Jiri Pirko wrote: > nla_total_size(sizeof(u32)); > > + if (extack && > > + (extack->missing_attr || extack- > > >bad_attr)) > > Attr could be 0, right? I know that on the most of the places 0 is > UNSPEC, but I'm pretty sure not everywhere. Yeah, I guess we can't show a missing attribute of 0 now - bad_attr is a pointer so no problem there. I think I'll leave it like this - if anyone really wants to say "attribute 0 is missing" then we can add a flag later... The UAPI does take this into account by not including the attribute at all if the data is invalid, so 0 in the userspace API can be done johannes
Re: [PATCH 1/5] netlink: extended ACK reporting
On Sat, 2017-04-08 at 14:36 -0400, David Ahern wrote: > > I think v3 is in your future ... > > /home/dsa/kernel-4.git/include/linux/netlink.h:78:12: error: > ‘NETLINK_MAX_COOKIE_LEN’ undeclared here (not in a function) > u8 cookie[NETLINK_MAX_COOKIE_LEN]; > ^ > > it's defined in patch 3; needed in patch 1 Damn. Ok, that'll have to wait until Monday, unless the airport has useful wifi. johannes
Re: [PATCH 1/5] netlink: extended ACK reporting
Sat, Apr 08, 2017 at 08:37:01PM CEST, johan...@sipsolutions.net wrote: >On Sat, 2017-04-08 at 20:34 +0200, Jiri Pirko wrote: >> nla_total_size(sizeof(u32)); >> > + if (extack && >> > + (extack->missing_attr || extack- >> > >bad_attr)) >> >> Attr could be 0, right? I know that on the most of the places 0 is >> UNSPEC, but I'm pretty sure not everywhere. > >Yeah, I guess we can't show a missing attribute of 0 now - bad_attr is >a pointer so no problem there. > >I think I'll leave it like this - if anyone really wants to say >"attribute 0 is missing" then we can add a flag later... The UAPI does >take this into account by not including the attribute at all if the >data is invalid, so 0 in the userspace API can be done It a known issue, should be fixed right now. We are in no hurry. This waited +15 years to be done, no harm in couple more days. Also, could you please attach a patch to iproute2 for example which would make use of this. I just want to make sure it clicks. Thanks!
Re: [PATCH] ibmveth: Support to enable LSO/CSO for Trunk VEA.
From: Sivakumar Krishnasamy Date: Fri, 7 Apr 2017 05:57:59 -0400 > Enable largesend and checksum offload for ibmveth configured in trunk mode. > Added support to SKB frag_list in TX path by skb_linearize'ing such SKBs. > > Signed-off-by: Sivakumar Krishnasamy Why is linearization necessary? It would seem that the gains you get from GRO are nullified by linearizing the SKB and thus copying all the data around and allocating buffers. Finally, all of that new checksumming stuff looks extremely suspicious. You have to explain why that is happening and why it isn't because this driver is doing something incorrectly. Thanks.