| 146 | | CRIT_DROP, /// Node is not interesting, stop recursion here in the graph |
| 147 | | CRIT_RECURS, /// Node is not selected, but we can recurs through it |
| 148 | | CRIT_SELECT, /// Node is selected, and may be recursed down |
| | 152 | TOPO_CRIT_DROP, /// Node is not interesting, stop recursion here in the graph |
| | 153 | TOPO_CRIT_RECURS, /// Node is not selected, but we can recurs through it |
| | 154 | TOPO_CRIT_SELECT, /// Node is selected, and may be recursed down |
| | 155 | }; |
| | 156 | |
| | 157 | enum topo_cmp_e |
| | 158 | { |
| | 159 | TOPO_CMP_LEFT = -1, /// left better than right |
| | 160 | TOPO_CMP_EQ = 0, /// left equals right |
| | 161 | TOPO_CMP_RIGHT = 1, /// right better than left |
| | 162 | }; |
| | 163 | |
| | 164 | struct topo_select_item_s |
| | 165 | { |
| | 166 | const struct topo_node_s *node; |
| | 167 | struct topo_metrics_s metrics; // not a pointer ! |
| 158 | | typedef enum topo_crit_val_e crit_func_t(struct topo_node_s *node, struct topo_metrics_s *metrics, void *priv); |
| 159 | | |
| 160 | | error_t select( |
| 161 | | struct topo_node_s *start, /// Start node |
| 162 | | crit_func_t *crit, void *crit_priv, /// Criterium function, telling whether a node is eligible |
| 163 | | size_t max_nodes, /// Maximal number of nodes to return |
| 164 | | struct topo_node_s **nodes); /// Output nodes. Table must be allocated by caller and be able to contain max_nodes |
| | 176 | typedef enum topo_crit_val_e topo_crit_func_t( |
| | 177 | const struct topo_select_item_s *item, |
| | 178 | const void *priv); |
| | 179 | |
| | 180 | /** |
| | 181 | Sort function |
| | 182 | @param left Node/metrics to compare |
| | 183 | @param right Node/metrics to compare |
| | 184 | @param priv Sort private data |
| | 185 | @returns comparaison result |
| | 186 | */ |
| | 187 | typedef enum topo_cmp_e topo_sort_func_t( |
| | 188 | const struct topo_select_item_s *left, |
| | 189 | const struct topo_select_item_s *right, |
| | 190 | const void *priv); |
| | 191 | |
| | 192 | error_t topo_select( |
| | 193 | const struct topo_node_s *start, /// Start node |
| | 194 | topo_crit_func_t *crit, const void *crit_priv, /// Criterium function, telling whether a node is eligible |
| | 195 | topo_sort_func_t *sort, const void *sort_priv, /// Sorting function, telling order of nodes |
| | 196 | size_t max_items, /// Maximal number of nodes to return |
| | 197 | struct topo_select_item_s *items); /// Output nodes+metrics. Table must be allocated by caller and be able to contain @tt max_items |
| 170 | | error_t next( |
| 171 | | struct topo_node_s *node, /// node of our model where we are coming from |
| 172 | | struct topo_port_s *input, /// input in node. May be NULL on start node |
| 173 | | const struct topo_addr_s *dest, /// destination address for the current address space |
| 174 | | struct topo_metrics_s *metrics, /// Metrics to update on the go |
| 175 | | struct topo_port_s **output_peer); /// Input port of the next hop |
| 176 | | |
| 177 | | error_t select_next( |
| 178 | | struct topo_node_s *node, /// node of our model where we are coming from |
| 179 | | struct topo_port_s *input, /// input in node. May be NULL on start node |
| 180 | | struct topo_metrics_s *metrics, /// Metrics to update on the go |
| 181 | | struct topo_port_s **output_peer); /// Input port of the next hop |
| 182 | | }}} |
| 183 | | |
| 184 | | |
| 185 | | = Open questions = |
| 186 | | |
| 187 | | * Are edges of graph internal to node's private data or are explicit ? |
| 188 | | * How to handle multiple output connexions of the same addressing type ? |
| 189 | | * Maybe add an "output" index with source node ? (after source node, there should be no hesitation possible) |
| 190 | | |
| | 203 | #!c |
| | 204 | /** |
| | 205 | Initialize a topology node. |
| | 206 | */ |
| | 207 | typedef void topo_model_init_func_t(struct topo_node_s *node, const void *param); |
| | 208 | |
| | 209 | /** |
| | 210 | Destroy a topology node. Reclaim all associated memory |
| | 211 | */ |
| | 212 | typedef void topo_model_cleanup_func_t(struct topo_node_s *node); |
| | 213 | |
| | 214 | /** |
| | 215 | Compute routing and cost from this node to the next hop, routing |
| | 216 | towards a given destination |
| | 217 | |
| | 218 | @param node Node of our model where we are coming from |
| | 219 | @param input Input port in node. May be NULL on start node |
| | 220 | @param dest Destination address for the current address space |
| | 221 | @param metrics Metrics to update on the go |
| | 222 | @param peer_input Input port of the next hop |
| | 223 | */ |
| | 224 | typedef error_t topo_model_journey_next_func_t( |
| | 225 | const struct topo_node_s *node, |
| | 226 | const struct topo_port_s *input, |
| | 227 | const struct topo_addr_s *dest, |
| | 228 | struct topo_metrics_s *metrics, |
| | 229 | struct topo_port_s *peer_input); |
| | 230 | |
| | 231 | /** |
| | 232 | Explore the topology graph. Each call to this function must return next |
| | 233 | valid port. |
| | 234 | |
| | 235 | @param node Current node |
| | 236 | @param input Port where we came from, exploration should not "go back" to this edge. May be NULL on recursion start |
| | 237 | @param metrics Metrics up to this node |
| | 238 | @param item Returned item for next recursion |
| | 239 | @param state Pointer to a void* where select_next can store its internal state. |
| | 240 | |
| | 241 | @tt *state is @tt NULL on first call for each node. |
| | 242 | |
| | 243 | Successive calls to select_next for a given node in a given exploration use the same @tt state value. |
| | 244 | |
| | 245 | @note As there is no warning for end of iteration, there is no way of calling @tt free(), so @tt *state should be a pointer to preallocated internal data. |
| | 246 | */ |
| | 247 | typedef error_t topo_model_select_next_func_t( |
| | 248 | const struct topo_node_s *node, |
| | 249 | const struct topo_port_s *input, |
| | 250 | const struct topo_metrics_s *input_metrics, |
| | 251 | struct topo_select_item_s *item, |
| | 252 | void **state); |
| | 253 | }}} |
| | 254 | |
| | 255 | = topo_model_s struct = |
| | 256 | |
| | 257 | {{{ |
| | 258 | #!c |
| | 259 | struct topo_model_s |
| | 260 | { |
| | 261 | topo_model_init_func_t *init; |
| | 262 | topo_model_cleanup_func_t *cleanup; |
| | 263 | topo_model_journey_next_func_t *journey_next; |
| | 264 | topo_model_select_next_func_t *select_next; |
| | 265 | }; |
| | 266 | }}} |