Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.(Internet mail)
On 2021/4/12, 4:48 PM, "Dumitru Ceara" wrote: On 4/8/21 1:24 PM, gmingchen(陈供明) wrote: > > > On 2021/4/7, 12:01 AM, "Dumitru Ceara" wrote: > > On 4/6/21 12:11 PM, Mark Gray wrote: > > I had a conversation with Dumitru and this patch came up in the > > conversation. He made an interesting suggestion (Dumitru, please correct > > me if I get this wrong) that this could be refactored as an external > > tool. This cmdline tool could, for example, take a set of IP addresses > > and return the wildcard representation. For example, > > > > # ./ovs-new-tool > > ... > > > > Then this tool could optionally be used by a CMS. The other advantage of > > this is that it could also be used in other places. > > Given that OVN is essentially a stack of compilers (NB -> SB -> > openflow) I was wondering if it would be reasonable and worth it to go a > step forward and implement this feature to "combine IP addresses with > wildcard" as a library. This would allow using it at different levels > in the stack, e.g.: > - at CMS level/as a standalone cmdline tool. > > My concern is whether the process after cms can correctly handle this > non-standard cidr format (1.1.1.0/255.255.255.253). I would expect this to not be a problem but it depends on CMS indeed. Yes. > > - in ovn-northd (for example when generating SB address sets from NB > address sets) > > If the non-standard cidr format ip address can be handled reasonably > here, I think this is a good idea. These are OVN internals so the approach you were proposing in ovn-controller could be implemented at this level too. It is indeed the case. I wonder if the scale of the IP address is not so important, so that fewer people respond now. So, I wonder if the patch can be put here first, if this problem is more common, then further targeted discussion. > > - in ovn-controller (as the current patch is doing). > > Thanks, > Gongming > Thanks, Dumitru ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.(Internet mail)
On 2021/4/7, 12:01 AM, "Dumitru Ceara" wrote: On 4/6/21 12:11 PM, Mark Gray wrote: > I had a conversation with Dumitru and this patch came up in the > conversation. He made an interesting suggestion (Dumitru, please correct > me if I get this wrong) that this could be refactored as an external > tool. This cmdline tool could, for example, take a set of IP addresses > and return the wildcard representation. For example, > > # ./ovs-new-tool > ... > > Then this tool could optionally be used by a CMS. The other advantage of > this is that it could also be used in other places. Given that OVN is essentially a stack of compilers (NB -> SB -> openflow) I was wondering if it would be reasonable and worth it to go a step forward and implement this feature to "combine IP addresses with wildcard" as a library. This would allow using it at different levels in the stack, e.g.: - at CMS level/as a standalone cmdline tool. My concern is whether the process after cms can correctly handle this non-standard cidr format (1.1.1.0/255.255.255.253). - in ovn-northd (for example when generating SB address sets from NB address sets) If the non-standard cidr format ip address can be handled reasonably here, I think this is a good idea. - in ovn-controller (as the current patch is doing). Thanks, Gongming Regards, Dumitru ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.(Internet mail)
On 2021/4/6, 6:11 PM, "Mark Gray" wrote: On 01/04/2021 13:28, gmingchen(陈供明) wrote: > Correct some words > > > On 2021/4/1, 8:17 PM, "gmingchen(陈供明)" wrote: > > > > On 2021/3/30, 4:59 PM, "Mark Gray" wrote: > > On 29/03/2021 13:30, gmingchen(陈供明) wrote: > > > > On 2021/3/25, 11:30 PM, "Mark Gray" wrote: > > > > On 19/03/2021 13:01, Dumitru Ceara wrote: > > > On 3/10/21 2:29 PM, gmingchen(陈供明) wrote: > > >> From: Gongming Chen > > >> > > > > Thanks for the patch. Looks like a lot of thought went into the > > algorithm and it has been interesting to review. > > > > Do you know if there are any well-known algorithms to do this? It seems > > like a common problem? If there was, it may be better to use it as we > > could reference standard documentation. > > > > Hi Mark, > > First of all, thanks for the review. > > > > Unfortunately, I did not find a well-known algorithms. > > Ok. Thats a shame. It's kind of like IP subnetting so I thought there > may be something. > > > > > >> This patch merges ipv4 addresses with wildcard masks, and replaces this > > >> ipv4 addresses with the combined ip/mask. This will greatly reduce the > > >> entries in the ovs security group flow table, especially when the host > > >> size is large. > > >> > > >> Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 > > >> ports(1.1.1.2-1.1.1.254). > > >> Only focus on the number of ip addresses, the original 253 addresses will > > >> be combined into 13 addresses. > > >> 1.1.1.2/31 > > >> 1.1.1.4/30 > > >> 1.1.1.8/29 > > >> 1.1.1.16/28 > > >> 1.1.1.32/27 > > >> 1.1.1.64/26 > > >> 1.1.1.128/26 > > >> 1.1.1.192/27 > > >> 1.1.1.224/28 > > >> 1.1.1.240/29 > > >> 1.1.1.248/30 > > >> 1.1.1.252/31 > > >> 1.1.1.254 > > >> > > >> Some scenes are similar to the following: > > >> 1.1.1.2, 1.1.1.6 > > >> After the combine: > > >> 1.1.1.2/255.255.255.251 > > >> You can use ovn-match-ip utility to match ip. > > >> such as: > > >> ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 > > >> 1.1.1.2/255.255.255.251 will show. > > >> > > >> Simple description of the algorithm. > > >> There are two situations > > >> 1. Combine once > > >> such as: > > >> 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 > > >> Combined into: 1.1.1.0/31, 1.0.1.0/31 > > >> 2. Combine multiple times > > >> 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 > > >> Combined into: 1.0.1.0/255.254.255.254 > > >> > > >> Considering the actual scene and simplicity, the first case is used to > > >> combine once. > > >> > > >> ...00... > > >> ...01... > > >> ...10... > > >> ...11... > > >> "..." means the same value omitted. > > >> Obviously, the above value can be expressed as ...00.../11100111. This > > >> continuous interval that can be represented by one or several wildcard > > >> masks is called a segment. > > >> Only if all 2<
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.(Internet mail)
Correct some words On 2021/4/1, 8:17 PM, "gmingchen(陈供明)" wrote: On 2021/3/30, 4:59 PM, "Mark Gray" wrote: On 29/03/2021 13:30, gmingchen(陈供明) wrote: > > On 2021/3/25, 11:30 PM, "Mark Gray" wrote: > > On 19/03/2021 13:01, Dumitru Ceara wrote: > > On 3/10/21 2:29 PM, gmingchen(陈供明) wrote: > >> From: Gongming Chen > >> > > Thanks for the patch. Looks like a lot of thought went into the > algorithm and it has been interesting to review. > > Do you know if there are any well-known algorithms to do this? It seems > like a common problem? If there was, it may be better to use it as we > could reference standard documentation. > > Hi Mark, > First of all, thanks for the review. > > Unfortunately, I did not find a well-known algorithms. Ok. Thats a shame. It's kind of like IP subnetting so I thought there may be something. > > >> This patch merges ipv4 addresses with wildcard masks, and replaces this > >> ipv4 addresses with the combined ip/mask. This will greatly reduce the > >> entries in the ovs security group flow table, especially when the host > >> size is large. > >> > >> Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 > >> ports(1.1.1.2-1.1.1.254). > >> Only focus on the number of ip addresses, the original 253 addresses will > >> be combined into 13 addresses. > >> 1.1.1.2/31 > >> 1.1.1.4/30 > >> 1.1.1.8/29 > >> 1.1.1.16/28 > >> 1.1.1.32/27 > >> 1.1.1.64/26 > >> 1.1.1.128/26 > >> 1.1.1.192/27 > >> 1.1.1.224/28 > >> 1.1.1.240/29 > >> 1.1.1.248/30 > >> 1.1.1.252/31 > >> 1.1.1.254 > >> > >> Some scenes are similar to the following: > >> 1.1.1.2, 1.1.1.6 > >> After the combine: > >> 1.1.1.2/255.255.255.251 > >> You can use ovn-match-ip utility to match ip. > >> such as: > >> ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 > >> 1.1.1.2/255.255.255.251 will show. > >> > >> Simple description of the algorithm. > >> There are two situations > >> 1. Combine once > >> such as: > >> 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 > >> Combined into: 1.1.1.0/31, 1.0.1.0/31 > >> 2. Combine multiple times > >> 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 > >> Combined into: 1.0.1.0/255.254.255.254 > >> > >> Considering the actual scene and simplicity, the first case is used to > >> combine once. > >> > >> ...00... > >> ...01... > >> ...10... > >> ...11... > >> "..." means the same value omitted. > >> Obviously, the above value can be expressed as ...00.../11100111. This > >> continuous interval that can be represented by one or several wildcard > >> masks is called a segment. > >> Only if all 2< >> exist, can they be combined into 00...(n)/00...( n) > >> > >> First sort all the values by size. Iterate through each value. > >> 1. Find a new segment, where two values differ only by 1 bit, such as > >> ...0... and ...1... > >> diff = ip_next ^ ip > >> if (diff & (diff-1)) == 0 > >> new_segment = true > >> The first non-zero place in the high direction of ip is the end of the > >> segment(segment_end). > >> For example...100... and...101..., the segment_end is ...111... > >> > >> 2. Count the number of consecutive and less than continuous_size in the > >> segment. > >>
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.(Internet mail)
On 2021/3/30, 4:59 PM, "Mark Gray" wrote: On 29/03/2021 13:30, gmingchen(陈供明) wrote: > > On 2021/3/25, 11:30 PM, "Mark Gray" wrote: > > On 19/03/2021 13:01, Dumitru Ceara wrote: > > On 3/10/21 2:29 PM, gmingchen(陈供明) wrote: > >> From: Gongming Chen > >> > > Thanks for the patch. Looks like a lot of thought went into the > algorithm and it has been interesting to review. > > Do you know if there are any well-known algorithms to do this? It seems > like a common problem? If there was, it may be better to use it as we > could reference standard documentation. > > Hi Mark, > First of all, thanks for the review. > > Unfortunately, I did not find a well-known algorithms. Ok. Thats a shame. It's kind of like IP subnetting so I thought there may be something. > > >> This patch merges ipv4 addresses with wildcard masks, and replaces this > >> ipv4 addresses with the combined ip/mask. This will greatly reduce the > >> entries in the ovs security group flow table, especially when the host > >> size is large. > >> > >> Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 > >> ports(1.1.1.2-1.1.1.254). > >> Only focus on the number of ip addresses, the original 253 addresses will > >> be combined into 13 addresses. > >> 1.1.1.2/31 > >> 1.1.1.4/30 > >> 1.1.1.8/29 > >> 1.1.1.16/28 > >> 1.1.1.32/27 > >> 1.1.1.64/26 > >> 1.1.1.128/26 > >> 1.1.1.192/27 > >> 1.1.1.224/28 > >> 1.1.1.240/29 > >> 1.1.1.248/30 > >> 1.1.1.252/31 > >> 1.1.1.254 > >> > >> Some scenes are similar to the following: > >> 1.1.1.2, 1.1.1.6 > >> After the combine: > >> 1.1.1.2/255.255.255.251 > >> You can use ovn-match-ip utility to match ip. > >> such as: > >> ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 > >> 1.1.1.2/255.255.255.251 will show. > >> > >> Simple description of the algorithm. > >> There are two situations > >> 1. Combine once > >> such as: > >> 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 > >> Combined into: 1.1.1.0/31, 1.0.1.0/31 > >> 2. Combine multiple times > >> 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 > >> Combined into: 1.0.1.0/255.254.255.254 > >> > >> Considering the actual scene and simplicity, the first case is used to > >> combine once. > >> > >> ...00... > >> ...01... > >> ...10... > >> ...11... > >> "..." means the same value omitted. > >> Obviously, the above value can be expressed as ...00.../11100111. This > >> continuous interval that can be represented by one or several wildcard > >> masks is called a segment. > >> Only if all 2< >> exist, can they be combined into 00...(n)/00...( n) > >> > >> First sort all the values by size. Iterate through each value. > >> 1. Find a new segment, where two values differ only by 1 bit, such as > >> ...0... and ...1... > >> diff = ip_next ^ ip > >> if (diff & (diff-1)) == 0 > >> new_segment = true > >> The first non-zero place in the high direction of ip is the end of the > >> segment(segment_end). > >> For example...100... and...101..., the segment_end is ...111... > >> > >> 2. Count the number of consecutive and less than continuous_size in the > >> segment. > >> diff = ip_next - ip > >> if (diff & (diff-1)) == 0 && ip_next <= segment_end > >> continuous_size++ > >> > >> 3. Combine different ip intervals in the segment according to > >> continuous_size. > >> In continuous_size, from the highest bit of 1 to the lowest bit of 1, in > >> the order of segment start, each bit t
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.(Internet mail)
On 2021/3/25, 11:30 PM, "Mark Gray" wrote: On 19/03/2021 13:01, Dumitru Ceara wrote: > On 3/10/21 2:29 PM, gmingchen(陈供明) wrote: >> From: Gongming Chen >> Thanks for the patch. Looks like a lot of thought went into the algorithm and it has been interesting to review. Do you know if there are any well-known algorithms to do this? It seems like a common problem? If there was, it may be better to use it as we could reference standard documentation. Hi Mark, First of all, thanks for the review. Unfortunately, I did not find a well-known algorithms. >> This patch merges ipv4 addresses with wildcard masks, and replaces this >> ipv4 addresses with the combined ip/mask. This will greatly reduce the >> entries in the ovs security group flow table, especially when the host >> size is large. >> >> Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 >> ports(1.1.1.2-1.1.1.254). >> Only focus on the number of ip addresses, the original 253 addresses will >> be combined into 13 addresses. >> 1.1.1.2/31 >> 1.1.1.4/30 >> 1.1.1.8/29 >> 1.1.1.16/28 >> 1.1.1.32/27 >> 1.1.1.64/26 >> 1.1.1.128/26 >> 1.1.1.192/27 >> 1.1.1.224/28 >> 1.1.1.240/29 >> 1.1.1.248/30 >> 1.1.1.252/31 >> 1.1.1.254 >> >> Some scenes are similar to the following: >> 1.1.1.2, 1.1.1.6 >> After the combine: >> 1.1.1.2/255.255.255.251 >> You can use ovn-match-ip utility to match ip. >> such as: >> ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 >> 1.1.1.2/255.255.255.251 will show. >> >> Simple description of the algorithm. >> There are two situations >> 1. Combine once >> such as: >> 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 >> Combined into: 1.1.1.0/31, 1.0.1.0/31 >> 2. Combine multiple times >> 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 >> Combined into: 1.0.1.0/255.254.255.254 >> >> Considering the actual scene and simplicity, the first case is used to >> combine once. >> >> ...00... >> ...01... >> ...10... >> ...11... >> "..." means the same value omitted. >> Obviously, the above value can be expressed as ...00.../11100111. This >> continuous interval that can be represented by one or several wildcard >> masks is called a segment. >> Only if all 2<> exist, can they be combined into 00...(n)/00...( n) >> >> First sort all the values by size. Iterate through each value. >> 1. Find a new segment, where two values differ only by 1 bit, such as >> ...0... and ...1... >> diff = ip_next ^ ip >> if (diff & (diff-1)) == 0 >> new_segment = true >> The first non-zero place in the high direction of ip is the end of the >> segment(segment_end). >> For example...100... and...101..., the segment_end is ...111... >> >> 2. Count the number of consecutive and less than continuous_size in the >> segment. >> diff = ip_next - ip >> if (diff & (diff-1)) == 0 && ip_next <= segment_end >> continuous_size++ >> >> 3. Combine different ip intervals in the segment according to >> continuous_size. >> In continuous_size, from the highest bit of 1 to the lowest bit of 1, in >> the order of segment start, each bit that is 1 is a different ip interval >> that can be combined with a wildcard mask. >> For example, 000, 001, 010: >> continuous_size: 3 (binary 11), segment_start: 000 >> mask: ~(1 << 1 - 1) = 110; ~(1 << 0 - 1) = 111; >> Combined to: 000/110, 010/111 >> >> 4. The ip that cannot be recorded in a segment will not be combined. >> >> Signed-off-by: Gongming Chen >> --- > > Hi Gongming, > > Sorry for the delayed review. > > I have a few general remarks/concerns and some specific comments inline. > First, the general remarks. > > I'm wondering if it would make more sense for this wildcard combination > of IPs to be done outside OVN, in the CMS, for the following reasons: > > - it's IPv4 specific. > - the CMS usually has more information about when it is matching on IP > sets and can probably optimize the match it uses in the ACL.
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
On 2021/3/19, 9:02 PM, "Dumitru Ceara" wrote: On 3/10/21 2:29 PM, gmingchen(陈供明) wrote: > From: Gongming Chen > > This patch merges ipv4 addresses with wildcard masks, and replaces this > ipv4 addresses with the combined ip/mask. This will greatly reduce the > entries in the ovs security group flow table, especially when the host > size is large. > > Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 > ports(1.1.1.2-1.1.1.254). > Only focus on the number of ip addresses, the original 253 addresses will > be combined into 13 addresses. > 1.1.1.2/31 > 1.1.1.4/30 > 1.1.1.8/29 > 1.1.1.16/28 > 1.1.1.32/27 > 1.1.1.64/26 > 1.1.1.128/26 > 1.1.1.192/27 > 1.1.1.224/28 > 1.1.1.240/29 > 1.1.1.248/30 > 1.1.1.252/31 > 1.1.1.254 > > Some scenes are similar to the following: > 1.1.1.2, 1.1.1.6 > After the combine: > 1.1.1.2/255.255.255.251 > You can use ovn-match-ip utility to match ip. > such as: > ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 > 1.1.1.2/255.255.255.251 will show. > > Simple description of the algorithm. > There are two situations > 1. Combine once > such as: > 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 > Combined into: 1.1.1.0/31, 1.0.1.0/31 > 2. Combine multiple times > 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 > Combined into: 1.0.1.0/255.254.255.254 > > Considering the actual scene and simplicity, the first case is used to > combine once. > > ...00... > ...01... > ...10... > ...11... > "..." means the same value omitted. > Obviously, the above value can be expressed as ...00.../11100111. This > continuous interval that can be represented by one or several wildcard > masks is called a segment. > Only if all 2< exist, can they be combined into 00...(n)/00...( n) > > First sort all the values by size. Iterate through each value. > 1. Find a new segment, where two values differ only by 1 bit, such as > ...0... and ...1... > diff = ip_next ^ ip > if (diff & (diff-1)) == 0 > new_segment = true > The first non-zero place in the high direction of ip is the end of the > segment(segment_end). > For example...100... and...101..., the segment_end is ...111... > > 2. Count the number of consecutive and less than continuous_size in the > segment. > diff = ip_next - ip > if (diff & (diff-1)) == 0 && ip_next <= segment_end > continuous_size++ > > 3. Combine different ip intervals in the segment according to > continuous_size. > In continuous_size, from the highest bit of 1 to the lowest bit of 1, in > the order of segment start, each bit that is 1 is a different ip interval > that can be combined with a wildcard mask. > For example, 000, 001, 010: > continuous_size: 3 (binary 11), segment_start: 000 > mask: ~(1 << 1 - 1) = 110; ~(1 << 0 - 1) = 111; > Combined to: 000/110, 010/111 > > 4. The ip that cannot be recorded in a segment will not be combined. > > Signed-off-by: Gongming Chen > --- Hi Gongming, Sorry for the delayed review. I have a few general remarks/concerns and some specific comments inline. First, the general remarks. I'm wondering if it would make more sense for this wildcard combination of IPs to be done outside OVN, in the CMS, for the following reasons: - it's IPv4 specific. - the CMS usually has more information about when it is matching on IP sets and can probably optimize the match it uses in the ACL. - the code in expr_const_sets_add() used to be a relatively direct translation from sets of constants to sets of port names/IPs; this changes with the optimization your proposing. - the new utility, ovn-match-ip, would be useful but I'm worried that users will often forget to use it. I'm curious about your and the maintainers' opinion on these points. Hi Dumitru, First, thanks for your review. On the one hand, I agree with your point of view. The cms side is more clear about the details of the ip, and the ip can be better optimized. However, on the other hand, I think that ovn, as a network provider, should not assume that upper layers such as cms have already made these optimizations. In fact, some cms do not have such a function, such as openstack, k8s, and they hope that this specific and complex work will be realized by the network provider. In te
[ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
From: Gongming Chen This patch merges ipv4 addresses with wildcard masks, and replaces this ipv4 addresses with the combined ip/mask. This will greatly reduce the entries in the ovs security group flow table, especially when the host size is large. Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 ports(1.1.1.2-1.1.1.254). Only focus on the number of ip addresses, the original 253 addresses will be combined into 13 addresses. 1.1.1.2/31 1.1.1.4/30 1.1.1.8/29 1.1.1.16/28 1.1.1.32/27 1.1.1.64/26 1.1.1.128/26 1.1.1.192/27 1.1.1.224/28 1.1.1.240/29 1.1.1.248/30 1.1.1.252/31 1.1.1.254 Some scenes are similar to the following: 1.1.1.2, 1.1.1.6 After the combine: 1.1.1.2/255.255.255.251 You can use ovn-match-ip utility to match ip. such as: ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 1.1.1.2/255.255.255.251 will show. Simple description of the algorithm. There are two situations 1. Combine once such as: 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.1.1.0/31, 1.0.1.0/31 2. Combine multiple times 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.0.1.0/255.254.255.254 Considering the actual scene and simplicity, the first case is used to combine once. ...00... ...01... ...10... ...11... "..." means the same value omitted. Obviously, the above value can be expressed as ...00.../11100111. This continuous interval that can be represented by one or several wildcard masks is called a segment. Only if all 2< --- debian/ovn-common.install | 1 + lib/expr.c| 219 ++ rhel/ovn-fedora.spec.in | 1 + tests/ovn.at | 136 +++ tests/test-ovn.c | 9 ++ utilities/automake.mk | 5 +- utilities/ovn-match-ip.in | 78 ++ 7 files changed, 382 insertions(+), 67 deletions(-) create mode 100755 utilities/ovn-match-ip.in diff --git a/debian/ovn-common.install b/debian/ovn-common.install index 8e5915724..0095df918 100644 --- a/debian/ovn-common.install +++ b/debian/ovn-common.install @@ -5,6 +5,7 @@ usr/bin/ovn-ic-nbctl usr/bin/ovn-ic-sbctl usr/bin/ovn-trace usr/bin/ovn-detrace +usr/bin/ovn-match-ip usr/share/ovn/scripts/ovn-ctl usr/share/ovn/scripts/ovndb-servers.ocf usr/share/ovn/scripts/ovn-lib diff --git a/lib/expr.c b/lib/expr.c index f061a8fbe..0a7203817 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -1060,6 +1060,200 @@ expr_constant_set_destroy(struct expr_constant_set *cs) } } +struct ip_in +{ +uint32_t *ip; +size_t size; +}; + +struct ip_out_entry +{ +uint32_t ip; +uint32_t mask; +bool masked; +}; + +struct ip_out +{ +struct ip_out_entry *entries; +size_t used; +size_t size; +}; + +static int +compare_mask_ip(const void *a, const void *b) +{ +uint32_t a_ = *(uint32_t *)a; +uint32_t b_ = *(uint32_t *)b; + +return a_ < b_ ? -1 : a_ > b_; +} + +/* Function to check ip return data and xrealloc. */ +static void +check_realloc_ip_out(struct ip_out *ip_out_data){ +if (ip_out_data->used >= ip_out_data->size) { +ip_out_data->entries = x2nrealloc(ip_out_data->entries, +&ip_out_data->size, +sizeof *ip_out_data->entries); +} +} + +/* Simple description of the algorithm. + * There are two situations + * 1. Combine once + * such as: + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.1.1.0/31, 1.0.1.0/31 + * 2. Combine multiple times + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.0.1.0/255.254.255.254 + * + * Considering the actual scene and simplicity, the first case is used to + * combine once. + * + * ...00... + * ...01... + * ...10... + * ...11... + * "..." means the same value omitted. + * Obviously, the above value can be expressed as ...00.../11100111. This + * continuous interval that can be represented by one or several wildcard + * masks is called a segment. + * Only if all 2size, sizeof(uint32_t), + compare_mask_ip); +memset(ip_out_data, 0, sizeof(struct ip_out)); + +for (i = 0; i < ip_in_data->size; i++) { +if (i + 1 >= ip_in_data->size) { +if (!recording) { +goto end_when_not_recording; +} else { +goto end_when_recording; +} +} +/* Not recording in a segment. + * Record a new segment or not combine. */ +if (!recording) { +connect = ip_in_data->ip[i + 1] ^ ip_in_data->ip[i]; +/* Only one bit different. */ +if ((connect & (connect - 1)) == 0) { +recording = true; +start = ip_in_data->ip[i]; +continuous_size = 2; +mask_base = connect; + +int j = 0; +end = start; +/* The first non-zero place in the high direction is + * the end of the segment. */ +while (j <
[ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
From: Gongming Chen This patch merges ipv4 addresses with wildcard masks, and replaces this ipv4 addresses with the combined ip/mask. This will greatly reduce the entries in the ovs security group flow table, especially when the host size is large. Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 ports(1.1.1.2-1.1.1.254). Only focus on the number of ip addresses, the original 253 addresses will be combined into 13 addresses. 1.1.1.2/31 1.1.1.4/30 1.1.1.8/29 1.1.1.16/28 1.1.1.32/27 1.1.1.64/26 1.1.1.128/26 1.1.1.192/27 1.1.1.224/28 1.1.1.240/29 1.1.1.248/30 1.1.1.252/31 1.1.1.254 Some scenes are similar to the following: 1.1.1.2, 1.1.1.6 After the combine: 1.1.1.2/255.255.255.251 You can use ovn-match-ip utility to match ip. such as: ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 1.1.1.2/255.255.255.251 will show. Simple description of the algorithm. There are two situations 1. Combine once such as: 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.1.1.0/31, 1.0.1.0/31 2. Combine multiple times 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.0.1.0/255.254.255.254 Considering the actual scene and simplicity, the first case is used to combine once. ...00... ...01... ...10... ...11... "..." means the same value omitted. Obviously, the above value can be expressed as ...00.../11100111. This continuous interval that can be represented by one or several wildcard masks is called a segment. Only if all 2< --- debian/ovn-common.install | 1 + lib/expr.c| 219 ++ rhel/ovn-fedora.spec.in | 1 + tests/ovn.at | 136 +++ tests/test-ovn.c | 9 ++ utilities/automake.mk | 5 +- utilities/ovn-match-ip.in | 78 ++ 7 files changed, 382 insertions(+), 67 deletions(-) create mode 100755 utilities/ovn-match-ip.in diff --git a/debian/ovn-common.install b/debian/ovn-common.install index 8e5915724..0095df918 100644 --- a/debian/ovn-common.install +++ b/debian/ovn-common.install @@ -5,6 +5,7 @@ usr/bin/ovn-ic-nbctl usr/bin/ovn-ic-sbctl usr/bin/ovn-trace usr/bin/ovn-detrace +usr/bin/ovn-match-ip usr/share/ovn/scripts/ovn-ctl usr/share/ovn/scripts/ovndb-servers.ocf usr/share/ovn/scripts/ovn-lib diff --git a/lib/expr.c b/lib/expr.c index f061a8fbe..0a7203817 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -1060,6 +1060,200 @@ expr_constant_set_destroy(struct expr_constant_set *cs) } } +struct ip_in +{ +uint32_t *ip; +size_t size; +}; + +struct ip_out_entry +{ +uint32_t ip; +uint32_t mask; +bool masked; +}; + +struct ip_out +{ +struct ip_out_entry *entries; +size_t used; +size_t size; +}; + +static int +compare_mask_ip(const void *a, const void *b) +{ +uint32_t a_ = *(uint32_t *)a; +uint32_t b_ = *(uint32_t *)b; + +return a_ < b_ ? -1 : a_ > b_; +} + +/* Function to check ip return data and xrealloc. */ +static void +check_realloc_ip_out(struct ip_out *ip_out_data){ +if (ip_out_data->used >= ip_out_data->size) { +ip_out_data->entries = x2nrealloc(ip_out_data->entries, +&ip_out_data->size, +sizeof *ip_out_data->entries); +} +} + +/* Simple description of the algorithm. + * There are two situations + * 1. Combine once + * such as: + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.1.1.0/31, 1.0.1.0/31 + * 2. Combine multiple times + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.0.1.0/255.254.255.254 + * + * Considering the actual scene and simplicity, the first case is used to + * combine once. + * + * ...00... + * ...01... + * ...10... + * ...11... + * "..." means the same value omitted. + * Obviously, the above value can be expressed as ...00.../11100111. This + * continuous interval that can be represented by one or several wildcard + * masks is called a segment. + * Only if all 2size, sizeof(uint32_t), + compare_mask_ip); +memset(ip_out_data, 0, sizeof(struct ip_out)); + +for (i = 0; i < ip_in_data->size; i++) { +if (i + 1 >= ip_in_data->size) { +if (!recording) { +goto end_when_not_recording; +} else { +goto end_when_recording; +} +} +/* Not recording in a segment. + * Record a new segment or not combine. */ +if (!recording) { +connect = ip_in_data->ip[i + 1] ^ ip_in_data->ip[i]; +/* Only one bit different. */ +if ((connect & (connect - 1)) == 0) { +recording = true; +start = ip_in_data->ip[i]; +continuous_size = 2; +mask_base = connect; + +int j = 0; +end = start; +/* The first non-zero place in the high direction is + * the end of the segment. */ +while (j < 32 && ((start &
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
Sorry, I just noticed that ovsrobot reported some errors. https://github.com/ovsrobot/ovn/actions/runs/583964200 I check and fix it and resubmit. Thanks, Gongming On 2021/3/10, 5:48 PM, "gmingchen(陈供明)" wrote: Hi all, please review this patch, thanks. By the way, is there any plan for this patch? Thanks, Gongming On 2021/2/20, 5:13 PM, "gmingchen(陈供明)" wrote: From: Gongming Chen This patch merges ipv4 addresses with wildcard masks, and replaces this ipv4 addresses with the combined ip/mask. This will greatly reduce the entries in the ovs security group flow table, especially when the host size is large. Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 ports(1.1.1.2-1.1.1.254). Only focus on the number of ip addresses, the original 253 addresses will be combined into 13 addresses. 1.1.1.2/31 1.1.1.4/30 1.1.1.8/29 1.1.1.16/28 1.1.1.32/27 1.1.1.64/26 1.1.1.128/26 1.1.1.192/27 1.1.1.224/28 1.1.1.240/29 1.1.1.248/30 1.1.1.252/31 1.1.1.254 Some scenes are similar to the following: 1.1.1.2, 1.1.1.6 After the combine: 1.1.1.2/255.255.255.251 You can use ovn-match-ip utility to match ip. such as: ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 1.1.1.2/255.255.255.251 will show. Simple description of the algorithm. There are two situations 1. Combine once such as: 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.1.1.0/31, 1.0.1.0/31 2. Combine multiple times 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.0.1.0/255.254.255.254 Considering the actual scene and simplicity, the first case is used to combine once. ...00... ...01... ...10... ...11... "..." means the same value omitted. Obviously, the above value can be expressed as ...00.../11100111. This continuous interval that can be represented by one or several wildcard masks is called a segment. Only if all 2< --- debian/ovn-common.install | 1 + lib/expr.c| 219 ++ rhel/ovn-fedora.spec.in | 1 + tests/ovn.at | 136 +++ tests/test-ovn.c | 9 ++ utilities/automake.mk | 5 +- utilities/ovn-match-ip.in | 78 ++ 7 files changed, 382 insertions(+), 67 deletions(-) create mode 100755 utilities/ovn-match-ip.in diff --git a/debian/ovn-common.install b/debian/ovn-common.install index 8e5915724..0095df918 100644 --- a/debian/ovn-common.install +++ b/debian/ovn-common.install @@ -5,6 +5,7 @@ usr/bin/ovn-ic-nbctl usr/bin/ovn-ic-sbctl usr/bin/ovn-trace usr/bin/ovn-detrace +usr/bin/ovn-match-ip usr/share/ovn/scripts/ovn-ctl usr/share/ovn/scripts/ovndb-servers.ocf usr/share/ovn/scripts/ovn-lib diff --git a/lib/expr.c b/lib/expr.c index f061a8fbe..0a7203817 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -1060,6 +1060,200 @@ expr_constant_set_destroy(struct expr_constant_set *cs) } } +struct ip_in +{ +uint32_t *ip; +size_t size; +}; + +struct ip_out_entry +{ +uint32_t ip; +uint32_t mask; +bool masked; +}; + +struct ip_out +{ +struct ip_out_entry *entries; +size_t used; +size_t size; +}; + +static int +compare_mask_ip(const void *a, const void *b) +{ +uint32_t a_ = *(uint32_t *)a; +uint32_t b_ = *(uint32_t *)b; + +return a_ < b_ ? -1 : a_ > b_; +} + +/* Function to check ip return data and xrealloc. */ +static void +check_realloc_ip_out(struct ip_out *ip_out_data){ +if (ip_out_data->used >= ip_out_data->size) { +ip_out_data->entries = x2nrealloc(ip_out_data->entries, +&ip_out_data->size, +sizeof *ip_out_data->entries); +} +} + +/* Simple description of the algorithm. + * There are two situations + * 1. Combine once + * such as: + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.1.1.0/31, 1.0.1.0/31 + * 2. Combine multiple times + * 1.1.1.
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
Hi all, please review this patch, thanks. By the way, is there any plan for this patch? Thanks, Gongming On 2021/2/20, 5:13 PM, "gmingchen(陈供明)" wrote: From: Gongming Chen This patch merges ipv4 addresses with wildcard masks, and replaces this ipv4 addresses with the combined ip/mask. This will greatly reduce the entries in the ovs security group flow table, especially when the host size is large. Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 ports(1.1.1.2-1.1.1.254). Only focus on the number of ip addresses, the original 253 addresses will be combined into 13 addresses. 1.1.1.2/31 1.1.1.4/30 1.1.1.8/29 1.1.1.16/28 1.1.1.32/27 1.1.1.64/26 1.1.1.128/26 1.1.1.192/27 1.1.1.224/28 1.1.1.240/29 1.1.1.248/30 1.1.1.252/31 1.1.1.254 Some scenes are similar to the following: 1.1.1.2, 1.1.1.6 After the combine: 1.1.1.2/255.255.255.251 You can use ovn-match-ip utility to match ip. such as: ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 1.1.1.2/255.255.255.251 will show. Simple description of the algorithm. There are two situations 1. Combine once such as: 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.1.1.0/31, 1.0.1.0/31 2. Combine multiple times 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.0.1.0/255.254.255.254 Considering the actual scene and simplicity, the first case is used to combine once. ...00... ...01... ...10... ...11... "..." means the same value omitted. Obviously, the above value can be expressed as ...00.../11100111. This continuous interval that can be represented by one or several wildcard masks is called a segment. Only if all 2< --- debian/ovn-common.install | 1 + lib/expr.c| 219 ++ rhel/ovn-fedora.spec.in | 1 + tests/ovn.at | 136 +++ tests/test-ovn.c | 9 ++ utilities/automake.mk | 5 +- utilities/ovn-match-ip.in | 78 ++ 7 files changed, 382 insertions(+), 67 deletions(-) create mode 100755 utilities/ovn-match-ip.in diff --git a/debian/ovn-common.install b/debian/ovn-common.install index 8e5915724..0095df918 100644 --- a/debian/ovn-common.install +++ b/debian/ovn-common.install @@ -5,6 +5,7 @@ usr/bin/ovn-ic-nbctl usr/bin/ovn-ic-sbctl usr/bin/ovn-trace usr/bin/ovn-detrace +usr/bin/ovn-match-ip usr/share/ovn/scripts/ovn-ctl usr/share/ovn/scripts/ovndb-servers.ocf usr/share/ovn/scripts/ovn-lib diff --git a/lib/expr.c b/lib/expr.c index f061a8fbe..0a7203817 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -1060,6 +1060,200 @@ expr_constant_set_destroy(struct expr_constant_set *cs) } } +struct ip_in +{ +uint32_t *ip; +size_t size; +}; + +struct ip_out_entry +{ +uint32_t ip; +uint32_t mask; +bool masked; +}; + +struct ip_out +{ +struct ip_out_entry *entries; +size_t used; +size_t size; +}; + +static int +compare_mask_ip(const void *a, const void *b) +{ +uint32_t a_ = *(uint32_t *)a; +uint32_t b_ = *(uint32_t *)b; + +return a_ < b_ ? -1 : a_ > b_; +} + +/* Function to check ip return data and xrealloc. */ +static void +check_realloc_ip_out(struct ip_out *ip_out_data){ +if (ip_out_data->used >= ip_out_data->size) { +ip_out_data->entries = x2nrealloc(ip_out_data->entries, +&ip_out_data->size, +sizeof *ip_out_data->entries); +} +} + +/* Simple description of the algorithm. + * There are two situations + * 1. Combine once + * such as: + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.1.1.0/31, 1.0.1.0/31 + * 2. Combine multiple times + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.0.1.0/255.254.255.254 + * + * Considering the actual scene and simplicity, the first case is used to + * combine once. + * + * ...00... + * ...01... + * ...10... + * ...11... + * "..." means the same value omitted. + * Obviously, the above value can be expressed as ...00.../11100111. This + * continuous interval that can be represented by one or several wildcard + * masks is called a segment. + * Only if all 2<ip, ip_in_data->size, sizeof(uint32_t), + compare_mask_ip); +memset(ip_out_data, 0, sizeof(struct ip_out)); + +for (i = 0; i < ip_in_data->size; i++) { +if (i + 1 >= i
[ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
From: Gongming Chen This patch merges ipv4 addresses with wildcard masks, and replaces this ipv4 addresses with the combined ip/mask. This will greatly reduce the entries in the ovs security group flow table, especially when the host size is large. Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 ports(1.1.1.2-1.1.1.254). Only focus on the number of ip addresses, the original 253 addresses will be combined into 13 addresses. 1.1.1.2/31 1.1.1.4/30 1.1.1.8/29 1.1.1.16/28 1.1.1.32/27 1.1.1.64/26 1.1.1.128/26 1.1.1.192/27 1.1.1.224/28 1.1.1.240/29 1.1.1.248/30 1.1.1.252/31 1.1.1.254 Some scenes are similar to the following: 1.1.1.2, 1.1.1.6 After the combine: 1.1.1.2/255.255.255.251 You can use ovn-match-ip utility to match ip. such as: ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 1.1.1.2/255.255.255.251 will show. Simple description of the algorithm. There are two situations 1. Combine once such as: 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.1.1.0/31, 1.0.1.0/31 2. Combine multiple times 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.0.1.0/255.254.255.254 Considering the actual scene and simplicity, the first case is used to combine once. ...00... ...01... ...10... ...11... "..." means the same value omitted. Obviously, the above value can be expressed as ...00.../11100111. This continuous interval that can be represented by one or several wildcard masks is called a segment. Only if all 2< --- debian/ovn-common.install | 1 + lib/expr.c| 219 ++ rhel/ovn-fedora.spec.in | 1 + tests/ovn.at | 136 +++ tests/test-ovn.c | 9 ++ utilities/automake.mk | 5 +- utilities/ovn-match-ip.in | 78 ++ 7 files changed, 382 insertions(+), 67 deletions(-) create mode 100755 utilities/ovn-match-ip.in diff --git a/debian/ovn-common.install b/debian/ovn-common.install index 8e5915724..0095df918 100644 --- a/debian/ovn-common.install +++ b/debian/ovn-common.install @@ -5,6 +5,7 @@ usr/bin/ovn-ic-nbctl usr/bin/ovn-ic-sbctl usr/bin/ovn-trace usr/bin/ovn-detrace +usr/bin/ovn-match-ip usr/share/ovn/scripts/ovn-ctl usr/share/ovn/scripts/ovndb-servers.ocf usr/share/ovn/scripts/ovn-lib diff --git a/lib/expr.c b/lib/expr.c index f061a8fbe..0a7203817 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -1060,6 +1060,200 @@ expr_constant_set_destroy(struct expr_constant_set *cs) } } +struct ip_in +{ +uint32_t *ip; +size_t size; +}; + +struct ip_out_entry +{ +uint32_t ip; +uint32_t mask; +bool masked; +}; + +struct ip_out +{ +struct ip_out_entry *entries; +size_t used; +size_t size; +}; + +static int +compare_mask_ip(const void *a, const void *b) +{ +uint32_t a_ = *(uint32_t *)a; +uint32_t b_ = *(uint32_t *)b; + +return a_ < b_ ? -1 : a_ > b_; +} + +/* Function to check ip return data and xrealloc. */ +static void +check_realloc_ip_out(struct ip_out *ip_out_data){ +if (ip_out_data->used >= ip_out_data->size) { +ip_out_data->entries = x2nrealloc(ip_out_data->entries, +&ip_out_data->size, +sizeof *ip_out_data->entries); +} +} + +/* Simple description of the algorithm. + * There are two situations + * 1. Combine once + * such as: + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.1.1.0/31, 1.0.1.0/31 + * 2. Combine multiple times + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.0.1.0/255.254.255.254 + * + * Considering the actual scene and simplicity, the first case is used to + * combine once. + * + * ...00... + * ...01... + * ...10... + * ...11... + * "..." means the same value omitted. + * Obviously, the above value can be expressed as ...00.../11100111. This + * continuous interval that can be represented by one or several wildcard + * masks is called a segment. + * Only if all 2size, sizeof(uint32_t), + compare_mask_ip); +memset(ip_out_data, 0, sizeof(struct ip_out)); + +for (i = 0; i < ip_in_data->size; i++) { +if (i + 1 >= ip_in_data->size) { +if (!recording) { +goto end_when_not_recording; +} else { +goto end_when_recording; +} +} +/* Not recording in a segment. + * Record a new segment or not combine. */ +if (!recording) { +connect = ip_in_data->ip[i + 1] ^ ip_in_data->ip[i]; +/* Only one bit different. */ +if ((connect & (connect - 1)) == 0) { +recording = true; +start = ip_in_data->ip[i]; +continuous_size = 2; +mask_base = connect; + +int j = 0; +end = start; +/* The first non-zero place in the high direction is + * the end of the segment. */ +while (j <
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
Hi Dumitru, Sorry to reply you so late. The ovn-match-ip utility has been submitted, and using ovn-match-ip is much more convenient than before. Therefore, the disable-combine-ipv4 option has also been removed The code and commit log also briefly describe and organize the algorithm. The test in this example has been added as 'ip4.src == $set5'. Thanks, Gongming Chen On 2021/2/10, 4:20 AM, "Dumitru Ceara" wrote: Resending as my previous try didn't make it on the mailing list. On 2/9/21 1:06 PM, Dumitru Ceara wrote: > On 2/9/21 12:26 PM, gmingchen(陈供明) wrote: >> Hi Dumitru, >> Thanks for review. >> >> On 2021/2/8, 6:19 PM, "Dumitru Ceara" wrote: >> >> On 2/7/21 1:25 PM, gmingchen(陈供明) wrote: >> > From: Gongming Chen >> >> Hi Gongming, >> >> First of all, thanks for the contribution! >> >> This is not a full review, just some comments for now. >> >> It seems that there's a memory leak with your patch applied. >> AddressSanitizer reports: >> >> Direct leak of 12 byte(s) in 1 object(s) allocated from: >> #0 0x49644d in malloc >> >> (/home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/tests/ovstest+0x49644d) >> >> #1 0x538604 in xmalloc >> /home/runner/work/ovn/ovn/ovs_src/lib/util.c:138:15 >> #2 0x62636f in expr_const_sets_add >> >> /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../lib/expr.c:1237:18 >> >> #3 0x4cf8f6 in create_addr_sets >> >> /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/test-ovn.c:230:5 >> >> #4 0x4cf8f6 in test_parse_expr__ >> >> /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/test-ovn.c:296:5 >> >> #5 0x4dfd04 in ovs_cmdl_run_command__ >> /home/runner/work/ovn/ovn/ovs_src/lib/command-line.c:247:17 >> #6 0x4c6810 in test_ovn_main >> >> /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/test-ovn.c:1635:5 >> >> #7 0x4c6810 in ovstest_wrapper_test_ovn_main__ >> >> /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/test-ovn.c:1638:1 >> >> #8 0x4dfd04 in ovs_cmdl_run_command__ >> /home/runner/work/ovn/ovn/ovs_src/lib/command-line.c:247:17 >> #9 0x4c5fe3 in main >> >> /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/ovstest.c:150:9 >> >> #10 0x7f71aa6ddbf6 in __libc_start_main >> (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6) >> >> Full reports are available in the ovsrobot OVN github CI run >> artifacts: >> https://github.com/ovsrobot/ovn/actions/runs/545416492 >> >> Just a note, if you push the branch to your own fork it will >> trigger the >> github action to run CI and the "linux clang test asan" job will >> also >> enable AddressSanitizer. >> >> Thanks, there are really missing the free ip_data.ip, resulting in a >> memory leak. > > Ok. > >> >> There are also a few style related issues (e.g., sizeof args), >> please >> see the guidelines here: >> >> >> https://github.com/ovn-org/ovn/blob/master/Documentation/internals/contributing/coding-style.rst >> >> >> Sorry, does this mean that >> ip_r_data->ip = xmalloc(4 * sizeof(uint32_t)) >> should be replaced with >> ip_r_data->ip = xmalloc(4 * sizeof ip_r_data->ip)? > > Actually: > sizeof *ip_r_data->ip > >> >> > >> > In the ovn security group, each host ip corresponds to at least >> 4 flow >> > tables (different connection states). As the scale of hosts >> using the >> > security group increases, the ovs security group flow table will >> > increase sharply, especially when it is applied the remote group >> > feature in OpenStack. >> > >> > This patch merges ipv4 addresses with wildcard masks, and >> replaces this >> > ipv4 addresses with the merged ip/mask. This will greatly &
[ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
From: Gongming Chen This patch merges ipv4 addresses with wildcard masks, and replaces this ipv4 addresses with the combined ip/mask. This will greatly reduce the entries in the ovs security group flow table, especially when the host size is large. Analysis in the simplest scenario, a network 1.1.1.0/24 network,create 253 ports(1.1.1.2-1.1.1.254). Only focus on the number of ip addresses, the original 253 addresses will be combined into 13 addresses. 1.1.1.2/31 1.1.1.4/30 1.1.1.8/29 1.1.1.16/28 1.1.1.32/27 1.1.1.64/26 1.1.1.128/26 1.1.1.192/27 1.1.1.224/28 1.1.1.240/29 1.1.1.248/30 1.1.1.252/31 1.1.1.254 Some scenes are similar to the following: 1.1.1.2, 1.1.1.6 After the combine: 1.1.1.2/255.255.255.251 You can use ovn-match-ip utility to match ip. such as: ovs-ofctl dump-flows br-int | ovn-match-ip 1.1.1.6 1.1.1.2/255.255.255.251 will show. Simple description of the algorithm. There are two situations 1. Combine once such as: 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.1.1.0/31, 1.0.1.0/31 2. Combine multiple times 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 Combined into: 1.0.1.0/255.254.255.254 Considering the actual scene and simplicity, the first case is used to combine once. ...00... ...01... ...10... ...11... "..." means the same value omitted. Obviously, the above value can be expressed as ...00.../11100111. This continuous interval that can be represented by one or several wildcard masks is called a segment. Only if all 2< --- debian/ovn-common.install | 1 + lib/expr.c| 219 ++ rhel/ovn-fedora.spec.in | 1 + tests/ovn.at | 136 +++ tests/test-ovn.c | 9 ++ utilities/automake.mk | 5 +- utilities/ovn-match-ip.in | 78 ++ 7 files changed, 382 insertions(+), 67 deletions(-) create mode 100755 utilities/ovn-match-ip.in diff --git a/debian/ovn-common.install b/debian/ovn-common.install index 8e5915724..0095df918 100644 --- a/debian/ovn-common.install +++ b/debian/ovn-common.install @@ -5,6 +5,7 @@ usr/bin/ovn-ic-nbctl usr/bin/ovn-ic-sbctl usr/bin/ovn-trace usr/bin/ovn-detrace +usr/bin/ovn-match-ip usr/share/ovn/scripts/ovn-ctl usr/share/ovn/scripts/ovndb-servers.ocf usr/share/ovn/scripts/ovn-lib diff --git a/lib/expr.c b/lib/expr.c index f061a8fbe..0a7203817 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -1060,6 +1060,200 @@ expr_constant_set_destroy(struct expr_constant_set *cs) } } +struct ip_in +{ +uint32_t *ip; +size_t size; +}; + +struct ip_out_entry +{ +uint32_t ip; +uint32_t mask; +bool masked; +}; + +struct ip_out +{ +struct ip_out_entry *entries; +size_t used; +size_t size; +}; + +static int +compare_mask_ip(const void *a, const void *b) +{ +uint32_t a_ = *(uint32_t *)a; +uint32_t b_ = *(uint32_t *)b; + +return a_ < b_ ? -1 : a_ > b_; +} + +/* Function to check ip return data and xrealloc. */ +static void +check_realloc_ip_out(struct ip_out *ip_out_data){ +if (ip_out_data->used >= ip_out_data->size) { +ip_out_data->entries = x2nrealloc(ip_out_data->entries, +&ip_out_data->size, +sizeof *ip_out_data->entries); +} +} + +/* Simple description of the algorithm. + * There are two situations + * 1. Combine once + * such as: + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.1.1.0/31, 1.0.1.0/31 + * 2. Combine multiple times + * 1.1.1.0 1.1.1.1 1.0.1.0 1.0.1.1 + * Combined into: 1.0.1.0/255.254.255.254 + * + * Considering the actual scene and simplicity, the first case is used to + * combine once. + * + * ...00... + * ...01... + * ...10... + * ...11... + * "..." means the same value omitted. + * Obviously, the above value can be expressed as ...00.../11100111. This + * continuous interval that can be represented by one or several wildcard + * masks is called a segment. + * Only if all 2size, sizeof(uint32_t), + compare_mask_ip); +memset(ip_out_data, 0, sizeof(struct ip_out)); + +for (i = 0; i < ip_in_data->size; i++) { +if (i + 1 >= ip_in_data->size) { +if (!recording) { +goto end_when_not_recording; +} else { +goto end_when_recording; +} +} +/* Not recording in a segment. + * Record a new segment or not combine. */ +if (!recording) { +connect = ip_in_data->ip[i + 1] ^ ip_in_data->ip[i]; +/* Only one bit different. */ +if ((connect & (connect - 1)) == 0) { +recording = true; +start = ip_in_data->ip[i]; +continuous_size = 2; +mask_base = connect; + +int j = 0; +end = start; +/* The first non-zero place in the high direction is + * the end of the segment. */ +while (j <
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
Hi Mark, Sorry for getting back to you late. Thanks for your review. I totally agree with your very detailed suggestion. I think it is very useful, especially x2nrealloc. I will resubmit later. Thanks, Gongming On 2021/2/11, 9:26 AM, "Mark Michelson" wrote: Hi Gongming. I saw Dumitru's review, so I won't repeat anything he said. I have a few comments of my own below. On 2/7/21 7:25 AM, gmingchen(陈供明) wrote: > From: Gongming Chen > > In the ovn security group, each host ip corresponds to at least 4 flow > tables (different connection states). As the scale of hosts using the > security group increases, the ovs security group flow table will > increase sharply, especially when it is applied the remote group > feature in OpenStack. > > This patch merges ipv4 addresses with wildcard masks, and replaces this > ipv4 addresses with the merged ip/mask. This will greatly reduce the > entries in the ovs security group flow table, especially when the host > size is large. After being used in a production environment, the number > of ovs flow tables will be reduced by at least 50% in most scenarios, > when the remote group in OpenStack is applied. > > Analysis in the simplest scenario, a network 1.1.1.0/24 network, enable > the OpenStack security group remote group feature, create 253 virtual > machine ports(1.1.1.2-1.1.1.254). > > Only focus on the number of ip addresses, in the table=44 table: > ./configure --disable-combine-ipv4: > 1.1.1.2-1.1.1.254(253 flow meters) * 4(connection status) * > 1(local net of localport) = 1012 > > ./configure --enable-combine-ipv4(default): > 1.1.1.2/31 > 1.1.1.4/30 > 1.1.1.8/29 > 1.1.1.16/28 > 1.1.1.32/27 > 1.1.1.64/26 > 1.1.1.128/26 > 1.1.1.192/27 > 1.1.1.224/28 > 1.1.1.240/29 > 1.1.1.248/30 > 1.1.1.252/31 > 1.1.1.254 > 13 flow tables * 4(connection status) * 1(local net of localport) = 52 > > Reduced from 1012 flow meters to 52, a 19.4 times reduction. > > Some scenes are similar to the following: > 1.1.1.2, 1.1.1.6 > After the combine: > 1.1.1.2/255.255.255.251 > This will slightly increase the difficulty of finding the flow table > corresponding to a single address. > such as: > ovs-ofctl dump-flows br-int | grep 1.1.1.6 > The result is empty. > 1.1.1.6 will match 1.1.1.2/255.255.255.251 > > Signed-off-by: Gongming Chen > --- > configure.ac | 1 + > lib/expr.c | 217 +++ > m4/ovn.m4| 21 > tests/atlocal.in | 1 + > tests/ovn.at | 286 +-- > 5 files changed, 443 insertions(+), 83 deletions(-) > > diff --git a/configure.ac b/configure.ac > index b2d084318..6dc51a5cc 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -131,6 +131,7 @@ OVS_LIBTOOL_VERSIONS > OVS_CHECK_CXX > AX_FUNC_POSIX_MEMALIGN > OVN_CHECK_UNBOUND > +OVN_CHECK_COMBINE_IPV4 > > OVS_CHECK_INCLUDE_NEXT([stdio.h string.h]) > AC_CONFIG_FILES([lib/libovn.sym]) > diff --git a/lib/expr.c b/lib/expr.c > index 796e88ac7..0b6dee3b3 100644 > --- a/lib/expr.c > +++ b/lib/expr.c > @@ -1030,6 +1030,194 @@ expr_constant_set_destroy(struct expr_constant_set *cs) > } > } > > +struct ip_v > +{ > +uint32_t *ip; > +uint32_t size; > +}; > + > +struct ip_r > +{ > +uint32_t *ip; > +uint32_t *mask; > +uint32_t used; > +uint32_t size; > +bool *masked; > +}; Since the ip, mask, and masked arrays all have the same size, it would make memory management easier if they were combined into a single struct. For example: struct ip_r_entry { uint32_t ip; uint32_t mask; bool masked; }; struct ip_r { struct ip_r_entry *entries; uint32_t used; uint32_t size; }; This reduces the number of malloced pointers from 3 to 1, making it easier to reallocate and free data when necessary. Also what do the names ip_v and ip_r mean? I'm guessing that ip_v might mean "IP vector"? But I have no idea what ip_r means. I think these structs could use better names. > + > +/* Macro to check ip return data and xrealloc. */ > +#define CHECK_REALLOC_IP_R_DATA(IP_R_DATA) \ > +if (IP_R_DATA->used >= IP_R_DATA->size) { \ > +
Re: [ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
Hi Dumitru, Thanks for review. On 2021/2/8, 6:19 PM, "Dumitru Ceara" wrote: On 2/7/21 1:25 PM, gmingchen(陈供明) wrote: > From: Gongming Chen Hi Gongming, First of all, thanks for the contribution! This is not a full review, just some comments for now. It seems that there's a memory leak with your patch applied. AddressSanitizer reports: Direct leak of 12 byte(s) in 1 object(s) allocated from: #0 0x49644d in malloc (/home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/tests/ovstest+0x49644d) #1 0x538604 in xmalloc /home/runner/work/ovn/ovn/ovs_src/lib/util.c:138:15 #2 0x62636f in expr_const_sets_add /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../lib/expr.c:1237:18 #3 0x4cf8f6 in create_addr_sets /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/test-ovn.c:230:5 #4 0x4cf8f6 in test_parse_expr__ /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/test-ovn.c:296:5 #5 0x4dfd04 in ovs_cmdl_run_command__ /home/runner/work/ovn/ovn/ovs_src/lib/command-line.c:247:17 #6 0x4c6810 in test_ovn_main /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/test-ovn.c:1635:5 #7 0x4c6810 in ovstest_wrapper_test_ovn_main__ /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/test-ovn.c:1638:1 #8 0x4dfd04 in ovs_cmdl_run_command__ /home/runner/work/ovn/ovn/ovs_src/lib/command-line.c:247:17 #9 0x4c5fe3 in main /home/runner/work/ovn/ovn/ovn-20.12.90/_build/sub/../../tests/ovstest.c:150:9 #10 0x7f71aa6ddbf6 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6) Full reports are available in the ovsrobot OVN github CI run artifacts: https://github.com/ovsrobot/ovn/actions/runs/545416492 Just a note, if you push the branch to your own fork it will trigger the github action to run CI and the "linux clang test asan" job will also enable AddressSanitizer. Thanks, there are really missing the free ip_data.ip, resulting in a memory leak. There are also a few style related issues (e.g., sizeof args), please see the guidelines here: https://github.com/ovn-org/ovn/blob/master/Documentation/internals/contributing/coding-style.rst Sorry, does this mean that ip_r_data->ip = xmalloc(4 * sizeof(uint32_t)) should be replaced with ip_r_data->ip = xmalloc(4 * sizeof ip_r_data->ip)? > > In the ovn security group, each host ip corresponds to at least 4 flow > tables (different connection states). As the scale of hosts using the > security group increases, the ovs security group flow table will > increase sharply, especially when it is applied the remote group > feature in OpenStack. > > This patch merges ipv4 addresses with wildcard masks, and replaces this > ipv4 addresses with the merged ip/mask. This will greatly reduce the > entries in the ovs security group flow table, especially when the host > size is large. After being used in a production environment, the number > of ovs flow tables will be reduced by at least 50% in most scenarios, > when the remote group in OpenStack is applied. I think it would be great to describe the algorithm here, in the commit log, but also in the comments in the code. You are right, I will resubmit and add the description of the algorithm to the commit log and the code comments. > > Analysis in the simplest scenario, a network 1.1.1.0/24 network, enable > the OpenStack security group remote group feature, create 253 virtual > machine ports(1.1.1.2-1.1.1.254). > > Only focus on the number of ip addresses, in the table=44 table: > ./configure --disable-combine-ipv4: > 1.1.1.2-1.1.1.254(253 flow meters) * 4(connection status) * > 1(local net of localport) = 1012 > > ./configure --enable-combine-ipv4(default): > 1.1.1.2/31 > 1.1.1.4/30 > 1.1.1.8/29 > 1.1.1.16/28 > 1.1.1.32/27 > 1.1.1.64/26 > 1.1.1.128/26 > 1.1.1.192/27 > 1.1.1.224/28 > 1.1.1.240/29 > 1.1.1.248/30 > 1.1.1.252/31 > 1.1.1.254 > 13 flow tables * 4(connection status) * 1(local net of localport) = 52 > > Reduced from 1012 flow meters to 52, a 19.4 times reduction. > > Some scenes are similar to the following: > 1.1.1.2, 1.1.1.6 > After the combine: > 1.1.1.2/255.255.255.251 > This will slightly increase the difficulty of finding the flow table > corresponding to a single address. > such as: > ovs-ofctl dump-flows br-int | grep 1.1.1.6 > The result is empty. > 1.1.1.6 will match 1.1.1.2/255.255.255.251 Would it make sense and potentially make the life of t
Re: [ovs-dev] [PATCH ovn] tests: Fix Port_Binding up test.
Thanks, Gongming On Feb 8, 2021, at 6:01 PM, Numan Siddique wrote: On Mon, Feb 8, 2021 at 2:40 PM Dumitru Ceara wrote: > > On 2/7/21 3:52 AM, gmingchen(陈供明) wrote: > > From: Gongming Chen > > > > After setting the iface-id, immediately check the up status of the port > > binding, it will occasionally fail, especially when the port binding > > status is reported later. > > > > When it fails, the following will be output: > > Checking values in sb Port_Binding with logical_port=lsp1 against false... found false > > ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 external-ids:iface-id=lsp1 > > ./ovn-macros.at:307: "$@" > > Checking values in sb Port_Binding with logical_port=lsp1 against true... found false > > _uuid : 15ebabb6-3dbb-4806-aa85-d1c03e3b39f6 > > logical_port: lsp1 > > up : true > > ./ovn-macros.at:393: hard failure > > > > Fixes: 4d3cb42b076b ("binding: Set Logical_Switch_Port.up when all OVS flows are installed.") > > Signed-off-by: Gongming Chen > > --- > > Thanks for the fix! > > Acked-by: Dumitru Ceara Thanks for the fix. I applied this patch to master. I also added your name to the AUTHORS list. Numan > > ___ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
From: Gongming Chen In the ovn security group, each host ip corresponds to at least 4 flow tables (different connection states). As the scale of hosts using the security group increases, the ovs security group flow table will increase sharply, especially when it is applied the remote group feature in OpenStack. This patch merges ipv4 addresses with wildcard masks, and replaces this ipv4 addresses with the merged ip/mask. This will greatly reduce the entries in the ovs security group flow table, especially when the host size is large. After being used in a production environment, the number of ovs flow tables will be reduced by at least 50% in most scenarios, when the remote group in OpenStack is applied. Analysis in the simplest scenario, a network 1.1.1.0/24 network, enable the OpenStack security group remote group feature, create 253 virtual machine ports(1.1.1.2-1.1.1.254). Only focus on the number of ip addresses, in the table=44 table: ./configure --disable-combine-ipv4: 1.1.1.2-1.1.1.254(253 flow meters) * 4(connection status) * 1(local net of localport) = 1012 ./configure --enable-combine-ipv4(default): 1.1.1.2/31 1.1.1.4/30 1.1.1.8/29 1.1.1.16/28 1.1.1.32/27 1.1.1.64/26 1.1.1.128/26 1.1.1.192/27 1.1.1.224/28 1.1.1.240/29 1.1.1.248/30 1.1.1.252/31 1.1.1.254 13 flow tables * 4(connection status) * 1(local net of localport) = 52 Reduced from 1012 flow meters to 52, a 19.4 times reduction. Some scenes are similar to the following: 1.1.1.2, 1.1.1.6 After the combine: 1.1.1.2/255.255.255.251 This will slightly increase the difficulty of finding the flow table corresponding to a single address. such as: ovs-ofctl dump-flows br-int | grep 1.1.1.6 The result is empty. 1.1.1.6 will match 1.1.1.2/255.255.255.251 Signed-off-by: Gongming Chen --- configure.ac | 1 + lib/expr.c | 217 +++ m4/ovn.m4| 21 tests/atlocal.in | 1 + tests/ovn.at | 286 +-- 5 files changed, 443 insertions(+), 83 deletions(-) diff --git a/configure.ac b/configure.ac index b2d084318..6dc51a5cc 100644 --- a/configure.ac +++ b/configure.ac @@ -131,6 +131,7 @@ OVS_LIBTOOL_VERSIONS OVS_CHECK_CXX AX_FUNC_POSIX_MEMALIGN OVN_CHECK_UNBOUND +OVN_CHECK_COMBINE_IPV4 OVS_CHECK_INCLUDE_NEXT([stdio.h string.h]) AC_CONFIG_FILES([lib/libovn.sym]) diff --git a/lib/expr.c b/lib/expr.c index 796e88ac7..0b6dee3b3 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -1030,6 +1030,194 @@ expr_constant_set_destroy(struct expr_constant_set *cs) } } +struct ip_v +{ +uint32_t *ip; +uint32_t size; +}; + +struct ip_r +{ +uint32_t *ip; +uint32_t *mask; +uint32_t used; +uint32_t size; +bool *masked; +}; + +/* Macro to check ip return data and xrealloc. */ +#define CHECK_REALLOC_IP_R_DATA(IP_R_DATA) \ +if (IP_R_DATA->used >= IP_R_DATA->size) { \ +IP_R_DATA->ip = xrealloc(IP_R_DATA->ip, \ +2 * IP_R_DATA->size * sizeof(uint32_t)); \ +IP_R_DATA->mask = xrealloc(IP_R_DATA->mask, \ +2 * IP_R_DATA->size * sizeof(uint32_t)); \ +IP_R_DATA->masked = xrealloc(IP_R_DATA->masked, \ +2 * IP_R_DATA->size * sizeof(bool)); \ +IP_R_DATA->size = IP_R_DATA->size * 2; \ +} + +static void +combine_ipv4_in_mask(struct ip_v *ip_data, struct ip_r *ip_r_data){ +int i = 0, recorded =0; +uint32_t diff, connect, start, end, continuous_size, mask_base; + +start = 0; +continuous_size = 0; +mask_base = 0; +end = 0; + +memset(ip_r_data, 0, sizeof(struct ip_r)); +ip_r_data->ip = xmalloc(4 * sizeof(uint32_t)); +ip_r_data->mask = xmalloc(4 * sizeof(uint32_t)); +ip_r_data->masked = xmalloc(4 * sizeof(bool)); +ip_r_data->size = 4; + +while (i < ip_data->size) { +if (i + 1 >= ip_data->size) { +goto end_segment; +} + +diff = ip_data->ip[i + 1] - ip_data->ip[i]; +/* Ignore equal node. */ +if (0 == diff) { +i++; +continue; +} +/* Continuous in the segment. */ +if ((diff & (diff - 1)) == 0) { +/* New segment. */ +if (0 == recorded) { +connect = ip_data->ip[i + 1] ^ ip_data->ip[i]; +/* Only one bit different. */ +if (0 == (connect & (connect - 1))) { +recorded = 1; +start = ip_data->ip[i]; +continuous_size = 2; +mask_base = connect; + +int j = 0; +end = start; +/* The first non-zero place in the high direction is + * the end of the segment. */ +while (j < 32 && (0 == (start & (mask_base << j { +end |= (mask_base << j); +j++; +} + +i++; +continue; +/* Different segme
[ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
From: Gongming Chen In the ovn security group, each host ip corresponds to at least 4 flow tables (different connection states). As the scale of hosts using the security group increases, the ovs security group flow table will increase sharply, especially when it is applied the remote group feature in OpenStack. This patch merges ipv4 addresses with wildcard masks, and replaces this ipv4 addresses with the merged ip/mask. This will greatly reduce the entries in the ovs security group flow table, especially when the host size is large. After being used in a production environment, the number of ovs flow tables will be reduced by at least 50% in most scenarios, when the remote group in OpenStack is applied. Analysis in the simplest scenario, a network 1.1.1.0/24 network, enable the OpenStack security group remote group feature, create 253 virtual machine ports(1.1.1.2-1.1.1.254). Only focus on the number of ip addresses, in the table=44 table: ./configure --disable-combine-ipv4: 1.1.1.2-1.1.1.254(253 flow meters) * 4(connection status) * 1(local net of localport) = 1012 ./configure --enable-combine-ipv4(default): 1.1.1.2/31 1.1.1.4/30 1.1.1.8/29 1.1.1.16/28 1.1.1.32/27 1.1.1.64/26 1.1.1.128/26 1.1.1.192/27 1.1.1.224/28 1.1.1.240/29 1.1.1.248/30 1.1.1.252/31 1.1.1.254 13 flow tables * 4(connection status) * 1(local net of localport) = 52 Reduced from 1012 flow meters to 52, a 19.4 times reduction. Some scenes are similar to the following: 1.1.1.2, 1.1.1.6 After the combine: 1.1.1.2/255.255.255.251 This will slightly increase the difficulty of finding the flow table corresponding to a single address. such as: ovs-ofctl dump-flows br-int | grep 1.1.1.6 The result is empty. 1.1.1.6 will match 1.1.1.2/255.255.255.251 Signed-off-by: Gongming Chen --- configure.ac | 1 + lib/expr.c | 207 ++ m4/ovn.m4| 21 tests/atlocal.in | 1 + tests/ovn.at | 286 +-- 5 files changed, 433 insertions(+), 83 deletions(-) diff --git a/configure.ac b/configure.ac index b2d084318..6dc51a5cc 100644 --- a/configure.ac +++ b/configure.ac @@ -131,6 +131,7 @@ OVS_LIBTOOL_VERSIONS OVS_CHECK_CXX AX_FUNC_POSIX_MEMALIGN OVN_CHECK_UNBOUND +OVN_CHECK_COMBINE_IPV4 OVS_CHECK_INCLUDE_NEXT([stdio.h string.h]) AC_CONFIG_FILES([lib/libovn.sym]) diff --git a/lib/expr.c b/lib/expr.c index 796e88ac7..50f089609 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -1030,6 +1030,184 @@ expr_constant_set_destroy(struct expr_constant_set *cs) } } +struct ip_v +{ +uint32_t *ip; +uint32_t size; +}; + +struct ip_r +{ +uint32_t *ip; +uint32_t *mask; +uint32_t used; +uint32_t size; +bool *masked; +}; + +/* Macro to check ip return data and realloc. */ +#define CHECK_REALLOC_IP_R_DATA(IP_R_DATA) \ +if(IP_R_DATA->used >= IP_R_DATA->size){ \ +IP_R_DATA->ip = realloc(IP_R_DATA->ip, 2 * IP_R_DATA->size * sizeof(uint32_t)); \ +IP_R_DATA->mask = realloc(IP_R_DATA->mask, 2 * IP_R_DATA->size * sizeof(uint32_t)); \ +IP_R_DATA->masked = realloc(IP_R_DATA->masked, 2 * IP_R_DATA->size * sizeof(bool)); \ +IP_R_DATA->size = IP_R_DATA->size * 2; \ +} + +static void combine_ipv4_in_mask(struct ip_v *ip_data, struct ip_r *ip_r_data){ +int i = 0, recorded =0; +uint32_t diff, connect, start, end, continuous_size, mask_base; + +start = 0; +continuous_size = 0; +mask_base = 0; +end = 0; + +memset(ip_r_data, 0, sizeof(struct ip_r)); +ip_r_data->ip = malloc(4 * sizeof(uint32_t)); +ip_r_data->mask = malloc(4 * sizeof(uint32_t)); +ip_r_data->masked = malloc(4 * sizeof(bool)); +ip_r_data->size = 4; + +while(i < ip_data->size){ +if(i + 1 >= ip_data->size){ +goto end_segment; +} + +diff = ip_data->ip[i+1] - ip_data->ip[i]; +/* Ignore equal node */ +if(0 == diff){ +i++; +continue; +} +/* Continuous in the segment */ +if((diff & (diff-1)) == 0){ +/* New segment */ +if(0 == recorded){ +connect = ip_data->ip[i+1] ^ ip_data->ip[i]; +/* Only one bit different */ +if(0 == (connect & (connect-1))){ +recorded = 1; +start = ip_data->ip[i]; +continuous_size = 2; +mask_base = connect; + +int j = 0; +end = start; +/*The first non-zero place in the high direction is the end of the segment*/ +while(j < 32 && (0 == (start & (mask_base << j{ +end |= (mask_base << j); +j++; +} + +i++; +continue; +/* Different segments and different bit, dnot merge */ +}else { +CHECK_REALLOC_IP_R_DAT
[ovs-dev] [PATCH ovn] expr: Combine multiple ipv4 with wildcard mask.
From: Gongming Chen In the ovn security group, each host ip corresponds to at least 4 flow tables (different connection states). As the scale of hosts using the security group increases, the ovs security group flow table will increase sharply, especially when it is applied the remote group feature in OpenStack. This patch merges ipv4 addresses with wildcard masks, and replaces this ipv4 addresses with the merged ip/mask. This will greatly reduce the entries in the ovs security group flow table, especially when the host size is large. After being used in a production environment, the number of ovs flow tables will be reduced by at least 50% in most scenarios, when the remote group in OpenStack is applied. Analysis in the simplest scenario, a network 1.1.1.0/24 network, enable the OpenStack security group remote group feature, create 253 virtual machine ports(1.1.1.2-1.1.1.254). Only focus on the number of ip addresses, in the table=44 table: ./configure --disable-combine-ipv4: 1.1.1.2-1.1.1.254(253 flow meters) * 4(connection status) * 1(local net of localport) = 1012 ./configure --enable-combine-ipv4(default): 1.1.1.2/31 1.1.1.4/30 1.1.1.8/29 1.1.1.16/28 1.1.1.32/27 1.1.1.64/26 1.1.1.128/26 1.1.1.192/27 1.1.1.224/28 1.1.1.240/29 1.1.1.248/30 1.1.1.252/31 1.1.1.254 13 flow tables * 4(connection status) * 1(local net of localport) = 52 Reduced from 1012 flow meters to 52, a 19.4 times reduction. Some scenes are similar to the following: 1.1.1.2, 1.1.1.6 After the combine: 1.1.1.2/255.255.255.251 This will slightly increase the difficulty of finding the flow table corresponding to a single address. such as: ovs-ofctl dump-flows br-int | grep 1.1.1.6 The result is empty. 1.1.1.6 will match 1.1.1.2/255.255.255.251 Signed-off-by: Gongming Chen --- configure.ac | 1 + lib/expr.c | 207 ++ m4/ovn.m4| 21 tests/atlocal.in | 1 + tests/ovn.at | 286 +-- 5 files changed, 433 insertions(+), 83 deletions(-) diff --git a/configure.ac b/configure.ac index b2d084318..6dc51a5cc 100644 --- a/configure.ac +++ b/configure.ac @@ -131,6 +131,7 @@ OVS_LIBTOOL_VERSIONS OVS_CHECK_CXX AX_FUNC_POSIX_MEMALIGN OVN_CHECK_UNBOUND +OVN_CHECK_COMBINE_IPV4 OVS_CHECK_INCLUDE_NEXT([stdio.h string.h]) AC_CONFIG_FILES([lib/libovn.sym]) diff --git a/lib/expr.c b/lib/expr.c index 796e88ac7..50f089609 100644 --- a/lib/expr.c +++ b/lib/expr.c @@ -1030,6 +1030,184 @@ expr_constant_set_destroy(struct expr_constant_set *cs) } } +struct ip_v +{ +uint32_t *ip; +uint32_t size; +}; + +struct ip_r +{ +uint32_t *ip; +uint32_t *mask; +uint32_t used; +uint32_t size; +bool *masked; +}; + +/* Macro to check ip return data and realloc. */ +#define CHECK_REALLOC_IP_R_DATA(IP_R_DATA) \ +if(IP_R_DATA->used >= IP_R_DATA->size){ \ +IP_R_DATA->ip = realloc(IP_R_DATA->ip, 2 * IP_R_DATA->size * sizeof(uint32_t)); \ +IP_R_DATA->mask = realloc(IP_R_DATA->mask, 2 * IP_R_DATA->size * sizeof(uint32_t)); \ +IP_R_DATA->masked = realloc(IP_R_DATA->masked, 2 * IP_R_DATA->size * sizeof(bool)); \ +IP_R_DATA->size = IP_R_DATA->size * 2; \ +} + +static void combine_ipv4_in_mask(struct ip_v *ip_data, struct ip_r *ip_r_data){ +int i = 0, recorded =0; +uint32_t diff, connect, start, end, continuous_size, mask_base; + +start = 0; +continuous_size = 0; +mask_base = 0; +end = 0; + +memset(ip_r_data, 0, sizeof(struct ip_r)); +ip_r_data->ip = malloc(4 * sizeof(uint32_t)); +ip_r_data->mask = malloc(4 * sizeof(uint32_t)); +ip_r_data->masked = malloc(4 * sizeof(bool)); +ip_r_data->size = 4; + +while(i < ip_data->size){ +if(i + 1 >= ip_data->size){ +goto end_segment; +} + +diff = ip_data->ip[i+1] - ip_data->ip[i]; +/* Ignore equal node */ +if(0 == diff){ +i++; +continue; +} +/* Continuous in the segment */ +if((diff & (diff-1)) == 0){ +/* New segment */ +if(0 == recorded){ +connect = ip_data->ip[i+1] ^ ip_data->ip[i]; +/* Only one bit different */ +if(0 == (connect & (connect-1))){ +recorded = 1; +start = ip_data->ip[i]; +continuous_size = 2; +mask_base = connect; + +int j = 0; +end = start; +/*The first non-zero place in the high direction is the end of the segment*/ +while(j < 32 && (0 == (start & (mask_base << j{ +end |= (mask_base << j); +j++; +} + +i++; +continue; +/* Different segments and different bit, dnot merge */ +}else { +CHECK_REALLOC_IP_R_DAT
[ovs-dev] [PATCH ovn] tests: Fix Port_Binding up test.
From: Gongming Chen After setting the iface-id, immediately check the up status of the port binding, it will occasionally fail, especially when the port binding status is reported later. When it fails, the following will be output: Checking values in sb Port_Binding with logical_port=lsp1 against false... found false ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 external-ids:iface-id=lsp1 ./ovn-macros.at:307: "$@" Checking values in sb Port_Binding with logical_port=lsp1 against true... found false _uuid : 15ebabb6-3dbb-4806-aa85-d1c03e3b39f6 logical_port: lsp1 up : true ./ovn-macros.at:393: hard failure Fixes: 4d3cb42b076b ("binding: Set Logical_Switch_Port.up when all OVS flows are installed.") Signed-off-by: Gongming Chen --- tests/ovn.at | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ovn.at b/tests/ovn.at index 80c9fe138..43dc16dd8 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -23885,7 +23885,7 @@ check ovn-nbctl --wait=hv sync check_column "false" Port_Binding up logical_port=lsp1 check ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 external-ids:iface-id=lsp1 -check_column "true" Port_Binding up logical_port=lsp1 +wait_column "true" Port_Binding up logical_port=lsp1 wait_column "true" nb:Logical_Switch_Port up name=lsp1 OVS_WAIT_UNTIL([test `ovs-vsctl get Interface lsp1 external_ids:ovn-installed` = '"true"']) -- 2.23.0 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Re: [ovs-dev] [PATCH ovn] tests: Fix Port_Binding up test.
Hi Dumitru, I have corrected the patch format and resubmitted it. Please check it. Thanks, Gongming > On Feb 7, 2021, at 12:25 AM, gmingchen(陈供明) wrote: > > From: Gongming Chen > > After setting the iface-id, immediately check the up status of the port > binding, it will occasionally fail, especially when the port binding > status is reported later. > > When it fails, the following will be output: > Checking values in sb Port_Binding with logical_port=lsp1 against false... > found false > ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 > external-ids:iface-id=lsp1 > ./ovn-macros.at:307: "$@" > Checking values in sb Port_Binding with logical_port=lsp1 against true... > found false > _uuid : 15ebabb6-3dbb-4806-aa85-d1c03e3b39f6 > logical_port: lsp1 > up : true > ./ovn-macros.at:393: hard failure > > Fixes: 4d3cb42b076b ("binding: Set Logical_Switch_Port.up when all OVS flows > are installed.") > Signed-off-by: Gongming Chen > --- > tests/ovn.at | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/tests/ovn.at b/tests/ovn.at > index 80c9fe138..43dc16dd8 100644 > --- a/tests/ovn.at > +++ b/tests/ovn.at > @@ -23885,7 +23885,7 @@ check ovn-nbctl --wait=hv sync > check_column "false" Port_Binding up logical_port=lsp1 > > check ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 > external-ids:iface-id=lsp1 > -check_column "true" Port_Binding up logical_port=lsp1 > +wait_column "true" Port_Binding up logical_port=lsp1 > wait_column "true" nb:Logical_Switch_Port up name=lsp1 > OVS_WAIT_UNTIL([test `ovs-vsctl get Interface lsp1 > external_ids:ovn-installed` = '"true"']) > > -- > 2.23.0 > ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH ovn] tests: Fix Port_Binding up test.
From: Gongming Chen After setting the iface-id, immediately check the up status of the port binding, it will occasionally fail, especially when the port binding status is reported later. When it fails, the following will be output: Checking values in sb Port_Binding with logical_port=lsp1 against false... found false ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 external-ids:iface-id=lsp1 ./ovn-macros.at:307: "$@" Checking values in sb Port_Binding with logical_port=lsp1 against true... found false _uuid : 15ebabb6-3dbb-4806-aa85-d1c03e3b39f6 logical_port: lsp1 up : true ./ovn-macros.at:393: hard failure Fixes: 4d3cb42b076b ("binding: Set Logical_Switch_Port.up when all OVS flows are installed.") Signed-off-by: Gongming Chen --- tests/ovn.at | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ovn.at b/tests/ovn.at index 80c9fe138..43dc16dd8 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -23885,7 +23885,7 @@ check ovn-nbctl --wait=hv sync check_column "false" Port_Binding up logical_port=lsp1 check ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 external-ids:iface-id=lsp1 -check_column "true" Port_Binding up logical_port=lsp1 +wait_column "true" Port_Binding up logical_port=lsp1 wait_column "true" nb:Logical_Switch_Port up name=lsp1 OVS_WAIT_UNTIL([test `ovs-vsctl get Interface lsp1 external_ids:ovn-installed` = '"true"']) -- 2.23.0 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH ovn] tests: Fix Port_Binding up test.
After setting the iface-id, immediately check the up status of the port binding, it will occasionally fail, especially when the port binding status is reported later. When it fails, the following will be output: Checking values in sb Port_Binding with logical_port=lsp1 against false... found false ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 external-ids:iface-id=lsp1 ./ovn-macros.at:307: "$@" Checking values in sb Port_Binding with logical_port=lsp1 against true... found false _uuid : 15ebabb6-3dbb-4806-aa85-d1c03e3b39f6 logical_port: lsp1 up : true ./ovn-macros.at:393: hard failure Fixes: 4d3cb42b076b ("binding: Set Logical_Switch_Port.up when all OVS flows are installed.") Signed-off-by: Gongming Chen --- tests/ovn.at | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ovn.at b/tests/ovn.at index 80c9fe138..43dc16dd8 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -23885,7 +23885,7 @@ check ovn-nbctl --wait=hv sync check_column "false" Port_Binding up logical_port=lsp1 check ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 external-ids:iface-id=lsp1 -check_column "true" Port_Binding up logical_port=lsp1 +wait_column "true" Port_Binding up logical_port=lsp1 wait_column "true" nb:Logical_Switch_Port up name=lsp1 OVS_WAIT_UNTIL([test `ovs-vsctl get Interface lsp1 external_ids:ovn-installed` = '"true"']) -- 2.23.0 ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH ovn] tests: Fix Port_Binding up test.
After setting the iface-id, immediately check the up status of the port binding, it will occasionally fail, especially when the port binding status is reported later. When it fails, the following will be output: Checking values in sb Port_Binding with logical_port=lsp1 against false... found false ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 external-ids:iface-id=lsp1 ./ovn-macros.at:307: "$@" Checking values in sb Port_Binding with logical_port=lsp1 against true... found false _uuid : 15ebabb6-3dbb-4806-aa85-d1c03e3b39f6 logical_port: lsp1 up : true ./ovn-macros.at:393: hard failure Fixes: 4d3cb42b076b("binding: Set Logical_Switch_Port.up when all OVS flows are installed") Signed-off-by: Gongming Chen --- tests/ovn.at | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ovn.at b/tests/ovn.at index 80c9fe138..43dc16dd8 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -23885,7 +23885,7 @@ check ovn-nbctl --wait=hv sync check_column "false" Port_Binding up logical_port=lsp1 check ovs-vsctl add-port br-int lsp1 -- set Interface lsp1 external-ids:iface-id=lsp1 -check_column "true" Port_Binding up logical_port=lsp1 +wait_column "true" Port_Binding up logical_port=lsp1 wait_column "true" nb:Logical_Switch_Port up name=lsp1 OVS_WAIT_UNTIL([test `ovs-vsctl get Interface lsp1 external_ids:ovn-installed` = '"true"']) ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev