Add support for RFC 6598/Carrier Grade NAT subnets. to libalias and ipfw.

In libalias, a new flag PKT_ALIAS_UNREGISTERED_RFC6598 is added.
 This is like PKT_ALIAS_UNREGISTERED_ONLY, but also is RFC 6598 aware.
Also, we add a new NAT option to ipfw called unreg_cgn, which is like
 unreg_only, but also is RFC 6598-aware.  The reason for the new
 flags/options is to avoid breaking existing networks, especially those
 which rely on RFC 6598 as an external address.

Submitted by:	Neel Chauhan <neel AT neelc DOT org>
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D22877
This commit is contained in:
Alexander V. Chernikov 2020-01-24 20:35:41 +00:00
parent cd0047f3a9
commit 75b893375f
7 changed files with 33 additions and 4 deletions

View File

@ -3233,8 +3233,11 @@ Deny any incoming connection from outside world.
Try to leave the alias port numbers unchanged from
the actual local port numbers.
.It Cm unreg_only
Traffic on the local network not originating from an
Traffic on the local network not originating from a RFC 1918
unregistered address spaces will be ignored.
.It Cm unreg_cgn
Like unreg_only, but includes the RFC 6598 (Carrier Grade NAT)
address range.
.It Cm reset
Reset table of the packet aliasing engine on address change.
.It Cm reverse

View File

@ -220,6 +220,7 @@ enum tokens {
TOK_DENY_INC,
TOK_SAME_PORTS,
TOK_UNREG_ONLY,
TOK_UNREG_CGN,
TOK_SKIP_GLOBAL,
TOK_RESET_ADDR,
TOK_ALIAS_REV,

View File

@ -43,8 +43,8 @@ help(void)
"add [num] [set N] [prob x] RULE-BODY\n"
"{pipe|queue} N config PIPE-BODY\n"
"[pipe|queue] {zero|delete|show} [N{,N}]\n"
"nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|reset|\n"
" reverse|proxy_only|redirect_addr linkspec|\n"
"nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|unreg_cgn|\n"
" reset|reverse|proxy_only|redirect_addr linkspec|\n"
" redirect_port linkspec|redirect_proto linkspec}\n"
"set [disable N... enable N...] | move [rule] X to Y | swap X Y | show\n"
"set N {show|list|zero|resetlog|delete} [N{,N}] | flush\n"

View File

@ -60,6 +60,7 @@ static struct _s_x nat_params[] = {
{ "deny_in", TOK_DENY_INC },
{ "same_ports", TOK_SAME_PORTS },
{ "unreg_only", TOK_UNREG_ONLY },
{ "unreg_cgn", TOK_UNREG_CGN },
{ "skip_global", TOK_SKIP_GLOBAL },
{ "reset", TOK_RESET_ADDR },
{ "reverse", TOK_ALIAS_REV },
@ -663,6 +664,9 @@ nat_show_cfg(struct nat44_cfg_nat *n, void *arg)
} else if (n->mode & PKT_ALIAS_UNREGISTERED_ONLY) {
printf(" unreg_only");
n->mode &= ~PKT_ALIAS_UNREGISTERED_ONLY;
} else if (n->mode & PKT_ALIAS_UNREGISTERED_CGN) {
printf(" unreg_cgn");
n->mode &= ~PKT_ALIAS_UNREGISTERED_CGN;
} else if (n->mode & PKT_ALIAS_RESET_ON_ADDR_CHANGE) {
printf(" reset");
n->mode &= ~PKT_ALIAS_RESET_ON_ADDR_CHANGE;

View File

@ -1413,6 +1413,10 @@ LibAliasInLocked(struct libalias *la, char *ptr, int maxpacketsize)
#define UNREG_ADDR_C_LOWER 0xc0a80000
#define UNREG_ADDR_C_UPPER 0xc0a8ffff
/* 100.64.0.0 -> 100.127.255.255 (RFC 6598 - Carrier Grade NAT) */
#define UNREG_ADDR_CGN_LOWER 0x64400000
#define UNREG_ADDR_CGN_UPPER 0x647fffff
int
LibAliasOut(struct libalias *la, char *ptr, int maxpacketsize)
{
@ -1464,7 +1468,8 @@ LibAliasOutLocked(struct libalias *la, char *ptr, /* valid IP packet */
}
addr_save = GetDefaultAliasAddress(la);
if (la->packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY) {
if (la->packetAliasMode & PKT_ALIAS_UNREGISTERED_ONLY ||
la->packetAliasMode & PKT_ALIAS_UNREGISTERED_CGN) {
u_long addr;
int iclass;
@ -1476,6 +1481,9 @@ LibAliasOutLocked(struct libalias *la, char *ptr, /* valid IP packet */
iclass = 2;
else if (addr >= UNREG_ADDR_A_LOWER && addr <= UNREG_ADDR_A_UPPER)
iclass = 1;
else if (addr >= UNREG_ADDR_CGN_LOWER && addr <= UNREG_ADDR_CGN_UPPER &&
la->packetAliasMode & PKT_ALIAS_UNREGISTERED_CGN)
iclass = 4;
if (iclass == 0) {
SetDefaultAliasAddress(la, pip->ip_src);

View File

@ -228,6 +228,14 @@ struct mbuf *m_megapullup(struct mbuf *, int);
*/
#define PKT_ALIAS_SKIP_GLOBAL 0x200
/*
* Like PKT_ALIAS_UNREGISTERED_ONLY, but includes the RFC 6598
* (Carrier Grade NAT) address range as follows:
*
* 100.64.0.0 -> 100.127.255.255
*/
#define PKT_ALIAS_UNREGISTERED_CGN 0x400
/* Function return codes. */
#define PKT_ALIAS_ERROR -1
#define PKT_ALIAS_OK 1

View File

@ -212,6 +212,11 @@ This option is useful in the case that the packet aliasing host has both
registered and unregistered subnets on different interfaces.
The registered subnet is fully accessible to the outside world, so traffic
from it does not need to be passed through the packet aliasing engine.
.It Dv PKT_ALIAS_UNREGISTERED_CGN
Like PKT_ALIAS_UNREGISTERED_ONLY, but includes the RFC 6598 (Carrier Grade
NAT) subnet as follows:
.Pp
100.64.0.0 -> 100.127.255.255 (RFC 6598 subnet)
.It Dv PKT_ALIAS_RESET_ON_ADDR_CHANGE
When this mode bit is set and
.Fn LibAliasSetAddress