Commit 76aba64a authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [VLAN]: __vlan_hwaccel_rx can use the faster ether_compare_addr
  [PKT_SCHED] HTB: initialize upper bound properly
  [IPV4]: Clear skb cb on IP input
  [NET]: Update frag_list in pskb_trim
parents 52393ccc 0610d11b
......@@ -23,8 +23,8 @@ struct vlan_collection;
struct vlan_dev_info;
struct hlist_node;
#include <linux/proc_fs.h> /* for proc_dir_entry */
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#define VLAN_HLEN 4 /* The additional bytes (on top of the Ethernet header)
* that VLAN requires.
......@@ -185,7 +185,8 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb,
* This allows the VLAN to have a different MAC than the underlying
* device, and still route correctly.
*/
if (!memcmp(eth_hdr(skb)->h_dest, skb->dev->dev_addr, ETH_ALEN))
if (!compare_ether_addr(eth_hdr(skb)->h_dest,
skb->dev->dev_addr))
skb->pkt_type = PACKET_HOST;
break;
};
......
......@@ -257,11 +257,11 @@ struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
}
static void skb_drop_fraglist(struct sk_buff *skb)
static void skb_drop_list(struct sk_buff **listp)
{
struct sk_buff *list = skb_shinfo(skb)->frag_list;
struct sk_buff *list = *listp;
skb_shinfo(skb)->frag_list = NULL;
*listp = NULL;
do {
struct sk_buff *this = list;
......@@ -270,6 +270,11 @@ static void skb_drop_fraglist(struct sk_buff *skb)
} while (list);
}
static inline void skb_drop_fraglist(struct sk_buff *skb)
{
skb_drop_list(&skb_shinfo(skb)->frag_list);
}
static void skb_clone_fraglist(struct sk_buff *skb)
{
struct sk_buff *list;
......@@ -830,41 +835,75 @@ int skb_pad(struct sk_buff *skb, int pad)
int ___pskb_trim(struct sk_buff *skb, unsigned int len)
{
struct sk_buff **fragp;
struct sk_buff *frag;
int offset = skb_headlen(skb);
int nfrags = skb_shinfo(skb)->nr_frags;
int i;
int err;
if (skb_cloned(skb) &&
unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))))
return err;
for (i = 0; i < nfrags; i++) {
int end = offset + skb_shinfo(skb)->frags[i].size;
if (end > len) {
if (skb_cloned(skb)) {
if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
return -ENOMEM;
}
if (len <= offset) {
put_page(skb_shinfo(skb)->frags[i].page);
skb_shinfo(skb)->nr_frags--;
} else {
skb_shinfo(skb)->frags[i].size = len - offset;
}
if (end < len) {
offset = end;
continue;
}
offset = end;
if (len > offset)
skb_shinfo(skb)->frags[i++].size = len - offset;
skb_shinfo(skb)->nr_frags = i;
for (; i < nfrags; i++)
put_page(skb_shinfo(skb)->frags[i].page);
if (skb_shinfo(skb)->frag_list)
skb_drop_fraglist(skb);
break;
}
if (offset < len) {
for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp);
fragp = &frag->next) {
int end = offset + frag->len;
if (skb_shared(frag)) {
struct sk_buff *nfrag;
nfrag = skb_clone(frag, GFP_ATOMIC);
if (unlikely(!nfrag))
return -ENOMEM;
nfrag->next = frag->next;
frag = nfrag;
*fragp = frag;
}
if (end < len) {
offset = end;
continue;
}
if (end > len &&
unlikely((err = pskb_trim(frag, len - offset))))
return err;
if (frag->next)
skb_drop_list(&frag->next);
break;
}
if (len > skb_headlen(skb)) {
skb->data_len -= skb->len - len;
skb->len = len;
} else {
if (len <= skb_headlen(skb)) {
skb->len = len;
skb->data_len = 0;
skb->tail = skb->data + len;
if (skb_shinfo(skb)->frag_list && !skb_cloned(skb))
skb_drop_fraglist(skb);
} else {
skb->data_len -= skb->len - len;
skb->len = len;
}
skb->len = len;
skb->data_len = 0;
skb->tail = skb->data + len;
}
return 0;
......
......@@ -428,6 +428,9 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
goto drop;
}
/* Remove any debris in the socket control block */
memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
ip_rcv_finish);
......
......@@ -196,7 +196,7 @@ struct htb_class
struct qdisc_rate_table *rate; /* rate table of the class itself */
struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */
long buffer,cbuffer; /* token bucket depth/rate */
long mbuffer; /* max wait time */
psched_tdiff_t mbuffer; /* max wait time */
long tokens,ctokens; /* current number of tokens */
psched_time_t t_c; /* checkpoint time */
};
......@@ -1601,7 +1601,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
/* set class to be in HTB_CAN_SEND state */
cl->tokens = hopt->buffer;
cl->ctokens = hopt->cbuffer;
cl->mbuffer = 60000000; /* 1min */
cl->mbuffer = PSCHED_JIFFIE2US(HZ*60) /* 1min */
PSCHED_GET_TIME(cl->t_c);
cl->cmode = HTB_CAN_SEND;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment