* Lookup an IP into the LPM table. * * @param lpm * LPM object handle * @param ip * IP to be looked up in the LPM table * @param next_hop * Next hop of the most specific rule found for IP (valid on lookup hit only) * @return * -EINVAL for incorrect arguments, -ENOENT on lookup miss, 0 on lookup hit */
| 275 | * -EINVAL for incorrect arguments, -ENOENT on lookup miss, 0 on lookup hit |
| 276 | */ |
| 277 | static inline int |
| 278 | rte_lpm_lookup(const struct rte_lpm *lpm, uint32_t ip, uint32_t *next_hop) |
| 279 | { |
| 280 | unsigned tbl24_index = (ip >> 8); |
| 281 | uint32_t tbl_entry; |
| 282 | const uint32_t *ptbl; |
| 283 | |
| 284 | /* DEBUG: Check user input arguments. */ |
| 285 | RTE_LPM_RETURN_IF_TRUE(((lpm == NULL) || (next_hop == NULL)), -EINVAL); |
| 286 | |
| 287 | /* Copy tbl24 entry */ |
| 288 | ptbl = (const uint32_t *)(&lpm->tbl24[tbl24_index]); |
| 289 | tbl_entry = *ptbl; |
| 290 | |
| 291 | /* Memory ordering is not required in lookup. Because dataflow |
| 292 | * dependency exists, compiler or HW won't be able to re-order |
| 293 | * the operations. |
| 294 | */ |
| 295 | /* Copy tbl8 entry (only if needed) */ |
| 296 | if (unlikely((tbl_entry & RTE_LPM_VALID_EXT_ENTRY_BITMASK) == |
| 297 | RTE_LPM_VALID_EXT_ENTRY_BITMASK)) { |
| 298 | |
| 299 | unsigned tbl8_index = (uint8_t)ip + |
| 300 | (((uint32_t)tbl_entry & 0x00FFFFFF) * |
| 301 | RTE_LPM_TBL8_GROUP_NUM_ENTRIES); |
| 302 | |
| 303 | ptbl = (const uint32_t *)&lpm->tbl8[tbl8_index]; |
| 304 | tbl_entry = *ptbl; |
| 305 | } |
| 306 | |
| 307 | *next_hop = ((uint32_t)tbl_entry & 0x00FFFFFF); |
| 308 | return (tbl_entry & RTE_LPM_LOOKUP_SUCCESS) ? 0 : -ENOENT; |
| 309 | } |
| 310 | |
| 311 | /** |
| 312 | * Lookup multiple IP addresses in an LPM table. This may be implemented as a |
no outgoing calls