diff options
Diffstat (limited to 'net/ipv6')
31 files changed, 70 insertions, 47 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 4da664538f52..c250d0af10d7 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -40,7 +40,6 @@ * status etc. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e19457fe4f6e..5a0ba58b86cc 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -23,7 +23,6 @@ #include <linux/module.h> #include <linux/capability.h> -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -660,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; diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index d31c0d6c0448..9d4831bd4335 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -24,7 +24,6 @@ * This file is derived from net/ipv4/ah.c. */ -#include <linux/config.h> #include <linux/module.h> #include <net/ip.h> #include <net/ah.h> diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 39ec528923f6..f6881d7a0385 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -14,7 +14,6 @@ */ #include <linux/capability.h> -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/types.h> diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index a15a6f320f70..a278d5e862fe 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -24,7 +24,6 @@ * This file is derived from net/ipv4/esp.c */ -#include <linux/config.h> #include <linux/module.h> #include <net/ip.h> #include <net/xfrm.h> diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index a18d4256372c..9d0ee7f0eeb5 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -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) diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index eb2865d5ae28..5c950cc79d80 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -13,7 +13,6 @@ * 2 of the License, or(at your option) any later version. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/in6.h> #include <linux/ipv6.h> @@ -187,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); diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 2ae84c961678..d2f3fc990bfa 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -14,7 +14,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/random.h> diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 2cb6149349bf..764221220afd 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -19,7 +19,6 @@ * remove ip6_null_entry from the top of * routing table. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/net.h> diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index f9ca63912fbf..1d672b0547f2 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -10,7 +10,6 @@ */ #include <linux/capability.h> -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index aceee252503d..df8f051c0fce 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -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) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index abb94de33768..2c5b44575af0 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -28,7 +28,6 @@ * for datagram xmit */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/string.h> @@ -230,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); @@ -835,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); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index a995796b5a57..bc77c0e1a943 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -19,7 +19,6 @@ * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/capability.h> #include <linux/errno.h> diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index f28cd37feed3..b285b0357084 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -30,7 +30,6 @@ * The decompression of IP datagram MUST be done after the reassembly, * AH/ESP processing. */ -#include <linux/config.h> #include <linux/module.h> #include <net/ip.h> #include <net/xfrm.h> diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 4c20eeb3d568..c28e5c287447 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -27,7 +27,6 @@ #include <linux/module.h> #include <linux/capability.h> -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -58,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; diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c index 16482785bdfd..dd4d1ce77769 100644 --- a/net/ipv6/ipv6_syms.c +++ b/net/ipv6/ipv6_syms.c @@ -1,5 +1,4 @@ -#include <linux/config.h> #include <linux/module.h> #include <net/protocol.h> #include <net/ipv6.h> diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 6e871afbb2c7..9d697d4dcffc 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -28,7 +28,6 @@ * - MLDv2 support */ -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/types.h> diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index dfa20d3be9b6..b50055b9278d 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -48,7 +48,6 @@ #endif #include <linux/module.h> -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 0b5bd5587a3e..7ef143c0ebf6 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -19,7 +19,6 @@ */ #include <linux/capability.h> -#include <linux/config.h> #include <linux/in.h> #include <linux/skbuff.h> #include <linux/kmod.h> diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index de1175c27f6d..8629ba195d2d 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c @@ -15,7 +15,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/module.h> #include <linux/skbuff.h> #include <linux/icmpv6.h> diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 2a71c3b669f1..c2ab38ff46af 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -20,7 +20,6 @@ * structures. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/ipv6.h> #include <linux/in6.h> diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index c32a029e43f0..00d5583807f7 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -14,7 +14,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/string.h> diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 779ddf77f4d4..efee7a6301a8 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -17,7 +17,6 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/sched.h> #include <linux/socket.h> #include <linux/net.h> diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index eef985e010ea..4e299c69e1c6 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -28,7 +28,6 @@ * YOSHIFUJI,H. @USAGI Always remove fragment header to * calculate ICV correctly. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/string.h> diff --git a/net/ipv6/route.c b/net/ipv6/route.c index e728980160d2..87c39c978cd0 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -25,7 +25,6 @@ */ #include <linux/capability.h> -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/times.h> diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 6578c3080f47..c56aeece2bf5 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -18,7 +18,6 @@ * Nate Thompson <nate@thebog.net>: 6to4 support */ -#include <linux/config.h> #include <linux/module.h> #include <linux/capability.h> #include <linux/errno.h> diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 8eff9fa1e983..7a4639db1346 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -7,7 +7,6 @@ #include <linux/mm.h> #include <linux/sysctl.h> -#include <linux/config.h> #include <linux/in6.h> #include <linux/ipv6.h> #include <net/ndisc.h> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index b36d5b2e7c30..5bdcb9002cf7 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -26,7 +26,6 @@ */ #include <linux/module.h> -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -270,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) @@ -930,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; @@ -1606,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, }; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 8d3432a70f3a..ccc57f434cd3 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -23,7 +23,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index ee715f2691e9..73cd250aecbb 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -12,7 +12,6 @@ */ #include <linux/compiler.h> -#include <linux/config.h> #include <linux/netdevice.h> #include <net/addrconf.h> #include <net/xfrm.h> diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index d37768e5064f..6b44fe8516c3 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -21,7 +21,6 @@ * Based on net/ipv4/xfrm4_tunnel.c * */ -#include <linux/config.h> #include <linux/module.h> #include <linux/xfrm.h> #include <linux/list.h> |