Intermediary EEM scripting: more fun with Power-over-Ethernet

In my last post I described how you can power off PoE on a range of switchports at certain times. But what if you’re lazy like me and don’t want to spend time figuring out which ports are utilizing Power-over-Ethernet? Can’t mr. switch do this himself? Well yes he can! Here you go:

event manager applet SelectivePowerOff
 action 0.0 cli command "enable"
 action 0.1 cli command "show power inline"
 action 0.2 foreach line "$_cli_result" "\n"
 action 1.1  regexp "^([^[:space:]]*)[[:space:]]*[^[:space:]]*[[:space:]]*on.*$" "$line" temp interface
 action 1.2  if $_regexp_result eq 1
 action 1.3   cli command "conf t"
 action 1.4   cli command "interface $interface"
 action 1.5   cli command "power inline never"
 action 1.6   syslog msg "Turned off PoE on $interface"
 action 1.7  end
 action 2.1 end

Basically what we’re doing here is using the “show power inline” command and processing it line by line. If we find an interface where the PoE operational status (column “Oper”) is on, we run the command “power inline never” on that interface. We also log a message to syslog telling we’ve turned off the power on that interface.

event manager applet SelectivePowerOn
 action 0.0 cli command "enable"
 action 0.1 cli command "show power inline"
 action 0.2 foreach line "$_cli_result" "\n"
 action 1.1  regexp "^([^[:space:]]*)[[:space:]]*off.*$" "$line" temp interface
 action 1.2  if $_regexp_result eq 1
 action 1.3   cli command "conf t"
 action 1.4   cli command "interface $interface"
 action 1.5   cli command "no power inline never"
 action 1.6   syslog msg "Turned on PoE on $interface"
 action 1.7  end
 action 2.1 end
 exit

Here we go through the same “show power inline” and check if the PoE administrative status (column “Admin”) is off. If it is, we run the command “no power inline never” on that interface. We also log a message telling we’ve turned on the power.

If you combine this with the event timer, you’ll have a fully automated solution.

Turning off Power-over-Ethernet ports at night to save power

Goal

Turn off Power-over-Ethernet on selected switch ports at selected times using the Cisco IOS EEM (Embedded Event Manager). Ultimately we want to reduce the energy consumption by turning off equipment that’s not being used at selected times.

In this example we have 7 switchports (FastEthernet 1/0/12 through 1/0/18) that have PoE equipment (phones) attached to them. As the company is not expecting calls to be conducted before 7:00 and after 22:00, there’s no need to keep the phones on, so we can power them off.

Prerequisites

For this configuration you’ll need one switch or router that:

  • has Power-over-Ethernet ports
  • supports EEM
  • has a correctly configured clock

Basically almost anything that runs Cisco IOS will have EEM. The configuration steps below are being done on a Catalyst 3750-48PS-S running IOS 12.2(55)SE8. As the events are time-based, your switch should have an accurate clock. Configure NTP first if you haven’t.

Configure the switch

The event manager works by way of applets: you define an applet which contains:

  • What to do: an action (or actions)
  • When to do it: an event (or events)

We’re going to need two applets: one that turns off the PoE at 22:00 and one that turns on the PoE at 7:00.

Start by defining a new applet, the one that’ll turn off the PoE. Let’s call it “PowerOff”:

l3s1(config-applet)#?
Event Manager Applet Entry Configuration Commands:
  action       Add or modify an action statement
  description  Add or modify an applet description
  event        Add or modify event information
  exit         Exit from Event Manager applet configuration submode
  help         Description of the interactive help system
  no           Negate a command or set its defaults
  trigger      Enter applet trigger configuration submode

l3s1(config-applet)#

As we look in the help we see two things that are important to us: “action” defining a set of actions this applet will execute, “event” which will describe when “action” will take place, the event being “time”.

Defining the actions

Notice the use of the label. The label dictates in which order the actions will be executed, in an ASCII sorted manner. You don’t have to use these particular labels, but how I’m using them seems to be a common way.

l3s1(config-applet)#action 0.0 cli command enable
l3s1(config-applet)#action 1.0 cli command conf t
l3s1(config-applet)#action 1.1 cli command interface range FastEthernet 1/0/12 - 18
l3s1(config-applet)#action 1.2 cli command power inline never
l3s1(config-applet)#action 2.0 cli command end

warning-145066_640 If you’re thinking about just turning off PoE on every port, keep in mind that “power inline never” can flap the port. So always exclude ports that link to devices that should not be disturbed (like as servers, uplinks to other switches, etc…).

Defining the events

Now that’s we’ve told the PowerOff applet what to do, now we need to tell it when to do it. The event we’re basing on is “time”, and the time specification is in cron format:

l3s1(config-applet)#event timer cron cron-entry "0 22 * * *"
l3s1(config-applet)#end
l3s1#

Let’s verify the result:

l3s1#show event manager policy registered
No.  Class     Type    Event Type          Trap  Time Registered           Secu  Name
1    applet    user    timer cron          Off   Sun Aug 24 12:23:16 2014  none  PowerOff
 cron entry {0 22 * * *}
 maxrun 20.000
 action 0.0 cli command "enable"
 action 1.0 cli command "conf t"
 action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
 action 1.2 cli command "power inline never"
 action 1.3 cli command "end"

l3s1#

We’re going to need to power on the equipment again. We’ll do that by way of a PowerOn applet:

l3s1#conf t
l3s1(config)#event manager applet PowerOn
l3s1(config-applet)#action 0.0 cli command "enable"
l3s1(config-applet)#action 1.0 cli command "conf t"
l3s1(config-applet)#action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
l3s1(config-applet)#action 1.2 cli command "no power inline never"
l3s1(config-applet)#action 2.0 cli command "end"
l3s1(config-applet)#event timer cron cron-entry "0 7 * * *"
l3s1(config-applet)#end
l3s1#

Verify:

l3s1#show event manager policy registered
No.  Class     Type    Event Type          Trap  Time Registered           Secu  Name
1    applet    user    timer cron          Off   Sun Aug 24 12:23:16 2014  none  PowerOff
 cron entry {0 22 * * *}
 maxrun 20.000
 action 0.0 cli command "enable"
 action 1.0 cli command "conf t"
 action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
 action 1.2 cli command "power inline never"
 action 1.3 cli command "end"

2    applet    user    timer cron          Off   Sun Aug 24 12:23:41 2014  none  PowerOn
 cron entry {0 7 * * *}
 maxrun 20.000
 action 0.0 cli command "enable"
 action 1.0 cli command "conf t"
 action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
 action 1.2 cli command "no power inline never"
 action 1.3 cli command "end"

l3s1#

Full configuration

event manager applet PowerOff
 event timer cron cron-entry "0 22 * * *"
 action 0.0 cli command "enable"
 action 1.0 cli command "conf t"
 action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
 action 1.2 cli command "power inline never"
 action 1.3 cli command "end"
event manager applet PowerOn
 event timer cron cron-entry "0 7 * * *"
 action 0.0 cli command "enable"
 action 1.0 cli command "conf t"
 action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
 action 1.2 cli command "no power inline never"
 action 1.3 cli command "end"

