1
0
Fork 0

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Pull networking fixes from David Miller:

 1) Clamp timeouts to INT_MAX in conntrack, from Jay Elliot.

 2) Fix broken UAPI for BPF_PROG_TYPE_PERF_EVENT, from Hendrik
    Brueckner.

 3) Fix locking in ieee80211_sta_tear_down_BA_sessions, from Johannes
    Berg.

 4) Add missing barriers to ptr_ring, from Michael S. Tsirkin.

 5) Don't advertise gigabit in sh_eth when not available, from Thomas
    Petazzoni.

 6) Check network namespace when delivering to netlink taps, from Kevin
    Cernekee.

 7) Kill a race in raw_sendmsg(), from Mohamed Ghannam.

 8) Use correct address in TCP md5 lookups when replying to an incoming
    segment, from Christoph Paasch.

 9) Add schedule points to BPF map alloc/free, from Eric Dumazet.

10) Don't allow silly mtu values to be used in ipv4/ipv6 multicast, also
    from Eric Dumazet.

11) Fix SKB leak in tipc, from Jon Maloy.

12) Disable MAC learning on OVS ports of mlxsw, from Yuval Mintz.

13) SKB leak fix in skB_complete_tx_timestamp(), from Willem de Bruijn.

14) Add some new qmi_wwan device IDs, from Daniele Palmas.

15) Fix static key imbalance in ingress qdisc, from Jiri Pirko.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (76 commits)
  net: qcom/emac: Reduce timeout for mdio read/write
  net: sched: fix static key imbalance in case of ingress/clsact_init error
  net: sched: fix clsact init error path
  ip_gre: fix wrong return value of erspan_rcv
  net: usb: qmi_wwan: add Telit ME910 PID 0x1101 support
  pkt_sched: Remove TC_RED_OFFLOADED from uapi
  net: sched: Move to new offload indication in RED
  net: sched: Add TCA_HW_OFFLOAD
  net: aquantia: Increment driver version
  net: aquantia: Fix typo in ethtool statistics names
  net: aquantia: Update hw counters on hw init
  net: aquantia: Improve link state and statistics check interval callback
  net: aquantia: Fill in multicast counter in ndev stats from hardware
  net: aquantia: Fill ndev stat couters from hardware
  net: aquantia: Extend stat counters to 64bit values
  net: aquantia: Fix hardware DMA stream overload on large MRRS
  net: aquantia: Fix actual speed capabilities reporting
  sock: free skb in skb_complete_tx_timestamp on error
  s390/qeth: update takeover IPs after configuration change
  s390/qeth: lock IP table while applying takeover changes
  ...
zero-colors
Linus Torvalds 2017-12-15 13:08:37 -08:00
commit 7a3c296ae0
95 changed files with 800 additions and 385 deletions

View File

@ -13117,6 +13117,7 @@ F: drivers/dma/dw/
SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET DRIVER
M: Jie Deng <jiedeng@synopsys.com>
M: Jose Abreu <Jose.Abreu@synopsys.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/synopsys/

View File

@ -121,7 +121,7 @@
switch0port10: port@10 {
reg = <10>;
label = "dsa";
phy-mode = "xgmii";
phy-mode = "xaui";
link = <&switch1port10>;
};
};
@ -208,7 +208,7 @@
switch1port10: port@10 {
reg = <10>;
label = "dsa";
phy-mode = "xgmii";
phy-mode = "xaui";
link = <&switch0port10>;
};
};

View File

@ -1,4 +1,5 @@
generic-y += barrier.h
generic-y += bpf_perf_event.h
generic-y += bug.h
generic-y += clkdev.h
generic-y += current.h

View File

@ -338,6 +338,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
break;
case PHY_INTERFACE_MODE_XGMII:
case PHY_INTERFACE_MODE_XAUI:
cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
break;
case PHY_INTERFACE_MODE_RXAUI:

View File

@ -50,7 +50,7 @@
#define AQ_CFG_PCI_FUNC_MSIX_IRQS 9U
#define AQ_CFG_PCI_FUNC_PORTS 2U
#define AQ_CFG_SERVICE_TIMER_INTERVAL (2 * HZ)
#define AQ_CFG_SERVICE_TIMER_INTERVAL (1 * HZ)
#define AQ_CFG_POLLING_TIMER_INTERVAL ((unsigned int)(2 * HZ))
#define AQ_CFG_SKB_FRAGS_MAX 32U
@ -80,6 +80,7 @@
#define AQ_CFG_DRV_VERSION __stringify(NIC_MAJOR_DRIVER_VERSION)"."\
__stringify(NIC_MINOR_DRIVER_VERSION)"."\
__stringify(NIC_BUILD_DRIVER_VERSION)"."\
__stringify(NIC_REVISION_DRIVER_VERSION)
__stringify(NIC_REVISION_DRIVER_VERSION) \
AQ_CFG_DRV_VERSION_SUFFIX
#endif /* AQ_CFG_H */

View File

@ -66,14 +66,14 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
"OutUCast",
"OutMCast",
"OutBCast",
"InUCastOctects",
"OutUCastOctects",
"InMCastOctects",
"OutMCastOctects",
"InBCastOctects",
"OutBCastOctects",
"InOctects",
"OutOctects",
"InUCastOctets",
"OutUCastOctets",
"InMCastOctets",
"OutMCastOctets",
"InBCastOctets",
"OutBCastOctets",
"InOctets",
"OutOctets",
"InPacketsDma",
"OutPacketsDma",
"InOctetsDma",

View File

@ -46,6 +46,28 @@ struct aq_hw_link_status_s {
unsigned int mbps;
};
struct aq_stats_s {
u64 uprc;
u64 mprc;
u64 bprc;
u64 erpt;
u64 uptc;
u64 mptc;
u64 bptc;
u64 erpr;
u64 mbtc;
u64 bbtc;
u64 mbrc;
u64 bbrc;
u64 ubrc;
u64 ubtc;
u64 dpc;
u64 dma_pkt_rc;
u64 dma_pkt_tc;
u64 dma_oct_rc;
u64 dma_oct_tc;
};
#define AQ_HW_IRQ_INVALID 0U
#define AQ_HW_IRQ_LEGACY 1U
#define AQ_HW_IRQ_MSI 2U
@ -85,7 +107,9 @@ struct aq_hw_ops {
void (*destroy)(struct aq_hw_s *self);
int (*get_hw_caps)(struct aq_hw_s *self,
struct aq_hw_caps_s *aq_hw_caps);
struct aq_hw_caps_s *aq_hw_caps,
unsigned short device,
unsigned short subsystem_device);
int (*hw_ring_tx_xmit)(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
unsigned int frags);
@ -164,8 +188,7 @@ struct aq_hw_ops {
int (*hw_update_stats)(struct aq_hw_s *self);
int (*hw_get_hw_stats)(struct aq_hw_s *self, u64 *data,
unsigned int *p_count);
struct aq_stats_s *(*hw_get_hw_stats)(struct aq_hw_s *self);
int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);

View File

@ -37,6 +37,8 @@ static unsigned int aq_itr_rx;
module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644);
MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate");
static void aq_nic_update_ndev_stats(struct aq_nic_s *self);
static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues)
{
struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
@ -166,11 +168,8 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
static void aq_nic_service_timer_cb(struct timer_list *t)
{
struct aq_nic_s *self = from_timer(self, t, service_timer);
struct net_device *ndev = aq_nic_get_ndev(self);
int ctimer = AQ_CFG_SERVICE_TIMER_INTERVAL;
int err = 0;
unsigned int i = 0U;
struct aq_ring_stats_rx_s stats_rx;
struct aq_ring_stats_tx_s stats_tx;
if (aq_utils_obj_test(&self->header.flags, AQ_NIC_FLAGS_IS_NOT_READY))
goto err_exit;
@ -182,23 +181,14 @@ static void aq_nic_service_timer_cb(struct timer_list *t)
if (self->aq_hw_ops.hw_update_stats)
self->aq_hw_ops.hw_update_stats(self->aq_hw);
memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
for (i = AQ_DIMOF(self->aq_vec); i--;) {
if (self->aq_vec[i])
aq_vec_add_stats(self->aq_vec[i], &stats_rx, &stats_tx);
}
aq_nic_update_ndev_stats(self);
ndev->stats.rx_packets = stats_rx.packets;
ndev->stats.rx_bytes = stats_rx.bytes;
ndev->stats.rx_errors = stats_rx.errors;
ndev->stats.tx_packets = stats_tx.packets;
ndev->stats.tx_bytes = stats_tx.bytes;
ndev->stats.tx_errors = stats_tx.errors;
/* If no link - use faster timer rate to detect link up asap */
if (!netif_carrier_ok(self->ndev))
ctimer = max(ctimer / 2, 1);
err_exit:
mod_timer(&self->service_timer,
jiffies + AQ_CFG_SERVICE_TIMER_INTERVAL);
mod_timer(&self->service_timer, jiffies + ctimer);
}
static void aq_nic_polling_timer_cb(struct timer_list *t)
@ -222,7 +212,7 @@ static struct net_device *aq_nic_ndev_alloc(void)
struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,
const struct ethtool_ops *et_ops,
struct device *dev,
struct pci_dev *pdev,
struct aq_pci_func_s *aq_pci_func,
unsigned int port,
const struct aq_hw_ops *aq_hw_ops)
@ -242,7 +232,7 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,
ndev->netdev_ops = ndev_ops;
ndev->ethtool_ops = et_ops;
SET_NETDEV_DEV(ndev, dev);
SET_NETDEV_DEV(ndev, &pdev->dev);
ndev->if_port = port;
self->ndev = ndev;
@ -254,7 +244,8 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,
self->aq_hw = self->aq_hw_ops.create(aq_pci_func, self->port,
&self->aq_hw_ops);
err = self->aq_hw_ops.get_hw_caps(self->aq_hw, &self->aq_hw_caps);
err = self->aq_hw_ops.get_hw_caps(self->aq_hw, &self->aq_hw_caps,
pdev->device, pdev->subsystem_device);
if (err < 0)
goto err_exit;
@ -749,16 +740,40 @@ int aq_nic_get_regs_count(struct aq_nic_s *self)
void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
{
struct aq_vec_s *aq_vec = NULL;
unsigned int i = 0U;
unsigned int count = 0U;
int err = 0;
struct aq_vec_s *aq_vec = NULL;
struct aq_stats_s *stats = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw);
err = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw, data, &count);
if (err < 0)
if (!stats)
goto err_exit;
data += count;
data[i] = stats->uprc + stats->mprc + stats->bprc;
data[++i] = stats->uprc;
data[++i] = stats->mprc;
data[++i] = stats->bprc;
data[++i] = stats->erpt;
data[++i] = stats->uptc + stats->mptc + stats->bptc;
data[++i] = stats->uptc;
data[++i] = stats->mptc;
data[++i] = stats->bptc;
data[++i] = stats->ubrc;
data[++i] = stats->ubtc;
data[++i] = stats->mbrc;
data[++i] = stats->mbtc;
data[++i] = stats->bbrc;
data[++i] = stats->bbtc;
data[++i] = stats->ubrc + stats->mbrc + stats->bbrc;
data[++i] = stats->ubtc + stats->mbtc + stats->bbtc;
data[++i] = stats->dma_pkt_rc;
data[++i] = stats->dma_pkt_tc;
data[++i] = stats->dma_oct_rc;
data[++i] = stats->dma_oct_tc;
data[++i] = stats->dpc;
i++;
data += i;
count = 0U;
for (i = 0U, aq_vec = self->aq_vec[0];
@ -768,7 +783,20 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
}
err_exit:;
(void)err;
}
static void aq_nic_update_ndev_stats(struct aq_nic_s *self)
{
struct net_device *ndev = self->ndev;
struct aq_stats_s *stats = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw);
ndev->stats.rx_packets = stats->uprc + stats->mprc + stats->bprc;
ndev->stats.rx_bytes = stats->ubrc + stats->mbrc + stats->bbrc;
ndev->stats.rx_errors = stats->erpr;
ndev->stats.tx_packets = stats->uptc + stats->mptc + stats->bptc;
ndev->stats.tx_bytes = stats->ubtc + stats->mbtc + stats->bbtc;
ndev->stats.tx_errors = stats->erpt;
ndev->stats.multicast = stats->mprc;
}
void aq_nic_get_link_ksettings(struct aq_nic_s *self,

View File

@ -71,7 +71,7 @@ struct aq_nic_cfg_s {
struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,
const struct ethtool_ops *et_ops,
struct device *dev,
struct pci_dev *pdev,
struct aq_pci_func_s *aq_pci_func,
unsigned int port,
const struct aq_hw_ops *aq_hw_ops);

View File

@ -51,7 +51,8 @@ struct aq_pci_func_s *aq_pci_func_alloc(struct aq_hw_ops *aq_hw_ops,
pci_set_drvdata(pdev, self);
self->pdev = pdev;
err = aq_hw_ops->get_hw_caps(NULL, &self->aq_hw_caps);
err = aq_hw_ops->get_hw_caps(NULL, &self->aq_hw_caps, pdev->device,
pdev->subsystem_device);
if (err < 0)
goto err_exit;
@ -59,7 +60,7 @@ struct aq_pci_func_s *aq_pci_func_alloc(struct aq_hw_ops *aq_hw_ops,
for (port = 0; port < self->ports; ++port) {
struct aq_nic_s *aq_nic = aq_nic_alloc_cold(ndev_ops, eth_ops,
&pdev->dev, self,
pdev, self,
port, aq_hw_ops);
if (!aq_nic) {

View File

@ -18,9 +18,20 @@
#include "hw_atl_a0_internal.h"
static int hw_atl_a0_get_hw_caps(struct aq_hw_s *self,
struct aq_hw_caps_s *aq_hw_caps)
struct aq_hw_caps_s *aq_hw_caps,
unsigned short device,
unsigned short subsystem_device)
{
memcpy(aq_hw_caps, &hw_atl_a0_hw_caps_, sizeof(*aq_hw_caps));
if (device == HW_ATL_DEVICE_ID_D108 && subsystem_device == 0x0001)
aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_10G;
if (device == HW_ATL_DEVICE_ID_D109 && subsystem_device == 0x0001) {
aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_10G;
aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_5G;
}
return 0;
}
@ -333,6 +344,10 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self,
hw_atl_a0_hw_rss_set(self, &aq_nic_cfg->aq_rss);
hw_atl_a0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss);
/* Reset link status and read out initial hardware counters */
self->aq_link_status.mbps = 0;
hw_atl_utils_update_stats(self);
err = aq_hw_err_from_flags(self);
if (err < 0)
goto err_exit;

View File

@ -16,11 +16,23 @@
#include "hw_atl_utils.h"
#include "hw_atl_llh.h"
#include "hw_atl_b0_internal.h"
#include "hw_atl_llh_internal.h"
static int hw_atl_b0_get_hw_caps(struct aq_hw_s *self,
struct aq_hw_caps_s *aq_hw_caps)
struct aq_hw_caps_s *aq_hw_caps,
unsigned short device,
unsigned short subsystem_device)
{
memcpy(aq_hw_caps, &hw_atl_b0_hw_caps_, sizeof(*aq_hw_caps));
if (device == HW_ATL_DEVICE_ID_D108 && subsystem_device == 0x0001)
aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_10G;
if (device == HW_ATL_DEVICE_ID_D109 && subsystem_device == 0x0001) {
aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_10G;
aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_5G;
}
return 0;
}
@ -357,6 +369,7 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self,
};
int err = 0;
u32 val;
self->aq_nic_cfg = aq_nic_cfg;
@ -374,6 +387,20 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self,
hw_atl_b0_hw_rss_set(self, &aq_nic_cfg->aq_rss);
hw_atl_b0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss);
/* Force limit MRRS on RDM/TDM to 2K */
val = aq_hw_read_reg(self, pci_reg_control6_adr);
aq_hw_write_reg(self, pci_reg_control6_adr, (val & ~0x707) | 0x404);
/* TX DMA total request limit. B0 hardware is not capable to
* handle more than (8K-MRRS) incoming DMA data.
* Value 24 in 256byte units
*/
aq_hw_write_reg(self, tx_dma_total_req_limit_adr, 24);
/* Reset link status and read out initial hardware counters */
self->aq_link_status.mbps = 0;
hw_atl_utils_update_stats(self);
err = aq_hw_err_from_flags(self);
if (err < 0)
goto err_exit;

