From owner-freebsd-net Tue Jun 4 16:50:25 2002 Delivered-To: freebsd-net@freebsd.org Received: from inje.iskon.hr (inje.iskon.hr [213.191.128.16]) by hub.freebsd.org (Postfix) with ESMTP id 3AC4037B405 for ; Tue, 4 Jun 2002 16:49:41 -0700 (PDT) Received: from tel.fer.hr (zg07-088.dialin.iskon.hr [213.191.150.89]) by mail.iskon.hr (8.11.4/8.11.4/Iskon 8.11.3-1) with ESMTP id g54NnWj28744 for ; Wed, 5 Jun 2002 01:49:34 +0200 (MEST) Message-ID: <3CFD51EC.AD9D7192@tel.fer.hr> Date: Wed, 05 Jun 2002 01:49:01 +0200 From: Marko Zec X-Mailer: Mozilla 4.78 [en] (Windows NT 5.0; U) X-Accept-Language: en MIME-Version: 1.0 To: freebsd-net@freebsd.org Subject: Patch for review: source VIPA Content-Type: multipart/mixed; boundary="------------2FB848ED7893B437F014C895" Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org This is a multi-part message in MIME format. --------------2FB848ED7893B437F014C895 Content-Type: text/plain; charset=iso-8859-2 Content-Transfer-Encoding: 7bit Bellow is a patch that enables all outgoing sessions to always use the same source IP address by default, no matter what outbound interface is used. If on a multi-homed host the source IP address always originates from an "always-up" internal virtual interface, than the established TCP sessions won't break in case of failure of one of the physical interfaces, or similar serious network topology changes. The idea is not new, as far as I know it was introduced a couple of years ago in OS/390 V2R5 TCP/IP implementation, if not earlier. IBM called this feature "Virtual IP Address - VIPA", so just for fun I also borrowed the name along with the idea... Anyway, after applying the patch (against 4.6-RC3 kernel source), a new sysctl variable net.inet.ip.sourcevipa becomes available, which can be set to an existing IP address of desired internal interface. Although any interface can be used for source-VIPA feature, the patch also provides a new interface type "vipa", which is nothing else than a standard loopback ifc, but without the loopback flag set, so that it can be conveniently advertised via the routed daemon. The following line should be added to your kernel config file in order to make the vipa ifc available: pseudo-device vipa 1 Here is an configuration example: vmbsd# routed vmbsd# ifconfig lnc0: flags=8843 mtu 1500 inet 192.168.201.143 netmask 0xffffff00 broadcast 192.168.201.255 ether 00:50:56:ac:c9:7a lnc1: flags=8843 mtu 1500 inet 192.168.202.143 netmask 0xffffff00 broadcast 192.168.202.255 ether 00:50:56:ac:c9:8c lo0: flags=8049 mtu 16384 inet 127.0.0.1 netmask 0xff000000 vipa0: flags=61 mtu 1500 inet 192.168.1.1 netmask 0xffffffff vmbsd# sysctl net.inet.ip.sourcevipa net.inet.ip.sourcevipa: none vmbsd# sysctl net.inet.ip.sourcevipa=192.168.1.1 net.inet.ip.sourcevipa: none -> 192.168.1.1 vmbsd# vmbsd# telnet 192.168.201.10 [cut] %who am i marko ttyp2 Jun 5 01:37 (192.168.1.1) Have fun! --------------2FB848ED7893B437F014C895 Content-Type: text/plain; charset=iso-8859-2; name="vipa.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="vipa.diff" --- netinet/in_pcb.c Thu May 2 04:36:50 2002 +++ netinet/in_pcb.c.vipa Wed Jun 5 00:14:19 2002 @@ -122,6 +122,50 @@ SYSCTL_PROC(_net_inet_ip_portrange, OID_ SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hilast, CTLTYPE_INT|CTLFLAG_RW, &ipport_hilastauto, 0, &sysctl_net_ipport_check, "I", ""); + +static char sourcevipastr[16] = "none"; +static u_long sourcevipa=0; + +static int +sourcevipa_sysctl(SYSCTL_HANDLER_ARGS) +{ + int error; + u_char i,j; + u_long addr=0; + char *c; + + error = sysctl_handle_string(oidp, + oidp->oid_arg1, oidp->oid_arg2, req); + if (error) + return error; + c=sourcevipastr; + for (i=0;i<4;i++) { + j=0; + while (*c>='0'&&*c<='9') { + j*=10; + j+=*c-'0'; + c++; + } + if (*c!=0) + c++; + addr=(addr<<8)+j; + } + sourcevipa=addr; + if (addr) { + unsigned char *ucp=(u_char *)&addr; + sprintf(sourcevipastr, "%d.%d.%d.%d", + ucp[0], ucp[1], ucp[2], ucp[3]); + } else { + sprintf(sourcevipastr, "none"); + } + return 0; +} + +SYSCTL_PROC(_net_inet_ip, OID_AUTO, sourcevipa, CTLTYPE_STRING|CTLFLAG_RW, + sourcevipastr, sizeof(sourcevipastr), &sourcevipa_sysctl, "A", + "Always try to use this IP address as source"); + + /* * in_pcb.c: manage the Protocol Control Blocks. * @@ -438,7 +482,25 @@ in_pcbladdr(inp, nam, plocal_sin) * to our address on another net goes to loopback). */ if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) - ia = ifatoia(ro->ro_rt->rt_ifa); + { + /* + * Use source VIPA, if available + * M. Zec (zec@tel.fer.hr) 2002/06/24 + */ + if (sourcevipa) { + u_long addr = sin->sin_addr.s_addr; + u_short fport = sin->sin_port; + + sin->sin_addr.s_addr = htonl(sourcevipa); + sin->sin_port = 0; + ia = ifatoia(ifa_ifwithaddr(sintosa(sin))); + sin->sin_addr.s_addr = addr; + sin->sin_port = fport; + } + + if (ia == 0) + ia = ifatoia(ro->ro_rt->rt_ifa); + } if (ia == 0) { u_short fport = sin->sin_port; --- net/if_loop.c Thu Dec 20 11:30:16 2001 +++ net/if_loop.c.vipa Wed Jun 5 00:16:40 2002 @@ -38,6 +38,7 @@ * Loopback interface driver for protocol testing and timing. */ #include "loop.h" +#include "vipa.h" #include "opt_atalk.h" #include "opt_inet.h" @@ -53,6 +54,7 @@ #include #include +#include #include #include #include @@ -103,7 +105,7 @@ int looutput __P((struct ifnet *ifp, #define LOMTU 16384 #endif -struct ifnet loif[NLOOP]; +struct ifnet loif[NLOOP+NVIPA]; /* ARGSUSED */ static void @@ -113,11 +115,18 @@ loopattach(dummy) register struct ifnet *ifp; register int i = 0; - for (ifp = loif; i < NLOOP; ifp++) { - ifp->if_name = "lo"; - ifp->if_unit = i++; - ifp->if_mtu = LOMTU; - ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; + for (ifp = loif; i < NLOOP+NVIPA; ifp++) { + if (iif_name = "lo"; + ifp->if_unit = i++; + ifp->if_mtu = LOMTU; + ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST; + } else { + ifp->if_name = "vipa"; + ifp->if_unit = i++ - NLOOP; + ifp->if_mtu = ETHERMTU; + ifp->if_flags = IFF_SMART; /* joke! */ + } ifp->if_ioctl = loioctl; ifp->if_output = looutput; ifp->if_type = IFT_LOOP; --- conf/files Sat May 4 10:48:53 2002 +++ conf/files.vipa Tue Jun 4 23:56:15 2002 @@ -698,6 +698,7 @@ net/if_faith.c optional faith net/if_fddisubr.c optional fddi net/if_gif.c optional gif net/if_loop.c optional loop +net/if_loop.c optional vipa net/if_media.c standard net/if_mib.c standard net/if_ppp.c optional ppp --- i386/conf/LINT Wed Jun 5 00:20:55 2002 +++ i386/conf/LINT.vipa Wed Jun 5 00:19:59 2002 @@ -525,6 +525,8 @@ options ETHER_8023 # enable Ethernet_8 options ETHER_8022 # enable Ethernet_802.2 frame options ETHER_SNAP # enable Ethernet_802.2/SNAP frame +pseudo-device vipa 1 # Virtual IP Address (routable loopback) + # for IPv6 pseudo-device gif #IPv6 and IPv4 tunneling pseudo-device faith 1 #for IPv6 and IPv4 translation --------------2FB848ED7893B437F014C895-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message