Merge tag 'v3.10.58' into update
authorStricted <info@stricted.net>
Wed, 21 Mar 2018 21:31:25 +0000 (22:31 +0100)
committerStricted <info@stricted.net>
Wed, 21 Mar 2018 21:31:25 +0000 (22:31 +0100)
This is the 3.10.58 stable release

23 files changed:
Makefile
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/myricom/myri10ge/myri10ge.c
drivers/net/hyperv/netvsc_drv.c
drivers/usb/core/hub.c
drivers/usb/core/quirks.c
drivers/usb/serial/cp210x.c
include/linux/usb/quirks.h
include/net/inet_connection_sock.h
include/net/sctp/command.h
include/net/sock.h
include/net/tcp.h
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/ip6_gre.c
net/ipv6/sit.c
net/ipv6/tcp_ipv6.c
net/l2tp/l2tp_ppp.c
net/openvswitch/actions.c
net/packet/af_packet.c
net/packet/internal.h
net/sctp/sm_statefuns.c

index 2e86bf6a11780d73d119be62beeef7df9deeec9b..abb79ff7acba5888d3af1dbf0764c5f61c41a737 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 10
-SUBLEVEL = 57
+SUBLEVEL = 58
 EXTRAVERSION =
 NAME = TOSSUG Baby Fish
 
index 4942ddf9c8aed2878ae9fdae1c74799a2a71b5e8..3de4069f020e35da50f4e547c5b79edbeb9a44e9 100644 (file)
@@ -6767,7 +6767,8 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                skb->protocol = eth_type_trans(skb, tp->dev);
 
                if (len > (tp->dev->mtu + ETH_HLEN) &&
-                   skb->protocol != htons(ETH_P_8021Q)) {
+                   skb->protocol != htons(ETH_P_8021Q) &&
+                   skb->protocol != htons(ETH_P_8021AD)) {
                        dev_kfree_skb(skb);
                        goto drop_it_no_recycle;
                }
@@ -7759,8 +7760,6 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        entry = tnapi->tx_prod;
        base_flags = 0;
-       if (skb->ip_summed == CHECKSUM_PARTIAL)
-               base_flags |= TXD_FLAG_TCPUDP_CSUM;
 
        mss = skb_shinfo(skb)->gso_size;
        if (mss) {
@@ -7776,6 +7775,13 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
                hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN;
 
+               /* HW/FW can not correctly segment packets that have been
+                * vlan encapsulated.
+                */
+               if (skb->protocol == htons(ETH_P_8021Q) ||
+                   skb->protocol == htons(ETH_P_8021AD))
+                       return tg3_tso_bug(tp, skb);
+
                if (!skb_is_gso_v6(skb)) {
                        iph->check = 0;
                        iph->tot_len = htons(mss + hdr_len);
@@ -7822,6 +7828,17 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                base_flags |= tsflags << 12;
                        }
                }
+       } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               /* HW/FW can not correctly checksum packets that have been
+                * vlan encapsulated.
+                */
+               if (skb->protocol == htons(ETH_P_8021Q) ||
+                   skb->protocol == htons(ETH_P_8021AD)) {
+                       if (skb_checksum_help(skb))
+                               goto drop;
+               } else  {
+                       base_flags |= TXD_FLAG_TCPUDP_CSUM;
+               }
        }
 
        if (tg3_flag(tp, USE_JUMBO_BDFLAG) &&
index 7be9788ed0f6fddcb43abd1b384b0424ad33cb22..4fb93c5b556319e3cb90b2e0144eb31fbd69ceaf 100644 (file)
@@ -856,6 +856,10 @@ static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type)
                return -ENOMEM;
        dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
                                   DMA_BIDIRECTIONAL);