View File

@ -2343,6 +2343,9 @@
#define tx_dma_desc_base_addrmsw_adr(descriptor) \
(0x00007c04u + (descriptor) * 0x40)
/* tx dma total request limit */
#define tx_dma_total_req_limit_adr 0x00007b20u
/* tx interrupt moderation control register definitions
* Preprocessor definitions for TX Interrupt Moderation Control Register
* Base Address: 0x00008980
@ -2369,6 +2372,9 @@
/* default value of bitfield reg_res_dsbl */
#define pci_reg_res_dsbl_default 0x1
/* PCI core control register */
#define pci_reg_control6_adr 0x1014u
/* global microprocessor scratch pad definitions */
#define glb_cpu_scratch_scp_adr(scratch_scp) (0x00000300u + (scratch_scp) * 0x4)

View File

@ -503,73 +503,43 @@ int hw_atl_utils_update_stats(struct aq_hw_s *self)
struct hw_atl_s *hw_self = PHAL_ATLANTIC;
struct hw_aq_atl_utils_mbox mbox;
if (!self->aq_link_status.mbps)
return 0;
hw_atl_utils_mpi_read_stats(self, &mbox);
#define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \
mbox.stats._N_ - hw_self->last_stats._N_)
if (self->aq_link_status.mbps) {
AQ_SDELTA(uprc);
AQ_SDELTA(mprc);
AQ_SDELTA(bprc);
AQ_SDELTA(erpt);
AQ_SDELTA(uprc);
AQ_SDELTA(mprc);
AQ_SDELTA(bprc);
AQ_SDELTA(erpt);
AQ_SDELTA(uptc);
AQ_SDELTA(mptc);
AQ_SDELTA(bptc);
AQ_SDELTA(erpr);
AQ_SDELTA(ubrc);
AQ_SDELTA(ubtc);
AQ_SDELTA(mbrc);
AQ_SDELTA(mbtc);
AQ_SDELTA(bbrc);
AQ_SDELTA(bbtc);
AQ_SDELTA(dpc);
AQ_SDELTA(uptc);
AQ_SDELTA(mptc);
AQ_SDELTA(bptc);
AQ_SDELTA(erpr);
AQ_SDELTA(ubrc);
AQ_SDELTA(ubtc);
AQ_SDELTA(mbrc);
AQ_SDELTA(mbtc);
AQ_SDELTA(bbrc);
AQ_SDELTA(bbtc);
AQ_SDELTA(dpc);
}
#undef AQ_SDELTA
hw_self->curr_stats.dma_pkt_rc = stats_rx_dma_good_pkt_counterlsw_get(self);
hw_self->curr_stats.dma_pkt_tc = stats_tx_dma_good_pkt_counterlsw_get(self);
hw_self->curr_stats.dma_oct_rc = stats_rx_dma_good_octet_counterlsw_get(self);
hw_self->curr_stats.dma_oct_tc = stats_tx_dma_good_octet_counterlsw_get(self);
memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats));
return 0;
}
int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
u64 *data, unsigned int *p_count)
struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
{
struct hw_atl_s *hw_self = PHAL_ATLANTIC;
struct hw_atl_stats_s *stats = &hw_self->curr_stats;
int i = 0;
data[i] = stats->uprc + stats->mprc + stats->bprc;
data[++i] = stats->uprc;
data[++i] = stats->mprc;
data[++i] = stats->bprc;
data[++i] = stats->erpt;
data[++i] = stats->uptc + stats->mptc + stats->bptc;
data[++i] = stats->uptc;
data[++i] = stats->mptc;
data[++i] = stats->bptc;
data[++i] = stats->ubrc;
data[++i] = stats->ubtc;
data[++i] = stats->mbrc;
data[++i] = stats->mbtc;
data[++i] = stats->bbrc;
data[++i] = stats->bbtc;
data[++i] = stats->ubrc + stats->mbrc + stats->bbrc;
data[++i] = stats->ubtc + stats->mbtc + stats->bbtc;
data[++i] = stats_rx_dma_good_pkt_counterlsw_get(self);
data[++i] = stats_tx_dma_good_pkt_counterlsw_get(self);
data[++i] = stats_rx_dma_good_octet_counterlsw_get(self);
data[++i] = stats_tx_dma_good_octet_counterlsw_get(self);
data[++i] = stats->dpc;
if (p_count)
*p_count = ++i;
return 0;
return &PHAL_ATLANTIC->curr_stats;
}
static const u32 hw_atl_utils_hw_mac_regs[] = {

View File

@ -129,7 +129,7 @@ struct __packed hw_aq_atl_utils_mbox {
struct __packed hw_atl_s {
struct aq_hw_s base;
struct hw_atl_stats_s last_stats;
struct hw_atl_stats_s curr_stats;
struct aq_stats_s curr_stats;
u64 speed;
unsigned int chip_features;
u32 fw_ver_actual;
@ -207,8 +207,6 @@ int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version);
int hw_atl_utils_update_stats(struct aq_hw_s *self);
int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
u64 *data,
unsigned int *p_count);
struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self);
#endif /* HW_ATL_UTILS_H */

View File

@ -11,8 +11,10 @@
#define VER_H
#define NIC_MAJOR_DRIVER_VERSION 1
#define NIC_MINOR_DRIVER_VERSION 5
#define NIC_BUILD_DRIVER_VERSION 345
#define NIC_MINOR_DRIVER_VERSION 6
#define NIC_BUILD_DRIVER_VERSION 13
#define NIC_REVISION_DRIVER_VERSION 0
#define AQ_CFG_DRV_VERSION_SUFFIX "-kern"
#endif /* VER_H */

View File

