Skip to content

Seed CAM tables with pipelined ICMP

  • “We’re SNMP-only on this site — no gNMI streaming. Half my access ports show empty CAM between polls because the hosts barely talk.”
  • “Maintenance window starts in ten minutes. I want every host on these VLANs freshly learned before I start a traceroute.”
  • “That /24 is mostly idle print servers and IPMI BMCs. They go silent for hours, age out of the CAM, and l2trace can’t see them when I need to.”

The failure mode is timing, not collection. A switch ages a dynamic MAC out of its CAM on a ~5-minute timer (Cisco’s default; faster on some vendors). SNMP polling runs every 120s by default. When a host’s last transmission plus the poll gap exceeds the aging timer, the entry is gone from the switch and never makes it into a poll — so l2trace silently loses a host that’s still plugged in and online.

seed-cam closes the gap by making the hosts talk. It walks the subnets you give it with pipelined ICMP echo. Every host that replies puts its source MAC back through the switch, which refreshes the CAM entry, and the next SNMP poll picks it up before aging fires. This is the Breitbart 2004 §VI.B technique — they measured 160 nodes/sec in 16-node bursts as the stable rate on campus L3 gear of that era, and the defaults track those numbers.

One thing to be clear about up front: the seeder does not write to the bitemporal log. It produces no observations of its own. All it does is provoke traffic — visibility still arrives through the normal SNMP poll cycle and the reconciler that processes it. If your SNMP collector isn’t running, seeding accomplishes nothing.

  • An SNMP poller configured against the switches that front the subnets you’re seeding, running on its normal cadence. The seeder feeds that cycle; it does not replace it.
  • ICMP reachability from the l2trace host to the target subnets. Replies don’t have to succeed for the effect — a firewalled or dead host costs nothing — but the path has to carry the echo request far enough that the host’s switch sees a frame.
  • ICMP socket permission. The pinger uses unprivileged SOCK_DGRAM ICMP on Linux when net.ipv4.ping_group_range covers the caller’s GID (default on most modern distros), and falls back to raw sockets (root / CAP_NET_RAW) otherwise.
  • IPv4 subnets. v6 ping seeding isn’t implemented yet — pass IPv4 CIDRs only.

The minimal case. --duration 0 (the default) means one full pass, then exit:

Terminal window
l2trace seed-cam --subnets 10.0.0.0/24

It expands the CIDR to host IPs (skipping network and broadcast for /30 and wider; /31 and /32 return every address per RFC 3021), paces the ICMP at the default 160 IPs/sec in 16-host bursts, and prints a one-line summary:

seeding 254 IPs across 10.0.0.0/24 (burst=16, interval=0.100s, target rate=160.0/s)
sweep 1: 198/254 responded (78.0%) in 1.6s

The response count is informational. A host that didn’t reply was either down, firewalled, or slower than the per-ping timeout — none of which the seeder treats as an error, because a non-responding host simply doesn’t refresh its CAM entry and that’s the steady state you started from.

Pass several subnets as a comma-separated list and they’re expanded and de-duplicated together:

Terminal window
l2trace seed-cam --subnets 10.0.0.0/24,10.0.1.0/24,10.2.0.0/23

Pre-incident freshen, timed against your poll

Section titled “Pre-incident freshen, timed against your poll”

Before a maintenance window or a planned trace, you want every host learned and you want the freshen to outlast at least one SNMP poll so the entries actually land in the log. Run the seeder in a loop with a deadline. --duration greater than zero repeats the sweep until the clock runs out:

Terminal window
l2trace seed-cam --subnets 10.0.0.0/24 --duration 600

That keeps re-provoking the subnet for ten minutes, comfortably across multiple 120s poll cycles. Each iteration prints its own summary line so you can watch the response rate hold steady (or climb, as previously silent hosts get woken up and stay chatty for a bit).

The two pacing knobs are --rate (target IPs/sec across the whole sweep) and --burst (how many ICMPs go out in each chunk). The inter-burst interval is derived as burst / rate, so at the defaults that’s 16 / 160 = 0.1s between bursts.

Push the rate up on a modern data-center fabric where the L3 path has headroom:

Terminal window
l2trace seed-cam --subnets 10.0.0.0/24,10.0.1.0/24 --rate 320 --duration 600

Pull it down on legacy gear with strict control-plane policing (CoPP), where a fast pipelined sweep can trip rate-limit detection on the router that has to answer ARP and punt the ICMP:

Terminal window
l2trace seed-cam --subnets 10.0.0.0/24 --rate 60 --burst 8

--timeout is the per-ping wait in seconds (default 1.0). Lower it on a low-latency LAN to finish sweeps faster; raise it only if real hosts are genuinely slow to answer and you care about the response-rate readout (you usually don’t — the CAM refresh happens on the reply regardless of whether the seeder was still listening for it).

The seeder itself can’t tell you the CAM is fresh — it doesn’t read the switch. Confirm through the normal path: wait for one SNMP poll to complete after the sweep, then check that the hosts you cared about now show open CAM entries. If a host pinged-and-responded during the sweep but still has no observation a poll later, the gap is in SNMP collection or reconciliation, not in seeding — chase it there.