Including fixes from bluetooth and IPsec.

The bridge patch is actually a follow-up to a recent fix in the same
 area. We have a pending v6.8 AF_UNIX regression; it should be solved
 soon, but not in time for this PR.
 
 Current release - regressions:
 
  - eth: ks8851: Queue RX packets in IRQ handler instead of disabling BHs
 
  - net: bridge: fix corrupted ethernet header on multicast-to-unicast
 
 Current release - new code bugs:
 
  - xfrm: fix possible bad pointer derferencing in error path
 
 Previous releases - regressionis:
 
  - core: fix out-of-bounds access in ops_init
 
  - ipv6:
    - fix potential uninit-value access in __ip6_make_skb()
    - fib6_rules: avoid possible NULL dereference in fib6_rule_action()
 
  - tcp: use refcount_inc_not_zero() in tcp_twsk_unique().
 
  - rtnetlink: correct nested IFLA_VF_VLAN_LIST attribute validation
 
  - rxrpc: fix congestion control algorithm
 
  - bluetooth:
    - l2cap: fix slab-use-after-free in l2cap_connect()
    - msft: fix slab-use-after-free in msft_do_close()
 
  - eth: hns3: fix kernel crash when devlink reload during initialization
 
  - eth: dsa: mv88e6xxx: add phylink_get_caps for the mv88e6320/21 family
 
 Previous releases - always broken:
 
  - xfrm: preserve vlan tags for transport mode software GRO
 
  - tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets
 
  - eth: hns3: keep using user config after hardware reset
 
 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmY8uHASHHBhYmVuaUBy
 ZWRoYXQuY29tAAoJECkkeY3MjxOkedQQAJ4qDwzqUvo+4Ixnn8xQOEeoaqDAfLGR
 TBVFgpG72Hd8sT6C92AO2FPOiBkn5D6VL6QsCsOHmoCBmx9opxdM6K+WIuAldlju
 0IZ/Z2tML5xE7hdrtpI54iqU4OCbf8M9mJrabHaNetWRwLZruLagvyvpdNNtEoup
 nhoVetUYBYmxb3MQ0ez6/zTxvbO1ry7H1xVwbe21hOJszoxuYhLQRx7GBMBm2xn3
 g6m0T7H8EhPKaY/eGoPONcRQ3v29PEuqgVWg0imNy3P4KkTOhshW0jg11mXfaZQA
 32zwLKecdv1gU8Q3Si0ALMtzL3ZC1Iqo4GOEfpr6Bj5Gu+Jd+enPsRDA2hEtMggD
 uh6d9FU4XULZzX5CFEXCoZs0f9N/FNjkDIWUFdHG+0I8pybw+Fbifub76uN1YC5Y
 /02WrtlieOy38UG2FW/zTDRqXMwdwY+VhnVVjK42VnVVFCOM3ucXI/wj5uvytk0B
 iZIWLKtKrVKuUdSdcFvh+Y4z1rK3SFqT5qJEsjzHkLsoap9sbyJrS+MEDeCxv8c4
 RDycwqWdlf1csZFDJ/sIxU9+DvpYY+Zh/ZQgTaU86etWYN7GngSYKFgHSD5F+81X
 kQJgmYInUafzButoL3Kc6JYzfjXYVX9MKAWAjtGdhr7wHOzQHF2U4BUTS4TopjYV
 BQx1t4dZ4n1F
 =qYKQ
 -----END PGP SIGNATURE-----

Merge tag 'net-6.9-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from Paolo Abeni:
 "Including fixes from bluetooth and IPsec.

  The bridge patch is actually a follow-up to a recent fix in the same
  area. We have a pending v6.8 AF_UNIX regression; it should be solved
  soon, but not in time for this PR.

  Current release - regressions:

   - eth: ks8851: Queue RX packets in IRQ handler instead of disabling
     BHs

   - net: bridge: fix corrupted ethernet header on multicast-to-unicast

  Current release - new code bugs:

   - xfrm: fix possible bad pointer derferencing in error path

  Previous releases - regressionis:

   - core: fix out-of-bounds access in ops_init

   - ipv6:
      - fix potential uninit-value access in __ip6_make_skb()
      - fib6_rules: avoid possible NULL dereference in fib6_rule_action()

   - tcp: use refcount_inc_not_zero() in tcp_twsk_unique().

   - rtnetlink: correct nested IFLA_VF_VLAN_LIST attribute validation

   - rxrpc: fix congestion control algorithm

   - bluetooth:
      - l2cap: fix slab-use-after-free in l2cap_connect()
      - msft: fix slab-use-after-free in msft_do_close()

   - eth: hns3: fix kernel crash when devlink reload during
     initialization

   - eth: dsa: mv88e6xxx: add phylink_get_caps for the mv88e6320/21
     family

  Previous releases - always broken:

   - xfrm: preserve vlan tags for transport mode software GRO

   - tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets

   - eth: hns3: keep using user config after hardware reset"

* tag 'net-6.9-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (47 commits)
  net: dsa: mv88e6xxx: read cmode on mv88e6320/21 serdes only ports
  net: dsa: mv88e6xxx: add phylink_get_caps for the mv88e6320/21 family
  net: hns3: fix kernel crash when devlink reload during initialization
  net: hns3: fix port vlan filter not disabled issue
  net: hns3: use appropriate barrier function after setting a bit value
  net: hns3: release PTP resources if pf initialization failed
  net: hns3: change type of numa_node_mask as nodemask_t
  net: hns3: direct return when receive a unknown mailbox message
  net: hns3: using user configure after hardware reset
  net/smc: fix neighbour and rtable leak in smc_ib_find_route()
  ipv6: prevent NULL dereference in ip6_output()
  hsr: Simplify code for announcing HSR nodes timer setup
  ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action()
  dt-bindings: net: mediatek: remove wrongly added clocks and SerDes
  rxrpc: Only transmit one ACK per jumbo packet received
  rxrpc: Fix congestion control algorithm
  selftests: test_bridge_neigh_suppress.sh: Fix failures due to duplicate MAC
  ipv6: Fix potential uninit-value access in __ip6_make_skb()
  net: phy: marvell-88q2xxx: add support for Rev B1 and B2
  appletalk: Improve handling of broadcast packets
  ...
This commit is contained in:
Linus Torvalds 2024-05-09 08:48:57 -07:00
commit 8c3b7565f8
47 changed files with 520 additions and 206 deletions

View file

@ -337,8 +337,8 @@ allOf:
minItems: 4
clocks:
minItems: 34
maxItems: 34
minItems: 24
maxItems: 24
clock-names:
items:
@ -351,18 +351,6 @@ allOf:
- const: ethwarp_wocpu1
- const: ethwarp_wocpu0
- const: esw
- const: netsys0
- const: netsys1
- const: sgmii_tx250m
- const: sgmii_rx250m
- const: sgmii2_tx250m
- const: sgmii2_rx250m
- const: top_usxgmii0_sel
- const: top_usxgmii1_sel
- const: top_sgm0_sel
- const: top_sgm1_sel
- const: top_xfi_phy0_xtal_sel
- const: top_xfi_phy1_xtal_sel
- const: top_eth_gmii_sel
- const: top_eth_refck_50m_sel
- const: top_eth_sys_200m_sel
@ -375,16 +363,10 @@ allOf:
- const: top_netsys_sync_250m_sel
- const: top_netsys_ppefb_250m_sel
- const: top_netsys_warp_sel
- const: wocpu1
- const: wocpu0
- const: xgp1
- const: xgp2
- const: xgp3
mediatek,sgmiisys:
minItems: 2
maxItems: 2
patternProperties:
"^mac@[0-1]$":
type: object

View file

@ -1144,6 +1144,12 @@ attribute-sets:
-
name: mcast-querier-state
type: binary
-
name: fdb-n-learned
type: u32
-
name: fdb-max-learned
type: u32
-
name: linkinfo-brport-attrs
name-prefix: ifla-brport-

View file

