aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/ipv6.c')
-rw-r--r--net/sctp/ipv6.c28
1 files changed, 8 insertions, 20 deletions
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 1d7ac70ba39f..732689140fb8 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -58,6 +58,7 @@
58#include <linux/netdevice.h> 58#include <linux/netdevice.h>
59#include <linux/init.h> 59#include <linux/init.h>
60#include <linux/ipsec.h> 60#include <linux/ipsec.h>
61#include <linux/slab.h>
61 62
62#include <linux/ipv6.h> 63#include <linux/ipv6.h>
63#include <linux/icmpv6.h> 64#include <linux/icmpv6.h>
@@ -231,7 +232,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
231 if (!(transport->param_flags & SPP_PMTUD_ENABLE)) 232 if (!(transport->param_flags & SPP_PMTUD_ENABLE))
232 skb->local_df = 1; 233 skb->local_df = 1;
233 234
234 return ip6_xmit(sk, skb, &fl, np->opt, 0); 235 return ip6_xmit(sk, skb, &fl, np->opt);
235} 236}
236 237
237/* Returns the dst cache entry for the given source and destination ip 238/* Returns the dst cache entry for the given source and destination ip
@@ -276,20 +277,7 @@ static struct dst_entry *sctp_v6_get_dst(struct sctp_association *asoc,
276static inline int sctp_v6_addr_match_len(union sctp_addr *s1, 277static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
277 union sctp_addr *s2) 278 union sctp_addr *s2)
278{ 279{
279 struct in6_addr *a1 = &s1->v6.sin6_addr; 280 return ipv6_addr_diff(&s1->v6.sin6_addr, &s2->v6.sin6_addr);
280 struct in6_addr *a2 = &s2->v6.sin6_addr;
281 int i, j;
282
283 for (i = 0; i < 4 ; i++) {
284 __be32 a1xora2;
285
286 a1xora2 = a1->s6_addr32[i] ^ a2->s6_addr32[i];
287
288 if ((j = fls(ntohl(a1xora2))))
289 return (i * 32 + 32 - j);
290 }
291
292 return (i*32);
293} 281}
294 282
295/* Fills in the source address(saddr) based on the destination address(daddr) 283/* Fills in the source address(saddr) based on the destination address(daddr)
@@ -371,13 +359,13 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist,
371 } 359 }
372 360
373 read_lock_bh(&in6_dev->lock); 361 read_lock_bh(&in6_dev->lock);
374 for (ifp = in6_dev->addr_list; ifp; ifp = ifp->if_next) { 362 list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
375 /* Add the address to the local list. */ 363 /* Add the address to the local list. */
376 addr = t_new(struct sctp_sockaddr_entry, GFP_ATOMIC); 364 addr = t_new(struct sctp_sockaddr_entry, GFP_ATOMIC);
377 if (addr) { 365 if (addr) {
378 addr->a.v6.sin6_family = AF_INET6; 366 addr->a.v6.sin6_family = AF_INET6;
379 addr->a.v6.sin6_port = 0; 367 addr->a.v6.sin6_port = 0;
380 addr->a.v6.sin6_addr = ifp->addr; 368 ipv6_addr_copy(&addr->a.v6.sin6_addr, &ifp->addr);
381 addr->a.v6.sin6_scope_id = dev->ifindex; 369 addr->a.v6.sin6_scope_id = dev->ifindex;
382 addr->valid = 1; 370 addr->valid = 1;
383 INIT_LIST_HEAD(&addr->list); 371 INIT_LIST_HEAD(&addr->list);
@@ -418,7 +406,7 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
418{ 406{
419 addr->v6.sin6_family = AF_INET6; 407 addr->v6.sin6_family = AF_INET6;
420 addr->v6.sin6_port = 0; 408 addr->v6.sin6_port = 0;
421 addr->v6.sin6_addr = inet6_sk(sk)->rcv_saddr; 409 ipv6_addr_copy(&addr->v6.sin6_addr, &inet6_sk(sk)->rcv_saddr);
422} 410}
423 411
424/* Initialize sk->sk_rcv_saddr from sctp_addr. */ 412/* Initialize sk->sk_rcv_saddr from sctp_addr. */
@@ -431,7 +419,7 @@ static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk)
431 inet6_sk(sk)->rcv_saddr.s6_addr32[3] = 419 inet6_sk(sk)->rcv_saddr.s6_addr32[3] =
432 addr->v4.sin_addr.s_addr; 420 addr->v4.sin_addr.s_addr;
433 } else { 421 } else {
434 inet6_sk(sk)->rcv_saddr = addr->v6.sin6_addr; 422 ipv6_addr_copy(&inet6_sk(sk)->rcv_saddr, &addr->v6.sin6_addr);
435 } 423 }
436} 424}
437 425
@@ -444,7 +432,7 @@ static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
444 inet6_sk(sk)->daddr.s6_addr32[2] = htonl(0x0000ffff); 432 inet6_sk(sk)->daddr.s6_addr32[2] = htonl(0x0000ffff);
445 inet6_sk(sk)->daddr.s6_addr32[3] = addr->v4.sin_addr.s_addr; 433 inet6_sk(sk)->daddr.s6_addr32[3] = addr->v4.sin_addr.s_addr;
446 } else { 434 } else {
447 inet6_sk(sk)->daddr = addr->v6.sin6_addr; 435 ipv6_addr_copy(&inet6_sk(sk)->daddr, &addr->v6.sin6_addr);
448 } 436 }
449} 437}
450 438