]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Extend rt netlink parse functions to support encap behavior
authorCarmine Scarpitta <cscarpit@cisco.com>
Fri, 21 Feb 2025 15:05:17 +0000 (16:05 +0100)
committerCarmine Scarpitta <cscarpit@cisco.com>
Wed, 30 Apr 2025 15:51:25 +0000 (15:51 +0000)
Previous commits introduced the encap_behavior field to the SRv6
nexthop, enabling the association of one of the encapsulation behaviors
defined in RFC 8986 with an SRv6 nexthop.

This commit extends Zebra rt netlink parse functions by extracting
the encapsulation behavior from the Netlink message received from the
kernel.

Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
zebra/rt_netlink.c

index 40209bd1f78f3665f3bfb4f02b4877ab7d7bdce2..8f6a032959d92808b6c3586793e7afd304c3f41a 100644 (file)
@@ -483,7 +483,8 @@ parse_encap_seg6local(struct rtattr *tb,
        return act;
 }
 
-static int parse_encap_seg6(struct rtattr *tb, struct in6_addr *segs)
+static int parse_encap_seg6(struct rtattr *tb, struct in6_addr *segs,
+                           enum srv6_headend_behavior *encap_behavior)
 {
        struct rtattr *tb_encap[SEG6_IPTUNNEL_MAX + 1] = {};
        struct seg6_iptunnel_encap *ipt = NULL;
@@ -495,6 +496,24 @@ static int parse_encap_seg6(struct rtattr *tb, struct in6_addr *segs)
                ipt = (struct seg6_iptunnel_encap *)
                        RTA_DATA(tb_encap[SEG6_IPTUNNEL_SRH]);
 
+               switch (ipt->mode) {
+               case SEG6_IPTUN_MODE_INLINE:
+                       *encap_behavior = SRV6_HEADEND_BEHAVIOR_H_INSERT;
+                       break;
+               case SEG6_IPTUN_MODE_ENCAP:
+                       *encap_behavior = SRV6_HEADEND_BEHAVIOR_H_ENCAPS;
+                       break;
+               case SEG6_IPTUN_MODE_ENCAP_RED:
+                       *encap_behavior = SRV6_HEADEND_BEHAVIOR_H_ENCAPS_RED;
+                       break;
+               case SEG6_IPTUN_MODE_L2ENCAP:
+                       *encap_behavior = SRV6_HEADEND_BEHAVIOR_H_ENCAPS_L2;
+                       break;
+               case SEG6_IPTUN_MODE_L2ENCAP_RED:
+                       *encap_behavior = SRV6_HEADEND_BEHAVIOR_H_ENCAPS_L2_RED;
+                       break;
+               }
+
                for (i = ipt->srh[0].first_segment; i >= 0; i--)
                        memcpy(&segs[i], &ipt->srh[0].segments[i],
                               sizeof(struct in6_addr));
@@ -519,6 +538,7 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
        struct seg6local_context seg6l_ctx = {};
        struct in6_addr segs[SRV6_MAX_SIDS] = {};
        int num_segs = 0;
+       enum srv6_headend_behavior srv6_encap_behavior = SRV6_HEADEND_BEHAVIOR_H_ENCAPS;
 
        vrf_id_t nh_vrf_id = vrf_id;
        size_t sz = (afi == AFI_IP) ? 4 : 16;
@@ -566,7 +586,7 @@ parse_nexthop_unicast(ns_id_t ns_id, struct rtmsg *rtm, struct rtattr **tb,
        if (tb[RTA_ENCAP] && tb[RTA_ENCAP_TYPE]
            && *(uint16_t *)RTA_DATA(tb[RTA_ENCAP_TYPE])
                       == LWTUNNEL_ENCAP_SEG6) {
-               num_segs = parse_encap_seg6(tb[RTA_ENCAP], segs);
+               num_segs = parse_encap_seg6(tb[RTA_ENCAP], segs, &srv6_encap_behavior);
        }
 
        if (rtm->rtm_flags & RTNH_F_ONLINK)
@@ -611,6 +631,7 @@ static uint16_t parse_multipath_nexthops_unicast(ns_id_t ns_id, struct nexthop_g
        struct seg6local_context seg6l_ctx = {};
        struct in6_addr segs[SRV6_MAX_SIDS] = {};
        int num_segs = 0;
+       enum srv6_headend_behavior srv6_encap_behavior = SRV6_HEADEND_BEHAVIOR_H_ENCAPS;
        struct rtattr *rtnh_tb[RTA_MAX + 1] = {};
 
        int len = RTA_PAYLOAD(tb[RTA_MULTIPATH]);
@@ -664,8 +685,8 @@ static uint16_t parse_multipath_nexthops_unicast(ns_id_t ns_id, struct nexthop_g
                        if (rtnh_tb[RTA_ENCAP] && rtnh_tb[RTA_ENCAP_TYPE]
                            && *(uint16_t *)RTA_DATA(rtnh_tb[RTA_ENCAP_TYPE])
                                       == LWTUNNEL_ENCAP_SEG6) {
-                               num_segs = parse_encap_seg6(rtnh_tb[RTA_ENCAP],
-                                                           segs);
+                               num_segs = parse_encap_seg6(rtnh_tb[RTA_ENCAP], segs,
+                                                           &srv6_encap_behavior);
                        }
                }