diff --git a/Makefile b/Makefile
index 595076d..afe001e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 3
 PATCHLEVEL = 10
-SUBLEVEL = 11
+SUBLEVEL = 12
 EXTRAVERSION =
 NAME = TOSSUG Baby Fish
 
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi 
b/arch/arm/boot/dts/at91sam9260.dtsi
index 84c4bef..43a18f7 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -340,6 +340,14 @@
                                        };
                                };
 
+                               i2c_gpio0 {
+                                       pinctrl_i2c_gpio0: i2c_gpio0-0 {
+                                               atmel,pins =
+                                                       <0 23 0x0 0x3   /* PA23 
gpio I2C_SDA pin */
+                                                        0 24 0x0 0x3>; /* PA24 
gpio I2C_SCL pin */
+                                       };
+                               };
+
                                pioA: gpio@fffff400 {
                                        compatible = "atmel,at91rm9200-gpio";
                                        reg = <0xfffff400 0x200>;
@@ -592,6 +600,8 @@
                i2c-gpio,delay-us = <2>;        /* ~100 kHz */
                #address-cells = <1>;
                #size-cells = <0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c_gpio0>;
                status = "disabled";
        };
 };
diff --git a/arch/x86/include/asm/xor_avx.h b/arch/x86/include/asm/xor_avx.h
index 7ea79c5..492b298 100644
--- a/arch/x86/include/asm/xor_avx.h
+++ b/arch/x86/include/asm/xor_avx.h
@@ -167,12 +167,12 @@ static struct xor_block_template xor_block_avx = {
 
 #define AVX_XOR_SPEED \
 do { \
-       if (cpu_has_avx) \
+       if (cpu_has_avx && cpu_has_osxsave) \
                xor_speed(&xor_block_avx); \
 } while (0)
 
 #define AVX_SELECT(FASTEST) \
-       (cpu_has_avx ? &xor_block_avx : FASTEST)
+       (cpu_has_avx && cpu_has_osxsave ? &xor_block_avx : FASTEST)
 
 #else
 
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index f975696..666cf3a 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3770,11 +3770,17 @@ static int bond_neigh_init(struct neighbour *n)
  * The bonding ndo_neigh_setup is called at init time beofre any
  * slave exists. So we must declare proxy setup function which will
  * be used at run time to resolve the actual slave neigh param setup.
+ *
+ * It's also called by master devices (such as vlans) to setup their
+ * underlying devices. In that case - do nothing, we're already set up from
+ * our init.
  */
 static int bond_neigh_setup(struct net_device *dev,
                            struct neigh_parms *parms)
 {
-       parms->neigh_setup   = bond_neigh_init;
+       /* modify only our neigh_parms */
+       if (parms->dev == dev)
+               parms->neigh_setup = bond_neigh_init;
 
        return 0;
 }
diff --git a/drivers/net/ethernet/broadcom/tg3.c 
b/drivers/net/ethernet/broadcom/tg3.c
index a13463e..0877a05 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -3003,6 +3003,19 @@ static bool tg3_phy_power_bug(struct tg3 *tp)
        return false;
 }
 
+static bool tg3_phy_led_bug(struct tg3 *tp)
+{
+       switch (tg3_asic_rev(tp)) {
+       case ASIC_REV_5719:
+               if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
+                   !tp->pci_fn)
+                       return true;
+               return false;
+       }
+
+       return false;
+}
+
 static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
 {
        u32 val;
@@ -3050,8 +3063,9 @@ static void tg3_power_down_phy(struct tg3 *tp, bool 
do_low_power)
                }
                return;
        } else if (do_low_power) {
-               tg3_writephy(tp, MII_TG3_EXT_CTRL,
-                            MII_TG3_EXT_CTRL_FORCE_LED_OFF);
+               if (!tg3_phy_led_bug(tp))
+                       tg3_writephy(tp, MII_TG3_EXT_CTRL,
+                                    MII_TG3_EXT_CTRL_FORCE_LED_OFF);
 
                val = MII_TG3_AUXCTL_PCTL_100TX_LPWR |
                      MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c 
b/drivers/net/ethernet/emulex/benet/be_main.c
index 6e43426..7371626 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2561,8 +2561,8 @@ static int be_close(struct net_device *netdev)
        /* Wait for all pending tx completions to arrive so that
         * all tx skbs are freed.
         */
-       be_tx_compl_clean(adapter);
        netif_tx_disable(netdev);
+       be_tx_compl_clean(adapter);
 
        be_rx_qs_destroy(adapter);
 
diff --git a/drivers/net/ethernet/marvell/mvneta.c 
b/drivers/net/ethernet/marvell/mvneta.c
index c966785..254f255 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -136,7 +136,9 @@
 #define      MVNETA_GMAC_FORCE_LINK_PASS         BIT(1)
 #define      MVNETA_GMAC_CONFIG_MII_SPEED        BIT(5)
 #define      MVNETA_GMAC_CONFIG_GMII_SPEED       BIT(6)
+#define      MVNETA_GMAC_AN_SPEED_EN             BIT(7)
 #define      MVNETA_GMAC_CONFIG_FULL_DUPLEX      BIT(12)
+#define      MVNETA_GMAC_AN_DUPLEX_EN            BIT(13)
 #define MVNETA_MIB_COUNTERS_BASE                 0x3080
 #define      MVNETA_MIB_LATE_COLLISION           0x7c
 #define MVNETA_DA_FILT_SPEC_MCAST                0x3400
@@ -911,6 +913,13 @@ static void mvneta_defaults_set(struct mvneta_port *pp)
        /* Assign port SDMA configuration */
        mvreg_write(pp, MVNETA_SDMA_CONFIG, val);
 
+       /* Disable PHY polling in hardware, since we're using the
+        * kernel phylib to do this.
+        */
+       val = mvreg_read(pp, MVNETA_UNIT_CONTROL);
+       val &= ~MVNETA_PHY_POLLING_ENABLE;
+       mvreg_write(pp, MVNETA_UNIT_CONTROL, val);
+
        mvneta_set_ucast_table(pp, -1);
        mvneta_set_special_mcast_table(pp, -1);
        mvneta_set_other_mcast_table(pp, -1);
@@ -2288,7 +2297,9 @@ static void mvneta_adjust_link(struct net_device *ndev)
                        val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
                        val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
                                 MVNETA_GMAC_CONFIG_GMII_SPEED |
-                                MVNETA_GMAC_CONFIG_FULL_DUPLEX);
+                                MVNETA_GMAC_CONFIG_FULL_DUPLEX |
+                                MVNETA_GMAC_AN_SPEED_EN |
+                                MVNETA_GMAC_AN_DUPLEX_EN);
 
                        if (phydev->duplex)
                                val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
