-
Notifications
You must be signed in to change notification settings - Fork 236
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lflow: Fix conjunction ID allocation problem with DP groups.
When DP group is enabled, a lflow attached to a DP group will be processed against each of the DPs in the group one by one. The current conjunction ID allocation algorithm didn't take into account the DP, so when a lflow is processed, if it generates conjunctions, it will try to allocate conjunction IDs repeatedly for each DP. The function lflow_conj_ids_alloc has a protection to avoid leaking the IDs - it free the existing IDs before allocating again for the same lflow. Because of this the coverage counter 'lflow_conj_free_unexpected' will increase. In most cases this is not a problem. Most likely each allocation for the same lflow would get the same ID and use it for different OVS flows with different DP metadata match, without conflict. However, there is a chance (although extremely small) that this can lead to double allocation, when different DPs have different n_conjs for the same lflow. For example: - 2 DPs (DP1 and DP2) in a DPG used by lflow A, which uses port-group PG1, in the below form: inport == @pg1 && (tcp.src == {1, 2, 3} || tcp.dst == {4, 5, 6}) This can generate flows with n_conjs of 1 or 2, depending on how many ports PG1 is evaluated to. If PG1 is evaluated with no ports, then there is no match (no flows). If PG1 is evaluated to 1 port, then there is an conjunction (n_conjs == 1) due to the '||'. If PG1 is evaluated to 2 or more ports, there will be 2 conjunctions (n_conjs == 2). - Assume PG1 is divided into SB port-groups PG1-DP1, PG1-DP2. PG1-DP1 has 1 port, PG1-DP2 has 2 ports. - Now the lflow is parsed against DP1 first, which end up with n_conjs = 1, and allocates a single conj_id (say, ID_1). - The lflow is parsed against DP2, which end up with n_conjs = 2. Now it frees the existing ID_1 allocated for the lflow, and reallocates 2 conjunction IDs. The algorithm would try to allocate ID_1 and (ID_1 + 1). However, assume that ID_1 + 1 happened to be allocated by another lflow-2 already (its uuid prefix happened to be ID_1 + 1, which is unfortunate), so the algorithm would move on to the next available continuous 2 IDs and allocate for the lflow for DP2. - At this moment, the ID_1 allocated for lflow for DP1 is still in use, but lost track in the conj_ids table (already free-ed). Now lflow-3 comes and happens to have its uuid prefix being ID_1, although very unlikely but still possible, and it requires a conjunction ID, so ID_1 is then allocated to the lflow-3. - Now ID_1 is used by OVS flows of lflow-1 and lflow-3. Double allocation! Packets hitting these flows would have unpredictable behavior. The fix is rather straightforward. Just take DP uuid as part of the allocation key, together with lflow uuid, and change the hash algorithm to consider both uuids. A major change, though, is the free part. When a lflow is deleted/reprocessed, we need to free the IDs for all the DPs, so the patch introduced another hmap index from lflow uuid to the list of DP nodes. For unit test, the algorithm itself didn't change much except for the hashing. So for the convenience of testing it introduces a test_mode so that it still uses the lflow uuid prefix for unit test only. The patch also adds a check in the PG test to make sure the counter lflow_conj_free_unexpected is always 0. The updated test would fail without this patch. Fixes: b609aee ("lflow: Consistent conjunction id generation.") Signed-off-by: Han Zhou <hzhou@ovn.org> Acked-by: Mark Michelson <mmichels@redhat.com>
- Loading branch information
Showing
6 changed files
with
175 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.