Line data Source code
1 : /* SPDX-License-Identifier: BSD-2-Clause 2 : * Copyright(c) HCL TECHNOLOGIES LTD 3 : * Submitted on behalf of a third-party: Intel Corporation, a 4 : * Delaware corporation, having its principal place of business 5 : * at 2200 Mission College Boulevard, 6 : * Santa Clara, California 95052, USA 7 : */ 8 : 9 : #include "vr_dpdk_n3k_nexthop.h" 10 : #include "offload_entry/vr_dpdk_n3k_offload_entry.h" 11 : #include "vr_dpdk_n3k_flow.h" 12 : 13 : #include <rte_log.h> 14 : #include <rte_malloc.h> 15 : 16 : #include "vr_dpdk.h" 17 : #include "vr_nexthop.h" 18 : #include "vr_packet.h" 19 : 20 : int 21 82 : vr_dpdk_n3k_offload_nexthop_validate(const struct vr_nexthop* nh) 22 : { 23 82 : if (!nh) { 24 0 : return -ENOENT; 25 : } 26 : 27 : /* TODO(n3k): Handle multiple routers */ 28 82 : if (nh->nh_rid != 0) 29 0 : return -ENOTSUP; 30 : 31 82 : if (vr_nexthop_is_being_edited(nh)) { 32 0 : return -EAGAIN; 33 : } 34 : 35 82 : if (nh->nh_type == NH_COMPOSITE && nh->nh_component_cnt == 0) { 36 0 : RTE_LOG(WARNING, VROUTER, "%s(): Composite nh with 0 components, id = %d\n", 37 : __func__, nh->nh_id); 38 : /* This shouldn't usually happen, but check it anyway, so that rest of 39 : * the code can assume non-zero nh_component_count for all composite 40 : * nexthops. It should simplify some logic. */ 41 0 : return -ENOTSUP; 42 : } 43 : 44 82 : return 0; 45 : } 46 : 47 : const struct vr_nexthop * 48 76 : vr_dpdk_n3k_offload_nexthop_get(uint32_t id) 49 : { 50 : /* Note: Using `__vrouter_get_nexthop` instead of `vrouter_get_nexthop`, as 51 : * the returned pointer will be short-lived (we never persist it). The RCU 52 : * mechanism guarantees that the pointer will be valid until the next 53 : * synchronization point. Thus, there's no need to bump the nh refcount via 54 : * the usage of `vrouter_get_nexthop`. */ 55 76 : const struct vr_nexthop *nh = __vrouter_get_nexthop(vrouter_get(0), id); 56 : 57 76 : if (vr_dpdk_n3k_offload_nexthop_validate(nh) != 0) { 58 0 : return NULL; 59 : } 60 : 61 76 : return nh; 62 : } 63 : 64 : /* This needs to be aligned because it could be cast to struct rte_ether_addr */ 65 : const uint8_t vr_n3k_offload_zero_mac[VR_ETHER_ALEN] __attribute__((aligned(2))) = {0,}; 66 : 67 4 : int vr_dpdk_n3k_offload_nexthop_get_cnh_idx( 68 : const struct vr_nexthop *nh, uint16_t idx, uint32_t *nh_idx) 69 : { 70 4 : if (!nh || nh->nh_type != NH_COMPOSITE) 71 0 : return -EINVAL; 72 : 73 4 : if (idx >= nh->nh_component_cnt) { 74 0 : return -EINVAL; 75 : } 76 : 77 4 : struct vr_nexthop *cnh = nh->nh_component_nh[idx].cnh; 78 4 : if (!cnh) { 79 0 : return -ENOENT; 80 : } 81 : 82 4 : *nh_idx = cnh->nh_id; 83 4 : return 0; 84 : } 85 : 86 4 : int vr_dpdk_n3k_offload_nexthop_get_cnh_label( 87 : const struct vr_nexthop *nh, uint16_t idx, uint32_t *label) 88 : { 89 4 : if (!nh || nh->nh_type != NH_COMPOSITE) 90 0 : return -EINVAL; 91 : 92 4 : if (idx >= nh->nh_component_cnt) { 93 0 : return -EINVAL; 94 : } 95 : 96 4 : *label = nh->nh_component_nh[idx].cnh_label; 97 4 : return 0; 98 : }