@ -199,9 +199,11 @@ static int emac_rockchip_probe(struct platform_device *pdev)
/* RMII interface needs always a rate of 50MHz */
err = clk_set_rate(priv->refclk, 50000000);
if (err)
if (err) {
dev_err(dev,
"failed to change reference clock rate (%d)\n", err);
goto out_regulator_disable;
}
if (priv->soc_data->need_div_macclk) {
priv->macclk = devm_clk_get(dev, "macclk");
@ -230,12 +232,14 @@ static int emac_rockchip_probe(struct platform_device *pdev)
err = arc_emac_probe(ndev, interface);
if (err) {
dev_err(dev, "failed to probe arc emac (%d)\n", err);
goto out_regulator_disable;
goto out_clk_disable_macclk;
}
return 0;
out_clk_disable_macclk:
clk_disable_unprepare(priv->macclk);
if (priv->soc_data->need_div_macclk)
clk_disable_unprepare(priv->macclk);
out_regulator_disable:
if (priv->regulator)
regulator_disable(priv->regulator);

View File

@ -4081,7 +4081,6 @@ static void skge_remove(struct pci_dev *pdev)
if (hw->ports > 1) {
skge_write32(hw, B0_IMSK, 0);
skge_read32(hw, B0_IMSK);
free_irq(pdev->irq, hw);
}
spin_unlock_irq(&hw->hw_lock);

View File

@ -188,7 +188,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
struct net_device *dev = mdev->pndev[port];
struct mlx4_en_priv *priv = netdev_priv(dev);
struct net_device_stats *stats = &dev->stats;
struct mlx4_cmd_mailbox *mailbox;
struct mlx4_cmd_mailbox *mailbox, *mailbox_priority;
u64 in_mod = reset << 8 | port;
int err;
int i, counter_index;
@ -198,6 +198,13 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
mailbox = mlx4_alloc_cmd_mailbox(mdev->dev);
if (IS_ERR(mailbox))
return PTR_ERR(mailbox);
mailbox_priority = mlx4_alloc_cmd_mailbox(mdev->dev);
if (IS_ERR(mailbox_priority)) {
mlx4_free_cmd_mailbox(mdev->dev, mailbox);
return PTR_ERR(mailbox_priority);
}
err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, in_mod, 0,
MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
MLX4_CMD_NATIVE);
@ -206,6 +213,28 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
mlx4_en_stats = mailbox->buf;
memset(&tmp_counter_stats, 0, sizeof(tmp_counter_stats));
counter_index = mlx4_get_default_counter_index(mdev->dev, port);
err = mlx4_get_counter_stats(mdev->dev, counter_index,
&tmp_counter_stats, reset);
/* 0xffs indicates invalid value */
memset(mailbox_priority->buf, 0xff,
sizeof(*flowstats) * MLX4_NUM_PRIORITIES);
if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN) {
memset(mailbox_priority->buf, 0,
sizeof(*flowstats) * MLX4_NUM_PRIORITIES);
err = mlx4_cmd_box(mdev->dev, 0, mailbox_priority->dma,
in_mod | MLX4_DUMP_ETH_STATS_FLOW_CONTROL,
0, MLX4_CMD_DUMP_ETH_STATS,
MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
if (err)
goto out;
}
flowstats = mailbox_priority->buf;
spin_lock_bh(&priv->stats_lock);
mlx4_en_fold_software_stats(dev);
@ -345,31 +374,6 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
priv->pkstats.tx_prio[8][0] = be64_to_cpu(mlx4_en_stats->TTOT_novlan);
priv->pkstats.tx_prio[8][1] = be64_to_cpu(mlx4_en_stats->TOCT_novlan);
spin_unlock_bh(&priv->stats_lock);
memset(&tmp_counter_stats, 0, sizeof(tmp_counter_stats));
counter_index = mlx4_get_default_counter_index(mdev->dev, port);
err = mlx4_get_counter_stats(mdev->dev, counter_index,
&tmp_counter_stats, reset);
/* 0xffs indicates invalid value */
memset(mailbox->buf, 0xff, sizeof(*flowstats) * MLX4_NUM_PRIORITIES);
if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_FLOWSTATS_EN) {
memset(mailbox->buf, 0,
sizeof(*flowstats) * MLX4_NUM_PRIORITIES);
err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma,
in_mod | MLX4_DUMP_ETH_STATS_FLOW_CONTROL,
0, MLX4_CMD_DUMP_ETH_STATS,
MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
if (err)
goto out;
}
flowstats = mailbox->buf;
spin_lock_bh(&priv->stats_lock);
if (tmp_counter_stats.counter_mode == 0) {
priv->pf_stats.rx_bytes = be64_to_cpu(tmp_counter_stats.rx_bytes);
priv->pf_stats.tx_bytes = be64_to_cpu(tmp_counter_stats.tx_bytes);
@ -410,6 +414,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
out:
mlx4_free_cmd_mailbox(mdev->dev, mailbox);
mlx4_free_cmd_mailbox(mdev->dev, mailbox_priority);
return err;
}

View File

@ -185,7 +185,7 @@ void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf)
if (priv->mdev->dev->caps.flags &
MLX4_DEV_CAP_FLAG_UC_LOOPBACK) {
buf[3] = mlx4_en_test_registers(priv);
if (priv->port_up)
if (priv->port_up && dev->mtu >= MLX4_SELFTEST_LB_MIN_MTU)
buf[4] = mlx4_en_test_loopback(priv);
}

View File

@ -153,6 +153,9 @@
#define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN)
#define HEADER_COPY_SIZE (128 - NET_IP_ALIGN)
#define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN)
#define PREAMBLE_LEN 8
#define MLX4_SELFTEST_LB_MIN_MTU (MLX4_LOOPBACK_TEST_PAYLOAD + NET_IP_ALIGN + \
ETH_HLEN + PREAMBLE_LEN)
#define MLX4_EN_MIN_MTU 46
/* VLAN_HLEN is added twice,to support skb vlan tagged with multiple

View File

@ -611,7 +611,6 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev)
MLX4_MAX_PORTS;
else
res_alloc->guaranteed[t] = 0;
res_alloc->res_free -= res_alloc->guaranteed[t];
break;
default:
break;

View File

@ -4300,6 +4300,7 @@ static int mlxsw_sp_port_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port)
{
u16 vid = 1;
int err;
err = mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, true);
@ -4312,8 +4313,19 @@ static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port)
true, false);
if (err)
goto err_port_vlan_set;
for (; vid <= VLAN_N_VID - 1; vid++) {
err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_port,
vid, false);
if (err)
goto err_vid_learning_set;
}
return 0;
err_vid_learning_set:
for (vid--; vid >= 1; vid--)
mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, true);
err_port_vlan_set:
mlxsw_sp_port_stp_set(mlxsw_sp_port, false);
err_port_stp_set:
@ -4323,6 +4335,12 @@ err_port_stp_set:
static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port)
{
u16 vid;
for (vid = VLAN_N_VID - 1; vid >= 1; vid--)
mlxsw_sp_port_vid_learning_set(mlxsw_sp_port,
vid, true);
mlxsw_sp_port_vlan_set(mlxsw_sp_port, 2, VLAN_N_VID - 1,
false, false);
mlxsw_sp_port_stp_set(mlxsw_sp_port, false);

View File

@ -47,6 +47,7 @@
#define MDIO_CLK_25_28 7
#define MDIO_WAIT_TIMES 1000
#define MDIO_STATUS_DELAY_TIME 1
static int emac_mdio_read(struct mii_bus *bus, int addr, int regnum)
{
@ -65,7 +66,7 @@ static int emac_mdio_read(struct mii_bus *bus, int addr, int regnum)
if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg,
!(reg & (MDIO_START | MDIO_BUSY)),
100, MDIO_WAIT_TIMES * 100))
MDIO_STATUS_DELAY_TIME, MDIO_WAIT_TIMES * 100))
return -EIO;
return (reg >> MDIO_DATA_SHFT) & MDIO_DATA_BMSK;
@ -88,8 +89,8 @@ static int emac_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
writel(reg, adpt->base + EMAC_MDIO_CTRL);
if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg,
!(reg & (MDIO_START | MDIO_BUSY)), 100,
MDIO_WAIT_TIMES * 100))
!(reg & (MDIO_START | MDIO_BUSY)),
MDIO_STATUS_DELAY_TIME, MDIO_WAIT_TIMES * 100))
return -EIO;
return 0;

View File

@ -2308,32 +2308,9 @@ static int __maybe_unused ravb_resume(struct device *dev)
struct ravb_private *priv = netdev_priv(ndev);
int ret = 0;
if (priv->wol_enabled) {
/* Reduce the usecount of the clock to zero and then
* restore it to its original value. This is done to force
* the clock to be re-enabled which is a workaround
* for renesas-cpg-mssr driver which do not enable clocks
* when resuming from PSCI suspend/resume.
*
* Without this workaround the driver fails to communicate
* with the hardware if WoL was enabled when the system
* entered PSCI suspend. This is due to that if WoL is enabled
* we explicitly keep the clock from being turned off when
* suspending, but in PSCI sleep power is cut so the clock
* is disabled anyhow, the clock driver is not aware of this
* so the clock is not turned back on when resuming.
*
* TODO: once the renesas-cpg-mssr suspend/resume is working
* this clock dance should be removed.
*/
clk_disable(priv->clk);
clk_disable(priv->clk);
clk_enable(priv->clk);
clk_enable(priv->clk);
/* Set reset mode to rearm the WoL logic */
/* If WoL is enabled set reset mode to rearm the WoL logic */
if (priv->wol_enabled)
ravb_write(ndev, CCC_OPC_RESET, CCC);
}
/* All register have been reset to default values.
* Restore all registers which where setup at probe time and

View File

@ -1892,6 +1892,16 @@ static int sh_eth_phy_init(struct net_device *ndev)
return PTR_ERR(phydev);
}
/* mask with MAC supported features */
if (mdp->cd->register_type != SH_ETH_REG_GIGABIT) {
int err = phy_set_max_speed(phydev, SPEED_100);
if (err) {
netdev_err(ndev, "failed to limit PHY to 100 Mbit/s\n");
phy_disconnect(phydev);
return err;
}
}
phy_attached_info(phydev);
return 0;

View File

@ -1379,8 +1379,8 @@ static int rr_close(struct net_device *dev)
rrpriv->info_dma);
rrpriv->info = NULL;
free_irq(pdev->irq, dev);
spin_unlock_irqrestore(&rrpriv->lock, flags);
free_irq(pdev->irq, dev);
return 0;
}

View File

@ -239,14 +239,10 @@ static int at803x_resume(struct phy_device *phydev)
{
int value;
mutex_lock(&phydev->lock);
value = phy_read(phydev, MII_BMCR);
value &= ~(BMCR_PDOWN | BMCR_ISOLATE);
phy_write(phydev, MII_BMCR, value);
mutex_unlock(&phydev->lock);
return 0;
}

View File

@ -637,6 +637,10 @@ static int m88e1510_config_aneg(struct phy_device *phydev)
if (err < 0)
goto error;
/* Do not touch the fiber page if we're in copper->sgmii mode */
if (phydev->interface == PHY_INTERFACE_MODE_SGMII)
return 0;
/* Then the fiber link */
err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE);
if (err < 0)

View File

@ -270,6 +270,7 @@ static void of_mdiobus_link_mdiodev(struct mii_bus *bus,
if (addr == mdiodev->addr) {
dev->of_node = child;
dev->fwnode = of_fwnode_handle(child);
return;
}
}

View File

@ -22,6 +22,7 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/netdevice.h>
#include <linux/bitfield.h>
static int meson_gxl_config_init(struct phy_device *phydev)
{
@ -50,6 +51,77 @@ static int meson_gxl_config_init(struct phy_device *phydev)
return 0;
}
/* This function is provided to cope with the possible failures of this phy
* during aneg process. When aneg fails, the PHY reports that aneg is done
* but the value found in MII_LPA is wrong:
* - Early failures: MII_LPA is just 0x0001. if MII_EXPANSION reports that
* the link partner (LP) supports aneg but the LP never acked our base
* code word, it is likely that we never sent it to begin with.
* - Late failures: MII_LPA is filled with a value which seems to make sense
* but it actually is not what the LP is advertising. It seems that we
* can detect this using a magic bit in the WOL bank (reg 12 - bit 12).
* If this particular bit is not set when aneg is reported being done,
* it means MII_LPA is likely to be wrong.
*
* In both case, forcing a restart of the aneg process solve the problem.
* When this failure happens, the first retry is usually successful but,
* in some cases, it may take up to 6 retries to get a decent result
*/
static int meson_gxl_read_status(struct phy_device *phydev)
{
int ret, wol, lpa, exp;
if (phydev->autoneg == AUTONEG_ENABLE) {
ret = genphy_aneg_done(phydev);
if (ret < 0)
return ret;
else if (!ret)
goto read_status_continue;
/* Need to access WOL bank, make sure the access is open */
ret = phy_write(phydev, 0x14, 0x0000);
if (ret)
return ret;
ret = phy_write(phydev, 0x14, 0x0400);
if (ret)
return ret;
ret = phy_write(phydev, 0x14, 0x0000);
if (ret)
return ret;
ret = phy_write(phydev, 0x14, 0x0400);
if (ret)
return ret;
/* Request LPI_STATUS WOL register */
ret = phy_write(phydev, 0x14, 0x8D80);
if (ret)
return ret;
/* Read LPI_STATUS value */
wol = phy_read(phydev, 0x15);
if (wol < 0)
return wol;
lpa = phy_read(phydev, MII_LPA);
if (lpa < 0)
return lpa;
exp = phy_read(phydev, MII_EXPANSION);
if (exp < 0)
return exp;
if (!(wol & BIT(12)) ||
((exp & EXPANSION_NWAY) && !(lpa & LPA_LPACK))) {
/* Looks like aneg failed after all */
phydev_dbg(phydev, "LPA corruption - aneg restart\n");
return genphy_restart_aneg(phydev);
}
}
read_status_continue:
return genphy_read_status(phydev);
}
static struct phy_driver meson_gxl_phy[] = {
{
.phy_id = 0x01814400,
@ -60,7 +132,7 @@ static struct phy_driver meson_gxl_phy[] = {
.config_init = meson_gxl_config_init,
.config_aneg = genphy_config_aneg,
.aneg_done = genphy_aneg_done,
.read_status = genphy_read_status,
.read_status = meson_gxl_read_status,
.suspend = genphy_suspend,
.resume = genphy_resume,
},

View File

@ -828,7 +828,6 @@ EXPORT_SYMBOL(phy_stop);
*/
void phy_start(struct phy_device *phydev)
{
bool do_resume = false;
int err = 0;
mutex_lock(&phydev->lock);
@ -841,6 +840,9 @@ void phy_start(struct phy_device *phydev)
phydev->state = PHY_UP;
break;
case PHY_HALTED:
/* if phy was suspended, bring the physical link up again */
phy_resume(phydev);
/* make sure interrupts are re-enabled for the PHY */
if (phydev->irq != PHY_POLL) {
err = phy_enable_interrupts(phydev);
@ -849,17 +851,12 @@ void phy_start(struct phy_device *phydev)
}
phydev->state = PHY_RESUMING;
do_resume = true;
break;
default:
break;
}
mutex_unlock(&phydev->lock);
/* if phy was suspended, bring the physical link up again */
if (do_resume)
phy_resume(phydev);
phy_trigger_machine(phydev, true);
}
EXPORT_SYMBOL(phy_start);

View File

@ -135,7 +135,9 @@ static int mdio_bus_phy_resume(struct device *dev)
if (!mdio_bus_phy_may_suspend(phydev))
goto no_resume;
mutex_lock(&phydev->lock);
ret = phy_resume(phydev);
mutex_unlock(&phydev->lock);
if (ret < 0)
return ret;
@ -1026,7 +1028,9 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
if (err)
goto error;
mutex_lock(&phydev->lock);
phy_resume(phydev);
mutex_unlock(&phydev->lock);
phy_led_triggers_register(phydev);
return err;
@ -1157,6 +1161,8 @@ int phy_resume(struct phy_device *phydev)
struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver);
int ret = 0;
WARN_ON(!mutex_is_locked(&phydev->lock));
if (phydev->drv && phydrv->resume)
ret = phydrv->resume(phydev);
@ -1639,13 +1645,9 @@ int genphy_resume(struct phy_device *phydev)
{
int value;
mutex_lock(&phydev->lock);
value = phy_read(phydev, MII_BMCR);
phy_write(phydev, MII_BMCR, value & ~BMCR_PDOWN);
mutex_unlock(&phydev->lock);
return 0;
}
EXPORT_SYMBOL(genphy_resume);

