summaryrefslogtreecommitdiff
path: root/pathd/path_pcep_lib.c
diff options
context:
space:
mode:
authorJavier Garcia <javier.garcia@voltanet.io>2021-05-21 09:15:52 +0200
committerJavier Garcia <javier.garcia@voltanet.io>2021-06-22 12:04:03 +0200
commit56634922390ff08d2ae06ecb0c32f94c07028561 (patch)
tree2c1fb1080e2b0dbd5397c8bbfba2d668d9fb116a /pathd/path_pcep_lib.c
parent5fe7f5b4798c548dbbc62865c08ee4be4d67e119 (diff)
pathd: Handle PCInitiated messages, thread controller. (2/4)
Co-authored-by: Javier Garcia <javier.garcia@voltanet.io> Signed-off-by: Sebastien Merle <sebastien@netdef.org> Signed-off-by: Javier Garcia <javier.garcia@voltanet.io>
Diffstat (limited to 'pathd/path_pcep_lib.c')
-rw-r--r--pathd/path_pcep_lib.c105
1 files changed, 101 insertions, 4 deletions
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;