Skip to content

Received IPv6 Router Advertisements are dropped, breaking FRR BGP unnumbered over grout ports #657

Description

@chdxD1

Description

Summary

grout's datapath drops all received ICMPv6 Router Advertisements (type 134) as
"unsupported", and never punts them to the per-interface control-plane TAP. Because
FRR's BGP unnumbered (neighbor <iface> interface remote-as ...) relies on receiving
the peer's Router Advertisement to auto-discover the peer's link-local next-hop, BGP
sessions over grout ports stay stuck in Idle forever. Numbered eBGP over the same
port works fine, which isolates the problem to RA handling specifically.

Details / root cause

In modules/ip6/datapath/icmp6_input.c, Router Advertisements fall into the
default/ICMP6_TYPE_ROUTER_ADVERT branch, which only punts to the control plane if a
callback has been registered for that ICMPv6 type — otherwise the packet is sent to the
icmp6_input_unsupported DROP node:

case ICMP6_TYPE_ROUTER_ADVERT:
default:
    if (icmp6_cb[icmp6->type] != NULL) {
        control_output_set_cb(mbuf, icmp6_cb[icmp6->type], gr_clock_ns());
        next = CONTROL;
    } else {
        next = UNSUPPORTED;          // -> icmp6_input_unsupported (GR_DROP_REGISTER)
    }

The only registered ICMPv6 callbacks are ECHO_REPLY and the four error types
(modules/ip6/control/icmp6.c):

icmp6_input_register_callback(ICMP6_TYPE_ECHO_REPLY, icmp6_input_cb);
icmp6_input_register_callback(ICMP6_ERR_DEST_UNREACH, icmp6_input_cb);
icmp6_input_register_callback(ICMP6_ERR_TTL_EXCEEDED, icmp6_input_cb);
icmp6_input_register_callback(ICMP6_ERR_PKT_TOO_BIG, icmp6_input_cb);
icmp6_input_register_callback(ICMP6_ERR_PARAM_PROBLEM, icmp6_input_cb);

There is no ICMP6_TYPE_ROUTER_ADVERT callback anywhere, and router_advert.c is
send-only (it generates grout's own RAs; there is no RA receiver). So received RAs are
always dropped and are never delivered to the kernel control-plane TAP where FRR listens.

By contrast, local TCP (e.g. BGP :179) is correctly punted to FRR:
modules/l4/l4_input_local.c sends non-UDP local traffic to the MANAGEMENT edge
(l4_loopback_output -> iface_cp_tx -> the interface cp_fd TAP). ICMPv6 is
registered as its own local proto handler (ip6_input_local_add_proto(IPPROTO_ICMPV6, "icmp6_input")), so RAs are intercepted before ever reaching that generic punt path.

Steps to reproduce

  1. Create a grout net_tap port and connect it (L2) to an FRR/Linux peer that sends
    IPv6 Router Advertisements on the link (e.g. an FRR leaf using neighbor <iface> interface remote-as external, which enables RA on the interface).
  2. Run FRR with the grout dataplane plugin inside grout's netns and configure BGP
    unnumbered over the grout port:
    router bgp 64497
    neighbor uplink1 interface remote-as external
  3. Observe: vtysh -c "show bgp summary" shows the neighbor stuck in Idle (never up).
  4. grcli graph stats shows a growing icmp6_input_unsupported counter and no
    corresponding control-plane RX (iface_cp_rx) for the RAs. tcpdump on the peer
    confirms RAs are being sent toward grout, but FRR never learns the peer link-local.
  5. Switch the same link to numbered p2p (assign IPs to the grout port and the peer)
    and the BGP session comes up immediately — confirming only RA delivery is broken.

Expected behaviour

Received Router Advertisements on a grout port should be punted to that interface's
control-plane TAP (like other local control traffic) so a userspace routing daemon
(FRR/BIRD) can consume them, enabling BGP unnumbered / SLAAC-style next-hop discovery.
At minimum, a way to register an RA punt callback (or a per-interface "punt RA to control
plane" knob) would unblock this.

Environment

  • FRR: BGP unnumbered eBGP over the grout uplink port.

Version

grout:edge (main / DPDK 25.11). Also reproduced against grout 0.16.2.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions