Skip to content

Add MPLS support#641

Draft
mmuzila wants to merge 6 commits into
DPDK:mainfrom
mmuzila:add_mpls
Draft

Add MPLS support#641
mmuzila wants to merge 6 commits into
DPDK:mainfrom
mmuzila:add_mpls

Conversation

@mmuzila

@mmuzila mmuzila commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

No description provided.

mmuzila added 6 commits July 10, 2026 15:01
Introduce the basic infrastructure types needed for MPLS support.

Add GR_NH_T_MPLS to the nexthop type enum for MPLS label imposition
and swap operations. Add GR_AF_MPLS (AF_MPLS = 28) to the address
family enum so that MPLS can register per-AF operations such as
nexthop resolution callbacks and per-VRF FIB lifecycle management.

Reserve a fib_mpls slot in the private VRF struct for the per-VRF
label forwarding table that will be populated by the MPLS module.

Extend nexthop_af_ops_from_mbuf() to recognize MPLS packets held for
ARP resolution. Packets marked with RTE_PTYPE_TUNNEL_MPLS_IN_GRE are
dispatched to the MPLS AF ops so that they get resubmitted to the
correct datapath node after the gateway nexthop becomes reachable.

Signed-off-by: Matej Muzila <mmuzila@redhat.com>
The nexthop info struct carries the output label stack, initial TTL,
and a gateway address for ARP/NDP resolution. Each MPLS nexthop stores its own
via address rather than referencing an existing IP route. MPLS nexthops are
managed through the generic GR_NH_ADD/DEL API, same as SRv6.

Label routes map an incoming label to a nexthop in the per-VRF LFIB.
The API provides add, delete, get, and streaming list operations with
the corresponding event types for route change notifications.

Signed-off-by: Matej Muzila <mmuzila@redhat.com>
Implement the MPLS nexthop type operations, the per-VRF label
forwarding information base, and the API request handlers.

The nexthop type ops handle creation, update, and teardown of MPLS
nexthops. Each MPLS nexthop holds a reference to an L3 nexthop for
gateway resolution.

The LFIB is a flat array of nexthop pointers indexed directly by the
20-bit label value, allocated per VRF via the vrf_fib_ops mechanism.

Signed-off-by: Matej Muzila <mmuzila@redhat.com>
Implement the three MPLS graph nodes (input, output, push) and the
control plane callbacks for held packet resolution.

The input node decodes the MPLS label stack in a while loop since
rte_graph forbids self-loop edges. It handles label swap (overwrite
and forward), pop with TTL propagation (RFC 1624 incremental checksum
update for IPv4), reserved labels 0/2/3, and stacked label processing
with a depth limit. Payload type after pop is detected from the IP
version nibble.

The output node resolves the gateway MAC from the via L3 nexthop. For
unresolved gateways, the MPLS nexthop pointer is stashed in the mbuf
priv data overlay before entering ip_hold, and restored on resubmit
via the MPLS AF ops. The ether type is selected from the packet type
bits so that popped IP packets get the correct L3 ether type while
swapped packets keep the MPLS ether type.

The push node is dispatched from ip_output and ip6_output for MPLS
nexthops. It checks MTU accounting for the label overhead, reads the
payload TTL, and prepends the label stack.

Signed-off-by: Matej Mužila <mmuzila@redhat.com>
Register grcli commands under "mpls route" for managing the MPLS
label forwarding table. The commands use a separate CLI context
since label routes are keyed by numeric labels, not IP prefixes,
and cannot reuse the existing cli_route_ops dispatch.

The list command streams label routes as a table with VRF, label,
nexthop ID, and origin columns. Event printers for label route
add/del notifications are also registered.

Signed-off-by: Matej Muzila <mmuzila@redhat.com>
Cover the main MPLS datapath operations.  A separate CLI test exercises
nexthop and label route CRUD through grcli.

Tests that send MPLS-encapsulated traffic from Linux namespaces
pre-resolve ARP with a plain IP ping before the MPLS test to avoid
a race between the iptunnel encap path and neighbor resolution.

Signed-off-by: Matej Muzila <mmuzila@redhat.com>
@vjardin

vjardin commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Please, can you explain how you would integrate it with frrouting ?

@mmuzila

mmuzila commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Please, can you explain how you would integrate it with frrouting ?

AFAIK the FRR zebra dplane plugin already handles IP routes, nexthops, and SRv6 bidirectionally.
MPLS would follow the same pattern:

FRR -> grout : FRR sends DPLANE_OP_LSP_INSTALL/UPDATE/DELETE when LDP, OSPF-SR,
ISIS-SR, or static MPLS configures a label switch. The plugin would extract the incoming
label and NHLFEs from the dplane context, create GR_NH_T_MPLS nexthops in grout (via
GR_NH_ADD), then bind them to the label with GR_MPLS_LABEL_ROUTE_ADD. For ECMP (multiple
NHLFEs), wrap individual MPLS nexthops in a GR_NH_T_GROUP.

grout -> FRR: Subscribe to GR_EVENT_MPLS_ROUTE_ADD/DEL in the zebra notification
handler, then call FRR's mpls_lsp_install()/mpls_lsp_uninstall() to reflect
externally-created label routes (e.g. from grcli) into FRR's LSP table.

Startup sync: After the existing nexthop/route sync passes, add a pass that streams
GR_MPLS_LABEL_ROUTE_LIST from grout and injects each entry into FRR via mpls_lsp_install().

The main complexity is that FRR's LSP NHLFEs don't carry nexthop IDs, so the plugin needs a
deterministic ID scheme (e.g. base_offset | (label << 4) | nhlfe_index) to
create/update/delete the grout nexthops. All of this goes in frr/rt_grout.c and
frr/zebra_dplane_grout.c, following the exact patterns already used for IP routes and SRv6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants