diff options
author | Javier Garcia <javier.garcia@voltanet.io> | 2021-06-23 09:23:52 +0200 |
---|---|---|
committer | Javier Garcia <javier.garcia@voltanet.io> | 2021-06-24 12:44:03 +0200 |
commit | 0a1bf4be7f3b830efff20abc62964f2f72c145df (patch) | |
tree | 9bf5957e222762f86ad2b5b7e6856afb03c79fa3 /pathd | |
parent | Merge pull request #8800 from donaldsharp/sr_vtysh_fix (diff) | |
download | frr-0a1bf4be7f3b830efff20abc62964f2f72c145df.tar.xz frr-0a1bf4be7f3b830efff20abc62964f2f72c145df.zip |
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 <javier.garcia@voltanet.io>
Diffstat (limited to 'pathd')
-rw-r--r-- | pathd/path_pcep_pcc.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/pathd/path_pcep_pcc.c b/pathd/path_pcep_pcc.c index 81a338ac6..4848ba7c0 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; } |