From 83a460d5a2580c8639e2009ce70a9c61ccc99fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarom=C3=ADr=20Smr=C4=8Dek?= <4plague@gmail.com> Date: Tue, 19 Sep 2023 17:18:05 +0200 Subject: [PATCH] WIP --- include/dp_vni.h | 12 +-- src/dp_lpm.c | 23 ++---- src/dp_vni.c | 176 +++++++++++++++++++++------------------- src/grpc/dp_grpc_impl.c | 12 ++- 4 files changed, 111 insertions(+), 112 deletions(-) diff --git a/include/dp_vni.h b/include/dp_vni.h index c62cf5227..663fe6c6f 100644 --- a/include/dp_vni.h +++ b/include/dp_vni.h @@ -34,7 +34,7 @@ struct dp_vni_data { struct rte_rib *ipv4[DP_NB_SOCKETS]; struct rte_rib6 *ipv6[DP_NB_SOCKETS]; struct dp_ref ref_count; - int socketid; + int socket_id; int vni; }; @@ -76,11 +76,11 @@ static __rte_always_inline struct rte_rib6 *dp_get_vni_route6_table(int vni, int int dp_vni_init(int socket_id); void dp_vni_free(void); -bool dp_is_vni_route_tbl_available(int vni, int type, int socket_id); -int dp_create_vni_route_table(int vni, int type, int socket_id); -int dp_delete_vni_route_table(int vni, int type); -int dp_reset_vni_route_table(int vni, int type, int socket_id); -int dp_reset_vni_all_route_tables(int socket_id); +bool dp_is_vni_route_table_available(int vni, int type, int socket_id); +int dp_create_vni_route_tables(int vni, int socket_id); +int dp_delete_vni_route_tables(int vni); +int dp_reset_vni_route_tables(int vni, int socket_id); +int dp_reset_all_vni_route_tables(int socket_id); #ifdef __cplusplus } diff --git a/src/dp_lpm.c b/src/dp_lpm.c index 832279e80..b3b08fc3b 100644 --- a/src/dp_lpm.c +++ b/src/dp_lpm.c @@ -53,7 +53,7 @@ int dp_lpm_reset_all_route_tables(int socketid) { int ret; - if (DP_FAILED(dp_reset_vni_all_route_tables(socketid))) + if (DP_FAILED(dp_reset_all_vni_route_tables(socketid))) return DP_GRPC_ERR_ROUTE_RESET; for (int i = 0; i < DP_MAX_PORTS; ++i) { @@ -71,13 +71,8 @@ int dp_lpm_reset_route_tables(int vni, int socketid) { int ret; - if (DP_FAILED(dp_reset_vni_route_table(vni, DP_IP_PROTO_IPV4, socketid))) { - DPS_LOG_ERR("Resetting vni route table failed", DP_LOG_VNI(vni), DP_LOG_SOCKID(socketid)); - return DP_GRPC_ERR_ROUTE_RESET; - } - - if (DP_FAILED(dp_reset_vni_route_table(vni, DP_IP_PROTO_IPV6, socketid))) { - DPS_LOG_ERR("Resetting vni route table failed", DP_LOG_VNI(vni), DP_LOG_SOCKID(socketid)); + if (DP_FAILED(dp_reset_vni_route_tables(vni, socketid))) { + DPS_LOG_ERR("Resetting vni route tables failed", DP_LOG_VNI(vni), DP_LOG_SOCKID(socketid)); return DP_GRPC_ERR_ROUTE_RESET; } @@ -491,7 +486,7 @@ int dp_setup_vm(int port_id, int vni, int socketid) { RTE_VERIFY(port_id < DP_MAX_PORTS); - if (DP_FAILED(dp_create_vni_route_table(vni, DP_IP_PROTO_IPV4, socketid))) + if (DP_FAILED(dp_create_vni_route_tables(vni, socketid))) return DP_ERROR; dp_init_firewall_rules_list(port_id); @@ -504,7 +499,7 @@ int dp_setup_vm6(int port_id, int vni, int socketid) { RTE_VERIFY(port_id < DP_MAX_PORTS); - if (DP_FAILED(dp_create_vni_route_table(vni, DP_IP_PROTO_IPV6, socketid))) + if (DP_FAILED(dp_create_vni_route_tables(vni, socketid))) return DP_ERROR; vm_table[port_id].vni = vni; @@ -580,10 +575,10 @@ void dp_del_vm(int portid, int socketid) dp_del_route(portid, vm_table[portid].vni, vm_table[portid].info.own_ip, 32, socketid); dp_del_route6(portid, vm_table[portid].vni, vm_table[portid].info.dhcp_ipv6, 128, socketid); - if (DP_FAILED(dp_delete_vni_route_table(vm_table[portid].vni, DP_IP_PROTO_IPV4))) - DPS_LOG_WARNING("Unable to delete route table", DP_LOG_VNI(vm_table[portid].vni), DP_LOG_PROTO(DP_IP_PROTO_IPV4)); - if (DP_FAILED(dp_delete_vni_route_table(vm_table[portid].vni, DP_IP_PROTO_IPV6))) - DPS_LOG_WARNING("Unable to delete route table", DP_LOG_VNI(vm_table[portid].vni), DP_LOG_PROTO(DP_IP_PROTO_IPV6)); + if (DP_FAILED(dp_delete_vni_route_tables(vm_table[portid].vni))) + DPS_LOG_WARNING("Unable to delete route tables", DP_LOG_VNI(vm_table[portid].vni)); + if (DP_FAILED(dp_delete_vni_route_tables(vm_table[portid].vni))) + DPS_LOG_WARNING("Unable to delete route tables", DP_LOG_VNI(vm_table[portid].vni)); dp_del_all_firewall_rules(portid); memset(&vm_table[portid], 0, sizeof(vm_table[portid])); diff --git a/src/dp_vni.c b/src/dp_vni.c index 9d2e70b6e..cdfefb6bc 100644 --- a/src/dp_vni.c +++ b/src/dp_vni.c @@ -20,7 +20,7 @@ void dp_vni_free(void) dp_free_jhash_table(vni_handle_tbl); } -bool dp_is_vni_route_tbl_available(int vni, int type, int socket_id) +bool dp_is_vni_route_table_available(int vni, int type, int socket_id) { struct dp_vni_data *vni_data; struct dp_vni_key vni_key = { @@ -29,10 +29,9 @@ bool dp_is_vni_route_tbl_available(int vni, int type, int socket_id) int ret; ret = rte_hash_lookup_data(vni_handle_tbl, &vni_key, (void **)&vni_data); - if (ret == -ENOENT) { - return false; - } else if (DP_FAILED(ret)) { - DPS_LOG_ERR("VNI lookup error", DP_LOG_VNI(vni), DP_LOG_VNI_TYPE(type), DP_LOG_RET(ret)); + if (DP_FAILED(ret)) { + if (ret != -ENOENT) + DPS_LOG_ERR("VNI lookup error", DP_LOG_VNI(vni), DP_LOG_RET(ret)); return false; } @@ -40,64 +39,111 @@ bool dp_is_vni_route_tbl_available(int vni, int type, int socket_id) || (type == DP_IP_PROTO_IPV6 && vni_data->ipv6[DP_SOCKETID(socket_id)]); } -static void dp_free_vni_value(struct dp_ref *ref) +static __rte_always_inline void dp_free_rib6(struct dp_vni_data *vni_data) +{ + rte_rib6_free(vni_data->ipv6[DP_SOCKETID(vni_data->socket_id)]); +} + +static __rte_always_inline void dp_free_rib(struct dp_vni_data *vni_data) +{ + rte_rib_free(vni_data->ipv4[DP_SOCKETID(vni_data->socket_id)]); +} + +static void dp_free_vni_data(struct dp_ref *ref) { - struct dp_vni_data *vni_value = container_of(ref, struct dp_vni_data, ref_count); - int dp_socketid = DP_SOCKETID(vni_value->socketid); + struct dp_vni_data *vni_data = container_of(ref, struct dp_vni_data, ref_count); - DPS_LOG_DEBUG("Freeing VNI", DP_LOG_VNI(vni_value->vni)); - rte_rib_free(vni_value->ipv4[dp_socketid]); - rte_rib6_free(vni_value->ipv6[dp_socketid]); + DPS_LOG_DEBUG("Freeing VNI", DP_LOG_VNI(vni_data->vni)); + dp_free_rib6(vni_data); + dp_free_rib(vni_data); - dp_del_all_neigh_nat_entries_in_vni(vni_value->vni); - rte_free(vni_value); + dp_del_all_neigh_nat_entries_in_vni(vni_data->vni); + rte_free(vni_data); } -static int dp_create_rib6(const struct dp_vni_key *key, int socket_id, struct dp_vni_data *vni_data) +static __rte_always_inline int dp_create_rib6(uint32_t vni, int socket_id, struct dp_vni_data *vni_data) { struct rte_rib6_conf config_ipv6; struct rte_rib6 *new_rib6; char s[64]; - /* create the LPM table */ config_ipv6.max_nodes = IPV6_DP_RIB_MAX_RULES; config_ipv6.ext_sz = sizeof(struct vm_route); - snprintf(s, sizeof(s), "IPV6_DP_RIB_%d_%d", key->vni, socket_id); + snprintf(s, sizeof(s), "IPV6_DP_RIB_%d_%d", vni, socket_id); new_rib6 = rte_rib6_create(s, socket_id, &config_ipv6); if (!new_rib6) { - DPS_LOG_ERR("Unable to create the DP RIB6 table", DP_LOG_SOCKID(socket_id)); + DPS_LOG_ERR("Unable to create DP RIB6 table", DP_LOG_SOCKID(socket_id)); return DP_ERROR; } + vni_data->vni = vni; + vni_data->socket_id = socket_id; vni_data->ipv6[DP_SOCKETID(socket_id)] = new_rib6; - vni_data->socketid = socket_id; return DP_OK; } -static int dp_create_rib(const struct dp_vni_key *key, int socket_id, struct dp_vni_data *vni_data) +static __rte_always_inline int dp_create_rib(uint32_t vni, int socket_id, struct dp_vni_data *vni_data) { struct rte_rib_conf config_ipv4; struct rte_rib *new_rib; char s[64]; - /* create the LPM table */ config_ipv4.max_nodes = IPV4_DP_RIB_MAX_RULES; config_ipv4.ext_sz = sizeof(struct vm_route); - snprintf(s, sizeof(s), "IPV4_DP_RIB_%d_%d", key->vni, socket_id); + snprintf(s, sizeof(s), "IPV4_DP_RIB_%d_%d", vni, socket_id); new_rib = rte_rib_create(s, socket_id, &config_ipv4); if (!new_rib) { - DPS_LOG_ERR("Unable to create the DP RIB table", DP_LOG_SOCKID(socket_id)); + DPS_LOG_ERR("Unable to create DP RIB table", DP_LOG_SOCKID(socket_id)); return DP_ERROR; } + vni_data->vni = vni; + vni_data->socket_id = socket_id; vni_data->ipv4[DP_SOCKETID(socket_id)] = new_rib; - vni_data->socketid = socket_id; return DP_OK; } -int dp_create_vni_route_table(int vni, int type, int socket_id) +static __rte_always_inline int dp_allocate_vni_route_tables(const struct dp_vni_key *vni_key, int socket_id) +{ + struct dp_vni_data *vni_data; + uint32_t vni = vni_key->vni; + int ret; + + vni_data = rte_zmalloc("vni_handle_table", sizeof(struct dp_vni_data), RTE_CACHE_LINE_SIZE); + if (!vni_data) { + DPS_LOG_ERR("VNI allocation failed", DP_LOG_VNI(vni)); + goto err_alloc; + } + + if (DP_FAILED(dp_create_rib(vni, socket_id, vni_data))) + goto err_rib; + + if (DP_FAILED(dp_create_rib6(vni, socket_id, vni_data))) + goto err_rib6; + + ret = rte_hash_add_key_data(vni_handle_tbl, vni_key, vni_data); + if (DP_FAILED(ret)) { + DPS_LOG_WARNING("Failed to add to VNI hashtable", DP_LOG_VNI(vni), DP_LOG_RET(ret)); + goto err_hash; + } + + dp_ref_init(&vni_data->ref_count, dp_free_vni_data); + return DP_OK; + +err_hash: + dp_free_rib6(vni_data); +err_rib6: + dp_free_rib(vni_data); +err_rib: + rte_free(vni_data); +err_alloc: + DPS_LOG_ERR("VNI creation failed", DP_LOG_VNI(vni)); + return DP_ERROR; +} + +int dp_create_vni_route_tables(int vni, int socket_id) { struct dp_vni_data *vni_data; struct dp_vni_key vni_key = { @@ -106,52 +152,20 @@ int dp_create_vni_route_table(int vni, int type, int socket_id) int ret; ret = rte_hash_lookup_data(vni_handle_tbl, &vni_key, (void **)&vni_data); - if (ret == -ENOENT) { - vni_data = rte_zmalloc("vni_handle_table", sizeof(struct dp_vni_data), RTE_CACHE_LINE_SIZE); - if (!vni_data) { - DPS_LOG_ERR("VNI allocation failed", DP_LOG_VNI(vni), DP_LOG_VNI_TYPE(type)); - return DP_ERROR; - } - if (type == DP_IP_PROTO_IPV4) { - if (DP_FAILED(dp_create_rib(&vni_key, socket_id, vni_data))) - goto err_free; - } else if (type == DP_IP_PROTO_IPV6) { - if (DP_FAILED(dp_create_rib6(&vni_key, socket_id, vni_data))) - goto err_free; - } else { - goto err_free; - } - ret = rte_hash_add_key_data(vni_handle_tbl, &vni_key, vni_data); - if (DP_FAILED(ret)) { - DPS_LOG_WARNING("Failed to add to route4 hashtable", DP_LOG_VNI(vni), DP_LOG_VNI_TYPE(type), DP_LOG_RET(ret)); + if (DP_FAILED(ret)) { + if (ret != -ENOENT) { + DPS_LOG_ERR("VNI creation error", DP_LOG_VNI(vni), DP_LOG_RET(ret)); return DP_ERROR; } - vni_data->vni = vni; - dp_ref_init(&vni_data->ref_count, dp_free_vni_value); - } else if (DP_FAILED(ret)) { - DPS_LOG_ERR("VNI creation error", DP_LOG_VNI(vni), DP_LOG_VNI_TYPE(type), DP_LOG_RET(ret)); - return DP_ERROR; - } else { - if ((type == DP_IP_PROTO_IPV4) && !vni_data->ipv4[DP_SOCKETID(socket_id)]) { - if (DP_FAILED(dp_create_rib(&vni_key, socket_id, vni_data))) - goto err; - } - if (type == DP_IP_PROTO_IPV6 && !vni_data->ipv6[DP_SOCKETID(socket_id)]) { - if (DP_FAILED(dp_create_rib6(&vni_key, socket_id, vni_data))) - goto err; - } - dp_ref_inc(&vni_data->ref_count); + return dp_allocate_vni_route_tables(&vni_key, socket_id); } + dp_ref_inc(&vni_data->ref_count); return DP_OK; -err_free: - rte_free(vni_data); -err: - DPS_LOG_ERR("VNI creation failed", DP_LOG_VNI(vni), DP_LOG_VNI_TYPE(type)); - return DP_ERROR; + } -int dp_delete_vni_route_table(int vni, int type) +int dp_delete_vni_route_tables(int vni) { struct dp_vni_data *vni_data; struct dp_vni_key vni_key = { @@ -176,7 +190,7 @@ int dp_delete_vni_route_table(int vni, int type) return DP_OK; } -int dp_reset_vni_route_table(int vni, int type, int socket_id) +int dp_reset_vni_route_tables(int vni, int socket_id) { struct dp_vni_data *vni_data; struct dp_vni_key vni_key = { @@ -190,48 +204,40 @@ int dp_reset_vni_route_table(int vni, int type, int socket_id) return DP_OK; } - if (type == DP_IP_PROTO_IPV4) { - if (vni_data->ipv4[DP_SOCKETID(socket_id)]) { - rte_rib_free(vni_data->ipv4[DP_SOCKETID(socket_id)]); - if (DP_FAILED(dp_create_rib(&vni_key, socket_id, vni_data))) - return DP_ERROR; - } else { + if (vni_data->ipv4[DP_SOCKETID(socket_id)]) { + rte_rib_free(vni_data->ipv4[DP_SOCKETID(socket_id)]); + if (DP_FAILED(dp_create_rib(vni, socket_id, vni_data))) return DP_ERROR; - } - } else if (type == DP_IP_PROTO_IPV6) { - if (vni_data->ipv6[DP_SOCKETID(socket_id)]) { - rte_rib6_free(vni_data->ipv6[DP_SOCKETID(socket_id)]); - if (DP_FAILED(dp_create_rib6(&vni_key, socket_id, vni_data))) - return DP_ERROR; - } else { + } + + if (vni_data->ipv6[DP_SOCKETID(socket_id)]) { + rte_rib6_free(vni_data->ipv6[DP_SOCKETID(socket_id)]); + if (DP_FAILED(dp_create_rib6(vni, socket_id, vni_data))) return DP_ERROR; - } - } else { - return DP_ERROR; } return DP_OK; } -int dp_reset_vni_all_route_tables(int socket_id) +int dp_reset_all_vni_route_tables(int socket_id) { struct dp_vni_data *vni_data; - const struct dp_vni_key *key; + const struct dp_vni_key *vni_key; uint32_t iter = 0; int32_t ret; if (rte_hash_count(vni_handle_tbl) == 0) return DP_OK; - while ((ret = rte_hash_iterate(vni_handle_tbl, (const void **)&key, (void **)&vni_data, &iter)) != -ENOENT) { + while ((ret = rte_hash_iterate(vni_handle_tbl, (const void **)&vni_key, (void **)&vni_data, &iter)) != -ENOENT) { if (vni_data->ipv4[DP_SOCKETID(socket_id)]) { rte_rib_free(vni_data->ipv4[DP_SOCKETID(socket_id)]); - if (DP_FAILED(dp_create_rib(key, socket_id, vni_data))) + if (DP_FAILED(dp_create_rib(vni_key->vni, socket_id, vni_data))) return DP_ERROR; } if (vni_data->ipv6[DP_SOCKETID(socket_id)]) { rte_rib6_free(vni_data->ipv6[DP_SOCKETID(socket_id)]); - if (DP_FAILED(dp_create_rib6(key, socket_id, vni_data))) + if (DP_FAILED(dp_create_rib6(vni_key->vni, socket_id, vni_data))) return DP_ERROR; } } diff --git a/src/grpc/dp_grpc_impl.c b/src/grpc/dp_grpc_impl.c index abfbf30fa..52f4ab87d 100644 --- a/src/grpc/dp_grpc_impl.c +++ b/src/grpc/dp_grpc_impl.c @@ -85,9 +85,7 @@ static int dp_process_create_lb(struct dp_grpc_responder *responder) ret = dp_create_lb(request, ul_addr6); if (DP_FAILED(ret)) goto err_vnf; - if (DP_FAILED(dp_create_vni_route_table(vni, DP_IP_PROTO_IPV4, - rte_eth_dev_socket_id(dp_port_get_pf0_id()))) - ) { + if (DP_FAILED(dp_create_vni_route_tables(vni, rte_eth_dev_socket_id(dp_port_get_pf0_id())))) { ret = DP_GRPC_ERR_VNI_INIT4; goto err_lb; } @@ -122,7 +120,7 @@ static int dp_process_delete_lb(struct dp_grpc_responder *responder) if (DP_FAILED(ret)) return ret; - if (DP_FAILED(dp_delete_vni_route_table(lb.vni, DP_IP_PROTO_IPV4))) + if (DP_FAILED(dp_delete_vni_route_tables(lb.vni))) return DP_GRPC_ERR_VNI_FREE4; return DP_GRPC_OK; @@ -168,9 +166,9 @@ static int dp_process_check_vniinuse(struct dp_grpc_responder *responder) struct dpgrpc_vni_in_use *reply = dp_grpc_single_reply(responder); if (request->type == DP_VNI_IPV4) { - reply->in_use = dp_is_vni_route_tbl_available(request->vni, - DP_IP_PROTO_IPV4, - rte_eth_dev_socket_id(dp_port_get_pf0_id())); + reply->in_use = dp_is_vni_route_table_available(request->vni, + DP_IP_PROTO_IPV4, + rte_eth_dev_socket_id(dp_port_get_pf0_id())); } else return DP_GRPC_ERR_WRONG_TYPE;