Back to Basics — CAM Table Population

Posted on July 14th, 2008 in Catalyst, LAN, Switching by Aaron Conaway

At the office, we reprovision servers like it’s going out of style.  It happens so often that my cabling documentation rarely matches what’s actually out in field, which is a pretty big problem when you’re trying to find to what switch port a server is connected.  I finally relegated myself to asking for the MAC address of the server, having the admin ping something, and then tracing it down through the CAM table entries of the switches.  It works, but the guys really don’t know how a switch populates its CAM table, so they always say “Why can’t you just look on the switch?  I shouldn’t have to ping anything.”  Here’s one just for the aspiring system admin.

The Content Addressable Memory (CAM) table on a switch keeps track of MAC addresses and on what port they appear, along with some other stuff like age.  When a device that’s plugged into a particular port sends a frame to the switch, the switch makes note of the source MAC and the port and checks the CAM table.  If it’s a new MAC, it adds an entry in the CAM table; if it’s an existing on a different port, it removes the old entry and adds a new one; if it’s an old MAC on the same port, it updates the age.  By default, Cisco switches keep CAM entries for 300 seconds, so they don’t stay there forever.

What about the destination MAC?  Good question.  That’s a pretty important field when sending a packet, but, when generating a CAM entry, the destination MAC is ignored.  If  a host talks, a switch knows exactly from where the frame came, but there’s no way to know exactly where it should go without the destination first speaking up.

Let’s set up an example.  You have a Cisco 2950 switch that you’ve just powered on with nothing plugged into it except the console cable. If you do a show mac-address-table, you’ll see the CAM table — a table of MAC addresses that the switch knows; you would think that it would be empty since nothing’s plugge din, but the switch has its own MACs, so it always knows those guys.  There’s not much to see here yet, though, since we haven’t hooked anything up to the switch yet.

Switch#sh mac-address-table
Mac Address Table
-------------------------------------------
Vlan    Mac Address       Type        Ports
----    -----------       --------    -----
 All    000a.f43b.ddc0    STATIC      CPU
 All    0100.0ccc.cccc    STATIC      CPU
 All    0100.0ccc.cccd    STATIC      CPU
 All    0100.0cdd.dddd    STATIC      CPU
Switch#

Next, let’s plug a Linux desktop up to it.  Once that box has booted, what should you see in the CAM table?  If you guessed the MAC of the Linux box, you may be right; it all depends on if the server sent a frame or not.  There’s lots of things that run on a Linux box that could send frames on startup — DHCP requests, multicast services, network-based storage — so, more than likely, a frame did get sent.  The only way to know it to take a gander.

Switch#sh mac-address-table
Mac Address Table
-------------------------------------------
Vlan    Mac Address       Type        Ports
----    -----------       --------    -----
...
   1    001c.0cbb.ada2    DYNAMIC     Fa0/1
Switch#

Ah…it worked. That’s good, but it’s boring with only a single device. Let’s plug in a simply-configured and fully-booted Cisco router and see what happens. More than likely the router won’t speak until spoken to, so the CAM table won’t update, and the switch won’t know where to send the frame, right? Yes, but the frame still gets sent. If the switch doesn’t know where the destination MAC lives (i.e., it’s not in the CAM table), then it floods the frame out every port except the one on which it was received.

When I first learned that this is how it worked, I immediately wondered why LANs weren’t flooded out constantly. I didn’t think long enough to realize that the host being sent the packet will actually respond within several milliseconds (hopefully), so the CAM table will then have an entry for that guy. In reality, it’s even simpler than that. Since most of the world runs TCP/IP, we have this wonderful thing called ARP. When a host needs to talk to another host on the same network segment (IP subnet), it checks its ARP table, and, if it doesn’t know a MAC for that IP, it will actually ask what MAC it should use via a broadcast message. In a well-behaved network, the mystery host will answer with a “Here I am!” type message, which causes the switch to generate a CAM entry. In a “perfect world”, you should only have a few floods on a switch per day/week/month/year/decade.

Here’s a couple items of note.

  • A trunk interface will have a whole bunch of MACs listed as attached to that port.  This is quite normal, so don’t freak out.
  • If someone plugs a switch or hub into one of your ports, you will see multiple CAM entries for the same port.  This is a good way to see who brought in their Linksys hub from home.
  • If a host hasn’t sent a frame in more than 5 minutes, it disappears from the CAM table, so the whole discovery process starts over again.
  • There’s a limit to the size of a CAM table, so it’s possible to fill it up and then every new destination gets flooded.  Wow, I can see your packets.

Have fun.  Be safe.  Practice safe computing.  Lock down your network.

How Screen Can Change Your Life

Posted on July 10th, 2008 in Tools by Aaron Conaway

Alright, that’s an exaggeration, but screen is pretty freaking cool.  It’s an app that’s (usually) run under Linux that lets you run commands then detach from that session and reattach later.  It doesn’t seem like much, but a few examples can show what it does for me.

I have a backup script at home that takes a target file, tars up everything listed in there, zips up the new file, and puts it on an external drive.  It’s very simple but takes about 3 hours to run.  I run it manually, so, in normal circumstances, I have to SSH in to my box and keep that window open for 3 hours while the backup runs.  With screen, I can open a new shell, run the script, and detach from it while everything gets backed up.

To do this, I log into my box and simply type screen.   This takes me to a new shell that’s no different than the one I got when I first logged into the box, and, from here, I run my backup script and watch it dump output like it’s going out of style.  When I see it’s running as expected, I do a Ctrl-A, D to detach from the session and return to my original shell.  From there, I can do my other business or just log off.  When I want to check status, I log into the box again, type screen -r to reattach, and I’m back at my backup session.

How about something more network-dude(tte)-based?  In the past, we’ve had issues with our VPN kicking us off at random times while we’re trying to do some maintenance.  This sucked pretty badly for us when we were doing log archive searches or running custom reporting scripts that may each take several minutes to run  — when we got kicked off, we lost everything we had.  Since we weren’t the guys doing the VPN at the time, we wound up using screen to help alleviate some of those problems.  We would VPN in and connect to one of the Linux management servers.   From there, we would open a new screen session and do our work.  When the inevitable boot came around, we could just reattach to the screen session to find our stuff still running.  That saves a whole mess of frustration when something happens at 03:00.

What else?  I’ve mentioned in past articles that I use screen to run dynagen labs — I have a shell for dynamips, one for dynagen, and one for each console that all run in the same screen session.  I can use my function keys to add new shells, navigate among them, and detach when I’m done. I editing my .screenrc file on my lab box so that I get the same setup just by typing screen. I stole most of this off the Intrawebs, but here’s my .screenrc file.  It sets up the function keys for navigation and opens (and labels) the multiple sessions for my labs.

bindkey -k k7 detach
bindkey -k k8 kill
bindkey -k k9 screen
bindkey -k k; title
bindkey -k F1 prev
bindkey -k F2 next
termcapinfo xterm ti@:te@
term vt100
multiuser on
shell -$SHELL
screen -t dyanmips 0
screen -t dynagen 1
screen -t R0 2
screen -t R1 3
select 0

Check the man pages or ask me for more details.