mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 21:10:28 +00:00
pathd. TED support . Validation of candidate path - [part 2/4]
- Explicit segment list nai will be resolved to corresponded sid. - Dynamic segment list (from pce) will be validated. - If segment list could not be resolved or validated won't be used. - Now this new config is supported segment-list sl-1 index 10 nai prefix 10.1.2.1/32 iface 1 index 30 nai adjacency 10.2.5.2 10.2.5.5 index 40 nai prefix 10.10.10.5/32 algorithm 0 Signed-off-by: Javier Garcia <javier.garcia@voltanet.io>
This commit is contained in:
parent
75c69d151c
commit
f2b9485d6f
297
pathd/path_cli.c
297
pathd/path_cli.c
@ -34,6 +34,7 @@
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "pathd/path_cli_clippy.c"
|
||||
#endif
|
||||
#include "pathd/path_ted.h"
|
||||
|
||||
#define XPATH_MAXATTRSIZE 64
|
||||
#define XPATH_MAXKEYSIZE 42
|
||||
@ -47,6 +48,18 @@ static int config_write_segment_routing(struct vty *vty);
|
||||
static int config_write_traffic_eng(struct vty *vty);
|
||||
static int config_write_segment_lists(struct vty *vty);
|
||||
static int config_write_sr_policies(struct vty *vty);
|
||||
static int segment_list_has_src_dst(
|
||||
struct vty *vty, char *xpath, long index, const char *index_str,
|
||||
struct in_addr adj_src_ipv4, struct in_addr adj_dst_ipv4,
|
||||
struct in6_addr adj_src_ipv6, struct in6_addr adj_dst_ipv6,
|
||||
const char *adj_src_ipv4_str, const char *adj_dst_ipv4_str,
|
||||
const char *adj_src_ipv6_str, const char *adj_dst_ipv6_str);
|
||||
static int segment_list_has_prefix(
|
||||
struct vty *vty, char *xpath, long index, const char *index_str,
|
||||
const struct prefix_ipv4 *prefix_ipv4, const char *prefix_ipv4_str,
|
||||
const struct prefix_ipv6 *prefix_ipv6, const char *prefix_ipv6_str,
|
||||
const char *has_algo, long algo, const char *algo_str,
|
||||
const char *has_iface_id, long iface_id, const char *iface_id_str);
|
||||
|
||||
DEFINE_MTYPE_STATIC(PATHD, PATH_CLI, "Client");
|
||||
|
||||
@ -144,6 +157,7 @@ DEFPY(show_srte_policy,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Show detailed SR-TE info
|
||||
*/
|
||||
@ -295,56 +309,227 @@ void cli_show_srte_segment_list(struct vty *vty, struct lyd_node *dnode,
|
||||
yang_dnode_get_string(dnode, "./name"));
|
||||
}
|
||||
|
||||
static int segment_list_has_src_dst(
|
||||
struct vty *vty, char *xpath, long index, const char *index_str,
|
||||
struct in_addr adj_src_ipv4, struct in_addr adj_dst_ipv4,
|
||||
struct in6_addr adj_src_ipv6, struct in6_addr adj_dst_ipv6,
|
||||
const char *adj_src_ipv4_str, const char *adj_dst_ipv4_str,
|
||||
const char *adj_src_ipv6_str, const char *adj_dst_ipv6_str)
|
||||
{
|
||||
const char *node_src_id;
|
||||
uint32_t ted_sid = MPLS_LABEL_NONE;
|
||||
|
||||
struct ipaddr ip_src = {};
|
||||
struct ipaddr ip_dst = {};
|
||||
if (adj_src_ipv4_str != NULL) {
|
||||
ip_src.ipa_type = IPADDR_V4;
|
||||
ip_src.ip._v4_addr = adj_src_ipv4;
|
||||
ip_dst.ipa_type = IPADDR_V4;
|
||||
ip_dst.ip._v4_addr = adj_dst_ipv4;
|
||||
} else if (adj_src_ipv6_str != NULL) {
|
||||
ip_src.ipa_type = IPADDR_V6;
|
||||
ip_src.ip._v6_addr = adj_src_ipv6;
|
||||
ip_dst.ipa_type = IPADDR_V6;
|
||||
ip_dst.ip._v6_addr = adj_dst_ipv6;
|
||||
} else {
|
||||
return CMD_ERR_NO_MATCH;
|
||||
}
|
||||
ted_sid = path_ted_query_type_f(&ip_src, &ip_dst);
|
||||
if (ted_sid == MPLS_LABEL_NONE) {
|
||||
zlog_warn(
|
||||
"%s: [rcv ted] CLI NOT FOUND Continue query_type_f SRC (%pIA) DST (%pIA)!",
|
||||
__func__, &ip_src, &ip_dst);
|
||||
}
|
||||
/* type */
|
||||
snprintf(xpath, XPATH_MAXLEN, "./segment[index='%s']/nai/type",
|
||||
index_str);
|
||||
if (adj_src_ipv4_str != NULL) {
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
"ipv4_adjacency");
|
||||
node_src_id = adj_src_ipv4_str;
|
||||
} else if (adj_src_ipv6_str != NULL) {
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
"ipv6_adjacency");
|
||||
node_src_id = adj_src_ipv6_str;
|
||||
} else {
|
||||
return CMD_ERR_NO_MATCH;
|
||||
}
|
||||
/* addresses */
|
||||
snprintf(xpath, XPATH_MAXLEN, "./segment[index='%s']/nai/local-address",
|
||||
index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, node_src_id);
|
||||
snprintf(xpath, XPATH_MAXLEN,
|
||||
"./segment[index='%s']/nai/remote-address", index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
adj_dst_ipv4_str ? adj_dst_ipv4_str
|
||||
: adj_dst_ipv6_str);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
int segment_list_has_prefix(
|
||||
struct vty *vty, char *xpath, long index, const char *index_str,
|
||||
const struct prefix_ipv4 *prefix_ipv4, const char *prefix_ipv4_str,
|
||||
const struct prefix_ipv6 *prefix_ipv6, const char *prefix_ipv6_str,
|
||||
const char *has_algo, long algo, const char *algo_str,
|
||||
const char *has_iface_id, long iface_id, const char *iface_id_str)
|
||||
{
|
||||
char buf_prefix[INET6_ADDRSTRLEN];
|
||||
|
||||
uint32_t ted_sid = MPLS_LABEL_NONE;
|
||||
struct prefix prefix_cli = {};
|
||||
struct ipaddr pre_ipaddr = {};
|
||||
/* prefix with algorithm or local interface id */
|
||||
/* Type */
|
||||
snprintf(xpath, XPATH_MAXLEN, "./segment[index='%s']/nai/type",
|
||||
index_str);
|
||||
if (has_iface_id != NULL) {
|
||||
if (prefix_ipv4_str != NULL) {
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
"ipv4_local_iface");
|
||||
} else if (prefix_ipv6_str != NULL) {
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
"ipv6_local_iface");
|
||||
} else {
|
||||
return CMD_ERR_NO_MATCH;
|
||||
}
|
||||
} else {
|
||||
if (prefix_ipv4_str != NULL) {
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
"ipv4_algo");
|
||||
} else if (prefix_ipv6_str != NULL) {
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
"ipv6_algo");
|
||||
} else {
|
||||
return CMD_ERR_NO_MATCH;
|
||||
}
|
||||
}
|
||||
/* Prefix */
|
||||
if (prefix_ipv4_str != NULL) {
|
||||
if (!str2prefix(prefix_ipv4_str, &prefix_cli)) {
|
||||
vty_out(vty, "%% Malformed prefix\n");
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
inet_ntop(AF_INET, &prefix_cli.u.prefix4, buf_prefix,
|
||||
sizeof(buf_prefix));
|
||||
pre_ipaddr.ipa_type = IPADDR_V4;
|
||||
pre_ipaddr.ip._v4_addr = prefix_cli.u.prefix4;
|
||||
} else if (prefix_ipv6_str != NULL) {
|
||||
if (!str2prefix(prefix_ipv6_str, &prefix_cli)) {
|
||||
vty_out(vty, "%% Malformed prefix\n");
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
inet_ntop(AF_INET6, &prefix_cli.u.prefix6, buf_prefix,
|
||||
sizeof(buf_prefix));
|
||||
pre_ipaddr.ipa_type = IPADDR_V6;
|
||||
pre_ipaddr.ip._v6_addr = prefix_cli.u.prefix6;
|
||||
} else {
|
||||
return CMD_ERR_NO_MATCH;
|
||||
}
|
||||
snprintf(xpath, XPATH_MAXLEN, "./segment[index='%s']/nai/local-address",
|
||||
index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, buf_prefix);
|
||||
snprintf(xpath, XPATH_MAXLEN,
|
||||
"./segment[index='%s']/nai/local-prefix-len", index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
prefix_ipv4_str
|
||||
? strchr(prefix_ipv4_str, '/') + 1
|
||||
: strchr(prefix_ipv6_str, '/') + 1);
|
||||
/* Alg / Iface */
|
||||
if (has_algo != NULL) {
|
||||
snprintf(xpath, XPATH_MAXLEN,
|
||||
"./segment[index='%s']/nai/algorithm", index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, algo_str);
|
||||
} else {
|
||||
if (has_iface_id != NULL) {
|
||||
snprintf(xpath, XPATH_MAXLEN,
|
||||
"./segment[index='%s']/nai/local-interface",
|
||||
index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
iface_id_str);
|
||||
}
|
||||
}
|
||||
if (has_algo != NULL) {
|
||||
ted_sid = path_ted_query_type_c(&prefix_cli, algo);
|
||||
if (ted_sid == MPLS_LABEL_NONE) {
|
||||
zlog_err(
|
||||
"%s: [rcv ted] CLI NOT FOUND Continue query_type_c PREFIX (%pIA/%d) ALGO (%ld) sid:(%d)!",
|
||||
__func__, &pre_ipaddr, prefix_cli.prefixlen,
|
||||
algo, ted_sid);
|
||||
}
|
||||
}
|
||||
if (has_iface_id != NULL) {
|
||||
ted_sid = path_ted_query_type_e(&prefix_cli, iface_id);
|
||||
if (ted_sid == MPLS_LABEL_NONE) {
|
||||
zlog_err(
|
||||
"%s: [rcv ted] CLI NOT FOUND Continue query_type_e PREFIX (%pIA/%d) IFACE (%ld) sid:(%d)!",
|
||||
__func__, &pre_ipaddr, prefix_cli.prefixlen,
|
||||
iface_id, ted_sid);
|
||||
}
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
/*
|
||||
* XPath: /frr-pathd:pathd/srte/segment-list/segment
|
||||
*/
|
||||
DEFPY(srte_segment_list_segment,
|
||||
srte_segment_list_segment_cmd,
|
||||
"index (0-4294967295)$index mpls label (16-1048575)$label "
|
||||
/* clang-format off */
|
||||
DEFPY(srte_segment_list_segment, srte_segment_list_segment_cmd,
|
||||
"index (0-4294967295)$index <[mpls$has_mpls_label label (16-1048575)$label] "
|
||||
"|"
|
||||
"[nai$has_nai <"
|
||||
"node <A.B.C.D$node_ipv4|X:X::X:X$node_ipv6>"
|
||||
">]",
|
||||
"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>"
|
||||
"| adjacency$has_adj "
|
||||
"<A.B.C.D$adj_src_ipv4 A.B.C.D$adj_dst_ipv4|X:X::X:X$adj_src_ipv6 X:X::X:X$adj_dst_ipv6>"
|
||||
">]"
|
||||
">",
|
||||
"Index\n"
|
||||
"Index Value\n"
|
||||
"MPLS or IP Label\n"
|
||||
"Label\n"
|
||||
"Label Value\n"
|
||||
"Segment NAI\n"
|
||||
"NAI node identifier\n"
|
||||
"NAI IPv4 node identifier\n"
|
||||
"NAI IPv6 node identifier\n")
|
||||
"NAI prefix identifier\n"
|
||||
"NAI IPv4 prefix identifier\n"
|
||||
"NAI IPv6 prefix identifier\n"
|
||||
"IGP Algorithm\n"
|
||||
"Algorithm Value SPF or Strict-SPF\n"
|
||||
"Interface Id\n"
|
||||
"Interface Value\n"
|
||||
"ADJ identifier\n"
|
||||
"ADJ IPv4 src identifier\n"
|
||||
"ADJ IPv4 dst identifier\n"
|
||||
"ADJ IPv6 src identifier\n"
|
||||
"ADJ IPv6 dst identifier\n")
|
||||
/* clang-format on */
|
||||
{
|
||||
char xpath[XPATH_MAXLEN];
|
||||
const char *node_id;
|
||||
int status = CMD_SUCCESS;
|
||||
|
||||
|
||||
snprintf(xpath, sizeof(xpath), "./segment[index='%s']", index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
|
||||
snprintf(xpath, sizeof(xpath), "./segment[index='%s']/sid-value",
|
||||
index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, label_str);
|
||||
|
||||
if (has_nai != NULL) {
|
||||
snprintf(xpath, sizeof(xpath), "./segment[index='%s']/nai/type",
|
||||
index_str);
|
||||
if (node_ipv4_str != NULL) {
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
"ipv4_node");
|
||||
node_id = node_ipv4_str;
|
||||
} else if (node_ipv6_str != NULL) {
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
|
||||
"ipv6_node");
|
||||
node_id = node_ipv6_str;
|
||||
} else {
|
||||
return CMD_ERR_NO_MATCH;
|
||||
}
|
||||
if (has_mpls_label != NULL) {
|
||||
snprintf(xpath, sizeof(xpath),
|
||||
"./segment[index='%s']/nai/local-address", index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, node_id);
|
||||
"./segment[index='%s']/sid-value", index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, label_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,
|
||||
adj_src_ipv6, adj_dst_ipv6,
|
||||
adj_src_ipv4_str, adj_dst_ipv4_str,
|
||||
adj_dst_ipv6_str, adj_src_ipv6_str);
|
||||
if (status != CMD_SUCCESS)
|
||||
return status;
|
||||
} else {
|
||||
snprintf(xpath, sizeof(xpath), "./segment[index='%s']/nai",
|
||||
index_str);
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
segment_list_has_prefix(
|
||||
vty, xpath, index, index_str, prefix_ipv4,
|
||||
prefix_ipv4_str, prefix_ipv6, prefix_ipv6_str, has_algo,
|
||||
algo, algo_str, has_iface_id, iface_id, iface_id_str);
|
||||
if (status != CMD_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
@ -369,23 +554,60 @@ void cli_show_srte_segment_list_segment(struct vty *vty,
|
||||
struct lyd_node *dnode,
|
||||
bool show_defaults)
|
||||
{
|
||||
vty_out(vty, " index %s mpls label %s",
|
||||
yang_dnode_get_string(dnode, "./index"),
|
||||
yang_dnode_get_string(dnode, "./sid-value"));
|
||||
vty_out(vty, " index %s ", yang_dnode_get_string(dnode, "./index"));
|
||||
if (yang_dnode_exists(dnode, "./sid-value")) {
|
||||
vty_out(vty, " mpls label %s",
|
||||
yang_dnode_get_string(dnode, "./sid-value"));
|
||||
}
|
||||
if (yang_dnode_exists(dnode, "./nai")) {
|
||||
struct ipaddr addr;
|
||||
struct ipaddr addr_rmt;
|
||||
|
||||
switch (yang_dnode_get_enum(dnode, "./nai/type")) {
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM:
|
||||
yang_dnode_get_ip(&addr, dnode, "./nai/local-address");
|
||||
vty_out(vty, " nai node %pI4", &addr.ipaddr_v4);
|
||||
vty_out(vty, " nai prefix %pI4", &addr.ipaddr_v4);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM:
|
||||
yang_dnode_get_ip(&addr, dnode, "./nai/local-address");
|
||||
vty_out(vty, " nai node %pI6", &addr.ipaddr_v6);
|
||||
vty_out(vty, " nai prefix %pI6", &addr.ipaddr_v6);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY:
|
||||
yang_dnode_get_ip(&addr, dnode, "./nai/local-address");
|
||||
yang_dnode_get_ip(&addr_rmt, dnode,
|
||||
"./nai/remote-address");
|
||||
vty_out(vty, " nai adjacency %pI4", &addr.ipaddr_v4);
|
||||
vty_out(vty, " %pI4", &addr_rmt.ipaddr_v4);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY:
|
||||
yang_dnode_get_ip(&addr, dnode, "./nai/local-address");
|
||||
yang_dnode_get_ip(&addr_rmt, dnode,
|
||||
"./nai/remote-address");
|
||||
vty_out(vty, " nai adjacency %pI6", &addr.ipaddr_v6);
|
||||
vty_out(vty, " %pI6", &addr_rmt.ipaddr_v6);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (yang_dnode_exists(dnode, "./nai/local-prefix-len")) {
|
||||
vty_out(vty, "/%s",
|
||||
yang_dnode_get_string(
|
||||
dnode, "./nai/local-prefix-len"));
|
||||
}
|
||||
if (yang_dnode_exists(dnode, "./nai/local-interface")) {
|
||||
vty_out(vty, " iface %s",
|
||||
yang_dnode_get_string(dnode,
|
||||
"./nai/local-interface"));
|
||||
}
|
||||
if (yang_dnode_exists(dnode, "./nai/algorithm")) {
|
||||
vty_out(vty, " algorithm %s",
|
||||
yang_dnode_get_string(dnode,
|
||||
"./nai/algorithm"));
|
||||
}
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
@ -1038,6 +1260,7 @@ int config_write_segment_routing(struct vty *vty)
|
||||
int config_write_traffic_eng(struct vty *vty)
|
||||
{
|
||||
vty_out(vty, " traffic-eng\n");
|
||||
path_ted_config_write(vty);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,7 @@ const struct frr_yang_module_info frr_pathd_info = {
|
||||
.xpath = "/frr-pathd:pathd/srte/segment-list/segment/sid-value",
|
||||
.cbs = {
|
||||
.modify = pathd_srte_segment_list_segment_sid_value_modify,
|
||||
.destroy = pathd_srte_segment_list_segment_sid_value_destroy,
|
||||
},
|
||||
.priority = NB_DFLT_PRIORITY - 1
|
||||
},
|
||||
@ -114,6 +115,10 @@ const struct frr_yang_module_info frr_pathd_info = {
|
||||
.xpath = "/frr-pathd:pathd/srte/segment-list/segment/nai/local-interface",
|
||||
.cbs = {.modify = dummy_modify, .destroy = dummy_destroy}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-pathd:pathd/srte/segment-list/segment/nai/local-prefix-len",
|
||||
.cbs = {.modify = dummy_modify, .destroy = dummy_destroy}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-pathd:pathd/srte/segment-list/segment/nai/remote-address",
|
||||
.cbs = {.modify = dummy_modify, .destroy = dummy_destroy}
|
||||
@ -122,6 +127,10 @@ const struct frr_yang_module_info frr_pathd_info = {
|
||||
.xpath = "/frr-pathd:pathd/srte/segment-list/segment/nai/remote-interface",
|
||||
.cbs = {.modify = dummy_modify, .destroy = dummy_destroy}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-pathd:pathd/srte/segment-list/segment/nai/algorithm",
|
||||
.cbs = {.modify = dummy_modify, .destroy = dummy_destroy}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-pathd:pathd/srte/policy",
|
||||
.cbs = {
|
||||
|
@ -43,6 +43,8 @@ int pathd_srte_segment_list_segment_nai_destroy(
|
||||
struct nb_cb_destroy_args *args);
|
||||
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_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);
|
||||
|
@ -160,6 +160,22 @@ int pathd_srte_segment_list_segment_sid_value_modify(
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
int pathd_srte_segment_list_segment_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);
|
||||
segment->sid_value = MPLS_LABEL_NONE;
|
||||
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)
|
||||
{
|
||||
struct srte_segment_entry *segment;
|
||||
@ -184,6 +200,8 @@ void pathd_srte_segment_list_segment_nai_apply_finish(
|
||||
enum srte_segment_nai_type type;
|
||||
struct ipaddr local_addr, remote_addr;
|
||||
uint32_t local_iface = 0, remote_iface = 0;
|
||||
uint8_t algo = 0, local_prefix_len = 0;
|
||||
const char *algo_buf, *local_prefix_len_buf;
|
||||
|
||||
segment = nb_running_get_entry(args->dnode, NULL, true);
|
||||
type = yang_dnode_get_enum(args->dnode, "./type");
|
||||
@ -207,12 +225,31 @@ void pathd_srte_segment_list_segment_nai_apply_finish(
|
||||
remote_iface = yang_dnode_get_uint32(args->dnode,
|
||||
"./remote-interface");
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM:
|
||||
algo_buf = yang_dnode_get_string(args->dnode, "./algorithm");
|
||||
algo = atoi(algo_buf);
|
||||
local_prefix_len_buf = yang_dnode_get_string(
|
||||
args->dnode, "./local-prefix-len");
|
||||
local_prefix_len = atoi(local_prefix_len_buf);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE:
|
||||
local_iface =
|
||||
yang_dnode_get_uint32(args->dnode, "./local-interface");
|
||||
local_prefix_len_buf = yang_dnode_get_string(
|
||||
args->dnode, "./local-prefix-len");
|
||||
local_prefix_len = atoi(local_prefix_len_buf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
srte_segment_entry_set_nai(segment, type, &local_addr, local_iface,
|
||||
&remote_addr, remote_iface);
|
||||
zlog_debug(" Segment list name (%d) index (%s) ", segment->index,
|
||||
segment->segment_list->name);
|
||||
if (srte_segment_entry_set_nai(segment, type, &local_addr, local_iface,
|
||||
&remote_addr, remote_iface, algo,
|
||||
local_prefix_len))
|
||||
SET_FLAG(segment->segment_list->flags,
|
||||
F_SEGMENT_LIST_SID_CONFLICT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -246,6 +246,10 @@ path_pcep_config_list_path_hops(struct srte_segment_list *segment_list)
|
||||
switch (segment->nai_type) {
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM:
|
||||
memcpy(&hop->nai.local_addr, &segment->nai_local_addr,
|
||||
sizeof(struct ipaddr));
|
||||
break;
|
||||
@ -278,6 +282,7 @@ int path_pcep_config_update_path(struct path *path)
|
||||
assert(path->nbkey.preference != 0);
|
||||
assert(path->nbkey.endpoint.ipa_type == IPADDR_V4);
|
||||
|
||||
int number_of_sid_clashed = 0;
|
||||
struct path_hop *hop;
|
||||
struct path_metric *metric;
|
||||
int index;
|
||||
@ -297,40 +302,44 @@ int path_pcep_config_update_path(struct path *path)
|
||||
if (candidate->lsp->segment_list) {
|
||||
SET_FLAG(candidate->lsp->segment_list->flags,
|
||||
F_SEGMENT_LIST_DELETED);
|
||||
srte_segment_list_del(candidate->lsp->segment_list);
|
||||
candidate->lsp->segment_list = NULL;
|
||||
}
|
||||
|
||||
if (path->first_hop != NULL) {
|
||||
snprintf(segment_list_name_buff, sizeof(segment_list_name_buff),
|
||||
"%s-%u", path->name, path->plsp_id);
|
||||
segment_list_name = segment_list_name_buff;
|
||||
if (path->first_hop == NULL)
|
||||
return PATH_NB_ERR;
|
||||
|
||||
segment_list = srte_segment_list_add(segment_list_name);
|
||||
segment_list->protocol_origin = path->update_origin;
|
||||
strlcpy(segment_list->originator, path->originator,
|
||||
sizeof(segment_list->originator));
|
||||
SET_FLAG(segment_list->flags, F_SEGMENT_LIST_NEW);
|
||||
SET_FLAG(segment_list->flags, F_SEGMENT_LIST_MODIFIED);
|
||||
snprintf(segment_list_name_buff, sizeof(segment_list_name_buff),
|
||||
"%s-%u", path->name, path->plsp_id);
|
||||
segment_list_name = segment_list_name_buff;
|
||||
|
||||
for (hop = path->first_hop, index = 10; hop != NULL;
|
||||
hop = hop->next, index += 10) {
|
||||
assert(hop->has_sid);
|
||||
assert(hop->is_mpls);
|
||||
segment_list = srte_segment_list_add(segment_list_name);
|
||||
segment_list->protocol_origin = path->update_origin;
|
||||
strlcpy(segment_list->originator, path->originator,
|
||||
sizeof(segment_list->originator));
|
||||
SET_FLAG(segment_list->flags, F_SEGMENT_LIST_NEW);
|
||||
SET_FLAG(segment_list->flags, F_SEGMENT_LIST_MODIFIED);
|
||||
|
||||
segment = srte_segment_entry_add(segment_list, index);
|
||||
for (hop = path->first_hop, index = 10; hop != NULL;
|
||||
hop = hop->next, index += 10) {
|
||||
assert(hop->has_sid);
|
||||
assert(hop->is_mpls);
|
||||
|
||||
segment->sid_value = (mpls_label_t)hop->sid.mpls.label;
|
||||
SET_FLAG(segment->segment_list->flags,
|
||||
F_SEGMENT_LIST_MODIFIED);
|
||||
segment = srte_segment_entry_add(segment_list, index);
|
||||
|
||||
if (hop->has_nai)
|
||||
srte_segment_entry_set_nai(
|
||||
segment, srte_nai_type(hop->nai.type),
|
||||
&hop->nai.local_addr,
|
||||
hop->nai.local_iface,
|
||||
&hop->nai.remote_addr,
|
||||
hop->nai.remote_iface);
|
||||
}
|
||||
segment->sid_value = (mpls_label_t)hop->sid.mpls.label;
|
||||
SET_FLAG(segment->segment_list->flags, F_SEGMENT_LIST_MODIFIED);
|
||||
|
||||
if (!hop->has_nai)
|
||||
continue;
|
||||
if (srte_segment_entry_set_nai(
|
||||
segment, srte_nai_type(hop->nai.type),
|
||||
&hop->nai.local_addr, hop->nai.local_iface,
|
||||
&hop->nai.remote_addr, hop->nai.remote_iface, 0, 0)
|
||||
== PATH_SID_ERROR)
|
||||
/* TED queries don't match PCE */
|
||||
/* Don't apply srte,zebra changes */
|
||||
number_of_sid_clashed++;
|
||||
}
|
||||
|
||||
candidate->lsp->segment_list = segment_list;
|
||||
@ -352,7 +361,11 @@ int path_pcep_config_update_path(struct path *path)
|
||||
candidate->lsp->objfun = path->pce_objfun;
|
||||
}
|
||||
|
||||
srte_apply_changes();
|
||||
if (number_of_sid_clashed)
|
||||
SET_FLAG(segment->segment_list->flags,
|
||||
F_SEGMENT_LIST_SID_CONFLICT);
|
||||
else
|
||||
srte_apply_changes();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -402,6 +415,16 @@ enum pcep_sr_subobj_nai pcep_nai_type(enum srte_segment_nai_type type)
|
||||
return PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY:
|
||||
return PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY_LINK_LOCAL_ADDRESSES:
|
||||
return PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE:
|
||||
return PCEP_SR_SUBOBJ_NAI_IPV4_NODE;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE:
|
||||
return PCEP_SR_SUBOBJ_NAI_IPV6_NODE;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM:
|
||||
return PCEP_SR_SUBOBJ_NAI_IPV4_NODE;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM:
|
||||
return PCEP_SR_SUBOBJ_NAI_IPV6_NODE;
|
||||
default:
|
||||
return PCEP_SR_SUBOBJ_NAI_UNKNOWN;
|
||||
}
|
||||
|
263
pathd/pathd.c
263
pathd/pathd.c
@ -189,14 +189,20 @@ void srte_segment_entry_del(struct srte_segment_entry *segment)
|
||||
* @param type The remote address of the adjacency
|
||||
* @param type The remote interface index of the unumbered adjacency
|
||||
*/
|
||||
void srte_segment_entry_set_nai(struct srte_segment_entry *segment,
|
||||
enum srte_segment_nai_type type,
|
||||
struct ipaddr *local_ip, uint32_t local_iface,
|
||||
struct ipaddr *remote_ip, uint32_t remote_iface)
|
||||
int srte_segment_entry_set_nai(struct srte_segment_entry *segment,
|
||||
enum srte_segment_nai_type type,
|
||||
struct ipaddr *local_ip, uint32_t local_iface,
|
||||
struct ipaddr *remote_ip, uint32_t remote_iface,
|
||||
uint8_t algo, uint8_t pref_len)
|
||||
{
|
||||
int32_t status = 0;
|
||||
struct prefix pre = {0};
|
||||
segment->nai_type = type;
|
||||
memcpy(&segment->nai_local_addr, local_ip, sizeof(struct ipaddr));
|
||||
|
||||
if (!segment || !local_ip || !remote_ip)
|
||||
return 1;
|
||||
|
||||
switch (type) {
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE:
|
||||
@ -205,6 +211,7 @@ void srte_segment_entry_set_nai(struct srte_segment_entry *segment,
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY:
|
||||
memcpy(&segment->nai_remote_addr, remote_ip,
|
||||
sizeof(struct ipaddr));
|
||||
status = srte_ted_do_query_type_f(segment, local_ip, remote_ip);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY:
|
||||
memcpy(&segment->nai_remote_addr, remote_ip,
|
||||
@ -212,12 +219,68 @@ void srte_segment_entry_set_nai(struct srte_segment_entry *segment,
|
||||
segment->nai_local_iface = local_iface;
|
||||
segment->nai_remote_iface = remote_iface;
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM:
|
||||
pre.family = AF_INET6;
|
||||
pre.prefixlen = pref_len;
|
||||
pre.u.prefix6 = local_ip->ip._v6_addr;
|
||||
segment->nai_local_prefix_len = pref_len;
|
||||
segment->nai_algorithm = algo;
|
||||
status = srte_ted_do_query_type_c(segment, &pre, algo);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM:
|
||||
pre.family = AF_INET;
|
||||
pre.prefixlen = pref_len;
|
||||
pre.u.prefix4 = local_ip->ip._v4_addr;
|
||||
segment->nai_local_prefix_len = pref_len;
|
||||
segment->nai_algorithm = algo;
|
||||
status = srte_ted_do_query_type_c(segment, &pre, algo);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE:
|
||||
pre.family = AF_INET6;
|
||||
pre.prefixlen = pref_len;
|
||||
pre.u.prefix6 = local_ip->ip._v6_addr;
|
||||
segment->nai_local_prefix_len = pref_len;
|
||||
segment->nai_local_iface = local_iface;
|
||||
status = srte_ted_do_query_type_e(segment, &pre, local_iface);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE:
|
||||
pre.family = AF_INET;
|
||||
pre.prefixlen = pref_len;
|
||||
pre.u.prefix4 = local_ip->ip._v4_addr;
|
||||
segment->nai_local_prefix_len = pref_len;
|
||||
segment->nai_local_iface = local_iface;
|
||||
status = srte_ted_do_query_type_e(segment, &pre, local_iface);
|
||||
break;
|
||||
default:
|
||||
segment->nai_local_addr.ipa_type = IPADDR_NONE;
|
||||
segment->nai_local_iface = 0;
|
||||
segment->nai_remote_addr.ipa_type = IPADDR_NONE;
|
||||
segment->nai_remote_iface = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark segment as modified depending in protocol and sid conditions
|
||||
*
|
||||
* @param protocol_origin Origin of the segment list
|
||||
* @param s_list Ptr to segment list with flags,sid to modidy
|
||||
* @param s_entry Ptr to segment entry with sid to modidy
|
||||
* @param ted_sid The sid from ted query
|
||||
* @return void
|
||||
*/
|
||||
void srte_segment_set_local_modification(struct srte_segment_list *s_list,
|
||||
struct srte_segment_entry *s_entry,
|
||||
uint32_t ted_sid)
|
||||
{
|
||||
if (!s_list || !s_entry)
|
||||
return;
|
||||
|
||||
if (s_list->protocol_origin == SRTE_ORIGIN_LOCAL
|
||||
&& s_entry->sid_value != ted_sid) {
|
||||
s_entry->sid_value = ted_sid;
|
||||
SET_FLAG(s_list->flags, F_SEGMENT_LIST_MODIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -288,6 +351,105 @@ struct srte_policy *srte_policy_find(uint32_t color, struct ipaddr *endpoint)
|
||||
return RB_FIND(srte_policy_head, &srte_policies, &search);
|
||||
}
|
||||
|
||||
/*
|
||||
* After new data from igp,local and pce the segment list :
|
||||
* Mark as invalid for origin pce if cannot be validated
|
||||
* Updated for origin local
|
||||
*/
|
||||
int srte_policy_update_ted_sid(void)
|
||||
{
|
||||
|
||||
int number_of_sid_clashed = 0;
|
||||
struct srte_segment_list *s_list;
|
||||
struct srte_segment_entry *s_entry;
|
||||
|
||||
if (!path_ted_is_initialized())
|
||||
return 0;
|
||||
if (RB_EMPTY(srte_segment_list_head, &srte_segment_lists))
|
||||
return 0;
|
||||
|
||||
RB_FOREACH (s_list, srte_segment_list_head, &srte_segment_lists) {
|
||||
if (CHECK_FLAG(s_list->flags, F_SEGMENT_LIST_DELETED))
|
||||
continue;
|
||||
RB_FOREACH (s_entry, srte_segment_entry_head,
|
||||
&s_list->segments) {
|
||||
PATH_TED_DEBUG(
|
||||
"%s:PATHD-TED: SL: Name: %s index:(%d) sid:(%d) prefix_len:(%d) local iface:(%d) algorithm:(%d)",
|
||||
__func__, s_list->name, s_entry->index,
|
||||
s_entry->sid_value,
|
||||
s_entry->nai_local_prefix_len,
|
||||
s_entry->nai_local_iface,
|
||||
s_entry->nai_algorithm);
|
||||
struct prefix prefix_cli = {0};
|
||||
|
||||
switch (s_entry->nai_type) {
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY:
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY:
|
||||
number_of_sid_clashed +=
|
||||
srte_ted_do_query_type_f(
|
||||
s_entry,
|
||||
&s_entry->nai_local_addr,
|
||||
&s_entry->nai_remote_addr);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE:
|
||||
prefix_cli.family = AF_INET6;
|
||||
prefix_cli.prefixlen =
|
||||
s_entry->nai_local_prefix_len;
|
||||
prefix_cli.u.prefix6 =
|
||||
s_entry->nai_local_addr.ip._v6_addr;
|
||||
number_of_sid_clashed +=
|
||||
srte_ted_do_query_type_e(
|
||||
s_entry, &prefix_cli,
|
||||
s_entry->nai_local_iface);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE:
|
||||
prefix_cli.family = AF_INET;
|
||||
prefix_cli.prefixlen =
|
||||
s_entry->nai_local_prefix_len;
|
||||
prefix_cli.u.prefix4 =
|
||||
s_entry->nai_local_addr.ip._v4_addr;
|
||||
number_of_sid_clashed +=
|
||||
srte_ted_do_query_type_e(
|
||||
s_entry, &prefix_cli,
|
||||
s_entry->nai_local_iface);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM:
|
||||
prefix_cli.family = AF_INET6;
|
||||
prefix_cli.prefixlen =
|
||||
s_entry->nai_local_prefix_len;
|
||||
prefix_cli.u.prefix6 =
|
||||
s_entry->nai_local_addr.ip._v6_addr;
|
||||
number_of_sid_clashed +=
|
||||
srte_ted_do_query_type_c(
|
||||
s_entry, &prefix_cli,
|
||||
s_entry->nai_algorithm);
|
||||
break;
|
||||
case SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM:
|
||||
prefix_cli.family = AF_INET;
|
||||
prefix_cli.prefixlen =
|
||||
s_entry->nai_local_prefix_len;
|
||||
prefix_cli.u.prefix4 =
|
||||
s_entry->nai_local_addr.ip._v4_addr;
|
||||
number_of_sid_clashed +=
|
||||
srte_ted_do_query_type_c(
|
||||
s_entry, &prefix_cli,
|
||||
s_entry->nai_algorithm);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (number_of_sid_clashed) {
|
||||
SET_FLAG(s_list->flags, F_SEGMENT_LIST_SID_CONFLICT);
|
||||
number_of_sid_clashed = 0;
|
||||
} else
|
||||
UNSET_FLAG(s_list->flags, F_SEGMENT_LIST_SID_CONFLICT);
|
||||
}
|
||||
srte_apply_changes();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a policy binding SID.
|
||||
*
|
||||
@ -323,7 +485,9 @@ srte_policy_best_candidate(const struct srte_policy *policy)
|
||||
&policy->candidate_paths) {
|
||||
/* search for highest preference with existing segment list */
|
||||
if (!CHECK_FLAG(candidate->flags, F_CANDIDATE_DELETED)
|
||||
&& candidate->lsp->segment_list)
|
||||
&& candidate->lsp->segment_list
|
||||
&& (!CHECK_FLAG(candidate->lsp->segment_list->flags,
|
||||
F_SEGMENT_LIST_SID_CONFLICT)))
|
||||
return candidate;
|
||||
}
|
||||
|
||||
@ -535,6 +699,7 @@ void srte_candidate_set_bandwidth(struct srte_candidate *candidate,
|
||||
{
|
||||
struct srte_policy *policy = candidate->policy;
|
||||
char endpoint[46];
|
||||
|
||||
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
|
||||
zlog_debug(
|
||||
"SR-TE(%s, %u): candidate %s %sconfig bandwidth set to %f B/s",
|
||||
@ -1139,3 +1304,91 @@ const char *srte_candidate_metric_name(enum srte_candidate_metric_type type)
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
int32_t srte_ted_do_query_type_c(struct srte_segment_entry *entry,
|
||||
struct prefix *prefix_cli, uint32_t algo)
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint32_t ted_sid = MPLS_LABEL_NONE;
|
||||
|
||||
if (!entry || !prefix_cli)
|
||||
return 0;
|
||||
|
||||
if (!path_ted_is_initialized())
|
||||
return 0;
|
||||
|
||||
ted_sid = path_ted_query_type_c(prefix_cli, algo);
|
||||
if (ted_sid == MPLS_LABEL_NONE) {
|
||||
zlog_warn(" %s: PATHD-TED: SL: ERROR query C : ted-sid (%d)",
|
||||
__func__, ted_sid);
|
||||
} else {
|
||||
zlog_debug("%s: PATHD-TED: SL: Sucess query C : ted-sid (%d)",
|
||||
__func__, ted_sid);
|
||||
}
|
||||
if (CHECK_SID(entry->segment_list->protocol_origin, ted_sid,
|
||||
entry->sid_value)) {
|
||||
status = PATH_SID_ERROR;
|
||||
} else
|
||||
srte_segment_set_local_modification(entry->segment_list, entry,
|
||||
ted_sid);
|
||||
return status;
|
||||
}
|
||||
|
||||
int32_t srte_ted_do_query_type_e(struct srte_segment_entry *entry,
|
||||
struct prefix *prefix_cli,
|
||||
uint32_t local_iface)
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint32_t ted_sid = MPLS_LABEL_NONE;
|
||||
|
||||
if (!entry || !prefix_cli)
|
||||
return 0;
|
||||
|
||||
if (!path_ted_is_initialized())
|
||||
return 0;
|
||||
|
||||
ted_sid = path_ted_query_type_e(prefix_cli, local_iface);
|
||||
if (ted_sid == MPLS_LABEL_NONE) {
|
||||
zlog_warn(" %s: PATHD-TED: SL: ERROR query E : ted-sid (%d)",
|
||||
__func__, ted_sid);
|
||||
} else {
|
||||
zlog_debug("%s: PATHD-TED: SL: Sucess query E : ted-sid (%d)",
|
||||
__func__, ted_sid);
|
||||
}
|
||||
if (CHECK_SID(entry->segment_list->protocol_origin, ted_sid,
|
||||
entry->sid_value)) {
|
||||
status = PATH_SID_ERROR;
|
||||
} else
|
||||
srte_segment_set_local_modification(entry->segment_list, entry,
|
||||
ted_sid);
|
||||
return status;
|
||||
}
|
||||
|
||||
int32_t srte_ted_do_query_type_f(struct srte_segment_entry *entry,
|
||||
struct ipaddr *local, struct ipaddr *remote)
|
||||
{
|
||||
int32_t status = 0;
|
||||
uint32_t ted_sid = MPLS_LABEL_NONE;
|
||||
|
||||
if (!entry || !local || !remote)
|
||||
return 0;
|
||||
|
||||
if (!path_ted_is_initialized())
|
||||
return status;
|
||||
|
||||
ted_sid = path_ted_query_type_f(local, remote);
|
||||
if (ted_sid == MPLS_LABEL_NONE) {
|
||||
zlog_warn("%s:SL: ERROR query F : ted-sid (%d)", __func__,
|
||||
ted_sid);
|
||||
} else {
|
||||
zlog_debug("%s:SL: Sucess query F : ted-sid (%d)", __func__,
|
||||
ted_sid);
|
||||
}
|
||||
if (CHECK_SID(entry->segment_list->protocol_origin, ted_sid,
|
||||
entry->sid_value)) {
|
||||
status = PATH_SID_ERROR;
|
||||
} else
|
||||
srte_segment_set_local_modification(entry->segment_list, entry,
|
||||
ted_sid);
|
||||
return status;
|
||||
}
|
||||
|
@ -24,6 +24,13 @@
|
||||
#include "lib/ipaddr.h"
|
||||
#include "lib/srte.h"
|
||||
#include "lib/hook.h"
|
||||
#include "lib/prefix.h"
|
||||
|
||||
#define PATH_SID_ERROR 1
|
||||
#define PATH_SID_NO_ERROR 0
|
||||
#define CHECK_SID(or, ts, es) \
|
||||
((or == SRTE_ORIGIN_PCEP && (ts == MPLS_LABEL_NONE || es != ts)) \
|
||||
|| (or == SRTE_ORIGIN_LOCAL && ts == MPLS_LABEL_NONE))
|
||||
|
||||
DECLARE_MGROUP(PATHD);
|
||||
|
||||
@ -100,7 +107,12 @@ enum srte_segment_nai_type {
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV6_NODE = 2,
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY = 3,
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY = 4,
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY = 5
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY = 5,
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY_LINK_LOCAL_ADDRESSES = 6,
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE = 7,
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE = 8,
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM = 9,
|
||||
SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM = 10
|
||||
};
|
||||
|
||||
enum objfun_type {
|
||||
@ -175,6 +187,9 @@ struct srte_segment_entry {
|
||||
/* NAI remote interface when nai type is not IPv4 unnumbered adjacency
|
||||
*/
|
||||
uint32_t nai_remote_iface;
|
||||
/* Support draft-ietf-spring-segment-routing-policy sl types queries*/
|
||||
uint8_t nai_local_prefix_len;
|
||||
uint8_t nai_algorithm;
|
||||
};
|
||||
RB_HEAD(srte_segment_entry_head, srte_segment_entry);
|
||||
RB_PROTOTYPE(srte_segment_entry_head, srte_segment_entry, entry,
|
||||
@ -200,6 +215,7 @@ struct srte_segment_list {
|
||||
#define F_SEGMENT_LIST_NEW 0x0002
|
||||
#define F_SEGMENT_LIST_MODIFIED 0x0004
|
||||
#define F_SEGMENT_LIST_DELETED 0x0008
|
||||
#define F_SEGMENT_LIST_SID_CONFLICT 0x0010
|
||||
};
|
||||
RB_HEAD(srte_segment_list_head, srte_segment_list);
|
||||
RB_PROTOTYPE(srte_segment_list_head, srte_segment_list, entry,
|
||||
@ -361,14 +377,18 @@ struct srte_segment_list *srte_segment_list_find(const char *name);
|
||||
struct srte_segment_entry *
|
||||
srte_segment_entry_add(struct srte_segment_list *segment_list, uint32_t index);
|
||||
void srte_segment_entry_del(struct srte_segment_entry *segment);
|
||||
void srte_segment_entry_set_nai(struct srte_segment_entry *segment,
|
||||
enum srte_segment_nai_type type,
|
||||
struct ipaddr *local_ip, uint32_t local_iface,
|
||||
struct ipaddr *remote_ip,
|
||||
uint32_t remote_iface);
|
||||
int srte_segment_entry_set_nai(struct srte_segment_entry *segment,
|
||||
enum srte_segment_nai_type type,
|
||||
struct ipaddr *local_ip, uint32_t local_iface,
|
||||
struct ipaddr *remote_ip, uint32_t remote_iface,
|
||||
uint8_t algo, uint8_t pref_len);
|
||||
void srte_segment_set_local_modification(struct srte_segment_list *s_list,
|
||||
struct srte_segment_entry *s_entry,
|
||||
uint32_t ted_sid);
|
||||
struct srte_policy *srte_policy_add(uint32_t color, struct ipaddr *endpoint);
|
||||
void srte_policy_del(struct srte_policy *policy);
|
||||
struct srte_policy *srte_policy_find(uint32_t color, struct ipaddr *endpoint);
|
||||
int srte_policy_update_ted_sid(void);
|
||||
void srte_policy_update_binding_sid(struct srte_policy *policy,
|
||||
uint32_t binding_sid);
|
||||
void srte_apply_changes(void);
|
||||
@ -414,4 +434,40 @@ void pathd_shutdown(void);
|
||||
/* path_cli.c */
|
||||
void path_cli_init(void);
|
||||
|
||||
|
||||
/**
|
||||
* Search for sid based in prefix and algorithm
|
||||
*
|
||||
* @param Prefix The prefix to use
|
||||
* @param algo Algorithm we want to query for
|
||||
* @param ted_sid Sid to query
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
int32_t srte_ted_do_query_type_c(struct srte_segment_entry *entry,
|
||||
struct prefix *prefix_cli, uint32_t algo);
|
||||
|
||||
/**
|
||||
* Search for sid based in prefix and interface id
|
||||
*
|
||||
* @param Prefix The prefix to use
|
||||
* @param local_iface The id of interface
|
||||
* @param ted_sid Sid to query
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
int32_t srte_ted_do_query_type_e(struct srte_segment_entry *entry,
|
||||
struct prefix *prefix_cli,
|
||||
uint32_t local_iface);
|
||||
/**
|
||||
* Search for sid based in local and remote ip
|
||||
*
|
||||
* @param entry entry to update
|
||||
* @param local Local addr for query
|
||||
* @param remote Local addr for query
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
int32_t srte_ted_do_query_type_f(struct srte_segment_entry *entry,
|
||||
struct ipaddr *local, struct ipaddr *remote);
|
||||
#endif /* _FRR_PATHD_H_ */
|
||||
|
@ -84,51 +84,71 @@ module frr-pathd {
|
||||
leaf index {
|
||||
type uint32;
|
||||
description "Segment index";
|
||||
}
|
||||
leaf sid-value {
|
||||
type rt-types:mpls-label;
|
||||
}
|
||||
leaf sid-value {
|
||||
type rt-types:mpls-label;
|
||||
description "MPLS label value";
|
||||
}
|
||||
container nai {
|
||||
presence "The segment has a Node or Adjacency Identifier";
|
||||
leaf type {
|
||||
description "NAI type";
|
||||
mandatory true;
|
||||
description "MPLS label value";
|
||||
}
|
||||
container nai {
|
||||
presence "The segement has a Node or Adjacency Identifier";
|
||||
leaf type {
|
||||
description "NAI type";
|
||||
mandatory true;
|
||||
type enumeration {
|
||||
enum ipv4_node {
|
||||
value 1;
|
||||
description "IPv4 node identifier";
|
||||
}
|
||||
enum ipv6_node {
|
||||
value 2;
|
||||
description "IPv6 node identifier";
|
||||
}
|
||||
enum ipv4_adjacency {
|
||||
value 3;
|
||||
description "IPv4 adjacency";
|
||||
}
|
||||
enum ipv6_adjacency {
|
||||
value 4;
|
||||
description "IPv6 adjacency";
|
||||
}
|
||||
enum ipv4_unnumbered_adjacency {
|
||||
value 5;
|
||||
description "IPv4 unnumbered adjacency";
|
||||
}
|
||||
type enumeration {
|
||||
enum ipv4_node {
|
||||
value 1;
|
||||
description "IPv4 node identifier";
|
||||
}
|
||||
enum ipv6_node {
|
||||
value 2;
|
||||
description "IPv6 node identifier";
|
||||
}
|
||||
enum ipv4_adjacency {
|
||||
value 3;
|
||||
description "IPv4 adjacency";
|
||||
}
|
||||
enum ipv6_adjacency {
|
||||
value 4;
|
||||
description "IPv6 adjacency";
|
||||
}
|
||||
enum ipv4_unnumbered_adjacency {
|
||||
value 5;
|
||||
description "IPv4 unnumbered adjacency";
|
||||
}
|
||||
enum ipv4_local_iface {
|
||||
value 7;
|
||||
description "IPv4 prefix with local interface id";
|
||||
}
|
||||
enum ipv6_local_iface {
|
||||
value 8;
|
||||
description "IPv6 prefix with local interface id";
|
||||
}
|
||||
enum ipv4_algo {
|
||||
value 9;
|
||||
description "IPv4 prefix with optional algorithm";
|
||||
}
|
||||
enum ipv6_algo {
|
||||
value 10;
|
||||
description "IPv6 prefix with optional algorithm";
|
||||
}
|
||||
}
|
||||
leaf local-address {
|
||||
type inet:ip-address;
|
||||
mandatory true;
|
||||
}
|
||||
leaf local-interface {
|
||||
type uint32;
|
||||
mandatory true;
|
||||
when "../type = 'ipv4_unnumbered_adjacency'";
|
||||
}
|
||||
leaf remote-address {
|
||||
type inet:ip-address;
|
||||
}
|
||||
leaf local-address {
|
||||
type inet:ip-address;
|
||||
mandatory true;
|
||||
}
|
||||
leaf local-prefix-len {
|
||||
type uint8;
|
||||
mandatory true;
|
||||
when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_algo' or ../type = 'ipv6_algo'";
|
||||
}
|
||||
leaf local-interface {
|
||||
type uint32;
|
||||
mandatory true;
|
||||
when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_unnumbered_adjacency'";
|
||||
}
|
||||
leaf remote-address {
|
||||
type inet:ip-address;
|
||||
mandatory true;
|
||||
when "../type = 'ipv4_adjacency' or ../type = 'ipv6_adjacency' or ../type = 'ipv4_unnumbered_adjacency'";
|
||||
}
|
||||
@ -137,6 +157,11 @@ module frr-pathd {
|
||||
mandatory true;
|
||||
when "../type = 'ipv4_unnumbered_adjacency'";
|
||||
}
|
||||
leaf algorithm {
|
||||
type uint8;
|
||||
mandatory true;
|
||||
when "../type = 'ipv4_algo' or ../type = 'ipv6_algo'";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user