@ -5709,7 +5709,7 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
F: drivers/media/dvb-frontends/cxd2820r*
CXGB3 ETHERNET DRIVER (CXGB3)
M: Raju Rangoju <rajur@chelsio.com>
M: Potnuri Bharat Teja <bharat@chelsio.com>
L: netdev@vger.kernel.org
S: Supported
W: http://www.chelsio.com
@ -5730,7 +5730,7 @@ W: http://www.chelsio.com
F: drivers/crypto/chelsio
CXGB4 ETHERNET DRIVER (CXGB4)
M: Raju Rangoju <rajur@chelsio.com>
M: Potnuri Bharat Teja <bharat@chelsio.com>
L: netdev@vger.kernel.org
S: Supported
W: http://www.chelsio.com
@ -5759,7 +5759,7 @@ F: drivers/infiniband/hw/cxgb4/
F: include/uapi/rdma/cxgb4-abi.h
CXGB4VF ETHERNET DRIVER (CXGB4VF)
M: Raju Rangoju <rajur@chelsio.com>
M: Potnuri Bharat Teja <bharat@chelsio.com>
L: netdev@vger.kernel.org
S: Supported
W: http://www.chelsio.com

View file

@ -82,7 +82,8 @@ pins-clk {
};
&mmc1 {
bt_reset: bt-reset {
bluetooth@2 {
reg = <2>;
compatible = "mediatek,mt7921s-bluetooth";
pinctrl-names = "default";
pinctrl-0 = <&bt_pins_reset>;

View file

@ -15,8 +15,6 @@
#define VERSION "0.1"
#define QCA_BDADDR_DEFAULT (&(bdaddr_t) {{ 0xad, 0x5a, 0x00, 0x00, 0x00, 0x00 }})
int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
enum qca_btsoc_type soc_type)
{
@ -101,7 +99,8 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
{
struct sk_buff *skb;
struct edl_event_hdr *edl;
char cmd, build_label[QCA_FW_BUILD_VER_LEN];
char *build_label;
char cmd;
int build_lbl_len, err = 0;
bt_dev_dbg(hdev, "QCA read fw build info");
@ -116,6 +115,11 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
return err;
}
if (skb->len < sizeof(*edl)) {
err = -EILSEQ;
goto out;
}
edl = (struct edl_event_hdr *)(skb->data);
if (!edl) {
bt_dev_err(hdev, "QCA read fw build info with no header");
@ -131,14 +135,25 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
goto out;
}
build_lbl_len = edl->data[0];
if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 1) {
memcpy(build_label, edl->data + 1, build_lbl_len);
*(build_label + build_lbl_len) = '\0';
if (skb->len < sizeof(*edl) + 1) {
err = -EILSEQ;
goto out;
}
build_lbl_len = edl->data[0];
if (skb->len < sizeof(*edl) + 1 + build_lbl_len) {
err = -EILSEQ;
goto out;
}
build_label = kstrndup(&edl->data[1], build_lbl_len, GFP_KERNEL);
if (!build_label)
goto out;
hci_set_fw_info(hdev, "%s", build_label);
kfree(build_label);
out:
kfree_skb(skb);
return err;
@ -237,6 +252,11 @@ static int qca_read_fw_board_id(struct hci_dev *hdev, u16 *bid)
goto out;
}
if (skb->len < 3) {
err = -EILSEQ;
goto out;
}
*bid = (edl->data[1] << 8) + edl->data[2];
bt_dev_dbg(hdev, "%s: bid = %x", __func__, *bid);
@ -267,9 +287,10 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
}
EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
static void qca_tlv_check_data(struct hci_dev *hdev,
static int qca_tlv_check_data(struct hci_dev *hdev,
struct qca_fw_config *config,
u8 *fw_data, enum qca_btsoc_type soc_type)
u8 *fw_data, size_t fw_size,
enum qca_btsoc_type soc_type)
{
const u8 *data;
u32 type_len;
@ -279,12 +300,16 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
struct tlv_type_patch *tlv_patch;
struct tlv_type_nvm *tlv_nvm;
uint8_t nvm_baud_rate = config->user_baud_rate;
u8 type;
config->dnld_mode = QCA_SKIP_EVT_NONE;
config->dnld_type = QCA_SKIP_EVT_NONE;
switch (config->type) {
case ELF_TYPE_PATCH:
if (fw_size < 7)
return -EINVAL;
config->dnld_mode = QCA_SKIP_EVT_VSE_CC;
config->dnld_type = QCA_SKIP_EVT_VSE_CC;
@ -293,6 +318,9 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
bt_dev_dbg(hdev, "File version : 0x%x", fw_data[6]);
break;
case TLV_TYPE_PATCH:
if (fw_size < sizeof(struct tlv_type_hdr) + sizeof(struct tlv_type_patch))
return -EINVAL;
tlv = (struct tlv_type_hdr *)fw_data;
type_len = le32_to_cpu(tlv->type_len);
tlv_patch = (struct tlv_type_patch *)tlv->data;
@ -332,25 +360,64 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
break;
case TLV_TYPE_NVM:
if (fw_size < sizeof(struct tlv_type_hdr))
return -EINVAL;
tlv = (struct tlv_type_hdr *)fw_data;
type_len = le32_to_cpu(tlv->type_len);
length = (type_len >> 8) & 0x00ffffff;
length = type_len >> 8;
type = type_len & 0xff;
BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
/* Some NVM files have more than one set of tags, only parse
* the first set when it has type 2 for now. When there is
* more than one set there is an enclosing header of type 4.
*/
if (type == 4) {
if (fw_size < 2 * sizeof(struct tlv_type_hdr))
return -EINVAL;
tlv++;
type_len = le32_to_cpu(tlv->type_len);
length = type_len >> 8;
type = type_len & 0xff;
}
BT_DBG("TLV Type\t\t : 0x%x", type);
BT_DBG("Length\t\t : %d bytes", length);
if (type != 2)
break;
if (fw_size < length + (tlv->data - fw_data))
return -EINVAL;
idx = 0;
data = tlv->data;
while (idx < length) {
while (idx < length - sizeof(struct tlv_type_nvm)) {
tlv_nvm = (struct tlv_type_nvm *)(data + idx);
tag_id = le16_to_cpu(tlv_nvm->tag_id);
tag_len = le16_to_cpu(tlv_nvm->tag_len);
if (length < idx + sizeof(struct tlv_type_nvm) + tag_len)
return -EINVAL;
/* Update NVM tags as needed */
switch (tag_id) {
case EDL_TAG_ID_BD_ADDR:
if (tag_len != sizeof(bdaddr_t))
return -EINVAL;
memcpy(&config->bdaddr, tlv_nvm->data, sizeof(bdaddr_t));
break;
case EDL_TAG_ID_HCI:
if (tag_len < 3)
return -EINVAL;
/* HCI transport layer parameters
* enabling software inband sleep
* onto controller side.
@ -366,6 +433,9 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
break;
case EDL_TAG_ID_DEEP_SLEEP:
if (tag_len < 1)
return -EINVAL;
/* Sleep enable mask
* enabling deep sleep feature on controller.
*/
@ -374,14 +444,16 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
break;
}
idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len);
idx += sizeof(struct tlv_type_nvm) + tag_len;
}
break;
default:
BT_ERR("Unknown TLV type %d", config->type);
break;
return -EINVAL;
}
return 0;
}
static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
@ -531,7 +603,9 @@ static int qca_download_firmware(struct hci_dev *hdev,
memcpy(data, fw->data, size);
release_firmware(fw);
qca_tlv_check_data(hdev, config, data, soc_type);
ret = qca_tlv_check_data(hdev, config, data, size, soc_type);
if (ret)
goto out;
segment = data;
remain = size;
@ -614,7 +688,7 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
}
EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
static int qca_check_bdaddr(struct hci_dev *hdev)
static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *config)
{
struct hci_rp_read_bd_addr *bda;
struct sk_buff *skb;
@ -638,7 +712,7 @@ static int qca_check_bdaddr(struct hci_dev *hdev)
}
bda = (struct hci_rp_read_bd_addr *)skb->data;
if (!bacmp(&bda->bdaddr, QCA_BDADDR_DEFAULT))
if (!bacmp(&bda->bdaddr, &config->bdaddr))
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
kfree_skb(skb);
@ -667,7 +741,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
const char *firmware_name)
{
struct qca_fw_config config;
struct qca_fw_config config = {};
int err;
u8 rom_ver = 0;
u32 soc_ver;
@ -852,7 +926,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
break;
}
err = qca_check_bdaddr(hdev);
err = qca_check_bdaddr(hdev, &config);
if (err)
return err;

View file

