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

srv6: Introduce IPv6 address in segment-list used by TE Policy #15057

Open
wants to merge 15 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
1 change: 1 addition & 0 deletions doc/user/pathd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ Configuration Commands
.. clicmd:: index INDEX nai adjacency A.B.C.D A.B.C.D
.. clicmd:: index INDEX nai prefix A.B.C.D/M algorithm <0|1>
.. clicmd:: index INDEX nai prefix A.B.C.D/M iface (0-65535)
.. clicmd:: index INDEX ipv6-address X:X::X:X

Delete or specify a segment in a segment list definition.

Expand Down
19 changes: 19 additions & 0 deletions lib/srte.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,25 @@ enum zebra_sr_policy_status {
ZEBRA_SR_POLICY_DOWN,
};

/* SR types. */
enum sr_types {
ZEBRA_SR_LSP_NONE = 0, /* No LSP. */
ZEBRA_SR_LSP_SRTE = 1, /* SR-TE LSP */
ZEBRA_SR_SRV6_SRTE = 2, /* SRv6 SID List*/
};

static inline enum lsp_types_t lsp_type_from_sr_type(enum sr_types sr_type)
{
switch (sr_type) {
case ZEBRA_SR_LSP_SRTE:
return ZEBRA_LSP_SRTE;
case ZEBRA_SR_LSP_NONE:
case ZEBRA_SR_SRV6_SRTE:
return ZEBRA_LSP_NONE;
}
return ZEBRA_LSP_NONE;
};

static inline int sr_policy_compare(const struct ipaddr *a_endpoint,
const struct ipaddr *b_endpoint,
uint32_t a_color, uint32_t b_color)
Expand Down
70 changes: 65 additions & 5 deletions lib/zclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -2330,8 +2330,7 @@ const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
/*
* Decode the nexthop-tracking update message
*/
static bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match,
struct zapi_route *nhr)
bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match, struct zapi_route *nhr)
{
uint32_t i;

Expand Down Expand Up @@ -2374,7 +2373,7 @@ static bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match,
STREAM_GETW(s, nhr->instance);
STREAM_GETC(s, nhr->distance);
STREAM_GETL(s, nhr->metric);
STREAM_GETW(s, nhr->nexthop_num);
STREAM_GETC(s, nhr->nexthop_num);

for (i = 0; i < nhr->nexthop_num; i++) {
if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0, 0) != 0)
Expand Down Expand Up @@ -3855,6 +3854,8 @@ enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient, int cmd,
int zapi_sr_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp)
{
struct zapi_srte_tunnel *zt = &zp->segment_list;
struct zapi_nexthop *znh;
int i;

stream_reset(s);

Expand All @@ -3878,6 +3879,32 @@ int zapi_sr_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp)
for (int i = 0; i < zt->label_num; i++)
stream_putl(s, zt->labels[i]);

/* Encode SRv6-TE */
if (zt->srv6_segs.num_segs > SRV6_MAX_SEGS) {
flog_err(EC_LIB_ZAPI_ENCODE, "%s: can't encode %zu SRv6 SIDS (maximum is %u)",
__func__, zt->srv6_segs.num_segs, SRV6_MAX_SEGS);
return -1;
}

stream_putw(s, zt->srv6_segs.num_segs);
if (zt->srv6_segs.num_segs)
stream_put(s, &zt->srv6_segs.segs[0],
zt->srv6_segs.num_segs * sizeof(struct in6_addr));

stream_putw(s, zt->nexthop_resolved_num);

stream_putw(s, zt->nexthop_resolved_num);

for (i = 0; i < zt->nexthop_resolved_num; i++) {
znh = &zt->nexthop_resolved[i];

if (zapi_nexthop_encode(s, znh, 0, 0) < 0)
return -1;
}

stream_putl(s, zt->metric);
stream_putc(s, zt->distance);

/* Put length at the first point of the stream. */
stream_putw_at(s, 0, stream_get_endp(s));

Expand All @@ -3886,9 +3913,11 @@ int zapi_sr_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp)

int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp)
{
memset(zp, 0, sizeof(*zp));

struct zapi_srte_tunnel *zt = &zp->segment_list;
struct zapi_nexthop *znh;
int i;

memset(zp, 0, sizeof(*zp));

STREAM_GETL(s, zp->color);
STREAM_GET_IPADDR(s, &zp->endpoint);
Expand All @@ -3908,6 +3937,37 @@ int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp)
for (int i = 0; i < zt->label_num; i++)
STREAM_GETL(s, zt->labels[i]);