A more advanced time schedule

What if you wanted to turn off the PoE equipment on sundays, for the entire day?

As PoE is already being turned off every day at 22:00, we only need to prevent the PowerOn sequence on sundays. We can do this by adding a day-of-week to the cron schedule of the PowerOn applet:

l3s1(config)#event manager applet PowerOn
l3s1(config-applet)#event timer cron cron-entry "0 7 * * 1-6"
l3s1(config-applet)#end
l3s1#

Verify:

l3s1#show event manager policy registered
No.  Class     Type    Event Type          Trap  Time Registered           Secu  Name
1    applet    user    timer cron          Off   Sun Aug 24 12:23:16 2014  none  PowerOff
 cron entry {0 22 * * *}
 maxrun 20.000
 action 0.0 cli command "enable"
 action 1.0 cli command "conf t"
 action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
 action 1.2 cli command "power inline never"
 action 1.3 cli command "end"

2    applet    user    timer cron          Off   Sun Aug 24 12:26:51 2014  none  PowerOn
 cron entry {0 7 * * 1-6}
 maxrun 20.000
 action 0.0 cli command "enable"
 action 1.0 cli command "conf t"
 action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
 action 1.2 cli command "no power inline never"
 action 1.3 cli command "end"

l3s1#

Full configuration

event manager applet PowerOff
 event timer cron cron-entry "0 22 * * *"
 action 0.0 cli command "enable"
 action 1.0 cli command "conf t"
 action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
 action 1.2 cli command "power inline never"
 action 1.3 cli command "end"
 event manager applet PowerOn
event timer cron cron-entry "0 7 * * 1-6"
 action 0.0 cli command "enable"
 action 1.0 cli command "conf t"
 action 1.1 cli command "interface range FastEthernet 1/0/12 - 18"
 action 1.2 cli command "no power inline never"
 action 1.3 cli command "end"

Cron time format

A helpful reminder from wikipedia how cron time is specified:

cron

Using a Cisco router’s AUX port to talk IP

Goal

Setup an AUX port on a Cisco router so we can talk IP over it. This is also called a back-to-back connection.

Cisco router back-to-back connection using the AUX ports

In this example we have two routers, each one has 1 AUX port:

  • R1, a Cisco 2610, which we will assign IP address 10.0.0.1/24
  • R2, a Cisco 1811, which we will assign IP address 10.0.0.2/24

Succes is when we can ping the other router’s IP.

The AUX port is actually an RS-232 port.

Prerequisites

For this configuration you’ll need:

  • Two Cisco routers equipped with an AUX port
  • A rolled cable with 8P8C endpoints. Rolled means the direction of the polarities is reversed on one side. View the pinout  @ Cisco.com. You can use a normal ethernet cable and refit one of the ends (now would be a good time to reuse that cable where you broke the latching tab off).

Caveats

  • If you connect the ports up front (before configuring the routers), the interface might not come up. Disconnecting and then reconnecting should bring it up.
  • Some configuration changes require shutting down (shutdown) and bringing back up (no shutdown) the Async interface, if the interface is already up and running.
  • This example connects the cable at the end.

Configuring router R1

R1 is the Cisco 2610.

Physical settings of the AUX port

Just like the console port, we can modify the configuration of the AUX port using the “line” configuration commands. Here we tell the port in which format bits must be processed, at what speed, etc… Let’s start by defining the operational mode of the AUX port:

! Select the auxiliary port to configure
r1(config)#line aux 0
! Set it up as a modem
r1(config-line)#modem InOut
! Allow all protocols to pass this port
r1(config-line)#transport input all

The default speed setting is 9600 bits per second or 1,2 kilobytes per second. We’re going to increase that to 115 200 bits per second (14,4 kilobytes per second):

r1(config-line)#speed 115200
r1(config-line)#exit
r1(config)#

Verifying our settings:

r1#show line aux 0
   Tty Typ     Tx/Rx    A Modem  Roty AccO AccI   Uses   Noise  Overruns   Int
    65 AUX 115200/115200- inout     -    -    -      0       0     0/0       -

Line 65, Location: "", Type: ""
Length: 24 lines, Width: 80 columns
Baud rate (TX/RX) is 115200/115200, no parity, 2 stopbits, 8 databits
Status: No Exit Banner, Modem Signals Polled
Capabilities: Modem Callout, Modem RI is CD
Modem state: Idle
Modem hardware state: noCTS noDSR  DTR RTS
Special Chars: Escape  Hold  Stop  Start  Disconnect  Activation
                ^^x    none   -     -       none
Timeouts:      Idle EXEC    Idle Session   Modem Answer  Session   Dispatch
               00:10:00        never                        none     not set
                            Idle Session Disconnect Warning
                              never
                            Login-sequence User Response
                             00:00:30
                            Autoselect Initial Wait
                              not set
Modem type is unknown.
Session limit is not set.
Time since activation: never
Editing is enabled.
History is enabled, history size is 20.
DNS resolution in show commands is enabled
Full user help is disabled
Allowed input transports are none.
Allowed output transports are none.
Preferred transport is telnet.
No output characters are padded
No special data dispatching characters
r1#

Note the noCTS and noDSR in the Modem hardware state line. This is because the cable isn’t connected yet. (Or, if it is connected, it’s a bad one).

That’s it for the physical properties of the AUX port. You can play with the settings here to modify how information is electronically being sent and interpreted, but remember to match the settings on the other side too if you do so. Next up is configuring the Async interface that belongs to the AUX port.

Configuring the Async interface

The AUX port A-Synchronous interface overlay, we can find these in Cisco IOS as Async interfaces. However, when configuring Async interfaces, we get to choose from 1 to 65:

r1(config)#interface Async ?
  <1-65>  Async interface number

r1(config)#interface Async

So how do we know which Async interface number corresponds with the AUX port? We can figure this out using the show line command:

r1#show line
   Tty Typ     Tx/Rx    A Modem  Roty AccO AccI   Uses   Noise  Overruns   Int
     0 CTY              -    -      -    -    -      0       0     0/0       -
    65 AUX 115200/115200- inout     -    -    -      0       0     0/0       -
*   66 VTY              -    -      -    -    -      2       0     0/0       -
    67 VTY              -    -      -    -    -      0       0     0/0       -
    68 VTY              -    -      -    -    -      0       0     0/0       -
    69 VTY              -    -      -    -    -      0       0     0/0       -
    70 VTY              -    -      -    -    -      0       0     0/0       -

Line(s) not in async mode -or- with no hardware support:
1-64

r1#

Number 65 here is our AUX port. We’re going to use PPP encapsulation and give it an IP address.

! Select the Async 65 interface
r1(config)#interface Async 65
! Set it up as a dedicated port
r1(config-if)#async mode dedicated
! Encapsulate using the PPP protocol
r1(config-if)#encapsulation ppp
! Assign an IP address
r1(config-if)#ip address 10.0.0.1 255.255.255.0
r1(config-if)#exit
r1(config)#

Verify:

