Saving IP space on your point to point peering subnets using /31 subnets aka RFC3021

Most of us are used to allocating a /30 subnet for point to point peering, which gives us 2 device IP’s, a network address, and a broadcast address. With the exhaustion of IPV4 space it’s useful to be able to save wherever you can, so where possible you should consider /31 allocation instead of /30. Most modern day vendors support RFC3021 and using it is as simple as just specifying the /31 subnet mask. I have used this on various Juniper and Cisco devices in the past without any issues, but unfortunately not all vendors or models support it so your mileage will vary.

I would also, always recommend performing further testing beyond just a ICMP reachability tests if broadcast protocols are involved. A prime example is if you use something like the OSPF routing protocol that uses broadcast as a discovery mechanism. It should work but if it does not then possibly see if you can set it o P2P operation before reverting back to a /30 allocation.
I need to mention Mikrotik specifically here because they do not support RFC3021 in an obvious way. If you just specify x.x.x.x/31 it wont work. You need to specify a /32 with a matching network address. So 1.1.1.0/31 would look like so

/ip address add address=1.1.1.0/32 network=1.1.1.1 interface=ether1

The above example is compatible with RFC3021 but is actually different in that the network address does not have to fall within the same /31 as the IP. I have struggled to find the RFC for this assignment scheme but it allows you to be able to add the same IP multiple times with a different network address. This allows you to reach multiple devices on the same network segment using only a single IP per device. This obviously only works if all devices support this format.

Example of using this to connect to 2 other routers with IP’s 2.2.2.2 and 3.3.3.3.

/ip address add address=1.1.1.0/32 network=2.2.2.2 interface=ether1
/ip address add address=1.1.1.0/32 network=3.3.3.3 interface=ether1

“Stealing” a single IP from a subnet that you do not control.

The requirements to do weird and wonderful things never cease when it comes to networking and unprepared clients. I won’t go into the why, but I will share with you an interesting hack that I have not really seen done elsewhere. Here is the scenario, I have a DMZ subnet and a DMZ router lets say on  1.1.1.0/28, I want to take one of those IP’s and terminate it on another device without using NAT.  Now here is the trick, the device in question sits one or more routed hops away and I DO NOT have access to the DMZ router.

This is especially useful when you want a device to actually have the IP terminated on it, and you want to avoid NAT because of ALG issues (eg SIP.).

You will need..

  • 1x Mikrotik router (in my case it was a virtual x86 one in a VM)
  • 1x Interface in the DMZ
  • 1x Interface in the “Other” network
  • Enable proxy-arp on the DMZ interface
  • Set up a filter to only deal with the arps you are interested in

The filter functionality we need to use on Mikrotik is only available under the bridging firewall (which is the equivalent of ebtables for all the netfilter people), so we need to use a bridge interface for the filtering to work. We filter because we don’t want to introduce a device that responds to all ARP requests on the network. Introducing new behaviour in a system may break something so avoid it where possible.

Possibly scenarios are.. an IP scanning security appliance performs network scans and detects all these new active IP’s and then raises false alarms or.. possibly there is another device on the segment also performing proxy-arp so as to make something work and introducing another proxy-arp device will break that. Cisco IOS configurations found in X.21 routers (and probably others) seem to like to enable proxy-arp by default, I never did like this and still to this day find them scattered around corporate environments.

Lets use the following IP’s in the example.

  • 1.1.1.1 DMZ router IP, aka the gateway to the internet
  • 1.1.1.3 Router IP, we strictly don’t need this but you probably want to allocate an IP to the router so that you can manage it.
  • 1.1.1.5 IP we want to steal/route onwards
  • 192.168.50.1/24 Router IP on the private network that the hosted device sits on
  • 192.168.50.12/24 IP of the device that needs to host the “stolen” IP

So lets get started by creating the bridge and enabling proxy-arp on it.

/interface bridge
add arp=proxy-arp name=br-dmz protocol-mode=none
/interface bridge port
add bridge=br-dmz interface=ether1

Lets number the interfaces

/ip address
 add address=1.1.1.3/28 interface=br-dmz
 add address=192.168.50.1/24 interface=ether2

Then we add the ARP filters that accept ARP requests for the router IP and the forwarded IP only.

/interface bridge filter
 add arp-dst-address=1.1.1.3/32 arp-opcode=request chain=input \
 mac-protocol=arp
 add arp-dst-address=1.1.1.5/32 arp-opcode=request chain=input \
 mac-protocol=arp
 add action=drop arp-opcode=request chain=input log=yes mac-protocol=arp

If you are using VLAN instead on physical interfaces you may need to enable

/interface bridge settings
 set use-ip-firewall-for-vlan=yes

OK, so now we have the “stolen” the IP lets send it to the device that we want host it on

/ip route
 add distance=1 dst-address=1.1.1.5/32 gateway=192.168.50.12
 add distance=1 dst-address=0.0.0.0/0 gateway=1.1.1.1

I wont go into how you get the host to use the IP as a source address for originating outgoing connections, but as it stands if you install 1.1.1.5/32 on an active physical interface or on a loopback interface(recommended) of the device, most devices will work from an inbound connection perspective (ie they will be reachable on that IP). I cannot really cover outgoing source address selection, as this will vary depending on the device and OS. but in most cases I would look to see if you can set a “preferential source address” attribute  on the default route of the devices routing table.