The FDP team is no longer accepting new bugs in Bugzilla. Please report your issues under FDP project in Jira. Thanks.
Bug 2020770 - ovs-vswitchd fails assertion start_ofs <= UINT16_MAX failed in ofpmp_postappend()
Summary: ovs-vswitchd fails assertion start_ofs <= UINT16_MAX failed in ofpmp_postappe...
Keywords:
Status: CLOSED NEXTRELEASE
Alias: None
Product: Red Hat Enterprise Linux Fast Datapath
Classification: Red Hat
Component: openvswitch2.15
Version: FDP 21.G
Hardware: Unspecified
OS: Unspecified
unspecified
high
Target Milestone: ---
: FDP 22.B
Assignee: Eelco Chaudron
QA Contact: Zhiqiang Fang
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2021-11-05 20:36 UTC by Jakub Libosvar
Modified: 2022-02-01 08:17 UTC (History)
6 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2022-02-01 08:17:06 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker FD-1639 0 None None None 2021-11-05 20:36:22 UTC

Description Jakub Libosvar 2021-11-05 20:36:12 UTC
Description of problem:
when ovn-controllers implements lots of flows or maybe some specific flow, vswitchd crashes with the following trace

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `ovs-vswitchd unix:/var/run/openvswitch/db.sock -vconsole:emer -vsyslog:err -vfi'.
Program terminated with signal SIGABRT, Aborted.
#0  0x00007f38efbe837f in raise () from /lib64/libc.so.6
[Current thread is 1 (Thread 0x7f38f2078c00 (LWP 372764))]
Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-151.el8.x86_64 libcap-ng-0.7.9-5.el8.x86_64 libevent-2.1.8-5.el8.x86_64 libibverbs-32.0-4.el8.x86_64 libnl3-3.5.0-1.el8.x86_64 numactl-libs-2.0.12-11.el8.x86_64 openssl-libs-1.1.1g-15.el8_3.x86_64 python3-libs-3.6.8-38.el8_4.x86_64 sssd-client-2.4.0-9.el8_4.2.x86_64 unbound-libs-1.7.3-15.el8.x86_64 zlib-1.2.11-17.el8.x86_64
(gdb) bt
#0  0x00007f38efbe837f in raise () from /lib64/libc.so.6
#1  0x00007f38efbd2db5 in abort () from /lib64/libc.so.6
#2  0x0000559e8ebde864 in ovs_abort_valist (err_no=err_no@entry=0, format=format@entry=0x559e8ed84510 "%s: assertion %s failed in %s()", args=args@entry=0x7ffe18e89eb0) at ../lib/util.c:419
#3  0x0000559e8ebe6754 in vlog_abort_valist (module_=<optimized out>, message=0x559e8ed84510 "%s: assertion %s failed in %s()", args=args@entry=0x7ffe18e89eb0) at ../lib/vlog.c:1249
#4  0x0000559e8ebe67fa in vlog_abort (module=module@entry=0x559e8f202f20 <this_module>, message=message@entry=0x559e8ed84510 "%s: assertion %s failed in %s()") at ../lib/vlog.c:1263
#5  0x0000559e8ebde57b in ovs_assert_failure (where=where@entry=0x559e8ed78f35 "../lib/ofp-msgs.c:995", function=function@entry=0x559e8ed79860 <__func__.9920> "ofpmp_postappend", 
    condition=condition@entry=0x559e8ed78f1d "start_ofs <= UINT16_MAX") at ../lib/util.c:86
#6  0x0000559e8eb9225a in ofpmp_postappend (replies=replies@entry=0x7ffe18e8a0d0, start_ofs=start_ofs@entry=80456) at ../include/openvswitch/list.h:257
#7  0x0000559e8eb84e22 in ofputil_append_flow_stats_reply (fs=fs@entry=0x7ffe18e8af40, replies=replies@entry=0x7ffe18e8a0d0, tun_table=0x559e910b0400) at ../lib/ofp-flow.c:1257
#8  0x0000559e8eabb522 in handle_flow_stats_request (ofconn=ofconn@entry=0x559e9138e5b0, request=request@entry=0x559eb8162e50) at ../ofproto/ofproto-provider.h:2073
#9  0x0000559e8eac162f in handle_single_part_openflow (type=OFPTYPE_FLOW_STATS_REQUEST, oh=0x559eb8162e50, ofconn=0x559e9138e5b0) at ../ofproto/ofproto.c:8560
#10 handle_openflow (ofconn=0x559e9138e5b0, msgs=0x7ffe18e8bef0) at ../ofproto/ofproto.c:8686
#11 0x0000559e8eaf70c4 in ofconn_run (handle_openflow=0x559e8eac08b0 <handle_openflow>, ofconn=0x559e9138e5b0) at ../ofproto/connmgr.c:1329
#12 connmgr_run (mgr=0x559e9069e340, handle_openflow=handle_openflow@entry=0x559e8eac08b0 <handle_openflow>) at ../ofproto/connmgr.c:356
#13 0x0000559e8eaba308 in ofproto_run (p=0x559e907e0220) at ../ofproto/ofproto.c:1891
#14 0x0000559e8eaa5b7c in bridge_run__ () at ../vswitchd/bridge.c:3251
#15 0x0000559e8eaac07d in bridge_run () at ../vswitchd/bridge.c:3310
#16 0x0000559e8e4442d5 in main (argc=<optimized out>, argv=<optimized out>) at ../vswitchd/ovs-vswitchd.c:127

Version-Release number of selected component (if applicable):
openvswitch2.15-2.15.0-38.el8fdp.x86_64

How reproducible:
Unknown

Steps to Reproduce:
1. We have 1000 node environment with 9900 logical switch ports
2. Some nodes crash with the error above - gateway nodes crash in 100% of cases
3.


Additional info:
We have live environment ready up for further troubleshooting

Comment 2 Jakub Libosvar 2021-11-09 17:44:28 UTC
The crash happens when "ovs-ofctl dump-flows" is envoked.

Comment 3 Mike Pattrick 2021-11-09 22:27:02 UTC
I performed some triage on the provided core dump, and found that this crash is triggered when ofpmp_postappend() encounters a flow with more than 65535 bytes worth of action. In this case, there is a flow with 80360 bytes worth of actions.


(gdb) f 8
#8  0x0000559e8eabb522 in handle_flow_stats_request
2073	    return ovsrcu_get(struct tun_table *, &ofproto->metadata_tab);
(gdb) p ((struct rule **)rules->collection->objs)[406076]->actions->ofpacts_len
$7 = 80360
(gdb) ovs_dump_ofpacts 0x559eb5a743b8 80360
(struct ofpact *) 0x559eb5a743b8: {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}
(struct ofpact *) 0x559eb5a743d0: {type = OFPACT_RESUBMIT, raw = 38 '&', len = 16}
(struct ofpact *) 0x559eb5a743e0: {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}
(struct ofpact *) 0x559eb5a743f8: {type = OFPACT_RESUBMIT, raw = 38 '&', len = 16}
(struct ofpact *) 0x559eb5a74408: {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}
[...Over 4000 lines truncated]
(struct ofpact *) 0x559eb5a87d78: {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}
(struct ofpact *) 0x559eb5a87d90: {type = OFPACT_RESUBMIT, raw = 38 '&', len = 16}


I attempted to reproduce this condition with ovs-ofctl; however, the ovs-ofctl utility would not allow me to produce an action larger than 65535 bytes:

# ovs-ofctl --bundle add-flows s1 large_flow.txt
Error OFPBMC_BAD_LEN for: (***only uses 56 bytes out of 65592***)
00000000  05 0e 00 38 00 00 00 06-00 00 00 00 00 00 00 00 |...8............|
00000010  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 64 |...............d|
00000020  ff ff ff ff ff ff ff ff-ff ff ff ff 00 00 00 00 |................|


I'm not too familiar with OVN, but I see that it does modify flow structs directly. It may be adding structures that are invalid in OVS.

Comment 4 Eelco Chaudron 2021-11-10 10:49:23 UTC
(gdb) ovs_dump_ovs_list replies 'struct ofpbuf' list_node dump
...
(struct ofpbuf *) 0x559eb8c4b2f0 =
  {base = 0x559ec1d8a080, data = 0x559ec1d8a080, size = 64376, allocated = 65640, header = 0x559ec1d8a080, msg = 0x559ec1d8a098, list_node = {prev = 0x559eb861d798, next = 0x559eb8a41dd8}, source = OFPBUF_MALLOC}

(struct ofpbuf *) 0x559eb8a41db0 =
  {base = 0x559ec1d9a0f0, data = 0x559ec1d9a0f0, size = 45352, allocated = 125808, header = 0x559ec1d9a0f0, msg = 0x559ec1d9a108, list_node = {prev = 0x559eb8c4b318, next = 0x559eb12d1a48}, source = OFPBUF_MALLOC}

(struct ofpbuf *) 0x559eb12d1a20 =
  {base = 0x559ec1db8c70, data = 0x559ec1db8c70, size = 80600, allocated = 80632, header = 0x559ec1db8c70, msg = 0x559ec1db8c88, list_node = {prev = 0x559eb8a41dd8, next = 0x7ffe18e8a0d0}, source = OFPBUF_MALLOC}

^^ Total 926 entries!!

(gdb) p start_ofs
$4 = 80456

(gdb) p *(struct ofp10_flow_stats *) (((struct ofpbuf *) 0x559eb12d1a20)->data + start_ofs)
$23 = {length = 36864, table_id = 37 '%', pad = 0 '\000', match = {wildcards = 1929445376, in_port = 26403, dl_src = {{ea = "\270\200\000d\000", be16 = {32952, 25600, 0}}}, dl_dst = {{ea = "\000\000\000\024\001t", be16 = {0, 5120, 29697}}}, dl_vlan = 29697, dl_vlan_pcp = 0 '\000', 
    pad1 = "", dl_type = 0, nw_tos = 200 '\310', nw_proto = 143 '\217', pad2 = "&K", nw_src = 0, nw_dst = 0, tp_src = 0, tp_dst = 0}, duration_sec = 0, duration_nsec = 69075200, priority = 0, idle_timeout = 768, hard_timeout = 128, pad2 = "\004\b\000\000\000", cookie = {
    hi = 2349137920, lo = 0}, packet_count = {hi = 402718719, lo = 539164672}, byte_count = {hi = 385877760, lo = 136315136}}

(gdb) p /x ((struct ofp10_flow_stats *) (((struct ofpbuf *) 0x559eb12d1a20)->data + start_ofs))->length
$26 = 0x9000

 0x0090 -> 144  ====  size = 80600 - start_ofs = 80456  => 144

(gdb) p /x ((struct ofp10_flow_stats *) (((struct ofpbuf *) 0x559eb12d1a20)->data))->length
$27 = 0x1101

 0x0111 -> 273


Question why is the last fragment of 80600 not broken up?

Looks like the previous length was rather large, as for the split we allocated 125808 bytes, and the previous size restored was 45352, so this might hint that the previous message was 125808 - 45352 = 80456 bytes :(

What was the previous request?!?
Data msg header (previous message):

(gdb) p *(struct ofp_header *) (((struct ofpbuf *) 0x559eb12d1a20)->data)
$33 = {version = 1 '\001', type = 17 '\021', length = 6144, xid = 67108864}

Version is 1 --> OFP10_VERSION = 0x01
Type is 17 --> #define OFPT10_STATS_REPLY 17

(gdb) p *(struct ofp10_stats_msg *) (((struct ofpbuf *) 0x559eb12d1a20)->data)
$34 = {header = {version = 1 '\001', type = 17 '\021', length = 6144, xid = 67108864}, type = 65535, flags = 0}

(gdb) p /x ((struct ofp10_stats_msg *) (((struct ofpbuf *) 0x559eb12d1a20)->data))->header.length
$36 = 0x1800

== 24 bytes

(gdb) p sizeof(struct ofp10_stats_msg)
$50 = 12

but type = OFPST_VENDOR 0xffff so:

(gdb) p sizeof(struct nicira10_stats_msg)
$51 = 24

(gdb) p *(struct nicira10_stats_msg *) (((struct ofpbuf *) 0x559eb12d1a20)->data)
$53 = {vsm = {osm = {header = {version = 1 '\001', type = 17 '\021', length = 6144, xid = 67108864}, type = 65535, flags = 0}, vendor = 539164672}, subtype = 0, pad = "\000\000\000"}

Next message is than at ->data + 24

0x559ec1db8c70+24 = 0x559ec1db8c88 ==== ->msg

(gdb) p *(struct ofp10_flow_stats *) (((struct ofpbuf *) 0x559eb12d1a20)->data + 24)
(gdb) p /x *(struct ofp10_flow_stats *) (((struct ofpbuf *) 0x559eb12d1a20)->msg)
$37 = {length = 12346, table_id = 37 '%', pad = 0 '\000', match = {wildcards = 1929445376, in_port = 26403, dl_src = {{ea = "\270\200\000d\000", be16 = {32952, 25600, 0}}}, dl_dst = {{ea = "\000\000\000\024\001t", be16 = {0, 5120, 29697}}}, dl_vlan = 29697, dl_vlan_pcp = 0 '\000', 
    pad1 = "", dl_type = 0, nw_tos = 69 'E', nw_proto = 199 '\307', pad2 = "<", nw_src = 0, nw_dst = 0, tp_src = 0, tp_dst = 0}, duration_sec = 0, duration_nsec = 69075200, priority = 0, idle_timeout = 128, hard_timeout = 128, pad2 = "\004\b\000\000\000", cookie = {hi = 16777216, 
    lo = 0}, packet_count = {hi = 402718719, lo = 539164672}, byte_count = {hi = 520095488, lo = 69075200}}

(gdb) p /x ((struct ofp10_flow_stats *) (((struct ofpbuf *) 0x559eb12d1a20)->data + 24))->length
$39 = 0x303a

3a30 => 14896

The below next entry looks odd!?

(gdb)  p *(struct ofp10_flow_stats *) (((struct ofpbuf *) 0x559eb12d1a20)->msg + 0x3a30)
$58 = {length = 65535, table_id = 0 '\000', pad = 16 '\020', match = {wildcards = 539164672, in_port = 3584, dl_src = {{ea = "\377\370'\000\000", be16 = {63743, 39, 0}}}, dl_dst = {{ea = "\377\377\000\030\000", be16 = {65535, 6144, 0}}}, dl_vlan = 8227, dl_vlan_pcp = 0 '\000', 
    pad1 = "\a", dl_type = 7936, nw_tos = 0 '\000', nw_proto = 1 '\001', pad2 = "\036\004", nw_src = 0, nw_dst = 2600730624, tp_src = 65535, tp_dst = 4096}, duration_sec = 539164672, duration_nsec = 4177464832, priority = 39, idle_timeout = 0, hard_timeout = 65535, 
  pad2 = "\000\030\000\000# ", cookie = {hi = 520095488, lo = 69075200}, packet_count = {hi = 0, lo = 2265055232}, byte_count = {hi = 268500991, lo = 539164672}}


0xffff + 3a30 == 0x13a2f -> 80431  + 24 for header = 80455 offset -> len at start 80456....

This looks almost like the correct size (-1 byte), but the content also looks corrupted.
I inspected a lot of code but could not find any clue on how this could happen.

But these are the things that keep me awake at night, and at 00:36 I had a perfect theory, and I could go to sleep :)

The total message size is indeed over 64K, and as the size is stored in uint16, it overflowed.

80456 - 24 (hdr) = 80432 => 0x13a30 => htons(0x13a30) = 0x303a


So what was the previous flow entry that added so many actions that it went over 64K?


(gdb) frame 8
#8  0x0000559e8eabb522 in handle_flow_stats_request (ofconn=ofconn@entry=0x559e9138e5b0, request=request@entry=0x559eb8162e50) at ../ofproto/ofproto-provider.h:2073
(gdb) p i__
$2 = 406077

So previous entry was 406076

(gdb) p (struct rule *)rules->collection.objs[i__ - 1]
$9 = (struct rule *) 0x559eb59d6ab0
(gdb) p *(struct rule *)rules->collection.objs[i__ - 1]
$10 = {ofproto = 0x559e907e0220, cr = {node = {prev = 0x559eb5a50238, next = {p = 0x559eb5a71148}}, priority = 100, cls_match = {p = 0x559ebe235990}, match = {{{flow = 0x559eb5a50b30, mask = 0x559eb5a50b50}, flows = {
          0x559eb5a50b30, 0x559eb5a50b50}}, tun_md = 0x0}}, table_id = 37 '%', state = RULE_INSERTED, mutex = {lock = {__data = {__lock = 0, __count = 0, __owner = 0, __nusers = 0, __kind = 2, __spins = 0, __elision = 0, __list = {
          __prev = 0x0, __next = 0x0}}, __size = '\000' <repeats 16 times>, "\002", '\000' <repeats 22 times>, __align = 0}, where = 0x559e8ed54c5d "<unlocked>"}, ref_count = {count = 2}, flow_cookie = 17107597769310208, 
  cookie_node = {hash = 2280874424, d = 0x559ea11ca418, s = 0x559eb613ed28}, flags = (unknown: 0), hard_timeout = 0, idle_timeout = 0, importance = 0, removed_reason = 6 '\006', eviction_group = 0x0, evg_node = {idx = 0, 
    priority = 0}, actions = 0x559eb5a743b0, meter_list_node = {prev = 0x559eb59d6b80, next = 0x559eb59d6b80}, monitor_flags = (unknown: 0), add_seqno = 541882, modify_seqno = 541882, expirable = {prev = 0x559eb59d6ba8, 
    next = 0x559eb59d6ba8}, created = 2075283079, modified = 2075283079, match_tlv_bitmap = 0, ofpacts_tlv_bitmap = 0}


(gdb) p *((struct rule *)rules->collection.objs[i__ - 1])->actions
$12 = {has_meter = false, has_learn_with_delete = false, has_groups = false, ofpacts_len = 80360, ofpacts = 0x559eb5a743b8}


(gdb) ovs_dump_ofpacts 0x559eb5a743b8 80360
(struct ofpact *) 0x559eb5a743b8: {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}
(struct ofpact *) 0x559eb5a743d0: {type = OFPACT_RESUBMIT, raw = 38 '&', len = 16}
(struct ofpact *) 0x559eb5a743e0: {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}
...
...
(struct ofpact *) 0x559eb5a87d28: {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}
(struct ofpact *) 0x559eb5a87d40: {type = OFPACT_RESUBMIT, raw = 38 '&', len = 16}
(struct ofpact *) 0x559eb5a87d50: {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}
(struct ofpact *) 0x559eb5a87d68: {type = OFPACT_RESUBMIT, raw = 38 '&', len = 16}
(struct ofpact *) 0x559eb5a87d78: {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}
(struct ofpact *) 0x559eb5a87d90: {type = OFPACT_RESUBMIT, raw = 38 '&', len = 16}

Total of 4019 entries...

(gdb) p *(struct ofpact_set_field*) 0x559eb5a87d78
$16 = {{{ofpact = {type = OFPACT_SET_FIELD, raw = 255 '\377', len = 24}, flow_has_vlan = false, field = 0x559e8f0c4e20 <mf_fields+6496>}, pad21 = "\006\377\030\000\000\000\000\000 N\f\217\236U\000"}, value = 0x559eb5a87d88}
(gdb) p * (struct mf_field *)0x559e8f0c4e20
$17 = {id = MFF_REG15, name = 0x559e8ed686e1 "reg15", extra_name = 0x0, n_bytes = 4, n_bits = 32, variable_len = false, maskable = MFM_FULLY, string = MFS_HEXADECIMAL, prereqs = MFP_NONE, writable = true, mapped = false, 
  usable_protocols_exact = (OFPUTIL_P_OF10_NXM | OFPUTIL_P_OF10_NXM_TID | OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM | OFPUTIL_P_OF14_OXM | OFPUTIL_P_OF15_OXM), 
  usable_protocols_cidr = (OFPUTIL_P_OF10_NXM | OFPUTIL_P_OF10_NXM_TID | OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM | OFPUTIL_P_OF14_OXM | OFPUTIL_P_OF15_OXM), 
  usable_protocols_bitwise = (OFPUTIL_P_OF10_NXM | OFPUTIL_P_OF10_NXM_TID | OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM | OFPUTIL_P_OF14_OXM | OFPUTIL_P_OF15_OXM), flow_be32ofs = -1}

(gdb) p *(struct ofpact_resubmit *) 0x559eb5a87d90
$18 = {{{ofpact = {type = OFPACT_RESUBMIT, raw = 38 '&', len = 16}, in_port = 65528, table_id = 38 '&', with_ct_orig = false}, pad34 = "&&\020\000\370\377\000\000&\000\000\000\000\000\000"}}

So we have so many actions that it overflows the 64K limit... 

A quick peek at the openflows spec does not show a solution, actually, it does not mention these limits at all.

Comment 5 Dumitru Ceara 2021-11-10 11:05:17 UTC
It's very likely these flows are added by ovn-controller here, for the MC_FLOOD multicast group that handles BUM traffic:

https://github.com/ovn-org/ovn/blob/d659b6538b00bd72aeca1fc5dd3a3c337ac53f37/controller/physical.c#L1526

I'm guessing this is for the provider logical switch which has a lot of ports connected to it.

Comment 6 Eelco Chaudron 2021-11-10 20:52:17 UTC
I've been trying to add 4k actions into a single flow rule, and from code/ovs-ofctl add-flow I'm not able to do this without overrunning the message length when creating the flow.

This makes me wonder how OVN is able to do so, or if OVN is sending such a message that could corrupt the flows?!?

Dumitru is there data we can take from the live setup, which could help us recreate the problem? Or do you see an easy way to let OVN create these many actions?

Comment 7 Dumitru Ceara 2021-11-10 23:32:17 UTC
(In reply to Eelco Chaudron from comment #6)
> I've been trying to add 4k actions into a single flow rule, and from
> code/ovs-ofctl add-flow I'm not able to do this without overrunning the
> message length when creating the flow.
> 
> This makes me wonder how OVN is able to do so, or if OVN is sending such a
> message that could corrupt the flows?!?

ovn-controller uses bundles, maybe that's the difference?

> 
> Dumitru is there data we can take from the live setup, which could help us
> recreate the problem? Or do you see an easy way to let OVN create these many
> actions?

In any case, we can repr the crash in an OVN sandbox; from an OVN source directory, run:

$ make sandbox

$ ./ovn-setup.sh # This creates a very simple topology with a couple of switches.

$ # Add 1200 more ports to one of the switches and bind them to OVN
$ for i in $(seq 1 1200); do echo "Adding port $i"; p=lsp$i; ovs-vsctl add-port br-int $p -- set interface $p external_ids:iface-id=$p; ovn-nbctl lsp-add sw0 $p; done

$ # Try to dump OVS flows (table=38 has the large flows), this crashes ovs-vswitchd running in the sandbox.
$ ovs-ofctl dump-flows br-int table=38

Comment 8 Eelco Chaudron 2021-11-11 11:46:38 UTC
So OVN is communicating with OVS using OpenFlow15, which as it turns out has a slightly optimized message format compared to OpenFlow10 which is used by default for the ovs-ofctl commands. So to avoid the crash for now, please use the  -O OpenFlow15 option when dumping the flows. For example:

  ovs-ofctl dump-flows -O OpenFlow15 br-int 

Note that I assumed if you add enough interfaces to OVN we will eventually also hit the 64K limit. But doing a quick test with 2000 interfaces it looks like we get two flow entries. So there must be some split logic, however, I did not investigate.

The next step from my side will be to come up with a patch to no longer crash OVS and just log a message and skip reporting the specific flow.

Comment 9 Eelco Chaudron 2021-11-11 12:04:23 UTC
Did a quick test, and it looks like OVN is not splitting up the flows at all, but it will just fail adding the correct flows.
If you use the reproduced in #7, with the following:

 for i in $(seq 1 1365); do echo "Adding port $i"; p=lsp$i; ovs-vsctl add-port br-int $p -- set interface $p external_ids:iface-id=$p; ovn-nbctl lsp-add sw0 $p; done

The flow dumped will look like this, only a single resubmit:

ovs-ofctl dump-flows -O OpenFlow15  br-int table=38
...
 cookie=0x5bbbbfcb, duration=123.316s, table=38, n_packets=0, n_bytes=0, idle_age=123, priority=100,reg15=0x8000,metadata=0x1 actions=set_field:0x28d->reg13,set_field:0x287->reg15,resubmit(,39)
 cookie=0x667e983f, duration=123.316s, table=38, n_packets=0, n_bytes=0, idle_age=123, priority=100,reg15=0x8005,metadata=0x1 actions=set_field:0x28d->reg13,set_field:0x287->reg15,resubmit(,39)

Comment 11 Eelco Chaudron 2021-11-11 13:42:30 UTC
Jakub can you confirm that the crash is no longer happening if you use the -O option? If so please use this for now, and in the meantime Mike will create a scratch build with excluding the offending flow from a flow dump with an older protocol.

  ovs-ofctl dump-flows -O OpenFlow15 br-int

Comment 12 Jakub Libosvar 2021-11-12 17:43:43 UTC
(In reply to Eelco Chaudron from comment #11)
> Jakub can you confirm that the crash is no longer happening if you use the
> -O option? If so please use this for now, and in the meantime Mike will
> create a scratch build with excluding the offending flow from a flow dump
> with an older protocol.
> 
>   ovs-ofctl dump-flows -O OpenFlow15 br-int

I confirm it does not crash with OpenFlow15 option passed. Thanks!

Comment 14 Eelco Chaudron 2021-12-06 16:59:09 UTC
Send patch upstream, including test:

https://mail.openvswitch.org/pipermail/ovs-dev/2021-December/389947.html

Comment 16 Eelco Chaudron 2022-01-10 08:21:14 UTC
Sent out a v4 patch:

https://patchwork.ozlabs.org/project/openvswitch/list/?series=280231

Comment 17 Eelco Chaudron 2022-02-01 08:17:06 UTC
Fix got accepted upstream, and was backported all the way down to 2.13.

$ git show 4056ae487
commit 4056ae4875541197eab1b346ab84f23077ff9dea
Author: Eelco Chaudron <echaudro>
Date:   Mon Jan 10 09:13:49 2022 +0100

    ofp-flow: Skip flow reply if it exceeds the maximum message size.
    
    Currently, if a flow reply results in a message which exceeds
    the maximum reply size, it will assert OVS. This would happen
    when OVN uses OpenFlow15 to add large flows, and they get read
    using OpenFlow10 with ovs-ofctl.
    
    This patch prevents this and adds a test case to make sure the
    code behaves as expected.
    
    Signed-off-by: Eelco Chaudron <echaudro>
    Reviewed-by: Maxime Coquelin <maxime.coquelin>
    Signed-off-by: Ilya Maximets <i.maximets>


Will close this BZ as the fix will make its way down to downstream automatically in the next release (FDP 22.B).


Note You need to log in before you can comment on or make changes to this bug.