From 56634922390ff08d2ae06ecb0c32f94c07028561 Mon Sep 17 00:00:00 2001 From: Javier Garcia Date: Fri, 21 May 2021 09:15:52 +0200 Subject: [PATCH] pathd: Handle PCInitiated messages, thread controller. (2/4) Co-authored-by: Javier Garcia Signed-off-by: Sebastien Merle Signed-off-by: Javier Garcia --- pathd/path_pcep_controller.c | 24 ++++++ pathd/path_pcep_controller.h | 6 ++ pathd/path_pcep_debug.c | 16 ++++ pathd/path_pcep_lib.c | 105 ++++++++++++++++++++++- pathd/path_pcep_lib.h | 3 +- pathd/path_pcep_pcc.c | 157 ++++++++++++++++++++++++++++++----- pathd/path_pcep_pcc.h | 3 + 7 files changed, 288 insertions(+), 26 deletions(-) diff --git a/pathd/path_pcep_controller.c b/pathd/path_pcep_controller.c index 528dcc3539..449c40c16c 100644 --- a/pathd/path_pcep_controller.c +++ b/pathd/path_pcep_controller.c @@ -57,6 +57,7 @@ enum pcep_ctrl_event_type { EV_PCEPLIB_EVENT, EV_RESET_PCC_SESSION, EV_SEND_REPORT, + EV_SEND_ERROR, EV_PATH_REFINED }; @@ -328,6 +329,14 @@ int pcep_ctrl_send_report(struct frr_pthread *fpt, int pcc_id, } +int pcep_ctrl_send_error(struct frr_pthread *fpt, int pcc_id, + struct pcep_error *error) +{ + struct ctrl_state *ctrl_state = get_ctrl_state(fpt); + return send_to_thread(ctrl_state, pcc_id, EV_SEND_ERROR, 0, error); +} + + /* ------------ Internal Functions Called from Main Thread ------------ */ int pcep_ctrl_halt_cb(struct frr_pthread *fpt, void **res) @@ -368,6 +377,13 @@ void pcep_thread_update_path(struct ctrl_state *ctrl_state, int pcc_id, path); } +void pcep_thread_initiate_path(struct ctrl_state *ctrl_state, int pcc_id, + struct path *path) +{ + send_to_main(ctrl_state, pcc_id, PCEP_MAIN_EVENT_INITIATE_CANDIDATE, + path); +} + void pcep_thread_remove_candidate_path_segments(struct ctrl_state *ctrl_state, struct pcc_state *pcc_state) { @@ -743,6 +759,7 @@ int pcep_thread_event_handler(struct thread *thread) struct pcep_refine_path_event_data *refine_data = NULL; struct path *path_copy = NULL; + struct pcep_error *error = NULL; switch (type) { case EV_UPDATE_PCC_OPTS: @@ -818,6 +835,13 @@ int pcep_thread_event_handler(struct thread *thread) refine_data = (struct pcep_refine_path_event_data *)payload; pcep_thread_path_refined_event(ctrl_state, refine_data); break; + case EV_SEND_ERROR: + assert(payload != NULL); + error = (struct pcep_error *)payload; + pcc_state = pcep_pcc_get_pcc_by_id(ctrl_state->pcc, pcc_id); + pcep_pcc_send_error(ctrl_state, pcc_state, error, + (bool)sub_type); + break; default: flog_warn(EC_PATH_PCEP_RECOVERABLE_INTERNAL_ERROR, "Unexpected event received in controller thread: %u", diff --git a/pathd/path_pcep_controller.h b/pathd/path_pcep_controller.h index 1b7c3a4c72..f55cc0db72 100644 --- a/pathd/path_pcep_controller.h +++ b/pathd/path_pcep_controller.h @@ -27,6 +27,7 @@ struct pcc_state; enum pcep_main_event_type { PCEP_MAIN_EVENT_UNDEFINED = 0, PCEP_MAIN_EVENT_START_SYNC, + PCEP_MAIN_EVENT_INITIATE_CANDIDATE, PCEP_MAIN_EVENT_UPDATE_CANDIDATE, PCEP_MAIN_EVENT_REMOVE_CANDIDATE_LSP, }; @@ -137,10 +138,15 @@ struct pcep_pcc_info *pcep_ctrl_get_pcc_info(struct frr_pthread *fpt, int pcep_ctrl_send_report(struct frr_pthread *fpt, int pcc_id, struct path *path, bool is_stable); +int pcep_ctrl_send_error(struct frr_pthread *fpt, int pcc_id, + struct pcep_error *error); + /* Functions called from the controller thread */ void pcep_thread_start_sync(struct ctrl_state *ctrl_state, int pcc_id); void pcep_thread_update_path(struct ctrl_state *ctrl_state, int pcc_id, struct path *path); +void pcep_thread_initiate_path(struct ctrl_state *ctrl_state, int pcc_id, + struct path *path); void pcep_thread_cancel_timer(struct thread **thread); void pcep_thread_schedule_reconnect(struct ctrl_state *ctrl_state, int pcc_id, int retry_count, struct thread **thread); diff --git a/pathd/path_pcep_debug.c b/pathd/path_pcep_debug.c index e14f6bc4a5..b0802ae6c3 100644 --- a/pathd/path_pcep_debug.c +++ b/pathd/path_pcep_debug.c @@ -780,6 +780,10 @@ const char *pcep_tlv_type_name(enum pcep_object_tlv_types tlv_type) switch (tlv_type) { case PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR: return "NO_PATH_VECTOR"; + case PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST: + return "OBJECTIVE_FUNCTION_LIST"; + case PCEP_OBJ_TLV_TYPE_VENDOR_INFO: + return "VENDOR_INFO"; case PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY: return "STATEFUL_PCE_CAPABILITY"; case PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME: @@ -802,6 +806,18 @@ const char *pcep_tlv_type_name(enum pcep_object_tlv_types tlv_type) return "PATH_SETUP_TYPE"; case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY: return "PATH_SETUP_TYPE_CAPABILITY"; + case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID: + return "SRPOLICY_POL_ID"; + case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME: + return "SRPOLICY_POL_NAME"; + case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID: + return "SRPOLICY_CPATH_ID"; + case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE: + return "SRPOLICY_CPATH_PREFERENCE"; + case PCEP_OBJ_TLV_TYPE_UNKNOWN: + return "UNKNOWN"; + case PCEP_OBJ_TLV_TYPE_ARBITRARY: + return "ARBITRARY"; default: return "UNKNOWN"; } diff --git a/pathd/path_pcep_lib.c b/pathd/path_pcep_lib.c index e9d699de47..d7e544b3f0 100644 --- a/pathd/path_pcep_lib.c +++ b/pathd/path_pcep_lib.c @@ -35,6 +35,7 @@ DEFINE_MTYPE_STATIC(PATHD, PCEPLIB_MESSAGES, "PCEPlib PCEP Messages"); #define DEFAULT_LSAP_SETUP_PRIO 4 #define DEFAULT_LSAP_HOLDING_PRIO 4 #define DEFAULT_LSAP_LOCAL_PRETECTION false +#define MAX_PATH_NAME_SIZE 255 /* pceplib logging callback */ static int pceplib_logging_cb(int level, const char *fmt, va_list args); @@ -76,8 +77,18 @@ static void pcep_lib_parse_srp(struct path *path, struct pcep_object_srp *srp); static void pcep_lib_parse_lsp(struct path *path, struct pcep_object_lsp *lsp); static void pcep_lib_parse_lspa(struct path *path, struct pcep_object_lspa *lspa); +static void pcep_lib_parse_lsp_symbolic_name( + struct path *path, struct pcep_object_tlv_symbolic_path_name *tlv); static void pcep_lib_parse_metric(struct path *path, struct pcep_object_metric *obj); +static void +pcep_lib_parse_endpoints_ipv4(struct path *path, + struct pcep_object_endpoints_ipv4 *obj); +static void +pcep_lib_parse_endpoints_ipv6(struct path *path, + struct pcep_object_endpoints_ipv6 *obj); +static void pcep_lib_parse_vendor_info(struct path *path, + struct pcep_object_vendor_info *obj); static void pcep_lib_parse_ero(struct path *path, struct pcep_object_ro *ero); static struct path_hop *pcep_lib_parse_ero_sr(struct path_hop *next, struct pcep_ro_subobj_sr *sr); @@ -160,7 +171,7 @@ pcep_lib_connect(struct ipaddr *src_addr, int src_port, struct ipaddr *dst_addr, } config->support_stateful_pce_lsp_update = true; - config->support_pce_lsp_instantiation = false; + config->support_pce_lsp_instantiation = pcep_options->pce_initiated; config->support_include_db_version = false; config->support_lsp_triggered_resync = false; config->support_lsp_delta_sync = false; @@ -381,9 +392,25 @@ struct pcep_message *pcep_lib_format_request(struct pcep_caps *caps, } } -struct pcep_message *pcep_lib_format_error(int error_type, int error_value) +struct pcep_message *pcep_lib_format_error(int error_type, int error_value, + struct path *path) { - return pcep_msg_create_error(error_type, error_value); + double_linked_list *objs, *srp_tlvs; + struct pcep_object_srp *srp; + struct pcep_object_tlv_header *tlv; + + if ((path == NULL) || (path->srp_id == 0)) + return pcep_msg_create_error(error_type, error_value); + + objs = dll_initialize(); + srp_tlvs = dll_initialize(); + tlv = (struct pcep_object_tlv_header *)pcep_tlv_create_path_setup_type( + SR_TE_PST); + dll_append(srp_tlvs, tlv); + srp = pcep_obj_create_srp(path->do_remove, path->srp_id, srp_tlvs); + dll_append(objs, srp); + return pcep_msg_create_error_with_objects(error_type, error_value, + objs); } struct pcep_message *pcep_lib_format_request_cancelled(uint32_t reqid) @@ -417,6 +444,9 @@ struct path *pcep_lib_parse_path(struct pcep_message *msg) struct pcep_object_metric *metric = NULL; struct pcep_object_bandwidth *bandwidth = NULL; struct pcep_object_objective_function *of = NULL; + struct pcep_object_endpoints_ipv4 *epv4 = NULL; + struct pcep_object_endpoints_ipv6 *epv6 = NULL; + struct pcep_object_vendor_info *vendor_info = NULL; path = pcep_new_path(); @@ -470,6 +500,21 @@ struct path *pcep_lib_parse_path(struct pcep_message *msg) path->has_pce_objfun = true; path->pce_objfun = of->of_code; break; + case CLASS_TYPE(PCEP_OBJ_CLASS_ENDPOINTS, + PCEP_OBJ_TYPE_ENDPOINT_IPV4): + epv4 = (struct pcep_object_endpoints_ipv4 *)obj; + pcep_lib_parse_endpoints_ipv4(path, epv4); + break; + case CLASS_TYPE(PCEP_OBJ_CLASS_ENDPOINTS, + PCEP_OBJ_TYPE_ENDPOINT_IPV6): + epv6 = (struct pcep_object_endpoints_ipv6 *)obj; + pcep_lib_parse_endpoints_ipv6(path, epv6); + break; + case CLASS_TYPE(PCEP_OBJ_CLASS_VENDOR_INFO, + PCEP_OBJ_TYPE_VENDOR_INFO): + vendor_info = (struct pcep_object_vendor_info *)obj; + pcep_lib_parse_vendor_info(path, vendor_info); + break; default: flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_OBJECT, "Unexpected PCEP object %s (%u) / %s (%u)", @@ -632,7 +677,8 @@ double_linked_list *pcep_lib_format_path(struct pcep_caps *caps, tlv = (struct pcep_object_tlv_header *) pcep_tlv_create_tlv_arbitrary( binding_sid_lsp_tlv_data, - sizeof(binding_sid_lsp_tlv_data), 65505); + sizeof(binding_sid_lsp_tlv_data), + PCEP_OBJ_TYPE_CISCO_BSID); assert(tlv != NULL); dll_append(lsp_tlvs, tlv); } @@ -904,6 +950,8 @@ void pcep_lib_parse_lsp(struct path *path, struct pcep_object_lsp *lsp) double_linked_list *tlvs = lsp->header.tlv_list; double_linked_list_node *node; struct pcep_object_tlv_header *tlv; + struct pcep_object_tlv_symbolic_path_name *name; + struct pcep_object_tlv_arbitrary *arb_tlv; path->plsp_id = lsp->plsp_id; path->status = lsp->operational_status; @@ -919,6 +967,17 @@ void pcep_lib_parse_lsp(struct path *path, struct pcep_object_lsp *lsp) for (node = tlvs->head; node != NULL; node = node->next_node) { tlv = (struct pcep_object_tlv_header *)node->data; switch (tlv->type) { + case PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME: + name = (struct pcep_object_tlv_symbolic_path_name *)tlv; + pcep_lib_parse_lsp_symbolic_name(path, name); + break; + case PCEP_OBJ_TYPE_CISCO_BSID: + arb_tlv = (struct pcep_object_tlv_arbitrary *)tlv; + memcpy(&path->binding_sid, arb_tlv->data + 2, + sizeof(path->binding_sid)); + path->binding_sid = ntohl(path->binding_sid); + path->binding_sid = (path->binding_sid >> 12); + break; default: flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_TLV, "Unexpected LSP TLV %s (%u)", @@ -928,6 +987,16 @@ void pcep_lib_parse_lsp(struct path *path, struct pcep_object_lsp *lsp) } } +void pcep_lib_parse_lsp_symbolic_name( + struct path *path, struct pcep_object_tlv_symbolic_path_name *tlv) +{ + uint16_t size = tlv->symbolic_path_name_length; + assert(path->name == NULL); + size = size > MAX_PATH_NAME_SIZE ? MAX_PATH_NAME_SIZE : size; + path->name = XCALLOC(MTYPE_PCEP, size); + strlcpy((char *)path->name, tlv->symbolic_path_name, size + 1); +} + void pcep_lib_parse_lspa(struct path *path, struct pcep_object_lspa *lspa) { path->has_affinity_filters = true; @@ -952,6 +1021,34 @@ void pcep_lib_parse_metric(struct path *path, struct pcep_object_metric *obj) path->first_metric = metric; } +void pcep_lib_parse_endpoints_ipv4(struct path *path, + struct pcep_object_endpoints_ipv4 *obj) +{ + SET_IPADDR_V4(&path->pcc_addr); + path->pcc_addr.ipaddr_v4 = obj->src_ipv4; + SET_IPADDR_V4(&path->nbkey.endpoint); + path->nbkey.endpoint.ipaddr_v4 = obj->dst_ipv4; +} + +void pcep_lib_parse_endpoints_ipv6(struct path *path, + struct pcep_object_endpoints_ipv6 *obj) +{ + SET_IPADDR_V6(&path->pcc_addr); + path->pcc_addr.ipaddr_v6 = obj->src_ipv6; + SET_IPADDR_V6(&path->nbkey.endpoint); + path->nbkey.endpoint.ipaddr_v6 = obj->dst_ipv6; +} + +void pcep_lib_parse_vendor_info(struct path *path, + struct pcep_object_vendor_info *obj) +{ + if (obj->enterprise_number == ENTERPRISE_NUMBER_CISCO + && obj->enterprise_specific_info == ENTERPRISE_COLOR_CISCO) + path->nbkey.color = obj->enterprise_specific_info1; + else + path->nbkey.color = 0; +} + void pcep_lib_parse_ero(struct path *path, struct pcep_object_ro *ero) { struct path_hop *hop = NULL; diff --git a/pathd/path_pcep_lib.h b/pathd/path_pcep_lib.h index 3f34edcb3f..524f385d14 100644 --- a/pathd/path_pcep_lib.h +++ b/pathd/path_pcep_lib.h @@ -37,7 +37,8 @@ struct pcep_message *pcep_lib_format_request(struct pcep_caps *caps, struct path *path); struct pcep_message *pcep_lib_format_request_cancelled(uint32_t reqid); -struct pcep_message *pcep_lib_format_error(int error_type, int error_value); +struct pcep_message *pcep_lib_format_error(int error_type, int error_value, + struct path *path); struct path *pcep_lib_parse_path(struct pcep_message *msg); void pcep_lib_parse_capabilities(struct pcep_message *msg, struct pcep_caps *caps); diff --git a/pathd/path_pcep_pcc.c b/pathd/path_pcep_pcc.c index 779c400b86..81a338ac63 100644 --- a/pathd/path_pcep_pcc.c +++ b/pathd/path_pcep_pcc.c @@ -93,7 +93,8 @@ static void send_pcep_message(struct pcc_state *pcc_state, struct pcep_message *msg); static void send_pcep_error(struct pcc_state *pcc_state, enum pcep_error_type error_type, - enum pcep_error_value error_value); + enum pcep_error_value error_value, + struct path *trigger_path); static void send_report(struct pcc_state *pcc_state, struct path *path); static void send_comp_request(struct ctrl_state *ctrl_state, struct pcc_state *pcc_state, @@ -541,8 +542,8 @@ void pcep_pcc_send_report(struct ctrl_state *ctrl_state, return; } - PCEP_DEBUG("%s Send report for candidate path %s", pcc_state->tag, - path->name); + PCEP_DEBUG("(%s)%s Send report for candidate path %s", __func__, + pcc_state->tag, path->name); /* ODL and Cisco requires the first reported * LSP to have a DOWN status, the later status changes @@ -555,6 +556,8 @@ void pcep_pcc_send_report(struct ctrl_state *ctrl_state, /* 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)) { + 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); @@ -564,6 +567,19 @@ void pcep_pcc_send_report(struct ctrl_state *ctrl_state, } +void pcep_pcc_send_error(struct ctrl_state *ctrl_state, + struct pcc_state *pcc_state, struct pcep_error *error, + bool sub_type) +{ + + PCEP_DEBUG("(%s) Send error after PcInitiated ", __func__); + + + send_pcep_error(pcc_state, error->error_type, error->error_value, + error->path); + pcep_free_path(error->path); + XFREE(MTYPE_PCEP, error); +} /* ------------ Timeout handler ------------ */ void pcep_pcc_timeout_handler(struct ctrl_state *ctrl_state, @@ -651,6 +667,9 @@ void pcep_pcc_pathd_event_handler(struct ctrl_state *ctrl_state, PCEP_DEBUG("%s Candidate path %s removed", pcc_state->tag, path->name); path->was_removed = true; + /* Removed as response to a PcInitiated 'R'emove*/ + /* RFC 8281 #5.4 LSP Deletion*/ + path->do_remove = path->was_removed; if (pcc_state->caps.is_stateful) send_report(pcc_state, path); return; @@ -1203,14 +1222,113 @@ void handle_pcep_lsp_initiate(struct ctrl_state *ctrl_state, struct pcc_state *pcc_state, struct pcep_message *msg) { - PCEP_DEBUG("%s Received LSP initiate, not supported yet", - pcc_state->tag); + char err[MAX_ERROR_MSG_SIZE] = ""; + struct path *path; + + path = pcep_lib_parse_path(msg); + + if (!pcc_state->pce_opts->config_opts.pce_initiated) { + /* PCE Initiated is not enabled */ + flog_warn(EC_PATH_PCEP_UNSUPPORTED_PCEP_FEATURE, + "Not allowed PCE initiated path received: %s", + format_pcep_message(msg)); + send_pcep_error(pcc_state, PCEP_ERRT_LSP_INSTANTIATE_ERROR, + PCEP_ERRV_UNACCEPTABLE_INSTANTIATE_ERROR, path); + return; + } - /* TODO when we support both PCC and PCE initiated sessions, - * we should first check the session type before - * rejecting this message. */ - send_pcep_error(pcc_state, PCEP_ERRT_INVALID_OPERATION, - PCEP_ERRV_LSP_NOT_PCE_INITIATED); + if (path->do_remove) { + // lookup in nbkey sequential as no endpoint + struct nbkey_map_data *key; + char endpoint[46]; + + frr_each (nbkey_map, &pcc_state->nbkey_map, key) { + ipaddr2str(&key->nbkey.endpoint, endpoint, + sizeof(endpoint)); + flog_warn( + EC_PATH_PCEP_UNSUPPORTED_PCEP_FEATURE, + "FOR_EACH nbkey [color (%d) endpoint (%s)] path [plsp_id (%d)] ", + key->nbkey.color, endpoint, path->plsp_id); + if (path->plsp_id == key->plspid) { + flog_warn( + EC_PATH_PCEP_UNSUPPORTED_PCEP_FEATURE, + "FOR_EACH MATCH nbkey [color (%d) endpoint (%s)] path [plsp_id (%d)] ", + key->nbkey.color, endpoint, + path->plsp_id); + path->nbkey = key->nbkey; + break; + } + } + } else { + if (path->first_hop == NULL /*ero sets first_hop*/) { + /* If the PCC receives a PCInitiate message without an + * ERO and the R flag in the SRP object != zero, then it + * MUST send a PCErr message with Error-type=6 + * (Mandatory Object missing) and Error-value=9 (ERO + * object missing). */ + flog_warn(EC_PATH_PCEP_UNSUPPORTED_PCEP_FEATURE, + "ERO object missing or incomplete : %s", + format_pcep_message(msg)); + send_pcep_error(pcc_state, + PCEP_ERRT_LSP_INSTANTIATE_ERROR, + PCEP_ERRV_INTERNAL_ERROR, path); + return; + } + + if (path->plsp_id != 0) { + /* If the PCC receives a PCInitiate message with a + * non-zero PLSP-ID and the R flag in the SRP object set + * to zero, then it MUST send a PCErr message with + * Error-type=19 (Invalid Operation) and Error-value=8 + * (Non-zero PLSP-ID in the LSP Initiate Request) */ + flog_warn( + EC_PATH_PCEP_PROTOCOL_ERROR, + "PCE initiated path with non-zero PLSP ID: %s", + format_pcep_message(msg)); + send_pcep_error(pcc_state, PCEP_ERRT_INVALID_OPERATION, + PCEP_ERRV_LSP_INIT_NON_ZERO_PLSP_ID, + path); + return; + } + + if (path->name == NULL) { + /* If the PCC receives a PCInitiate message without a + * SYMBOLIC-PATH-NAME TLV, then it MUST send a PCErr + * message with Error-type=10 (Reception of an invalid + * object) and Error-value=8 (SYMBOLIC-PATH-NAME TLV + * missing) */ + flog_warn( + EC_PATH_PCEP_PROTOCOL_ERROR, + "PCE initiated path without symbolic name: %s", + format_pcep_message(msg)); + send_pcep_error( + pcc_state, PCEP_ERRT_RECEPTION_OF_INV_OBJECT, + PCEP_ERRV_SYMBOLIC_PATH_NAME_TLV_MISSING, path); + return; + } + } + + /* TODO: If there is a conflict with the symbolic path name of an + * existing LSP, the PCC MUST send a PCErr message with Error-type=23 + * (Bad Parameter value) and Error-value=1 (SYMBOLIC-PATH-NAME in + * use) */ + + specialize_incoming_path(pcc_state, path); + /* TODO: Validate the PCC address received from the PCE is valid */ + PCEP_DEBUG("%s Received LSP initiate", pcc_state->tag); + PCEP_DEBUG_PATH("%s", format_path(path)); + + if (validate_incoming_path(pcc_state, path, err, sizeof(err))) { + pcep_thread_initiate_path(ctrl_state, pcc_state->id, path); + } else { + /* FIXME: Monitor the amount of errors from the PCE and + * possibly disconnect and blacklist */ + flog_warn(EC_PATH_PCEP_UNSUPPORTED_PCEP_FEATURE, + "Unsupported PCEP protocol feature: %s", err); + pcep_free_path(path); + send_pcep_error(pcc_state, PCEP_ERRT_INVALID_OPERATION, + PCEP_ERRV_LSP_NOT_PCE_INITIATED, path); + } } void handle_pcep_comp_reply(struct ctrl_state *ctrl_state, @@ -1232,7 +1350,7 @@ void handle_pcep_comp_reply(struct ctrl_state *ctrl_state, pcc_state->tag, path->req_id); PCEP_DEBUG_PATH("%s", format_path(path)); send_pcep_error(pcc_state, PCEP_ERRT_UNKNOWN_REQ_REF, - PCEP_ERRV_UNASSIGNED); + PCEP_ERRV_UNASSIGNED, NULL); return; } @@ -1447,13 +1565,14 @@ void send_pcep_message(struct pcc_state *pcc_state, struct pcep_message *msg) void send_pcep_error(struct pcc_state *pcc_state, enum pcep_error_type error_type, - enum pcep_error_value error_value) + enum pcep_error_value error_value, + struct path *trigger_path) { struct pcep_message *msg; PCEP_DEBUG("%s Sending PCEP error type %s (%d) value %s (%d)", pcc_state->tag, pcep_error_type_name(error_type), error_type, pcep_error_value_name(error_type, error_value), error_value); - msg = pcep_lib_format_error(error_type, error_value); + msg = pcep_lib_format_error(error_type, error_value, trigger_path); send_pcep_message(pcc_state, msg); } @@ -1504,7 +1623,8 @@ void specialize_outgoing_path(struct pcc_state *pcc_state, struct path *path) /* Updates the path for the PCC */ void specialize_incoming_path(struct pcc_state *pcc_state, struct path *path) { - set_pcc_address(pcc_state, &path->nbkey, &path->pcc_addr); + if (IS_IPADDR_NONE(&path->pcc_addr)) + set_pcc_address(pcc_state, &path->nbkey, &path->pcc_addr); path->sender = pcc_state->pce_opts->addr; path->pcc_id = pcc_state->id; path->update_origin = SRTE_ORIGIN_PCEP; @@ -1538,7 +1658,7 @@ bool validate_incoming_path(struct pcc_state *pcc_state, struct path *path, } if (err_type != 0) { - send_pcep_error(pcc_state, err_type, err_value); + send_pcep_error(pcc_state, err_type, err_value, NULL); return false; } @@ -1564,7 +1684,6 @@ void send_comp_request(struct ctrl_state *ctrl_state, if (!pcc_state->is_best) { return; } - /* TODO: Add a timer to retry the computation request ? */ specialize_outgoing_path(pcc_state, req->path); @@ -1579,10 +1698,7 @@ void send_comp_request(struct ctrl_state *ctrl_state, send_pcep_message(pcc_state, msg); req->was_sent = true; - /* TODO: Enable this back when the pcep config changes are merged back - */ - // timeout = pcc_state->pce_opts->config_opts.pcep_request_time_seconds; - timeout = 30; + timeout = pcc_state->pce_opts->config_opts.pcep_request_time_seconds; pcep_thread_schedule_timeout(ctrl_state, pcc_state->id, TO_COMPUTATION_REQUEST, timeout, (void *)req, &req->t_retry); @@ -1641,7 +1757,6 @@ void set_pcc_address(struct pcc_state *pcc_state, struct lsp_nb_key *nbkey, } } - /* ------------ Data Structure Helper Functions ------------ */ void lookup_plspid(struct pcc_state *pcc_state, struct path *path) diff --git a/pathd/path_pcep_pcc.h b/pathd/path_pcep_pcc.h index ceac6f3278..9e712baf16 100644 --- a/pathd/path_pcep_pcc.h +++ b/pathd/path_pcep_pcc.h @@ -125,6 +125,9 @@ 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, bool is_stable); +void pcep_pcc_send_error(struct ctrl_state *ctrl_state, + struct pcc_state *pcc_state, struct pcep_error *path, + bool is_stable); int pcep_pcc_multi_pce_sync_path(struct ctrl_state *ctrl_state, int pcc_id, struct pcc_state **pcc_state_list); int pcep_pcc_multi_pce_remove_pcc(struct ctrl_state *ctrl_state, -- 2.39.5