[Devel] [PATCH RHEL7 COMMIT] vzprivnet: Weak sparse networks
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Mar 24 08:53:32 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 31f6eaf97d683147f23d0b1e2df18286209520c9
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date: Thu Mar 24 19:53:32 2016 +0400
vzprivnet: Weak sparse networks
Port diff-vz-privnet-weak-sparse
privnet: Weak sparse networks
As per Vitaly Obernikhin request - weak private nets support
is required for weak ones :\ Nobody wants to add the required
"external" ip addresses to priv-network.
Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
net/ipv4/netfilter/ip_vzprivnet.c | 53 ++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/net/ipv4/netfilter/ip_vzprivnet.c b/net/ipv4/netfilter/ip_vzprivnet.c
index 170b0c5..01933ac 100644
--- a/net/ipv4/netfilter/ip_vzprivnet.c
+++ b/net/ipv4/netfilter/ip_vzprivnet.c
@@ -521,7 +521,7 @@ static struct file_operations proc_vzprivnet_ops = {
.write = vzpriv_write,
};
-static int sparse_add(unsigned int netid, u32 ip, u32 mask)
+static int sparse_add(unsigned int netid, u32 ip, u32 mask, int weak)
{
int err;
struct vzprivnet_sparse *pns, *epns = NULL;
@@ -565,6 +565,8 @@ found_net:
list_add_tail(&pne->list, &pns->entries);
tree_insert(&entries_root, &pne->range);
pne = NULL;
+ } else if (weak) {
+ pns->pn.weak = 1;
} else if (pns == epns) {
err = -EEXIST;
goto out_unlock;
@@ -609,13 +611,16 @@ static void sparse_free_one(struct vzprivnet_sparse *pns)
kfree(pns);
}
-static int sparse_del_net(unsigned int netid)
+static int sparse_del_net(unsigned int netid, int weak)
{
struct vzprivnet_sparse *pns;
list_for_each_entry(pns, &vzpriv_sparse, list)
if (pns->netid == netid) {
- sparse_free_one(pns);
+ if (weak)
+ pns->pn.weak = 0;
+ else
+ sparse_free_one(pns);
return 0;
}
@@ -637,7 +642,7 @@ static int sparse_del_ip(u32 ip)
return 0;
}
-static int sparse_del(unsigned int netid, u32 ip)
+static int sparse_del(unsigned int netid, u32 ip, int weak)
{
int err;
@@ -645,7 +650,7 @@ static int sparse_del(unsigned int netid, u32 ip)
if (ip != 0)
err = sparse_del_ip(ip);
else
- err = sparse_del_net(netid);
+ err = sparse_del_net(netid, weak);
write_unlock_bh(&vzprivlock);
return err;
@@ -655,15 +660,17 @@ static int sparse_del(unsigned int netid, u32 ip)
* +ID to add a network
* +ID:a.b.c.d to add an IP to network
* +ID:a.b.c.d/m to add a subnet to network
+ * +ID:* to make a network weak
* -ID to remove the whole network
* -a.b.c.d to remove an IP or bounding subnet (from its network)
+ * -ID:* to make a network "strong" ;)
*
* No weak networks here!
*/
#define is_eol(ch) ((ch) == '\0' || (ch) == '\n')
-static int parse_sparse_add(const char *str, unsigned int *netid, u32 *ip, u32 *mask)
+static int parse_sparse_add(const char *str, unsigned int *netid, u32 *ip, u32 *mask, int *weak)
{
unsigned int m;
char *end;
@@ -678,6 +685,14 @@ static int parse_sparse_add(const char *str, unsigned int *netid, u32 *ip, u32 *
return -EINVAL;
str = end + 1;
+ if (*str == '*') {
+ if (!is_eol(*(str + 1)))
+ return -EINVAL;
+
+ *weak = 1;
+ return 0;
+ }
+
if (!in4_pton(str, -1, (u8 *)ip, -1, (const char **)&end))
return -EINVAL;
@@ -698,30 +713,35 @@ static int parse_sparse_add(const char *str, unsigned int *netid, u32 *ip, u32 *
return 0;
}
-static int parse_sparse_remove(const char *str, unsigned int *netid, u32 *ip)
+static int parse_sparse_remove(const char *str, unsigned int *netid, u32 *ip, int *weak)
{
char *end;
if (strchr(str, '.')) {
if (!in4_pton(str, -1, (u8 *)ip, -1, (const char **)&end))
return -EINVAL;
- } else
+ } else {
*netid = simple_strtol(str, &end, 10);
+ if (end[0] == ':' && end[1] == '*') {
+ end += 2;
+ *weak = 1;
+ }
+ }
return (is_eol(*end) ? 0 : -EINVAL);
}
static int parse_sparse(const char *param, int *add,
- unsigned int *netid, u32 *ip, u32 *mask)
+ unsigned int *netid, u32 *ip, u32 *mask, int *weak)
{
if (param[0] == '+') {
*add = 1;
- return parse_sparse_add(param + 1, netid, ip, mask);
+ return parse_sparse_add(param + 1, netid, ip, mask, weak);
}
if (param[0] == '-') {
*add = 0;
- return parse_sparse_remove(param + 1, netid, ip);
+ return parse_sparse_remove(param + 1, netid, ip, weak);
}
return -EINVAL;
@@ -752,18 +772,18 @@ static ssize_t sparse_write(struct file * file, const char __user *buf,
err = -EINVAL;
while (*s) {
- int add;
+ int add, weak = 0;
unsigned int netid = 0;
u32 ip = 0, mask = 0;
- err = parse_sparse(s, &add, &netid, &ip, &mask);
+ err = parse_sparse(s, &add, &netid, &ip, &mask, &weak);
if (err)
goto out;
if (add)
- err = sparse_add(netid, ip, mask);
+ err = sparse_add(netid, ip, mask, weak);
else
- err = sparse_del(netid, ip);
+ err = sparse_del(netid, ip, weak);
if (err)
goto out;
@@ -804,6 +824,9 @@ static int sparse_seq_show(struct seq_file *s, void *v)
pns = list_entry(lh, struct vzprivnet_sparse, list);
seq_printf(s, "%u: ", pns->netid);
+ if (pns->pn.weak)
+ seq_puts(s, "* ");
+
list_for_each_entry(pne, &pns->entries, list) {
seq_printf(s, "%pI4", &pne->range.netip);
if (~pne->range.rmask != 0) /* subnet */
More information about the Devel
mailing list