r1#show interface Async 65
Async65 is down, line protocol is down
  Hardware is Async Serial
  Internet address is 10.0.0.1/24
  MTU 1500 bytes, BW 115 Kbit, DLY 100000 usec,
     reliability 255/255, txload 1/255, rxload 1/255
  Encapsulation PPP, LCP Closed, loopback not set
  Keepalive not set
  DTR is pulsed for 5 seconds on reset
  Last input 01:00:17, output 01:00:17, output hang never
  Last clearing of "show interface" counters 00:41:12
  Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 0
  Queueing strategy: weighted fair
  Output queue: 0/1000/64/0 (size/max total/threshold/drops)
     Conversations  0/1/16 (active/max active/max total)
     Reserved Conversations 0/0 (allocated/max allocated)
     Available Bandwidth 86 kilobits/sec
  5 minute input rate 0 bits/sec, 0 packets/sec
  5 minute output rate 0 bits/sec, 0 packets/sec
     0 packets input, 0 bytes, 0 no buffer
     Received 0 broadcasts, 0 runts, 0 giants, 0 throttles
     0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 0 abort
     0 packets output, 0 bytes, 0 underruns
     0 output errors, 0 collisions, 0 interface resets
     0 output buffer failures, 0 output buffers swapped out
     0 carrier transitions
r1#

Configuring router R2

R2 is the Cisco 1811.

We don’t need to do anything special here, just mirror and adjust as necessary. Router B will get 10.0.0.2 as IP address.

r2(config)#line aux 0
r2(config-line)#modem InOut
r2(config-line)#transport input all
r2(config-line)#speed 115200
r2(config-line)#exit
r2(config)#do show line
   Tty Typ     Tx/Rx    A Modem  Roty AccO AccI   Uses   Noise  Overruns   Int
*     0 CTY              -    -      -    -    -      0       0     0/0       -
      1 TTY              - inout     -    -    -      0       0     0/0       -
      5 AUX 115200/115200- inout     -    -    -      0       0     0/0       -
      6 VTY              -    -      -    -    -      0       0     0/0       -
      7 VTY              -    -      -    -    -      0       0     0/0       -
      8 VTY              -    -      -    -    -      0       0     0/0       -
      9 VTY              -    -      -    -    -      0       0     0/0       -
     10 VTY              -    -      -    -    -      0       0     0/0       -

Line(s) not in async mode -or- with no hardware support: 
2-4

r3(config)#
r2(config)#interface Async 5
r2(config-if)#async mode dedicated
r2(config-if)#encapsulation ppp
r2(config-if)#ip address 10.0.0.2 255.255.255.0
r2(config-if)#exit
r2(config)#

Bringing up the configuration

Now connect the cable between the AUX ports of the routers. The interface should come up.

Don’t forget: you need a rolled cable.

r1#
*Mar  1 00:12:26.756: %LINK-3-UPDOWN: Interface Async65, changed state to up
*Mar  1 00:12:27.769: %LINEPROTO-5-UPDOWN: Line protocol on Interface Async65, changed state to up
r1#

Now verify operation:

r1#show line aux 0
   Tty Typ     Tx/Rx    A Modem  Roty AccO AccI   Uses   Noise  Overruns   Int
A   65 AUX 115200/115200- inout     -    -    -      2       0     0/49967   -

Line 65, Location: "PPP: 10.0.0.2", Type: ""
Length: 24 lines, Width: 80 columns
Baud rate (TX/RX) is 115200/115200, no parity, 2 stopbits, 8 databits
Status: Ready, Active, No Exit Banner, Async Interface Active
  CTS Raised, Modem Signals Polled
Capabilities: Modem Callout, Modem RI is CD, 
  Line is permanent async interface
Modem state: Ready
Line is running PPP for address 10.0.0.2.
0 output packets queued, 1 input packets.
 Async Escape map is 00000000000000000101000000000000
Modem hardware state: CTS* DSR*  DTR RTS
Special Chars: Escape  Hold  Stop  Start  Disconnect  Activation
                ^^x    none   -     -       none         
Timeouts:      Idle EXEC    Idle Session   Modem Answer  Session   Dispatch
               00:10:00        never                        none     not set
                            Idle Session Disconnect Warning
                              never 
                            Login-sequence User Response
                             00:00:30
                            Autoselect Initial Wait
                              not set 
Modem type is unknown.
Session limit is not set.
Time since activation: 00:03:23
Editing is enabled.
History is enabled, history size is 20.
DNS resolution in show commands is enabled
Full user help is disabled
Allowed input transports are pad v120 telnet rlogin udptn.
Allowed output transports are pad v120 telnet rlogin.
Preferred transport is telnet.
No output characters are padded
No special data dispatching characters
r1#show interface Async 65
Async65 is up, line protocol is up 
  Hardware is Async Serial
  Internet address is 10.0.0.1/24
  MTU 1500 bytes, BW 115 Kbit, DLY 100000 usec, 
     reliability 255/255, txload 1/255, rxload 1/255
  Encapsulation PPP, LCP Open
  Open: IPCP, loopback not set
  Keepalive not set
  DTR is pulsed for 5 seconds on reset
  Last input 00:02:30, output 00:02:30, output hang never
  Last clearing of "show interface" counters 00:12:52
  Input queue: 1/75/0/0 (size/max/drops/flushes); Total output drops: 0
  Queueing strategy: weighted fair
  Output queue: 0/1000/64/0 (size/max total/threshold/drops) 
     Conversations  0/1/32 (active/max active/max total)
     Reserved Conversations 0/0 (allocated/max allocated)
     Available Bandwidth 86 kilobits/sec
  5 minute input rate 0 bits/sec, 0 packets/sec
  5 minute output rate 0 bits/sec, 0 packets/sec
     13 packets input, 649 bytes, 0 no buffer
     Received 0 broadcasts, 0 runts, 0 giants, 0 throttles
     0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored, 0 abort
     13 packets output, 657 bytes, 0 underruns
     0 output errors, 0 collisions, 1 interface resets
     0 output buffer failures, 0 output buffers swapped out
     0 carrier transitions
r1#

That all looks good, now a ping test:

r1#ping 10.0.0.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.0.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 24/26/28 ms
r1#

Success! Note the high latency, it goes up if the speed is lower. A 9600 bit/s connection will give you a whopping 120 ms latency (a round-trip of 240 ms!).

Use

Although this is unlikely to ever see production use, it is great for a lab setup:

  • It gives you an extra port on your router.
  • The low bandwidth and high latency can be used to emulate a WAN connection or congestion.

References

A quick introduction to IPv6

This article serves as a quick introduction for those who know their way around IPv4 but know nothing of IPv6.

The old

Let’s take a look at an IPv4 address:

192.0.43.10

We have 4 groups of each 8 bits, for a total of 32 bits. This gives us 232 possibilities, 4 294 967 296 to be exact. Every IP address has a network part and a host part. The subnetmask determines which part is the network part and which is the host part.

For example, 192.0.43.10 with subnetmask 255.255.0.0 means 192.0 is the network part and 43.10 the host part.

If you want to communicate with networks where the 192.0 part differs, you need a router.

Today we use the CIDR notation for our subnetmasks, for example /24. The 24 says how many bits are set to 1 in the subnetmask.

