Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 Jun 2014 02:37:03 +0000 (16:37 -1000)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 Jun 2014 02:37:03 +0000 (16:37 -1000)
Pull networking fixes from David Miller:

 1) Fix checksumming regressions, from Tom Herbert.

 2) Undo unintentional permissions changes for SCTP rto_alpha and
    rto_beta sysfs knobs, from Denial Borkmann.

 3) VXLAN, like other IP tunnels, should advertize it's encapsulation
    size using dev->needed_headroom instead of dev->hard_header_len.
    From Cong Wang.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net:
  net: sctp: fix permissions for rto_alpha and rto_beta knobs
  vxlan: Checksum fixes
  net: add skb_pop_rcv_encapsulation
  udp: call __skb_checksum_complete when doing full checksum
  net: Fix save software checksum complete
  net: Fix GSO constants to match NETIF flags
  udp: ipv4: do not waste time in __udp4_lib_mcast_demux_lookup
  vxlan: use dev->needed_headroom instead of dev->hard_header_len
  MAINTAINERS: update cxgb4 maintainer

MAINTAINERS
drivers/net/vxlan.c
include/linux/netdev_features.h
include/linux/netdevice.h
include/linux/skbuff.h
include/net/udp.h
net/core/datagram.c
net/core/skbuff.c
net/ipv4/udp.c
net/sctp/sysctl.c

index 055f95238d8823a70e18fc33e3c0a407a5a5d123..134483f206e42661947e0bc4b84ef09ab07abd1b 100644 (file)
@@ -2594,7 +2594,7 @@ S:        Supported
 F:     drivers/infiniband/hw/cxgb3/
 
 CXGB4 ETHERNET DRIVER (CXGB4)
-M:     Dimitris Michailidis <dm@chelsio.com>
+M:     Hariprasad S <hariprasad@chelsio.com>
 L:     netdev@vger.kernel.org
 W:     http://www.chelsio.com
 S:     Supported
index 1610d51dbb5c5621499077114ad0b35cd762d19a..ade33ef82823b230a34890d77af039d8531aefb7 100644 (file)
@@ -1156,15 +1156,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
        if (!vs)
                goto drop;
 
-       /* If the NIC driver gave us an encapsulated packet
-        * with the encapsulation mark, the device checksummed it
-        * for us. Otherwise force the upper layers to verify it.
-        */
-       if ((skb->ip_summed != CHECKSUM_UNNECESSARY && skb->ip_summed != CHECKSUM_PARTIAL) ||
-           !skb->encapsulation)
-               skb->ip_summed = CHECKSUM_NONE;
-
-       skb->encapsulation = 0;
+       skb_pop_rcv_encapsulation(skb);
 
        vs->rcv(vs, skb, vxh->vx_vni);
        return 0;
@@ -1201,6 +1193,7 @@ static void vxlan_rcv(struct vxlan_sock *vs,
        skb_reset_mac_header(skb);
        skb_scrub_packet(skb, !net_eq(vxlan->net, dev_net(vxlan->dev)));
        skb->protocol = eth_type_trans(skb, vxlan->dev);
+       skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
 
        /* Ignore packet loops (and multicast echo) */
        if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
@@ -2247,9 +2240,9 @@ static void vxlan_setup(struct net_device *dev)
        eth_hw_addr_random(dev);
        ether_setup(dev);
        if (vxlan->default_dst.remote_ip.sa.sa_family == AF_INET6)
-               dev->hard_header_len = ETH_HLEN + VXLAN6_HEADROOM;
+               dev->needed_headroom = ETH_HLEN + VXLAN6_HEADROOM;
        else
-               dev->hard_header_len = ETH_HLEN + VXLAN_HEADROOM;
+               dev->needed_headroom = ETH_HLEN + VXLAN_HEADROOM;
 
        dev->netdev_ops = &vxlan_netdev_ops;
        dev->destructor = free_netdev;
@@ -2646,8 +2639,7 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
                if (!tb[IFLA_MTU])
                        dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
 
-               /* update header length based on lower device */
-               dev->hard_header_len = lowerdev->hard_header_len +
+               dev->needed_headroom = lowerdev->hard_header_len +
                                       (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
        } else if (use_ipv6)
                vxlan->flags |= VXLAN_F_IPV6;
index e5a589435e2b7df943a935b4cf6dfd6c46dd74ed..d99800cbdcf3b7b4029e4b3f325aec6b1e4382dc 100644 (file)
@@ -117,6 +117,7 @@ enum {
 #define NETIF_F_GSO_IPIP       __NETIF_F(GSO_IPIP)
 #define NETIF_F_GSO_SIT                __NETIF_F(GSO_SIT)
 #define NETIF_F_GSO_UDP_TUNNEL __NETIF_F(GSO_UDP_TUNNEL)
+#define NETIF_F_GSO_UDP_TUNNEL_CSUM __NETIF_F(GSO_UDP_TUNNEL_CSUM)
 #define NETIF_F_GSO_MPLS       __NETIF_F(GSO_MPLS)
 #define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER)
 #define NETIF_F_HW_VLAN_STAG_RX        __NETIF_F(HW_VLAN_STAG_RX)
index abe3de1db932a09016d430ff699a993e6761bc83..66f9a04ec27041445afddbb70729b039719387c5 100644 (file)
@@ -3305,6 +3305,13 @@ static inline bool net_gso_ok(netdev_features_t features, int gso_type)
        BUILD_BUG_ON(SKB_GSO_TCP_ECN != (NETIF_F_TSO_ECN >> NETIF_F_GSO_SHIFT));
        BUILD_BUG_ON(SKB_GSO_TCPV6   != (NETIF_F_TSO6 >> NETIF_F_GSO_SHIFT));
        BUILD_BUG_ON(SKB_GSO_FCOE    != (NETIF_F_FSO >> NETIF_F_GSO_SHIFT));
+       BUILD_BUG_ON(SKB_GSO_GRE     != (NETIF_F_GSO_GRE >> NETIF_F_GSO_SHIFT));
+       BUILD_BUG_ON(SKB_GSO_GRE_CSUM != (NETIF_F_GSO_GRE_CSUM >> NETIF_F_GSO_SHIFT));
+       BUILD_BUG_ON(SKB_GSO_IPIP    != (NETIF_F_GSO_IPIP >> NETIF_F_GSO_SHIFT));
+       BUILD_BUG_ON(SKB_GSO_SIT     != (NETIF_F_GSO_SIT >> NETIF_F_GSO_SHIFT));
+       BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL != (NETIF_F_GSO_UDP_TUNNEL >> NETIF_F_GSO_SHIFT));
+       BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL_CSUM != (NETIF_F_GSO_UDP_TUNNEL_CSUM >> NETIF_F_GSO_SHIFT));
+       BUILD_BUG_ON(SKB_GSO_MPLS    != (NETIF_F_GSO_MPLS >> NETIF_F_GSO_SHIFT));
 
        return (features & feature) == feature;
 }
index 5b5cd3189c985f89a055e35d8d1c67c63879d8fc..ec89301ada418aff749bf924da1b7f63040ac048 100644 (file)
@@ -338,17 +338,18 @@ enum {
 
        SKB_GSO_GRE = 1 << 6,
 
-       SKB_GSO_IPIP = 1 << 7,
+       SKB_GSO_GRE_CSUM = 1 << 7,
 
-       SKB_GSO_SIT = 1 << 8,
+       SKB_GSO_IPIP = 1 << 8,
 
-       SKB_GSO_UDP_TUNNEL = 1 << 9,
+       SKB_GSO_SIT = 1 << 9,
 
-       SKB_GSO_MPLS = 1 << 10,
+       SKB_GSO_UDP_TUNNEL = 1 << 10,
 
        SKB_GSO_UDP_TUNNEL_CSUM = 1 << 11,
 
-       SKB_GSO_GRE_CSUM = 1 << 12,
+       SKB_GSO_MPLS = 1 << 12,
+
 };
 
 #if BITS_PER_LONG > 32
@@ -1853,6 +1854,18 @@ static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len)
        return pskb_may_pull(skb, skb_network_offset(skb) + len);
 }
 
+static inline void skb_pop_rcv_encapsulation(struct sk_buff *skb)
+{
+       /* Only continue with checksum unnecessary if device indicated
+        * it is valid across encapsulation (skb->encapsulation was set).
+        */
+       if (skb->ip_summed == CHECKSUM_UNNECESSARY && !skb->encapsulation)
+               skb->ip_summed = CHECKSUM_NONE;
+
+       skb->encapsulation = 0;
+       skb->csum_valid = 0;
+}
+
 /*
  * CPUs often take a performance hit when accessing unaligned memory
  * locations. The actual performance hit varies, it can be small if the
index 2ecfc6e156098dbd37b3763a3040109a19e85810..68a1fefe3dfe46c3fc8f4847fa074fdb237573bb 100644 (file)
@@ -111,7 +111,9 @@ struct sk_buff;
  */
 static inline __sum16 __udp_lib_checksum_complete(struct sk_buff *skb)
 {
-       return __skb_checksum_complete_head(skb, UDP_SKB_CB(skb)->cscov);
+       return (UDP_SKB_CB(skb)->cscov == skb->len ?
+               __skb_checksum_complete(skb) :
+               __skb_checksum_complete_head(skb, UDP_SKB_CB(skb)->cscov));
 }
 
 static inline int udp_lib_checksum_complete(struct sk_buff *skb)
index 6b1c04ca1d5090410f436fbf74e50813e09634c3..488dd1a825c05b704a26d8c88582454f1745be4c 100644 (file)
@@ -739,22 +739,38 @@ __sum16 __skb_checksum_complete_head(struct sk_buff *skb, int len)
        __sum16 sum;
 
        sum = csum_fold(skb_checksum(skb, 0, len, skb->csum));