@ -29,6 +29,7 @@
#define EDL_PATCH_CONFIG_RES_EVT (0x00)
#define QCA_DISABLE_LOGGING_SUB_OP (0x14)
#define EDL_TAG_ID_BD_ADDR 2
#define EDL_TAG_ID_HCI (17)
#define EDL_TAG_ID_DEEP_SLEEP (27)
@ -47,7 +48,6 @@
#define get_soc_ver(soc_id, rom_ver) \
((le32_to_cpu(soc_id) << 16) | (le16_to_cpu(rom_ver)))
#define QCA_FW_BUILD_VER_LEN 255
#define QCA_HSP_GF_SOC_ID 0x1200
#define QCA_HSP_GF_SOC_MASK 0x0000ff00
@ -94,6 +94,7 @@ struct qca_fw_config {
uint8_t user_baud_rate;
enum qca_tlv_dnld_mode dnld_mode;
enum qca_tlv_dnld_mode dnld_type;
bdaddr_t bdaddr;
};
struct edl_event_hdr {

View file

@ -637,12 +637,12 @@ static void mv88e6351_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
MAC_1000FD;
}
static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
static int mv88e63xx_get_port_serdes_cmode(struct mv88e6xxx_chip *chip, int port)
{
u16 reg, val;
int err;
err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, &reg);
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
if (err)
return err;
@ -651,16 +651,16 @@ static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip)
return 0xf;
val = reg & ~MV88E6XXX_PORT_STS_PHY_DETECT;
err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, val);
err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, val);
if (err)
return err;
err = mv88e6xxx_port_read(chip, 4, MV88E6XXX_PORT_STS, &val);
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &val);
if (err)
return err;
/* Restore PHY_DETECT value */
err = mv88e6xxx_port_write(chip, 4, MV88E6XXX_PORT_STS, reg);
err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_STS, reg);
if (err)
return err;
@ -688,7 +688,30 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
if (err <= 0)
return;
cmode = mv88e6352_get_port4_serdes_cmode(chip);
cmode = mv88e63xx_get_port_serdes_cmode(chip, port);
if (cmode < 0)
dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
port);
else
mv88e6xxx_translate_cmode(cmode, supported);
}
}
static void mv88e632x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
struct phylink_config *config)
{
unsigned long *supported = config->supported_interfaces;
int cmode;
/* Translate the default cmode */
mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
MAC_1000FD;
/* Port 0/1 are serdes only ports */
if (port == 0 || port == 1) {
cmode = mv88e63xx_get_port_serdes_cmode(chip, port);
if (cmode < 0)
dev_err(chip->dev, "p%d: failed to read serdes cmode\n",
port);
@ -5093,7 +5116,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6352_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
.phylink_get_caps = mv88e6185_phylink_get_caps,
.phylink_get_caps = mv88e632x_phylink_get_caps,
};
static const struct mv88e6xxx_ops mv88e6321_ops = {
@ -5139,7 +5162,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.gpio_ops = &mv88e6352_gpio_ops,
.avb_ops = &mv88e6352_avb_ops,
.ptp_ops = &mv88e6352_ptp_ops,
.phylink_get_caps = mv88e6185_phylink_get_caps,
.phylink_get_caps = mv88e632x_phylink_get_caps,
};
static const struct mv88e6xxx_ops mv88e6341_ops = {

View file

@ -897,7 +897,7 @@ struct hnae3_handle {
struct hnae3_roce_private_info rinfo;
};
u32 numa_node_mask; /* for multi-chip support */
nodemask_t numa_node_mask; /* for multi-chip support */
enum hnae3_port_base_vlan_state port_base_vlan_state;

View file

@ -1537,6 +1537,9 @@ static int hclge_configure(struct hclge_dev *hdev)
cfg.default_speed, ret);
return ret;
}
hdev->hw.mac.req_speed = hdev->hw.mac.speed;
hdev->hw.mac.req_autoneg = AUTONEG_ENABLE;
hdev->hw.mac.req_duplex = DUPLEX_FULL;
hclge_parse_link_mode(hdev, cfg.speed_ability);
@ -1766,7 +1769,8 @@ static int hclge_vport_setup(struct hclge_vport *vport, u16 num_tqps)
nic->pdev = hdev->pdev;
nic->ae_algo = &ae_algo;
nic->numa_node_mask = hdev->numa_node_mask;
bitmap_copy(nic->numa_node_mask.bits, hdev->numa_node_mask.bits,
MAX_NUMNODES);
nic->kinfo.io_base = hdev->hw.hw.io_base;
ret = hclge_knic_setup(vport, num_tqps,
@ -2458,7 +2462,8 @@ static int hclge_init_roce_base_info(struct hclge_vport *vport)
roce->pdev = nic->pdev;
roce->ae_algo = nic->ae_algo;
roce->numa_node_mask = nic->numa_node_mask;
bitmap_copy(roce->numa_node_mask.bits, nic->numa_node_mask.bits,
MAX_NUMNODES);
return 0;
}
@ -3342,9 +3347,9 @@ hclge_set_phy_link_ksettings(struct hnae3_handle *handle,
return ret;
}
hdev->hw.mac.autoneg = cmd->base.autoneg;
hdev->hw.mac.speed = cmd->base.speed;
hdev->hw.mac.duplex = cmd->base.duplex;
hdev->hw.mac.req_autoneg = cmd->base.autoneg;
hdev->hw.mac.req_speed = cmd->base.speed;
hdev->hw.mac.req_duplex = cmd->base.duplex;
linkmode_copy(hdev->hw.mac.advertising, cmd->link_modes.advertising);
return 0;
@ -3377,9 +3382,9 @@ static int hclge_tp_port_init(struct hclge_dev *hdev)
if (!hnae3_dev_phy_imp_supported(hdev))
return 0;
cmd.base.autoneg = hdev->hw.mac.autoneg;
cmd.base.speed = hdev->hw.mac.speed;
cmd.base.duplex = hdev->hw.mac.duplex;
cmd.base.autoneg = hdev->hw.mac.req_autoneg;
cmd.base.speed = hdev->hw.mac.req_speed;
cmd.base.duplex = hdev->hw.mac.req_duplex;
linkmode_copy(cmd.link_modes.advertising, hdev->hw.mac.advertising);
return hclge_set_phy_link_ksettings(&hdev->vport->nic, &cmd);
@ -7952,8 +7957,7 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
/* Set the DOWN flag here to disable link updating */
set_bit(HCLGE_STATE_DOWN, &hdev->state);
/* flush memory to make sure DOWN is seen by service task */
smp_mb__before_atomic();
smp_mb__after_atomic(); /* flush memory to make sure DOWN is seen by service task */
hclge_flush_link_update(hdev);
}
}
@ -9906,6 +9910,7 @@ static int hclge_set_vlan_protocol_type(struct hclge_dev *hdev)
static int hclge_init_vlan_filter(struct hclge_dev *hdev)
{
struct hclge_vport *vport;
bool enable = true;
int ret;
int i;
@ -9925,8 +9930,12 @@ static int hclge_init_vlan_filter(struct hclge_dev *hdev)
vport->cur_vlan_fltr_en = true;
}
if (test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, hdev->ae_dev->caps) &&
!test_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, hdev->ae_dev->caps))
enable = false;
return hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
HCLGE_FILTER_FE_INGRESS, true, 0);
HCLGE_FILTER_FE_INGRESS, enable, 0);
}
static int hclge_init_vlan_type(struct hclge_dev *hdev)
@ -11622,16 +11631,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
if (ret)
goto out;
ret = hclge_devlink_init(hdev);
if (ret)
goto err_pci_uninit;
devl_lock(hdev->devlink);
/* Firmware command queue initialize */
ret = hclge_comm_cmd_queue_init(hdev->pdev, &hdev->hw.hw);
if (ret)
goto err_devlink_uninit;
goto err_pci_uninit;
/* Firmware command initialize */
ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version,
@ -11759,7 +11762,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
ret = hclge_update_port_info(hdev);
if (ret)
goto err_mdiobus_unreg;
goto err_ptp_uninit;
INIT_KFIFO(hdev->mac_tnl_log);
@ -11799,6 +11802,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
dev_warn(&pdev->dev,
"failed to wake on lan init, ret = %d\n", ret);
ret = hclge_devlink_init(hdev);
if (ret)
goto err_ptp_uninit;
hclge_state_init(hdev);
hdev->last_reset_time = jiffies;
@ -11806,10 +11813,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
HCLGE_DRIVER_NAME);
hclge_task_schedule(hdev, round_jiffies_relative(HZ));
devl_unlock(hdev->devlink);
return 0;
err_ptp_uninit:
hclge_ptp_uninit(hdev);
err_mdiobus_unreg:
if (hdev->hw.mac.phydev)
mdiobus_unregister(hdev->hw.mac.mdio_bus);
@ -11819,9 +11826,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
pci_free_irq_vectors(pdev);
err_cmd_uninit:
hclge_comm_cmd_uninit(hdev->ae_dev, &hdev->hw.hw);
err_devlink_uninit:
devl_unlock(hdev->devlink);
hclge_devlink_uninit(hdev);
err_pci_uninit:
pcim_iounmap(pdev, hdev->hw.hw.io_base);
pci_release_regions(pdev);

