|
|
ebb439 |
From e552cd40bf8abb3eb5ff80bd25c13105e427119a Mon Sep 17 00:00:00 2001
|
|
|
ebb439 |
From: Dumitru Ceara <dceara@redhat.com>
|
|
|
ebb439 |
Date: Thu, 15 Oct 2020 11:12:30 +0200
|
|
|
ebb439 |
Subject: [PATCH 7/7] ofctrl.c: Add a predictable resolution for conflicting
|
|
|
ebb439 |
flow actions.
|
|
|
ebb439 |
|
|
|
ebb439 |
Until now, in case the ACL configuration generates openflows that have
|
|
|
ebb439 |
the same match but different actions, ovn-controller was using the
|
|
|
ebb439 |
following approach:
|
|
|
ebb439 |
1. If the flow being added contains conjunctive actions, merge its
|
|
|
ebb439 |
actions with the already existing flow.
|
|
|
ebb439 |
2. Otherwise, if the flow is being added incrementally
|
|
|
ebb439 |
(update_installed_flows_by_track), don't install the new flow but
|
|
|
ebb439 |
instead keep the old one.
|
|
|
ebb439 |
3. Otherwise, (update_installed_flows_by_compare), don't install the
|
|
|
ebb439 |
new flow but instead keep the old one.
|
|
|
ebb439 |
|
|
|
ebb439 |
Even though one can argue that having an ACL with a match that includes
|
|
|
ebb439 |
the match of another ACL is a misconfiguration, it can happen that the
|
|
|
ebb439 |
users provision OVN like this. Depending on the order of reading and
|
|
|
ebb439 |
installing the logical flows, the above operations can yield
|
|
|
ebb439 |
unpredictable results, e.g., allow specific traffic but then after
|
|
|
ebb439 |
ovn-controller is restarted (or a recompute happens) that specific
|
|
|
ebb439 |
traffic starts being dropped.
|
|
|
ebb439 |
|
|
|
ebb439 |
A simple example of ACL configuration is:
|
|
|
ebb439 |
ovn-nbctl acl-add ls to-lport 3 '(ip4.src==10.0.0.1 ||
|
|
|
ebb439 |
ip4.src==10.0.0.2) && (ip4.dst == 10.0.0.3 || ip4.dst == 10.0.0.4)' allow
|
|
|
ebb439 |
ovn-nbctl acl-add ls to-lport 3 'ip4.src==10.0.0.1' allow
|
|
|
ebb439 |
ovn-nbctl acl-add ls to-lport 2 'arp' allow
|
|
|
ebb439 |
ovn-nbctl acl-add ls to-lport 1 'ip4' drop
|
|
|
ebb439 |
|
|
|
ebb439 |
This is a pattern used by most CMSs:
|
|
|
ebb439 |
- define a default deny policy.
|
|
|
ebb439 |
- punch holes in the default deny policy based on user specific
|
|
|
ebb439 |
configurations.
|
|
|
ebb439 |
|
|
|
ebb439 |
Without this commit the behavior for traffic from 10.0.0.1 to 10.0.0.5
|
|
|
ebb439 |
is unpredictable. Depending on the order of operations traffic might be
|
|
|
ebb439 |
dropped or allowed.
|
|
|
ebb439 |
|
|
|
ebb439 |
It's also quite hard to force the CMS to ensure that such match overlaps
|
|
|
ebb439 |
never occur.
|
|
|
ebb439 |
|
|
|
ebb439 |
To address this issue we now ensure that all desired flows refering the
|
|
|
ebb439 |
same installed flow are partially sorted in the following way:
|
|
|
ebb439 |
- first all flows with action "allow".
|
|
|
ebb439 |
- then all flows with action "drop".
|
|
|
ebb439 |
- then a single flow with action "conjunction" (resulting from merging
|
|
|
ebb439 |
all flows with the same match and action conjunction).
|
|
|
ebb439 |
|
|
|
ebb439 |
This ensures that "allow" flows have precedence over "drop" flows which
|
|
|
ebb439 |
in turn have precedence over "conjunction" flows. Essentially less
|
|
|
ebb439 |
restrictive flows are always preferred over more restrictive flows whenever a match
|
|
|
ebb439 |
conflict happens.
|
|
|
ebb439 |
|
|
|
ebb439 |
CC: Daniel Alvarez <dalvarez@redhat.com>
|
|
|
ebb439 |
Reported-at: https://bugzilla.redhat.com/1871931
|
|
|
ebb439 |
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
|
|
|
ebb439 |
Acked-by: Mark Gray <mark.d.gray@redhat.com>
|
|
|
ebb439 |
Signed-off-by: Han Zhou <hzhou@ovn.org>
|
|
|
ebb439 |
(cherry picked from upstream commit 986b3d5e4ad6f05245d021ba699c957246294a22)
|
|
|
ebb439 |
|
|
|
ebb439 |
Change-Id: Ibf49b5103ea34e5f268782f81cdae9cc7c06cae0
|
|
|
ebb439 |
---
|
|
|
ebb439 |
controller/ofctrl.c | 74 ++++++++++++++++--
|
|
|
ebb439 |
tests/ovn.at | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
ebb439 |
2 files changed, 283 insertions(+), 5 deletions(-)
|
|
|
ebb439 |
|
|
|
ebb439 |
diff --git a/controller/ofctrl.c b/controller/ofctrl.c
|
|
|
ebb439 |
index f444cae..79529d1 100644
|
|
|
ebb439 |
--- a/controller/ofctrl.c
|
|
|
ebb439 |
+++ b/controller/ofctrl.c
|
|
|
ebb439 |
@@ -188,6 +188,14 @@ struct sb_flow_ref {
|
|
|
ebb439 |
* relationship is 1 to N. A link is added when a flow addition is processed.
|
|
|
ebb439 |
* A link is removed when a flow deletion is processed, the desired flow
|
|
|
ebb439 |
* table is cleared, or the installed flow table is cleared.
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
+ * To ensure predictable behavior, the list of desired flows is maintained
|
|
|
ebb439 |
+ * partially sorted in the following way (from least restrictive to most
|
|
|
ebb439 |
+ * restrictive wrt. match):
|
|
|
ebb439 |
+ * - allow flows without action conjunction.
|
|
|
ebb439 |
+ * - drop flows without action conjunction.
|
|
|
ebb439 |
+ * - a single flow with action conjunction.
|
|
|
ebb439 |
+ *
|
|
|
ebb439 |
* The first desired_flow in the list is the active one, the one that is
|
|
|
ebb439 |
* actually installed.
|
|
|
ebb439 |
*/
|
|
|
ebb439 |
@@ -796,6 +804,12 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type)
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
static bool
|
|
|
ebb439 |
+flow_action_has_drop(const struct ovn_flow *f)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ return f->ofpacts_len == 0;
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static bool
|
|
|
ebb439 |
flow_action_has_conj(const struct ovn_flow *f)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
const struct ofpact *a = NULL;
|
|
|
ebb439 |
@@ -808,6 +822,33 @@ flow_action_has_conj(const struct ovn_flow *f)
|
|
|
ebb439 |
return false;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
+static bool
|
|
|
ebb439 |
+flow_action_has_allow(const struct ovn_flow *f)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ return !flow_action_has_drop(f) && !flow_action_has_conj(f);
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+/* Returns true if flow 'a' is preferred over flow 'b'. */
|
|
|
ebb439 |
+static bool
|
|
|
ebb439 |
+flow_is_preferred(const struct ovn_flow *a, const struct ovn_flow *b)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ if (flow_action_has_allow(b)) {
|
|
|
ebb439 |
+ return false;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ if (flow_action_has_allow(a)) {
|
|
|
ebb439 |
+ return true;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ if (flow_action_has_drop(b)) {
|
|
|
ebb439 |
+ return false;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ if (flow_action_has_drop(a)) {
|
|
|
ebb439 |
+ return true;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ /* Flows 'a' and 'b' should never both have action conjunction. */
|
|
|
ebb439 |
+ OVS_NOT_REACHED();
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
/* Adds the desired flow to the list of desired flows that have same match
|
|
|
ebb439 |
* conditions as the installed flow.
|
|
|
ebb439 |
*
|
|
|
ebb439 |
@@ -820,8 +861,18 @@ flow_action_has_conj(const struct ovn_flow *f)
|
|
|
ebb439 |
static bool
|
|
|
ebb439 |
link_installed_to_desired(struct installed_flow *i, struct desired_flow *d)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
+ struct desired_flow *f;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ /* Find first 'f' such that 'd' is preferred over 'f'. If no such desired
|
|
|
ebb439 |
+ * flow exists then 'f' will point after the last element of the list.
|
|
|
ebb439 |
+ */
|
|
|
ebb439 |
+ LIST_FOR_EACH (f, installed_ref_list_node, &i->desired_refs) {
|
|
|
ebb439 |
+ if (flow_is_preferred(&d->flow, &f->flow)) {
|
|
|
ebb439 |
+ break;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ ovs_list_insert(&f->installed_ref_list_node, &d->installed_ref_list_node);
|
|
|
ebb439 |
d->installed_flow = i;
|
|
|
ebb439 |
- ovs_list_push_back(&i->desired_refs, &d->installed_ref_list_node);
|
|
|
ebb439 |
return installed_flow_get_active(i) == d;
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
@@ -1789,8 +1840,14 @@ update_installed_flows_by_compare(struct ovn_desired_flow_table *flow_table,
|
|
|
ebb439 |
link_installed_to_desired(i, d);
|
|
|
ebb439 |
} else if (!d->installed_flow) {
|
|
|
ebb439 |
/* This is a desired_flow that conflicts with one installed
|
|
|
ebb439 |
- * previously but not linked yet. */
|
|
|
ebb439 |
- link_installed_to_desired(i, d);
|
|
|
ebb439 |
+ * previously but not linked yet. However, if this flow becomes
|
|
|
ebb439 |
+ * active, e.g., it is less restrictive than the previous active
|
|
|
ebb439 |
+ * flow then modify the installed flow.
|
|
|
ebb439 |
+ */
|
|
|
ebb439 |
+ if (link_installed_to_desired(i, d)) {
|
|
|
ebb439 |
+ installed_flow_mod(&i->flow, &d->flow, msgs);
|
|
|
ebb439 |
+ ovn_flow_log(&i->flow, "updating installed (conflict)");
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
}
|
|
|
ebb439 |
@@ -1919,8 +1976,15 @@ update_installed_flows_by_track(struct ovn_desired_flow_table *flow_table,
|
|
|
ebb439 |
ovn_flow_log(&i->flow, "updating installed (tracked)");
|
|
|
ebb439 |
} else {
|
|
|
ebb439 |
/* Adding a new flow that conflicts with an existing installed
|
|
|
ebb439 |
- * flow, so just add it to the link. */
|
|
|
ebb439 |
- link_installed_to_desired(i, f);
|
|
|
ebb439 |
+ * flow, so add it to the link. If this flow becomes active,
|
|
|
ebb439 |
+ * e.g., it is less restrictive than the previous active flow
|
|
|
ebb439 |
+ * then modify the installed flow.
|
|
|
ebb439 |
+ */
|
|
|
ebb439 |
+ if (link_installed_to_desired(i, f)) {
|
|
|
ebb439 |
+ installed_flow_mod(&i->flow, &f->flow, msgs);
|
|
|
ebb439 |
+ ovn_flow_log(&i->flow,
|
|
|
ebb439 |
+ "updating installed (tracked conflict)");
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
}
|
|
|
ebb439 |
/* The track_list_node emptyness is used to check if the node is
|
|
|
ebb439 |
* already added to track list, so initialize it again here. */
|
|
|
ebb439 |
diff --git a/tests/ovn.at b/tests/ovn.at
|
|
|
ebb439 |
index 6f1ab59..53f5d4d 100644
|
|
|
ebb439 |
--- a/tests/ovn.at
|
|
|
ebb439 |
+++ b/tests/ovn.at
|
|
|
ebb439 |
@@ -13727,6 +13727,220 @@ grep conjunction.*conjunction.*conjunction | wc -l`])
|
|
|
ebb439 |
OVN_CLEANUP([hv1])
|
|
|
ebb439 |
AT_CLEANUP
|
|
|
ebb439 |
|
|
|
ebb439 |
+AT_SETUP([ovn -- Superseeding ACLs with conjunction])
|
|
|
ebb439 |
+ovn_start
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ovn-nbctl ls-add ls1
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ovn-nbctl lsp-add ls1 ls1-lp1 \
|
|
|
ebb439 |
+-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01"
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ovn-nbctl lsp-add ls1 ls1-lp2 \
|
|
|
ebb439 |
+-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02"
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+net_add n1
|
|
|
ebb439 |
+sim_add hv1
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+as hv1
|
|
|
ebb439 |
+ovs-vsctl add-br br-phys
|
|
|
ebb439 |
+ovn_attach n1 br-phys 192.168.0.1
|
|
|
ebb439 |
+ovs-vsctl -- add-port br-int hv1-vif1 -- \
|
|
|
ebb439 |
+ set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
|
|
|
ebb439 |
+ options:tx_pcap=hv1/vif1-tx.pcap \
|
|
|
ebb439 |
+ options:rxq_pcap=hv1/vif1-rx.pcap \
|
|
|
ebb439 |
+ ofport-request=1
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ovs-vsctl -- add-port br-int hv1-vif2 -- \
|
|
|
ebb439 |
+ set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
|
|
|
ebb439 |
+ options:tx_pcap=hv1/vif2-tx.pcap \
|
|
|
ebb439 |
+ options:rxq_pcap=hv1/vif2-rx.pcap \
|
|
|
ebb439 |
+ ofport-request=2
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
|
|
|
ebb439 |
+#
|
|
|
ebb439 |
+# This shell function causes an ip packet to be received on INPORT.
|
|
|
ebb439 |
+# The packet's content has Ethernet destination DST and source SRC
|
|
|
ebb439 |
+# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
|
|
|
ebb439 |
+# The OUTPORTs (zero or more) list the VIFs on which the packet should
|
|
|
ebb439 |
+# be received. INPORT and the OUTPORTs are specified as logical switch
|
|
|
ebb439 |
+# port numbers, e.g. 11 for vif11.
|
|
|
ebb439 |
+test_ip() {
|
|
|
ebb439 |
+ # This packet has bad checksums but logical L3 routing doesn't check.
|
|
|
ebb439 |
+ local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
|
|
|
ebb439 |
+ local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
|
|
|
ebb439 |
+${dst_ip}0035111100080000
|
|
|
ebb439 |
+ shift; shift; shift; shift; shift
|
|
|
ebb439 |
+ as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
|
|
|
ebb439 |
+ for outport; do
|
|
|
ebb439 |
+ echo $packet >> $outport.expected
|
|
|
ebb439 |
+ done
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ip_to_hex() {
|
|
|
ebb439 |
+ printf "%02x%02x%02x%02x" "$@"
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+reset_pcap_file() {
|
|
|
ebb439 |
+ local iface=$1
|
|
|
ebb439 |
+ local pcap_file=$2
|
|
|
ebb439 |
+ ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
|
|
|
ebb439 |
+options:rxq_pcap=dummy-rx.pcap
|
|
|
ebb439 |
+ rm -f ${pcap_file}*.pcap
|
|
|
ebb439 |
+ ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
|
|
|
ebb439 |
+options:rxq_pcap=${pcap_file}-rx.pcap
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Add a default deny ACL and an allow ACL for specific IP traffic.
|
|
|
ebb439 |
+ovn-nbctl acl-add ls1 to-lport 2 'arp' allow
|
|
|
ebb439 |
+ovn-nbctl acl-add ls1 to-lport 1 'ip4' drop
|
|
|
ebb439 |
+ovn-nbctl acl-add ls1 to-lport 3 '(ip4.src==10.0.0.1 || ip4.src==10.0.0.2) && (ip4.dst == 10.0.0.3 || ip4.dst == 10.0.0.4)' allow
|
|
|
ebb439 |
+ovn-nbctl acl-add ls1 to-lport 3 '(ip4.src==10.0.0.1 || ip4.src==10.0.0.42) && (ip4.dst == 10.0.0.3 || ip4.dst == 10.0.0.4)' allow
|
|
|
ebb439 |
+ovn-nbctl --wait=hv sync
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
|
|
|
ebb439 |
+for src in `seq 1 2`; do
|
|
|
ebb439 |
+ for dst in `seq 3 4`; do
|
|
|
ebb439 |
+ sip=`ip_to_hex 10 0 0 $src`
|
|
|
ebb439 |
+ dip=`ip_to_hex 10 0 0 $dst`
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ test_ip 1 f00000000001 f00000000002 $sip $dip 2
|
|
|
ebb439 |
+ done
|
|
|
ebb439 |
+done
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.5 should be dropped.
|
|
|
ebb439 |
+dip=`ip_to_hex 10 0 0 5`
|
|
|
ebb439 |
+for src in `seq 1 2`; do
|
|
|
ebb439 |
+ sip=`ip_to_hex 10 0 0 $src`
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ test_ip 1 f00000000001 f00000000002 $sip $dip
|
|
|
ebb439 |
+done
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+cat 2.expected > expout
|
|
|
ebb439 |
+$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
|
|
|
ebb439 |
+AT_CHECK([cat 2.packets], [0], [expout])
|
|
|
ebb439 |
+reset_pcap_file hv1-vif2 hv1/vif2
|
|
|
ebb439 |
+rm -f 2.packets
|
|
|
ebb439 |
+> 2.expected
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Add two less restrictive allow ACLs for src IP 10.0.0.1.
|
|
|
ebb439 |
+ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1 || ip4.src==10.0.0.1' allow
|
|
|
ebb439 |
+ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1' allow
|
|
|
ebb439 |
+ovn-nbctl --wait=hv sync
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Check OVS flows, the less restrictive flows should have been installed.
|
|
|
ebb439 |
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
|
|
|
ebb439 |
+ grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
|
|
|
ebb439 |
+priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
|
|
|
ebb439 |
+])
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
|
|
|
ebb439 |
+for src in `seq 1 2`; do
|
|
|
ebb439 |
+ for dst in `seq 3 4`; do
|
|
|
ebb439 |
+ sip=`ip_to_hex 10 0 0 $src`
|
|
|
ebb439 |
+ dip=`ip_to_hex 10 0 0 $dst`
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ test_ip 1 f00000000001 f00000000002 $sip $dip 2
|
|
|
ebb439 |
+ done
|
|
|
ebb439 |
+done
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Traffic 10.0.0.2 -> 10.0.0.5 should be dropped.
|
|
|
ebb439 |
+sip=`ip_to_hex 10 0 0 2`
|
|
|
ebb439 |
+dip=`ip_to_hex 10 0 0 5`
|
|
|
ebb439 |
+test_ip 1 f00000000001 f00000000002 $sip $dip
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Traffic 10.0.0.1 -> 10.0.0.5 should be allowed.
|
|
|
ebb439 |
+sip=`ip_to_hex 10 0 0 1`
|
|
|
ebb439 |
+dip=`ip_to_hex 10 0 0 5`
|
|
|
ebb439 |
+test_ip 1 f00000000001 f00000000002 $sip $dip 2
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+cat 2.expected > expout
|
|
|
ebb439 |
+$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
|
|
|
ebb439 |
+AT_CHECK([cat 2.packets], [0], [expout])
|
|
|
ebb439 |
+reset_pcap_file hv1-vif2 hv1/vif2
|
|
|
ebb439 |
+rm -f 2.packets
|
|
|
ebb439 |
+> 2.expected
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+#sleep infinity
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Remove the first less restrictive allow ACL.
|
|
|
ebb439 |
+ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1 || ip4.src==10.0.0.1'
|
|
|
ebb439 |
+ovn-nbctl --wait=hv sync
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Check OVS flows, the second less restrictive allow ACL should have been installed.
|
|
|
ebb439 |
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
|
|
|
ebb439 |
+ grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
|
|
|
ebb439 |
+priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
|
|
|
ebb439 |
+])
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Remove the less restrictive allow ACL.
|
|
|
ebb439 |
+ovn-nbctl acl-del ls1 to-lport 3 'ip4.src==10.0.0.1'
|
|
|
ebb439 |
+ovn-nbctl --wait=hv sync
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Check OVS flows, the 10.0.0.1 conjunction should have been reinstalled.
|
|
|
ebb439 |
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
|
|
|
ebb439 |
+ grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
|
|
|
ebb439 |
+priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=conjunction(2,2/2),conjunction(3,2/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
|
|
|
ebb439 |
+])
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
|
|
|
ebb439 |
+for src in `seq 1 2`; do
|
|
|
ebb439 |
+ for dst in `seq 3 4`; do
|
|
|
ebb439 |
+ sip=`ip_to_hex 10 0 0 $src`
|
|
|
ebb439 |
+ dip=`ip_to_hex 10 0 0 $dst`
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ test_ip 1 f00000000001 f00000000002 $sip $dip 2
|
|
|
ebb439 |
+ done
|
|
|
ebb439 |
+done
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.5 should be dropped.
|
|
|
ebb439 |
+dip=`ip_to_hex 10 0 0 5`
|
|
|
ebb439 |
+for src in `seq 1 2`; do
|
|
|
ebb439 |
+ sip=`ip_to_hex 10 0 0 $src`
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ test_ip 1 f00000000001 f00000000002 $sip $dip
|
|
|
ebb439 |
+done
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+cat 2.expected > expout
|
|
|
ebb439 |
+$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
|
|
|
ebb439 |
+AT_CHECK([cat 2.packets], [0], [expout])
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Re-add the less restrictive allow ACL for src IP 10.0.0.1
|
|
|
ebb439 |
+ovn-nbctl acl-add ls1 to-lport 3 'ip4.src==10.0.0.1' allow
|
|
|
ebb439 |
+ovn-nbctl --wait=hv sync
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+# Check OVS flows, the less restrictive flows should have been installed.
|
|
|
ebb439 |
+AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | \
|
|
|
ebb439 |
+ grep "priority=1003" | awk '{print $7 " " $8}' | sort], [0], [dnl
|
|
|
ebb439 |
+priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,1/2),conjunction(3,1/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 actions=resubmit(,46)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 actions=conjunction(2,2/2)
|
|
|
ebb439 |
+priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 actions=conjunction(3,2/2)
|
|
|
ebb439 |
+])
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+OVN_CLEANUP([hv1])
|
|
|
ebb439 |
+AT_CLEANUP
|
|
|
ebb439 |
+
|
|
|
ebb439 |
# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
|
|
|
ebb439 |
AT_SETUP([ovn -- L2 Drop and Allow ACL w/ Stateful ACL])
|
|
|
ebb439 |
ovn_start
|
|
|
ebb439 |
--
|
|
|
ebb439 |
1.8.3.1
|
|
|
ebb439 |
|