aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rpkid/portal-gui/scripts/rpkigui-rcynic.py43
-rw-r--r--rpkid/rpki/gui/app/views.py5
-rw-r--r--rpkid/rpki/gui/cacheview/admin.py12
-rw-r--r--rpkid/rpki/gui/cacheview/models.py111
-rw-r--r--rpkid/rpki/gui/models.py13
-rw-r--r--rpkid/rpki/gui/routeview/models.py8
6 files changed, 86 insertions, 106 deletions
diff --git a/rpkid/portal-gui/scripts/rpkigui-rcynic.py b/rpkid/portal-gui/scripts/rpkigui-rcynic.py
index abf56ca1..41557962 100644
--- a/rpkid/portal-gui/scripts/rpkigui-rcynic.py
+++ b/rpkid/portal-gui/scripts/rpkigui-rcynic.py
@@ -18,15 +18,16 @@ default_logfile = '/var/rcynic/data/summary.xml'
default_root = '/var/rcynic/data'
import time, vobject
-from rpki.gui.cacheview import models
+
+from django.db import transaction
+import django.db.models
+
from rpki.rcynic import rcynic_xml_iterator, label_iterator
from rpki.sundial import datetime
import rpki
-from django.db import transaction
-import django.db.models
+from rpki.gui.cacheview import models
debug = False
-fam_map = { 'roa_prefix_set_ipv6': 6, 'roa_prefix_set_ipv4': 4 }
class rcynic_object(object):
@@ -99,10 +100,6 @@ class rcynic_object(object):
return True
-# munge IPv6 addresses
-def munge(family, value):
- return value if family == 4 else (value >> 65) & 0x7fffffffffffffffL
-
class rcynic_cert(rcynic_object):
model_class = models.Cert
@@ -129,18 +126,17 @@ class rcynic_cert(rcynic_object):
else:
obj.asns.add(q[0])
- for family, addrset in (4, cert.resources.v4), (6, cert.resources.v6):
+ for cls, addr_obj, addrset in (models.AddressRange, obj.addresses, cert.resources.v4), (models.AddressRangeV6, obj.addresses_v6, cert.resources.v6):
for rng in addrset:
if debug:
sys.stderr.write('processing %s\n' % rng)
- attrs = { 'family': family, 'min': munge(family, rng.min),
- 'max': munge(family, rng.max) }
- q = models.AddressRange.objects.filter(**attrs)
+ attrs = { 'prefix_min': rng.min, 'prefix_max': rng.max }
+ q = cls.objects.filter(**attrs)
if not q:
- obj.addresses.create(**attrs)
+ addr_obj.create(**attrs)
else:
- obj.addresses.add(q[0])
+ addr_obj.add(q[0])
if debug:
print 'finished processing rescert at %s' % cert.uri
@@ -153,17 +149,22 @@ class rcynic_roa(rcynic_object):
obj.save()
obj.prefixes.clear()
for pfxset in roa.prefix_sets:
- family = fam_map[pfxset.__class__.__name__]
+ if pfxset.__class__.__name__ == 'roa_prefix_set_ipv6':
+ roa_cls = models.ROAPrefixV6
+ prefix_obj = obj.prefixes_v6
+ else:
+ roa_cls = models.ROAPrefixV4
+ prefix_obj = obj.prefixes
+
for pfx in pfxset:
- attrs = { 'family' : family,
- 'prefix_min': munge(family, pfx.min()),
- 'prefix_max': munge(family, pfx.max()),
+ attrs = { 'prefix_min': pfx.min(),
+ 'prefix_max': pfx.max(),
'max_length': pfx.max_prefixlen }
- q = models.ROAPrefix.objects.filter(**attrs)
+ q = roa_cls.objects.filter(**attrs)
if not q:
- obj.prefixes.create(**attrs)
+ prefix_obj.create(**attrs)
else:
- obj.prefixes.add(q[0])
+ prefix_obj.add(q[0])
class rcynic_gbr(rcynic_object):
model_class = models.Ghostbuster
diff --git a/rpkid/rpki/gui/app/views.py b/rpkid/rpki/gui/app/views.py
index b96cbff2..82721266 100644
--- a/rpkid/rpki/gui/app/views.py
+++ b/rpkid/rpki/gui/app/views.py
@@ -927,9 +927,8 @@ def route_view(request):
# see draft-sidr-roa-validation-10
# 1. fetch all covering ROAs
- # FIXME: need to munge IPv6 address prior to this query!
- roas = rpki.gui.cacheview.models.ROAPrefix.objects.filter(prefix_min__lte=obj.prefix_min,
- prefix_max__gte=obj.prefix_max, family=obj.family)
+ roas = rpki.gui.cacheview.models.ROAPrefixV4.objects.filter(prefix_min__lte=obj.prefix_min,
+ prefix_max__gte=obj.prefix_max)
# 2. if there are candidate set is empty, end with invalid
if not roas.exists():
obj.status = 'unknown'
diff --git a/rpkid/rpki/gui/cacheview/admin.py b/rpkid/rpki/gui/cacheview/admin.py
index 05bab881..74b62961 100644
--- a/rpkid/rpki/gui/cacheview/admin.py
+++ b/rpkid/rpki/gui/cacheview/admin.py
@@ -25,10 +25,16 @@ class ASRangeAdmin(admin.ModelAdmin):
class AddressRangeAdmin(admin.ModelAdmin):
pass
+class AddressRangeV6Admin(admin.ModelAdmin):
+ pass
+
class CertAdmin(admin.ModelAdmin):
pass
-class ROAPrefixAdmin(admin.ModelAdmin):
+class ROAPrefixV4Admin(admin.ModelAdmin):
+ pass
+
+class ROAPrefixV6Admin(admin.ModelAdmin):
pass
class ROAAdmin(admin.ModelAdmin):
@@ -46,11 +52,13 @@ class ValidationStatus_ROAAdmin(admin.ModelAdmin): pass
class ValidationStatus_GhostbusterAdmin(admin.ModelAdmin): pass
admin.site.register(models.AddressRange, AddressRangeAdmin)
+admin.site.register(models.AddressRangeV6, AddressRangeV6Admin)
admin.site.register(models.ASRange, AddressRangeAdmin)
admin.site.register(models.Cert, CertAdmin)
admin.site.register(models.Ghostbuster, GhostbusterAdmin)
admin.site.register(models.ROA, ROAAdmin)
-admin.site.register(models.ROAPrefix, ROAPrefixAdmin)
+admin.site.register(models.ROAPrefixV4, ROAPrefixV4Admin)
+admin.site.register(models.ROAPrefixV6, ROAPrefixV6Admin)
admin.site.register(models.ValidationLabel, ValidationLabelAdmin)
admin.site.register(models.ValidationStatus_Cert, ValidationStatus_CertAdmin)
admin.site.register(models.ValidationStatus_ROA, ValidationStatus_ROAAdmin)
diff --git a/rpkid/rpki/gui/cacheview/models.py b/rpkid/rpki/gui/cacheview/models.py
index dfeb4e0b..598d7f1d 100644
--- a/rpkid/rpki/gui/cacheview/models.py
+++ b/rpkid/rpki/gui/cacheview/models.py
@@ -21,48 +21,24 @@ from django.db import models
import rpki.ipaddrs
import rpki.resource_set
+import rpki.gui.models
class TelephoneField(models.CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 255
models.CharField.__init__(self, *args, **kwargs)
-class AddressRange(models.Model):
- """Represents an IP address range.
-
- The db backend doesn't support unsigned 64-bit integer, so store
- the /63 in the database, and have the display function regenerate
- the full value. since nothing larger than a /48 should be
- announced globally, it should be ok to pad the lower 65 bits of
- `max` with 1s. """
-
- family = models.PositiveSmallIntegerField(null=False)
- min = models.BigIntegerField(null=False)
- max = models.BigIntegerField(null=False)
-
- def get_min_display(self):
- "Return the min address value as an rpki.ipaddr object."
- return rpki.ipaddrs.v4addr(self.min) if self.family == 4 else rpki.ipaddrs.v6addr(self.min << 65)
-
- def get_max_display(self):
- "Return the max address value as an rpki.ipaddr object."
- # FIXME this may fail for an IPv6 /64 single block, since we
- # don't store the lower 65 bits in the database
- return rpki.ipaddrs.v4addr(self.max) if self.family == 4 else rpki.ipaddrs.v6addr((self.max << 65) | 0x1ffffffffffffffffL)
-
- class Meta:
- ordering = ('family', 'min', 'max')
+class AddressRange(rpki.gui.models.PrefixV4):
@models.permalink
def get_absolute_url(self):
return ('rpki.gui.cacheview.views.addressrange_detail', [str(self.pk)])
- def as_resource_range(self):
- cls = rpki.resource_set.resource_range_ipv4 if self.family == 4 else rpki.resource_set.resource_range_ipv6
- return cls(self.get_min_display(), self.get_max_display())
+class AddressRangeV6(rpki.gui.models.PrefixV6):
- def __unicode__(self):
- return u'%s' % self.as_resource_range()
+ @models.permalink
+ def get_absolute_url(self):
+ return ('rpki.gui.cacheview.views.addressrange_detail_v6', [str(self.pk)])
class ASRange(models.Model):
min = models.PositiveIntegerField(null=False)
@@ -89,16 +65,13 @@ class ValidationLabel(models.Model):
Represents a specific error condition defined in the rcynic XML
output file.
"""
- label = models.CharField(max_length=79, db_index=True, unique=True)
+ label = models.CharField(max_length=79, db_index=True, unique=True, null=False)
status = models.CharField(max_length=255, null=False)
kind = models.PositiveSmallIntegerField(choices=kinds, null=False)
def __unicode__(self):
return self.label
- class Meta:
- verbose_name_plural = 'ValidationLabels'
-
generations = list(enumerate(('current', 'backup')))
generations_dict = dict((val, key) for (key, val) in generations)
@@ -167,6 +140,7 @@ class Cert(SignedObject):
Object representing a resource certificate.
"""
addresses = models.ManyToManyField(AddressRange, related_name='certs')
+ addresses_v6 = models.ManyToManyField(AddressRangeV6, related_name='certs')
asns = models.ManyToManyField(ASRange, related_name='certs')
issuer = models.ForeignKey('Cert', related_name='children', null=True, blank=True)
sia = models.CharField(max_length=255, null=False)
@@ -180,61 +154,46 @@ class ValidationStatus_Cert(ValidationStatus):
null=False)
class ROAPrefix(models.Model):
- """One prefix in a ROA.
-
- See comment above in AddressRange about how IPv6 addresses are
- stored.
+ "Abstract base class for ROA mixin."
- The prefix is broken out into min and max values rather than min/bits in
- order to allow for searches using sql. """
-
- family = models.PositiveSmallIntegerField(null=False)
- prefix_min = models.BigIntegerField(null=False, db_index=True)
- prefix_max = models.BigIntegerField(null=False, db_index=True)
max_length = models.PositiveSmallIntegerField(null=False)
class Meta:
- ordering = ('prefix_min', 'prefix_max', 'max_length')
- verbose_name_plural = 'ROAPrefixes'
-
- def min(self):
- "Return the min prefix value as an rpki.ipaddrs.v?addr object."
- if self.family == 4:
- return rpki.ipaddrs.v4addr(self.prefix_min)
- return rpki.ipaddrs.v6addr(self.prefix_min << 65)
-
- def max(self):
- "Return the max prefix value as an rpki.ipaddrs.v?addr object."
- if self.family == 4:
- return rpki.ipaddrs.v4addr(self.prefix_max)
- return rpki.ipaddrs.v6addr((self.prefix_max << 65) | 0x1ffffffffffffffffL)
-
- def get_prefix_min_display(self):
- return str(self.min())
-
- def get_prefix_max_display(self):
- return str(self.max())
-
- def as_resource_range(self):
- "Return the prefix as a rpki.resource_set.resource_range_ip object."
- if self.family == 4:
- return rpki.resource_set.resource_range_ipv4(self.min(), self.max())
- else:
- return rpki.resource_set.resource_range_ipv6((self.min() << 65),
- (self.max() << 65) | 0x1ffffffffffffffffL)
+ abstract = True
def as_roa_prefix(self):
"Return value as a rpki.resource_set.roa_prefix_ip object."
rng = self.as_resource_range()
- cls = rpki.resource_set.roa_prefix_ipv4 if self.family == 4 else rpki.resource_set.roa_prefix_ipv6
- return cls(rng.min, rng.prefixlen(), self.max_length)
+ return self.roa_cls(rng.prefix_min, rng.prefixlen(), self.max_length)
def __unicode__(self):
- return u'%s' % str(self.as_roa_prefix())
+ p = self.as_resource_range()
+ if p.prefixlen() == self.max_length:
+ return str(p)
+ return '%s-%s' % (str(p), self.max_length)
+
+# ROAPrefix is declared first, so subclass picks up __unicode__ from it.
+class ROAPrefixV4(ROAPrefix, rpki.gui.models.PrefixV4):
+ "One v4 prefix in a ROA."
+
+ roa_cls = rpki.resource_set.roa_prefix_ipv4
+
+ class Meta:
+ ordering = ('prefix_min',)
+
+# ROAPrefix is declared first, so subclass picks up __unicode__ from it.
+class ROAPrefixV6(ROAPrefix, rpki.gui.models.PrefixV6):
+ "One v6 prefix in a ROA."
+
+ roa_cls = rpki.resource_set.roa_prefix_ipv6
+
+ class Meta:
+ ordering = ('prefix_min',)
class ROA(SignedObject):
asid = models.PositiveIntegerField(null=False)
- prefixes = models.ManyToManyField(ROAPrefix, related_name='roas')
+ prefixes = models.ManyToManyField(ROAPrefixV4, related_name='roas')
+ prefixes_v6 = models.ManyToManyField(ROAPrefixV6, related_name='roas')
issuer = models.ForeignKey('Cert', related_name='roas', null=False)
@models.permalink
diff --git a/rpkid/rpki/gui/models.py b/rpkid/rpki/gui/models.py
index 323d43e6..933fe5ee 100644
--- a/rpkid/rpki/gui/models.py
+++ b/rpkid/rpki/gui/models.py
@@ -54,12 +54,17 @@ class Prefix(models.Model):
def prefixlen(self):
"Returns the prefix length for the prefix in this object."
- return self.as_range().prefixlen()
+ return self.as_resource_range().prefixlen()
def get_prefix_display(self):
- "Returns a string version of the prefix in this object."
+ "Return a string representatation of this IP prefix."
return str(self.as_resource_range())
+ def __unicode__(self):
+ """This method may be overridden by subclasses. The default
+ implementation calls get_prefix_display(). """
+ return self.get_prefix_display()
+
class Meta:
abstract = True
@@ -74,7 +79,7 @@ class PrefixV4(Prefix):
prefix_min = IPv4AddressField(db_index=True, null=False)
prefix_max = IPv4AddressField(db_index=True, null=False)
- class Meta:
+ class Meta(Prefix.Meta):
abstract = True
class PrefixV6(Prefix):
@@ -85,7 +90,7 @@ class PrefixV6(Prefix):
prefix_min = IPv6AddressField(db_index=True, null=False)
prefix_max = IPv6AddressField(db_index=True, null=False)
- class Meta:
+ class Meta(Prefix.Meta):
abstract = True
# vim:sw=4 ts=8 expandtab
diff --git a/rpkid/rpki/gui/routeview/models.py b/rpkid/rpki/gui/routeview/models.py
index 99dd0297..912ae929 100644
--- a/rpkid/rpki/gui/routeview/models.py
+++ b/rpkid/rpki/gui/routeview/models.py
@@ -9,4 +9,12 @@ class RouteOrigin(rpki.gui.models.PrefixV4):
def __unicode__(self):
return u"AS%d's route origin for %s" % (self.asn, self.get_prefix_display())
+class RouteOriginV6(rpki.gui.models.PrefixV6):
+ "Represents a BGP routing table entry."
+
+ asn = django.db.models.PositiveIntegerField(help_text='origin AS', null=False)
+
+ def __unicode__(self):
+ return u"AS%d's route origin for %s" % (self.asn, self.get_prefix_display())
+
# vim:sw=4 ts=8 expandtab