From 48fcdb4797c1cae4d6cb08591a92b21d22756748 Mon Sep 17 00:00:00 2001 From: l0310 Date: Wed, 2 Dec 2015 19:20:07 +0800 Subject: [PATCH] ovn-northd: Can't use ct() for router ports. This patch ensures that we do not attempt to use connection tracking for logical ports with type=router. This does not work as the traffic through a logical router port is not symmetric since logical routers are distributed. The result was that traffic between logical ports on different hypervisors that went through a logical router would fail if ACLs were in use. GitHub-PR: #92 Reported-at: https://bugs.launchpad.net/networking-ovn/+bug/1522022 Signed-off-by: l0310 [russell@ovn.org updated commit message, style tweaks] Signed-off-by: Russell Bryant --- ovn/northd/ovn-northd.c | 30 ++++++++++++++++++++++++++++-- ovn/ovn-nb.xml | 5 +++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c index 270b116a7..d8e482452 100644 --- a/ovn/northd/ovn-northd.c +++ b/ovn/northd/ovn-northd.c @@ -964,9 +964,11 @@ has_stateful_acl(struct ovn_datapath *od) } static void -build_acls(struct ovn_datapath *od, struct hmap *lflows) +build_acls(struct ovn_datapath *od, struct hmap *lflows, struct hmap *ports) { bool has_stateful = has_stateful_acl(od); + struct ovn_port *op; + struct ds match_in, match_out; /* Ingress and Egress Pre-ACL Table (Priority 0): Packets are * allowed by default. */ @@ -983,6 +985,30 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows) * send all IP packets through the conntrack action, which handles * defragmentation, in order to match L4 headers. */ if (has_stateful) { + HMAP_FOR_EACH (op, key_node, ports) { + if (op->od == od && !strcmp(op->nbs->type, "router")) { + /* Can't use ct() for router ports. Consider the following configuration: + lp1(10.0.0.2) on hostA--ls1--lr0--ls2--lp2(10.0.1.2) on hostB, + For a ping from lp1 to lp2, First, the response will go through ct() + with a zone for lp2 in the ls2 ingress pipeline on hostB. + That ct zone knows about this connection. Next, it goes through ct() + with the zone for the router port in the egress pipeline of ls2 on hostB. + This zone does not know about the connection, as the icmp request + went through the logical router on hostA, not hostB. This would only work + with distributed conntrack state across all chassis. */ + + ds_init(&match_in); + ds_init(&match_out); + ds_put_format(&match_in, "ip && inport == %s", op->json_key); + ds_put_format(&match_out, "ip && outport == %s", op->json_key); + ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_ACL, 110, ds_cstr(&match_in), "next;"); + ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 110, ds_cstr(&match_out), "next;"); + + ds_destroy(&match_in); + ds_destroy(&match_out); + } + } + /* Ingress and Egress Pre-ACL Table (Priority 100). * * Regardless of whether the ACL is "from-lport" or "to-lport", @@ -1100,7 +1126,7 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports, continue; } - build_acls(od, lflows); + build_acls(od, lflows, ports); } /* Logical switch ingress table 0: Admission control framework (priority diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml index a1fa0eeed..ef34c9b9e 100644 --- a/ovn/ovn-nb.xml +++ b/ovn/ovn-nb.xml @@ -383,6 +383,11 @@ restrictive policy, it is important to remember to allow flows such as ARP and IPv6 neighbor discovery packets.

+ +

+ Note that you can not create an ACL matching on a port with + type=router. +

-- 2.20.1