Commit baacc263 by Bach Dániel

firewall: make ipv6 addresses configurable and optional #37

parent 44d036dd
......@@ -12,8 +12,9 @@ import re
mac_re = re.compile(r'^([0-9a-fA-F]{2}(:|$)){6}$')
alfanum_re = re.compile(r'^[A-Za-z0-9_-]+$')
domain_re = re.compile(r'^([A-Za-z0-9_-]\.?)+$')
ipv4_re = re.compile('^[0-9]+\.([0-9]+)\.([0-9]+)\.([0-9]+)$')
ipv4_re = re.compile('^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$')
reverse_domain_re = re.compile(r'^(%\([abcd]\)d|[a-z0-9.-])+$')
ipv6_template_re = re.compile(r'^(%\([abcd]\)[dxX]|[A-Za-z0-9:-])+$')
class MACAddressFormField(fields.RegexField):
......@@ -220,6 +221,17 @@ def val_reverse_domain(value):
raise ValidationError(u'%s - invalid reverse domain name' % value)
def is_valid_ipv6_template(value):
"""Check whether the parameter is a valid ipv6 template."""
return ipv6_template_re.match(value) is not None
def val_ipv6_template(value):
"""Validate whether the parameter is a valid ipv6 template."""
if not is_valid_ipv6_template(value):
raise ValidationError(u'%s - invalid reverse ipv6 template' % value)
def is_valid_ipv4_address(value):
"""Check whether the parameter is a valid IPv4 address."""
return ipv4_re.match(value) is not None
......@@ -249,9 +261,11 @@ def val_mx(value):
"Should be: <priority>:<hostname>"))
def ipv4_2_ipv6(ipv4):
def ipv4_2_ipv6(ipv6_template, ipv4):
"""Convert IPv4 address string to IPv6 address string."""
m = ipv4_re.match(ipv4)
return ("2001:738:2001:4031:%s:%s:%s:0" %
return (ipv6_template % {'a': int(,
'b': int(,
'c': int(,
'd': int(})
......@@ -9,6 +9,7 @@ from django.db import models
from django.forms import ValidationError
from django.utils.translation import ugettext_lazy as _
from firewall.fields import (MACAddressField, val_alfanum, val_reverse_domain,
val_domain, val_ipv4, val_ipv6, val_mx,
ipv4_2_ipv6, IPNetworkField, IPAddressField)
from django.core.validators import MinValueValidator, MaxValueValidator
......@@ -247,6 +248,10 @@ class Vlan(AclBase, models.Model):
'For example, the template for the standard reverse '
'address is: "%(d)d.%(c)d.%(b)d.%(a)".'),
ipv6_template = models.TextField(
verbose_name=_('ipv6 template'),
dhcp_pool = models.TextField(blank=True, verbose_name=_('DHCP pool'),
'The address range of the DHCP pool: '
......@@ -303,10 +308,13 @@ class Vlan(AclBase, models.Model):
ipv4 = str(ipv4)
if ipv4 not in used_v4:
logger.debug("Found unused IPv4 address %s.", ipv4)
ipv6 = ipv4_2_ipv6(ipv4)
if ipv6 not in used_v6:
logger.debug("Found unused IPv6 address %s.", ipv6)
return {'ipv4': ipv4, 'ipv6': ipv6}
if self.network6 is None:
return {'ipv4': ipv4, 'ipv6': None}
ipv6 = ipv4_2_ipv6(self.ipv6_template, ipv4)
if ipv6 not in used_v6:
logger.debug("Found unused IPv6 address %s.", ipv6)
return {'ipv4': ipv4, 'ipv6': ipv6}
raise ValidationError(_("All IP addresses are already in use."))
......@@ -448,7 +456,7 @@ class Host(models.Model):
def save(self, *args, **kwargs):
if not and self.ipv6 == "auto":
self.ipv6 = ipv4_2_ipv6(self.ipv4)
self.ipv6 = ipv4_2_ipv6(self.vlan.ipv6_template, self.ipv4)
super(Host, self).save(*args, **kwargs)
......@@ -231,6 +231,7 @@ class VlanForm(ModelForm):
'Domain name service',
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment