3 * Linux INET6 implementation
6 * Pedro Roque <roque@di.fc.ul.pt>
8 * Based on linux/ipv4/udp.c
10 * $Id: udp.c,v 1.59 2000/11/28 13:38:38 davem Exp $
13 * Hideaki YOSHIFUJI : sin6_scope_id support
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
21 #include <linux/config.h>
22 #include <linux/errno.h>
23 #include <linux/types.h>
24 #include <linux/socket.h>
25 #include <linux/sockios.h>
26 #include <linux/sched.h>
27 #include <linux/net.h>
28 #include <linux/in6.h>
29 #include <linux/netdevice.h>
30 #include <linux/if_arp.h>
31 #include <linux/ipv6.h>
32 #include <linux/icmpv6.h>
33 #include <linux/init.h>
34 #include <asm/uaccess.h>
40 #include <net/ndisc.h>
41 #include <net/protocol.h>
42 #include <net/transp_v6.h>
43 #include <net/ip6_route.h>
44 #include <net/addrconf.h>
47 #include <net/inet_common.h>
49 #include <net/checksum.h>
51 struct udp_mib udp_stats_in6
[NR_CPUS
*2];
53 /* Grrr, addr_type already calculated by caller, but I don't want
54 * to add some silly "cookie" argument to this method just for that.
56 static int udp_v6_get_port(struct sock
*sk
, unsigned short snum
)
58 write_lock_bh(&udp_hash_lock
);
60 int best_size_so_far
, best
, result
, i
;
62 if (udp_port_rover
> sysctl_local_port_range
[1] ||
63 udp_port_rover
< sysctl_local_port_range
[0])
64 udp_port_rover
= sysctl_local_port_range
[0];
65 best_size_so_far
= 32767;
66 best
= result
= udp_port_rover
;
67 for (i
= 0; i
< UDP_HTABLE_SIZE
; i
++, result
++) {
71 sk
= udp_hash
[result
& (UDP_HTABLE_SIZE
- 1)];
73 if (result
> sysctl_local_port_range
[1])
74 result
= sysctl_local_port_range
[0] +
75 ((result
- sysctl_local_port_range
[0]) &
76 (UDP_HTABLE_SIZE
- 1));
81 if (++size
>= best_size_so_far
)
83 } while ((sk
= sk
->next
) != NULL
);
84 best_size_so_far
= size
;
89 for(;; result
+= UDP_HTABLE_SIZE
) {
90 if (result
> sysctl_local_port_range
[1])
91 result
= sysctl_local_port_range
[0]
92 + ((result
- sysctl_local_port_range
[0]) &
93 (UDP_HTABLE_SIZE
- 1));
94 if (!udp_lport_inuse(result
))
98 udp_port_rover
= snum
= result
;
101 int addr_type
= ipv6_addr_type(&sk
->net_pinfo
.af_inet6
.rcv_saddr
);
103 for (sk2
= udp_hash
[snum
& (UDP_HTABLE_SIZE
- 1)];
106 if (sk2
->num
== snum
&&
108 sk2
->bound_dev_if
== sk
->bound_dev_if
&&
110 addr_type
== IPV6_ADDR_ANY
||
111 !ipv6_addr_cmp(&sk
->net_pinfo
.af_inet6
.rcv_saddr
,
112 &sk2
->net_pinfo
.af_inet6
.rcv_saddr
) ||
113 (addr_type
== IPV6_ADDR_MAPPED
&&
114 sk2
->family
== AF_INET
&&
115 sk
->rcv_saddr
== sk2
->rcv_saddr
)) &&
116 (!sk2
->reuse
|| !sk
->reuse
))
122 if (sk
->pprev
== NULL
) {
123 struct sock
**skp
= &udp_hash
[snum
& (UDP_HTABLE_SIZE
- 1)];
124 if ((sk
->next
= *skp
) != NULL
)
125 (*skp
)->pprev
= &sk
->next
;
128 sock_prot_inc_use(sk
->prot
);
131 write_unlock_bh(&udp_hash_lock
);
135 write_unlock_bh(&udp_hash_lock
);
139 static void udp_v6_hash(struct sock
*sk
)
144 static void udp_v6_unhash(struct sock
*sk
)
146 write_lock_bh(&udp_hash_lock
);
149 sk
->next
->pprev
= sk
->pprev
;
150 *sk
->pprev
= sk
->next
;
153 sock_prot_dec_use(sk
->prot
);
156 write_unlock_bh(&udp_hash_lock
);
159 static struct sock
*udp_v6_lookup(struct in6_addr
*saddr
, u16 sport
,
160 struct in6_addr
*daddr
, u16 dport
, int dif
)
162 struct sock
*sk
, *result
= NULL
;
163 unsigned short hnum
= ntohs(dport
);
166 read_lock(&udp_hash_lock
);
167 for(sk
= udp_hash
[hnum
& (UDP_HTABLE_SIZE
- 1)]; sk
!= NULL
; sk
= sk
->next
) {
168 if((sk
->num
== hnum
) &&
169 (sk
->family
== PF_INET6
)) {
170 struct ipv6_pinfo
*np
= &sk
->net_pinfo
.af_inet6
;
173 if(sk
->dport
!= sport
)
177 if(!ipv6_addr_any(&np
->rcv_saddr
)) {
178 if(ipv6_addr_cmp(&np
->rcv_saddr
, daddr
))
182 if(!ipv6_addr_any(&np
->daddr
)) {
183 if(ipv6_addr_cmp(&np
->daddr
, saddr
))
187 if(sk
->bound_dev_if
) {
188 if(sk
->bound_dev_if
!= dif
)
195 } else if(score
> badness
) {
203 read_unlock(&udp_hash_lock
);
211 int udpv6_connect(struct sock
*sk
, struct sockaddr
*uaddr
, int addr_len
)
213 struct sockaddr_in6
*usin
= (struct sockaddr_in6
*) uaddr
;
214 struct ipv6_pinfo
*np
= &sk
->net_pinfo
.af_inet6
;
215 struct in6_addr
*daddr
;
216 struct in6_addr saddr
;
217 struct dst_entry
*dst
;
219 struct ip6_flowlabel
*flowlabel
= NULL
;
223 if (usin
->sin6_family
== AF_INET
) {
224 err
= udp_connect(sk
, uaddr
, addr_len
);
228 if (addr_len
< SIN6_LEN_RFC2133
)
231 if (usin
->sin6_family
!= AF_INET6
)
232 return -EAFNOSUPPORT
;
234 fl
.fl6_flowlabel
= 0;
236 fl
.fl6_flowlabel
= usin
->sin6_flowinfo
&IPV6_FLOWINFO_MASK
;
237 if (fl
.fl6_flowlabel
&IPV6_FLOWLABEL_MASK
) {
238 flowlabel
= fl6_sock_lookup(sk
, fl
.fl6_flowlabel
);
239 if (flowlabel
== NULL
)
241 ipv6_addr_copy(&usin
->sin6_addr
, &flowlabel
->dst
);
245 addr_type
= ipv6_addr_type(&usin
->sin6_addr
);
247 if (addr_type
== IPV6_ADDR_ANY
) {
251 usin
->sin6_addr
.s6_addr
[15] = 0x01;
254 daddr
= &usin
->sin6_addr
;
256 if (addr_type
== IPV6_ADDR_MAPPED
) {
257 struct sockaddr_in sin
;
259 sin
.sin_family
= AF_INET
;
260 sin
.sin_addr
.s_addr
= daddr
->s6_addr32
[3];
261 sin
.sin_port
= usin
->sin6_port
;
263 err
= udp_connect(sk
, (struct sockaddr
*) &sin
, sizeof(sin
));
269 ipv6_addr_set(&np
->daddr
, 0, 0,
270 __constant_htonl(0x0000ffff),
273 if(ipv6_addr_any(&np
->saddr
)) {
274 ipv6_addr_set(&np
->saddr
, 0, 0,
275 __constant_htonl(0x0000ffff),
279 if(ipv6_addr_any(&np
->rcv_saddr
)) {
280 ipv6_addr_set(&np
->rcv_saddr
, 0, 0,
281 __constant_htonl(0x0000ffff),
287 if (addr_type
&IPV6_ADDR_LINKLOCAL
) {
288 if (addr_len
>= sizeof(struct sockaddr_in6
) &&
289 usin
->sin6_scope_id
) {
290 if (sk
->bound_dev_if
&& sk
->bound_dev_if
!= usin
->sin6_scope_id
) {
291 fl6_sock_release(flowlabel
);
294 sk
->bound_dev_if
= usin
->sin6_scope_id
;
297 /* Connect to link-local address requires an interface */
298 if (sk
->bound_dev_if
== 0)
302 ipv6_addr_copy(&np
->daddr
, daddr
);
303 np
->flow_label
= fl
.fl6_flowlabel
;
305 sk
->dport
= usin
->sin6_port
;
308 * Check for a route to destination an obtain the
309 * destination cache for it.
312 fl
.proto
= IPPROTO_UDP
;
313 fl
.fl6_dst
= &np
->daddr
;
315 fl
.oif
= sk
->bound_dev_if
;
316 fl
.uli_u
.ports
.dport
= sk
->dport
;
317 fl
.uli_u
.ports
.sport
= sk
->sport
;
320 if (flowlabel
->opt
&& flowlabel
->opt
->srcrt
) {
321 struct rt0_hdr
*rt0
= (struct rt0_hdr
*) flowlabel
->opt
->srcrt
;
322 fl
.fl6_dst
= rt0
->addr
;
324 } else if (np
->opt
&& np
->opt
->srcrt
) {
325 struct rt0_hdr
*rt0
= (struct rt0_hdr
*) np
->opt
->srcrt
;
326 fl
.fl6_dst
= rt0
->addr
;
329 dst
= ip6_route_output(sk
, &fl
);
331 if ((err
= dst
->error
) != 0) {
333 fl6_sock_release(flowlabel
);
337 ip6_dst_store(sk
, dst
, fl
.fl6_dst
);
339 /* get the source adddress used in the apropriate device */
341 err
= ipv6_get_saddr(dst
, daddr
, &saddr
);
344 if(ipv6_addr_any(&np
->saddr
))
345 ipv6_addr_copy(&np
->saddr
, &saddr
);
347 if(ipv6_addr_any(&np
->rcv_saddr
)) {
348 ipv6_addr_copy(&np
->rcv_saddr
, &saddr
);
349 sk
->rcv_saddr
= LOOPBACK4_IPV6
;
351 sk
->state
= TCP_ESTABLISHED
;
353 fl6_sock_release(flowlabel
);
358 static void udpv6_close(struct sock
*sk
, long timeout
)
360 inet_sock_release(sk
);
364 * This should be easy, if there is something there we
365 * return it, otherwise we block.
368 int udpv6_recvmsg(struct sock
*sk
, struct msghdr
*msg
, int len
,
369 int noblock
, int flags
, int *addr_len
)
375 *addr_len
=sizeof(struct sockaddr_in6
);
377 if (flags
& MSG_ERRQUEUE
)
378 return ipv6_recv_error(sk
, msg
, len
);
380 skb
= skb_recv_datagram(sk
, flags
, noblock
, &err
);
384 copied
= skb
->len
- sizeof(struct udphdr
);
387 msg
->msg_flags
|= MSG_TRUNC
;
390 if (skb
->ip_summed
==CHECKSUM_UNNECESSARY
) {
391 err
= skb_copy_datagram_iovec(skb
, sizeof(struct udphdr
), msg
->msg_iov
,
393 } else if (msg
->msg_flags
&MSG_TRUNC
) {
394 if ((unsigned short)csum_fold(csum_partial(skb
->h
.raw
, skb
->len
, skb
->csum
)))
396 err
= skb_copy_datagram_iovec(skb
, sizeof(struct udphdr
), msg
->msg_iov
,
399 err
= copy_and_csum_toiovec(msg
->msg_iov
, skb
, sizeof(struct udphdr
));
406 sock_recv_timestamp(msg
, sk
, skb
);
408 /* Copy the address. */
410 struct sockaddr_in6
*sin6
;
412 sin6
= (struct sockaddr_in6
*) msg
->msg_name
;
413 sin6
->sin6_family
= AF_INET6
;
414 sin6
->sin6_port
= skb
->h
.uh
->source
;
415 sin6
->sin6_flowinfo
= 0;
416 sin6
->sin6_scope_id
= 0;
418 if (skb
->protocol
== __constant_htons(ETH_P_IP
)) {
419 ipv6_addr_set(&sin6
->sin6_addr
, 0, 0,
420 __constant_htonl(0xffff), skb
->nh
.iph
->saddr
);
421 if (sk
->protinfo
.af_inet
.cmsg_flags
)
422 ip_cmsg_recv(msg
, skb
);
424 memcpy(&sin6
->sin6_addr
, &skb
->nh
.ipv6h
->saddr
,
425 sizeof(struct in6_addr
));
427 if (sk
->net_pinfo
.af_inet6
.rxopt
.all
)
428 datagram_recv_ctl(sk
, msg
, skb
);
429 if (ipv6_addr_type(&sin6
->sin6_addr
) & IPV6_ADDR_LINKLOCAL
) {
430 struct inet6_skb_parm
*opt
= (struct inet6_skb_parm
*) skb
->cb
;
431 sin6
->sin6_scope_id
= opt
->iif
;
438 skb_free_datagram(sk
, skb
);
444 if (flags
&MSG_PEEK
) {
446 spin_lock_irq(&sk
->receive_queue
.lock
);
447 if (skb
== skb_peek(&sk
->receive_queue
)) {
448 __skb_unlink(skb
, &sk
->receive_queue
);
451 spin_unlock_irq(&sk
->receive_queue
.lock
);
456 /* Error for blocking case is chosen to masquerade
457 as some normal condition.
459 err
= (flags
&MSG_DONTWAIT
) ? -EAGAIN
: -EHOSTUNREACH
;
460 UDP6_INC_STATS_USER(UdpInErrors
);
464 void udpv6_err(struct sk_buff
*skb
, struct ipv6hdr
*hdr
,
465 struct inet6_skb_parm
*opt
,
466 int type
, int code
, unsigned char *buff
, __u32 info
)
468 struct net_device
*dev
= skb
->dev
;
469 struct in6_addr
*saddr
= &hdr
->saddr
;
470 struct in6_addr
*daddr
= &hdr
->daddr
;
475 if (buff
+ sizeof(struct udphdr
) > skb
->tail
)
478 uh
= (struct udphdr
*) buff
;
480 sk
= udp_v6_lookup(daddr
, uh
->dest
, saddr
, uh
->source
, dev
->ifindex
);
485 if (!icmpv6_err_convert(type
, code
, &err
) &&
486 !sk
->net_pinfo
.af_inet6
.recverr
)
489 if (sk
->state
!=TCP_ESTABLISHED
&&
490 !sk
->net_pinfo
.af_inet6
.recverr
)
493 if (sk
->net_pinfo
.af_inet6
.recverr
)
494 ipv6_icmp_error(sk
, skb
, err
, uh
->dest
, ntohl(info
), (u8
*)(uh
+1));
497 sk
->error_report(sk
);
502 static inline int udpv6_queue_rcv_skb(struct sock
* sk
, struct sk_buff
*skb
)
504 #if defined(CONFIG_FILTER)
505 if (sk
->filter
&& skb
->ip_summed
!= CHECKSUM_UNNECESSARY
) {
506 if ((unsigned short)csum_fold(csum_partial(skb
->h
.raw
, skb
->len
, skb
->csum
))) {
507 UDP6_INC_STATS_BH(UdpInErrors
);
508 IP6_INC_STATS_BH(Ip6InDiscards
);
512 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
515 if (sock_queue_rcv_skb(sk
,skb
)<0) {
516 UDP6_INC_STATS_BH(UdpInErrors
);
517 IP6_INC_STATS_BH(Ip6InDiscards
);
521 IP6_INC_STATS_BH(Ip6InDelivers
);
522 UDP6_INC_STATS_BH(UdpInDatagrams
);
526 static struct sock
*udp_v6_mcast_next(struct sock
*sk
,
527 u16 loc_port
, struct in6_addr
*loc_addr
,
528 u16 rmt_port
, struct in6_addr
*rmt_addr
,
532 unsigned short num
= ntohs(loc_port
);
533 for(; s
; s
= s
->next
) {
535 struct ipv6_pinfo
*np
= &s
->net_pinfo
.af_inet6
;
537 if(s
->dport
!= rmt_port
)
540 if(!ipv6_addr_any(&np
->daddr
) &&
541 ipv6_addr_cmp(&np
->daddr
, rmt_addr
))
544 if (s
->bound_dev_if
&& s
->bound_dev_if
!= dif
)
547 if(!ipv6_addr_any(&np
->rcv_saddr
)) {
548 if(ipv6_addr_cmp(&np
->rcv_saddr
, loc_addr
) == 0)
551 if(!inet6_mc_check(s
, loc_addr
))
560 * Note: called only from the BH handler context,
561 * so we don't need to lock the hashes.
563 static void udpv6_mcast_deliver(struct udphdr
*uh
,
564 struct in6_addr
*saddr
, struct in6_addr
*daddr
,
567 struct sock
*sk
, *sk2
;
568 struct sk_buff
*buff
;
571 read_lock(&udp_hash_lock
);
572 sk
= udp_hash
[ntohs(uh
->dest
) & (UDP_HTABLE_SIZE
- 1)];
573 dif
= skb
->dev
->ifindex
;
574 sk
= udp_v6_mcast_next(sk
, uh
->dest
, daddr
, uh
->source
, saddr
, dif
);
580 while((sk2
= udp_v6_mcast_next(sk2
->next
, uh
->dest
, saddr
,
581 uh
->source
, daddr
, dif
))) {
583 buff
= skb_clone(skb
, GFP_ATOMIC
);
587 if (sock_queue_rcv_skb(sk2
, buff
) >= 0)
592 if (sock_queue_rcv_skb(sk
, skb
) < 0) {
596 read_unlock(&udp_hash_lock
);
599 int udpv6_rcv(struct sk_buff
*skb
, unsigned long len
)
603 struct net_device
*dev
= skb
->dev
;
604 struct in6_addr
*saddr
= &skb
->nh
.ipv6h
->saddr
;
605 struct in6_addr
*daddr
= &skb
->nh
.ipv6h
->daddr
;
609 __skb_pull(skb
, skb
->h
.raw
- skb
->data
);
611 ulen
= ntohs(uh
->len
);
613 /* Check for jumbo payload */
614 if (ulen
== 0 && skb
->nh
.ipv6h
->payload_len
== 0)
617 if (ulen
> len
|| len
< sizeof(*uh
)) {
619 printk(KERN_DEBUG
"UDP: short packet: %d/%ld\n", ulen
, len
);
620 UDP6_INC_STATS_BH(UdpInErrors
);
625 if (uh
->check
== 0) {
626 /* IPv6 draft-v2 section 8.1 says that we SHOULD log
627 this error. Well, it is reasonable.
630 printk(KERN_INFO
"IPv6: udp checksum is 0\n");
636 if (skb
->ip_summed
==CHECKSUM_HW
) {
637 if (csum_ipv6_magic(saddr
, daddr
, ulen
, IPPROTO_UDP
, skb
->csum
))
639 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
640 } else if (skb
->ip_summed
!= CHECKSUM_UNNECESSARY
)
641 skb
->csum
= ~csum_ipv6_magic(saddr
, daddr
, ulen
, IPPROTO_UDP
, 0);
646 * Multicast receive code
648 if (ipv6_addr_type(daddr
) & IPV6_ADDR_MULTICAST
) {
649 udpv6_mcast_deliver(uh
, saddr
, daddr
, skb
);
656 * check socket cache ... must talk to Alan about his plans
657 * for sock caches... i'll skip this for now.
660 sk
= udp_v6_lookup(saddr
, uh
->source
, daddr
, uh
->dest
, dev
->ifindex
);
663 if (skb
->ip_summed
!= CHECKSUM_UNNECESSARY
&&
664 (unsigned short)csum_fold(csum_partial((char*)uh
, len
, skb
->csum
)))
666 UDP6_INC_STATS_BH(UdpNoPorts
);
668 icmpv6_send(skb
, ICMPV6_DEST_UNREACH
, ICMPV6_PORT_UNREACH
, 0, dev
);
676 udpv6_queue_rcv_skb(sk
, skb
);
681 UDP6_INC_STATS_BH(UdpInErrors
);
696 struct in6_addr
*daddr
;
703 static int udpv6_getfrag(const void *data
, struct in6_addr
*addr
,
704 char *buff
, unsigned int offset
, unsigned int len
)
706 struct udpv6fakehdr
*udh
= (struct udpv6fakehdr
*) data
;
714 offset
-= sizeof(struct udphdr
);
716 dst
+= sizeof(struct udphdr
);
718 clen
-= sizeof(struct udphdr
);
721 if (csum_partial_copy_fromiovecend(dst
, udh
->iov
, offset
,
726 struct in6_addr
*daddr
;
728 udh
->wcheck
= csum_partial((char *)udh
, sizeof(struct udphdr
),
735 * use packet destination address
736 * this should improve cache locality
740 udh
->uh
.check
= csum_ipv6_magic(addr
, daddr
,
741 udh
->pl_len
, IPPROTO_UDP
,
743 if (udh
->uh
.check
== 0)
746 memcpy(buff
, udh
, sizeof(struct udphdr
));
751 static int udpv6_sendmsg(struct sock
*sk
, struct msghdr
*msg
, int ulen
)
753 struct ipv6_txoptions opt_space
;
754 struct udpv6fakehdr udh
;
755 struct ipv6_pinfo
*np
= &sk
->net_pinfo
.af_inet6
;
756 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*) msg
->msg_name
;
757 struct ipv6_txoptions
*opt
= NULL
;
758 struct ip6_flowlabel
*flowlabel
= NULL
;
760 int addr_len
= msg
->msg_namelen
;
761 struct in6_addr
*daddr
;
762 int len
= ulen
+ sizeof(struct udphdr
);
768 /* Rough check on arithmetic overflow,
769 better check is made in ip6_build_xmit
771 if (ulen
< 0 || ulen
> INT_MAX
- sizeof(struct udphdr
))
774 fl
.fl6_flowlabel
= 0;
778 if (sin6
->sin6_family
== AF_INET
)
779 return udp_sendmsg(sk
, msg
, ulen
);
781 if (addr_len
< SIN6_LEN_RFC2133
)
784 if (sin6
->sin6_family
&& sin6
->sin6_family
!= AF_INET6
)
787 if (sin6
->sin6_port
== 0)
790 udh
.uh
.dest
= sin6
->sin6_port
;
791 daddr
= &sin6
->sin6_addr
;
794 fl
.fl6_flowlabel
= sin6
->sin6_flowinfo
&IPV6_FLOWINFO_MASK
;
795 if (fl
.fl6_flowlabel
&IPV6_FLOWLABEL_MASK
) {
796 flowlabel
= fl6_sock_lookup(sk
, fl
.fl6_flowlabel
);
797 if (flowlabel
== NULL
)
799 daddr
= &flowlabel
->dst
;
803 /* Otherwise it will be difficult to maintain sk->dst_cache. */
804 if (sk
->state
== TCP_ESTABLISHED
&&
805 !ipv6_addr_cmp(daddr
, &sk
->net_pinfo
.af_inet6
.daddr
))
806 daddr
= &sk
->net_pinfo
.af_inet6
.daddr
;
808 if (addr_len
>= sizeof(struct sockaddr_in6
) &&
809 sin6
->sin6_scope_id
&&
810 ipv6_addr_type(daddr
)&IPV6_ADDR_LINKLOCAL
)
811 fl
.oif
= sin6
->sin6_scope_id
;
813 if (sk
->state
!= TCP_ESTABLISHED
)
816 udh
.uh
.dest
= sk
->dport
;
817 daddr
= &sk
->net_pinfo
.af_inet6
.daddr
;
818 fl
.fl6_flowlabel
= np
->flow_label
;
821 addr_type
= ipv6_addr_type(daddr
);
823 if (addr_type
== IPV6_ADDR_MAPPED
) {
824 struct sockaddr_in sin
;
826 sin
.sin_family
= AF_INET
;
827 sin
.sin_addr
.s_addr
= daddr
->s6_addr32
[3];
828 sin
.sin_port
= udh
.uh
.dest
;
829 msg
->msg_name
= (struct sockaddr
*)(&sin
);
830 msg
->msg_namelen
= sizeof(sin
);
831 fl6_sock_release(flowlabel
);
833 return udp_sendmsg(sk
, msg
, ulen
);
838 fl
.oif
= sk
->bound_dev_if
;
841 if (msg
->msg_controllen
) {
843 memset(opt
, 0, sizeof(struct ipv6_txoptions
));
845 err
= datagram_send_ctl(msg
, &fl
, opt
, &hlimit
);
847 fl6_sock_release(flowlabel
);
850 if ((fl
.fl6_flowlabel
&IPV6_FLOWLABEL_MASK
) && !flowlabel
) {
851 flowlabel
= fl6_sock_lookup(sk
, fl
.fl6_flowlabel
);
852 if (flowlabel
== NULL
)
855 if (!(opt
->opt_nflen
|opt
->opt_flen
))
861 opt
= fl6_merge_options(&opt_space
, flowlabel
, opt
);
862 if (opt
&& opt
->srcrt
)
865 udh
.uh
.source
= sk
->sport
;
866 udh
.uh
.len
= len
< 0x10000 ? htons(len
) : 0;
868 udh
.iov
= msg
->msg_iov
;
872 fl
.proto
= IPPROTO_UDP
;
874 if (fl
.fl6_src
== NULL
&& !ipv6_addr_any(&np
->saddr
))
875 fl
.fl6_src
= &np
->saddr
;
876 fl
.uli_u
.ports
.dport
= udh
.uh
.dest
;
877 fl
.uli_u
.ports
.sport
= udh
.uh
.source
;
879 err
= ip6_build_xmit(sk
, udpv6_getfrag
, &udh
, &fl
, len
, opt
, hlimit
,
882 fl6_sock_release(flowlabel
);
887 UDP6_INC_STATS_USER(UdpOutDatagrams
);
891 static struct inet6_protocol udpv6_protocol
=
893 udpv6_rcv
, /* UDP handler */
894 udpv6_err
, /* UDP error control */
896 IPPROTO_UDP
, /* protocol ID */
903 #define LINE_FMT "%-190s\n"
905 static void get_udp6_sock(struct sock
*sp
, char *tmpbuf
, int i
)
907 struct in6_addr
*dest
, *src
;
910 dest
= &sp
->net_pinfo
.af_inet6
.daddr
;
911 src
= &sp
->net_pinfo
.af_inet6
.rcv_saddr
;
912 destp
= ntohs(sp
->dport
);
913 srcp
= ntohs(sp
->sport
);
915 "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
916 "%02X %08X:%08X %02X:%08lX %08X %5d %8d %ld %d %p",
918 src
->s6_addr32
[0], src
->s6_addr32
[1],
919 src
->s6_addr32
[2], src
->s6_addr32
[3], srcp
,
920 dest
->s6_addr32
[0], dest
->s6_addr32
[1],
921 dest
->s6_addr32
[2], dest
->s6_addr32
[3], destp
,
923 atomic_read(&sp
->wmem_alloc
), atomic_read(&sp
->rmem_alloc
),
927 atomic_read(&sp
->refcnt
), sp
);
930 int udp6_get_info(char *buffer
, char **start
, off_t offset
, int length
)
932 int len
= 0, num
= 0, i
;
935 char tmpbuf
[LINE_LEN
+2];
937 if (offset
< LINE_LEN
+1)
938 len
+= sprintf(buffer
, LINE_FMT
,
940 "local_address " /* 38 */
941 "remote_address " /* 38 */
942 "st tx_queue rx_queue tr tm->when retrnsmt" /* 41 */
943 " uid timeout inode"); /* 21 */
947 read_lock(&udp_hash_lock
);
948 for (i
= 0; i
< UDP_HTABLE_SIZE
; i
++) {
951 for (sk
= udp_hash
[i
]; sk
; sk
= sk
->next
, num
++) {
952 if (sk
->family
!= PF_INET6
)
957 get_udp6_sock(sk
, tmpbuf
, i
);
958 len
+= sprintf(buffer
+len
, LINE_FMT
, tmpbuf
);
964 read_unlock(&udp_hash_lock
);
965 begin
= len
- (pos
- offset
);
966 *start
= buffer
+ begin
;
975 struct proto udpv6_prot
= {
978 connect
: udpv6_connect
,
979 disconnect
: udp_disconnect
,
981 destroy
: inet6_destroy_sock
,
982 setsockopt
: ipv6_setsockopt
,
983 getsockopt
: ipv6_getsockopt
,
984 sendmsg
: udpv6_sendmsg
,
985 recvmsg
: udpv6_recvmsg
,
986 backlog_rcv
: udpv6_queue_rcv_skb
,
988 unhash
: udp_v6_unhash
,
989 get_port
: udp_v6_get_port
,
992 void __init
udpv6_init(void)
994 inet6_add_protocol(&udpv6_protocol
);