* Remove a table from the LPM tree */
| 1234 | * Remove a table from the LPM tree |
| 1235 | */ |
| 1236 | static void |
| 1237 | remove_tbl(struct rte_lpm6 *lpm, struct rte_lpm_tbl8_hdr *tbl_hdr, |
| 1238 | uint32_t tbl_ind, struct rte_lpm6_rule *lsp_rule) |
| 1239 | { |
| 1240 | struct rte_lpm6_tbl_entry *owner_entry; |
| 1241 | |
| 1242 | if (tbl_hdr->owner_tbl_ind == TBL24_IND) |
| 1243 | owner_entry = &lpm->tbl24[tbl_hdr->owner_entry_ind]; |
| 1244 | else { |
| 1245 | uint32_t owner_tbl_ind = tbl_hdr->owner_tbl_ind; |
| 1246 | owner_entry = &lpm->tbl8[ |
| 1247 | owner_tbl_ind * RTE_LPM6_TBL8_GROUP_NUM_ENTRIES + |
| 1248 | tbl_hdr->owner_entry_ind]; |
| 1249 | |
| 1250 | struct rte_lpm_tbl8_hdr *owner_tbl_hdr = |
| 1251 | &lpm->tbl8_hdrs[owner_tbl_ind]; |
| 1252 | if (--owner_tbl_hdr->ref_cnt == 0) |
| 1253 | remove_tbl(lpm, owner_tbl_hdr, owner_tbl_ind, lsp_rule); |
| 1254 | } |
| 1255 | |
| 1256 | assert(owner_entry->ext_entry == 1); |
| 1257 | |
| 1258 | /* unlink the table */ |
| 1259 | if (lsp_rule != NULL) { |
| 1260 | struct rte_lpm6_tbl_entry new_tbl_entry = { |
| 1261 | .next_hop = lsp_rule->next_hop, |
| 1262 | .depth = lsp_rule->depth, |
| 1263 | .valid = VALID, |
| 1264 | .valid_group = VALID, |
| 1265 | .ext_entry = 0 |
| 1266 | }; |
| 1267 | |
| 1268 | *owner_entry = new_tbl_entry; |
| 1269 | } else { |
| 1270 | struct rte_lpm6_tbl_entry new_tbl_entry = { |
| 1271 | .next_hop = 0, |
| 1272 | .depth = 0, |
| 1273 | .valid = INVALID, |
| 1274 | .valid_group = INVALID, |
| 1275 | .ext_entry = 0 |
| 1276 | }; |
| 1277 | |
| 1278 | *owner_entry = new_tbl_entry; |
| 1279 | } |
| 1280 | |
| 1281 | /* return the table to the pool */ |
| 1282 | tbl8_put(lpm, tbl_ind); |
| 1283 | } |
| 1284 | |
| 1285 | /* |
| 1286 | * Deletes a rule |
no test coverage detected