[ovs-dev] [PATCH ovn] ovn-controller: Avoid infinite replying for TCP/ICMP connection reset messages

mheib at redhat.com mheib at redhat.com
Wed Oct 6 15:28:15 UTC 2021


From: Mohammad Heib <mheib at redhat.com>

When the ovn controller receives an ip packet that targets a lport that has ACL
rule to reject ip packets, the controller will reply with TCP_RST or icmp4/6 unreachable packet
to notify the sender that the destination is not available.

In turn, the receiver host will receive the notification packet and handle it as a normal IP packet
and if the receiver host is part of the same logical-switch/port-group or has IP reject ACL rule
it will send TCP_RST or icmp4/6 unreachable packet replying to the TCP_RST or icmp4/6 unreachable
packet we received and here we will enter to an infinity loop of replying about replying which
will consume high CPU.

To avoid such scenarios this patch proposes to drop/ignore TCP_RST or icmp4/6 unreachable packets
that received on lport that has  IP reject ACL rules.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1934011
Fixes: 64f8c9e9f ("actions: Add a new OVN action - reject {}.")
Signed-off-by: Mohammad Heib <mheib at redhat.com>
---
 controller/pinctrl.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index cc3edaaf4..eff599d2b 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -1934,11 +1934,40 @@ pinctrl_handle_sctp_abort(struct rconn *swconn, const struct flow *ip_flow,
     dp_packet_uninit(&packet);
 }
 
+static bool
+pinctrl_handle_reject_ignore_pkt(const struct flow *ip_flow,
+                                 struct dp_packet *pkt_in)
+{
+    if (ip_flow->nw_proto == IPPROTO_TCP) {
+        struct tcp_header *th = dp_packet_l4(pkt_in);
+        if (!th || (TCP_FLAGS(th->tcp_ctl) & TCP_RST)) {
+            return true;
+        }
+    } else {
+        if (is_icmpv4(ip_flow, NULL)) {
+            struct icmp_header *ih = dp_packet_l4(pkt_in);
+            if (!ih || (ih->icmp_type == ICMP4_DST_UNREACH)) {
+                return true;
+            }
+        } else if (is_icmpv6(ip_flow, NULL)) {
+            struct icmp6_data_header *ih = dp_packet_l4(pkt_in);
+            if (!ih || (ih->icmp6_base.icmp6_type == ICMP6_DST_UNREACH)) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
 static void
 pinctrl_handle_reject(struct rconn *swconn, const struct flow *ip_flow,
                       struct dp_packet *pkt_in,
                       const struct match *md, struct ofpbuf *userdata)
 {
+    if (pinctrl_handle_reject_ignore_pkt(ip_flow, pkt_in)) {
+        return;
+    }
+
     if (ip_flow->nw_proto == IPPROTO_TCP) {
         pinctrl_handle_tcp_reset(swconn, ip_flow, pkt_in, md, userdata, true);
     } else if (ip_flow->nw_proto == IPPROTO_SCTP) {
-- 
2.27.0



More information about the dev mailing list