Skip to content

Commit

Permalink
Flush VM's flow table entries after removing an interface
Browse files Browse the repository at this point in the history
  • Loading branch information
PlagueCZ committed Sep 15, 2023
1 parent 51b8186 commit 880c568
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 8 deletions.
1 change: 1 addition & 0 deletions include/dp_flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ void dp_free_flow(struct dp_ref *ref);
void dp_free_network_nat_port(struct flow_value *cntrack);
void dp_remove_nat_flows(uint16_t port_id, int nat_type); // TODO create proper enum!
void dp_remove_neighnat_flows(uint32_t ipv4, uint32_t vni, uint16_t min_port, uint16_t max_port);
void dp_remove_vm_flows(uint16_t port_id, uint32_t ipv4, uint32_t vni);

hash_sig_t dp_get_conntrack_flow_hash_value(struct flow_key *key);

Expand Down
39 changes: 31 additions & 8 deletions src/dp_flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,13 @@ void dp_process_aged_flows_non_offload(void)
}
}

static __rte_always_inline void dp_remove_flow(struct flow_value *flow_val)
{
if (offload_mode_enabled)
dp_rte_flow_remove(flow_val);
dp_age_out_flow(flow_val);
}

void dp_remove_nat_flows(uint16_t port_id, int nat_type)
{
struct flow_value *flow_val = NULL;
Expand All @@ -438,11 +445,8 @@ void dp_remove_nat_flows(uint16_t port_id, int nat_type)
return;
}
// NAT/VIP are in 1:1 relation to a VM (port_id), no need to check IP:port
if (flow_val->created_port_id == port_id && flow_val->nf_info.nat_type == nat_type) {
if (offload_mode_enabled)
dp_rte_flow_remove(flow_val);
dp_age_out_flow(flow_val);
}
if (flow_val->created_port_id == port_id && flow_val->nf_info.nat_type == nat_type)
dp_remove_flow(flow_val);
}
}

Expand All @@ -461,13 +465,32 @@ void dp_remove_neighnat_flows(uint32_t ipv4, uint32_t vni, uint16_t min_port, ui
if (next_key->vni == vni && next_key->ip_dst == ipv4
&& next_key->port_dst >= min_port && next_key->port_dst < max_port
) {
if (offload_mode_enabled)
dp_rte_flow_remove(flow_val);
dp_age_out_flow(flow_val);
dp_remove_flow(flow_val);
}
}
}

void dp_remove_vm_flows(uint16_t port_id, uint32_t ipv4, uint32_t vni)
{
struct flow_value *flow_val = NULL;
const struct flow_key *next_key;
uint32_t iter = 0;
int ret;

while ((ret = rte_hash_iterate(ipv4_flow_tbl, (const void **)&next_key, (void **)&flow_val, &iter)) != -ENOENT) {
if (DP_FAILED(ret)) {
DPS_LOG_ERR("Iterating flow table failed while removing VM flows", DP_LOG_RET(ret));
return;
}
if (flow_val->created_port_id == port_id
|| (next_key->vni == vni && flow_val->flow_key[DP_FLOW_DIR_ORG].ip_dst == ipv4)
) {
dp_remove_flow(flow_val);
}
}
}


hash_sig_t dp_get_conntrack_flow_hash_value(struct flow_key *key)
{
//It is not necessary to first test if this key exists, since for now, this function
Expand Down
6 changes: 6 additions & 0 deletions src/grpc/dp_grpc_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,12 +555,17 @@ static int dp_process_delete_interface(struct dp_grpc_responder *responder)
struct dpgrpc_iface_id *request = &responder->request.del_iface;

int port_id;
uint32_t ipv4;
uint32_t vni;
int ret = DP_GRPC_OK;

port_id = dp_get_portid_with_vm_handle(request->iface_id);
if (DP_FAILED(port_id))
return DP_GRPC_ERR_NOT_FOUND;

ipv4 = dp_get_dhcp_range_ip4(port_id);
vni = dp_get_vm_vni(port_id);

dp_del_vnf_with_vnf_key(dp_get_vm_ul_ip6(port_id));
if (DP_FAILED(dp_port_stop(port_id)))
ret = DP_GRPC_ERR_PORT_STOP;
Expand All @@ -570,6 +575,7 @@ static int dp_process_delete_interface(struct dp_grpc_responder *responder)
#ifdef ENABLE_VIRTSVC
dp_virtsvc_del_vm(port_id);
#endif
dp_remove_vm_flows(port_id, ipv4, vni);
return ret;
}

Expand Down

0 comments on commit 880c568

Please sign in to comment.