summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pathd/path_pcep_config.c2
-rw-r--r--pathd/path_pcep_pcc.c53
2 files changed, 53 insertions, 2 deletions
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 81a338ac63..b72a536ef4 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);
@@ -558,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);
}
@@ -1340,7 +1341,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 +1377,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 +1855,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 +1905,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;
}