[Devel] [PATCH RHEL7 COMMIT] vzprivnet: Catch v4 conflict on add
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Mar 24 08:53:39 PDT 2016
The commit is pushed to "branch-rh7-3.10.0-327.10.1.vz7.12.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.10.1.vz7.12.3
------>
commit a20a26284b4275c8ad98e007cb324c6287dcdd15
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date: Thu Mar 24 19:53:39 2016 +0400
vzprivnet: Catch v4 conflict on add
Port diff-vzprivnet-catch-v4-conflict-on-add
privnet: Catch v4 conflict on adding
There's a possibility to add intersecting values into different
subetworks. Fix this.
This is only v4 fix. The v6 one will be later.
https://jira.sw.ru/browse/PSBM-6404
Since conflicting privnet entry isn't added to tree, the subsequent
removal of one may cause an oops, so this is also an oops fix...
Ported from rh5
https://jira.sw.ru/browse/PSBM-7345
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
net/ipv4/netfilter/ip_vzprivnet.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/net/ipv4/netfilter/ip_vzprivnet.c b/net/ipv4/netfilter/ip_vzprivnet.c
index b7035c2..4b5671bf 100644
--- a/net/ipv4/netfilter/ip_vzprivnet.c
+++ b/net/ipv4/netfilter/ip_vzprivnet.c
@@ -122,7 +122,12 @@ static struct vzprivnet_range *legacy_search(u32 ip)
static int tree_insert(struct rb_root *root, struct vzprivnet_range *data)
{
struct rb_node **link = &(root->rb_node), *parent = NULL;
- u32 ip = ntohl(data->netip);
+ u32 ip;
+ u32 end_ip;
+
+ ip = ntohl(data->netip);
+ end_ip = ip | ~ntohl(data->rmask);
+
while (*link) {
struct vzprivnet_range *p = rb_entry(*link, struct vzprivnet_range, node);
@@ -131,7 +136,7 @@ static int tree_insert(struct rb_root *root, struct vzprivnet_range *data)
start = ntohl(p->netip);
end = start | ~ntohl(p->rmask);
- if (start <= ip && ip <= end)
+ if (!(ip > end || start > end_ip))
return -EEXIST;
parent = *link;
@@ -589,7 +594,7 @@ static int sparse_add(unsigned int netid, u32 ip, u32 mask, int weak)
{
int err;
struct vzprivnet_sparse *pns, *epns = NULL;
- struct vzprivnet_entry *pne = NULL, *tmp;
+ struct vzprivnet_entry *pne = NULL;
err = -ENOMEM;
@@ -616,20 +621,14 @@ static int sparse_add(unsigned int netid, u32 ip, u32 mask, int weak)
found_net:
if (ip != 0) {
- err = -EEXIST;
- ip &= mask;
- list_for_each_entry(tmp, &pns->entries, list) {
- if ((ip & tmp->range.rmask) == tmp->range.netip)
- goto out_unlock;
- if ((tmp->range.netip & mask) == ip)
- goto out_unlock;
- }
-
pne->range.netip = ip & mask;
pne->range.rmask = mask;
pne->range.pn = &pns->pn;
+ err = tree_insert(&entries_root, &pne->range);
+ if (err)
+ goto out_unlock;
+
list_add_tail(&pne->list, &pns->entries);
- tree_insert(&entries_root, &pne->range);
pne = NULL;
} else if (weak) {
pns->pn.weak = 1;
More information about the Devel
mailing list