diff --git a/drivers/net/ethernet/realtek/8139cp.c 
b/drivers/net/ethernet/realtek/8139cp.c
index 887aebe..9095ff9 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -524,6 +524,7 @@ rx_status_loop:
                                         PCI_DMA_FROMDEVICE);
                if (dma_mapping_error(&cp->pdev->dev, new_mapping)) {
                        dev->stats.rx_dropped++;
+                       kfree_skb(new_skb);
                        goto rx_next;
                }
 
diff --git a/drivers/net/ethernet/sfc/filter.c 
b/drivers/net/ethernet/sfc/filter.c
index 2738b5f..a520465 100644
--- a/drivers/net/ethernet/sfc/filter.c
+++ b/drivers/net/ethernet/sfc/filter.c
@@ -675,7 +675,7 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct 
efx_filter_spec *spec,
                BUILD_BUG_ON(EFX_FILTER_INDEX_UC_DEF != 0);
                BUILD_BUG_ON(EFX_FILTER_INDEX_MC_DEF !=
                             EFX_FILTER_MC_DEF - EFX_FILTER_UC_DEF);
-               rep_index = spec->type - EFX_FILTER_INDEX_UC_DEF;
+               rep_index = spec->type - EFX_FILTER_UC_DEF;
                ins_index = rep_index;
 
                spin_lock_bh(&state->lock);
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 6e91931..06eba6e 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -727,6 +727,10 @@ static int macvlan_validate(struct nlattr *tb[], struct 
nlattr *data[])
                        return -EADDRNOTAVAIL;
        }
 
+       if (data && data[IFLA_MACVLAN_FLAGS] &&
+           nla_get_u16(data[IFLA_MACVLAN_FLAGS]) & ~MACVLAN_FLAG_NOPROMISC)
+               return -EINVAL;
+
        if (data && data[IFLA_MACVLAN_MODE]) {
                switch (nla_get_u32(data[IFLA_MACVLAN_MODE])) {
                case MACVLAN_MODE_PRIVATE:
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 2491eb2..7b54f4f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1076,8 +1076,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, 
struct tun_file *tfile,
        u32 rxhash;
 
        if (!(tun->flags & TUN_NO_PI)) {
-               if ((len -= sizeof(pi)) > total_len)
+               if (len < sizeof(pi))
                        return -EINVAL;
+               len -= sizeof(pi);
 
                if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
                        return -EFAULT;
@@ -1085,8 +1086,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, 
struct tun_file *tfile,
        }
 
        if (tun->flags & TUN_VNET_HDR) {
-               if ((len -= tun->vnet_hdr_sz) > total_len)
+               if (len < tun->vnet_hdr_sz)
                        return -EINVAL;
+               len -= tun->vnet_hdr_sz;
 
                if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
                        return -EFAULT;
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 8728198..25ba7ec 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -400,6 +400,10 @@ static const struct usb_device_id mbim_devs[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x68a2, USB_CLASS_COMM, 
USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
          .driver_info = (unsigned long)&cdc_mbim_info_zlp,
        },
+       /* HP hs2434 Mobile Broadband Module needs ZLPs */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x3f0, 0x4b1d, USB_CLASS_COMM, 
USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+         .driver_info = (unsigned long)&cdc_mbim_info_zlp,
+       },
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, 
USB_CDC_PROTO_NONE),
          .driver_info = (unsigned long)&cdc_mbim_info,
        },
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 57325f3..054489f 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1090,7 +1090,7 @@ static netdev_tx_t vxlan_xmit_one(struct sk_buff *skb, 
struct net_device *dev,
        iph->daddr      = dst;
        iph->saddr      = fl4.saddr;
        iph->ttl        = ttl ? : ip4_dst_hoplimit(&rt->dst);
-       tunnel_ip_select_ident(skb, old_iph, &rt->dst);
+       __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 
        nf_reset(skb);
 
diff --git a/drivers/net/wireless/mwifiex/main.c 
b/drivers/net/wireless/mwifiex/main.c
index 2eb88ea..c4a2e77 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -363,20 +363,6 @@ static void mwifiex_fw_dpc(const struct firmware 
*firmware, void *context)
                dev_err(adapter->dev, "cannot create default STA interface\n");
                goto err_add_intf;
        }
-
-       /* Create AP interface by default */
-       if (!mwifiex_add_virtual_intf(adapter->wiphy, "uap%d",
-                                     NL80211_IFTYPE_AP, NULL, NULL)) {
-               dev_err(adapter->dev, "cannot create default AP interface\n");
-               goto err_add_intf;
-       }
-
-       /* Create P2P interface by default */
-       if (!mwifiex_add_virtual_intf(adapter->wiphy, "p2p%d",
-                                     NL80211_IFTYPE_P2P_CLIENT, NULL, NULL)) {
-               dev_err(adapter->dev, "cannot create default P2P interface\n");
-               goto err_add_intf;
-       }
        rtnl_unlock();
 
        mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c
index 771812d..3bb9401 100644
--- a/drivers/rtc/rtc-max77686.c
+++ b/drivers/rtc/rtc-max77686.c
@@ -240,9 +240,9 @@ static int max77686_rtc_read_alarm(struct device *dev, 
struct rtc_wkalrm *alrm)
        }
 
        alrm->pending = 0;