View File

@ -1204,12 +1204,14 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x1199, 0x9079, 10)}, /* Sierra Wireless EM74xx */
{QMI_FIXED_INTF(0x1199, 0x907b, 8)}, /* Sierra Wireless EM74xx */
{QMI_FIXED_INTF(0x1199, 0x907b, 10)}, /* Sierra Wireless EM74xx */
{QMI_FIXED_INTF(0x1199, 0x9091, 8)}, /* Sierra Wireless EM7565 */
{QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
{QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */
{QMI_FIXED_INTF(0x1c9e, 0x9801, 3)}, /* Telewell TW-3G HSPA+ */

View File

@ -81,6 +81,7 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
* can be looked up later */
of_node_get(child);
phy->mdio.dev.of_node = child;
phy->mdio.dev.fwnode = of_fwnode_handle(child);
/* All data is now stored in the phy struct;
* register it */
@ -111,6 +112,7 @@ static int of_mdiobus_register_device(struct mii_bus *mdio,
*/
of_node_get(child);
mdiodev->dev.of_node = child;
mdiodev->dev.fwnode = of_fwnode_handle(child);
/* All data is now stored in the mdiodev struct; register it. */
rc = mdio_device_register(mdiodev);
@ -206,6 +208,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
mdio->phy_mask = ~0;
mdio->dev.of_node = np;
mdio->dev.fwnode = of_fwnode_handle(np);
/* Get bus level PHY reset GPIO details */
mdio->reset_delay_us = DEFAULT_GPIO_RESET_DELAY;

View File

@ -565,9 +565,9 @@ enum qeth_cq {
};
struct qeth_ipato {
int enabled;
int invert4;
int invert6;
bool enabled;
bool invert4;
bool invert6;
struct list_head entries;
};

View File

@ -1480,9 +1480,9 @@ static int qeth_setup_card(struct qeth_card *card)
qeth_set_intial_options(card);
/* IP address takeover */
INIT_LIST_HEAD(&card->ipato.entries);
card->ipato.enabled = 0;
card->ipato.invert4 = 0;
card->ipato.invert6 = 0;
card->ipato.enabled = false;
card->ipato.invert4 = false;
card->ipato.invert6 = false;
/* init QDIO stuff */
qeth_init_qdio_info(card);
INIT_DELAYED_WORK(&card->buffer_reclaim_work, qeth_buffer_reclaim_work);

View File

@ -82,7 +82,7 @@ void qeth_l3_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
const u8 *);
int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
void qeth_l3_update_ipato(struct qeth_card *card);
struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions);
int qeth_l3_add_ip(struct qeth_card *, struct qeth_ipaddr *);
int qeth_l3_delete_ip(struct qeth_card *, struct qeth_ipaddr *);

View File

@ -164,8 +164,8 @@ static void qeth_l3_convert_addr_to_bits(u8 *addr, u8 *bits, int len)
}
}
int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
struct qeth_ipaddr *addr)
static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
struct qeth_ipaddr *addr)
{
struct qeth_ipato_entry *ipatoe;
u8 addr_bits[128] = {0, };
@ -174,6 +174,8 @@ int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
if (!card->ipato.enabled)
return 0;
if (addr->type != QETH_IP_TYPE_NORMAL)
return 0;
qeth_l3_convert_addr_to_bits((u8 *) &addr->u, addr_bits,
(addr->proto == QETH_PROT_IPV4)? 4:16);
@ -290,8 +292,7 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
memcpy(addr, tmp_addr, sizeof(struct qeth_ipaddr));
addr->ref_counter = 1;
if (addr->type == QETH_IP_TYPE_NORMAL &&
qeth_l3_is_addr_covered_by_ipato(card, addr)) {
if (qeth_l3_is_addr_covered_by_ipato(card, addr)) {
QETH_CARD_TEXT(card, 2, "tkovaddr");
addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
}
@ -605,6 +606,27 @@ int qeth_l3_setrouting_v6(struct qeth_card *card)
/*
* IP address takeover related functions
*/
/**
* qeth_l3_update_ipato() - Update 'takeover' property, for all NORMAL IPs.
*
* Caller must hold ip_lock.
*/
void qeth_l3_update_ipato(struct qeth_card *card)
{
struct qeth_ipaddr *addr;
unsigned int i;
hash_for_each(card->ip_htable, i, addr, hnode) {
if (addr->type != QETH_IP_TYPE_NORMAL)
continue;
if (qeth_l3_is_addr_covered_by_ipato(card, addr))
addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
else
addr->set_flags &= ~QETH_IPA_SETIP_TAKEOVER_FLAG;
}
}
static void qeth_l3_clear_ipato_list(struct qeth_card *card)
{
struct qeth_ipato_entry *ipatoe, *tmp;
@ -616,6 +638,7 @@ static void qeth_l3_clear_ipato_list(struct qeth_card *card)
kfree(ipatoe);
}
qeth_l3_update_ipato(card);
spin_unlock_bh(&card->ip_lock);
}
@ -640,8 +663,10 @@ int qeth_l3_add_ipato_entry(struct qeth_card *card,
}
}
if (!rc)
if (!rc) {
list_add_tail(&new->entry, &card->ipato.entries);
qeth_l3_update_ipato(card);
}
spin_unlock_bh(&card->ip_lock);
@ -664,6 +689,7 @@ void qeth_l3_del_ipato_entry(struct qeth_card *card,
(proto == QETH_PROT_IPV4)? 4:16) &&
(ipatoe->mask_bits == mask_bits)) {
list_del(&ipatoe->entry);
qeth_l3_update_ipato(card);
kfree(ipatoe);
}
}

View File

@ -370,8 +370,8 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev_get_drvdata(dev);
struct qeth_ipaddr *addr;
int i, rc = 0;
bool enable;
int rc = 0;
if (!card)
return -EINVAL;
@ -384,25 +384,18 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
}
if (sysfs_streq(buf, "toggle")) {
card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
} else if (sysfs_streq(buf, "1")) {
card->ipato.enabled = 1;
hash_for_each(card->ip_htable, i, addr, hnode) {
if ((addr->type == QETH_IP_TYPE_NORMAL) &&
qeth_l3_is_addr_covered_by_ipato(card, addr))
addr->set_flags |=
QETH_IPA_SETIP_TAKEOVER_FLAG;
}
} else if (sysfs_streq(buf, "0")) {
card->ipato.enabled = 0;
hash_for_each(card->ip_htable, i, addr, hnode) {
if (addr->set_flags &
QETH_IPA_SETIP_TAKEOVER_FLAG)
addr->set_flags &=
~QETH_IPA_SETIP_TAKEOVER_FLAG;
}
} else
enable = !card->ipato.enabled;
} else if (kstrtobool(buf, &enable)) {
rc = -EINVAL;
goto out;
}
if (card->ipato.enabled != enable) {
card->ipato.enabled = enable;
spin_lock_bh(&card->ip_lock);
qeth_l3_update_ipato(card);
spin_unlock_bh(&card->ip_lock);
}
out:
mutex_unlock(&card->conf_mutex);
return rc ? rc : count;
@ -428,20 +421,27 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
const char *buf, size_t count)
{
struct qeth_card *card = dev_get_drvdata(dev);
bool invert;
int rc = 0;
if (!card)
return -EINVAL;
mutex_lock(&card->conf_mutex);
if (sysfs_streq(buf, "toggle"))
card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
else if (sysfs_streq(buf, "1"))
card->ipato.invert4 = 1;
else if (sysfs_streq(buf, "0"))
card->ipato.invert4 = 0;
else
if (sysfs_streq(buf, "toggle")) {
invert = !card->ipato.invert4;
} else if (kstrtobool(buf, &invert)) {
rc = -EINVAL;
goto out;
}
if (card->ipato.invert4 != invert) {
card->ipato.invert4 = invert;
spin_lock_bh(&card->ip_lock);
qeth_l3_update_ipato(card);
spin_unlock_bh(&card->ip_lock);
}
out:
mutex_unlock(&card->conf_mutex);
return rc ? rc : count;
}
@ -607,20 +607,27 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev_get_drvdata(dev);
bool invert;
int rc = 0;
if (!card)
return -EINVAL;
mutex_lock(&card->conf_mutex);
if (sysfs_streq(buf, "toggle"))
card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
else if (sysfs_streq(buf, "1"))
card->ipato.invert6 = 1;
else if (sysfs_streq(buf, "0"))
card->ipato.invert6 = 0;
else
if (sysfs_streq(buf, "toggle")) {
invert = !card->ipato.invert6;
} else if (kstrtobool(buf, &invert)) {
rc = -EINVAL;
goto out;
}
if (card->ipato.invert6 != invert) {
card->ipato.invert6 = invert;
spin_lock_bh(&card->ip_lock);
qeth_l3_update_ipato(card);
spin_unlock_bh(&card->ip_lock);
}
out:
mutex_unlock(&card->conf_mutex);
return rc ? rc : count;
}

View File

@ -101,12 +101,18 @@ static inline bool ptr_ring_full_bh(struct ptr_ring *r)
/* Note: callers invoking this in a loop must use a compiler barrier,
* for example cpu_relax(). Callers must hold producer_lock.
* Callers are responsible for making sure pointer that is being queued
* points to a valid data.
*/
static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)
{
if (unlikely(!r->size) || r->queue[r->producer])
return -ENOSPC;
/* Make sure the pointer we are storing points to a valid data. */
/* Pairs with smp_read_barrier_depends in __ptr_ring_consume. */
smp_wmb();
r->queue[r->producer++] = ptr;
if (unlikely(r->producer >= r->size))
r->producer = 0;
@ -275,6 +281,9 @@ static inline void *__ptr_ring_consume(struct ptr_ring *r)
if (ptr)
__ptr_ring_discard_one(r);
/* Make sure anyone accessing data through the pointer is up to date. */
/* Pairs with smp_wmb in __ptr_ring_produce. */
smp_read_barrier_depends();
return ptr;
}

