summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libalias/alias.h5
-rw-r--r--lib/libalias/alias_db.c112
-rw-r--r--lib/libalias/libalias.360
-rw-r--r--sys/netinet/libalias/alias.h5
-rw-r--r--sys/netinet/libalias/alias_db.c112
-rw-r--r--sys/netinet/libalias/libalias.360
6 files changed, 300 insertions, 54 deletions
diff --git a/lib/libalias/alias.h b/lib/libalias/alias.h
index 2285d97..9f15579 100644
--- a/lib/libalias/alias.h
+++ b/lib/libalias/alias.h
@@ -52,6 +52,11 @@ struct alias_link;
u_char);
extern int
+ PacketAliasAddServer(struct alias_link *link,
+ struct in_addr addr,
+ u_short port);
+
+ extern int
PacketAliasPptp(struct in_addr);
extern struct alias_link *
diff --git a/lib/libalias/alias_db.c b/lib/libalias/alias_db.c
index 431a757..bc020f3 100644
--- a/lib/libalias/alias_db.c
+++ b/lib/libalias/alias_db.c
@@ -237,6 +237,13 @@ struct tcp_dat
int fwhole; /* Which firewall record is used for this hole? */
};
+struct server /* LSNAT server pool (circular list) */
+{
+ struct in_addr addr;
+ u_short port;
+ struct server *next;
+};
+
struct alias_link /* Main data structure */
{
struct in_addr src_addr; /* Address and port information */
@@ -247,6 +254,7 @@ struct alias_link /* Main data structure */
u_short dst_port;
u_short alias_port;
u_short proxy_port;
+ struct server *server;
int link_type; /* Type of link: TCP, UDP, ICMP, PPTP, frag */
@@ -778,6 +786,17 @@ DeleteLink(struct alias_link *link)
ClearFWHole(link);
#endif
+/* Free memory allocated for LSNAT server pool */
+ if (link->server != NULL) {
+ struct server *head, *curr, *next;
+
+ head = curr = link->server;
+ do {
+ next = curr->next;
+ free(curr);
+ } while ((curr = next) != head);
+ }
+
/* Adjust output table pointers */
link_last = link->last_out;
link_next = link->next_out;
@@ -871,6 +890,7 @@ AddLink(struct in_addr src_addr,
link->src_port = src_port;
link->dst_port = dst_port;
link->proxy_port = 0;
+ link->server = NULL;
link->link_type = link_type;
link->sockfd = -1;
link->flags = 0;
@@ -1044,6 +1064,7 @@ _FindLinkOut(struct in_addr src_addr,
while (link != NULL)
{
if (link->src_addr.s_addr == src_addr.s_addr
+ && link->server == NULL
&& link->dst_addr.s_addr == dst_addr.s_addr
&& link->dst_port == dst_port
&& link->src_port == src_port
@@ -1207,39 +1228,39 @@ _FindLinkIn(struct in_addr dst_addr,
if (link_fully_specified != NULL)
{
link_fully_specified->timestamp = timeStamp;
- return link_fully_specified;
+ link = link_fully_specified;
}
else if (link_unknown_dst_port != NULL)
- {
- return replace_partial_links
- ? ReLink(link_unknown_dst_port,
- link_unknown_dst_port->src_addr, dst_addr, alias_addr,
- link_unknown_dst_port->src_port, dst_port, alias_port,
- link_type)
- : link_unknown_dst_port;
- }
+ link = link_unknown_dst_port;
else if (link_unknown_dst_addr != NULL)
- {
- return replace_partial_links
- ? ReLink(link_unknown_dst_addr,
- link_unknown_dst_addr->src_addr, dst_addr, alias_addr,
- link_unknown_dst_addr->src_port, dst_port, alias_port,
- link_type)
- : link_unknown_dst_addr;
- }
+ link = link_unknown_dst_addr;
else if (link_unknown_all != NULL)
- {
- return replace_partial_links
- ? ReLink(link_unknown_all,
- link_unknown_all->src_addr, dst_addr, alias_addr,
- link_unknown_all->src_port, dst_port, alias_port,
- link_type)
- : link_unknown_all;
- }
+ link = link_unknown_all;
else
+ return (NULL);
+
+ if (replace_partial_links &&
+ (link->flags & LINK_PARTIALLY_SPECIFIED || link->server != NULL))
{
- return(NULL);
+ struct in_addr src_addr;
+ u_short src_port;
+
+ if (link->server != NULL) { /* LSNAT link */
+ src_addr = link->server->addr;
+ src_port = link->server->port;
+ link->server = link->server->next;
+ } else {
+ src_addr = link->src_addr;
+ src_port = link->src_port;
+ }
+
+ link = ReLink(link,
+ src_addr, dst_addr, alias_addr,
+ src_port, dst_port, alias_port,
+ link_type);
}
+
+ return (link);
}
static struct alias_link *
@@ -1527,7 +1548,13 @@ FindOriginalAddress(struct in_addr alias_addr)
}
else
{
- if (link->src_addr.s_addr == INADDR_ANY)
+ if (link->server != NULL) { /* LSNAT link */
+ struct in_addr src_addr;
+
+ src_addr = link->server->addr;
+ link->server = link->server->next;
+ return (src_addr);
+ } else if (link->src_addr.s_addr == INADDR_ANY)
return aliasAddress;
else
return link->src_addr;
@@ -2035,6 +2062,7 @@ UninitPacketAliasLog(void)
-- "outside world" means other than alias*.c routines --
PacketAliasRedirectPort()
+ PacketAliasAddServer()
PacketAliasRedirectPptp()
PacketAliasRedirectAddr()
PacketAliasRedirectDelete()
@@ -2092,6 +2120,36 @@ PacketAliasRedirectPort(struct in_addr src_addr, u_short src_port,
return link;
}
+/* Add server to the pool of servers */
+int
+PacketAliasAddServer(struct alias_link *link, struct in_addr addr, u_short port)
+{
+ struct server *server;
+
+ server = malloc(sizeof(struct server));
+
+ if (server != NULL) {
+ struct server *head;
+
+ server->addr = addr;
+ server->port = port;
+
+ head = link->server;
+ if (head == NULL)
+ server->next = server;
+ else {
+ struct server *s;
+
+ for (s = head; s->next != head; s = s->next);
+ s->next = server;
+ server->next = head;
+ }
+ link->server = server;
+ return (0);
+ } else
+ return (-1);
+}
+
/* Translate PPTP packets to a machine on the inside
* XXX This function is made obsolete by PacketAliasRedirectPptp().
*/
diff --git a/lib/libalias/libalias.3 b/lib/libalias/libalias.3
index 42840af..36788d5 100644
--- a/lib/libalias/libalias.3
+++ b/lib/libalias/libalias.3
@@ -376,6 +376,14 @@ is called to change the address after
.Fn PacketAliasRedirectPort
is called, a zero reference will track this change.
.Pp
+If the link is further set up to operate for a load sharing, then
+.Fa local_addr
+and
+.Fa local_port
+are ignored, and are selected dynamically from the server pool, as described in
+.Fn PacketAliasAddServer
+below.
+.Pp
If
.Fa remote_addr
is zero, this indicates to redirect packets from any remote address.
@@ -434,6 +442,12 @@ is called to change the address after
.Fn PacketAliasRedirectAddr
is called, a zero reference will track this change.
.Pp
+If the link is further set up to operate for a load sharing, then
+.Fa local_addr
+is ignored, and is selected dynamically from the server pool, as described in
+.Fn PacketAliasAddServer
+below.
+.Pp
If subsequent calls to
.Fn PacketAliasRedirectAddr
use the same aliasing address, all new incoming traffic to this aliasing
@@ -471,6 +485,52 @@ If
is returned, then the function call did not complete successfully.
.Ed
.Pp
+.Ft int
+.Fo PacketAliasAddServer
+.Fa "struct alias_link *link"
+.Fa "struct in_addr addr"
+.Fa "u_short port"
+.Fc
+.Bd -ragged -offset indent
+This function sets the
+.Fa link
+up for Load Sharing using IP Network Address Translation (RFC 2391, LSNAT).
+LSNAT operates as follows.
+A client attempts to access a server by using the server virtual address.
+The LSNAT router transparently redirects the request to one of the hosts
+in server pool, selected using a real-time load sharing algorithm.
+Multiple sessions may be initiated from the same client, and each session
+could be directed to a different host based on load balance across server
+pool hosts at the time.
+If load share is desired for just a few specific services, the configuration
+on LSNAT could be defined to restrict load share for just the services
+desired.
+.Pp
+Currently, only the simplest selection algorithm is implemented, where a
+host is selected on a round-robin basis only, without regard to load on
+the host.
+.Pp
+First, the
+.Fa link
+is created by either
+.Fn PacketAliasRedirectPort
+or
+.Fn PacketAliasRedirectAddr .
+Then,
+.Fn PacketAliasAddServer
+is called multiple times to add entries to the
+.Fa link Ns 's
+server pool.
+.Pp
+For links created with
+.Fn PacketAliasRedirectAddr ,
+the
+.Fa port
+argument is ignored and could have any value, e.g. htons(~0).
+.Pp
+This function returns 0 on success, -1 otherwise.
+.Ed
+.Pp
.Ft void
.Fn PacketAliasRedirectDelete "struct alias_link *link"
.Bd -ragged -offset indent
diff --git a/sys/netinet/libalias/alias.h b/sys/netinet/libalias/alias.h
index 2285d97..9f15579 100644
--- a/sys/netinet/libalias/alias.h
+++ b/sys/netinet/libalias/alias.h
@@ -52,6 +52,11 @@ struct alias_link;
u_char);
extern int
+ PacketAliasAddServer(struct alias_link *link,
+ struct in_addr addr,
+ u_short port);
+
+ extern int
PacketAliasPptp(struct in_addr);
extern struct alias_link *
diff --git a/sys/netinet/libalias/alias_db.c b/sys/netinet/libalias/alias_db.c
index 431a757..bc020f3 100644
--- a/sys/netinet/libalias/alias_db.c
+++ b/sys/netinet/libalias/alias_db.c
@@ -237,6 +237,13 @@ struct tcp_dat
int fwhole; /* Which firewall record is used for this hole? */
};
+struct server /* LSNAT server pool (circular list) */
+{
+ struct in_addr addr;
+ u_short port;
+ struct server *next;
+};
+
struct alias_link /* Main data structure */
{
struct in_addr src_addr; /* Address and port information */
@@ -247,6 +254,7 @@ struct alias_link /* Main data structure */
u_short dst_port;
u_short alias_port;
u_short proxy_port;
+ struct server *server;
int link_type; /* Type of link: TCP, UDP, ICMP, PPTP, frag */
@@ -778,6 +786,17 @@ DeleteLink(struct alias_link *link)
ClearFWHole(link);
#endif
+/* Free memory allocated for LSNAT server pool */
+ if (link->server != NULL) {
+ struct server *head, *curr, *next;
+
+ head = curr = link->server;
+ do {
+ next = curr->next;
+ free(curr);
+ } while ((curr = next) != head);
+ }
+
/* Adjust output table pointers */
link_last = link->last_out;
link_next = link->next_out;
@@ -871,6 +890,7 @@ AddLink(struct in_addr src_addr,
link->src_port = src_port;
link->dst_port = dst_port;
link->proxy_port = 0;
+ link->server = NULL;
link->link_type = link_type;
link->sockfd = -1;
link->flags = 0;
@@ -1044,6 +1064,7 @@ _FindLinkOut(struct in_addr src_addr,
while (link != NULL)
{
if (link->src_addr.s_addr == src_addr.s_addr
+ && link->server == NULL
&& link->dst_addr.s_addr == dst_addr.s_addr
&& link->dst_port == dst_port
&& link->src_port == src_port
@@ -1207,39 +1228,39 @@ _FindLinkIn(struct in_addr dst_addr,
if (link_fully_specified != NULL)
{
link_fully_specified->timestamp = timeStamp;
- return link_fully_specified;
+ link = link_fully_specified;
}
else if (link_unknown_dst_port != NULL)
- {
- return replace_partial_links
- ? ReLink(link_unknown_dst_port,
- link_unknown_dst_port->src_addr, dst_addr, alias_addr,
- link_unknown_dst_port->src_port, dst_port, alias_port,
- link_type)
- : link_unknown_dst_port;
- }
+ link = link_unknown_dst_port;
else if (link_unknown_dst_addr != NULL)
- {
- return replace_partial_links
- ? ReLink(link_unknown_dst_addr,
- link_unknown_dst_addr->src_addr, dst_addr, alias_addr,
- link_unknown_dst_addr->src_port, dst_port, alias_port,
- link_type)
- : link_unknown_dst_addr;
- }
+ link = link_unknown_dst_addr;
else if (link_unknown_all != NULL)
- {
- return replace_partial_links
- ? ReLink(link_unknown_all,
- link_unknown_all->src_addr, dst_addr, alias_addr,
- link_unknown_all->src_port, dst_port, alias_port,
- link_type)
- : link_unknown_all;
- }
+ link = link_unknown_all;
else
+ return (NULL);
+
+ if (replace_partial_links &&
+ (link->flags & LINK_PARTIALLY_SPECIFIED || link->server != NULL))
{
- return(NULL);
+ struct in_addr src_addr;
+ u_short src_port;
+
+ if (link->server != NULL) { /* LSNAT link */
+ src_addr = link->server->addr;
+ src_port = link->server->port;
+ link->server = link->server->next;
+ } else {
+ src_addr = link->src_addr;
+ src_port = link->src_port;
+ }
+
+ link = ReLink(link,
+ src_addr, dst_addr, alias_addr,
+ src_port, dst_port, alias_port,
+ link_type);
}
+
+ return (link);
}
static struct alias_link *
@@ -1527,7 +1548,13 @@ FindOriginalAddress(struct in_addr alias_addr)
}
else
{
- if (link->src_addr.s_addr == INADDR_ANY)
+ if (link->server != NULL) { /* LSNAT link */
+ struct in_addr src_addr;
+
+ src_addr = link->server->addr;
+ link->server = link->server->next;
+ return (src_addr);
+ } else if (link->src_addr.s_addr == INADDR_ANY)
return aliasAddress;
else
return link->src_addr;
@@ -2035,6 +2062,7 @@ UninitPacketAliasLog(void)
-- "outside world" means other than alias*.c routines --
PacketAliasRedirectPort()
+ PacketAliasAddServer()
PacketAliasRedirectPptp()
PacketAliasRedirectAddr()
PacketAliasRedirectDelete()
@@ -2092,6 +2120,36 @@ PacketAliasRedirectPort(struct in_addr src_addr, u_short src_port,
return link;
}
+/* Add server to the pool of servers */
+int
+PacketAliasAddServer(struct alias_link *link, struct in_addr addr, u_short port)
+{
+ struct server *server;
+
+ server = malloc(sizeof(struct server));
+
+ if (server != NULL) {
+ struct server *head;
+
+ server->addr = addr;
+ server->port = port;
+
+ head = link->server;
+ if (head == NULL)
+ server->next = server;
+ else {
+ struct server *s;
+
+ for (s = head; s->next != head; s = s->next);
+ s->next = server;
+ server->next = head;
+ }
+ link->server = server;
+ return (0);
+ } else
+ return (-1);
+}
+
/* Translate PPTP packets to a machine on the inside
* XXX This function is made obsolete by PacketAliasRedirectPptp().
*/
diff --git a/sys/netinet/libalias/libalias.3 b/sys/netinet/libalias/libalias.3
index 42840af..36788d5 100644
--- a/sys/netinet/libalias/libalias.3
+++ b/sys/netinet/libalias/libalias.3
@@ -376,6 +376,14 @@ is called to change the address after
.Fn PacketAliasRedirectPort
is called, a zero reference will track this change.
.Pp
+If the link is further set up to operate for a load sharing, then
+.Fa local_addr
+and
+.Fa local_port
+are ignored, and are selected dynamically from the server pool, as described in
+.Fn PacketAliasAddServer
+below.
+.Pp
If
.Fa remote_addr
is zero, this indicates to redirect packets from any remote address.
@@ -434,6 +442,12 @@ is called to change the address after
.Fn PacketAliasRedirectAddr
is called, a zero reference will track this change.
.Pp
+If the link is further set up to operate for a load sharing, then
+.Fa local_addr
+is ignored, and is selected dynamically from the server pool, as described in
+.Fn PacketAliasAddServer
+below.
+.Pp
If subsequent calls to
.Fn PacketAliasRedirectAddr
use the same aliasing address, all new incoming traffic to this aliasing
@@ -471,6 +485,52 @@ If
is returned, then the function call did not complete successfully.
.Ed
.Pp
+.Ft int
+.Fo PacketAliasAddServer
+.Fa "struct alias_link *link"
+.Fa "struct in_addr addr"
+.Fa "u_short port"
+.Fc
+.Bd -ragged -offset indent
+This function sets the
+.Fa link
+up for Load Sharing using IP Network Address Translation (RFC 2391, LSNAT).
+LSNAT operates as follows.
+A client attempts to access a server by using the server virtual address.
+The LSNAT router transparently redirects the request to one of the hosts
+in server pool, selected using a real-time load sharing algorithm.
+Multiple sessions may be initiated from the same client, and each session
+could be directed to a different host based on load balance across server
+pool hosts at the time.
+If load share is desired for just a few specific services, the configuration
+on LSNAT could be defined to restrict load share for just the services
+desired.
+.Pp
+Currently, only the simplest selection algorithm is implemented, where a
+host is selected on a round-robin basis only, without regard to load on
+the host.
+.Pp
+First, the
+.Fa link
+is created by either
+.Fn PacketAliasRedirectPort
+or
+.Fn PacketAliasRedirectAddr .
+Then,
+.Fn PacketAliasAddServer
+is called multiple times to add entries to the
+.Fa link Ns 's
+server pool.
+.Pp
+For links created with
+.Fn PacketAliasRedirectAddr ,
+the
+.Fa port
+argument is ignored and could have any value, e.g. htons(~0).
+.Pp
+This function returns 0 on success, -1 otherwise.
+.Ed
+.Pp
.Ft void
.Fn PacketAliasRedirectDelete "struct alias_link *link"
.Bd -ragged -offset indent
OpenPOWER on IntegriCloud