17 #define KMSG_COMPONENT "IPVS"
18 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
22 #include <linux/kernel.h>
23 #include <linux/netfilter.h>
24 #include <linux/netfilter_ipv4.h>
25 #include <linux/udp.h>
40 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
42 uh = skb_header_pointer(skb, iph.
len,
sizeof(_udph), &_udph);
53 if (ip_vs_todrop(net_ipvs(net))) {
58 ip_vs_service_put(svc);
68 if (!*cpp && ignored <= 0) {
72 ip_vs_service_put(svc);
77 ip_vs_service_put(svc);
85 udp_fast_csum_update(
int af,
struct udphdr *
uhdr,
90 #ifdef CONFIG_IP_VS_IPV6
93 csum_fold(ip_vs_check_diff16(oldip->
ip6, newip->
ip6,
94 ip_vs_check_diff2(oldport, newport,
95 ~csum_unfold(uhdr->
check))));
99 csum_fold(ip_vs_check_diff4(oldip->
ip, newip->
ip,
100 ip_vs_check_diff2(oldport, newport,
101 ~csum_unfold(uhdr->
check))));
107 udp_partial_csum_update(
int af,
struct udphdr *uhdr,
112 #ifdef CONFIG_IP_VS_IPV6
115 ~csum_fold(ip_vs_check_diff16(oldip->
ip6, newip->
ip6,
116 ip_vs_check_diff2(oldlen, newlen,
117 csum_unfold(uhdr->
check))));
121 ~csum_fold(ip_vs_check_diff4(oldip->
ip, newip->
ip,
122 ip_vs_check_diff2(oldlen, newlen,
123 csum_unfold(uhdr->
check))));
132 unsigned int udphoff;
134 int payload_csum = 0;
136 #ifdef CONFIG_IP_VS_IPV6
138 udphoff =
sizeof(
struct ipv6hdr);
141 udphoff = ip_hdrlen(skb);
142 oldlen = skb->
len - udphoff;
162 oldlen = skb->
len - udphoff;
167 udph = (
void *)skb_network_header(skb) + udphoff;
174 udp_partial_csum_update(cp->
af, udph, &cp->
daddr, &cp->
vaddr,
177 }
else if (!payload_csum && (udph->
check != 0)) {
179 udp_fast_csum_update(cp->
af, udph, &cp->
daddr, &cp->
vaddr,
188 #ifdef CONFIG_IP_VS_IPV6
201 if (udph->
check == 0)
204 IP_VS_DBG(11,
"O-pkt: %s O-csum=%d (+%zd)\n",
206 (
char*)&(udph->
check) - (
char*)udph);
213 udp_dnat_handler(
struct sk_buff *skb,
217 unsigned int udphoff;
219 int payload_csum = 0;
221 #ifdef CONFIG_IP_VS_IPV6
223 udphoff =
sizeof(
struct ipv6hdr);
226 udphoff = ip_hdrlen(skb);
227 oldlen = skb->
len - udphoff;
248 oldlen = skb->
len - udphoff;
253 udph = (
void *)skb_network_header(skb) + udphoff;
260 udp_partial_csum_update(cp->
af, udph, &cp->
vaddr, &cp->
daddr,
263 }
else if (!payload_csum && (udph->
check != 0)) {
265 udp_fast_csum_update(cp->
af, udph, &cp->
vaddr, &cp->
daddr,
274 #ifdef CONFIG_IP_VS_IPV6
287 if (udph->
check == 0)
299 unsigned int udphoff;
301 #ifdef CONFIG_IP_VS_IPV6
303 udphoff =
sizeof(
struct ipv6hdr);
306 udphoff = ip_hdrlen(skb);
308 uh = skb_header_pointer(skb, udphoff,
sizeof(_udph), &_udph);
312 if (uh->
check != 0) {
316 skb->
len - udphoff, 0);
318 #ifdef CONFIG_IP_VS_IPV6
321 &ipv6_hdr(skb)->
daddr,
326 "Failed checksum for");
337 "Failed checksum for");
365 hash = udp_app_hashkey(port);
368 spin_lock_bh(&ipvs->udp_app_lock);
370 if (i->
port == port) {
375 list_add(&inc->
p_list, &ipvs->udp_apps[hash]);
379 spin_unlock_bh(&ipvs->udp_app_lock);
385 udp_unregister_app(
struct net *net,
struct ip_vs_app *inc)
390 spin_lock_bh(&ipvs->udp_app_lock);
393 spin_unlock_bh(&ipvs->udp_app_lock);
397 static int udp_app_conn_bind(
struct ip_vs_conn *cp)
399 struct netns_ipvs *ipvs = net_ipvs(ip_vs_conn_net(cp));
409 hash = udp_app_hashkey(cp->
vport);
411 spin_lock(&ipvs->udp_app_lock);
416 spin_unlock(&ipvs->udp_app_lock);
419 "%s:%u to app %s on port %u\n",
421 IP_VS_DBG_ADDR(cp->
af, &cp->
caddr),
423 IP_VS_DBG_ADDR(cp->
af, &cp->
vaddr),
433 spin_unlock(&ipvs->udp_app_lock);
450 static const char * udp_state_name(
int state)
454 return udp_state_name_table[
state] ? udp_state_name_table[
state] :
"?";
463 pr_err(
"UDP no ns data\n");
477 sizeof(udp_timeouts));
496 .init_netns = __udp_init,
497 .exit_netns = __udp_exit,
498 .conn_schedule = udp_conn_schedule,
501 .snat_handler = udp_snat_handler,
502 .dnat_handler = udp_dnat_handler,
503 .csum_check = udp_csum_check,
504 .state_transition = udp_state_transition,
505 .state_name = udp_state_name,
506 .register_app = udp_register_app,
507 .unregister_app = udp_unregister_app,
508 .app_conn_bind = udp_app_conn_bind,
510 .timeout_change =
NULL,