View File

@ -44,10 +44,10 @@ struct guehdr {
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 proto_ctype;
__u16 flags;
__u8 proto_ctype;
__be16 flags;
};
__u32 word;
__be32 word;
};
};
@ -84,11 +84,10 @@ static inline size_t guehdr_priv_flags_len(__be32 flags)
* if there is an unknown standard or private flags, or the options length for
* the flags exceeds the options length specific in hlen of the GUE header.
*/
static inline int validate_gue_flags(struct guehdr *guehdr,
size_t optlen)
static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
{
__be16 flags = guehdr->flags;
size_t len;
__be32 flags = guehdr->flags;
if (flags & ~GUE_FLAGS_ALL)
return 1;
@ -101,12 +100,13 @@ static inline int validate_gue_flags(struct guehdr *guehdr,
/* Private flags are last four bytes accounted in
* guehdr_flags_len
*/
flags = *(__be32 *)((void *)&guehdr[1] + len - GUE_LEN_PRIV);
__be32 pflags = *(__be32 *)((void *)&guehdr[1] +
len - GUE_LEN_PRIV);
if (flags & ~GUE_PFLAGS_ALL)
if (pflags & ~GUE_PFLAGS_ALL)
return 1;
len += guehdr_priv_flags_len(flags);
len += guehdr_priv_flags_len(pflags);
if (len > optlen)
return 1;
}

View File

@ -34,6 +34,7 @@
#include <net/flow_dissector.h>
#define IPV4_MAX_PMTU 65535U /* RFC 2675, Section 5.1 */
#define IPV4_MIN_MTU 68 /* RFC 791 */
struct sock;

View File

@ -71,6 +71,7 @@ struct Qdisc {
* qdisc_tree_decrease_qlen() should stop.
*/
#define TCQ_F_INVISIBLE 0x80 /* invisible by default in dump */
#define TCQ_F_OFFLOADED 0x200 /* qdisc is offloaded to HW */
u32 limit;
const struct Qdisc_ops *ops;
struct qdisc_size_table __rcu *stab;

View File

@ -256,7 +256,6 @@ struct tc_red_qopt {
#define TC_RED_ECN 1
#define TC_RED_HARDDROP 2
#define TC_RED_ADAPTATIVE 4
#define TC_RED_OFFLOADED 8
};
struct tc_red_xstats {

View File

@ -557,6 +557,7 @@ enum {
TCA_PAD,
TCA_DUMP_INVISIBLE,
TCA_CHAIN,
TCA_HW_OFFLOAD,
__TCA_MAX
};

View File

@ -114,6 +114,7 @@ static void htab_free_elems(struct bpf_htab *htab)
pptr = htab_elem_get_ptr(get_htab_elem(htab, i),
htab->map.key_size);
free_percpu(pptr);
cond_resched();
}
free_elems:
bpf_map_area_free(htab->elems);
@ -159,6 +160,7 @@ static int prealloc_init(struct bpf_htab *htab)
goto free_elems;
htab_elem_set_ptr(get_htab_elem(htab, i), htab->map.key_size,
pptr);
cond_resched();
}
skip_percpu_elems:

View File

@ -343,14 +343,13 @@ static const struct bpf_func_proto bpf_perf_event_read_value_proto = {
.arg4_type = ARG_CONST_SIZE,
};
static DEFINE_PER_CPU(struct perf_sample_data, bpf_sd);
static DEFINE_PER_CPU(struct perf_sample_data, bpf_trace_sd);
static __always_inline u64
__bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map,
u64 flags, struct perf_raw_record *raw)
u64 flags, struct perf_sample_data *sd)
{
struct bpf_array *array = container_of(map, struct bpf_array, map);
struct perf_sample_data *sd = this_cpu_ptr(&bpf_sd);
unsigned int cpu = smp_processor_id();
u64 index = flags & BPF_F_INDEX_MASK;
struct bpf_event_entry *ee;
@ -373,8 +372,6 @@ __bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map,
if (unlikely(event->oncpu != cpu))
return -EOPNOTSUPP;
perf_sample_data_init(sd, 0, 0);
sd->raw = raw;
perf_event_output(event, sd, regs);
return 0;
}
@ -382,6 +379,7 @@ __bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map,
BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map,
u64, flags, void *, data, u64, size)
{
struct perf_sample_data *sd = this_cpu_ptr(&bpf_trace_sd);
struct perf_raw_record raw = {
.frag = {
.size = size,
@ -392,7 +390,10 @@ BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map,
if (unlikely(flags & ~(BPF_F_INDEX_MASK)))
return -EINVAL;
return __bpf_perf_event_output(regs, map, flags, &raw);
perf_sample_data_init(sd, 0, 0);
sd->raw = &raw;
return __bpf_perf_event_output(regs, map, flags, sd);
}
static const struct bpf_func_proto bpf_perf_event_output_proto = {
@ -407,10 +408,12 @@ static const struct bpf_func_proto bpf_perf_event_output_proto = {
};
static DEFINE_PER_CPU(struct pt_regs, bpf_pt_regs);
static DEFINE_PER_CPU(struct perf_sample_data, bpf_misc_sd);
u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy)
{
struct perf_sample_data *sd = this_cpu_ptr(&bpf_misc_sd);
struct pt_regs *regs = this_cpu_ptr(&bpf_pt_regs);
struct perf_raw_frag frag = {
.copy = ctx_copy,
@ -428,8 +431,10 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
};
perf_fetch_caller_regs(regs);
perf_sample_data_init(sd, 0, 0);
sd->raw = &raw;
return __bpf_perf_event_output(regs, map, flags, &raw);
return __bpf_perf_event_output(regs, map, flags, sd);
}
BPF_CALL_0(bpf_get_current_task)

View File

@ -1214,7 +1214,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
orig_node->last_seen = jiffies;
/* find packet count of corresponding one hop neighbor */
spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
if_num = if_incoming->if_num;
orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num];
neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
@ -1224,7 +1224,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
} else {
neigh_rq_count = 0;
}
spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
/* pay attention to not get a value bigger than 100 % */
if (orig_eq_count > neigh_rq_count)

View File

@ -814,7 +814,7 @@ static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv,
}
orig_gw = batadv_gw_node_get(bat_priv, orig_node);
if (!orig_node)
if (!orig_gw)
goto out;
if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0)

View File

@ -499,6 +499,8 @@ int batadv_frag_send_packet(struct sk_buff *skb,
*/
if (skb->priority >= 256 && skb->priority <= 263)
frag_header.priority = skb->priority - 256;
else
frag_header.priority = 0;
ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr);
ether_addr_copy(frag_header.dest, orig_node->orig);

View File

@ -482,7 +482,7 @@ static void batadv_tp_reset_sender_timer(struct batadv_tp_vars *tp_vars)
/**
* batadv_tp_sender_timeout - timer that fires in case of packet loss
* @arg: address of the related tp_vars
* @t: address to timer_list inside tp_vars
*
* If fired it means that there was packet loss.
* Switch to Slow Start, set the ss_threshold to half of the current cwnd and
@ -1106,7 +1106,7 @@ static void batadv_tp_reset_receiver_timer(struct batadv_tp_vars *tp_vars)
/**
* batadv_tp_receiver_shutdown - stop a tp meter receiver when timeout is
* reached without received ack
* @arg: address of the related tp_vars
* @t: address to timer_list inside tp_vars
*/
static void batadv_tp_receiver_shutdown(struct timer_list *t)
{

View File

@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>

View File

@ -4293,7 +4293,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
struct sock *sk = skb->sk;
if (!skb_may_tx_timestamp(sk, false))
return;
goto err;
/* Take a reference to prevent skb_orphan() from freeing the socket,
* but only if the socket refcount is not zero.
@ -4302,7 +4302,11 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
*skb_hwtstamps(skb) = *hwtstamps;
__skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND, false);
sock_put(sk);
return;
}
err:
kfree_skb(skb);
}
EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp);

View File

@ -16,7 +16,6 @@
#include <linux/of_net.h>
#include <linux/of_mdio.h>
#include <linux/mdio.h>
#include <linux/list.h>
#include <net/rtnetlink.h>
#include <net/pkt_cls.h>
#include <net/tc_act/tc_mirred.h>

View File

@ -1428,7 +1428,7 @@ skip:
static bool inetdev_valid_mtu(unsigned int mtu)
{
return mtu >= 68;
return mtu >= IPV4_MIN_MTU;
}
static void inetdev_send_gratuitous_arp(struct net_device *dev,

View File

@ -89,6 +89,7 @@
#include <linux/rtnetlink.h>
#include <linux/times.h>
#include <linux/pkt_sched.h>
#include <linux/byteorder/generic.h>
#include <net/net_namespace.h>
#include <net/arp.h>
@ -321,6 +322,23 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted)
return scount;
}
/* source address selection per RFC 3376 section 4.2.13 */
static __be32 igmpv3_get_srcaddr(struct net_device *dev,
const struct flowi4 *fl4)
{
struct in_device *in_dev = __in_dev_get_rcu(dev);
if (!in_dev)
return htonl(INADDR_ANY);
for_ifa(in_dev) {
if (inet_ifa_match(fl4->saddr, ifa))
return fl4->saddr;
} endfor_ifa(in_dev);
return htonl(INADDR_ANY);
}
static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu)
{
struct sk_buff *skb;
@ -368,7 +386,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu)
pip->frag_off = htons(IP_DF);
pip->ttl = 1;
pip->daddr = fl4.daddr;
pip->saddr = fl4.saddr;
pip->saddr = igmpv3_get_srcaddr(dev, &fl4);
pip->protocol = IPPROTO_IGMP;
pip->tot_len = 0; /* filled in later */
ip_select_ident(net, skb, NULL);
@ -404,16 +422,17 @@ static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
}
static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc,
int type, struct igmpv3_grec **ppgr)
int type, struct igmpv3_grec **ppgr, unsigned int mtu)
{
struct net_device *dev = pmc->interface->dev;
struct igmpv3_report *pih;
struct igmpv3_grec *pgr;
if (!skb)
skb = igmpv3_newpack(dev, dev->mtu);
if (!skb)
return NULL;
if (!skb) {
skb = igmpv3_newpack(dev, mtu);
if (!skb)
return NULL;
}
pgr = skb_put(skb, sizeof(struct igmpv3_grec));
pgr->grec_type = type;
pgr->grec_auxwords = 0;
@ -436,12 +455,17 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
struct igmpv3_grec *pgr = NULL;
struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list;
int scount, stotal, first, isquery, truncate;
unsigned int mtu;
if (pmc->multiaddr == IGMP_ALL_HOSTS)
return skb;
if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports)
return skb;
mtu = READ_ONCE(dev->mtu);
if (mtu < IPV4_MIN_MTU)
return skb;
isquery = type == IGMPV3_MODE_IS_INCLUDE ||
type == IGMPV3_MODE_IS_EXCLUDE;
truncate = type == IGMPV3_MODE_IS_EXCLUDE ||
@ -462,7 +486,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) {
if (skb)
igmpv3_sendpack(skb);
skb = igmpv3_newpack(dev, dev->mtu);
skb = igmpv3_newpack(dev, mtu);
}
}
first = 1;
@ -498,12 +522,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
pgr->grec_nsrcs = htons(scount);
if (skb)
igmpv3_sendpack(skb);
skb = igmpv3_newpack(dev, dev->mtu);
skb = igmpv3_newpack(dev, mtu);
first = 1;
scount = 0;
}
if (first) {
skb = add_grhead(skb, pmc, type, &pgr);
skb = add_grhead(skb, pmc, type, &pgr, mtu);
first = 0;
}
if (!skb)
@ -538,7 +562,7 @@ empty_source:
igmpv3_sendpack(skb);
skb = NULL; /* add_grhead will get a new one */
}
skb = add_grhead(skb, pmc, type, &pgr);
skb = add_grhead(skb, pmc, type, &pgr, mtu);
}
}
if (pgr)

View File

