diff options
36 files changed, 286 insertions, 144 deletions
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index dd3a0a232ea0..818a573669e6 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c | |||
| @@ -3584,7 +3584,11 @@ static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr, | |||
| 3584 | fl6.flowi6_oif = dst_addr->sin6_scope_id; | 3584 | fl6.flowi6_oif = dst_addr->sin6_scope_id; |
| 3585 | 3585 | ||
| 3586 | *dst = ip6_route_output(&init_net, NULL, &fl6); | 3586 | *dst = ip6_route_output(&init_net, NULL, &fl6); |
| 3587 | if (*dst) | 3587 | if ((*dst)->error) { |
| 3588 | dst_release(*dst); | ||
| 3589 | *dst = NULL; | ||
| 3590 | return -ENETUNREACH; | ||
| 3591 | } else | ||
| 3588 | return 0; | 3592 | return 0; |
| 3589 | #endif | 3593 | #endif |
| 3590 | 3594 | ||
diff --git a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h index c2c0680a1146..ac37cacc6136 100644 --- a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h +++ b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h | |||
| @@ -157,7 +157,7 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, | |||
| 157 | CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0; | 157 | CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0; |
| 158 | *fcoe_enc_error = (desc->flags & | 158 | *fcoe_enc_error = (desc->flags & |
| 159 | CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0; | 159 | CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0; |
| 160 | *fcoe_eof = (u8)((desc->checksum_fcoe >> | 160 | *fcoe_eof = (u8)((le16_to_cpu(desc->checksum_fcoe) >> |
| 161 | CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) & | 161 | CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) & |
| 162 | CQ_ENET_RQ_DESC_FCOE_EOF_MASK); | 162 | CQ_ENET_RQ_DESC_FCOE_EOF_MASK); |
| 163 | *checksum = 0; | 163 | *checksum = 0; |
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c index 22bf03a1829e..c347b6236f8f 100644 --- a/drivers/net/ethernet/cisco/enic/enic_pp.c +++ b/drivers/net/ethernet/cisco/enic/enic_pp.c | |||
| @@ -72,7 +72,7 @@ static int enic_set_port_profile(struct enic *enic, int vf) | |||
| 72 | struct enic_port_profile *pp; | 72 | struct enic_port_profile *pp; |
| 73 | struct vic_provinfo *vp; | 73 | struct vic_provinfo *vp; |
| 74 | const u8 oui[3] = VIC_PROVINFO_CISCO_OUI; | 74 | const u8 oui[3] = VIC_PROVINFO_CISCO_OUI; |
| 75 | const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX); | 75 | const __be16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX); |
| 76 | char uuid_str[38]; | 76 | char uuid_str[38]; |
| 77 | char client_mac_str[18]; | 77 | char client_mac_str[18]; |
| 78 | u8 *client_mac; | 78 | u8 *client_mac; |
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 27d651a80f3f..55cbf65512c3 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c | |||
| @@ -2328,19 +2328,11 @@ jme_change_mtu(struct net_device *netdev, int new_mtu) | |||
| 2328 | ((new_mtu) < IPV6_MIN_MTU)) | 2328 | ((new_mtu) < IPV6_MIN_MTU)) |
| 2329 | return -EINVAL; | 2329 | return -EINVAL; |
| 2330 | 2330 | ||
| 2331 | if (new_mtu > 4000) { | ||
| 2332 | jme->reg_rxcs &= ~RXCS_FIFOTHNP; | ||
| 2333 | jme->reg_rxcs |= RXCS_FIFOTHNP_64QW; | ||
| 2334 | jme_restart_rx_engine(jme); | ||
| 2335 | } else { | ||
| 2336 | jme->reg_rxcs &= ~RXCS_FIFOTHNP; | ||
| 2337 | jme->reg_rxcs |= RXCS_FIFOTHNP_128QW; | ||
| 2338 | jme_restart_rx_engine(jme); | ||
| 2339 | } | ||
| 2340 | 2331 | ||
| 2341 | netdev->mtu = new_mtu; | 2332 | netdev->mtu = new_mtu; |
| 2342 | netdev_update_features(netdev); | 2333 | netdev_update_features(netdev); |
| 2343 | 2334 | ||
| 2335 | jme_restart_rx_engine(jme); | ||
| 2344 | jme_reset_link(jme); | 2336 | jme_reset_link(jme); |
| 2345 | 2337 | ||
| 2346 | return 0; | 2338 | return 0; |
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h index 4304072bd3c5..3efc897c9913 100644 --- a/drivers/net/ethernet/jme.h +++ b/drivers/net/ethernet/jme.h | |||
| @@ -730,7 +730,7 @@ enum jme_rxcs_values { | |||
| 730 | RXCS_RETRYCNT_60 = 0x00000F00, | 730 | RXCS_RETRYCNT_60 = 0x00000F00, |
| 731 | 731 | ||
| 732 | RXCS_DEFAULT = RXCS_FIFOTHTP_128T | | 732 | RXCS_DEFAULT = RXCS_FIFOTHTP_128T | |
| 733 | RXCS_FIFOTHNP_128QW | | 733 | RXCS_FIFOTHNP_16QW | |
| 734 | RXCS_DMAREQSZ_128B | | 734 | RXCS_DMAREQSZ_128B | |
| 735 | RXCS_RETRYGAP_256ns | | 735 | RXCS_RETRYGAP_256ns | |
| 736 | RXCS_RETRYCNT_32, | 736 | RXCS_RETRYCNT_32, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 8fa41f3082cf..9129ace02560 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
| @@ -1036,7 +1036,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector) | |||
| 1036 | struct mlx4_priv *priv = mlx4_priv(dev); | 1036 | struct mlx4_priv *priv = mlx4_priv(dev); |
| 1037 | int vec = 0, err = 0, i; | 1037 | int vec = 0, err = 0, i; |
| 1038 | 1038 | ||
| 1039 | spin_lock(&priv->msix_ctl.pool_lock); | 1039 | mutex_lock(&priv->msix_ctl.pool_lock); |
| 1040 | for (i = 0; !vec && i < dev->caps.comp_pool; i++) { | 1040 | for (i = 0; !vec && i < dev->caps.comp_pool; i++) { |
| 1041 | if (~priv->msix_ctl.pool_bm & 1ULL << i) { | 1041 | if (~priv->msix_ctl.pool_bm & 1ULL << i) { |
| 1042 | priv->msix_ctl.pool_bm |= 1ULL << i; | 1042 | priv->msix_ctl.pool_bm |= 1ULL << i; |
| @@ -1058,7 +1058,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector) | |||
| 1058 | eq_set_ci(&priv->eq_table.eq[vec], 1); | 1058 | eq_set_ci(&priv->eq_table.eq[vec], 1); |
| 1059 | } | 1059 | } |
| 1060 | } | 1060 | } |
| 1061 | spin_unlock(&priv->msix_ctl.pool_lock); | 1061 | mutex_unlock(&priv->msix_ctl.pool_lock); |
| 1062 | 1062 | ||
| 1063 | if (vec) { | 1063 | if (vec) { |
| 1064 | *vector = vec; | 1064 | *vector = vec; |
| @@ -1079,13 +1079,13 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec) | |||
| 1079 | if (likely(i >= 0)) { | 1079 | if (likely(i >= 0)) { |
| 1080 | /*sanity check , making sure were not trying to free irq's | 1080 | /*sanity check , making sure were not trying to free irq's |
| 1081 | Belonging to a legacy EQ*/ | 1081 | Belonging to a legacy EQ*/ |
| 1082 | spin_lock(&priv->msix_ctl.pool_lock); | 1082 | mutex_lock(&priv->msix_ctl.pool_lock); |
| 1083 | if (priv->msix_ctl.pool_bm & 1ULL << i) { | 1083 | if (priv->msix_ctl.pool_bm & 1ULL << i) { |
| 1084 | free_irq(priv->eq_table.eq[vec].irq, | 1084 | free_irq(priv->eq_table.eq[vec].irq, |
| 1085 | &priv->eq_table.eq[vec]); | 1085 | &priv->eq_table.eq[vec]); |
| 1086 | priv->msix_ctl.pool_bm &= ~(1ULL << i); | 1086 | priv->msix_ctl.pool_bm &= ~(1ULL << i); |
| 1087 | } | 1087 | } |
| 1088 | spin_unlock(&priv->msix_ctl.pool_lock); | 1088 | mutex_unlock(&priv->msix_ctl.pool_lock); |
| 1089 | } | 1089 | } |
| 1090 | 1090 | ||
| 1091 | } | 1091 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 9c5fbad513f8..d498f049c74e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
| @@ -531,15 +531,14 @@ int mlx4_change_port_types(struct mlx4_dev *dev, | |||
| 531 | for (port = 0; port < dev->caps.num_ports; port++) { | 531 | for (port = 0; port < dev->caps.num_ports; port++) { |
| 532 | /* Change the port type only if the new type is different | 532 | /* Change the port type only if the new type is different |
| 533 | * from the current, and not set to Auto */ | 533 | * from the current, and not set to Auto */ |
| 534 | if (port_types[port] != dev->caps.port_type[port + 1]) { | 534 | if (port_types[port] != dev->caps.port_type[port + 1]) |
| 535 | change = 1; | 535 | change = 1; |
| 536 | dev->caps.port_type[port + 1] = port_types[port]; | ||
| 537 | } | ||
| 538 | } | 536 | } |
| 539 | if (change) { | 537 | if (change) { |
| 540 | mlx4_unregister_device(dev); | 538 | mlx4_unregister_device(dev); |
| 541 | for (port = 1; port <= dev->caps.num_ports; port++) { | 539 | for (port = 1; port <= dev->caps.num_ports; port++) { |
| 542 | mlx4_CLOSE_PORT(dev, port); | 540 | mlx4_CLOSE_PORT(dev, port); |
| 541 | dev->caps.port_type[port] = port_types[port - 1]; | ||
| 543 | err = mlx4_SET_PORT(dev, port); | 542 | err = mlx4_SET_PORT(dev, port); |
| 544 | if (err) { | 543 | if (err) { |
| 545 | mlx4_err(dev, "Failed to set port %d, " | 544 | mlx4_err(dev, "Failed to set port %d, " |
| @@ -1828,7 +1827,7 @@ slave_start: | |||
| 1828 | goto err_master_mfunc; | 1827 | goto err_master_mfunc; |
| 1829 | 1828 | ||
| 1830 | priv->msix_ctl.pool_bm = 0; | 1829 | priv->msix_ctl.pool_bm = 0; |
| 1831 | spin_lock_init(&priv->msix_ctl.pool_lock); | 1830 | mutex_init(&priv->msix_ctl.pool_lock); |
| 1832 | 1831 | ||
| 1833 | mlx4_enable_msi_x(dev); | 1832 | mlx4_enable_msi_x(dev); |
| 1834 | if ((mlx4_is_mfunc(dev)) && | 1833 | if ((mlx4_is_mfunc(dev)) && |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index c92269f8c057..28f8251561f4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
| @@ -697,7 +697,7 @@ struct mlx4_sense { | |||
| 697 | 697 | ||
| 698 | struct mlx4_msix_ctl { | 698 | struct mlx4_msix_ctl { |
| 699 | u64 pool_bm; | 699 | u64 pool_bm; |
| 700 | spinlock_t pool_lock; | 700 | struct mutex pool_lock; |
| 701 | }; | 701 | }; |
| 702 | 702 | ||
| 703 | struct mlx4_steer { | 703 | struct mlx4_steer { |
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 4fa0bcb25dfc..4b2f54565f64 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c | |||
| @@ -1009,7 +1009,7 @@ static void emac_rx_handler(void *token, int len, int status) | |||
| 1009 | int ret; | 1009 | int ret; |
| 1010 | 1010 | ||
| 1011 | /* free and bail if we are shutting down */ | 1011 | /* free and bail if we are shutting down */ |
| 1012 | if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) { | 1012 | if (unlikely(!netif_running(ndev))) { |
| 1013 | dev_kfree_skb_any(skb); | 1013 | dev_kfree_skb_any(skb); |
| 1014 | return; | 1014 | return; |
| 1015 | } | 1015 | } |
| @@ -1038,7 +1038,9 @@ static void emac_rx_handler(void *token, int len, int status) | |||
| 1038 | recycle: | 1038 | recycle: |
| 1039 | ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, | 1039 | ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, |
| 1040 | skb_tailroom(skb), GFP_KERNEL); | 1040 | skb_tailroom(skb), GFP_KERNEL); |
| 1041 | if (WARN_ON(ret < 0)) | 1041 | |
| 1042 | WARN_ON(ret == -ENOMEM); | ||
| 1043 | if (unlikely(ret < 0)) | ||
| 1042 | dev_kfree_skb_any(skb); | 1044 | dev_kfree_skb_any(skb); |
| 1043 | } | 1045 | } |
| 1044 | 1046 | ||
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index c81f136ae670..0856e1b7a849 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c | |||
| @@ -30,16 +30,16 @@ | |||
| 30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
| 31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
| 32 | 32 | ||
| 33 | MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IC1001 PHY drivers"); | 33 | MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers"); |
| 34 | MODULE_AUTHOR("Michael Barkowski"); | 34 | MODULE_AUTHOR("Michael Barkowski"); |
| 35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
| 36 | 36 | ||
| 37 | /* IP101A/IP1001 */ | 37 | /* IP101A/G - IP1001 */ |
| 38 | #define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ | 38 | #define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ |
| 39 | #define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ | 39 | #define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ |
| 40 | #define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ | 40 | #define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ |
| 41 | #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ | 41 | #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ |
| 42 | #define IP101A_APS_ON 2 /* IP101A APS Mode bit */ | 42 | #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ |
| 43 | 43 | ||
| 44 | static int ip175c_config_init(struct phy_device *phydev) | 44 | static int ip175c_config_init(struct phy_device *phydev) |
| 45 | { | 45 | { |
| @@ -98,20 +98,24 @@ static int ip175c_config_init(struct phy_device *phydev) | |||
| 98 | 98 | ||
| 99 | static int ip1xx_reset(struct phy_device *phydev) | 99 | static int ip1xx_reset(struct phy_device *phydev) |
| 100 | { | 100 | { |
| 101 | int err, bmcr; | 101 | int bmcr; |
| 102 | 102 | ||
| 103 | /* Software Reset PHY */ | 103 | /* Software Reset PHY */ |
| 104 | bmcr = phy_read(phydev, MII_BMCR); | 104 | bmcr = phy_read(phydev, MII_BMCR); |
| 105 | if (bmcr < 0) | ||
| 106 | return bmcr; | ||
| 105 | bmcr |= BMCR_RESET; | 107 | bmcr |= BMCR_RESET; |
| 106 | err = phy_write(phydev, MII_BMCR, bmcr); | 108 | bmcr = phy_write(phydev, MII_BMCR, bmcr); |
| 107 | if (err < 0) | 109 | if (bmcr < 0) |
| 108 | return err; | 110 | return bmcr; |
| 109 | 111 | ||
| 110 | do { | 112 | do { |
| 111 | bmcr = phy_read(phydev, MII_BMCR); | 113 | bmcr = phy_read(phydev, MII_BMCR); |
| 114 | if (bmcr < 0) | ||
| 115 | return bmcr; | ||
| 112 | } while (bmcr & BMCR_RESET); | 116 | } while (bmcr & BMCR_RESET); |
| 113 | 117 | ||
| 114 | return err; | 118 | return 0; |
| 115 | } | 119 | } |
| 116 | 120 | ||
| 117 | static int ip1001_config_init(struct phy_device *phydev) | 121 | static int ip1001_config_init(struct phy_device *phydev) |
| @@ -124,7 +128,10 @@ static int ip1001_config_init(struct phy_device *phydev) | |||
| 124 | 128 | ||
| 125 | /* Enable Auto Power Saving mode */ | 129 | /* Enable Auto Power Saving mode */ |
| 126 | c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2); | 130 | c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2); |
| 131 | if (c < 0) | ||
| 132 | return c; | ||
| 127 | c |= IP1001_APS_ON; | 133 | c |= IP1001_APS_ON; |
| 134 | c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c); | ||
| 128 | if (c < 0) | 135 | if (c < 0) |
| 129 | return c; | 136 | return c; |
| 130 | 137 | ||
| @@ -132,14 +139,19 @@ static int ip1001_config_init(struct phy_device *phydev) | |||
| 132 | /* Additional delay (2ns) used to adjust RX clock phase | 139 | /* Additional delay (2ns) used to adjust RX clock phase |
| 133 | * at RGMII interface */ | 140 | * at RGMII interface */ |
| 134 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); | 141 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); |
| 142 | if (c < 0) | ||
| 143 | return c; | ||
| 144 | |||
| 135 | c |= IP1001_PHASE_SEL_MASK; | 145 | c |= IP1001_PHASE_SEL_MASK; |
| 136 | c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); | 146 | c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); |
| 147 | if (c < 0) | ||
| 148 | return c; | ||
| 137 | } | 149 | } |
| 138 | 150 | ||
| 139 | return c; | 151 | return 0; |
| 140 | } | 152 | } |
| 141 | 153 | ||
| 142 | static int ip101a_config_init(struct phy_device *phydev) | 154 | static int ip101a_g_config_init(struct phy_device *phydev) |
| 143 | { | 155 | { |
| 144 | int c; | 156 | int c; |
| 145 | 157 | ||
| @@ -149,7 +161,7 @@ static int ip101a_config_init(struct phy_device *phydev) | |||
| 149 | 161 | ||
| 150 | /* Enable Auto Power Saving mode */ | 162 | /* Enable Auto Power Saving mode */ |
| 151 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); | 163 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); |
| 152 | c |= IP101A_APS_ON; | 164 | c |= IP101A_G_APS_ON; |
| 153 | return c; | 165 | return c; |
| 154 | } | 166 | } |
| 155 | 167 | ||
| @@ -191,6 +203,7 @@ static struct phy_driver ip1001_driver = { | |||
| 191 | .phy_id_mask = 0x0ffffff0, | 203 | .phy_id_mask = 0x0ffffff0, |
| 192 | .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | | 204 | .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | |
| 193 | SUPPORTED_Asym_Pause, | 205 | SUPPORTED_Asym_Pause, |
| 206 | .flags = PHY_HAS_INTERRUPT, | ||
| 194 | .config_init = &ip1001_config_init, | 207 | .config_init = &ip1001_config_init, |
| 195 | .config_aneg = &genphy_config_aneg, | 208 | .config_aneg = &genphy_config_aneg, |
| 196 | .read_status = &genphy_read_status, | 209 | .read_status = &genphy_read_status, |
| @@ -199,13 +212,14 @@ static struct phy_driver ip1001_driver = { | |||
| 199 | .driver = { .owner = THIS_MODULE,}, | 212 | .driver = { .owner = THIS_MODULE,}, |
| 200 | }; | 213 | }; |
| 201 | 214 | ||
| 202 | static struct phy_driver ip101a_driver = { | 215 | static struct phy_driver ip101a_g_driver = { |
| 203 | .phy_id = 0x02430c54, | 216 | .phy_id = 0x02430c54, |
| 204 | .name = "ICPlus IP101A", | 217 | .name = "ICPlus IP101A/G", |
| 205 | .phy_id_mask = 0x0ffffff0, | 218 | .phy_id_mask = 0x0ffffff0, |
| 206 | .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | | 219 | .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | |
| 207 | SUPPORTED_Asym_Pause, | 220 | SUPPORTED_Asym_Pause, |
| 208 | .config_init = &ip101a_config_init, | 221 | .flags = PHY_HAS_INTERRUPT, |
| 222 | .config_init = &ip101a_g_config_init, | ||
| 209 | .config_aneg = &genphy_config_aneg, | 223 | .config_aneg = &genphy_config_aneg, |
| 210 | .read_status = &genphy_read_status, | 224 | .read_status = &genphy_read_status, |
| 211 | .suspend = genphy_suspend, | 225 | .suspend = genphy_suspend, |
| @@ -221,7 +235,7 @@ static int __init icplus_init(void) | |||
| 221 | if (ret < 0) | 235 | if (ret < 0) |
| 222 | return -ENODEV; | 236 | return -ENODEV; |
| 223 | 237 | ||
| 224 | ret = phy_driver_register(&ip101a_driver); | 238 | ret = phy_driver_register(&ip101a_g_driver); |
| 225 | if (ret < 0) | 239 | if (ret < 0) |
| 226 | return -ENODEV; | 240 | return -ENODEV; |
| 227 | 241 | ||
| @@ -231,7 +245,7 @@ static int __init icplus_init(void) | |||
| 231 | static void __exit icplus_exit(void) | 245 | static void __exit icplus_exit(void) |
| 232 | { | 246 | { |
| 233 | phy_driver_unregister(&ip1001_driver); | 247 | phy_driver_unregister(&ip1001_driver); |
| 234 | phy_driver_unregister(&ip101a_driver); | 248 | phy_driver_unregister(&ip101a_g_driver); |
| 235 | phy_driver_unregister(&ip175c_driver); | 249 | phy_driver_unregister(&ip175c_driver); |
| 236 | } | 250 | } |
| 237 | 251 | ||
| @@ -241,6 +255,7 @@ module_exit(icplus_exit); | |||
| 241 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { | 255 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { |
| 242 | { 0x02430d80, 0x0ffffff0 }, | 256 | { 0x02430d80, 0x0ffffff0 }, |
| 243 | { 0x02430d90, 0x0ffffff0 }, | 257 | { 0x02430d90, 0x0ffffff0 }, |
| 258 | { 0x02430c54, 0x0ffffff0 }, | ||
| 244 | { } | 259 | { } |
| 245 | }; | 260 | }; |
| 246 | 261 | ||
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index edfa15d2e795..486b4048850d 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c | |||
| @@ -2024,14 +2024,22 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
| 2024 | continue; | 2024 | continue; |
| 2025 | } | 2025 | } |
| 2026 | if (PPP_MP_CB(p)->sequence != seq) { | 2026 | if (PPP_MP_CB(p)->sequence != seq) { |
| 2027 | u32 oldseq; | ||
| 2027 | /* Fragment `seq' is missing. If it is after | 2028 | /* Fragment `seq' is missing. If it is after |
| 2028 | minseq, it might arrive later, so stop here. */ | 2029 | minseq, it might arrive later, so stop here. */ |
| 2029 | if (seq_after(seq, minseq)) | 2030 | if (seq_after(seq, minseq)) |
| 2030 | break; | 2031 | break; |
| 2031 | /* Fragment `seq' is lost, keep going. */ | 2032 | /* Fragment `seq' is lost, keep going. */ |
| 2032 | lost = 1; | 2033 | lost = 1; |
| 2034 | oldseq = seq; | ||
| 2033 | seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? | 2035 | seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? |
| 2034 | minseq + 1: PPP_MP_CB(p)->sequence; | 2036 | minseq + 1: PPP_MP_CB(p)->sequence; |
| 2037 | |||
| 2038 | if (ppp->debug & 1) | ||
| 2039 | netdev_printk(KERN_DEBUG, ppp->dev, | ||
| 2040 | "lost frag %u..%u\n", | ||
| 2041 | oldseq, seq-1); | ||
| 2042 | |||
| 2035 | goto again; | 2043 | goto again; |
| 2036 | } | 2044 | } |
| 2037 | 2045 | ||
| @@ -2076,6 +2084,10 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
| 2076 | struct sk_buff *tmp2; | 2084 | struct sk_buff *tmp2; |
| 2077 | 2085 | ||
| 2078 | skb_queue_reverse_walk_from_safe(list, p, tmp2) { | 2086 | skb_queue_reverse_walk_from_safe(list, p, tmp2) { |
| 2087 | if (ppp->debug & 1) | ||
| 2088 | netdev_printk(KERN_DEBUG, ppp->dev, | ||
| 2089 | "discarding frag %u\n", | ||
| 2090 | PPP_MP_CB(p)->sequence); | ||
| 2079 | __skb_unlink(p, list); | 2091 | __skb_unlink(p, list); |
| 2080 | kfree_skb(p); | 2092 | kfree_skb(p); |
| 2081 | } | 2093 | } |
| @@ -2091,6 +2103,17 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
| 2091 | /* If we have discarded any fragments, | 2103 | /* If we have discarded any fragments, |
| 2092 | signal a receive error. */ | 2104 | signal a receive error. */ |
| 2093 | if (PPP_MP_CB(head)->sequence != ppp->nextseq) { | 2105 | if (PPP_MP_CB(head)->sequence != ppp->nextseq) { |
| 2106 | skb_queue_walk_safe(list, p, tmp) { | ||
| 2107 | if (p == head) | ||
| 2108 | break; | ||
| 2109 | if (ppp->debug & 1) | ||
| 2110 | netdev_printk(KERN_DEBUG, ppp->dev, | ||
| 2111 | "discarding frag %u\n", | ||
| 2112 | PPP_MP_CB(p)->sequence); | ||
| 2113 | __skb_unlink(p, list); | ||
| 2114 | kfree_skb(p); | ||
| 2115 | } | ||
| 2116 | |||
| 2094 | if (ppp->debug & 1) | 2117 | if (ppp->debug & 1) |
| 2095 | netdev_printk(KERN_DEBUG, ppp->dev, | 2118 | netdev_printk(KERN_DEBUG, ppp->dev, |
| 2096 | " missed pkts %u..%u\n", | 2119 | " missed pkts %u..%u\n", |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 41a61efc331e..90a30026a931 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
| @@ -573,6 +573,13 @@ static const struct usb_device_id products [] = { | |||
| 573 | .driver_info = 0, | 573 | .driver_info = 0, |
| 574 | }, | 574 | }, |
| 575 | 575 | ||
| 576 | /* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */ | ||
| 577 | { | ||
| 578 | USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM, | ||
| 579 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | ||
| 580 | .driver_info = 0, | ||
| 581 | }, | ||
| 582 | |||
| 576 | /* | 583 | /* |
| 577 | * WHITELIST!!! | 584 | * WHITELIST!!! |
| 578 | * | 585 | * |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 304fe78ff60e..e1324b4a0f66 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
| @@ -1632,7 +1632,7 @@ static int hso_get_count(struct tty_struct *tty, | |||
| 1632 | struct hso_serial *serial = get_serial_by_tty(tty); | 1632 | struct hso_serial *serial = get_serial_by_tty(tty); |
| 1633 | struct hso_tiocmget *tiocmget = serial->tiocmget; | 1633 | struct hso_tiocmget *tiocmget = serial->tiocmget; |
| 1634 | 1634 | ||
| 1635 | memset(&icount, 0, sizeof(struct serial_icounter_struct)); | 1635 | memset(icount, 0, sizeof(struct serial_icounter_struct)); |
| 1636 | 1636 | ||
| 1637 | if (!tiocmget) | 1637 | if (!tiocmget) |
| 1638 | return -ENOENT; | 1638 | return -ENOENT; |
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c index f701d4127087..c3197ce0e2ad 100644 --- a/drivers/net/usb/zaurus.c +++ b/drivers/net/usb/zaurus.c | |||
| @@ -316,6 +316,11 @@ static const struct usb_device_id products [] = { | |||
| 316 | ZAURUS_MASTER_INTERFACE, | 316 | ZAURUS_MASTER_INTERFACE, |
| 317 | .driver_info = ZAURUS_PXA_INFO, | 317 | .driver_info = ZAURUS_PXA_INFO, |
| 318 | }, { | 318 | }, { |
| 319 | /* C-750/C-760/C-860/SL-C3000 PDA in MDLM mode */ | ||
| 320 | USB_DEVICE_AND_INTERFACE_INFO(0x04DD, 0x9031, USB_CLASS_COMM, | ||
| 321 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | ||
| 322 | .driver_info = (unsigned long) &bogus_mdlm_info, | ||
| 323 | }, { | ||
| 319 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | 324 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
| 320 | | USB_DEVICE_ID_MATCH_DEVICE, | 325 | | USB_DEVICE_ID_MATCH_DEVICE, |
| 321 | .idVendor = 0x04DD, | 326 | .idVendor = 0x04DD, |
| @@ -349,6 +354,13 @@ static const struct usb_device_id products [] = { | |||
| 349 | ZAURUS_MASTER_INTERFACE, | 354 | ZAURUS_MASTER_INTERFACE, |
| 350 | .driver_info = OLYMPUS_MXL_INFO, | 355 | .driver_info = OLYMPUS_MXL_INFO, |
| 351 | }, | 356 | }, |
| 357 | |||
| 358 | /* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */ | ||
| 359 | { | ||
| 360 | USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM, | ||
| 361 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | ||
| 362 | .driver_info = (unsigned long) &bogus_mdlm_info, | ||
| 363 | }, | ||
| 352 | { }, // END | 364 | { }, // END |
| 353 | }; | 365 | }; |
| 354 | MODULE_DEVICE_TABLE(usb, products); | 366 | MODULE_DEVICE_TABLE(usb, products); |
diff --git a/include/linux/if_link.h b/include/linux/if_link.h index c52d4b5f872a..4b24ff453aee 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h | |||
| @@ -137,6 +137,7 @@ enum { | |||
| 137 | IFLA_AF_SPEC, | 137 | IFLA_AF_SPEC, |
| 138 | IFLA_GROUP, /* Group the device belongs to */ | 138 | IFLA_GROUP, /* Group the device belongs to */ |
| 139 | IFLA_NET_NS_FD, | 139 | IFLA_NET_NS_FD, |
| 140 | IFLA_EXT_MASK, /* Extended info mask, VFs, etc */ | ||
| 140 | __IFLA_MAX | 141 | __IFLA_MAX |
| 141 | }; | 142 | }; |
| 142 | 143 | ||
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 8797ed16feb2..4dd5bd6994a8 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h | |||
| @@ -285,8 +285,8 @@ struct ebt_table { | |||
| 285 | struct module *me; | 285 | struct module *me; |
| 286 | }; | 286 | }; |
| 287 | 287 | ||
| 288 | #define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \ | 288 | #define EBT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) & \ |
| 289 | ~(__alignof__(struct ebt_replace)-1)) | 289 | ~(__alignof__(struct _xt_align)-1)) |
| 290 | extern struct ebt_table *ebt_register_table(struct net *net, | 290 | extern struct ebt_table *ebt_register_table(struct net *net, |
| 291 | const struct ebt_table *table); | 291 | const struct ebt_table *table); |
| 292 | extern void ebt_unregister_table(struct net *net, struct ebt_table *table); | 292 | extern void ebt_unregister_table(struct net *net, struct ebt_table *table); |
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 8e872ead88b5..577592ea0ea0 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h | |||
| @@ -602,6 +602,9 @@ struct tcamsg { | |||
| 602 | #define TCA_ACT_TAB 1 /* attr type must be >=1 */ | 602 | #define TCA_ACT_TAB 1 /* attr type must be >=1 */ |
| 603 | #define TCAA_MAX 1 | 603 | #define TCAA_MAX 1 |
| 604 | 604 | ||
| 605 | /* New extended info filters for IFLA_EXT_MASK */ | ||
| 606 | #define RTEXT_FILTER_VF (1 << 0) | ||
| 607 | |||
| 605 | /* End of information exported to user level */ | 608 | /* End of information exported to user level */ |
| 606 | 609 | ||
| 607 | #ifdef __KERNEL__ | 610 | #ifdef __KERNEL__ |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 50db9b04a552..ae86adee3746 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -1465,6 +1465,16 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset) | |||
| 1465 | } | 1465 | } |
| 1466 | #endif /* NET_SKBUFF_DATA_USES_OFFSET */ | 1466 | #endif /* NET_SKBUFF_DATA_USES_OFFSET */ |
| 1467 | 1467 | ||
| 1468 | static inline void skb_mac_header_rebuild(struct sk_buff *skb) | ||
| 1469 | { | ||
| 1470 | if (skb_mac_header_was_set(skb)) { | ||
| 1471 | const unsigned char *old_mac = skb_mac_header(skb); | ||
| 1472 | |||
| 1473 | skb_set_mac_header(skb, -skb->mac_len); | ||
| 1474 | memmove(skb_mac_header(skb), old_mac, skb->mac_len); | ||
| 1475 | } | ||
| 1476 | } | ||
| 1477 | |||
| 1468 | static inline int skb_checksum_start_offset(const struct sk_buff *skb) | 1478 | static inline int skb_checksum_start_offset(const struct sk_buff *skb) |
| 1469 | { | 1479 | { |
| 1470 | return skb->csum_start - skb_headroom(skb); | 1480 | return skb->csum_start - skb_headroom(skb); |
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 8a2b0ae7dbd2..ab86036bbf0c 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h | |||
| @@ -209,7 +209,7 @@ extern struct nf_conntrack_tuple_hash * | |||
| 209 | __nf_conntrack_find(struct net *net, u16 zone, | 209 | __nf_conntrack_find(struct net *net, u16 zone, |
| 210 | const struct nf_conntrack_tuple *tuple); | 210 | const struct nf_conntrack_tuple *tuple); |
| 211 | 211 | ||
| 212 | extern void nf_conntrack_hash_insert(struct nf_conn *ct); | 212 | extern int nf_conntrack_hash_check_insert(struct nf_conn *ct); |
| 213 | extern void nf_ct_delete_from_lists(struct nf_conn *ct); | 213 | extern void nf_ct_delete_from_lists(struct nf_conn *ct); |
| 214 | extern void nf_ct_insert_dying_list(struct nf_conn *ct); | 214 | extern void nf_ct_insert_dying_list(struct nf_conn *ct); |
| 215 | 215 | ||
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index 678f1ffaf843..370293901971 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, void *); | 7 | typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, void *); |
| 8 | typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *); | 8 | typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *); |
| 9 | typedef u16 (*rtnl_calcit_func)(struct sk_buff *); | 9 | typedef u16 (*rtnl_calcit_func)(struct sk_buff *, struct nlmsghdr *); |
| 10 | 10 | ||
| 11 | extern int __rtnl_register(int protocol, int msgtype, | 11 | extern int __rtnl_register(int protocol, int msgtype, |
| 12 | rtnl_doit_func, rtnl_dumpit_func, | 12 | rtnl_doit_func, rtnl_dumpit_func, |
diff --git a/net/atm/clip.c b/net/atm/clip.c index c12c2582457c..127fe70a1baa 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c | |||
| @@ -46,8 +46,8 @@ | |||
| 46 | 46 | ||
| 47 | static struct net_device *clip_devs; | 47 | static struct net_device *clip_devs; |
| 48 | static struct atm_vcc *atmarpd; | 48 | static struct atm_vcc *atmarpd; |
| 49 | static struct neigh_table clip_tbl; | ||
| 50 | static struct timer_list idle_timer; | 49 | static struct timer_list idle_timer; |
| 50 | static const struct neigh_ops clip_neigh_ops; | ||
| 51 | 51 | ||
| 52 | static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip) | 52 | static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip) |
| 53 | { | 53 | { |
| @@ -123,6 +123,8 @@ static int neigh_check_cb(struct neighbour *n) | |||
| 123 | struct atmarp_entry *entry = neighbour_priv(n); | 123 | struct atmarp_entry *entry = neighbour_priv(n); |
| 124 | struct clip_vcc *cv; | 124 | struct clip_vcc *cv; |
| 125 | 125 | ||
| 126 | if (n->ops != &clip_neigh_ops) | ||
| 127 | return 0; | ||
| 126 | for (cv = entry->vccs; cv; cv = cv->next) { | 128 | for (cv = entry->vccs; cv; cv = cv->next) { |
| 127 | unsigned long exp = cv->last_use + cv->idle_timeout; | 129 | unsigned long exp = cv->last_use + cv->idle_timeout; |
| 128 | 130 | ||
| @@ -154,10 +156,10 @@ static int neigh_check_cb(struct neighbour *n) | |||
| 154 | 156 | ||
| 155 | static void idle_timer_check(unsigned long dummy) | 157 | static void idle_timer_check(unsigned long dummy) |
| 156 | { | 158 | { |
| 157 | write_lock(&clip_tbl.lock); | 159 | write_lock(&arp_tbl.lock); |
| 158 | __neigh_for_each_release(&clip_tbl, neigh_check_cb); | 160 | __neigh_for_each_release(&arp_tbl, neigh_check_cb); |
| 159 | mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ); | 161 | mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ); |
| 160 | write_unlock(&clip_tbl.lock); | 162 | write_unlock(&arp_tbl.lock); |
| 161 | } | 163 | } |
| 162 | 164 | ||
| 163 | static int clip_arp_rcv(struct sk_buff *skb) | 165 | static int clip_arp_rcv(struct sk_buff *skb) |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index e287346e0934..2a83914b0277 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -826,6 +826,8 @@ next_elt: | |||
| 826 | write_unlock_bh(&tbl->lock); | 826 | write_unlock_bh(&tbl->lock); |
| 827 | cond_resched(); | 827 | cond_resched(); |
| 828 | write_lock_bh(&tbl->lock); | 828 | write_lock_bh(&tbl->lock); |
| 829 | nht = rcu_dereference_protected(tbl->nht, | ||
| 830 | lockdep_is_held(&tbl->lock)); | ||
| 829 | } | 831 | } |
| 830 | /* Cycle through all hash buckets every base_reachable_time/2 ticks. | 832 | /* Cycle through all hash buckets every base_reachable_time/2 ticks. |
| 831 | * ARP entry timeouts range from 1/2 base_reachable_time to 3/2 | 833 | * ARP entry timeouts range from 1/2 base_reachable_time to 3/2 |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 65aebd450027..606a6e8f3671 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -60,7 +60,6 @@ struct rtnl_link { | |||
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | static DEFINE_MUTEX(rtnl_mutex); | 62 | static DEFINE_MUTEX(rtnl_mutex); |
| 63 | static u16 min_ifinfo_dump_size; | ||
| 64 | 63 | ||
| 65 | void rtnl_lock(void) | 64 | void rtnl_lock(void) |
| 66 | { | 65 | { |
| @@ -724,10 +723,11 @@ static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b) | |||
| 724 | } | 723 | } |
| 725 | 724 | ||
| 726 | /* All VF info */ | 725 | /* All VF info */ |
| 727 | static inline int rtnl_vfinfo_size(const struct net_device *dev) | 726 | static inline int rtnl_vfinfo_size(const struct net_device *dev, |
| 727 | u32 ext_filter_mask) | ||
| 728 | { | 728 | { |
| 729 | if (dev->dev.parent && dev_is_pci(dev->dev.parent)) { | 729 | if (dev->dev.parent && dev_is_pci(dev->dev.parent) && |
| 730 | 730 | (ext_filter_mask & RTEXT_FILTER_VF)) { | |
| 731 | int num_vfs = dev_num_vf(dev->dev.parent); | 731 | int num_vfs = dev_num_vf(dev->dev.parent); |
| 732 | size_t size = nla_total_size(sizeof(struct nlattr)); | 732 | size_t size = nla_total_size(sizeof(struct nlattr)); |
| 733 | size += nla_total_size(num_vfs * sizeof(struct nlattr)); | 733 | size += nla_total_size(num_vfs * sizeof(struct nlattr)); |
| @@ -766,7 +766,8 @@ static size_t rtnl_port_size(const struct net_device *dev) | |||
| 766 | return port_self_size; | 766 | return port_self_size; |
| 767 | } | 767 | } |
| 768 | 768 | ||
| 769 | static noinline size_t if_nlmsg_size(const struct net_device *dev) | 769 | static noinline size_t if_nlmsg_size(const struct net_device *dev, |
| 770 | u32 ext_filter_mask) | ||
| 770 | { | 771 | { |
| 771 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) | 772 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) |
| 772 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ | 773 | + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ |
| @@ -784,8 +785,9 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev) | |||
| 784 | + nla_total_size(4) /* IFLA_MASTER */ | 785 | + nla_total_size(4) /* IFLA_MASTER */ |
| 785 | + nla_total_size(1) /* IFLA_OPERSTATE */ | 786 | + nla_total_size(1) /* IFLA_OPERSTATE */ |
| 786 | + nla_total_size(1) /* IFLA_LINKMODE */ | 787 | + nla_total_size(1) /* IFLA_LINKMODE */ |
| 787 | + nla_total_size(4) /* IFLA_NUM_VF */ | 788 | + nla_total_size(ext_filter_mask |
| 788 | + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */ | 789 | & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ |
| 790 | + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ | ||
| 789 | + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ | 791 | + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ |
| 790 | + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ | 792 | + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ |
| 791 | + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */ | 793 | + rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */ |
| @@ -868,7 +870,7 @@ static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev) | |||
| 868 | 870 | ||
| 869 | static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | 871 | static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, |
| 870 | int type, u32 pid, u32 seq, u32 change, | 872 | int type, u32 pid, u32 seq, u32 change, |
| 871 | unsigned int flags) | 873 | unsigned int flags, u32 ext_filter_mask) |
| 872 | { | 874 | { |
| 873 | struct ifinfomsg *ifm; | 875 | struct ifinfomsg *ifm; |
| 874 | struct nlmsghdr *nlh; | 876 | struct nlmsghdr *nlh; |
| @@ -941,10 +943,11 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 941 | goto nla_put_failure; | 943 | goto nla_put_failure; |
| 942 | copy_rtnl_link_stats64(nla_data(attr), stats); | 944 | copy_rtnl_link_stats64(nla_data(attr), stats); |
| 943 | 945 | ||
| 944 | if (dev->dev.parent) | 946 | if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF)) |
| 945 | NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent)); | 947 | NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent)); |
| 946 | 948 | ||
| 947 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { | 949 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent |
| 950 | && (ext_filter_mask & RTEXT_FILTER_VF)) { | ||
| 948 | int i; | 951 | int i; |
| 949 | 952 | ||
| 950 | struct nlattr *vfinfo, *vf; | 953 | struct nlattr *vfinfo, *vf; |
| @@ -1048,6 +1051,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1048 | struct net_device *dev; | 1051 | struct net_device *dev; |
| 1049 | struct hlist_head *head; | 1052 | struct hlist_head *head; |
| 1050 | struct hlist_node *node; | 1053 | struct hlist_node *node; |
| 1054 | struct nlattr *tb[IFLA_MAX+1]; | ||
| 1055 | u32 ext_filter_mask = 0; | ||
| 1051 | 1056 | ||
| 1052 | s_h = cb->args[0]; | 1057 | s_h = cb->args[0]; |
| 1053 | s_idx = cb->args[1]; | 1058 | s_idx = cb->args[1]; |
| @@ -1055,6 +1060,12 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1055 | rcu_read_lock(); | 1060 | rcu_read_lock(); |
| 1056 | cb->seq = net->dev_base_seq; | 1061 | cb->seq = net->dev_base_seq; |
| 1057 | 1062 | ||
| 1063 | nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, | ||
| 1064 | ifla_policy); | ||
| 1065 | |||
| 1066 | if (tb[IFLA_EXT_MASK]) | ||
| 1067 | ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); | ||
| 1068 | |||
| 1058 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { | 1069 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { |
| 1059 | idx = 0; | 1070 | idx = 0; |
| 1060 | head = &net->dev_index_head[h]; | 1071 | head = &net->dev_index_head[h]; |
| @@ -1064,7 +1075,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1064 | if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, | 1075 | if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, |
| 1065 | NETLINK_CB(cb->skb).pid, | 1076 | NETLINK_CB(cb->skb).pid, |
| 1066 | cb->nlh->nlmsg_seq, 0, | 1077 | cb->nlh->nlmsg_seq, 0, |
| 1067 | NLM_F_MULTI) <= 0) | 1078 | NLM_F_MULTI, |
| 1079 | ext_filter_mask) <= 0) | ||
| 1068 | goto out; | 1080 | goto out; |
| 1069 | 1081 | ||
| 1070 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | 1082 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
| @@ -1100,6 +1112,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { | |||
| 1100 | [IFLA_VF_PORTS] = { .type = NLA_NESTED }, | 1112 | [IFLA_VF_PORTS] = { .type = NLA_NESTED }, |
| 1101 | [IFLA_PORT_SELF] = { .type = NLA_NESTED }, | 1113 | [IFLA_PORT_SELF] = { .type = NLA_NESTED }, |
| 1102 | [IFLA_AF_SPEC] = { .type = NLA_NESTED }, | 1114 | [IFLA_AF_SPEC] = { .type = NLA_NESTED }, |
| 1115 | [IFLA_EXT_MASK] = { .type = NLA_U32 }, | ||
| 1103 | }; | 1116 | }; |
| 1104 | EXPORT_SYMBOL(ifla_policy); | 1117 | EXPORT_SYMBOL(ifla_policy); |
| 1105 | 1118 | ||
| @@ -1509,8 +1522,6 @@ errout: | |||
| 1509 | 1522 | ||
| 1510 | if (send_addr_notify) | 1523 | if (send_addr_notify) |
| 1511 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 1524 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
| 1512 | min_ifinfo_dump_size = max_t(u16, if_nlmsg_size(dev), | ||
| 1513 | min_ifinfo_dump_size); | ||
| 1514 | 1525 | ||
| 1515 | return err; | 1526 | return err; |
| 1516 | } | 1527 | } |
| @@ -1842,6 +1853,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
| 1842 | struct net_device *dev = NULL; | 1853 | struct net_device *dev = NULL; |
| 1843 | struct sk_buff *nskb; | 1854 | struct sk_buff *nskb; |
| 1844 | int err; | 1855 | int err; |
| 1856 | u32 ext_filter_mask = 0; | ||
| 1845 | 1857 | ||
| 1846 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); | 1858 | err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); |
| 1847 | if (err < 0) | 1859 | if (err < 0) |
| @@ -1850,6 +1862,9 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
| 1850 | if (tb[IFLA_IFNAME]) | 1862 | if (tb[IFLA_IFNAME]) |
| 1851 | nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); | 1863 | nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); |
| 1852 | 1864 | ||
| 1865 | if (tb[IFLA_EXT_MASK]) | ||
| 1866 | ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); | ||
| 1867 | |||
| 1853 | ifm = nlmsg_data(nlh); | 1868 | ifm = nlmsg_data(nlh); |
| 1854 | if (ifm->ifi_index > 0) | 1869 | if (ifm->ifi_index > 0) |
| 1855 | dev = __dev_get_by_index(net, ifm->ifi_index); | 1870 | dev = __dev_get_by_index(net, ifm->ifi_index); |
| @@ -1861,12 +1876,12 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
| 1861 | if (dev == NULL) | 1876 | if (dev == NULL) |
| 1862 | return -ENODEV; | 1877 | return -ENODEV; |
| 1863 | 1878 | ||
| 1864 | nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL); | 1879 | nskb = nlmsg_new(if_nlmsg_size(dev, ext_filter_mask), GFP_KERNEL); |
| 1865 | if (nskb == NULL) | 1880 | if (nskb == NULL) |
| 1866 | return -ENOBUFS; | 1881 | return -ENOBUFS; |
| 1867 | 1882 | ||
| 1868 | err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid, | 1883 | err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid, |
| 1869 | nlh->nlmsg_seq, 0, 0); | 1884 | nlh->nlmsg_seq, 0, 0, ext_filter_mask); |
| 1870 | if (err < 0) { | 1885 | if (err < 0) { |
| 1871 | /* -EMSGSIZE implies BUG in if_nlmsg_size */ | 1886 | /* -EMSGSIZE implies BUG in if_nlmsg_size */ |
| 1872 | WARN_ON(err == -EMSGSIZE); | 1887 | WARN_ON(err == -EMSGSIZE); |
| @@ -1877,8 +1892,31 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
| 1877 | return err; | 1892 | return err; |
| 1878 | } | 1893 | } |
| 1879 | 1894 | ||
| 1880 | static u16 rtnl_calcit(struct sk_buff *skb) | 1895 | static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) |
| 1881 | { | 1896 | { |
| 1897 | struct net *net = sock_net(skb->sk); | ||
| 1898 | struct net_device *dev; | ||
| 1899 | struct nlattr *tb[IFLA_MAX+1]; | ||
| 1900 | u32 ext_filter_mask = 0; | ||
| 1901 | u16 min_ifinfo_dump_size = 0; | ||
| 1902 | |||
| 1903 | nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ifla_policy); | ||
| 1904 | |||
| 1905 | if (tb[IFLA_EXT_MASK]) | ||
| 1906 | ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); | ||
| 1907 | |||
| 1908 | if (!ext_filter_mask) | ||
| 1909 | return NLMSG_GOODSIZE; | ||
| 1910 | /* | ||
| 1911 | * traverse the list of net devices and compute the minimum | ||
| 1912 | * buffer size based upon the filter mask. | ||
| 1913 | */ | ||
| 1914 | list_for_each_entry(dev, &net->dev_base_head, dev_list) { | ||
| 1915 | min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size, | ||
| 1916 | if_nlmsg_size(dev, | ||
| 1917 | ext_filter_mask)); | ||
| 1918 | } | ||
| 1919 | |||
| 1882 | return min_ifinfo_dump_size; | 1920 | return min_ifinfo_dump_size; |
| 1883 | } | 1921 | } |
| 1884 | 1922 | ||
| @@ -1913,13 +1951,11 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) | |||
| 1913 | int err = -ENOBUFS; | 1951 | int err = -ENOBUFS; |
| 1914 | size_t if_info_size; | 1952 | size_t if_info_size; |
| 1915 | 1953 | ||
| 1916 | skb = nlmsg_new((if_info_size = if_nlmsg_size(dev)), GFP_KERNEL); | 1954 | skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), GFP_KERNEL); |
| 1917 | if (skb == NULL) | 1955 | if (skb == NULL) |
| 1918 | goto errout; | 1956 | goto errout; |
| 1919 | 1957 | ||
| 1920 | min_ifinfo_dump_size = max_t(u16, if_info_size, min_ifinfo_dump_size); | 1958 | err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0, 0); |
| 1921 | |||
| 1922 | err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0); | ||
| 1923 | if (err < 0) { | 1959 | if (err < 0) { |
| 1924 | /* -EMSGSIZE implies BUG in if_nlmsg_size() */ | 1960 | /* -EMSGSIZE implies BUG in if_nlmsg_size() */ |
| 1925 | WARN_ON(err == -EMSGSIZE); | 1961 | WARN_ON(err == -EMSGSIZE); |
| @@ -1977,7 +2013,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 1977 | return -EOPNOTSUPP; | 2013 | return -EOPNOTSUPP; |
| 1978 | calcit = rtnl_get_calcit(family, type); | 2014 | calcit = rtnl_get_calcit(family, type); |
| 1979 | if (calcit) | 2015 | if (calcit) |
| 1980 | min_dump_alloc = calcit(skb); | 2016 | min_dump_alloc = calcit(skb, nlh); |
| 1981 | 2017 | ||
| 1982 | __rtnl_unlock(); | 2018 | __rtnl_unlock(); |
| 1983 | rtnl = net->rtnl; | 2019 | rtnl = net->rtnl; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 6b3ca5ba4450..38673d2860e2 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
| @@ -65,7 +65,7 @@ | |||
| 65 | it is infeasible task. The most general solutions would be | 65 | it is infeasible task. The most general solutions would be |
| 66 | to keep skb->encapsulation counter (sort of local ttl), | 66 | to keep skb->encapsulation counter (sort of local ttl), |
| 67 | and silently drop packet when it expires. It is a good | 67 | and silently drop packet when it expires. It is a good |
| 68 | solution, but it supposes maintaing new variable in ALL | 68 | solution, but it supposes maintaining new variable in ALL |
| 69 | skb, even if no tunneling is used. | 69 | skb, even if no tunneling is used. |
| 70 | 70 | ||
| 71 | Current solution: xmit_recursion breaks dead loops. This is a percpu | 71 | Current solution: xmit_recursion breaks dead loops. This is a percpu |
| @@ -91,14 +91,14 @@ | |||
| 91 | 91 | ||
| 92 | One of them is to parse packet trying to detect inner encapsulation | 92 | One of them is to parse packet trying to detect inner encapsulation |
| 93 | made by our node. It is difficult or even impossible, especially, | 93 | made by our node. It is difficult or even impossible, especially, |
| 94 | taking into account fragmentation. TO be short, tt is not solution at all. | 94 | taking into account fragmentation. TO be short, ttl is not solution at all. |
| 95 | 95 | ||
| 96 | Current solution: The solution was UNEXPECTEDLY SIMPLE. | 96 | Current solution: The solution was UNEXPECTEDLY SIMPLE. |
| 97 | We force DF flag on tunnels with preconfigured hop limit, | 97 | We force DF flag on tunnels with preconfigured hop limit, |
| 98 | that is ALL. :-) Well, it does not remove the problem completely, | 98 | that is ALL. :-) Well, it does not remove the problem completely, |
| 99 | but exponential growth of network traffic is changed to linear | 99 | but exponential growth of network traffic is changed to linear |
| 100 | (branches, that exceed pmtu are pruned) and tunnel mtu | 100 | (branches, that exceed pmtu are pruned) and tunnel mtu |
| 101 | fastly degrades to value <68, where looping stops. | 101 | rapidly degrades to value <68, where looping stops. |
| 102 | Yes, it is not good if there exists a router in the loop, | 102 | Yes, it is not good if there exists a router in the loop, |
| 103 | which does not force DF, even when encapsulating packets have DF set. | 103 | which does not force DF, even when encapsulating packets have DF set. |
| 104 | But it is not our problem! Nobody could accuse us, we made | 104 | But it is not our problem! Nobody could accuse us, we made |
| @@ -457,8 +457,8 @@ static void ipgre_err(struct sk_buff *skb, u32 info) | |||
| 457 | GRE tunnels with enabled checksum. Tell them "thank you". | 457 | GRE tunnels with enabled checksum. Tell them "thank you". |
| 458 | 458 | ||
| 459 | Well, I wonder, rfc1812 was written by Cisco employee, | 459 | Well, I wonder, rfc1812 was written by Cisco employee, |
| 460 | what the hell these idiots break standrads established | 460 | what the hell these idiots break standards established |
| 461 | by themself??? | 461 | by themselves??? |
| 462 | */ | 462 | */ |
| 463 | 463 | ||
| 464 | const struct iphdr *iph = (const struct iphdr *)skb->data; | 464 | const struct iphdr *iph = (const struct iphdr *)skb->data; |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index aea5a199c37a..b072386cee21 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
| @@ -630,6 +630,7 @@ static int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 630 | 630 | ||
| 631 | pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num); | 631 | pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num); |
| 632 | 632 | ||
| 633 | err = -EOPNOTSUPP; | ||
| 633 | if (flags & MSG_OOB) | 634 | if (flags & MSG_OOB) |
| 634 | goto out; | 635 | goto out; |
| 635 | 636 | ||
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index 63418185f524..e3db3f915114 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c | |||
| @@ -110,10 +110,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) | |||
| 110 | 110 | ||
| 111 | skb_push(skb, sizeof(*iph)); | 111 | skb_push(skb, sizeof(*iph)); |
| 112 | skb_reset_network_header(skb); | 112 | skb_reset_network_header(skb); |
| 113 | 113 | skb_mac_header_rebuild(skb); | |
| 114 | memmove(skb->data - skb->mac_len, skb_mac_header(skb), | ||
| 115 | skb->mac_len); | ||
| 116 | skb_set_mac_header(skb, -skb->mac_len); | ||
| 117 | 114 | ||
| 118 | xfrm4_beet_make_header(skb); | 115 | xfrm4_beet_make_header(skb); |
| 119 | 116 | ||
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 534972e114ac..ed4bf11ef9f4 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c | |||
| @@ -66,7 +66,6 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 66 | 66 | ||
| 67 | static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | 67 | static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) |
| 68 | { | 68 | { |
| 69 | const unsigned char *old_mac; | ||
| 70 | int err = -EINVAL; | 69 | int err = -EINVAL; |
| 71 | 70 | ||
| 72 | if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP) | 71 | if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP) |
| @@ -84,10 +83,9 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | |||
| 84 | if (!(x->props.flags & XFRM_STATE_NOECN)) | 83 | if (!(x->props.flags & XFRM_STATE_NOECN)) |
| 85 | ipip_ecn_decapsulate(skb); | 84 | ipip_ecn_decapsulate(skb); |
| 86 | 85 | ||
| 87 | old_mac = skb_mac_header(skb); | ||
| 88 | skb_set_mac_header(skb, -skb->mac_len); | ||
| 89 | memmove(skb_mac_header(skb), old_mac, skb->mac_len); | ||
| 90 | skb_reset_network_header(skb); | 86 | skb_reset_network_header(skb); |
| 87 | skb_mac_header_rebuild(skb); | ||
| 88 | |||
| 91 | err = 0; | 89 | err = 0; |
| 92 | 90 | ||
| 93 | out: | 91 | out: |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index c7e95c8c579f..5aa3981a3922 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
| @@ -1926,8 +1926,10 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt, | |||
| 1926 | }; | 1926 | }; |
| 1927 | 1927 | ||
| 1928 | dst = ip6_route_output(net, NULL, &fl6); | 1928 | dst = ip6_route_output(net, NULL, &fl6); |
| 1929 | if (!dst) | 1929 | if (dst->error) { |
| 1930 | dst_release(dst); | ||
| 1930 | goto out_free; | 1931 | goto out_free; |
| 1932 | } | ||
| 1931 | 1933 | ||
| 1932 | skb_dst_drop(skb); | 1934 | skb_dst_drop(skb); |
| 1933 | skb_dst_set(skb, dst); | 1935 | skb_dst_set(skb, dst); |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index d8f02ef88e59..c964958ac470 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1545,9 +1545,10 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | |||
| 1545 | &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex); | 1545 | &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex); |
| 1546 | 1546 | ||
| 1547 | dst = ip6_route_output(net, NULL, &fl6); | 1547 | dst = ip6_route_output(net, NULL, &fl6); |
| 1548 | if (dst == NULL) | 1548 | if (dst->error) { |
| 1549 | dst_release(dst); | ||
| 1549 | return; | 1550 | return; |
| 1550 | 1551 | } | |
| 1551 | dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); | 1552 | dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); |
| 1552 | if (IS_ERR(dst)) | 1553 | if (IS_ERR(dst)) |
| 1553 | return; | 1554 | return; |
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c index a81ce9450750..9949a356d62c 100644 --- a/net/ipv6/xfrm6_mode_beet.c +++ b/net/ipv6/xfrm6_mode_beet.c | |||
| @@ -80,7 +80,6 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 80 | static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) | 80 | static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) |
| 81 | { | 81 | { |
| 82 | struct ipv6hdr *ip6h; | 82 | struct ipv6hdr *ip6h; |
| 83 | const unsigned char *old_mac; | ||
| 84 | int size = sizeof(struct ipv6hdr); | 83 | int size = sizeof(struct ipv6hdr); |
| 85 | int err; | 84 | int err; |
| 86 | 85 | ||
| @@ -90,10 +89,7 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) | |||
| 90 | 89 | ||
| 91 | __skb_push(skb, size); | 90 | __skb_push(skb, size); |
| 92 | skb_reset_network_header(skb); | 91 | skb_reset_network_header(skb); |
| 93 | 92 | skb_mac_header_rebuild(skb); | |
| 94 | old_mac = skb_mac_header(skb); | ||
| 95 | skb_set_mac_header(skb, -skb->mac_len); | ||
| 96 | memmove(skb_mac_header(skb), old_mac, skb->mac_len); | ||
| 97 | 93 | ||
| 98 | xfrm6_beet_make_header(skb); | 94 | xfrm6_beet_make_header(skb); |
| 99 | 95 | ||
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 261e6e6f487e..9f2095b19ad0 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c | |||
| @@ -63,7 +63,6 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 63 | static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | 63 | static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) |
| 64 | { | 64 | { |
| 65 | int err = -EINVAL; | 65 | int err = -EINVAL; |
| 66 | const unsigned char *old_mac; | ||
| 67 | 66 | ||
| 68 | if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) | 67 | if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) |
| 69 | goto out; | 68 | goto out; |
| @@ -80,10 +79,9 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | |||
| 80 | if (!(x->props.flags & XFRM_STATE_NOECN)) | 79 | if (!(x->props.flags & XFRM_STATE_NOECN)) |
| 81 | ipip6_ecn_decapsulate(skb); | 80 | ipip6_ecn_decapsulate(skb); |
| 82 | 81 | ||
| 83 | old_mac = skb_mac_header(skb); | ||
| 84 | skb_set_mac_header(skb, -skb->mac_len); | ||
| 85 | memmove(skb_mac_header(skb), old_mac, skb->mac_len); | ||
| 86 | skb_reset_network_header(skb); | 82 | skb_reset_network_header(skb); |
| 83 | skb_mac_header_rebuild(skb); | ||
| 84 | |||
| 87 | err = 0; | 85 | err = 0; |
| 88 | 86 | ||
| 89 | out: | 87 | out: |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 611c3359b94d..2555816e7788 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
| @@ -232,6 +232,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc, | |||
| 232 | __be16 dport = 0; /* destination port to forward */ | 232 | __be16 dport = 0; /* destination port to forward */ |
| 233 | unsigned int flags; | 233 | unsigned int flags; |
| 234 | struct ip_vs_conn_param param; | 234 | struct ip_vs_conn_param param; |
| 235 | const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; | ||
| 235 | union nf_inet_addr snet; /* source network of the client, | 236 | union nf_inet_addr snet; /* source network of the client, |
| 236 | after masking */ | 237 | after masking */ |
| 237 | 238 | ||
| @@ -267,7 +268,6 @@ ip_vs_sched_persist(struct ip_vs_service *svc, | |||
| 267 | { | 268 | { |
| 268 | int protocol = iph.protocol; | 269 | int protocol = iph.protocol; |
| 269 | const union nf_inet_addr *vaddr = &iph.daddr; | 270 | const union nf_inet_addr *vaddr = &iph.daddr; |
| 270 | const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; | ||
| 271 | __be16 vport = 0; | 271 | __be16 vport = 0; |
| 272 | 272 | ||
| 273 | if (dst_port == svc->port) { | 273 | if (dst_port == svc->port) { |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 76613f5a55c0..ed86a3be678e 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -404,19 +404,49 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct, | |||
| 404 | &net->ct.hash[repl_hash]); | 404 | &net->ct.hash[repl_hash]); |
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | void nf_conntrack_hash_insert(struct nf_conn *ct) | 407 | int |
| 408 | nf_conntrack_hash_check_insert(struct nf_conn *ct) | ||
| 408 | { | 409 | { |
| 409 | struct net *net = nf_ct_net(ct); | 410 | struct net *net = nf_ct_net(ct); |
| 410 | unsigned int hash, repl_hash; | 411 | unsigned int hash, repl_hash; |
| 412 | struct nf_conntrack_tuple_hash *h; | ||
| 413 | struct hlist_nulls_node *n; | ||
| 411 | u16 zone; | 414 | u16 zone; |
| 412 | 415 | ||
| 413 | zone = nf_ct_zone(ct); | 416 | zone = nf_ct_zone(ct); |
| 414 | hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); | 417 | hash = hash_conntrack(net, zone, |
| 415 | repl_hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_REPLY].tuple); | 418 | &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); |
| 419 | repl_hash = hash_conntrack(net, zone, | ||
| 420 | &ct->tuplehash[IP_CT_DIR_REPLY].tuple); | ||
| 421 | |||
| 422 | spin_lock_bh(&nf_conntrack_lock); | ||
| 416 | 423 | ||
| 424 | /* See if there's one in the list already, including reverse */ | ||
| 425 | hlist_nulls_for_each_entry(h, n, &net->ct.hash[hash], hnnode) | ||
| 426 | if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, | ||
| 427 | &h->tuple) && | ||
| 428 | zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h))) | ||
| 429 | goto out; | ||
| 430 | hlist_nulls_for_each_entry(h, n, &net->ct.hash[repl_hash], hnnode) | ||
| 431 | if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, | ||
| 432 | &h->tuple) && | ||
| 433 | zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h))) | ||
| 434 | goto out; | ||
| 435 | |||
| 436 | add_timer(&ct->timeout); | ||
| 437 | nf_conntrack_get(&ct->ct_general); | ||
| 417 | __nf_conntrack_hash_insert(ct, hash, repl_hash); | 438 | __nf_conntrack_hash_insert(ct, hash, repl_hash); |
| 439 | NF_CT_STAT_INC(net, insert); | ||
| 440 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 441 | |||
| 442 | return 0; | ||
| 443 | |||
| 444 | out: | ||
| 445 | NF_CT_STAT_INC(net, insert_failed); | ||
| 446 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 447 | return -EEXIST; | ||
| 418 | } | 448 | } |
| 419 | EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert); | 449 | EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert); |
| 420 | 450 | ||
| 421 | /* Confirm a connection given skb; places it in hash table */ | 451 | /* Confirm a connection given skb; places it in hash table */ |
| 422 | int | 452 | int |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 9307b033c0c9..30c9d4ca0218 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -1367,15 +1367,12 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, | |||
| 1367 | nf_ct_protonum(ct)); | 1367 | nf_ct_protonum(ct)); |
| 1368 | if (helper == NULL) { | 1368 | if (helper == NULL) { |
| 1369 | rcu_read_unlock(); | 1369 | rcu_read_unlock(); |
| 1370 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 1371 | #ifdef CONFIG_MODULES | 1370 | #ifdef CONFIG_MODULES |
| 1372 | if (request_module("nfct-helper-%s", helpname) < 0) { | 1371 | if (request_module("nfct-helper-%s", helpname) < 0) { |
| 1373 | spin_lock_bh(&nf_conntrack_lock); | ||
| 1374 | err = -EOPNOTSUPP; | 1372 | err = -EOPNOTSUPP; |
| 1375 | goto err1; | 1373 | goto err1; |
| 1376 | } | 1374 | } |
| 1377 | 1375 | ||
| 1378 | spin_lock_bh(&nf_conntrack_lock); | ||
| 1379 | rcu_read_lock(); | 1376 | rcu_read_lock(); |
| 1380 | helper = __nf_conntrack_helper_find(helpname, | 1377 | helper = __nf_conntrack_helper_find(helpname, |
| 1381 | nf_ct_l3num(ct), | 1378 | nf_ct_l3num(ct), |
| @@ -1468,8 +1465,10 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, | |||
| 1468 | if (tstamp) | 1465 | if (tstamp) |
| 1469 | tstamp->start = ktime_to_ns(ktime_get_real()); | 1466 | tstamp->start = ktime_to_ns(ktime_get_real()); |
| 1470 | 1467 | ||
| 1471 | add_timer(&ct->timeout); | 1468 | err = nf_conntrack_hash_check_insert(ct); |
| 1472 | nf_conntrack_hash_insert(ct); | 1469 | if (err < 0) |
| 1470 | goto err2; | ||
| 1471 | |||
| 1473 | rcu_read_unlock(); | 1472 | rcu_read_unlock(); |
| 1474 | 1473 | ||
| 1475 | return ct; | 1474 | return ct; |
| @@ -1490,6 +1489,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 1490 | struct nf_conntrack_tuple otuple, rtuple; | 1489 | struct nf_conntrack_tuple otuple, rtuple; |
| 1491 | struct nf_conntrack_tuple_hash *h = NULL; | 1490 | struct nf_conntrack_tuple_hash *h = NULL; |
| 1492 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); | 1491 | struct nfgenmsg *nfmsg = nlmsg_data(nlh); |
| 1492 | struct nf_conn *ct; | ||
| 1493 | u_int8_t u3 = nfmsg->nfgen_family; | 1493 | u_int8_t u3 = nfmsg->nfgen_family; |
| 1494 | u16 zone; | 1494 | u16 zone; |
| 1495 | int err; | 1495 | int err; |
| @@ -1510,27 +1510,22 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 1510 | return err; | 1510 | return err; |
| 1511 | } | 1511 | } |
| 1512 | 1512 | ||
| 1513 | spin_lock_bh(&nf_conntrack_lock); | ||
| 1514 | if (cda[CTA_TUPLE_ORIG]) | 1513 | if (cda[CTA_TUPLE_ORIG]) |
| 1515 | h = __nf_conntrack_find(net, zone, &otuple); | 1514 | h = nf_conntrack_find_get(net, zone, &otuple); |
| 1516 | else if (cda[CTA_TUPLE_REPLY]) | 1515 | else if (cda[CTA_TUPLE_REPLY]) |
| 1517 | h = __nf_conntrack_find(net, zone, &rtuple); | 1516 | h = nf_conntrack_find_get(net, zone, &rtuple); |
| 1518 | 1517 | ||
| 1519 | if (h == NULL) { | 1518 | if (h == NULL) { |
| 1520 | err = -ENOENT; | 1519 | err = -ENOENT; |
| 1521 | if (nlh->nlmsg_flags & NLM_F_CREATE) { | 1520 | if (nlh->nlmsg_flags & NLM_F_CREATE) { |
| 1522 | struct nf_conn *ct; | ||
| 1523 | enum ip_conntrack_events events; | 1521 | enum ip_conntrack_events events; |
| 1524 | 1522 | ||
| 1525 | ct = ctnetlink_create_conntrack(net, zone, cda, &otuple, | 1523 | ct = ctnetlink_create_conntrack(net, zone, cda, &otuple, |
| 1526 | &rtuple, u3); | 1524 | &rtuple, u3); |
| 1527 | if (IS_ERR(ct)) { | 1525 | if (IS_ERR(ct)) |
| 1528 | err = PTR_ERR(ct); | 1526 | return PTR_ERR(ct); |
| 1529 | goto out_unlock; | 1527 | |
| 1530 | } | ||
| 1531 | err = 0; | 1528 | err = 0; |
| 1532 | nf_conntrack_get(&ct->ct_general); | ||
| 1533 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 1534 | if (test_bit(IPS_EXPECTED_BIT, &ct->status)) | 1529 | if (test_bit(IPS_EXPECTED_BIT, &ct->status)) |
| 1535 | events = IPCT_RELATED; | 1530 | events = IPCT_RELATED; |
| 1536 | else | 1531 | else |
| @@ -1545,23 +1540,19 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 1545 | ct, NETLINK_CB(skb).pid, | 1540 | ct, NETLINK_CB(skb).pid, |
| 1546 | nlmsg_report(nlh)); | 1541 | nlmsg_report(nlh)); |
| 1547 | nf_ct_put(ct); | 1542 | nf_ct_put(ct); |
| 1548 | } else | 1543 | } |
| 1549 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 1550 | 1544 | ||
| 1551 | return err; | 1545 | return err; |
| 1552 | } | 1546 | } |
| 1553 | /* implicit 'else' */ | 1547 | /* implicit 'else' */ |
| 1554 | 1548 | ||
| 1555 | /* We manipulate the conntrack inside the global conntrack table lock, | ||
| 1556 | * so there's no need to increase the refcount */ | ||
| 1557 | err = -EEXIST; | 1549 | err = -EEXIST; |
| 1550 | ct = nf_ct_tuplehash_to_ctrack(h); | ||
| 1558 | if (!(nlh->nlmsg_flags & NLM_F_EXCL)) { | 1551 | if (!(nlh->nlmsg_flags & NLM_F_EXCL)) { |
| 1559 | struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); | 1552 | spin_lock_bh(&nf_conntrack_lock); |
| 1560 | |||
| 1561 | err = ctnetlink_change_conntrack(ct, cda); | 1553 | err = ctnetlink_change_conntrack(ct, cda); |
| 1554 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 1562 | if (err == 0) { | 1555 | if (err == 0) { |
| 1563 | nf_conntrack_get(&ct->ct_general); | ||
| 1564 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 1565 | nf_conntrack_eventmask_report((1 << IPCT_REPLY) | | 1556 | nf_conntrack_eventmask_report((1 << IPCT_REPLY) | |
| 1566 | (1 << IPCT_ASSURED) | | 1557 | (1 << IPCT_ASSURED) | |
| 1567 | (1 << IPCT_HELPER) | | 1558 | (1 << IPCT_HELPER) | |
| @@ -1570,15 +1561,10 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
| 1570 | (1 << IPCT_MARK), | 1561 | (1 << IPCT_MARK), |
| 1571 | ct, NETLINK_CB(skb).pid, | 1562 | ct, NETLINK_CB(skb).pid, |
| 1572 | nlmsg_report(nlh)); | 1563 | nlmsg_report(nlh)); |
| 1573 | nf_ct_put(ct); | 1564 | } |
| 1574 | } else | ||
| 1575 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 1576 | |||
| 1577 | return err; | ||
| 1578 | } | 1565 | } |
| 1579 | 1566 | ||
| 1580 | out_unlock: | 1567 | nf_ct_put(ct); |
| 1581 | spin_unlock_bh(&nf_conntrack_lock); | ||
| 1582 | return err; | 1568 | return err; |
| 1583 | } | 1569 | } |
| 1584 | 1570 | ||
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index b3a7db678b8d..ce60cf0f6c11 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
| @@ -203,6 +203,27 @@ err: | |||
| 203 | return status; | 203 | return status; |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | #ifdef CONFIG_BRIDGE_NETFILTER | ||
| 207 | /* When called from bridge netfilter, skb->data must point to MAC header | ||
| 208 | * before calling skb_gso_segment(). Else, original MAC header is lost | ||
| 209 | * and segmented skbs will be sent to wrong destination. | ||
| 210 | */ | ||
| 211 | static void nf_bridge_adjust_skb_data(struct sk_buff *skb) | ||
| 212 | { | ||
| 213 | if (skb->nf_bridge) | ||
| 214 | __skb_push(skb, skb->network_header - skb->mac_header); | ||
| 215 | } | ||
| 216 | |||
| 217 | static void nf_bridge_adjust_segmented_data(struct sk_buff *skb) | ||
| 218 | { | ||
| 219 | if (skb->nf_bridge) | ||
| 220 | __skb_pull(skb, skb->network_header - skb->mac_header); | ||
| 221 | } | ||
| 222 | #else | ||
| 223 | #define nf_bridge_adjust_skb_data(s) do {} while (0) | ||
| 224 | #define nf_bridge_adjust_segmented_data(s) do {} while (0) | ||
| 225 | #endif | ||
| 226 | |||
| 206 | int nf_queue(struct sk_buff *skb, | 227 | int nf_queue(struct sk_buff *skb, |
| 207 | struct list_head *elem, | 228 | struct list_head *elem, |
| 208 | u_int8_t pf, unsigned int hook, | 229 | u_int8_t pf, unsigned int hook, |
| @@ -212,7 +233,7 @@ int nf_queue(struct sk_buff *skb, | |||
| 212 | unsigned int queuenum) | 233 | unsigned int queuenum) |
| 213 | { | 234 | { |
| 214 | struct sk_buff *segs; | 235 | struct sk_buff *segs; |
| 215 | int err; | 236 | int err = -EINVAL; |
| 216 | unsigned int queued; | 237 | unsigned int queued; |
| 217 | 238 | ||
| 218 | if (!skb_is_gso(skb)) | 239 | if (!skb_is_gso(skb)) |
| @@ -228,23 +249,25 @@ int nf_queue(struct sk_buff *skb, | |||
| 228 | break; | 249 | break; |
| 229 | } | 250 | } |
| 230 | 251 | ||
| 252 | nf_bridge_adjust_skb_data(skb); | ||
| 231 | segs = skb_gso_segment(skb, 0); | 253 | segs = skb_gso_segment(skb, 0); |
| 232 | /* Does not use PTR_ERR to limit the number of error codes that can be | 254 | /* Does not use PTR_ERR to limit the number of error codes that can be |
| 233 | * returned by nf_queue. For instance, callers rely on -ECANCELED to mean | 255 | * returned by nf_queue. For instance, callers rely on -ECANCELED to mean |
| 234 | * 'ignore this hook'. | 256 | * 'ignore this hook'. |
| 235 | */ | 257 | */ |
| 236 | if (IS_ERR(segs)) | 258 | if (IS_ERR(segs)) |
| 237 | return -EINVAL; | 259 | goto out_err; |
| 238 | |||
| 239 | queued = 0; | 260 | queued = 0; |
| 240 | err = 0; | 261 | err = 0; |
| 241 | do { | 262 | do { |
| 242 | struct sk_buff *nskb = segs->next; | 263 | struct sk_buff *nskb = segs->next; |
| 243 | 264 | ||
| 244 | segs->next = NULL; | 265 | segs->next = NULL; |
| 245 | if (err == 0) | 266 | if (err == 0) { |
| 267 | nf_bridge_adjust_segmented_data(segs); | ||
| 246 | err = __nf_queue(segs, elem, pf, hook, indev, | 268 | err = __nf_queue(segs, elem, pf, hook, indev, |
| 247 | outdev, okfn, queuenum); | 269 | outdev, okfn, queuenum); |
| 270 | } | ||
| 248 | if (err == 0) | 271 | if (err == 0) |
| 249 | queued++; | 272 | queued++; |
| 250 | else | 273 | else |
| @@ -252,11 +275,12 @@ int nf_queue(struct sk_buff *skb, | |||
| 252 | segs = nskb; | 275 | segs = nskb; |
| 253 | } while (segs); | 276 | } while (segs); |
| 254 | 277 | ||
| 255 | /* also free orig skb if only some segments were queued */ | 278 | if (queued) { |
| 256 | if (unlikely(err && queued)) | ||
| 257 | err = 0; | ||
| 258 | if (err == 0) | ||
| 259 | kfree_skb(skb); | 279 | kfree_skb(skb); |
| 280 | return 0; | ||
| 281 | } | ||
| 282 | out_err: | ||
| 283 | nf_bridge_adjust_segmented_data(skb); | ||
| 260 | return err; | 284 | return err; |
| 261 | } | 285 | } |
| 262 | 286 | ||
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index 3aae66facf9f..4d5057902839 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c | |||
| @@ -152,9 +152,10 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info) | |||
| 152 | fl6.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) | | 152 | fl6.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) | |
| 153 | (iph->flow_lbl[1] << 8) | iph->flow_lbl[2]; | 153 | (iph->flow_lbl[1] << 8) | iph->flow_lbl[2]; |
| 154 | dst = ip6_route_output(net, NULL, &fl6); | 154 | dst = ip6_route_output(net, NULL, &fl6); |
| 155 | if (dst == NULL) | 155 | if (dst->error) { |
| 156 | dst_release(dst); | ||
| 156 | return false; | 157 | return false; |
| 157 | 158 | } | |
| 158 | skb_dst_drop(skb); | 159 | skb_dst_drop(skb); |
| 159 | skb_dst_set(skb, dst); | 160 | skb_dst_set(skb, dst); |
| 160 | skb->dev = dst->dev; | 161 | skb->dev = dst->dev; |
