summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-28 01:19:40 -0700
committerDavid S. Miller <davem@davemloft.net>2008-06-28 01:19:40 -0700
commit1b63ba8a86c85524a8d7e5953b314ce71ebcb9c9 (patch)
treefe3dc41cbb47ae12b7c3faf6a88b097349e50d5a /net/core
parente35c3269edba151e1c703d87068a28ce2cd65bb0 (diff)
parentd420895efb259a78dda50f95289571faa6e10e41 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/wireless/iwlwifi/iwl4965-base.c
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/net_namespace.c3
-rw-r--r--net/core/skbuff.c17
3 files changed, 20 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index f6944ecd5b2e..472676dd550e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2107,6 +2107,10 @@ int netif_receive_skb(struct sk_buff *skb)
rcu_read_lock();
+ /* Don't receive packets in an exiting network namespace */
+ if (!net_alive(dev_net(skb->dev)))
+ goto out;
+
#ifdef CONFIG_NET_CLS_ACT
if (skb->tc_verd & TC_NCLS) {
skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
@@ -3034,7 +3038,7 @@ EXPORT_SYMBOL(dev_unicast_delete);
/**
* dev_unicast_add - add a secondary unicast address
* @dev: device
- * @addr: address to delete
+ * @addr: address to add
* @alen: length of @addr
*
* Add a secondary unicast address to the device or increase
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 72b4c184dd84..7c52fe277b62 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -140,6 +140,9 @@ static void cleanup_net(struct work_struct *work)
struct pernet_operations *ops;
struct net *net;
+ /* Be very certain incoming network packets will not find us */
+ rcu_barrier();
+
net = container_of(work, struct net, work);
mutex_lock(&net_mutex);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 2df012be973d..7c571560e9d2 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1290,12 +1290,14 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
{
unsigned int nr_pages = spd->nr_pages;
unsigned int poff, plen, len, toff, tlen;
- int headlen, seg;
+ int headlen, seg, error = 0;
toff = *offset;
tlen = *total_len;
- if (!tlen)
+ if (!tlen) {
+ error = 1;
goto err;
+ }
/*
* if the offset is greater than the linear part, go directly to
@@ -1337,7 +1339,8 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
* just jump directly to update and return, no point
* in going over fragments when the output is full.
*/
- if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb))
+ error = spd_fill_page(spd, virt_to_page(p), plen, poff, skb);
+ if (error)
goto done;
tlen -= plen;
@@ -1367,7 +1370,8 @@ map_frag:
if (!plen)
break;
- if (spd_fill_page(spd, f->page, plen, poff, skb))
+ error = spd_fill_page(spd, f->page, plen, poff, skb);
+ if (error)
break;
tlen -= plen;
@@ -1380,7 +1384,10 @@ done:
return 0;
}
err:
- return 1;
+ /* update the offset to reflect the linear part skip, if any */
+ if (!error)
+ *offset = toff;
+ return error;
}
/*