aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/raw.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r--net/ipv6/raw.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 331af3b882ac..a4894f4f1944 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -299,9 +299,9 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
299 } 299 }
300 300
301 inet->inet_rcv_saddr = inet->inet_saddr = v4addr; 301 inet->inet_rcv_saddr = inet->inet_saddr = v4addr;
302 ipv6_addr_copy(&np->rcv_saddr, &addr->sin6_addr); 302 np->rcv_saddr = addr->sin6_addr;
303 if (!(addr_type & IPV6_ADDR_MULTICAST)) 303 if (!(addr_type & IPV6_ADDR_MULTICAST))
304 ipv6_addr_copy(&np->saddr, &addr->sin6_addr); 304 np->saddr = addr->sin6_addr;
305 err = 0; 305 err = 0;
306out_unlock: 306out_unlock:
307 rcu_read_unlock(); 307 rcu_read_unlock();
@@ -383,7 +383,8 @@ static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb)
383 } 383 }
384 384
385 /* Charge it to the socket. */ 385 /* Charge it to the socket. */
386 if (ip_queue_rcv_skb(sk, skb) < 0) { 386 skb_dst_drop(skb);
387 if (sock_queue_rcv_skb(sk, skb) < 0) {
387 kfree_skb(skb); 388 kfree_skb(skb);
388 return NET_RX_DROP; 389 return NET_RX_DROP;
389 } 390 }
@@ -494,7 +495,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
494 if (sin6) { 495 if (sin6) {
495 sin6->sin6_family = AF_INET6; 496 sin6->sin6_family = AF_INET6;
496 sin6->sin6_port = 0; 497 sin6->sin6_port = 0;
497 ipv6_addr_copy(&sin6->sin6_addr, &ipv6_hdr(skb)->saddr); 498 sin6->sin6_addr = ipv6_hdr(skb)->saddr;
498 sin6->sin6_flowinfo = 0; 499 sin6->sin6_flowinfo = 0;
499 sin6->sin6_scope_id = 0; 500 sin6->sin6_scope_id = 0;
500 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) 501 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
@@ -610,6 +611,8 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
610 struct sk_buff *skb; 611 struct sk_buff *skb;
611 int err; 612 int err;
612 struct rt6_info *rt = (struct rt6_info *)*dstp; 613 struct rt6_info *rt = (struct rt6_info *)*dstp;
614 int hlen = LL_RESERVED_SPACE(rt->dst.dev);
615 int tlen = rt->dst.dev->needed_tailroom;
613 616
614 if (length > rt->dst.dev->mtu) { 617 if (length > rt->dst.dev->mtu) {
615 ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu); 618 ipv6_local_error(sk, EMSGSIZE, fl6, rt->dst.dev->mtu);
@@ -619,11 +622,11 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
619 goto out; 622 goto out;
620 623
621 skb = sock_alloc_send_skb(sk, 624 skb = sock_alloc_send_skb(sk,
622 length + LL_ALLOCATED_SPACE(rt->dst.dev) + 15, 625 length + hlen + tlen + 15,
623 flags & MSG_DONTWAIT, &err); 626 flags & MSG_DONTWAIT, &err);
624 if (skb == NULL) 627 if (skb == NULL)
625 goto error; 628 goto error;
626 skb_reserve(skb, LL_RESERVED_SPACE(rt->dst.dev)); 629 skb_reserve(skb, hlen);
627 630
628 skb->priority = sk->sk_priority; 631 skb->priority = sk->sk_priority;
629 skb->mark = sk->sk_mark; 632 skb->mark = sk->sk_mark;
@@ -843,11 +846,11 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
843 goto out; 846 goto out;
844 847
845 if (!ipv6_addr_any(daddr)) 848 if (!ipv6_addr_any(daddr))
846 ipv6_addr_copy(&fl6.daddr, daddr); 849 fl6.daddr = *daddr;
847 else 850 else
848 fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ 851 fl6.daddr.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
849 if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr)) 852 if (ipv6_addr_any(&fl6.saddr) && !ipv6_addr_any(&np->saddr))
850 ipv6_addr_copy(&fl6.saddr, &np->saddr); 853 fl6.saddr = np->saddr;
851 854
852 final_p = fl6_update_dst(&fl6, opt, &final); 855 final_p = fl6_update_dst(&fl6, opt, &final);
853 856