* Traverses on subtree and retrieves more specific routes * for a given in args ip/depth prefix * last = NULL means the first invocation */
| 165 | * last = NULL means the first invocation |
| 166 | */ |
| 167 | struct rte_rib_node * |
| 168 | rte_rib_get_nxt(struct rte_rib *rib, uint32_t ip, |
| 169 | uint8_t depth, struct rte_rib_node *last, int flag) |
| 170 | { |
| 171 | struct rte_rib_node *tmp, *prev = NULL; |
| 172 | |
| 173 | if (unlikely(rib == NULL || depth > RIB_MAXDEPTH)) { |
| 174 | rte_errno = EINVAL; |
| 175 | return NULL; |
| 176 | } |
| 177 | |
| 178 | if (last == NULL) { |
| 179 | tmp = rib->tree; |
| 180 | while ((tmp) && (tmp->depth < depth)) |
| 181 | tmp = get_nxt_node(tmp, ip); |
| 182 | } else { |
| 183 | tmp = last; |
| 184 | while ((tmp->parent != NULL) && (is_right_node(tmp) || |
| 185 | (tmp->parent->right == NULL))) { |
| 186 | tmp = tmp->parent; |
| 187 | if (is_valid_node(tmp) && |
| 188 | (is_covered(tmp->ip, ip, depth) && |
| 189 | (tmp->depth > depth))) |
| 190 | return tmp; |
| 191 | } |
| 192 | tmp = (tmp->parent) ? tmp->parent->right : NULL; |
| 193 | } |
| 194 | while (tmp) { |
| 195 | if (is_valid_node(tmp) && |
| 196 | (is_covered(tmp->ip, ip, depth) && |
| 197 | (tmp->depth > depth))) { |
| 198 | prev = tmp; |
| 199 | if (flag == RTE_RIB_GET_NXT_COVER) |
| 200 | return prev; |
| 201 | } |
| 202 | tmp = (tmp->left) ? tmp->left : tmp->right; |
| 203 | } |
| 204 | return prev; |
| 205 | } |
| 206 | |
| 207 | void |
| 208 | rte_rib_remove(struct rte_rib *rib, uint32_t ip, uint8_t depth) |