mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 05:27:16 +02:00

If you have undefined behavior compilation checking gcc starts to complain about a bunch of places that do not have return's. When most of them actually do and we have the assert's to prove it. I'm just doing this to make the compiler happy for me, so I can continue to do work. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
542 lines
16 KiB
C
542 lines
16 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (C) 2020 NetDEF, Inc.
|
|
*/
|
|
|
|
#include <zebra.h>
|
|
|
|
#include <northbound.h>
|
|
#include <yang.h>
|
|
#include <printfrr.h>
|
|
#include "pceplib/pcep_msg_objects.h"
|
|
#include "pathd/pathd.h"
|
|
#include "pathd/path_pcep.h"
|
|
#include "pathd/path_pcep_config.h"
|
|
#include "pathd/path_pcep_debug.h"
|
|
#include "frrevent.h"
|
|
|
|
#define MAX_XPATH 256
|
|
#define MAX_FLOAT_LEN 22
|
|
#define INETADDR4_MAXLEN 16
|
|
#define INETADDR6_MAXLEN 40
|
|
#define INITIATED_CANDIDATE_PREFERENCE 255
|
|
#define INITIATED_POLICY_COLOR 1
|
|
|
|
|
|
static void copy_candidate_objfun_info(struct srte_candidate *candidate,
|
|
struct path *path);
|
|
static void copy_candidate_affinity_filters(struct srte_candidate *candidate,
|
|
struct path *path);
|
|
static struct path_hop *
|
|
path_pcep_config_list_path_hops(struct srte_segment_list *segment_list);
|
|
static struct srte_candidate *lookup_candidate(struct lsp_nb_key *key);
|
|
static char *candidate_name(struct srte_candidate *candidate);
|
|
static enum pcep_lsp_operational_status
|
|
status_int_to_ext(enum srte_policy_status status);
|
|
static enum pcep_sr_subobj_nai pcep_nai_type(enum srte_segment_nai_type type);
|
|
static enum srte_segment_nai_type srte_nai_type(enum pcep_sr_subobj_nai type);
|
|
|
|
void path_pcep_refine_path(struct path *path)
|
|
{
|
|
struct srte_candidate *candidate = lookup_candidate(&path->nbkey);
|
|
struct srte_lsp *lsp;
|
|
|
|
if (candidate == NULL)
|
|
return;
|
|
|
|
lsp = candidate->lsp;
|
|
|
|
if (path->name == NULL)
|
|
path->name = candidate_name(candidate);
|
|
if (path->type == SRTE_CANDIDATE_TYPE_UNDEFINED)
|
|
path->type = candidate->type;
|
|
if (path->create_origin == SRTE_ORIGIN_UNDEFINED)
|
|
path->create_origin = candidate->protocol_origin;
|
|
if ((path->update_origin == SRTE_ORIGIN_UNDEFINED)
|
|
&& (lsp->segment_list != NULL))
|
|
path->update_origin = lsp->segment_list->protocol_origin;
|
|
}
|
|
|
|
struct path *path_pcep_config_get_path(struct lsp_nb_key *key)
|
|
{
|
|
struct srte_candidate *candidate = lookup_candidate(key);
|
|
if (candidate == NULL)
|
|
return NULL;
|
|
return candidate_to_path(candidate);
|
|
}
|
|
|
|
void path_pcep_config_list_path(path_list_cb_t cb, void *arg)
|
|
{
|
|
struct path *path;
|
|
struct srte_policy *policy;
|
|
struct srte_candidate *candidate;
|
|
|
|
RB_FOREACH (policy, srte_policy_head, &srte_policies) {
|
|
RB_FOREACH (candidate, srte_candidate_head,
|
|
&policy->candidate_paths) {
|
|
path = candidate_to_path(candidate);
|
|
if (!cb(path, arg))
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
struct path *candidate_to_path(struct srte_candidate *candidate)
|
|
{
|
|
char *name;
|
|
struct path *path;
|
|
struct path_hop *hop = NULL;
|
|
struct path_metric *metric = NULL;
|
|
struct srte_policy *policy;
|
|
struct srte_lsp *lsp;
|
|
enum pcep_lsp_operational_status status;
|
|
enum srte_protocol_origin update_origin = 0;
|
|
char *originator = NULL;
|
|
|
|
policy = candidate->policy;
|
|
lsp = candidate->lsp;
|
|
|
|
if (lsp->segment_list != NULL) {
|
|
hop = path_pcep_config_list_path_hops(lsp->segment_list);
|
|
update_origin = lsp->segment_list->protocol_origin;
|
|
originator = XSTRDUP(MTYPE_PCEP, lsp->segment_list->originator);
|
|
}
|
|
path = pcep_new_path();
|
|
name = candidate_name(candidate);
|
|
if (CHECK_FLAG(candidate->flags, F_CANDIDATE_BEST)) {
|
|
status = status_int_to_ext(policy->status);
|
|
} else {
|
|
status = PCEP_LSP_OPERATIONAL_DOWN;
|
|
}
|
|
for (uint32_t i = 0; i < MAX_METRIC_TYPE; i++) {
|
|
struct path_metric *path_metric;
|
|
struct srte_metric *srte_metric = &lsp->metrics[i];
|
|
if (CHECK_FLAG(srte_metric->flags, F_METRIC_IS_DEFINED)) {
|
|
path_metric = pcep_new_metric();
|
|
path_metric->next = metric;
|
|
metric = path_metric;
|
|
metric->type = i + 1;
|
|
metric->value = srte_metric->value;
|
|
metric->enforce = CHECK_FLAG(srte_metric->flags,
|
|
F_METRIC_IS_REQUIRED);
|
|
metric->is_bound = CHECK_FLAG(srte_metric->flags,
|
|
F_METRIC_IS_BOUND);
|
|
metric->is_computed = CHECK_FLAG(srte_metric->flags,
|
|
F_METRIC_IS_COMPUTED);
|
|
}
|
|
}
|
|
*path = (struct path){
|
|
.nbkey = (struct lsp_nb_key){.color = policy->color,
|
|
.endpoint = policy->endpoint,
|
|
.preference =
|
|
candidate->preference},
|
|
.create_origin = lsp->protocol_origin,
|
|
.update_origin = update_origin,
|
|
.originator = originator,
|
|
.plsp_id = 0,
|
|
.name = name,
|
|
.type = candidate->type,
|
|
.srp_id = policy->srp_id,
|
|
.req_id = 0,
|
|
.binding_sid = policy->binding_sid,
|
|
.status = status,
|
|
.do_remove = false,
|
|
.go_active = false,
|
|
.was_created = false,
|
|
.was_removed = false,
|
|
.is_synching = false,
|
|
.is_delegated = false,
|
|
.first_hop = hop,
|
|
.first_metric = metric};
|
|
|
|
path->has_bandwidth = CHECK_FLAG(lsp->flags, F_CANDIDATE_HAS_BANDWIDTH);
|
|
if (path->has_bandwidth) {
|
|
path->enforce_bandwidth =
|
|
CHECK_FLAG(lsp->flags, F_CANDIDATE_REQUIRED_BANDWIDTH);
|
|
path->bandwidth = lsp->bandwidth;
|
|
} else {
|
|
path->enforce_bandwidth = true;
|
|
path->bandwidth = 0;
|
|
}
|
|
|
|
copy_candidate_objfun_info(candidate, path);
|
|
copy_candidate_affinity_filters(candidate, path);
|
|
|
|
return path;
|
|
}
|
|
|
|
void copy_candidate_objfun_info(struct srte_candidate *candidate,
|
|
struct path *path)
|
|
{
|
|
struct srte_lsp *lsp = candidate->lsp;
|
|
|
|
if (lsp != NULL) {
|
|
if (CHECK_FLAG(lsp->flags, F_CANDIDATE_HAS_OBJFUN)) {
|
|
path->has_pce_objfun = true;
|
|
path->pce_objfun = lsp->objfun;
|
|
} else {
|
|
path->has_pce_objfun = false;
|
|
path->pce_objfun = OBJFUN_UNDEFINED;
|
|
}
|
|
}
|
|
if (CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_OBJFUN)) {
|
|
path->has_pcc_objfun = true;
|
|
path->pcc_objfun = candidate->objfun;
|
|
path->enforce_pcc_objfun = CHECK_FLAG(
|
|
candidate->flags, F_CANDIDATE_REQUIRED_OBJFUN);
|
|
|
|
} else {
|
|
path->has_pcc_objfun = false;
|
|
path->pcc_objfun = OBJFUN_UNDEFINED;
|
|
UNSET_FLAG(candidate->flags, F_CANDIDATE_REQUIRED_OBJFUN);
|
|
}
|
|
}
|
|
|
|
void copy_candidate_affinity_filters(struct srte_candidate *candidate,
|
|
struct path *path)
|
|
{
|
|
bool eany = CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_EXCLUDE_ANY);
|
|
bool iany = CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_INCLUDE_ANY);
|
|
bool iall = CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_INCLUDE_ALL);
|
|
path->has_affinity_filters = eany || iany || iall;
|
|
path->affinity_filters[AFFINITY_FILTER_EXCLUDE_ANY - 1] =
|
|
eany ? candidate->affinity_filters[AFFINITY_FILTER_EXCLUDE_ANY
|
|
- 1]
|
|
: 0;
|
|
path->affinity_filters[AFFINITY_FILTER_INCLUDE_ANY - 1] =
|
|
iany ? candidate->affinity_filters[AFFINITY_FILTER_INCLUDE_ANY
|
|
- 1]
|
|
: 0;
|
|
path->affinity_filters[AFFINITY_FILTER_INCLUDE_ALL - 1] =
|
|
iall ? candidate->affinity_filters[AFFINITY_FILTER_INCLUDE_ALL
|
|
- 1]
|
|
: 0;
|
|
}
|
|
|
|
struct path_hop *
|
|
path_pcep_config_list_path_hops(struct srte_segment_list *segment_list)
|
|
{
|
|
struct srte_segment_entry *segment;
|
|
struct path_hop *hop = NULL, *last_hop = NULL;
|
|
|
|
RB_FOREACH_REVERSE (segment, srte_segment_entry_head,
|
|
&segment_list->segments) {
|
|
hop = pcep_new_hop();
|
|
*hop = (struct path_hop){
|
|
.next = last_hop,
|
|
.is_loose = false,
|
|
.has_sid = true,
|
|
.is_mpls = true,
|
|
.has_attribs = false,
|
|
.sid = {.mpls = {.label = segment->sid_value}},
|
|
.has_nai =
|
|
segment->nai_type != SRTE_SEGMENT_NAI_TYPE_NONE,
|
|
.nai = {.type = pcep_nai_type(segment->nai_type)}};
|
|
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;
|
|
case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY:
|
|
case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY:
|
|
memcpy(&hop->nai.local_addr, &segment->nai_local_addr,
|
|
sizeof(struct ipaddr));
|
|
memcpy(&hop->nai.remote_addr, &segment->nai_remote_addr,
|
|
sizeof(struct ipaddr));
|
|
break;
|
|
case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY:
|
|
memcpy(&hop->nai.local_addr, &segment->nai_local_addr,
|
|
sizeof(struct ipaddr));
|
|
hop->nai.local_iface = segment->nai_local_iface;
|
|
memcpy(&hop->nai.remote_addr, &segment->nai_remote_addr,
|
|
sizeof(struct ipaddr));
|
|
hop->nai.remote_iface = segment->nai_remote_iface;
|
|
break;
|
|
case SRTE_SEGMENT_NAI_TYPE_NONE:
|
|
case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY_LINK_LOCAL_ADDRESSES:
|
|
break;
|
|
}
|
|
last_hop = hop;
|
|
}
|
|
return hop;
|
|
}
|
|
|
|
int path_pcep_config_initiate_path(struct path *path)
|
|
{
|
|
struct srte_policy *policy;
|
|
struct srte_candidate *candidate;
|
|
|
|
if (path->do_remove) {
|
|
zlog_warn("PCE %s tried to REMOVE pce-initiate a path ",
|
|
path->originator);
|
|
candidate = lookup_candidate(&path->nbkey);
|
|
if (candidate) {
|
|
if (!path->is_delegated) {
|
|
zlog_warn(
|
|
"(%s)PCE tried to REMOVE but it's not Delegated!",
|
|
__func__);
|
|
return ERROR_19_1;
|
|
}
|
|
if (candidate->type != SRTE_CANDIDATE_TYPE_DYNAMIC) {
|
|
zlog_warn(
|
|
"(%s)PCE tried to REMOVE but it's not PCE origin!",
|
|
__func__);
|
|
return ERROR_19_9;
|
|
}
|
|
zlog_warn(
|
|
"(%s)PCE tried to REMOVE found candidate!, let's remove",
|
|
__func__);
|
|
candidate->policy->srp_id = path->srp_id;
|
|
SET_FLAG(candidate->policy->flags, F_POLICY_DELETED);
|
|
SET_FLAG(candidate->flags, F_CANDIDATE_DELETED);
|
|
} else {
|
|
zlog_warn("(%s)PCE tried to REMOVE not existing LSP!",
|
|
__func__);
|
|
return ERROR_19_3;
|
|
}
|
|
srte_apply_changes();
|
|
} else {
|
|
assert(!IS_IPADDR_NONE(&path->nbkey.endpoint));
|
|
|
|
if (path->nbkey.preference == 0)
|
|
path->nbkey.preference = INITIATED_CANDIDATE_PREFERENCE;
|
|
|
|
if (path->nbkey.color == 0)
|
|
path->nbkey.color = INITIATED_POLICY_COLOR;
|
|
|
|
candidate = lookup_candidate(&path->nbkey);
|
|
if (!candidate) {
|
|
policy = srte_policy_add(
|
|
path->nbkey.color, &path->nbkey.endpoint,
|
|
SRTE_ORIGIN_PCEP, path->originator);
|
|
strlcpy(policy->name, path->name, sizeof(policy->name));
|
|
policy->binding_sid = path->binding_sid;
|
|
SET_FLAG(policy->flags, F_POLICY_NEW);
|
|
candidate = srte_candidate_add(
|
|
policy, path->nbkey.preference,
|
|
SRTE_ORIGIN_PCEP, path->originator);
|
|
candidate->policy->srp_id = path->srp_id;
|
|
strlcpy(candidate->name, path->name,
|
|
sizeof(candidate->name));
|
|
SET_FLAG(candidate->flags, F_CANDIDATE_NEW);
|
|
} else {
|
|
policy = candidate->policy;
|
|
if ((path->originator != candidate->originator)
|
|
|| (path->originator != policy->originator)) {
|
|
/* There is already an initiated path from
|
|
* another PCE, show a warning and regect the
|
|
* initiated path */
|
|
zlog_warn(
|
|
"PCE %s tried to initiate a path already initiated by PCE %s",
|
|
path->originator,
|
|
candidate->originator);
|
|
return 1;
|
|
}
|
|
if ((policy->protocol_origin != SRTE_ORIGIN_PCEP)
|
|
|| (candidate->protocol_origin
|
|
!= SRTE_ORIGIN_PCEP)) {
|
|
/* There is already an initiated path from
|
|
* another PCE, show a warning and regect the
|
|
* initiated path */
|
|
zlog_warn(
|
|
"PCE %s tried to initiate a path created localy",
|
|
path->originator);
|
|
return 1;
|
|
}
|
|
}
|
|
return path_pcep_config_update_path(path);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int path_pcep_config_update_path(struct path *path)
|
|
{
|
|
assert(path != NULL);
|
|
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;
|
|
char segment_list_name_buff[64 + 1 + 64 + 1 + 11 + 1];
|
|
char *segment_list_name = NULL;
|
|
struct srte_candidate *candidate;
|
|
struct srte_segment_list *segment_list = NULL;
|
|
struct srte_segment_entry *segment;
|
|
|
|
candidate = lookup_candidate(&path->nbkey);
|
|
|
|
// if there is no candidate to update we are done
|
|
if (!candidate)
|
|
return 0;
|
|
|
|
candidate->policy->srp_id = path->srp_id;
|
|
// first clean up old segment list if present
|
|
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)
|
|
return PATH_NB_ERR;
|
|
|
|
snprintf(segment_list_name_buff, sizeof(segment_list_name_buff),
|
|
"%s-%u", path->name, path->plsp_id);
|
|
segment_list_name = segment_list_name_buff;
|
|
|
|
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);
|
|
|
|
for (hop = path->first_hop, index = 10; hop != NULL;
|
|
hop = hop->next, index += 10) {
|
|
assert(hop->has_sid);
|
|
assert(hop->is_mpls);
|
|
|
|
segment = srte_segment_entry_add(segment_list, index);
|
|
|
|
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;
|
|
SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
|
|
|
|
for (metric = path->first_metric; metric != NULL; metric = metric->next)
|
|
srte_lsp_set_metric(
|
|
candidate->lsp,
|
|
(enum srte_candidate_metric_type)metric->type,
|
|
metric->value, metric->enforce, metric->is_bound,
|
|
metric->is_computed);
|
|
|
|
if (path->has_bandwidth)
|
|
srte_lsp_set_bandwidth(candidate->lsp, path->bandwidth,
|
|
path->enforce_bandwidth);
|
|
|
|
if (path->has_pce_objfun) {
|
|
SET_FLAG(candidate->lsp->flags, F_CANDIDATE_HAS_OBJFUN);
|
|
candidate->lsp->objfun = path->pce_objfun;
|
|
}
|
|
|
|
if (number_of_sid_clashed)
|
|
SET_FLAG(segment_list->flags, F_SEGMENT_LIST_SID_CONFLICT);
|
|
else
|
|
srte_apply_changes();
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct srte_candidate *lookup_candidate(struct lsp_nb_key *key)
|
|
{
|
|
struct srte_policy *policy = NULL;
|
|
policy = srte_policy_find(key->color, &key->endpoint);
|
|
if (policy == NULL)
|
|
return NULL;
|
|
return srte_candidate_find(policy, key->preference);
|
|
}
|
|
|
|
char *candidate_name(struct srte_candidate *candidate)
|
|
{
|
|
if (candidate->protocol_origin == SRTE_ORIGIN_PCEP
|
|
|| candidate->protocol_origin == SRTE_ORIGIN_BGP)
|
|
return asprintfrr(MTYPE_PCEP, "%s", candidate->policy->name);
|
|
else
|
|
return asprintfrr(MTYPE_PCEP, "%s-%s", candidate->policy->name,
|
|
candidate->name);
|
|
}
|
|
|
|
enum pcep_lsp_operational_status
|
|
status_int_to_ext(enum srte_policy_status status)
|
|
{
|
|
switch (status) {
|
|
case SRTE_POLICY_STATUS_UP:
|
|
return PCEP_LSP_OPERATIONAL_ACTIVE;
|
|
case SRTE_POLICY_STATUS_GOING_UP:
|
|
return PCEP_LSP_OPERATIONAL_GOING_UP;
|
|
case SRTE_POLICY_STATUS_GOING_DOWN:
|
|
return PCEP_LSP_OPERATIONAL_GOING_DOWN;
|
|
case SRTE_POLICY_STATUS_DOWN:
|
|
case SRTE_POLICY_STATUS_UNKNOWN:
|
|
return PCEP_LSP_OPERATIONAL_DOWN;
|
|
}
|
|
|
|
assert(!"Reached end of function where we are not expecting to");
|
|
return PCEP_LSP_OPERATIONAL_DOWN;
|
|
}
|
|
|
|
enum pcep_sr_subobj_nai pcep_nai_type(enum srte_segment_nai_type type)
|
|
{
|
|
switch (type) {
|
|
case SRTE_SEGMENT_NAI_TYPE_NONE:
|
|
return PCEP_SR_SUBOBJ_NAI_ABSENT;
|
|
case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE:
|
|
return PCEP_SR_SUBOBJ_NAI_IPV4_NODE;
|
|
case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE:
|
|
return PCEP_SR_SUBOBJ_NAI_IPV6_NODE;
|
|
case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY:
|
|
return PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY;
|
|
case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY:
|
|
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;
|
|
}
|
|
}
|
|
|
|
enum srte_segment_nai_type srte_nai_type(enum pcep_sr_subobj_nai type)
|
|
{
|
|
switch (type) {
|
|
case PCEP_SR_SUBOBJ_NAI_ABSENT:
|
|
return SRTE_SEGMENT_NAI_TYPE_NONE;
|
|
case PCEP_SR_SUBOBJ_NAI_IPV4_NODE:
|
|
return SRTE_SEGMENT_NAI_TYPE_IPV4_NODE;
|
|
case PCEP_SR_SUBOBJ_NAI_IPV6_NODE:
|
|
return SRTE_SEGMENT_NAI_TYPE_IPV6_NODE;
|
|
case PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY:
|
|
return SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY;
|
|
case PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY:
|
|
return SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY;
|
|
case PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY:
|
|
return SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY;
|
|
case PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY:
|
|
case PCEP_SR_SUBOBJ_NAI_UNKNOWN:
|
|
return SRTE_SEGMENT_NAI_TYPE_NONE;
|
|
}
|
|
|
|
assert(!"Reached end of function where we were not expecting to");
|
|
return SRTE_SEGMENT_NAI_TYPE_NONE;
|
|
}
|