mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-27 09:11:49 +00:00
567 lines
17 KiB
Diff
567 lines
17 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index bc4dd5b..3f23cb7 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 3
|
|
PATCHLEVEL = 4
|
|
-SUBLEVEL = 61
|
|
+SUBLEVEL = 62
|
|
EXTRAVERSION =
|
|
NAME = Saber-toothed Squirrel
|
|
|
|
diff --git a/arch/m32r/boot/compressed/Makefile b/arch/m32r/boot/compressed/Makefile
|
|
index 177716b..01729c2 100644
|
|
--- a/arch/m32r/boot/compressed/Makefile
|
|
+++ b/arch/m32r/boot/compressed/Makefile
|
|
@@ -43,9 +43,9 @@ endif
|
|
|
|
OBJCOPYFLAGS += -R .empty_zero_page
|
|
|
|
-suffix_$(CONFIG_KERNEL_GZIP) = gz
|
|
-suffix_$(CONFIG_KERNEL_BZIP2) = bz2
|
|
-suffix_$(CONFIG_KERNEL_LZMA) = lzma
|
|
+suffix-$(CONFIG_KERNEL_GZIP) = gz
|
|
+suffix-$(CONFIG_KERNEL_BZIP2) = bz2
|
|
+suffix-$(CONFIG_KERNEL_LZMA) = lzma
|
|
|
|
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
|
|
$(call if_changed,ld)
|
|
diff --git a/arch/m32r/boot/compressed/misc.c b/arch/m32r/boot/compressed/misc.c
|
|
index 370d608..28a0952 100644
|
|
--- a/arch/m32r/boot/compressed/misc.c
|
|
+++ b/arch/m32r/boot/compressed/misc.c
|
|
@@ -28,7 +28,7 @@ static unsigned long free_mem_ptr;
|
|
static unsigned long free_mem_end_ptr;
|
|
|
|
#ifdef CONFIG_KERNEL_BZIP2
|
|
-static void *memset(void *s, int c, size_t n)
|
|
+void *memset(void *s, int c, size_t n)
|
|
{
|
|
char *ss = s;
|
|
|
|
@@ -39,6 +39,16 @@ static void *memset(void *s, int c, size_t n)
|
|
#endif
|
|
|
|
#ifdef CONFIG_KERNEL_GZIP
|
|
+void *memcpy(void *dest, const void *src, size_t n)
|
|
+{
|
|
+ char *d = dest;
|
|
+ const char *s = src;
|
|
+ while (n--)
|
|
+ *d++ = *s++;
|
|
+
|
|
+ return dest;
|
|
+}
|
|
+
|
|
#define BOOT_HEAP_SIZE 0x10000
|
|
#include "../../../../lib/decompress_inflate.c"
|
|
#endif
|
|
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
|
index 8c45818..8375622 100644
|
|
--- a/arch/x86/kvm/emulate.c
|
|
+++ b/arch/x86/kvm/emulate.c
|
|
@@ -3737,10 +3737,6 @@ static int decode_operand(struct x86_emulate_ctxt *ctxt, struct operand *op,
|
|
break;
|
|
case OpMem8:
|
|
ctxt->memop.bytes = 1;
|
|
- if (ctxt->memop.type == OP_REG) {
|
|
- ctxt->memop.addr.reg = decode_register(ctxt, ctxt->modrm_rm, 1);
|
|
- fetch_register_operand(&ctxt->memop);
|
|
- }
|
|
goto mem_common;
|
|
case OpMem16:
|
|
ctxt->memop.bytes = 2;
|
|
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
|
|
index d9f8358..80103bb 100644
|
|
--- a/drivers/net/bonding/bond_main.c
|
|
+++ b/drivers/net/bonding/bond_main.c
|
|
@@ -3750,11 +3750,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/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
|
|
index 2205db7..1b44047 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/macvtap.c b/drivers/net/macvtap.c
|
|
index 5151f06..77ce8b2 100644
|
|
--- a/drivers/net/macvtap.c
|
|
+++ b/drivers/net/macvtap.c
|
|
@@ -642,6 +642,28 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb,
|
|
return 0;
|
|
}
|
|
|
|
+static unsigned long iov_pages(const struct iovec *iv, int offset,
|
|
+ unsigned long nr_segs)
|
|
+{
|
|
+ unsigned long seg, base;
|
|
+ int pages = 0, len, size;
|
|
+
|
|
+ while (nr_segs && (offset >= iv->iov_len)) {
|
|
+ offset -= iv->iov_len;
|
|
+ ++iv;
|
|
+ --nr_segs;
|
|
+ }
|
|
+
|
|
+ for (seg = 0; seg < nr_segs; seg++) {
|
|
+ base = (unsigned long)iv[seg].iov_base + offset;
|
|
+ len = iv[seg].iov_len - offset;
|
|
+ size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT;
|
|
+ pages += size;
|
|
+ offset = 0;
|
|
+ }
|
|
+
|
|
+ return pages;
|
|
+}
|
|
|
|
/* Get packet from user space buffer */
|
|
static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
|
@@ -688,31 +710,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
|
if (unlikely(count > UIO_MAXIOV))
|
|
goto err;
|
|
|
|
- if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY))
|
|
- zerocopy = true;
|
|
-
|
|
- if (zerocopy) {
|
|
- /* Userspace may produce vectors with count greater than
|
|
- * MAX_SKB_FRAGS, so we need to linearize parts of the skb
|
|
- * to let the rest of data to be fit in the frags.
|
|
- */
|
|
- if (count > MAX_SKB_FRAGS) {
|
|
- copylen = iov_length(iv, count - MAX_SKB_FRAGS);
|
|
- if (copylen < vnet_hdr_len)
|
|
- copylen = 0;
|
|
- else
|
|
- copylen -= vnet_hdr_len;
|
|
- }
|
|
- /* There are 256 bytes to be copied in skb, so there is enough
|
|
- * room for skb expand head in case it is used.
|
|
- * The rest buffer is mapped from userspace.
|
|
- */
|
|
- if (copylen < vnet_hdr.hdr_len)
|
|
- copylen = vnet_hdr.hdr_len;
|
|
- if (!copylen)
|
|
- copylen = GOODCOPY_LEN;
|
|
+ if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) {
|
|
+ copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN;
|
|
linear = copylen;
|
|
- } else {
|
|
+ if (iov_pages(iv, vnet_hdr_len + copylen, count)
|
|
+ <= MAX_SKB_FRAGS)
|
|
+ zerocopy = true;
|
|
+ }
|
|
+
|
|
+ if (!zerocopy) {
|
|
copylen = len;
|
|
linear = vnet_hdr.hdr_len;
|
|
}
|
|
@@ -724,9 +730,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m,
|
|
|
|
if (zerocopy)
|
|
err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count);
|
|
- else
|
|
+ else {
|
|
err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len,
|
|
len);
|
|
+ if (!err && m && m->msg_control) {
|
|
+ struct ubuf_info *uarg = m->msg_control;
|
|
+ uarg->callback(uarg);
|
|
+ }
|
|
+ }
|
|
+
|
|
if (err)
|
|
goto err_kfree;
|
|
|
|
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
|
|
index c896b8f..194f879 100644
|
|
--- a/drivers/net/tun.c
|
|
+++ b/drivers/net/tun.c
|
|
@@ -615,8 +615,9 @@ static ssize_t tun_get_user(struct tun_struct *tun,
|
|
int offset = 0;
|
|
|
|
if (!(tun->flags & TUN_NO_PI)) {
|
|
- if ((len -= sizeof(pi)) > count)
|
|
+ if (len < sizeof(pi))
|
|
return -EINVAL;
|
|
+ len -= sizeof(pi);
|
|
|
|
if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
|
|
return -EFAULT;
|
|
@@ -624,8 +625,9 @@ static ssize_t tun_get_user(struct tun_struct *tun,
|
|
}
|
|
|
|
if (tun->flags & TUN_VNET_HDR) {
|
|
- if ((len -= tun->vnet_hdr_sz) > count)
|
|
+ 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/vhost/vhost.c b/drivers/vhost/vhost.c
|
|
index 1a9e2a9..a50cb9c 100644
|
|
--- a/drivers/vhost/vhost.c
|
|
+++ b/drivers/vhost/vhost.c
|
|
@@ -1603,6 +1603,7 @@ void vhost_zerocopy_callback(struct ubuf_info *ubuf)
|
|
struct vhost_ubuf_ref *ubufs = ubuf->ctx;
|
|
struct vhost_virtqueue *vq = ubufs->vq;
|
|
|
|
+ vhost_poll_queue(&vq->poll);
|
|
/* set len = 1 to mark this desc buffers done DMA */
|
|
vq->heads[ubuf->desc].len = VHOST_DMA_DONE_LEN;
|
|
kref_put(&ubufs->kref, vhost_zerocopy_done_signal);
|
|
diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
|
|
index ba45e6b..f5a21d0 100644
|
|
--- a/include/linux/icmpv6.h
|
|
+++ b/include/linux/icmpv6.h
|
|
@@ -123,6 +123,8 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
|
|
#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/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
|
|
index 9069071..ca670d9 100644
|
|
--- a/net/bridge/br_multicast.c
|
|
+++ b/net/bridge/br_multicast.c
|
|
@@ -1155,7 +1155,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(mld2q->mld2q_mrc) : 1;
|
|
+
|
|
+ max_delay = max(msecs_to_jiffies(MLDV2_MRC(ntohs(mld2q->mld2q_mrc))), 1UL);
|
|
}
|
|
|
|
if (!group)
|
|
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
|
|
index 69b7ca3..ebd4b21 100644
|
|
--- a/net/core/neighbour.c
|
|
+++ b/net/core/neighbour.c
|
|
@@ -1442,16 +1442,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/sysctl_net_core.c b/net/core/sysctl_net_core.c
|
|
index 0c28508..77d1550 100644
|
|
--- a/net/core/sysctl_net_core.c
|
|
+++ b/net/core/sysctl_net_core.c
|
|
@@ -19,6 +19,9 @@
|
|
#include <net/sock.h>
|
|
#include <net/net_ratelimit.h>
|
|
|
|
+static int zero = 0;
|
|
+static int ushort_max = USHRT_MAX;
|
|
+
|
|
#ifdef CONFIG_RPS
|
|
static int rps_sock_flow_sysctl(ctl_table *table, int write,
|
|
void __user *buffer, size_t *lenp, loff_t *ppos)
|
|
@@ -197,7 +200,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/fib_trie.c b/net/ipv4/fib_trie.c
|
|
index 30b88d7..424704a 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>
|
|
@@ -1772,10 +1771,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/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/ipv6/addrconf.c b/net/ipv6/addrconf.c
|
|
index d427f1b..abfa007 100644
|
|
--- a/net/ipv6/addrconf.c
|
|
+++ b/net/ipv6/addrconf.c
|
|
@@ -910,12 +910,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 (!ift || IS_ERR(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);
|
|
printk(KERN_INFO
|
|
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
|
|
index 27ac95a..dbf20f6 100644
|
|
--- a/net/ipv6/icmp.c
|
|
+++ b/net/ipv6/icmp.c
|
|
@@ -917,6 +917,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)
|
|
@@ -928,7 +936,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 c3a007d..5bb77a6 100644
|
|
--- a/net/ipv6/ip6_fib.c
|
|
+++ b/net/ipv6/ip6_fib.c
|
|
@@ -949,14 +949,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 843d6eb..5cc78e6 100644
|
|
--- a/net/ipv6/ndisc.c
|
|
+++ b/net/ipv6/ndisc.c
|
|
@@ -441,7 +441,6 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
|
|
int hlen = LL_RESERVED_SPACE(dev);
|
|
int tlen = dev->needed_tailroom;
|
|
int len;
|
|
- int err;
|
|
u8 *opt;
|
|
|
|
if (!dev->addr_len)
|
|
@@ -451,14 +450,12 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
|
|
if (llinfo)
|
|
len += ndisc_opt_addr_space(dev);
|
|
|
|
- skb = sock_alloc_send_skb(sk,
|
|
- (MAX_HEADER + sizeof(struct ipv6hdr) +
|
|
- len + hlen + tlen),
|
|
- 1, &err);
|
|
+ skb = alloc_skb((MAX_HEADER + sizeof(struct ipv6hdr) +
|
|
+ len + hlen + tlen), GFP_ATOMIC);
|
|
if (!skb) {
|
|
ND_PRINTK0(KERN_ERR
|
|
- "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n",
|
|
- __func__, err);
|
|
+ "ICMPv6 ND: %s() failed to allocate an skb.\n",
|
|
+ __func__);
|
|
return NULL;
|
|
}
|
|
|
|
@@ -486,6 +483,11 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
|
|
csum_partial(hdr,
|
|
len, 0));
|
|
|
|
+ /* 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/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
|
|
index 7ee7121..c4717e8 100644
|
|
--- a/net/ipv6/tcp_ipv6.c
|
|
+++ b/net/ipv6/tcp_ipv6.c
|
|
@@ -1571,7 +1571,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_tclass(ipv6_hdr(skb));
|
|
+ np->rcv_tclass = ipv6_tclass(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/sched/sch_htb.c b/net/sched/sch_htb.c
|
|
index f08b9166..caa5aff 100644
|
|
--- a/net/sched/sch_htb.c
|
|
+++ b/net/sched/sch_htb.c
|
|
@@ -86,7 +86,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 {
|
|
diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c
|
|
index 527e3f0..dd625af 100644
|
|
--- a/net/tipc/eth_media.c
|
|
+++ b/net/tipc/eth_media.c
|
|
@@ -53,6 +53,7 @@ struct eth_bearer {
|
|
struct tipc_bearer *bearer;
|
|
struct net_device *dev;
|
|
struct packet_type tipc_packet_type;
|
|
+ struct work_struct setup;
|
|
struct work_struct cleanup;
|
|
};
|
|
|
|
@@ -138,6 +139,17 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
|
|
}
|
|
|
|
/**
|
|
+ * setup_bearer - setup association between Ethernet bearer and interface
|
|
+ */
|
|
+static void setup_bearer(struct work_struct *work)
|
|
+{
|
|
+ struct eth_bearer *eb_ptr =
|
|
+ container_of(work, struct eth_bearer, setup);
|
|
+
|
|
+ dev_add_pack(&eb_ptr->tipc_packet_type);
|
|
+}
|
|
+
|
|
+/**
|
|
* enable_bearer - attach TIPC bearer to an Ethernet interface
|
|
*/
|
|
|
|
@@ -181,7 +193,8 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
|
|
eb_ptr->tipc_packet_type.func = recv_msg;
|
|
eb_ptr->tipc_packet_type.af_packet_priv = eb_ptr;
|
|
INIT_LIST_HEAD(&(eb_ptr->tipc_packet_type.list));
|
|
- dev_add_pack(&eb_ptr->tipc_packet_type);
|
|
+ INIT_WORK(&eb_ptr->setup, setup_bearer);
|
|
+ schedule_work(&eb_ptr->setup);
|
|
|
|
/* Associate TIPC bearer with Ethernet bearer */
|
|
|