/24 = 11 11 11 11 . 11 11 11 11 . 11 11 11 11 . 00 00 00 00 = 255.255.255.0 = the first three groups are the network part.

Now, 4 billion sounds plentiful, in practice a lot less are usable:

  • Per subnet we lose two addresses to the network address itself and the broadcast address. If we take the default gateway into account we lose 3 (losing as in, cannot be assigned to a host).
  • Three ranges are reserved for private use (these are not routed on the internet): 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16
  • Some special ranges like multicast (240.0.0.0/4) cannot be used to connect devices
  • Waste by assigning big blocks to organizations who don’t need them

In short, the IPv4 addressing scheme doesn’t suffice anymore. As more and more equipment gets connected to the internet (think mobile phones, interactive services such as digital television, general increase in internet usage, etc…) the number of available  addresses is sinking rapidly. Not “oh we can manage”, but Titanic scale sinking. IANA, who distributes the entire IP space to the independent RIR’s, handed out the last usable /8 blocks in February 2011. In other words: we’re out. Game over.

Postponement of the inevitable

The shortage of IP addresses was predicted long beforehand, that’s why technologies were developed to make better use of the already scarce address space. Where we used classful addressing before, we implemented CIDR, which makes classless addressing possible. Hence the name, Classless Inter-Domain Routing.

Another technique, more prominent, is the application of NAT, Network Address Translation. NAT makes it possible to have multiple nodes, each with their own private IP address, to share one public IP address. That is how most computer networks are organized these days.

The new

One of the biggest changes of IPv6 compared to the IPv4 is obviously the length of the addresses. Where we had 32 bits before, we now have 128. These 128 bits are usually displayed as 8 groups of 16 bits.

128 bits = 2128 = 3,4 x 1038 = unspeakable = enough to give every grain of sand on earth an IP address.

So, we said they are displayed in 8 groups of each 16 bits. We write them hexadecimal. This is an example of a valid IPv6 address:

2002:3e19:ff3a:76cd:21:1418:6f8:1234

Notice the groups are separated by colons!

Fact 1: IPv6: 128 bits, divided in 8 groups of each 16 bits, displayed hexadecimal with colon as delimiter.

Short notation

IPv6 has a short notation as well. We do this by replacing the 0’s in the address by 2 colons.

Example 1:

2002:3e19:ff3a:76cd:21:1418:0:1234

we can write this as

2002:3e19:ff3a:76cd:21:1418::1234

Example 2:

2002:3e19:ff3a:76cd:21:0:0:1234

becomes

2002:3e19:ff3a:76cd:21::1234

Note that you can only shorten the 0’s at one point in the address. How else would you know how many zero’s to use and where? The following example is WRONG:

2002::76cd:21::1234 -> Where do we put how much zero’s? You don’t know, so the computer definitely doesn’t know! The address we wrote down has become ambiguous. That’s something computers really don’t like.

Fact 2: IPv6 addresses can be shortened by replacing 0’s with double colons, but only if  the entire address remains unambiguous.

Subnetting

Subnetting basically works in the same way as IPv4. With the difference there are now 128 bits for the subnetmask and they are always shown in CIDR fashion.

For example: /64: one half is the network address, the other half is the host address.

ARP doesn’t exist anymore

ARP has disappeared with IPv6. Everything has been replaced with the Neighbor Discovery Protocol, NDP. If you are running Windows you can see the discovered neighbours with

netsh interface ipv6 show neighbors

With Cisco IOS:

show ipv6 neighbors

You can filter ARP on your network, IPv6 will continue to work, as it is not dependent on ARP. The NDP protocol is the most important protocol of IPv6, it basically makes the whole system work.

Fact 3: ARP is no more, Neighbour Discovery Protocol has replaced it.

The link-local address

Every network interface, when its being initialized for IPv6, gets a “link-local” address. This address is meant for communication within the bounds of the local network. Routers do not forward packets that have link-local addresses. Link-local addresses are somewhat resemblant of the IPv4 APIPA (Automatic Private IP Addressing). This link-local address is needed for other protocols (for example, NDP).

The range reserved for link-local addresses is:

fe80::/10

This means from fe80:: up to and including  febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff.

The operating system will automatically assign the host part based on the MAC address of the adaptor*. This kind of address is NOT the same as private IP addresses in IPv4 although it can be used to communicate with other hosts within the scope of the link (ie, everything that’s reachable at layer 2).

Fact 4: Every network interface gets a link-local address.

* Note: using the MAC address is just one of the ways the operating system may generate the host part. An OS may purposely (to hide the MAC address) use another source of randomness.

Private addresses & NAT

Private addresses still exist, they are called ULA’s: Unique Local Addresses. These are not routed on the internet.

The address range reserved for ULA is:

fd00::/8

However, IPv6 was designed so that every computer should get a “Global” IP address, which is the equivalent of an IPv4 public address. This means NAT is history. Although NAT can still be used, it is the opinion of this author we might as well go back to living in caves if you decide to do so.

Erase the idea of NAT, it simply does not apply anymore. Every node gets a globally unique IPv6 address that is directly addressable and routable without further ado.

Fact 5: Unique Local Addresses is the new private address range

Recommendation: no more private addresses, no more NAT. Every computer gets a global address.

Wait just a minute! What about these link-local addresses?

These are ONLY meant to make the Neighbour Discovery Protocol work. You do not, in any case, assign these yourself. If you assign this kind of address to an interface to debug a connectivity problem, you’re doing it wrong.

Two types of addresses: link-local and global

So by now we know of two address types:

  • Link-local: every interface gets them automatically, calculated based on MAC address, within the fe80::/10 subnet.
  • Global: a global address is a public, via internet accessible, IP addresses. Every computer should get one to participate in a network.

What’s the percent sign in the link-local address?

If you’ve run the ipconfig command before, you might have noticed the following:

There’s a “%” sign and a number behind your link-local address. This is the zone index. It is used to add extra routing information, in the case of link-local addresses it is used to indicate which interface we’re talking about.

Why do we need a zone index? Every interface gets a link-local address, but these are all within the same subnet, fe80::/10. By using the zone index, we can distinguish them.

With most UNIX operating systems the name of the interface is appended, for example:

fe80::3%eth0.

Windows just uses an incrementing number. As you add more interfaces to your system, they will get a higher and higher number each time one is added. Different interfaces will have different zone indexes.

Fact 6: link-local addresses need a zone index to distinguish different network interfaces.

Hint: if you want to use link-local addresses to communicate with other nodes, you’ll need to use this zone index and know how the two are physically connected. Let’s say you have two network adapters in your computer, NIC1 & NIC2. NIC1 gets a zone index of 14 and NIC2 gets a zone index of 17. If you want to ping a device using its link-local (for example, fe80::806b:6ed0:448a:a990) address connected to NIC2, you’ll need to use

ping fe80::806b:6ed0:448a:a990%17

If it was connected to NIC1, you’d use

ping fe80::806b:6ed0:448a:a990%14

Obviously you’ll need to use this zone index in other programs as well when using link-local addresses, not just ping.

