Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for SRv6 SID Manager #15604

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
84 changes: 84 additions & 0 deletions doc/user/zebra.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,35 @@ and this section also helps that case.
!
...

.. clicmd:: format NAME

Specify the SID allocation schema for the SIDs allocated from this locator. Currently,
FRR supports supports the following allocation schemas:

- `usid-f3216`
- `uncompressed`

::

router# configure terminal
router(config)# segment-routinig
router(config-sr)# srv6
router(config-srv6)# locators
router(config-srv6-locators)# locator loc1
router(config-srv6-locator)# prefix fc00:0:1::/48
router(config-srv6-locator)# format usid-f3216

router(config-srv6-locator)# show run
...
segment-routing
srv6
locators
locator loc1
prefix fc00:0:1::/48
format usid-f3216
!
...

.. clicmd:: encapsulation

Configure parameters for SRv6 encapsulation.
Expand All @@ -1029,6 +1058,61 @@ and this section also helps that case.

Configure the source address of the outer encapsulating IPv6 header.

.. clicmd:: formats

Configure SRv6 SID formats.

.. clicmd:: format NAME

Configure SRv6 SID format.

.. clicmd:: compressed usid

Enable SRv6 uSID compression and configure SRv6 uSID compression parameters.

.. clicmd:: local-id-block start START

Configure the start value for the Local ID Block (LIB).

.. clicmd:: local-id-block explicit start START end END

Configure the start/end values for the Explicit LIB (ELIB).

.. clicmd:: wide-local-id-block start START end END

Configure the start/end values for the Wide LIB (W-LIB).

.. clicmd:: wide-local-id-block explicit start START

Configure the start value for the Explicit Wide LIB (EW-LIB).

::

router# configure terminal
router(config)# segment-routinig
router(config-sr)# srv6
router(config-srv6)# formats
router(config-srv6-formats)# format usid-f3216
router(config-srv6-format)# compressed usid
router(config-srv6-format-usid)# local-id-block start 0xD000
router(config-srv6-format-usid)# local-id-block explicit start 0xF000 end 0xFDFF
router(config-srv6-format-usid)# wide-local-id-block start 0xFFF4 end 0xFFF5
router(config-srv6-format-usid)# wide-local-id-block explicit start 0xFFF4

router(config-srv6-locator)# show run
...
segment-routing
srv6
formats
format usid-f3216
compressed usid
local-id-block start 0xD000
local-id-block explicit start 0xF000 end 0xFDFF
wide-local-id-block start 0xFFF4 end 0xFFF5
wide-local-id-block explicit start 0xFFF4
!
...

.. _multicast-rib-commands:

Multicast RIB Commands
Expand Down
3 changes: 3 additions & 0 deletions lib/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ enum node_type {
SRV6_LOCS_NODE, /* SRv6 locators node */
SRV6_LOC_NODE, /* SRv6 locator node */
SRV6_ENCAP_NODE, /* SRv6 encapsulation node */
SRV6_SID_FORMATS_NODE, /* SRv6 SID formats config node */
SRV6_SID_FORMAT_NODE, /* SRv6 SID format config node */
SRV6_SID_FORMAT_USID_NODE, /* SRv6 SID compressed uSID format config node */
VTY_NODE, /* Vty node. */
FPM_NODE, /* Dataplane FPM node. */
LINK_PARAMS_NODE, /* Link-parameters node */
Expand Down
6 changes: 5 additions & 1 deletion lib/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,9 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_SRV6_LOCATOR_DELETE),
DESC_ENTRY(ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK),
DESC_ENTRY(ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK),
DESC_ENTRY(ZEBRA_SRV6_MANAGER_GET_LOCATOR),
DESC_ENTRY(ZEBRA_SRV6_MANAGER_GET_SRV6_SID),
DESC_ENTRY(ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID),
DESC_ENTRY(ZEBRA_ERROR),
DESC_ENTRY(ZEBRA_CLIENT_CAPABILITIES),
DESC_ENTRY(ZEBRA_OPAQUE_MESSAGE),
Expand All @@ -461,7 +464,8 @@ static const struct zebra_desc_table command_types[] = {
DESC_ENTRY(ZEBRA_TC_CLASS_DELETE),
DESC_ENTRY(ZEBRA_TC_FILTER_ADD),
DESC_ENTRY(ZEBRA_TC_FILTER_DELETE),
DESC_ENTRY(ZEBRA_OPAQUE_NOTIFY)
DESC_ENTRY(ZEBRA_OPAQUE_NOTIFY),
DESC_ENTRY(ZEBRA_SRV6_SID_NOTIFY)
};
#undef DESC_ENTRY

Expand Down
24 changes: 24 additions & 0 deletions lib/srv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
DEFINE_QOBJ_TYPE(srv6_locator);
DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR, "SRV6 locator");
DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR_CHUNK, "SRV6 locator chunk");
DEFINE_MTYPE_STATIC(LIB, SRV6_SID_CTX, "SRv6 SID context");

const char *seg6local_action2str(uint32_t action)
{
Expand Down Expand Up @@ -154,6 +155,29 @@ void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk)
XFREE(MTYPE_SRV6_LOCATOR_CHUNK, *chunk);
}

struct srv6_sid_ctx *srv6_sid_ctx_alloc(enum seg6local_action_t behavior,
struct in_addr *nh4,
struct in6_addr *nh6, vrf_id_t vrf_id)
{
struct srv6_sid_ctx *ctx = NULL;

ctx = XCALLOC(MTYPE_SRV6_SID_CTX, sizeof(struct srv6_sid_ctx));
ctx->behavior = behavior;
if (nh4)
ctx->nh4 = *nh4;
if (nh6)
ctx->nh6 = *nh6;
if (vrf_id)
ctx->vrf_id = vrf_id;

return ctx;
}

void srv6_sid_ctx_free(struct srv6_sid_ctx *ctx)
{
XFREE(MTYPE_SRV6_SID_CTX, ctx);
}

json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk)
{
json_object *jo_root = NULL;
Expand Down
71 changes: 71 additions & 0 deletions lib/srv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ struct srv6_locator {
uint8_t flags;
#define SRV6_LOCATOR_USID (1 << 0) /* The SRv6 Locator is a uSID Locator */

/* Pointer to the SID format. */
void *sid_format;

/* Pointer to the parent SID block of the locator. */
void *sid_block;

QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(srv6_locator);
Expand Down Expand Up @@ -183,6 +189,17 @@ struct nexthop_srv6 {
struct seg6_seg_stack *seg6_segs;
};

/* Context for an SRv6 SID */
struct srv6_sid_ctx {
/* Behavior associated with the SID */
enum seg6local_action_t behavior;

/* Behavior-specific attributes */
struct in_addr nh4;
struct in6_addr nh6;
vrf_id_t vrf_id;
};

static inline const char *seg6_mode2str(enum seg6_mode_t mode)
{
switch (mode) {
Expand Down Expand Up @@ -246,6 +263,54 @@ const char *seg6local_context2str(char *str, size_t size,
const struct seg6local_context *ctx,
uint32_t action);

static inline const char *srv6_sid_ctx2str(char *str, size_t size,
const struct srv6_sid_ctx *ctx)
{
int len = 0;

len += snprintf(str + len, size - len, "%s",
seg6local_action2str(ctx->behavior));

switch (ctx->behavior) {
case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC:
break;

case ZEBRA_SEG6_LOCAL_ACTION_END:
len += snprintf(str + len, size - len, " USP");
break;

case ZEBRA_SEG6_LOCAL_ACTION_END_X:
case ZEBRA_SEG6_LOCAL_ACTION_END_DX6:
len += snprintfrr(str + len, size - len, " nh6 %pI6", &ctx->nh6);
break;

case ZEBRA_SEG6_LOCAL_ACTION_END_DX4:
len += snprintfrr(str + len, size - len, " nh4 %pI4", &ctx->nh4);
break;

case ZEBRA_SEG6_LOCAL_ACTION_END_T:
case ZEBRA_SEG6_LOCAL_ACTION_END_DT6:
case ZEBRA_SEG6_LOCAL_ACTION_END_DT4:
case ZEBRA_SEG6_LOCAL_ACTION_END_DT46:
len += snprintf(str + len, size - len, " vrf_id %u",
ctx->vrf_id);
break;

case ZEBRA_SEG6_LOCAL_ACTION_END_DX2:
case ZEBRA_SEG6_LOCAL_ACTION_END_B6:
case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP:
case ZEBRA_SEG6_LOCAL_ACTION_END_BM:
case ZEBRA_SEG6_LOCAL_ACTION_END_S:
case ZEBRA_SEG6_LOCAL_ACTION_END_AS:
case ZEBRA_SEG6_LOCAL_ACTION_END_AM:
case ZEBRA_SEG6_LOCAL_ACTION_END_BPF:
default:
len += snprintf(str + len, size - len, " unknown(%s)", __func__);
}

return str;
}

int snprintf_seg6_segs(char *str,
size_t size, const struct seg6_segs *segs);

Expand All @@ -260,6 +325,12 @@ json_object *srv6_locator_detailed_json(const struct srv6_locator *loc);
json_object *
srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk);

extern struct srv6_sid_ctx *srv6_sid_ctx_alloc(enum seg6local_action_t behavior,
struct in_addr *nh4,
struct in6_addr *nh6,
vrf_id_t vrf_id);
extern void srv6_sid_ctx_free(struct srv6_sid_ctx *ctx);

#ifdef __cplusplus
}
#endif
Expand Down