diff options
Diffstat (limited to 'net/ipv6/udp.c')
-rw-r--r-- | net/ipv6/udp.c | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index eff050ac7049..69b146843a20 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <net/udp.h> | 51 | #include <net/udp.h> |
52 | #include <net/raw.h> | 52 | #include <net/raw.h> |
53 | #include <net/inet_common.h> | 53 | #include <net/inet_common.h> |
54 | #include <net/tcp_states.h> | ||
54 | 55 | ||
55 | #include <net/ip6_checksum.h> | 56 | #include <net/ip6_checksum.h> |
56 | #include <net/xfrm.h> | 57 | #include <net/xfrm.h> |
@@ -58,7 +59,7 @@ | |||
58 | #include <linux/proc_fs.h> | 59 | #include <linux/proc_fs.h> |
59 | #include <linux/seq_file.h> | 60 | #include <linux/seq_file.h> |
60 | 61 | ||
61 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6); | 62 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; |
62 | 63 | ||
63 | /* Grrr, addr_type already calculated by caller, but I don't want | 64 | /* Grrr, addr_type already calculated by caller, but I don't want |
64 | * to add some silly "cookie" argument to this method just for that. | 65 | * to add some silly "cookie" argument to this method just for that. |
@@ -477,13 +478,12 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) | |||
477 | /* RFC 2460 section 8.1 says that we SHOULD log | 478 | /* RFC 2460 section 8.1 says that we SHOULD log |
478 | this error. Well, it is reasonable. | 479 | this error. Well, it is reasonable. |
479 | */ | 480 | */ |
480 | LIMIT_NETDEBUG( | 481 | LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0\n"); |
481 | printk(KERN_INFO "IPv6: udp checksum is 0\n")); | ||
482 | goto discard; | 482 | goto discard; |
483 | } | 483 | } |
484 | 484 | ||
485 | if (ulen < skb->len) { | 485 | if (ulen < skb->len) { |
486 | if (__pskb_trim(skb, ulen)) | 486 | if (pskb_trim_rcsum(skb, ulen)) |
487 | goto discard; | 487 | goto discard; |
488 | saddr = &skb->nh.ipv6h->saddr; | 488 | saddr = &skb->nh.ipv6h->saddr; |
489 | daddr = &skb->nh.ipv6h->daddr; | 489 | daddr = &skb->nh.ipv6h->daddr; |
@@ -493,7 +493,7 @@ static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) | |||
493 | if (skb->ip_summed==CHECKSUM_HW) { | 493 | if (skb->ip_summed==CHECKSUM_HW) { |
494 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 494 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
495 | if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) { | 495 | if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) { |
496 | LIMIT_NETDEBUG(printk(KERN_DEBUG "udp v6 hw csum failure.\n")); | 496 | LIMIT_NETDEBUG(KERN_DEBUG "udp v6 hw csum failure.\n"); |
497 | skb->ip_summed = CHECKSUM_NONE; | 497 | skb->ip_summed = CHECKSUM_NONE; |
498 | } | 498 | } |
499 | } | 499 | } |
@@ -637,6 +637,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
637 | int addr_len = msg->msg_namelen; | 637 | int addr_len = msg->msg_namelen; |
638 | int ulen = len; | 638 | int ulen = len; |
639 | int hlimit = -1; | 639 | int hlimit = -1; |
640 | int tclass = -1; | ||
640 | int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; | 641 | int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; |
641 | int err; | 642 | int err; |
642 | 643 | ||
@@ -758,7 +759,7 @@ do_udp_sendmsg: | |||
758 | memset(opt, 0, sizeof(struct ipv6_txoptions)); | 759 | memset(opt, 0, sizeof(struct ipv6_txoptions)); |
759 | opt->tot_len = sizeof(*opt); | 760 | opt->tot_len = sizeof(*opt); |
760 | 761 | ||
761 | err = datagram_send_ctl(msg, fl, opt, &hlimit); | 762 | err = datagram_send_ctl(msg, fl, opt, &hlimit, &tclass); |
762 | if (err < 0) { | 763 | if (err < 0) { |
763 | fl6_sock_release(flowlabel); | 764 | fl6_sock_release(flowlabel); |
764 | return err; | 765 | return err; |
@@ -773,8 +774,7 @@ do_udp_sendmsg: | |||
773 | } | 774 | } |
774 | if (opt == NULL) | 775 | if (opt == NULL) |
775 | opt = np->opt; | 776 | opt = np->opt; |
776 | if (flowlabel) | 777 | opt = fl6_merge_options(&opt_space, flowlabel, opt); |
777 | opt = fl6_merge_options(&opt_space, flowlabel, opt); | ||
778 | 778 | ||
779 | fl->proto = IPPROTO_UDP; | 779 | fl->proto = IPPROTO_UDP; |
780 | ipv6_addr_copy(&fl->fl6_dst, daddr); | 780 | ipv6_addr_copy(&fl->fl6_dst, daddr); |
@@ -799,10 +799,8 @@ do_udp_sendmsg: | |||
799 | if (final_p) | 799 | if (final_p) |
800 | ipv6_addr_copy(&fl->fl6_dst, final_p); | 800 | ipv6_addr_copy(&fl->fl6_dst, final_p); |
801 | 801 | ||
802 | if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) { | 802 | if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) |
803 | dst_release(dst); | ||
804 | goto out; | 803 | goto out; |
805 | } | ||
806 | 804 | ||
807 | if (hlimit < 0) { | 805 | if (hlimit < 0) { |
808 | if (ipv6_addr_is_multicast(&fl->fl6_dst)) | 806 | if (ipv6_addr_is_multicast(&fl->fl6_dst)) |
@@ -815,6 +813,12 @@ do_udp_sendmsg: | |||
815 | hlimit = ipv6_get_hoplimit(dst->dev); | 813 | hlimit = ipv6_get_hoplimit(dst->dev); |
816 | } | 814 | } |
817 | 815 | ||
816 | if (tclass < 0) { | ||
817 | tclass = np->tclass; | ||
818 | if (tclass < 0) | ||
819 | tclass = 0; | ||
820 | } | ||
821 | |||
818 | if (msg->msg_flags&MSG_CONFIRM) | 822 | if (msg->msg_flags&MSG_CONFIRM) |
819 | goto do_confirm; | 823 | goto do_confirm; |
820 | back_from_confirm: | 824 | back_from_confirm: |
@@ -825,7 +829,7 @@ back_from_confirm: | |||
825 | /* ... which is an evident application bug. --ANK */ | 829 | /* ... which is an evident application bug. --ANK */ |
826 | release_sock(sk); | 830 | release_sock(sk); |
827 | 831 | ||
828 | LIMIT_NETDEBUG(printk(KERN_DEBUG "udp cork app bug 2\n")); | 832 | LIMIT_NETDEBUG(KERN_DEBUG "udp cork app bug 2\n"); |
829 | err = -EINVAL; | 833 | err = -EINVAL; |
830 | goto out; | 834 | goto out; |
831 | } | 835 | } |
@@ -834,9 +838,10 @@ back_from_confirm: | |||
834 | 838 | ||
835 | do_append_data: | 839 | do_append_data: |
836 | up->len += ulen; | 840 | up->len += ulen; |
837 | err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, sizeof(struct udphdr), | 841 | err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, |
838 | hlimit, opt, fl, (struct rt6_info*)dst, | 842 | sizeof(struct udphdr), hlimit, tclass, opt, fl, |
839 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); | 843 | (struct rt6_info*)dst, |
844 | corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); | ||
840 | if (err) | 845 | if (err) |
841 | udp_v6_flush_pending_frames(sk); | 846 | udp_v6_flush_pending_frames(sk); |
842 | else if (!corkreq) | 847 | else if (!corkreq) |
@@ -1054,8 +1059,6 @@ struct proto udpv6_prot = { | |||
1054 | .obj_size = sizeof(struct udp6_sock), | 1059 | .obj_size = sizeof(struct udp6_sock), |
1055 | }; | 1060 | }; |
1056 | 1061 | ||
1057 | extern struct proto_ops inet6_dgram_ops; | ||
1058 | |||
1059 | static struct inet_protosw udpv6_protosw = { | 1062 | static struct inet_protosw udpv6_protosw = { |
1060 | .type = SOCK_DGRAM, | 1063 | .type = SOCK_DGRAM, |
1061 | .protocol = IPPROTO_UDP, | 1064 | .protocol = IPPROTO_UDP, |