+       if (unlikely(pci_dma_mapping_error(mgp->pdev, dmatest_bus))) {
+               __free_page(dmatest_page);
+               return -ENOMEM;
+       }
 
        /* Run a small DMA test.
         * The magic multipliers to the length tell the firmware
@@ -1191,6 +1195,7 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
                        int bytes, int watchdog)
 {
        struct page *page;
+       dma_addr_t bus;
        int idx;
 #if MYRI10GE_ALLOC_SIZE > 4096
        int end_offset;
@@ -1215,11 +1220,21 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
                                        rx->watchdog_needed = 1;
                                return;
                        }
+
+                       bus = pci_map_page(mgp->pdev, page, 0,
+                                          MYRI10GE_ALLOC_SIZE,
+                                          PCI_DMA_FROMDEVICE);
+                       if (unlikely(pci_dma_mapping_error(mgp->pdev, bus))) {
+                               __free_pages(page, MYRI10GE_ALLOC_ORDER);
+                               if (rx->fill_cnt - rx->cnt < 16)
+                                       rx->watchdog_needed = 1;
+                               return;
+                       }
+
                        rx->page = page;
                        rx->page_offset = 0;
-                       rx->bus = pci_map_page(mgp->pdev, page, 0,
-                                              MYRI10GE_ALLOC_SIZE,
-                                              PCI_DMA_FROMDEVICE);
+                       rx->bus = bus;
+
                }
                rx->info[idx].page = rx->page;
                rx->info[idx].page_offset = rx->page_offset;
@@ -2576,6 +2591,35 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
        mb();
 }
 
+static void myri10ge_unmap_tx_dma(struct myri10ge_priv *mgp,
+                                 struct myri10ge_tx_buf *tx, int idx)
+{
+       unsigned int len;
+       int last_idx;
+
+       /* Free any DMA resources we've alloced and clear out the skb slot */
+       last_idx = (idx + 1) & tx->mask;
+       idx = tx->req & tx->mask;
+       do {
+               len = dma_unmap_len(&tx->info[idx], len);
+               if (len) {
+                       if (tx->info[idx].skb != NULL)
+                               pci_unmap_single(mgp->pdev,
+                                                dma_unmap_addr(&tx->info[idx],
+                                                               bus), len,
+                                                PCI_DMA_TODEVICE);
+                       else
+                               pci_unmap_page(mgp->pdev,
+                                              dma_unmap_addr(&tx->info[idx],
+                                                             bus), len,
+                                              PCI_DMA_TODEVICE);
+                       dma_unmap_len_set(&tx->info[idx], len, 0);
+                       tx->info[idx].skb = NULL;
+               }
+               idx = (idx + 1) & tx->mask;
+       } while (idx != last_idx);
+}
+
 /*
  * Transmit a packet.  We need to split the packet so that a single
  * segment does not cross myri10ge->tx_boundary, so this makes segment
@@ -2599,7 +2643,7 @@ static netdev_tx_t myri10ge_xmit(struct sk_buff *skb,
        u32 low;
        __be32 high_swapped;
        unsigned int len;
-       int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments;
+       int idx, avail, frag_cnt, frag_idx, count, mss, max_segments;
        u16 pseudo_hdr_offset, cksum_offset, queue;
        int cum_len, seglen, boundary, rdma_count;
        u8 flags, odd_flag;
@@ -2696,9 +2740,12 @@ again:
 
        /* map the skb for DMA */
        len = skb_headlen(skb);
+       bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+       if (unlikely(pci_dma_mapping_error(mgp->pdev, bus)))
+               goto drop;
+
        idx = tx->req & tx->mask;
        tx->info[idx].skb = skb;
-       bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE);
        dma_unmap_addr_set(&tx->info[idx], bus, bus);
        dma_unmap_len_set(&tx->info[idx], len, len);
 
@@ -2797,12 +2844,16 @@ again:
                        break;
 
                /* map next fragment for DMA */
-               idx = (count + tx->req) & tx->mask;
                frag = &skb_shinfo(skb)->frags[frag_idx];
                frag_idx++;
                len = skb_frag_size(frag);
                bus = skb_frag_dma_map(&mgp->pdev->dev, frag, 0, len,
                                       DMA_TO_DEVICE);
+               if (unlikely(pci_dma_mapping_error(mgp->pdev, bus))) {
+                       myri10ge_unmap_tx_dma(mgp, tx, idx);
+                       goto drop;
+               }
+               idx = (count + tx->req) & tx->mask;
                dma_unmap_addr_set(&tx->info[idx], bus, bus);
                dma_unmap_len_set(&tx->info[idx], len, len);
        }
@@ -2833,31 +2884,8 @@ again:
        return NETDEV_TX_OK;
 
 abort_linearize:
-       /* Free any DMA resources we've alloced and clear out the skb
-        * slot so as to not trip up assertions, and to avoid a
-        * double-free if linearizing fails */
+       myri10ge_unmap_tx_dma(mgp, tx, idx);
 
-       last_idx = (idx + 1) & tx->mask;
-       idx = tx->req & tx->mask;
-       tx->info[idx].skb = NULL;
-       do {
-               len = dma_unmap_len(&tx->info[idx], len);
-               if (len) {
-                       if (tx->info[idx].skb != NULL)
-                               pci_unmap_single(mgp->pdev,
-                                                dma_unmap_addr(&tx->info[idx],
-                                                               bus), len,
-                                                PCI_DMA_TODEVICE);
-                       else
-                               pci_unmap_page(mgp->pdev,
-                                              dma_unmap_addr(&tx->info[idx],
-                                                             bus), len,
-                                              PCI_DMA_TODEVICE);
-                       dma_unmap_len_set(&tx->info[idx], len, 0);
-                       tx->info[idx].skb = NULL;
-               }
-               idx = (idx + 1) & tx->mask;
-       } while (idx != last_idx);
        if (skb_is_gso(skb)) {
                netdev_err(mgp->dev, "TSO but wanted to linearize?!?!?\n");
                goto drop;
index aea78fc2e48f30894a9ee7aeab0cd92f0d53b6d3..59e9c56e5b8abc63b0ebaa8ed972bd2538cc8f67 100644 (file)
@@ -138,6 +138,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
        struct hv_netvsc_packet *packet;
        int ret;
        unsigned int i, num_pages, npg_data;
+       u32 skb_length = skb->len;
 
        /* Add multipages for skb->data and additional 2 for RNDIS */
        npg_data = (((unsigned long)skb->data + skb_headlen(skb) - 1)
@@ -208,7 +209,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
        ret = rndis_filter_send(net_device_ctx->device_ctx,
                                  packet);
        if (ret == 0) {
-               net->stats.tx_bytes += skb->len;
+               net->stats.tx_bytes += skb_length;
                net->stats.tx_packets++;
        } else {
                kfree(packet);
index abdbaa581a11fa0467f4f5f5d313830eb9db0a87..5155d19f8b41b8fae637308d0f0ee2e1c502bf0f 100644 (file)
@@ -2105,8 +2105,10 @@ void usb_set_device_state(struct usb_device *udev,
                                        || new_state == USB_STATE_SUSPENDED)
                                ;       /* No change to wakeup settings */
                        else if (new_state == USB_STATE_CONFIGURED)
-                               wakeup = udev->actconfig->desc.bmAttributes
-                                        & USB_CONFIG_ATT_WAKEUP;
+                               wakeup = (udev->quirks &
+                                       USB_QUIRK_IGNORE_REMOTE_WAKEUP) ? 0 :
+                                       udev->actconfig->desc.bmAttributes &
+                                       USB_CONFIG_ATT_WAKEUP;
                        else
                                wakeup = 0;
                }
index 1053eb651b2f945d2647715a3990a51138fcb0e0..a301b3fa622b6a3e7502b032f5897f1704c8f2bb 100644 (file)
@@ -162,6 +162,10 @@ static const struct usb_device_id usb_interface_quirk_list[] = {
        { USB_VENDOR_AND_INTERFACE_INFO(0x046d, USB_CLASS_VIDEO, 1, 0),
          .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* ASUS Base Station(T100) */
+       { USB_DEVICE(0x0b05, 0x17e0), .driver_info =
+                       USB_QUIRK_IGNORE_REMOTE_WAKEUP },
+
        { }  /* terminating entry must be last */
 };
 
index b14379659e351342dfa0a57a32c0c7a19d6af4e6..b22a4bc308e2014319b4f876c50a531cc66f0390 100644 (file)
@@ -122,6 +122,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */
        { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
        { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
+       { USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
@@ -155,6 +156,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
        { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
        { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
+       { USB_DEVICE(0x1D6F, 0x0010) }, /* Seluxit ApS RF Dongle */
        { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */
        { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */
        { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */
index 52f944dfe2fd68305f1f19a4f08c018e9226595c..49587dc22f5d055a782a8a947e76a8535a953dcb 100644 (file)
@@ -30,4 +30,7 @@
    descriptor */
 #define USB_QUIRK_DELAY_INIT           0x00000040
 
+/* device generates spurious wakeup, ignore remote wakeup capability */
+#define USB_QUIRK_IGNORE_REMOTE_WAKEUP 0x00000200
+
 #endif /* __LINUX_USB_QUIRKS_H */
index b4322314606f9eecc57065cd77d7877137bc6f49..2da0c72f48e37304e1dbf9178c36bd722f00c073 100644 (file)
@@ -62,6 +62,7 @@ struct inet_connection_sock_af_ops {
        void        (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
        int         (*bind_conflict)(const struct sock *sk,
                                     const struct inet_bind_bucket *tb, bool relax);
+       void        (*mtu_reduced)(struct sock *sk);
 };
 
 /** inet_connection_sock - INET connection oriented sock
index 35247271e5571153110fa7759e6c24c13c1114aa..5f39c1cc0766baaad663d98882168b275859ded4 100644 (file)
@@ -118,7 +118,7 @@ typedef enum {
  * analysis of the state functions, but in reality just taken from
  * thin air in the hopes othat we don't trigger a kernel panic.
  */
-#define SCTP_MAX_NUM_COMMANDS 14
+#define SCTP_MAX_NUM_COMMANDS 20
 
 typedef union {
        __s32 i32;
index 66bef38c5180aeba0fafae541d7f261bba5dffc6..02199accb6be2b9ddeffdef24dc001c686b2e9d5 100644 (file)
@@ -936,7 +936,6 @@ struct proto {
                                                struct sk_buff *skb);
 
        void            (*release_cb)(struct sock *sk);
-       void            (*mtu_reduced)(struct sock *sk);
 
        /* Keeping track of sk's, looking them up, and port selection methods. */
        void                    (*hash)(struct sock *sk);
index 18af925cef1ff8da3a5253cb9e22f8c6095a7d45..85a69deaf091b2fa1c843588ec7554492d31bb36 100644 (file)
@@ -463,6 +463,7 @@ extern const u8 *tcp_parse_md5sig_option(const struct tcphdr *th);
  */
 
 extern void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb);
+void tcp_v4_mtu_reduced(struct sock *sk);
 extern int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb);
 extern struct sock * tcp_create_openreq_child(struct sock *sk,
                                              struct request_sock *req,
index fb244f4a38b523b4939d1a3cd4e69ae59cc69cbb..35c01585cdeb2d0cb30986166b32168e079d7f5b 100644 (file)
@@ -268,7 +268,7 @@ EXPORT_SYMBOL(tcp_v4_connect);
  * It can be called through tcp_release_cb() if socket was owned by user
  * at the time tcp_v4_err() was called to handle ICMP message.
  */
-static void tcp_v4_mtu_reduced(struct sock *sk)
+void tcp_v4_mtu_reduced(struct sock *sk)
 {
        struct dst_entry *dst;
        struct inet_sock *inet = inet_sk(sk);
@@ -298,6 +298,7 @@ static void tcp_v4_mtu_reduced(struct sock *sk)
                tcp_simple_retransmit(sk);
        } /* else let the usual retransmit timer handle it */
 }
+EXPORT_SYMBOL(tcp_v4_mtu_reduced);
 
 static void do_redirect(struct sk_buff *skb, struct sock *sk)
 {
@@ -2143,6 +2144,7 @@ const struct inet_connection_sock_af_ops ipv4_specific = {
        .compat_setsockopt = compat_ip_setsockopt,
        .compat_getsockopt = compat_ip_getsockopt,
 #endif
+       .mtu_reduced       = tcp_v4_mtu_reduced,
 };
 EXPORT_SYMBOL(ipv4_specific);
 
@@ -2978,7 +2980,6 @@ struct proto tcp_prot = {
        .sendpage               = tcp_sendpage,
        .backlog_rcv            = tcp_v4_do_rcv,
        .release_cb             = tcp_release_cb,
-       .mtu_reduced            = tcp_v4_mtu_reduced,
        .hash                   = inet_hash,
        .unhash                 = inet_unhash,
        .get_port               = inet_csk_get_port,
index a79b1f43a3e8a181441b1c1e7714fea9ed37513f..eef147cff1265516bf16a6fea281e05a56098cf5 100644 (file)
@@ -774,7 +774,7 @@ void tcp_release_cb(struct sock *sk)
                __sock_put(sk);
        }
        if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) {
-               sk->sk_prot->mtu_reduced(sk);
+               inet_csk(sk)->icsk_af_ops->mtu_reduced(sk);
                __sock_put(sk);
        }
 }
@@ -2035,9 +2035,7 @@ void tcp_send_loss_probe(struct sock *sk)
        if (WARN_ON(!skb || !tcp_skb_pcount(skb)))
                goto rearm_timer;
 
-       /* Probe with zero data doesn't trigger fast recovery. */
-       if (skb->len > 0)
-               err = __tcp_retransmit_skb(sk, skb);
+       err = __tcp_retransmit_skb(sk, skb);
 
        /* Record snd_nxt for loss detection. */
        if (likely(!err))
index b67143e621209a84d40fbf97a93e7792d1dcfd6d..475a16d7b9557fffdd04732353d5e60d740d3d48 100644 (file)
@@ -2730,8 +2730,18 @@ static void init_loopback(struct net_device *dev)
                        if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE))
                                continue;
 
-                       if (sp_ifa->rt)
-                               continue;
+                       if (sp_ifa->rt) {
+                               /* This dst has been added to garbage list when
+                                * lo device down, release this obsolete dst and
+                                * reallocate a new router for ifa.
+                                */
+                               if (sp_ifa->rt->dst.obsolete > 0) {
+                                       ip6_rt_put(sp_ifa->rt);
+                                       sp_ifa->rt = NULL;
+                               } else {
+                                       continue;
+                               }
+                       }
 
                        sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0);
 
index 7dca7c43fdf14f8a5d61afd2beced09fe8e2c211..250a73e77f57b2d8b85f0e4419479a83e2c34f6c 100644 (file)
@@ -787,7 +787,7 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
                encap_limit = t->parms.encap_limit;
 
        memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
-       fl6.flowi6_proto = IPPROTO_IPIP;
+       fl6.flowi6_proto = IPPROTO_GRE;
 
        dsfield = ipv4_get_dsfield(iph);
 
@@ -837,7 +837,7 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
                encap_limit = t->parms.encap_limit;
 
        memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6));
-       fl6.flowi6_proto = IPPROTO_IPV6;
+       fl6.flowi6_proto = IPPROTO_GRE;
 
        dsfield = ipv6_get_dsfield(ipv6h);
        if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
index 8d22460a811ba1254cfd3655cdce73456a00efb9..4ddf67c6355bc1662016caba331b785d7cb8e3b4 100644 (file)
@@ -101,19 +101,19 @@ static struct ip_tunnel *ipip6_tunnel_lookup(struct net *net,
        for_each_ip_tunnel_rcu(t, sitn->tunnels_r_l[h0 ^ h1]) {
                if (local == t->parms.iph.saddr &&
                    remote == t->parms.iph.daddr &&
-                   (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
+                   (!dev || !t->parms.link || dev->ifindex == t->parms.link) &&
                    (t->dev->flags & IFF_UP))
                        return t;
        }
        for_each_ip_tunnel_rcu(t, sitn->tunnels_r[h0]) {
                if (remote == t->parms.iph.daddr &&
-                   (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
+                   (!dev || !t->parms.link || dev->ifindex == t->parms.link) &&
                    (t->dev->flags & IFF_UP))
                        return t;
        }
        for_each_ip_tunnel_rcu(t, sitn->tunnels_l[h1]) {
                if (local == t->parms.iph.saddr &&
-                   (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
+                   (!dev || !t->parms.link || dev->ifindex == t->parms.link) &&
                    (t->dev->flags & IFF_UP))
                        return t;
        }
index f3fa7fa2ae31f438546ba452b41853ac00c5e131..c27303d4482fdc0264accfd622c5a1b62597ee7c 100644 (file)
@@ -1655,6 +1655,7 @@ static const struct inet_connection_sock_af_ops ipv6_specific = {
        .compat_setsockopt = compat_ipv6_setsockopt,
        .compat_getsockopt = compat_ipv6_getsockopt,
 #endif
+       .mtu_reduced       = tcp_v6_mtu_reduced,
 };
 
 #ifdef CONFIG_TCP_MD5SIG
@@ -1686,6 +1687,7 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = {
        .compat_setsockopt = compat_ipv6_setsockopt,
        .compat_getsockopt = compat_ipv6_getsockopt,
 #endif
+       .mtu_reduced       = tcp_v4_mtu_reduced,
 };
 
 #ifdef CONFIG_TCP_MD5SIG
@@ -1923,7 +1925,6 @@ struct proto tcpv6_prot = {
        .sendpage               = tcp_sendpage,
        .backlog_rcv            = tcp_v6_do_rcv,
        .release_cb             = tcp_release_cb,
-       .mtu_reduced            = tcp_v6_mtu_reduced,
        .hash                   = tcp_v6_hash,
        .unhash                 = inet_unhash,
        .get_port               = inet_csk_get_port,
index 164fa9dcd97de5f547ae2e20a38f023a14a47cdc..c3ae2411650c703171e61fda811add6ad281c614 100644 (file)
@@ -756,7 +756,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
        /* If PMTU discovery was enabled, use the MTU that was discovered */
        dst = sk_dst_get(tunnel->sock);
        if (dst != NULL) {
-               u32 pmtu = dst_mtu(__sk_dst_get(tunnel->sock));
+               u32 pmtu = dst_mtu(dst);
+
                if (pmtu != 0)
                        session->mtu = session->mru = pmtu -
                                PPPOL2TP_HEADER_OVERHEAD;
index 894b6cbdd9295841e6782268b8743fcb63358391..c4779ca590322115ae3eadc3daa7ef7583b02997 100644 (file)
@@ -40,6 +40,9 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
 
 static int make_writable(struct sk_buff *skb, int write_len)
 {
+       if (!pskb_may_pull(skb, write_len))
+               return -ENOMEM;
+
        if (!skb_cloned(skb) || skb_clone_writable(skb, write_len))
                return 0;
 
@@ -68,6 +71,8 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
 
        vlan_set_encap_proto(skb, vhdr);
        skb->mac_header += VLAN_HLEN;
+       if (skb_network_offset(skb) < ETH_HLEN)
+               skb_set_network_header(skb, ETH_HLEN);
        skb_reset_mac_len(skb);
 
        return 0;
index b16a7b83014d755213d231a8b73de07c3c1b3413..1e8ff53dded4528a3c7ddcce6b56686e95699555 100644 (file)
@@ -565,6 +565,7 @@ static void init_prb_bdqc(struct packet_sock *po,
        p1->tov_in_jiffies = msecs_to_jiffies(p1->retire_blk_tov);
        p1->blk_sizeof_priv = req_u->req3.tp_sizeof_priv;
 
+       p1->max_frame_len = p1->kblk_size - BLK_PLUS_PRIV(p1->blk_sizeof_priv);
        prb_init_ft_ops(p1, req_u);
        prb_setup_retire_blk_timer(po, tx_ring);
        prb_open_block(p1, pbd);
@@ -1803,6 +1804,18 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
                        if ((int)snaplen < 0)
                                snaplen = 0;
                }
+       } else if (unlikely(macoff + snaplen >
+                           GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len)) {
+               u32 nval;
+
+               nval = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len - macoff;
+               pr_err_once("tpacket_rcv: packet too big, clamped from %u to %u. macoff=%u\n",
+                           snaplen, nval, macoff);
+               snaplen = nval;
+               if (unlikely((int)snaplen < 0)) {
+                       snaplen = 0;
+                       macoff = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len;
+               }
        }
        spin_lock(&sk->sk_receive_queue.lock);
        h.raw = packet_current_rx_frame(po, skb,
@@ -3652,8 +3665,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
                        goto out;
                if (po->tp_version >= TPACKET_V3 &&
-                   req->tp_block_size <=
-                                               BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv))
+                   (int)(req->tp_block_size -
+                         BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0)
                        goto out;
                if (unlikely(req->tp_frame_size < po->tp_hdrlen +
                                        po->tp_reserve))
index 1035fa2d909c7f18c100266c85ec07bce4a73a97..ca086c0c2c085cb3f3ff00834644d05d8769e7e3 100644 (file)
@@ -29,6 +29,7 @@ struct tpacket_kbdq_core {
        char            *pkblk_start;
        char            *pkblk_end;
        int             kblk_size;
+       unsigned int    max_frame_len;
        unsigned int    knum_blocks;
        uint64_t        knxt_seq_num;
        char            *prev;
index 6eb26403de6a7d9b9b0103ed8fc58a9534dfec04..edc204b05c825b1b8a97f0d37c049a1b5d75c008 100644 (file)
@@ -1782,9 +1782,22 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(struct net *net,
        /* Update the content of current association. */
        sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc));
        sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
-       sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-                       SCTP_STATE(SCTP_STATE_ESTABLISHED));
-       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
+       if (sctp_state(asoc, SHUTDOWN_PENDING) &&
+           (sctp_sstate(asoc->base.sk, CLOSING) ||
+            sock_flag(asoc->base.sk, SOCK_DEAD))) {
+               /* if were currently in SHUTDOWN_PENDING, but the socket
+                * has been closed by user, don't transition to ESTABLISHED.
+                * Instead trigger SHUTDOWN bundled with COOKIE_ACK.
+                */
+               sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
+               return sctp_sf_do_9_2_start_shutdown(net, ep, asoc,
+                                                    SCTP_ST_CHUNK(0), NULL,
+                                                    commands);
+       } else {
+               sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+                               SCTP_STATE(SCTP_STATE_ESTABLISHED));
+               sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
+       }
        return SCTP_DISPOSITION_CONSUME;
 
 nomem_ev: