mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
staticd: Add infrastructure for SRv6
This commit adds datastructures and helper functions required to support SRv6 in staticd. * List of locators * List of SIDs * Data structure to represent an SRv6 SID * Functions to allocate/deallocate an SRv6 SID * Functions to allocate, deallocate and lookup a locator * Function to initialize/Cleanup SRv6 Signed-off-by: Yuqing Zhao <galadriel.zyq@alibaba-inc.com>
This commit is contained in:
parent
2025a0c617
commit
807d90050d
134
staticd/static_srv6.c
Normal file
134
staticd/static_srv6.c
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* STATICd - Segment Routing over IPv6 (SRv6) code
|
||||||
|
* Copyright (C) 2025 Alibaba Inc.
|
||||||
|
* Yuqing Zhao
|
||||||
|
* Lingyu Zhang
|
||||||
|
*/
|
||||||
|
#include <zebra.h>
|
||||||
|
|
||||||
|
#include "vrf.h"
|
||||||
|
#include "nexthop.h"
|
||||||
|
|
||||||
|
#include "static_routes.h"
|
||||||
|
#include "static_srv6.h"
|
||||||
|
#include "static_vrf.h"
|
||||||
|
#include "static_zebra.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of SRv6 SIDs.
|
||||||
|
*/
|
||||||
|
struct list *srv6_locators;
|
||||||
|
struct list *srv6_sids;
|
||||||
|
|
||||||
|
DEFINE_MTYPE_STATIC(STATIC, STATIC_SRV6_LOCATOR, "Static SRv6 locator");
|
||||||
|
DEFINE_MTYPE_STATIC(STATIC, STATIC_SRV6_SID, "Static SRv6 SID");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate an SRv6 SID object and initialize the fields common to all the
|
||||||
|
* behaviors (i.e., SID address and behavor).
|
||||||
|
*/
|
||||||
|
struct static_srv6_sid *static_srv6_sid_alloc(struct prefix_ipv6 *addr)
|
||||||
|
{
|
||||||
|
struct static_srv6_sid *sid = NULL;
|
||||||
|
|
||||||
|
sid = XCALLOC(MTYPE_STATIC_SRV6_SID, sizeof(struct static_srv6_sid));
|
||||||
|
sid->addr = *addr;
|
||||||
|
|
||||||
|
return sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void static_srv6_sid_free(struct static_srv6_sid *sid)
|
||||||
|
{
|
||||||
|
XFREE(MTYPE_STATIC_SRV6_SID, sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct static_srv6_locator *static_srv6_locator_lookup(const char *name)
|
||||||
|
{
|
||||||
|
struct static_srv6_locator *locator;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(srv6_locators, node, locator))
|
||||||
|
if (!strncmp(name, locator->name, SRV6_LOCNAME_SIZE))
|
||||||
|
return locator;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look-up an SRv6 SID in the list of SRv6 SIDs.
|
||||||
|
*/
|
||||||
|
struct static_srv6_sid *static_srv6_sid_lookup(struct prefix_ipv6 *sid_addr)
|
||||||
|
{
|
||||||
|
struct static_srv6_sid *sid;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(srv6_sids, node, sid))
|
||||||
|
if (memcmp(&sid->addr, sid_addr, sizeof(struct prefix_ipv6)) == 0)
|
||||||
|
return sid;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct static_srv6_locator *static_srv6_locator_alloc(const char *name)
|
||||||
|
{
|
||||||
|
struct static_srv6_locator *locator = NULL;
|
||||||
|
|
||||||
|
locator = XCALLOC(MTYPE_STATIC_SRV6_LOCATOR, sizeof(struct static_srv6_locator));
|
||||||
|
strlcpy(locator->name, name, sizeof(locator->name));
|
||||||
|
|
||||||
|
return locator;
|
||||||
|
}
|
||||||
|
|
||||||
|
void static_srv6_locator_free(struct static_srv6_locator *locator)
|
||||||
|
{
|
||||||
|
XFREE(MTYPE_STATIC_SRV6_LOCATOR, locator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_static_srv6_locator(void *val)
|
||||||
|
{
|
||||||
|
static_srv6_locator_free((struct static_srv6_locator *)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove an SRv6 SID from the zebra RIB (if it was previously installed) and
|
||||||
|
* release the memory previously allocated for the SID.
|
||||||
|
*/
|
||||||
|
void static_srv6_sid_del(struct static_srv6_sid *sid)
|
||||||
|
{
|
||||||
|
if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID)) {
|
||||||
|
static_zebra_release_srv6_sid(sid);
|
||||||
|
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CHECK_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA)) {
|
||||||
|
static_zebra_srv6_sid_uninstall(sid);
|
||||||
|
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA);
|
||||||
|
}
|
||||||
|
|
||||||
|
XFREE(MTYPE_STATIC_SRV6_SID, sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void delete_static_srv6_sid(void *val)
|
||||||
|
{
|
||||||
|
static_srv6_sid_free((struct static_srv6_sid *)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize SRv6 data structures.
|
||||||
|
*/
|
||||||
|
void static_srv6_init(void)
|
||||||
|
{
|
||||||
|
srv6_locators = list_new();
|
||||||
|
srv6_locators->del = delete_static_srv6_locator;
|
||||||
|
srv6_sids = list_new();
|
||||||
|
srv6_sids->del = delete_static_srv6_sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clean up all the SRv6 data structures.
|
||||||
|
*/
|
||||||
|
void static_srv6_cleanup(void)
|
||||||
|
{
|
||||||
|
list_delete(&srv6_locators);
|
||||||
|
list_delete(&srv6_sids);
|
||||||
|
}
|
99
staticd/static_srv6.h
Normal file
99
staticd/static_srv6.h
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* STATICd - Segment Routing over IPv6 (SRv6) header
|
||||||
|
* Copyright (C) 2025 Alibaba Inc.
|
||||||
|
* Yuqing Zhao
|
||||||
|
* Lingyu Zhang
|
||||||
|
*/
|
||||||
|
#ifndef __STATIC_SRV6_H__
|
||||||
|
#define __STATIC_SRV6_H__
|
||||||
|
|
||||||
|
#include "vrf.h"
|
||||||
|
#include "srv6.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Attributes for an SRv6 SID */
|
||||||
|
struct static_srv6_sid_attributes {
|
||||||
|
/* VRF name */
|
||||||
|
char vrf_name[VRF_NAMSIZ];
|
||||||
|
char ifname[IFNAMSIZ];
|
||||||
|
struct in6_addr nh6;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Static SRv6 SID */
|
||||||
|
struct static_srv6_sid {
|
||||||
|
/* SRv6 SID address */
|
||||||
|
struct prefix_ipv6 addr;
|
||||||
|
/* behavior bound to the SRv6 SID */
|
||||||
|
enum srv6_endpoint_behavior_codepoint behavior;
|
||||||
|
/* SID attributes */
|
||||||
|
struct static_srv6_sid_attributes attributes;
|
||||||
|
|
||||||
|
/* SRv6 SID flags */
|
||||||
|
uint8_t flags;
|
||||||
|
/*
|
||||||
|
* this SRv6 SID has been allocated by SID Manager
|
||||||
|
* and can be installed in the zebra RIB
|
||||||
|
*/
|
||||||
|
#define STATIC_FLAG_SRV6_SID_VALID (1 << 0)
|
||||||
|
/* this SRv6 SID has been installed in the zebra RIB */
|
||||||
|
#define STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA (1 << 1)
|
||||||
|
|
||||||
|
char locator_name[SRV6_LOCNAME_SIZE];
|
||||||
|
struct static_srv6_locator *locator;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct static_srv6_locator {
|
||||||
|
char name[SRV6_LOCNAME_SIZE];
|
||||||
|
struct prefix_ipv6 prefix;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bit length of SRv6 locator described in
|
||||||
|
* draft-ietf-bess-srv6-services-05#section-3.2.1
|
||||||
|
*/
|
||||||
|
uint8_t block_bits_length;
|
||||||
|
uint8_t node_bits_length;
|
||||||
|
uint8_t function_bits_length;
|
||||||
|
uint8_t argument_bits_length;
|
||||||
|
|
||||||
|
uint8_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* List of SRv6 SIDs. */
|
||||||
|
extern struct list *srv6_locators;
|
||||||
|
extern struct list *srv6_sids;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate an SRv6 SID object and initialize its fields, SID address and
|
||||||
|
* behavor.
|
||||||
|
*/
|
||||||
|
extern struct static_srv6_sid *static_srv6_sid_alloc(struct prefix_ipv6 *addr);
|
||||||
|
extern void static_srv6_sid_free(struct static_srv6_sid *sid);
|
||||||
|
/* Look-up an SRv6 SID in the list of SRv6 SIDs. */
|
||||||
|
extern struct static_srv6_sid *static_srv6_sid_lookup(struct prefix_ipv6 *sid_addr);
|
||||||
|
/*
|
||||||
|
* Remove an SRv6 SID from the zebra RIB (if it was previously installed) and
|
||||||
|
* release the memory previously allocated for the SID.
|
||||||
|
*/
|
||||||
|
extern void static_srv6_sid_del(struct static_srv6_sid *sid);
|
||||||
|
|
||||||
|
/* Initialize SRv6 data structures. */
|
||||||
|
extern void static_srv6_init(void);
|
||||||
|
/* Clean up all the SRv6 data structures. */
|
||||||
|
extern void static_srv6_cleanup(void);
|
||||||
|
|
||||||
|
struct static_srv6_locator *static_srv6_locator_alloc(const char *name);
|
||||||
|
void static_srv6_locator_free(struct static_srv6_locator *locator);
|
||||||
|
struct static_srv6_locator *static_srv6_locator_lookup(const char *name);
|
||||||
|
|
||||||
|
void delete_static_srv6_sid(void *val);
|
||||||
|
void delete_static_srv6_locator(void *val);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STATIC_SRV6_H__ */
|
|
@ -19,6 +19,7 @@ staticd_libstatic_a_SOURCES = \
|
||||||
staticd/static_vty.c \
|
staticd/static_vty.c \
|
||||||
staticd/static_nb.c \
|
staticd/static_nb.c \
|
||||||
staticd/static_nb_config.c \
|
staticd/static_nb_config.c \
|
||||||
|
staticd/static_srv6.c \
|
||||||
# end
|
# end
|
||||||
|
|
||||||
noinst_HEADERS += \
|
noinst_HEADERS += \
|
||||||
|
@ -29,6 +30,7 @@ noinst_HEADERS += \
|
||||||
staticd/static_vty.h \
|
staticd/static_vty.h \
|
||||||
staticd/static_vrf.h \
|
staticd/static_vrf.h \
|
||||||
staticd/static_nb.h \
|
staticd/static_nb.h \
|
||||||
|
staticd/static_srv6.h \
|
||||||
# end
|
# end
|
||||||
|
|
||||||
clippy_scan += \
|
clippy_scan += \
|
||||||
|
|
Loading…
Reference in a new issue