@ -266,7 +266,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
len = gre_hdr_len + sizeof(*ershdr);
if (unlikely(!pskb_may_pull(skb, len)))
return -ENOMEM;
return PACKET_REJECT;
iph = ip_hdr(skb);
ershdr = (struct erspanhdr *)(skb->data + gre_hdr_len);

View File

@ -349,8 +349,8 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
dev->needed_headroom = t_hlen + hlen;
mtu -= (dev->hard_header_len + t_hlen);
if (mtu < 68)
mtu = 68;
if (mtu < IPV4_MIN_MTU)
mtu = IPV4_MIN_MTU;
return mtu;
}

View File

@ -373,7 +373,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
if (!xt_find_jump_offset(offsets, newpos,
newinfo->number))
return 0;
e = entry0 + newpos;
} else {
/* ... this is a fallthru */
newpos = pos + e->next_offset;

View File

@ -439,7 +439,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
if (!xt_find_jump_offset(offsets, newpos,
newinfo->number))
return 0;
e = entry0 + newpos;
} else {
/* ... this is a fallthru */
newpos = pos + e->next_offset;

View File

@ -813,12 +813,13 @@ static int clusterip_net_init(struct net *net)
static void clusterip_net_exit(struct net *net)
{
#ifdef CONFIG_PROC_FS
struct clusterip_net *cn = net_generic(net, clusterip_net_id);
#ifdef CONFIG_PROC_FS
proc_remove(cn->procdir);
cn->procdir = NULL;
#endif
nf_unregister_net_hook(net, &cip_arp_ops);
WARN_ON_ONCE(!list_empty(&cn->configs));
}
static struct pernet_operations clusterip_net_ops = {

View File

@ -513,11 +513,16 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
int err;
struct ip_options_data opt_copy;
struct raw_frag_vec rfv;
int hdrincl;
err = -EMSGSIZE;
if (len > 0xFFFF)
goto out;
/* hdrincl should be READ_ONCE(inet->hdrincl)
* but READ_ONCE() doesn't work with bit fields
*/
hdrincl = inet->hdrincl;
/*
* Check the flags.
*/
@ -593,7 +598,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
/* Linux does not mangle headers on raw sockets,
* so that IP options + IP_HDRINCL is non-sense.
*/
if (inet->hdrincl)
if (hdrincl)
goto done;
if (ipc.opt->opt.srr) {
if (!daddr)
@ -615,12 +620,12 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
RT_SCOPE_UNIVERSE,
inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
hdrincl ? IPPROTO_RAW : sk->sk_protocol,
inet_sk_flowi_flags(sk) |
(inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
(hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
daddr, saddr, 0, 0, sk->sk_uid);
if (!inet->hdrincl) {
if (!hdrincl) {
rfv.msg = msg;
rfv.hlen = 0;
@ -645,7 +650,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
goto do_confirm;
back_from_confirm:
if (inet->hdrincl)
if (hdrincl)
err = raw_send_hdrinc(sk, &fl4, msg, len,
&rt, msg->msg_flags, &ipc.sockc);

View File

@ -508,9 +508,6 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep)
u32 new_sample = tp->rcv_rtt_est.rtt_us;
long m = sample;
if (m == 0)
m = 1;
if (new_sample != 0) {
/* If we sample in larger samples in the non-timestamp
* case, we could grossly overestimate the RTT especially
@ -547,6 +544,8 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp)
if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq))
return;
delta_us = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcv_rtt_est.time);
if (!delta_us)
delta_us = 1;
tcp_rcv_rtt_update(tp, delta_us, 1);
new_measure:
@ -563,8 +562,11 @@ static inline void tcp_rcv_rtt_measure_ts(struct sock *sk,
(TCP_SKB_CB(skb)->end_seq -
TCP_SKB_CB(skb)->seq >= inet_csk(sk)->icsk_ack.rcv_mss)) {
u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr;
u32 delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ);
u32 delta_us;
if (!delta)
delta = 1;
delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ);
tcp_rcv_rtt_update(tp, delta_us, 0);
}
}

View File

@ -848,7 +848,7 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
req->ts_recent,
0,
tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->daddr,
tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr,
AF_INET),
inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0,
ip_hdr(skb)->tos);

View File

@ -264,6 +264,7 @@ void tcp_delack_timer_handler(struct sock *sk)
icsk->icsk_ack.pingpong = 0;
icsk->icsk_ack.ato = TCP_ATO_MIN;
}
tcp_mstamp_refresh(tcp_sk(sk));
tcp_send_ack(sk);
__NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKS);
}
@ -632,6 +633,7 @@ static void tcp_keepalive_timer (struct timer_list *t)
goto out;
}
tcp_mstamp_refresh(tp);
if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) {
if (tp->linger2 >= 0) {
const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN;

View File

@ -1682,16 +1682,16 @@ static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel)
}
static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc,
int type, struct mld2_grec **ppgr)
int type, struct mld2_grec **ppgr, unsigned int mtu)
{
struct net_device *dev = pmc->idev->dev;
struct mld2_report *pmr;
struct mld2_grec *pgr;
if (!skb)
skb = mld_newpack(pmc->idev, dev->mtu);
if (!skb)
return NULL;
if (!skb) {
skb = mld_newpack(pmc->idev, mtu);
if (!skb)
return NULL;
}
pgr = skb_put(skb, sizeof(struct mld2_grec));
pgr->grec_type = type;
pgr->grec_auxwords = 0;
@ -1714,10 +1714,15 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
struct mld2_grec *pgr = NULL;
struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list;
int scount, stotal, first, isquery, truncate;
unsigned int mtu;
if (pmc->mca_flags & MAF_NOREPORT)
return skb;
mtu = READ_ONCE(dev->mtu);
if (mtu < IPV6_MIN_MTU)
return skb;
isquery = type == MLD2_MODE_IS_INCLUDE ||
type == MLD2_MODE_IS_EXCLUDE;
truncate = type == MLD2_MODE_IS_EXCLUDE ||
@ -1738,7 +1743,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) {
if (skb)
mld_sendpack(skb);
skb = mld_newpack(idev, dev->mtu);
skb = mld_newpack(idev, mtu);
}
}
first = 1;
@ -1774,12 +1779,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
pgr->grec_nsrcs = htons(scount);
if (skb)
mld_sendpack(skb);
skb = mld_newpack(idev, dev->mtu);
skb = mld_newpack(idev, mtu);
first = 1;
scount = 0;
}
if (first) {
skb = add_grhead(skb, pmc, type, &pgr);
skb = add_grhead(skb, pmc, type, &pgr, mtu);
first = 0;
}
if (!skb)
@ -1814,7 +1819,7 @@ empty_source:
mld_sendpack(skb);
skb = NULL; /* add_grhead will get a new one */
}
skb = add_grhead(skb, pmc, type, &pgr);
skb = add_grhead(skb, pmc, type, &pgr, mtu);
}
}
if (pgr)

View File

@ -458,7 +458,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
if (!xt_find_jump_offset(offsets, newpos,
newinfo->number))
return 0;
e = entry0 + newpos;
} else {
/* ... this is a fallthru */
newpos = pos + e->next_offset;

View File

@ -33,13 +33,19 @@ static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par)
if (range->flags & NF_NAT_RANGE_MAP_IPS)
return -EINVAL;
return 0;
return nf_ct_netns_get(par->net, par->family);
}
static void masquerade_tg6_destroy(const struct xt_tgdtor_param *par)
{
nf_ct_netns_put(par->net, par->family);
}
static struct xt_target masquerade_tg6_reg __read_mostly = {
.name = "MASQUERADE",
.family = NFPROTO_IPV6,
.checkentry = masquerade_tg6_checkentry,
.destroy = masquerade_tg6_destroy,
.target = masquerade_tg6,
.targetsize = sizeof(struct nf_nat_range),
.table = "nat",

View File

@ -994,7 +994,7 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
req->ts_recent, sk->sk_bound_dev_if,
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr),
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr),
0, 0);
}

View File

@ -291,16 +291,15 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
int i;
mutex_lock(&sta->ampdu_mlme.mtx);
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
___ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
WLAN_REASON_QSTA_LEAVE_QBSS,
reason != AGG_STOP_DESTROY_STA &&
reason != AGG_STOP_PEER_REQUEST);
}
mutex_unlock(&sta->ampdu_mlme.mtx);
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
___ieee80211_stop_tx_ba_session(sta, i, reason);
mutex_unlock(&sta->ampdu_mlme.mtx);
/* stopping might queue the work again - so cancel only afterwards */
cancel_work_sync(&sta->ampdu_mlme.work);

View File

