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: [IPV6]: Added GSO support for TCPv6 [NET]: Generalise TSO-specific bits from skb_setup_caps [IPV6]: Added GSO support for TCPv6 [IPV6]: Remove redundant length check on input [NETFILTER]: SCTP conntrack: fix crash triggered by packet without chunks [TG3]: Update version and reldate [TG3]: Add TSO workaround using GSO [TG3]: Turn on hw fix for ASF problems [TG3]: Add rx BD workaround [TG3]: Add tg3_netif_stop() in vlan functions [TCP]: Reset gso_segs if packet is dodgy
This commit is contained in:
@@ -659,8 +659,6 @@ int inet6_sk_rebuild_header(struct sock *sk)
|
||||
}
|
||||
|
||||
ip6_dst_store(sk, dst, NULL);
|
||||
sk->sk_route_caps = dst->dev->features &
|
||||
~(NETIF_F_IP_CSUM | NETIF_F_TSO);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@@ -179,7 +179,7 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
|
||||
|
||||
static struct inet6_protocol destopt_protocol = {
|
||||
.handler = ipv6_destopt_rcv,
|
||||
.flags = INET6_PROTO_NOPOLICY,
|
||||
.flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
|
||||
};
|
||||
|
||||
void __init ipv6_destopt_init(void)
|
||||
@@ -340,7 +340,7 @@ looped_back:
|
||||
|
||||
static struct inet6_protocol rthdr_protocol = {
|
||||
.handler = ipv6_rthdr_rcv,
|
||||
.flags = INET6_PROTO_NOPOLICY,
|
||||
.flags = INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
|
||||
};
|
||||
|
||||
void __init ipv6_rthdr_init(void)
|
||||
|
@@ -186,8 +186,6 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
|
||||
}
|
||||
|
||||
ip6_dst_store(sk, dst, NULL);
|
||||
sk->sk_route_caps = dst->dev->features &
|
||||
~(NETIF_F_IP_CSUM | NETIF_F_TSO);
|
||||
}
|
||||
|
||||
skb->dst = dst_clone(dst);
|
||||
|
@@ -84,14 +84,9 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
|
||||
*/
|
||||
IP6CB(skb)->iif = skb->dst ? ((struct rt6_info *)skb->dst)->rt6i_idev->dev->ifindex : dev->ifindex;
|
||||
|
||||
if (skb->len < sizeof(struct ipv6hdr))
|
||||
if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
|
||||
goto err;
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) {
|
||||
IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
hdr = skb->nh.ipv6h;
|
||||
|
||||
if (hdr->version != 6)
|
||||
|
@@ -229,7 +229,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
|
||||
skb->priority = sk->sk_priority;
|
||||
|
||||
mtu = dst_mtu(dst);
|
||||
if ((skb->len <= mtu) || ipfragok) {
|
||||
if ((skb->len <= mtu) || ipfragok || skb_shinfo(skb)->gso_size) {
|
||||
IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
|
||||
return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
|
||||
dst_output);
|
||||
@@ -834,7 +834,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
|
||||
/* specify the length of each IP datagram fragment*/
|
||||
skb_shinfo(skb)->gso_size = mtu - fragheaderlen -
|
||||
sizeof(struct frag_hdr);
|
||||
skb_shinfo(skb)->gso_type = SKB_GSO_UDPV4;
|
||||
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
|
||||
ipv6_select_ident(skb, &fhdr);
|
||||
skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
|
||||
__skb_queue_tail(&sk->sk_write_queue, skb);
|
||||
|
@@ -57,9 +57,71 @@
|
||||
|
||||
DEFINE_SNMP_STAT(struct ipstats_mib, ipv6_statistics) __read_mostly;
|
||||
|
||||
static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
|
||||
{
|
||||
struct sk_buff *segs = ERR_PTR(-EINVAL);
|
||||
struct ipv6hdr *ipv6h;
|
||||
struct inet6_protocol *ops;
|
||||
int proto;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
|
||||
goto out;
|
||||
|
||||
ipv6h = skb->nh.ipv6h;
|
||||
proto = ipv6h->nexthdr;
|
||||
__skb_pull(skb, sizeof(*ipv6h));
|
||||
|
||||
rcu_read_lock();
|
||||
for (;;) {
|
||||
struct ipv6_opt_hdr *opth;
|
||||
int len;
|
||||
|
||||
if (proto != NEXTHDR_HOP) {
|
||||
ops = rcu_dereference(inet6_protos[proto]);
|
||||
|
||||
if (unlikely(!ops))
|
||||
goto unlock;
|
||||
|
||||
if (!(ops->flags & INET6_PROTO_GSO_EXTHDR))
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, 8)))
|
||||
goto unlock;
|
||||
|
||||
opth = (void *)skb->data;
|
||||
len = opth->hdrlen * 8 + 8;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, len)))
|
||||
goto unlock;
|
||||
|
||||
proto = opth->nexthdr;
|
||||
__skb_pull(skb, len);
|
||||
}
|
||||
|
||||
skb->h.raw = skb->data;
|
||||
if (likely(ops->gso_segment))
|
||||
segs = ops->gso_segment(skb, features);
|
||||
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
|
||||
if (unlikely(IS_ERR(segs)))
|
||||
goto out;
|
||||
|
||||
for (skb = segs; skb; skb = skb->next) {
|
||||
ipv6h = skb->nh.ipv6h;
|
||||
ipv6h->payload_len = htons(skb->len - skb->mac_len);
|
||||
}
|
||||
|
||||
out:
|
||||
return segs;
|
||||
}
|
||||
|
||||
static struct packet_type ipv6_packet_type = {
|
||||
.type = __constant_htons(ETH_P_IPV6),
|
||||
.func = ipv6_rcv,
|
||||
.gso_segment = ipv6_gso_segment,
|
||||
};
|
||||
|
||||
struct ip6_ra_chain *ip6_ra_chain;
|
||||
|
@@ -269,9 +269,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
|
||||
ipv6_addr_copy(&np->saddr, saddr);
|
||||
inet->rcv_saddr = LOOPBACK4_IPV6;
|
||||
|
||||
sk->sk_gso_type = SKB_GSO_TCPV6;
|
||||
ip6_dst_store(sk, dst, NULL);
|
||||
sk->sk_route_caps = dst->dev->features &
|
||||
~(NETIF_F_IP_CSUM | NETIF_F_TSO);
|
||||
|
||||
icsk->icsk_ext_hdr_len = 0;
|
||||
if (np->opt)
|
||||
@@ -929,9 +928,8 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
|
||||
* comment in that function for the gory details. -acme
|
||||
*/
|
||||
|
||||
sk->sk_gso_type = SKB_GSO_TCPV6;
|
||||
ip6_dst_store(newsk, dst, NULL);
|
||||
newsk->sk_route_caps = dst->dev->features &
|
||||
~(NETIF_F_IP_CSUM | NETIF_F_TSO);
|
||||
|
||||
newtcp6sk = (struct tcp6_sock *)newsk;
|
||||
inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
|
||||
@@ -1605,6 +1603,7 @@ struct proto tcpv6_prot = {
|
||||
static struct inet6_protocol tcpv6_protocol = {
|
||||
.handler = tcp_v6_rcv,
|
||||
.err_handler = tcp_v6_err,
|
||||
.gso_segment = tcp_tso_segment,
|
||||
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user