-       ret = regmap_read(info->max77686->regmap, MAX77686_REG_STATUS1, &val);
+       ret = regmap_read(info->max77686->regmap, MAX77686_REG_STATUS2, &val);
        if (ret < 0) {
-               dev_err(info->dev, "%s:%d fail to read status1 reg(%d)\n",
+               dev_err(info->dev, "%s:%d fail to read status2 reg(%d)\n",
                                __func__, __LINE__, ret);
                goto out;
        }
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 8ca5ac7..d6a518c 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -307,6 +307,11 @@ static void vhost_zerocopy_callback(struct ubuf_info 
*ubuf, bool success)
        struct vhost_virtqueue *vq = ubufs->vq;
        int cnt = atomic_read(&ubufs->kref.refcount);
 
+       /* set len to mark this desc buffers done DMA */
+       vq->heads[ubuf->desc].len = success ?
+               VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN;
+       vhost_net_ubuf_put(ubufs);
+
        /*
         * Trigger polling thread if guest stopped submitting new buffers:
         * in this case, the refcount after decrement will eventually reach 1
@@ -317,10 +322,6 @@ static void vhost_zerocopy_callback(struct ubuf_info 
*ubuf, bool success)
         */
        if (cnt <= 2 || !(cnt % 16))
                vhost_poll_queue(&vq->poll);
-       /* set len to mark this desc buffers done DMA */
-       vq->heads[ubuf->desc].len = success ?
-               VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN;
-       vhost_net_ubuf_put(ubufs);
 }
 
 /* Expects to be always run from workqueue - which acts as
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 850e95b..b8b7dc7 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -101,6 +101,7 @@ struct inet6_skb_parm {
 #define IP6SKB_FORWARDED       2
 #define IP6SKB_REROUTED                4
 #define IP6SKB_ROUTERALERT     8
+#define IP6SKB_FRAGMENTED      16
 };
 
 #define IP6CB(skb)     ((struct inet6_skb_parm*)((skb)->cb))
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 93024a4..8e0b6c8 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -61,6 +61,7 @@ struct genl_family {
        struct list_head        ops_list;       /* private */
        struct list_head        family_list;    /* private */
        struct list_head        mcast_groups;   /* private */
+       struct module           *module;
 };
 
 /**
@@ -121,9 +122,24 @@ struct genl_ops {
        struct list_head        ops_list;
 };
 
-extern int genl_register_family(struct genl_family *family);
-extern int genl_register_family_with_ops(struct genl_family *family,
+extern int __genl_register_family(struct genl_family *family);
+
+static inline int genl_register_family(struct genl_family *family)
+{
+       family->module = THIS_MODULE;
+       return __genl_register_family(family);
+}
+
+extern int __genl_register_family_with_ops(struct genl_family *family,
        struct genl_ops *ops, size_t n_ops);
+
+static inline int genl_register_family_with_ops(struct genl_family *family,
+       struct genl_ops *ops, size_t n_ops)
+{
+       family->module = THIS_MODULE;
+       return __genl_register_family_with_ops(family, ops, n_ops);
+}
+
 extern int genl_unregister_family(struct genl_family *family);
 extern int genl_register_ops(struct genl_family *, struct genl_ops *ops);
 extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 09b1360..a9942e1 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -141,20 +141,6 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct 
iphdr *iph,
        return INET_ECN_encapsulate(tos, inner);
 }
 
-static inline void tunnel_ip_select_ident(struct sk_buff *skb,
-                                         const struct iphdr  *old_iph,
-                                         struct dst_entry *dst)
-{
-       struct iphdr *iph = ip_hdr(skb);
-
-       /* Use inner packet iph-id if possible. */
-       if (skb->protocol == htons(ETH_P_IP) && old_iph->id)
-               iph->id = old_iph->id;
-       else
-               __ip_select_ident(iph, dst,
-                                 (skb_shinfo(skb)->gso_segs ?: 1) - 1);
-}
-
 static inline void iptunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        int err;
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index e7f4e21..63ed1d1 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -682,13 +682,19 @@ struct psched_ratecfg {
        u64     rate_bps;
        u32     mult;
        u16     overhead;
+       u8      linklayer;
        u8      shift;
 };
 
 static inline u64 psched_l2t_ns(const struct psched_ratecfg *r,
                                unsigned int len)
 {
-       return ((u64)(len + r->overhead) * r->mult) >> r->shift;
+       len += r->overhead;
+
+       if (unlikely(r->linklayer == TC_LINKLAYER_ATM))
+               return ((u64)(DIV_ROUND_UP(len,48)*53) * r->mult) >> r->shift;
+
+       return ((u64)len * r->mult) >> r->shift;
 }
 
 extern void psched_ratecfg_precompute(struct psched_ratecfg *r, const struct 
tc_ratespec *conf);
@@ -699,6 +705,7 @@ static inline void psched_ratecfg_getrate(struct 
tc_ratespec *res,
        memset(res, 0, sizeof(*res));
        res->rate = r->rate_bps >> 3;
        res->overhead = r->overhead;
+       res->linklayer = (r->linklayer & TC_LINKLAYER_MASK);
 }
 
 #endif
diff --git a/include/uapi/linux/icmpv6.h b/include/uapi/linux/icmpv6.h
index e0133c7..590beda 100644
--- a/include/uapi/linux/icmpv6.h
+++ b/include/uapi/linux/icmpv6.h
@@ -115,6 +115,8 @@ struct icmp6hdr {
 #define ICMPV6_NOT_NEIGHBOUR           2
 #define ICMPV6_ADDR_UNREACH            3
 #define ICMPV6_PORT_UNREACH            4
+#define ICMPV6_POLICY_FAIL             5
+#define ICMPV6_REJECT_ROUTE            6
 
 /*
  *     Codes for Time Exceeded
diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index dbd71b0..09d62b92 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -73,9 +73,17 @@ struct tc_estimator {
 #define TC_H_ROOT      (0xFFFFFFFFU)
 #define TC_H_INGRESS    (0xFFFFFFF1U)
 
+/* Need to corrospond to iproute2 tc/tc_core.h "enum link_layer" */
+enum tc_link_layer {
+       TC_LINKLAYER_UNAWARE, /* Indicate unaware old iproute2 util */
+       TC_LINKLAYER_ETHERNET,
+       TC_LINKLAYER_ATM,
+};
+#define TC_LINKLAYER_MASK 0x0F /* limit use to lower 4 bits */
+
 struct tc_ratespec {
        unsigned char   cell_log;
-       unsigned char   __reserved;
+       __u8            linklayer; /* lower 4 bits */
        unsigned short  overhead;
        short           cell_align;
        unsigned short  mpu;
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index ebfa444..84dd783 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -161,7 +161,7 @@ void br_fdb_change_mac_address(struct net_bridge *br, const 
u8 *newaddr)
        if (!pv)
                return;
 
-       for_each_set_bit_from(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) {
+       for_each_set_bit_from(vid, pv->vlan_bitmap, VLAN_N_VID) {
                f = __br_fdb_get(br, br->dev->dev_addr, vid);
                if (f && f->is_local && !f->dst)
                        fdb_delete(br, f);
@@ -725,7 +725,7 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
                /* VID was specified, so use it. */
                err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
        } else {
-               if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN)) {
+               if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) {
                        err = __br_fdb_add(ndm, p, addr, nlh_flags, 0);
                        goto out;
                }
@@ -734,7 +734,7 @@ int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
                 * specify a VLAN.  To be nice, add/update entry for every
                 * vlan on this port.
                 */
-               for_each_set_bit(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) {
+               for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
                        err = __br_fdb_add(ndm, p, addr, nlh_flags, vid);
                        if (err)
                                goto out;
@@ -812,7 +812,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
 
                err = __br_fdb_delete(p, addr, vid);
        } else {
-               if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN)) {
+               if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID)) {
                        err = __br_fdb_delete(p, addr, 0);
                        goto out;
                }