Multicast replaces broadcast

Broadcast addresses do not exist anymore. Everything is now based on multicast and anycast. There’s a multicast address for nodes with a link-local addresses:

ff02::1

There’s a special one for routers as well:

ff02::2

NDP uses multicast.

The multicast address range is ff00::/8

Fact 7: Broadcast is replaced by multicast

Creating subnets

The subnetting system hasn’t really changed technically, subnets are created just the same as with IPv4. However, there is one important rule you should obey:

The smallest LAN subnet is a /64. Which means, one half of the address, is the network address, the other half is the host address.

Note that it’s technically still possible to create smaller subnets, but those are not compatible with Stateless Address Auto Configuration (which we’ll cover a bit later). If you want to create smaller subnets, you’ll have to use DHCPv6.

Fact 8: the smallest LAN subnet is a /64 (for SLAAC)

Aside from that we have ::/0. This range is used for ::1, which is the IPv6 loopback address. ::1 is for IPv6 what 127.0.0.1 is for IPv4.

Fact 9: ::1 is IPv6’s loopback address

Prefixes

In IPv6 terminology, when we assign IPv6 addresses, we talk about prefixes. Prefixes are a combination of a IPv6 prefix (an address) and a prefix length. We write them like this:

2001:6f8:1418::/48

As you can see, this is the same as an IPv4 network address combined with the CIDR style notation of the subnetmask. Prefixes replaces the network addresses as we know from IPv4.

A simple formula:

48 (subnetbits that are 1) / 16 (how many bits per group) = 3. This means, the first three groups determine the network part, the others the host part.

The situation in the future will most likely be that your provider will give you a prefix and below this prefix you may create as much subnets as you want. Popular right now are /48 and /56 prefixes. As the regular LAN subnets are /64, you either have, depending on the prefix you got, room to create your own subnets:

If your provider gives you a /48, you have an entire group to play with:

2001:6f8:1418:   1234   :baf1:85ab:ef9:1
              /48    /64

A /48 means you have 16 bits you can subnet with. That’s 65 536 networks.

If you only got a /56, you have one half of a group to play with. 8 bits mean 256 networks.

Fact 10: addresses are assigned based on a prefix.

Stateless Address Auto Configuration (SLAAC)

New in IPv6 is Stateless Address Auto Configuration. Stateless means there’s no mechanism that keeps state of a node (like DHCP in IPv4). You’ve already seen Stateless Auto Configuration in action with the link-local addresses. SLAAC allows a client to configure their addresses themselves, without requiring a DHCP server.

But how do you get a global address and set the default gateway, so you can reach other networks and thus the internet?

This is done by means of router advertisements. It’s part of the Neighbor Discovery Protocol. A Router Advertisement (RA) contains a prefix a node may use. When a node receives a prefix they may use from the router advertisements (a /64 prefix), the node derives the host part of the address using the MAC address of the interface.

The result is you get an address where the first part (the network part) is the prefix and the second half (the host part) is the auto configured address based on the MAC address.

Example 1: SLAAC

We know quite a bit know about IPv6. Let’s start with a simple example. One laptop will connect to a Cisco 2821 router.

  • The Cisco’s IP address is 9a9b:1234::1/64 on the GigabitEthernet 0/0 interface.
  • The laptop is directly connected to GigabitEthernet 0/0.
  • We will send out a Route Advertisement (RA) for the 9a8b:1234::/64 prefix, allowing stateless auto configuration.

The end result is that the laptop automatically assigns itself an address with the 9a8b:1234::/64 prefix.

Let’s start by enabling IPv6 unicast routing:

Router(config)#ipv6 unicast-routing 
Router(config)#

Now configure the g0/0 interface:

Router(config)#interface GigabitEthernet 0/0 
Router(config-if)#ipv6 address 9a8b:1234::1/64
Router(config-if)#no shutdown
Router(config-if)#exit
Router(config)#

Verify operation with:

Router#show ipv6 interface GigabitEthernet 0/0
GigabitEthernet0/0 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::217:E0FF:FE56:1F58
  No Virtual link-local address(es):
  Global unicast address(es):
    9A8B:1234::1, subnet is 9A8B:1234::/64
  Joined group address(es):
    FF02::1
    FF02::2
    FF02::1:FF00:1
    FF02::1:FF56:1F58
  MTU is 1500 bytes
  ICMP error messages limited to one every 100 milliseconds
  ICMP redirects are enabled
  ICMP unreachables are sent
  ND DAD is enabled, number of DAD attempts: 1
  ND reachable time is 30000 milliseconds (using 30000)
  ND advertised reachable time is 0 (unspecified)
  ND advertised retransmit interval is 0 (unspecified)
  ND router advertisements are sent every 200 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use stateless autoconfig for addresses.
Router#

By now the router is already sending out RA’s, but only doing so every 200 seconds. That means, in the worst case, it may take up to 200 seconds for any client to receive an RA and configure itself. We’re going to modify this interval to send an RA every 10 seconds:

Router(config)#
Router(config)#interface GigabitEthernet 0/0
Router(config-if)#ipv6 nd ra interval 10
Router(config-if)#exit
Router(config)#

Again, verifying:

Router#show ipv6 interface GigabitEthernet 0/0
GigabitEthernet0/0 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::217:E0FF:FE56:1F58
  No Virtual link-local address(es):
  Global unicast address(es):
    9A8B:1234::1, subnet is 9A8B:1234::/64
  Joined group address(es):
    FF02::1
    FF02::2
    FF02::1:FF00:1
    FF02::1:FF56:1F58
  MTU is 1500 bytes
  ICMP error messages limited to one every 100 milliseconds
  ICMP redirects are enabled
  ICMP unreachables are sent
  ND DAD is enabled, number of DAD attempts: 1
  ND reachable time is 30000 milliseconds (using 30000)
  ND advertised reachable time is 0 (unspecified)
  ND advertised retransmit interval is 0 (unspecified)
  ND router advertisements are sent every 10 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use stateless autoconfig for addresses.
Router#

Let’s turn back to our client and see if our client already has an IPv6 address:

Hooray! We can see that the laptop picked up the RA and configured itself accordingly. Our 9a8b:1234::/64 prefix is being used because Windows automatically assigned our computer an address that begins with 9a8b:1234::. Note that the default gateway has been set to the link-local address of the router and includes the zone index.

Now let’s have a closer to look at an RA:

Here we can clearly see the router advertising our prefix and any prefix lengths that are of interest. The packet was sent to a multicast address (ff02::01) and the source address is the link-local address of our router.

The RA also contains a number of timers such as router lifetime and a valid lifetime for the prefix. This means if, for example, the valid lifetime of the prefix is 60 seconds and no RA with that prefix has been received for 61 seconds, the nodes will remove any addresses it assigned to itself based on that prefix.

Managed address configuration/other stateful configuration

In an RA, we can specify two flags called managed address configuration and other stateful configuration. This influences how the client configures itself.

  • Managed address: client should not use auto configuration but instead try DHCPv6. The default gateway still gets set to the node where the router advertisements are received from. This way the client’s behavior is the same as IPv4, except for the gateway bit.
  • Other stateful configuration: use auto configuration, but try to get other parameters such as DNS servers via DHCPv6.

