mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 20:32:18 +00:00
zebra: ZEBRA_ROUTE_ADD supports seg6local route (step1)
With this patch, zclient can intall seg6local rotues whem they set properties nh_seg6local_{action,ctx} on struct nexthop and set ZEBRA_FLAG_SEG6LOCAL_ROUTE on zapi_route's flag. Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
This commit is contained in:
parent
cb7775a974
commit
8689b25a08
@ -22,9 +22,18 @@
|
||||
|
||||
#ifdef HAVE_NETLINK
|
||||
|
||||
/* The following definition is to workaround an issue in the Linux kernel
|
||||
* header files with redefinition of 'struct in6_addr' in both
|
||||
* netinet/in.h and linux/in6.h.
|
||||
* Reference - https://sourceware.org/ml/libc-alpha/2013-01/msg00599.html
|
||||
*/
|
||||
#define _LINUX_IN6_H
|
||||
|
||||
#include <net/if_arp.h>
|
||||
#include <linux/lwtunnel.h>
|
||||
#include <linux/mpls_iptunnel.h>
|
||||
#include <linux/seg6_iptunnel.h>
|
||||
#include <linux/seg6_local.h>
|
||||
#include <linux/neighbour.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/nexthop.h>
|
||||
@ -38,6 +47,8 @@
|
||||
#include "if.h"
|
||||
#include "log.h"
|
||||
#include "prefix.h"
|
||||
#include "plist.h"
|
||||
#include "plist_int.h"
|
||||
#include "connected.h"
|
||||
#include "table.h"
|
||||
#include "memory.h"
|
||||
@ -1262,6 +1273,52 @@ static bool _netlink_route_build_singlepath(const struct prefix *p,
|
||||
sizeof(label_buf)))
|
||||
return false;
|
||||
|
||||
if (nexthop->nh_seg6local_ctx) {
|
||||
struct rtattr *nest;
|
||||
const struct seg6local_context *ctx;
|
||||
|
||||
ctx = nexthop->nh_seg6local_ctx;
|
||||
nl_attr_put16(nlmsg, req_size, RTA_ENCAP_TYPE,
|
||||
LWTUNNEL_ENCAP_SEG6_LOCAL);
|
||||
|
||||
nest = nl_attr_nest(nlmsg, req_size, RTA_ENCAP);
|
||||
switch (nexthop->nh_seg6local_action) {
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END:
|
||||
nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END);
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_X:
|
||||
nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_X);
|
||||
nl_attr_put(nlmsg, req_size, SEG6_LOCAL_NH6, &ctx->nh6,
|
||||
sizeof(struct in6_addr));
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_T:
|
||||
nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_T);
|
||||
nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_TABLE,
|
||||
ctx->table);
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_DX4:
|
||||
nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DX4);
|
||||
nl_attr_put(nlmsg, req_size, SEG6_LOCAL_NH4, &ctx->nh4,
|
||||
sizeof(struct in_addr));
|
||||
break;
|
||||
case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
|
||||
nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DT6);
|
||||
nl_attr_put32(nlmsg, req_size, SEG6_LOCAL_TABLE,
|
||||
ctx->table);
|
||||
break;
|
||||
default:
|
||||
zlog_err("%s: unsupport seg6local behaviour action=%u",
|
||||
__func__, nexthop->nh_seg6local_action);
|
||||
break;
|
||||
}
|
||||
nl_attr_nest_end(nlmsg, nest);
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK))
|
||||
rtmsg->rtm_flags |= RTNH_F_ONLINK;
|
||||
|
||||
@ -2256,6 +2313,67 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
|
||||
nl_attr_nest_end(&req->n, nest);
|
||||
}
|
||||
|
||||
if (nh->nh_seg6local_ctx) {
|
||||
uint32_t action;
|
||||
uint16_t encap;
|
||||
struct rtattr *nest;
|
||||
const struct seg6local_context *ctx;
|
||||
|
||||
req->nhm.nh_family = AF_INET6;
|
||||
action = nh->nh_seg6local_action;
|
||||
ctx = nh->nh_seg6local_ctx;
|
||||
encap = LWTUNNEL_ENCAP_SEG6_LOCAL;
|
||||
nl_attr_put(&req->n, buflen, NHA_ENCAP_TYPE,
|
||||
&encap, sizeof(uint16_t));
|
||||
|
||||
nest = nl_attr_nest(&req->n, buflen,
|
||||
NHA_ENCAP | NLA_F_NESTED);
|
||||
switch (action) {
|
||||
case SEG6_LOCAL_ACTION_END:
|
||||
nl_attr_put32(&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END);
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_X:
|
||||
nl_attr_put32(&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_X);
|
||||
nl_attr_put(&req->n, buflen,
|
||||
SEG6_LOCAL_NH6, &ctx->nh6,
|
||||
sizeof(struct in6_addr));
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_T:
|
||||
nl_attr_put32(&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_T);
|
||||
nl_attr_put32(&req->n, buflen,
|
||||
SEG6_LOCAL_TABLE,
|
||||
ctx->table);
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_DX4:
|
||||
nl_attr_put32(&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DX4);
|
||||
nl_attr_put(&req->n, buflen,
|
||||
SEG6_LOCAL_NH4, &ctx->nh4,
|
||||
sizeof(struct in_addr));
|
||||
break;
|
||||
case SEG6_LOCAL_ACTION_END_DT6:
|
||||
nl_attr_put32(&req->n, buflen,
|
||||
SEG6_LOCAL_ACTION,
|
||||
SEG6_LOCAL_ACTION_END_DT6);
|
||||
nl_attr_put32(&req->n, buflen,
|
||||
SEG6_LOCAL_TABLE,
|
||||
ctx->table);
|
||||
break;
|
||||
default:
|
||||
zlog_err("%s: unsupport seg6local behaviour action=%u",
|
||||
__func__, action);
|
||||
break;
|
||||
}
|
||||
nl_attr_nest_end(&req->n, nest);
|
||||
}
|
||||
|
||||
nexthop_done:
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
|
@ -1747,6 +1747,18 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
|
||||
&api_nh->labels[0]);
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(flags, ZEBRA_FLAG_SEG6LOCAL_ROUTE)
|
||||
&& api_nh->type != NEXTHOP_TYPE_BLACKHOLE) {
|
||||
if (IS_ZEBRA_DEBUG_RECV)
|
||||
zlog_debug("%s: adding seg6local action %s",
|
||||
__func__,
|
||||
seg6local_action2str(
|
||||
api_nh->seg6local_action));
|
||||
|
||||
nexthop_add_seg6local(nexthop, api_nh->seg6local_action,
|
||||
&api_nh->seg6local_ctx);
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_RECV) {
|
||||
labelbuf[0] = '\0';
|
||||
nhbuf[0] = '\0';
|
||||
|
@ -1007,6 +1007,7 @@ void nhg_ctx_free(struct nhg_ctx **ctx)
|
||||
nh = nhg_ctx_get_nh(*ctx);
|
||||
|
||||
nexthop_del_labels(nh);
|
||||
nexthop_del_seg6local(nh);
|
||||
|
||||
done:
|
||||
XFREE(MTYPE_NHG_CTX, *ctx);
|
||||
@ -1377,6 +1378,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);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
||||
zlog_debug("%s: nh %pNHv => %p (%u)",
|
||||
|
@ -653,6 +653,15 @@ static void show_route_nexthop_helper(struct vty *vty,
|
||||
sizeof(buf), 1));
|
||||
}
|
||||
|
||||
if (nexthop->nh_seg6local_ctx) {
|
||||
seg6local_context2str(buf, sizeof(buf),
|
||||
nexthop->nh_seg6local_ctx,
|
||||
nexthop->nh_seg6local_action);
|
||||
vty_out(vty, ", seg6local %s %s",
|
||||
seg6local_action2str(nexthop->nh_seg6local_action),
|
||||
buf);
|
||||
}
|
||||
|
||||
if (nexthop->weight)
|
||||
vty_out(vty, ", weight %u", nexthop->weight);
|
||||
|
||||
@ -675,6 +684,7 @@ static void show_nexthop_json_helper(json_object *json_nexthop,
|
||||
char buf[SRCDEST2STR_BUFFER];
|
||||
json_object *json_labels = NULL;
|
||||
json_object *json_backups = NULL;
|
||||
json_object *json_seg6local = NULL;
|
||||
int i;
|
||||
|
||||
json_object_int_add(json_nexthop, "flags",
|
||||
@ -852,6 +862,15 @@ static void show_nexthop_json_helper(json_object *json_nexthop,
|
||||
if (nexthop->srte_color)
|
||||
json_object_int_add(json_nexthop, "srteColor",
|
||||
nexthop->srte_color);
|
||||
|
||||
if (nexthop->nh_seg6local_ctx) {
|
||||
json_seg6local = json_object_new_object();
|
||||
json_object_string_add(
|
||||
json_seg6local, "action",
|
||||
seg6local_action2str(nexthop->nh_seg6local_action));
|
||||
json_object_object_add(json_nexthop, "seg6local",
|
||||
json_seg6local);
|
||||
}
|
||||
}
|
||||
|
||||
static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
|
||||
|
Loading…
Reference in New Issue
Block a user