aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-28 04:19:40 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-28 04:19:40 -0400
commit1b63ba8a86c85524a8d7e5953b314ce71ebcb9c9 (patch)
treefe3dc41cbb47ae12b7c3faf6a88b097349e50d5a /net/ipv6
parente35c3269edba151e1c703d87068a28ce2cd65bb0 (diff)
parentd420895efb259a78dda50f95289571faa6e10e41 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/wireless/iwlwifi/iwl4965-base.c
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_input.c9
-rw-r--r--net/ipv6/ipv6_sockglue.c11
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c3
-rw-r--r--net/ipv6/reassembly.c2
-rw-r--r--net/ipv6/route.c6
-rw-r--r--net/ipv6/tcp_ipv6.c6
7 files changed, 27 insertions, 12 deletions
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index f77a6011c302..34e5a96623ae 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -100,6 +100,15 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
100 if (hdr->version != 6) 100 if (hdr->version != 6)
101 goto err; 101 goto err;
102 102
103 /*
104 * RFC4291 2.5.3
105 * A packet received on an interface with a destination address
106 * of loopback must be dropped.
107 */
108 if (!(dev->flags & IFF_LOOPBACK) &&
109 ipv6_addr_loopback(&hdr->daddr))
110 goto err;
111
103 skb->transport_header = skb->network_header + sizeof(*hdr); 112 skb->transport_header = skb->network_header + sizeof(*hdr);
104 IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); 113 IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
105 114
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index a9988841172a..030c0c956f9d 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -343,18 +343,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
343 case IPV6_DSTOPTS: 343 case IPV6_DSTOPTS:
344 { 344 {
345 struct ipv6_txoptions *opt; 345 struct ipv6_txoptions *opt;
346
347 /* remove any sticky options header with a zero option
348 * length, per RFC3542.
349 */
346 if (optlen == 0) 350 if (optlen == 0)
347 optval = NULL; 351 optval = NULL;
352 else if (optlen < sizeof(struct ipv6_opt_hdr) ||
353 optlen & 0x7 || optlen > 8 * 255)
354 goto e_inval;
348 355
349 /* hop-by-hop / destination options are privileged option */ 356 /* hop-by-hop / destination options are privileged option */
350 retv = -EPERM; 357 retv = -EPERM;
351 if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) 358 if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
352 break; 359 break;
353 360
354 if (optlen < sizeof(struct ipv6_opt_hdr) ||
355 optlen & 0x7 || optlen > 8 * 255)
356 goto e_inval;
357
358 opt = ipv6_renew_options(sk, np->opt, optname, 361 opt = ipv6_renew_options(sk, np->opt, optname,
359 (struct ipv6_opt_hdr __user *)optval, 362 (struct ipv6_opt_hdr __user *)optval,
360 optlen); 363 optlen);
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 27a5e8b48d93..f405cea21a8b 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -129,7 +129,7 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
129 .priority = NF_IP6_PRI_MANGLE, 129 .priority = NF_IP6_PRI_MANGLE,
130 }, 130 },
131 { 131 {
132 .hook = ip6t_local_hook, 132 .hook = ip6t_route_hook,
133 .owner = THIS_MODULE, 133 .owner = THIS_MODULE,
134 .pf = PF_INET6, 134 .pf = PF_INET6,
135 .hooknum = NF_INET_LOCAL_IN, 135 .hooknum = NF_INET_LOCAL_IN,
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index e65e26e210ee..cf20bc4fd60d 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -207,9 +207,10 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
207 arg.id = id; 207 arg.id = id;
208 arg.src = src; 208 arg.src = src;
209 arg.dst = dst; 209 arg.dst = dst;
210
211 read_lock_bh(&nf_frags.lock);
210 hash = ip6qhashfn(id, src, dst); 212 hash = ip6qhashfn(id, src, dst);
211 213
212 local_bh_disable();
213 q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); 214 q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
214 local_bh_enable(); 215 local_bh_enable();
215 if (q == NULL) 216 if (q == NULL)
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 13509f906d89..6ab957ec2dd6 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -245,6 +245,8 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
245 arg.id = id; 245 arg.id = id;
246 arg.src = src; 246 arg.src = src;
247 arg.dst = dst; 247 arg.dst = dst;
248
249 read_lock(&ip6_frags.lock);
248 hash = ip6qhashfn(id, src, dst); 250 hash = ip6qhashfn(id, src, dst);
249 251
250 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); 252 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index efe036aa3dd1..751e98f9b8b4 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -238,7 +238,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr)
238static inline struct rt6_info *rt6_device_match(struct net *net, 238static inline struct rt6_info *rt6_device_match(struct net *net,
239 struct rt6_info *rt, 239 struct rt6_info *rt,
240 int oif, 240 int oif,
241 int strict) 241 int flags)
242{ 242{
243 struct rt6_info *local = NULL; 243 struct rt6_info *local = NULL;
244 struct rt6_info *sprt; 244 struct rt6_info *sprt;
@@ -251,7 +251,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
251 if (dev->flags & IFF_LOOPBACK) { 251 if (dev->flags & IFF_LOOPBACK) {
252 if (sprt->rt6i_idev == NULL || 252 if (sprt->rt6i_idev == NULL ||
253 sprt->rt6i_idev->dev->ifindex != oif) { 253 sprt->rt6i_idev->dev->ifindex != oif) {
254 if (strict && oif) 254 if (flags & RT6_LOOKUP_F_IFACE && oif)
255 continue; 255 continue;
256 if (local && (!oif || 256 if (local && (!oif ||
257 local->rt6i_idev->dev->ifindex == oif)) 257 local->rt6i_idev->dev->ifindex == oif))
@@ -264,7 +264,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
264 if (local) 264 if (local)
265 return local; 265 return local;
266 266
267 if (strict) 267 if (flags & RT6_LOOKUP_F_IFACE)
268 return net->ipv6.ip6_null_entry; 268 return net->ipv6.ip6_null_entry;
269 } 269 }
270 return rt; 270 return rt;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 09be09cc1aa6..30dbab7cc3cc 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1946,7 +1946,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1946 1946
1947 seq_printf(seq, 1947 seq_printf(seq,
1948 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " 1948 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
1949 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d\n", 1949 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %lu %lu %u %u %d\n",
1950 i, 1950 i,
1951 src->s6_addr32[0], src->s6_addr32[1], 1951 src->s6_addr32[0], src->s6_addr32[1],
1952 src->s6_addr32[2], src->s6_addr32[3], srcp, 1952 src->s6_addr32[2], src->s6_addr32[3], srcp,
@@ -1962,8 +1962,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
1962 icsk->icsk_probes_out, 1962 icsk->icsk_probes_out,
1963 sock_i_ino(sp), 1963 sock_i_ino(sp),
1964 atomic_read(&sp->sk_refcnt), sp, 1964 atomic_read(&sp->sk_refcnt), sp,
1965 icsk->icsk_rto, 1965 jiffies_to_clock_t(icsk->icsk_rto),
1966 icsk->icsk_ack.ato, 1966 jiffies_to_clock_t(icsk->icsk_ack.ato),
1967 (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, 1967 (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
1968 tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh 1968 tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh
1969 ); 1969 );