diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 21:16:41 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 21:16:41 -0400 |
| commit | cae61ba37b4c2672704cbd8a626fbd85be7e67d9 (patch) | |
| tree | 035a181a7c079ff3c4f073c8d5abfc9da8c4a407 | |
| parent | ca755175f245b91f72cfa474aaa8acd9c26996f4 (diff) | |
| parent | 418c96ac151a16a5094a95d14252c92c1d47ec67 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
1) Unbreak zebra and other netlink apps, from Eric W Biederman.
2) Some new qmi_wwan device IDs, from Aleksander Morgado.
3) Fix info leak in DCB netlink handler of qlcnic driver, from Dan
Carpenter.
4) inet_getid() and ipv6_select_ident() do not generate monotonically
increasing ID numbers, fix from Eric Dumazet.
5) Fix memory leak in __sk_prepare_filter(), from Leon Yu.
6) Netlink leftover bytes warning message is user triggerable, rate
limit it. From Michal Schmidt.
7) Fix non-linear SKB panic in ipvs, from Peter Christensen.
8) Congestion window undo needs to be performed even if only never
retransmitted data is SACK'd, fix from Yuching Cheng.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (24 commits)
net: filter: fix possible memory leak in __sk_prepare_filter()
net: ec_bhf: Add runtime dependencies
tcp: fix cwnd undo on DSACK in F-RTO
netlink: Only check file credentials for implicit destinations
ipheth: Add support for iPad 2 and iPad 3
team: fix mtu setting
net: fix inet_getid() and ipv6_select_ident() bugs
net: qmi_wwan: interface #11 in Sierra Wireless MC73xx is not QMI
net: qmi_wwan: add additional Sierra Wireless QMI devices
bridge: Prevent insertion of FDB entry with disallowed vlan
netlink: rate-limit leftover bytes warning and print process name
bridge: notify user space after fdb update
net: qmi_wwan: add Netgear AirCard 341U
net: fix wrong mac_len calculation for vlans
batman-adv: fix NULL pointer dereferences
net/mlx4_core: Reset RoCE VF gids when guest driver goes down
emac: aggregation of v1-2 PLB errors for IER register
emac: add missing support of 10mbit in emac/rgmii
can: only rename enabled led triggers when changing the netdev name
ipvs: Fix panic due to non-linear skb
...
31 files changed, 279 insertions, 87 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 8ccf31c95a15..6c484ac93da7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -3153,10 +3153,9 @@ S: Maintained | |||
| 3153 | F: drivers/scsi/eata_pio.* | 3153 | F: drivers/scsi/eata_pio.* |
| 3154 | 3154 | ||
| 3155 | EBTABLES | 3155 | EBTABLES |
| 3156 | M: Bart De Schuymer <bart.de.schuymer@pandora.be> | ||
| 3157 | L: netfilter-devel@vger.kernel.org | 3156 | L: netfilter-devel@vger.kernel.org |
| 3158 | W: http://ebtables.sourceforge.net/ | 3157 | W: http://ebtables.sourceforge.net/ |
| 3159 | S: Maintained | 3158 | S: Orphan |
| 3160 | F: include/linux/netfilter_bridge/ebt_*.h | 3159 | F: include/linux/netfilter_bridge/ebt_*.h |
| 3161 | F: include/uapi/linux/netfilter_bridge/ebt_*.h | 3160 | F: include/uapi/linux/netfilter_bridge/ebt_*.h |
| 3162 | F: net/bridge/netfilter/ebt*.c | 3161 | F: net/bridge/netfilter/ebt*.c |
diff --git a/drivers/net/can/led.c b/drivers/net/can/led.c index a3d99a8fd2d1..ab7f1b01be49 100644 --- a/drivers/net/can/led.c +++ b/drivers/net/can/led.c | |||
| @@ -97,6 +97,9 @@ static int can_led_notifier(struct notifier_block *nb, unsigned long msg, | |||
| 97 | if (!priv) | 97 | if (!priv) |
| 98 | return NOTIFY_DONE; | 98 | return NOTIFY_DONE; |
| 99 | 99 | ||
| 100 | if (!priv->tx_led_trig || !priv->rx_led_trig) | ||
| 101 | return NOTIFY_DONE; | ||
| 102 | |||
| 100 | if (msg == NETDEV_CHANGENAME) { | 103 | if (msg == NETDEV_CHANGENAME) { |
| 101 | snprintf(name, sizeof(name), "%s-tx", netdev->name); | 104 | snprintf(name, sizeof(name), "%s-tx", netdev->name); |
| 102 | led_trigger_rename_static(name, priv->tx_led_trig); | 105 | led_trigger_rename_static(name, priv->tx_led_trig); |
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index d7401017a3f1..051349458462 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig | |||
| @@ -39,6 +39,7 @@ source "drivers/net/ethernet/cisco/Kconfig" | |||
| 39 | config CX_ECAT | 39 | config CX_ECAT |
| 40 | tristate "Beckhoff CX5020 EtherCAT master support" | 40 | tristate "Beckhoff CX5020 EtherCAT master support" |
| 41 | depends on PCI | 41 | depends on PCI |
| 42 | depends on X86 || COMPILE_TEST | ||
| 42 | ---help--- | 43 | ---help--- |
| 43 | Driver for EtherCAT master module located on CCAT FPGA | 44 | Driver for EtherCAT master module located on CCAT FPGA |
| 44 | that can be found on Beckhoff CX5020, and possibly other of CX | 45 | that can be found on Beckhoff CX5020, and possibly other of CX |
diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c index 9d75fef6396f..63eb959a28aa 100644 --- a/drivers/net/ethernet/ibm/emac/mal.c +++ b/drivers/net/ethernet/ibm/emac/mal.c | |||
| @@ -682,10 +682,7 @@ static int mal_probe(struct platform_device *ofdev) | |||
| 682 | goto fail6; | 682 | goto fail6; |
| 683 | 683 | ||
| 684 | /* Enable all MAL SERR interrupt sources */ | 684 | /* Enable all MAL SERR interrupt sources */ |
| 685 | if (mal->version == 2) | 685 | set_mal_dcrn(mal, MAL_IER, MAL_IER_EVENTS); |
| 686 | set_mal_dcrn(mal, MAL_IER, MAL2_IER_EVENTS); | ||
| 687 | else | ||
| 688 | set_mal_dcrn(mal, MAL_IER, MAL1_IER_EVENTS); | ||
| 689 | 686 | ||
| 690 | /* Enable EOB interrupt */ | 687 | /* Enable EOB interrupt */ |
| 691 | mal_enable_eob_irq(mal); | 688 | mal_enable_eob_irq(mal); |
diff --git a/drivers/net/ethernet/ibm/emac/mal.h b/drivers/net/ethernet/ibm/emac/mal.h index e431a32e3d69..eeade2ea8334 100644 --- a/drivers/net/ethernet/ibm/emac/mal.h +++ b/drivers/net/ethernet/ibm/emac/mal.h | |||
| @@ -95,24 +95,20 @@ | |||
| 95 | 95 | ||
| 96 | 96 | ||
| 97 | #define MAL_IER 0x02 | 97 | #define MAL_IER 0x02 |
| 98 | /* MAL IER bits */ | ||
| 98 | #define MAL_IER_DE 0x00000010 | 99 | #define MAL_IER_DE 0x00000010 |
| 99 | #define MAL_IER_OTE 0x00000004 | 100 | #define MAL_IER_OTE 0x00000004 |
| 100 | #define MAL_IER_OE 0x00000002 | 101 | #define MAL_IER_OE 0x00000002 |
| 101 | #define MAL_IER_PE 0x00000001 | 102 | #define MAL_IER_PE 0x00000001 |
| 102 | /* MAL V1 IER bits */ | ||
| 103 | #define MAL1_IER_NWE 0x00000008 | ||
| 104 | #define MAL1_IER_SOC_EVENTS MAL1_IER_NWE | ||
| 105 | #define MAL1_IER_EVENTS (MAL1_IER_SOC_EVENTS | MAL_IER_DE | \ | ||
| 106 | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE) | ||
| 107 | 103 | ||
| 108 | /* MAL V2 IER bits */ | 104 | /* PLB read/write/timeout errors */ |
| 109 | #define MAL2_IER_PT 0x00000080 | 105 | #define MAL_IER_PTE 0x00000080 |
| 110 | #define MAL2_IER_PRE 0x00000040 | 106 | #define MAL_IER_PRE 0x00000040 |
| 111 | #define MAL2_IER_PWE 0x00000020 | 107 | #define MAL_IER_PWE 0x00000020 |
| 112 | #define MAL2_IER_SOC_EVENTS (MAL2_IER_PT | MAL2_IER_PRE | MAL2_IER_PWE) | ||
| 113 | #define MAL2_IER_EVENTS (MAL2_IER_SOC_EVENTS | MAL_IER_DE | \ | ||
| 114 | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE) | ||
| 115 | 108 | ||
| 109 | #define MAL_IER_SOC_EVENTS (MAL_IER_PTE | MAL_IER_PRE | MAL_IER_PWE) | ||
| 110 | #define MAL_IER_EVENTS (MAL_IER_SOC_EVENTS | MAL_IER_DE | \ | ||
| 111 | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE) | ||
| 116 | 112 | ||
| 117 | #define MAL_TXCASR 0x04 | 113 | #define MAL_TXCASR 0x04 |
| 118 | #define MAL_TXCARR 0x05 | 114 | #define MAL_TXCARR 0x05 |
diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c index 4fb2f96da23b..a01182cce965 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.c +++ b/drivers/net/ethernet/ibm/emac/rgmii.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | 45 | ||
| 46 | /* RGMIIx_SSR */ | 46 | /* RGMIIx_SSR */ |
| 47 | #define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8)) | 47 | #define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8)) |
| 48 | #define RGMII_SSR_10(idx) (0x1 << ((idx) * 8)) | ||
| 48 | #define RGMII_SSR_100(idx) (0x2 << ((idx) * 8)) | 49 | #define RGMII_SSR_100(idx) (0x2 << ((idx) * 8)) |
| 49 | #define RGMII_SSR_1000(idx) (0x4 << ((idx) * 8)) | 50 | #define RGMII_SSR_1000(idx) (0x4 << ((idx) * 8)) |
| 50 | 51 | ||
| @@ -139,6 +140,8 @@ void rgmii_set_speed(struct platform_device *ofdev, int input, int speed) | |||
| 139 | ssr |= RGMII_SSR_1000(input); | 140 | ssr |= RGMII_SSR_1000(input); |
| 140 | else if (speed == SPEED_100) | 141 | else if (speed == SPEED_100) |
| 141 | ssr |= RGMII_SSR_100(input); | 142 | ssr |= RGMII_SSR_100(input); |
| 143 | else if (speed == SPEED_10) | ||
| 144 | ssr |= RGMII_SSR_10(input); | ||
| 142 | 145 | ||
| 143 | out_be32(&p->ssr, ssr); | 146 | out_be32(&p->ssr, ssr); |
| 144 | 147 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 7cf9dadcb471..c187d748115f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -2044,6 +2044,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) | |||
| 2044 | if (!mlx4_is_slave(dev)) { | 2044 | if (!mlx4_is_slave(dev)) { |
| 2045 | mlx4_init_mac_table(dev, &info->mac_table); | 2045 | mlx4_init_mac_table(dev, &info->mac_table); |
| 2046 | mlx4_init_vlan_table(dev, &info->vlan_table); | 2046 | mlx4_init_vlan_table(dev, &info->vlan_table); |
| 2047 | mlx4_init_roce_gid_table(dev, &info->gid_table); | ||
| 2047 | info->base_qpn = mlx4_get_base_qpn(dev, port); | 2048 | info->base_qpn = mlx4_get_base_qpn(dev, port); |
| 2048 | } | 2049 | } |
| 2049 | 2050 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 212cea440f90..8e9eb02e09cb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
| @@ -695,6 +695,17 @@ struct mlx4_mac_table { | |||
| 695 | int max; | 695 | int max; |
| 696 | }; | 696 | }; |
| 697 | 697 | ||
| 698 | #define MLX4_ROCE_GID_ENTRY_SIZE 16 | ||
| 699 | |||
| 700 | struct mlx4_roce_gid_entry { | ||
| 701 | u8 raw[MLX4_ROCE_GID_ENTRY_SIZE]; | ||
| 702 | }; | ||
| 703 | |||
| 704 | struct mlx4_roce_gid_table { | ||
| 705 | struct mlx4_roce_gid_entry roce_gids[MLX4_ROCE_MAX_GIDS]; | ||
| 706 | struct mutex mutex; | ||
| 707 | }; | ||
| 708 | |||
| 698 | #define MLX4_MAX_VLAN_NUM 128 | 709 | #define MLX4_MAX_VLAN_NUM 128 |
| 699 | #define MLX4_VLAN_TABLE_SIZE (MLX4_MAX_VLAN_NUM << 2) | 710 | #define MLX4_VLAN_TABLE_SIZE (MLX4_MAX_VLAN_NUM << 2) |
| 700 | 711 | ||
| @@ -758,6 +769,7 @@ struct mlx4_port_info { | |||
| 758 | struct device_attribute port_mtu_attr; | 769 | struct device_attribute port_mtu_attr; |
| 759 | struct mlx4_mac_table mac_table; | 770 | struct mlx4_mac_table mac_table; |
| 760 | struct mlx4_vlan_table vlan_table; | 771 | struct mlx4_vlan_table vlan_table; |
| 772 | struct mlx4_roce_gid_table gid_table; | ||
| 761 | int base_qpn; | 773 | int base_qpn; |
| 762 | }; | 774 | }; |
| 763 | 775 | ||
| @@ -788,10 +800,6 @@ enum { | |||
| 788 | MLX4_USE_RR = 1, | 800 | MLX4_USE_RR = 1, |
| 789 | }; | 801 | }; |
| 790 | 802 | ||
| 791 | struct mlx4_roce_gid_entry { | ||
| 792 | u8 raw[16]; | ||
| 793 | }; | ||
| 794 | |||
| 795 | struct mlx4_priv { | 803 | struct mlx4_priv { |
| 796 | struct mlx4_dev dev; | 804 | struct mlx4_dev dev; |
| 797 | 805 | ||
| @@ -839,7 +847,6 @@ struct mlx4_priv { | |||
| 839 | int fs_hash_mode; | 847 | int fs_hash_mode; |
| 840 | u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS]; | 848 | u8 virt2phys_pkey[MLX4_MFUNC_MAX][MLX4_MAX_PORTS][MLX4_MAX_PORT_PKEYS]; |
| 841 | __be64 slave_node_guids[MLX4_MFUNC_MAX]; | 849 | __be64 slave_node_guids[MLX4_MFUNC_MAX]; |
| 842 | struct mlx4_roce_gid_entry roce_gids[MLX4_MAX_PORTS][MLX4_ROCE_MAX_GIDS]; | ||
| 843 | 850 | ||
| 844 | atomic_t opreq_count; | 851 | atomic_t opreq_count; |
| 845 | struct work_struct opreq_task; | 852 | struct work_struct opreq_task; |
| @@ -1140,6 +1147,8 @@ int mlx4_change_port_types(struct mlx4_dev *dev, | |||
| 1140 | 1147 | ||
| 1141 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); | 1148 | void mlx4_init_mac_table(struct mlx4_dev *dev, struct mlx4_mac_table *table); |
| 1142 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); | 1149 | void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table); |
| 1150 | void mlx4_init_roce_gid_table(struct mlx4_dev *dev, | ||
| 1151 | struct mlx4_roce_gid_table *table); | ||
| 1143 | void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan); | 1152 | void __mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, u16 vlan); |
| 1144 | int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); | 1153 | int __mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); |
| 1145 | 1154 | ||
| @@ -1149,6 +1158,7 @@ int mlx4_get_slave_from_resource_id(struct mlx4_dev *dev, | |||
| 1149 | enum mlx4_resource resource_type, | 1158 | enum mlx4_resource resource_type, |
| 1150 | u64 resource_id, int *slave); | 1159 | u64 resource_id, int *slave); |
| 1151 | void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id); | 1160 | void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id); |
| 1161 | void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave); | ||
| 1152 | int mlx4_init_resource_tracker(struct mlx4_dev *dev); | 1162 | int mlx4_init_resource_tracker(struct mlx4_dev *dev); |
| 1153 | 1163 | ||
| 1154 | void mlx4_free_resource_tracker(struct mlx4_dev *dev, | 1164 | void mlx4_free_resource_tracker(struct mlx4_dev *dev, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index b5b3549b0c8d..5ec6f203c6e6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
| @@ -75,6 +75,16 @@ void mlx4_init_vlan_table(struct mlx4_dev *dev, struct mlx4_vlan_table *table) | |||
| 75 | table->total = 0; | 75 | table->total = 0; |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | void mlx4_init_roce_gid_table(struct mlx4_dev *dev, | ||
| 79 | struct mlx4_roce_gid_table *table) | ||
| 80 | { | ||
| 81 | int i; | ||
| 82 | |||
| 83 | mutex_init(&table->mutex); | ||
| 84 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) | ||
| 85 | memset(table->roce_gids[i].raw, 0, MLX4_ROCE_GID_ENTRY_SIZE); | ||
| 86 | } | ||
| 87 | |||
| 78 | static int validate_index(struct mlx4_dev *dev, | 88 | static int validate_index(struct mlx4_dev *dev, |
| 79 | struct mlx4_mac_table *table, int index) | 89 | struct mlx4_mac_table *table, int index) |
| 80 | { | 90 | { |
| @@ -584,6 +594,84 @@ int mlx4_get_base_gid_ix(struct mlx4_dev *dev, int slave, int port) | |||
| 584 | } | 594 | } |
| 585 | EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix); | 595 | EXPORT_SYMBOL_GPL(mlx4_get_base_gid_ix); |
| 586 | 596 | ||
| 597 | static int mlx4_reset_roce_port_gids(struct mlx4_dev *dev, int slave, | ||
| 598 | int port, struct mlx4_cmd_mailbox *mailbox) | ||
| 599 | { | ||
| 600 | struct mlx4_roce_gid_entry *gid_entry_mbox; | ||
| 601 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
| 602 | int num_gids, base, offset; | ||
| 603 | int i, err; | ||
| 604 | |||
| 605 | num_gids = mlx4_get_slave_num_gids(dev, slave, port); | ||
| 606 | base = mlx4_get_base_gid_ix(dev, slave, port); | ||
| 607 | |||
| 608 | memset(mailbox->buf, 0, MLX4_MAILBOX_SIZE); | ||
| 609 | |||
| 610 | mutex_lock(&(priv->port[port].gid_table.mutex)); | ||
| 611 | /* Zero-out gids belonging to that slave in the port GID table */ | ||
| 612 | for (i = 0, offset = base; i < num_gids; offset++, i++) | ||
| 613 | memcpy(priv->port[port].gid_table.roce_gids[offset].raw, | ||
| 614 | zgid_entry.raw, MLX4_ROCE_GID_ENTRY_SIZE); | ||
| 615 | |||
| 616 | /* Now, copy roce port gids table to mailbox for passing to FW */ | ||
| 617 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)mailbox->buf; | ||
| 618 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++) | ||
| 619 | memcpy(gid_entry_mbox->raw, | ||
| 620 | priv->port[port].gid_table.roce_gids[i].raw, | ||
| 621 | MLX4_ROCE_GID_ENTRY_SIZE); | ||
| 622 | |||
| 623 | err = mlx4_cmd(dev, mailbox->dma, | ||
| 624 | ((u32)port) | (MLX4_SET_PORT_GID_TABLE << 8), 1, | ||
| 625 | MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, | ||
| 626 | MLX4_CMD_NATIVE); | ||
| 627 | mutex_unlock(&(priv->port[port].gid_table.mutex)); | ||
| 628 | return err; | ||
| 629 | } | ||
| 630 | |||
| 631 | |||
| 632 | void mlx4_reset_roce_gids(struct mlx4_dev *dev, int slave) | ||
| 633 | { | ||
| 634 | struct mlx4_active_ports actv_ports; | ||
| 635 | struct mlx4_cmd_mailbox *mailbox; | ||
| 636 | int num_eth_ports, err; | ||
| 637 | int i; | ||
| 638 | |||
| 639 | if (slave < 0 || slave > dev->num_vfs) | ||
| 640 | return; | ||
| 641 | |||
| 642 | actv_ports = mlx4_get_active_ports(dev, slave); | ||
| 643 | |||
| 644 | for (i = 0, num_eth_ports = 0; i < dev->caps.num_ports; i++) { | ||
| 645 | if (test_bit(i, actv_ports.ports)) { | ||
| 646 | if (dev->caps.port_type[i + 1] != MLX4_PORT_TYPE_ETH) | ||
| 647 | continue; | ||
| 648 | num_eth_ports++; | ||
| 649 | } | ||
| 650 | } | ||
| 651 | |||
| 652 | if (!num_eth_ports) | ||
| 653 | return; | ||
| 654 | |||
| 655 | /* have ETH ports. Alloc mailbox for SET_PORT command */ | ||
| 656 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
| 657 | if (IS_ERR(mailbox)) | ||
| 658 | return; | ||
| 659 | |||
| 660 | for (i = 0; i < dev->caps.num_ports; i++) { | ||
| 661 | if (test_bit(i, actv_ports.ports)) { | ||
| 662 | if (dev->caps.port_type[i + 1] != MLX4_PORT_TYPE_ETH) | ||
| 663 | continue; | ||
| 664 | err = mlx4_reset_roce_port_gids(dev, slave, i + 1, mailbox); | ||
| 665 | if (err) | ||
| 666 | mlx4_warn(dev, "Could not reset ETH port GID table for slave %d, port %d (%d)\n", | ||
| 667 | slave, i + 1, err); | ||
| 668 | } | ||
| 669 | } | ||
| 670 | |||
| 671 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
| 672 | return; | ||
| 673 | } | ||
| 674 | |||
| 587 | static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | 675 | static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, |
| 588 | u8 op_mod, struct mlx4_cmd_mailbox *inbox) | 676 | u8 op_mod, struct mlx4_cmd_mailbox *inbox) |
| 589 | { | 677 | { |
| @@ -692,10 +780,12 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | |||
| 692 | /* 2. Check that do not have duplicates in OTHER | 780 | /* 2. Check that do not have duplicates in OTHER |
| 693 | * entries in the port GID table | 781 | * entries in the port GID table |
| 694 | */ | 782 | */ |
| 783 | |||
| 784 | mutex_lock(&(priv->port[port].gid_table.mutex)); | ||
| 695 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { | 785 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { |
| 696 | if (i >= base && i < base + num_gids) | 786 | if (i >= base && i < base + num_gids) |
| 697 | continue; /* don't compare to slave's current gids */ | 787 | continue; /* don't compare to slave's current gids */ |
| 698 | gid_entry_tbl = &priv->roce_gids[port - 1][i]; | 788 | gid_entry_tbl = &priv->port[port].gid_table.roce_gids[i]; |
| 699 | if (!memcmp(gid_entry_tbl->raw, zgid_entry.raw, sizeof(zgid_entry))) | 789 | if (!memcmp(gid_entry_tbl->raw, zgid_entry.raw, sizeof(zgid_entry))) |
| 700 | continue; | 790 | continue; |
| 701 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); | 791 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); |
| @@ -709,6 +799,7 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | |||
| 709 | mlx4_warn(dev, "requested gid entry for slave:%d " | 799 | mlx4_warn(dev, "requested gid entry for slave:%d " |
| 710 | "is a duplicate of gid at index %d\n", | 800 | "is a duplicate of gid at index %d\n", |
| 711 | slave, i); | 801 | slave, i); |
| 802 | mutex_unlock(&(priv->port[port].gid_table.mutex)); | ||
| 712 | return -EINVAL; | 803 | return -EINVAL; |
| 713 | } | 804 | } |
| 714 | } | 805 | } |
| @@ -717,16 +808,24 @@ static int mlx4_common_set_port(struct mlx4_dev *dev, int slave, u32 in_mod, | |||
| 717 | /* insert slave GIDs with memcpy, starting at slave's base index */ | 808 | /* insert slave GIDs with memcpy, starting at slave's base index */ |
| 718 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); | 809 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); |
| 719 | for (i = 0, offset = base; i < num_gids; gid_entry_mbox++, offset++, i++) | 810 | for (i = 0, offset = base; i < num_gids; gid_entry_mbox++, offset++, i++) |
| 720 | memcpy(priv->roce_gids[port - 1][offset].raw, gid_entry_mbox->raw, 16); | 811 | memcpy(priv->port[port].gid_table.roce_gids[offset].raw, |
| 812 | gid_entry_mbox->raw, MLX4_ROCE_GID_ENTRY_SIZE); | ||
| 721 | 813 | ||
| 722 | /* Now, copy roce port gids table to current mailbox for passing to FW */ | 814 | /* Now, copy roce port gids table to current mailbox for passing to FW */ |
| 723 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); | 815 | gid_entry_mbox = (struct mlx4_roce_gid_entry *)(inbox->buf); |
| 724 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++) | 816 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; gid_entry_mbox++, i++) |
| 725 | memcpy(gid_entry_mbox->raw, priv->roce_gids[port - 1][i].raw, 16); | 817 | memcpy(gid_entry_mbox->raw, |
| 726 | 818 | priv->port[port].gid_table.roce_gids[i].raw, | |
| 727 | break; | 819 | MLX4_ROCE_GID_ENTRY_SIZE); |
| 820 | |||
| 821 | err = mlx4_cmd(dev, inbox->dma, in_mod & 0xffff, op_mod, | ||
| 822 | MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, | ||
| 823 | MLX4_CMD_NATIVE); | ||
| 824 | mutex_unlock(&(priv->port[port].gid_table.mutex)); | ||
| 825 | return err; | ||
| 728 | } | 826 | } |
| 729 | return mlx4_cmd(dev, inbox->dma, in_mod, op_mod, | 827 | |
| 828 | return mlx4_cmd(dev, inbox->dma, in_mod & 0xffff, op_mod, | ||
| 730 | MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, | 829 | MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B, |
| 731 | MLX4_CMD_NATIVE); | 830 | MLX4_CMD_NATIVE); |
| 732 | } | 831 | } |
| @@ -1099,7 +1198,8 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, | |||
| 1099 | num_vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1; | 1198 | num_vfs = bitmap_weight(slaves_pport.slaves, dev->num_vfs + 1) - 1; |
| 1100 | 1199 | ||
| 1101 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { | 1200 | for (i = 0; i < MLX4_ROCE_MAX_GIDS; i++) { |
| 1102 | if (!memcmp(priv->roce_gids[port - 1][i].raw, gid, 16)) { | 1201 | if (!memcmp(priv->port[port].gid_table.roce_gids[i].raw, gid, |
| 1202 | MLX4_ROCE_GID_ENTRY_SIZE)) { | ||
| 1103 | found_ix = i; | 1203 | found_ix = i; |
| 1104 | break; | 1204 | break; |
| 1105 | } | 1205 | } |
| @@ -1187,7 +1287,8 @@ int mlx4_get_roce_gid_from_slave(struct mlx4_dev *dev, int port, int slave_id, | |||
| 1187 | if (!mlx4_is_master(dev)) | 1287 | if (!mlx4_is_master(dev)) |
| 1188 | return -EINVAL; | 1288 | return -EINVAL; |
| 1189 | 1289 | ||
| 1190 | memcpy(gid, priv->roce_gids[port - 1][slave_id].raw, 16); | 1290 | memcpy(gid, priv->port[port].gid_table.roce_gids[slave_id].raw, |
| 1291 | MLX4_ROCE_GID_ENTRY_SIZE); | ||
| 1191 | return 0; | 1292 | return 0; |
| 1192 | } | 1293 | } |
| 1193 | EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); | 1294 | EXPORT_SYMBOL(mlx4_get_roce_gid_from_slave); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 8f1254a79832..f16e539749c4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
| @@ -586,6 +586,7 @@ void mlx4_free_resource_tracker(struct mlx4_dev *dev, | |||
| 586 | } | 586 | } |
| 587 | /* free master's vlans */ | 587 | /* free master's vlans */ |
| 588 | i = dev->caps.function; | 588 | i = dev->caps.function; |
| 589 | mlx4_reset_roce_gids(dev, i); | ||
| 589 | mutex_lock(&priv->mfunc.master.res_tracker.slave_list[i].mutex); | 590 | mutex_lock(&priv->mfunc.master.res_tracker.slave_list[i].mutex); |
| 590 | rem_slave_vlans(dev, i); | 591 | rem_slave_vlans(dev, i); |
| 591 | mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[i].mutex); | 592 | mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[i].mutex); |
| @@ -4681,7 +4682,7 @@ static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave) | |||
| 4681 | void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) | 4682 | void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave) |
| 4682 | { | 4683 | { |
| 4683 | struct mlx4_priv *priv = mlx4_priv(dev); | 4684 | struct mlx4_priv *priv = mlx4_priv(dev); |
| 4684 | 4685 | mlx4_reset_roce_gids(dev, slave); | |
| 4685 | mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); | 4686 | mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex); |
| 4686 | rem_slave_vlans(dev, slave); | 4687 | rem_slave_vlans(dev, slave); |
| 4687 | rem_slave_macs(dev, slave); | 4688 | rem_slave_macs(dev, slave); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c index a51fe18f09a8..561cb11ca58c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | |||
| @@ -1020,6 +1020,7 @@ static int qlcnic_dcb_peer_app_info(struct net_device *netdev, | |||
| 1020 | struct qlcnic_dcb_cee *peer; | 1020 | struct qlcnic_dcb_cee *peer; |
| 1021 | int i; | 1021 | int i; |
| 1022 | 1022 | ||
| 1023 | memset(info, 0, sizeof(*info)); | ||
| 1023 | *app_count = 0; | 1024 | *app_count = 0; |
| 1024 | 1025 | ||
| 1025 | if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state)) | 1026 | if (!test_bit(QLCNIC_DCB_STATE, &adapter->dcb->state)) |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 767fe61b5ac9..ce4989be86d9 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
| @@ -1724,6 +1724,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1724 | * to traverse list in reverse under rcu_read_lock | 1724 | * to traverse list in reverse under rcu_read_lock |
| 1725 | */ | 1725 | */ |
| 1726 | mutex_lock(&team->lock); | 1726 | mutex_lock(&team->lock); |
| 1727 | team->port_mtu_change_allowed = true; | ||
| 1727 | list_for_each_entry(port, &team->port_list, list) { | 1728 | list_for_each_entry(port, &team->port_list, list) { |
| 1728 | err = dev_set_mtu(port->dev, new_mtu); | 1729 | err = dev_set_mtu(port->dev, new_mtu); |
| 1729 | if (err) { | 1730 | if (err) { |
| @@ -1732,6 +1733,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1732 | goto unwind; | 1733 | goto unwind; |
| 1733 | } | 1734 | } |
| 1734 | } | 1735 | } |
| 1736 | team->port_mtu_change_allowed = false; | ||
| 1735 | mutex_unlock(&team->lock); | 1737 | mutex_unlock(&team->lock); |
| 1736 | 1738 | ||
| 1737 | dev->mtu = new_mtu; | 1739 | dev->mtu = new_mtu; |
| @@ -1741,6 +1743,7 @@ static int team_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1741 | unwind: | 1743 | unwind: |
| 1742 | list_for_each_entry_continue_reverse(port, &team->port_list, list) | 1744 | list_for_each_entry_continue_reverse(port, &team->port_list, list) |
| 1743 | dev_set_mtu(port->dev, dev->mtu); | 1745 | dev_set_mtu(port->dev, dev->mtu); |
| 1746 | team->port_mtu_change_allowed = false; | ||
| 1744 | mutex_unlock(&team->lock); | 1747 | mutex_unlock(&team->lock); |
| 1745 | 1748 | ||
| 1746 | return err; | 1749 | return err; |
| @@ -2851,7 +2854,9 @@ static int team_device_event(struct notifier_block *unused, | |||
| 2851 | break; | 2854 | break; |
| 2852 | case NETDEV_PRECHANGEMTU: | 2855 | case NETDEV_PRECHANGEMTU: |
| 2853 | /* Forbid to change mtu of underlaying device */ | 2856 | /* Forbid to change mtu of underlaying device */ |
| 2854 | return NOTIFY_BAD; | 2857 | if (!port->team->port_mtu_change_allowed) |
| 2858 | return NOTIFY_BAD; | ||
| 2859 | break; | ||
| 2855 | case NETDEV_PRE_TYPE_CHANGE: | 2860 | case NETDEV_PRE_TYPE_CHANGE: |
| 2856 | /* Forbid to change type of underlaying device */ | 2861 | /* Forbid to change type of underlaying device */ |
| 2857 | return NOTIFY_BAD; | 2862 | return NOTIFY_BAD; |
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 421934c83f1c..973275fef250 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c | |||
| @@ -59,6 +59,8 @@ | |||
| 59 | #define USB_PRODUCT_IPHONE_3GS 0x1294 | 59 | #define USB_PRODUCT_IPHONE_3GS 0x1294 |
| 60 | #define USB_PRODUCT_IPHONE_4 0x1297 | 60 | #define USB_PRODUCT_IPHONE_4 0x1297 |
| 61 | #define USB_PRODUCT_IPAD 0x129a | 61 | #define USB_PRODUCT_IPAD 0x129a |
| 62 | #define USB_PRODUCT_IPAD_2 0x12a2 | ||
| 63 | #define USB_PRODUCT_IPAD_3 0x12a6 | ||
| 62 | #define USB_PRODUCT_IPAD_MINI 0x12ab | 64 | #define USB_PRODUCT_IPAD_MINI 0x12ab |
| 63 | #define USB_PRODUCT_IPHONE_4_VZW 0x129c | 65 | #define USB_PRODUCT_IPHONE_4_VZW 0x129c |
| 64 | #define USB_PRODUCT_IPHONE_4S 0x12a0 | 66 | #define USB_PRODUCT_IPHONE_4S 0x12a0 |
| @@ -107,6 +109,14 @@ static struct usb_device_id ipheth_table[] = { | |||
| 107 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | 109 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, |
| 108 | IPHETH_USBINTF_PROTO) }, | 110 | IPHETH_USBINTF_PROTO) }, |
| 109 | { USB_DEVICE_AND_INTERFACE_INFO( | 111 | { USB_DEVICE_AND_INTERFACE_INFO( |
| 112 | USB_VENDOR_APPLE, USB_PRODUCT_IPAD_2, | ||
| 113 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
| 114 | IPHETH_USBINTF_PROTO) }, | ||
| 115 | { USB_DEVICE_AND_INTERFACE_INFO( | ||
| 116 | USB_VENDOR_APPLE, USB_PRODUCT_IPAD_3, | ||
| 117 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
| 118 | IPHETH_USBINTF_PROTO) }, | ||
| 119 | { USB_DEVICE_AND_INTERFACE_INFO( | ||
| 110 | USB_VENDOR_APPLE, USB_PRODUCT_IPAD_MINI, | 120 | USB_VENDOR_APPLE, USB_PRODUCT_IPAD_MINI, |
| 111 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | 121 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, |
| 112 | IPHETH_USBINTF_PROTO) }, | 122 | IPHETH_USBINTF_PROTO) }, |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 83208d4fdc59..dc4bf06948c7 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -748,11 +748,15 @@ static const struct usb_device_id products[] = { | |||
| 748 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | 748 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ |
| 749 | {QMI_FIXED_INTF(0x1199, 0x68c0, 8)}, /* Sierra Wireless MC73xx */ | 749 | {QMI_FIXED_INTF(0x1199, 0x68c0, 8)}, /* Sierra Wireless MC73xx */ |
| 750 | {QMI_FIXED_INTF(0x1199, 0x68c0, 10)}, /* Sierra Wireless MC73xx */ | 750 | {QMI_FIXED_INTF(0x1199, 0x68c0, 10)}, /* Sierra Wireless MC73xx */ |
| 751 | {QMI_FIXED_INTF(0x1199, 0x68c0, 11)}, /* Sierra Wireless MC73xx */ | ||
| 752 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 751 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
| 753 | {QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */ | 752 | {QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */ |
| 754 | {QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */ | 753 | {QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */ |
| 755 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ | 754 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ |
| 755 | {QMI_FIXED_INTF(0x1199, 0x9053, 8)}, /* Sierra Wireless Modem */ | ||
| 756 | {QMI_FIXED_INTF(0x1199, 0x9054, 8)}, /* Sierra Wireless Modem */ | ||
| 757 | {QMI_FIXED_INTF(0x1199, 0x9055, 8)}, /* Netgear AirCard 341U */ | ||
| 758 | {QMI_FIXED_INTF(0x1199, 0x9056, 8)}, /* Sierra Wireless Modem */ | ||
| 759 | {QMI_FIXED_INTF(0x1199, 0x9061, 8)}, /* Sierra Wireless Modem */ | ||
| 756 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 760 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
| 757 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ | 761 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ |
| 758 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 762 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index b41dc84e9431..8735ef1f44ae 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
| @@ -826,7 +826,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
| 826 | if (ret) | 826 | if (ret) |
| 827 | goto out_remove_mac; | 827 | goto out_remove_mac; |
| 828 | 828 | ||
| 829 | if (!mvm->bf_allowed_vif && | 829 | if (!mvm->bf_allowed_vif && false && |
| 830 | vif->type == NL80211_IFTYPE_STATION && !vif->p2p && | 830 | vif->type == NL80211_IFTYPE_STATION && !vif->p2p && |
| 831 | mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED){ | 831 | mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BF_UPDATED){ |
| 832 | mvm->bf_allowed_vif = mvmvif; | 832 | mvm->bf_allowed_vif = mvmvif; |
diff --git a/include/linux/if_team.h b/include/linux/if_team.h index a899dc24be15..a6aa970758a2 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h | |||
| @@ -194,6 +194,7 @@ struct team { | |||
| 194 | bool user_carrier_enabled; | 194 | bool user_carrier_enabled; |
| 195 | bool queue_override_enabled; | 195 | bool queue_override_enabled; |
| 196 | struct list_head *qom_lists; /* array of queue override mapping lists */ | 196 | struct list_head *qom_lists; /* array of queue override mapping lists */ |
| 197 | bool port_mtu_change_allowed; | ||
| 197 | struct { | 198 | struct { |
| 198 | unsigned int count; | 199 | unsigned int count; |
| 199 | unsigned int interval; /* in ms */ | 200 | unsigned int interval; /* in ms */ |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index f64b01787ddc..034cda789a15 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
| @@ -16,9 +16,10 @@ static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb) | |||
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | enum netlink_skb_flags { | 18 | enum netlink_skb_flags { |
| 19 | NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */ | 19 | NETLINK_SKB_MMAPED = 0x1, /* Packet data is mmaped */ |
| 20 | NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */ | 20 | NETLINK_SKB_TX = 0x2, /* Packet was sent by userspace */ |
| 21 | NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */ | 21 | NETLINK_SKB_DELIVERED = 0x4, /* Packet was delivered */ |
| 22 | NETLINK_SKB_DST = 0x8, /* Dst set in sendto or sendmsg */ | ||
| 22 | }; | 23 | }; |
| 23 | 24 | ||
| 24 | struct netlink_skb_parms { | 25 | struct netlink_skb_parms { |
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 6efe73c79c52..058271bde27a 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h | |||
| @@ -177,16 +177,9 @@ static inline void inet_peer_refcheck(const struct inet_peer *p) | |||
| 177 | /* can be called with or without local BH being disabled */ | 177 | /* can be called with or without local BH being disabled */ |
| 178 | static inline int inet_getid(struct inet_peer *p, int more) | 178 | static inline int inet_getid(struct inet_peer *p, int more) |
| 179 | { | 179 | { |
| 180 | int old, new; | ||
| 181 | more++; | 180 | more++; |
| 182 | inet_peer_refcheck(p); | 181 | inet_peer_refcheck(p); |
| 183 | do { | 182 | return atomic_add_return(more, &p->ip_id_count) - more; |
| 184 | old = atomic_read(&p->ip_id_count); | ||
| 185 | new = old + more; | ||
| 186 | if (!new) | ||
| 187 | new = 1; | ||
| 188 | } while (atomic_cmpxchg(&p->ip_id_count, old, new) != old); | ||
| 189 | return new; | ||
| 190 | } | 183 | } |
| 191 | 184 | ||
| 192 | #endif /* _NET_INETPEER_H */ | 185 | #endif /* _NET_INETPEER_H */ |
diff --git a/lib/nlattr.c b/lib/nlattr.c index fc6754720ced..10ad042d01be 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c | |||
| @@ -201,8 +201,8 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head, | |||
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | if (unlikely(rem > 0)) | 203 | if (unlikely(rem > 0)) |
| 204 | printk(KERN_WARNING "netlink: %d bytes leftover after parsing " | 204 | pr_warn_ratelimited("netlink: %d bytes leftover after parsing attributes in process `%s'.\n", |
| 205 | "attributes.\n", rem); | 205 | rem, current->comm); |
| 206 | 206 | ||
| 207 | err = 0; | 207 | err = 0; |
| 208 | errout: | 208 | errout: |
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index 8c7ca811de6e..96b66fd30f96 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c | |||
| @@ -415,7 +415,7 @@ batadv_mcast_forw_ipv4_node_get(struct batadv_priv *bat_priv) | |||
| 415 | hlist_for_each_entry_rcu(tmp_orig_node, | 415 | hlist_for_each_entry_rcu(tmp_orig_node, |
| 416 | &bat_priv->mcast.want_all_ipv4_list, | 416 | &bat_priv->mcast.want_all_ipv4_list, |
| 417 | mcast_want_all_ipv4_node) { | 417 | mcast_want_all_ipv4_node) { |
| 418 | if (!atomic_inc_not_zero(&orig_node->refcount)) | 418 | if (!atomic_inc_not_zero(&tmp_orig_node->refcount)) |
| 419 | continue; | 419 | continue; |
| 420 | 420 | ||
| 421 | orig_node = tmp_orig_node; | 421 | orig_node = tmp_orig_node; |
| @@ -442,7 +442,7 @@ batadv_mcast_forw_ipv6_node_get(struct batadv_priv *bat_priv) | |||
| 442 | hlist_for_each_entry_rcu(tmp_orig_node, | 442 | hlist_for_each_entry_rcu(tmp_orig_node, |
| 443 | &bat_priv->mcast.want_all_ipv6_list, | 443 | &bat_priv->mcast.want_all_ipv6_list, |
| 444 | mcast_want_all_ipv6_node) { | 444 | mcast_want_all_ipv6_node) { |
| 445 | if (!atomic_inc_not_zero(&orig_node->refcount)) | 445 | if (!atomic_inc_not_zero(&tmp_orig_node->refcount)) |
| 446 | continue; | 446 | continue; |
| 447 | 447 | ||
| 448 | orig_node = tmp_orig_node; | 448 | orig_node = tmp_orig_node; |
| @@ -493,7 +493,7 @@ batadv_mcast_forw_unsnoop_node_get(struct batadv_priv *bat_priv) | |||
| 493 | hlist_for_each_entry_rcu(tmp_orig_node, | 493 | hlist_for_each_entry_rcu(tmp_orig_node, |
| 494 | &bat_priv->mcast.want_all_unsnoopables_list, | 494 | &bat_priv->mcast.want_all_unsnoopables_list, |
| 495 | mcast_want_all_unsnoopables_node) { | 495 | mcast_want_all_unsnoopables_node) { |
| 496 | if (!atomic_inc_not_zero(&orig_node->refcount)) | 496 | if (!atomic_inc_not_zero(&tmp_orig_node->refcount)) |
| 497 | continue; | 497 | continue; |
| 498 | 498 | ||
| 499 | orig_node = tmp_orig_node; | 499 | orig_node = tmp_orig_node; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a1e5bb7d06e8..dc4d301d3a72 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
| @@ -7519,9 +7519,9 @@ int __init l2cap_init(void) | |||
| 7519 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs, | 7519 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, bt_debugfs, |
| 7520 | NULL, &l2cap_debugfs_fops); | 7520 | NULL, &l2cap_debugfs_fops); |
| 7521 | 7521 | ||
| 7522 | debugfs_create_u16("l2cap_le_max_credits", 0466, bt_debugfs, | 7522 | debugfs_create_u16("l2cap_le_max_credits", 0644, bt_debugfs, |
| 7523 | &le_max_credits); | 7523 | &le_max_credits); |
| 7524 | debugfs_create_u16("l2cap_le_default_mps", 0466, bt_debugfs, | 7524 | debugfs_create_u16("l2cap_le_default_mps", 0644, bt_debugfs, |
| 7525 | &le_default_mps); | 7525 | &le_default_mps); |
| 7526 | 7526 | ||
| 7527 | bt_6lowpan_init(); | 7527 | bt_6lowpan_init(); |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 9203d5a1943f..474d36f93342 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
| @@ -487,6 +487,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, | |||
| 487 | { | 487 | { |
| 488 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; | 488 | struct hlist_head *head = &br->hash[br_mac_hash(addr, vid)]; |
| 489 | struct net_bridge_fdb_entry *fdb; | 489 | struct net_bridge_fdb_entry *fdb; |
| 490 | bool fdb_modified = false; | ||
| 490 | 491 | ||
| 491 | /* some users want to always flood. */ | 492 | /* some users want to always flood. */ |
| 492 | if (hold_time(br) == 0) | 493 | if (hold_time(br) == 0) |
| @@ -507,10 +508,15 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, | |||
| 507 | source->dev->name); | 508 | source->dev->name); |
| 508 | } else { | 509 | } else { |
| 509 | /* fastpath: update of existing entry */ | 510 | /* fastpath: update of existing entry */ |
| 510 | fdb->dst = source; | 511 | if (unlikely(source != fdb->dst)) { |
| 512 | fdb->dst = source; | ||
| 513 | fdb_modified = true; | ||
| 514 | } | ||
| 511 | fdb->updated = jiffies; | 515 | fdb->updated = jiffies; |
| 512 | if (unlikely(added_by_user)) | 516 | if (unlikely(added_by_user)) |
| 513 | fdb->added_by_user = 1; | 517 | fdb->added_by_user = 1; |
| 518 | if (unlikely(fdb_modified)) | ||
| 519 | fdb_notify(br, fdb, RTM_NEWNEIGH); | ||
| 514 | } | 520 | } |
| 515 | } else { | 521 | } else { |
| 516 | spin_lock(&br->hash_lock); | 522 | spin_lock(&br->hash_lock); |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 7985deaff52f..04d6348fd530 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
| @@ -147,8 +147,8 @@ static int br_handle_local_finish(struct sk_buff *skb) | |||
| 147 | struct net_bridge_port *p = br_port_get_rcu(skb->dev); | 147 | struct net_bridge_port *p = br_port_get_rcu(skb->dev); |
| 148 | u16 vid = 0; | 148 | u16 vid = 0; |
| 149 | 149 | ||
| 150 | br_vlan_get_tag(skb, &vid); | 150 | /* check if vlan is allowed, to avoid spoofing */ |
| 151 | if (p->flags & BR_LEARNING) | 151 | if (p->flags & BR_LEARNING && br_should_learn(p, skb, &vid)) |
| 152 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false); | 152 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false); |
| 153 | return 0; /* process further */ | 153 | return 0; /* process further */ |
| 154 | } | 154 | } |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 06811d79f89f..59d3a85c5873 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
| @@ -581,6 +581,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
| 581 | struct sk_buff *skb, u16 *vid); | 581 | struct sk_buff *skb, u16 *vid); |
| 582 | bool br_allowed_egress(struct net_bridge *br, const struct net_port_vlans *v, | 582 | bool br_allowed_egress(struct net_bridge *br, const struct net_port_vlans *v, |
| 583 | const struct sk_buff *skb); | 583 | const struct sk_buff *skb); |
| 584 | bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid); | ||
| 584 | struct sk_buff *br_handle_vlan(struct net_bridge *br, | 585 | struct sk_buff *br_handle_vlan(struct net_bridge *br, |
| 585 | const struct net_port_vlans *v, | 586 | const struct net_port_vlans *v, |
| 586 | struct sk_buff *skb); | 587 | struct sk_buff *skb); |
| @@ -648,6 +649,12 @@ static inline bool br_allowed_egress(struct net_bridge *br, | |||
| 648 | return true; | 649 | return true; |
| 649 | } | 650 | } |
| 650 | 651 | ||
| 652 | static inline bool br_should_learn(struct net_bridge_port *p, | ||
| 653 | struct sk_buff *skb, u16 *vid) | ||
| 654 | { | ||
| 655 | return true; | ||
| 656 | } | ||
| 657 | |||
| 651 | static inline struct sk_buff *br_handle_vlan(struct net_bridge *br, | 658 | static inline struct sk_buff *br_handle_vlan(struct net_bridge *br, |
| 652 | const struct net_port_vlans *v, | 659 | const struct net_port_vlans *v, |
| 653 | struct sk_buff *skb) | 660 | struct sk_buff *skb) |
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 4a3716102789..5fee2feaf292 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
| @@ -241,6 +241,34 @@ bool br_allowed_egress(struct net_bridge *br, | |||
| 241 | return false; | 241 | return false; |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | /* Called under RCU */ | ||
| 245 | bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) | ||
| 246 | { | ||
| 247 | struct net_bridge *br = p->br; | ||
| 248 | struct net_port_vlans *v; | ||
| 249 | |||
| 250 | if (!br->vlan_enabled) | ||
| 251 | return true; | ||
| 252 | |||
| 253 | v = rcu_dereference(p->vlan_info); | ||
| 254 | if (!v) | ||
| 255 | return false; | ||
| 256 | |||
| 257 | br_vlan_get_tag(skb, vid); | ||
| 258 | if (!*vid) { | ||
| 259 | *vid = br_get_pvid(v); | ||
| 260 | if (*vid == VLAN_N_VID) | ||
| 261 | return false; | ||
| 262 | |||
| 263 | return true; | ||
| 264 | } | ||
| 265 | |||
| 266 | if (test_bit(*vid, v->vlan_bitmap)) | ||
| 267 | return true; | ||
| 268 | |||
| 269 | return false; | ||
| 270 | } | ||
| 271 | |||
| 244 | /* Must be protected by RTNL. | 272 | /* Must be protected by RTNL. |
| 245 | * Must be called with vid in range from 1 to 4094 inclusive. | 273 | * Must be called with vid in range from 1 to 4094 inclusive. |
| 246 | */ | 274 | */ |
diff --git a/net/core/dev.c b/net/core/dev.c index 9abc503b19b7..fb8b0546485b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2283,8 +2283,8 @@ EXPORT_SYMBOL(skb_checksum_help); | |||
| 2283 | 2283 | ||
| 2284 | __be16 skb_network_protocol(struct sk_buff *skb, int *depth) | 2284 | __be16 skb_network_protocol(struct sk_buff *skb, int *depth) |
| 2285 | { | 2285 | { |
| 2286 | unsigned int vlan_depth = skb->mac_len; | ||
| 2286 | __be16 type = skb->protocol; | 2287 | __be16 type = skb->protocol; |
| 2287 | int vlan_depth = skb->mac_len; | ||
| 2288 | 2288 | ||
| 2289 | /* Tunnel gso handlers can set protocol to ethernet. */ | 2289 | /* Tunnel gso handlers can set protocol to ethernet. */ |
| 2290 | if (type == htons(ETH_P_TEB)) { | 2290 | if (type == htons(ETH_P_TEB)) { |
| @@ -2297,15 +2297,30 @@ __be16 skb_network_protocol(struct sk_buff *skb, int *depth) | |||
| 2297 | type = eth->h_proto; | 2297 | type = eth->h_proto; |
| 2298 | } | 2298 | } |
| 2299 | 2299 | ||
| 2300 | while (type == htons(ETH_P_8021Q) || type == htons(ETH_P_8021AD)) { | 2300 | /* if skb->protocol is 802.1Q/AD then the header should already be |
| 2301 | struct vlan_hdr *vh; | 2301 | * present at mac_len - VLAN_HLEN (if mac_len > 0), or at |
| 2302 | 2302 | * ETH_HLEN otherwise | |
| 2303 | if (unlikely(!pskb_may_pull(skb, vlan_depth + VLAN_HLEN))) | 2303 | */ |
| 2304 | return 0; | 2304 | if (type == htons(ETH_P_8021Q) || type == htons(ETH_P_8021AD)) { |
| 2305 | 2305 | if (vlan_depth) { | |
| 2306 | vh = (struct vlan_hdr *)(skb->data + vlan_depth); | 2306 | if (unlikely(WARN_ON(vlan_depth < VLAN_HLEN))) |
| 2307 | type = vh->h_vlan_encapsulated_proto; | 2307 | return 0; |
| 2308 | vlan_depth += VLAN_HLEN; | 2308 | vlan_depth -= VLAN_HLEN; |
| 2309 | } else { | ||
| 2310 | vlan_depth = ETH_HLEN; | ||
| 2311 | } | ||
| 2312 | do { | ||
| 2313 | struct vlan_hdr *vh; | ||
| 2314 | |||
| 2315 | if (unlikely(!pskb_may_pull(skb, | ||
| 2316 | vlan_depth + VLAN_HLEN))) | ||
| 2317 | return 0; | ||
| 2318 | |||
| 2319 | vh = (struct vlan_hdr *)(skb->data + vlan_depth); | ||
| 2320 | type = vh->h_vlan_encapsulated_proto; | ||
| 2321 | vlan_depth += VLAN_HLEN; | ||
| 2322 | } while (type == htons(ETH_P_8021Q) || | ||
| 2323 | type == htons(ETH_P_8021AD)); | ||
| 2309 | } | 2324 | } |
| 2310 | 2325 | ||
| 2311 | *depth = vlan_depth; | 2326 | *depth = vlan_depth; |
diff --git a/net/core/filter.c b/net/core/filter.c index 9d79ca0a6e8e..4aec7b93f1a9 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -1559,8 +1559,13 @@ static struct sk_filter *__sk_prepare_filter(struct sk_filter *fp, | |||
| 1559 | fp->jited = 0; | 1559 | fp->jited = 0; |
| 1560 | 1560 | ||
| 1561 | err = sk_chk_filter(fp->insns, fp->len); | 1561 | err = sk_chk_filter(fp->insns, fp->len); |
| 1562 | if (err) | 1562 | if (err) { |
| 1563 | if (sk != NULL) | ||
| 1564 | sk_filter_uncharge(sk, fp); | ||
| 1565 | else | ||
| 1566 | kfree(fp); | ||
| 1563 | return ERR_PTR(err); | 1567 | return ERR_PTR(err); |
| 1568 | } | ||
| 1564 | 1569 | ||
| 1565 | /* Probe if we can JIT compile the filter and if so, do | 1570 | /* Probe if we can JIT compile the filter and if so, do |
| 1566 | * the compilation of the filter. | 1571 | * the compilation of the filter. |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index d6b46eb2f94c..3a26b3b23f16 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -2684,13 +2684,12 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack) | |||
| 2684 | bool recovered = !before(tp->snd_una, tp->high_seq); | 2684 | bool recovered = !before(tp->snd_una, tp->high_seq); |
| 2685 | 2685 | ||
| 2686 | if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */ | 2686 | if (tp->frto) { /* F-RTO RFC5682 sec 3.1 (sack enhanced version). */ |
| 2687 | if (flag & FLAG_ORIG_SACK_ACKED) { | 2687 | /* Step 3.b. A timeout is spurious if not all data are |
| 2688 | /* Step 3.b. A timeout is spurious if not all data are | 2688 | * lost, i.e., never-retransmitted data are (s)acked. |
| 2689 | * lost, i.e., never-retransmitted data are (s)acked. | 2689 | */ |
| 2690 | */ | 2690 | if (tcp_try_undo_loss(sk, flag & FLAG_ORIG_SACK_ACKED)) |
| 2691 | tcp_try_undo_loss(sk, true); | ||
| 2692 | return; | 2691 | return; |
| 2693 | } | 2692 | |
| 2694 | if (after(tp->snd_nxt, tp->high_seq) && | 2693 | if (after(tp->snd_nxt, tp->high_seq) && |
| 2695 | (flag & FLAG_DATA_SACKED || is_dupack)) { | 2694 | (flag & FLAG_DATA_SACKED || is_dupack)) { |
| 2696 | tp->frto = 0; /* Loss was real: 2nd part of step 3.a */ | 2695 | tp->frto = 0; /* Loss was real: 2nd part of step 3.a */ |
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c index 6313abd53c9d..56596ce390a1 100644 --- a/net/ipv6/output_core.c +++ b/net/ipv6/output_core.c | |||
| @@ -12,7 +12,7 @@ void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) | |||
| 12 | { | 12 | { |
| 13 | static atomic_t ipv6_fragmentation_id; | 13 | static atomic_t ipv6_fragmentation_id; |
| 14 | struct in6_addr addr; | 14 | struct in6_addr addr; |
| 15 | int old, new; | 15 | int ident; |
| 16 | 16 | ||
| 17 | #if IS_ENABLED(CONFIG_IPV6) | 17 | #if IS_ENABLED(CONFIG_IPV6) |
| 18 | struct inet_peer *peer; | 18 | struct inet_peer *peer; |
| @@ -26,15 +26,10 @@ void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) | |||
| 26 | return; | 26 | return; |
| 27 | } | 27 | } |
| 28 | #endif | 28 | #endif |
| 29 | do { | 29 | ident = atomic_inc_return(&ipv6_fragmentation_id); |
| 30 | old = atomic_read(&ipv6_fragmentation_id); | ||
| 31 | new = old + 1; | ||
| 32 | if (!new) | ||
| 33 | new = 1; | ||
| 34 | } while (atomic_cmpxchg(&ipv6_fragmentation_id, old, new) != old); | ||
| 35 | 30 | ||
| 36 | addr = rt->rt6i_dst.addr; | 31 | addr = rt->rt6i_dst.addr; |
| 37 | addr.s6_addr32[0] ^= (__force __be32)new; | 32 | addr.s6_addr32[0] ^= (__force __be32)ident; |
| 38 | fhdr->identification = htonl(secure_ipv6_id(addr.s6_addr32)); | 33 | fhdr->identification = htonl(secure_ipv6_id(addr.s6_addr32)); |
| 39 | } | 34 | } |
| 40 | EXPORT_SYMBOL(ipv6_select_ident); | 35 | EXPORT_SYMBOL(ipv6_select_ident); |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 4f26ee46b51f..3d2d2c8108ca 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
| @@ -1392,15 +1392,19 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) | |||
| 1392 | 1392 | ||
| 1393 | if (ipip) { | 1393 | if (ipip) { |
| 1394 | __be32 info = ic->un.gateway; | 1394 | __be32 info = ic->un.gateway; |
| 1395 | __u8 type = ic->type; | ||
| 1396 | __u8 code = ic->code; | ||
| 1395 | 1397 | ||
| 1396 | /* Update the MTU */ | 1398 | /* Update the MTU */ |
| 1397 | if (ic->type == ICMP_DEST_UNREACH && | 1399 | if (ic->type == ICMP_DEST_UNREACH && |
| 1398 | ic->code == ICMP_FRAG_NEEDED) { | 1400 | ic->code == ICMP_FRAG_NEEDED) { |
| 1399 | struct ip_vs_dest *dest = cp->dest; | 1401 | struct ip_vs_dest *dest = cp->dest; |
| 1400 | u32 mtu = ntohs(ic->un.frag.mtu); | 1402 | u32 mtu = ntohs(ic->un.frag.mtu); |
| 1403 | __be16 frag_off = cih->frag_off; | ||
| 1401 | 1404 | ||
| 1402 | /* Strip outer IP and ICMP, go to IPIP header */ | 1405 | /* Strip outer IP and ICMP, go to IPIP header */ |
| 1403 | __skb_pull(skb, ihl + sizeof(_icmph)); | 1406 | if (pskb_pull(skb, ihl + sizeof(_icmph)) == NULL) |
| 1407 | goto ignore_ipip; | ||
| 1404 | offset2 -= ihl + sizeof(_icmph); | 1408 | offset2 -= ihl + sizeof(_icmph); |
| 1405 | skb_reset_network_header(skb); | 1409 | skb_reset_network_header(skb); |
| 1406 | IP_VS_DBG(12, "ICMP for IPIP %pI4->%pI4: mtu=%u\n", | 1410 | IP_VS_DBG(12, "ICMP for IPIP %pI4->%pI4: mtu=%u\n", |
| @@ -1408,7 +1412,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) | |||
| 1408 | ipv4_update_pmtu(skb, dev_net(skb->dev), | 1412 | ipv4_update_pmtu(skb, dev_net(skb->dev), |
| 1409 | mtu, 0, 0, 0, 0); | 1413 | mtu, 0, 0, 0, 0); |
| 1410 | /* Client uses PMTUD? */ | 1414 | /* Client uses PMTUD? */ |
| 1411 | if (!(cih->frag_off & htons(IP_DF))) | 1415 | if (!(frag_off & htons(IP_DF))) |
| 1412 | goto ignore_ipip; | 1416 | goto ignore_ipip; |
| 1413 | /* Prefer the resulting PMTU */ | 1417 | /* Prefer the resulting PMTU */ |
| 1414 | if (dest) { | 1418 | if (dest) { |
| @@ -1427,12 +1431,13 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) | |||
| 1427 | /* Strip outer IP, ICMP and IPIP, go to IP header of | 1431 | /* Strip outer IP, ICMP and IPIP, go to IP header of |
| 1428 | * original request. | 1432 | * original request. |
| 1429 | */ | 1433 | */ |
| 1430 | __skb_pull(skb, offset2); | 1434 | if (pskb_pull(skb, offset2) == NULL) |
| 1435 | goto ignore_ipip; | ||
| 1431 | skb_reset_network_header(skb); | 1436 | skb_reset_network_header(skb); |
| 1432 | IP_VS_DBG(12, "Sending ICMP for %pI4->%pI4: t=%u, c=%u, i=%u\n", | 1437 | IP_VS_DBG(12, "Sending ICMP for %pI4->%pI4: t=%u, c=%u, i=%u\n", |
| 1433 | &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, | 1438 | &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, |
| 1434 | ic->type, ic->code, ntohl(info)); | 1439 | type, code, ntohl(info)); |
| 1435 | icmp_send(skb, ic->type, ic->code, info); | 1440 | icmp_send(skb, type, code, info); |
| 1436 | /* ICMP can be shorter but anyways, account it */ | 1441 | /* ICMP can be shorter but anyways, account it */ |
| 1437 | ip_vs_out_stats(cp, skb); | 1442 | ip_vs_out_stats(cp, skb); |
| 1438 | 1443 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 81dca96d2be6..f22757a29cd0 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -1373,7 +1373,9 @@ retry: | |||
| 1373 | bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, | 1373 | bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, |
| 1374 | struct user_namespace *user_ns, int cap) | 1374 | struct user_namespace *user_ns, int cap) |
| 1375 | { | 1375 | { |
| 1376 | return sk_ns_capable(nsp->sk, user_ns, cap); | 1376 | return ((nsp->flags & NETLINK_SKB_DST) || |
| 1377 | file_ns_capable(nsp->sk->sk_socket->file, user_ns, cap)) && | ||
| 1378 | ns_capable(user_ns, cap); | ||
| 1377 | } | 1379 | } |
| 1378 | EXPORT_SYMBOL(__netlink_ns_capable); | 1380 | EXPORT_SYMBOL(__netlink_ns_capable); |
| 1379 | 1381 | ||
| @@ -2293,6 +2295,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2293 | struct sk_buff *skb; | 2295 | struct sk_buff *skb; |
| 2294 | int err; | 2296 | int err; |
| 2295 | struct scm_cookie scm; | 2297 | struct scm_cookie scm; |
| 2298 | u32 netlink_skb_flags = 0; | ||
| 2296 | 2299 | ||
| 2297 | if (msg->msg_flags&MSG_OOB) | 2300 | if (msg->msg_flags&MSG_OOB) |
| 2298 | return -EOPNOTSUPP; | 2301 | return -EOPNOTSUPP; |
| @@ -2314,6 +2317,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2314 | if ((dst_group || dst_portid) && | 2317 | if ((dst_group || dst_portid) && |
| 2315 | !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) | 2318 | !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) |
| 2316 | goto out; | 2319 | goto out; |
| 2320 | netlink_skb_flags |= NETLINK_SKB_DST; | ||
| 2317 | } else { | 2321 | } else { |
| 2318 | dst_portid = nlk->dst_portid; | 2322 | dst_portid = nlk->dst_portid; |
| 2319 | dst_group = nlk->dst_group; | 2323 | dst_group = nlk->dst_group; |
| @@ -2343,6 +2347,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 2343 | NETLINK_CB(skb).portid = nlk->portid; | 2347 | NETLINK_CB(skb).portid = nlk->portid; |
| 2344 | NETLINK_CB(skb).dst_group = dst_group; | 2348 | NETLINK_CB(skb).dst_group = dst_group; |
| 2345 | NETLINK_CB(skb).creds = siocb->scm->creds; | 2349 | NETLINK_CB(skb).creds = siocb->scm->creds; |
| 2350 | NETLINK_CB(skb).flags = netlink_skb_flags; | ||
| 2346 | 2351 | ||
| 2347 | err = -EFAULT; | 2352 | err = -EFAULT; |
| 2348 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 2353 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { |
