Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

vzctl set --ipadd/--ipdel: add ability to specify netmasks

This is a preliminary support for specifying netmasks for venet.
It allows to specify a netmask in CIDR notation for IPv4 and IPv6
addresses.

Same IP address with a different netmask is considered to be a separate IP.

This is a work in progress, the next steps are:
* modify all etc/dists/scripts/*{add,del}_ip.sh to understand IP_ADDR
  with netmasks (quite a lot of work)
* document it in vzctl(8) man page (easy)

http://bugzilla.openvz.org/1671
http://bugzilla.openvz.org/1088

Signed-off-by: Kir Kolyshkin <kir@openvz.org>
  • Loading branch information...
commit f018af5faa10fbe2fa56363c5b393485372c246f 1 parent 89b8940
@kolyshkin kolyshkin authored
Showing with 51 additions and 26 deletions.
  1. +1 −0  include/util.h
  2. +3 −26 src/lib/config.c
  3. +47 −0 src/lib/util.c
View
1  include/util.h
@@ -44,6 +44,7 @@ unsigned long min_ul(unsigned long val1, unsigned long val2);
int yesno2id(const char *str);
int get_addr_family(const char *addr);
int get_netaddr(const char *ip_str, void *ip);
+char *canon_ip(const char *str);
char *subst_VEID(envid_t veid, char *src);
int get_pagesize();
int get_mem(unsigned long long *mem);
View
29 src/lib/config.c
@@ -752,28 +752,10 @@ static int store_cap(vps_param *old_p, vps_param *vps_p, vps_config *conf,
}
/********************** Network ************************/
-static int check_ip_dot(char *ip)
-{
- int i;
- char *str = ip;
- char *p;
-
- for (i = 0; i < 5; i++) {
- if ((p = strchr(str, '.')) == NULL)
- break;
- str = p + 1;
- }
- if (i != 3)
- return VZ_BADIP;
- return 0;
-}
-
static int parse_ip(vps_param *vps_p, char *val, int id)
{
char *token;
- char dst[INET6_ADDRSTRLEN];
- unsigned char ip[sizeof(struct in6_addr)];
- int family;
+ char *dst;
net_param *net;
if (id == PARAM_IP_ADD)
@@ -795,13 +777,8 @@ static int parse_ip(vps_param *vps_p, char *val, int id)
continue;
if (!strcmp(token, "::0"))
continue;
- if (!strchr(token, ':')) {
- if (check_ip_dot(token))
- return ERR_INVAL;
- }
- if ((family = get_netaddr(token, ip)) < 0)
- return ERR_INVAL;
- if (inet_ntop(family, ip, dst, sizeof(dst)) == NULL)
+ dst = canon_ip(token);
+ if (dst == NULL)
return ERR_INVAL;
if (!find_ip(&net->ip, dst))
add_str_param(&net->ip, dst);
View
47 src/lib/util.c
@@ -290,6 +290,53 @@ int get_netaddr(const char *ip_str, void *ip)
return family;
}
+static inline int max_netmask(int family)
+{
+ if (family == AF_INET)
+ return 32;
+ else if (family == AF_INET6)
+ return 128;
+ else
+ return -1;
+}
+
+/* Check and "canonicalize" an IP address with optional netmask
+ * (in CIDR notation). Basically */
+char *canon_ip(const char *str)
+{
+ const char *ipstr, *maskstr;
+ int mask, family;
+ unsigned int ip[4];
+ static char dst[INET6_ADDRSTRLEN + sizeof("/128")];
+
+ maskstr = strchr(str, '/');
+ if (maskstr) {
+ ipstr = strndupa(str, maskstr - str);
+ maskstr++;
+ }
+ else {
+ ipstr = str;
+ }
+ family = get_netaddr(ipstr, ip);
+ if (family < 0)
+ return NULL;
+ if ((inet_ntop(family, ip, dst, sizeof(dst))) == NULL)
+ return NULL;
+
+ if (maskstr == NULL)
+ goto out;
+
+ /* Parse netmask */
+ if (parse_int(maskstr, &mask) != 0)
+ return NULL;
+ if (mask > max_netmask(family) || mask < 0)
+ return NULL;
+ sprintf(dst + strlen(dst), "/%d", mask);
+
+out:
+ return dst;
+}
+
char *subst_VEID(envid_t veid, char *src)
{
char *srcp;
Please sign in to comment.
Something went wrong with that request. Please try again.