forked from Mirror/frr
lib: add new structures for srv6-locator (step2)
This commit is a part of #5853 works that add new structures for SRv6-locator. This structure will be used by zebra and another routing daemon and its ZAPI messaging to manage SRv6-locator. Encoder/decoder for ZAPI stream is also added by this commit. Real configuration mechanism isn't implemented at this commit. later commit add real configure implementation. This commit add only SRv6-locator's structures and misc functions. Signed-off-by: Hiroki Shirokura <slank.dev@gmail.com>
This commit is contained in:
parent
6c0a7c0941
commit
f2867068e6
85
lib/srv6.c
85
lib/srv6.c
|
@ -22,6 +22,10 @@
|
||||||
#include "srv6.h"
|
#include "srv6.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
DEFINE_QOBJ_TYPE(srv6_locator);
|
||||||
|
DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR, "SRV6 locator");
|
||||||
|
DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR_CHUNK, "SRV6 locator chunk");
|
||||||
|
|
||||||
const char *seg6local_action2str(uint32_t action)
|
const char *seg6local_action2str(uint32_t action)
|
||||||
{
|
{
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
@ -117,3 +121,84 @@ const char *seg6local_context2str(char *str, size_t size,
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct srv6_locator *srv6_locator_alloc(const char *name)
|
||||||
|
{
|
||||||
|
struct srv6_locator *locator = NULL;
|
||||||
|
|
||||||
|
locator = XCALLOC(MTYPE_SRV6_LOCATOR, sizeof(struct srv6_locator));
|
||||||
|
strlcpy(locator->name, name, sizeof(locator->name));
|
||||||
|
locator->chunks = list_new();
|
||||||
|
QOBJ_REG(locator, srv6_locator);
|
||||||
|
return locator;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct srv6_locator_chunk *srv6_locator_chunk_alloc(void)
|
||||||
|
{
|
||||||
|
struct srv6_locator_chunk *chunk = NULL;
|
||||||
|
|
||||||
|
chunk = XCALLOC(MTYPE_SRV6_LOCATOR_CHUNK,
|
||||||
|
sizeof(struct srv6_locator_chunk));
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv6_locator_free(struct srv6_locator *locator)
|
||||||
|
{
|
||||||
|
XFREE(MTYPE_SRV6_LOCATOR, locator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void srv6_locator_chunk_free(struct srv6_locator_chunk *chunk)
|
||||||
|
{
|
||||||
|
XFREE(MTYPE_SRV6_LOCATOR_CHUNK, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk)
|
||||||
|
{
|
||||||
|
char str[256];
|
||||||
|
json_object *jo_root = NULL;
|
||||||
|
|
||||||
|
jo_root = json_object_new_object();
|
||||||
|
prefix2str(&chunk->prefix, str, sizeof(str));
|
||||||
|
json_object_string_add(jo_root, "prefix", str);
|
||||||
|
json_object_string_add(jo_root, "proto",
|
||||||
|
zebra_route_string(chunk->proto));
|
||||||
|
|
||||||
|
return jo_root;
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object *srv6_locator_json(const struct srv6_locator *loc)
|
||||||
|
{
|
||||||
|
char str[256];
|
||||||
|
struct listnode *node;
|
||||||
|
struct srv6_locator_chunk *chunk;
|
||||||
|
json_object *jo_root = NULL;
|
||||||
|
json_object *jo_chunk = NULL;
|
||||||
|
json_object *jo_chunks = NULL;
|
||||||
|
|
||||||
|
jo_root = json_object_new_object();
|
||||||
|
|
||||||
|
/* set name */
|
||||||
|
json_object_string_add(jo_root, "name", loc->name);
|
||||||
|
|
||||||
|
/* set prefix */
|
||||||
|
prefix2str(&loc->prefix, str, sizeof(str));
|
||||||
|
json_object_string_add(jo_root, "prefix", str);
|
||||||
|
|
||||||
|
/* set function_bits_length */
|
||||||
|
json_object_int_add(jo_root, "function_bits_length",
|
||||||
|
loc->function_bits_length);
|
||||||
|
|
||||||
|
/* set status_up */
|
||||||
|
json_object_boolean_add(jo_root, "status_up",
|
||||||
|
loc->status_up);
|
||||||
|
|
||||||
|
/* set chunks */
|
||||||
|
jo_chunks = json_object_new_array();
|
||||||
|
json_object_object_add(jo_root, "chunks", jo_chunks);
|
||||||
|
for (ALL_LIST_ELEMENTS_RO((struct list *)loc->chunks, node, chunk)) {
|
||||||
|
jo_chunk = srv6_locator_chunk_json(chunk);
|
||||||
|
json_object_array_add(jo_chunks, jo_chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return jo_root;
|
||||||
|
}
|
||||||
|
|
32
lib/srv6.h
32
lib/srv6.h
|
@ -21,10 +21,14 @@
|
||||||
#define _FRR_SRV6_H
|
#define _FRR_SRV6_H
|
||||||
|
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
|
#include "prefix.h"
|
||||||
|
#include "json.h"
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#define SRV6_MAX_SIDS 16
|
#define SRV6_MAX_SIDS 16
|
||||||
|
#define SRV6_LOCNAME_SIZE 256
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -69,6 +73,27 @@ struct seg6local_context {
|
||||||
uint32_t table;
|
uint32_t table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct srv6_locator {
|
||||||
|
char name[SRV6_LOCNAME_SIZE];
|
||||||
|
struct prefix_ipv6 prefix;
|
||||||
|
uint8_t function_bits_length;
|
||||||
|
int algonum;
|
||||||
|
uint64_t current;
|
||||||
|
bool status_up;
|
||||||
|
struct list *chunks;
|
||||||
|
|
||||||
|
QOBJ_FIELDS;
|
||||||
|
};
|
||||||
|
DECLARE_QOBJ_TYPE(srv6_locator);
|
||||||
|
|
||||||
|
struct srv6_locator_chunk {
|
||||||
|
uint8_t keep;
|
||||||
|
uint8_t proto;
|
||||||
|
uint16_t instance;
|
||||||
|
uint32_t session_id;
|
||||||
|
struct prefix_ipv6 prefix;
|
||||||
|
};
|
||||||
|
|
||||||
static inline const char *seg6_mode2str(enum seg6_mode_t mode)
|
static inline const char *seg6_mode2str(enum seg6_mode_t mode)
|
||||||
{
|
{
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
@ -126,6 +151,13 @@ const char *seg6local_context2str(char *str, size_t size,
|
||||||
int snprintf_seg6_segs(char *str,
|
int snprintf_seg6_segs(char *str,
|
||||||
size_t size, const struct seg6_segs *segs);
|
size_t size, const struct seg6_segs *segs);
|
||||||
|
|
||||||
|
extern struct srv6_locator *srv6_locator_alloc(const char *name);
|
||||||
|
extern struct srv6_locator_chunk *srv6_locator_chunk_alloc(void);
|
||||||
|
extern void srv6_locator_free(struct srv6_locator *locator);
|
||||||
|
extern void srv6_locator_chunk_free(struct srv6_locator_chunk *chunk);
|
||||||
|
json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk);
|
||||||
|
json_object *srv6_locator_json(const struct srv6_locator *loc);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
184
lib/zclient.c
184
lib/zclient.c
|
@ -41,6 +41,7 @@
|
||||||
#include "lib_errors.h"
|
#include "lib_errors.h"
|
||||||
#include "srte.h"
|
#include "srte.h"
|
||||||
#include "printfrr.h"
|
#include "printfrr.h"
|
||||||
|
#include "srv6.h"
|
||||||
|
|
||||||
DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient");
|
DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient");
|
||||||
DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs");
|
DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs");
|
||||||
|
@ -2637,6 +2638,174 @@ stream_failure:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to srv6 manager in a syncronous way
|
||||||
|
*
|
||||||
|
* It first writes the request to zcient output buffer and then
|
||||||
|
* immediately reads the answer from the input buffer.
|
||||||
|
*
|
||||||
|
* @param zclient Zclient used to connect to srv6 manager (zebra)
|
||||||
|
* @result Result of response
|
||||||
|
*/
|
||||||
|
int srv6_manager_connect(struct zclient *zclient)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
int ret, result = 0;
|
||||||
|
uint16_t cmd = ZEBRA_SRV6_MANAGER_CONNECT;
|
||||||
|
|
||||||
|
if (zclient_debug)
|
||||||
|
zlog_debug("Connecting to SRv6 Manager");
|
||||||
|
|
||||||
|
if (zclient->sock < 0) {
|
||||||
|
zlog_debug("%s: invalid zclient socket", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send request */
|
||||||
|
s = zclient->obuf;
|
||||||
|
stream_reset(s);
|
||||||
|
zclient_create_header(s, cmd, VRF_DEFAULT);
|
||||||
|
|
||||||
|
stream_putc(s, zclient->redist_default); /* proto */
|
||||||
|
stream_putw(s, zclient->instance); /* instance */
|
||||||
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
|
ret = writen(zclient->sock, s->data, stream_get_endp(s));
|
||||||
|
if (ret < 0) {
|
||||||
|
flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
|
||||||
|
close(zclient->sock);
|
||||||
|
zclient->sock = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
|
||||||
|
close(zclient->sock);
|
||||||
|
zclient->sock = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (zclient_debug)
|
||||||
|
zlog_debug("SRv6 Manager connect request sent (%d bytes)", ret);
|
||||||
|
|
||||||
|
/* read response */
|
||||||
|
if (zclient_read_sync_response(zclient, cmd)
|
||||||
|
!= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
s = zclient->ibuf;
|
||||||
|
|
||||||
|
/* read instance and proto */
|
||||||
|
uint8_t proto;
|
||||||
|
uint16_t instance;
|
||||||
|
|
||||||
|
STREAM_GETC(s, proto);
|
||||||
|
STREAM_GETW(s, instance);
|
||||||
|
|
||||||
|
/* sanity */
|
||||||
|
if (proto != zclient->redist_default)
|
||||||
|
flog_err(
|
||||||
|
EC_LIB_ZAPI_ENCODE,
|
||||||
|
"Wrong proto (%u) in SRv6 Manager connect response. Should be %u",
|
||||||
|
proto, zclient->redist_default);
|
||||||
|
if (instance != zclient->instance)
|
||||||
|
flog_err(
|
||||||
|
EC_LIB_ZAPI_ENCODE,
|
||||||
|
"Wrong instId (%u) in SRv6 Manager connect response. Should be %u",
|
||||||
|
instance, zclient->instance);
|
||||||
|
|
||||||
|
/* result code */
|
||||||
|
STREAM_GETC(s, result);
|
||||||
|
if (zclient_debug)
|
||||||
|
zlog_debug("SRv6 Manager connect-response received, result %u", result);
|
||||||
|
|
||||||
|
return (int)result;
|
||||||
|
|
||||||
|
stream_failure:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to request a srv6-locator chunk in an Asyncronous way
|
||||||
|
*
|
||||||
|
* It first writes the request to zclient output buffer and then
|
||||||
|
* immediately reads the answer from the input buffer.
|
||||||
|
*
|
||||||
|
* @param zclient Zclient used to connect to table manager (zebra)
|
||||||
|
* @param locator_name Name of SRv6-locator
|
||||||
|
* @result 0 on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
int srv6_manager_get_locator_chunk(struct zclient *zclient,
|
||||||
|
const char *locator_name)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
const size_t len = strlen(locator_name);
|
||||||
|
|
||||||
|
if (zclient_debug)
|
||||||
|
zlog_debug("Getting SRv6-Locator Chunk %s", locator_name);
|
||||||
|
|
||||||
|
if (zclient->sock < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* send request */
|
||||||
|
s = zclient->obuf;
|
||||||
|
stream_reset(s);
|
||||||
|
zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK, VRF_DEFAULT);
|
||||||
|
|
||||||
|
/* proto */
|
||||||
|
stream_putc(s, zclient->redist_default);
|
||||||
|
|
||||||
|
/* instance */
|
||||||
|
stream_putw(s, zclient->instance);
|
||||||
|
|
||||||
|
/* locator_name */
|
||||||
|
stream_putw(s, len);
|
||||||
|
stream_put(s, locator_name, len);
|
||||||
|
|
||||||
|
/* Put length at the first point of the stream. */
|
||||||
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
|
|
||||||
|
return zclient_send_message(zclient);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to release a srv6-locator chunk
|
||||||
|
*
|
||||||
|
* @param zclient Zclient used to connect to table manager (zebra)
|
||||||
|
* @param locator_name Name of SRv6-locator
|
||||||
|
* @result 0 on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
int srv6_manager_release_locator_chunk(struct zclient *zclient,
|
||||||
|
const char *locator_name)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
const size_t len = strlen(locator_name);
|
||||||
|
|
||||||
|
if (zclient_debug)
|
||||||
|
zlog_debug("Releasing SRv6-Locator Chunk %s", locator_name);
|
||||||
|
|
||||||
|
if (zclient->sock < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* send request */
|
||||||
|
s = zclient->obuf;
|
||||||
|
stream_reset(s);
|
||||||
|
zclient_create_header(s, ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK,
|
||||||
|
VRF_DEFAULT);
|
||||||
|
|
||||||
|
/* proto */
|
||||||
|
stream_putc(s, zclient->redist_default);
|
||||||
|
|
||||||
|
/* instance */
|
||||||
|
stream_putw(s, zclient->instance);
|
||||||
|
|
||||||
|
/* locator_name */
|
||||||
|
stream_putw(s, len);
|
||||||
|
stream_put(s, locator_name, len);
|
||||||
|
|
||||||
|
/* Put length at the first point of the stream. */
|
||||||
|
stream_putw_at(s, 0, stream_get_endp(s));
|
||||||
|
|
||||||
|
return zclient_send_message(zclient);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Asynchronous label chunk request
|
* Asynchronous label chunk request
|
||||||
*
|
*
|
||||||
|
@ -3927,6 +4096,21 @@ static int zclient_read(struct thread *thread)
|
||||||
case ZEBRA_MLAG_FORWARD_MSG:
|
case ZEBRA_MLAG_FORWARD_MSG:
|
||||||
zclient_mlag_handle_msg(command, zclient, length, vrf_id);
|
zclient_mlag_handle_msg(command, zclient, length, vrf_id);
|
||||||
break;
|
break;
|
||||||
|
case ZEBRA_SRV6_LOCATOR_ADD:
|
||||||
|
if (zclient->srv6_locator_add)
|
||||||
|
(*zclient->srv6_locator_add)(command, zclient, length,
|
||||||
|
vrf_id);
|
||||||
|
break;
|
||||||
|
case ZEBRA_SRV6_LOCATOR_DELETE:
|
||||||
|
if (zclient->srv6_locator_delete)
|
||||||
|
(*zclient->srv6_locator_delete)(command, zclient,
|
||||||
|
length, vrf_id);
|
||||||
|
break;
|
||||||
|
case ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK:
|
||||||
|
if (zclient->process_srv6_locator_chunk)
|
||||||
|
(*zclient->process_srv6_locator_chunk)(command, zclient,
|
||||||
|
length, vrf_id);
|
||||||
|
break;
|
||||||
case ZEBRA_ERROR:
|
case ZEBRA_ERROR:
|
||||||
zclient_handle_error(command, zclient, length, vrf_id);
|
zclient_handle_error(command, zclient, length, vrf_id);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include "mlag.h"
|
#include "mlag.h"
|
||||||
#include "srte.h"
|
#include "srte.h"
|
||||||
|
#include "srv6.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -216,6 +217,11 @@ typedef enum {
|
||||||
ZEBRA_NHG_NOTIFY_OWNER,
|
ZEBRA_NHG_NOTIFY_OWNER,
|
||||||
ZEBRA_EVPN_REMOTE_NH_ADD,
|
ZEBRA_EVPN_REMOTE_NH_ADD,
|
||||||
ZEBRA_EVPN_REMOTE_NH_DEL,
|
ZEBRA_EVPN_REMOTE_NH_DEL,
|
||||||
|
ZEBRA_SRV6_LOCATOR_ADD,
|
||||||
|
ZEBRA_SRV6_LOCATOR_DELETE,
|
||||||
|
ZEBRA_SRV6_MANAGER_CONNECT,
|
||||||
|
ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK,
|
||||||
|
ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK,
|
||||||
ZEBRA_ERROR,
|
ZEBRA_ERROR,
|
||||||
ZEBRA_CLIENT_CAPABILITIES,
|
ZEBRA_CLIENT_CAPABILITIES,
|
||||||
ZEBRA_OPAQUE_MESSAGE,
|
ZEBRA_OPAQUE_MESSAGE,
|
||||||
|
@ -387,6 +393,11 @@ struct zclient {
|
||||||
int (*mlag_process_down)(void);
|
int (*mlag_process_down)(void);
|
||||||
int (*mlag_handle_msg)(struct stream *msg, int len);
|
int (*mlag_handle_msg)(struct stream *msg, int len);
|
||||||
int (*nhg_notify_owner)(ZAPI_CALLBACK_ARGS);
|
int (*nhg_notify_owner)(ZAPI_CALLBACK_ARGS);
|
||||||
|
int (*srv6_locator_add)(ZAPI_CALLBACK_ARGS);
|
||||||
|
int (*srv6_locator_delete)(ZAPI_CALLBACK_ARGS);
|
||||||
|
int (*srv6_function_add)(ZAPI_CALLBACK_ARGS);
|
||||||
|
int (*srv6_function_delete)(ZAPI_CALLBACK_ARGS);
|
||||||
|
void (*process_srv6_locator_chunk)(ZAPI_CALLBACK_ARGS);
|
||||||
int (*handle_error)(enum zebra_error_types error);
|
int (*handle_error)(enum zebra_error_types error);
|
||||||
int (*opaque_msg_handler)(ZAPI_CALLBACK_ARGS);
|
int (*opaque_msg_handler)(ZAPI_CALLBACK_ARGS);
|
||||||
int (*opaque_register_handler)(ZAPI_CALLBACK_ARGS);
|
int (*opaque_register_handler)(ZAPI_CALLBACK_ARGS);
|
||||||
|
@ -1051,6 +1062,11 @@ extern int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
|
||||||
uint32_t *start, uint32_t *end);
|
uint32_t *start, uint32_t *end);
|
||||||
extern int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
|
extern int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
|
||||||
uint32_t end);
|
uint32_t end);
|
||||||
|
extern int srv6_manager_connect(struct zclient *zclient);
|
||||||
|
extern int srv6_manager_get_locator_chunk(struct zclient *zclient,
|
||||||
|
const char *locator_name);
|
||||||
|
extern int srv6_manager_release_locator_chunk(struct zclient *zclient,
|
||||||
|
const char *locator_name);
|
||||||
|
|
||||||
extern enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient,
|
extern enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient,
|
||||||
int cmd,
|
int cmd,
|
||||||
|
|
Loading…
Reference in a new issue