diff -u --new-file --recursive linux/include/linux/ip_masq.h linux.devel/include/linux/ip_masq.h --- linux/include/linux/ip_masq.h Wed Oct 13 15:24:48 1999 +++ linux.devel/include/linux/ip_masq.h Wed Oct 13 12:33:12 1999 @@ -113,6 +113,7 @@ u_int16_t vport; unsigned vs_flags; /* virtual service flags */ unsigned timeout; /* persistent timeout in ticks */ + u_int32_t netmask; /* persistent netmask */ /* destination specific options */ u_int32_t daddr; /* real destination address */ diff -u --new-file --recursive linux/include/net/ip_vs.h linux.devel/include/net/ip_vs.h --- linux/include/net/ip_vs.h Wed Oct 13 15:24:48 1999 +++ linux.devel/include/net/ip_vs.h Wed Oct 13 12:40:41 1999 @@ -58,6 +58,7 @@ __u16 protocol; /* which protocol (TCP/UDP) */ unsigned flags; /* service status flags */ unsigned timeout; /* persistent timeout in ticks */ + __u32 netmask; /* grouping granularity */ struct list_head destinations; /* real server d-linked list */ struct ip_vs_scheduler *scheduler; /* bound scheduler object */ void *sched_data; /* scheduler application data */ diff -u --new-file --recursive linux/ipvs-0.9.1-2.2.12/CREDITS linux.devel/ipvs-0.9.1-2.2.12/CREDITS --- linux/ipvs-0.9.1-2.2.12/CREDITS Wed Oct 6 17:03:13 1999 +++ linux.devel/ipvs-0.9.1-2.2.12/CREDITS Wed Oct 13 15:36:15 1999 @@ -25,8 +25,9 @@ Gave a talk about Linux Virtual Server in the LinuxExpo'99. Lars Marowsky-Bree - Hosting the www.LinuxVirtualServer.org site. - Gave a talk about Linux Virtual Server in Linux Kongress'99 + Hosting the http://www.LinuxVirtualServer.org/ site. + Gave a talk about Linux Virtual Server at Linux Kongress'99 + Added netmask support to ipvs. Rob Thomas Wrote the the "Greased Turkey" document about how to setup a diff -u --new-file --recursive linux/ipvs-0.9.1-2.2.12/ChangeLog linux.devel/ipvs-0.9.1-2.2.12/ChangeLog --- linux/ipvs-0.9.1-2.2.12/ChangeLog Wed Oct 6 17:33:09 1999 +++ linux.devel/ipvs-0.9.1-2.2.12/ChangeLog Wed Oct 13 15:35:02 1999 @@ -1,5 +1,15 @@ ChangeLog of Virtual Server patch for Linux 2.2 +Virtual Server patch for Linux 2.2 - Version 0.9.2 - October 13, 1999 + +Changes: + * Added support for netmasks with persistence + The client source address is masked with this netmask for the purpose + of accessing the templates. Added a new port to the service structure + and changed ipvsadm to support this. Defaults to a 255.255.255.255, + which emulates the old behaviour. (Lars Marowsky-Bree ) + + Virtual Server patch for Linux 2.2 - Version 0.9.1 - October 6, 1999 Changes: diff -u --new-file --recursive linux/ipvs-0.9.1-2.2.12/README linux.devel/ipvs-0.9.1-2.2.12/README --- linux/ipvs-0.9.1-2.2.12/README Wed Oct 6 12:33:40 1999 +++ linux.devel/ipvs-0.9.1-2.2.12/README Wed Oct 13 15:37:05 1999 @@ -1,7 +1,7 @@ README of IP Virtual Server Patch for Linux 2.2.12 ----------------------------------------------------------------------- -Virtual Server Patch for Linux 2.2.12 - Version 0.9.1 - October 6, 1999 +Virtual Server Patch for Linux 2.2.12 - Version 0.9.2 - October 13, 1999 Copyright (c) 1998,1999 by Wensong Zhang, Peter Kese. This is free software. See below for details. @@ -14,17 +14,17 @@ http://www.linux-vs.org/ for the most recent information and original sources about IPVS. -We now call the Linux box running ipvs LinuxDirector. Thank +We now call the Linux box running ipvs LinuxVirtualServer. Thank Robert Thomas for this name, I love it. :-) -This patch (Version 0.9.1) is for the Linux kernel 2.2.12. See the ChangeLog +This patch (Version 0.9.2) is for the Linux kernel 2.2.12. See the ChangeLog for how the code has been improved and what new features it has now. To rebuild a Linux kernel with virtual server support, first get a clean copy of the Linux kernel source of the right version and apply the patch to the kernel. The commands can be as follows: cd /usr/src/linux - cat /ipvs-0.9.1-2.2.12.patch | patch -p1 + cat /ipvs-0.9.2-2.2.12.patch | patch -p1 Then make sure the following kernel compile options at least are selected via "make menuconfig" or "make xconfig". diff -u --new-file --recursive linux/ipvs-0.9.1-2.2.12/ipvsadm-1.4/Makefile linux.devel/ipvs-0.9.1-2.2.12/ipvsadm-1.4/Makefile --- linux/ipvs-0.9.1-2.2.12/ipvsadm-1.4/Makefile Wed Oct 13 15:24:50 1999 +++ linux.devel/ipvs-0.9.1-2.2.12/ipvsadm-1.4/Makefile Wed Oct 13 12:28:51 1999 @@ -3,7 +3,7 @@ SBIN = /sbin MAN = /usr/man/man8 INSTALL = install -INCLUDE = -I$(RPM_BUILD_DIR)/linux/include +INCLUDE = -I/usr/src/redhat/BUILD/linux/include all: ipvsadm diff -u --new-file --recursive linux/ipvs-0.9.1-2.2.12/ipvsadm-1.4/ipvsadm.8 linux.devel/ipvs-0.9.1-2.2.12/ipvsadm-1.4/ipvsadm.8 --- linux/ipvs-0.9.1-2.2.12/ipvsadm-1.4/ipvsadm.8 Tue Oct 5 16:12:15 1999 +++ linux.devel/ipvs-0.9.1-2.2.12/ipvsadm-1.4/ipvsadm.8 Wed Oct 13 15:31:46 1999 @@ -23,6 +23,8 @@ .B ipvsadm -[A|E] -[t|u] \fIservice-address\fP [-s \fIscheduler\fP] .ti 15 .B [-p [\fItimeout\fP]] +.ti 15 +.B [-M [\fInetmask\fP]] .br .B ipvsadm -D -[t|u] \fIservice-address\fP .br @@ -125,6 +127,13 @@ request). The \fItimeout\fP of persistent sessions can be specified by the values in seconds, the default is 300 seconds. Use this option to solve problems with cookies, SSL, or FTP with tunneling or direct routing. +.TP +.B -M, --netmask \fInetmask\fP +For persistent ports, allows you to specify the granularity at which the +clients are grouped. The source address of the request is masked with this +netmask to, for example, direct all clients from a /24 network to the same +real server. The default is \fI255.255.255.255\fP. Use this option to solve +problems with non-persistent cache clusters on the client side. .TP .B -r, --real-server \fIserver-address\fP Real server that an associated request for service may be assigned to. diff -u --new-file --recursive linux/ipvs-0.9.1-2.2.12/ipvsadm-1.4/ipvsadm.c linux.devel/ipvs-0.9.1-2.2.12/ipvsadm-1.4/ipvsadm.c --- linux/ipvs-0.9.1-2.2.12/ipvsadm-1.4/ipvsadm.c Tue Oct 5 16:14:58 1999 +++ linux.devel/ipvs-0.9.1-2.2.12/ipvsadm-1.4/ipvsadm.c Wed Oct 13 15:26:02 1999 @@ -20,6 +20,7 @@ * Wensong Zhang : added the long options * Wensong Zhang : added the hostname and portname input * Wensong Zhang : added the hostname and portname output + * Lars Marowsky-Brée : added netmask support * * ippfvsadm - Port Fowarding & Virtual Server ADMinistration program * @@ -92,6 +93,7 @@ char * port_to_service(int port, unsigned short proto); int parse_service(char *buf, u_int16_t proto, u_int32_t *addr, u_int16_t *port); +int parse_netmask(char *buf, u_int32_t *addr); int parse_timeout(char *buf, unsigned *timeout); void usage_exit(char *program); @@ -116,6 +118,7 @@ {"persistent", 2, 0, 'p'}, {"real-server", 1, 0, 'r'}, {"masquerading", 0, 0, 'm'}, + {"netmask", 0, 0, 'M'}, {"ipip", 0, 0, 'i'}, {"gatewaying", 0, 0, 'g'}, {"weight", 1, 0, 'w'}, @@ -158,12 +161,12 @@ case 'A': mc.m_cmd = IP_MASQ_CMD_ADD; mc.m_target = IP_MASQ_TARGET_VS; - optstr = "t:u:s:p::"; + optstr = "t:u:s:M:p::"; break; case 'E': mc.m_cmd = IP_MASQ_CMD_SET; mc.m_target = IP_MASQ_TARGET_VS; - optstr = "t:u:s:p::"; + optstr = "t:u:s:M:p::"; break; case 'D': mc.m_cmd = IP_MASQ_CMD_DEL; @@ -204,7 +207,9 @@ * Set direct routing as default forwarding method */ mc.u.vs_user.masq_flags = IP_MASQ_F_VS_DROUTE; - + /* Default to /32 masking */ + mc.u.vs_user.netmask = ((unsigned long int) 0xffffffff); + while ((c=getopt_long(argc, argv, optstr, long_options, NULL)) != EOF) { switch (c) { @@ -221,6 +226,12 @@ if (parse != 2) fail(2, "illegal virtual server " "address:port specified"); break; + case 'M': + parse = parse_netmask(optarg, + &mc.u.vs_user.netmask); + if (parse != 1) fail(2, "illegal virtual server " + "mask specified"); + break; case 's': if (strlen(mc.m_tname) != 0) fail(2, "multiple scheduling modules specified"); @@ -380,6 +391,25 @@ /* + * Get netmask. + * Return 0 if failed, + * 1 if addr read + */ +int parse_netmask(char *buf, u_int32_t *addr) +{ + struct in_addr inaddr; + + if (inet_aton(buf, &inaddr) != 0) + *addr = inaddr.s_addr; + else if (host_to_addr(buf, &inaddr) != -1) + *addr = inaddr.s_addr; + else + return 0; + + return 1; +} + +/* * Get IP address and port from the argument. * Return 0 if failed, * 1 if addr read @@ -438,8 +468,8 @@ void usage_exit(char *program) { - printf("ipvsadm v1.4 1999/10/5\n" - "Usage: %s -[A|E] -[t|u] service-address [-s scheduler] [-p [timeout]]\n" + printf("ipvsadm v1.5 1999/10/13\n" + "Usage: %s -[A|E] -[t|u] service-address [-s scheduler] [-p [timeout]] [-M [netmask]]\n" " %s -D -[t|u] service-address\n" " %s -C\n" " %s -[a|e] -[t|u] service-address -r server-address [options]\n" @@ -464,6 +494,7 @@ " --scheduler -s It can be rr|wrr|lc|wlc,\n" " the default scheduler is %s.\n" " --persistent -p [timeout] persistent port\n" + " --netmask -M [netmask] granularity mask\n" " --real-server -r server-address server-address is host (and port)\n" " --masquerading -m masquerading (NAT)\n" " --ipip -i ipip encapsulation (tunneling)\n" @@ -528,9 +559,10 @@ /* virtual service variables */ static char protocol[20]; struct in_addr laddr; + struct in_addr lmask; unsigned short lport; static char scheduler[10]; - static char flags[20]; + static char flags[40]; unsigned int timeout; /* destination variables */ @@ -544,7 +576,8 @@ int n; unsigned long temp; - + unsigned long temp2; + if (buf[0] == ' ') { /* destination entry */ if ((n = sscanf(buf, " %s %lX:%hX %s %d %d %d", @@ -567,13 +600,14 @@ tmpbuf, fwd, weight, activeconns, inactconns); } else { /* virtual service entry */ - if ((n = sscanf(buf, "%s %lX:%hX %s %s %d", protocol, &temp, - &lport, scheduler, flags, &timeout)) == -1) + if ((n = sscanf(buf, "%s %lX:%hX %s %s %d %lX", protocol, &temp, + &lport, scheduler, flags, &timeout, &temp2)) == -1) exit(1); - if (n!=6 && n!=4) + if (n!=7 && n!=4) fail(2, "unexpected input data"); laddr.s_addr = (__u32) htonl(temp); + lmask.s_addr = (__u32) htonl(temp2); if (strcmp(protocol, "TCP") == 0) proto = IPPROTO_TCP; else if (strcmp(protocol, "UDP") == 0) proto = IPPROTO_UDP; else proto = 0; @@ -589,7 +623,7 @@ if (n == 4) printf("\n"); else - printf(" %s %d\n", flags, timeout/HZ); + printf(" %s %d mask: %s\n", flags, timeout/HZ, inet_ntoa(lmask)); } } diff -u --new-file --recursive linux/net/ipv4/ip_vs.c linux.devel/net/ipv4/ip_vs.c --- linux/net/ipv4/ip_vs.c Wed Oct 13 15:24:48 1999 +++ linux.devel/net/ipv4/ip_vs.c Wed Oct 13 14:54:14 1999 @@ -1140,6 +1140,8 @@ svc->protocol = protocol; svc->flags = mm->vs_flags; svc->timeout = mm->timeout; + svc->netmask = mm->netmask; + INIT_LIST_HEAD(&svc->destinations); /* @@ -1183,7 +1185,8 @@ */ svc->flags = mm->vs_flags | IP_VS_SVC_F_HASHED; svc->timeout = mm->timeout; - + svc->netmask = mm->netmask; + /* * Unbind the old scheduler */ @@ -1413,12 +1416,17 @@ const __u16 *portp; struct ip_masq *mst; __u16 dport; /* destination port to forward */ - + __u32 snet; /* Source network of the request, after masking */ + portp = (__u16 *)&(((char *)iph)[iph->ihl*4]); - IP_VS_DBG("P-schedule: src %08lX:%04X dest %08lX:%04X", + /* Mask saddr with the netmask to adjust template granularity */ + snet = iph->saddr & svc->netmask; + + IP_VS_DBG("P-schedule: src %08lX:%04X dest %08lX:%04X masked net: %08lX", ntohl(iph->saddr), ntohs(portp[0]), - ntohl(iph->daddr), ntohs(portp[1])); + ntohl(iph->daddr), ntohs(portp[1]), + ntohl(snet)); /* * As far as we know, FTP is a very complicated network protocol, and @@ -1434,14 +1442,16 @@ * is created for other persistent services. */ if (portp[1] == svc->port) { + /* Check if a template already exists */ if (svc->port != ftpport) - mst = ip_vs_in_get(iph->protocol, iph->saddr, 0, + mst = ip_vs_in_get(iph->protocol, snet, 0, iph->daddr, portp[1]); else - mst = ip_vs_in_get(iph->protocol, iph->saddr, 0, + mst = ip_vs_in_get(iph->protocol, snet, 0, iph->daddr, 0); if (mst == NULL) { + /* No template found */ read_lock(&__ip_vs_lock); dest = svc->scheduler->schedule(svc); @@ -1458,13 +1468,13 @@ mst = ip_masq_new_vs(svc->protocol, svc->addr, svc->port, dest->addr, dest->port, - iph->saddr, 0, + snet, 0, 0); else mst = ip_masq_new_vs(svc->protocol, svc->addr, 0, dest->addr, 0, - iph->saddr, 0, + snet, 0, 0); if (mst == NULL) { @@ -1485,6 +1495,7 @@ read_unlock(&__ip_vs_lock); } else { + /* Template found */ dest = mst->dest; /* * Checking the dest server status. @@ -1500,7 +1511,7 @@ IP_VS_DBG("destination is not available for " "%d src %08lX:%04X dest %08lX:%04X " "-> %08lX:%04X\n", iph->protocol, - ntohl(iph->saddr), ntohs(portp[0]), + ntohl(snet), ntohs(portp[0]), ntohl(iph->daddr), ntohs(portp[1]), (dest!=NULL)? ntohl(dest->addr):0, (dest!=NULL)? ntohs(dest->port):0); @@ -1515,12 +1526,12 @@ dport = dest->port; } else { - mst = ip_vs_in_get(iph->protocol, iph->saddr, 0, + mst = ip_vs_in_get(iph->protocol, snet, 0, iph->daddr, 0); if (mst == NULL) { IP_VS_DBG("no catch-all template found for %d src " "%08lX:%04X dest %08lX:%04X", iph->protocol, - ntohl(iph->saddr), ntohs(portp[0]), + ntohl(snet), ntohs(portp[0]), ntohl(iph->daddr), ntohs(portp[1])); return NULL; } @@ -1540,7 +1551,7 @@ IP_VS_DBG("destination is not available for " "%d src %08lX:%04X dest %08lX:%04X " "-> %08lX:%04X\n", iph->protocol, - ntohl(iph->saddr), ntohs(portp[0]), + ntohl(snet), ntohs(portp[0]), ntohl(iph->daddr), ntohs(portp[1]), (dest!=NULL)? ntohl(dest->addr):0, (dest!=NULL)? ntohs(dest->port):0); @@ -1777,8 +1788,8 @@ struct list_head *l, *e, *p, *q; size = sprintf(buf+len, - "IP Virtual Server version 0.9.1 (size=%d)\n" - "Prot LocalAddress:Port Scheduler Flags\n" + "IP Virtual Server version 0.9.2 (size=%d)\n" + "Prot LocalAddress:Port Scheduler Flags Netmask\n" " -> RemoteAddress:Port Forward Weight ActiveConn InActConn\n", IP_VS_TAB_SIZE); pos += size; @@ -1798,8 +1809,9 @@ pos += size; if (svc->flags & IP_VS_SVC_F_PERSISTENT) - size = sprintf(buf+len, " persistent %d\n", - svc->timeout); + size = sprintf(buf+len, " persistent %d %08lX\n", + svc->timeout, + ntohl(svc->netmask)); else size = sprintf(buf+len, "\n");