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 CLI about locator and related funcs #16894

Open
wants to merge 3 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions doc/user/zebra.rst
Original file line number Diff line number Diff line change
Expand Up @@ -894,19 +894,27 @@ and this section also helps that case.
function development holds the owner of the chunk of this locator, and no
other routing protocol will use this area.

Additionally, if a static local SID is configured,
it will also be displayed in this section.

::

router# show segment-routing srv6 locator loc1 detail
Name: loc1
Prefix: 2001:db8:1:1::/64
Chunks:
- prefix: 2001:db8:1:1::/64, owner: system
sids:
-sid 2001:db8:1:1:fff1:11::/128
behavior End.uDT46
vrf Vrf1

router# show segment-routing srv6 locator loc2 detail
Name: loc2
Prefix: 2001:db8:2:2::/64
Chunks:
- prefix: 2001:db8:2:2::/64, owner: sharp
sids:

.. clicmd:: segment-routing

Expand Down Expand Up @@ -991,6 +999,43 @@ and this section also helps that case.
!
...

.. clicmd:: sid WORD behavior <uN|uDT4|uDT6|uDT46> [vrf VRF]

Specify the locator sid manually. Configuring a local sid in a purely static mode
by specifying the sid value would generate a unique mySID table entry.
This feature will support the configuration of static SRv6 decapsulation on the system.

It supports four parameter options, corresponding to the following functions:
End.uN, End.uDT4, End.uDT6, End.uDT46

When configuring the local sid, if the action is set to 'uN', no vrf should be set.
While for any other action, it is necessary to specify a specific vrf.

::

router# configure terminal
router(config)# segment-routing
router(config-sr)# srv6
router(config-srv6)# locators
router(config-srv6-locators)# locator loc1
router(config-srv6-locator)# prefix fcbb:bbbb:1::/48 block-len 32 node-len 16 func-bits 16
router(config-srv6-locator)# sid fcbb:bbbb:1:fe01:: behavior uDT6 vrf Vrf1
router(config-srv6-locator)# sid fcbb:bbbb:1:fe02:abcd:: behavior uDT4 vrf Vrf1
router(config-srv6-locator)# sid fcbb:bbbb:1:fe03:abcd:abcd:: behavior uDT46 vrf Vrf2

router(config-srv6-locator)# show run
...
segment-routing
srv6
locators
locator loc1
prefix fcbb:bbbb:1::/48 block-len 32 node-len 16 func-bits 16
sid fcbb:bbbb:1:fe01:: behavior uDT6 vrf Vrf1
sid fcbb:bbbb:1:fe02:abcd:: behavior uDT4 vrf Vrf1
sid fcbb:bbbb:1:fe03:abcd:abcd:: behavior uDT46 vrf Vrf2
!
...

.. clicmd:: behavior usid

Specify the SRv6 locator as a Micro-segment (uSID) locator. When a locator is
Expand Down
1 change: 1 addition & 0 deletions lib/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ enum node_type {
SRV6_NODE, /* SRv6 node */
SRV6_LOCS_NODE, /* SRv6 locators node */
SRV6_LOC_NODE, /* SRv6 locator node */
SRV6_PREFIX_NODE, /* SRv6 locator prefix node */
SRV6_ENCAP_NODE, /* SRv6 encapsulation node */
SRV6_SID_FORMATS_NODE, /* SRv6 SID formats config node */
SRV6_SID_FORMAT_USID_F3216_NODE, /* SRv6 uSID f3216 format config node */
Expand Down
57 changes: 57 additions & 0 deletions lib/srv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ const char *seg6local_action2str(uint32_t action)
return "End.AM";
case ZEBRA_SEG6_LOCAL_ACTION_END_DT46:
return "End.DT46";
case ZEBRA_SEG6_LOCAL_ACTION_END_UN:
return "End.uN";
case ZEBRA_SEG6_LOCAL_ACTION_END_UDT4:
return "End.uDT4";
case ZEBRA_SEG6_LOCAL_ACTION_END_UDT6:
return "End.uDT6";
case ZEBRA_SEG6_LOCAL_ACTION_END_UDT46:
return "End.uDT46";
case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC:
return "unspec";
default:
Expand Down Expand Up @@ -167,6 +175,8 @@ struct srv6_locator *srv6_locator_alloc(const char *name)
locator->chunks = list_new();
locator->chunks->del = srv6_locator_chunk_list_free;

locator->sids = list_new();

QOBJ_REG(locator, srv6_locator);
return locator;
}
Expand Down Expand Up @@ -205,6 +215,20 @@ void srv6_locator_free(struct srv6_locator *locator)
}
}

struct seg6_sid *srv6_locator_sid_alloc(void)
{
struct seg6_sid *sid = NULL;

sid = XCALLOC(MTYPE_SRV6_LOCATOR_CHUNK, sizeof(struct seg6_sid));
strlcpy(sid->vrfName, "Default", sizeof(sid->vrfName));
return sid;
}

