diff options
54 files changed, 211 insertions, 164 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 57f52cdce32e..9ba04c0bab8d 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt | |||
| @@ -2387,7 +2387,7 @@ broadcast: Like active-backup, there is not much advantage to this | |||
| 2387 | and packet type ID), so in a "gatewayed" configuration, all | 2387 | and packet type ID), so in a "gatewayed" configuration, all |
| 2388 | outgoing traffic will generally use the same device. Incoming | 2388 | outgoing traffic will generally use the same device. Incoming |
| 2389 | traffic may also end up on a single device, but that is | 2389 | traffic may also end up on a single device, but that is |
| 2390 | dependent upon the balancing policy of the peer's 8023.ad | 2390 | dependent upon the balancing policy of the peer's 802.3ad |
| 2391 | implementation. In a "local" configuration, traffic will be | 2391 | implementation. In a "local" configuration, traffic will be |
| 2392 | distributed across the devices in the bond. | 2392 | distributed across the devices in the bond. |
| 2393 | 2393 | ||
diff --git a/arch/Kconfig b/arch/Kconfig index 1aafb4efbb51..d789a89cb32c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
| @@ -937,9 +937,6 @@ config STRICT_MODULE_RWX | |||
| 937 | and non-text memory will be made non-executable. This provides | 937 | and non-text memory will be made non-executable. This provides |
| 938 | protection against certain security exploits (e.g. writing to text) | 938 | protection against certain security exploits (e.g. writing to text) |
| 939 | 939 | ||
| 940 | config ARCH_WANT_RELAX_ORDER | ||
| 941 | bool | ||
| 942 | |||
| 943 | config ARCH_HAS_REFCOUNT | 940 | config ARCH_HAS_REFCOUNT |
| 944 | bool | 941 | bool |
| 945 | help | 942 | help |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 0be3828752e5..4e83f950713e 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
| @@ -44,7 +44,6 @@ config SPARC | |||
| 44 | select ARCH_HAS_SG_CHAIN | 44 | select ARCH_HAS_SG_CHAIN |
| 45 | select CPU_NO_EFFICIENT_FFS | 45 | select CPU_NO_EFFICIENT_FFS |
| 46 | select LOCKDEP_SMALL if LOCKDEP | 46 | select LOCKDEP_SMALL if LOCKDEP |
| 47 | select ARCH_WANT_RELAX_ORDER | ||
| 48 | 47 | ||
| 49 | config SPARC32 | 48 | config SPARC32 |
| 50 | def_bool !64BIT | 49 | def_bool !64BIT |
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 49b80da51ba7..805ab45e9b5a 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c | |||
| @@ -565,8 +565,10 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, | |||
| 565 | return true; | 565 | return true; |
| 566 | default: | 566 | default: |
| 567 | bpf_warn_invalid_xdp_action(action); | 567 | bpf_warn_invalid_xdp_action(action); |
| 568 | /* fall through */ | ||
| 568 | case XDP_ABORTED: | 569 | case XDP_ABORTED: |
| 569 | trace_xdp_exception(nic->netdev, prog, action); | 570 | trace_xdp_exception(nic->netdev, prog, action); |
| 571 | /* fall through */ | ||
| 570 | case XDP_DROP: | 572 | case XDP_DROP: |
| 571 | /* Check if it's a recycled page, if not | 573 | /* Check if it's a recycled page, if not |
| 572 | * unmap the DMA mapping. | 574 | * unmap the DMA mapping. |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c index 523f9d05a810..8a32eb7d47b9 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c | |||
| @@ -175,31 +175,9 @@ static s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw) | |||
| 175 | **/ | 175 | **/ |
| 176 | static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) | 176 | static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) |
| 177 | { | 177 | { |
| 178 | #ifndef CONFIG_SPARC | ||
| 179 | u32 regval; | ||
| 180 | u32 i; | ||
| 181 | #endif | ||
| 182 | s32 ret_val; | 178 | s32 ret_val; |
| 183 | 179 | ||
| 184 | ret_val = ixgbe_start_hw_generic(hw); | 180 | ret_val = ixgbe_start_hw_generic(hw); |
| 185 | |||
| 186 | #ifndef CONFIG_SPARC | ||
| 187 | /* Disable relaxed ordering */ | ||
| 188 | for (i = 0; ((i < hw->mac.max_tx_queues) && | ||
| 189 | (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { | ||
| 190 | regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i)); | ||
| 191 | regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; | ||
| 192 | IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval); | ||
| 193 | } | ||
| 194 | |||
| 195 | for (i = 0; ((i < hw->mac.max_rx_queues) && | ||
| 196 | (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) { | ||
| 197 | regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); | ||
| 198 | regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN | | ||
| 199 | IXGBE_DCA_RXCTRL_HEAD_WRO_EN); | ||
| 200 | IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); | ||
| 201 | } | ||
| 202 | #endif | ||
| 203 | if (ret_val) | 181 | if (ret_val) |
| 204 | return ret_val; | 182 | return ret_val; |
| 205 | 183 | ||
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index 2c19070d2a0b..6e6ab6f6875e 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | |||
| @@ -366,25 +366,6 @@ s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw) | |||
| 366 | } | 366 | } |
| 367 | IXGBE_WRITE_FLUSH(hw); | 367 | IXGBE_WRITE_FLUSH(hw); |
| 368 | 368 | ||
| 369 | #ifndef CONFIG_ARCH_WANT_RELAX_ORDER | ||
| 370 | /* Disable relaxed ordering */ | ||
| 371 | for (i = 0; i < hw->mac.max_tx_queues; i++) { | ||
| 372 | u32 regval; | ||
| 373 | |||
| 374 | regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i)); | ||
| 375 | regval &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; | ||
| 376 | IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval); | ||
| 377 | } | ||
| 378 | |||
| 379 | for (i = 0; i < hw->mac.max_rx_queues; i++) { | ||
| 380 | u32 regval; | ||
| 381 | |||
| 382 | regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); | ||
| 383 | regval &= ~(IXGBE_DCA_RXCTRL_DATA_WRO_EN | | ||
| 384 | IXGBE_DCA_RXCTRL_HEAD_WRO_EN); | ||
| 385 | IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval); | ||
| 386 | } | ||
| 387 | #endif | ||
| 388 | return 0; | 369 | return 0; |
| 389 | } | 370 | } |
| 390 | 371 | ||
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index 72c565712a5f..c3e7a8191128 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | |||
| @@ -1048,7 +1048,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
| 1048 | { | 1048 | { |
| 1049 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 1049 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
| 1050 | struct ixgbe_ring *temp_ring; | 1050 | struct ixgbe_ring *temp_ring; |
| 1051 | int i, err = 0; | 1051 | int i, j, err = 0; |
| 1052 | u32 new_rx_count, new_tx_count; | 1052 | u32 new_rx_count, new_tx_count; |
| 1053 | 1053 | ||
| 1054 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 1054 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
| @@ -1085,8 +1085,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
| 1085 | } | 1085 | } |
| 1086 | 1086 | ||
| 1087 | /* allocate temporary buffer to store rings in */ | 1087 | /* allocate temporary buffer to store rings in */ |
| 1088 | i = max_t(int, adapter->num_tx_queues, adapter->num_rx_queues); | 1088 | i = max_t(int, adapter->num_tx_queues + adapter->num_xdp_queues, |
| 1089 | i = max_t(int, i, adapter->num_xdp_queues); | 1089 | adapter->num_rx_queues); |
| 1090 | temp_ring = vmalloc(i * sizeof(struct ixgbe_ring)); | 1090 | temp_ring = vmalloc(i * sizeof(struct ixgbe_ring)); |
| 1091 | 1091 | ||
| 1092 | if (!temp_ring) { | 1092 | if (!temp_ring) { |
| @@ -1118,8 +1118,8 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
| 1118 | } | 1118 | } |
| 1119 | } | 1119 | } |
| 1120 | 1120 | ||
| 1121 | for (i = 0; i < adapter->num_xdp_queues; i++) { | 1121 | for (j = 0; j < adapter->num_xdp_queues; j++, i++) { |
| 1122 | memcpy(&temp_ring[i], adapter->xdp_ring[i], | 1122 | memcpy(&temp_ring[i], adapter->xdp_ring[j], |
| 1123 | sizeof(struct ixgbe_ring)); | 1123 | sizeof(struct ixgbe_ring)); |
| 1124 | 1124 | ||
| 1125 | temp_ring[i].count = new_tx_count; | 1125 | temp_ring[i].count = new_tx_count; |
| @@ -1139,10 +1139,10 @@ static int ixgbe_set_ringparam(struct net_device *netdev, | |||
| 1139 | memcpy(adapter->tx_ring[i], &temp_ring[i], | 1139 | memcpy(adapter->tx_ring[i], &temp_ring[i], |
| 1140 | sizeof(struct ixgbe_ring)); | 1140 | sizeof(struct ixgbe_ring)); |
| 1141 | } | 1141 | } |
| 1142 | for (i = 0; i < adapter->num_xdp_queues; i++) { | 1142 | for (j = 0; j < adapter->num_xdp_queues; j++, i++) { |
| 1143 | ixgbe_free_tx_resources(adapter->xdp_ring[i]); | 1143 | ixgbe_free_tx_resources(adapter->xdp_ring[j]); |
| 1144 | 1144 | ||
| 1145 | memcpy(adapter->xdp_ring[i], &temp_ring[i], | 1145 | memcpy(adapter->xdp_ring[j], &temp_ring[i], |
| 1146 | sizeof(struct ixgbe_ring)); | 1146 | sizeof(struct ixgbe_ring)); |
| 1147 | } | 1147 | } |
| 1148 | 1148 | ||
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index d962368d08d0..4d76afd13868 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
| @@ -4881,7 +4881,7 @@ static void ixgbe_clear_udp_tunnel_port(struct ixgbe_adapter *adapter, u32 mask) | |||
| 4881 | IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))) | 4881 | IXGBE_FLAG_GENEVE_OFFLOAD_CAPABLE))) |
| 4882 | return; | 4882 | return; |
| 4883 | 4883 | ||
| 4884 | vxlanctrl = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) && ~mask; | 4884 | vxlanctrl = IXGBE_READ_REG(hw, IXGBE_VXLANCTRL) & ~mask; |
| 4885 | IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, vxlanctrl); | 4885 | IXGBE_WRITE_REG(hw, IXGBE_VXLANCTRL, vxlanctrl); |
| 4886 | 4886 | ||
| 4887 | if (mask & IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK) | 4887 | if (mask & IXGBE_VXLANCTRL_VXLAN_UDPPORT_MASK) |
| @@ -8529,6 +8529,10 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) | |||
| 8529 | return ixgbe_ptp_set_ts_config(adapter, req); | 8529 | return ixgbe_ptp_set_ts_config(adapter, req); |
| 8530 | case SIOCGHWTSTAMP: | 8530 | case SIOCGHWTSTAMP: |
| 8531 | return ixgbe_ptp_get_ts_config(adapter, req); | 8531 | return ixgbe_ptp_get_ts_config(adapter, req); |
| 8532 | case SIOCGMIIPHY: | ||
| 8533 | if (!adapter->hw.phy.ops.read_reg) | ||
| 8534 | return -EOPNOTSUPP; | ||
| 8535 | /* fall through */ | ||
| 8532 | default: | 8536 | default: |
| 8533 | return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); | 8537 | return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); |
| 8534 | } | 8538 | } |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 032089efc1a0..c16718d296d3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | |||
| @@ -3505,20 +3505,6 @@ static int mlxsw_sp_fib_lpm_tree_link(struct mlxsw_sp *mlxsw_sp, | |||
| 3505 | static void mlxsw_sp_fib_lpm_tree_unlink(struct mlxsw_sp *mlxsw_sp, | 3505 | static void mlxsw_sp_fib_lpm_tree_unlink(struct mlxsw_sp *mlxsw_sp, |
| 3506 | struct mlxsw_sp_fib *fib) | 3506 | struct mlxsw_sp_fib *fib) |
| 3507 | { | 3507 | { |
| 3508 | struct mlxsw_sp_prefix_usage req_prefix_usage = {{ 0 } }; | ||
| 3509 | struct mlxsw_sp_lpm_tree *lpm_tree; | ||
| 3510 | |||
| 3511 | /* Aggregate prefix lengths across all virtual routers to make | ||
| 3512 | * sure we only have used prefix lengths in the LPM tree. | ||
| 3513 | */ | ||
| 3514 | mlxsw_sp_vrs_prefixes(mlxsw_sp, fib->proto, &req_prefix_usage); | ||
| 3515 | lpm_tree = mlxsw_sp_lpm_tree_get(mlxsw_sp, &req_prefix_usage, | ||
| 3516 | fib->proto); | ||
| 3517 | if (IS_ERR(lpm_tree)) | ||
| 3518 | goto err_tree_get; | ||
| 3519 | mlxsw_sp_vrs_lpm_tree_replace(mlxsw_sp, fib, lpm_tree); | ||
| 3520 | |||
| 3521 | err_tree_get: | ||
| 3522 | if (!mlxsw_sp_prefix_usage_none(&fib->prefix_usage)) | 3508 | if (!mlxsw_sp_prefix_usage_none(&fib->prefix_usage)) |
| 3523 | return; | 3509 | return; |
| 3524 | mlxsw_sp_vr_lpm_tree_unbind(mlxsw_sp, fib); | 3510 | mlxsw_sp_vr_lpm_tree_unbind(mlxsw_sp, fib); |
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index c3f77e3b7819..e365866600ba 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c | |||
| @@ -1339,7 +1339,17 @@ ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64) | |||
| 1339 | 1339 | ||
| 1340 | static int ppp_dev_init(struct net_device *dev) | 1340 | static int ppp_dev_init(struct net_device *dev) |
| 1341 | { | 1341 | { |
| 1342 | struct ppp *ppp; | ||
| 1343 | |||
| 1342 | netdev_lockdep_set_classes(dev); | 1344 | netdev_lockdep_set_classes(dev); |
| 1345 | |||
| 1346 | ppp = netdev_priv(dev); | ||
| 1347 | /* Let the netdevice take a reference on the ppp file. This ensures | ||
| 1348 | * that ppp_destroy_interface() won't run before the device gets | ||
| 1349 | * unregistered. | ||
| 1350 | */ | ||
| 1351 | atomic_inc(&ppp->file.refcnt); | ||
| 1352 | |||
| 1343 | return 0; | 1353 | return 0; |
| 1344 | } | 1354 | } |
| 1345 | 1355 | ||
| @@ -1362,6 +1372,15 @@ static void ppp_dev_uninit(struct net_device *dev) | |||
| 1362 | wake_up_interruptible(&ppp->file.rwait); | 1372 | wake_up_interruptible(&ppp->file.rwait); |
| 1363 | } | 1373 | } |
| 1364 | 1374 | ||
| 1375 | static void ppp_dev_priv_destructor(struct net_device *dev) | ||
| 1376 | { | ||
| 1377 | struct ppp *ppp; | ||
| 1378 | |||
| 1379 | ppp = netdev_priv(dev); | ||
| 1380 | if (atomic_dec_and_test(&ppp->file.refcnt)) | ||
| 1381 | ppp_destroy_interface(ppp); | ||
| 1382 | } | ||
| 1383 | |||
| 1365 | static const struct net_device_ops ppp_netdev_ops = { | 1384 | static const struct net_device_ops ppp_netdev_ops = { |
| 1366 | .ndo_init = ppp_dev_init, | 1385 | .ndo_init = ppp_dev_init, |
| 1367 | .ndo_uninit = ppp_dev_uninit, | 1386 | .ndo_uninit = ppp_dev_uninit, |
| @@ -1387,6 +1406,7 @@ static void ppp_setup(struct net_device *dev) | |||
| 1387 | dev->tx_queue_len = 3; | 1406 | dev->tx_queue_len = 3; |
| 1388 | dev->type = ARPHRD_PPP; | 1407 | dev->type = ARPHRD_PPP; |
| 1389 | dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; | 1408 | dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; |
| 1409 | dev->priv_destructor = ppp_dev_priv_destructor; | ||
| 1390 | netif_keep_dst(dev); | 1410 | netif_keep_dst(dev); |
| 1391 | } | 1411 | } |
| 1392 | 1412 | ||
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 29c7e2ec0dcb..52ea80bcd639 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
| @@ -560,6 +560,7 @@ static const struct driver_info wwan_info = { | |||
| 560 | #define NVIDIA_VENDOR_ID 0x0955 | 560 | #define NVIDIA_VENDOR_ID 0x0955 |
| 561 | #define HP_VENDOR_ID 0x03f0 | 561 | #define HP_VENDOR_ID 0x03f0 |
| 562 | #define MICROSOFT_VENDOR_ID 0x045e | 562 | #define MICROSOFT_VENDOR_ID 0x045e |
| 563 | #define UBLOX_VENDOR_ID 0x1546 | ||
| 563 | 564 | ||
| 564 | static const struct usb_device_id products[] = { | 565 | static const struct usb_device_id products[] = { |
| 565 | /* BLACKLIST !! | 566 | /* BLACKLIST !! |
| @@ -869,6 +870,18 @@ static const struct usb_device_id products[] = { | |||
| 869 | USB_CDC_PROTO_NONE), | 870 | USB_CDC_PROTO_NONE), |
| 870 | .driver_info = (unsigned long)&zte_cdc_info, | 871 | .driver_info = (unsigned long)&zte_cdc_info, |
| 871 | }, { | 872 | }, { |
| 873 | /* U-blox TOBY-L2 */ | ||
| 874 | USB_DEVICE_AND_INTERFACE_INFO(UBLOX_VENDOR_ID, 0x1143, USB_CLASS_COMM, | ||
| 875 | USB_CDC_SUBCLASS_ETHERNET, | ||
| 876 | USB_CDC_PROTO_NONE), | ||
| 877 | .driver_info = (unsigned long)&wwan_info, | ||
| 878 | }, { | ||
| 879 | /* U-blox SARA-U2 */ | ||
| 880 | USB_DEVICE_AND_INTERFACE_INFO(UBLOX_VENDOR_ID, 0x1104, USB_CLASS_COMM, | ||
| 881 | USB_CDC_SUBCLASS_ETHERNET, | ||
| 882 | USB_CDC_PROTO_NONE), | ||
| 883 | .driver_info = (unsigned long)&wwan_info, | ||
| 884 | }, { | ||
| 872 | USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, | 885 | USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, |
| 873 | USB_CDC_PROTO_NONE), | 886 | USB_CDC_PROTO_NONE), |
| 874 | .driver_info = (unsigned long) &cdc_info, | 887 | .driver_info = (unsigned long) &cdc_info, |
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 8390859e79e7..f1af7d63d678 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
| @@ -368,6 +368,11 @@ static inline void __bpf_prog_uncharge(struct user_struct *user, u32 pages) | |||
| 368 | { | 368 | { |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | static inline int bpf_obj_get_user(const char __user *pathname) | ||
| 372 | { | ||
| 373 | return -EOPNOTSUPP; | ||
| 374 | } | ||
| 375 | |||
| 371 | static inline struct net_device *__dev_map_lookup_elem(struct bpf_map *map, | 376 | static inline struct net_device *__dev_map_lookup_elem(struct bpf_map *map, |
| 372 | u32 key) | 377 | u32 key) |
| 373 | { | 378 | { |
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 2c2a5514b0df..528b24c78308 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h | |||
| @@ -108,9 +108,10 @@ struct ebt_table { | |||
| 108 | 108 | ||
| 109 | #define EBT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) & \ | 109 | #define EBT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) & \ |
| 110 | ~(__alignof__(struct _xt_align)-1)) | 110 | ~(__alignof__(struct _xt_align)-1)) |
| 111 | extern struct ebt_table *ebt_register_table(struct net *net, | 111 | extern int ebt_register_table(struct net *net, |
| 112 | const struct ebt_table *table, | 112 | const struct ebt_table *table, |
| 113 | const struct nf_hook_ops *); | 113 | const struct nf_hook_ops *ops, |
| 114 | struct ebt_table **res); | ||
| 114 | extern void ebt_unregister_table(struct net *net, struct ebt_table *table, | 115 | extern void ebt_unregister_table(struct net *net, struct ebt_table *table, |
| 115 | const struct nf_hook_ops *); | 116 | const struct nf_hook_ops *); |
| 116 | extern unsigned int ebt_do_table(struct sk_buff *skb, | 117 | extern unsigned int ebt_do_table(struct sk_buff *skb, |
diff --git a/include/uapi/linux/netfilter/xt_bpf.h b/include/uapi/linux/netfilter/xt_bpf.h index b97725af2ac0..da161b56c79e 100644 --- a/include/uapi/linux/netfilter/xt_bpf.h +++ b/include/uapi/linux/netfilter/xt_bpf.h | |||
| @@ -23,6 +23,7 @@ enum xt_bpf_modes { | |||
| 23 | XT_BPF_MODE_FD_PINNED, | 23 | XT_BPF_MODE_FD_PINNED, |
| 24 | XT_BPF_MODE_FD_ELF, | 24 | XT_BPF_MODE_FD_ELF, |
| 25 | }; | 25 | }; |
| 26 | #define XT_BPF_MODE_PATH_PINNED XT_BPF_MODE_FD_PINNED | ||
| 26 | 27 | ||
| 27 | struct xt_bpf_info_v1 { | 28 | struct xt_bpf_info_v1 { |
| 28 | __u16 mode; | 29 | __u16 mode; |
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index e833ed914358..be1dde967208 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c | |||
| @@ -363,6 +363,7 @@ out: | |||
| 363 | putname(pname); | 363 | putname(pname); |
| 364 | return ret; | 364 | return ret; |
| 365 | } | 365 | } |
| 366 | EXPORT_SYMBOL_GPL(bpf_obj_get_user); | ||
| 366 | 367 | ||
| 367 | static void bpf_evict_inode(struct inode *inode) | 368 | static void bpf_evict_inode(struct inode *inode) |
| 368 | { | 369 | { |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index b914fbe1383e..8b8d6ba39e23 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
| @@ -653,6 +653,10 @@ static void mark_reg_read(const struct bpf_verifier_state *state, u32 regno) | |||
| 653 | { | 653 | { |
| 654 | struct bpf_verifier_state *parent = state->parent; | 654 | struct bpf_verifier_state *parent = state->parent; |
| 655 | 655 | ||
| 656 | if (regno == BPF_REG_FP) | ||
| 657 | /* We don't need to worry about FP liveness because it's read-only */ | ||
| 658 | return; | ||
| 659 | |||
| 656 | while (parent) { | 660 | while (parent) { |
| 657 | /* if read wasn't screened by an earlier write ... */ | 661 | /* if read wasn't screened by an earlier write ... */ |
| 658 | if (state->regs[regno].live & REG_LIVE_WRITTEN) | 662 | if (state->regs[regno].live & REG_LIVE_WRITTEN) |
| @@ -2345,6 +2349,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) | |||
| 2345 | * copy register state to dest reg | 2349 | * copy register state to dest reg |
| 2346 | */ | 2350 | */ |
| 2347 | regs[insn->dst_reg] = regs[insn->src_reg]; | 2351 | regs[insn->dst_reg] = regs[insn->src_reg]; |
| 2352 | regs[insn->dst_reg].live |= REG_LIVE_WRITTEN; | ||
| 2348 | } else { | 2353 | } else { |
| 2349 | /* R1 = (u32) R2 */ | 2354 | /* R1 = (u32) R2 */ |
| 2350 | if (is_pointer_value(env, insn->src_reg)) { | 2355 | if (is_pointer_value(env, insn->src_reg)) { |
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index 2585b100ebbb..276b60262981 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c | |||
| @@ -65,8 +65,8 @@ static int ebt_broute(struct sk_buff *skb) | |||
| 65 | 65 | ||
| 66 | static int __net_init broute_net_init(struct net *net) | 66 | static int __net_init broute_net_init(struct net *net) |
| 67 | { | 67 | { |
| 68 | net->xt.broute_table = ebt_register_table(net, &broute_table, NULL); | 68 | return ebt_register_table(net, &broute_table, NULL, |
| 69 | return PTR_ERR_OR_ZERO(net->xt.broute_table); | 69 | &net->xt.broute_table); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | static void __net_exit broute_net_exit(struct net *net) | 72 | static void __net_exit broute_net_exit(struct net *net) |
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c index 45a00dbdbcad..c41da5fac84f 100644 --- a/net/bridge/netfilter/ebtable_filter.c +++ b/net/bridge/netfilter/ebtable_filter.c | |||
| @@ -93,8 +93,8 @@ static const struct nf_hook_ops ebt_ops_filter[] = { | |||
| 93 | 93 | ||
| 94 | static int __net_init frame_filter_net_init(struct net *net) | 94 | static int __net_init frame_filter_net_init(struct net *net) |
| 95 | { | 95 | { |
| 96 | net->xt.frame_filter = ebt_register_table(net, &frame_filter, ebt_ops_filter); | 96 | return ebt_register_table(net, &frame_filter, ebt_ops_filter, |
| 97 | return PTR_ERR_OR_ZERO(net->xt.frame_filter); | 97 | &net->xt.frame_filter); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static void __net_exit frame_filter_net_exit(struct net *net) | 100 | static void __net_exit frame_filter_net_exit(struct net *net) |
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c index 57cd5bb154e7..08df7406ecb3 100644 --- a/net/bridge/netfilter/ebtable_nat.c +++ b/net/bridge/netfilter/ebtable_nat.c | |||
| @@ -93,8 +93,8 @@ static const struct nf_hook_ops ebt_ops_nat[] = { | |||
| 93 | 93 | ||
| 94 | static int __net_init frame_nat_net_init(struct net *net) | 94 | static int __net_init frame_nat_net_init(struct net *net) |
| 95 | { | 95 | { |
| 96 | net->xt.frame_nat = ebt_register_table(net, &frame_nat, ebt_ops_nat); | 96 | return ebt_register_table(net, &frame_nat, ebt_ops_nat, |
| 97 | return PTR_ERR_OR_ZERO(net->xt.frame_nat); | 97 | &net->xt.frame_nat); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static void __net_exit frame_nat_net_exit(struct net *net) | 100 | static void __net_exit frame_nat_net_exit(struct net *net) |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 83951f978445..3b3dcf719e07 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
| @@ -1169,9 +1169,8 @@ static void __ebt_unregister_table(struct net *net, struct ebt_table *table) | |||
| 1169 | kfree(table); | 1169 | kfree(table); |
| 1170 | } | 1170 | } |
| 1171 | 1171 | ||
| 1172 | struct ebt_table * | 1172 | int ebt_register_table(struct net *net, const struct ebt_table *input_table, |
| 1173 | ebt_register_table(struct net *net, const struct ebt_table *input_table, | 1173 | const struct nf_hook_ops *ops, struct ebt_table **res) |
| 1174 | const struct nf_hook_ops *ops) | ||
| 1175 | { | 1174 | { |
| 1176 | struct ebt_table_info *newinfo; | 1175 | struct ebt_table_info *newinfo; |
| 1177 | struct ebt_table *t, *table; | 1176 | struct ebt_table *t, *table; |
| @@ -1183,7 +1182,7 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table, | |||
| 1183 | repl->entries == NULL || repl->entries_size == 0 || | 1182 | repl->entries == NULL || repl->entries_size == 0 || |
| 1184 | repl->counters != NULL || input_table->private != NULL) { | 1183 | repl->counters != NULL || input_table->private != NULL) { |
| 1185 | BUGPRINT("Bad table data for ebt_register_table!!!\n"); | 1184 | BUGPRINT("Bad table data for ebt_register_table!!!\n"); |
| 1186 | return ERR_PTR(-EINVAL); | 1185 | return -EINVAL; |
| 1187 | } | 1186 | } |
| 1188 | 1187 | ||
| 1189 | /* Don't add one table to multiple lists. */ | 1188 | /* Don't add one table to multiple lists. */ |
| @@ -1252,16 +1251,18 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table, | |||
| 1252 | list_add(&table->list, &net->xt.tables[NFPROTO_BRIDGE]); | 1251 | list_add(&table->list, &net->xt.tables[NFPROTO_BRIDGE]); |
| 1253 | mutex_unlock(&ebt_mutex); | 1252 | mutex_unlock(&ebt_mutex); |
| 1254 | 1253 | ||
| 1254 | WRITE_ONCE(*res, table); | ||
| 1255 | |||
| 1255 | if (!ops) | 1256 | if (!ops) |
| 1256 | return table; | 1257 | return 0; |
| 1257 | 1258 | ||
| 1258 | ret = nf_register_net_hooks(net, ops, hweight32(table->valid_hooks)); | 1259 | ret = nf_register_net_hooks(net, ops, hweight32(table->valid_hooks)); |
| 1259 | if (ret) { | 1260 | if (ret) { |
| 1260 | __ebt_unregister_table(net, table); | 1261 | __ebt_unregister_table(net, table); |
| 1261 | return ERR_PTR(ret); | 1262 | *res = NULL; |
| 1262 | } | 1263 | } |
| 1263 | 1264 | ||
| 1264 | return table; | 1265 | return ret; |
| 1265 | free_unlock: | 1266 | free_unlock: |
| 1266 | mutex_unlock(&ebt_mutex); | 1267 | mutex_unlock(&ebt_mutex); |
| 1267 | free_chainstack: | 1268 | free_chainstack: |
| @@ -1276,7 +1277,7 @@ free_newinfo: | |||
| 1276 | free_table: | 1277 | free_table: |
| 1277 | kfree(table); | 1278 | kfree(table); |
| 1278 | out: | 1279 | out: |
| 1279 | return ERR_PTR(ret); | 1280 | return ret; |
| 1280 | } | 1281 | } |
| 1281 | 1282 | ||
| 1282 | void ebt_unregister_table(struct net *net, struct ebt_table *table, | 1283 | void ebt_unregister_table(struct net *net, struct ebt_table *table, |
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index 416bb304a281..1859c473b21a 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c | |||
| @@ -86,7 +86,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb, | |||
| 86 | greh = (struct gre_base_hdr *)skb_transport_header(skb); | 86 | greh = (struct gre_base_hdr *)skb_transport_header(skb); |
| 87 | pcsum = (__sum16 *)(greh + 1); | 87 | pcsum = (__sum16 *)(greh + 1); |
| 88 | 88 | ||
| 89 | if (gso_partial) { | 89 | if (gso_partial && skb_is_gso(skb)) { |
| 90 | unsigned int partial_adj; | 90 | unsigned int partial_adj; |
| 91 | 91 | ||
| 92 | /* Adjust checksum to account for the fact that | 92 | /* Adjust checksum to account for the fact that |
diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 811689e523c3..f75fc6b53115 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c | |||
| @@ -330,7 +330,8 @@ static unsigned int ipv4_synproxy_hook(void *priv, | |||
| 330 | if (synproxy == NULL) | 330 | if (synproxy == NULL) |
| 331 | return NF_ACCEPT; | 331 | return NF_ACCEPT; |
| 332 | 332 | ||
| 333 | if (nf_is_loopback_packet(skb)) | 333 | if (nf_is_loopback_packet(skb) || |
| 334 | ip_hdr(skb)->protocol != IPPROTO_TCP) | ||
| 334 | return NF_ACCEPT; | 335 | return NF_ACCEPT; |
| 335 | 336 | ||
| 336 | thoff = ip_hdrlen(skb); | 337 | thoff = ip_hdrlen(skb); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ac6fde5d45f1..3d9f1c2f81c5 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -2513,7 +2513,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
| 2513 | struct rtable *ort = (struct rtable *) dst_orig; | 2513 | struct rtable *ort = (struct rtable *) dst_orig; |
| 2514 | struct rtable *rt; | 2514 | struct rtable *rt; |
| 2515 | 2515 | ||
| 2516 | rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, DST_OBSOLETE_NONE, 0); | 2516 | rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, DST_OBSOLETE_DEAD, 0); |
| 2517 | if (rt) { | 2517 | if (rt) { |
| 2518 | struct dst_entry *new = &rt->dst; | 2518 | struct dst_entry *new = &rt->dst; |
| 2519 | 2519 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5676237d2b0f..e45177ceb0ee 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -2240,20 +2240,16 @@ int udp_v4_early_demux(struct sk_buff *skb) | |||
| 2240 | iph = ip_hdr(skb); | 2240 | iph = ip_hdr(skb); |
| 2241 | uh = udp_hdr(skb); | 2241 | uh = udp_hdr(skb); |
| 2242 | 2242 | ||
| 2243 | if (skb->pkt_type == PACKET_BROADCAST || | 2243 | if (skb->pkt_type == PACKET_MULTICAST) { |
| 2244 | skb->pkt_type == PACKET_MULTICAST) { | ||
| 2245 | in_dev = __in_dev_get_rcu(skb->dev); | 2244 | in_dev = __in_dev_get_rcu(skb->dev); |
| 2246 | 2245 | ||
| 2247 | if (!in_dev) | 2246 | if (!in_dev) |
| 2248 | return 0; | 2247 | return 0; |
| 2249 | 2248 | ||
| 2250 | /* we are supposed to accept bcast packets */ | 2249 | ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr, |
| 2251 | if (skb->pkt_type == PACKET_MULTICAST) { | 2250 | iph->protocol); |
| 2252 | ours = ip_check_mc_rcu(in_dev, iph->daddr, iph->saddr, | 2251 | if (!ours) |
| 2253 | iph->protocol); | 2252 | return 0; |
| 2254 | if (!ours) | ||
| 2255 | return 0; | ||
| 2256 | } | ||
| 2257 | 2253 | ||
| 2258 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, | 2254 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, |
| 2259 | uh->source, iph->saddr, | 2255 | uh->source, iph->saddr, |
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 97658bfc1b58..e360d55be555 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c | |||
| @@ -120,7 +120,7 @@ static struct sk_buff *__skb_udp_tunnel_segment(struct sk_buff *skb, | |||
| 120 | * will be using a length value equal to only one MSS sized | 120 | * will be using a length value equal to only one MSS sized |
| 121 | * segment instead of the entire frame. | 121 | * segment instead of the entire frame. |
| 122 | */ | 122 | */ |
| 123 | if (gso_partial) { | 123 | if (gso_partial && skb_is_gso(skb)) { |
| 124 | uh->len = htons(skb_shinfo(skb)->gso_size + | 124 | uh->len = htons(skb_shinfo(skb)->gso_size + |
| 125 | SKB_GSO_CB(skb)->data_offset + | 125 | SKB_GSO_CB(skb)->data_offset + |
| 126 | skb->head - (unsigned char *)uh); | 126 | skb->head - (unsigned char *)uh); |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 96861c702c06..4a96ebbf8eda 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -3820,8 +3820,8 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) | |||
| 3820 | goto out; | 3820 | goto out; |
| 3821 | 3821 | ||
| 3822 | if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || | 3822 | if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || |
| 3823 | dev_net(dev)->ipv6.devconf_all->accept_dad < 1 || | 3823 | (dev_net(dev)->ipv6.devconf_all->accept_dad < 1 && |
| 3824 | idev->cnf.accept_dad < 1 || | 3824 | idev->cnf.accept_dad < 1) || |
| 3825 | !(ifp->flags&IFA_F_TENTATIVE) || | 3825 | !(ifp->flags&IFA_F_TENTATIVE) || |
| 3826 | ifp->flags & IFA_F_NODAD) { | 3826 | ifp->flags & IFA_F_NODAD) { |
| 3827 | bump_id = ifp->flags & IFA_F_TENTATIVE; | 3827 | bump_id = ifp->flags & IFA_F_TENTATIVE; |
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index cdb3728faca7..4a87f9428ca5 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
| @@ -105,7 +105,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
| 105 | 105 | ||
| 106 | for (skb = segs; skb; skb = skb->next) { | 106 | for (skb = segs; skb; skb = skb->next) { |
| 107 | ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff); | 107 | ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff); |
| 108 | if (gso_partial) | 108 | if (gso_partial && skb_is_gso(skb)) |
| 109 | payload_len = skb_shinfo(skb)->gso_size + | 109 | payload_len = skb_shinfo(skb)->gso_size + |
| 110 | SKB_GSO_CB(skb)->data_offset + | 110 | SKB_GSO_CB(skb)->data_offset + |
| 111 | skb->head - (unsigned char *)(ipv6h + 1); | 111 | skb->head - (unsigned char *)(ipv6h + 1); |
diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c index a5cd43d75393..437af8c95277 100644 --- a/net/ipv6/netfilter/ip6t_SYNPROXY.c +++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c | |||
| @@ -353,7 +353,7 @@ static unsigned int ipv6_synproxy_hook(void *priv, | |||
| 353 | nexthdr = ipv6_hdr(skb)->nexthdr; | 353 | nexthdr = ipv6_hdr(skb)->nexthdr; |
| 354 | thoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, | 354 | thoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, |
| 355 | &frag_off); | 355 | &frag_off); |
| 356 | if (thoff < 0) | 356 | if (thoff < 0 || nexthdr != IPPROTO_TCP) |
| 357 | return NF_ACCEPT; | 357 | return NF_ACCEPT; |
| 358 | 358 | ||
| 359 | th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); | 359 | th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 26cc9f483b6d..a96d5b385d8f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -1325,7 +1325,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori | |||
| 1325 | struct dst_entry *new = NULL; | 1325 | struct dst_entry *new = NULL; |
| 1326 | 1326 | ||
| 1327 | rt = dst_alloc(&ip6_dst_blackhole_ops, loopback_dev, 1, | 1327 | rt = dst_alloc(&ip6_dst_blackhole_ops, loopback_dev, 1, |
| 1328 | DST_OBSOLETE_NONE, 0); | 1328 | DST_OBSOLETE_DEAD, 0); |
| 1329 | if (rt) { | 1329 | if (rt) { |
| 1330 | rt6_info_init(rt); | 1330 | rt6_info_init(rt); |
| 1331 | 1331 | ||
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index e495b5e484b1..cf84f7b37cd9 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
| @@ -1191,14 +1191,17 @@ static int ip_set_swap(struct net *net, struct sock *ctnl, struct sk_buff *skb, | |||
| 1191 | from->family == to->family)) | 1191 | from->family == to->family)) |
| 1192 | return -IPSET_ERR_TYPE_MISMATCH; | 1192 | return -IPSET_ERR_TYPE_MISMATCH; |
| 1193 | 1193 | ||
| 1194 | if (from->ref_netlink || to->ref_netlink) | 1194 | write_lock_bh(&ip_set_ref_lock); |
| 1195 | |||
| 1196 | if (from->ref_netlink || to->ref_netlink) { | ||
| 1197 | write_unlock_bh(&ip_set_ref_lock); | ||
| 1195 | return -EBUSY; | 1198 | return -EBUSY; |
| 1199 | } | ||
| 1196 | 1200 | ||
| 1197 | strncpy(from_name, from->name, IPSET_MAXNAMELEN); | 1201 | strncpy(from_name, from->name, IPSET_MAXNAMELEN); |
| 1198 | strncpy(from->name, to->name, IPSET_MAXNAMELEN); | 1202 | strncpy(from->name, to->name, IPSET_MAXNAMELEN); |
| 1199 | strncpy(to->name, from_name, IPSET_MAXNAMELEN); | 1203 | strncpy(to->name, from_name, IPSET_MAXNAMELEN); |
| 1200 | 1204 | ||
| 1201 | write_lock_bh(&ip_set_ref_lock); | ||
| 1202 | swap(from->ref, to->ref); | 1205 | swap(from->ref, to->ref); |
| 1203 | ip_set(inst, from_id) = to; | 1206 | ip_set(inst, from_id) = to; |
| 1204 | ip_set(inst, to_id) = from; | 1207 | ip_set(inst, to_id) = from; |
| @@ -2072,25 +2075,28 @@ static struct pernet_operations ip_set_net_ops = { | |||
| 2072 | static int __init | 2075 | static int __init |
| 2073 | ip_set_init(void) | 2076 | ip_set_init(void) |
| 2074 | { | 2077 | { |
| 2075 | int ret = nfnetlink_subsys_register(&ip_set_netlink_subsys); | 2078 | int ret = register_pernet_subsys(&ip_set_net_ops); |
| 2079 | |||
| 2080 | if (ret) { | ||
| 2081 | pr_err("ip_set: cannot register pernet_subsys.\n"); | ||
| 2082 | return ret; | ||
| 2083 | } | ||
| 2076 | 2084 | ||
| 2085 | ret = nfnetlink_subsys_register(&ip_set_netlink_subsys); | ||
| 2077 | if (ret != 0) { | 2086 | if (ret != 0) { |
| 2078 | pr_err("ip_set: cannot register with nfnetlink.\n"); | 2087 | pr_err("ip_set: cannot register with nfnetlink.\n"); |
| 2088 | unregister_pernet_subsys(&ip_set_net_ops); | ||
| 2079 | return ret; | 2089 | return ret; |
| 2080 | } | 2090 | } |
| 2091 | |||
| 2081 | ret = nf_register_sockopt(&so_set); | 2092 | ret = nf_register_sockopt(&so_set); |
| 2082 | if (ret != 0) { | 2093 | if (ret != 0) { |
| 2083 | pr_err("SO_SET registry failed: %d\n", ret); | 2094 | pr_err("SO_SET registry failed: %d\n", ret); |
| 2084 | nfnetlink_subsys_unregister(&ip_set_netlink_subsys); | 2095 | nfnetlink_subsys_unregister(&ip_set_netlink_subsys); |
| 2096 | unregister_pernet_subsys(&ip_set_net_ops); | ||
| 2085 | return ret; | 2097 | return ret; |
| 2086 | } | 2098 | } |
| 2087 | ret = register_pernet_subsys(&ip_set_net_ops); | 2099 | |
| 2088 | if (ret) { | ||
| 2089 | pr_err("ip_set: cannot register pernet_subsys.\n"); | ||
| 2090 | nf_unregister_sockopt(&so_set); | ||
| 2091 | nfnetlink_subsys_unregister(&ip_set_netlink_subsys); | ||
| 2092 | return ret; | ||
| 2093 | } | ||
| 2094 | pr_info("ip_set: protocol %u\n", IPSET_PROTOCOL); | 2100 | pr_info("ip_set: protocol %u\n", IPSET_PROTOCOL); |
| 2095 | return 0; | 2101 | return 0; |
| 2096 | } | 2102 | } |
| @@ -2098,9 +2104,10 @@ ip_set_init(void) | |||
| 2098 | static void __exit | 2104 | static void __exit |
| 2099 | ip_set_fini(void) | 2105 | ip_set_fini(void) |
| 2100 | { | 2106 | { |
| 2101 | unregister_pernet_subsys(&ip_set_net_ops); | ||
| 2102 | nf_unregister_sockopt(&so_set); | 2107 | nf_unregister_sockopt(&so_set); |
| 2103 | nfnetlink_subsys_unregister(&ip_set_netlink_subsys); | 2108 | nfnetlink_subsys_unregister(&ip_set_netlink_subsys); |
| 2109 | |||
| 2110 | unregister_pernet_subsys(&ip_set_net_ops); | ||
| 2104 | pr_debug("these are the famous last words\n"); | 2111 | pr_debug("these are the famous last words\n"); |
| 2105 | } | 2112 | } |
| 2106 | 2113 | ||
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c index 20bfbd315f61..613eb212cb48 100644 --- a/net/netfilter/ipset/ip_set_hash_ip.c +++ b/net/netfilter/ipset/ip_set_hash_ip.c | |||
| @@ -123,13 +123,12 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 123 | return ret; | 123 | return ret; |
| 124 | 124 | ||
| 125 | ip &= ip_set_hostmask(h->netmask); | 125 | ip &= ip_set_hostmask(h->netmask); |
| 126 | e.ip = htonl(ip); | ||
| 127 | if (e.ip == 0) | ||
| 128 | return -IPSET_ERR_HASH_ELEM; | ||
| 126 | 129 | ||
| 127 | if (adt == IPSET_TEST) { | 130 | if (adt == IPSET_TEST) |
| 128 | e.ip = htonl(ip); | ||
| 129 | if (e.ip == 0) | ||
| 130 | return -IPSET_ERR_HASH_ELEM; | ||
| 131 | return adtfn(set, &e, &ext, &ext, flags); | 131 | return adtfn(set, &e, &ext, &ext, flags); |
| 132 | } | ||
| 133 | 132 | ||
| 134 | ip_to = ip; | 133 | ip_to = ip; |
| 135 | if (tb[IPSET_ATTR_IP_TO]) { | 134 | if (tb[IPSET_ATTR_IP_TO]) { |
| @@ -148,17 +147,20 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 148 | 147 | ||
| 149 | hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); | 148 | hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1); |
| 150 | 149 | ||
| 151 | if (retried) | 150 | if (retried) { |
| 152 | ip = ntohl(h->next.ip); | 151 | ip = ntohl(h->next.ip); |
| 153 | for (; !before(ip_to, ip); ip += hosts) { | ||
| 154 | e.ip = htonl(ip); | 152 | e.ip = htonl(ip); |
| 155 | if (e.ip == 0) | 153 | } |
| 156 | return -IPSET_ERR_HASH_ELEM; | 154 | for (; ip <= ip_to;) { |
| 157 | ret = adtfn(set, &e, &ext, &ext, flags); | 155 | ret = adtfn(set, &e, &ext, &ext, flags); |
| 158 | |||
| 159 | if (ret && !ip_set_eexist(ret, flags)) | 156 | if (ret && !ip_set_eexist(ret, flags)) |
| 160 | return ret; | 157 | return ret; |
| 161 | 158 | ||
| 159 | ip += hosts; | ||
| 160 | e.ip = htonl(ip); | ||
| 161 | if (e.ip == 0) | ||
| 162 | return 0; | ||
| 163 | |||
| 162 | ret = 0; | 164 | ret = 0; |
| 163 | } | 165 | } |
| 164 | return ret; | 166 | return ret; |
diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c index b64cf14e8352..f3ba8348cf9d 100644 --- a/net/netfilter/ipset/ip_set_hash_ipmark.c +++ b/net/netfilter/ipset/ip_set_hash_ipmark.c | |||
| @@ -149,7 +149,7 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 149 | 149 | ||
| 150 | if (retried) | 150 | if (retried) |
| 151 | ip = ntohl(h->next.ip); | 151 | ip = ntohl(h->next.ip); |
| 152 | for (; !before(ip_to, ip); ip++) { | 152 | for (; ip <= ip_to; ip++) { |
| 153 | e.ip = htonl(ip); | 153 | e.ip = htonl(ip); |
| 154 | ret = adtfn(set, &e, &ext, &ext, flags); | 154 | ret = adtfn(set, &e, &ext, &ext, flags); |
| 155 | 155 | ||
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c index f438740e6c6a..ddb8039ec1d2 100644 --- a/net/netfilter/ipset/ip_set_hash_ipport.c +++ b/net/netfilter/ipset/ip_set_hash_ipport.c | |||
| @@ -178,7 +178,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 178 | 178 | ||
| 179 | if (retried) | 179 | if (retried) |
| 180 | ip = ntohl(h->next.ip); | 180 | ip = ntohl(h->next.ip); |
| 181 | for (; !before(ip_to, ip); ip++) { | 181 | for (; ip <= ip_to; ip++) { |
| 182 | p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) | 182 | p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) |
| 183 | : port; | 183 | : port; |
| 184 | for (; p <= port_to; p++) { | 184 | for (; p <= port_to; p++) { |
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c index 6215fb898c50..a7f4d7a85420 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportip.c +++ b/net/netfilter/ipset/ip_set_hash_ipportip.c | |||
| @@ -185,7 +185,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 185 | 185 | ||
| 186 | if (retried) | 186 | if (retried) |
| 187 | ip = ntohl(h->next.ip); | 187 | ip = ntohl(h->next.ip); |
| 188 | for (; !before(ip_to, ip); ip++) { | 188 | for (; ip <= ip_to; ip++) { |
| 189 | p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) | 189 | p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) |
| 190 | : port; | 190 | : port; |
| 191 | for (; p <= port_to; p++) { | 191 | for (; p <= port_to; p++) { |
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index 5ab1b99a53c2..a2f19b9906e9 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c | |||
| @@ -271,7 +271,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 271 | 271 | ||
| 272 | if (retried) | 272 | if (retried) |
| 273 | ip = ntohl(h->next.ip); | 273 | ip = ntohl(h->next.ip); |
| 274 | for (; !before(ip_to, ip); ip++) { | 274 | for (; ip <= ip_to; ip++) { |
| 275 | e.ip = htonl(ip); | 275 | e.ip = htonl(ip); |
| 276 | p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) | 276 | p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) |
| 277 | : port; | 277 | : port; |
| @@ -281,7 +281,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 281 | ip == ntohl(h->next.ip) && | 281 | ip == ntohl(h->next.ip) && |
| 282 | p == ntohs(h->next.port) | 282 | p == ntohs(h->next.port) |
| 283 | ? ntohl(h->next.ip2) : ip2_from; | 283 | ? ntohl(h->next.ip2) : ip2_from; |
| 284 | while (!after(ip2, ip2_to)) { | 284 | while (ip2 <= ip2_to) { |
| 285 | e.ip2 = htonl(ip2); | 285 | e.ip2 = htonl(ip2); |
| 286 | ip2_last = ip_set_range_to_cidr(ip2, ip2_to, | 286 | ip2_last = ip_set_range_to_cidr(ip2, ip2_to, |
| 287 | &cidr); | 287 | &cidr); |
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index 5d9e895452e7..1c67a1761e45 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c | |||
| @@ -193,7 +193,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 193 | } | 193 | } |
| 194 | if (retried) | 194 | if (retried) |
| 195 | ip = ntohl(h->next.ip); | 195 | ip = ntohl(h->next.ip); |
| 196 | while (!after(ip, ip_to)) { | 196 | while (ip <= ip_to) { |
| 197 | e.ip = htonl(ip); | 197 | e.ip = htonl(ip); |
| 198 | last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); | 198 | last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); |
| 199 | ret = adtfn(set, &e, &ext, &ext, flags); | 199 | ret = adtfn(set, &e, &ext, &ext, flags); |
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index 44cf11939c91..d417074f1c1a 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c | |||
| @@ -255,7 +255,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 255 | 255 | ||
| 256 | if (retried) | 256 | if (retried) |
| 257 | ip = ntohl(h->next.ip); | 257 | ip = ntohl(h->next.ip); |
| 258 | while (!after(ip, ip_to)) { | 258 | while (ip <= ip_to) { |
| 259 | e.ip = htonl(ip); | 259 | e.ip = htonl(ip); |
| 260 | last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); | 260 | last = ip_set_range_to_cidr(ip, ip_to, &e.cidr); |
| 261 | ret = adtfn(set, &e, &ext, &ext, flags); | 261 | ret = adtfn(set, &e, &ext, &ext, flags); |
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c index db614e13b193..7f9ae2e9645b 100644 --- a/net/netfilter/ipset/ip_set_hash_netnet.c +++ b/net/netfilter/ipset/ip_set_hash_netnet.c | |||
| @@ -250,13 +250,13 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 250 | if (retried) | 250 | if (retried) |
| 251 | ip = ntohl(h->next.ip[0]); | 251 | ip = ntohl(h->next.ip[0]); |
| 252 | 252 | ||
| 253 | while (!after(ip, ip_to)) { | 253 | while (ip <= ip_to) { |
| 254 | e.ip[0] = htonl(ip); | 254 | e.ip[0] = htonl(ip); |
| 255 | last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); | 255 | last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); |
| 256 | ip2 = (retried && | 256 | ip2 = (retried && |
| 257 | ip == ntohl(h->next.ip[0])) ? ntohl(h->next.ip[1]) | 257 | ip == ntohl(h->next.ip[0])) ? ntohl(h->next.ip[1]) |
| 258 | : ip2_from; | 258 | : ip2_from; |
| 259 | while (!after(ip2, ip2_to)) { | 259 | while (ip2 <= ip2_to) { |
| 260 | e.ip[1] = htonl(ip2); | 260 | e.ip[1] = htonl(ip2); |
| 261 | last2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]); | 261 | last2 = ip_set_range_to_cidr(ip2, ip2_to, &e.cidr[1]); |
| 262 | ret = adtfn(set, &e, &ext, &ext, flags); | 262 | ret = adtfn(set, &e, &ext, &ext, flags); |
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index 54b64b6cd0cd..e6ef382febe4 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c | |||
| @@ -241,7 +241,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 241 | 241 | ||
| 242 | if (retried) | 242 | if (retried) |
| 243 | ip = ntohl(h->next.ip); | 243 | ip = ntohl(h->next.ip); |
| 244 | while (!after(ip, ip_to)) { | 244 | while (ip <= ip_to) { |
| 245 | e.ip = htonl(ip); | 245 | e.ip = htonl(ip); |
| 246 | last = ip_set_range_to_cidr(ip, ip_to, &cidr); | 246 | last = ip_set_range_to_cidr(ip, ip_to, &cidr); |
| 247 | e.cidr = cidr - 1; | 247 | e.cidr = cidr - 1; |
diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c index aff846960ac4..8602f2595a1a 100644 --- a/net/netfilter/ipset/ip_set_hash_netportnet.c +++ b/net/netfilter/ipset/ip_set_hash_netportnet.c | |||
| @@ -291,7 +291,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 291 | if (retried) | 291 | if (retried) |
| 292 | ip = ntohl(h->next.ip[0]); | 292 | ip = ntohl(h->next.ip[0]); |
| 293 | 293 | ||
| 294 | while (!after(ip, ip_to)) { | 294 | while (ip <= ip_to) { |
| 295 | e.ip[0] = htonl(ip); | 295 | e.ip[0] = htonl(ip); |
| 296 | ip_last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); | 296 | ip_last = ip_set_range_to_cidr(ip, ip_to, &e.cidr[0]); |
| 297 | p = retried && ip == ntohl(h->next.ip[0]) ? ntohs(h->next.port) | 297 | p = retried && ip == ntohl(h->next.ip[0]) ? ntohs(h->next.port) |
| @@ -301,7 +301,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 301 | ip2 = (retried && ip == ntohl(h->next.ip[0]) && | 301 | ip2 = (retried && ip == ntohl(h->next.ip[0]) && |
| 302 | p == ntohs(h->next.port)) ? ntohl(h->next.ip[1]) | 302 | p == ntohs(h->next.port)) ? ntohl(h->next.ip[1]) |
| 303 | : ip2_from; | 303 | : ip2_from; |
| 304 | while (!after(ip2, ip2_to)) { | 304 | while (ip2 <= ip2_to) { |
| 305 | e.ip[1] = htonl(ip2); | 305 | e.ip[1] = htonl(ip2); |
| 306 | ip2_last = ip_set_range_to_cidr(ip2, ip2_to, | 306 | ip2_last = ip_set_range_to_cidr(ip2, ip2_to, |
| 307 | &e.cidr[1]); | 307 | &e.cidr[1]); |
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 90d396814798..4527921b1c3a 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
| @@ -921,6 +921,7 @@ ip_vs_prepare_tunneled_skb(struct sk_buff *skb, int skb_af, | |||
| 921 | { | 921 | { |
| 922 | struct sk_buff *new_skb = NULL; | 922 | struct sk_buff *new_skb = NULL; |
| 923 | struct iphdr *old_iph = NULL; | 923 | struct iphdr *old_iph = NULL; |
| 924 | __u8 old_dsfield; | ||
| 924 | #ifdef CONFIG_IP_VS_IPV6 | 925 | #ifdef CONFIG_IP_VS_IPV6 |
| 925 | struct ipv6hdr *old_ipv6h = NULL; | 926 | struct ipv6hdr *old_ipv6h = NULL; |
| 926 | #endif | 927 | #endif |
| @@ -945,7 +946,7 @@ ip_vs_prepare_tunneled_skb(struct sk_buff *skb, int skb_af, | |||
| 945 | *payload_len = | 946 | *payload_len = |
| 946 | ntohs(old_ipv6h->payload_len) + | 947 | ntohs(old_ipv6h->payload_len) + |
| 947 | sizeof(*old_ipv6h); | 948 | sizeof(*old_ipv6h); |
| 948 | *dsfield = ipv6_get_dsfield(old_ipv6h); | 949 | old_dsfield = ipv6_get_dsfield(old_ipv6h); |
| 949 | *ttl = old_ipv6h->hop_limit; | 950 | *ttl = old_ipv6h->hop_limit; |
| 950 | if (df) | 951 | if (df) |
| 951 | *df = 0; | 952 | *df = 0; |
| @@ -960,12 +961,15 @@ ip_vs_prepare_tunneled_skb(struct sk_buff *skb, int skb_af, | |||
| 960 | 961 | ||
| 961 | /* fix old IP header checksum */ | 962 | /* fix old IP header checksum */ |
| 962 | ip_send_check(old_iph); | 963 | ip_send_check(old_iph); |
| 963 | *dsfield = ipv4_get_dsfield(old_iph); | 964 | old_dsfield = ipv4_get_dsfield(old_iph); |
| 964 | *ttl = old_iph->ttl; | 965 | *ttl = old_iph->ttl; |
| 965 | if (payload_len) | 966 | if (payload_len) |
| 966 | *payload_len = ntohs(old_iph->tot_len); | 967 | *payload_len = ntohs(old_iph->tot_len); |
| 967 | } | 968 | } |
| 968 | 969 | ||
| 970 | /* Implement full-functionality option for ECN encapsulation */ | ||
| 971 | *dsfield = INET_ECN_encapsulate(old_dsfield, old_dsfield); | ||
| 972 | |||
| 969 | return skb; | 973 | return skb; |
| 970 | error: | 974 | error: |
| 971 | kfree_skb(skb); | 975 | kfree_skb(skb); |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 929927171426..64e1ee091225 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -1048,7 +1048,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net, | |||
| 1048 | if (nla_put_string(skb, NFTA_CHAIN_TYPE, basechain->type->name)) | 1048 | if (nla_put_string(skb, NFTA_CHAIN_TYPE, basechain->type->name)) |
| 1049 | goto nla_put_failure; | 1049 | goto nla_put_failure; |
| 1050 | 1050 | ||
| 1051 | if (nft_dump_stats(skb, nft_base_chain(chain)->stats)) | 1051 | if (basechain->stats && nft_dump_stats(skb, basechain->stats)) |
| 1052 | goto nla_put_failure; | 1052 | goto nla_put_failure; |
| 1053 | } | 1053 | } |
| 1054 | 1054 | ||
| @@ -1487,8 +1487,8 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy, | |||
| 1487 | 1487 | ||
| 1488 | chain2 = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], | 1488 | chain2 = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], |
| 1489 | genmask); | 1489 | genmask); |
| 1490 | if (IS_ERR(chain2)) | 1490 | if (!IS_ERR(chain2)) |
| 1491 | return PTR_ERR(chain2); | 1491 | return -EEXIST; |
| 1492 | } | 1492 | } |
| 1493 | 1493 | ||
| 1494 | if (nla[NFTA_CHAIN_COUNTERS]) { | 1494 | if (nla[NFTA_CHAIN_COUNTERS]) { |
| @@ -2741,8 +2741,10 @@ cont: | |||
| 2741 | list_for_each_entry(i, &ctx->table->sets, list) { | 2741 | list_for_each_entry(i, &ctx->table->sets, list) { |
| 2742 | if (!nft_is_active_next(ctx->net, i)) | 2742 | if (!nft_is_active_next(ctx->net, i)) |
| 2743 | continue; | 2743 | continue; |
| 2744 | if (!strcmp(set->name, i->name)) | 2744 | if (!strcmp(set->name, i->name)) { |
| 2745 | kfree(set->name); | ||
| 2745 | return -ENFILE; | 2746 | return -ENFILE; |
| 2747 | } | ||
| 2746 | } | 2748 | } |
| 2747 | return 0; | 2749 | return 0; |
| 2748 | } | 2750 | } |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index c83a3b5e1c6c..d8571f414208 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
| @@ -892,7 +892,7 @@ void *xt_copy_counters_from_user(const void __user *user, unsigned int len, | |||
| 892 | if (copy_from_user(&compat_tmp, user, sizeof(compat_tmp)) != 0) | 892 | if (copy_from_user(&compat_tmp, user, sizeof(compat_tmp)) != 0) |
| 893 | return ERR_PTR(-EFAULT); | 893 | return ERR_PTR(-EFAULT); |
| 894 | 894 | ||
| 895 | strlcpy(info->name, compat_tmp.name, sizeof(info->name)); | 895 | memcpy(info->name, compat_tmp.name, sizeof(info->name) - 1); |
| 896 | info->num_counters = compat_tmp.num_counters; | 896 | info->num_counters = compat_tmp.num_counters; |
| 897 | user += sizeof(compat_tmp); | 897 | user += sizeof(compat_tmp); |
| 898 | } else | 898 | } else |
| @@ -905,9 +905,9 @@ void *xt_copy_counters_from_user(const void __user *user, unsigned int len, | |||
| 905 | if (copy_from_user(info, user, sizeof(*info)) != 0) | 905 | if (copy_from_user(info, user, sizeof(*info)) != 0) |
| 906 | return ERR_PTR(-EFAULT); | 906 | return ERR_PTR(-EFAULT); |
| 907 | 907 | ||
| 908 | info->name[sizeof(info->name) - 1] = '\0'; | ||
| 909 | user += sizeof(*info); | 908 | user += sizeof(*info); |
| 910 | } | 909 | } |
| 910 | info->name[sizeof(info->name) - 1] = '\0'; | ||
| 911 | 911 | ||
| 912 | size = sizeof(struct xt_counters); | 912 | size = sizeof(struct xt_counters); |
| 913 | size *= info->num_counters; | 913 | size *= info->num_counters; |
diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c index 38986a95216c..29123934887b 100644 --- a/net/netfilter/xt_bpf.c +++ b/net/netfilter/xt_bpf.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/syscalls.h> | ||
| 11 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
| 12 | #include <linux/filter.h> | 13 | #include <linux/filter.h> |
| 13 | #include <linux/bpf.h> | 14 | #include <linux/bpf.h> |
| @@ -49,6 +50,22 @@ static int __bpf_mt_check_fd(int fd, struct bpf_prog **ret) | |||
| 49 | return 0; | 50 | return 0; |
| 50 | } | 51 | } |
| 51 | 52 | ||
| 53 | static int __bpf_mt_check_path(const char *path, struct bpf_prog **ret) | ||
| 54 | { | ||
| 55 | mm_segment_t oldfs = get_fs(); | ||
| 56 | int retval, fd; | ||
| 57 | |||
| 58 | set_fs(KERNEL_DS); | ||
| 59 | fd = bpf_obj_get_user(path); | ||
| 60 | set_fs(oldfs); | ||
| 61 | if (fd < 0) | ||
| 62 | return fd; | ||
| 63 | |||
| 64 | retval = __bpf_mt_check_fd(fd, ret); | ||
| 65 | sys_close(fd); | ||
| 66 | return retval; | ||
| 67 | } | ||
| 68 | |||
| 52 | static int bpf_mt_check(const struct xt_mtchk_param *par) | 69 | static int bpf_mt_check(const struct xt_mtchk_param *par) |
| 53 | { | 70 | { |
| 54 | struct xt_bpf_info *info = par->matchinfo; | 71 | struct xt_bpf_info *info = par->matchinfo; |
| @@ -66,9 +83,10 @@ static int bpf_mt_check_v1(const struct xt_mtchk_param *par) | |||
| 66 | return __bpf_mt_check_bytecode(info->bpf_program, | 83 | return __bpf_mt_check_bytecode(info->bpf_program, |
| 67 | info->bpf_program_num_elem, | 84 | info->bpf_program_num_elem, |
| 68 | &info->filter); | 85 | &info->filter); |
| 69 | else if (info->mode == XT_BPF_MODE_FD_PINNED || | 86 | else if (info->mode == XT_BPF_MODE_FD_ELF) |
| 70 | info->mode == XT_BPF_MODE_FD_ELF) | ||
| 71 | return __bpf_mt_check_fd(info->fd, &info->filter); | 87 | return __bpf_mt_check_fd(info->fd, &info->filter); |
| 88 | else if (info->mode == XT_BPF_MODE_PATH_PINNED) | ||
| 89 | return __bpf_mt_check_path(info->path, &info->filter); | ||
| 72 | else | 90 | else |
| 73 | return -EINVAL; | 91 | return -EINVAL; |
| 74 | } | 92 | } |
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index e75ef39669c5..575d2153e3b8 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c | |||
| @@ -76,7 +76,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, | |||
| 76 | transparent = nf_sk_is_transparent(sk); | 76 | transparent = nf_sk_is_transparent(sk); |
| 77 | 77 | ||
| 78 | if (info->flags & XT_SOCKET_RESTORESKMARK && !wildcard && | 78 | if (info->flags & XT_SOCKET_RESTORESKMARK && !wildcard && |
| 79 | transparent) | 79 | transparent && sk_fullsock(sk)) |
| 80 | pskb->mark = sk->sk_mark; | 80 | pskb->mark = sk->sk_mark; |
| 81 | 81 | ||
| 82 | if (sk != skb->sk) | 82 | if (sk != skb->sk) |
| @@ -133,7 +133,7 @@ socket_mt6_v1_v2_v3(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 133 | transparent = nf_sk_is_transparent(sk); | 133 | transparent = nf_sk_is_transparent(sk); |
| 134 | 134 | ||
| 135 | if (info->flags & XT_SOCKET_RESTORESKMARK && !wildcard && | 135 | if (info->flags & XT_SOCKET_RESTORESKMARK && !wildcard && |
| 136 | transparent) | 136 | transparent && sk_fullsock(sk)) |
| 137 | pskb->mark = sk->sk_mark; | 137 | pskb->mark = sk->sk_mark; |
| 138 | 138 | ||
| 139 | if (sk != skb->sk) | 139 | if (sk != skb->sk) |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 94c11cf0459d..f34750691c5c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -2266,16 +2266,17 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | |||
| 2266 | cb->min_dump_alloc = control->min_dump_alloc; | 2266 | cb->min_dump_alloc = control->min_dump_alloc; |
| 2267 | cb->skb = skb; | 2267 | cb->skb = skb; |
| 2268 | 2268 | ||
| 2269 | if (cb->start) { | ||
| 2270 | ret = cb->start(cb); | ||
| 2271 | if (ret) | ||
| 2272 | goto error_unlock; | ||
| 2273 | } | ||
| 2274 | |||
| 2269 | nlk->cb_running = true; | 2275 | nlk->cb_running = true; |
| 2270 | 2276 | ||
| 2271 | mutex_unlock(nlk->cb_mutex); | 2277 | mutex_unlock(nlk->cb_mutex); |
| 2272 | 2278 | ||
| 2273 | ret = 0; | 2279 | ret = netlink_dump(sk); |
| 2274 | if (cb->start) | ||
| 2275 | ret = cb->start(cb); | ||
| 2276 | |||
| 2277 | if (!ret) | ||
| 2278 | ret = netlink_dump(sk); | ||
| 2279 | 2280 | ||
| 2280 | sock_put(sk); | 2281 | sock_put(sk); |
| 2281 | 2282 | ||
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 7d99029df342..a140dd4a84af 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
| @@ -233,7 +233,7 @@ static int tipc_bcast_xmit(struct net *net, struct sk_buff_head *pkts, | |||
| 233 | struct sk_buff_head xmitq; | 233 | struct sk_buff_head xmitq; |
| 234 | int rc = 0; | 234 | int rc = 0; |
| 235 | 235 | ||
| 236 | __skb_queue_head_init(&xmitq); | 236 | skb_queue_head_init(&xmitq); |
| 237 | tipc_bcast_lock(net); | 237 | tipc_bcast_lock(net); |
| 238 | if (tipc_link_bc_peers(l)) | 238 | if (tipc_link_bc_peers(l)) |
| 239 | rc = tipc_link_xmit(l, pkts, &xmitq); | 239 | rc = tipc_link_xmit(l, pkts, &xmitq); |
| @@ -263,7 +263,7 @@ static int tipc_rcast_xmit(struct net *net, struct sk_buff_head *pkts, | |||
| 263 | u32 dst, selector; | 263 | u32 dst, selector; |
| 264 | 264 | ||
| 265 | selector = msg_link_selector(buf_msg(skb_peek(pkts))); | 265 | selector = msg_link_selector(buf_msg(skb_peek(pkts))); |
| 266 | __skb_queue_head_init(&_pkts); | 266 | skb_queue_head_init(&_pkts); |
| 267 | 267 | ||
| 268 | list_for_each_entry_safe(n, tmp, &dests->list, list) { | 268 | list_for_each_entry_safe(n, tmp, &dests->list, list) { |
| 269 | dst = n->value; | 269 | dst = n->value; |
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 121e59a1d0e7..17146c16ee2d 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
| @@ -568,6 +568,14 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err) | |||
| 568 | msg_set_destnode(msg, dnode); | 568 | msg_set_destnode(msg, dnode); |
| 569 | msg_set_destport(msg, dport); | 569 | msg_set_destport(msg, dport); |
| 570 | *err = TIPC_OK; | 570 | *err = TIPC_OK; |
| 571 | |||
| 572 | if (!skb_cloned(skb)) | ||
| 573 | return true; | ||
| 574 | |||
| 575 | /* Unclone buffer in case it was bundled */ | ||
| 576 | if (pskb_expand_head(skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC)) | ||
| 577 | return false; | ||
| 578 | |||
| 571 | return true; | 579 | return true; |
| 572 | } | 580 | } |
| 573 | 581 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 690874293cfc..d396cb61a280 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -549,6 +549,14 @@ nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = { | |||
| 549 | [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED }, | 549 | [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED }, |
| 550 | }; | 550 | }; |
| 551 | 551 | ||
| 552 | /* policy for packet pattern attributes */ | ||
| 553 | static const struct nla_policy | ||
| 554 | nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = { | ||
| 555 | [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, }, | ||
| 556 | [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, }, | ||
| 557 | [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 }, | ||
| 558 | }; | ||
| 559 | |||
| 552 | static int nl80211_prepare_wdev_dump(struct sk_buff *skb, | 560 | static int nl80211_prepare_wdev_dump(struct sk_buff *skb, |
| 553 | struct netlink_callback *cb, | 561 | struct netlink_callback *cb, |
| 554 | struct cfg80211_registered_device **rdev, | 562 | struct cfg80211_registered_device **rdev, |
| @@ -10532,7 +10540,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
| 10532 | u8 *mask_pat; | 10540 | u8 *mask_pat; |
| 10533 | 10541 | ||
| 10534 | nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat, | 10542 | nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat, |
| 10535 | NULL, info->extack); | 10543 | nl80211_packet_pattern_policy, |
| 10544 | info->extack); | ||
| 10536 | err = -EINVAL; | 10545 | err = -EINVAL; |
| 10537 | if (!pat_tb[NL80211_PKTPAT_MASK] || | 10546 | if (!pat_tb[NL80211_PKTPAT_MASK] || |
| 10538 | !pat_tb[NL80211_PKTPAT_PATTERN]) | 10547 | !pat_tb[NL80211_PKTPAT_PATTERN]) |
| @@ -10781,7 +10790,8 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, | |||
| 10781 | rem) { | 10790 | rem) { |
| 10782 | u8 *mask_pat; | 10791 | u8 *mask_pat; |
| 10783 | 10792 | ||
| 10784 | nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat, NULL, NULL); | 10793 | nla_parse_nested(pat_tb, MAX_NL80211_PKTPAT, pat, |
| 10794 | nl80211_packet_pattern_policy, NULL); | ||
| 10785 | if (!pat_tb[NL80211_PKTPAT_MASK] || | 10795 | if (!pat_tb[NL80211_PKTPAT_MASK] || |
| 10786 | !pat_tb[NL80211_PKTPAT_PATTERN]) | 10796 | !pat_tb[NL80211_PKTPAT_PATTERN]) |
| 10787 | return -EINVAL; | 10797 | return -EINVAL; |
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c index acf00104ef31..30e5746085b8 100644 --- a/net/xfrm/xfrm_device.c +++ b/net/xfrm/xfrm_device.c | |||
| @@ -91,6 +91,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | if (!dev->xfrmdev_ops || !dev->xfrmdev_ops->xdo_dev_state_add) { | 93 | if (!dev->xfrmdev_ops || !dev->xfrmdev_ops->xdo_dev_state_add) { |
| 94 | xso->dev = NULL; | ||
| 94 | dev_put(dev); | 95 | dev_put(dev); |
| 95 | return 0; | 96 | return 0; |
| 96 | } | 97 | } |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 2515cd2bc5db..8ac9d32fb79d 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
| @@ -429,7 +429,8 @@ resume: | |||
| 429 | nf_reset(skb); | 429 | nf_reset(skb); |
| 430 | 430 | ||
| 431 | if (decaps) { | 431 | if (decaps) { |
| 432 | skb->sp->olen = 0; | 432 | if (skb->sp) |
| 433 | skb->sp->olen = 0; | ||
| 433 | skb_dst_drop(skb); | 434 | skb_dst_drop(skb); |
| 434 | gro_cells_receive(&gro_cells, skb); | 435 | gro_cells_receive(&gro_cells, skb); |
| 435 | return 0; | 436 | return 0; |
| @@ -440,7 +441,8 @@ resume: | |||
| 440 | 441 | ||
| 441 | err = x->inner_mode->afinfo->transport_finish(skb, xfrm_gro || async); | 442 | err = x->inner_mode->afinfo->transport_finish(skb, xfrm_gro || async); |
| 442 | if (xfrm_gro) { | 443 | if (xfrm_gro) { |
| 443 | skb->sp->olen = 0; | 444 | if (skb->sp) |
| 445 | skb->sp->olen = 0; | ||
| 444 | skb_dst_drop(skb); | 446 | skb_dst_drop(skb); |
| 445 | gro_cells_receive(&gro_cells, skb); | 447 | gro_cells_receive(&gro_cells, skb); |
| 446 | return err; | 448 | return err; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 0dab1cd79ce4..12213477cd3a 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -732,12 +732,12 @@ restart: | |||
| 732 | } | 732 | } |
| 733 | } | 733 | } |
| 734 | } | 734 | } |
| 735 | out: | ||
| 736 | spin_unlock_bh(&net->xfrm.xfrm_state_lock); | ||
| 735 | if (cnt) { | 737 | if (cnt) { |
| 736 | err = 0; | 738 | err = 0; |
| 737 | xfrm_policy_cache_flush(); | 739 | xfrm_policy_cache_flush(); |
| 738 | } | 740 | } |
| 739 | out: | ||
| 740 | spin_unlock_bh(&net->xfrm.xfrm_state_lock); | ||
| 741 | return err; | 741 | return err; |
| 742 | } | 742 | } |
| 743 | EXPORT_SYMBOL(xfrm_state_flush); | 743 | EXPORT_SYMBOL(xfrm_state_flush); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 2bfbd9121e3b..b997f1395357 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -657,6 +657,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 657 | 657 | ||
| 658 | if (err < 0) { | 658 | if (err < 0) { |
| 659 | x->km.state = XFRM_STATE_DEAD; | 659 | x->km.state = XFRM_STATE_DEAD; |
| 660 | xfrm_dev_state_delete(x); | ||
| 660 | __xfrm_state_put(x); | 661 | __xfrm_state_put(x); |
| 661 | goto out; | 662 | goto out; |
| 662 | } | 663 | } |
diff --git a/tools/testing/selftests/networking/timestamping/rxtimestamp.c b/tools/testing/selftests/networking/timestamping/rxtimestamp.c index 00f286661dcd..dd4162fc0419 100644 --- a/tools/testing/selftests/networking/timestamping/rxtimestamp.c +++ b/tools/testing/selftests/networking/timestamping/rxtimestamp.c | |||
| @@ -341,7 +341,7 @@ int main(int argc, char **argv) | |||
| 341 | return 0; | 341 | return 0; |
| 342 | case 'n': | 342 | case 'n': |
| 343 | t = atoi(optarg); | 343 | t = atoi(optarg); |
| 344 | if (t > ARRAY_SIZE(test_cases)) | 344 | if (t >= ARRAY_SIZE(test_cases)) |
| 345 | error(1, 0, "Invalid test case: %d", t); | 345 | error(1, 0, "Invalid test case: %d", t); |
| 346 | all_tests = false; | 346 | all_tests = false; |
| 347 | test_cases[t].enabled = true; | 347 | test_cases[t].enabled = true; |
