/* // Copyright (c) 2017 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. */ /** * @file * L3fwd lpm6 header file is for IPv6 specific declarations */ #ifndef L3FWD_LPM6_H #define L3FWD_LPM6_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "l3fwd_common.h" #include "l3fwd_lpm4.h" #include "interface.h" /** * Define all RTE MBUF offset size */ #define MBUF_HDR_ROOM 256 /**< MBUF HEADER ROOM OFFSET */ /* IPv6 */ #define IP_HDR_SIZE_IPV6 40 /**< IPv6 HEADER OFFSET */ #define IP_HDR_SRC_ADR_OFST_IPV6 8 /**< IPv6 HEADER SRC IP ADDRESS OFFSET */ #define IP_HDR_DST_ADR_OFST_IPV6 24 /**< IPv6 HEADER DST IP ADDRESS OFFSET */ /* IPV6 Rules and Tables8s */ #define IPV6_L3FWD_LPM_MAX_RULES 1024 /**< Number of LPM6 Rules*/ #define IPV6_L3FWD_LPM_NUMBER_TBL8S (1 << 16) /**< Number of Table 8 for LPM6 */ #define MAX_FIB_PATHS 8 /**< MAX FIB PATH, If ECMP feature is enabled */ /** * A structure used to define the routing information for IPv6 * This structure is used as input parameters for route ADD */ struct ipv6_routing_info { uint8_t dst_ipv6[RTE_LPM_IPV6_ADDR_SIZE]; /**< DST IPv6 Address */ uint8_t depth; /**< Depth */ uint32_t metric; /**< Metrics */ uint32_t fib_nh_size; /**< num of fib paths, greater than if Multipath(ECMP) feature is supported*/ uint8_t nh_ipv6[MAX_FIB_PATHS][RTE_LPM_IPV6_ADDR_SIZE]; /**< NextHop IP Address */ uint8_t out_port[MAX_FIB_PATHS]; /**< OUTGOING PORT */ } __rte_cache_aligned; /**< RTE CACHE ALIGNED */ /** * A structure used to define the fib path for Destination IPv6 Address * This fib path is shared accross different fib_info. */ struct ipv6_fib_path { uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE]; /**< Next hop IP address (only valid for remote routes) */ uint32_t refcount; /**< Refcount, greater then 1 if multiple fib_info has same fib_path*/ uint8_t out_port; /**< Output port */ struct l2_adj_ipv6_entry *l2_adj_ipv6_ptr;/**< Address of the L2 ADJ table entry */ } __rte_cache_aligned; /**< RTE CACHE ALIGNED */ /** * A structure used to define the fib info (Route info) * This fib info structure can have multiple fib paths. */ struct ipv6_fib_info { uint8_t dst_ipv6[RTE_LPM_IPV6_ADDR_SIZE]; /**< DST IPv6 Address */ uint8_t depth; /**< Depth */ uint32_t metric; /**< Metric */ uint32_t fib_nh_size; /**< num of fib paths, greater than if Multipath(ECMP) feature is supported*/ struct ipv6_fib_path *path[MAX_FIB_PATHS]; /**< Array of pointers to the fib_path */ } __rte_cache_aligned; /**< RTE CACHE ALIGNED */ /** * A structure used to define the L2 Adjacency table */ struct l2_adj_ipv6_entry { struct ether_addr eth_addr; /**< Ether address */ uint8_t out_port_id; /**< Outgoing port */ uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE]; /**< Next hop IP address (only valid for remote routes) */ uint32_t refcount; /**< Refcount, greater then 1 if multiple fib_path has same L2_adj_entry*/ uint8_t l2_string[256]; /**< L2 string, to rewrite the packet before transmission */ l2_phy_interface_t *phy_port; /**< Address of the L2 physical interface structure */ uint8_t flags; /**< flags for marking this entry as resolved or unresolved. */ } __rte_cache_aligned; /**< RTE CACHE ALIGNED */ /** * A structure used to define the L2 Adjacency table */ struct l2_adj_key_ipv6 { /*128 Bit of IPv6 Address */ /*<48bit Network> <16bit Subnet> <64bit Interface> */ uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE]; /**< Next hop IPv6 address */ uint8_t out_port_id; /**< Outgoing port */ uint8_t filler1; /**< Filler 1, for better hash key */ uint8_t filler2; /**< Filler2, for better hash key*/ uint8_t filler3; /**< Filler3, for better hash Key */ }; /** * A structure used to define the fib path key for hash table */ struct fib_path_key_ipv6 { /*128 Bit of IPv6 Address */ /*<48bit Network> <16bit Subnet> <64bit Interface> */ uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE]; /**< Next hop IPv6 address */ uint8_t out_port; /**< Outgoing port */ uint8_t filler1; /**< Filler 1, for better hash key */ uint8_t filler2; /**< Filler2, for better hash key*/ uint8_t filler3; /**< Filler3, for better hash Key */ }; struct ipv6_protocol_type { uint8_t protocol_type; /**< Protocol Type */ void (*func) (struct rte_mbuf **, uint16_t, uint64_t, l2_phy_interface_t *); } __rte_cache_aligned; /* Function Declarations */ /** * To creare LPM6 table, Cuckoo hash table for fib_path and l2_adj_entry tables * @return * 0 for failure, 1 for success */ int lpm6_init(void); /** * To add a route in LPM6 table by populating fib_path and L2 Adjacency. * @param data * To add the route based on ipv6_routing_info stucture. * @return * 0 for failure, 1 for success */ int lpm6_table_route_add(struct ipv6_routing_info *data); /** * To Delete the IP route and corresponding fib_path and L2 Adjacency entries. * @param dst_ipv6 * Destionation IPv6 for which the route need to deleted * @param depth * netmask for the Destination IP * @return * 0 for failure, 1 for success */ int lpm6_table_route_delete(uint8_t dst_ipv6[RTE_LPM_IPV6_ADDR_SIZE], uint8_t depth); /** * To perform a LPM6 table lookup * @param pkts_burst * Burst of packets that needs to be lookup in LPM6 table * @param nb_pkts * Number of valid L3 packets * @param pkts_mask * number of valid pkts mask that needs to be lookup in LPM6 table * @return * 0 for failure, 1 for success */ int lpm6_table_lookup(struct rte_mbuf **pkts_burst, uint16_t nb_pkts, uint64_t pkts_mask, l2_phy_interface_t *port_ptr[RTE_PORT_IN_BURST_SIZE_MAX], uint64_t *hit_mask); /** * To forward the valid L3 packets for LMP6 table lookup and forward ICMP Pkts to ICMP module * @param m * packet burst of type rte_mbuf * @param nb_pkts * Number of valid L3 packets * @param valid_pkts_mask * Valid IPv6 packets mask that needs to be processed * @param in_port * IPv6 Pkt received form the input port. * @return * None */ void l3fwd_rx_ipv6_packets(struct rte_mbuf **m, uint16_t nb_pkts, uint64_t valid_pkts_mask, l2_phy_interface_t *in_port); /** * To populate the fib_path for the nexthop IPv6 and outgoing port * @param nh_ipv6 * NextHop Ip Address for which L2_adj_entry needs to be populated * @param out_port * outgong port ID * @return * NULL if lookup fails, Address of the type ipv6_fib_path if lookup success */ struct ipv6_fib_path *populate_ipv6_fib_path(uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE], uint8_t out_port); /** * To retrieve the fib_path entry for the nexthop IP and outgoing port * This queries with cuckoo hash table based on the fib_path_key_ipv4 * @param path_key * Key which is required for Cuckook hash table lookup * @return * NULL if lookup fails, Address of type ipv6_fib_path if lookup success */ struct ipv6_fib_path *retrieve_ipv6_fib_path_entry(struct fib_path_key_ipv6 path_key); /** * To retrieve the l2_adj_entry for the nexthop IP and outgoing port * This queries with cuckoo hash table based on the l2_adj_key_ipv6 * @param l2_adj_key * Key which is required for Cuckook hash table lookup * @return * NULL if lookup fails, Address of type l2_adj_ipv6_entry if lookup success */ struct l2_adj_ipv6_entry *retrieve_ipv6_l2_adj_entry(struct l2_adj_key_ipv6 l2_adj_key); /** * To populate the l2_adj_entry for the nexthop IP and outgoing port * @param nh_ip * NextHop Ip Address for which L2_adj_entry needs to be populated * @param portid * outgong port ID * @return * NULL if lookup fails, Address of the L2_adj_ipv6_entry if lookup success */ struct l2_adj_ipv6_entry *populate_ipv6_l2_adj(uint8_t nh_ip[RTE_LPM_IPV6_ADDR_SIZE], uint8_t portid); /** * To get the destination MAC Address for the nexthop IP and outgoing port * @param nh_ipv6 * Next HOP IP Address for which MAC address is needed * @param out_phy_port * Outgoing physical port * @param hw_addr * pointet to the ether_add, This gets update with valid MAC address based on nh_ip and out port * @return * 0 if failure, 1 if success */ int get_dest_mac_for_nexthop_ipv6(uint8_t nh_ipv6[RTE_LPM_IPV6_ADDR_SIZE], uint32_t out_phy_port, struct ether_addr *hw_addr); /** * To delete the ipv6 fib path and l2 adjacency entry from the cuckoo hash table * @return * None */ void remove_ipv6_fib_l2_adj_entry(void *entry); void ipv6_l3_protocol_type_add(uint8_t protocol_type, void (*func) (struct rte_mbuf **, uint16_t, uint64_t, l2_phy_interface_t *)); void ipv6_local_deliver(struct rte_mbuf **, uint16_t, uint64_t, l2_phy_interface_t *); void ipv6_forward_deliver(struct rte_mbuf **, uint16_t, uint64_t, l2_phy_interface_t *); int is_valid_ipv6_pkt(struct ipv6_hdr *pkt, uint32_t link_len); uint8_t ipv6_hash_load_balance(struct rte_mbuf *mbuf); /** * To resolve l2_adj_entry based on nexthop IP, outgoing port and ether hw address. * @param nh_ip * NextHop Ip Address for which L2_adj_entry needs to be resolved * @param portid * outgong port ID * @hw_addr * Ethernet hardware address for the above nexthop IP and out port ID. * @return * Return is void. */ void resolve_ipv6_l2_adj(uint8_t nh_ip[RTE_LPM_IPV6_ADDR_SIZE], uint8_t portid, struct ether_addr *hw_addr); void ipv6_iterate__hash_table(void); #endif /* L3FWD_LPM_H */