* Add a route */
| 849 | * Add a route |
| 850 | */ |
| 851 | int |
| 852 | rte_lpm6_add(struct rte_lpm6 *lpm, const uint8_t *ip, uint8_t depth, |
| 853 | uint32_t next_hop) |
| 854 | { |
| 855 | struct rte_lpm6_tbl_entry *tbl; |
| 856 | struct rte_lpm6_tbl_entry *tbl_next = NULL; |
| 857 | /* init to avoid compiler warning */ |
| 858 | uint32_t tbl_next_num = 123456; |
| 859 | int status; |
| 860 | uint8_t masked_ip[RTE_LPM6_IPV6_ADDR_SIZE]; |
| 861 | int i; |
| 862 | |
| 863 | /* Check user arguments. */ |
| 864 | if ((lpm == NULL) || (depth < 1) || (depth > RTE_LPM6_MAX_DEPTH)) |
| 865 | return -EINVAL; |
| 866 | |
| 867 | /* Copy the IP and mask it to avoid modifying user's input data. */ |
| 868 | ip6_copy_addr(masked_ip, ip); |
| 869 | ip6_mask_addr(masked_ip, depth); |
| 870 | |
| 871 | /* Simulate adding a new route */ |
| 872 | int ret = simulate_add(lpm, masked_ip, depth); |
| 873 | if (ret < 0) |
| 874 | return ret; |
| 875 | |
| 876 | /* Add the rule to the rule table. */ |
| 877 | int is_new_rule = rule_add(lpm, masked_ip, depth, next_hop); |
| 878 | /* If there is no space available for new rule return error. */ |
| 879 | if (is_new_rule < 0) |
| 880 | return is_new_rule; |
| 881 | |
| 882 | /* Inspect the first three bytes through tbl24 on the first step. */ |
| 883 | tbl = lpm->tbl24; |
| 884 | status = add_step(lpm, tbl, TBL24_IND, &tbl_next, &tbl_next_num, |
| 885 | masked_ip, ADD_FIRST_BYTE, 1, depth, next_hop, |
| 886 | is_new_rule); |
| 887 | assert(status >= 0); |
| 888 | |
| 889 | /* |
| 890 | * Inspect one by one the rest of the bytes until |
| 891 | * the process is completed. |
| 892 | */ |
| 893 | for (i = ADD_FIRST_BYTE; i < RTE_LPM6_IPV6_ADDR_SIZE && status == 1; i++) { |
| 894 | tbl = tbl_next; |
| 895 | status = add_step(lpm, tbl, tbl_next_num, &tbl_next, |
| 896 | &tbl_next_num, masked_ip, 1, (uint8_t)(i + 1), |
| 897 | depth, next_hop, is_new_rule); |
| 898 | assert(status >= 0); |
| 899 | } |
| 900 | |
| 901 | return status; |
| 902 | } |
| 903 | |
| 904 | /* |
| 905 | * Takes a pointer to a table entry and inspect one level. |