@ -103,7 +103,6 @@ struct bitstr {
#define INC_BIT(bs) if((++(bs)->bit)>7){(bs)->cur++;(bs)->bit=0;}
#define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;}
#define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;}
#define CHECK_BOUND(bs,n) if((bs)->cur+(n)>(bs)->end)return(H323_ERROR_BOUND)
static unsigned int get_len(struct bitstr *bs);
static unsigned int get_bit(struct bitstr *bs);
static unsigned int get_bits(struct bitstr *bs, unsigned int b);
@ -165,6 +164,19 @@ static unsigned int get_len(struct bitstr *bs)
return v;
}
static int nf_h323_error_boundary(struct bitstr *bs, size_t bytes, size_t bits)
{
bits += bs->bit;
bytes += bits / BITS_PER_BYTE;
if (bits % BITS_PER_BYTE > 0)
bytes++;
if (*bs->cur + bytes > *bs->end)
return 1;
return 0;
}
/****************************************************************************/
static unsigned int get_bit(struct bitstr *bs)
{
@ -279,8 +291,8 @@ static int decode_bool(struct bitstr *bs, const struct field_t *f,
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
INC_BIT(bs);
CHECK_BOUND(bs, 0);
if (nf_h323_error_boundary(bs, 0, 0))
return H323_ERROR_BOUND;
return H323_ERROR_NONE;
}
@ -293,11 +305,14 @@ static int decode_oid(struct bitstr *bs, const struct field_t *f,
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
BYTE_ALIGN(bs);
CHECK_BOUND(bs, 1);
if (nf_h323_error_boundary(bs, 1, 0))
return H323_ERROR_BOUND;
len = *bs->cur++;
bs->cur += len;
if (nf_h323_error_boundary(bs, 0, 0))
return H323_ERROR_BOUND;
CHECK_BOUND(bs, 0);
return H323_ERROR_NONE;
}
@ -319,6 +334,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f,
bs->cur += 2;
break;
case CONS: /* 64K < Range < 4G */
if (nf_h323_error_boundary(bs, 0, 2))
return H323_ERROR_BOUND;
len = get_bits(bs, 2) + 1;
BYTE_ALIGN(bs);
if (base && (f->attr & DECODE)) { /* timeToLive */
@ -330,7 +347,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f,
break;
case UNCO:
BYTE_ALIGN(bs);
CHECK_BOUND(bs, 2);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
len = get_len(bs);
bs->cur += len;
break;
@ -341,7 +359,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f,
PRINT("\n");
CHECK_BOUND(bs, 0);
if (nf_h323_error_boundary(bs, 0, 0))
return H323_ERROR_BOUND;
return H323_ERROR_NONE;
}
@ -357,7 +376,8 @@ static int decode_enum(struct bitstr *bs, const struct field_t *f,
INC_BITS(bs, f->sz);
}
CHECK_BOUND(bs, 0);
if (nf_h323_error_boundary(bs, 0, 0))
return H323_ERROR_BOUND;
return H323_ERROR_NONE;
}
@ -375,12 +395,14 @@ static int decode_bitstr(struct bitstr *bs, const struct field_t *f,
len = f->lb;
break;
case WORD: /* 2-byte length */
CHECK_BOUND(bs, 2);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
len = (*bs->cur++) << 8;
len += (*bs->cur++) + f->lb;
break;
case SEMI:
CHECK_BOUND(bs, 2);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
len = get_len(bs);
break;
default:
@ -391,7 +413,8 @@ static int decode_bitstr(struct bitstr *bs, const struct field_t *f,
bs->cur += len >> 3;
bs->bit = len & 7;
CHECK_BOUND(bs, 0);
if (nf_h323_error_boundary(bs, 0, 0))
return H323_ERROR_BOUND;
return H323_ERROR_NONE;
}
@ -404,12 +427,15 @@ static int decode_numstr(struct bitstr *bs, const struct field_t *f,
PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name);
/* 2 <= Range <= 255 */
if (nf_h323_error_boundary(bs, 0, f->sz))
return H323_ERROR_BOUND;
len = get_bits(bs, f->sz) + f->lb;
BYTE_ALIGN(bs);
INC_BITS(bs, (len << 2));
CHECK_BOUND(bs, 0);
if (nf_h323_error_boundary(bs, 0, 0))
return H323_ERROR_BOUND;
return H323_ERROR_NONE;
}
@ -440,15 +466,19 @@ static int decode_octstr(struct bitstr *bs, const struct field_t *f,
break;
case BYTE: /* Range == 256 */
BYTE_ALIGN(bs);
CHECK_BOUND(bs, 1);
if (nf_h323_error_boundary(bs, 1, 0))
return H323_ERROR_BOUND;
len = (*bs->cur++) + f->lb;
break;
case SEMI:
BYTE_ALIGN(bs);
CHECK_BOUND(bs, 2);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
len = get_len(bs) + f->lb;
break;
default: /* 2 <= Range <= 255 */
if (nf_h323_error_boundary(bs, 0, f->sz))
return H323_ERROR_BOUND;
len = get_bits(bs, f->sz) + f->lb;
BYTE_ALIGN(bs);
break;
@ -458,7 +488,8 @@ static int decode_octstr(struct bitstr *bs, const struct field_t *f,
PRINT("\n");
CHECK_BOUND(bs, 0);
if (nf_h323_error_boundary(bs, 0, 0))
return H323_ERROR_BOUND;
return H323_ERROR_NONE;
}
@ -473,10 +504,13 @@ static int decode_bmpstr(struct bitstr *bs, const struct field_t *f,
switch (f->sz) {
case BYTE: /* Range == 256 */
BYTE_ALIGN(bs);
CHECK_BOUND(bs, 1);
if (nf_h323_error_boundary(bs, 1, 0))
return H323_ERROR_BOUND;
len = (*bs->cur++) + f->lb;
break;
default: /* 2 <= Range <= 255 */
if (nf_h323_error_boundary(bs, 0, f->sz))
return H323_ERROR_BOUND;
len = get_bits(bs, f->sz) + f->lb;
BYTE_ALIGN(bs);
break;
@ -484,7 +518,8 @@ static int decode_bmpstr(struct bitstr *bs, const struct field_t *f,
bs->cur += len << 1;
CHECK_BOUND(bs, 0);
if (nf_h323_error_boundary(bs, 0, 0))
return H323_ERROR_BOUND;
return H323_ERROR_NONE;
}
@ -503,9 +538,13 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f,
base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
/* Extensible? */
if (nf_h323_error_boundary(bs, 0, 1))
return H323_ERROR_BOUND;
ext = (f->attr & EXT) ? get_bit(bs) : 0;
/* Get fields bitmap */
if (nf_h323_error_boundary(bs, 0, f->sz))
return H323_ERROR_BOUND;
bmp = get_bitmap(bs, f->sz);
if (base)
*(unsigned int *)base = bmp;
@ -525,9 +564,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f,
/* Decode */
if (son->attr & OPEN) { /* Open field */
CHECK_BOUND(bs, 2);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
len = get_len(bs);
CHECK_BOUND(bs, len);
if (nf_h323_error_boundary(bs, len, 0))
return H323_ERROR_BOUND;
if (!base || !(son->attr & DECODE)) {
PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
" ", son->name);
@ -555,8 +596,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f,
return H323_ERROR_NONE;
/* Get the extension bitmap */
if (nf_h323_error_boundary(bs, 0, 7))
return H323_ERROR_BOUND;
bmp2_len = get_bits(bs, 7) + 1;
CHECK_BOUND(bs, (bmp2_len + 7) >> 3);
if (nf_h323_error_boundary(bs, 0, bmp2_len))
return H323_ERROR_BOUND;
bmp2 = get_bitmap(bs, bmp2_len);
bmp |= bmp2 >> f->sz;
if (base)
@ -567,9 +611,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f,
for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
/* Check Range */
if (i >= f->ub) { /* Newer Version? */
CHECK_BOUND(bs, 2);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
len = get_len(bs);
CHECK_BOUND(bs, len);
if (nf_h323_error_boundary(bs, len, 0))
return H323_ERROR_BOUND;
bs->cur += len;
continue;
}
@ -583,9 +629,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f,
if (!((0x80000000 >> opt) & bmp2)) /* Not present */
continue;
CHECK_BOUND(bs, 2);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
len = get_len(bs);
CHECK_BOUND(bs, len);
if (nf_h323_error_boundary(bs, len, 0))
return H323_ERROR_BOUND;
if (!base || !(son->attr & DECODE)) {
PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
son->name);
@ -623,22 +671,27 @@ static int decode_seqof(struct bitstr *bs, const struct field_t *f,
switch (f->sz) {
case BYTE:
BYTE_ALIGN(bs);
CHECK_BOUND(bs, 1);
if (nf_h323_error_boundary(bs, 1, 0))
return H323_ERROR_BOUND;
count = *bs->cur++;
break;
case WORD:
BYTE_ALIGN(bs);
CHECK_BOUND(bs, 2);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
count = *bs->cur++;
count <<= 8;
count += *bs->cur++;
break;
case SEMI:
BYTE_ALIGN(bs);
CHECK_BOUND(bs, 2);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
count = get_len(bs);
break;
default:
if (nf_h323_error_boundary(bs, 0, f->sz))
return H323_ERROR_BOUND;
count = get_bits(bs, f->sz);
break;
}
@ -658,8 +711,11 @@ static int decode_seqof(struct bitstr *bs, const struct field_t *f,
for (i = 0; i < count; i++) {
if (son->attr & OPEN) {
BYTE_ALIGN(bs);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
len = get_len(bs);
CHECK_BOUND(bs, len);
if (nf_h323_error_boundary(bs, len, 0))
return H323_ERROR_BOUND;
if (!base || !(son->attr & DECODE)) {
PRINT("%*.s%s\n", (level + 1) * TAB_SIZE,
" ", son->name);
@ -710,11 +766,17 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f,
base = (base && (f->attr & DECODE)) ? base + f->offset : NULL;
/* Decode the choice index number */
if (nf_h323_error_boundary(bs, 0, 1))
return H323_ERROR_BOUND;
if ((f->attr & EXT) && get_bit(bs)) {
ext = 1;
if (nf_h323_error_boundary(bs, 0, 7))
return H323_ERROR_BOUND;
type = get_bits(bs, 7) + f->lb;
} else {
ext = 0;
if (nf_h323_error_boundary(bs, 0, f->sz))
return H323_ERROR_BOUND;
type = get_bits(bs, f->sz);
if (type >= f->lb)
return H323_ERROR_RANGE;
@ -727,8 +789,11 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f,
/* Check Range */
if (type >= f->ub) { /* Newer version? */
BYTE_ALIGN(bs);
if (nf_h323_error_boundary(bs, 2, 0))
return H323_ERROR_BOUND;
len = get_len(bs);
CHECK_BOUND(bs, len);
if (nf_h323_error_boundary(bs, len, 0))
return H323_ERROR_BOUND;
bs->cur += len;
return H323_ERROR_NONE;
}
@ -742,8 +807,11 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f,
if (ext || (son->attr & OPEN)) {
BYTE_ALIGN(bs);
if (nf_h323_error_boundary(bs, len, 0))
return H323_ERROR_BOUND;
len = get_len(bs);
CHECK_BOUND(bs, len);
if (nf_h323_error_boundary(bs, len, 0))
return H323_ERROR_BOUND;
if (!base || !(son->attr & DECODE)) {
PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
son->name);

View File

@ -45,7 +45,6 @@
#include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/nf_conntrack_timestamp.h>
#include <net/netfilter/nf_conntrack_labels.h>
#include <net/netfilter/nf_conntrack_seqadj.h>
#include <net/netfilter/nf_conntrack_synproxy.h>
#ifdef CONFIG_NF_NAT_NEEDED
#include <net/netfilter/nf_nat_core.h>
@ -1566,9 +1565,11 @@ static int ctnetlink_change_helper(struct nf_conn *ct,
static int ctnetlink_change_timeout(struct nf_conn *ct,
const struct nlattr * const cda[])
{
u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
u64 timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
ct->timeout = nfct_time_stamp + timeout * HZ;
if (timeout > INT_MAX)
timeout = INT_MAX;
ct->timeout = nfct_time_stamp + (u32)timeout;
if (test_bit(IPS_DYING_BIT, &ct->status))
return -ETIME;
@ -1768,6 +1769,7 @@ ctnetlink_create_conntrack(struct net *net,
int err = -EINVAL;
struct nf_conntrack_helper *helper;
struct nf_conn_tstamp *tstamp;
u64 timeout;
ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC);
if (IS_ERR(ct))
@ -1776,7 +1778,10 @@ ctnetlink_create_conntrack(struct net *net,
if (!cda[CTA_TIMEOUT])
goto err1;
ct->timeout = nfct_time_stamp + ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
if (timeout > INT_MAX)
timeout = INT_MAX;
ct->timeout = (u32)timeout + nfct_time_stamp;
rcu_read_lock();
if (cda[CTA_HELP]) {

View File

@ -1039,6 +1039,9 @@ static int tcp_packet(struct nf_conn *ct,
IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK])
timeout = timeouts[TCP_CONNTRACK_UNACK];
else if (ct->proto.tcp.last_win == 0 &&
timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
timeout = timeouts[TCP_CONNTRACK_RETRANS];
else
timeout = timeouts[new_state];
spin_unlock_bh(&ct->lock);

View File

@ -5847,6 +5847,12 @@ static int __net_init nf_tables_init_net(struct net *net)
return 0;
}
static void __net_exit nf_tables_exit_net(struct net *net)
{
WARN_ON_ONCE(!list_empty(&net->nft.af_info));
WARN_ON_ONCE(!list_empty(&net->nft.commit_list));
}
int __nft_release_basechain(struct nft_ctx *ctx)
{
struct nft_rule *rule, *nr;
@ -5917,6 +5923,7 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi)
static struct pernet_operations nf_tables_net_ops = {
.init = nf_tables_init_net,
.exit = nf_tables_exit_net,
};
static int __init nf_tables_module_init(void)

View File

@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/capability.h>
#include <net/netlink.h>
#include <net/sock.h>
@ -407,6 +408,9 @@ static int nfnl_cthelper_new(struct net *net, struct sock *nfnl,
struct nfnl_cthelper *nlcth;
int ret = 0;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE])
return -EINVAL;
@ -611,6 +615,9 @@ static int nfnl_cthelper_get(struct net *net, struct sock *nfnl,
struct nfnl_cthelper *nlcth;
bool tuple_set = false;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (nlh->nlmsg_flags & NLM_F_DUMP) {
struct netlink_dump_control c = {
.dump = nfnl_cthelper_dump_table,
@ -678,6 +685,9 @@ static int nfnl_cthelper_del(struct net *net, struct sock *nfnl,
struct nfnl_cthelper *nlcth, *n;
int j = 0, ret;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (tb[NFCTH_NAME])
helper_name = nla_data(tb[NFCTH_NAME]);

View File

@ -1093,10 +1093,15 @@ static int __net_init nfnl_log_net_init(struct net *net)
static void __net_exit nfnl_log_net_exit(struct net *net)
{
struct nfnl_log_net *log = nfnl_log_pernet(net);
unsigned int i;
#ifdef CONFIG_PROC_FS
remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter);
#endif
nf_log_unset(net, &nfulnl_logger);
for (i = 0; i < INSTANCE_BUCKETS; i++)
WARN_ON_ONCE(!hlist_empty(&log->instance_table[i]));
}
static struct pernet_operations nfnl_log_net_ops = {

View File

@ -1512,10 +1512,15 @@ static int __net_init nfnl_queue_net_init(struct net *net)
static void __net_exit nfnl_queue_net_exit(struct net *net)
{
struct nfnl_queue_net *q = nfnl_queue_pernet(net);
unsigned int i;
nf_unregister_queue_handler(net);
#ifdef CONFIG_PROC_FS
remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter);
#endif
for (i = 0; i < INSTANCE_BUCKETS; i++)
WARN_ON_ONCE(!hlist_empty(&q->instance_table[i]));
}
static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list)

View File

@ -214,6 +214,8 @@ static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = {
[NFTA_EXTHDR_OFFSET] = { .type = NLA_U32 },
[NFTA_EXTHDR_LEN] = { .type = NLA_U32 },
[NFTA_EXTHDR_FLAGS] = { .type = NLA_U32 },
[NFTA_EXTHDR_OP] = { .type = NLA_U32 },
[NFTA_EXTHDR_SREG] = { .type = NLA_U32 },
};
static int nft_exthdr_init(const struct nft_ctx *ctx,

View File

@ -1729,8 +1729,17 @@ static int __net_init xt_net_init(struct net *net)
return 0;
}
static void __net_exit xt_net_exit(struct net *net)
{
int i;
for (i = 0; i < NFPROTO_NUMPROTO; i++)
WARN_ON_ONCE(!list_empty(&net->xt.tables[i]));
}
static struct pernet_operations xt_net_ops = {
.init = xt_net_init,
.exit = xt_net_exit,
};
static int __init xt_init(void)

View File

@ -27,6 +27,9 @@ static int __bpf_mt_check_bytecode(struct sock_filter *insns, __u16 len,
{
struct sock_fprog_kern program;
if (len > XT_BPF_MAX_NUM_INSTR)
return -EINVAL;
program.len = len;
program.filter = insns;
@ -55,6 +58,9 @@ static int __bpf_mt_check_path(const char *path, struct bpf_prog **ret)
mm_segment_t oldfs = get_fs();
int retval, fd;
if (strnlen(path, XT_BPF_PATH_MAX) == XT_BPF_PATH_MAX)
return -EINVAL;
set_fs(KERNEL_DS);
fd = bpf_obj_get_user(path, 0);
set_fs(oldfs);

View File

@ -19,6 +19,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/capability.h>
#include <linux/if.h>
#include <linux/inetdevice.h>
#include <linux/ip.h>
@ -70,6 +71,9 @@ static int xt_osf_add_callback(struct net *net, struct sock *ctnl,
struct xt_osf_finger *kf = NULL, *sf;
int err = 0;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (!osf_attrs[OSF_ATTR_FINGER])
return -EINVAL;
@ -115,6 +119,9 @@ static int xt_osf_remove_callback(struct net *net, struct sock *ctnl,
struct xt_osf_finger *sf;
int err = -ENOENT;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (!osf_attrs[OSF_ATTR_FINGER])
return -EINVAL;

View File

@ -253,6 +253,9 @@ static int __netlink_deliver_tap_skb(struct sk_buff *skb,
struct sock *sk = skb->sk;
int ret = -ENOMEM;
if (!net_eq(dev_net(dev), sock_net(sk)))
return 0;
dev_hold(dev);
if (is_vmalloc_addr(skb->head))

View File

@ -22,7 +22,6 @@
#include <net/pkt_sched.h>
#include <uapi/linux/tc_act/tc_ife.h>
#include <net/tc_act/tc_ife.h>
#include <linux/rtnetlink.h>
static int skbmark_encode(struct sk_buff *skb, void *skbdata,
struct tcf_meta_info *e)

View File

@ -22,7 +22,6 @@
#include <net/pkt_sched.h>
#include <uapi/linux/tc_act/tc_ife.h>
#include <net/tc_act/tc_ife.h>
#include <linux/rtnetlink.h>
static int skbtcindex_encode(struct sk_buff *skb, void *skbdata,
struct tcf_meta_info *e)

View File

@ -23,7 +23,6 @@
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/kmod.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <net/net_namespace.h>
#include <net/sock.h>
@ -352,6 +351,8 @@ void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
{
struct tcf_chain *chain;
if (!block)
return;
/* Hold a refcnt for all chains, except 0, so that they don't disappear
* while we are iterating.
*/
@ -378,8 +379,6 @@ void tcf_block_put(struct tcf_block *block)
{
struct tcf_block_ext_info ei = {0, };
if (!block)
return;
tcf_block_put_ext(block, block->q, &ei);
}

View File

@ -45,7 +45,6 @@
#include <net/netlink.h>
#include <net/act_api.h>
#include <net/pkt_cls.h>
#include <linux/netdevice.h>
#include <linux/idr.h>
struct tc_u_knode {

View File

@ -795,6 +795,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
tcm->tcm_info = refcount_read(&q->refcnt);
if (nla_put_string(skb, TCA_KIND, q->ops->id))
goto nla_put_failure;
if (nla_put_u8(skb, TCA_HW_OFFLOAD, !!(q->flags & TCQ_F_OFFLOADED)))
goto nla_put_failure;
if (q->ops->dump && q->ops->dump(q, skb) < 0)
goto nla_put_failure;
qlen = q->q.qlen;

View File

@ -68,6 +68,8 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt)
struct net_device *dev = qdisc_dev(sch);
int err;
net_inc_ingress_queue();
mini_qdisc_pair_init(&q->miniqp, sch, &dev->miniq_ingress);
q->block_info.binder_type = TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS;
@ -78,7 +80,6 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt)
if (err)
return err;
net_inc_ingress_queue();
sch->flags |= TCQ_F_CPUSTATS;
return 0;
@ -172,6 +173,9 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt)
struct net_device *dev = qdisc_dev(sch);
int err;
net_inc_ingress_queue();
net_inc_egress_queue();
mini_qdisc_pair_init(&q->miniqp_ingress, sch, &dev->miniq_ingress);
q->ingress_block_info.binder_type = TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS;
@ -190,18 +194,11 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt)
err = tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info);
if (err)
goto err_egress_block_get;
net_inc_ingress_queue();
net_inc_egress_queue();
return err;
sch->flags |= TCQ_F_CPUSTATS;
return 0;
err_egress_block_get:
tcf_block_put_ext(q->ingress_block, sch, &q->ingress_block_info);
return err;
}
static void clsact_destroy(struct Qdisc *sch)

View File

@ -157,6 +157,7 @@ static int red_offload(struct Qdisc *sch, bool enable)
.handle = sch->handle,
.parent = sch->parent,
};
int err;
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
return -EOPNOTSUPP;
@ -171,7 +172,14 @@ static int red_offload(struct Qdisc *sch, bool enable)
opt.command = TC_RED_DESTROY;
}
return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt);
if (!err && enable)
sch->flags |= TCQ_F_OFFLOADED;
else
sch->flags &= ~TCQ_F_OFFLOADED;
return err;
}
static void red_destroy(struct Qdisc *sch)
@ -274,7 +282,7 @@ static int red_init(struct Qdisc *sch, struct nlattr *opt)
return red_change(sch, opt);
}
static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt)
static int red_dump_offload_stats(struct Qdisc *sch, struct tc_red_qopt *opt)
{
struct net_device *dev = qdisc_dev(sch);
struct tc_red_qopt_offload hw_stats = {
@ -286,21 +294,12 @@ static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt)
.stats.qstats = &sch->qstats,
},
};
int err;
opt->flags &= ~TC_RED_OFFLOADED;
if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc)
if (!(sch->flags & TCQ_F_OFFLOADED))
return 0;
err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
&hw_stats);
if (err == -EOPNOTSUPP)
return 0;
if (!err)
opt->flags |= TC_RED_OFFLOADED;
return err;
return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
&hw_stats);
}
static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
@ -319,7 +318,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
int err;
sch->qstats.backlog = q->qdisc->qstats.backlog;
err = red_dump_offload(sch, &opt);
err = red_dump_offload_stats(sch, &opt);
if (err)
goto nla_put_failure;
@ -347,7 +346,7 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
.marked = q->stats.prob_mark + q->stats.forced_mark,
};
if (tc_can_offload(dev) && dev->netdev_ops->ndo_setup_tc) {
if (sch->flags & TCQ_F_OFFLOADED) {
struct red_stats hw_stats = {0};
struct tc_red_qopt_offload hw_stats_request = {
.command = TC_RED_XSTATS,

View File

@ -3891,13 +3891,17 @@ static int sctp_setsockopt_reset_streams(struct sock *sk,
struct sctp_association *asoc;
int retval = -EINVAL;
if (optlen < sizeof(struct sctp_reset_streams))
if (optlen < sizeof(*params))
return -EINVAL;
params = memdup_user(optval, optlen);
if (IS_ERR(params))
return PTR_ERR(params);
if (params->srs_number_streams * sizeof(__u16) >
optlen - sizeof(*params))
goto out;
asoc = sctp_id2assoc(sk, params->srs_assoc_id);
if (!asoc)
goto out;

View File

@ -1140,7 +1140,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq,
__skb_dequeue(arrvq);
__skb_queue_tail(inputq, skb);
}
refcount_dec(&skb->users);
kfree_skb(skb);
spin_unlock_bh(&inputq->lock);
continue;
}

View File

@ -25,17 +25,45 @@ endif
$(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.x509)
@$(kecho) " GEN $@"
@echo '#include "reg.h"' > $@
@echo 'const u8 shipped_regdb_certs[] = {' >> $@
@for f in $^ ; do hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ ; done
@echo '};' >> $@
@echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);' >> $@
@(set -e; \
allf=""; \
for f in $^ ; do \
# similar to hexdump -v -e '1/1 "0x%.2x," "\n"' \
thisf=$$(od -An -v -tx1 < $$f | \
sed -e 's/ /\n/g' | \
sed -e 's/^[0-9a-f]\+$$/\0/;t;d' | \
sed -e 's/^/0x/;s/$$/,/'); \
# file should not be empty - maybe command substitution failed? \
test ! -z "$$thisf";\
allf=$$allf$$thisf;\
done; \
( \
echo '#include "reg.h"'; \
echo 'const u8 shipped_regdb_certs[] = {'; \
echo "$$allf"; \
echo '};'; \
echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);'; \
) >> $@)
$(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \
$(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%)/*.x509)
@$(kecho) " GEN $@"
@echo '#include "reg.h"' > $@
@echo 'const u8 extra_regdb_certs[] = {' >> $@
@for f in $^ ; do test -f $$f && hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ || true ; done
@echo '};' >> $@
@echo 'unsigned int extra_regdb_certs_len = sizeof(extra_regdb_certs);' >> $@
@(set -e; \
allf=""; \
for f in $^ ; do \
# similar to hexdump -v -e '1/1 "0x%.2x," "\n"' \
thisf=$$(od -An -v -tx1 < $$f | \
sed -e 's/ /\n/g' | \
sed -e 's/^[0-9a-f]\+$$/\0/;t;d' | \
sed -e 's/^/0x/;s/$$/,/'); \
# file should not be empty - maybe command substitution failed? \
test ! -z "$$thisf";\
allf=$$allf$$thisf;\
done; \
( \
echo '#include "reg.h"'; \
echo 'const u8 extra_regdb_certs[] = {'; \
echo "$$allf"; \
echo '};'; \
echo 'unsigned int extra_regdb_certs_len = sizeof(extra_regdb_certs);'; \
) >> $@)

View File

@ -0,0 +1,7 @@
#if defined(__aarch64__)
#include "../../arch/arm64/include/uapi/asm/bpf_perf_event.h"
#elif defined(__s390__)
#include "../../arch/s390/include/uapi/asm/bpf_perf_event.h"
#else
#include <uapi/asm-generic/bpf_perf_event.h>
#endif

View File

@ -1,19 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(CURDIR)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
endif
include $(srctree)/tools/scripts/Makefile.arch
$(call detected_var,SRCARCH)
LIBDIR := ../../../lib
BPFDIR := $(LIBDIR)/bpf
APIDIR := ../../../include/uapi
ASMDIR:= ../../../arch/$(ARCH)/include/uapi
GENDIR := ../../../../include/generated
GENHDR := $(GENDIR)/autoconf.h
@ -21,7 +10,7 @@ ifneq ($(wildcard $(GENHDR)),)
GENFLAGS := -DHAVE_GENHDR
endif
CFLAGS += -Wall -O2 -I$(APIDIR) -I$(ASMDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include
CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include
LDLIBS += -lcap -lelf
TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \