You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (84 commits) wimax: fix kernel-doc for debufs_dentry member of struct wimax_dev net: convert pegasus driver to net_device_ops bnx2x: Prevent eeprom set when driver is down net: switch kaweth driver to netdevops pcnet32: round off carrier watch timer i2400m/usb: wrap USB power saving in #ifdef CONFIG_PM wimax: testing for rfkill support should also test for CONFIG_RFKILL_MODULE wimax: fix kconfig interactions with rfkill and input layers wimax: fix '#ifndef CONFIG_BUG' layout to avoid warning r6040: bump release number to 0.20 r6040: warn about MAC address being unset r6040: check PHY status when bringing interface up r6040: make printks consistent with DRV_NAME gianfar: Fixup use of BUS_ID_SIZE mlx4_en: Returning real Max in get_ringparam mlx4_en: Consider inline packets on completion netdev: bfin_mac: enable bfin_mac net dev driver for BF51x qeth: convert to net_device_ops vlan: add neigh_setup dm9601: warn on invalid mac address ...
This commit is contained in:
+102
-5
@@ -672,8 +672,7 @@ int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
|
||||
|
||||
EXPORT_SYMBOL_GPL(ipv6_opt_accepted);
|
||||
|
||||
static struct inet6_protocol *ipv6_gso_pull_exthdrs(struct sk_buff *skb,
|
||||
int proto)
|
||||
static int ipv6_gso_pull_exthdrs(struct sk_buff *skb, int proto)
|
||||
{
|
||||
struct inet6_protocol *ops = NULL;
|
||||
|
||||
@@ -704,7 +703,7 @@ static struct inet6_protocol *ipv6_gso_pull_exthdrs(struct sk_buff *skb,
|
||||
__skb_pull(skb, len);
|
||||
}
|
||||
|
||||
return ops;
|
||||
return proto;
|
||||
}
|
||||
|
||||
static int ipv6_gso_send_check(struct sk_buff *skb)
|
||||
@@ -721,7 +720,9 @@ static int ipv6_gso_send_check(struct sk_buff *skb)
|
||||
err = -EPROTONOSUPPORT;
|
||||
|
||||
rcu_read_lock();
|
||||
ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
|
||||
ops = rcu_dereference(inet6_protos[
|
||||
ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr)]);
|
||||
|
||||
if (likely(ops && ops->gso_send_check)) {
|
||||
skb_reset_transport_header(skb);
|
||||
err = ops->gso_send_check(skb);
|
||||
@@ -757,7 +758,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, int features)
|
||||
segs = ERR_PTR(-EPROTONOSUPPORT);
|
||||
|
||||
rcu_read_lock();
|
||||
ops = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr);
|
||||
ops = rcu_dereference(inet6_protos[
|
||||
ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr)]);
|
||||
|
||||
if (likely(ops && ops->gso_segment)) {
|
||||
skb_reset_transport_header(skb);
|
||||
segs = ops->gso_segment(skb, features);
|
||||
@@ -777,11 +780,105 @@ out:
|
||||
return segs;
|
||||
}
|
||||
|
||||
struct ipv6_gro_cb {
|
||||
struct napi_gro_cb napi;
|
||||
int proto;
|
||||
};
|
||||
|
||||
#define IPV6_GRO_CB(skb) ((struct ipv6_gro_cb *)(skb)->cb)
|
||||
|
||||
static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct inet6_protocol *ops;
|
||||
struct sk_buff **pp = NULL;
|
||||
struct sk_buff *p;
|
||||
struct ipv6hdr *iph;
|
||||
unsigned int nlen;
|
||||
int flush = 1;
|
||||
int proto;
|
||||
|
||||
if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
|
||||
goto out;
|
||||
|
||||
iph = ipv6_hdr(skb);
|
||||
__skb_pull(skb, sizeof(*iph));
|
||||
|
||||
flush += ntohs(iph->payload_len) != skb->len;
|
||||
|
||||
rcu_read_lock();
|
||||
proto = ipv6_gso_pull_exthdrs(skb, iph->nexthdr);
|
||||
IPV6_GRO_CB(skb)->proto = proto;
|
||||
ops = rcu_dereference(inet6_protos[proto]);
|
||||
if (!ops || !ops->gro_receive)
|
||||
goto out_unlock;
|
||||
|
||||
flush--;
|
||||
skb_reset_transport_header(skb);
|
||||
nlen = skb_network_header_len(skb);
|
||||
|
||||
for (p = *head; p; p = p->next) {
|
||||
struct ipv6hdr *iph2;
|
||||
|
||||
if (!NAPI_GRO_CB(p)->same_flow)
|
||||
continue;
|
||||
|
||||
iph2 = ipv6_hdr(p);
|
||||
|
||||
/* All fields must match except length. */
|
||||
if (nlen != skb_network_header_len(p) ||
|
||||
memcmp(iph, iph2, offsetof(struct ipv6hdr, payload_len)) ||
|
||||
memcmp(&iph->nexthdr, &iph2->nexthdr,
|
||||
nlen - offsetof(struct ipv6hdr, nexthdr))) {
|
||||
NAPI_GRO_CB(p)->same_flow = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
NAPI_GRO_CB(p)->flush |= flush;
|
||||
}
|
||||
|
||||
NAPI_GRO_CB(skb)->flush |= flush;
|
||||
|
||||
pp = ops->gro_receive(head, skb);
|
||||
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
|
||||
out:
|
||||
NAPI_GRO_CB(skb)->flush |= flush;
|
||||
|
||||
return pp;
|
||||
}
|
||||
|
||||
static int ipv6_gro_complete(struct sk_buff *skb)
|
||||
{
|
||||
struct inet6_protocol *ops;
|
||||
struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
int err = -ENOSYS;
|
||||
|
||||
iph->payload_len = htons(skb->len - skb_network_offset(skb) -
|
||||
sizeof(*iph));
|
||||
|
||||
rcu_read_lock();
|
||||
ops = rcu_dereference(inet6_protos[IPV6_GRO_CB(skb)->proto]);
|
||||
if (WARN_ON(!ops || !ops->gro_complete))
|
||||
goto out_unlock;
|
||||
|
||||
err = ops->gro_complete(skb);
|
||||
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct packet_type ipv6_packet_type = {
|
||||
.type = __constant_htons(ETH_P_IPV6),
|
||||
.func = ipv6_rcv,
|
||||
.gso_send_check = ipv6_gso_send_check,
|
||||
.gso_segment = ipv6_gso_segment,
|
||||
.gro_receive = ipv6_gro_receive,
|
||||
.gro_complete = ipv6_gro_complete,
|
||||
};
|
||||
|
||||
static int __init ipv6_packet_init(void)
|
||||
|
||||
+41
-4
@@ -101,7 +101,7 @@ static void tcp_v6_hash(struct sock *sk)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ __sum16 tcp_v6_check(struct tcphdr *th, int len,
|
||||
static __inline__ __sum16 tcp_v6_check(int len,
|
||||
struct in6_addr *saddr,
|
||||
struct in6_addr *daddr,
|
||||
__wsum base)
|
||||
@@ -501,7 +501,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
|
||||
if (skb) {
|
||||
struct tcphdr *th = tcp_hdr(skb);
|
||||
|
||||
th->check = tcp_v6_check(th, skb->len,
|
||||
th->check = tcp_v6_check(skb->len,
|
||||
&treq->loc_addr, &treq->rmt_addr,
|
||||
csum_partial(th, skb->len, skb->csum));
|
||||
|
||||
@@ -942,6 +942,41 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb)
|
||||
{
|
||||
struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
|
||||
switch (skb->ip_summed) {
|
||||
case CHECKSUM_COMPLETE:
|
||||
if (!tcp_v6_check(skb->len, &iph->saddr, &iph->daddr,
|
||||
skb->csum)) {
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
break;
|
||||
}
|
||||
|
||||
/* fall through */
|
||||
case CHECKSUM_NONE:
|
||||
NAPI_GRO_CB(skb)->flush = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tcp_gro_receive(head, skb);
|
||||
}
|
||||
EXPORT_SYMBOL(tcp6_gro_receive);
|
||||
|
||||
int tcp6_gro_complete(struct sk_buff *skb)
|
||||
{
|
||||
struct ipv6hdr *iph = ipv6_hdr(skb);
|
||||
struct tcphdr *th = tcp_hdr(skb);
|
||||
|
||||
th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb),
|
||||
&iph->saddr, &iph->daddr, 0);
|
||||
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
|
||||
|
||||
return tcp_gro_complete(skb);
|
||||
}
|
||||
EXPORT_SYMBOL(tcp6_gro_complete);
|
||||
|
||||
static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
|
||||
u32 ts, struct tcp_md5sig_key *key, int rst)
|
||||
{
|
||||
@@ -1429,14 +1464,14 @@ out:
|
||||
static __sum16 tcp_v6_checksum_init(struct sk_buff *skb)
|
||||
{
|
||||
if (skb->ip_summed == CHECKSUM_COMPLETE) {
|
||||
if (!tcp_v6_check(tcp_hdr(skb), skb->len, &ipv6_hdr(skb)->saddr,
|
||||
if (!tcp_v6_check(skb->len, &ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr, skb->csum)) {
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
skb->csum = ~csum_unfold(tcp_v6_check(tcp_hdr(skb), skb->len,
|
||||
skb->csum = ~csum_unfold(tcp_v6_check(skb->len,
|
||||
&ipv6_hdr(skb)->saddr,
|
||||
&ipv6_hdr(skb)->daddr, 0));
|
||||
|
||||
@@ -2062,6 +2097,8 @@ static struct inet6_protocol tcpv6_protocol = {
|
||||
.err_handler = tcp_v6_err,
|
||||
.gso_send_check = tcp_v6_gso_send_check,
|
||||
.gso_segment = tcp_tso_segment,
|
||||
.gro_receive = tcp6_gro_receive,
|
||||
.gro_complete = tcp6_gro_complete,
|
||||
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user