]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: ZEBRA_ROUTE_ADD supports seg6 route (step3)
authorHiroki Shirokura <slank.dev@gmail.com>
Thu, 17 Dec 2020 14:43:01 +0000 (23:43 +0900)
committerMark Stapp <mjs@voltanet.io>
Wed, 2 Jun 2021 14:24:48 +0000 (10:24 -0400)
With this patch, zclient can intall seg6 rotues when
they set properties "nh_seg6_segs" on struct nexthop
and set ZEBRA_FLAG_SEG6_ROUTE on zapi_route's flag.

Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
zebra/rt_netlink.c
zebra/zapi_msg.c
zebra/zebra_nhg.c
zebra/zebra_vty.c

index 2ddda7449ca0882a0547fd21727022956f35ff71..00eb0b6644e1e0535af719e300bbf70f66fa819d 100644 (file)
@@ -1286,6 +1286,26 @@ static bool _netlink_route_encode_nexthop_src(const struct nexthop *nexthop,
        return true;
 }
 
+static size_t fill_seg6ipt_encap(char *buffer, size_t buflen,
+                                struct in6_addr *seg)
+{
+       struct seg6_iptunnel_encap *ipt;
+       struct ipv6_sr_hdr *srh;
+       const size_t srhlen = 24;
+       memset(buffer, 0, buflen);
+
+       ipt = (struct seg6_iptunnel_encap *)buffer;
+       ipt->mode = SEG6_IPTUN_MODE_ENCAP;
+       srh = ipt->srh;
+       srh->hdrlen = (srhlen >> 3) - 1;
+       srh->type = 4;
+       srh->segments_left = 0;
+       srh->first_segment = 0;
+       memcpy(&srh->segments[0], seg, sizeof(struct in6_addr));
+
+       return srhlen + 4;
+}
+
 /* This function takes a nexthop as argument and adds
  * the appropriate netlink attributes to an existing
  * netlink message.
@@ -1367,6 +1387,21 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
                nl_attr_nest_end(nlmsg, nest);
        }
 
+       if (nexthop->nh_seg6_segs) {
+               char tun_buf[4096];
+               size_t tun_len;
+               struct rtattr *nest;
+
+               nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE,
+                             LWTUNNEL_ENCAP_SEG6);
+               nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
+               tun_len = fill_seg6ipt_encap(tun_buf, sizeof(tun_buf),
+                                            nexthop->nh_seg6_segs);
+               nl_attr_put(nlmsg, req_size, SEG6_IPTUNNEL_SRH,
+                           tun_buf, tun_len);
+               nl_attr_nest_end(nlmsg, nest);
+       }
+
        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
                rtmsg->rtm_flags |= RTNH_F_ONLINK;
 
@@ -2422,6 +2457,23 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
                                nl_attr_nest_end(&req->n, nest);
                        }
 
+                       if (nh->nh_seg6_segs) {
+                               char tun_buf[4096];
+                               size_t tun_len;
+                               struct rtattr *nest;
+
+                               nl_attr_put16(&req->n, buflen, NHA_ENCAP_TYPE,
+                                             LWTUNNEL_ENCAP_SEG6);
+                               nest = nl_attr_nest(&req->n, buflen,
+                                                   NHA_ENCAP | NLA_F_NESTED);
+                               tun_len = fill_seg6ipt_encap(tun_buf,
+                                               sizeof(tun_buf),
+                                               nh->nh_seg6_segs);
+                               nl_attr_put(&req->n, buflen, SEG6_IPTUNNEL_SRH,
+                                               tun_buf, tun_len);
+                               nl_attr_nest_end(&req->n, nest);
+                       }
+
 nexthop_done:
 
                        if (IS_ZEBRA_DEBUG_KERNEL)
index fa6a4cfca7ca752b5802ea9799a5ab81878960a9..25c51e2227e262644524cc25cc2371d69ddfc392 100644 (file)
@@ -1783,6 +1783,14 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
                                              &api_nh->seg6local_ctx);
                }
 
+               if (CHECK_FLAG(flags, ZEBRA_FLAG_SEG6_ROUTE)
+                   && api_nh->type != NEXTHOP_TYPE_BLACKHOLE) {
+                       if (IS_ZEBRA_DEBUG_RECV)
+                               zlog_debug("%s: adding seg6", __func__);
+
+                       nexthop_add_seg6(nexthop, &api_nh->seg6_segs);
+               }
+
                if (IS_ZEBRA_DEBUG_RECV) {
                        labelbuf[0] = '\0';
                        nhbuf[0] = '\0';
index ddd37b4df7d33e2ffb5cdf9e7360799e00fd85d7..84ce97b00890863dbf7b86d52565adf479a41232 100644 (file)
@@ -1008,6 +1008,7 @@ void nhg_ctx_free(struct nhg_ctx **ctx)
 
        nexthop_del_labels(nh);
        nexthop_del_seg6local(nh);
+       nexthop_del_seg6(nh);
 
 done:
        XFREE(MTYPE_NHG_CTX, *ctx);
@@ -1379,6 +1380,7 @@ static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh,
        /* The copy may have allocated labels; free them if necessary. */
        nexthop_del_labels(&lookup);
        nexthop_del_seg6local(&lookup);
+       nexthop_del_seg6(&lookup);
 
        if (IS_ZEBRA_DEBUG_NHG_DETAIL)
                zlog_debug("%s: nh %pNHv => %p (%u)",
index c178ce075c6cd8eaf3a87371c9ac5f2454f74a6a..fae443ca2ec1b81a9d07c4071c01b9a88aaa26cf 100644 (file)
@@ -662,6 +662,11 @@ static void show_route_nexthop_helper(struct vty *vty,
                        buf);
        }
 
+       if (nexthop->nh_seg6_segs) {
+               inet_ntop(AF_INET6, nexthop->nh_seg6_segs, buf, sizeof(buf));
+               vty_out(vty, ", seg6 %s", buf);
+       }
+
        if (nexthop->weight)
                vty_out(vty, ", weight %u", nexthop->weight);
 
@@ -685,6 +690,7 @@ static void show_nexthop_json_helper(json_object *json_nexthop,
        json_object *json_labels = NULL;
        json_object *json_backups = NULL;
        json_object *json_seg6local = NULL;
+       json_object *json_seg6 = NULL;
        int i;
 
        json_object_int_add(json_nexthop, "flags",
@@ -871,6 +877,13 @@ static void show_nexthop_json_helper(json_object *json_nexthop,
                json_object_object_add(json_nexthop, "seg6local",
                                       json_seg6local);
        }
+
+       if (nexthop->nh_seg6_segs) {
+               json_seg6 = json_object_new_object();
+               inet_ntop(AF_INET6, nexthop->nh_seg6_segs, buf, sizeof(buf));
+               json_object_string_add(json_seg6, "segs", buf);
+               json_object_object_add(json_nexthop, "seg6", json_seg6);
+       }
 }
 
 static void vty_show_ip_route(struct vty *vty, struct route_node *rn,