@@ -1,5 +1,6 @@
Post-v20.09.0
---------------------
+ - ACL priority range changed from 0 - 32767 to 0 - 30000.
OVN v20.09.0 - xx xxx xxxx
@@ -5362,6 +5362,14 @@ build_acl_log(struct ds *actions, const struct nbrec_acl *acl)
ds_put_cstr(actions, "); ");
}
+static uint16_t
+acl_priority_base(uint16_t acl_priority)
+{
+ /* acl_priority range is 0 - 30000, so the resulted priority
+ * is between 1000 and 61000. */
+ return OVN_ACL_PRI_OFFSET + acl_priority * 2;
+}
+
static void
build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows,
enum ovn_stage stage, struct nbrec_acl *acl,
@@ -5384,7 +5392,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows,
ingress ? "next(pipeline=egress,table=5);"
: "next(pipeline=ingress,table=20);");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET + 10,
+ acl_priority_base(acl->priority) + 1,
ds_cstr(&match), ds_cstr(&actions), stage_hint);
ds_clear(&match);
ds_clear(&actions);
@@ -5399,7 +5407,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows,
ingress ? "next(pipeline=egress,table=5);"
: "next(pipeline=ingress,table=20);");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET + 10,
+ acl_priority_base(acl->priority) + 1,
ds_cstr(&match), ds_cstr(&actions), stage_hint);
/* IP traffic */
@@ -5419,7 +5427,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows,
ingress ? "next(pipeline=egress,table=5);"
: "next(pipeline=ingress,table=20);");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET,
+ acl_priority_base(acl->priority),
ds_cstr(&match), ds_cstr(&actions), stage_hint);
ds_clear(&match);
ds_clear(&actions);
@@ -5437,7 +5445,7 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows,
ingress ? "next(pipeline=egress,table=5);"
: "next(pipeline=ingress,table=20);");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET,
+ acl_priority_base(acl->priority),
ds_cstr(&match), ds_cstr(&actions), stage_hint);
ds_destroy(&match);
@@ -5463,7 +5471,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
build_acl_log(&actions, acl);
ds_put_cstr(&actions, "next;");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET,
+ acl_priority_base(acl->priority),
acl->match, ds_cstr(&actions),
&acl->header_);
ds_destroy(&actions);
@@ -5489,7 +5497,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
build_acl_log(&actions, acl);
ds_put_cstr(&actions, "next;");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET,
+ acl_priority_base(acl->priority),
ds_cstr(&match),
ds_cstr(&actions),
&acl->header_);
@@ -5508,7 +5516,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
build_acl_log(&actions, acl);
ds_put_cstr(&actions, "next;");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET,
+ acl_priority_base(acl->priority),
ds_cstr(&match), ds_cstr(&actions),
&acl->header_);
@@ -5536,7 +5544,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
build_acl_log(&actions, acl);
ds_put_cstr(&actions, "/* drop */");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET,
+ acl_priority_base(acl->priority),
ds_cstr(&match), ds_cstr(&actions),
&acl->header_);
}
@@ -5563,7 +5571,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
build_acl_log(&actions, acl);
ds_put_cstr(&actions, "/* drop */");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET,
+ acl_priority_base(acl->priority),
ds_cstr(&match), ds_cstr(&actions),
&acl->header_);
}
@@ -5578,7 +5586,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
build_acl_log(&actions, acl);
ds_put_cstr(&actions, "/* drop */");
ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET,
+ acl_priority_base(acl->priority),
acl->match, ds_cstr(&actions),
&acl->header_);
}
@@ -1,7 +1,7 @@
{
"name": "OVN_Northbound",
- "version": "5.27.0",
- "cksum": "3507518247 26773",
+ "version": "5.28.0",
+ "cksum": "3562758453 26773",
"tables": {
"NB_Global": {
"columns": {
@@ -211,7 +211,7 @@
"min": 0, "max": 1}},
"priority": {"type": {"key": {"type": "integer",
"minInteger": 0,
- "maxInteger": 32767}}},
+ "maxInteger": 30000}}},
"direction": {"type": {"key": {"type": "string",
"enum": ["set", ["from-lport", "to-lport"]]}}},
"match": {"type": "string"},
@@ -1646,10 +1646,10 @@
<column name="priority">
<p>
- The ACL rule's priority. Rules with numerically higher priority
- take precedence over those with lower. If two ACL rules with
- the same priority both match, then the one actually applied to a
- packet is undefined.
+ The ACL rule's priority, an integer between 0 and 30000. Rules with
+ numerically higher priority take precedence over those with lower. If
+ two ACL rules with the same priority both match, then the one actually
+ applied to a packet is undefined.
</p>
<p>
@@ -12817,13 +12817,19 @@ test_ipv6_packet() {
as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
}
-# test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
+# test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM
+# TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM [OUTPORT]
#
-# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
-# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
-# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
+# Causes a TCP packet to be sent from the INPORT. If the OUTPORT is specified,
+# the original packet is expected to be received at OUTPORT. Otherwise, a TCP
+# reset packet is expected to be received at INPORT.
#
-# INPORT is an lport number, e.g. 11 for vif11.
+# The packet is an TCP syn segment with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST,
+# IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified. EXP_IP_CHKSUM and
+# EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment
+# generated from ACL rule hit.
+#
+# INPORT and OUTPORT are lport numbers, e.g. 11 for vif11.
# HV is an hypervisor number
# ETH_SRC and ETH_DST are each 12 hex digits.
# IPV4_SRC and IPV4_DST are each 8 hex digits.
@@ -12834,13 +12840,20 @@ test_tcp_syn_packet() {
local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
shift 12
+ local outport=$1
local ip_ttl=ff
local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
- local tcp_rst_ttl=3f
- local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ipv4_dst}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000250140000${exp_tcp_rst_chksum}0000
- echo $reply >> vif$inport.expected
+ if test x$outport == x; then
+ echo TCPRESET
+ local tcp_rst_ttl=3f
+ local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ipv4_dst}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000250140000${exp_tcp_rst_chksum}0000
+ echo $reply >> vif$inport.expected
+ else
+ echo ORIGINAL
+ echo $packet >> vif$outport.expected
+ fi
as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
}
@@ -12886,6 +12899,10 @@ ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
+# A higher priority rule that allows all traffic sent from p21 to dst IP of p31
+ovn-nbctl --log acl-add sw0 from-lport 1001 "inport == \"sw0-p21\"
+ && ip4.dst == 192.168.1.31" allow
+
# Allow some time for ovn-northd and ovn-controller to catch up.
ovn-nbctl --timeout=3 --wait=hv sync
@@ -12899,6 +12916,10 @@ test_tcp_syn_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(i
test_tcp_syn_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 8b40 3039 0000 b85f 70e4
test_tcp_syn_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 8b40 3039 0000 b854 70d9
+# From p21 to p31, the packet should be received in p31, because of the last
+# rule.
+test_tcp_syn_packet 21 2 000000000021 000000000031 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 31) 0000 8b40 3039 0000 b854 70d9 31
+
for i in 1 2 3; do
OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
done
When there "reject" is used as ACL action, there are logical flows generated to handle TCP and non-TCP packets separately, so that tcp_reset is used to reject TCP packets while ICMP is used to reject non-TCP packets. The current implementation uses priority OVN_ACL_PRI_OFFSET + acl_priroity + 10 for handling TCP packets, while OVN_ACL_PRI_OFFSET + acl_priroity for non-TCP packets. This can cause the ACL priorities defined by users incorrectly handled. For example, a user creates two ACLs: 1. priority: 1001, match: tcp.dst == 443, action: allow 2. priority: 1000, match: any, action: reject The generates lflows would be: 1. priority: 2010, match: any, action: tcp_reset 2. priority: 2001, match: tcp.dst == 443, action: allow 3. priority: 2000, match: any, action: icmp Now if a TCP packet with dst port 443 comes, it will be rejected. This patch fixes the problem by using OVN_ACL_PRI_OFFSET + acl_priority * 2 + 1 as flow priority for the tcp_reset flow, and OVN_ACL_PRI_OFFSET + acl_priority * 2 for other ACL related flows including the ICMP flows. Fixes: 366ac0d89 ("OVN: add tcp_reset action to ovn acl reject support") Signed-off-by: Han Zhou <hzhou@ovn.org> --- NEWS | 1 + northd/ovn-northd.c | 28 ++++++++++++++++++---------- ovn-nb.ovsschema | 6 +++--- ovn-nb.xml | 8 ++++---- tests/ovn.at | 37 +++++++++++++++++++++++++++++-------- 5 files changed, 55 insertions(+), 25 deletions(-)