class NetworkFacility(models.Model): local_asn = ASNField(verbose_name="Local ASN", null=True, blank=True) avail_sonet = models.BooleanField(default=False) avail_ethernet = models.BooleanField(default=False) avail_atm = models.BooleanField(default=False) net = models.ForeignKey( Network, default=0, related_name="netfac_set", verbose_name="Network", on_delete=models.CASCADE, ) fac = models.ForeignKey( Facility, default=0, related_name="netfac_set", verbose_name="Facility", on_delete=models.CASCADE, ) ignored_fields = ["city", "country", "name"] class Meta: unique_together = ("net", "fac", "local_asn") verbose_name = "Network Facility" verbose_name_plural = "Network Facilities"
class Network(models.Model): asn = ASNField(unique=True) name = models.CharField(max_length=255) irr_as_set = models.CharField(max_length=255, blank=True, null=True) info_prefixes6 = models.PositiveIntegerField(blank=True, default=0) info_prefixes4 = models.PositiveIntegerField(blank=True, default=0) class Meta: ordering = ["asn"] def __str__(self): return "AS{} - {}".format(self.asn, self.name)
class NetworkIXLAN(models.Model): asn = ASNField() name = models.CharField(max_length=255) ipaddr6 = models.GenericIPAddressField(protocol='IPv6', blank=True, null=True) ipaddr4 = models.GenericIPAddressField(protocol='IPv4', blank=True, null=True) is_rs_peer = models.BooleanField(default=False) ix_id = models.PositiveIntegerField() ixlan_id = models.PositiveIntegerField() class Meta: ordering = ['asn', 'ipaddr6', 'ipaddr4'] verbose_name = 'Network IX LAN' verbose_name_plural = 'Network IX LANs' def __str__(self): return 'AS{} on {} - IPv6: {} - IPv4: {}'.format( self.asn, self.name, self.ipaddr6, self.ipaddr4)
class NetworkIXLan(models.Model): asn = ASNField(verbose_name="ASN") ipaddr4 = InetAddressField( verbose_name="IPv4", validators=[AddressFamilyValidator(4)], blank=True, null=True, ) ipaddr6 = InetAddressField( verbose_name="IPv6", validators=[AddressFamilyValidator(6)], blank=True, null=True, ) is_rs_peer = models.BooleanField(default=False) notes = models.CharField(max_length=255, blank=True) speed = models.PositiveIntegerField() operational = models.BooleanField(default=True) net = models.ForeignKey( Network, default=0, related_name="netixlan_set", verbose_name="Network", on_delete=models.CASCADE, ) ixlan = models.ForeignKey( IXLan, default=0, related_name="netixlan_set", verbose_name="Internet Exchange LAN", on_delete=models.CASCADE, ) ignored_fields = ["ix_id", "name"] class Meta: verbose_name = "Public Peering Exchange Point" verbose_name_plural = "Public Peering Exchange Points"
class IXLan(models.Model): name = models.CharField(max_length=255, blank=True) descr = models.TextField(blank=True) mtu = models.PositiveIntegerField(null=True, blank=True) vlan = models.PositiveIntegerField(null=True, blank=True) dot1q_support = models.BooleanField(default=False) rs_asn = ASNField( verbose_name="Route Server ASN", allow_zero=True, null=True, blank=True, default=0, ) arp_sponge = MACAddressField(verbose_name="ARP sponging MAC", null=True, unique=True, blank=True) ixf_ixp_member_list_url = models.URLField( verbose_name="IX-F Member Export URL", null=True, blank=True) ixf_ixp_member_list_url_visible = models.CharField( verbose_name="IX-F Member Export URL Visibility", max_length=64, choices=Visibility.choices, default=Visibility.PRIVATE, ) ix = models.ForeignKey( InternetExchange, default=0, related_name="ixlan_set", verbose_name="Internet Exchange", on_delete=models.CASCADE, ) class Meta: verbose_name = "Internet Exchange LAN" verbose_name_plural = "Internet Exchange LANs"
class Network(models.Model): asn = ASNField(unique=True, verbose_name="ASN") name = models.CharField(max_length=255, unique=True) name_long = models.CharField(max_length=255, blank=True) aka = models.CharField(max_length=255, blank=True, verbose_name="Also Known As") irr_as_set = models.CharField( max_length=255, blank=True, verbose_name="IRR AS-SET/ROUTE-SET", help_text= "Reference to an AS-SET or ROUTE-SET in Internet Routing Registry (IRR)", ) website = URLField(blank=True) looking_glass = URLField(blank=True) route_server = URLField(blank=True) notes = models.TextField(blank=True) notes_private = models.TextField(blank=True) info_traffic = models.CharField(max_length=39, blank=True, choices=Traffic.choices) info_ratio = models.CharField( max_length=45, blank=True, choices=Ratio.choices, default=Ratio.NOT_DISCLOSED, ) info_scope = models.CharField( max_length=39, blank=True, choices=Scope.choices, default=Scope.NOT_DISCLOSED, ) info_type = models.CharField( max_length=60, blank=True, choices=NetType.choices, default=NetType.NOT_DISCLOSED, ) info_prefixes4 = models.PositiveIntegerField( null=True, blank=True, help_text= "Recommended maximum number of IPv4 routes/prefixes to be configured on peering sessions for this ASN", ) info_prefixes6 = models.PositiveIntegerField( null=True, blank=True, help_text= "Recommended maximum number of IPv6 routes/prefixes to be configured on peering sessions for this ASN", ) info_unicast = models.BooleanField(default=False) info_multicast = models.BooleanField(default=False) info_ipv6 = models.BooleanField(default=False) info_never_via_route_servers = models.BooleanField( default=False, help_text= "Indicates if this network will announce its routes via route servers or not", ) policy_url = URLField(blank=True) policy_general = models.CharField(max_length=72, blank=True, choices=GeneralPolicy.choices) policy_locations = models.CharField( max_length=72, blank=True, choices=LocationsPolicy.choices, ) policy_ratio = models.BooleanField(default=False) policy_contracts = models.CharField( max_length=36, blank=True, choices=ContractsPolicy.choices, ) org = models.ForeignKey( Organization, related_name="net_set", verbose_name="Organization", on_delete=models.CASCADE, ) def __str__(self): return self.name
class NetworkIXLAN(models.Model): asn = ASNField() name = models.CharField(max_length=255) ipaddr6 = InetAddressField( store_prefix_length=False, blank=True, null=True, validators=[AddressFamilyValidator(6)], ) ipaddr4 = InetAddressField( store_prefix_length=False, blank=True, null=True, validators=[AddressFamilyValidator(4)], ) is_rs_peer = models.BooleanField(default=False) ix_id = models.PositiveIntegerField() ixlan_id = models.PositiveIntegerField() objects = NetManager() logger = logging.getLogger("peering.manager.peeringdb") class Meta: ordering = ["asn", "ipaddr6", "ipaddr4"] verbose_name = "Network IX LAN" verbose_name_plural = "Network IX LANs" def save(self, *args, **kwargs): super().save(*args, **kwargs) # Ignore if we do not have any IP addresses if not self.ipaddr6 and not self.ipaddr4: self.logger.debug( "network ixlan with as%s and ixlan id %s ignored" ", no ipv6 and no ipv4", self.asn, self.ixlan_id, ) return # Trigger the build of a new PeerRecord or just ignore if it already # exists, assumes it exists # Note that there is not point of doing the same thing when a Network # or a NetworkIXLAN is deleted because it will automatically delete the # PeerRecord linked to it using the foreign key (with the CASCADE mode) network = None peer_record_exists = True try: # Try guessing the Network given its ASN network = Network.objects.get(asn=self.asn) # Try finding if the PeerRecord already exists PeerRecord.objects.get(network=network, network_ixlan=self) except Network.DoesNotExist: # The network does not exist, well not much to do self.logger.debug( "network with as%s does not exist, required for " "peer record creation", self.asn, ) except PeerRecord.DoesNotExist: # But if the exception is raised, it does not peer_record_exists = False # If the PeerRecord does not exist, create it if not peer_record_exists: PeerRecord.objects.create(network=network, network_ixlan=self) self.logger.debug( "peer record created with as%s and ixlan id %s", self.asn, self.ixlan_id ) else: self.logger.debug( "peer record with as%s and ixlan id %s exists", self.asn, self.ixlan_id ) def __str__(self): return "AS{} on {} - IPv6: {} - IPv4: {}".format( self.asn, self.name, self.ipaddr6, self.ipaddr4 )
class NetworkIXLAN(models.Model): asn = ASNField() name = models.CharField(max_length=255) ipaddr6 = models.GenericIPAddressField(protocol='IPv6', blank=True, null=True) ipaddr4 = models.GenericIPAddressField(protocol='IPv4', blank=True, null=True) is_rs_peer = models.BooleanField(default=False) ix_id = models.PositiveIntegerField() ixlan_id = models.PositiveIntegerField() logger = logging.getLogger('peering.manager.peeringdb') class Meta: ordering = ['asn', 'ipaddr6', 'ipaddr4'] verbose_name = 'Network IX LAN' verbose_name_plural = 'Network IX LANs' def save(self, *args, **kwargs): super(NetworkIXLAN, self).save(*args, **kwargs) # Ignore if we do not have any IP addresses if not self.ipaddr6 and not self.ipaddr4: self.logger.debug('network ixlan with as%s and ixlan id %s ignored' ', no ipv6 and no ipv4', self.asn, self.ixlan_id) return # Trigger the build of a new PeerRecord or just ignore if it already # exists, assumes it exists # Note that there is not point of doing the same thing when a Network # or a NetworkIXLAN is deleted because it will automatically delete the # PeerRecord linked to it using the foreign key (with the CASCADE mode) network = None peer_record_exists = True try: # Try guessing the Network given its ASN network = Network.objects.get(asn=self.asn) # Try finding if the PeerRecord already exists PeerRecord.objects.get(network=network, network_ixlan=self) except Network.DoesNotExist: # The network does not exist, well not much to do self.logger.debug('network with as%s does not exist, required for ' 'peer record creation', self.asn) except PeerRecord.DoesNotExist: # But if the exception is raised, it does not peer_record_exists = False # If the PeerRecord does not exist, create it if not peer_record_exists: PeerRecord.objects.create(network=network, network_ixlan=self) self.logger.debug('peer record created with as%s and ixlan id %s', self.asn, self.ixlan_id) else: self.logger.debug('peer record with as%s and ixlan id %s exists', self.asn, self.ixlan_id) def __str__(self): return 'AS{} on {} - IPv6: {} - IPv4: {}'.format(self.asn, self.name, self.ipaddr6, self.ipaddr4)
class NetworkIXLan(models.Model): asn = ASNField(verbose_name="ASN") ipaddr4 = InetAddressField( verbose_name="IPv4", validators=[AddressFamilyValidator(4)], blank=True, null=True, ) ipaddr6 = InetAddressField( verbose_name="IPv6", validators=[AddressFamilyValidator(6)], blank=True, null=True, ) is_rs_peer = models.BooleanField(default=False) notes = models.CharField(max_length=255, blank=True) speed = models.PositiveIntegerField() operational = models.BooleanField(default=True) net = models.ForeignKey( to="peeringdb.Network", default=0, related_name="netixlan_set", verbose_name="Network", on_delete=models.CASCADE, ) ixlan = models.ForeignKey( to="peeringdb.IXLan", default=0, related_name="netixlan_set", verbose_name="Internet Exchange LAN", on_delete=models.CASCADE, ) ignored_fields = ["ix_id", "name"] class Meta: verbose_name = "Public Peering Exchange Point" verbose_name_plural = "Public Peering Exchange Points" @property def cidr4(self): try: return self.cidr(address_family=4) except ValueError: return None @property def cidr6(self): try: return self.cidr(address_family=6) except ValueError: return None def get_ixlan_prefix(self, address_family=0): """ Returns matching `CidrAddressField` containing this `NetworkIXLan`'s IP addresses. When `address_family` is set to `4` or `6` only the prefix also matching the address family will be returned. """ prefixes = IXLanPrefix.objects.filter(ixlan=self.ixlan) if address_family in (4, 6): prefixes = prefixes.filter(prefix__family=address_family) r = [] if address_family != 6: for p in prefixes: if self.ipaddr4 in p.prefix: r.append(p.prefix) break if address_family != 4: for p in prefixes: if self.ipaddr6 in p.prefix: r.append(p.prefix) break return r if len(r) != 1 else r[0] def cidr(self, address_family=4): """ Returns a Python IP interface object with the IP address and prefix length set. """ if address_family not in (4, 6): raise ValueError("Address family must be 4 or 6") if address_family == 4 and not self.ipaddr4: raise ValueError("IPv4 address is not set") if address_family == 6 and not self.ipaddr6: raise ValueError("IPv6 address is not set") prefix = self.get_ixlan_prefix(address_family=address_family) address = self.ipaddr4 if address_family == 4 else self.ipaddr6 return ipaddress.ip_interface(f"{address.ip}/{prefix.prefixlen}")