summaryrefslogtreecommitdiffstats
path: root/sbin/natd
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2000-04-27 17:55:17 +0000
committerru <ru@FreeBSD.org>2000-04-27 17:55:17 +0000
commitb3e08f68b86b8fdfc12ed867172fdb8a3887efcc (patch)
tree586556fc58f922a1d2594f516586e5333074304b /sbin/natd
parentc6bc2e1ae7d131ca52907b6e59844fce4651fbb4 (diff)
downloadFreeBSD-src-b3e08f68b86b8fdfc12ed867172fdb8a3887efcc.zip
FreeBSD-src-b3e08f68b86b8fdfc12ed867172fdb8a3887efcc.tar.gz
Load Sharing using IP Network Address Translation (RFC 2391, LSNAT).
Diffstat (limited to 'sbin/natd')
-rw-r--r--sbin/natd/natd.842
-rw-r--r--sbin/natd/natd.c82
2 files changed, 106 insertions, 18 deletions
diff --git a/sbin/natd/natd.8 b/sbin/natd/natd.8
index fbdbb97..1feabd1 100644
--- a/sbin/natd/natd.8
+++ b/sbin/natd/natd.8
@@ -35,7 +35,7 @@ Network Address Translation Daemon
.Op Fl interface Ar interface
.Op Fl config Ar configfile
.Op Fl redirect_port Ar linkspec
-.Op Fl redirect_address Ar localIP publicIP
+.Op Fl redirect_address Ar linkspec
.Op Fl reverse
.Op Fl proxy_only
.Op Fl proxy_rule Ar proxyspec
@@ -163,7 +163,45 @@ the incoming traffic will be directed to the last
translated local address (192.168.0.4), but outgoing
traffic to the first two addresses will still be aliased
to specified public address.
-
+.It Fl redirect_port Ar proto Xo
+.Ar targetIP Ns : Ns Xo
+.Ar targetPORT Ns Oo , Ns
+.Ar targetIP Ns : Ns Xo
+.Ar targetPORT Ns Oo , Ns
+.Ar ...
+.Oc Oc
+.Xc
+.Xc
+.Op Ar aliasIP Ns : Ns Xo
+.Ar aliasPORT
+.Xc
+.Oo Ar remoteIP Ns
+.Op : Ns Ar remotePORT
+.Oc
+.Xc
+.It Fl redirect_address Xo
+.Ar localIP Ns Oo , Ns
+.Ar localIP Ns Oo , Ns
+.Ar ...
+.Oc Oc
+.Ar publicIP
+.Xc
+These forms of
+.Fl redirect_port
+and
+.Fl redirect_address
+are used to transparently offload network load on a single server and
+distribute the load across a pool of servers.
+This function is known as
+.Em LSNAT
+(RFC 2391).
+For example, the argument
+.Pp
+.Dl Ar tcp www1:http,www2:http,www3:http www:http
+.Pp
+means that incoming HTTP requests for host www will be transparently
+redirected to one of the www1, www2 or www3, where a host is selected
+simply on a round-robin basis, without regard to load on the net.
.It Fl dynamic
If the
.Fl n
diff --git a/sbin/natd/natd.c b/sbin/natd/natd.c
index 6bc4c5d..2714a15 100644
--- a/sbin/natd/natd.c
+++ b/sbin/natd/natd.c
@@ -1021,7 +1021,7 @@ static struct OptionInfo optionTable[] = {
{ RedirectPort,
0,
String,
- "tcp|udp local_addr:local_port_range [public_addr:]public_port_range"
+ "tcp|udp local_addr:local_port_range[,...] [public_addr:]public_port_range"
" [remote_addr[:remote_port_range]]",
"redirect a port (or ports) for incoming traffic",
"redirect_port",
@@ -1030,7 +1030,7 @@ static struct OptionInfo optionTable[] = {
{ RedirectAddress,
0,
String,
- "local_addr public_addr",
+ "local_addr[,...] public_addr",
"define mapping between local and public addresses",
"redirect_address",
NULL },
@@ -1348,6 +1348,7 @@ void SetupPortRedirect (const char* parms)
{
char buf[128];
char* ptr;
+ char* serverPool;
struct in_addr localAddr;
struct in_addr publicAddr;
struct in_addr remoteAddr;
@@ -1362,6 +1363,7 @@ void SetupPortRedirect (const char* parms)
char* protoName;
char* separator;
int i;
+ struct alias_link *link = NULL;
strcpy (buf, parms);
/*
@@ -1379,11 +1381,20 @@ void SetupPortRedirect (const char* parms)
if (!ptr)
errx (1, "redirect_port: missing local address");
- if ( StrToAddrAndPortRange (ptr, &localAddr, protoName, &portRange) != 0 )
- errx (1, "redirect_port: invalid local port range");
-
- localPort = GETLOPORT(portRange);
- numLocalPorts = GETNUMPORTS(portRange);
+ separator = strchr(ptr, ',');
+ if (separator) { /* LSNAT redirection syntax. */
+ localAddr.s_addr = INADDR_NONE;
+ localPort = ~0;
+ numLocalPorts = 1;
+ serverPool = ptr;
+ } else {
+ if ( StrToAddrAndPortRange (ptr, &localAddr, protoName, &portRange) != 0 )
+ errx (1, "redirect_port: invalid local port range");
+
+ localPort = GETLOPORT(portRange);
+ numLocalPorts = GETNUMPORTS(portRange);
+ serverPool = NULL;
+ }
/*
* Extract public port and optionally address.
@@ -1446,13 +1457,30 @@ void SetupPortRedirect (const char* parms)
if (numRemotePorts == 1 && remotePort == 0)
remotePortCopy = 0;
- PacketAliasRedirectPort (localAddr,
- htons(localPort + i),
- remoteAddr,
- htons(remotePortCopy),
- publicAddr,
- htons(publicPort + i),
- proto);
+ link = PacketAliasRedirectPort (localAddr,
+ htons(localPort + i),
+ remoteAddr,
+ htons(remotePortCopy),
+ publicAddr,
+ htons(publicPort + i),
+ proto);
+ }
+
+/*
+ * Setup LSNAT server pool.
+ */
+ if (serverPool != NULL && link != NULL) {
+ ptr = strtok(serverPool, ",");
+ while (ptr != NULL) {
+ if (StrToAddrAndPortRange(ptr, &localAddr, protoName, &portRange) != 0)
+ errx(1, "redirect_port: invalid local port range");
+
+ localPort = GETLOPORT(portRange);
+ if (GETNUMPORTS(portRange) != 1)
+ errx(1, "redirect_port: local port must be single in this context");
+ PacketAliasAddServer(link, localAddr, htons(localPort));
+ ptr = strtok(NULL, ",");
+ }
}
}
@@ -1460,8 +1488,11 @@ void SetupAddressRedirect (const char* parms)
{
char buf[128];
char* ptr;
+ char* separator;
struct in_addr localAddr;
struct in_addr publicAddr;
+ char* serverPool;
+ struct alias_link *link;
strcpy (buf, parms);
/*
@@ -1471,7 +1502,14 @@ void SetupAddressRedirect (const char* parms)
if (!ptr)
errx (1, "redirect_address: missing local address");
- StrToAddr (ptr, &localAddr);
+ separator = strchr(ptr, ',');
+ if (separator) { /* LSNAT redirection syntax. */
+ localAddr.s_addr = INADDR_NONE;
+ serverPool = ptr;
+ } else {
+ StrToAddr (ptr, &localAddr);
+ serverPool = NULL;
+ }
/*
* Extract public address.
*/
@@ -1480,7 +1518,19 @@ void SetupAddressRedirect (const char* parms)
errx (1, "redirect_address: missing public address");
StrToAddr (ptr, &publicAddr);
- PacketAliasRedirectAddr (localAddr, publicAddr);
+ link = PacketAliasRedirectAddr(localAddr, publicAddr);
+
+/*
+ * Setup LSNAT server pool.
+ */
+ if (serverPool != NULL && link != NULL) {
+ ptr = strtok(serverPool, ",");
+ while (ptr != NULL) {
+ StrToAddr(ptr, &localAddr);
+ PacketAliasAddServer(link, localAddr, htons(~0));
+ ptr = strtok(NULL, ",");
+ }
+ }
}
void StrToAddr (const char* str, struct in_addr* addr)
OpenPOWER on IntegriCloud