[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