If we want our network nodes to use a managed address, or get other stateful configuration, from a DHCPv6 server, we need to explicitly say so in our route advertisements. RA’s don’t have room for DNS server information, leaving our clients dead in the water when trying to resolve hostnames. Thus, you will most likely use any of the two flags discussed.

We’ll work this out in example 2, where we use the other stateful configuration flag and a DHCPv6 server to provision our clients with DNS server addresses.

Example 2: SLAAC with other stateful configuration

Let’s resume our previous example, example 1. We already have a working IPv6 network, but now we want to expand the provision of our clients to include IPv6 DNS servers. As clients are useless without name resolving, this will be most applicable.

  • DONE The Cisco’s IP address is 9a9b:1234::1/64 on the GigabitEthernet 0/0 interface.
  • DONE The laptop is directly connected to GigabitEthernet 0/0.
  • DONE We will send out a Route Advertisement (RA) for the 9a8b:1234::/64 prefix, allowing stateless auto configuration.
  • Our RA’s have the Other Configuration flag set
  • The Cisco router will act as a DHCPv6 server
  • The laptop will receive 2001:4860:4860::8888 and 2001:4860:4860::8844 as DNS servers

Create the DHCPv6 scope. Creating a DHCPv6 scope is basically the same how you do it for IPv4:

Router(config)#ipv6 dhcp pool MyLocalIPv6net
Router(config-dhcpv6)#dns-server 2001:4860:4860::8888
Router(config-dhcpv6)#dns-server 2001:4860:4860::8844
Router(config-dhcpv6)#link-address 9a8b:1234::/64
Router(config-dhcpv6)#exit
Router(config)#

Note:

  • The usage of link-address. This tells the router that this DHCP pool should respond to requests matching the address 9a8b:1234::/64, which is our local subnet we created for our clients.
  • We did not specify any  network addresses to be handed out, as the clients will configure themselves using SLAAC.

Next we enable the other configuration flag and allow DHCP server operation on the interface:

Router(config)#interface GigabitEthernet 0/0
Router(config-if)#ipv6 nd other-config-flag
Router(config-if)#ipv6 dhcp server automatic
Router(config-if)#exit
Router(config)#

Verification:

Router#show ipv6 dhcp pool
DHCPv6 pool: MyLocalIPv6net
  Link-address prefix: 9A8B:1234::/64
  DNS server: 2001:4860:4860::8888
  DNS server: 2001:4860:4860::8844
  Active clients: 0
Router#show ipv6 interface GigabitEthernet 0/0
GigabitEthernet0/0 is up, line protocol is up
  IPv6 is enabled, link-local address is FE80::217:E0FF:FE56:1F58
  No Virtual link-local address(es):
  Global unicast address(es):
    9A8B:1234::1, subnet is 9A8B:1234::/64
  Joined group address(es):
    FF02::1
    FF02::2
    FF02::1:2
    FF02::1:FF00:1
    FF02::1:FF56:1F58
    FF05::1:3
  MTU is 1500 bytes
  ICMP error messages limited to one every 100 milliseconds
  ICMP redirects are enabled
  ICMP unreachables are sent
  ND DAD is enabled, number of DAD attempts: 1
  ND reachable time is 30000 milliseconds (using 30000)
  ND advertised reachable time is 0 (unspecified)
  ND advertised retransmit interval is 0 (unspecified)
  ND router advertisements are sent every 10 seconds
  ND router advertisements live for 1800 seconds
  ND advertised default router preference is Medium
  Hosts use stateless autoconfig for addresses.
  Hosts use DHCP to obtain other configuration.
Router#

And check our client with

ipconfig /all

(You might have to force the client by disabling the network interface and re-enabling it)

Success! Windows 7 is using the DNS servers we configured in the pool.

Caveats

Privacy extensions – what’s that temporary IPv6 address?

By now you might have noticed your network interface got 2 global IP addresses when using Stateless Address Auto Configuration. One is “IPv6 Address” and the other is “Temporary IPv6 Address”.

That has to do with the IPv6 privacy extensions that are enabled by default on Windows 7. Normally, Windows will always configure the same host part of the IP address when using Stateless Address Auto Configuration. This effectively allows IPv6 nodes, and in turn, people, to be tracked where they are. To solve this, Windows automatically assigns itself a temporary IPv6 address, and uses that one as source address when making a connection to another node. The default setting for Windows is to create a new temporary IPv6 address every 24 hours.

NAT gave me security – now it’s gone!

One “advantage” to NAT is that, by default, “assumably” incoming connections from the internet are impossible. However, by some clever routing tricks (which are normally blocked by providers), I can reach your private network using your router, gaining access to your internal computers.

But yes, with IPv6 this appearance of security, disappears. That’s why firewalls will become a lot more important. It’s up to a good system administrator to throw out all the garbage IPv6 traffic and strictly allow what’s necessary. The least-privilege principal is definitely a good starting point.

What about site-local addresses?

Yes, there was such a thing as site-local addresses, intended to replace the private IP ranges from IPv4. This deprecated however and site-local addresses should not be used. The range reserved for this type of address was fec0::/10.

Windows automatically gets fec0:0:0:ffff:: DNS servers?

That is part of the old site-local addresses standard which has been deprecated. But Windows still uses these when it doesn’t find any other way to configure DNS servers. How you can make your clients use specific DNS servers is explained in example 2. If Windows fails to retrieve the other configuration needed from the DHCP server (because it’s down or there’s an error in the configuration of it) or no managed configuration flag or other configuration flag is set, Windows will use the fec0 DNS servers it’s programmed to do.

If there’s no DNS server at those fec0 addresses, Windows will fail to resolve hostnames.

For completeness, these are the DNS addresses Windows will use:

  • fec0:0:0:ffff::1%1
  • fec0:0:0:ffff::2%1
  • fec0:0:0:ffff::3%1

What happens when a computer is connected to both an IPv4 and an IPv6 network?

That situation is called dual stack. If you connect to a hostname that has an IPv6 address (AAAA record) and the operating system has determined that the IPv6 stack is in a usable state, it will try and connect using IPv6. If you connect to a hostname that doesn’t have an IPv6 address record, it will just use IPv4. That’s why since Windows Vista you see two DNS queries when connecting to a hostname, one for AAAA records and one for A records. The general rule of thumb is: if it’s reachable via IPv6, use IPv6, otherwise fall back to IPv4.

This can create problems with wrongly configured IPv6 networks: the operating system has determined that its IPv6 stack is usable when in fact it’s not, by, for example, a wrongly configured router sending out RA’s. Result: the user will experience connectivity issues. Dead tunnels caused by IPv4 to IPv6 transition techniques is another example.

Policy Based Routing example: route one subnet via ISP A and another via ISP B

Goal

Setup a network with a Cisco router that routes one local subnet via internet connection A and another local subnet via internet connection B.

In this example we’ll use one LAN side, which has two subnets:

  • 192.168.1.0/24
  • 192.168.2.0/24

