]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - net/netfilter/ipvs/ip_vs_core.c
Initial 2.6.37
[mcf548x/linux.git] / net / netfilter / ipvs / ip_vs_core.c
1 /*
2  * IPVS         An implementation of the IP virtual server support for the
3  *              LINUX operating system.  IPVS is now implemented as a module
4  *              over the Netfilter framework. IPVS can be used to build a
5  *              high-performance and highly available server based on a
6  *              cluster of servers.
7  *
8  * Authors:     Wensong Zhang <wensong@linuxvirtualserver.org>
9  *              Peter Kese <peter.kese@ijs.si>
10  *              Julian Anastasov <ja@ssi.bg>
11  *
12  *              This program is free software; you can redistribute it and/or
13  *              modify it under the terms of the GNU General Public License
14  *              as published by the Free Software Foundation; either version
15  *              2 of the License, or (at your option) any later version.
16  *
17  * The IPVS code for kernel 2.2 was done by Wensong Zhang and Peter Kese,
18  * with changes/fixes from Julian Anastasov, Lars Marowsky-Bree, Horms
19  * and others.
20  *
21  * Changes:
22  *      Paul `Rusty' Russell            properly handle non-linear skbs
23  *      Harald Welte                    don't use nfcache
24  *
25  */
26
27 #define KMSG_COMPONENT "IPVS"
28 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
29
30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/ip.h>
33 #include <linux/tcp.h>
34 #include <linux/sctp.h>
35 #include <linux/icmp.h>
36 #include <linux/slab.h>
37
38 #include <net/ip.h>
39 #include <net/tcp.h>
40 #include <net/udp.h>
41 #include <net/icmp.h>                   /* for icmp_send */
42 #include <net/route.h>
43 #include <net/ip6_checksum.h>
44
45 #include <linux/netfilter.h>
46 #include <linux/netfilter_ipv4.h>
47
48 #ifdef CONFIG_IP_VS_IPV6
49 #include <net/ipv6.h>
50 #include <linux/netfilter_ipv6.h>
51 #include <net/ip6_route.h>
52 #endif
53
54 #include <net/ip_vs.h>
55
56
57 EXPORT_SYMBOL(register_ip_vs_scheduler);
58 EXPORT_SYMBOL(unregister_ip_vs_scheduler);
59 EXPORT_SYMBOL(ip_vs_proto_name);
60 EXPORT_SYMBOL(ip_vs_conn_new);
61 EXPORT_SYMBOL(ip_vs_conn_in_get);
62 EXPORT_SYMBOL(ip_vs_conn_out_get);
63 #ifdef CONFIG_IP_VS_PROTO_TCP
64 EXPORT_SYMBOL(ip_vs_tcp_conn_listen);
65 #endif
66 EXPORT_SYMBOL(ip_vs_conn_put);
67 #ifdef CONFIG_IP_VS_DEBUG
68 EXPORT_SYMBOL(ip_vs_get_debug_level);
69 #endif
70
71
72 /* ID used in ICMP lookups */
73 #define icmp_id(icmph)          (((icmph)->un).echo.id)
74 #define icmpv6_id(icmph)        (icmph->icmp6_dataun.u_echo.identifier)
75
76 const char *ip_vs_proto_name(unsigned proto)
77 {
78         static char buf[20];
79
80         switch (proto) {
81         case IPPROTO_IP:
82                 return "IP";
83         case IPPROTO_UDP:
84                 return "UDP";
85         case IPPROTO_TCP:
86                 return "TCP";
87         case IPPROTO_SCTP:
88                 return "SCTP";
89         case IPPROTO_ICMP:
90                 return "ICMP";
91 #ifdef CONFIG_IP_VS_IPV6
92         case IPPROTO_ICMPV6:
93                 return "ICMPv6";
94 #endif
95         default:
96                 sprintf(buf, "IP_%d", proto);
97                 return buf;
98         }
99 }
100
101 void ip_vs_init_hash_table(struct list_head *table, int rows)
102 {
103         while (--rows >= 0)
104                 INIT_LIST_HEAD(&table[rows]);
105 }
106
107 static inline void
108 ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
109 {
110         struct ip_vs_dest *dest = cp->dest;
111         if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) {
112                 spin_lock(&dest->stats.lock);
113                 dest->stats.ustats.inpkts++;
114                 dest->stats.ustats.inbytes += skb->len;
115                 spin_unlock(&dest->stats.lock);
116
117                 spin_lock(&dest->svc->stats.lock);
118                 dest->svc->stats.ustats.inpkts++;
119                 dest->svc->stats.ustats.inbytes += skb->len;
120                 spin_unlock(&dest->svc->stats.lock);
121
122                 spin_lock(&ip_vs_stats.lock);
123                 ip_vs_stats.ustats.inpkts++;
124                 ip_vs_stats.ustats.inbytes += skb->len;
125                 spin_unlock(&ip_vs_stats.lock);
126         }
127 }
128
129
130 static inline void
131 ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
132 {
133         struct ip_vs_dest *dest = cp->dest;
134         if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) {
135                 spin_lock(&dest->stats.lock);
136                 dest->stats.ustats.outpkts++;
137                 dest->stats.ustats.outbytes += skb->len;
138                 spin_unlock(&dest->stats.lock);
139
140                 spin_lock(&dest->svc->stats.lock);
141                 dest->svc->stats.ustats.outpkts++;
142                 dest->svc->stats.ustats.outbytes += skb->len;
143                 spin_unlock(&dest->svc->stats.lock);
144
145                 spin_lock(&ip_vs_stats.lock);
146                 ip_vs_stats.ustats.outpkts++;
147                 ip_vs_stats.ustats.outbytes += skb->len;
148                 spin_unlock(&ip_vs_stats.lock);
149         }
150 }
151
152
153 static inline void
154 ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc)
155 {
156         spin_lock(&cp->dest->stats.lock);
157         cp->dest->stats.ustats.conns++;
158         spin_unlock(&cp->dest->stats.lock);
159
160         spin_lock(&svc->stats.lock);
161         svc->stats.ustats.conns++;
162         spin_unlock(&svc->stats.lock);
163
164         spin_lock(&ip_vs_stats.lock);
165         ip_vs_stats.ustats.conns++;
166         spin_unlock(&ip_vs_stats.lock);
167 }
168
169
170 static inline int
171 ip_vs_set_state(struct ip_vs_conn *cp, int direction,
172                 const struct sk_buff *skb,
173                 struct ip_vs_protocol *pp)
174 {
175         if (unlikely(!pp->state_transition))
176                 return 0;
177         return pp->state_transition(cp, direction, skb, pp);
178 }
179
180 static inline void
181 ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc,
182                               struct sk_buff *skb, int protocol,
183                               const union nf_inet_addr *caddr, __be16 cport,
184                               const union nf_inet_addr *vaddr, __be16 vport,
185                               struct ip_vs_conn_param *p)
186 {
187         ip_vs_conn_fill_param(svc->af, protocol, caddr, cport, vaddr, vport, p);
188         p->pe = svc->pe;
189         if (p->pe && p->pe->fill_param)
190                 p->pe->fill_param(p, skb);
191 }
192
193 /*
194  *  IPVS persistent scheduling function
195  *  It creates a connection entry according to its template if exists,
196  *  or selects a server and creates a connection entry plus a template.
197  *  Locking: we are svc user (svc->refcnt), so we hold all dests too
198  *  Protocols supported: TCP, UDP
199  */
200 static struct ip_vs_conn *
201 ip_vs_sched_persist(struct ip_vs_service *svc,
202                     struct sk_buff *skb,
203                     __be16 ports[2])
204 {
205         struct ip_vs_conn *cp = NULL;
206         struct ip_vs_iphdr iph;
207         struct ip_vs_dest *dest;
208         struct ip_vs_conn *ct;
209         __be16 dport = 0;               /* destination port to forward */
210         unsigned int flags;
211         struct ip_vs_conn_param param;
212         union nf_inet_addr snet;        /* source network of the client,
213                                            after masking */
214
215         ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
216
217         /* Mask saddr with the netmask to adjust template granularity */
218 #ifdef CONFIG_IP_VS_IPV6
219         if (svc->af == AF_INET6)
220                 ipv6_addr_prefix(&snet.in6, &iph.saddr.in6, svc->netmask);
221         else
222 #endif
223                 snet.ip = iph.saddr.ip & svc->netmask;
224
225         IP_VS_DBG_BUF(6, "p-schedule: src %s:%u dest %s:%u "
226                       "mnet %s\n",
227                       IP_VS_DBG_ADDR(svc->af, &iph.saddr), ntohs(ports[0]),
228                       IP_VS_DBG_ADDR(svc->af, &iph.daddr), ntohs(ports[1]),
229                       IP_VS_DBG_ADDR(svc->af, &snet));
230
231         /*
232          * As far as we know, FTP is a very complicated network protocol, and
233          * it uses control connection and data connections. For active FTP,
234          * FTP server initialize data connection to the client, its source port
235          * is often 20. For passive FTP, FTP server tells the clients the port
236          * that it passively listens to,  and the client issues the data
237          * connection. In the tunneling or direct routing mode, the load
238          * balancer is on the client-to-server half of connection, the port
239          * number is unknown to the load balancer. So, a conn template like
240          * <caddr, 0, vaddr, 0, daddr, 0> is created for persistent FTP
241          * service, and a template like <caddr, 0, vaddr, vport, daddr, dport>
242          * is created for other persistent services.
243          */
244         {
245                 int protocol = iph.protocol;
246                 const union nf_inet_addr *vaddr = &iph.daddr;
247                 const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
248                 __be16 vport = 0;
249
250                 if (ports[1] == svc->port) {
251                         /* non-FTP template:
252                          * <protocol, caddr, 0, vaddr, vport, daddr, dport>
253                          * FTP template:
254                          * <protocol, caddr, 0, vaddr, 0, daddr, 0>
255                          */
256                         if (svc->port != FTPPORT)
257                                 vport = ports[1];
258                 } else {
259                         /* Note: persistent fwmark-based services and
260                          * persistent port zero service are handled here.
261                          * fwmark template:
262                          * <IPPROTO_IP,caddr,0,fwmark,0,daddr,0>
263                          * port zero template:
264                          * <protocol,caddr,0,vaddr,0,daddr,0>
265                          */
266                         if (svc->fwmark) {
267                                 protocol = IPPROTO_IP;
268                                 vaddr = &fwmark;
269                         }
270                 }
271                 ip_vs_conn_fill_param_persist(svc, skb, protocol, &snet, 0,
272                                               vaddr, vport, &param);
273         }
274
275         /* Check if a template already exists */
276         ct = ip_vs_ct_in_get(&param);
277         if (!ct || !ip_vs_check_template(ct)) {
278                 /* No template found or the dest of the connection
279                  * template is not available.
280                  */
281                 dest = svc->scheduler->schedule(svc, skb);
282                 if (!dest) {
283                         IP_VS_DBG(1, "p-schedule: no dest found.\n");
284                         kfree(param.pe_data);
285                         return NULL;
286                 }
287
288                 if (ports[1] == svc->port && svc->port != FTPPORT)
289                         dport = dest->port;
290
291                 /* Create a template
292                  * This adds param.pe_data to the template,
293                  * and thus param.pe_data will be destroyed
294                  * when the template expires */
295                 ct = ip_vs_conn_new(&param, &dest->addr, dport,
296                                     IP_VS_CONN_F_TEMPLATE, dest);
297                 if (ct == NULL) {
298                         kfree(param.pe_data);
299                         return NULL;
300                 }
301
302                 ct->timeout = svc->timeout;
303         } else {
304                 /* set destination with the found template */
305                 dest = ct->dest;
306                 kfree(param.pe_data);
307         }
308
309         dport = ports[1];
310         if (dport == svc->port && dest->port)
311                 dport = dest->port;
312
313         flags = (svc->flags & IP_VS_SVC_F_ONEPACKET
314                  && iph.protocol == IPPROTO_UDP)?
315                 IP_VS_CONN_F_ONE_PACKET : 0;
316
317         /*
318          *    Create a new connection according to the template
319          */
320         ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, ports[0],
321                               &iph.daddr, ports[1], &param);
322         cp = ip_vs_conn_new(&param, &dest->addr, dport, flags, dest);
323         if (cp == NULL) {
324                 ip_vs_conn_put(ct);
325                 return NULL;
326         }
327
328         /*
329          *    Add its control
330          */
331         ip_vs_control_add(cp, ct);
332         ip_vs_conn_put(ct);
333
334         ip_vs_conn_stats(cp, svc);
335         return cp;
336 }
337
338
339 /*
340  *  IPVS main scheduling function
341  *  It selects a server according to the virtual service, and
342  *  creates a connection entry.
343  *  Protocols supported: TCP, UDP
344  */
345 struct ip_vs_conn *
346 ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
347                struct ip_vs_protocol *pp, int *ignored)
348 {
349         struct ip_vs_conn *cp = NULL;
350         struct ip_vs_iphdr iph;
351         struct ip_vs_dest *dest;
352         __be16 _ports[2], *pptr;
353         unsigned int flags;
354
355         *ignored = 1;
356         ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
357         pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports);
358         if (pptr == NULL)
359                 return NULL;
360
361         /*
362          * FTPDATA needs this check when using local real server.
363          * Never schedule Active FTPDATA connections from real server.
364          * For LVS-NAT they must be already created. For other methods
365          * with persistence the connection is created on SYN+ACK.
366          */
367         if (pptr[0] == FTPDATA) {
368                 IP_VS_DBG_PKT(12, svc->af, pp, skb, 0,
369                               "Not scheduling FTPDATA");
370                 return NULL;
371         }
372
373         /*
374          * Do not schedule replies from local real server. It is risky
375          * for fwmark services but mostly for persistent services.
376          */
377         if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) &&
378             (svc->flags & IP_VS_SVC_F_PERSISTENT || svc->fwmark) &&
379             (cp = pp->conn_in_get(svc->af, skb, pp, &iph, iph.len, 1))) {
380                 IP_VS_DBG_PKT(12, svc->af, pp, skb, 0,
381                               "Not scheduling reply for existing connection");
382                 __ip_vs_conn_put(cp);
383                 return NULL;
384         }
385
386         /*
387          *    Persistent service
388          */
389         if (svc->flags & IP_VS_SVC_F_PERSISTENT) {
390                 *ignored = 0;
391                 return ip_vs_sched_persist(svc, skb, pptr);
392         }
393
394         /*
395          *    Non-persistent service
396          */
397         if (!svc->fwmark && pptr[1] != svc->port) {
398                 if (!svc->port)
399                         pr_err("Schedule: port zero only supported "
400                                "in persistent services, "
401                                "check your ipvs configuration\n");
402                 return NULL;
403         }
404
405         *ignored = 0;
406
407         dest = svc->scheduler->schedule(svc, skb);
408         if (dest == NULL) {
409                 IP_VS_DBG(1, "Schedule: no dest found.\n");
410                 return NULL;
411         }
412
413         flags = (svc->flags & IP_VS_SVC_F_ONEPACKET
414                  && iph.protocol == IPPROTO_UDP)?
415                 IP_VS_CONN_F_ONE_PACKET : 0;
416
417         /*
418          *    Create a connection entry.
419          */
420         {
421                 struct ip_vs_conn_param p;
422                 ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr,
423                                       pptr[0], &iph.daddr, pptr[1], &p);
424                 cp = ip_vs_conn_new(&p, &dest->addr,
425                                     dest->port ? dest->port : pptr[1],
426                                     flags, dest);
427                 if (!cp)
428                         return NULL;
429         }
430
431         IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u "
432                       "d:%s:%u conn->flags:%X conn->refcnt:%d\n",
433                       ip_vs_fwd_tag(cp),
434                       IP_VS_DBG_ADDR(svc->af, &cp->caddr), ntohs(cp->cport),
435                       IP_VS_DBG_ADDR(svc->af, &cp->vaddr), ntohs(cp->vport),
436                       IP_VS_DBG_ADDR(svc->af, &cp->daddr), ntohs(cp->dport),
437                       cp->flags, atomic_read(&cp->refcnt));
438
439         ip_vs_conn_stats(cp, svc);
440         return cp;
441 }
442
443
444 /*
445  *  Pass or drop the packet.
446  *  Called by ip_vs_in, when the virtual service is available but
447  *  no destination is available for a new connection.
448  */
449 int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
450                 struct ip_vs_protocol *pp)
451 {
452         __be16 _ports[2], *pptr;
453         struct ip_vs_iphdr iph;
454         int unicast;
455         ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
456
457         pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports);
458         if (pptr == NULL) {
459                 ip_vs_service_put(svc);
460                 return NF_DROP;
461         }
462
463 #ifdef CONFIG_IP_VS_IPV6
464         if (svc->af == AF_INET6)
465                 unicast = ipv6_addr_type(&iph.daddr.in6) & IPV6_ADDR_UNICAST;
466         else
467 #endif
468                 unicast = (inet_addr_type(&init_net, iph.daddr.ip) == RTN_UNICAST);
469
470         /* if it is fwmark-based service, the cache_bypass sysctl is up
471            and the destination is a non-local unicast, then create
472            a cache_bypass connection entry */
473         if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) {
474                 int ret, cs;
475                 struct ip_vs_conn *cp;
476                 unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
477                                       iph.protocol == IPPROTO_UDP)?
478                                       IP_VS_CONN_F_ONE_PACKET : 0;
479                 union nf_inet_addr daddr =  { .all = { 0, 0, 0, 0 } };
480
481                 ip_vs_service_put(svc);
482
483                 /* create a new connection entry */
484                 IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__);
485                 {
486                         struct ip_vs_conn_param p;
487                         ip_vs_conn_fill_param(svc->af, iph.protocol,
488                                               &iph.saddr, pptr[0],
489                                               &iph.daddr, pptr[1], &p);
490                         cp = ip_vs_conn_new(&p, &daddr, 0,
491                                             IP_VS_CONN_F_BYPASS | flags,
492                                             NULL);
493                         if (!cp)
494                                 return NF_DROP;
495                 }
496
497                 /* statistics */
498                 ip_vs_in_stats(cp, skb);
499
500                 /* set state */
501                 cs = ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pp);
502
503                 /* transmit the first SYN packet */
504                 ret = cp->packet_xmit(skb, cp, pp);
505                 /* do not touch skb anymore */
506
507                 atomic_inc(&cp->in_pkts);
508                 ip_vs_conn_put(cp);
509                 return ret;
510         }
511
512         /*
513          * When the virtual ftp service is presented, packets destined
514          * for other services on the VIP may get here (except services
515          * listed in the ipvs table), pass the packets, because it is
516          * not ipvs job to decide to drop the packets.
517          */
518         if ((svc->port == FTPPORT) && (pptr[1] != FTPPORT)) {
519                 ip_vs_service_put(svc);
520                 return NF_ACCEPT;
521         }
522
523         ip_vs_service_put(svc);
524
525         /*
526          * Notify the client that the destination is unreachable, and
527          * release the socket buffer.
528          * Since it is in IP layer, the TCP socket is not actually
529          * created, the TCP RST packet cannot be sent, instead that
530          * ICMP_PORT_UNREACH is sent here no matter it is TCP/UDP. --WZ
531          */
532 #ifdef CONFIG_IP_VS_IPV6
533         if (svc->af == AF_INET6) {
534                 if (!skb->dev) {
535                         struct net *net = dev_net(skb_dst(skb)->dev);
536
537                         skb->dev = net->loopback_dev;
538                 }
539                 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
540         } else
541 #endif
542                 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
543
544         return NF_DROP;
545 }
546
547 __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
548 {
549         return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
550 }
551
552 static inline enum ip_defrag_users ip_vs_defrag_user(unsigned int hooknum)
553 {
554         if (NF_INET_LOCAL_IN == hooknum)
555                 return IP_DEFRAG_VS_IN;
556         if (NF_INET_FORWARD == hooknum)
557                 return IP_DEFRAG_VS_FWD;
558         return IP_DEFRAG_VS_OUT;
559 }
560
561 static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
562 {
563         int err = ip_defrag(skb, user);
564
565         if (!err)
566                 ip_send_check(ip_hdr(skb));
567
568         return err;
569 }
570
571 #ifdef CONFIG_IP_VS_IPV6
572 static inline int ip_vs_gather_frags_v6(struct sk_buff *skb, u_int32_t user)
573 {
574         /* TODO IPv6: Find out what to do here for IPv6 */
575         return 0;
576 }
577 #endif
578
579 /*
580  * Packet has been made sufficiently writable in caller
581  * - inout: 1=in->out, 0=out->in
582  */
583 void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
584                     struct ip_vs_conn *cp, int inout)
585 {
586         struct iphdr *iph        = ip_hdr(skb);
587         unsigned int icmp_offset = iph->ihl*4;
588         struct icmphdr *icmph    = (struct icmphdr *)(skb_network_header(skb) +
589                                                       icmp_offset);
590         struct iphdr *ciph       = (struct iphdr *)(icmph + 1);
591
592         if (inout) {
593                 iph->saddr = cp->vaddr.ip;
594                 ip_send_check(iph);
595                 ciph->daddr = cp->vaddr.ip;
596                 ip_send_check(ciph);
597         } else {
598                 iph->daddr = cp->daddr.ip;
599                 ip_send_check(iph);
600                 ciph->saddr = cp->daddr.ip;
601                 ip_send_check(ciph);
602         }
603
604         /* the TCP/UDP/SCTP port */
605         if (IPPROTO_TCP == ciph->protocol || IPPROTO_UDP == ciph->protocol ||
606             IPPROTO_SCTP == ciph->protocol) {
607                 __be16 *ports = (void *)ciph + ciph->ihl*4;
608
609                 if (inout)
610                         ports[1] = cp->vport;
611                 else
612                         ports[0] = cp->dport;
613         }
614
615         /* And finally the ICMP checksum */
616         icmph->checksum = 0;
617         icmph->checksum = ip_vs_checksum_complete(skb, icmp_offset);
618         skb->ip_summed = CHECKSUM_UNNECESSARY;
619
620         if (inout)
621                 IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph,
622                         "Forwarding altered outgoing ICMP");
623         else
624                 IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph,
625                         "Forwarding altered incoming ICMP");
626 }
627
628 #ifdef CONFIG_IP_VS_IPV6
629 void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
630                     struct ip_vs_conn *cp, int inout)
631 {
632         struct ipv6hdr *iph      = ipv6_hdr(skb);
633         unsigned int icmp_offset = sizeof(struct ipv6hdr);
634         struct icmp6hdr *icmph   = (struct icmp6hdr *)(skb_network_header(skb) +
635                                                       icmp_offset);
636         struct ipv6hdr *ciph     = (struct ipv6hdr *)(icmph + 1);
637
638         if (inout) {
639                 iph->saddr = cp->vaddr.in6;
640                 ciph->daddr = cp->vaddr.in6;
641         } else {
642                 iph->daddr = cp->daddr.in6;
643                 ciph->saddr = cp->daddr.in6;
644         }
645
646         /* the TCP/UDP/SCTP port */
647         if (IPPROTO_TCP == ciph->nexthdr || IPPROTO_UDP == ciph->nexthdr ||
648             IPPROTO_SCTP == ciph->nexthdr) {
649                 __be16 *ports = (void *)ciph + sizeof(struct ipv6hdr);
650
651                 if (inout)
652                         ports[1] = cp->vport;
653                 else
654                         ports[0] = cp->dport;
655         }
656
657         /* And finally the ICMP checksum */
658         icmph->icmp6_cksum = ~csum_ipv6_magic(&iph->saddr, &iph->daddr,
659                                               skb->len - icmp_offset,
660                                               IPPROTO_ICMPV6, 0);
661         skb->csum_start = skb_network_header(skb) - skb->head + icmp_offset;
662         skb->csum_offset = offsetof(struct icmp6hdr, icmp6_cksum);
663         skb->ip_summed = CHECKSUM_PARTIAL;
664
665         if (inout)
666                 IP_VS_DBG_PKT(11, AF_INET6, pp, skb,
667                               (void *)ciph - (void *)iph,
668                               "Forwarding altered outgoing ICMPv6");
669         else
670                 IP_VS_DBG_PKT(11, AF_INET6, pp, skb,
671                               (void *)ciph - (void *)iph,
672                               "Forwarding altered incoming ICMPv6");
673 }
674 #endif
675
676 /* Handle relevant response ICMP messages - forward to the right
677  * destination host. Used for NAT and local client.
678  */
679 static int handle_response_icmp(int af, struct sk_buff *skb,
680                                 union nf_inet_addr *snet,
681                                 __u8 protocol, struct ip_vs_conn *cp,
682                                 struct ip_vs_protocol *pp,
683                                 unsigned int offset, unsigned int ihl)
684 {
685         unsigned int verdict = NF_DROP;
686
687         if (IP_VS_FWD_METHOD(cp) != 0) {
688                 pr_err("shouldn't reach here, because the box is on the "
689                        "half connection in the tun/dr module.\n");
690         }
691
692         /* Ensure the checksum is correct */
693         if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
694                 /* Failed checksum! */
695                 IP_VS_DBG_BUF(1, "Forward ICMP: failed checksum from %s!\n",
696                               IP_VS_DBG_ADDR(af, snet));
697                 goto out;
698         }
699
700         if (IPPROTO_TCP == protocol || IPPROTO_UDP == protocol ||
701             IPPROTO_SCTP == protocol)
702                 offset += 2 * sizeof(__u16);
703         if (!skb_make_writable(skb, offset))
704                 goto out;
705
706 #ifdef CONFIG_IP_VS_IPV6
707         if (af == AF_INET6)
708                 ip_vs_nat_icmp_v6(skb, pp, cp, 1);
709         else
710 #endif
711                 ip_vs_nat_icmp(skb, pp, cp, 1);
712
713 #ifdef CONFIG_IP_VS_IPV6
714         if (af == AF_INET6) {
715                 if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0)
716                         goto out;
717         } else
718 #endif
719                 if ((sysctl_ip_vs_snat_reroute ||
720                      skb_rtable(skb)->rt_flags & RTCF_LOCAL) &&
721                     ip_route_me_harder(skb, RTN_LOCAL) != 0)
722                         goto out;
723
724         /* do the statistics and put it back */
725         ip_vs_out_stats(cp, skb);
726
727         skb->ipvs_property = 1;
728         if (!(cp->flags & IP_VS_CONN_F_NFCT))
729                 ip_vs_notrack(skb);
730         else
731                 ip_vs_update_conntrack(skb, cp, 0);
732         verdict = NF_ACCEPT;
733
734 out:
735         __ip_vs_conn_put(cp);
736
737         return verdict;
738 }
739
740 /*
741  *      Handle ICMP messages in the inside-to-outside direction (outgoing).
742  *      Find any that might be relevant, check against existing connections.
743  *      Currently handles error types - unreachable, quench, ttl exceeded.
744  */
745 static int ip_vs_out_icmp(struct sk_buff *skb, int *related,
746                           unsigned int hooknum)
747 {
748         struct iphdr *iph;
749         struct icmphdr  _icmph, *ic;
750         struct iphdr    _ciph, *cih;    /* The ip header contained within the ICMP */
751         struct ip_vs_iphdr ciph;
752         struct ip_vs_conn *cp;
753         struct ip_vs_protocol *pp;
754         unsigned int offset, ihl;
755         union nf_inet_addr snet;
756
757         *related = 1;
758
759         /* reassemble IP fragments */
760         if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
761                 if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum)))
762                         return NF_STOLEN;
763         }
764
765         iph = ip_hdr(skb);
766         offset = ihl = iph->ihl * 4;
767         ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph);
768         if (ic == NULL)
769                 return NF_DROP;
770
771         IP_VS_DBG(12, "Outgoing ICMP (%d,%d) %pI4->%pI4\n",
772                   ic->type, ntohs(icmp_id(ic)),
773                   &iph->saddr, &iph->daddr);
774
775         /*
776          * Work through seeing if this is for us.
777          * These checks are supposed to be in an order that means easy
778          * things are checked first to speed up processing.... however
779          * this means that some packets will manage to get a long way
780          * down this stack and then be rejected, but that's life.
781          */
782         if ((ic->type != ICMP_DEST_UNREACH) &&
783             (ic->type != ICMP_SOURCE_QUENCH) &&
784             (ic->type != ICMP_TIME_EXCEEDED)) {
785                 *related = 0;
786                 return NF_ACCEPT;
787         }
788
789         /* Now find the contained IP header */
790         offset += sizeof(_icmph);
791         cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
792         if (cih == NULL)
793                 return NF_ACCEPT; /* The packet looks wrong, ignore */
794
795         pp = ip_vs_proto_get(cih->protocol);
796         if (!pp)
797                 return NF_ACCEPT;
798
799         /* Is the embedded protocol header present? */
800         if (unlikely(cih->frag_off & htons(IP_OFFSET) &&
801                      pp->dont_defrag))
802                 return NF_ACCEPT;
803
804         IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset,
805                       "Checking outgoing ICMP for");
806
807         offset += cih->ihl * 4;
808
809         ip_vs_fill_iphdr(AF_INET, cih, &ciph);
810         /* The embedded headers contain source and dest in reverse order */
811         cp = pp->conn_out_get(AF_INET, skb, pp, &ciph, offset, 1);
812         if (!cp)
813                 return NF_ACCEPT;
814
815         snet.ip = iph->saddr;
816         return handle_response_icmp(AF_INET, skb, &snet, cih->protocol, cp,
817                                     pp, offset, ihl);
818 }
819
820 #ifdef CONFIG_IP_VS_IPV6
821 static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related,
822                              unsigned int hooknum)
823 {
824         struct ipv6hdr *iph;
825         struct icmp6hdr _icmph, *ic;
826         struct ipv6hdr  _ciph, *cih;    /* The ip header contained
827                                            within the ICMP */
828         struct ip_vs_iphdr ciph;
829         struct ip_vs_conn *cp;
830         struct ip_vs_protocol *pp;
831         unsigned int offset;
832         union nf_inet_addr snet;
833
834         *related = 1;
835
836         /* reassemble IP fragments */
837         if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) {
838                 if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum)))
839                         return NF_STOLEN;
840         }
841
842         iph = ipv6_hdr(skb);
843         offset = sizeof(struct ipv6hdr);
844         ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph);
845         if (ic == NULL)
846                 return NF_DROP;
847
848         IP_VS_DBG(12, "Outgoing ICMPv6 (%d,%d) %pI6->%pI6\n",
849                   ic->icmp6_type, ntohs(icmpv6_id(ic)),
850                   &iph->saddr, &iph->daddr);
851
852         /*
853          * Work through seeing if this is for us.
854          * These checks are supposed to be in an order that means easy
855          * things are checked first to speed up processing.... however
856          * this means that some packets will manage to get a long way
857          * down this stack and then be rejected, but that's life.
858          */
859         if ((ic->icmp6_type != ICMPV6_DEST_UNREACH) &&
860             (ic->icmp6_type != ICMPV6_PKT_TOOBIG) &&
861             (ic->icmp6_type != ICMPV6_TIME_EXCEED)) {
862                 *related = 0;
863                 return NF_ACCEPT;
864         }
865
866         /* Now find the contained IP header */
867         offset += sizeof(_icmph);
868         cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
869         if (cih == NULL)
870                 return NF_ACCEPT; /* The packet looks wrong, ignore */
871
872         pp = ip_vs_proto_get(cih->nexthdr);
873         if (!pp)
874                 return NF_ACCEPT;
875
876         /* Is the embedded protocol header present? */
877         /* TODO: we don't support fragmentation at the moment anyways */
878         if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag))
879                 return NF_ACCEPT;
880
881         IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset,
882                       "Checking outgoing ICMPv6 for");
883
884         offset += sizeof(struct ipv6hdr);
885
886         ip_vs_fill_iphdr(AF_INET6, cih, &ciph);
887         /* The embedded headers contain source and dest in reverse order */
888         cp = pp->conn_out_get(AF_INET6, skb, pp, &ciph, offset, 1);
889         if (!cp)
890                 return NF_ACCEPT;
891
892         ipv6_addr_copy(&snet.in6, &iph->saddr);
893         return handle_response_icmp(AF_INET6, skb, &snet, cih->nexthdr, cp,
894                                     pp, offset, sizeof(struct ipv6hdr));
895 }
896 #endif
897
898 /*
899  * Check if sctp chunc is ABORT chunk
900  */
901 static inline int is_sctp_abort(const struct sk_buff *skb, int nh_len)
902 {
903         sctp_chunkhdr_t *sch, schunk;
904         sch = skb_header_pointer(skb, nh_len + sizeof(sctp_sctphdr_t),
905                         sizeof(schunk), &schunk);
906         if (sch == NULL)
907                 return 0;
908         if (sch->type == SCTP_CID_ABORT)
909                 return 1;
910         return 0;
911 }
912
913 static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len)
914 {
915         struct tcphdr _tcph, *th;
916
917         th = skb_header_pointer(skb, nh_len, sizeof(_tcph), &_tcph);
918         if (th == NULL)
919                 return 0;
920         return th->rst;
921 }
922
923 /* Handle response packets: rewrite addresses and send away...
924  * Used for NAT and local client.
925  */
926 static unsigned int
927 handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
928                 struct ip_vs_conn *cp, int ihl)
929 {
930         IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet");
931
932         if (!skb_make_writable(skb, ihl))
933                 goto drop;
934
935         /* mangle the packet */
936         if (pp->snat_handler && !pp->snat_handler(skb, pp, cp))
937                 goto drop;
938
939 #ifdef CONFIG_IP_VS_IPV6
940         if (af == AF_INET6)
941                 ipv6_hdr(skb)->saddr = cp->vaddr.in6;
942         else
943 #endif
944         {
945                 ip_hdr(skb)->saddr = cp->vaddr.ip;
946                 ip_send_check(ip_hdr(skb));
947         }
948
949         /*
950          * nf_iterate does not expect change in the skb->dst->dev.
951          * It looks like it is not fatal to enable this code for hooks
952          * where our handlers are at the end of the chain list and
953          * when all next handlers use skb->dst->dev and not outdev.
954          * It will definitely route properly the inout NAT traffic
955          * when multiple paths are used.
956          */
957
958         /* For policy routing, packets originating from this
959          * machine itself may be routed differently to packets
960          * passing through.  We want this packet to be routed as
961          * if it came from this machine itself.  So re-compute
962          * the routing information.
963          */
964 #ifdef CONFIG_IP_VS_IPV6
965         if (af == AF_INET6) {
966                 if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0)
967                         goto drop;
968         } else
969 #endif
970                 if ((sysctl_ip_vs_snat_reroute ||
971                      skb_rtable(skb)->rt_flags & RTCF_LOCAL) &&
972                     ip_route_me_harder(skb, RTN_LOCAL) != 0)
973                         goto drop;
974
975         IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT");
976
977         ip_vs_out_stats(cp, skb);
978         ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
979         skb->ipvs_property = 1;
980         if (!(cp->flags & IP_VS_CONN_F_NFCT))
981                 ip_vs_notrack(skb);
982         else
983                 ip_vs_update_conntrack(skb, cp, 0);
984         ip_vs_conn_put(cp);
985
986         LeaveFunction(11);
987         return NF_ACCEPT;
988
989 drop:
990         ip_vs_conn_put(cp);
991         kfree_skb(skb);
992         LeaveFunction(11);
993         return NF_STOLEN;
994 }
995
996 /*
997  *      Check if outgoing packet belongs to the established ip_vs_conn.
998  */
999 static unsigned int
1000 ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
1001 {
1002         struct ip_vs_iphdr iph;
1003         struct ip_vs_protocol *pp;
1004         struct ip_vs_conn *cp;
1005
1006         EnterFunction(11);
1007
1008         /* Already marked as IPVS request or reply? */
1009         if (skb->ipvs_property)
1010                 return NF_ACCEPT;
1011
1012         /* Bad... Do not break raw sockets */
1013         if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT &&
1014                      af == AF_INET)) {
1015                 struct sock *sk = skb->sk;
1016                 struct inet_sock *inet = inet_sk(skb->sk);
1017
1018                 if (inet && sk->sk_family == PF_INET && inet->nodefrag)
1019                         return NF_ACCEPT;
1020         }
1021
1022         if (unlikely(!skb_dst(skb)))
1023                 return NF_ACCEPT;
1024
1025         ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1026 #ifdef CONFIG_IP_VS_IPV6
1027         if (af == AF_INET6) {
1028                 if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
1029                         int related;
1030                         int verdict = ip_vs_out_icmp_v6(skb, &related,
1031                                                         hooknum);
1032
1033                         if (related)
1034                                 return verdict;
1035                         ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1036                 }
1037         } else
1038 #endif
1039                 if (unlikely(iph.protocol == IPPROTO_ICMP)) {
1040                         int related;
1041                         int verdict = ip_vs_out_icmp(skb, &related, hooknum);
1042
1043                         if (related)
1044                                 return verdict;
1045                         ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1046                 }
1047
1048         pp = ip_vs_proto_get(iph.protocol);
1049         if (unlikely(!pp))
1050                 return NF_ACCEPT;
1051
1052         /* reassemble IP fragments */
1053 #ifdef CONFIG_IP_VS_IPV6
1054         if (af == AF_INET6) {
1055                 if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) {
1056                         if (ip_vs_gather_frags_v6(skb,
1057                                                   ip_vs_defrag_user(hooknum)))
1058                                 return NF_STOLEN;
1059                 }
1060
1061                 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1062         } else
1063 #endif
1064                 if (unlikely(ip_hdr(skb)->frag_off & htons(IP_MF|IP_OFFSET) &&
1065                              !pp->dont_defrag)) {
1066                         if (ip_vs_gather_frags(skb,
1067                                                ip_vs_defrag_user(hooknum)))
1068                                 return NF_STOLEN;
1069
1070                         ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1071                 }
1072
1073         /*
1074          * Check if the packet belongs to an existing entry
1075          */
1076         cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0);
1077
1078         if (likely(cp))
1079                 return handle_response(af, skb, pp, cp, iph.len);
1080         if (sysctl_ip_vs_nat_icmp_send &&
1081             (pp->protocol == IPPROTO_TCP ||
1082              pp->protocol == IPPROTO_UDP ||
1083              pp->protocol == IPPROTO_SCTP)) {
1084                 __be16 _ports[2], *pptr;
1085
1086                 pptr = skb_header_pointer(skb, iph.len,
1087                                           sizeof(_ports), _ports);
1088                 if (pptr == NULL)
1089                         return NF_ACCEPT;       /* Not for me */
1090                 if (ip_vs_lookup_real_service(af, iph.protocol,
1091                                               &iph.saddr,
1092                                               pptr[0])) {
1093                         /*
1094                          * Notify the real server: there is no
1095                          * existing entry if it is not RST
1096                          * packet or not TCP packet.
1097                          */
1098                         if ((iph.protocol != IPPROTO_TCP &&
1099                              iph.protocol != IPPROTO_SCTP)
1100                              || ((iph.protocol == IPPROTO_TCP
1101                                   && !is_tcp_reset(skb, iph.len))
1102                                  || (iph.protocol == IPPROTO_SCTP
1103                                         && !is_sctp_abort(skb,
1104                                                 iph.len)))) {
1105 #ifdef CONFIG_IP_VS_IPV6
1106                                 if (af == AF_INET6) {
1107                                         struct net *net =
1108                                                 dev_net(skb_dst(skb)->dev);
1109
1110                                         if (!skb->dev)
1111                                                 skb->dev = net->loopback_dev;
1112                                         icmpv6_send(skb,
1113                                                     ICMPV6_DEST_UNREACH,
1114                                                     ICMPV6_PORT_UNREACH,
1115                                                     0);
1116                                 } else
1117 #endif
1118                                         icmp_send(skb,
1119                                                   ICMP_DEST_UNREACH,
1120                                                   ICMP_PORT_UNREACH, 0);
1121                                 return NF_DROP;
1122                         }
1123                 }
1124         }
1125         IP_VS_DBG_PKT(12, af, pp, skb, 0,
1126                       "ip_vs_out: packet continues traversal as normal");
1127         return NF_ACCEPT;
1128 }
1129
1130 /*
1131  *      It is hooked at the NF_INET_FORWARD and NF_INET_LOCAL_IN chain,
1132  *      used only for VS/NAT.
1133  *      Check if packet is reply for established ip_vs_conn.
1134  */
1135 static unsigned int
1136 ip_vs_reply4(unsigned int hooknum, struct sk_buff *skb,
1137              const struct net_device *in, const struct net_device *out,
1138              int (*okfn)(struct sk_buff *))
1139 {
1140         return ip_vs_out(hooknum, skb, AF_INET);
1141 }
1142
1143 /*
1144  *      It is hooked at the NF_INET_LOCAL_OUT chain, used only for VS/NAT.
1145  *      Check if packet is reply for established ip_vs_conn.
1146  */
1147 static unsigned int
1148 ip_vs_local_reply4(unsigned int hooknum, struct sk_buff *skb,
1149                    const struct net_device *in, const struct net_device *out,
1150                    int (*okfn)(struct sk_buff *))
1151 {
1152         unsigned int verdict;
1153
1154         /* Disable BH in LOCAL_OUT until all places are fixed */
1155         local_bh_disable();
1156         verdict = ip_vs_out(hooknum, skb, AF_INET);
1157         local_bh_enable();
1158         return verdict;
1159 }
1160
1161 #ifdef CONFIG_IP_VS_IPV6
1162
1163 /*
1164  *      It is hooked at the NF_INET_FORWARD and NF_INET_LOCAL_IN chain,
1165  *      used only for VS/NAT.
1166  *      Check if packet is reply for established ip_vs_conn.
1167  */
1168 static unsigned int
1169 ip_vs_reply6(unsigned int hooknum, struct sk_buff *skb,
1170              const struct net_device *in, const struct net_device *out,
1171              int (*okfn)(struct sk_buff *))
1172 {
1173         return ip_vs_out(hooknum, skb, AF_INET6);
1174 }
1175
1176 /*
1177  *      It is hooked at the NF_INET_LOCAL_OUT chain, used only for VS/NAT.
1178  *      Check if packet is reply for established ip_vs_conn.
1179  */
1180 static unsigned int
1181 ip_vs_local_reply6(unsigned int hooknum, struct sk_buff *skb,
1182                    const struct net_device *in, const struct net_device *out,
1183                    int (*okfn)(struct sk_buff *))
1184 {
1185         unsigned int verdict;
1186
1187         /* Disable BH in LOCAL_OUT until all places are fixed */
1188         local_bh_disable();
1189         verdict = ip_vs_out(hooknum, skb, AF_INET6);
1190         local_bh_enable();
1191         return verdict;
1192 }
1193
1194 #endif
1195
1196 /*
1197  *      Handle ICMP messages in the outside-to-inside direction (incoming).
1198  *      Find any that might be relevant, check against existing connections,
1199  *      forward to the right destination host if relevant.
1200  *      Currently handles error types - unreachable, quench, ttl exceeded.
1201  */
1202 static int
1203 ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
1204 {
1205         struct iphdr *iph;
1206         struct icmphdr  _icmph, *ic;
1207         struct iphdr    _ciph, *cih;    /* The ip header contained within the ICMP */
1208         struct ip_vs_iphdr ciph;
1209         struct ip_vs_conn *cp;
1210         struct ip_vs_protocol *pp;
1211         unsigned int offset, ihl, verdict;
1212         union nf_inet_addr snet;
1213
1214         *related = 1;
1215
1216         /* reassemble IP fragments */
1217         if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
1218                 if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum)))
1219                         return NF_STOLEN;
1220         }
1221
1222         iph = ip_hdr(skb);
1223         offset = ihl = iph->ihl * 4;
1224         ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph);
1225         if (ic == NULL)
1226                 return NF_DROP;
1227
1228         IP_VS_DBG(12, "Incoming ICMP (%d,%d) %pI4->%pI4\n",
1229                   ic->type, ntohs(icmp_id(ic)),
1230                   &iph->saddr, &iph->daddr);
1231
1232         /*
1233          * Work through seeing if this is for us.
1234          * These checks are supposed to be in an order that means easy
1235          * things are checked first to speed up processing.... however
1236          * this means that some packets will manage to get a long way
1237          * down this stack and then be rejected, but that's life.
1238          */
1239         if ((ic->type != ICMP_DEST_UNREACH) &&
1240             (ic->type != ICMP_SOURCE_QUENCH) &&
1241             (ic->type != ICMP_TIME_EXCEEDED)) {
1242                 *related = 0;
1243                 return NF_ACCEPT;
1244         }
1245
1246         /* Now find the contained IP header */
1247         offset += sizeof(_icmph);
1248         cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
1249         if (cih == NULL)
1250                 return NF_ACCEPT; /* The packet looks wrong, ignore */
1251
1252         pp = ip_vs_proto_get(cih->protocol);
1253         if (!pp)
1254                 return NF_ACCEPT;
1255
1256         /* Is the embedded protocol header present? */
1257         if (unlikely(cih->frag_off & htons(IP_OFFSET) &&
1258                      pp->dont_defrag))
1259                 return NF_ACCEPT;
1260
1261         IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset,
1262                       "Checking incoming ICMP for");
1263
1264         offset += cih->ihl * 4;
1265
1266         ip_vs_fill_iphdr(AF_INET, cih, &ciph);
1267         /* The embedded headers contain source and dest in reverse order */
1268         cp = pp->conn_in_get(AF_INET, skb, pp, &ciph, offset, 1);
1269         if (!cp) {
1270                 /* The packet could also belong to a local client */
1271                 cp = pp->conn_out_get(AF_INET, skb, pp, &ciph, offset, 1);
1272                 if (cp) {
1273                         snet.ip = iph->saddr;
1274                         return handle_response_icmp(AF_INET, skb, &snet,
1275                                                     cih->protocol, cp, pp,
1276                                                     offset, ihl);
1277                 }
1278                 return NF_ACCEPT;
1279         }
1280
1281         verdict = NF_DROP;
1282
1283         /* Ensure the checksum is correct */
1284         if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
1285                 /* Failed checksum! */
1286                 IP_VS_DBG(1, "Incoming ICMP: failed checksum from %pI4!\n",
1287                           &iph->saddr);
1288                 goto out;
1289         }
1290
1291         /* do the statistics and put it back */
1292         ip_vs_in_stats(cp, skb);
1293         if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol)
1294                 offset += 2 * sizeof(__u16);
1295         verdict = ip_vs_icmp_xmit(skb, cp, pp, offset);
1296         /* LOCALNODE from FORWARD hook is not supported */
1297         if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
1298             skb_rtable(skb)->rt_flags & RTCF_LOCAL) {
1299                 IP_VS_DBG(1, "%s(): "
1300                           "local delivery to %pI4 but in FORWARD\n",
1301                           __func__, &skb_rtable(skb)->rt_dst);
1302                 verdict = NF_DROP;
1303         }
1304
1305   out:
1306         __ip_vs_conn_put(cp);
1307
1308         return verdict;
1309 }
1310
1311 #ifdef CONFIG_IP_VS_IPV6
1312 static int
1313 ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1314 {
1315         struct ipv6hdr *iph;
1316         struct icmp6hdr _icmph, *ic;
1317         struct ipv6hdr  _ciph, *cih;    /* The ip header contained
1318                                            within the ICMP */
1319         struct ip_vs_iphdr ciph;
1320         struct ip_vs_conn *cp;
1321         struct ip_vs_protocol *pp;
1322         unsigned int offset, verdict;
1323         union nf_inet_addr snet;
1324         struct rt6_info *rt;
1325
1326         *related = 1;
1327
1328         /* reassemble IP fragments */
1329         if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) {
1330                 if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum)))
1331                         return NF_STOLEN;
1332         }
1333
1334         iph = ipv6_hdr(skb);
1335         offset = sizeof(struct ipv6hdr);
1336         ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph);
1337         if (ic == NULL)
1338                 return NF_DROP;
1339
1340         IP_VS_DBG(12, "Incoming ICMPv6 (%d,%d) %pI6->%pI6\n",
1341                   ic->icmp6_type, ntohs(icmpv6_id(ic)),
1342                   &iph->saddr, &iph->daddr);
1343
1344         /*
1345          * Work through seeing if this is for us.
1346          * These checks are supposed to be in an order that means easy
1347          * things are checked first to speed up processing.... however
1348          * this means that some packets will manage to get a long way
1349          * down this stack and then be rejected, but that's life.
1350          */
1351         if ((ic->icmp6_type != ICMPV6_DEST_UNREACH) &&
1352             (ic->icmp6_type != ICMPV6_PKT_TOOBIG) &&
1353             (ic->icmp6_type != ICMPV6_TIME_EXCEED)) {
1354                 *related = 0;
1355                 return NF_ACCEPT;
1356         }
1357
1358         /* Now find the contained IP header */
1359         offset += sizeof(_icmph);
1360         cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
1361         if (cih == NULL)
1362                 return NF_ACCEPT; /* The packet looks wrong, ignore */
1363
1364         pp = ip_vs_proto_get(cih->nexthdr);
1365         if (!pp)
1366                 return NF_ACCEPT;
1367
1368         /* Is the embedded protocol header present? */
1369         /* TODO: we don't support fragmentation at the moment anyways */
1370         if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag))
1371                 return NF_ACCEPT;
1372
1373         IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset,
1374                       "Checking incoming ICMPv6 for");
1375
1376         offset += sizeof(struct ipv6hdr);
1377
1378         ip_vs_fill_iphdr(AF_INET6, cih, &ciph);
1379         /* The embedded headers contain source and dest in reverse order */
1380         cp = pp->conn_in_get(AF_INET6, skb, pp, &ciph, offset, 1);
1381         if (!cp) {
1382                 /* The packet could also belong to a local client */
1383                 cp = pp->conn_out_get(AF_INET6, skb, pp, &ciph, offset, 1);
1384                 if (cp) {
1385                         ipv6_addr_copy(&snet.in6, &iph->saddr);
1386                         return handle_response_icmp(AF_INET6, skb, &snet,
1387                                                     cih->nexthdr,
1388                                                     cp, pp, offset,
1389                                                     sizeof(struct ipv6hdr));
1390                 }
1391                 return NF_ACCEPT;
1392         }
1393
1394         verdict = NF_DROP;
1395
1396         /* do the statistics and put it back */
1397         ip_vs_in_stats(cp, skb);
1398         if (IPPROTO_TCP == cih->nexthdr || IPPROTO_UDP == cih->nexthdr ||
1399             IPPROTO_SCTP == cih->nexthdr)
1400                 offset += 2 * sizeof(__u16);
1401         verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset);
1402         /* LOCALNODE from FORWARD hook is not supported */
1403         if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD &&
1404             (rt = (struct rt6_info *) skb_dst(skb)) &&
1405             rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK) {
1406                 IP_VS_DBG(1, "%s(): "
1407                           "local delivery to %pI6 but in FORWARD\n",
1408                           __func__, &rt->rt6i_dst);
1409                 verdict = NF_DROP;
1410         }
1411
1412         __ip_vs_conn_put(cp);
1413
1414         return verdict;
1415 }
1416 #endif
1417
1418
1419 /*
1420  *      Check if it's for virtual services, look it up,
1421  *      and send it on its way...
1422  */
1423 static unsigned int
1424 ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
1425 {
1426         struct ip_vs_iphdr iph;
1427         struct ip_vs_protocol *pp;
1428         struct ip_vs_conn *cp;
1429         int ret, restart, pkts;
1430
1431         /* Already marked as IPVS request or reply? */
1432         if (skb->ipvs_property)
1433                 return NF_ACCEPT;
1434
1435         /*
1436          *      Big tappo:
1437          *      - remote client: only PACKET_HOST
1438          *      - route: used for struct net when skb->dev is unset
1439          */
1440         if (unlikely((skb->pkt_type != PACKET_HOST &&
1441                       hooknum != NF_INET_LOCAL_OUT) ||
1442                      !skb_dst(skb))) {
1443                 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1444                 IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s"
1445                               " ignored in hook %u\n",
1446                               skb->pkt_type, iph.protocol,
1447                               IP_VS_DBG_ADDR(af, &iph.daddr), hooknum);
1448                 return NF_ACCEPT;
1449         }
1450         ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1451
1452         /* Bad... Do not break raw sockets */
1453         if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT &&
1454                      af == AF_INET)) {
1455                 struct sock *sk = skb->sk;
1456                 struct inet_sock *inet = inet_sk(skb->sk);
1457
1458                 if (inet && sk->sk_family == PF_INET && inet->nodefrag)
1459                         return NF_ACCEPT;
1460         }
1461
1462 #ifdef CONFIG_IP_VS_IPV6
1463         if (af == AF_INET6) {
1464                 if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
1465                         int related;
1466                         int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum);
1467
1468                         if (related)
1469                                 return verdict;
1470                         ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1471                 }
1472         } else
1473 #endif
1474                 if (unlikely(iph.protocol == IPPROTO_ICMP)) {
1475                         int related;
1476                         int verdict = ip_vs_in_icmp(skb, &related, hooknum);
1477
1478                         if (related)
1479                                 return verdict;
1480                         ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1481                 }
1482
1483         /* Protocol supported? */
1484         pp = ip_vs_proto_get(iph.protocol);
1485         if (unlikely(!pp))
1486                 return NF_ACCEPT;
1487
1488         /*
1489          * Check if the packet belongs to an existing connection entry
1490          */
1491         cp = pp->conn_in_get(af, skb, pp, &iph, iph.len, 0);
1492
1493         if (unlikely(!cp)) {
1494                 int v;
1495
1496                 if (!pp->conn_schedule(af, skb, pp, &v, &cp))
1497                         return v;
1498         }
1499
1500         if (unlikely(!cp)) {
1501                 /* sorry, all this trouble for a no-hit :) */
1502                 IP_VS_DBG_PKT(12, af, pp, skb, 0,
1503                               "ip_vs_in: packet continues traversal as normal");
1504                 return NF_ACCEPT;
1505         }
1506
1507         IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet");
1508
1509         /* Check the server status */
1510         if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
1511                 /* the destination server is not available */
1512
1513                 if (sysctl_ip_vs_expire_nodest_conn) {
1514                         /* try to expire the connection immediately */
1515                         ip_vs_conn_expire_now(cp);
1516                 }
1517                 /* don't restart its timer, and silently
1518                    drop the packet. */
1519                 __ip_vs_conn_put(cp);
1520                 return NF_DROP;
1521         }
1522
1523         ip_vs_in_stats(cp, skb);
1524         restart = ip_vs_set_state(cp, IP_VS_DIR_INPUT, skb, pp);
1525         if (cp->packet_xmit)
1526                 ret = cp->packet_xmit(skb, cp, pp);
1527                 /* do not touch skb anymore */
1528         else {
1529                 IP_VS_DBG_RL("warning: packet_xmit is null");
1530                 ret = NF_ACCEPT;
1531         }
1532
1533         /* Increase its packet counter and check if it is needed
1534          * to be synchronized
1535          *
1536          * Sync connection if it is about to close to
1537          * encorage the standby servers to update the connections timeout
1538          */
1539         pkts = atomic_add_return(1, &cp->in_pkts);
1540         if (af == AF_INET && (ip_vs_sync_state & IP_VS_STATE_MASTER) &&
1541             cp->protocol == IPPROTO_SCTP) {
1542                 if ((cp->state == IP_VS_SCTP_S_ESTABLISHED &&
1543                         (pkts % sysctl_ip_vs_sync_threshold[1]
1544                          == sysctl_ip_vs_sync_threshold[0])) ||
1545                                 (cp->old_state != cp->state &&
1546                                  ((cp->state == IP_VS_SCTP_S_CLOSED) ||
1547                                   (cp->state == IP_VS_SCTP_S_SHUT_ACK_CLI) ||
1548                                   (cp->state == IP_VS_SCTP_S_SHUT_ACK_SER)))) {
1549                         ip_vs_sync_conn(cp);
1550                         goto out;
1551                 }
1552         }
1553
1554         /* Keep this block last: TCP and others with pp->num_states <= 1 */
1555         else if (af == AF_INET &&
1556             (ip_vs_sync_state & IP_VS_STATE_MASTER) &&
1557             (((cp->protocol != IPPROTO_TCP ||
1558                cp->state == IP_VS_TCP_S_ESTABLISHED) &&
1559               (pkts % sysctl_ip_vs_sync_threshold[1]
1560                == sysctl_ip_vs_sync_threshold[0])) ||
1561              ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
1562               ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
1563                (cp->state == IP_VS_TCP_S_CLOSE) ||
1564                (cp->state == IP_VS_TCP_S_CLOSE_WAIT) ||
1565                (cp->state == IP_VS_TCP_S_TIME_WAIT)))))
1566                 ip_vs_sync_conn(cp);
1567 out:
1568         cp->old_state = cp->state;
1569
1570         ip_vs_conn_put(cp);
1571         return ret;
1572 }
1573
1574 /*
1575  *      AF_INET handler in NF_INET_LOCAL_IN chain
1576  *      Schedule and forward packets from remote clients
1577  */
1578 static unsigned int
1579 ip_vs_remote_request4(unsigned int hooknum, struct sk_buff *skb,
1580                       const struct net_device *in,
1581                       const struct net_device *out,
1582                       int (*okfn)(struct sk_buff *))
1583 {
1584         return ip_vs_in(hooknum, skb, AF_INET);
1585 }
1586
1587 /*
1588  *      AF_INET handler in NF_INET_LOCAL_OUT chain
1589  *      Schedule and forward packets from local clients
1590  */
1591 static unsigned int
1592 ip_vs_local_request4(unsigned int hooknum, struct sk_buff *skb,
1593                      const struct net_device *in, const struct net_device *out,
1594                      int (*okfn)(struct sk_buff *))
1595 {
1596         unsigned int verdict;
1597
1598         /* Disable BH in LOCAL_OUT until all places are fixed */
1599         local_bh_disable();
1600         verdict = ip_vs_in(hooknum, skb, AF_INET);
1601         local_bh_enable();
1602         return verdict;
1603 }
1604
1605 #ifdef CONFIG_IP_VS_IPV6
1606
1607 /*
1608  *      AF_INET6 handler in NF_INET_LOCAL_IN chain
1609  *      Schedule and forward packets from remote clients
1610  */
1611 static unsigned int
1612 ip_vs_remote_request6(unsigned int hooknum, struct sk_buff *skb,
1613                       const struct net_device *in,
1614                       const struct net_device *out,
1615                       int (*okfn)(struct sk_buff *))
1616 {
1617         return ip_vs_in(hooknum, skb, AF_INET6);
1618 }
1619
1620 /*
1621  *      AF_INET6 handler in NF_INET_LOCAL_OUT chain
1622  *      Schedule and forward packets from local clients
1623  */
1624 static unsigned int
1625 ip_vs_local_request6(unsigned int hooknum, struct sk_buff *skb,
1626                      const struct net_device *in, const struct net_device *out,
1627                      int (*okfn)(struct sk_buff *))
1628 {
1629         unsigned int verdict;
1630
1631         /* Disable BH in LOCAL_OUT until all places are fixed */
1632         local_bh_disable();
1633         verdict = ip_vs_in(hooknum, skb, AF_INET6);
1634         local_bh_enable();
1635         return verdict;
1636 }
1637
1638 #endif
1639
1640
1641 /*
1642  *      It is hooked at the NF_INET_FORWARD chain, in order to catch ICMP
1643  *      related packets destined for 0.0.0.0/0.
1644  *      When fwmark-based virtual service is used, such as transparent
1645  *      cache cluster, TCP packets can be marked and routed to ip_vs_in,
1646  *      but ICMP destined for 0.0.0.0/0 cannot not be easily marked and
1647  *      sent to ip_vs_in_icmp. So, catch them at the NF_INET_FORWARD chain
1648  *      and send them to ip_vs_in_icmp.
1649  */
1650 static unsigned int
1651 ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb,
1652                    const struct net_device *in, const struct net_device *out,
1653                    int (*okfn)(struct sk_buff *))
1654 {
1655         int r;
1656
1657         if (ip_hdr(skb)->protocol != IPPROTO_ICMP)
1658                 return NF_ACCEPT;
1659
1660         return ip_vs_in_icmp(skb, &r, hooknum);
1661 }
1662
1663 #ifdef CONFIG_IP_VS_IPV6
1664 static unsigned int
1665 ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb,
1666                       const struct net_device *in, const struct net_device *out,
1667                       int (*okfn)(struct sk_buff *))
1668 {
1669         int r;
1670
1671         if (ipv6_hdr(skb)->nexthdr != IPPROTO_ICMPV6)
1672                 return NF_ACCEPT;
1673
1674         return ip_vs_in_icmp_v6(skb, &r, hooknum);
1675 }
1676 #endif
1677
1678
1679 static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
1680         /* After packet filtering, change source only for VS/NAT */
1681         {
1682                 .hook           = ip_vs_reply4,
1683                 .owner          = THIS_MODULE,
1684                 .pf             = PF_INET,
1685                 .hooknum        = NF_INET_LOCAL_IN,
1686                 .priority       = 99,
1687         },
1688         /* After packet filtering, forward packet through VS/DR, VS/TUN,
1689          * or VS/NAT(change destination), so that filtering rules can be
1690          * applied to IPVS. */
1691         {
1692                 .hook           = ip_vs_remote_request4,
1693                 .owner          = THIS_MODULE,
1694                 .pf             = PF_INET,
1695                 .hooknum        = NF_INET_LOCAL_IN,
1696                 .priority       = 101,
1697         },
1698         /* Before ip_vs_in, change source only for VS/NAT */
1699         {
1700                 .hook           = ip_vs_local_reply4,
1701                 .owner          = THIS_MODULE,
1702                 .pf             = PF_INET,
1703                 .hooknum        = NF_INET_LOCAL_OUT,
1704                 .priority       = -99,
1705         },
1706         /* After mangle, schedule and forward local requests */
1707         {
1708                 .hook           = ip_vs_local_request4,
1709                 .owner          = THIS_MODULE,
1710                 .pf             = PF_INET,
1711                 .hooknum        = NF_INET_LOCAL_OUT,
1712                 .priority       = -98,
1713         },
1714         /* After packet filtering (but before ip_vs_out_icmp), catch icmp
1715          * destined for 0.0.0.0/0, which is for incoming IPVS connections */
1716         {
1717                 .hook           = ip_vs_forward_icmp,
1718                 .owner          = THIS_MODULE,
1719                 .pf             = PF_INET,
1720                 .hooknum        = NF_INET_FORWARD,
1721                 .priority       = 99,
1722         },
1723         /* After packet filtering, change source only for VS/NAT */
1724         {
1725                 .hook           = ip_vs_reply4,
1726                 .owner          = THIS_MODULE,
1727                 .pf             = PF_INET,
1728                 .hooknum        = NF_INET_FORWARD,
1729                 .priority       = 100,
1730         },
1731 #ifdef CONFIG_IP_VS_IPV6
1732         /* After packet filtering, change source only for VS/NAT */
1733         {
1734                 .hook           = ip_vs_reply6,
1735                 .owner          = THIS_MODULE,
1736                 .pf             = PF_INET6,
1737                 .hooknum        = NF_INET_LOCAL_IN,
1738                 .priority       = 99,
1739         },
1740         /* After packet filtering, forward packet through VS/DR, VS/TUN,
1741          * or VS/NAT(change destination), so that filtering rules can be
1742          * applied to IPVS. */
1743         {
1744                 .hook           = ip_vs_remote_request6,
1745                 .owner          = THIS_MODULE,
1746                 .pf             = PF_INET6,
1747                 .hooknum        = NF_INET_LOCAL_IN,
1748                 .priority       = 101,
1749         },
1750         /* Before ip_vs_in, change source only for VS/NAT */
1751         {
1752                 .hook           = ip_vs_local_reply6,
1753                 .owner          = THIS_MODULE,
1754                 .pf             = PF_INET,
1755                 .hooknum        = NF_INET_LOCAL_OUT,
1756                 .priority       = -99,
1757         },
1758         /* After mangle, schedule and forward local requests */
1759         {
1760                 .hook           = ip_vs_local_request6,
1761                 .owner          = THIS_MODULE,
1762                 .pf             = PF_INET6,
1763                 .hooknum        = NF_INET_LOCAL_OUT,
1764                 .priority       = -98,
1765         },
1766         /* After packet filtering (but before ip_vs_out_icmp), catch icmp
1767          * destined for 0.0.0.0/0, which is for incoming IPVS connections */
1768         {
1769                 .hook           = ip_vs_forward_icmp_v6,
1770                 .owner          = THIS_MODULE,
1771                 .pf             = PF_INET6,
1772                 .hooknum        = NF_INET_FORWARD,
1773                 .priority       = 99,
1774         },
1775         /* After packet filtering, change source only for VS/NAT */
1776         {
1777                 .hook           = ip_vs_reply6,
1778                 .owner          = THIS_MODULE,
1779                 .pf             = PF_INET6,
1780                 .hooknum        = NF_INET_FORWARD,
1781                 .priority       = 100,
1782         },
1783 #endif
1784 };
1785
1786
1787 /*
1788  *      Initialize IP Virtual Server
1789  */
1790 static int __init ip_vs_init(void)
1791 {
1792         int ret;
1793
1794         ip_vs_estimator_init();
1795
1796         ret = ip_vs_control_init();
1797         if (ret < 0) {
1798                 pr_err("can't setup control.\n");
1799                 goto cleanup_estimator;
1800         }
1801
1802         ip_vs_protocol_init();
1803
1804         ret = ip_vs_app_init();
1805         if (ret < 0) {
1806                 pr_err("can't setup application helper.\n");
1807                 goto cleanup_protocol;
1808         }
1809
1810         ret = ip_vs_conn_init();
1811         if (ret < 0) {
1812                 pr_err("can't setup connection table.\n");
1813                 goto cleanup_app;
1814         }
1815
1816         ret = nf_register_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
1817         if (ret < 0) {
1818                 pr_err("can't register hooks.\n");
1819                 goto cleanup_conn;
1820         }
1821
1822         pr_info("ipvs loaded.\n");
1823         return ret;
1824
1825   cleanup_conn:
1826         ip_vs_conn_cleanup();
1827   cleanup_app:
1828         ip_vs_app_cleanup();
1829   cleanup_protocol:
1830         ip_vs_protocol_cleanup();
1831         ip_vs_control_cleanup();
1832   cleanup_estimator:
1833         ip_vs_estimator_cleanup();
1834         return ret;
1835 }
1836
1837 static void __exit ip_vs_cleanup(void)
1838 {
1839         nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
1840         ip_vs_conn_cleanup();
1841         ip_vs_app_cleanup();
1842         ip_vs_protocol_cleanup();
1843         ip_vs_control_cleanup();
1844         ip_vs_estimator_cleanup();
1845         pr_info("ipvs unloaded.\n");
1846 }
1847
1848 module_init(ip_vs_init);
1849 module_exit(ip_vs_cleanup);
1850 MODULE_LICENSE("GPL");