From 0a1bf4be7f3b830efff20abc62964f2f72c145df Mon Sep 17 00:00:00 2001 From: Javier Garcia Date: Wed, 23 Jun 2021 09:23:52 +0200 Subject: [PATCH 1/2] pathd: If pce ret no-path to PcReq don't retry PcReq nor delegate(1/2) Based in RFC 5440 @4.2.2 ""...after a no-path , the pcc may decide" and RFC 8231 #5.8.3 "... pcc must not set PcReq after path is delegated" So will not (try) to delegate the path with no-path neither must do further retries. Signed-off-by: Javier Garcia --- pathd/path_pcep_pcc.c | 52 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/pathd/path_pcep_pcc.c b/pathd/path_pcep_pcc.c index 81a338ac63..4848ba7c0c 100644 --- a/pathd/path_pcep_pcc.c +++ b/pathd/path_pcep_pcc.c @@ -128,6 +128,8 @@ static struct req_entry *push_new_req(struct pcc_state *pcc_state, struct path *path); static void repush_req(struct pcc_state *pcc_state, struct req_entry *req); static struct req_entry *pop_req(struct pcc_state *pcc_state, uint32_t reqid); +static struct req_entry *pop_req_no_reqid(struct pcc_state *pcc_state, + uint32_t reqid); static bool add_reqid_mapping(struct pcc_state *pcc_state, struct path *path); static void remove_reqid_mapping(struct pcc_state *pcc_state, struct path *path); @@ -1340,7 +1342,11 @@ void handle_pcep_comp_reply(struct ctrl_state *ctrl_state, struct path *path; path = pcep_lib_parse_path(msg); - req = pop_req(pcc_state, path->req_id); + if (path->no_path) { + req = pop_req_no_reqid(pcc_state, path->req_id); + } else { + req = pop_req(pcc_state, path->req_id); + } if (req == NULL) { /* TODO: check the rate of bad computation reply and close * the connection if more that a given rate. @@ -1372,6 +1378,9 @@ void handle_pcep_comp_reply(struct ctrl_state *ctrl_state, if (path->no_path) { PCEP_DEBUG("%s Computation for path %s did not find any result", pcc_state->tag, path->name); + free_req_entry(req); + pcep_free_path(path); + return; } else if (validate_incoming_path(pcc_state, path, err, sizeof(err))) { /* Updating a dynamic path will automatically delegate it */ pcep_thread_update_path(ctrl_state, pcc_state->id, path); @@ -1847,6 +1856,20 @@ struct req_entry *pop_req(struct pcc_state *pcc_state, uint32_t reqid) return req; } +struct req_entry *pop_req_no_reqid(struct pcc_state *pcc_state, uint32_t reqid) +{ + struct path path = {.req_id = reqid}; + struct req_entry key = {.path = &path}; + struct req_entry *req; + + req = RB_FIND(req_entry_head, &pcc_state->requests, &key); + if (req == NULL) + return NULL; + RB_REMOVE(req_entry_head, &pcc_state->requests, req); + + return req; +} + bool add_reqid_mapping(struct pcc_state *pcc_state, struct path *path) { struct req_map_data *mapping; @@ -1883,6 +1906,33 @@ uint32_t lookup_reqid(struct pcc_state *pcc_state, struct path *path) bool has_pending_req_for(struct pcc_state *pcc_state, struct path *path) { + struct req_entry key = {.path = path}; + struct req_entry *req; + + + PCEP_DEBUG_PATH("(%s) %s", format_path(path), __func__); + /* Looking for request without result */ + if (path->no_path || !path->first_hop) { + PCEP_DEBUG_PATH("%s Path : no_path|!first_hop", __func__); + /* ...and already was handle */ + req = RB_FIND(req_entry_head, &pcc_state->requests, &key); + if (!req) { + /* we must purge remaining reqid */ + PCEP_DEBUG_PATH("%s Purge pending reqid: no_path(%s)", + __func__, + path->no_path ? "TRUE" : "FALSE"); + if (lookup_reqid(pcc_state, path) != 0) { + PCEP_DEBUG_PATH("%s Purge pending reqid: DONE ", + __func__); + remove_reqid_mapping(pcc_state, path); + return true; + } else { + return false; + } + } + } + + return lookup_reqid(pcc_state, path) != 0; } From c9daf7efc6cbf812c1a737c28027227570f1297d Mon Sep 17 00:00:00 2001 From: Javier Garcia Date: Thu, 24 Jun 2021 12:39:40 +0200 Subject: [PATCH 2/2] pathd: Handle srp_id correctly (2/2) Based on RFC 8231 #5.8.3 PcUpd RFC 8181 #5.1 Pcinit Signed-off-by: Javier Garcia --- pathd/path_pcep_config.c | 2 ++ pathd/path_pcep_pcc.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pathd/path_pcep_config.c b/pathd/path_pcep_config.c index 0349618304..4c16b83948 100644 --- a/pathd/path_pcep_config.c +++ b/pathd/path_pcep_config.c @@ -332,6 +332,7 @@ int path_pcep_config_initiate_path(struct path *path) candidate = srte_candidate_add( policy, path->nbkey.preference, SRTE_ORIGIN_PCEP, path->originator); + candidate->policy->srp_id = path->srp_id; strlcpy(candidate->name, path->name, sizeof(candidate->name)); SET_FLAG(candidate->flags, F_CANDIDATE_NEW); @@ -387,6 +388,7 @@ int path_pcep_config_update_path(struct path *path) if (!candidate) return 0; + candidate->policy->srp_id = path->srp_id; // first clean up old segment list if present if (candidate->lsp->segment_list) { SET_FLAG(candidate->lsp->segment_list->flags, diff --git a/pathd/path_pcep_pcc.c b/pathd/path_pcep_pcc.c index 4848ba7c0c..b72a536ef4 100644 --- a/pathd/path_pcep_pcc.c +++ b/pathd/path_pcep_pcc.c @@ -560,7 +560,6 @@ void pcep_pcc_send_report(struct ctrl_state *ctrl_state, if (is_stable && (real_status != PCEP_LSP_OPERATIONAL_DOWN)) { PCEP_DEBUG("(%s)%s Send report for candidate path (!DOWN) %s", __func__, pcc_state->tag, path->name); - path->srp_id = 0; path->status = real_status; send_report(pcc_state, path); }