1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2020 NetDEF, Inc.
*/
#ifndef _PATH_PCEP_CONTROLLER_H_
#define _PATH_PCEP_CONTROLLER_H_
#include "pathd/path_pcep.h"
struct ctrl_state;
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,
};
typedef int (*pcep_main_event_handler_t)(enum pcep_main_event_type type,
int pcc_id, void *payload);
typedef void (*pcep_refine_callback_t)(struct ctrl_state *ctrl_state,
struct pcc_state *pcc_state,
struct path *path, void *payload);
enum pcep_pathd_event_type {
PCEP_PATH_UNDEFINED = 0,
PCEP_PATH_CREATED,
PCEP_PATH_UPDATED,
PCEP_PATH_REMOVED
};
struct ctrl_state {
struct event_loop *main;
struct event_loop *self;
pcep_main_event_handler_t main_event_handler;
struct pcc_opts *pcc_opts;
int pcc_count;
int pcc_last_id;
struct pcc_state *pcc[MAX_PCC];
};
/* Timer handling data structures */
enum pcep_ctrl_timeout_type { TO_UNDEFINED, TO_COMPUTATION_REQUEST, TO_MAX };
enum pcep_ctrl_timer_type {
TM_UNDEFINED,
TM_RECONNECT_PCC,
TM_PCEPLIB_TIMER,
TM_TIMEOUT,
TM_CALCULATE_BEST_PCE,
TM_SESSION_TIMEOUT_PCC,
TM_MAX
};
struct pcep_ctrl_timer_data {
struct ctrl_state *ctrl_state;
enum pcep_ctrl_timer_type timer_type;
enum pcep_ctrl_timeout_type timeout_type;
int pcc_id;
void *payload;
};
/* Socket handling data structures */
enum pcep_ctrl_socket_type { SOCK_PCEPLIB = 1 };
struct pcep_ctrl_socket_data {
struct ctrl_state *ctrl_state;
enum pcep_ctrl_socket_type type;
bool is_read;
int fd;
int pcc_id;
void *payload;
};
typedef void (*pcep_ctrl_thread_callback)(struct event *);
/* PCC connection information, populated in a thread-safe
* manner with pcep_ctrl_get_pcc_info() */
struct pcep_pcc_info {
struct ctrl_state *ctrl_state; /* will be NULL when returned */
char pce_name[64];
int pcc_id;
struct ipaddr pcc_addr;
uint16_t pcc_port;
int status;
short msd;
uint32_t next_reqid;
uint32_t next_plspid;
bool is_best_multi_pce;
bool previous_best;
uint8_t precedence;
};
/* Functions called from the main thread */
int pcep_ctrl_initialize(struct event_loop *main_thread,
struct frr_pthread **fpt,
pcep_main_event_handler_t event_handler);
int pcep_ctrl_finalize(struct frr_pthread **fpt);
int pcep_ctrl_update_pcc_options(struct frr_pthread *fpt,
struct pcc_opts *opts);
int pcep_ctrl_update_pce_options(struct frr_pthread *fpt,
struct pce_opts *opts);
int pcep_ctrl_remove_pcc(struct frr_pthread *fpt, struct pce_opts *pce_opts);
int pcep_ctrl_reset_pcc_session(struct frr_pthread *fpt, char *pce_name);
int pcep_ctrl_pathd_event(struct frr_pthread *fpt,
enum pcep_pathd_event_type type, struct path *path);
int pcep_ctrl_sync_path(struct frr_pthread *fpt, int pcc_id, struct path *path);
int pcep_ctrl_sync_done(struct frr_pthread *fpt, int pcc_id);
struct counters_group *pcep_ctrl_get_counters(struct frr_pthread *fpt,
int pcc_id);
pcep_session *pcep_ctrl_get_pcep_session(struct frr_pthread *fpt, int pcc_id);
struct pcep_pcc_info *pcep_ctrl_get_pcc_info(struct frr_pthread *fpt,
const char *pce_name);
/* Asynchronously send a report. The caller is giving away the path structure,
* it shouldn't be allocated on the stack. If `pcc_id` is `0` the report is
* sent by all PCCs. The parameter is_stable is used to hint whether the status
* will soon change, this is used to ensure all report updates are sent even
* when missing status update events */
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 event **thread);
void pcep_thread_schedule_reconnect(struct ctrl_state *ctrl_state, int pcc_id,
int retry_count, struct event **thread);
void pcep_thread_schedule_timeout(struct ctrl_state *ctrl_state, int pcc_id,
enum pcep_ctrl_timeout_type type,
uint32_t delay, void *param,
struct event **thread);
void pcep_thread_schedule_session_timeout(struct ctrl_state *ctrl_state,
int pcc_id, int delay,
struct event **thread);
void pcep_thread_remove_candidate_path_segments(struct ctrl_state *ctrl_state,
struct pcc_state *pcc_state);
void pcep_thread_schedule_sync_best_pce(struct ctrl_state *ctrl_state,
int pcc_id, int delay,
struct event **thread);
void pcep_thread_schedule_pceplib_timer(struct ctrl_state *ctrl_state,
int delay, void *payload,
struct event **thread,
pcep_ctrl_thread_callback cb);
int pcep_thread_socket_read(void *fpt, void **thread, int fd, void *payload,
pcep_ctrl_thread_callback cb);
int pcep_thread_socket_write(void *fpt, void **thread, int fd, void *payload,
pcep_ctrl_thread_callback cb);
int pcep_thread_send_ctrl_event(void *fpt, void *payload,
pcep_ctrl_thread_callback cb);
void pcep_thread_pcep_event(struct event *thread);
int pcep_thread_pcc_count(struct ctrl_state *ctrl_state);
/* Called by the PCC to refine a path in the main thread */
int pcep_thread_refine_path(struct ctrl_state *ctrl_state, int pcc_id,
pcep_refine_callback_t cb, struct path *path,
void *payload);
#endif // _PATH_PCEP_CONTROLLER_H_
|