mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 10:09:17 +00:00
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>
This commit is contained in:
parent
2aa01034f3
commit
76fb7ae4de
@ -1286,6 +1286,26 @@ static bool _netlink_route_encode_nexthop_src(const struct nexthop *nexthop,
|
|||||||
return true;
|
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
|
/* This function takes a nexthop as argument and adds
|
||||||
* the appropriate netlink attributes to an existing
|
* the appropriate netlink attributes to an existing
|
||||||
* netlink message.
|
* netlink message.
|
||||||
@ -1367,6 +1387,21 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
|
|||||||
nl_attr_nest_end(nlmsg, nest);
|
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))
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
||||||
rtmsg->rtm_flags |= RTNH_F_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);
|
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:
|
nexthop_done:
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||||
|
@ -1783,6 +1783,14 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
|
|||||||
&api_nh->seg6local_ctx);
|
&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) {
|
if (IS_ZEBRA_DEBUG_RECV) {
|
||||||
labelbuf[0] = '\0';
|
labelbuf[0] = '\0';
|
||||||
nhbuf[0] = '\0';
|
nhbuf[0] = '\0';
|
||||||
|
@ -1008,6 +1008,7 @@ void nhg_ctx_free(struct nhg_ctx **ctx)
|
|||||||
|
|
||||||
nexthop_del_labels(nh);
|
nexthop_del_labels(nh);
|
||||||
nexthop_del_seg6local(nh);
|
nexthop_del_seg6local(nh);
|
||||||
|
nexthop_del_seg6(nh);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
XFREE(MTYPE_NHG_CTX, *ctx);
|
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. */
|
/* The copy may have allocated labels; free them if necessary. */
|
||||||
nexthop_del_labels(&lookup);
|
nexthop_del_labels(&lookup);
|
||||||
nexthop_del_seg6local(&lookup);
|
nexthop_del_seg6local(&lookup);
|
||||||
|
nexthop_del_seg6(&lookup);
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
||||||
zlog_debug("%s: nh %pNHv => %p (%u)",
|
zlog_debug("%s: nh %pNHv => %p (%u)",
|
||||||
|
@ -662,6 +662,11 @@ static void show_route_nexthop_helper(struct vty *vty,
|
|||||||
buf);
|
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)
|
if (nexthop->weight)
|
||||||
vty_out(vty, ", weight %u", 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_labels = NULL;
|
||||||
json_object *json_backups = NULL;
|
json_object *json_backups = NULL;
|
||||||
json_object *json_seg6local = NULL;
|
json_object *json_seg6local = NULL;
|
||||||
|
json_object *json_seg6 = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
json_object_int_add(json_nexthop, "flags",
|
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_object_object_add(json_nexthop, "seg6local",
|
||||||
json_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,
|
static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
|
||||||
|
Loading…
Reference in New Issue
Block a user