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; ...@@ -23,8 +23,8 @@ struct vlan_collection;
struct vlan_dev_info; struct vlan_dev_info;
struct hlist_node; struct hlist_node;
#include <linux/proc_fs.h> /* for proc_dir_entry */
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h>
#define VLAN_HLEN 4 /* The additional bytes (on top of the Ethernet header) #define VLAN_HLEN 4 /* The additional bytes (on top of the Ethernet header)
* that VLAN requires. * that VLAN requires.
...@@ -185,7 +185,8 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, ...@@ -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 * This allows the VLAN to have a different MAC than the underlying
* device, and still route correctly. * 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; skb->pkt_type = PACKET_HOST;
break; break;
}; };
......
...@@ -257,11 +257,11 @@ nodata: ...@@ -257,11 +257,11 @@ nodata:
} }
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 { do {
struct sk_buff *this = list; struct sk_buff *this = list;
...@@ -270,6 +270,11 @@ static void skb_drop_fraglist(struct sk_buff *skb) ...@@ -270,6 +270,11 @@ static void skb_drop_fraglist(struct sk_buff *skb)
} while (list); } 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) static void skb_clone_fraglist(struct sk_buff *skb)
{ {
struct sk_buff *list; struct sk_buff *list;
...@@ -830,41 +835,75 @@ free_skb: ...@@ -830,41 +835,75 @@ free_skb:
int ___pskb_trim(struct sk_buff *skb, unsigned int len) int ___pskb_trim(struct sk_buff *skb, unsigned int len)
{ {
struct sk_buff **fragp;
struct sk_buff *frag;
int offset = skb_headlen(skb); int offset = skb_headlen(skb);
int nfrags = skb_shinfo(skb)->nr_frags; int nfrags = skb_shinfo(skb)->nr_frags;
int i; 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++) { for (i = 0; i < nfrags; i++) {
int end = offset + skb_shinfo(skb)->frags[i].size; int end = offset + skb_shinfo(skb)->frags[i].size;
if (end > len) {
if (skb_cloned(skb)) { if (end < len) {
if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) offset = end;
return -ENOMEM; continue;
} }
if (len <= offset) {
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); put_page(skb_shinfo(skb)->frags[i].page);
skb_shinfo(skb)->nr_frags--;
} else { if (skb_shinfo(skb)->frag_list)
skb_shinfo(skb)->frags[i].size = len - offset; skb_drop_fraglist(skb);
break;
} }
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; 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 (offset < len) { if (len > skb_headlen(skb)) {
skb->data_len -= skb->len - len; skb->data_len -= skb->len - len;
skb->len = len; skb->len = len;
} else { } else {
if (len <= skb_headlen(skb)) {
skb->len = len; skb->len = len;
skb->data_len = 0; skb->data_len = 0;
skb->tail = skb->data + len; 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;
}
} }
return 0; return 0;
......
...@@ -428,6 +428,9 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, ...@@ -428,6 +428,9 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
goto drop; 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, return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
ip_rcv_finish); ip_rcv_finish);
......
...@@ -196,7 +196,7 @@ struct htb_class ...@@ -196,7 +196,7 @@ struct htb_class
struct qdisc_rate_table *rate; /* rate table of the class itself */ struct qdisc_rate_table *rate; /* rate table of the class itself */
struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */ struct qdisc_rate_table *ceil; /* ceiling rate (limits borrows too) */
long buffer,cbuffer; /* token bucket depth/rate */ 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 */ long tokens,ctokens; /* current number of tokens */
psched_time_t t_c; /* checkpoint time */ psched_time_t t_c; /* checkpoint time */
}; };
...@@ -1601,7 +1601,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, ...@@ -1601,7 +1601,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
/* set class to be in HTB_CAN_SEND state */ /* set class to be in HTB_CAN_SEND state */
cl->tokens = hopt->buffer; cl->tokens = hopt->buffer;
cl->ctokens = hopt->cbuffer; cl->ctokens = hopt->cbuffer;
cl->mbuffer = 60000000; /* 1min */ cl->mbuffer = PSCHED_JIFFIE2US(HZ*60) /* 1min */
PSCHED_GET_TIME(cl->t_c); PSCHED_GET_TIME(cl->t_c);
cl->cmode = HTB_CAN_SEND; 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