We want traffic destined for the internet, originating from the 192.168.1.0/24 network, to be sent to ISP A, which is connected to FastEthernet0

We want traffic destined for the internet, originating from the 192.168.2.0/24 network, to be sent to ISP B, which is connected to FastEthernet1

Both internet connections get their IP address via DHCP.

Prerequisites

For this  configuration you’ll need:

  • One dual WAN router, such as a 1811
  • Two internet connections (or simulated ones)
  • 2 nodes, one for the 192.168.1.0/24 subnet and one for the 192.168.2.0/24 subnet. These can be two different computers, or two virtual machines, etc…
    • ClientA, Windows 7, will connect to 192.168.1.0/24 and surf the net using ISP A
    • ClientB, Windows XP, will connect to 192.168.2.0/24 and surf the net using ISP B

Configure the router

Let’s start by defining our WAN interfaces first, which are FastEthernet0 and FastEthernet1 for a Cisco 1811.  Ports FastEthernet2 to 9 are the integrated switch. Both WAN interfaces use DHCP to obtain an IP address.

Setting up the WAN interfaces

r3(config)#interface FastEthernet0
r3(config-if)#ip address dhcp
r3(config-if)#ip nat outside
r3(config-if)#no shutdown
r3(config-if)#interface FastEthernet1
r3(config-if)#ip address dhcp
r3(config-if)#ip nat outside
r3(config-if)#no shutdown
r3(config-if)#exit
r3(config)#

Verifying WAN operation

We can verify our WAN connection by running the following commands and observing their output.

! Display a list of interfaces and their IPv4 addresses
r3#show ip interface brief
Interface     IP-Address    OK? Method Status                Protocol
Async1        unassigned    YES unset  down                  down
FastEthernet0 213.193.228.1 YES DHCP   up                    up
FastEthernet1 88.9.5.1      YES DHCP   up                    up
FastEthernet2 unassigned    YES unset  up                    up
FastEthernet3 unassigned    YES unset  up                    down
FastEthernet4 unassigned    YES unset  up                    down
FastEthernet5 unassigned    YES unset  up                    down
FastEthernet6 unassigned    YES unset  up                    down
FastEthernet7 unassigned    YES unset  up                    down
FastEthernet8 unassigned    YES unset  up                    down
FastEthernet9 unassigned    YES unset  up                    down
NVI0          unassigned    YES unset  administratively down down
Vlan1         192.168.1.254 YES NVRAM  up                    up
r3#! Display IPv4 routes
r3#show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       + - replicated route, % - next hop override

Gateway of last resort is 213.193.228.254 to network 0.0.0.0

S*    0.0.0.0/0 [254/0] via 213.193.228.254
                [254/0] via 88.9.5.254
      88.0.0.0/8 is variably subnetted, 2 subnets, 2 masks
C        88.9.5.0/24 is directly connected, FastEthernet1
L        88.9.5.1/32 is directly connected, FastEthernet1
      192.168.1.0/24 is variably subnetted, 2 subnets, 2 masks
C        192.168.1.0/24 is directly connected, Vlan1
L        192.168.1.254/32 is directly connected, Vlan1
      192.168.2.0/24 is variably subnetted, 2 subnets, 2 masks
C        192.168.2.0/24 is directly connected, Vlan1
L        192.168.2.254/32 is directly connected, Vlan1
      213.193.228.0/24 is variably subnetted, 2 subnets, 2 masks
C        213.193.228.0/24 is directly connected, FastEthernet0
L        213.193.228.1/32 is directly connected, FastEthernet0
r3#! Ping ISP A's gateway
r3#ping 213.193.228.254
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 213.193.228.254, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/4 ms
r3#! Ping ISP B's gateway 
r3#ping 88.9.5.254
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 88.9.5.254, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/3/4 ms
r3#! Ping known-to-reply-to-ping address on the internet 
r3#ping 8.8.8.8
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 20/21/24 ms
r3#

Setting up the local network

We’re going to keep this simple. As described we have two internal IP ranges, we’ll assign an IP address to Vlan1 for each of the IP ranges. Of course this scenario is of little use in the real world, you would probably have two VLAN’s, etc… However, this is just a theory of operations exercise, we’ll just configure the computers connecting to the router manually.

r3(config)#interface Vlan1
r3(config-if)#ip address 192.168.1.254 255.255.255.0
r3(config-if)#ip address 192.168.2.254 255.255.255.0 secondary
r3(config-if)#ip nat inside
r3(config-if)#no shutdown
r3(config-if)#exit
r3(config)#

Verifying local network operation

Once we’ve configured the Vlan1 interface, we can check again with show ip interface that we have correctly configured the respective interface:

r3#show ip interface Vlan1

Now we configure our client machines. We will statically configure:

  • ClientA with IP address 192.168.1.5
  • ClientB with IP address 192.168.2.5

After applying the  network configuration, verify that we can ping the routers.

Configuring NAT

We configure two access-lists:

  • One for the 192.168.1.0/24 that should get translated to FastEthernet0’s IP address
  • One for the 192.168.2.0/24 that should get translated to FastEthernet1’s IP address
r3(config)#ip access-list standard 1
r3(config-std-nacl)#permit 192.168.1.0 0.0.0.255
r3(config-std-nacl)#exit
r3(config)#ip access-list standard 2
r3(config-std-nacl)#permit 192.168.2.0 0.0.0.255
r3(config-std-nacl)#exit
r3(config)#
r3(config)#ip nat inside source list 1 interface FastEthernet0 overload
r3(config)#ip nat inside source list 2 interface FastEthernet1 overload
r3(config)#

Basically what we’re telling here is that, when the packet’s source address gets translated, it should get the source address of the interface as specified. Thus, when packets from 192.168.1.0/24 get NAT’ed, they get the source IP of FastEthernet0. When packets from 192.168.2.0/24 get NAT’ed, they get the source IP of FastEthernet1.

Now, when the packets have their correct source address, that doesn’t mean they automatically fly out the right interface. We need to explicitly define that any packets for the interface from 192.168.1.0/24 must go via FastEthernet0 and from 192.168.2.0/24 via FastEthernet1. We do this with a route map.

Building the route-map

Using a route-map we can build policy based  routing. A route map can have several entries, and each entry can have any number of match & set statements. If an entry doesn’t match, the router continues evaluating the route map until it finds an entry that does. When the router finds an entry that does match, it does whatever you say it should do with the set statements.

Matching

The match statements describe on which traffic we should act. In this scenario we have two distinct types of traffic: that for ISP A and that for ISP B. So we’ll need to define two route map entries: one matching the traffic destined for ISP A and one matching the traffic destined for ISP B.

We will do the matching with an access-list. We have two different subnets we want to match, 192.168.1.0/24 and 192.168.2.0/24. But, if you remember correctly, we already have two access-lists matching those exacts subnets (ip access-list 1 & 2). So we’re going to re-use those.

Setting

The set statements describe what should happen on the traffic that matches. Again, we have two distinct types of traffic, that for ISP A and that for ISP B. When we’ve correctly matched the traffic we want, we have to set something, namely, what to do with it. The first route-map entry (matching traffic for ISP A) should make the router send the traffic to FastEthernet0. The second entry (matching traffic for ISP B) should make the router send the traffic to FastEthernet1.

Show me the money

We will call our route-map “ISPSelect”. (IOS calls it a tag).

! Create the first entry in our new route-map called "ISPSelect"
r3(config)#route-map ISPSelect permit 10
! Match the traffic from 192.168.1.0/24 with access-list 1
r3(config-route-map)#match ip address 1
! Set the interface the traffic should go to, to FastEthernet0
r3(config-route-map)#set interface FastEthernet0
r3(config-route-map)#exit

! Create the second entry in our route-map called "ISPSelect"
r3(config)#route-map ISPSelect permit 20
! Match the traffic from 192.168.2.0/24 with access-list 2
r3(config-route-map)#match ip address 2
! Set the interface the traffic should go to, to FastEthernet1
r3(config-route-map)#set interface FastEthernet1
r3(config-route-map)#exit
r3(config)#

Verifying route-map configuration

r3#show route-map ISPSelect
route-map ISPSelect, permit, sequence 10
 Match clauses:
 ip address (access-lists): 1
 Set clauses:
 interface FastEthernet0
 Policy routing matches: 0 packets, 0 bytes
route-map ISPSelect, permit, sequence 20
 Match clauses:
 ip address (access-lists): 2
 Set clauses:
 interface FastEthernet1
 Policy routing matches: 0 packets, 0 bytes
r3#

Applying the route-map

Now where do we apply this route-map? Let’s take the following rule into account:

Packets are first routed, then NAT’ed.

Since we’re talking about a route-map, the route-map influences what happens when the router routes the packets. So we have to apply this map to the interface where the packets are coming in. In this case, this is Vlan1. Using the ip policy route-map statement in the interface configuration, we can define which route-map we want to use there:

r3(config)#interface Vlan 1
r3(config-if)#ip policy route-map ISPSelect
r3(config-if)#exit
r3(config)#

Verifying route-map application

r3#show ip interface Vlan 1
Vlan1 is up, line protocol is up
 Internet address is 192.168.1.254/24
 Broadcast address is 255.255.255.255
 Address determined by non-volatile memory
 MTU is 1500 bytes
 Helper address is not set
 Directed broadcast forwarding is disabled
 Secondary address 192.168.2.254/24
 Outgoing access list is not set
 Inbound access list is not set
 Proxy ARP is disabled
 Local Proxy ARP is disabled
 Security level is default
 Split horizon is enabled
 ICMP redirects are always sent
 ICMP unreachables are always sent
 ICMP mask replies are never sent
 IP fast switching is enabled
 IP fast switching on the same interface is disabled
 IP Flow switching is disabled
 IP CEF switching is enabled
 IP CEF switching turbo vector
 IP Null turbo vector
 IP multicast fast switching is enabled
 IP multicast distributed fast switching is disabled
 IP route-cache flags are Fast, CEF
 Router Discovery is disabled
 IP output packet accounting is disabled
 IP access violation accounting is disabled
 TCP/IP header compression is disabled
 RTP/IP header compression is disabled
 Policy routing is enabled, using route map ISPSelect
 Network address translation is enabled, interface in domain inside
 BGP Policy Mapping is disabled
 Input features: Stateful Inspection, Virtual Fragment Reassembly, Virtual Fragment Reassembly After IPSec Decryption, Policy Routing, MCI Check
 Output features: NAT Inside, Stateful Inspection, NAT ALG proxy
 WCCP Redirect outbound is disabled
 WCCP Redirect inbound is disabled
 WCCP Redirect exclude is disabled
r3#

Testing

Right now you should be able to surf the internet from both subnets. Let’s verify traffic from our subnets are really following the right path. Let’s start by doing a traceroute. I’m going to trace the path to 8.8.8.8 and I’ll be using the -d switch to tracert to not do a reverse lookup on the IP addresses.

Doing a traceroute

Note the second hop.

Result on Windows 7, 192.168.1.0/24 subnet:

Result on Windows XP, 192.168.2.0/24 subnet:

A successful result is when packets from the Windows 7 computer get routed via 213.193.228.254, which is ISP A’s gateway and packets from the Windows XP computer get routed via 88.9.5.254, which is ISP B’s gateway.

Checking the NAT translation table

Further verification, check the NAT translation table on the router using show ip nat translations command. I’ll be pinging 8.8.8.8 from both the Windows 7 and the Windows XP workstation, which will create exactly two NAT entries in the translation table: one from the Windows 7 PC to 8.8.8.8 using ISP A and one from the Windows XP PC to 8.8.8.8 using ISP B.

r3#show ip nat translations
Pro  Inside global   Inside local    Outside local  Outside global
icmp 213.193.228.1:1 192.168.1.5:1   8.8.8.8:1      8.8.8.8:1
icmp 88.9.5.1:512  192.168.2.5:512 8.8.8.8:512    8.8.8.8:512
r3#

Further testing

You can do a packet capture between the router and the ISP’s modems.

You can pull the cables for the internet connections and check which subnets can still reach the internet.

Full configuration

!
! Last configuration change at 11:52:02 UTC Sat Jan 28 2012
!
version 15.1
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname r3
!
boot-start-marker
boot-end-marker
!
!
!
no aaa new-model
!
crypto pki token default removal timeout 0
!
!
dot11 syslog
ip source-route
!
!
!
!
!
ip cef
no ipv6 cef
!
multilink bundle-name authenticated
!
!
!
license udi pid CISCO1811/K9 sn CENSORED
!
!
!
!
!
!
!
!
!
interface Multilink1
 no ip address
 ppp multilink
 ppp multilink group 1
!
interface FastEthernet0
 ip address dhcp
 ip nat outside
 ip virtual-reassembly in
 duplex auto
 speed auto
!
interface FastEthernet1
 ip address dhcp
 ip nat outside
 ip virtual-reassembly in
 duplex auto
 speed auto
!
interface FastEthernet2
!
interface FastEthernet3
!
interface FastEthernet4
!
interface FastEthernet5
!
interface FastEthernet6
!
interface FastEthernet7
!
interface FastEthernet8
!
interface FastEthernet9
!
interface Vlan1
 ip address 192.168.2.254 255.255.255.0 secondary
 ip address 192.168.1.254 255.255.255.0
 ip nat inside
 ip virtual-reassembly in
 ip policy route-map ISPSelect
!
interface Async1
 no ip address
 encapsulation slip
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
ip nat inside source list 1 interface FastEthernet0 overload
ip nat inside source list 2 interface FastEthernet1 overload
!
logging esm config
access-list 1 permit 192.168.1.0 0.0.0.255
access-list 2 permit 192.168.2.0 0.0.0.255
!
!
!
!
route-map ISPSelect permit 10
 match ip address 1
 set interface FastEthernet0
!
route-map ISPSelect permit 20
 match ip address 2
 set interface FastEthernet1
!
!
!
control-plane
!
!
!
line con 0
 speed 115200
line 1
 modem InOut
 stopbits 1
 speed 115200
 flowcontrol hardware
line aux 0
line vty 0 4
 login
 transport input all
!
end