-       if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) && !sum &&
-           !skb->csum_complete_sw)
-               netdev_rx_csum_fault(skb->dev);
-
-       /* Save checksum complete for later use */
-       skb->csum = sum;
-       skb->ip_summed = CHECKSUM_COMPLETE;
-       skb->csum_complete_sw = 1;
-
+       if (likely(!sum)) {
+               if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
+                   !skb->csum_complete_sw)
+                       netdev_rx_csum_fault(skb->dev);
+       }
+       skb->csum_valid = !sum;
        return sum;
 }
 EXPORT_SYMBOL(__skb_checksum_complete_head);
 
 __sum16 __skb_checksum_complete(struct sk_buff *skb)
 {
-       return __skb_checksum_complete_head(skb, skb->len);
+       __wsum csum;
+       __sum16 sum;
+
+       csum = skb_checksum(skb, 0, skb->len, 0);
+
+       /* skb->csum holds pseudo checksum */
+       sum = csum_fold(csum_add(skb->csum, csum));
+       if (likely(!sum)) {
+               if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
+                   !skb->csum_complete_sw)
+                       netdev_rx_csum_fault(skb->dev);
+       }
+
+       /* Save full packet checksum */
+       skb->csum = csum;
+       skb->ip_summed = CHECKSUM_COMPLETE;
+       skb->csum_complete_sw = 1;
+       skb->csum_valid = !sum;
+
+       return sum;
 }
 EXPORT_SYMBOL(__skb_checksum_complete);
 
index bf92824af3f77179e519f73085f6642c32ca61b6..9cd5344fad73466e66c63f04efd4a2600074db4e 100644 (file)
@@ -689,6 +689,9 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->ooo_okay           = old->ooo_okay;
        new->no_fcs             = old->no_fcs;
        new->encapsulation      = old->encapsulation;
+       new->encap_hdr_csum     = old->encap_hdr_csum;
+       new->csum_valid         = old->csum_valid;
+       new->csum_complete_sw   = old->csum_complete_sw;
 #ifdef CONFIG_XFRM
        new->sp                 = secpath_get(old->sp);
 #endif
index 185ed3e598027a475b6ed62c4a0e9f9838793f4d..d92f94b7e4025dd4779e75e6a75f2de560713778 100644 (file)
@@ -1861,6 +1861,10 @@ static struct sock *__udp4_lib_mcast_demux_lookup(struct net *net,
        unsigned int count, slot = udp_hashfn(net, hnum, udp_table.mask);
        struct udp_hslot *hslot = &udp_table.hash[slot];
 
+       /* Do not bother scanning a too big list */
+       if (hslot->count > 10)
+               return NULL;
+
        rcu_read_lock();
 begin:
        count = 0;
index 7e5eb75549902eeeb2c0c0889daca8ee53317ccf..dcb19592761e3b80b92057ba5b834e568a338ab9 100644 (file)
@@ -34,6 +34,8 @@
  *    Sridhar Samudrala     <sri@us.ibm.com>
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <net/sctp/structs.h>
 #include <net/sctp/sctp.h>
 #include <linux/sysctl.h>
@@ -46,6 +48,11 @@ static int sack_timer_min = 1;
 static int sack_timer_max = 500;
 static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
 static int rwnd_scale_max = 16;
+static int rto_alpha_min = 0;
+static int rto_beta_min = 0;
+static int rto_alpha_max = 1000;
+static int rto_beta_max = 1000;
+
 static unsigned long max_autoclose_min = 0;
 static unsigned long max_autoclose_max =
        (MAX_SCHEDULE_TIMEOUT / HZ > UINT_MAX)
@@ -64,6 +71,9 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
 static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
                                void __user *buffer, size_t *lenp,
                                loff_t *ppos);
+static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
+                                  void __user *buffer, size_t *lenp,
+                                  loff_t *ppos);
 static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
                             void __user *buffer, size_t *lenp,
                             loff_t *ppos);
@@ -126,15 +136,19 @@ static struct ctl_table sctp_net_table[] = {
                .procname       = "rto_alpha_exp_divisor",
                .data           = &init_net.sctp.rto_alpha,
                .maxlen         = sizeof(int),
-               .mode           = 0444,
-               .proc_handler   = proc_dointvec,
+               .mode           = 0644,
+               .proc_handler   = proc_sctp_do_alpha_beta,
+               .extra1         = &rto_alpha_min,
+               .extra2         = &rto_alpha_max,
        },
        {
                .procname       = "rto_beta_exp_divisor",
                .data           = &init_net.sctp.rto_beta,
                .maxlen         = sizeof(int),
-               .mode           = 0444,
-               .proc_handler   = proc_dointvec,
+               .mode           = 0644,
+               .proc_handler   = proc_sctp_do_alpha_beta,
+               .extra1         = &rto_beta_min,
+               .extra2         = &rto_beta_max,
        },
        {
                .procname       = "max_burst",
@@ -403,6 +417,16 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
        return ret;
 }
 
+static int proc_sctp_do_alpha_beta(struct ctl_table *ctl, int write,
+                                  void __user *buffer, size_t *lenp,
+                                  loff_t *ppos)
+{
+       pr_warn_once("Changing rto_alpha or rto_beta may lead to "
+                    "suboptimal rtt/srtt estimations!\n");
+
+       return proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
+}
+
 static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
                             void __user *buffer, size_t *lenp,
                             loff_t *ppos)