From abc927aa738ca4c5e7434885d0dc58aebd3f31ca Mon Sep 17 00:00:00 2001 From: GalaxyGorilla Date: Wed, 17 Jun 2020 12:22:19 +0000 Subject: [PATCH 1/7] pathd: move NB code out of PCC module * use pathd utility functions and flags directly * rename path_pcep_nb* -> path_pcep_config* Signed-off-by: GalaxyGorilla --- pathd/path_pcep.c | 8 +- pathd/path_pcep_config.c | 550 +++++++++++++++++++ pathd/{path_pcep_nb.h => path_pcep_config.h} | 14 +- pathd/path_pcep_controller.c | 2 +- pathd/path_pcep_pcc.c | 4 +- pathd/pathd.c | 10 + pathd/pathd.h | 2 + pathd/subdir.am | 4 +- 8 files changed, 578 insertions(+), 16 deletions(-) create mode 100644 pathd/path_pcep_config.c rename pathd/{path_pcep_nb.h => path_pcep_config.h} (81%) diff --git a/pathd/path_pcep.c b/pathd/path_pcep.c index bec2a0353dd4..d73c524b7aaf 100644 --- a/pathd/path_pcep.c +++ b/pathd/path_pcep.c @@ -37,7 +37,7 @@ #include "pathd/path_pcep.h" #include "pathd/path_pcep_controller.h" #include "pathd/path_pcep_lib.h" -#include "pathd/path_pcep_nb.h" +#include "pathd/path_pcep_config.h" /* @@ -201,7 +201,7 @@ int pcep_main_event_handler(enum pcep_main_event_type type, int pcc_id, int pcep_main_event_start_sync(int pcc_id) { - path_nb_list_path(pcep_main_event_start_sync_cb, &pcc_id); + path_pcep_config_list_path(pcep_main_event_start_sync_cb, &pcc_id); pcep_ctrl_sync_done(pcep_g->fpt, pcc_id); return 0; } @@ -218,14 +218,14 @@ int pcep_main_event_update_candidate(struct path *path) struct path *resp = NULL; int ret = 0; - ret = path_nb_update_path(path); + ret = path_pcep_config_update_path(path); if (ret != PATH_NB_ERR && path->srp_id != 0) { /* ODL and Cisco requires the first reported * LSP to have a DOWN status, the later status changes * will be comunicated through hook calls. */ enum pcep_lsp_operational_status real_status; - if ((resp = path_nb_get_path(&path->nbkey))) { + if ((resp = path_pcep_config_get_path(&path->nbkey))) { resp->srp_id = path->srp_id; real_status = resp->status; resp->status = PCEP_LSP_OPERATIONAL_DOWN; diff --git a/pathd/path_pcep_config.c b/pathd/path_pcep_config.c new file mode 100644 index 000000000000..b08967f9d2fe --- /dev/null +++ b/pathd/path_pcep_config.c @@ -0,0 +1,550 @@ +/* + * Copyright (C) 2020 NetDEF, Inc. + * Sebastien Merle + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include "pathd/pathd.h" +#include "pathd/path_pcep.h" +#include "pathd/path_pcep_config.h" +#include "pathd/path_pcep_debug.h" + +#define MAX_XPATH 256 +#define MAX_FLOAT_LEN 22 +#define INETADDR4_MAXLEN 16 +#define INETADDR6_MAXLEN 40 + + +static struct path_hop * +path_pcep_config_list_path_hops(struct srte_segment_list *segment_list); + +static void path_pcep_config_delete_candidate_segment_list(struct lsp_nb_key *key); +static void +path_pcep_config_add_segment_list_segment(struct srte_segment_list *segment_list, + uint32_t index, uint32_t label); +static void +path_pcep_config_add_segment_list_segment_no_nai(struct srte_segment_list *segment_list, + uint32_t index); +static void path_pcep_config_add_segment_list_segment_nai_ipv4_node( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *ip); +static void path_pcep_config_add_segment_list_segment_nai_ipv6_node( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *ip); +static void path_pcep_config_add_segment_list_segment_nai_ipv4_adj( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *local_ip, struct ipaddr *remote_ip); +static void path_pcep_config_add_segment_list_segment_nai_ipv6_adj( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *local_ip, struct ipaddr *remote_ip); +static void path_pcep_config_add_segment_list_segment_nai_ipv4_unnumbered_adj( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *local_ip, uint32_t local_iface, struct ipaddr *remote_ip, + uint32_t remote_iface); +static struct srte_segment_list * +path_pcep_config_create_segment_list(const char *segment_list_name, + enum srte_protocol_origin protocol, + const char *originator); +static void +path_pcep_config_update_candidate_path(struct lsp_nb_key *key, + struct srte_segment_list *segment_list); +static void path_pcep_config_add_candidate_path_metric(uint32_t color, + struct ipaddr *endpoint, + uint32_t preference, + enum pcep_metric_types type, + float value, bool is_bound, + bool is_computed); +static void path_pcep_config_set_candidate_path_bandwidth(uint32_t color, + struct ipaddr *endpoint, + uint32_t preference, + float value); + +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); + +void path_pcep_config_lookup(struct path *path) +{ + struct srte_candidate *candidate = lookup_candidate(&path->nbkey); + if (candidate == NULL) + return; + 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) + && (candidate->segment_list != NULL)) + path->update_origin = candidate->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; + enum pcep_lsp_operational_status status; + enum srte_protocol_origin update_origin = 0; + char *originator = NULL; + + policy = candidate->policy; + + if (candidate->segment_list != NULL) { + hop = path_pcep_config_list_path_hops(candidate->segment_list); + update_origin = candidate->segment_list->protocol_origin; + originator = XSTRDUP(MTYPE_PCEP, + candidate->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; + } + if (CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_ABC_RT)) { + struct path_metric *new_metric = pcep_new_metric(); + new_metric->next = metric; + metric = new_metric; + metric->type = PCEP_METRIC_AGGREGATE_BW; + metric->value = candidate->metric_abc_rt; + metric->is_bound = CHECK_FLAG(candidate->flags, + F_CANDIDATE_METRIC_ABC_BOUND_RT); + metric->is_computed = CHECK_FLAG( + candidate->flags, F_CANDIDATE_METRIC_ABC_COMPUTED_RT); + } + if (CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_TE_RT)) { + struct path_metric *new_metric = pcep_new_metric(); + new_metric->next = metric; + metric = new_metric; + metric->type = PCEP_METRIC_TE; + metric->value = candidate->metric_te_rt; + metric->is_bound = CHECK_FLAG(candidate->flags, + F_CANDIDATE_METRIC_TE_BOUND_RT); + metric->is_computed = CHECK_FLAG( + candidate->flags, F_CANDIDATE_METRIC_TE_COMPUTED_RT); + } + *path = (struct path){ + .nbkey = (struct lsp_nb_key){.color = policy->color, + .endpoint = policy->endpoint, + .preference = + candidate->preference}, + .create_origin = candidate->protocol_origin, + .update_origin = update_origin, + .originator = originator, + .plsp_id = 0, + .name = name, + .type = candidate->type, + .srp_id = 0, + .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(candidate->flags, + F_CANDIDATE_HAS_BANDWIDTH_RT); + path->bandwidth = candidate->bandwidth_rt; + + return path; +} + +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: + 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; + default: + break; + } + last_hop = hop; + } + return hop; +} + +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); + + 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_segment_list *segment_list; + + path_pcep_config_delete_candidate_segment_list(&path->nbkey); + + 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; + segment_list = path_pcep_config_create_segment_list(segment_list_name, + path->update_origin, + path->originator); + for (hop = path->first_hop, index = 10; hop != NULL; + hop = hop->next, index += 10) { + assert(hop->has_sid); + assert(hop->is_mpls); + path_pcep_config_add_segment_list_segment(segment_list, index, + hop->sid.mpls.label); + if (hop->has_nai) { + switch (hop->nai.type) { + case PCEP_SR_SUBOBJ_NAI_IPV4_NODE: + path_pcep_config_add_segment_list_segment_nai_ipv4_node( + segment_list, index, + &hop->nai.local_addr); + break; + case PCEP_SR_SUBOBJ_NAI_IPV6_NODE: + path_pcep_config_add_segment_list_segment_nai_ipv6_node( + segment_list, index, + &hop->nai.local_addr); + break; + case PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY: + path_pcep_config_add_segment_list_segment_nai_ipv4_adj( + segment_list, index, + &hop->nai.local_addr, + &hop->nai.remote_addr); + break; + case PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY: + path_pcep_config_add_segment_list_segment_nai_ipv6_adj( + segment_list, index, + &hop->nai.local_addr, + &hop->nai.remote_addr); + break; + case PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY: + path_pcep_config_add_segment_list_segment_nai_ipv4_unnumbered_adj( + segment_list, index, + &hop->nai.local_addr, + hop->nai.local_iface, + &hop->nai.remote_addr, + hop->nai.remote_iface); + break; + default: + path_pcep_config_add_segment_list_segment_no_nai( + segment_list, index); + break; + } + } + } + } + + path_pcep_config_update_candidate_path(&path->nbkey, segment_list); + + for (metric = path->first_metric; metric != NULL; + metric = metric->next) { + path_pcep_config_add_candidate_path_metric( + path->nbkey.color, &path->nbkey.endpoint, + path->nbkey.preference, metric->type, metric->value, + metric->is_bound, metric->is_computed); + } + + if (path->has_bandwidth) { + path_pcep_config_set_candidate_path_bandwidth( + path->nbkey.color, &path->nbkey.endpoint, + path->nbkey.preference, path->bandwidth); + } + + srte_apply_changes(); + + return 0; +} + +/* Delete the candidate path segment list if it was created through PCEP + and by the given originator */ +void path_pcep_config_delete_candidate_segment_list(struct lsp_nb_key *key) +{ + struct srte_candidate *candidate = lookup_candidate(key); + + if ((candidate == NULL) || (candidate->segment_list == NULL)) + return; + + SET_FLAG(candidate->segment_list->flags, F_SEGMENT_LIST_DELETED); + + candidate->segment_list = NULL; + SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); +} + +void path_pcep_config_add_segment_list_segment(struct srte_segment_list *segment_list, + uint32_t index, uint32_t label) +{ + struct srte_segment_entry *segment; + + segment = srte_segment_entry_add(segment_list, index); + segment->sid_value = (mpls_label_t)label; + SET_FLAG(segment->segment_list->flags, F_SEGMENT_LIST_MODIFIED); +} + +void path_pcep_config_add_segment_list_segment_no_nai( + struct srte_segment_list *segment_list, uint32_t index) +{ + struct srte_segment_entry *segment; + + segment = srte_segment_entry_find(segment_list, index); + segment->nai_type = SRTE_SEGMENT_NAI_TYPE_NONE; + 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; +} + +void path_pcep_config_add_segment_list_segment_nai_ipv4_node( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *ip) +{ + struct srte_segment_entry *segment; + + segment = srte_segment_entry_find(segment_list, index); + segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV4_NODE; + memcpy(&segment->nai_local_addr, ip, sizeof(struct ipaddr)); +} + +void path_pcep_config_add_segment_list_segment_nai_ipv6_node( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *ip) +{ + struct srte_segment_entry *segment; + + segment = srte_segment_entry_find(segment_list, index); + segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV6_NODE; + memcpy(&segment->nai_local_addr, ip, sizeof(struct ipaddr)); +} + +void path_pcep_config_add_segment_list_segment_nai_ipv4_adj( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *local_ip, struct ipaddr *remote_ip) +{ + struct srte_segment_entry *segment; + + segment = srte_segment_entry_find(segment_list, index); + segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY; + memcpy(&segment->nai_local_addr, local_ip, sizeof(struct ipaddr)); + memcpy(&segment->nai_remote_addr, remote_ip, sizeof(struct ipaddr)); +} + +void path_pcep_config_add_segment_list_segment_nai_ipv6_adj( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *local_ip, struct ipaddr *remote_ip) +{ + struct srte_segment_entry *segment; + + segment = srte_segment_entry_find(segment_list, index); + segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY; + memcpy(&segment->nai_local_addr, local_ip, sizeof(struct ipaddr)); + memcpy(&segment->nai_remote_addr, remote_ip, sizeof(struct ipaddr)); +} + +void path_pcep_config_add_segment_list_segment_nai_ipv4_unnumbered_adj( + struct srte_segment_list *segment_list, uint32_t index, + struct ipaddr *local_ip, uint32_t local_iface, struct ipaddr *remote_ip, + uint32_t remote_iface) +{ + struct srte_segment_entry *segment; + + segment = srte_segment_entry_find(segment_list, index); + segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY; + memcpy(&segment->nai_local_addr, local_ip, sizeof(struct ipaddr)); + memcpy(&segment->nai_remote_addr, remote_ip, sizeof(struct ipaddr)); + segment->nai_local_iface = local_iface; + segment->nai_remote_iface = remote_iface; +} + +struct srte_segment_list * +path_pcep_config_create_segment_list(const char *segment_list_name, + enum srte_protocol_origin protocol, + const char *originator) +{ + struct srte_segment_list *segment_list; + + segment_list = srte_segment_list_add(segment_list_name); + SET_FLAG(segment_list->flags, F_SEGMENT_LIST_NEW); + + segment_list->protocol_origin = protocol; + strlcpy(segment_list->originator, originator, + sizeof(segment_list->originator)); + SET_FLAG(segment_list->flags, F_SEGMENT_LIST_MODIFIED); + + return segment_list; +} + +void path_pcep_config_update_candidate_path(struct lsp_nb_key *key, + struct srte_segment_list *segment_list) +{ + struct srte_policy *policy; + struct srte_candidate *candidate; + + policy = srte_policy_find(key->color, &key->endpoint); + candidate = srte_candidate_find(policy, key->preference); + + candidate->segment_list = segment_list; + assert(candidate->segment_list); + + SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); +} + +void path_pcep_config_add_candidate_path_metric(uint32_t color, struct ipaddr *endpoint, + uint32_t preference, + enum pcep_metric_types type, float value, + bool is_bound, bool is_computed) +{ + struct srte_policy *policy; + struct srte_candidate *candidate; + + policy = srte_policy_find(color, endpoint); + candidate = srte_candidate_find(policy, preference); + + srte_candidate_set_metric(candidate, type, value, is_bound, is_computed, + false); +} + +void path_pcep_config_set_candidate_path_bandwidth(uint32_t color, + struct ipaddr *endpoint, + uint32_t preference, float value) +{ + struct srte_policy *policy; + struct srte_candidate *candidate; + + policy = srte_policy_find(color, endpoint); + candidate = srte_candidate_find(policy, preference); + + srte_candidate_set_bandwidth(candidate, value, false); +} + +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) +{ + 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; + default: + 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; + default: + return PCEP_SR_SUBOBJ_NAI_UNKNOWN; + } +} diff --git a/pathd/path_pcep_nb.h b/pathd/path_pcep_config.h similarity index 81% rename from pathd/path_pcep_nb.h rename to pathd/path_pcep_config.h index b58e6fe89e4d..3d7421130ba1 100644 --- a/pathd/path_pcep_nb.h +++ b/pathd/path_pcep_config.h @@ -17,8 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef _PATH_PCEP_NB_H_ -#define _PATH_PCEP_NB_H_ +#ifndef _PATH_PCEP_CONFIG_H_ +#define _PATH_PCEP_CONFIG_H_ #include #include @@ -35,11 +35,11 @@ typedef int (*path_list_cb_t)(struct path *path, void *arg); and type. Used for path generated from PCEP message received from the PCE so they contains more information about the candidate path. If no matching policy or candidate path is found, nothing is changed */ -void path_nb_lookup(struct path *path); -struct path *path_nb_get_path(struct lsp_nb_key *key); -void path_nb_list_path(path_list_cb_t cb, void *arg); -int path_nb_update_path(struct path *path); +void path_pcep_config_lookup(struct path *path); +struct path *path_pcep_config_get_path(struct lsp_nb_key *key); +void path_pcep_config_list_path(path_list_cb_t cb, void *arg); +int path_pcep_config_update_path(struct path *path); struct path *candidate_to_path(struct srte_candidate *candidate); -#endif // _PATH_PCEP_NB_H_ +#endif // _PATH_PCEP_CONFIG_H_ diff --git a/pathd/path_pcep_controller.c b/pathd/path_pcep_controller.c index d8779e270613..85700f188416 100644 --- a/pathd/path_pcep_controller.c +++ b/pathd/path_pcep_controller.c @@ -33,7 +33,7 @@ #include "pathd/path_pcep.h" #include "pathd/path_pcep_controller.h" #include "pathd/path_pcep_pcc.h" -#include "pathd/path_pcep_nb.h" +#include "pathd/path_pcep_config.h" #include "pathd/path_pcep_debug.h" #define MAX_RECONNECT_DELAY 120 diff --git a/pathd/path_pcep_pcc.c b/pathd/path_pcep_pcc.c index 400c0abda501..ae7003bdf2b9 100644 --- a/pathd/path_pcep_pcc.c +++ b/pathd/path_pcep_pcc.c @@ -44,7 +44,7 @@ #include "pathd/path_pcep.h" #include "pathd/path_pcep_controller.h" #include "pathd/path_pcep_lib.h" -#include "pathd/path_pcep_nb.h" +#include "pathd/path_pcep_config.h" #include "pathd/path_pcep_debug.h" @@ -617,7 +617,7 @@ void handle_pcep_lsp_update(struct ctrl_state *ctrl_state, path = pcep_lib_parse_path(msg); lookup_nbkey(pcc_state, path); /* TODO: Investigate if this is safe to do in the controller thread */ - path_nb_lookup(path); + path_pcep_config_lookup(path); specialize_incoming_path(pcc_state, path); PCEP_DEBUG("%s Received LSP update", pcc_state->tag); PCEP_DEBUG_PATH("%s", format_path(path)); diff --git a/pathd/pathd.c b/pathd/pathd.c index f3b9247c6846..a9f9a532e1d7 100644 --- a/pathd/pathd.c +++ b/pathd/pathd.c @@ -498,6 +498,16 @@ struct srte_candidate *srte_candidate_find(struct srte_policy *policy, return RB_FIND(srte_candidate_head, &policy->candidate_paths, &search); } +struct srte_segment_entry * +srte_segment_entry_find(struct srte_segment_list *segment_list, uint32_t index) +{ + struct srte_segment_entry search; + + search.index = index; + return RB_FIND(srte_segment_entry_head, &segment_list->segments, + &search); +} + void srte_candidate_status_update(struct srte_policy *policy, struct srte_candidate *candidate, int status) { diff --git a/pathd/pathd.h b/pathd/pathd.h index edd318a267dc..a8e43f78576f 100644 --- a/pathd/pathd.h +++ b/pathd/pathd.h @@ -260,6 +260,8 @@ void srte_candidate_unset_metric(struct srte_candidate *candidate, bool is_config); struct srte_candidate *srte_candidate_find(struct srte_policy *policy, uint32_t preference); +struct srte_segment_entry * +srte_segment_entry_find(struct srte_segment_list *segment_list, uint32_t index); void srte_candidate_status_update(struct srte_policy *policy, struct srte_candidate *candidate, int status); const char *srte_origin2str(enum srte_protocol_origin origin); diff --git a/pathd/subdir.am b/pathd/subdir.am index db5438cec96b..45e022cceab2 100644 --- a/pathd/subdir.am +++ b/pathd/subdir.am @@ -42,7 +42,7 @@ noinst_HEADERS += \ pathd/path_pcep_debug.h \ pathd/path_pcep_lib.h \ pathd/path_pcep_memory.h \ - pathd/path_pcep_nb.h \ + pathd/path_pcep_config.h \ pathd/path_pcep_pcc.h \ pathd/path_zebra.h \ pathd/path_util.h \ @@ -64,7 +64,7 @@ pathd_pathd_pcep_la_SOURCES = \ pathd/path_pcep_debug.c \ pathd/path_pcep_lib.c \ pathd/path_pcep_memory.c \ - pathd/path_pcep_nb.c \ + pathd/path_pcep_config.c \ pathd/path_pcep_pcc.c \ # end pathd_pathd_pcep_la_CFLAGS = $(WERROR) From 0d835ff0e217c3633e610a974e37c4c58279125c Mon Sep 17 00:00:00 2001 From: GalaxyGorilla Date: Mon, 22 Jun 2020 11:20:49 +0000 Subject: [PATCH 2/7] pathd: introduce LSP child for candidate paths The new struct `srte_lsp` is meant to hold the runtime state of a candidate path, e.g. it can also be altered due to PCEP without a loss of initial configuration data. This is especially important for metrics support. Signed-off-by: GalaxyGorilla --- pathd/path_nb_config.c | 25 ++-- pathd/path_pcep_config.c | 159 +++++++++++++------------ pathd/path_zebra.c | 2 +- pathd/pathd.c | 246 +++++++++++++++++++++++---------------- pathd/pathd.h | 66 +++++++---- 5 files changed, 277 insertions(+), 221 deletions(-) diff --git a/pathd/path_nb_config.c b/pathd/path_nb_config.c index 7608092cbb24..bb9abdbe7ccb 100644 --- a/pathd/path_nb_config.c +++ b/pathd/path_nb_config.c @@ -420,17 +420,15 @@ int pathd_te_sr_policy_candidate_path_metrics_destroy( { struct srte_candidate *candidate; enum srte_candidate_metric_type type; - bool is_config; if (args->event != NB_EV_APPLY) return NB_OK; assert(args->context != NULL); - is_config = args->context->client == NB_CLIENT_CLI; candidate = nb_running_get_entry(args->dnode, NULL, true); type = yang_dnode_get_enum(args->dnode, "./type"); - srte_candidate_unset_metric(candidate, type, is_config); + srte_candidate_unset_metric(candidate, type); return NB_OK; } @@ -441,10 +439,9 @@ void pathd_te_sr_policy_candidate_path_metrics_apply_finish( struct srte_candidate *candidate; enum srte_candidate_metric_type type; float value; - bool is_bound = false, is_computed = false, is_config; + bool is_bound = false, is_computed = false; assert(args->context != NULL); - is_config = args->context->client == NB_CLIENT_CLI; candidate = nb_running_get_entry(args->dnode, NULL, true); @@ -455,8 +452,8 @@ void pathd_te_sr_policy_candidate_path_metrics_apply_finish( if (yang_dnode_exists(args->dnode, "./is-computed")) is_computed = yang_dnode_get_bool(args->dnode, "./is-computed"); - srte_candidate_set_metric(candidate, type, value, is_bound, is_computed, - is_config); + srte_candidate_set_metric(candidate, type, value, is_bound, + is_computed); } /* @@ -474,6 +471,7 @@ int pathd_te_sr_policy_candidate_path_protocol_origin_modify( candidate = nb_running_get_entry(args->dnode, NULL, true); protocol_origin = yang_dnode_get_enum(args->dnode, NULL); candidate->protocol_origin = protocol_origin; + candidate->lsp->protocol_origin = protocol_origin; SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); return NB_OK; @@ -495,6 +493,8 @@ int pathd_te_sr_policy_candidate_path_originator_modify( originator = yang_dnode_get_string(args->dnode, NULL); strlcpy(candidate->originator, originator, sizeof(candidate->originator)); + strlcpy(candidate->lsp->originator, originator, + sizeof(candidate->lsp->originator)); SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); return NB_OK; @@ -515,6 +515,7 @@ int pathd_te_sr_policy_candidate_path_discriminator_modify( candidate = nb_running_get_entry(args->dnode, NULL, true); discriminator = yang_dnode_get_uint32(args->dnode, NULL); candidate->discriminator = discriminator; + candidate->lsp->discriminator = discriminator; SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); return NB_OK; @@ -578,6 +579,7 @@ int pathd_te_sr_policy_candidate_path_segment_list_name_modify( return NB_OK; candidate->segment_list = srte_segment_list_find(segment_list_name); + candidate->lsp->segment_list = candidate->segment_list; assert(candidate->segment_list); SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); @@ -594,6 +596,7 @@ int pathd_te_sr_policy_candidate_path_segment_list_name_destroy( candidate = nb_running_get_entry(args->dnode, NULL, true); candidate->segment_list = NULL; + candidate->lsp->segment_list = NULL; SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); return NB_OK; @@ -607,16 +610,14 @@ int pathd_te_sr_policy_candidate_path_bandwidth_modify( { struct srte_candidate *candidate; float value; - bool is_config; if (args->event != NB_EV_APPLY) return NB_OK; assert(args->context != NULL); - is_config = args->context->client == NB_CLIENT_CLI; candidate = nb_running_get_entry(args->dnode, NULL, true); value = (float)yang_dnode_get_dec64(args->dnode, NULL); - srte_candidate_set_bandwidth(candidate, value, is_config); + srte_candidate_set_bandwidth(candidate, value); return NB_OK; } @@ -624,14 +625,12 @@ int pathd_te_sr_policy_candidate_path_bandwidth_destroy( struct nb_cb_destroy_args *args) { struct srte_candidate *candidate; - bool is_config; if (args->event != NB_EV_APPLY) return NB_OK; assert(args->context != NULL); - is_config = args->context->client == NB_CLIENT_CLI; candidate = nb_running_get_entry(args->dnode, NULL, true); - srte_candidate_unset_bandwidth(candidate, is_config); + srte_candidate_unset_bandwidth(candidate); return NB_OK; } diff --git a/pathd/path_pcep_config.c b/pathd/path_pcep_config.c index b08967f9d2fe..46c63977f83a 100644 --- a/pathd/path_pcep_config.c +++ b/pathd/path_pcep_config.c @@ -35,13 +35,11 @@ static struct path_hop * path_pcep_config_list_path_hops(struct srte_segment_list *segment_list); -static void path_pcep_config_delete_candidate_segment_list(struct lsp_nb_key *key); -static void -path_pcep_config_add_segment_list_segment(struct srte_segment_list *segment_list, - uint32_t index, uint32_t label); -static void -path_pcep_config_add_segment_list_segment_no_nai(struct srte_segment_list *segment_list, - uint32_t index); +static void path_pcep_config_delete_lsp_segment_list(struct lsp_nb_key *key); +static void path_pcep_config_add_segment_list_segment( + struct srte_segment_list *segment_list, uint32_t index, uint32_t label); +static void path_pcep_config_add_segment_list_segment_no_nai( + struct srte_segment_list *segment_list, uint32_t index); static void path_pcep_config_add_segment_list_segment_nai_ipv4_node( struct srte_segment_list *segment_list, uint32_t index, struct ipaddr *ip); @@ -60,23 +58,22 @@ static void path_pcep_config_add_segment_list_segment_nai_ipv4_unnumbered_adj( uint32_t remote_iface); static struct srte_segment_list * path_pcep_config_create_segment_list(const char *segment_list_name, - enum srte_protocol_origin protocol, - const char *originator); -static void -path_pcep_config_update_candidate_path(struct lsp_nb_key *key, - struct srte_segment_list *segment_list); -static void path_pcep_config_add_candidate_path_metric(uint32_t color, - struct ipaddr *endpoint, - uint32_t preference, - enum pcep_metric_types type, - float value, bool is_bound, - bool is_computed); -static void path_pcep_config_set_candidate_path_bandwidth(uint32_t color, - struct ipaddr *endpoint, - uint32_t preference, - float value); - -static struct srte_candidate* lookup_candidate(struct lsp_nb_key *key); + enum srte_protocol_origin protocol, + const char *originator); +static void path_pcep_config_update_lsp(struct lsp_nb_key *key, + struct srte_segment_list *segment_list); +static void path_pcep_config_add_lsp_metric(uint32_t color, + struct ipaddr *endpoint, + uint32_t preference, + enum pcep_metric_types type, + float value, bool is_bound, + bool is_computed); +static void path_pcep_config_set_lsp_bandwidth(uint32_t color, + struct ipaddr *endpoint, + uint32_t preference, + float value); + +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); @@ -85,6 +82,9 @@ static enum pcep_sr_subobj_nai pcep_nai_type(enum srte_segment_nai_type type); void path_pcep_config_lookup(struct path *path) { struct srte_candidate *candidate = lookup_candidate(&path->nbkey); + struct srte_lsp *lsp = candidate->lsp; + ; + if (candidate == NULL) return; if (path->name == NULL) @@ -94,8 +94,8 @@ void path_pcep_config_lookup(struct path *path) if (path->create_origin == SRTE_ORIGIN_UNDEFINED) path->create_origin = candidate->protocol_origin; if ((path->update_origin == SRTE_ORIGIN_UNDEFINED) - && (candidate->segment_list != NULL)) - path->update_origin = candidate->segment_list->protocol_origin; + && (lsp->segment_list != NULL)) + path->update_origin = lsp->segment_list->protocol_origin; } struct path *path_pcep_config_get_path(struct lsp_nb_key *key) @@ -129,17 +129,18 @@ struct path *candidate_to_path(struct srte_candidate *candidate) 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 (candidate->segment_list != NULL) { - hop = path_pcep_config_list_path_hops(candidate->segment_list); - update_origin = candidate->segment_list->protocol_origin; - originator = XSTRDUP(MTYPE_PCEP, - candidate->segment_list->originator); + 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); @@ -148,34 +149,34 @@ struct path *candidate_to_path(struct srte_candidate *candidate) } else { status = PCEP_LSP_OPERATIONAL_DOWN; } - if (CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_ABC_RT)) { + if (CHECK_FLAG(lsp->flags, F_CANDIDATE_HAS_METRIC_ABC)) { struct path_metric *new_metric = pcep_new_metric(); new_metric->next = metric; metric = new_metric; metric->type = PCEP_METRIC_AGGREGATE_BW; - metric->value = candidate->metric_abc_rt; - metric->is_bound = CHECK_FLAG(candidate->flags, - F_CANDIDATE_METRIC_ABC_BOUND_RT); - metric->is_computed = CHECK_FLAG( - candidate->flags, F_CANDIDATE_METRIC_ABC_COMPUTED_RT); + metric->value = lsp->metric_abc; + metric->is_bound = + CHECK_FLAG(lsp->flags, F_CANDIDATE_METRIC_ABC_BOUND); + metric->is_computed = + CHECK_FLAG(lsp->flags, F_CANDIDATE_METRIC_ABC_COMPUTED); } - if (CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_TE_RT)) { + if (CHECK_FLAG(lsp->flags, F_CANDIDATE_HAS_METRIC_TE)) { struct path_metric *new_metric = pcep_new_metric(); new_metric->next = metric; metric = new_metric; metric->type = PCEP_METRIC_TE; - metric->value = candidate->metric_te_rt; - metric->is_bound = CHECK_FLAG(candidate->flags, - F_CANDIDATE_METRIC_TE_BOUND_RT); - metric->is_computed = CHECK_FLAG( - candidate->flags, F_CANDIDATE_METRIC_TE_COMPUTED_RT); + metric->value = lsp->metric_te; + metric->is_bound = + CHECK_FLAG(lsp->flags, F_CANDIDATE_METRIC_TE_BOUND); + metric->is_computed = + CHECK_FLAG(lsp->flags, F_CANDIDATE_METRIC_TE_COMPUTED); } *path = (struct path){ .nbkey = (struct lsp_nb_key){.color = policy->color, .endpoint = policy->endpoint, .preference = candidate->preference}, - .create_origin = candidate->protocol_origin, + .create_origin = lsp->protocol_origin, .update_origin = update_origin, .originator = originator, .plsp_id = 0, @@ -194,14 +195,14 @@ struct path *candidate_to_path(struct srte_candidate *candidate) .first_hop = hop, .first_metric = metric}; - path->has_bandwidth = CHECK_FLAG(candidate->flags, - F_CANDIDATE_HAS_BANDWIDTH_RT); - path->bandwidth = candidate->bandwidth_rt; + path->has_bandwidth = CHECK_FLAG(lsp->flags, F_CANDIDATE_HAS_BANDWIDTH); + path->bandwidth = lsp->bandwidth; return path; } -struct path_hop *path_pcep_config_list_path_hops(struct srte_segment_list *segment_list) +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; @@ -261,22 +262,22 @@ int path_pcep_config_update_path(struct path *path) char *segment_list_name = NULL; struct srte_segment_list *segment_list; - path_pcep_config_delete_candidate_segment_list(&path->nbkey); + path_pcep_config_delete_lsp_segment_list(&path->nbkey); 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; - segment_list = path_pcep_config_create_segment_list(segment_list_name, - path->update_origin, - path->originator); + segment_list = path_pcep_config_create_segment_list( + segment_list_name, path->update_origin, + path->originator); for (hop = path->first_hop, index = 10; hop != NULL; hop = hop->next, index += 10) { assert(hop->has_sid); assert(hop->is_mpls); - path_pcep_config_add_segment_list_segment(segment_list, index, - hop->sid.mpls.label); + path_pcep_config_add_segment_list_segment( + segment_list, index, hop->sid.mpls.label); if (hop->has_nai) { switch (hop->nai.type) { case PCEP_SR_SUBOBJ_NAI_IPV4_NODE: @@ -318,18 +319,18 @@ int path_pcep_config_update_path(struct path *path) } } - path_pcep_config_update_candidate_path(&path->nbkey, segment_list); + path_pcep_config_update_lsp(&path->nbkey, segment_list); for (metric = path->first_metric; metric != NULL; metric = metric->next) { - path_pcep_config_add_candidate_path_metric( + path_pcep_config_add_lsp_metric( path->nbkey.color, &path->nbkey.endpoint, path->nbkey.preference, metric->type, metric->value, metric->is_bound, metric->is_computed); } if (path->has_bandwidth) { - path_pcep_config_set_candidate_path_bandwidth( + path_pcep_config_set_lsp_bandwidth( path->nbkey.color, &path->nbkey.endpoint, path->nbkey.preference, path->bandwidth); } @@ -341,21 +342,21 @@ int path_pcep_config_update_path(struct path *path) /* Delete the candidate path segment list if it was created through PCEP and by the given originator */ -void path_pcep_config_delete_candidate_segment_list(struct lsp_nb_key *key) +void path_pcep_config_delete_lsp_segment_list(struct lsp_nb_key *key) { struct srte_candidate *candidate = lookup_candidate(key); - if ((candidate == NULL) || (candidate->segment_list == NULL)) + if ((candidate == NULL) || (candidate->lsp->segment_list == NULL)) return; - SET_FLAG(candidate->segment_list->flags, F_SEGMENT_LIST_DELETED); + SET_FLAG(candidate->lsp->segment_list->flags, F_SEGMENT_LIST_DELETED); - candidate->segment_list = NULL; + candidate->lsp->segment_list = NULL; SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); } -void path_pcep_config_add_segment_list_segment(struct srte_segment_list *segment_list, - uint32_t index, uint32_t label) +void path_pcep_config_add_segment_list_segment( + struct srte_segment_list *segment_list, uint32_t index, uint32_t label) { struct srte_segment_entry *segment; @@ -440,8 +441,8 @@ void path_pcep_config_add_segment_list_segment_nai_ipv4_unnumbered_adj( struct srte_segment_list * path_pcep_config_create_segment_list(const char *segment_list_name, - enum srte_protocol_origin protocol, - const char *originator) + enum srte_protocol_origin protocol, + const char *originator) { struct srte_segment_list *segment_list; @@ -456,8 +457,8 @@ path_pcep_config_create_segment_list(const char *segment_list_name, return segment_list; } -void path_pcep_config_update_candidate_path(struct lsp_nb_key *key, - struct srte_segment_list *segment_list) +void path_pcep_config_update_lsp(struct lsp_nb_key *key, + struct srte_segment_list *segment_list) { struct srte_policy *policy; struct srte_candidate *candidate; @@ -465,16 +466,16 @@ void path_pcep_config_update_candidate_path(struct lsp_nb_key *key, policy = srte_policy_find(key->color, &key->endpoint); candidate = srte_candidate_find(policy, key->preference); - candidate->segment_list = segment_list; - assert(candidate->segment_list); + candidate->lsp->segment_list = segment_list; + assert(candidate->lsp->segment_list); SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); } -void path_pcep_config_add_candidate_path_metric(uint32_t color, struct ipaddr *endpoint, - uint32_t preference, - enum pcep_metric_types type, float value, - bool is_bound, bool is_computed) +void path_pcep_config_add_lsp_metric(uint32_t color, struct ipaddr *endpoint, + uint32_t preference, + enum pcep_metric_types type, float value, + bool is_bound, bool is_computed) { struct srte_policy *policy; struct srte_candidate *candidate; @@ -482,13 +483,11 @@ void path_pcep_config_add_candidate_path_metric(uint32_t color, struct ipaddr *e policy = srte_policy_find(color, endpoint); candidate = srte_candidate_find(policy, preference); - srte_candidate_set_metric(candidate, type, value, is_bound, is_computed, - false); + srte_lsp_set_metric(candidate->lsp, type, value, is_bound, is_computed); } -void path_pcep_config_set_candidate_path_bandwidth(uint32_t color, - struct ipaddr *endpoint, - uint32_t preference, float value) +void path_pcep_config_set_lsp_bandwidth(uint32_t color, struct ipaddr *endpoint, + uint32_t preference, float value) { struct srte_policy *policy; struct srte_candidate *candidate; @@ -496,10 +495,10 @@ void path_pcep_config_set_candidate_path_bandwidth(uint32_t color, policy = srte_policy_find(color, endpoint); candidate = srte_candidate_find(policy, preference); - srte_candidate_set_bandwidth(candidate, value, false); + srte_lsp_set_bandwidth(candidate->lsp, value); } -struct srte_candidate* lookup_candidate(struct lsp_nb_key *key) +struct srte_candidate *lookup_candidate(struct lsp_nb_key *key) { struct srte_policy *policy = NULL; policy = srte_policy_find(key->color, &key->endpoint); diff --git a/pathd/path_zebra.c b/pathd/path_zebra.c index fcc1a33c02cd..b15e5abdd92e 100644 --- a/pathd/path_zebra.c +++ b/pathd/path_zebra.c @@ -70,7 +70,7 @@ static void path_zebra_connected(struct zclient *zclient) if (!candidate) continue; - segment_list = candidate->segment_list; + segment_list = candidate->lsp->segment_list; if (!segment_list) continue; diff --git a/pathd/pathd.c b/pathd/pathd.c index a9f9a532e1d7..19651f552f7b 100644 --- a/pathd/pathd.c +++ b/pathd/pathd.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 NetDEF, Inc. + * Copyright (C) 2020 NetDEF, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -189,8 +189,8 @@ void srte_policy_update_binding_sid(struct srte_policy *policy, /* Reinstall the Binding-SID if necessary. */ if (policy->best_candidate) - path_zebra_add_sr_policy(policy, - policy->best_candidate->segment_list); + path_zebra_add_sr_policy( + policy, policy->best_candidate->lsp->segment_list); } static struct srte_candidate * @@ -202,7 +202,7 @@ 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->segment_list) + && candidate->lsp->segment_list) return candidate; } @@ -276,7 +276,7 @@ void srte_policy_apply_changes(struct srte_policy *policy) F_CANDIDATE_MODIFIED); path_zebra_add_sr_policy( - policy, new_best_candidate->segment_list); + policy, new_best_candidate->lsp->segment_list); } } else if (new_best_candidate) { /* The best candidate path did not change, but some of its @@ -286,9 +286,10 @@ void srte_policy_apply_changes(struct srte_policy *policy) bool candidate_changed = CHECK_FLAG(new_best_candidate->flags, F_CANDIDATE_MODIFIED); bool segment_list_changed = - new_best_candidate->segment_list - && CHECK_FLAG(new_best_candidate->segment_list->flags, - F_SEGMENT_LIST_MODIFIED); + new_best_candidate->lsp->segment_list + && CHECK_FLAG( + new_best_candidate->lsp->segment_list->flags, + F_SEGMENT_LIST_MODIFIED); if (candidate_changed || segment_list_changed) { /* TODO: add debug guard. */ @@ -297,7 +298,7 @@ void srte_policy_apply_changes(struct srte_policy *policy) new_best_candidate->name); path_zebra_add_sr_policy( - policy, new_best_candidate->segment_list); + policy, new_best_candidate->lsp->segment_list); } } @@ -311,8 +312,8 @@ void srte_policy_apply_changes(struct srte_policy *policy) trigger_pathd_candidate_created(candidate); } else if (CHECK_FLAG(candidate->flags, F_CANDIDATE_MODIFIED)) { trigger_pathd_candidate_updated(candidate); - } else if (candidate->segment_list - && CHECK_FLAG(candidate->segment_list->flags, + } else if (candidate->lsp->segment_list + && CHECK_FLAG(candidate->lsp->segment_list->flags, F_SEGMENT_LIST_MODIFIED)) { trigger_pathd_candidate_updated(candidate); } @@ -326,11 +327,15 @@ struct srte_candidate *srte_candidate_add(struct srte_policy *policy, uint32_t preference) { struct srte_candidate *candidate; + struct srte_lsp *lsp; candidate = XCALLOC(MTYPE_PATH_SR_CANDIDATE, sizeof(*candidate)); + lsp = XCALLOC(MTYPE_PATH_SR_CANDIDATE, sizeof(*lsp)); + candidate->preference = preference; candidate->policy = policy; candidate->type = SRTE_CANDIDATE_TYPE_UNDEFINED; + candidate->lsp = lsp; RB_INSERT(srte_candidate_head, &policy->candidate_paths, candidate); return candidate; @@ -342,147 +347,184 @@ void srte_candidate_del(struct srte_candidate *candidate) RB_REMOVE(srte_candidate_head, &srte_policy->candidate_paths, candidate); + + XFREE(MTYPE_PATH_SR_CANDIDATE, candidate->lsp); XFREE(MTYPE_PATH_SR_CANDIDATE, candidate); } void srte_candidate_set_bandwidth(struct srte_candidate *candidate, - float bandwidth, bool is_config) + float bandwidth) { struct srte_policy *policy = candidate->policy; char endpoint[46]; ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint)); - zlog_debug( - "SR-TE(%s, %u): candidate %s bandwidth set to %f B/s" - "(is_config: %s)", - endpoint, policy->color, candidate->name, bandwidth, - is_config ? "true" : "false"); - SET_FLAG(candidate->flags, F_CANDIDATE_HAS_BANDWIDTH_RT); - candidate->bandwidth_rt = bandwidth; - if (is_config) { - SET_FLAG(candidate->flags, F_CANDIDATE_HAS_BANDWIDTH); - candidate->bandwidth = bandwidth; - } + zlog_debug("SR-TE(%s, %u): candidate %s bandwidth set to %f B/s", + endpoint, policy->color, candidate->name, bandwidth); + SET_FLAG(candidate->flags, F_CANDIDATE_HAS_BANDWIDTH); + candidate->bandwidth = bandwidth; + + srte_lsp_set_bandwidth(candidate->lsp, bandwidth); } -void srte_candidate_unset_bandwidth(struct srte_candidate *candidate, - bool is_config) +void srte_lsp_set_bandwidth(struct srte_lsp *lsp, float bandwidth) { + struct srte_candidate *candidate = lsp->candidate; struct srte_policy *policy = candidate->policy; char endpoint[46]; ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint)); - zlog_debug( - "SR-TE(%s, %u): candidate %s bandwidth unset " - "(is_config: %s)", - endpoint, policy->color, candidate->name, - is_config ? "true" : "false"); - UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_BANDWIDTH_RT); - candidate->bandwidth_rt = 0; - if (is_config) { - UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_BANDWIDTH); - candidate->bandwidth = 0; - } + zlog_debug("SR-TE(%s, %u): candidate %s lsp bandwidth set to %f B/s", + endpoint, policy->color, candidate->name, bandwidth); + SET_FLAG(lsp->flags, F_CANDIDATE_HAS_BANDWIDTH); + lsp->bandwidth = bandwidth; +} + +void srte_candidate_unset_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 bandwidth unset", endpoint, + policy->color, candidate->name); + UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_BANDWIDTH); + candidate->bandwidth = 0; + + srte_lsp_unset_bandwidth(candidate->lsp); +} + +void srte_lsp_unset_bandwidth(struct srte_lsp *lsp) +{ + struct srte_candidate *candidate = lsp->candidate; + struct srte_policy *policy = candidate->policy; + char endpoint[46]; + ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint)); + zlog_debug("SR-TE(%s, %u): candidate %s lsp bandwidth unset", endpoint, + policy->color, candidate->name); + UNSET_FLAG(lsp->flags, F_CANDIDATE_HAS_BANDWIDTH); + lsp->bandwidth = 0; } void srte_candidate_set_metric(struct srte_candidate *candidate, enum srte_candidate_metric_type type, - float value, bool is_bound, bool is_computed, - bool is_config) + float value, bool is_bound, bool is_computed) { struct srte_policy *policy = candidate->policy; char endpoint[46]; ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint)); zlog_debug( "SR-TE(%s, %u): candidate %s metric %s (%u) set to %f " - "(is-bound: %s; is_computed: %s; is_config: %s)", + "(is-bound: %s; is_computed: %s)", endpoint, policy->color, candidate->name, srte_candidate_metric_name(type), type, value, - is_bound ? "true" : "false", is_computed ? "true" : "false", - is_config ? "true" : "false"); + is_bound ? "true" : "false", is_computed ? "true" : "false"); switch (type) { case SRTE_CANDIDATE_METRIC_TYPE_ABC: - SET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_ABC_RT); - COND_FLAG(candidate->flags, F_CANDIDATE_METRIC_ABC_BOUND_RT, + SET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_ABC); + COND_FLAG(candidate->flags, F_CANDIDATE_METRIC_ABC_BOUND, is_bound); - COND_FLAG(candidate->flags, F_CANDIDATE_METRIC_ABC_COMPUTED_RT, + COND_FLAG(candidate->flags, F_CANDIDATE_METRIC_ABC_COMPUTED, is_computed); - candidate->metric_abc_rt = value; - /* FIXME: Should be fixed by refactoring the data model */ - if (is_config) { - SET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_ABC); - COND_FLAG(candidate->flags, - F_CANDIDATE_METRIC_ABC_BOUND, is_bound); - COND_FLAG(candidate->flags, - F_CANDIDATE_METRIC_ABC_COMPUTED, is_computed); - candidate->metric_abc = value; - } + candidate->metric_abc = value; break; case SRTE_CANDIDATE_METRIC_TYPE_TE: - SET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_TE_RT); - COND_FLAG(candidate->flags, F_CANDIDATE_METRIC_TE_BOUND_RT, + SET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_TE); + COND_FLAG(candidate->flags, F_CANDIDATE_METRIC_TE_BOUND, is_bound); - COND_FLAG(candidate->flags, F_CANDIDATE_METRIC_TE_COMPUTED_RT, + COND_FLAG(candidate->flags, F_CANDIDATE_METRIC_TE_COMPUTED, is_computed); - candidate->metric_te_rt = value; - /* FIXME: Should be fixed by refactoring the data model */ - if (is_config) { - SET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_TE); - COND_FLAG(candidate->flags, F_CANDIDATE_METRIC_TE_BOUND, - is_bound); - COND_FLAG(candidate->flags, - F_CANDIDATE_METRIC_TE_COMPUTED, is_computed); - candidate->metric_te = value; - } + candidate->metric_te = value; break; default: break; } + + srte_lsp_set_metric(candidate->lsp, type, value, is_bound, is_computed); } -void srte_candidate_unset_metric(struct srte_candidate *candidate, - enum srte_candidate_metric_type type, - bool is_config) +void srte_lsp_set_metric(struct srte_lsp *lsp, + enum srte_candidate_metric_type type, float value, + bool is_bound, bool is_computed) { + struct srte_candidate *candidate = lsp->candidate; struct srte_policy *policy = candidate->policy; char endpoint[46]; ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint)); zlog_debug( - "SR-TE(%s, %u): candidate %s metric %s (%u) unset " - "(is_config: %s)", + "SR-TE(%s, %u): candidate %s lsp metric %s (%u) set to %f " + "(is-bound: %s; is_computed: %s)", endpoint, policy->color, candidate->name, - srte_candidate_metric_name(type), type, - is_config ? "true" : "false"); + srte_candidate_metric_name(type), type, value, + is_bound ? "true" : "false", is_computed ? "true" : "false"); switch (type) { case SRTE_CANDIDATE_METRIC_TYPE_ABC: - UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_ABC_RT); - UNSET_FLAG(candidate->flags, F_CANDIDATE_METRIC_ABC_BOUND_RT); - UNSET_FLAG(candidate->flags, - F_CANDIDATE_METRIC_ABC_COMPUTED_RT); - candidate->metric_abc_rt = 0; - /* FIXME: Should be fixed by refactoring the data model */ - if (is_config) { - UNSET_FLAG(candidate->flags, - F_CANDIDATE_HAS_METRIC_ABC); - UNSET_FLAG(candidate->flags, - F_CANDIDATE_METRIC_ABC_BOUND); - UNSET_FLAG(candidate->flags, - F_CANDIDATE_METRIC_ABC_COMPUTED); - candidate->metric_abc = 0; - } + SET_FLAG(lsp->flags, F_CANDIDATE_HAS_METRIC_ABC); + COND_FLAG(lsp->flags, F_CANDIDATE_METRIC_ABC_BOUND, is_bound); + COND_FLAG(lsp->flags, F_CANDIDATE_METRIC_ABC_COMPUTED, + is_computed); + lsp->metric_abc = value; break; case SRTE_CANDIDATE_METRIC_TYPE_TE: - UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_TE_RT); - UNSET_FLAG(candidate->flags, F_CANDIDATE_METRIC_TE_BOUND_RT); - UNSET_FLAG(candidate->flags, F_CANDIDATE_METRIC_TE_COMPUTED_RT); - candidate->metric_te_rt = 0; - /* FIXME: Should be fixed by refactoring the data model */ - if (is_config) { - UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_TE); - UNSET_FLAG(candidate->flags, - F_CANDIDATE_METRIC_TE_BOUND); - UNSET_FLAG(candidate->flags, - F_CANDIDATE_METRIC_TE_COMPUTED); - candidate->metric_te = 0; - } + SET_FLAG(lsp->flags, F_CANDIDATE_HAS_METRIC_TE); + COND_FLAG(lsp->flags, F_CANDIDATE_METRIC_TE_BOUND, is_bound); + COND_FLAG(lsp->flags, F_CANDIDATE_METRIC_TE_COMPUTED, + is_computed); + lsp->metric_te = value; + break; + default: + break; + } +} + +void srte_candidate_unset_metric(struct srte_candidate *candidate, + enum srte_candidate_metric_type type) +{ + struct srte_policy *policy = candidate->policy; + char endpoint[46]; + ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint)); + zlog_debug("SR-TE(%s, %u): candidate %s metric %s (%u) unset", endpoint, + policy->color, candidate->name, + srte_candidate_metric_name(type), type); + switch (type) { + case SRTE_CANDIDATE_METRIC_TYPE_ABC: + UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_ABC); + UNSET_FLAG(candidate->flags, F_CANDIDATE_METRIC_ABC_BOUND); + UNSET_FLAG(candidate->flags, F_CANDIDATE_METRIC_ABC_COMPUTED); + candidate->metric_abc = 0; + break; + case SRTE_CANDIDATE_METRIC_TYPE_TE: + UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_TE); + UNSET_FLAG(candidate->flags, F_CANDIDATE_METRIC_TE_BOUND); + UNSET_FLAG(candidate->flags, F_CANDIDATE_METRIC_TE_COMPUTED); + candidate->metric_te = 0; + break; + default: + break; + } + + srte_lsp_unset_metric(candidate->lsp, type); +} + +void srte_lsp_unset_metric(struct srte_lsp *lsp, + enum srte_candidate_metric_type type) +{ + struct srte_candidate *candidate = lsp->candidate; + struct srte_policy *policy = candidate->policy; + char endpoint[46]; + ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint)); + zlog_debug("SR-TE(%s, %u): candidate %s lsp metric %s (%u) unset", + endpoint, policy->color, candidate->name, + srte_candidate_metric_name(type), type); + switch (type) { + case SRTE_CANDIDATE_METRIC_TYPE_ABC: + UNSET_FLAG(lsp->flags, F_CANDIDATE_HAS_METRIC_ABC); + UNSET_FLAG(lsp->flags, F_CANDIDATE_METRIC_ABC_BOUND); + UNSET_FLAG(lsp->flags, F_CANDIDATE_METRIC_ABC_COMPUTED); + lsp->metric_abc = 0; + break; + case SRTE_CANDIDATE_METRIC_TYPE_TE: + UNSET_FLAG(lsp->flags, F_CANDIDATE_HAS_METRIC_TE); + UNSET_FLAG(lsp->flags, F_CANDIDATE_METRIC_TE_BOUND); + UNSET_FLAG(lsp->flags, F_CANDIDATE_METRIC_TE_COMPUTED); + lsp->metric_te = 0; break; default: break; diff --git a/pathd/pathd.h b/pathd/pathd.h index a8e43f78576f..0eaa0ee02361 100644 --- a/pathd/pathd.h +++ b/pathd/pathd.h @@ -114,12 +114,42 @@ RB_HEAD(srte_segment_list_head, srte_segment_list); RB_PROTOTYPE(srte_segment_list_head, srte_segment_list, entry, srte_segment_list_compare) +struct srte_lsp { + /* Backpointer to the Candidate Path. */ + struct srte_candidate *candidate; + + /* The associated Segment List. */ + struct srte_segment_list *segment_list; + + /* The Protocol-Origin. */ + enum srte_protocol_origin protocol_origin; + + /* The Originator */ + char originator[64]; + + /* The Discriminator */ + uint32_t discriminator; + + /* Flags. */ + uint32_t flags; + + /* Metrics Configured Value */ + float metric_abc; /* Agreggate Bandwidth Consumption */ + float metric_te; + + /* Bandwidth Configured Value */ + float bandwidth; +}; + struct srte_candidate { RB_ENTRY(srte_candidate) entry; /* Backpointer to SR Policy */ struct srte_policy *policy; + /* The LSP associated with this candidate path. */ + struct srte_lsp *lsp; + /* Administrative preference. */ uint32_t preference; @@ -161,24 +191,6 @@ struct srte_candidate { /* Bandwidth Configured Value */ float bandwidth; - - /* FIXME: This should be removed when the configuration/yang model is - * refactored, runtime data should be somewhere else */ - -#define F_CANDIDATE_HAS_METRIC_ABC_RT 0x010000 -#define F_CANDIDATE_METRIC_ABC_BOUND_RT 0x20000 -#define F_CANDIDATE_METRIC_ABC_COMPUTED_RT 0x40000 -#define F_CANDIDATE_HAS_METRIC_TE_RT 0x080000 -#define F_CANDIDATE_METRIC_TE_BOUND_RT 0x100000 -#define F_CANDIDATE_METRIC_TE_COMPUTED_RT 0x200000 -#define F_CANDIDATE_HAS_BANDWIDTH_RT 0x400000 - - /* Metrics Runtime Value */ - float metric_abc_rt; /* Agreggate Bandwidth Consumption */ - float metric_te_rt; - - /* Bandwidth Runtime Value */ - float bandwidth_rt; }; RB_HEAD(srte_candidate_head, srte_candidate); @@ -248,16 +260,20 @@ struct srte_candidate *srte_candidate_add(struct srte_policy *policy, uint32_t preference); void srte_candidate_del(struct srte_candidate *candidate); void srte_candidate_set_bandwidth(struct srte_candidate *candidate, - float bandwidth, bool is_config); -void srte_candidate_unset_bandwidth(struct srte_candidate *candidate, - bool is_config); + float bandwidth); +void srte_candidate_unset_bandwidth(struct srte_candidate *candidate); void srte_candidate_set_metric(struct srte_candidate *candidate, enum srte_candidate_metric_type type, - float value, bool is_cound, bool is_computed, - bool is_config); + float value, bool is_cound, bool is_computed); void srte_candidate_unset_metric(struct srte_candidate *candidate, - enum srte_candidate_metric_type type, - bool is_config); + enum srte_candidate_metric_type type); +void srte_lsp_set_bandwidth(struct srte_lsp *lsp, float bandwidth); +void srte_lsp_unset_bandwidth(struct srte_lsp *lsp); +void srte_lsp_set_metric(struct srte_lsp *lsp, + enum srte_candidate_metric_type type, float value, + bool is_cound, bool is_computed); +void srte_lsp_unset_metric(struct srte_lsp *lsp, + enum srte_candidate_metric_type type); struct srte_candidate *srte_candidate_find(struct srte_policy *policy, uint32_t preference); struct srte_segment_entry * From 02f4ac7c6a4dd4df515e070f712b18bfdb295957 Mon Sep 17 00:00:00 2001 From: GalaxyGorilla Date: Mon, 22 Jun 2020 13:38:36 +0000 Subject: [PATCH 3/7] pathd: refactor CLI commands to new config handling Signed-off-by: GalaxyGorilla --- pathd/path_cli.c | 76 +++++++++++++++--------------------------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/pathd/path_cli.c b/pathd/path_cli.c index 1e822ca36b3f..7935d550cf92 100644 --- a/pathd/path_cli.c +++ b/pathd/path_cli.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 NetDEF, Inc. + * Copyright (C) 2020 NetDEF, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -138,6 +138,9 @@ DEFPY(show_srte_policy_detail, show_srte_policy_detail_cmd, RB_FOREACH (candidate, srte_candidate_head, &policy->candidate_paths) { + struct srte_segment_list *segment_list; + + segment_list = candidate->lsp->segment_list; vty_out(vty, " %s Preference: %d Name: %s Type: %s Segment-List: %s Protocol-Origin: %s\n", CHECK_FLAG(candidate->flags, F_CANDIDATE_BEST) @@ -147,10 +150,13 @@ DEFPY(show_srte_policy_detail, show_srte_policy_detail_cmd, candidate->type == SRTE_CANDIDATE_TYPE_EXPLICIT ? "explicit" : "dynamic", - candidate->segment_list == NULL + segment_list == NULL + || segment_list->protocol_origin + == SRTE_ORIGIN_PCEP ? "(undefined)" - : candidate->segment_list->name, - srte_origin2str(candidate->protocol_origin)); + : candidate->lsp->segment_list->name, + srte_origin2str( + candidate->lsp->protocol_origin)); } vty_out(vty, "\n"); @@ -211,11 +217,6 @@ DEFPY(no_te_path_segment_list, no_te_path_segment_list_cmd, void cli_show_te_path_segment_list(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - enum srte_protocol_origin origin; - origin = yang_dnode_get_enum(dnode, "./protocol-origin"); - if (origin != SRTE_ORIGIN_LOCAL) - return; - vty_out(vty, "segment-list %s\n", yang_dnode_get_string(dnode, "./name")); } @@ -292,11 +293,6 @@ void cli_show_te_path_segment_list_segment(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - enum srte_protocol_origin origin; - origin = yang_dnode_get_enum(dnode, "../protocol-origin"); - if (origin != SRTE_ORIGIN_LOCAL) - return; - vty_out(vty, " index %s mpls label %s", yang_dnode_get_string(dnode, "./index"), yang_dnode_get_string(dnode, "./sid-value")); @@ -599,23 +595,21 @@ static void config_write_metric(struct vty *vty, config_write_float(vty, value); } -/* FIXME: Enable this back when the candidate path are only containing - * configuration data */ -// static int config_write_metric_cb(const struct lyd_node *dnode, void *arg) -// { -// struct vty *vty = arg; -// enum srte_candidate_metric_type type; -// bool is_bound = false; -// float value; +static int config_write_metric_cb(const struct lyd_node *dnode, void *arg) +{ + struct vty *vty = arg; + enum srte_candidate_metric_type type; + bool is_bound = false; + float value; -// type = yang_dnode_get_enum(dnode, "./type"); -// value = (float)yang_dnode_get_dec64(dnode, "./value"); -// if (yang_dnode_exists(dnode, "./is-bound")) -// is_bound = yang_dnode_get_bool(dnode, "./is-bound"); + type = yang_dnode_get_enum(dnode, "./type"); + value = (float)yang_dnode_get_dec64(dnode, "./value"); + if (yang_dnode_exists(dnode, "./is-bound")) + is_bound = yang_dnode_get_bool(dnode, "./is-bound"); -// config_write_metric(vty, type, value, is_bound); -// return YANG_ITER_CONTINUE; -// } + config_write_metric(vty, type, value, is_bound); + return YANG_ITER_CONTINUE; +} void cli_show_te_path_sr_policy_candidate_path(struct vty *vty, struct lyd_node *dnode, @@ -632,29 +626,7 @@ void cli_show_te_path_sr_policy_candidate_path(struct vty *vty, if (yang_dnode_exists(dnode, "./metrics")) vty_out(vty, " metrics"); - /* FIXME: Candidate path contains both configuration and transient - * data. This is not what we want os until it is fixed we need to - * hack around it */ - // yang_dnode_iterate(config_write_metric_cb, vty, dnode, "./metrics"); - struct srte_candidate *candidate; - bool is_bound; - candidate = nb_running_get_entry(dnode, NULL, true); - if (CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_ABC)) { - is_bound = CHECK_FLAG(candidate->flags, - F_CANDIDATE_METRIC_ABC_BOUND); - config_write_metric(vty, SRTE_CANDIDATE_METRIC_TYPE_ABC, - candidate->metric_abc, is_bound); - } - if (CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_METRIC_TE)) { - is_bound = CHECK_FLAG(candidate->flags, - F_CANDIDATE_METRIC_TE_BOUND); - config_write_metric(vty, SRTE_CANDIDATE_METRIC_TYPE_TE, - candidate->metric_te, is_bound); - } - if (CHECK_FLAG(candidate->flags, F_CANDIDATE_HAS_BANDWIDTH)) { - vty_out(vty, " bandwidth"); - config_write_float(vty, candidate->bandwidth); - } + yang_dnode_iterate(config_write_metric_cb, vty, dnode, "./metrics"); vty_out(vty, "\n"); } From 974e33359682db323989349b80ec5b44508e4c3a Mon Sep 17 00:00:00 2001 From: GalaxyGorilla Date: Thu, 25 Jun 2020 15:26:10 +0000 Subject: [PATCH 4/7] pathd: refactor NAI handling Signed-off-by: GalaxyGorilla --- pathd/path_nb_config.c | 33 ++++---- pathd/path_pcep_config.c | 159 ++++++++------------------------------- pathd/pathd.c | 31 ++++++++ pathd/pathd.h | 5 ++ 4 files changed, 82 insertions(+), 146 deletions(-) diff --git a/pathd/path_nb_config.c b/pathd/path_nb_config.c index bb9abdbe7ccb..35bfcc096006 100644 --- a/pathd/path_nb_config.c +++ b/pathd/path_nb_config.c @@ -181,38 +181,37 @@ void pathd_te_segment_list_segment_nai_apply_finish( { struct srte_segment_entry *segment; enum srte_segment_nai_type type; + struct ipaddr local_addr, remote_addr; + uint32_t local_iface = 0, remote_iface = 0; + segment = nb_running_get_entry(args->dnode, NULL, true); type = yang_dnode_get_enum(args->dnode, "./type"); + + yang_dnode_get_ip(&local_addr, args->dnode, "./local-address"); + switch (type) { case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE: case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE: - segment->nai_type = type; - yang_dnode_get_ip(&segment->nai_local_addr, args->dnode, - "./local-address"); break; case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY: case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY: - segment->nai_type = type; - yang_dnode_get_ip(&segment->nai_local_addr, args->dnode, - "./local-address"); - yang_dnode_get_ip(&segment->nai_remote_addr, args->dnode, + yang_dnode_get_ip(&remote_addr, args->dnode, "./remote-address"); break; case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY: - segment->nai_type = type; - yang_dnode_get_ip(&segment->nai_local_addr, args->dnode, - "./local-address"); - segment->nai_local_iface = - yang_dnode_get_uint32(args->dnode, "./local-interface"); - yang_dnode_get_ip(&segment->nai_remote_addr, args->dnode, + yang_dnode_get_ip(&remote_addr, args->dnode, "./remote-address"); - segment->nai_remote_iface = - yang_dnode_get_uint32(args->dnode, "./remote-interface"); + local_iface = + yang_dnode_get_uint32(args->dnode, "./local-interface"); + remote_iface = yang_dnode_get_uint32(args->dnode, + "./remote-interface"); break; default: - segment->nai_type = SRTE_SEGMENT_NAI_TYPE_NONE; - return; + break; } + + srte_segment_entry_set_nai(segment, type, &local_addr, local_iface, + &remote_addr, remote_iface); } /* diff --git a/pathd/path_pcep_config.c b/pathd/path_pcep_config.c index 46c63977f83a..68ec48f54cdd 100644 --- a/pathd/path_pcep_config.c +++ b/pathd/path_pcep_config.c @@ -38,24 +38,6 @@ path_pcep_config_list_path_hops(struct srte_segment_list *segment_list); static void path_pcep_config_delete_lsp_segment_list(struct lsp_nb_key *key); static void path_pcep_config_add_segment_list_segment( struct srte_segment_list *segment_list, uint32_t index, uint32_t label); -static void path_pcep_config_add_segment_list_segment_no_nai( - struct srte_segment_list *segment_list, uint32_t index); -static void path_pcep_config_add_segment_list_segment_nai_ipv4_node( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *ip); -static void path_pcep_config_add_segment_list_segment_nai_ipv6_node( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *ip); -static void path_pcep_config_add_segment_list_segment_nai_ipv4_adj( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *local_ip, struct ipaddr *remote_ip); -static void path_pcep_config_add_segment_list_segment_nai_ipv6_adj( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *local_ip, struct ipaddr *remote_ip); -static void path_pcep_config_add_segment_list_segment_nai_ipv4_unnumbered_adj( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *local_ip, uint32_t local_iface, struct ipaddr *remote_ip, - uint32_t remote_iface); static struct srte_segment_list * path_pcep_config_create_segment_list(const char *segment_list_name, enum srte_protocol_origin protocol, @@ -78,6 +60,7 @@ 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_config_lookup(struct path *path) { @@ -261,11 +244,11 @@ int path_pcep_config_update_path(struct path *path) char segment_list_name_buff[64 + 1 + 64 + 1 + 11 + 1]; char *segment_list_name = NULL; struct srte_segment_list *segment_list; + struct srte_segment_entry *segment; path_pcep_config_delete_lsp_segment_list(&path->nbkey); 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; @@ -279,42 +262,14 @@ int path_pcep_config_update_path(struct path *path) path_pcep_config_add_segment_list_segment( segment_list, index, hop->sid.mpls.label); if (hop->has_nai) { - switch (hop->nai.type) { - case PCEP_SR_SUBOBJ_NAI_IPV4_NODE: - path_pcep_config_add_segment_list_segment_nai_ipv4_node( - segment_list, index, - &hop->nai.local_addr); - break; - case PCEP_SR_SUBOBJ_NAI_IPV6_NODE: - path_pcep_config_add_segment_list_segment_nai_ipv6_node( - segment_list, index, - &hop->nai.local_addr); - break; - case PCEP_SR_SUBOBJ_NAI_IPV4_ADJACENCY: - path_pcep_config_add_segment_list_segment_nai_ipv4_adj( - segment_list, index, - &hop->nai.local_addr, - &hop->nai.remote_addr); - break; - case PCEP_SR_SUBOBJ_NAI_IPV6_ADJACENCY: - path_pcep_config_add_segment_list_segment_nai_ipv6_adj( - segment_list, index, - &hop->nai.local_addr, - &hop->nai.remote_addr); - break; - case PCEP_SR_SUBOBJ_NAI_UNNUMBERED_IPV4_ADJACENCY: - path_pcep_config_add_segment_list_segment_nai_ipv4_unnumbered_adj( - segment_list, index, - &hop->nai.local_addr, - hop->nai.local_iface, - &hop->nai.remote_addr, - hop->nai.remote_iface); - break; - default: - path_pcep_config_add_segment_list_segment_no_nai( - segment_list, index); - break; - } + segment = srte_segment_entry_find(segment_list, + index); + 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); } } } @@ -365,80 +320,6 @@ void path_pcep_config_add_segment_list_segment( SET_FLAG(segment->segment_list->flags, F_SEGMENT_LIST_MODIFIED); } -void path_pcep_config_add_segment_list_segment_no_nai( - struct srte_segment_list *segment_list, uint32_t index) -{ - struct srte_segment_entry *segment; - - segment = srte_segment_entry_find(segment_list, index); - segment->nai_type = SRTE_SEGMENT_NAI_TYPE_NONE; - 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; -} - -void path_pcep_config_add_segment_list_segment_nai_ipv4_node( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *ip) -{ - struct srte_segment_entry *segment; - - segment = srte_segment_entry_find(segment_list, index); - segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV4_NODE; - memcpy(&segment->nai_local_addr, ip, sizeof(struct ipaddr)); -} - -void path_pcep_config_add_segment_list_segment_nai_ipv6_node( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *ip) -{ - struct srte_segment_entry *segment; - - segment = srte_segment_entry_find(segment_list, index); - segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV6_NODE; - memcpy(&segment->nai_local_addr, ip, sizeof(struct ipaddr)); -} - -void path_pcep_config_add_segment_list_segment_nai_ipv4_adj( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *local_ip, struct ipaddr *remote_ip) -{ - struct srte_segment_entry *segment; - - segment = srte_segment_entry_find(segment_list, index); - segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY; - memcpy(&segment->nai_local_addr, local_ip, sizeof(struct ipaddr)); - memcpy(&segment->nai_remote_addr, remote_ip, sizeof(struct ipaddr)); -} - -void path_pcep_config_add_segment_list_segment_nai_ipv6_adj( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *local_ip, struct ipaddr *remote_ip) -{ - struct srte_segment_entry *segment; - - segment = srte_segment_entry_find(segment_list, index); - segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY; - memcpy(&segment->nai_local_addr, local_ip, sizeof(struct ipaddr)); - memcpy(&segment->nai_remote_addr, remote_ip, sizeof(struct ipaddr)); -} - -void path_pcep_config_add_segment_list_segment_nai_ipv4_unnumbered_adj( - struct srte_segment_list *segment_list, uint32_t index, - struct ipaddr *local_ip, uint32_t local_iface, struct ipaddr *remote_ip, - uint32_t remote_iface) -{ - struct srte_segment_entry *segment; - - segment = srte_segment_entry_find(segment_list, index); - segment->nai_type = SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY; - memcpy(&segment->nai_local_addr, local_ip, sizeof(struct ipaddr)); - memcpy(&segment->nai_remote_addr, remote_ip, sizeof(struct ipaddr)); - segment->nai_local_iface = local_iface; - segment->nai_remote_iface = remote_iface; -} - struct srte_segment_list * path_pcep_config_create_segment_list(const char *segment_list_name, enum srte_protocol_origin protocol, @@ -547,3 +428,23 @@ enum pcep_sr_subobj_nai pcep_nai_type(enum srte_segment_nai_type type) 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; + default: + return SRTE_SEGMENT_NAI_TYPE_NONE; + } +} diff --git a/pathd/pathd.c b/pathd/pathd.c index 19651f552f7b..106817b2a624 100644 --- a/pathd/pathd.c +++ b/pathd/pathd.c @@ -137,6 +137,37 @@ void srte_segment_entry_del(struct srte_segment_entry *segment) XFREE(MTYPE_PATH_SEGMENT_LIST, 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) +{ + segment->nai_type = type; + memcpy(&segment->nai_local_addr, local_ip, sizeof(struct ipaddr)); + + switch (type) { + case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE: + case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE: + break; + case SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY: + case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY: + memcpy(&segment->nai_remote_addr, remote_ip, + sizeof(struct ipaddr)); + break; + case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY: + memcpy(&segment->nai_remote_addr, remote_ip, + sizeof(struct ipaddr)); + segment->nai_local_iface = local_iface; + segment->nai_remote_iface = remote_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; + } +} + struct srte_policy *srte_policy_add(uint32_t color, struct ipaddr *endpoint) { struct srte_policy *policy; diff --git a/pathd/pathd.h b/pathd/pathd.h index 0eaa0ee02361..2fff73f6d42a 100644 --- a/pathd/pathd.h +++ b/pathd/pathd.h @@ -249,6 +249,11 @@ 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); 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); From 458c5b0edafc6b641ab486b0aae0a92b2f3cbf52 Mon Sep 17 00:00:00 2001 From: GalaxyGorilla Date: Fri, 26 Jun 2020 12:29:00 +0000 Subject: [PATCH 5/7] pathd: refactor metrics and bandwidth handling Signed-off-by: GalaxyGorilla --- pathd/path_pcep_config.c | 56 ++++++---------------------------------- 1 file changed, 8 insertions(+), 48 deletions(-) diff --git a/pathd/path_pcep_config.c b/pathd/path_pcep_config.c index 68ec48f54cdd..d0edb6df52c3 100644 --- a/pathd/path_pcep_config.c +++ b/pathd/path_pcep_config.c @@ -44,16 +44,6 @@ path_pcep_config_create_segment_list(const char *segment_list_name, const char *originator); static void path_pcep_config_update_lsp(struct lsp_nb_key *key, struct srte_segment_list *segment_list); -static void path_pcep_config_add_lsp_metric(uint32_t color, - struct ipaddr *endpoint, - uint32_t preference, - enum pcep_metric_types type, - float value, bool is_bound, - bool is_computed); -static void path_pcep_config_set_lsp_bandwidth(uint32_t color, - struct ipaddr *endpoint, - uint32_t preference, - float value); static struct srte_candidate *lookup_candidate(struct lsp_nb_key *key); static char *candidate_name(struct srte_candidate *candidate); @@ -243,6 +233,7 @@ int path_pcep_config_update_path(struct path *path) 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; struct srte_segment_entry *segment; @@ -276,19 +267,14 @@ int path_pcep_config_update_path(struct path *path) path_pcep_config_update_lsp(&path->nbkey, segment_list); - for (metric = path->first_metric; metric != NULL; - metric = metric->next) { - path_pcep_config_add_lsp_metric( - path->nbkey.color, &path->nbkey.endpoint, - path->nbkey.preference, metric->type, metric->value, - metric->is_bound, metric->is_computed); - } + candidate = lookup_candidate(&path->nbkey); - if (path->has_bandwidth) { - path_pcep_config_set_lsp_bandwidth( - path->nbkey.color, &path->nbkey.endpoint, - path->nbkey.preference, path->bandwidth); - } + for (metric = path->first_metric; metric != NULL; metric = metric->next) + srte_lsp_set_metric(candidate->lsp, metric->type, metric->value, + metric->is_bound, metric->is_computed); + + if (path->has_bandwidth) + srte_lsp_set_bandwidth(candidate->lsp, path->bandwidth); srte_apply_changes(); @@ -353,32 +339,6 @@ void path_pcep_config_update_lsp(struct lsp_nb_key *key, SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); } -void path_pcep_config_add_lsp_metric(uint32_t color, struct ipaddr *endpoint, - uint32_t preference, - enum pcep_metric_types type, float value, - bool is_bound, bool is_computed) -{ - struct srte_policy *policy; - struct srte_candidate *candidate; - - policy = srte_policy_find(color, endpoint); - candidate = srte_candidate_find(policy, preference); - - srte_lsp_set_metric(candidate->lsp, type, value, is_bound, is_computed); -} - -void path_pcep_config_set_lsp_bandwidth(uint32_t color, struct ipaddr *endpoint, - uint32_t preference, float value) -{ - struct srte_policy *policy; - struct srte_candidate *candidate; - - policy = srte_policy_find(color, endpoint); - candidate = srte_candidate_find(policy, preference); - - srte_lsp_set_bandwidth(candidate->lsp, value); -} - struct srte_candidate *lookup_candidate(struct lsp_nb_key *key) { struct srte_policy *policy = NULL; From 80adcd4071a3c17019c7201cbe86991827dbbe5d Mon Sep 17 00:00:00 2001 From: GalaxyGorilla Date: Fri, 26 Jun 2020 13:19:40 +0000 Subject: [PATCH 6/7] pathd: refactor LSP and Segment-List handling Signed-off-by: GalaxyGorilla --- pathd/path_pcep_config.c | 115 +++++++++++---------------------------- pathd/pathd.c | 3 + 2 files changed, 34 insertions(+), 84 deletions(-) diff --git a/pathd/path_pcep_config.c b/pathd/path_pcep_config.c index d0edb6df52c3..22cba9d00f90 100644 --- a/pathd/path_pcep_config.c +++ b/pathd/path_pcep_config.c @@ -34,17 +34,6 @@ static struct path_hop * path_pcep_config_list_path_hops(struct srte_segment_list *segment_list); - -static void path_pcep_config_delete_lsp_segment_list(struct lsp_nb_key *key); -static void path_pcep_config_add_segment_list_segment( - struct srte_segment_list *segment_list, uint32_t index, uint32_t label); -static struct srte_segment_list * -path_pcep_config_create_segment_list(const char *segment_list_name, - enum srte_protocol_origin protocol, - const char *originator); -static void path_pcep_config_update_lsp(struct lsp_nb_key *key, - 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 @@ -56,7 +45,6 @@ void path_pcep_config_lookup(struct path *path) { struct srte_candidate *candidate = lookup_candidate(&path->nbkey); struct srte_lsp *lsp = candidate->lsp; - ; if (candidate == NULL) return; @@ -234,40 +222,57 @@ int path_pcep_config_update_path(struct path *path) 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; + struct srte_segment_list *segment_list = NULL; struct srte_segment_entry *segment; - path_pcep_config_delete_lsp_segment_list(&path->nbkey); + candidate = lookup_candidate(&path->nbkey); + + // if there is no candidate to update we are done + if (!candidate) + return 0; + + // first clean up old segment list if present + if (candidate->lsp->segment_list) { + SET_FLAG(candidate->lsp->segment_list->flags, + F_SEGMENT_LIST_DELETED); + 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; - segment_list = path_pcep_config_create_segment_list( - segment_list_name, path->update_origin, - path->originator); + + 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); - path_pcep_config_add_segment_list_segment( - segment_list, index, hop->sid.mpls.label); - if (hop->has_nai) { - segment = srte_segment_entry_find(segment_list, - index); + + 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) 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); - } } } - path_pcep_config_update_lsp(&path->nbkey, segment_list); - - candidate = lookup_candidate(&path->nbkey); + 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, metric->type, metric->value, @@ -281,64 +286,6 @@ int path_pcep_config_update_path(struct path *path) return 0; } -/* Delete the candidate path segment list if it was created through PCEP - and by the given originator */ -void path_pcep_config_delete_lsp_segment_list(struct lsp_nb_key *key) -{ - struct srte_candidate *candidate = lookup_candidate(key); - - if ((candidate == NULL) || (candidate->lsp->segment_list == NULL)) - return; - - SET_FLAG(candidate->lsp->segment_list->flags, F_SEGMENT_LIST_DELETED); - - candidate->lsp->segment_list = NULL; - SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); -} - -void path_pcep_config_add_segment_list_segment( - struct srte_segment_list *segment_list, uint32_t index, uint32_t label) -{ - struct srte_segment_entry *segment; - - segment = srte_segment_entry_add(segment_list, index); - segment->sid_value = (mpls_label_t)label; - SET_FLAG(segment->segment_list->flags, F_SEGMENT_LIST_MODIFIED); -} - -struct srte_segment_list * -path_pcep_config_create_segment_list(const char *segment_list_name, - enum srte_protocol_origin protocol, - const char *originator) -{ - struct srte_segment_list *segment_list; - - segment_list = srte_segment_list_add(segment_list_name); - SET_FLAG(segment_list->flags, F_SEGMENT_LIST_NEW); - - segment_list->protocol_origin = protocol; - strlcpy(segment_list->originator, originator, - sizeof(segment_list->originator)); - SET_FLAG(segment_list->flags, F_SEGMENT_LIST_MODIFIED); - - return segment_list; -} - -void path_pcep_config_update_lsp(struct lsp_nb_key *key, - struct srte_segment_list *segment_list) -{ - struct srte_policy *policy; - struct srte_candidate *candidate; - - policy = srte_policy_find(key->color, &key->endpoint); - candidate = srte_candidate_find(policy, key->preference); - - candidate->lsp->segment_list = segment_list; - assert(candidate->lsp->segment_list); - - SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED); -} - struct srte_candidate *lookup_candidate(struct lsp_nb_key *key) { struct srte_policy *policy = NULL; diff --git a/pathd/pathd.c b/pathd/pathd.c index 106817b2a624..a5fd73ba1d6c 100644 --- a/pathd/pathd.c +++ b/pathd/pathd.c @@ -366,7 +366,10 @@ struct srte_candidate *srte_candidate_add(struct srte_policy *policy, candidate->preference = preference; candidate->policy = policy; candidate->type = SRTE_CANDIDATE_TYPE_UNDEFINED; + + lsp->candidate = candidate; candidate->lsp = lsp; + RB_INSERT(srte_candidate_head, &policy->candidate_paths, candidate); return candidate; From 71bd7c60548a4d67cb63486560448c27b456137f Mon Sep 17 00:00:00 2001 From: GalaxyGorilla Date: Mon, 29 Jun 2020 13:56:00 +0000 Subject: [PATCH 7/7] pathd: config read/write should be done via main thread Signed-off-by: GalaxyGorilla --- pathd/path_pcep_config.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pathd/path_pcep_config.c b/pathd/path_pcep_config.c index 22cba9d00f90..84fba7748461 100644 --- a/pathd/path_pcep_config.c +++ b/pathd/path_pcep_config.c @@ -25,6 +25,7 @@ #include "pathd/path_pcep.h" #include "pathd/path_pcep_config.h" #include "pathd/path_pcep_debug.h" +#include "thread.h" #define MAX_XPATH 256 #define MAX_FLOAT_LEN 22 @@ -41,13 +42,14 @@ 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_config_lookup(struct path *path) +static int path_pcep_config_lookup_cb(struct thread *t) { + struct path *path = THREAD_ARG(t); struct srte_candidate *candidate = lookup_candidate(&path->nbkey); struct srte_lsp *lsp = candidate->lsp; if (candidate == NULL) - return; + return 0; if (path->name == NULL) path->name = candidate_name(candidate); if (path->type == SRTE_CANDIDATE_TYPE_UNDEFINED) @@ -57,6 +59,16 @@ void path_pcep_config_lookup(struct path *path) if ((path->update_origin == SRTE_ORIGIN_UNDEFINED) && (lsp->segment_list != NULL)) path->update_origin = lsp->segment_list->protocol_origin; + + return 0; +} + +void path_pcep_config_lookup(struct path *path) +{ + /* + * Configuration access is strictly done via the main thread + */ + thread_execute(master, path_pcep_config_lookup_cb, path, 0); } struct path *path_pcep_config_get_path(struct lsp_nb_key *key)