udp.c (188933ac139a6f8ab06cad369bd0200af947b00d) | udp.c (63159f29be1df7f93563a8a0f78c5e65fc844ed6) |
---|---|
1/* 2 * UDP over IPv6 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on linux/ipv4/udp.c --- 39 unchanged lines hidden (view full) --- 48#include <net/inet6_hashtables.h> 49#include <net/busy_poll.h> 50 51#include <linux/proc_fs.h> 52#include <linux/seq_file.h> 53#include <trace/events/skb.h> 54#include "udp_impl.h" 55 | 1/* 2 * UDP over IPv6 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on linux/ipv4/udp.c --- 39 unchanged lines hidden (view full) --- 48#include <net/inet6_hashtables.h> 49#include <net/busy_poll.h> 50 51#include <linux/proc_fs.h> 52#include <linux/seq_file.h> 53#include <trace/events/skb.h> 54#include "udp_impl.h" 55 |
56static unsigned int udp6_ehashfn(struct net *net, 57 const struct in6_addr *laddr, 58 const u16 lport, 59 const struct in6_addr *faddr, 60 const __be16 fport) | 56static u32 udp6_ehashfn(const struct net *net, 57 const struct in6_addr *laddr, 58 const u16 lport, 59 const struct in6_addr *faddr, 60 const __be16 fport) |
61{ 62 static u32 udp6_ehash_secret __read_mostly; 63 static u32 udp_ipv6_hash_secret __read_mostly; 64 65 u32 lhash, fhash; 66 67 net_get_random_once(&udp6_ehash_secret, 68 sizeof(udp6_ehash_secret)); --- 30 unchanged lines hidden (view full) --- 99 100 if (sk2_rcv_saddr6 && 101 ipv6_addr_equal(&sk->sk_v6_rcv_saddr, sk2_rcv_saddr6)) 102 return 1; 103 104 return 0; 105} 106 | 61{ 62 static u32 udp6_ehash_secret __read_mostly; 63 static u32 udp_ipv6_hash_secret __read_mostly; 64 65 u32 lhash, fhash; 66 67 net_get_random_once(&udp6_ehash_secret, 68 sizeof(udp6_ehash_secret)); --- 30 unchanged lines hidden (view full) --- 99 100 if (sk2_rcv_saddr6 && 101 ipv6_addr_equal(&sk->sk_v6_rcv_saddr, sk2_rcv_saddr6)) 102 return 1; 103 104 return 0; 105} 106 |
107static unsigned int udp6_portaddr_hash(struct net *net, 108 const struct in6_addr *addr6, 109 unsigned int port) | 107static u32 udp6_portaddr_hash(const struct net *net, 108 const struct in6_addr *addr6, 109 unsigned int port) |
110{ 111 unsigned int hash, mix = net_hash_mix(net); 112 113 if (ipv6_addr_any(addr6)) 114 hash = jhash_1word(0, mix); 115 else if (ipv6_addr_v4mapped(addr6)) 116 hash = jhash_1word((__force u32)addr6->s6_addr32[3], mix); 117 else --- 268 unchanged lines hidden (view full) --- 386EXPORT_SYMBOL_GPL(udp6_lib_lookup); 387 388 389/* 390 * This should be easy, if there is something there we 391 * return it, otherwise we block. 392 */ 393 | 110{ 111 unsigned int hash, mix = net_hash_mix(net); 112 113 if (ipv6_addr_any(addr6)) 114 hash = jhash_1word(0, mix); 115 else if (ipv6_addr_v4mapped(addr6)) 116 hash = jhash_1word((__force u32)addr6->s6_addr32[3], mix); 117 else --- 268 unchanged lines hidden (view full) --- 386EXPORT_SYMBOL_GPL(udp6_lib_lookup); 387 388 389/* 390 * This should be easy, if there is something there we 391 * return it, otherwise we block. 392 */ 393 |
394int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, 395 struct msghdr *msg, size_t len, | 394int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, |
396 int noblock, int flags, int *addr_len) 397{ 398 struct ipv6_pinfo *np = inet6_sk(sk); 399 struct inet_sock *inet = inet_sk(sk); 400 struct sk_buff *skb; 401 unsigned int ulen, copied; 402 int peeked, off = 0; 403 int err; --- 142 unchanged lines hidden (view full) --- 546 const struct in6_addr *daddr = &hdr->daddr; 547 struct udphdr *uh = (struct udphdr *)(skb->data+offset); 548 struct sock *sk; 549 int err; 550 struct net *net = dev_net(skb->dev); 551 552 sk = __udp6_lib_lookup(net, daddr, uh->dest, 553 saddr, uh->source, inet6_iif(skb), udptable); | 395 int noblock, int flags, int *addr_len) 396{ 397 struct ipv6_pinfo *np = inet6_sk(sk); 398 struct inet_sock *inet = inet_sk(sk); 399 struct sk_buff *skb; 400 unsigned int ulen, copied; 401 int peeked, off = 0; 402 int err; --- 142 unchanged lines hidden (view full) --- 545 const struct in6_addr *daddr = &hdr->daddr; 546 struct udphdr *uh = (struct udphdr *)(skb->data+offset); 547 struct sock *sk; 548 int err; 549 struct net *net = dev_net(skb->dev); 550 551 sk = __udp6_lib_lookup(net, daddr, uh->dest, 552 saddr, uh->source, inet6_iif(skb), udptable); |
554 if (sk == NULL) { | 553 if (!sk) { |
555 ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), 556 ICMP6_MIB_INERRORS); 557 return; 558 } 559 560 if (type == ICMPV6_PKT_TOOBIG) { 561 if (!ip6_sk_accept_pmtu(sk)) 562 goto out; --- 182 unchanged lines hidden (view full) --- 745 struct sk_buff *skb, unsigned int final) 746{ 747 struct sk_buff *skb1 = NULL; 748 struct sock *sk; 749 unsigned int i; 750 751 for (i = 0; i < count; i++) { 752 sk = stack[i]; | 554 ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev), 555 ICMP6_MIB_INERRORS); 556 return; 557 } 558 559 if (type == ICMPV6_PKT_TOOBIG) { 560 if (!ip6_sk_accept_pmtu(sk)) 561 goto out; --- 182 unchanged lines hidden (view full) --- 744 struct sk_buff *skb, unsigned int final) 745{ 746 struct sk_buff *skb1 = NULL; 747 struct sock *sk; 748 unsigned int i; 749 750 for (i = 0; i < count; i++) { 751 sk = stack[i]; |
753 if (likely(skb1 == NULL)) | 752 if (likely(!skb1)) |
754 skb1 = (i == final) ? skb : skb_clone(skb, GFP_ATOMIC); 755 if (!skb1) { 756 atomic_inc(&sk->sk_drops); 757 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS, 758 IS_UDPLITE(sk)); 759 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, 760 IS_UDPLITE(sk)); 761 } --- 334 unchanged lines hidden (view full) --- 1096 err = udp_v6_send_skb(skb, &fl6); 1097 1098out: 1099 up->len = 0; 1100 up->pending = 0; 1101 return err; 1102} 1103 | 753 skb1 = (i == final) ? skb : skb_clone(skb, GFP_ATOMIC); 754 if (!skb1) { 755 atomic_inc(&sk->sk_drops); 756 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS, 757 IS_UDPLITE(sk)); 758 UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, 759 IS_UDPLITE(sk)); 760 } --- 334 unchanged lines hidden (view full) --- 1095 err = udp_v6_send_skb(skb, &fl6); 1096 1097out: 1098 up->len = 0; 1099 up->pending = 0; 1100 return err; 1101} 1102 |
1104int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, 1105 struct msghdr *msg, size_t len) | 1103int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) |
1106{ 1107 struct ipv6_txoptions opt_space; 1108 struct udp_sock *up = udp_sk(sk); 1109 struct inet_sock *inet = inet_sk(sk); 1110 struct ipv6_pinfo *np = inet6_sk(sk); 1111 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); 1112 struct in6_addr *daddr, *final_p, final; 1113 struct ipv6_txoptions *opt = NULL; --- 45 unchanged lines hidden (view full) --- 1159 sin.sin_family = AF_INET; 1160 sin.sin_port = sin6 ? sin6->sin6_port : inet->inet_dport; 1161 sin.sin_addr.s_addr = daddr->s6_addr32[3]; 1162 msg->msg_name = &sin; 1163 msg->msg_namelen = sizeof(sin); 1164do_udp_sendmsg: 1165 if (__ipv6_only_sock(sk)) 1166 return -ENETUNREACH; | 1104{ 1105 struct ipv6_txoptions opt_space; 1106 struct udp_sock *up = udp_sk(sk); 1107 struct inet_sock *inet = inet_sk(sk); 1108 struct ipv6_pinfo *np = inet6_sk(sk); 1109 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); 1110 struct in6_addr *daddr, *final_p, final; 1111 struct ipv6_txoptions *opt = NULL; --- 45 unchanged lines hidden (view full) --- 1157 sin.sin_family = AF_INET; 1158 sin.sin_port = sin6 ? sin6->sin6_port : inet->inet_dport; 1159 sin.sin_addr.s_addr = daddr->s6_addr32[3]; 1160 msg->msg_name = &sin; 1161 msg->msg_namelen = sizeof(sin); 1162do_udp_sendmsg: 1163 if (__ipv6_only_sock(sk)) 1164 return -ENETUNREACH; |
1167 return udp_sendmsg(iocb, sk, msg, len); | 1165 return udp_sendmsg(sk, msg, len); |
1168 } 1169 } 1170 1171 if (up->pending == AF_INET) | 1166 } 1167 } 1168 1169 if (up->pending == AF_INET) |
1172 return udp_sendmsg(iocb, sk, msg, len); | 1170 return udp_sendmsg(sk, msg, len); |
1173 1174 /* Rough check on arithmetic overflow, 1175 better check is made in ip6_append_data(). 1176 */ 1177 if (len > INT_MAX - sizeof(struct udphdr)) 1178 return -EMSGSIZE; 1179 1180 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; --- 23 unchanged lines hidden (view full) --- 1204 1205 fl6.fl6_dport = sin6->sin6_port; 1206 daddr = &sin6->sin6_addr; 1207 1208 if (np->sndflow) { 1209 fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK; 1210 if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { 1211 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 1171 1172 /* Rough check on arithmetic overflow, 1173 better check is made in ip6_append_data(). 1174 */ 1175 if (len > INT_MAX - sizeof(struct udphdr)) 1176 return -EMSGSIZE; 1177 1178 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; --- 23 unchanged lines hidden (view full) --- 1202 1203 fl6.fl6_dport = sin6->sin6_port; 1204 daddr = &sin6->sin6_addr; 1205 1206 if (np->sndflow) { 1207 fl6.flowlabel = sin6->sin6_flowinfo&IPV6_FLOWINFO_MASK; 1208 if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) { 1209 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
1212 if (flowlabel == NULL) | 1210 if (!flowlabel) |
1213 return -EINVAL; 1214 } 1215 } 1216 1217 /* 1218 * Otherwise it will be difficult to maintain 1219 * sk->sk_dst_cache. 1220 */ --- 31 unchanged lines hidden (view full) --- 1252 err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, 1253 &hlimit, &tclass, &dontfrag); 1254 if (err < 0) { 1255 fl6_sock_release(flowlabel); 1256 return err; 1257 } 1258 if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) { 1259 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); | 1211 return -EINVAL; 1212 } 1213 } 1214 1215 /* 1216 * Otherwise it will be difficult to maintain 1217 * sk->sk_dst_cache. 1218 */ --- 31 unchanged lines hidden (view full) --- 1250 err = ip6_datagram_send_ctl(sock_net(sk), sk, msg, &fl6, opt, 1251 &hlimit, &tclass, &dontfrag); 1252 if (err < 0) { 1253 fl6_sock_release(flowlabel); 1254 return err; 1255 } 1256 if ((fl6.flowlabel&IPV6_FLOWLABEL_MASK) && !flowlabel) { 1257 flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
1260 if (flowlabel == NULL) | 1258 if (!flowlabel) |
1261 return -EINVAL; 1262 } 1263 if (!(opt->opt_nflen|opt->opt_flen)) 1264 opt = NULL; 1265 connected = 0; 1266 } | 1259 return -EINVAL; 1260 } 1261 if (!(opt->opt_nflen|opt->opt_flen)) 1262 opt = NULL; 1263 connected = 0; 1264 } |
1267 if (opt == NULL) | 1265 if (!opt) |
1268 opt = np->opt; 1269 if (flowlabel) 1270 opt = fl6_merge_options(&opt_space, flowlabel, opt); 1271 opt = ipv6_fixup_options(&opt_space, opt); 1272 1273 fl6.flowi6_proto = sk->sk_protocol; 1274 if (!ipv6_addr_any(daddr)) 1275 fl6.daddr = *daddr; --- 309 unchanged lines hidden --- | 1266 opt = np->opt; 1267 if (flowlabel) 1268 opt = fl6_merge_options(&opt_space, flowlabel, opt); 1269 opt = ipv6_fixup_options(&opt_space, opt); 1270 1271 fl6.flowi6_proto = sk->sk_protocol; 1272 if (!ipv6_addr_any(daddr)) 1273 fl6.daddr = *daddr; --- 309 unchanged lines hidden --- |