| 282 | } |
| 283 | |
| 284 | struct rte_rib6_node * |
| 285 | rte_rib6_insert(struct rte_rib6 *rib, |
| 286 | const uint8_t ip[RTE_RIB6_IPV6_ADDR_SIZE], uint8_t depth) |
| 287 | { |
| 288 | struct rte_rib6_node **tmp; |
| 289 | struct rte_rib6_node *prev = NULL; |
| 290 | struct rte_rib6_node *new_node = NULL; |
| 291 | struct rte_rib6_node *common_node = NULL; |
| 292 | uint8_t common_prefix[RTE_RIB6_IPV6_ADDR_SIZE]; |
| 293 | uint8_t tmp_ip[RTE_RIB6_IPV6_ADDR_SIZE]; |
| 294 | int i, d; |
| 295 | uint8_t common_depth, ip_xor; |
| 296 | |
| 297 | if (unlikely((rib == NULL || ip == NULL || depth > RIB6_MAXDEPTH))) { |
| 298 | rte_errno = EINVAL; |
| 299 | return NULL; |
| 300 | } |
| 301 | |
| 302 | tmp = &rib->tree; |
| 303 | |
| 304 | for (i = 0; i < RTE_RIB6_IPV6_ADDR_SIZE; i++) |
| 305 | tmp_ip[i] = ip[i] & get_msk_part(depth, i); |
| 306 | |
| 307 | new_node = rte_rib6_lookup_exact(rib, tmp_ip, depth); |
| 308 | if (new_node != NULL) { |
| 309 | rte_errno = EEXIST; |
| 310 | return NULL; |
| 311 | } |
| 312 | |
| 313 | new_node = node_alloc(rib); |
| 314 | if (new_node == NULL) { |
| 315 | rte_errno = ENOMEM; |
| 316 | return NULL; |
| 317 | } |
| 318 | new_node->left = NULL; |
| 319 | new_node->right = NULL; |
| 320 | new_node->parent = NULL; |
| 321 | rte_rib6_copy_addr(new_node->ip, tmp_ip); |
| 322 | new_node->depth = depth; |
| 323 | new_node->flag = RTE_RIB_VALID_NODE; |
| 324 | |
| 325 | /* traverse down the tree to find matching node or closest matching */ |
| 326 | while (1) { |
| 327 | /* insert as the last node in the branch */ |
| 328 | if (*tmp == NULL) { |
| 329 | *tmp = new_node; |
| 330 | new_node->parent = prev; |
| 331 | ++rib->cur_routes; |
| 332 | return *tmp; |
| 333 | } |
| 334 | /* |
| 335 | * Intermediate node found. |
| 336 | * Previous rte_rib6_lookup_exact() returned NULL |
| 337 | * but node with proper search criteria is found. |
| 338 | * Validate intermediate node and return. |
| 339 | */ |
| 340 | if (rte_rib6_is_equal(tmp_ip, (*tmp)->ip) && |
| 341 | (depth == (*tmp)->depth)) { |