@@ -822,7 +822,7 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
                 * vlan on this port.
                 */
                err = -ENOENT;
-               for_each_set_bit(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) {
+               for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
                        err &= __br_fdb_delete(p, addr, vid);
                }
        }
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index d6448e3..d82058f 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1185,7 +1185,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
                max_delay = msecs_to_jiffies(ntohs(mld->mld_maxdelay));
                if (max_delay)
                        group = &mld->mld_mca;
-       } else if (skb->len >= sizeof(*mld2q)) {
+       } else {
                if (!pskb_may_pull(skb, sizeof(*mld2q))) {
                        err = -EINVAL;
                        goto out;
@@ -1193,7 +1193,8 @@ static int br_ip6_multicast_query(struct net_bridge *br,
                mld2q = (struct mld2_query *)icmp6_hdr(skb);
                if (!mld2q->mld2q_nsrcs)
                        group = &mld2q->mld2q_mca;
-               max_delay = mld2q->mld2q_mrc ? 
MLDV2_MRC(ntohs(mld2q->mld2q_mrc)) : 1;
+
+               max_delay = 
max(msecs_to_jiffies(MLDV2_MRC(ntohs(mld2q->mld2q_mrc))), 1UL);
        }
 
        if (!group)
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 8e3abf5..f66a034 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -128,7 +128,7 @@ static int br_fill_ifinfo(struct sk_buff *skb,
                else
                        pv = br_get_vlan_info(br);
 
-               if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN))
+               if (!pv || bitmap_empty(pv->vlan_bitmap, VLAN_N_VID))
                        goto done;
 
                af = nla_nest_start(skb, IFLA_AF_SPEC);
@@ -136,7 +136,7 @@ static int br_fill_ifinfo(struct sk_buff *skb,
                        goto nla_put_failure;
 
                pvid = br_get_pvid(pv);
-               for_each_set_bit(vid, pv->vlan_bitmap, BR_VLAN_BITMAP_LEN) {
+               for_each_set_bit(vid, pv->vlan_bitmap, VLAN_N_VID) {
                        vinfo.vid = vid;
                        vinfo.flags = 0;
                        if (vid == pvid)
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
index bd58b45..9a9ffe7 100644
--- a/net/bridge/br_vlan.c
+++ b/net/bridge/br_vlan.c
@@ -108,7 +108,7 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid)
 
        clear_bit(vid, v->vlan_bitmap);
        v->num_vlans--;
-       if (bitmap_empty(v->vlan_bitmap, BR_VLAN_BITMAP_LEN)) {
+       if (bitmap_empty(v->vlan_bitmap, VLAN_N_VID)) {
                if (v->port_idx)
                        rcu_assign_pointer(v->parent.port->vlan_info, NULL);
                else
@@ -122,7 +122,7 @@ static void __vlan_flush(struct net_port_vlans *v)
 {
        smp_wmb();
        v->pvid = 0;
-       bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
+       bitmap_zero(v->vlan_bitmap, VLAN_N_VID);
        if (v->port_idx)
                rcu_assign_pointer(v->parent.port->vlan_info, NULL);
        else
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 00ee068..c99cc37 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -345,14 +345,9 @@ u16 __netdev_pick_tx(struct net_device *dev, struct 
sk_buff *skb)
                if (new_index < 0)
                        new_index = skb_tx_hash(dev, skb);
 
-               if (queue_index != new_index && sk) {
-                       struct dst_entry *dst =
-                                   rcu_dereference_check(sk->sk_dst_cache, 1);
-
-                       if (dst && skb_dst(skb) == dst)
-                               sk_tx_queue_set(sk, queue_index);
-
-               }
+               if (queue_index != new_index && sk &&
+                   rcu_access_pointer(sk->sk_dst_cache))
+                       sk_tx_queue_set(sk, queue_index);
 
                queue_index = new_index;
        }
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index ce90b02..0034b61 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1445,16 +1445,18 @@ struct neigh_parms *neigh_parms_alloc(struct net_device 
*dev,
                atomic_set(&p->refcnt, 1);
                p->reachable_time =
                                neigh_rand_reach_time(p->base_reachable_time);
+               dev_hold(dev);
+               p->dev = dev;
+               write_pnet(&p->net, hold_net(net));
+               p->sysctl_table = NULL;
 
                if (ops->ndo_neigh_setup && ops->ndo_neigh_setup(dev, p)) {
+                       release_net(net);
+                       dev_put(dev);
                        kfree(p);
                        return NULL;
                }
 
-               dev_hold(dev);
-               p->dev = dev;
-               write_pnet(&p->net, hold_net(net));
-               p->sysctl_table = NULL;
                write_lock_bh(&tbl->lock);
                p->next         = tbl->parms.next;
                tbl->parms.next = p;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a08bd2b..fd01eca 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2142,7 +2142,7 @@ int ndo_dflt_fdb_del(struct ndmsg *ndm,
        /* If aging addresses are supported device will need to
         * implement its own handler for this.
         */
-       if (ndm->ndm_state & NUD_PERMANENT) {
+       if (!(ndm->ndm_state & NUD_PERMANENT)) {
                pr_info("%s: FDB only supports static addresses\n", dev->name);
                return -EINVAL;
        }
@@ -2374,7 +2374,7 @@ static int rtnl_bridge_getlink(struct sk_buff *skb, 
struct netlink_callback *cb)
        struct nlattr *extfilt;
        u32 filter_mask = 0;
 
-       extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct rtgenmsg),
+       extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg),
                                  IFLA_EXT_MASK);
        if (extfilt)
                filter_mask = nla_get_u32(extfilt);
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index cfdb46a..2ff093b 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -20,7 +20,9 @@
 #include <net/sock.h>
 #include <net/net_ratelimit.h>
 
+static int zero = 0;
 static int one = 1;
+static int ushort_max = USHRT_MAX;
 
 #ifdef CONFIG_RPS
 static int rps_sock_flow_sysctl(ctl_table *table, int write,
@@ -204,7 +206,9 @@ static struct ctl_table netns_core_table[] = {
                .data           = &init_net.core.sysctl_somaxconn,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = proc_dointvec
+               .extra1         = &zero,
+               .extra2         = &ushort_max,
+               .proc_handler   = proc_dointvec_minmax
        },
        { }
 };
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index dfc39d4..9e38217 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -771,7 +771,7 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, 
struct nlmsghdr *nlh,
                ci = nla_data(tb[IFA_CACHEINFO]);
                if (!ci->ifa_valid || ci->ifa_prefered > ci->ifa_valid) {
                        err = -EINVAL;
-                       goto errout;
+                       goto errout_free;
                }
                *pvalid_lft = ci->ifa_valid;
                *pprefered_lft = ci->ifa_prefered;
@@ -779,6 +779,8 @@ static struct in_ifaddr *rtm_to_ifaddr(struct net *net, 
struct nlmsghdr *nlh,
 
        return ifa;
 
+errout_free:
+       inet_free_ifa(ifa);
 errout:
        return ERR_PTR(err);
 }
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 49616fe..6e8a13d 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -71,7 +71,6 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/slab.h>
-#include <linux/prefetch.h>
 #include <linux/export.h>
 #include <net/net_namespace.h>
 #include <net/ip.h>
@@ -1761,10 +1760,8 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, 
struct rt_trie_node *c)
                        if (!c)
                                continue;
 
-                       if (IS_LEAF(c)) {
-                               prefetch(rcu_dereference_rtnl(p->child[idx]));
+                       if (IS_LEAF(c))
                                return (struct leaf *) c;
-                       }
 
                        /* Rescan start scanning in new node */
                        p = (struct tnode *) c;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 855004f..c52fee0 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -572,7 +572,7 @@ static int ipgre_header(struct sk_buff *skb, struct 
net_device *dev,
        if (daddr)
                memcpy(&iph->daddr, daddr, 4);
        if (iph->daddr)
-               return t->hlen;
+               return t->hlen + sizeof(*iph);
 
        return -(t->hlen + sizeof(*iph));
 }
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index cbfc37f..b7a4c21 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -686,7 +686,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device 
*dev,
        iph->daddr      =       fl4.daddr;
        iph->saddr      =       fl4.saddr;
        iph->ttl        =       ttl;
-       tunnel_ip_select_ident(skb, inner_iph, &rt->dst);
+       __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 
        iptunnel_xmit(skb, dev);
        return;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index dd44e0a..61e60d6 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -571,7 +571,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, 
struct msghdr *msg,
        flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos,
                           RT_SCOPE_UNIVERSE,
                           inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
-                          inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP,
+                          inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP |
+                           (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0),
                           daddr, saddr, 0, 0);
 
        if (!inet->hdrincl) {
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index ab450c0..2005561 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1118,6 +1118,13 @@ new_segment:
                                        goto wait_for_memory;
 
                                /*
+                                * All packets are restored as if they have
+                                * already been sent.
+                                */
+                               if (tp->repair)
+                                       TCP_SKB_CB(skb)->when = tcp_time_stamp;
+
+                               /*
                                 * Check whether we can use HW checksum.
                                 */
                                if (sk->sk_route_caps & NETIF_F_ALL_CSUM)
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index a9077f4..b6ae92a 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -206,8 +206,8 @@ static u32 cubic_root(u64 a)
  */
 static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
 {
-       u64 offs;
-       u32 delta, t, bic_target, max_cnt;
+       u32 delta, bic_target, max_cnt;
+       u64 offs, t;
 
        ca->ack_cnt++;  /* count the number of ACKs */
 
@@ -250,9 +250,11 @@ static inline void bictcp_update(struct bictcp *ca, u32 
cwnd)
         * if the cwnd < 1 million packets !!!
         */
 
+       t = (s32)(tcp_time_stamp - ca->epoch_start);
+       t += msecs_to_jiffies(ca->delay_min >> 3);
        /* change the unit from HZ to bictcp_HZ */
-       t = ((tcp_time_stamp + msecs_to_jiffies(ca->delay_min>>3)
-             - ca->epoch_start) << BICTCP_HZ) / HZ;
+       t <<= BICTCP_HZ;
+       do_div(t, HZ);
 
        if (t < ca->bic_K)              /* t - K */
                offs = ca->bic_K - t;
@@ -414,7 +416,7 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 
rtt_us)
                return;
 
        /* Discard delay samples right after fast recovery */
-       if ((s32)(tcp_time_stamp - ca->epoch_start) < HZ)
+       if (ca->epoch_start && (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
                return;
 
        delay = (rtt_us << 3) / USEC_PER_MSEC;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 9c62257..4b75aad 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3598,7 +3598,10 @@ static bool tcp_parse_aligned_timestamp(struct tcp_sock 
*tp, const struct tcphdr
                ++ptr;
                tp->rx_opt.rcv_tsval = ntohl(*ptr);
                ++ptr;
-               tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset;
+               if (*ptr)
+                       tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset;
+               else
+                       tp->rx_opt.rcv_tsecr = 0;
                return true;
        }
        return false;
@@ -3623,7 +3626,7 @@ static bool tcp_fast_parse_options(const struct sk_buff 
*skb,
        }
 
        tcp_parse_options(skb, &tp->rx_opt, 1, NULL);
-       if (tp->rx_opt.saw_tstamp)
+       if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
                tp->rx_opt.rcv_tsecr -= tp->tsoffset;
 
        return true;
@@ -5376,7 +5379,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, 
struct sk_buff *skb,
        int saved_clamp = tp->rx_opt.mss_clamp;
 
        tcp_parse_options(skb, &tp->rx_opt, 0, &foc);
-       if (tp->rx_opt.saw_tstamp)
+       if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr)
                tp->rx_opt.rcv_tsecr -= tp->tsoffset;
 
        if (th->ack) {
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index ec335fa..0145ce7 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2664,7 +2664,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct 
dst_entry *dst,
        int tcp_header_size;
        int mss;
 
-       skb = alloc_skb(MAX_TCP_HEADER + 15, sk_gfp_atomic(sk, GFP_ATOMIC));
+       skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC);
        if (unlikely(!skb)) {
                dst_release(dst);
                return NULL;
@@ -2808,6 +2808,8 @@ void tcp_connect_init(struct sock *sk)
 
        if (likely(!tp->repair))
                tp->rcv_nxt = 0;
+       else
+               tp->rcv_tstamp = tcp_time_stamp;
        tp->rcv_wup = tp->rcv_nxt;
        tp->copied_seq = tp->rcv_nxt;
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index fb8c94c..d3057f9 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1124,12 +1124,10 @@ retry:
        if (ifp->flags & IFA_F_OPTIMISTIC)
                addr_flags |= IFA_F_OPTIMISTIC;
 
-       ift = !max_addresses ||
-             ipv6_count_addresses(idev) < max_addresses ?
-               ipv6_add_addr(idev, &addr, tmp_plen,
-                             ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
-                             addr_flags) : NULL;
-       if (IS_ERR_OR_NULL(ift)) {
+       ift = ipv6_add_addr(idev, &addr, tmp_plen,
+                           ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
+                           addr_flags);
+       if (IS_ERR(ift)) {
                in6_ifa_put(ifp);
                in6_dev_put(idev);
                pr_info("%s: retry temporary address regeneration\n", __func__);
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index f083a58..b30ad37 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -251,38 +251,36 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct 
net *net,
 /* add a label */
 static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
 {
+       struct hlist_node *n;
+       struct ip6addrlbl_entry *last = NULL, *p = NULL;
        int ret = 0;
 
-       ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n",
-                       __func__,
-                       newp, replace);
+       ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n", __func__, newp,
+                 replace);
 
-       if (hlist_empty(&ip6addrlbl_table.head)) {
-               hlist_add_head_rcu(&newp->list, &ip6addrlbl_table.head);
-       } else {
-               struct hlist_node *n;
-               struct ip6addrlbl_entry *p = NULL;
-               hlist_for_each_entry_safe(p, n,
-                                         &ip6addrlbl_table.head, list) {
-                       if (p->prefixlen == newp->prefixlen &&
-                           net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) &&
-                           p->ifindex == newp->ifindex &&
-                           ipv6_addr_equal(&p->prefix, &newp->prefix)) {
-                               if (!replace) {
-                                       ret = -EEXIST;
-                                       goto out;
-                               }
-                               hlist_replace_rcu(&p->list, &newp->list);
-                               ip6addrlbl_put(p);
-                               goto out;
-                       } else if ((p->prefixlen == newp->prefixlen && 
!p->ifindex) ||
-                                  (p->prefixlen < newp->prefixlen)) {
-                               hlist_add_before_rcu(&newp->list, &p->list);
+       hlist_for_each_entry_safe(p, n, &ip6addrlbl_table.head, list) {
+               if (p->prefixlen == newp->prefixlen &&
+                   net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) &&
+                   p->ifindex == newp->ifindex &&
+                   ipv6_addr_equal(&p->prefix, &newp->prefix)) {
+                       if (!replace) {
+                               ret = -EEXIST;
                                goto out;
                        }
+                       hlist_replace_rcu(&p->list, &newp->list);
+                       ip6addrlbl_put(p);
+                       goto out;
+               } else if ((p->prefixlen == newp->prefixlen && !p->ifindex) ||
+                          (p->prefixlen < newp->prefixlen)) {
+                       hlist_add_before_rcu(&newp->list, &p->list);
+                       goto out;
                }
-               hlist_add_after_rcu(&p->list, &newp->list);
+               last = p;
        }
+       if (last)
+               hlist_add_after_rcu(&last->list, &newp->list);
+       else
+               hlist_add_head_rcu(&newp->list, &ip6addrlbl_table.head);
 out:
        if (!ret)
                ip6addrlbl_table.seq++;
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index b4ff0a4..70e704d 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -931,6 +931,14 @@ static const struct icmp6_err {
                .err    = ECONNREFUSED,
                .fatal  = 1,
        },
+       {       /* POLICY_FAIL */
+               .err    = EACCES,
+               .fatal  = 1,
+       },
+       {       /* REJECT_ROUTE */
+               .err    = EACCES,
+               .fatal  = 1,
+       },
 };
 
 int icmpv6_err_convert(u8 type, u8 code, int *err)
@@ -942,7 +950,7 @@ int icmpv6_err_convert(u8 type, u8 code, int *err)
        switch (type) {
        case ICMPV6_DEST_UNREACH:
                fatal = 1;
-               if (code <= ICMPV6_PORT_UNREACH) {
+               if (code < ARRAY_SIZE(tab_unreach)) {
                        *err  = tab_unreach[code].err;
                        fatal = tab_unreach[code].fatal;
                }
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 5fc9c7a..2221ff6 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -993,14 +993,22 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node 
*root,
 
                        if (ipv6_prefix_equal(&key->addr, args->addr, 
key->plen)) {
 #ifdef CONFIG_IPV6_SUBTREES
-                               if (fn->subtree)
-                                       fn = fib6_lookup_1(fn->subtree, args + 
1);
+                               if (fn->subtree) {
+                                       struct fib6_node *sfn;
+                                       sfn = fib6_lookup_1(fn->subtree,
+                                                           args + 1);
+                                       if (!sfn)
+                                               goto backtrack;
+                                       fn = sfn;
+                               }
 #endif
-                               if (!fn || fn->fn_flags & RTN_RTINFO)
+                               if (fn->fn_flags & RTN_RTINFO)
                                        return fn;
                        }
                }
-
+#ifdef CONFIG_IPV6_SUBTREES
+backtrack:
+#endif
                if (fn->fn_flags & RTN_ROOT)
                        break;
 
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index ca4ffcc..060a044 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -372,14 +372,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device 
*dev,
        int tlen = dev->needed_tailroom;
        struct sock *sk = dev_net(dev)->ipv6.ndisc_sk;
        struct sk_buff *skb;
-       int err;
 
-       skb = sock_alloc_send_skb(sk,
-                                 hlen + sizeof(struct ipv6hdr) + len + tlen,
-                                 1, &err);
+       skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC);
        if (!skb) {
-               ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb, 
err=%d\n",
-                         __func__, err);
+               ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n",
+                         __func__);
                return NULL;
        }
 
@@ -389,6 +386,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device 
*dev,
        skb_reserve(skb, hlen + sizeof(struct ipv6hdr));
        skb_reset_transport_header(skb);
 
+       /* Manually assign socket ownership as we avoid calling
+        * sock_alloc_send_pskb() to bypass wmem buffer limits
+        */
+       skb_set_owner_w(skb, sk);
+
        return skb;
 }
 
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 790d9f4..1aeb473 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -490,6 +490,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct 
sk_buff *prev,
        ipv6_hdr(head)->payload_len = htons(payload_len);
        ipv6_change_dsfield(ipv6_hdr(head), 0xff, ecn);
        IP6CB(head)->nhoff = nhoff;
+       IP6CB(head)->flags |= IP6SKB_FRAGMENTED;
 
        /* Yes, and fold redundant checksum back. 8) */
        if (head->ip_summed == CHECKSUM_COMPLETE)
@@ -524,6 +525,9 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
        struct net *net = dev_net(skb_dst(skb)->dev);
        int evicted;
 
+       if (IP6CB(skb)->flags & IP6SKB_FRAGMENTED)
+               goto fail_hdr;
+
        IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), 
IPSTATS_MIB_REASMREQDS);
 
        /* Jumbo payload inhibits frag. header */
@@ -544,6 +548,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
                                 ip6_dst_idev(skb_dst(skb)), 
IPSTATS_MIB_REASMOKS);
 
                IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb);
+               IP6CB(skb)->flags |= IP6SKB_FRAGMENTED;
                return 1;
        }
 
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 0a17ed9..66c7188 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1426,7 +1426,7 @@ ipv6_pktoptions:
                if (np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim)
                        np->mcast_hops = ipv6_hdr(opt_skb)->hop_limit;
                if (np->rxopt.bits.rxtclass)
-                       np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(skb));
+                       np->rcv_tclass = ipv6_get_dsfield(ipv6_hdr(opt_skb));
                if (ipv6_opt_accepted(sk, opt_skb)) {
                        skb_set_owner_r(opt_skb, sk);
                        opt_skb = xchg(&np->pktoptions, opt_skb);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 1076fe1..393f17e 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -364,7 +364,7 @@ int genl_unregister_ops(struct genl_family *family, struct 
genl_ops *ops)
 EXPORT_SYMBOL(genl_unregister_ops);
 
 /**
- * genl_register_family - register a generic netlink family
+ * __genl_register_family - register a generic netlink family
  * @family: generic netlink family
  *
  * Registers the specified family after validating it first. Only one
@@ -374,7 +374,7 @@ EXPORT_SYMBOL(genl_unregister_ops);
  *
  * Return 0 on success or a negative error code.
  */
-int genl_register_family(struct genl_family *family)
+int __genl_register_family(struct genl_family *family)
 {
        int err = -EINVAL;
 
@@ -430,10 +430,10 @@ errout_locked:
 errout:
        return err;
 }
-EXPORT_SYMBOL(genl_register_family);
+EXPORT_SYMBOL(__genl_register_family);
 
 /**
- * genl_register_family_with_ops - register a generic netlink family
+ * __genl_register_family_with_ops - register a generic netlink family
  * @family: generic netlink family
  * @ops: operations to be registered
  * @n_ops: number of elements to register
@@ -457,12 +457,12 @@ EXPORT_SYMBOL(genl_register_family);
  *
  * Return 0 on success or a negative error code.
  */
-int genl_register_family_with_ops(struct genl_family *family,
+int __genl_register_family_with_ops(struct genl_family *family,
        struct genl_ops *ops, size_t n_ops)
 {
        int err, i;
 
-       err = genl_register_family(family);
+       err = __genl_register_family(family);
        if (err)
                return err;
 
@@ -476,7 +476,7 @@ err_out:
        genl_unregister_family(family);
        return err;
 }
-EXPORT_SYMBOL(genl_register_family_with_ops);
+EXPORT_SYMBOL(__genl_register_family_with_ops);
 
 /**
  * genl_unregister_family - unregister generic netlink family
@@ -544,6 +544,30 @@ void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
 }
 EXPORT_SYMBOL(genlmsg_put);
 
+static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct genl_ops *ops = cb->data;
+       int rc;
+
+       genl_lock();
+       rc = ops->dumpit(skb, cb);
+       genl_unlock();
+       return rc;
+}
+
+static int genl_lock_done(struct netlink_callback *cb)
+{
+       struct genl_ops *ops = cb->data;
+       int rc = 0;
+
+       if (ops->done) {
+               genl_lock();
+               rc = ops->done(cb);
+               genl_unlock();
+       }
+       return rc;
+}
+
 static int genl_family_rcv_msg(struct genl_family *family,
                               struct sk_buff *skb,
                               struct nlmsghdr *nlh)
@@ -572,15 +596,34 @@ static int genl_family_rcv_msg(struct genl_family *family,
                return -EPERM;
 
        if (nlh->nlmsg_flags & NLM_F_DUMP) {
-               struct netlink_dump_control c = {
-                       .dump = ops->dumpit,
-                       .done = ops->done,
-               };
+               int rc;
 
                if (ops->dumpit == NULL)
                        return -EOPNOTSUPP;
 
-               return netlink_dump_start(net->genl_sock, skb, nlh, &c);
+               if (!family->parallel_ops) {
+                       struct netlink_dump_control c = {
+                               .module = family->module,
+                               .data = ops,
+                               .dump = genl_lock_dumpit,
+                               .done = genl_lock_done,
+                       };
+
+                       genl_unlock();
+                       rc = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
+                       genl_lock();
+
+               } else {
+                       struct netlink_dump_control c = {
+                               .module = family->module,
+                               .dump = ops->dumpit,
+                               .done = ops->done,
+                       };
+
+                       rc = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
+               }
+
+               return rc;
        }
 
        if (ops->doit == NULL)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 20a1bd0..a6895ab 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3259,9 +3259,11 @@ static int packet_getsockopt(struct socket *sock, int 
level, int optname,
 
                if (po->tp_version == TPACKET_V3) {
                        lv = sizeof(struct tpacket_stats_v3);
+                       st.stats3.tp_packets += st.stats3.tp_drops;
                        data = &st.stats3;
                } else {
                        lv = sizeof(struct tpacket_stats);
+                       st.stats1.tp_packets += st.stats1.tp_drops;
                        data = &st.stats1;
                }
 
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 281c1bd..51b968d 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -285,6 +285,45 @@ static struct Qdisc_ops *qdisc_lookup_ops(struct nlattr 
*kind)
        return q;
 }
 
+/* The linklayer setting were not transferred from iproute2, in older
+ * versions, and the rate tables lookup systems have been dropped in
+ * the kernel. To keep backward compatible with older iproute2 tc
+ * utils, we detect the linklayer setting by detecting if the rate
+ * table were modified.
+ *
+ * For linklayer ATM table entries, the rate table will be aligned to
+ * 48 bytes, thus some table entries will contain the same value.  The
+ * mpu (min packet unit) is also encoded into the old rate table, thus
+ * starting from the mpu, we find low and high table entries for
+ * mapping this cell.  If these entries contain the same value, when
+ * the rate tables have been modified for linklayer ATM.
+ *
+ * This is done by rounding mpu to the nearest 48 bytes cell/entry,
+ * and then roundup to the next cell, calc the table entry one below,
+ * and compare.
+ */
+static __u8 __detect_linklayer(struct tc_ratespec *r, __u32 *rtab)
+{
+       int low       = roundup(r->mpu, 48);
+       int high      = roundup(low+1, 48);
+       int cell_low  = low >> r->cell_log;
+       int cell_high = (high >> r->cell_log) - 1;
+
+       /* rtab is too inaccurate at rates > 100Mbit/s */
+       if ((r->rate > (100000000/8)) || (rtab[0] == 0)) {
+               pr_debug("TC linklayer: Giving up ATM detection\n");
+               return TC_LINKLAYER_ETHERNET;
+       }
+
+       if ((cell_high > cell_low) && (cell_high < 256)
+           && (rtab[cell_low] == rtab[cell_high])) {
+               pr_debug("TC linklayer: Detected ATM, low(%d)=high(%d)=%u\n",
+                        cell_low, cell_high, rtab[cell_high]);
+               return TC_LINKLAYER_ATM;
+       }
+       return TC_LINKLAYER_ETHERNET;
+}
+
 static struct qdisc_rate_table *qdisc_rtab_list;
 
 struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr 
*tab)
@@ -308,6 +347,8 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec 
*r, struct nlattr *ta
                rtab->rate = *r;
                rtab->refcnt = 1;
                memcpy(rtab->data, nla_data(tab), 1024);
+               if (r->linklayer == TC_LINKLAYER_UNAWARE)
+                       r->linklayer = __detect_linklayer(r, rtab->data);
                rtab->next = qdisc_rtab_list;
                qdisc_rtab_list = rtab;
        }
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 2022408..a7f838b 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -908,6 +908,7 @@ void psched_ratecfg_precompute(struct psched_ratecfg *r,
        memset(r, 0, sizeof(*r));
        r->overhead = conf->overhead;
        r->rate_bps = (u64)conf->rate << 3;
+       r->linklayer = (conf->linklayer & TC_LINKLAYER_MASK);
        r->mult = 1;
        /*
         * Calibrate mult, shift so that token counting is accurate
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index adaedd7..910667c 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -87,7 +87,7 @@ struct htb_class {
        unsigned int children;
        struct htb_class *parent;       /* parent class */
 
-       int prio;               /* these two are used only by leaves... */
+       u32 prio;               /* these two are used only by leaves... */
        int quantum;            /* but stored for parent-to-leaf return */
 
        union {
@@ -1312,6 +1312,7 @@ static int htb_change_class(struct Qdisc *sch, u32 
classid,
        struct htb_sched *q = qdisc_priv(sch);
        struct htb_class *cl = (struct htb_class *)*arg, *parent;
        struct nlattr *opt = tca[TCA_OPTIONS];
+       struct qdisc_rate_table *rtab = NULL, *ctab = NULL;
        struct nlattr *tb[TCA_HTB_MAX + 1];
        struct tc_htb_opt *hopt;
 
@@ -1333,6 +1334,18 @@ static int htb_change_class(struct Qdisc *sch, u32 
classid,
        if (!hopt->rate.rate || !hopt->ceil.rate)
                goto failure;
 
+       /* Keeping backward compatible with rate_table based iproute2 tc */
+       if (hopt->rate.linklayer == TC_LINKLAYER_UNAWARE) {
+               rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB]);
+               if (rtab)
+                       qdisc_put_rtab(rtab);
+       }
+       if (hopt->ceil.linklayer == TC_LINKLAYER_UNAWARE) {
+               ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB]);
+               if (ctab)
+                       qdisc_put_rtab(ctab);
+       }
+
        if (!cl) {              /* new class */
                struct Qdisc *new_q;
                int prio;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 515ce38..7e26ad4 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1179,7 +1179,7 @@ static u32 filter_connect(struct tipc_sock *tsock, struct 
sk_buff **buf)
                /* Accept only ACK or NACK message */
                if (unlikely(msg_errcode(msg))) {
                        sock->state = SS_DISCONNECTING;
-                       sk->sk_err = -ECONNREFUSED;
+                       sk->sk_err = ECONNREFUSED;
                        retval = TIPC_OK;
                        break;
                }
@@ -1190,7 +1190,7 @@ static u32 filter_connect(struct tipc_sock *tsock, struct 
sk_buff **buf)
                res = auto_connect(sock, msg);
                if (res) {
                        sock->state = SS_DISCONNECTING;
-                       sk->sk_err = res;
+                       sk->sk_err = -res;
                        retval = TIPC_OK;
                        break;
                }
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to