/* Decode SRv6-TE */
STREAM_GETW(s, zt->srv6_segs.num_segs);
riw777 marked this conversation as resolved.
Show resolved Hide resolved

if (zt->srv6_segs.num_segs > SRV6_MAX_SEGS) {
flog_err(EC_LIB_ZAPI_ENCODE, "%s: can't encode %zu SRv6 SIDS (maximum is %u)",
__func__, zt->srv6_segs.num_segs, SRV6_MAX_SEGS);
return -1;
}
if (zt->srv6_segs.num_segs)
STREAM_GET(&zt->srv6_segs.segs[0], s,
zt->srv6_segs.num_segs * sizeof(struct in6_addr));

STREAM_GETW(s, zt->nexthop_resolved_num);
if (zt->nexthop_resolved_num > MULTIPATH_NUM) {
flog_err(EC_LIB_ZAPI_ENCODE, "%s: invalid number of nexthops (%u)", __func__,
zt->nexthop_resolved_num);
return -1;
}

STREAM_GETW(s, zt->nexthop_resolved_num);

for (i = 0; i < zt->nexthop_resolved_num; i++) {
znh = &zt->nexthop_resolved[i];

if (zapi_nexthop_decode(s, znh, 0, 0) != 0)
return -1;
}

STREAM_GETL(s, zt->metric);
STREAM_GETC(s, zt->distance);

return 0;

stream_failure:
Expand Down
20 changes: 19 additions & 1 deletion lib/zclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -630,10 +630,25 @@ struct zapi_labels {
};

struct zapi_srte_tunnel {
enum lsp_types_t type;
enum sr_types type;

/* MPLS-TE */
mpls_label_t local_label;
uint8_t label_num;
mpls_label_t labels[MPLS_MAX_LABELS];

/* SRv6-TE */
struct seg6_segs srv6_segs;

/* For SRv6 resolution. contains
* the resolved next-hop obtained by nexthop tracking
* the original metric and distance values
*/
uint16_t nexthop_resolved_num;
struct zapi_nexthop nexthop_resolved[MULTIPATH_NUM];

uint32_t metric;
uint8_t distance;
};

struct zapi_sr_policy {
Expand Down Expand Up @@ -1375,6 +1390,9 @@ extern int zapi_client_close_notify_decode(struct stream *s,

extern int zclient_send_zebra_gre_request(struct zclient *client,
struct interface *ifp);

extern bool zapi_nexthop_update_decode(struct stream *s, struct prefix *match,
struct zapi_route *nhr);
#ifdef __cplusplus
}
#endif
Expand Down
13 changes: 13 additions & 0 deletions pathd/path_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,8 @@ int segment_list_has_prefix(
DEFPY(srte_segment_list_segment, srte_segment_list_segment_cmd,
"index (0-4294967295)$index <[mpls$has_mpls_label label (16-1048575)$label] "
"|"
"[ipv6-address$has_ipv6_address X:X::X:X$ipv6_address]"
"|"
"[nai$has_nai <"
"prefix <A.B.C.D/M$prefix_ipv4|X:X::X:X/M$prefix_ipv6>"
"<algorithm$has_algo (0-1)$algo| iface$has_iface_id (0-4294967295)$iface_id>"
Expand All @@ -478,6 +480,8 @@ DEFPY(srte_segment_list_segment, srte_segment_list_segment_cmd,
"MPLS or IP Label\n"
"Label\n"
"Label Value\n"
"IPv6 address\n"
"IPv6 address Value\n"
"Segment NAI\n"
"NAI prefix identifier\n"
"NAI IPv4 prefix identifier\n"
Expand Down Expand Up @@ -507,6 +511,12 @@ DEFPY(srte_segment_list_segment, srte_segment_list_segment_cmd,
return nb_cli_apply_changes(vty, NULL);
}

if (has_ipv6_address != NULL) {
snprintf(xpath, sizeof(xpath), "./segment[index='%s']/srv6-sid-value", index_str);
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, ipv6_address_str);
return nb_cli_apply_changes(vty, NULL);
}

if (has_adj != NULL) {
status = segment_list_has_src_dst(vty, xpath, index, index_str,
adj_src_ipv4, adj_dst_ipv4,
Expand Down Expand Up @@ -551,6 +561,9 @@ void cli_show_srte_segment_list_segment(struct vty *vty,
vty_out(vty, " mpls label %s",
yang_dnode_get_string(dnode, "sid-value"));
}
if (yang_dnode_exists(dnode, "srv6-sid-value"))
vty_out(vty, " ipv6-address %s", yang_dnode_get_string(dnode, "srv6-sid-value"));

if (yang_dnode_exists(dnode, "nai")) {
struct ipaddr addr;
struct ipaddr addr_rmt;
Expand Down
8 changes: 8 additions & 0 deletions pathd/path_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ const struct frr_yang_module_info frr_pathd_info = {
},
.priority = NB_DFLT_PRIORITY - 1
},
{
.xpath = "/frr-pathd:pathd/srte/segment-list/segment/srv6-sid-value",
.cbs = {
.modify = pathd_srte_segment_list_segment_srv6_sid_value_modify,
.destroy = pathd_srte_segment_list_segment_srv6_sid_value_destroy,
},
.priority = NB_DFLT_PRIORITY - 1
},
{
.xpath = "/frr-pathd:pathd/srte/segment-list/segment/nai",
.cbs = {
Expand Down
2 changes: 2 additions & 0 deletions pathd/path_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ void pathd_srte_segment_list_segment_nai_apply_finish(
struct nb_cb_apply_finish_args *args);
int pathd_srte_segment_list_segment_sid_value_destroy(
struct nb_cb_destroy_args *args);
int pathd_srte_segment_list_segment_srv6_sid_value_modify(struct nb_cb_modify_args *args);
int pathd_srte_segment_list_segment_srv6_sid_value_destroy(struct nb_cb_destroy_args *args);
int pathd_srte_policy_create(struct nb_cb_create_args *args);
int pathd_srte_policy_destroy(struct nb_cb_destroy_args *args);
const void *pathd_srte_policy_get_next(struct nb_cb_get_next_args *args);
Expand Down
31 changes: 31 additions & 0 deletions pathd/path_nb_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,36 @@ int pathd_srte_segment_list_segment_sid_value_destroy(
return NB_OK;
}

/*
* XPath: /frr-pathd:pathd/srte/segment-list/segment/srv6-sid-value
*/
int pathd_srte_segment_list_segment_srv6_sid_value_modify(struct nb_cb_modify_args *args)
{
struct srte_segment_entry *segment;

if (args->event != NB_EV_APPLY)
return NB_OK;

segment = nb_running_get_entry(args->dnode, NULL, true);
yang_dnode_get_ipv6(&segment->srv6_sid_value, args->dnode, NULL);
SET_FLAG(segment->segment_list->flags, F_SEGMENT_LIST_MODIFIED);

return NB_OK;
}

int pathd_srte_segment_list_segment_srv6_sid_value_destroy(struct nb_cb_destroy_args *args)
{
struct srte_segment_entry *segment;

if (args->event != NB_EV_APPLY)
return NB_OK;

segment = nb_running_get_entry(args->dnode, NULL, true);
memset(&segment->srv6_sid_value, 0, sizeof(segment->srv6_sid_value));
SET_FLAG(segment->segment_list->flags, F_SEGMENT_LIST_MODIFIED);

return NB_OK;
}

int pathd_srte_segment_list_segment_nai_destroy(struct nb_cb_destroy_args *args)
{
Expand Down Expand Up @@ -702,6 +732,7 @@ int pathd_srte_policy_candidate_path_segment_list_name_modify(
candidate = nb_running_get_entry(args->dnode, NULL, true);
segment_list_name = yang_dnode_get_string(args->dnode, NULL);

path_nht_removed(candidate);
candidate->segment_list = srte_segment_list_find(segment_list_name);
candidate->lsp->segment_list = candidate->segment_list;
assert(candidate->segment_list);
Expand Down
2 changes: 2 additions & 0 deletions pathd/path_pcep_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "pathd/path_pcep.h"
#include "pathd/path_pcep_config.h"
#include "pathd/path_pcep_debug.h"
#include "pathd/path_zebra.h"
#include "frrevent.h"

#define MAX_XPATH 256
Expand Down Expand Up @@ -421,6 +422,7 @@ int path_pcep_config_update_path(struct path *path)
number_of_sid_clashed++;
}

path_nht_removed(candidate);
candidate->lsp->segment_list = segment_list;
SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);

Expand Down
Loading
Loading