Sync from SUSE:SLFO:Main openvswitch revision 20c867be36de7426f256ac42e4295585

This commit is contained in:
Adrian Schröter 2024-10-11 10:06:10 +02:00
parent a94b355a87
commit 841364742a
9 changed files with 84 additions and 670 deletions

View File

@ -1,517 +0,0 @@
commit 9d840923d32124fe427de76e8234c49d64e4bb77
Author: Aaron Conole <aconole@redhat.com>
Date: Fri Mar 31 17:17:27 2023 -0400
ofproto-dpif-xlate: Always mask ip proto field.
The ofproto layer currently treats nw_proto field as overloaded to mean
both that a proper nw layer exists, as well as the value contained in
the header for the nw proto. However, this is incorrect behavior as
relevant standards permit that any value, including '0' should be treated
as a valid value.
Because of this overload, when the ofproto layer builds action list for
a packet with nw_proto of 0, it won't build the complete action list that
we expect to be built for the packet. That will cause a bad behavior
where all packets passing the datapath will fall into an incomplete
action set.
The fix here is to unwildcard nw_proto, allowing us to preserve setting
actions for protocols which we know have support for the actions we
program. This means that a traffic which contains nw_proto == 0 cannot
cause connectivity breakage with other traffic on the link.
Reported-by: David Marchand <dmarchand@redhat.com>
Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2134873
Acked-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Aaron Conole <aconole@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
diff --git a/include/openvswitch/meta-flow.h b/include/openvswitch/meta-flow.h
index 045dce8f5..3b0220aaa 100644
--- a/include/openvswitch/meta-flow.h
+++ b/include/openvswitch/meta-flow.h
@@ -2366,6 +2366,10 @@ void mf_format_subvalue(const union mf_subvalue *subvalue, struct ds *s);
void field_array_set(enum mf_field_id id, const union mf_value *,
struct field_array *);
+/* Mask the required l3 prerequisites if a 'set' action occurs. */
+void mf_set_mask_l3_prereqs(const struct mf_field *, const struct flow *,
+ struct flow_wildcards *);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index c576ae620..474344194 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -3676,3 +3676,28 @@ mf_bitmap_not(struct mf_bitmap x)
bitmap_not(x.bm, MFF_N_IDS);
return x;
}
+
+void
+mf_set_mask_l3_prereqs(const struct mf_field *mf, const struct flow *fl,
+ struct flow_wildcards *wc)
+{
+ if (is_ip_any(fl) &&
+ ((mf->id == MFF_IPV4_SRC) ||
+ (mf->id == MFF_IPV4_DST) ||
+ (mf->id == MFF_IPV6_SRC) ||
+ (mf->id == MFF_IPV6_DST) ||
+ (mf->id == MFF_IPV6_LABEL) ||
+ (mf->id == MFF_IP_DSCP) ||
+ (mf->id == MFF_IP_ECN) ||
+ (mf->id == MFF_IP_TTL))) {
+ WC_MASK_FIELD(wc, nw_proto);
+ } else if ((fl->dl_type == htons(ETH_TYPE_ARP)) &&
+ ((mf->id == MFF_ARP_OP) ||
+ (mf->id == MFF_ARP_SHA) ||
+ (mf->id == MFF_ARP_THA) ||
+ (mf->id == MFF_ARP_SPA) ||
+ (mf->id == MFF_ARP_TPA))) {
+ /* mask only the lower 8 bits. */
+ wc->masks.nw_proto = 0xff;
+ }
+}
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index a9cf3cbee..cffd733c5 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -5211,6 +5211,7 @@ compose_dec_ttl(struct xlate_ctx *ctx, struct ofpact_cnt_ids *ids)
}
ctx->wc->masks.nw_ttl = 0xff;
+ WC_MASK_FIELD(ctx->wc, nw_proto);
if (flow->nw_ttl > 1) {
flow->nw_ttl--;
return false;
@@ -7128,6 +7129,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
case OFPACT_SET_IPV4_SRC:
if (flow->dl_type == htons(ETH_TYPE_IP)) {
memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src);
+ WC_MASK_FIELD(wc, nw_proto);
flow->nw_src = ofpact_get_SET_IPV4_SRC(a)->ipv4;
}
break;
@@ -7135,12 +7137,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
case OFPACT_SET_IPV4_DST:
if (flow->dl_type == htons(ETH_TYPE_IP)) {
memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst);
+ WC_MASK_FIELD(wc, nw_proto);
flow->nw_dst = ofpact_get_SET_IPV4_DST(a)->ipv4;
}
break;
case OFPACT_SET_IP_DSCP:
if (is_ip_any(flow)) {
+ WC_MASK_FIELD(wc, nw_proto);
wc->masks.nw_tos |= IP_DSCP_MASK;
flow->nw_tos &= ~IP_DSCP_MASK;
flow->nw_tos |= ofpact_get_SET_IP_DSCP(a)->dscp;
@@ -7149,6 +7153,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
case OFPACT_SET_IP_ECN:
if (is_ip_any(flow)) {
+ WC_MASK_FIELD(wc, nw_proto);
wc->masks.nw_tos |= IP_ECN_MASK;
flow->nw_tos &= ~IP_ECN_MASK;
flow->nw_tos |= ofpact_get_SET_IP_ECN(a)->ecn;
@@ -7157,6 +7162,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
case OFPACT_SET_IP_TTL:
if (is_ip_any(flow)) {
+ WC_MASK_FIELD(wc, nw_proto);
wc->masks.nw_ttl = 0xff;
flow->nw_ttl = ofpact_get_SET_IP_TTL(a)->ttl;
}
@@ -7224,6 +7230,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
/* Set the field only if the packet actually has it. */
if (mf_are_prereqs_ok(mf, flow, wc)) {
+ mf_set_mask_l3_prereqs(mf, flow, wc);
mf_mask_field_masked(mf, ofpact_set_field_mask(set_field), wc);
mf_set_flow_value_masked(mf, set_field->value,
ofpact_set_field_mask(set_field),
@@ -7280,6 +7287,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
case OFPACT_DEC_TTL:
wc->masks.nw_ttl = 0xff;
+ WC_MASK_FIELD(wc, nw_proto);
if (compose_dec_ttl(ctx, ofpact_get_DEC_TTL(a))) {
return;
}
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index fa6111c1e..62291de4a 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -849,7 +849,7 @@ table=2 ip actions=set_field:192.168.3.91->ip_src,output(11)
AT_CHECK([ovs-ofctl -O OpenFlow12 add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,nw_frag=no,icmp_type=8,icmp_code=0'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,eth,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
+ [Megaflow: recirc_id=0,eth,icmp,in_port=1,nw_src=192.168.0.1,nw_frag=no
Datapath actions: 10,set(ipv4(src=192.168.3.91)),11,set(ipv4(src=192.168.3.90)),13
])
OVS_VSWITCHD_STOP
@@ -912,7 +912,7 @@ AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_ds
# Must match on the source address to be able to restore it's value for
# the second bucket
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,eth,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
+ [Megaflow: recirc_id=0,eth,icmp,in_port=1,nw_src=192.168.0.1,nw_frag=no
Datapath actions: set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),11
])
OVS_VSWITCHD_STOP
@@ -944,7 +944,7 @@ done
AT_CHECK([ovs-appctl dpctl/dump-flows | sed 's/dp_hash(.*\/0xf)/dp_hash(0xXXXX\/0xf)/' | sed 's/packets.*actions:/actions:/' | strip_ufid | strip_used | sort], [0], [dnl
flow-dump from the main thread:
recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), actions:hash(sym_l4(0)),recirc(0x1)
-recirc_id(0x1),dp_hash(0xXXXX/0xf),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(src=192.168.0.1,frag=no), actions:set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),10
+recirc_id(0x1),dp_hash(0xXXXX/0xf),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(src=192.168.0.1,proto=1,frag=no), actions:set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),10
])
OVS_VSWITCHD_STOP
@@ -959,7 +959,7 @@ AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_ds
# Must match on the source address to be able to restore it's value for
# the third bucket
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,eth,ip,in_port=1,nw_src=192.168.0.1,nw_frag=no
+ [Megaflow: recirc_id=0,eth,icmp,in_port=1,nw_src=192.168.0.1,nw_frag=no
Datapath actions: set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),11
])
OVS_VSWITCHD_STOP
@@ -1536,17 +1536,17 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=111,tos=0,ttl=2,frag=no)' -generate], [0], [stdout])
AT_CHECK([tail -4 stdout], [0], [
Final flow: ip,in_port=1,vlan_tci=0x0000,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=111,nw_tos=0,nw_ecn=0,nw_ttl=1,nw_frag=no
-Megaflow: recirc_id=0,eth,ip,in_port=1,nw_ttl=2,nw_frag=no
+Megaflow: recirc_id=0,eth,ip,in_port=1,nw_proto=111,nw_ttl=2,nw_frag=no
Datapath actions: set(ipv4(ttl=1)),2,userspace(pid=0,controller(reason=2,dont_send=0,continuation=0,recirc_id=1,rule_cookie=0,controller_id=0,max_len=65535)),4
])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=111,tos=0,ttl=3,frag=no)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,eth,ip,in_port=1,nw_ttl=3,nw_frag=no
+ [Megaflow: recirc_id=0,eth,ip,in_port=1,nw_proto=111,nw_ttl=3,nw_frag=no
Datapath actions: set(ipv4(ttl=2)),2,set(ipv4(ttl=1)),3,4
])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x86dd),ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=128,frag=no)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,eth,ipv6,in_port=1,nw_ttl=128,nw_frag=no
+ [Megaflow: recirc_id=0,eth,ipv6,in_port=1,nw_proto=10,nw_ttl=128,nw_frag=no
Datapath actions: set(ipv6(hlimit=127)),2,set(ipv6(hlimit=126)),3,4
])
@@ -1656,7 +1656,7 @@ AT_CHECK([ovs-vsctl -- \
--id=@q2 create Queue dscp=2], [0], [ignore])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(9),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0xff,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
- [Megaflow: recirc_id=0,skb_priority=0,eth,ip,in_port=9,nw_tos=252,nw_frag=no
+ [Megaflow: recirc_id=0,skb_priority=0,eth,icmp,in_port=9,nw_tos=252,nw_frag=no
Datapath actions: dnl
100,dnl
set(ipv4(tos=0x4/0xfc)),set(skb_priority(0x1)),1,dnl
@@ -8777,12 +8777,12 @@ recirc_id(0),in_port(3),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), p
])
AT_CHECK([ovs-appctl dpif/dump-flows -m br0 | strip_ufid | strip_used | sort], [0], [dnl
-skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(p1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), packets:0, bytes:0, used:never, actions:drop
-skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(p2),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=0/0,code=0/0), packets:0, bytes:0, used:never, actions:drop
+recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(p1),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), packets:0, bytes:0, used:never, actions:drop
+recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(p2),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=0/0,code=0/0), packets:0, bytes:0, used:never, actions:drop
])
AT_CHECK([ovs-appctl dpif/dump-flows -m br1 | strip_ufid | strip_used | sort], [0], [dnl
-skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(p3),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), packets:0, bytes:0, used:never, actions:drop
+recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(p3),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), packets:0, bytes:0, used:never, actions:drop
])
OVS_VSWITCHD_STOP
@@ -8942,10 +8942,10 @@ recirc_id(0),in_port(101),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no),
])
AT_CHECK([grep -e 'in_port(100).*packets:9' ovs-vswitchd.log | strip_ufid | filter_flow_dump], [0], [dnl
-skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(100),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), packets:9, bytes:954, used:0.0s, actions:101,3,2
+recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(100),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), packets:9, bytes:954, used:0.0s, actions:101,3,2
])
AT_CHECK([grep -e 'in_port(101).*packets:4' ovs-vswitchd.log | strip_ufid | filter_flow_dump], [0], [dnl
-skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(101),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), packets:4, bytes:424, used:0.0s, actions:100,2,3
+recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(101),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no),icmp(type=8/0,code=0/0), packets:4, bytes:424, used:0.0s, actions:100,2,3
])
AT_CHECK([ovs-ofctl dump-ports br0 pbr0], [0], [dnl
@@ -9637,12 +9637,12 @@ table=0 in_port=1,ip,nw_dst=10.0.0.3 actions=drop
done
sleep 1
AT_CHECK([strip_ufid < ovs-vswitchd.log | filter_flow_install | strip_used], [0], [dnl
-skb_priority(0),skb_mark(0),ct_state(-new-est-rel-rpl-inv-trk-snat-dnat),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), actions:2
-skb_priority(0),skb_mark(0),ct_state(-new-est-rel-rpl-inv-trk-snat-dnat),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), actions:drop
+recirc_id(0),dp_hash(0),skb_priority(0),in_port(1),skb_mark(0),ct_state(-new-est-rel-rpl-inv-trk-snat-dnat),ct_zone(0),ct_mark(0),ct_label(0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), actions:2
+recirc_id(0),dp_hash(0),skb_priority(0),in_port(1),skb_mark(0),ct_state(-new-est-rel-rpl-inv-trk-snat-dnat),ct_zone(0),ct_mark(0),ct_label(0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), actions:drop
])
AT_CHECK([strip_ufid < ovs-vswitchd.log | filter_flow_dump | grep 'packets:3'], [0], [dnl
-skb_priority(0),skb_mark(0),ct_state(0/0xff),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:3, bytes:318, used:0.0s, actions:2
-skb_priority(0),skb_mark(0),ct_state(0/0xff),ct_zone(0),ct_mark(0),ct_label(0),recirc_id(0),dp_hash(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:3, bytes:318, used:0.0s, actions:drop
+recirc_id(0),dp_hash(0),skb_priority(0),in_port(1),skb_mark(0),ct_state(0/0xff),ct_zone(0),ct_mark(0),ct_label(0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:3, bytes:318, used:0.0s, actions:2
+recirc_id(0),dp_hash(0),skb_priority(0),in_port(1),skb_mark(0),ct_state(0/0xff),ct_zone(0),ct_mark(0),ct_label(0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0), packets:3, bytes:318, used:0.0s, actions:drop
])
OVS_VSWITCHD_STOP
AT_CLEANUP])
@@ -10344,7 +10344,7 @@ recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x1234), packets:5, byte
])
AT_CHECK([grep 'modify' ovs-vswitchd.log | strip_ufid ], [0], [dnl
-dpif|DBG|dummy@ovs-dummy: put[[modify]] skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x1234), actions:push_vlan(vid=4,pcp=0),100
+dpif|DBG|dummy@ovs-dummy: put[[modify]] recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(1),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x1234), actions:push_vlan(vid=4,pcp=0),100
])
OVS_VSWITCHD_STOP
AT_CLEANUP
@@ -10425,8 +10425,8 @@ recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x8100),vlan(vid=99,pcp=
# are wildcarded.
AT_CHECK([grep '\(modify\)\|\(flow_add\)' ovs-vswitchd.log | strip_ufid ], [0], [dnl
dpif_netdev|DBG|flow_add: recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x1234), actions:100
-dpif|DBG|dummy@ovs-dummy: put[[modify]] skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x1234), actions:drop
-dpif|DBG|dummy@ovs-dummy: put[[modify]] skb_priority(0/0),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),recirc_id(0),dp_hash(0/0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x1234), actions:100
+dpif|DBG|dummy@ovs-dummy: put[[modify]] recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(1),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x1234), actions:drop
+dpif|DBG|dummy@ovs-dummy: put[[modify]] recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(1),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x1234), actions:100
dpif_netdev|DBG|flow_add: recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x8100),vlan(vid=99,pcp=7/0x0),encap(eth_type(0x1234)), actions:drop
])
OVS_VSWITCHD_STOP
@@ -10752,10 +10752,10 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 'in_port(2),eth(src=50:54:00:00:00:
AT_CHECK([cat ovs-vswitchd.log | strip_ufid | filter_flow_install], [0], [dnl
-ct_state(+new-est+trk),recirc_id(0x1),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), actions:drop
-ct_state(-new+est+trk),recirc_id(0x1),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=no), actions:1
recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=no), actions:ct(commit),2
recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=no), actions:ct,recirc(0x1)
+recirc_id(0x1),in_port(2),ct_state(+new-est+trk),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), actions:drop
+recirc_id(0x1),in_port(2),ct_state(-new+est+trk),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=no), actions:1
])
OVS_VSWITCHD_STOP
@@ -11161,9 +11161,9 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 'in_port(2),eth(src=50:54:00:00:00:
ovs-appctl revalidator/wait
AT_CHECK([cat ovs-vswitchd.log | strip_ufid | filter_flow_install], [0], [dnl
-ct_state(+rpl+trk),ct_label(0x1),recirc_id(0x1),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), actions:1
recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=17,frag=no),udp(src=1), actions:ct(commit,label=0x1),2
recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), actions:ct,recirc(0x1)
+recirc_id(0x1),in_port(2),ct_state(+rpl+trk),ct_label(0x1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), actions:1
])
OVS_VSWITCHD_STOP
@@ -11884,7 +11884,7 @@ ovs-ofctl dump-flows br0
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.10.10.2,dst=10.10.10.1,proto=1,tos=1,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
AT_CHECK([tail -3 stdout], [0], [dnl
-Megaflow: recirc_id=0,eth,ip,reg0=0/0x1,in_port=1,nw_src=10.10.10.2,nw_frag=no
+Megaflow: recirc_id=0,eth,icmp,reg0=0/0x1,in_port=1,nw_src=10.10.10.2,nw_frag=no
Datapath actions: drop
Translation failed (Recursion too deep), packet is dropped.
])
diff --git a/tests/ofproto.at b/tests/ofproto.at
index a666bebca..2fa8486a8 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -6538,3 +6538,185 @@ verify_deleted
OVS_VSWITCHD_STOP(["/<invalid/d"])
AT_CLEANUP
+
+AT_SETUP([ofproto - implicit mask of ipv4 proto with invalid proto field])
+OVS_VSWITCHD_START
+add_of_ports br0 1 2
+
+AT_DATA([flows.txt], [dnl
+table=0 in_port=1 priority=90,ip,nw_dst=192.168.1.20,actions=mod_nw_dst:192.168.20.20,output=2
+table=0 in_port=1 priority=89,ip,nw_dst=192.168.1.21,actions=mod_nw_src:192.168.20.21,output=2
+table=0 in_port=1 priority=88,ip,nw_dst=192.168.1.10,actions=dec_ttl,output=2
+table=0 in_port=1 priority=87,ip,nw_dst=192.168.1.19,actions=mod_nw_ttl:8,output=2
+table=0 in_port=1 priority=86,ip,nw_dst=192.168.1.18,actions=mod_nw_ecn:2,output=2
+table=0 in_port=1 priority=85,ip,nw_dst=192.168.1.17,actions=mod_nw_tos:0x40,output=2
+table=0 in_port=1 priority=84,ip,nw_dst=192.168.1.16,actions=set_field:192.168.20.26->nw_dst,output=2
+table=0 in_port=1 priority=83,ip,nw_dst=192.168.1.15,actions=set_field:192.168.21.26->nw_src,output=2
+table=0 in_port=1 priority=82,ip,nw_dst=192.168.1.14,actions=set_field:0x40->nw_tos,output=2
+table=0 in_port=1 priority=0,actions=drop
+])
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+dnl send a proto 0 packet to try and poison the DP flow path
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 \
+ '5054000000075054000000050800450000548de140004000289fc0a801c4c0a8011408003bf60002001bbf080a640000000032ad010000000000101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637'])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows], [0], [dnl
+flow-dump from the main thread:
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.1.20,proto=0,frag=no), packets:0, bytes:0, used:never, actions:2
+])
+
+dnl Send ICMP for mod nw_src and mod nw_dst
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.21,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.20,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
+
+dnl send ICMP that will dec TTL
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.10,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
+
+dnl send ICMP that will mod TTL
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.19,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
+
+dnl send ICMP that will mod ECN
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.18,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
+
+dnl send ICMP that will mod TOS
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.17,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
+
+dnl send ICMP that will set DST
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.16,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
+
+dnl send ICMP that will set SRC
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.15,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
+
+dnl send ICMP that will set TOS
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.14,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows | sort], [0], [dnl
+flow-dump from the main thread:
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.1.10,proto=1,ttl=64,frag=no), packets:0, bytes:0, used:never, actions:set(ipv4(ttl=63)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.1.14,proto=1,tos=0/0xfc,frag=no), packets:0, bytes:0, used:never, actions:set(ipv4(tos=0x40/0xfc)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.1.16,proto=1,frag=no), packets:0, bytes:0, used:never, actions:set(ipv4(dst=192.168.20.26)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.1.17,proto=1,tos=0/0xfc,frag=no), packets:0, bytes:0, used:never, actions:set(ipv4(tos=0x40/0xfc)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.1.18,proto=1,tos=0/0x3,frag=no), packets:0, bytes:0, used:never, actions:set(ipv4(tos=0x2/0x3)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.1.19,proto=1,ttl=64,frag=no), packets:0, bytes:0, used:never, actions:set(ipv4(ttl=8)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.1.20,proto=0,frag=no), packets:0, bytes:0, used:never, actions:2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.1.20,proto=1,frag=no), packets:0, bytes:0, used:never, actions:set(ipv4(dst=192.168.20.20)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.15,proto=1,frag=no), packets:0, bytes:0, used:never, actions:set(ipv4(src=192.168.21.26)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.1.21,proto=1,frag=no), packets:0, bytes:0, used:never, actions:set(ipv4(src=192.168.20.21)),2
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([ofproto - implicit mask of ipv6 proto with HOPOPT field])
+OVS_VSWITCHD_START
+add_of_ports br0 1 2
+
+AT_DATA([flows.txt], [dnl
+table=0 in_port=1 priority=77,ip6,ipv6_dst=111:db8::3,actions=dec_ttl,output=2
+table=0 in_port=1 priority=76,ip6,ipv6_dst=111:db8::4,actions=mod_nw_ttl:8,output=2
+table=0 in_port=1 priority=75,ip6,ipv6_dst=111:db8::5,actions=mod_nw_ecn:2,output=2
+table=0 in_port=1 priority=74,ip6,ipv6_dst=111:db8::6,actions=mod_nw_tos:0x40,output=2
+table=0 in_port=1 priority=73,ip6,ipv6_dst=111:db8::7,actions=set_field:2112:db8::2->ipv6_dst,output=2
+table=0 in_port=1 priority=72,ip6,ipv6_dst=111:db8::8,actions=set_field:2112:db8::3->ipv6_src,output=2
+table=0 in_port=1 priority=72,ip6,ipv6_dst=111:db8::9,actions=set_field:44->ipv6_label,output=2
+table=0 in_port=1 priority=0,actions=drop
+])
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+dnl send a proto 0 packet to try and poison the DP flow path
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x86dd),ipv6(src=2001:db8::1,dst=111:db8::3,proto=0,tclass=0,hlimit=64,frag=no)'])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows], [0], [dnl
+flow-dump from the main thread:
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x86dd),ipv6(dst=111:db8::3,proto=0,hlimit=0,frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,controller(reason=2,dont_send=0,continuation=0,recirc_id=1,rule_cookie=0,controller_id=0,max_len=65535))
+])
+
+dnl Send ICMP for mod nw_src and mod nw_dst
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x86dd),ipv6(src=2001:db8::1,dst=111:db8::3,proto=1,tclass=0,hlimit=64,frag=no),icmpv6(type=0,code=8)'])
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x86dd),ipv6(src=2001:db8::1,dst=111:db8::4,proto=1,tclass=0,hlimit=64,frag=no),icmpv6(type=0,code=8)'])
+
+dnl send ICMP that will dec TTL
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x86dd),ipv6(src=2001:db8::1,dst=111:db8::5,proto=1,tclass=0,hlimit=64,frag=no),icmpv6(type=0,code=8)'])
+
+dnl send ICMP that will mod TTL
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x86dd),ipv6(src=2001:db8::1,dst=111:db8::6,proto=1,tclass=0,hlimit=64,frag=no),icmpv6(type=0,code=8)'])
+
+dnl send ICMP that will mod ECN
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x86dd),ipv6(src=2001:db8::1,dst=111:db8::7,proto=1,tclass=0,hlimit=64,frag=no),icmpv6(type=0,code=8)'])
+
+dnl send ICMP that will mod TOS
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x86dd),ipv6(src=2001:db8::1,dst=111:db8::8,proto=1,tclass=0,hlimit=64,frag=no),icmpv6(type=0,code=8)'])
+
+dnl send ICMP that will set LABEL
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x86dd),ipv6(src=2001:db8::1,dst=111:db8::9,proto=1,tclass=0,hlimit=64,frag=no),icmpv6(type=0,code=8)'])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows | sort], [0], [dnl
+flow-dump from the main thread:
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x86dd),ipv6(dst=111:db8::3,proto=0,hlimit=0,frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,controller(reason=2,dont_send=0,continuation=0,recirc_id=1,rule_cookie=0,controller_id=0,max_len=65535))
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x86dd),ipv6(dst=111:db8::3,proto=1,hlimit=64,frag=no), packets:0, bytes:0, used:never, actions:set(ipv6(hlimit=63)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x86dd),ipv6(dst=111:db8::4,proto=1,hlimit=64,frag=no), packets:0, bytes:0, used:never, actions:set(ipv6(hlimit=8)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x86dd),ipv6(dst=111:db8::5,proto=1,tclass=0/0x3,frag=no), packets:0, bytes:0, used:never, actions:set(ipv6(tclass=0x2/0x3)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x86dd),ipv6(dst=111:db8::6,proto=1,tclass=0/0xfc,frag=no), packets:0, bytes:0, used:never, actions:set(ipv6(tclass=0x40/0xfc)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x86dd),ipv6(dst=111:db8::7,proto=1,frag=no), packets:0, bytes:0, used:never, actions:set(ipv6(dst=2112:db8::2)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x86dd),ipv6(dst=111:db8::9,label=0,proto=1,frag=no), packets:0, bytes:0, used:never, actions:set(ipv6(label=0x2c)),2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x86dd),ipv6(src=2001:db8::1,dst=111:db8::8,proto=1,frag=no), packets:0, bytes:0, used:never, actions:set(ipv6(src=2112:db8::3)),2
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([ofproto - implicit mask of ARP OPer field])
+OVS_VSWITCHD_START
+add_of_ports br0 1 2
+
+AT_DATA([flows.txt], [dnl
+table=0 in_port=1 priority=77,arp,arp_sha=00:01:02:03:04:06,actions=set_field:0x1->arp_op,2
+table=0 in_port=1 priority=76,arp,arp_sha=00:01:02:03:04:07,actions=set_field:00:02:03:04:05:06->arp_sha,2
+table=0 in_port=1 priority=75,arp,arp_sha=00:01:02:03:04:08,actions=set_field:ff:00:00:00:00:ff->arp_tha,2
+table=0 in_port=1 priority=74,arp,arp_sha=00:01:02:03:04:09,actions=set_field:172.31.110.26->arp_spa,2
+table=0 in_port=1 priority=73,arp,arp_sha=00:01:02:03:04:0a,actions=set_field:172.31.110.10->arp_tpa,2
+table=0 in_port=1 priority=1,actions=drop
+])
+
+AT_CHECK([ovs-ofctl del-flows br0])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+dnl Send op == 0 packet
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 \
+ 'ffffffffffffaa55aa550000080600010800060400000001020304070c0a00010000000000000c0a0002'])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows], [0], [dnl
+flow-dump from the main thread:
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0806),arp(op=0,sha=00:01:02:03:04:07), packets:0, bytes:0, used:never, actions:2
+])
+
+dnl Send op 2 -> set op
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0806),arp(sip=172.31.110.1,tip=172.31.110.25,op=2,sha=00:01:02:03:04:06,tha=ff:ff:ff:ff:ff:ff)'])
+
+dnl Send op 1 -> set SHA
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0806),arp(sip=172.31.110.1,tip=172.31.110.25,op=1,sha=00:01:02:03:04:07,tha=ff:ff:ff:ff:ff:ff)'])
+
+dnl Send op 1 -> set THA
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0806),arp(sip=172.31.110.1,tip=172.31.110.25,op=1,sha=00:01:02:03:04:08,tha=ff:ff:ff:ff:ff:ff)'])
+
+dnl Send op 1 -> set SIP
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0806),arp(sip=172.31.110.1,tip=172.31.110.25,op=1,sha=00:01:02:03:04:09,tha=ff:ff:ff:ff:ff:ff)'])
+
+dnl Send op 1 -> set TIP
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0806),arp(sip=172.31.110.1,tip=172.31.110.25,op=1,sha=00:01:02:03:04:0a,tha=ff:ff:ff:ff:ff:ff)'])
+
+AT_CHECK([ovs-appctl dpctl/dump-flows | sort], [0], [dnl
+flow-dump from the main thread:
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0806),arp(op=0,sha=00:01:02:03:04:07), packets:0, bytes:0, used:never, actions:2
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0806),arp(op=1,sha=00:01:02:03:04:07), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(action))
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0806),arp(op=1,sha=00:01:02:03:04:08,tha=ff:ff:ff:ff:ff:ff), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(action))
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0806),arp(op=2,sha=00:01:02:03:04:06), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(action))
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0806),arp(sip=172.31.110.1,op=1,sha=00:01:02:03:04:09), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(action))
+recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0806),arp(tip=172.31.110.25,op=1,sha=00:01:02:03:04:0a), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(action))
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
diff --git a/tests/packet-type-aware.at b/tests/packet-type-aware.at
index 3b5c66fe5..d63528e69 100644
--- a/tests/packet-type-aware.at
+++ b/tests/packet-type-aware.at
@@ -1021,7 +1021,7 @@ AT_CHECK([
], [0], [flow-dump from the main thread:
recirc_id(0),in_port(p0),packet_type(ns=0,id=0),eth(src=aa:bb:cc:00:00:02,dst=aa:bb:cc:00:00:01),eth_type(0x0800),ipv4(dst=20.0.0.1,proto=47,frag=no), packets:3, bytes:378, used:0.0s, actions:tnl_pop(gre_sys)
tunnel(src=20.0.0.2,dst=20.0.0.1,flags(-df-csum)),recirc_id(0),in_port(gre_sys),packet_type(ns=1,id=0x8847),eth_type(0x8847),mpls(label=999/0x0,tc=0/0,ttl=64/0x0,bos=1/1), packets:3, bytes:264, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=00:00:00:00:00:00),pop_mpls(eth_type=0x800),recirc(0x1)
-tunnel(src=20.0.0.2,dst=20.0.0.1,flags(-df-csum)),recirc_id(0x1),in_port(gre_sys),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(ttl=64,frag=no), packets:3, bytes:294, used:0.0s, actions:set(ipv4(ttl=63)),int-br
+tunnel(src=20.0.0.2,dst=20.0.0.1,flags(-df-csum)),recirc_id(0x1),in_port(gre_sys),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(proto=1,ttl=64,frag=no), packets:3, bytes:294, used:0.0s, actions:set(ipv4(ttl=63)),int-br
])
ovs-appctl time/warp 1000

