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 : #ifndef __VR_DPDK_N3K_NEXTHOP_H__ 10 : #define __VR_DPDK_N3K_NEXTHOP_H__ 11 : 12 : #include <rte_byteorder.h> 13 : #include "vr_defs.h" 14 : #include "vr_nexthop.h" 15 : #include "vr_packet.h" 16 : 17 : /* validates whether nexthop satisfies all the preconditions required by the 18 : * n3k offload module. 19 : * 20 : * @return 21 : * 0 on success 22 : * -EAGAIN on detected concurrent modification 23 : * -ENOENT on nh==NULL 24 : * -ENOTSUP on other conditions 25 : */ 26 : int vr_dpdk_n3k_offload_nexthop_validate(const struct vr_nexthop* nh); 27 : 28 : /* Note: Do not persist the returned pointer across the callback boundary. 29 : * 30 : * Returns NULL if the nexthop doesn't exists or fails validation (see 31 : * vr_dpdk_n3k_offload_nexthop_validate) */ 32 : const struct vr_nexthop * vr_dpdk_n3k_offload_nexthop_get(uint32_t id); 33 : 34 : extern const uint8_t vr_n3k_offload_zero_mac[VR_ETHER_ALEN]; 35 : 36 197 : static const uint8_t get_first_valid_ecmp_index(const struct vr_nexthop* nh) { 37 : int i; 38 788 : for (i = 0; i < VR_MAX_PHY_INF; ++i) { 39 591 : if (!nh->nh_encap_valid[i]) 40 591 : continue; 41 0 : return i; 42 : } 43 197 : return 0; 44 : } 45 : 46 197 : static inline const uint8_t nh_validate_underlay_index(const struct vr_nexthop* nh, int8_t underlay_ecmp_index) { 47 197 : if( !(nh->nh_flags & NH_FLAG_TUNNEL_UNDERLAY_ECMP) ) { 48 197 : return get_first_valid_ecmp_index(nh); 49 : } 50 : 51 0 : if( underlay_ecmp_index < 0 ) { 52 0 : return get_first_valid_ecmp_index(nh); 53 : } 54 : 55 0 : if( underlay_ecmp_index >= VR_MAX_PHY_INF ) { 56 0 : return get_first_valid_ecmp_index(nh); 57 : } 58 : 59 0 : if( !nh->nh_encap_valid[underlay_ecmp_index] ) { 60 0 : return get_first_valid_ecmp_index(nh); 61 : } 62 : 63 0 : return underlay_ecmp_index; 64 : } 65 : 66 66 : static inline const uint8_t *nh_src_mac(const struct vr_nexthop* nh, int8_t underlay_ecmp_index) { 67 66 : uint8_t loc_ecmp_index = nh_validate_underlay_index(nh, underlay_ecmp_index); 68 : 69 66 : if (nh->nh_data_size >= ((2 * VR_ETHER_ALEN)+(loc_ecmp_index*VR_ETHER_HLEN))) { 70 66 : struct vr_eth *eth = (struct vr_eth *)(nh->nh_data + (loc_ecmp_index*(VR_ETHER_HLEN))); 71 66 : return eth->eth_smac; 72 : } else { 73 0 : return vr_n3k_offload_zero_mac; 74 : } 75 : } 76 : 77 69 : static inline const uint8_t *nh_dst_mac(const struct vr_nexthop* nh, int8_t underlay_ecmp_index) { 78 69 : uint8_t loc_ecmp_index = nh_validate_underlay_index(nh, underlay_ecmp_index); 79 : 80 69 : if (nh->nh_data_size >= ((2 * VR_ETHER_ALEN)+(loc_ecmp_index*VR_ETHER_HLEN))) { 81 69 : struct vr_eth *eth = (struct vr_eth *)(nh->nh_data + (loc_ecmp_index*(VR_ETHER_HLEN))); 82 69 : return eth->eth_dmac; 83 : } else { 84 0 : return vr_n3k_offload_zero_mac; 85 : } 86 : } 87 : 88 60 : static inline rte_be32_t nh_tunnel_src_ip(const struct vr_nexthop* nh) { 89 : _Static_assert( 90 : offsetof(struct vr_nexthop, nh_udp_tun_sip) == 91 : offsetof(struct vr_nexthop, nh_vxlan_tun_sip) && 92 : offsetof(struct vr_nexthop, nh_gre_tun_sip) == 93 : offsetof(struct vr_nexthop, nh_vxlan_tun_sip), 94 : "nh_vxlan_tun_sip can be used regardless of tunnel type"); 95 60 : return nh->nh_type == NH_TUNNEL ? nh->nh_vxlan_tun_sip : 0; 96 : } 97 : 98 60 : static inline rte_be32_t nh_tunnel_dst_ip(const struct vr_nexthop* nh) { 99 : _Static_assert( 100 : offsetof(struct vr_nexthop, nh_udp_tun_dip) == 101 : offsetof(struct vr_nexthop, nh_vxlan_tun_dip) && 102 : offsetof(struct vr_nexthop, nh_gre_tun_dip) == 103 : offsetof(struct vr_nexthop, nh_vxlan_tun_dip), 104 : "nh_vxlan_tun_dip can be used regardless of tunnel type"); 105 60 : return nh->nh_type == NH_TUNNEL ? nh->nh_vxlan_tun_dip : 0; 106 : } 107 : 108 62 : static inline uint16_t nh_interface_id(const struct vr_nexthop* nh, int8_t underlay_ecmp_index) { 109 62 : uint8_t loc_ecmp_index = nh_validate_underlay_index(nh, underlay_ecmp_index); 110 : 111 62 : return nh->nh_dev_arr[loc_ecmp_index] != NULL ? nh->nh_dev_arr[loc_ecmp_index]->vif_idx : -1; 112 : } 113 : 114 : int vr_dpdk_n3k_offload_nexthop_get_cnh_idx( 115 : const struct vr_nexthop *nh, uint16_t idx, uint32_t *nh_idx); 116 : int vr_dpdk_n3k_offload_nexthop_get_cnh_label( 117 : const struct vr_nexthop *nh, uint16_t idx, uint32_t *label); 118 : 119 : #endif // __VR_DPDK_N3K_NEXTHOP_H__