Page MenuHomeFreeBSD

libalias: Add support for RFC 6598/Carrier Grade NAT subnets
ClosedPublic

Authored by nc on Dec 19 2019, 6:19 PM.

Details

Summary

This patch adds support for RFC 6598 (Carrier Grade NAT) subnets (100.64.0.0/10) in 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>

Test Plan

In short: test a network with an internal IP address in the 100.64.0.0/10 with unreg_cgn in IPFW, and see if NAT is performed.

Explained:

Compile a HEAD with this patch and reboot.

Add the following to /etc/rc.conf:

ifconfig_lan0="inet 100.64.0.1 netmask 255.255.255.0"
firewall_enable="YES"
firewall_nat_enable="YES"
firewall_script="/etc/ipfw.conf"

Add the following to /etc/ipfw.conf

#!/bin/sh

ipfw -q flush

ipfw nat 1 config if wan0 unreg_cgn
ipfw add 100 nat 1 ip from any to me in via wan0
ipfw add 200 nat 1 ip from 100.64.0.0/24 to any out via wan0
ipfw add allow ip from any to any

Replace wan0 with your WAN (outside) interface, and lan0 with your LAN (inside) interface.

Then run

kldload ipfw ipfw_nat

and

service netif restart

Then, add clients on the 100.64.0.0/24 subnet with the 100.64.0.1 gateway and 255.255.255.0 subnet mask.

You could also do DHCP, or NAT from a loopback interface, I won't mention that here.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

Looks good except for one typo in man page.

Is iclass used anywhere else other then that iclass== 0 check? Just curious if any documentation needs updated but I don't see any external reference or reason that's not a binary value well preexisting code so doesn't effect your review.

sbin/ipfw/ipfw.8
3240 ↗(On Diff #65816)

/s/tange/range/

Fix the ipfw man page typo.

rgrimes added a subscriber: rgrimes.

Looks good visually, need some others confirmed to have tested.

This revision is now accepted and ready to land.Jan 18 2020, 3:02 AM

LGTM. Thank you for submitting the patch!

Could you please update the testing section of the review to show the actual tests?

Also, do you think it would be possible to write some auto-test with atf-sh, testing this functionality?

sys/netinet/libalias/alias.h
237 ↗(On Diff #65850)

Can the definition be "..UNREGISTERED_CGN" or "..UNREGISTERED_SHARED" as stated in IANA registry to be consistent with the rest of the patch?

LGTM. Thank you for submitting the patch!

Could you please update the testing section of the review to show the actual tests?

Sure, will do.

Also, do you think it would be possible to write some auto-test with atf-sh, testing this functionality?

It may be possible, but I don't think it's too trivial. You will have to emulate clients. Those can be done with Jails, or loopback interfaces.

Testing from Jails may be a slight bit harder, as you would have to create and tear down the Jails, and loopback interfaces mean the client needs to be directed to use the loopback NAT instead of the default NIC.

This revision now requires review to proceed.Jan 21 2020, 4:40 AM
This revision is now accepted and ready to land.Jan 21 2020, 4:46 AM
nc requested review of this revision.Jan 21 2020, 4:46 AM

As for testing, you can perhaps use the packetdrill utility with these variables, to use a specific IP(v4/v6) version, and specific local and remote (simulated) IP address hosts over the TUN interface. I assume ipfw would apply to TUN interfaces just like regular interfaces even though they are only ephemeral in existance, during the test:

[--ip_version=[ipv4,ipv4_mapped_ipv6,ipv6]]
[--bind_port=bind_port]
[--connect_port=connect_port]
[--remote_ip=remote_ip]
[--local_ip=local_ip]

That may simplify the effort to test and validate this, since no jails setup is req'd

Sure, will do.

Thank you!

Also, do you think it would be possible to write some auto-test with atf-sh, testing this functionality?

It may be possible, but I don't think it's too trivial. You will have to emulate clients. Those can be done with Jails, or loopback interfaces.

Testing from Jails may be a slight bit harder, as you would have to create and tear down the Jails, and loopback interfaces mean the client needs to be directed to use the loopback NAT instead of the default NIC.

In fact, we already have most of the heavy-lifting done, with vnet wrappers & epair.
netinet6/exthdr.sh can be a good example.
I spent 30 minutes today to add an IPv4 redirect test here: D23075.

I don't see this as a blocker, but it looks like adding a test is not that hard :-)

Nevermind, I think I'll skip the tests if this can be committed anyways.

UPDATE: Maybe I'll try writing tests.

UPDATE 2: Actually, I'll skip it.

The problem is that my interface name may not be yours when plugging into ipfw. There may be inactive NICs, or NICs that are LAN-only. And I can't assume a fixed IP address either.

For instance, my desktop uses Realtek NICs while my home server has Broadcom. You may have Intel or Atheros NICs.

So I'll skip writing tests.

In D22877#511064, @neel_neelc.org wrote:

Nevermind, I think I'll skip the tests if this can be committed anyways.

UPDATE: Maybe I'll try writing tests.

UPDATE 2: Actually, I'll skip it.

The problem is that my interface name may not be yours when plugging into ipfw. There may be inactive NICs, or NICs that are LAN-only. And I can't assume a fixed IP address either.

Yes, that's a common problem for these kind of tests. The typical solution used is (a) - using virtual interfaces such as epair /w VNET and (b) - using IPv4 documentation prefixes. This makes it easy to setup & teardown a testing environment.

I'll commit this change, however I highly encourage you on trying to write the tests for this. I did a bunch of similar tests yesterday: D23316.

For instance, my desktop uses Realtek NICs while my home server has Broadcom. You may have Intel or Atheros NICs.

So I'll skip writing tests.

That's a bad one to write as a comment! :-)

After this is committed, I plan to write tests based upon D23316.

This revision is now accepted and ready to land.Jan 24 2020, 8:21 PM