View File

@ -1,121 +0,0 @@
commit 9a3f7ed905e525ebdcb14541e775211cbb0203bd
Author: Ales Musil <amusil@redhat.com>
Date: Wed Jul 12 07:12:29 2023 +0200
northd, controller: Add CoPP for SVC monitor
The SVC monitor was exposed without any limitation.
Add CoPP for the SVC monitor flow, which adds a way
for CMSs to limit the traffic that this flow accepts.
Signed-off-by: Ales Musil <amusil@redhat.com>
diff --git a/lib/copp.c b/lib/copp.c
index 603e3f5bf..11dd9029d 100644
--- a/lib/copp.c
+++ b/lib/copp.c
@@ -38,6 +38,7 @@ static char *copp_proto_names[COPP_PROTO_MAX] = {
[COPP_ND_RA_OPTS] = "nd-ra-opts",
[COPP_TCP_RESET] = "tcp-reset",
[COPP_REJECT] = "reject",
+ [COPP_SVC_MONITOR] = "svc-monitor",
[COPP_BFD] = "bfd",
};
diff --git a/lib/copp.h b/lib/copp.h
index f03004aa6..b99737220 100644
--- a/lib/copp.h
+++ b/lib/copp.h
@@ -37,6 +37,7 @@ enum copp_proto {
COPP_TCP_RESET,
COPP_BFD,
COPP_REJECT,
+ COPP_SVC_MONITOR,
COPP_PROTO_MAX,
COPP_PROTO_INVALID = COPP_PROTO_MAX,
};
diff --git a/northd/northd.c b/northd/northd.c
index 7ad4cdfad..1e05b8f22 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -8876,9 +8876,11 @@ build_lswitch_destination_lookup_bmcast(struct ovn_datapath *od,
{
if (od->nbs) {
- ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 110,
- "eth.dst == $svc_monitor_mac",
- "handle_svc_check(inport);");
+ ovn_lflow_metered(lflows, od, S_SWITCH_IN_L2_LKUP, 110, "eth.dst == "
+ "$svc_monitor_mac && (tcp || icmp || icmp6)",
+ "handle_svc_check(inport);",
+ copp_meter_get(COPP_SVC_MONITOR, od->nbs->copp,
+ meter_groups));
struct mcast_switch_info *mcast_sw_info = &od->mcast_info.sw;
diff --git a/ovn-nb.xml b/ovn-nb.xml
index 35acda107..59ac42dbd 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -466,6 +466,10 @@
<column name="meters" key="reject">
Rate limiting meter for packets that trigger a reject action
</column>
+ <column name="meters" key="svc-monitor">
+ Rate limiting meter for packets that are arriving to service
+ monitor MAC address.
+ </column>
<column name="external_ids">
See <em>External IDs</em> at the beginning of this document.
</column>
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index b8376991b..70350a781 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -3544,7 +3544,7 @@ AT_CHECK([ovn-sbctl list logical_flow | grep trigger_event -A 2 | grep -q meter0
# let's try to add an usupported protocol "dhcp"
AT_CHECK([ovn-nbctl --wait=hv copp-add copp5 dhcp meter1],[1],[],[dnl
-ovn-nbctl: Invalid control protocol. Allowed values: arp, arp-resolve, dhcpv4-opts, dhcpv6-opts, dns, event-elb, icmp4-error, icmp6-error, igmp, nd-na, nd-ns, nd-ns-resolve, nd-ra-opts, tcp-reset, bfd, reject.
+ovn-nbctl: Invalid control protocol. Allowed values: arp, arp-resolve, dhcpv4-opts, dhcpv6-opts, dns, event-elb, icmp4-error, icmp6-error, igmp, nd-na, nd-ns, nd-ns-resolve, nd-ra-opts, tcp-reset, bfd, reject, svc-monitor.
])
#Let's try to add a valid protocol to an unknown datapath
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index f8131b90e..7c009e157 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -7282,6 +7282,23 @@ OVS_WAIT_UNTIL([
])
kill $(pidof tcpdump)
+check ovn-nbctl set nb_global . options:svc_monitor_mac="33:33:33:33:33:33"
+check ovn-nbctl meter-add svc-meter drop 1 pktps 0
+check ovn-nbctl --wait=hv copp-add copp4 svc-monitor svc-meter
+check ovn-nbctl --wait=hv ls-copp-add copp4 sw0
+check ovn-appctl -t ovn-controller vlog/set vconn:dbg
+AT_CHECK([ovn-nbctl copp-list copp4], [0], [dnl
+svc-monitor: svc-meter
+])
+
+ip netns exec sw01 scapy -H <<-EOF
+p = Ether(dst="33:33:33:33:33:33", src="f0:00:00:01:02:03") /\
+ IP(dst="192.168.1.100", src="192.168.1.2") / TCP(dport=1234, sport=1234)
+sendp(p, iface='sw01', loop=0, verbose=0, count=20)
+EOF
+
+OVS_WAIT_UNTIL([test "1" = "$(grep -c "dl_dst=33:33:33:33:33:33" ovn-controller.log)"])
+
kill $(pidof ovn-controller)
as ovn-sb
@@ -7295,7 +7312,8 @@ OVS_APP_EXIT_AND_WAIT([NORTHD_TYPE])
as
OVS_TRAFFIC_VSWITCHD_STOP(["/.*error receiving.*/d
-/.*terminating with signal 15.*/d"])
+/.*terminating with signal 15.*/d
+/.*Service monitor not found/d"])
AT_CLEANUP
])

View File

@ -1,5 +1,5 @@
diff --git a/ovsdb/automake.mk b/ovsdb/automake.mk
index eba713bb6..f1c40d019 100644
index d484fe9de..c38a936ea 100644
--- a/ovsdb/automake.mk
+++ b/ovsdb/automake.mk
@@ -88,8 +88,9 @@ CLEANFILES += ovsdb/ovsdb-server.1
@ -13,7 +13,7 @@ index eba713bb6..f1c40d019 100644
MAN_ROOTS += ovsdb/ovsdb-idlc.1
CLEANFILES += ovsdb/ovsdb-idlc
SUFFIXES += .ovsidl .ovsschema
@@ -112,14 +113,18 @@ CLEANFILES += $(OVSIDL_BUILT)
@@ -112,7 +113,11 @@ CLEANFILES += $(OVSIDL_BUILT)
# at least for now.
$(OVSIDL_BUILT): ovsdb/ovsdb-idlc.in python/ovs/dirs.py
@ -23,11 +23,12 @@ index eba713bb6..f1c40d019 100644
# ovsdb-doc
+ovsdb_SCRIPTS += ovsdb/ovsdb-doc
EXTRA_DIST += ovsdb/ovsdb-doc
FLAKE8_PYFILES += ovsdb/ovsdb-doc
OVSDB_DOC = $(run_python) $(srcdir)/ovsdb/ovsdb-doc
ovsdb/ovsdb-doc: python/ovs/dirs.py
@@ -121,7 +126,7 @@ ovsdb/ovsdb-doc: python/ovs/dirs.py
# ovsdb-dot
EXTRA_DIST += ovsdb/ovsdb-dot.in ovsdb/dot2pic
FLAKE8_PYFILES += ovsdb/ovsdb-dot.in ovsdb/dot2pic
-noinst_SCRIPTS += ovsdb/ovsdb-dot
+ovsdb_SCRIPTS += ovsdb/ovsdb-dot
CLEANFILES += ovsdb/ovsdb-dot

BIN
openvswitch-3.1.0.tar.gz (Stored with Git LFS)

Binary file not shown.

BIN
openvswitch-3.3.1.tar.gz (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,3 +1,52 @@
-------------------------------------------------------------------
Wed Aug 28 05:18:36 UTC 2024 - Duraisankar P <Duraisankar.pitchumani@suse.com>
- Update openvswitch to 3.3.1. For a list of changes, check
https://github.com/openvswitch/ovs/blob/v3.3.1/NEWS
- Update OVN to 24.03.3. For a list of changes, check
https://github.com/ovn-org/ovn/blob/v24.03.3/NEWS
- Drop upstream fixed patches,
* CVE-2023-1668.patch
* CVE-2023-3152.patch
* CVE-2023-5366.patch
* openvswitch-2.17.8-gcc14-build-fix.patch
* openvswitch-CVE-2023-3966.patch
- Updated the patch for version v3.3.1
* install-ovsdb-tools.patch
-------------------------------------------------------------------
Tue Jul 30 13:50:21 UTC 2024 - pgajdos@suse.com
- remove dependency on /usr/bin/python3 using
%python3_fix_shebang_path macro, [bsc#1212476]
-------------------------------------------------------------------
Tue Jun 4 09:48:39 UTC 2024 - Martin Jambor <mjambor@suse.com>
- GCC 14 started to advertise c_atomic extension, older versions
didn't do that. Add check for __clang__, so GCC doesn't include
headers designed for Clang
(openvswitch-2.17.8-gcc14-build-fix.patch) [boo#1225906]
-------------------------------------------------------------------
Mon Feb 26 12:38:17 UTC 2024 - Dominique Leuenberger <dimstar@opensuse.org>
- Use %patch -P N instead of deprecated %patchN.
-------------------------------------------------------------------
Thu Feb 15 06:53:54 UTC 2024 - Duraisankar P <Duraisankar.pitchumani@suse.com>
- Fix CVE-2023-3966 [bsc#1219465] openvswitch3: Invalid memory access in Geneve with HW offload
- Added patch,
+openvswitch-CVE-2023-3966.patch
-------------------------------------------------------------------
Thu Feb 1 19:34:16 UTC 2024 - Duraisankar P <Duraisankar.pitchumani@suse.com>
- Fix CVE-2023-5366 [bsc#1216002], openvswitch: missing masks on a final stage with ports trie
- Added patch,
* CVE-2023-5366.patch
-------------------------------------------------------------------
Thu Dec 14 11:55:19 UTC 2023 - Dirk Müller <dmueller@suse.com>

View File

@ -1,7 +1,7 @@
#
# spec file for package openvswitch
#
# Copyright (c) 2023 SUSE LLC
# Copyright (c) 2024 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -18,14 +18,14 @@
%define skip_python2 1
%define ovs_lname libopenvswitch-3_1-0
%define ovn_lname libovn-23_03-0
%define ovs_version 3.1.0
%define ovn_version 23.03.0
%define ovs_lname libopenvswitch-3_3-0
%define ovn_lname libovn-24_03-0
%define ovs_version 3.3.1
%define ovn_version 24.03.3
%define ovs_dir ovs-%{ovs_version}
%define ovn_dir ovn-%{ovn_version}
%define rpmstate %{_rundir}/openvswitch-rpm-state-
%define _dpdkv 22.11.1
%define _dpdkv 23.11.1
%define name_tag ${nil}
#Compat macro for new _fillupdir macro introduced in Nov 2017
%if ! %{defined _fillupdir}
@ -77,14 +77,9 @@ Patch2: 0001-Don-t-change-permissions-of-dev-hugepages.patch
Patch3: 0001-Use-double-hash-for-OVS_USER_ID-comment.patch
# PATCH-FEATURE-UPSTREAM install-ovsdb-tools.patch -- Install some tools required for building OVN
Patch4: install-ovsdb-tools.patch
# PATCH-FIX-UPSTREAM CVE-2023-1668.patch
Patch5: CVE-2023-1668.patch
#OVN patches
# PATCH-FIX-OPENSUSE: 0001-Run-ovn-as-openvswitch-openvswitch.patch
Patch20: 0001-Run-ovn-as-openvswitch-openvswitch.patch
# PATCH-FIX-UPSTREAM CVE-2023-3152 [bsc#1212125] -- service monitor MAC flow is not rate limited
Patch21: CVE-2023-3152.patch
# CVE-2021-36980 [bsc#1188524], use-after-free in decode_NXAST_RAW_ENCAP
BuildRequires: autoconf
BuildRequires: %{python_module setuptools}
BuildRequires: automake
@ -129,9 +124,9 @@ BuildRequires: openssl-devel
BuildRequires: python3-rpm-macros
BuildRequires: systemd-units
Requires(post): systemd-units
Requires(postun):systemd-units
Requires(postun): systemd-units
Requires(pre): shadow-utils
Requires(preun):systemd-units
Requires(preun): systemd-units
%endif
# Needed by the testsuite
%if %{with check}
@ -177,7 +172,7 @@ License: Apache-2.0
Group: System/Libraries
%if %{with dpdk}
Requires: dpdk >= %{_dpdkv}
Requires: libdpdk-23 >= %{_dpdkv}
Requires: libdpdk-24 >= %{_dpdkv}
%endif
%description -n %{ovs_lname}
@ -413,17 +408,15 @@ Devel libraries and headers for Open Virtual Network.
%prep
%setup -q -n %{name}-%{ovs_version} -a 1
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch -P 0 -p1
%patch -P 1 -p1
%patch -P 2 -p1
%patch -P 3 -p1
%patch -P 4 -p1
# remove python/ovs/dirs.py - this is generated from template to have proper paths
rm python/ovs/dirs.py
cd %{ovn_dir}
%patch20 -p1
%patch21 -p1
%patch -P 20 -p1
%build
mkdir %ovs_dir
@ -734,6 +727,13 @@ popd
install -D -m 0644 %{SOURCE10} %{buildroot}%{_sysusersdir}/openvswitch.conf
%if %{suse_version} >= 1600
%python3_fix_shebang_path %{buildroot}%{_datadir}/%{name}/ovsdb/*
%python3_fix_shebang_path %{buildroot}%{_datadir}/%{name}/scripts/*
%python3_fix_shebang_path %{buildroot}%{_datadir}/%{name}/scripts/usdt/*
%python3_fix_shebang_path %{buildroot}%{_datadir}/%{name}/scripts/ovsdb/*
%endif
%pre -f openvswitch.pre
%if 0%{?suse_version}
%service_add_pre ovsdb-server.service ovs-vswitchd.service openvswitch.service ovs-delete-transient-ports.service
@ -1269,6 +1269,7 @@ fi
%{_bindir}/ovn-appctl
%{_bindir}/ovn-ic-nbctl
%{_bindir}/ovn-ic-sbctl
%{_bindir}/ovn-debug
%dir %{_datadir}/ovn
%dir %{_datadir}/ovn/scripts
%{_datadir}/ovn/scripts/ovn-ctl
@ -1291,6 +1292,7 @@ fi
%{_mandir}/man8/ovn-nbctl.8%{?ext_man}
%{_mandir}/man8/ovn-trace.8%{?ext_man}
%{_mandir}/man8/ovn-sbctl.8%{?ext_man}
%{_mandir}/man8/ovn-debug.8%{?ext_man}
%config(noreplace) %{_sysconfdir}/logrotate.d/ovn
%doc %ovn_dir/AUTHORS.rst %ovn_dir/CONTRIBUTING.rst %ovn_dir/NEWS %ovn_dir/README.rst
%license %ovn_dir/LICENSE %ovn_dir/NOTICE

BIN
ovn-23.03.0.tar.gz (Stored with Git LFS)

Binary file not shown.

BIN
ovn-24.03.3.tar.gz (Stored with Git LFS) Normal file

Binary file not shown.