View file

@ -279,11 +279,14 @@ struct hclge_mac {
u8 media_type; /* port media type, e.g. fibre/copper/backplane */
u8 mac_addr[ETH_ALEN];
u8 autoneg;
u8 req_autoneg;
u8 duplex;
u8 req_duplex;
u8 support_autoneg;
u8 speed_type; /* 0: sfp speed, 1: active speed */
u8 lane_num;
u32 speed;
u32 req_speed;
u32 max_speed;
u32 speed_ability; /* speed ability supported by current media */
u32 module_type; /* sub media type, e.g. kr/cr/sr/lr */
@ -891,7 +894,7 @@ struct hclge_dev {
u16 fdir_pf_filter_count; /* Num of guaranteed filters for this PF */
u16 num_alloc_vport; /* Num vports this driver supports */
u32 numa_node_mask;
nodemask_t numa_node_mask;
u16 rx_buf_len;
u16 num_tx_desc; /* desc num of per tx queue */
u16 num_rx_desc; /* desc num of per rx queue */

View file

@ -1077,12 +1077,13 @@ static void hclge_mbx_request_handling(struct hclge_mbx_ops_param *param)
hdev = param->vport->back;
cmd_func = hclge_mbx_ops_list[param->req->msg.code];
if (cmd_func)
ret = cmd_func(param);
else
if (!cmd_func) {
dev_err(&hdev->pdev->dev,
"un-supported mailbox message, code = %u\n",
param->req->msg.code);
return;
}
ret = cmd_func(param);
/* PF driver should not reply IMP */
if (hnae3_get_bit(param->req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) &&

View file

@ -412,7 +412,8 @@ static int hclgevf_set_handle_info(struct hclgevf_dev *hdev)
nic->ae_algo = &ae_algovf;
nic->pdev = hdev->pdev;
nic->numa_node_mask = hdev->numa_node_mask;
bitmap_copy(nic->numa_node_mask.bits, hdev->numa_node_mask.bits,
MAX_NUMNODES);
nic->flags |= HNAE3_SUPPORT_VF;
nic->kinfo.io_base = hdev->hw.hw.io_base;
@ -2082,8 +2083,8 @@ static int hclgevf_init_roce_base_info(struct hclgevf_dev *hdev)
roce->pdev = nic->pdev;
roce->ae_algo = nic->ae_algo;
roce->numa_node_mask = nic->numa_node_mask;
bitmap_copy(roce->numa_node_mask.bits, nic->numa_node_mask.bits,
MAX_NUMNODES);
return 0;
}
@ -2180,8 +2181,7 @@ static void hclgevf_set_timer_task(struct hnae3_handle *handle, bool enable)
} else {
set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
/* flush memory to make sure DOWN is seen by service task */
smp_mb__before_atomic();
smp_mb__after_atomic(); /* flush memory to make sure DOWN is seen by service task */
hclgevf_flush_link_update(hdev);
}
}
@ -2845,10 +2845,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
if (ret)
return ret;
ret = hclgevf_devlink_init(hdev);
if (ret)
goto err_devlink_init;
ret = hclge_comm_cmd_queue_init(hdev->pdev, &hdev->hw.hw);
if (ret)
goto err_cmd_queue_init;
@ -2941,6 +2937,10 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
hclgevf_init_rxd_adv_layout(hdev);
ret = hclgevf_devlink_init(hdev);
if (ret)
goto err_config;
set_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state);
hdev->last_reset_time = jiffies;
@ -2960,8 +2960,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
err_cmd_init:
hclge_comm_cmd_uninit(hdev->ae_dev, &hdev->hw.hw);
err_cmd_queue_init:
hclgevf_devlink_uninit(hdev);
err_devlink_init:
hclgevf_pci_uninit(hdev);
clear_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
return ret;

View file