void srv6_locator_sid_free(struct seg6_sid *sid)
{
XFREE(MTYPE_SRV6_LOCATOR_CHUNK, sid);
}

void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk)
{
XFREE(MTYPE_SRV6_LOCATOR_CHUNK, *chunk);
Expand Down Expand Up @@ -316,6 +340,27 @@ srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk)
return jo_root;
}

json_object *srv6_locator_sid_detailed_json(const struct srv6_locator *locator,
const struct seg6_sid *sid)
{
json_object *jo_root = NULL;
char buf[256];

jo_root = json_object_new_object();

/* set sid */
prefix2str(&sid->ipv6Addr, buf, sizeof(buf));
json_object_string_add(jo_root, "sid", buf);

/* set behavior */
json_object_string_add(jo_root, "behavior", seg6local_action2str(sid->sidaction));

/* set vrf */
json_object_string_add(jo_root, "vrf", sid->vrfName);

return jo_root;
}

json_object *srv6_locator_json(const struct srv6_locator *loc)
{
struct listnode *node;
Expand Down Expand Up @@ -392,10 +437,14 @@ json_object *srv6_locator_json(const struct srv6_locator *loc)
json_object *srv6_locator_detailed_json(const struct srv6_locator *loc)
{
struct listnode *node;
struct listnode *sidnode;
struct srv6_locator_chunk *chunk;
struct seg6_sid *sid = NULL;
json_object *jo_root = NULL;
json_object *jo_chunk = NULL;
json_object *jo_chunks = NULL;
json_object *jo_sid = NULL;
json_object *jo_sids = NULL;

jo_root = json_object_new_object();

Expand Down Expand Up @@ -461,5 +510,13 @@ json_object *srv6_locator_detailed_json(const struct srv6_locator *loc)
json_object_array_add(jo_chunks, jo_chunk);
}

/* set sids */
jo_sids = json_object_new_array();
json_object_object_add(jo_root, "sids", jo_sids);
for (ALL_LIST_ELEMENTS_RO(loc->sids, sidnode, sid)) {
jo_sid = srv6_locator_sid_detailed_json(loc, sid);
json_object_array_add(jo_sids, jo_sid);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • separate lib change from test change (separate commit).
  • this part of code should be made in the same commit as the changes done in show_srv6_locator_detail_cmd()

return jo_root;
}
22 changes: 22 additions & 0 deletions lib/srv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <zebra.h>
#include "prefix.h"
#include "json.h"
#include "vrf.h"

#include <arpa/inet.h>
#include <netinet/in.h>
Expand Down Expand Up @@ -63,6 +64,11 @@ enum seg6local_action_t {
ZEBRA_SEG6_LOCAL_ACTION_END_AM = 14,
ZEBRA_SEG6_LOCAL_ACTION_END_BPF = 15,
ZEBRA_SEG6_LOCAL_ACTION_END_DT46 = 16,

ZEBRA_SEG6_LOCAL_ACTION_END_UDT6 = 19,
ZEBRA_SEG6_LOCAL_ACTION_END_UDT4 = 20,
ZEBRA_SEG6_LOCAL_ACTION_END_UDT46 = 21,
ZEBRA_SEG6_LOCAL_ACTION_END_UN = 22,
};

/* Flavor operations for SRv6 End* Behaviors */
Expand Down Expand Up @@ -129,6 +135,7 @@ struct srv6_locator {
uint64_t current;
bool status_up;
struct list *chunks;
struct list *sids;

uint8_t flags;
#define SRV6_LOCATOR_USID (1 << 0) /* The SRv6 Locator is a uSID Locator */
Expand Down Expand Up @@ -167,6 +174,13 @@ struct srv6_locator_chunk {
uint8_t flags;
};

struct seg6_sid {
enum seg6local_action_t sidaction;
char vrfName[VRF_NAMSIZ + 1];
struct prefix_ipv6 ipv6Addr;
char sidstr[PREFIX_STRLEN];
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • add state to tell if it is active for usage or inactive.


/*
* SRv6 Endpoint Behavior codepoints, as defined by IANA in
* https://www.iana.org/assignments/segment-routing/segment-routing.xhtml
Expand Down Expand Up @@ -366,6 +380,10 @@ static inline const char *srv6_sid_ctx2str(char *str, size_t size,
case ZEBRA_SEG6_LOCAL_ACTION_END_AS:
case ZEBRA_SEG6_LOCAL_ACTION_END_AM:
case ZEBRA_SEG6_LOCAL_ACTION_END_BPF:
case ZEBRA_SEG6_LOCAL_ACTION_END_UN:
case ZEBRA_SEG6_LOCAL_ACTION_END_UDT4:
case ZEBRA_SEG6_LOCAL_ACTION_END_UDT6:
case ZEBRA_SEG6_LOCAL_ACTION_END_UDT46:
default:
snprintf(str + len, size - len, " unknown(%s)", __func__);
}
Expand All @@ -378,6 +396,8 @@ int snprintf_seg6_segs(char *str,

extern struct srv6_locator *srv6_locator_alloc(const char *name);
extern struct srv6_locator_chunk *srv6_locator_chunk_alloc(void);
extern struct seg6_sid *srv6_locator_sid_alloc(void);
extern void srv6_locator_sid_free(struct seg6_sid *sid);
extern void srv6_locator_free(struct srv6_locator *locator);
extern void srv6_locator_chunk_list_free(void *data);
extern void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk);
Expand All @@ -388,6 +408,8 @@ json_object *srv6_locator_json(const struct srv6_locator *loc);
json_object *srv6_locator_detailed_json(const struct srv6_locator *loc);
json_object *
srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk);
json_object *srv6_locator_sid_detailed_json(const struct srv6_locator *locator,
const struct seg6_sid *sid);

extern struct srv6_sid_format *srv6_sid_format_alloc(const char *name);
extern void srv6_sid_format_free(struct srv6_sid_format *format);
Expand Down
27 changes: 27 additions & 0 deletions lib/zclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,33 @@ int zapi_srv6_locator_decode(struct stream *s, struct srv6_locator *l)
return -1;
}

int zapi_srv6_locator_sid_encode(struct stream *s, struct srv6_locator *loc)
{
struct seg6_sid *sidtmp = NULL;
struct listnode *node = NULL;

stream_putw(s, strlen(loc->name));
stream_put(s, loc->name, strlen(loc->name));

stream_putw(s, loc->prefix.prefixlen);
stream_put(s, &loc->prefix.prefix, sizeof(loc->prefix.prefix));
stream_putc(s, loc->block_bits_length);
stream_putc(s, loc->node_bits_length);
stream_putc(s, loc->function_bits_length);
stream_putc(s, loc->argument_bits_length);

stream_putl(s, loc->sids->count);
for (ALL_LIST_ELEMENTS_RO(loc->sids, node, sidtmp)) {
stream_putw(s, sidtmp->ipv6Addr.prefixlen);
stream_put(s, &sidtmp->ipv6Addr.prefix, sizeof(sidtmp->ipv6Addr.prefix));
stream_putl(s, sidtmp->sidaction);
stream_putw(s, strlen(sidtmp->vrfName));
stream_put(s, sidtmp->vrfName, strlen(sidtmp->vrfName));
}

return 0;
}

static int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
{
int i;
Expand Down
5 changes: 5 additions & 0 deletions lib/zclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ typedef enum {
ZEBRA_SRV6_MANAGER_GET_LOCATOR,
ZEBRA_SRV6_MANAGER_GET_SRV6_SID,
ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID,
ZEBRA_SRV6_MANAGER_GET_LOCATOR_SID,
ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_SID,
ZEBRA_SRV6_MANAGER_GET_LOCATOR_ALL,
ZEBRA_ERROR,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GET_LOCATOR_ALL is unused. to be removed.

ZEBRA_CLIENT_CAPABILITIES,
ZEBRA_OPAQUE_MESSAGE,
Expand Down Expand Up @@ -1064,6 +1067,8 @@ extern struct interface *zebra_interface_link_params_read(struct stream *s,
bool *changed);
extern size_t zebra_interface_link_params_write(struct stream *,
struct interface *);

extern int zapi_srv6_locator_sid_encode(struct stream *s, struct srv6_locator *loc);
extern enum zclient_send_status
zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
uint32_t chunk_size, uint32_t base);
Expand Down
Empty file.
10 changes: 10 additions & 0 deletions tests/topotests/zebra_static_locator_sid/r1/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
router bgp 65000
no bgp ebgp-requires-policy
timers bgp start-timer 0
neighbor aaa peer-group
neighbor aaa remote-as 65001
neighbor 192.168.254.2 peer-group aaa
neighbor 192.168.255.2 remote-as 65001
neighbor 192.168.255.2 timers 3 10
exit-address-family
!
9 changes: 9 additions & 0 deletions tests/topotests/zebra_static_locator_sid/r1/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
!
interface r1-eth0
ip address 192.168.255.1/24
!
interface r1-eth1
ip address 192.168.254.1/24
!
ip forwarding
!
10 changes: 10 additions & 0 deletions tests/topotests/zebra_static_locator_sid/r2/bgpd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
router bgp 65001
no bgp ebgp-requires-policy
timers bgp start-timer 0
neighbor aaa peer-group
neighbor aaa remote-as 65000
neighbor 192.168.254.1 peer-group aaa
neighbor 192.168.255.1 remote-as 65000
neighbor 192.168.255.1 timers 3 10
exit-address-family
!
9 changes: 9 additions & 0 deletions tests/topotests/zebra_static_locator_sid/r2/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
!
interface r2-eth0
ip address 192.168.255.2/24
!
interface r2-eth1
ip address 192.168.254.2/24
!
ip forwarding
!
Loading
Loading