* Find range of tbl8 cells occupied by a rule */
| 1179 | * Find range of tbl8 cells occupied by a rule |
| 1180 | */ |
| 1181 | static void |
| 1182 | rule_find_range(struct rte_lpm6 *lpm, const uint8_t *ip, uint8_t depth, |
| 1183 | struct rte_lpm6_tbl_entry **from, |
| 1184 | struct rte_lpm6_tbl_entry **to, |
| 1185 | uint32_t *out_tbl_ind) |
| 1186 | { |
| 1187 | uint32_t ind; |
| 1188 | uint32_t first_3bytes = (uint32_t)ip[0] << 16 | ip[1] << 8 | ip[2]; |
| 1189 | |
| 1190 | if (depth <= 24) { |
| 1191 | /* rule is within the top level */ |
| 1192 | ind = first_3bytes; |
| 1193 | *from = &lpm->tbl24[ind]; |
| 1194 | ind += (1 << (24 - depth)) - 1; |
| 1195 | *to = &lpm->tbl24[ind]; |
| 1196 | *out_tbl_ind = TBL24_IND; |
| 1197 | } else { |
| 1198 | /* top level entry */ |
| 1199 | struct rte_lpm6_tbl_entry *tbl = &lpm->tbl24[first_3bytes]; |
| 1200 | assert(tbl->ext_entry == 1); |
| 1201 | /* first tbl8 */ |
| 1202 | uint32_t tbl_ind = tbl->lpm6_tbl8_gindex; |
| 1203 | tbl = &lpm->tbl8[tbl_ind * |
| 1204 | RTE_LPM6_TBL8_GROUP_NUM_ENTRIES]; |
| 1205 | /* current ip byte, the top level is already behind */ |
| 1206 | uint8_t byte = 3; |
| 1207 | /* minus top level */ |
| 1208 | depth -= 24; |
| 1209 | |
| 1210 | /* iterate through levels (tbl8s) |
| 1211 | * until we reach the last one |
| 1212 | */ |
| 1213 | while (depth > 8) { |
| 1214 | tbl += ip[byte]; |
| 1215 | assert(tbl->ext_entry == 1); |
| 1216 | /* go to the next level/tbl8 */ |
| 1217 | tbl_ind = tbl->lpm6_tbl8_gindex; |
| 1218 | tbl = &lpm->tbl8[tbl_ind * |
| 1219 | RTE_LPM6_TBL8_GROUP_NUM_ENTRIES]; |
| 1220 | byte += 1; |
| 1221 | depth -= 8; |
| 1222 | } |
| 1223 | |
| 1224 | /* last level/tbl8 */ |
| 1225 | ind = ip[byte] & depth_to_mask_1b(depth); |
| 1226 | *from = &tbl[ind]; |
| 1227 | ind += (1 << (8 - depth)) - 1; |
| 1228 | *to = &tbl[ind]; |
| 1229 | *out_tbl_ind = tbl_ind; |
| 1230 | } |
| 1231 | } |
| 1232 | |
| 1233 | /* |
| 1234 | * Remove a table from the LPM tree |
no test coverage detected