@ -236,7 +236,7 @@ struct hclgevf_dev {
u16 rss_size_max; /* HW defined max RSS task queue */
u16 num_alloc_vport; /* num vports this driver supports */
u32 numa_node_mask;
nodemask_t numa_node_mask;
u16 rx_buf_len;
u16 num_tx_desc; /* desc num of per tx queue */
u16 num_rx_desc; /* desc num of per rx queue */

View file

@ -234,12 +234,13 @@ static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt)
/**
* ks8851_rx_pkts - receive packets from the host
* @ks: The device information.
* @rxq: Queue of packets received in this function.
*
* This is called from the IRQ work queue when the system detects that there
* are packets in the receive queue. Find out how many packets there are and
* read them from the FIFO.
*/
static void ks8851_rx_pkts(struct ks8851_net *ks)
static void ks8851_rx_pkts(struct ks8851_net *ks, struct sk_buff_head *rxq)
{
struct sk_buff *skb;
unsigned rxfc;
@ -299,7 +300,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
ks8851_dbg_dumpkkt(ks, rxpkt);
skb->protocol = eth_type_trans(skb, ks->netdev);
__netif_rx(skb);
__skb_queue_tail(rxq, skb);
ks->netdev->stats.rx_packets++;
ks->netdev->stats.rx_bytes += rxlen;
@ -326,11 +327,11 @@ static void ks8851_rx_pkts(struct ks8851_net *ks)
static irqreturn_t ks8851_irq(int irq, void *_ks)
{
struct ks8851_net *ks = _ks;
struct sk_buff_head rxq;
unsigned handled = 0;
unsigned long flags;
unsigned int status;
local_bh_disable();
struct sk_buff *skb;
ks8851_lock(ks, &flags);
@ -384,7 +385,8 @@ static irqreturn_t ks8851_irq(int irq, void *_ks)
* from the device so do not bother masking just the RX
* from the device. */
ks8851_rx_pkts(ks);
__skb_queue_head_init(&rxq);
ks8851_rx_pkts(ks, &rxq);
}
/* if something stopped the rx process, probably due to wanting
@ -408,7 +410,9 @@ static irqreturn_t ks8851_irq(int irq, void *_ks)
if (status & IRQ_LCI)
mii_check_link(&ks->mii);
local_bh_enable();
if (status & IRQ_RXI)
while ((skb = __skb_dequeue(&rxq)))
netif_rx(skb);
return IRQ_HANDLED;
}

View file

@ -12,6 +12,8 @@
#include <linux/hwmon.h>
#define PHY_ID_88Q2220_REVB0 (MARVELL_PHY_ID_88Q2220 | 0x1)
#define PHY_ID_88Q2220_REVB1 (MARVELL_PHY_ID_88Q2220 | 0x2)
#define PHY_ID_88Q2220_REVB2 (MARVELL_PHY_ID_88Q2220 | 0x3)
#define MDIO_MMD_AN_MV_STAT 32769
#define MDIO_MMD_AN_MV_STAT_ANEG 0x0100
@ -129,6 +131,49 @@ static const struct mmd_val mv88q222x_revb0_init_seq1[] = {
{ MDIO_MMD_PCS, 0xfe05, 0x755c },
};
static const struct mmd_val mv88q222x_revb1_init_seq0[] = {
{ MDIO_MMD_PCS, 0xffe4, 0x0007 },
{ MDIO_MMD_AN, MDIO_AN_T1_CTRL, 0x0 },
{ MDIO_MMD_PCS, 0xffe3, 0x7000 },
{ MDIO_MMD_PMAPMD, MDIO_CTRL1, 0x0840 },
};
static const struct mmd_val mv88q222x_revb2_init_seq0[] = {
{ MDIO_MMD_PCS, 0xffe4, 0x0007 },
{ MDIO_MMD_AN, MDIO_AN_T1_CTRL, 0x0 },
{ MDIO_MMD_PMAPMD, MDIO_CTRL1, 0x0840 },
};
static const struct mmd_val mv88q222x_revb1_revb2_init_seq1[] = {
{ MDIO_MMD_PCS, 0xfe07, 0x125a },
{ MDIO_MMD_PCS, 0xfe09, 0x1288 },
{ MDIO_MMD_PCS, 0xfe08, 0x2588 },
{ MDIO_MMD_PCS, 0xfe72, 0x042c },
{ MDIO_MMD_PCS, 0xffe4, 0x0071 },
{ MDIO_MMD_PCS, 0xffe4, 0x0001 },
{ MDIO_MMD_PCS, 0xfe1b, 0x0048 },
{ MDIO_MMD_PMAPMD, 0x0000, 0x0000 },
{ MDIO_MMD_PCS, 0x0000, 0x0000 },
{ MDIO_MMD_PCS, 0xffdb, 0xfc10 },
{ MDIO_MMD_PCS, 0xfe1b, 0x58 },
{ MDIO_MMD_PCS, 0xfcad, 0x030c },
{ MDIO_MMD_PCS, 0x8032, 0x6001 },
{ MDIO_MMD_PCS, 0xfdff, 0x05a5 },
{ MDIO_MMD_PCS, 0xfdec, 0xdbaf },
{ MDIO_MMD_PCS, 0xfcab, 0x1054 },
{ MDIO_MMD_PCS, 0xfcac, 0x1483 },
{ MDIO_MMD_PCS, 0x8033, 0xc801 },
{ MDIO_MMD_AN, 0x8032, 0x2020 },
{ MDIO_MMD_AN, 0x8031, 0xa28 },
{ MDIO_MMD_AN, 0x8031, 0xc28 },
{ MDIO_MMD_PCS, 0xfbba, 0x0cb2 },
{ MDIO_MMD_PCS, 0xfbbb, 0x0c4a },
{ MDIO_MMD_PCS, 0xfe5f, 0xe8 },
{ MDIO_MMD_PCS, 0xfe05, 0x755c },
{ MDIO_MMD_PCS, 0xfa20, 0x002a },
{ MDIO_MMD_PCS, 0xfe11, 0x1105 },
};
static int mv88q2xxx_soft_reset(struct phy_device *phydev)
{
int ret;
@ -687,31 +732,72 @@ static int mv88q222x_soft_reset(struct phy_device *phydev)
return 0;
}
static int mv88q222x_revb0_config_init(struct phy_device *phydev)
static int mv88q222x_write_mmd_vals(struct phy_device *phydev,
const struct mmd_val *vals, size_t len)
{
int ret, i;
int ret;
for (i = 0; i < ARRAY_SIZE(mv88q222x_revb0_init_seq0); i++) {
ret = phy_write_mmd(phydev, mv88q222x_revb0_init_seq0[i].devad,
mv88q222x_revb0_init_seq0[i].regnum,
mv88q222x_revb0_init_seq0[i].val);
for (; len; vals++, len--) {
ret = phy_write_mmd(phydev, vals->devad, vals->regnum,
vals->val);
if (ret < 0)
return ret;
}
return 0;
}
static int mv88q222x_revb0_config_init(struct phy_device *phydev)
{
int ret;
ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb0_init_seq0,
ARRAY_SIZE(mv88q222x_revb0_init_seq0));
if (ret < 0)
return ret;
usleep_range(5000, 10000);
for (i = 0; i < ARRAY_SIZE(mv88q222x_revb0_init_seq1); i++) {
ret = phy_write_mmd(phydev, mv88q222x_revb0_init_seq1[i].devad,
mv88q222x_revb0_init_seq1[i].regnum,
mv88q222x_revb0_init_seq1[i].val);
if (ret < 0)
return ret;
}
ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb0_init_seq1,
ARRAY_SIZE(mv88q222x_revb0_init_seq1));
if (ret < 0)
return ret;
return mv88q2xxx_config_init(phydev);
}
static int mv88q222x_revb1_revb2_config_init(struct phy_device *phydev)
{
bool is_rev_b1 = phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] == PHY_ID_88Q2220_REVB1;
int ret;
if (is_rev_b1)
ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb1_init_seq0,
ARRAY_SIZE(mv88q222x_revb1_init_seq0));
else
ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb2_init_seq0,
ARRAY_SIZE(mv88q222x_revb2_init_seq0));
if (ret < 0)
return ret;
usleep_range(3000, 5000);
ret = mv88q222x_write_mmd_vals(phydev, mv88q222x_revb1_revb2_init_seq1,
ARRAY_SIZE(mv88q222x_revb1_revb2_init_seq1));
if (ret < 0)
return ret;
return mv88q2xxx_config_init(phydev);
}
static int mv88q222x_config_init(struct phy_device *phydev)
{
if (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] == PHY_ID_88Q2220_REVB0)
return mv88q222x_revb0_config_init(phydev);
else
return mv88q222x_revb1_revb2_config_init(phydev);
}
static int mv88q222x_cable_test_start(struct phy_device *phydev)
{
int ret;
@ -810,14 +896,15 @@ static struct phy_driver mv88q2xxx_driver[] = {
.get_sqi_max = mv88q2xxx_get_sqi_max,
},
{
PHY_ID_MATCH_EXACT(PHY_ID_88Q2220_REVB0),
.phy_id = MARVELL_PHY_ID_88Q2220,
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "mv88q2220",
.flags = PHY_POLL_CABLE_TEST,
.probe = mv88q2xxx_probe,
.get_features = mv88q2xxx_get_features,
.config_aneg = mv88q2xxx_config_aneg,
.aneg_done = genphy_c45_aneg_done,
.config_init = mv88q222x_revb0_config_init,
.config_init = mv88q222x_config_init,
.read_status = mv88q2xxx_read_status,
.soft_reset = mv88q222x_soft_reset,
.config_intr = mv88q2xxx_config_intr,
@ -836,7 +923,7 @@ module_phy_driver(mv88q2xxx_driver);
static struct mdio_device_id __maybe_unused mv88q2xxx_tbl[] = {
{ MARVELL_PHY_ID_88Q2110, MARVELL_PHY_ID_MASK },
{ PHY_ID_MATCH_EXACT(PHY_ID_88Q2220_REVB0), },
{ MARVELL_PHY_ID_88Q2220, MARVELL_PHY_ID_MASK },
{ /*sentinel*/ }
};
MODULE_DEVICE_TABLE(mdio, mv88q2xxx_tbl);

View file

