Skip to content

zebra: fix DVNI route encap type for IPv6 VTEPs#21911

Open
Manpreet-k0 wants to merge 1 commit into
FRRouting:masterfrom
Manpreet-k0:evpn_fix_v6
Open

zebra: fix DVNI route encap type for IPv6 VTEPs#21911
Manpreet-k0 wants to merge 1 commit into
FRRouting:masterfrom
Manpreet-k0:evpn_fix_v6

Conversation

@Manpreet-k0
Copy link
Copy Markdown
Contributor

_netlink_route_encode_label_info() hardcodes RTA_ENCAP_TYPE to LWTUNNEL_ENCAP_IP when encoding DVNI labels in route messages. For IPv6 VTEPs this causes the kernel to misinterpret the 16-byte IPv6 tunnel destination as a 4-byte IPv4 address, resulting in a corrupt nexthop dst and also programming route with incorrect encap type:

Fixed by selecting the encap type based on the nexthop address family, use LWTUNNEL_ENCAP_IP6 for pure IPv6 nexthops, LWTUNNEL_ENCAP_IP for IPv4 and IPv4-mapped-IPv6 nexthops.

brleaf1# show ip route vrf service_1 27.0.0.21
Routing entry for 27.0.0.21/32
  Known via "bgp", distance 20, metric 0, vrf service_1, best
  Last update 00:05:41 ago
  Flags: Selected
  Status: Installed
  * 2001:11::2, via vxlan99(vrf default) onlink, label 6000001, weight 1

Before Fix:

ip route show table all | grep 27.0.0.21
27.0.0.21  encap ip id 6000001 src 0.0.0.0 dst 32.1.0.17 ttl 0 tos 0 via inet6 2001:11::2 dev vxlan99 table service_1 proto bgp metric 20 onlink

After Fix:

ip route show table all | grep 27.0.0.21
27.0.0.21  encap ip6 id 6000001 src :: dst 2001:11::2 hoplimit 0 tc 0 via inet6 2001:11::2 dev vxlan99 table service_1 proto bgp metric 20 onlink

_netlink_route_encode_label_info() hardcodes RTA_ENCAP_TYPE to
LWTUNNEL_ENCAP_IP when encoding DVNI labels in route messages.
For IPv6 VTEPs this causes the kernel to misinterpret the 16-byte
IPv6 tunnel destination as a 4-byte IPv4 address, resulting in a
corrupt nexthop dst and also programming route with incorrect encap type:

Fixed by selecting the encap type based on the nexthop address family,
use LWTUNNEL_ENCAP_IP6 for pure IPv6 nexthops, LWTUNNEL_ENCAP_IP
for IPv4 and IPv4-mapped-IPv6 nexthops.

```
brleaf1# show ip route vrf service_1 27.0.0.21
Routing entry for 27.0.0.21/32
  Known via "bgp", distance 20, metric 0, vrf service_1, best
  Last update 00:05:41 ago
  Flags: Selected
  Status: Installed
  * 2001:11::2, via vxlan99(vrf default) onlink, label 6000001, weight 1
```
Before Fix:
```
ip route show table all | grep 27.0.0.21
27.0.0.21  encap ip id 6000001 src 0.0.0.0 dst 32.1.0.17 ttl 0 tos 0 via inet6 2001:11::2 dev vxlan99 table service_1 proto bgp metric 20 onlink
```
After Fix:
```
ip route show table all | grep 27.0.0.21
27.0.0.21  encap ip6 id 6000001 src :: dst 2001:11::2 hoplimit 0 tc 0 via inet6 2001:11::2 dev vxlan99 table service_1 proto bgp metric 20 onlink
```

Ticket: #4964647

Signed-off-by: Manpreet Kaur <manpreetk@nvidia.com>
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 11, 2026

Greptile Summary

This PR fixes the EVPN DVNI label encoding path in _netlink_route_encode_label_info() so that routes with pure IPv6 VTEPs emit LWTUNNEL_ENCAP_IP6 instead of the formerly hardcoded LWTUNNEL_ENCAP_IP, preventing the kernel from misinterpreting a 16-byte IPv6 tunnel destination as a 4-byte IPv4 address.

  • The encap-type selection now mirrors the logic already used in the nexthop-object code path (around line 3228): default to LWTUNNEL_ENCAP_IP, and switch to LWTUNNEL_ENCAP_IP6 only for NEXTHOP_TYPE_IPV6_IFINDEX nexthops that are not IPv4-mapped-IPv6 addresses.
  • All three cases handled by _netlink_nexthop_encode_dvni_label() — IPv4 IFINDEX, mapped-IPv6 IFINDEX, and pure IPv6 IFINDEX — now receive a consistent and correct RTA_ENCAP_TYPE value before the RTA_ENCAP nest is written.

Confidence Score: 5/5

Safe to merge; the change is a focused, minimal fix to the EVPN DVNI label encoding path with no side-effects on non-EVPN routes.

The new logic exactly mirrors the already-correct nexthop-object path (line 3228) and covers all three cases that _netlink_nexthop_encode_dvni_label() handles: IPv4 IFINDEX, IPv4-mapped-IPv6 IFINDEX, and pure IPv6 IFINDEX. The default of LWTUNNEL_ENCAP_IP is preserved for IPv4 and mapped-IPv6 cases, while LWTUNNEL_ENCAP_IP6 is now correctly selected for pure IPv6 VTEPs. No other code paths are touched.

No files require special attention.

Important Files Changed

Filename Overview
zebra/rt_netlink.c Adds encap-type selection logic in _netlink_route_encode_label_info() to use LWTUNNEL_ENCAP_IP6 for pure IPv6 EVPN nexthops instead of always using LWTUNNEL_ENCAP_IP; consistent with the existing nexthop-object code path at line 3228.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["_netlink_route_encode_label_info()"] --> B{"num_labels &&\nnh_label_type == ZEBRA_LSP_EVPN?"}
    B -- No --> C["MPLS encap or no encap"]
    B -- Yes --> D["encap_type = LWTUNNEL_ENCAP_IP (default)"]
    D --> E{"nexthop->type ==\nNEXTHOP_TYPE_IPV6_IFINDEX\n&& !IS_MAPPED_IPV6?"}
    E -- Yes --> F["encap_type = LWTUNNEL_ENCAP_IP6"]
    E -- No --> G["keep LWTUNNEL_ENCAP_IP"]
    F --> H["nl_attr_put16 RTA_ENCAP_TYPE"]
    G --> H
    H --> I["_netlink_nexthop_encode_dvni_label()"]
    I --> J{"nexthop type?"}
    J -- "IPV4_IFINDEX" --> K["Write LWTUNNEL_IP_DST (4 bytes)"]
    J -- "IPV6_IFINDEX + Mapped IPv6" --> L["Convert to IPv4, write LWTUNNEL_IP_DST"]
    J -- "IPV6_IFINDEX + Pure IPv6" --> M["Write LWTUNNEL_IP6_DST (16 bytes)"]
    J -- other --> N["Return false"]
Loading

Reviews (1): Last reviewed commit: "zebra: fix DVNI route encap type for IPv..." | Re-trigger Greptile

@Manpreet-k0
Copy link
Copy Markdown
Contributor Author

ci:rerun

2 similar comments
@Manpreet-k0
Copy link
Copy Markdown
Contributor Author

ci:rerun

@Manpreet-k0
Copy link
Copy Markdown
Contributor Author

ci:rerun

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant