lkml.org 
[lkml]   [2013]   [Sep]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: Linux 3.10.12

    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;
    }

    \
     
     \ /
      Last update: 2013-09-14 16:21    [W:7.560 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site