diff --git a/[refs] b/[refs] index 48ae50a4f536..cf772dea764b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bff528578fc3c4a14227b052a313109b5ffb73da +refs/heads/master: 279072882dc0149e5740dace075e1a49f087046d diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c index d498f049c74e..32f8799db190 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/main.c @@ -538,7 +538,7 @@ int mlx4_change_port_types(struct mlx4_dev *dev, mlx4_unregister_device(dev); for (port = 1; port <= dev->caps.num_ports; port++) { mlx4_CLOSE_PORT(dev, port); - dev->caps.port_type[port] = port_types[port - 1]; + dev->caps.port_type[port + 1] = port_types[port]; err = mlx4_SET_PORT(dev, port); if (err) { mlx4_err(dev, "Failed to set port %d, " diff --git a/trunk/drivers/net/ethernet/ti/davinci_emac.c b/trunk/drivers/net/ethernet/ti/davinci_emac.c index 4b2f54565f64..4fa0bcb25dfc 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_emac.c +++ b/trunk/drivers/net/ethernet/ti/davinci_emac.c @@ -1009,7 +1009,7 @@ static void emac_rx_handler(void *token, int len, int status) int ret; /* free and bail if we are shutting down */ - if (unlikely(!netif_running(ndev))) { + if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) { dev_kfree_skb_any(skb); return; } @@ -1038,9 +1038,7 @@ static void emac_rx_handler(void *token, int len, int status) recycle: ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, skb_tailroom(skb), GFP_KERNEL); - - WARN_ON(ret == -ENOMEM); - if (unlikely(ret < 0)) + if (WARN_ON(ret < 0)) dev_kfree_skb_any(skb); } diff --git a/trunk/drivers/net/phy/icplus.c b/trunk/drivers/net/phy/icplus.c index 0856e1b7a849..c81f136ae670 100644 --- a/trunk/drivers/net/phy/icplus.c +++ b/trunk/drivers/net/phy/icplus.c @@ -30,16 +30,16 @@ #include #include -MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers"); +MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IC1001 PHY drivers"); MODULE_AUTHOR("Michael Barkowski"); MODULE_LICENSE("GPL"); -/* IP101A/G - IP1001 */ -#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ -#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ -#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ -#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ -#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ +/* IP101A/IP1001 */ +#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ +#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ +#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ +#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ +#define IP101A_APS_ON 2 /* IP101A APS Mode bit */ static int ip175c_config_init(struct phy_device *phydev) { @@ -98,24 +98,20 @@ static int ip175c_config_init(struct phy_device *phydev) static int ip1xx_reset(struct phy_device *phydev) { - int bmcr; + int err, bmcr; /* Software Reset PHY */ bmcr = phy_read(phydev, MII_BMCR); - if (bmcr < 0) - return bmcr; bmcr |= BMCR_RESET; - bmcr = phy_write(phydev, MII_BMCR, bmcr); - if (bmcr < 0) - return bmcr; + err = phy_write(phydev, MII_BMCR, bmcr); + if (err < 0) + return err; do { bmcr = phy_read(phydev, MII_BMCR); - if (bmcr < 0) - return bmcr; } while (bmcr & BMCR_RESET); - return 0; + return err; } static int ip1001_config_init(struct phy_device *phydev) @@ -128,10 +124,7 @@ static int ip1001_config_init(struct phy_device *phydev) /* Enable Auto Power Saving mode */ c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2); - if (c < 0) - return c; c |= IP1001_APS_ON; - c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c); if (c < 0) return c; @@ -139,19 +132,14 @@ static int ip1001_config_init(struct phy_device *phydev) /* Additional delay (2ns) used to adjust RX clock phase * at RGMII interface */ c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); - if (c < 0) - return c; - c |= IP1001_PHASE_SEL_MASK; c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); - if (c < 0) - return c; } - return 0; + return c; } -static int ip101a_g_config_init(struct phy_device *phydev) +static int ip101a_config_init(struct phy_device *phydev) { int c; @@ -161,7 +149,7 @@ static int ip101a_g_config_init(struct phy_device *phydev) /* Enable Auto Power Saving mode */ c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); - c |= IP101A_G_APS_ON; + c |= IP101A_APS_ON; return c; } @@ -203,7 +191,6 @@ static struct phy_driver ip1001_driver = { .phy_id_mask = 0x0ffffff0, .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_INTERRUPT, .config_init = &ip1001_config_init, .config_aneg = &genphy_config_aneg, .read_status = &genphy_read_status, @@ -212,14 +199,13 @@ static struct phy_driver ip1001_driver = { .driver = { .owner = THIS_MODULE,}, }; -static struct phy_driver ip101a_g_driver = { +static struct phy_driver ip101a_driver = { .phy_id = 0x02430c54, - .name = "ICPlus IP101A/G", + .name = "ICPlus IP101A", .phy_id_mask = 0x0ffffff0, .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, - .flags = PHY_HAS_INTERRUPT, - .config_init = &ip101a_g_config_init, + .config_init = &ip101a_config_init, .config_aneg = &genphy_config_aneg, .read_status = &genphy_read_status, .suspend = genphy_suspend, @@ -235,7 +221,7 @@ static int __init icplus_init(void) if (ret < 0) return -ENODEV; - ret = phy_driver_register(&ip101a_g_driver); + ret = phy_driver_register(&ip101a_driver); if (ret < 0) return -ENODEV; @@ -245,7 +231,7 @@ static int __init icplus_init(void) static void __exit icplus_exit(void) { phy_driver_unregister(&ip1001_driver); - phy_driver_unregister(&ip101a_g_driver); + phy_driver_unregister(&ip101a_driver); phy_driver_unregister(&ip175c_driver); } @@ -255,7 +241,6 @@ module_exit(icplus_exit); static struct mdio_device_id __maybe_unused icplus_tbl[] = { { 0x02430d80, 0x0ffffff0 }, { 0x02430d90, 0x0ffffff0 }, - { 0x02430c54, 0x0ffffff0 }, { } }; diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index ae86adee3746..50db9b04a552 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -1465,16 +1465,6 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset) } #endif /* NET_SKBUFF_DATA_USES_OFFSET */ -static inline void skb_mac_header_rebuild(struct sk_buff *skb) -{ - if (skb_mac_header_was_set(skb)) { - const unsigned char *old_mac = skb_mac_header(skb); - - skb_set_mac_header(skb, -skb->mac_len); - memmove(skb_mac_header(skb), old_mac, skb->mac_len); - } -} - static inline int skb_checksum_start_offset(const struct sk_buff *skb) { return skb->csum_start - skb_headroom(skb); diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 38673d2860e2..6b3ca5ba4450 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -65,7 +65,7 @@ it is infeasible task. The most general solutions would be to keep skb->encapsulation counter (sort of local ttl), and silently drop packet when it expires. It is a good - solution, but it supposes maintaining new variable in ALL + solution, but it supposes maintaing new variable in ALL skb, even if no tunneling is used. Current solution: xmit_recursion breaks dead loops. This is a percpu @@ -91,14 +91,14 @@ One of them is to parse packet trying to detect inner encapsulation made by our node. It is difficult or even impossible, especially, - taking into account fragmentation. TO be short, ttl is not solution at all. + taking into account fragmentation. TO be short, tt is not solution at all. Current solution: The solution was UNEXPECTEDLY SIMPLE. We force DF flag on tunnels with preconfigured hop limit, that is ALL. :-) Well, it does not remove the problem completely, but exponential growth of network traffic is changed to linear (branches, that exceed pmtu are pruned) and tunnel mtu - rapidly degrades to value <68, where looping stops. + fastly degrades to value <68, where looping stops. Yes, it is not good if there exists a router in the loop, which does not force DF, even when encapsulating packets have DF set. 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) GRE tunnels with enabled checksum. Tell them "thank you". Well, I wonder, rfc1812 was written by Cisco employee, - what the hell these idiots break standards established - by themselves??? + what the hell these idiots break standrads established + by themself??? */ const struct iphdr *iph = (const struct iphdr *)skb->data; diff --git a/trunk/net/ipv4/xfrm4_mode_beet.c b/trunk/net/ipv4/xfrm4_mode_beet.c index e3db3f915114..63418185f524 100644 --- a/trunk/net/ipv4/xfrm4_mode_beet.c +++ b/trunk/net/ipv4/xfrm4_mode_beet.c @@ -110,7 +110,10 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) skb_push(skb, sizeof(*iph)); skb_reset_network_header(skb); - skb_mac_header_rebuild(skb); + + memmove(skb->data - skb->mac_len, skb_mac_header(skb), + skb->mac_len); + skb_set_mac_header(skb, -skb->mac_len); xfrm4_beet_make_header(skb); diff --git a/trunk/net/ipv4/xfrm4_mode_tunnel.c b/trunk/net/ipv4/xfrm4_mode_tunnel.c index ed4bf11ef9f4..534972e114ac 100644 --- a/trunk/net/ipv4/xfrm4_mode_tunnel.c +++ b/trunk/net/ipv4/xfrm4_mode_tunnel.c @@ -66,6 +66,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) { + const unsigned char *old_mac; int err = -EINVAL; if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP) @@ -83,9 +84,10 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) if (!(x->props.flags & XFRM_STATE_NOECN)) ipip_ecn_decapsulate(skb); + old_mac = skb_mac_header(skb); + skb_set_mac_header(skb, -skb->mac_len); + memmove(skb_mac_header(skb), old_mac, skb->mac_len); skb_reset_network_header(skb); - skb_mac_header_rebuild(skb); - err = 0; out: diff --git a/trunk/net/ipv6/xfrm6_mode_beet.c b/trunk/net/ipv6/xfrm6_mode_beet.c index 9949a356d62c..a81ce9450750 100644 --- a/trunk/net/ipv6/xfrm6_mode_beet.c +++ b/trunk/net/ipv6/xfrm6_mode_beet.c @@ -80,6 +80,7 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) { struct ipv6hdr *ip6h; + const unsigned char *old_mac; int size = sizeof(struct ipv6hdr); int err; @@ -89,7 +90,10 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) __skb_push(skb, size); skb_reset_network_header(skb); - skb_mac_header_rebuild(skb); + + old_mac = skb_mac_header(skb); + skb_set_mac_header(skb, -skb->mac_len); + memmove(skb_mac_header(skb), old_mac, skb->mac_len); xfrm6_beet_make_header(skb); diff --git a/trunk/net/ipv6/xfrm6_mode_tunnel.c b/trunk/net/ipv6/xfrm6_mode_tunnel.c index 9f2095b19ad0..261e6e6f487e 100644 --- a/trunk/net/ipv6/xfrm6_mode_tunnel.c +++ b/trunk/net/ipv6/xfrm6_mode_tunnel.c @@ -63,6 +63,7 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) { int err = -EINVAL; + const unsigned char *old_mac; if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) goto out; @@ -79,9 +80,10 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) if (!(x->props.flags & XFRM_STATE_NOECN)) ipip6_ecn_decapsulate(skb); + old_mac = skb_mac_header(skb); + skb_set_mac_header(skb, -skb->mac_len); + memmove(skb_mac_header(skb), old_mac, skb->mac_len); skb_reset_network_header(skb); - skb_mac_header_rebuild(skb); - err = 0; out: diff --git a/trunk/net/netfilter/nf_conntrack_netlink.c b/trunk/net/netfilter/nf_conntrack_netlink.c index cc705175765c..9307b033c0c9 100644 --- a/trunk/net/netfilter/nf_conntrack_netlink.c +++ b/trunk/net/netfilter/nf_conntrack_netlink.c @@ -1367,12 +1367,15 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, nf_ct_protonum(ct)); if (helper == NULL) { rcu_read_unlock(); + spin_unlock_bh(&nf_conntrack_lock); #ifdef CONFIG_MODULES if (request_module("nfct-helper-%s", helpname) < 0) { + spin_lock_bh(&nf_conntrack_lock); err = -EOPNOTSUPP; goto err1; } + spin_lock_bh(&nf_conntrack_lock); rcu_read_lock(); helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct), @@ -1466,10 +1469,7 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, tstamp->start = ktime_to_ns(ktime_get_real()); add_timer(&ct->timeout); - spin_lock_bh(&nf_conntrack_lock); nf_conntrack_hash_insert(ct); - nf_conntrack_get(&ct->ct_general); - spin_unlock_bh(&nf_conntrack_lock); rcu_read_unlock(); return ct; @@ -1490,7 +1490,6 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, struct nf_conntrack_tuple otuple, rtuple; struct nf_conntrack_tuple_hash *h = NULL; struct nfgenmsg *nfmsg = nlmsg_data(nlh); - struct nf_conn *ct; u_int8_t u3 = nfmsg->nfgen_family; u16 zone; int err; @@ -1513,22 +1512,25 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, spin_lock_bh(&nf_conntrack_lock); if (cda[CTA_TUPLE_ORIG]) - h = nf_conntrack_find_get(net, zone, &otuple); + h = __nf_conntrack_find(net, zone, &otuple); else if (cda[CTA_TUPLE_REPLY]) - h = nf_conntrack_find_get(net, zone, &rtuple); - spin_unlock_bh(&nf_conntrack_lock); + h = __nf_conntrack_find(net, zone, &rtuple); if (h == NULL) { err = -ENOENT; if (nlh->nlmsg_flags & NLM_F_CREATE) { + struct nf_conn *ct; enum ip_conntrack_events events; ct = ctnetlink_create_conntrack(net, zone, cda, &otuple, &rtuple, u3); - if (IS_ERR(ct)) - return PTR_ERR(ct); - + if (IS_ERR(ct)) { + err = PTR_ERR(ct); + goto out_unlock; + } err = 0; + nf_conntrack_get(&ct->ct_general); + spin_unlock_bh(&nf_conntrack_lock); if (test_bit(IPS_EXPECTED_BIT, &ct->status)) events = IPCT_RELATED; else @@ -1543,19 +1545,23 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, ct, NETLINK_CB(skb).pid, nlmsg_report(nlh)); nf_ct_put(ct); - } + } else + spin_unlock_bh(&nf_conntrack_lock); return err; } /* implicit 'else' */ + /* We manipulate the conntrack inside the global conntrack table lock, + * so there's no need to increase the refcount */ err = -EEXIST; - ct = nf_ct_tuplehash_to_ctrack(h); if (!(nlh->nlmsg_flags & NLM_F_EXCL)) { - spin_lock_bh(&nf_conntrack_lock); + struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); + err = ctnetlink_change_conntrack(ct, cda); - spin_unlock_bh(&nf_conntrack_lock); if (err == 0) { + nf_conntrack_get(&ct->ct_general); + spin_unlock_bh(&nf_conntrack_lock); nf_conntrack_eventmask_report((1 << IPCT_REPLY) | (1 << IPCT_ASSURED) | (1 << IPCT_HELPER) | @@ -1564,10 +1570,15 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, (1 << IPCT_MARK), ct, NETLINK_CB(skb).pid, nlmsg_report(nlh)); - } + nf_ct_put(ct); + } else + spin_unlock_bh(&nf_conntrack_lock); + + return err; } - nf_ct_put(ct); +out_unlock: + spin_unlock_bh(&nf_conntrack_lock); return err; }