Skip to content

Commit

Permalink
LB should forward the ICMP error types to correct backends
Browse files Browse the repository at this point in the history
Loadbalancer should be able to forward the icmp error packets
received from nord traffic to the backends.

Signed-off-by: Guvenc Gulce <[email protected]>
  • Loading branch information
guvenc committed Nov 13, 2023
1 parent e27fabd commit f4fa2cb
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/nodes/lb_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
{
struct dp_flow *df = dp_get_flow_ptr(m);
struct flow_value *cntrack = df->conntrack;
struct flow_key *flow_key;
uint32_t dst_ip, vni;
uint8_t *target_ip6;

Expand All @@ -45,11 +46,18 @@ static __rte_always_inline rte_edge_t get_next_index(__rte_unused struct rte_nod
&& dp_is_ip_lb(dst_ip, vni)
) {
if (df->l4_type == IPPROTO_ICMP) {
df->flags.nat = DP_CHG_UL_DST_IP;
return LB_NEXT_PACKET_RELAY;
/* Directly answer echo replies of loadbalanced IP, do not forward */
if (df->l4_info.icmp_field.icmp_type == RTE_IP_ICMP_ECHO_REQUEST) {
df->flags.nat = DP_CHG_UL_DST_IP;
return LB_NEXT_PACKET_RELAY;
}
/* ICMP error types conntrack keys are built from original TCP/UDP header, so let them slip */
if (df->l4_info.icmp_field.icmp_type != DP_IP_ICMP_TYPE_ERROR)
return LB_NEXT_DROP;
}

target_ip6 = dp_lb_get_backend_ip(dst_ip, vni, df->l4_info.trans_port.dst_port, df->l4_type);
flow_key = &cntrack->flow_key[DP_FLOW_DIR_ORG];
target_ip6 = dp_lb_get_backend_ip(dst_ip, vni, htons(flow_key->port_dst), flow_key->proto);
if (!target_ip6)
return LB_NEXT_DROP;

Expand Down
27 changes: 27 additions & 0 deletions test/test_lb.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,30 @@ def test_external_lb_relay(prepare_ipv4, grpc_client):

grpc_client.dellbtarget(lb_name, neigh_ul_ipv6)
grpc_client.dellb(lb_name)

def send_bounce_icmp_pkt_to_pf(ipv6_lb):
bounce_pkt = (Ether(dst=ipv6_multicast_mac, src=PF0.mac) /
IPv6(dst=ipv6_lb, src=local_ul_ipv6, nh=4) /
IP(dst=lb_ip, src=public_ip) /
ICMP(type=3, code=4) / # Type 3: Destination Unreachable, Code 4: fragmentation needed and DF set
IP(dst=public_ip, src=lb_ip) /
TCP(sport=8080, dport=8989))

delayed_sendp(bounce_pkt, PF0.tap)

def test_external_lb_icmp_error_relay(prepare_ipv4, grpc_client):

lb_ul_ipv6 = grpc_client.createlb(lb_name, vni1, lb_ip, "tcp/8080")
grpc_client.addlbtarget(lb_name, neigh_ul_ipv6)


threading.Thread(target=send_bounce_icmp_pkt_to_pf, args=(lb_ul_ipv6,)).start()
pkt = sniff_packet(PF0.tap, is_icmp_pkt, skip=1)

dst_ip = pkt[IPv6].dst
assert dst_ip == neigh_ul_ipv6, \
f"Wrong network-lb relayed icmp packet (outer dst ipv6: {dst_ip})"


grpc_client.dellbtarget(lb_name, neigh_ul_ipv6)
grpc_client.dellb(lb_name)

0 comments on commit f4fa2cb

Please sign in to comment.