diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 1 | ||||
-rw-r--r-- | net/ipv6/addrconf_core.c | 1 | ||||
-rw-r--r-- | net/ipv6/ah6.c | 8 | ||||
-rw-r--r-- | net/ipv6/exthdrs.c | 1 | ||||
-rw-r--r-- | net/ipv6/exthdrs_core.c | 1 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 1 | ||||
-rw-r--r-- | net/ipv6/inet6_connection_sock.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 1 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 8 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 8 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 1 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 2 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter.c | 14 | ||||
-rw-r--r-- | net/ipv6/netfilter/Kconfig | 1 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 7 | ||||
-rw-r--r-- | net/ipv6/proc.c | 1 | ||||
-rw-r--r-- | net/ipv6/raw.c | 1 | ||||
-rw-r--r-- | net/ipv6/reassembly.c | 1 | ||||
-rw-r--r-- | net/ipv6/route.c | 22 | ||||
-rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 1 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 25 | ||||
-rw-r--r-- | net/ipv6/udp.c | 27 | ||||
-rw-r--r-- | net/ipv6/udplite.c | 14 | ||||
-rw-r--r-- | net/ipv6/xfrm6_state.c | 1 |
25 files changed, 105 insertions, 47 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d0611a5de45f..cf88df82e2c2 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -87,6 +87,7 @@ #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/export.h> /* Set to 3 to get tracing... */ #define ACONF_DEBUG 2 diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c index 6b03826552e1..399287e595d7 100644 --- a/net/ipv6/addrconf_core.c +++ b/net/ipv6/addrconf_core.c @@ -3,6 +3,7 @@ * not configured or static. */ +#include <linux/export.h> #include <net/ipv6.h> #define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16) diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 2195ae651923..4c0f894d0843 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -324,8 +324,6 @@ static void ah6_output_done(struct crypto_async_request *base, int err) #endif } - err = ah->nexthdr; - kfree(AH_SKB_CB(skb)->tmp); xfrm_output_resume(skb, err); } @@ -466,12 +464,12 @@ static void ah6_input_done(struct crypto_async_request *base, int err) if (err) goto out; + err = ah->nexthdr; + skb->network_header += ah_hlen; memcpy(skb_network_header(skb), work_iph, hdr_len); __skb_pull(skb, ah_hlen + hdr_len); skb_set_transport_header(skb, -hdr_len); - - err = ah->nexthdr; out: kfree(AH_SKB_CB(skb)->tmp); xfrm_input_resume(skb, err); @@ -583,8 +581,6 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) if (err == -EINPROGRESS) goto out; - if (err == -EBUSY) - err = NET_XMIT_DROP; goto out_free; } diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 1318de4c3e8d..bf22a225f422 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -30,6 +30,7 @@ #include <linux/in6.h> #include <linux/icmpv6.h> #include <linux/slab.h> +#include <linux/export.h> #include <net/dst.h> #include <net/sock.h> diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c index 14ed0a955b56..37f548b7f6dc 100644 --- a/net/ipv6/exthdrs_core.c +++ b/net/ipv6/exthdrs_core.c @@ -2,6 +2,7 @@ * IPv6 library code, needed by static components when full IPv6 support is * not configured or static. */ +#include <linux/export.h> #include <net/ipv6.h> /* diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 34d244df907d..295571576f83 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -14,6 +14,7 @@ */ #include <linux/netdevice.h> +#include <linux/export.h> #include <net/fib_rules.h> #include <net/ipv6.h> diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index fee46d5a2f12..1567fb120392 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -85,7 +85,7 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, * request_sock (formerly open request) hash tables. */ static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport, - const u32 rnd, const u16 synq_hsize) + const u32 rnd, const u32 synq_hsize) { u32 c; diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 543039450193..4566dbd916d3 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -21,6 +21,7 @@ #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/slab.h> +#include <linux/export.h> #include <net/net_namespace.h> #include <net/sock.h> diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 027c7ff6f1e5..a46c64eb0a66 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -111,6 +111,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt ipv6_addr_loopback(&hdr->daddr)) goto err; + /* + * RFC4291 2.7 + * Multicast addresses must not be used as source addresses in IPv6 + * packets or appear in any Routing header. + */ + if (ipv6_addr_is_multicast(&hdr->saddr)) + goto err; + skb->transport_header = skb->network_header + sizeof(*hdr); IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index bdc15c9003d7..4e2e9ff67ef2 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -289,6 +289,8 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) if ((err = register_netdevice(dev)) < 0) goto failed_free; + strcpy(t->parms.name, dev->name); + dev_hold(dev); ip6_tnl_link(ip6n, t); return t; @@ -1407,7 +1409,6 @@ ip6_tnl_dev_init_gen(struct net_device *dev) struct ip6_tnl *t = netdev_priv(dev); t->dev = dev; - strcpy(t->parms.name, dev->name); dev->tstats = alloc_percpu(struct pcpu_tstats); if (!dev->tstats) return -ENOMEM; @@ -1487,6 +1488,7 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n) static int __net_init ip6_tnl_init_net(struct net *net) { struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); + struct ip6_tnl *t = NULL; int err; ip6n->tnls[0] = ip6n->tnls_wc; @@ -1507,6 +1509,10 @@ static int __net_init ip6_tnl_init_net(struct net *net) err = register_netdev(ip6n->fb_tnl_dev); if (err < 0) goto err_register; + + t = netdev_priv(ip6n->fb_tnl_dev); + + strcpy(t->parms.name, ip6n->fb_tnl_dev->name); return 0; err_register: diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index def0538e2413..449a9185b8f2 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -51,6 +51,7 @@ #include <linux/pim.h> #include <net/addrconf.h> #include <linux/netfilter_ipv6.h> +#include <linux/export.h> #include <net/ip6_checksum.h> struct mr6_table { diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index c99e3ee9781f..26cb08c84b74 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -503,7 +503,7 @@ done: goto e_inval; if (val > 255 || val < -1) goto e_inval; - np->mcast_hops = val; + np->mcast_hops = (val == -1 ? IPV6_DEFAULT_MCASTHOPS : val); retv = 0; break; diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 44e5b7f2a6c1..0cb78d7ddaf5 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1571,7 +1571,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, } if (!rt->rt6i_peer) rt6_bind_peer(rt, 1); - if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ)) + if (!inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ)) goto release; if (dev->addr_len) { diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 30fcee465448..db31561cc8df 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c @@ -3,6 +3,7 @@ #include <linux/ipv6.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv6.h> +#include <linux/export.h> #include <net/dst.h> #include <net/ipv6.h> #include <net/ip6_route.h> @@ -100,9 +101,16 @@ static int nf_ip6_route(struct net *net, struct dst_entry **dst, .pinet6 = (struct ipv6_pinfo *) &fake_pinfo, }; const void *sk = strict ? &fake_sk : NULL; - - *dst = ip6_route_output(net, sk, &fl->u.ip6); - return (*dst)->error; + struct dst_entry *result; + int err; + + result = ip6_route_output(net, sk, &fl->u.ip6); + err = result->error; + if (err) + dst_release(result); + else + *dst = result; + return err; } __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 448464844a25..f792b34cbe9c 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig @@ -186,7 +186,6 @@ config IP6_NF_MANGLE config IP6_NF_RAW tristate 'raw table support (required for TRACE)' - depends on NETFILTER_ADVANCED help This option adds a `raw' table to ip6tables. This table is the very first in the netfilter framework and hooks in at the PREROUTING diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index e8762c73b170..38f00b0298d3 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -182,7 +182,6 @@ fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst) return container_of(q, struct nf_ct_frag6_queue, q); oom: - pr_debug("Can't alloc new queue\n"); return NULL; } @@ -370,10 +369,10 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) struct sk_buff *clone; int i, plen = 0; - if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) { - pr_debug("Can't alloc skb\n"); + clone = alloc_skb(0, GFP_ATOMIC); + if (clone == NULL) goto out_oom; - } + clone->next = head->next; head->next = clone; skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list; diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 18ff5df7ec02..1008ce94bc33 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -21,6 +21,7 @@ #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/stddef.h> +#include <linux/export.h> #include <net/net_namespace.h> #include <net/ip.h> #include <net/sock.h> diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 6f7824e1cea4..331af3b882ac 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -61,6 +61,7 @@ #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/export.h> static struct raw_hashinfo raw_v6_hashinfo = { .lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock), diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index cc22099ac8b6..dfb164e9051a 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -42,6 +42,7 @@ #include <linux/jhash.h> #include <linux/skbuff.h> #include <linux/slab.h> +#include <linux/export.h> #include <net/sock.h> #include <net/snmp.h> diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 57b82dc1ae91..3399dd326287 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -26,6 +26,7 @@ #include <linux/capability.h> #include <linux/errno.h> +#include <linux/export.h> #include <linux/types.h> #include <linux/times.h> #include <linux/socket.h> @@ -76,7 +77,7 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, const struct in6_addr *dest); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ip6_default_advmss(const struct dst_entry *dst); -static unsigned int ip6_default_mtu(const struct dst_entry *dst); +static unsigned int ip6_mtu(const struct dst_entry *dst); static struct dst_entry *ip6_negative_advice(struct dst_entry *); static void ip6_dst_destroy(struct dst_entry *); static void ip6_dst_ifdown(struct dst_entry *, @@ -143,7 +144,7 @@ static struct dst_ops ip6_dst_ops_template = { .gc_thresh = 1024, .check = ip6_dst_check, .default_advmss = ip6_default_advmss, - .default_mtu = ip6_default_mtu, + .mtu = ip6_mtu, .cow_metrics = ipv6_cow_metrics, .destroy = ip6_dst_destroy, .ifdown = ip6_dst_ifdown, @@ -154,9 +155,11 @@ static struct dst_ops ip6_dst_ops_template = { .neigh_lookup = ip6_neigh_lookup, }; -static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) +static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst) { - return 0; + unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); + + return mtu ? : dst->dev->mtu; } static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) @@ -174,7 +177,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { .protocol = cpu_to_be16(ETH_P_IPV6), .destroy = ip6_dst_destroy, .check = ip6_dst_check, - .default_mtu = ip6_blackhole_default_mtu, + .mtu = ip6_blackhole_mtu, .default_advmss = ip6_default_advmss, .update_pmtu = ip6_rt_blackhole_update_pmtu, .cow_metrics = ip6_rt_blackhole_cow_metrics, @@ -1040,10 +1043,15 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst) return mtu; } -static unsigned int ip6_default_mtu(const struct dst_entry *dst) +static unsigned int ip6_mtu(const struct dst_entry *dst) { - unsigned int mtu = IPV6_MIN_MTU; struct inet6_dev *idev; + unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); + + if (mtu) + return mtu; + + mtu = IPV6_MIN_MTU; rcu_read_lock(); idev = __in6_dev_get(dst->dev); diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 6dcf5e7d661b..166a57c47d39 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -10,6 +10,7 @@ #include <linux/in6.h> #include <linux/ipv6.h> #include <linux/slab.h> +#include <linux/export.h> #include <net/ndisc.h> #include <net/ipv6.h> #include <net/addrconf.h> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 10b2b3165a1a..2dea4bb7b54a 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1255,6 +1255,13 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) if (!want_cookie || tmp_opt.tstamp_ok) TCP_ECN_create_request(req, tcp_hdr(skb)); + treq->iif = sk->sk_bound_dev_if; + + /* So that link locals have meaning */ + if (!sk->sk_bound_dev_if && + ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) + treq->iif = inet6_iif(skb); + if (!isn) { struct inet_peer *peer = NULL; @@ -1264,12 +1271,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) atomic_inc(&skb->users); treq->pktopts = skb; } - treq->iif = sk->sk_bound_dev_if; - - /* So that link locals have meaning */ - if (!sk->sk_bound_dev_if && - ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL) - treq->iif = inet6_iif(skb); if (want_cookie) { isn = cookie_v6_init_sequence(sk, skb, &req->mss); @@ -2161,12 +2162,18 @@ out: return 0; } +static const struct file_operations tcp6_afinfo_seq_fops = { + .owner = THIS_MODULE, + .open = tcp_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_net +}; + static struct tcp_seq_afinfo tcp6_seq_afinfo = { .name = "tcp6", .family = AF_INET6, - .seq_fops = { - .owner = THIS_MODULE, - }, + .seq_fops = &tcp6_afinfo_seq_fops, .seq_ops = { .show = tcp6_seq_show, }, diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index f4ca0a5b3457..8c2541915183 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -340,7 +340,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, struct ipv6_pinfo *np = inet6_sk(sk); struct inet_sock *inet = inet_sk(sk); struct sk_buff *skb; - unsigned int ulen; + unsigned int ulen, copied; int peeked; int err; int is_udplite = IS_UDPLITE(sk); @@ -363,9 +363,10 @@ try_again: goto out; ulen = skb->len - sizeof(struct udphdr); - if (len > ulen) - len = ulen; - else if (len < ulen) + copied = len; + if (copied > ulen) + copied = ulen; + else if (copied < ulen) msg->msg_flags |= MSG_TRUNC; is_udp4 = (skb->protocol == htons(ETH_P_IP)); @@ -376,14 +377,14 @@ try_again: * coverage checksum (UDP-Lite), do it before the copy. */ - if (len < ulen || UDP_SKB_CB(skb)->partial_cov) { + if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) { if (udp_lib_checksum_complete(skb)) goto csum_copy_err; } if (skb_csum_unnecessary(skb)) err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), - msg->msg_iov,len); + msg->msg_iov, copied ); else { err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); if (err == -EINVAL) @@ -432,7 +433,7 @@ try_again: datagram_recv_ctl(sk, msg, skb); } - err = len; + err = copied; if (flags & MSG_TRUNC) err = ulen; @@ -1424,13 +1425,19 @@ int udp6_seq_show(struct seq_file *seq, void *v) return 0; } +static const struct file_operations udp6_afinfo_seq_fops = { + .owner = THIS_MODULE, + .open = udp_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_net +}; + static struct udp_seq_afinfo udp6_seq_afinfo = { .name = "udp6", .family = AF_INET6, .udp_table = &udp_table, - .seq_fops = { - .owner = THIS_MODULE, - }, + .seq_fops = &udp6_afinfo_seq_fops, .seq_ops = { .show = udp6_seq_show, }, diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 986c4de5292e..1d08e21d9f69 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c @@ -11,6 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ +#include <linux/export.h> #include "udp_impl.h" static int udplitev6_rcv(struct sk_buff *skb) @@ -93,13 +94,20 @@ void udplitev6_exit(void) } #ifdef CONFIG_PROC_FS + +static const struct file_operations udplite6_afinfo_seq_fops = { + .owner = THIS_MODULE, + .open = udp_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_net +}; + static struct udp_seq_afinfo udplite6_seq_afinfo = { .name = "udplite6", .family = AF_INET6, .udp_table = &udplite_table, - .seq_fops = { - .owner = THIS_MODULE, - }, + .seq_fops = &udplite6_afinfo_seq_fops, .seq_ops = { .show = udp6_seq_show, }, diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 248f0b2a7ee9..f2d72b8a3faa 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c @@ -15,6 +15,7 @@ #include <linux/pfkeyv2.h> #include <linux/ipsec.h> #include <linux/netfilter_ipv6.h> +#include <linux/export.h> #include <net/dsfield.h> #include <net/ipv6.h> #include <net/addrconf.h> |