diff options
author | Hiroki Shirokura <slank.dev@gmail.com> | 2020-12-17 15:43:01 +0100 |
---|---|---|
committer | Mark Stapp <mjs@voltanet.io> | 2021-06-02 16:24:48 +0200 |
commit | 76fb7ae4dea7604afe1185df91de941d9e3ce58f (patch) | |
tree | 136d629c32287630a959bc687294baa9c5964d9c /zebra/rt_netlink.c | |
parent | lib: add new nexthop's attributes seg6 (step3) (diff) | |
download | frr-76fb7ae4dea7604afe1185df91de941d9e3ce58f.tar.xz frr-76fb7ae4dea7604afe1185df91de941d9e3ce58f.zip |
zebra: ZEBRA_ROUTE_ADD supports seg6 route (step3)
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>
Diffstat (limited to 'zebra/rt_netlink.c')
-rw-r--r-- | zebra/rt_netlink.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 2ddda7449..00eb0b664 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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) |