summaryrefslogtreecommitdiff
path: root/pathd/path_pcep_pcc.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2021-03-16 14:03:34 -0400
committerGitHub <noreply@github.com>2021-03-16 14:03:34 -0400
commit3406c16cbeecafb400cc2155a1ca9f9504c95b4e (patch)
tree7853ddaa015a1542723f925b863d4440d9ff3529 /pathd/path_pcep_pcc.c
parent30643d6f314c8b5462073b2382c799b7966528e8 (diff)
parent749714731ee9a59ae39be77e7db3915ce3ad0bd8 (diff)
Merge pull request #7963 from volta-networks/feat_pceplib_into_frr_github
pceplib: Integrate pcelib into frr
Diffstat (limited to 'pathd/path_pcep_pcc.c')
-rw-r--r--pathd/path_pcep_pcc.c73
1 files changed, 56 insertions, 17 deletions
diff --git a/pathd/path_pcep_pcc.c b/pathd/path_pcep_pcc.c
index c1f60edd22..9de3ba7811 100644
--- a/pathd/path_pcep_pcc.c
+++ b/pathd/path_pcep_pcc.c
@@ -55,6 +55,7 @@
#define MAX_ERROR_MSG_SIZE 256
#define MAX_COMPREQ_TRIES 3
+pthread_mutex_t g_pcc_info_mtx = PTHREAD_MUTEX_INITIALIZER;
/* PCEP Event Handler */
static void handle_pcep_open(struct ctrl_state *ctrl_state,
@@ -63,12 +64,15 @@ static void handle_pcep_open(struct ctrl_state *ctrl_state,
static void handle_pcep_message(struct ctrl_state *ctrl_state,
struct pcc_state *pcc_state,
struct pcep_message *msg);
+static void handle_pcep_lsp_initiate(struct ctrl_state *ctrl_state,
+ struct pcc_state *pcc_state,
+ struct pcep_message *msg);
static void handle_pcep_lsp_update(struct ctrl_state *ctrl_state,
struct pcc_state *pcc_state,
struct pcep_message *msg);
-static void handle_pcep_lsp_initiate(struct ctrl_state *ctrl_state,
+static void continue_pcep_lsp_update(struct ctrl_state *ctrl_state,
struct pcc_state *pcc_state,
- struct pcep_message *msg);
+ struct path *path, void *payload);
static void handle_pcep_comp_reply(struct ctrl_state *ctrl_state,
struct pcc_state *pcc_state,
struct pcep_message *msg);
@@ -543,23 +547,43 @@ void pcep_pcc_sync_done(struct ctrl_state *ctrl_state,
}
void pcep_pcc_send_report(struct ctrl_state *ctrl_state,
- struct pcc_state *pcc_state, struct path *path)
+ struct pcc_state *pcc_state, struct path *path,
+ bool is_stable)
{
- if (pcc_state->status != PCEP_PCC_OPERATING)
+ if ((pcc_state->status != PCEP_PCC_OPERATING)
+ || (!pcc_state->caps.is_stateful)) {
+ pcep_free_path(path);
return;
+ }
- if (pcc_state->caps.is_stateful) {
- PCEP_DEBUG("%s Send report for candidate path %s",
- pcc_state->tag, path->name);
+ PCEP_DEBUG("%s Send report for candidate path %s", pcc_state->tag,
+ path->name);
+
+ /* 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 = path->status;
+ path->status = PCEP_LSP_OPERATIONAL_DOWN;
+ send_report(pcc_state, path);
+
+ /* If no update is expected and the real status wasn't down, we need to
+ * send a second report with the real status */
+ if (is_stable && (real_status != PCEP_LSP_OPERATIONAL_DOWN)) {
+ path->srp_id = 0;
+ path->status = real_status;
send_report(pcc_state, path);
}
+
+ pcep_free_path(path);
}
+
/* ------------ Timeout handler ------------ */
void pcep_pcc_timeout_handler(struct ctrl_state *ctrl_state,
struct pcc_state *pcc_state,
- enum pcep_ctrl_timer_type type, void *param)
+ enum pcep_ctrl_timeout_type type, void *param)
{
struct req_entry *req;
@@ -926,6 +950,7 @@ int pcep_pcc_calculate_best_pce(struct pcc_state **pcc)
// Changed of state so ...
if (step_0_best != best_pce) {
+ pthread_mutex_lock(&g_pcc_info_mtx);
// Calculate previous
previous_best_pce = step_0_best;
// Clean state
@@ -970,6 +995,7 @@ int pcep_pcc_calculate_best_pce(struct pcc_state **pcc)
}
}
}
+ pthread_mutex_unlock(&g_pcc_info_mtx);
}
return ((best_pce == -1) ? 0 : pcc[best_pce]->id);
@@ -1094,18 +1120,24 @@ void pcep_pcc_copy_pcc_info(struct pcc_state **pcc,
}
pcc_info->ctrl_state = NULL;
- pcc_info->msd = pcc_state->pcc_opts->msd;
- pcc_info->pcc_port = pcc_state->pcc_opts->port;
+ if(pcc_state->pcc_opts){
+ pcc_info->msd = pcc_state->pcc_opts->msd;
+ pcc_info->pcc_port = pcc_state->pcc_opts->port;
+ }
pcc_info->next_plspid = pcc_state->next_plspid;
pcc_info->next_reqid = pcc_state->next_reqid;
pcc_info->status = pcc_state->status;
pcc_info->pcc_id = pcc_state->id;
+ pthread_mutex_lock(&g_pcc_info_mtx);
pcc_info->is_best_multi_pce = pcc_state->is_best;
pcc_info->previous_best = pcc_state->previous_best;
+ pthread_mutex_unlock(&g_pcc_info_mtx);
pcc_info->precedence =
pcc_state->pce_opts ? pcc_state->pce_opts->precedence : 0;
- memcpy(&pcc_info->pcc_addr, &pcc_state->pcc_addr_tr,
- sizeof(struct ipaddr));
+ if(pcc_state->pcc_addr_tr.ipa_type != IPADDR_NONE){
+ memcpy(&pcc_info->pcc_addr, &pcc_state->pcc_addr_tr,
+ sizeof(struct ipaddr));
+ }
}
@@ -1154,12 +1186,19 @@ void handle_pcep_lsp_update(struct ctrl_state *ctrl_state,
struct pcc_state *pcc_state,
struct pcep_message *msg)
{
- char err[MAX_ERROR_MSG_SIZE] = "";
struct path *path;
path = pcep_lib_parse_path(msg);
lookup_nbkey(pcc_state, path);
- /* TODO: Investigate if this is safe to do in the controller thread */
- path_pcep_config_lookup(path);
+ pcep_thread_refine_path(ctrl_state, pcc_state->id,
+ &continue_pcep_lsp_update, path, NULL);
+}
+
+void continue_pcep_lsp_update(struct ctrl_state *ctrl_state,
+ struct pcc_state *pcc_state, struct path *path,
+ void *payload)
+{
+ char err[MAX_ERROR_MSG_SIZE] = {0};
+
specialize_incoming_path(pcc_state, path);
PCEP_DEBUG("%s Received LSP update", pcc_state->tag);
PCEP_DEBUG_PATH("%s", format_path(path));
@@ -1309,13 +1348,13 @@ void select_transport_address(struct pcc_state *pcc_state)
* address */
if (IS_IPADDR_V4(&pcc_state->pce_opts->addr)) {
if (CHECK_FLAG(pcc_state->flags, F_PCC_STATE_HAS_IPV4)) {
- taddr->ipa_type = IPADDR_V4;
taddr->ipaddr_v4 = pcc_state->pcc_addr_v4;
+ taddr->ipa_type = IPADDR_V4;
}
} else {
if (CHECK_FLAG(pcc_state->flags, F_PCC_STATE_HAS_IPV6)) {
- taddr->ipa_type = IPADDR_V6;
taddr->ipaddr_v6 = pcc_state->pcc_addr_v6;
+ taddr->ipa_type = IPADDR_V6;
}
}
}