@ -3031,6 +3031,21 @@ static inline void skb_mac_header_rebuild(struct sk_buff *skb)
}
}
/* Move the full mac header up to current network_header.
* Leaves skb->data pointing at offset skb->mac_len into the mac_header.
* Must be provided the complete mac header length.
*/
static inline void skb_mac_header_rebuild_full(struct sk_buff *skb, u32 full_mac_len)
{
if (skb_mac_header_was_set(skb)) {
const unsigned char *old_mac = skb_mac_header(skb);
skb_set_mac_header(skb, -full_mac_len);
memmove(skb_mac_header(skb), old_mac, full_mac_len);
__skb_push(skb, full_mac_len - skb->mac_len);
}
}
static inline int skb_checksum_start_offset(const struct sk_buff *skb)
{
return skb->csum_start - skb_headroom(skb);

View file

@ -1049,6 +1049,9 @@ struct xfrm_offload {
#define CRYPTO_INVALID_PACKET_SYNTAX 64
#define CRYPTO_INVALID_PROTOCOL 128
/* Used to keep whole l2 header for transport mode GRO */
__u32 orig_mac_len;
__u8 proto;
__u8 inner_ipproto;
};

View file

@ -228,7 +228,7 @@ enum {
#define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)
/*
* Generic LSM security context for comunicating to user space
* Generic LSM security context for communicating to user space
* NOTE: Same format as sadb_x_sec_ctx
*/
struct xfrm_user_sec_ctx {

View file

@ -88,6 +88,7 @@ static inline void atalk_remove_socket(struct sock *sk)
static struct sock *atalk_search_socket(struct sockaddr_at *to,
struct atalk_iface *atif)
{
struct sock *def_socket = NULL;
struct sock *s;
read_lock_bh(&atalk_sockets_lock);
@ -98,8 +99,20 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to,
continue;
if (to->sat_addr.s_net == ATADDR_ANYNET &&
to->sat_addr.s_node == ATADDR_BCAST)
goto found;
to->sat_addr.s_node == ATADDR_BCAST) {
if (atif->address.s_node == at->src_node &&
atif->address.s_net == at->src_net) {
/* This socket's address matches the address of the interface
* that received the packet -- use it
*/
goto found;
}
/* Continue searching for a socket matching the interface address,
* but use this socket by default if no other one is found
*/
def_socket = s;
}
if (to->sat_addr.s_net == at->src_net &&
(to->sat_addr.s_node == at->src_node ||
@ -116,7 +129,7 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to,
goto found;
}
}
s = NULL;
s = def_socket;
found:
read_unlock_bh(&atalk_sockets_lock);
return s;

View file

@ -2768,8 +2768,6 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_unregister_suspend_notifier(hdev);
msft_unregister(hdev);
hci_dev_do_close(hdev);
if (!test_bit(HCI_INIT, &hdev->flags) &&
@ -2823,6 +2821,7 @@ void hci_release_dev(struct hci_dev *hdev)
hci_discovery_filter_clear(hdev);
hci_blocked_keys_clear(hdev);
hci_codec_list_clear(&hdev->local_codecs);
msft_release(hdev);
hci_dev_unlock(hdev);
ida_destroy(&hdev->unset_handle_ida);

View file

@ -7037,6 +7037,8 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
u16 handle = le16_to_cpu(ev->bis[i]);
bis = hci_conn_hash_lookup_handle(hdev, handle);
if (!bis)
continue;
set_bit(HCI_CONN_BIG_SYNC_FAILED, &bis->flags);
hci_connect_cfm(bis, ev->status);

View file

@ -415,6 +415,9 @@ static void l2cap_chan_timeout(struct work_struct *work)
BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
if (!conn)
return;
mutex_lock(&conn->chan_lock);
/* __set_chan_timer() calls l2cap_chan_hold(chan) while scheduling
* this work. No need to call l2cap_chan_hold(chan) here again.
@ -3902,13 +3905,12 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn,
return 0;
}
static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
struct l2cap_cmd_hdr *cmd,
u8 *data, u8 rsp_code, u8 amp_id)
static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
u8 *data, u8 rsp_code, u8 amp_id)
{
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
struct l2cap_chan *chan = NULL, *pchan;
struct l2cap_chan *chan = NULL, *pchan = NULL;
int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@ -3921,7 +3923,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
&conn->hcon->dst, ACL_LINK);
if (!pchan) {
result = L2CAP_CR_BAD_PSM;
goto sendresp;
goto response;
}
mutex_lock(&conn->chan_lock);
@ -4008,17 +4010,15 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
}
response:
l2cap_chan_unlock(pchan);
mutex_unlock(&conn->chan_lock);
l2cap_chan_put(pchan);
sendresp:
rsp.scid = cpu_to_le16(scid);
rsp.dcid = cpu_to_le16(dcid);
rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(status);
l2cap_send_cmd(conn, cmd->ident, rsp_code, sizeof(rsp), &rsp);
if (!pchan)
return;
if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) {
struct l2cap_info_req info;
info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
@ -4041,7 +4041,9 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
chan->num_conf_req++;
}
return chan;
l2cap_chan_unlock(pchan);
mutex_unlock(&conn->chan_lock);
l2cap_chan_put(pchan);
}
static int l2cap_connect_req(struct l2cap_conn *conn,

View file

@ -769,7 +769,7 @@ void msft_register(struct hci_dev *hdev)
mutex_init(&msft->filter_lock);
}
void msft_unregister(struct hci_dev *hdev)
void msft_release(struct hci_dev *hdev)
{
struct msft_data *msft = hdev->msft_data;

View file

@ -14,7 +14,7 @@
bool msft_monitor_supported(struct hci_dev *hdev);
void msft_register(struct hci_dev *hdev);
void msft_unregister(struct hci_dev *hdev);
void msft_release(struct hci_dev *hdev);
void msft_do_open(struct hci_dev *hdev);
void msft_do_close(struct hci_dev *hdev);
void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb);
@ -35,7 +35,7 @@ static inline bool msft_monitor_supported(struct hci_dev *hdev)
}
static inline void msft_register(struct hci_dev *hdev) {}
static inline void msft_unregister(struct hci_dev *hdev) {}
static inline void msft_release(struct hci_dev *hdev) {}
static inline void msft_do_open(struct hci_dev *hdev) {}
static inline void msft_do_close(struct hci_dev *hdev) {}
static inline void msft_vendor_evt(struct hci_dev *hdev, void *data,

View file

@ -83,6 +83,10 @@ static void sco_sock_timeout(struct work_struct *work)
struct sock *sk;
sco_conn_lock(conn);
if (!conn->hcon) {
sco_conn_unlock(conn);
return;
}
sk = conn->sk;
if (sk)
sock_hold(sk);

View file

@ -258,6 +258,7 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
{
struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
const unsigned char *src = eth_hdr(skb)->h_source;
struct sk_buff *nskb;
if (!should_deliver(p, skb))
return;
@ -266,12 +267,16 @@ static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
if (skb->dev == p->dev && ether_addr_equal(src, addr))
return;
skb = pskb_copy(skb, GFP_ATOMIC);
if (!skb) {
__skb_push(skb, ETH_HLEN);
nskb = pskb_copy(skb, GFP_ATOMIC);
__skb_pull(skb, ETH_HLEN);
if (!nskb) {
DEV_STATS_INC(dev, tx_dropped);
return;
}
skb = nskb;
__skb_pull(skb, ETH_HLEN);
if (!is_broadcast_ether_addr(addr))
memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);

View file

@ -69,12 +69,15 @@ DEFINE_COOKIE(net_cookie);
static struct net_generic *net_alloc_generic(void)
{
unsigned int gen_ptrs = READ_ONCE(max_gen_ptrs);
unsigned int generic_size;
struct net_generic *ng;
unsigned int generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]);
generic_size = offsetof(struct net_generic, ptr[gen_ptrs]);
ng = kzalloc(generic_size, GFP_KERNEL);
if (ng)
ng->s.len = max_gen_ptrs;
ng->s.len = gen_ptrs;
return ng;
}
@ -1307,7 +1310,11 @@ static int register_pernet_operations(struct list_head *list,
if (error < 0)
return error;
*ops->id = error;
max_gen_ptrs = max(max_gen_ptrs, *ops->id + 1);
/* This does not require READ_ONCE as writers already hold
* pernet_ops_rwsem. But WRITE_ONCE is needed to protect
* net_alloc_generic.
*/
WRITE_ONCE(max_gen_ptrs, max(max_gen_ptrs, *ops->id + 1));
}
error = __register_pernet_operations(list, ops);
if (error) {

View file

@ -2530,7 +2530,7 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
nla_for_each_nested(attr, tb[IFLA_VF_VLAN_LIST], rem) {
if (nla_type(attr) != IFLA_VF_VLAN_INFO ||
nla_len(attr) < NLA_HDRLEN) {
nla_len(attr) < sizeof(struct ifla_vf_vlan_info)) {
return -EINVAL;
}
if (len >= MAX_VLAN_LIST_LEN)

View file

@ -61,39 +61,36 @@ static bool hsr_check_carrier(struct hsr_port *master)
return false;
}
static void hsr_check_announce(struct net_device *hsr_dev,
unsigned char old_operstate)
static void hsr_check_announce(struct net_device *hsr_dev)
{
struct hsr_priv *hsr;
hsr = netdev_priv(hsr_dev);
if (READ_ONCE(hsr_dev->operstate) == IF_OPER_UP && old_operstate != IF_OPER_UP) {
/* Went up */
hsr->announce_count = 0;
mod_timer(&hsr->announce_timer,
jiffies + msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL));
if (netif_running(hsr_dev) && netif_oper_up(hsr_dev)) {
/* Enable announce timer and start sending supervisory frames */
if (!timer_pending(&hsr->announce_timer)) {
hsr->announce_count = 0;
mod_timer(&hsr->announce_timer, jiffies +
msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL));
}
} else {
/* Deactivate the announce timer */
timer_delete(&hsr->announce_timer);
}
if (READ_ONCE(hsr_dev->operstate) != IF_OPER_UP && old_operstate == IF_OPER_UP)
/* Went down */
del_timer(&hsr->announce_timer);
}
void hsr_check_carrier_and_operstate(struct hsr_priv *hsr)
{
struct hsr_port *master;
unsigned char old_operstate;
bool has_carrier;
master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
/* netif_stacked_transfer_operstate() cannot be used here since
* it doesn't set IF_OPER_LOWERLAYERDOWN (?)
*/
old_operstate = READ_ONCE(master->dev->operstate);
has_carrier = hsr_check_carrier(master);
hsr_set_operstate(master, has_carrier);
hsr_check_announce(master->dev, old_operstate);
hsr_check_announce(master->dev);
}
int hsr_get_max_mtu(struct hsr_priv *hsr)

View file

@ -2710,7 +2710,7 @@ void tcp_shutdown(struct sock *sk, int how)
/* If we've already sent a FIN, or it's a closed state, skip this. */
if ((1 << sk->sk_state) &
(TCPF_ESTABLISHED | TCPF_SYN_SENT |
TCPF_SYN_RECV | TCPF_CLOSE_WAIT)) {
TCPF_CLOSE_WAIT)) {
/* Clear out any half completed packets. FIN if needed. */
if (tcp_close_state(sk))
tcp_send_fin(sk);
@ -2819,7 +2819,7 @@ void __tcp_close(struct sock *sk, long timeout)
* machine. State transitions:
*
* TCP_ESTABLISHED -> TCP_FIN_WAIT1
* TCP_SYN_RECV -> TCP_FIN_WAIT1 (forget it, it's impossible)
* TCP_SYN_RECV -> TCP_FIN_WAIT1 (it is difficult)
* TCP_CLOSE_WAIT -> TCP_LAST_ACK
*
* are legal only when FIN has been sent (i.e. in window),

View file

@ -6761,6 +6761,8 @@ tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb)
tcp_initialize_rcv_mss(sk);
tcp_fast_path_on(tp);
if (sk->sk_shutdown & SEND_SHUTDOWN)
tcp_shutdown(sk, SEND_SHUTDOWN);
break;
case TCP_FIN_WAIT1: {

View file

@ -154,6 +154,12 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
if (tcptw->tw_ts_recent_stamp &&
(!twp || (reuse && time_after32(ktime_get_seconds(),
tcptw->tw_ts_recent_stamp)))) {
/* inet_twsk_hashdance() sets sk_refcnt after putting twsk
* and releasing the bucket lock.
*/
if (unlikely(!refcount_inc_not_zero(&sktw->sk_refcnt)))
return 0;
/* In case of repair and re-using TIME-WAIT sockets we still
* want to be sure that it is safe as above but honor the
* sequence numbers and time stamps set as part of the repair
@ -174,7 +180,7 @@ int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
tp->rx_opt.ts_recent = tcptw->tw_ts_recent;
tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
}
sock_hold(sktw);
return 1;
}

View file

@ -3563,7 +3563,9 @@ void tcp_send_fin(struct sock *sk)
return;
}
} else {
skb = alloc_skb_fclone(MAX_TCP_HEADER, sk->sk_allocation);
skb = alloc_skb_fclone(MAX_TCP_HEADER,
sk_gfp_mask(sk, GFP_ATOMIC |
__GFP_NOWARN));
if (unlikely(!skb))
return;

View file

@ -63,7 +63,11 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
ip_send_check(iph);
if (xo && (xo->flags & XFRM_GRO)) {
skb_mac_header_rebuild(skb);
/* The full l2 header needs to be preserved so that re-injecting the packet at l2
* works correctly in the presence of vlan tags.
*/
skb_mac_header_rebuild_full(skb, xo->orig_mac_len);
skb_reset_network_header(skb);
skb_reset_transport_header(skb);
return 0;
}

View file

@ -233,8 +233,12 @@ static int __fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
rt = pol_lookup_func(lookup,
net, table, flp6, arg->lookup_data, flags);
if (rt != net->ipv6.ip6_null_entry) {
struct inet6_dev *idev = ip6_dst_idev(&rt->dst);
if (!idev)
goto again;
err = fib6_rule_saddr(net, rule, flags, flp6,
ip6_dst_idev(&rt->dst)->dev);
idev->dev);
if (err == -EAGAIN)
goto again;

View file

@ -234,7 +234,7 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
skb->protocol = htons(ETH_P_IPV6);
skb->dev = dev;
if (unlikely(READ_ONCE(idev->cnf.disable_ipv6))) {
if (unlikely(!idev || READ_ONCE(idev->cnf.disable_ipv6))) {
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
kfree_skb_reason(skb, SKB_DROP_REASON_IPV6DISABLED);
return 0;
@ -1933,7 +1933,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
u8 icmp6_type;
if (sk->sk_socket->type == SOCK_RAW &&
!inet_test_bit(HDRINCL, sk))
!(fl6->flowi6_flags & FLOWI_FLAG_KNOWN_NH))
icmp6_type = fl6->fl6_icmp_type;
else
icmp6_type = icmp6_hdr(skb)->icmp6_type;

View file

@ -58,7 +58,11 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
skb_postpush_rcsum(skb, skb_network_header(skb), nhlen);
if (xo && (xo->flags & XFRM_GRO)) {
skb_mac_header_rebuild(skb);
/* The full l2 header needs to be preserved so that re-injecting the packet at l2
* works correctly in the presence of vlan tags.
*/
skb_mac_header_rebuild_full(skb, xo->orig_mac_len);
skb_reset_network_header(skb);
skb_reset_transport_header(skb);
return 0;
}

View file

@ -96,6 +96,43 @@ static void mptcp_pernet_set_defaults(struct mptcp_pernet *pernet)
}
#ifdef CONFIG_SYSCTL
static int mptcp_set_scheduler(const struct net *net, const char *name)
{
struct mptcp_pernet *pernet = mptcp_get_pernet(net);
struct mptcp_sched_ops *sched;
int ret = 0;
rcu_read_lock();
sched = mptcp_sched_find(name);
if (sched)
strscpy(pernet->scheduler, name, MPTCP_SCHED_NAME_MAX);
else
ret = -ENOENT;
rcu_read_unlock();
return ret;
}
static int proc_scheduler(struct ctl_table *ctl, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
const struct net *net = current->nsproxy->net_ns;
char val[MPTCP_SCHED_NAME_MAX];
struct ctl_table tbl = {
.data = val,
.maxlen = MPTCP_SCHED_NAME_MAX,
};
int ret;
strscpy(val, mptcp_get_scheduler(net), MPTCP_SCHED_NAME_MAX);
ret = proc_dostring(&tbl, write, buffer, lenp, ppos);
if (write && ret == 0)
ret = mptcp_set_scheduler(net, val);
return ret;
}
static struct ctl_table mptcp_sysctl_table[] = {
{
.procname = "enabled",
@ -148,7 +185,7 @@ static struct ctl_table mptcp_sysctl_table[] = {
.procname = "scheduler",
.maxlen = MPTCP_SCHED_NAME_MAX,
.mode = 0644,
.proc_handler = proc_dostring,
.proc_handler = proc_scheduler,
},
{
.procname = "close_timeout",

View file

@ -1518,6 +1518,7 @@ static void nci_rx_work(struct work_struct *work)
if (!nci_plen(skb->data)) {
kfree_skb(skb);
kcov_remote_stop();
break;
}

View file

@ -193,7 +193,7 @@ void rtm_phonet_notify(int event, struct net_device *dev, u8 dst)
struct sk_buff *skb;
int err = -ENOBUFS;
skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct rtmsg)) +
nla_total_size(1) + nla_total_size(4), GFP_KERNEL);
if (skb == NULL)
goto errout;

View file

@ -697,7 +697,7 @@ struct rxrpc_call {
* packets) rather than bytes.
*/
#define RXRPC_TX_SMSS RXRPC_JUMBO_DATALEN
#define RXRPC_MIN_CWND (RXRPC_TX_SMSS > 2190 ? 2 : RXRPC_TX_SMSS > 1095 ? 3 : 4)
#define RXRPC_MIN_CWND 4
u8 cong_cwnd; /* Congestion window size */
u8 cong_extra; /* Extra to send for congestion management */
u8 cong_ssthresh; /* Slow-start threshold */

View file

@ -174,12 +174,7 @@ struct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *rx, gfp_t gfp,
call->rx_winsize = rxrpc_rx_window_size;
call->tx_winsize = 16;
if (RXRPC_TX_SMSS > 2190)
call->cong_cwnd = 2;
else if (RXRPC_TX_SMSS > 1095)
call->cong_cwnd = 3;
else
call->cong_cwnd = 4;
call->cong_cwnd = RXRPC_MIN_CWND;
call->cong_ssthresh = RXRPC_TX_MAX_WINDOW;
call->rxnet = rxnet;

View file

@ -9,6 +9,17 @@
#include "ar-internal.h"
/* Override priority when generating ACKs for received DATA */
static const u8 rxrpc_ack_priority[RXRPC_ACK__INVALID] = {
[RXRPC_ACK_IDLE] = 1,
[RXRPC_ACK_DELAY] = 2,
[RXRPC_ACK_REQUESTED] = 3,
[RXRPC_ACK_DUPLICATE] = 4,
[RXRPC_ACK_EXCEEDS_WINDOW] = 5,
[RXRPC_ACK_NOSPACE] = 6,
[RXRPC_ACK_OUT_OF_SEQUENCE] = 7,
};
static void rxrpc_proto_abort(struct rxrpc_call *call, rxrpc_seq_t seq,
enum rxrpc_abort_reason why)
{
@ -365,7 +376,7 @@ static void rxrpc_input_queue_data(struct rxrpc_call *call, struct sk_buff *skb,
* Process a DATA packet.
*/
static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
bool *_notify)
bool *_notify, rxrpc_serial_t *_ack_serial, int *_ack_reason)
{
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
struct sk_buff *oos;
@ -418,8 +429,6 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
/* Send an immediate ACK if we fill in a hole */
else if (!skb_queue_empty(&call->rx_oos_queue))
ack_reason = RXRPC_ACK_DELAY;
else
call->ackr_nr_unacked++;
window++;
if (after(window, wtop)) {
@ -497,12 +506,16 @@ static void rxrpc_input_data_one(struct rxrpc_call *call, struct sk_buff *skb,
}
send_ack:
if (ack_reason >= 0)
rxrpc_send_ACK(call, ack_reason, serial,
rxrpc_propose_ack_input_data);
else
rxrpc_propose_delay_ACK(call, serial,
rxrpc_propose_ack_input_data);
if (ack_reason >= 0) {
if (rxrpc_ack_priority[ack_reason] > rxrpc_ack_priority[*_ack_reason]) {
*_ack_serial = serial;
*_ack_reason = ack_reason;
} else if (rxrpc_ack_priority[ack_reason] == rxrpc_ack_priority[*_ack_reason] &&
ack_reason == RXRPC_ACK_REQUESTED) {
*_ack_serial = serial;
*_ack_reason = ack_reason;
}
}
}
/*
@ -513,9 +526,11 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
struct rxrpc_jumbo_header jhdr;
struct rxrpc_skb_priv *sp = rxrpc_skb(skb), *jsp;
struct sk_buff *jskb;
rxrpc_serial_t ack_serial = 0;
unsigned int offset = sizeof(struct rxrpc_wire_header);
unsigned int len = skb->len - offset;
bool notify = false;
int ack_reason = 0;
while (sp->hdr.flags & RXRPC_JUMBO_PACKET) {
if (len < RXRPC_JUMBO_SUBPKTLEN)
@ -535,7 +550,7 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
jsp = rxrpc_skb(jskb);
jsp->offset = offset;
jsp->len = RXRPC_JUMBO_DATALEN;
rxrpc_input_data_one(call, jskb, &notify);
rxrpc_input_data_one(call, jskb, &notify, &ack_serial, &ack_reason);
rxrpc_free_skb(jskb, rxrpc_skb_put_jumbo_subpacket);
sp->hdr.flags = jhdr.flags;
@ -548,7 +563,16 @@ static bool rxrpc_input_split_jumbo(struct rxrpc_call *call, struct sk_buff *skb
sp->offset = offset;
sp->len = len;
rxrpc_input_data_one(call, skb, &notify);
rxrpc_input_data_one(call, skb, &notify, &ack_serial, &ack_reason);
if (ack_reason > 0) {
rxrpc_send_ACK(call, ack_reason, ack_serial,
rxrpc_propose_ack_input_data);
} else {
call->ackr_nr_unacked++;
rxrpc_propose_delay_ACK(call, sp->hdr.serial,
rxrpc_propose_ack_input_data);
}
if (notify) {
trace_rxrpc_notify_socket(call->debug_id, sp->hdr.serial);
rxrpc_notify_socket(call);
@ -685,9 +709,6 @@ static void rxrpc_input_ack_trailer(struct rxrpc_call *call, struct sk_buff *skb
call->tx_winsize = rwind;
}
if (call->cong_ssthresh > rwind)
call->cong_ssthresh = rwind;
mtu = min(ntohl(trailer->maxMTU), ntohl(trailer->ifMTU));
peer = call->peer;

View file

@ -209,13 +209,18 @@ int smc_ib_find_route(struct net *net, __be32 saddr, __be32 daddr,
if (IS_ERR(rt))
goto out;
if (rt->rt_uses_gateway && rt->rt_gw_family != AF_INET)
goto out;
neigh = rt->dst.ops->neigh_lookup(&rt->dst, NULL, &fl4.daddr);
if (neigh) {
memcpy(nexthop_mac, neigh->ha, ETH_ALEN);
*uses_gateway = rt->rt_uses_gateway;
return 0;
}
goto out_rt;
neigh = dst_neigh_lookup(&rt->dst, &fl4.daddr);
if (!neigh)
goto out_rt;
memcpy(nexthop_mac, neigh->ha, ETH_ALEN);
*uses_gateway = rt->rt_uses_gateway;
neigh_release(neigh);
ip_rt_put(rt);
return 0;
out_rt:
ip_rt_put(rt);
out:
return -ENOENT;
}

View file

@ -389,11 +389,15 @@ static int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
*/
static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
{
struct xfrm_offload *xo = xfrm_offload(skb);
int ihl = skb->data - skb_transport_header(skb);
if (skb->transport_header != skb->network_header) {
memmove(skb_transport_header(skb),
skb_network_header(skb), ihl);
if (xo)
xo->orig_mac_len =
skb_mac_header_was_set(skb) ? skb_mac_header_len(skb) : 0;
skb->network_header = skb->transport_header;
}
ip_hdr(skb)->tot_len = htons(skb->len + ihl);
@ -404,11 +408,15 @@ static int xfrm4_transport_input(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_transport_input(struct xfrm_state *x, struct sk_buff *skb)
{
#if IS_ENABLED(CONFIG_IPV6)
struct xfrm_offload *xo = xfrm_offload(skb);
int ihl = skb->data - skb_transport_header(skb);
if (skb->transport_header != skb->network_header) {
memmove(skb_transport_header(skb),
skb_network_header(skb), ihl);
if (xo)
xo->orig_mac_len =
skb_mac_header_was_set(skb) ? skb_mac_header_len(skb) : 0;
skb->network_header = skb->transport_header;
}
ipv6_hdr(skb)->payload_len = htons(skb->len + ihl -

View file

@ -3593,6 +3593,8 @@ xfrm_policy *xfrm_in_fwd_icmp(struct sk_buff *skb,
return pol;
pol = xfrm_policy_lookup(net, &fl1, family, XFRM_POLICY_FWD, if_id);
if (IS_ERR(pol))
pol = NULL;
}
return pol;

View file

@ -154,17 +154,9 @@ setup_topo()
setup_topo_ns $ns
done
ip link add name veth0 type veth peer name veth1
ip link set dev veth0 netns $h1 name eth0
ip link set dev veth1 netns $sw1 name swp1
ip link add name veth0 type veth peer name veth1
ip link set dev veth0 netns $sw1 name veth0
ip link set dev veth1 netns $sw2 name veth0
ip link add name veth0 type veth peer name veth1
ip link set dev veth0 netns $h2 name eth0
ip link set dev veth1 netns $sw2 name swp1
ip -n $h1 link add name eth0 type veth peer name swp1 netns $sw1
ip -n $sw1 link add name veth0 type veth peer name veth0 netns $sw2
ip -n $h2 link add name eth0 type veth peer name swp1 netns $sw2
}
setup_host_common()