class SwitchPort(mf.ModelBase, mixins.BasicEvents, mixins.Name): #定义表结构 table_name = 'switch_port' #port编号 port_num = fields.IntField() #admin状态 admin_state = df_fields.EnumField(('up', 'down')) lport = df_fields.ReferenceField(l2.LogicalPort) #接口类型 type = df_fields.EnumField(( constants.SWITCH_BRIDGE_INTERFACE, constants.SWITCH_PATCH_INTERFACE, constants.SWITCH_COMPUTE_INTERFACE, constants.SWITCH_TUNNEL_INTERFACE, constants.SWITCH_UNKNOWN_INTERFACE, ), ) #对端信息 peer = fields.StringField() #接口mac地址 mac_in_use = df_fields.MacAddressField() # attached_mac = df_fields.MacAddressField() #隧道类型 tunnel_type = fields.StringField()
class FlowClassifier(mf.ModelBase, mixins.BasicEvents, mixins.Topic, mixins.Name, mixins.UniqueKey): table_name = 'sfc_flowclassifier' ether_type = df_fields.EnumField([ constants.IPv4, constants.IPv6, ], ) protocol = df_fields.EnumField([ constants.PROTO_NAME_TCP, constants.PROTO_NAME_UDP, ], ) source_cidr = df_fields.IpNetworkField() dest_cidr = df_fields.IpNetworkField() source_transport_ports = df_fields.PortRangeField() dest_transport_ports = df_fields.PortRangeField() source_port = df_fields.ReferenceField(l2.LogicalPort) dest_port = df_fields.ReferenceField(l2.LogicalPort) # TODO(dimak) Add l7 parameters @property def is_classification_local(self): '''Should the flow classifier classification flows be installed locally For classification on source lport, we match using reg6, which is available only after classification app sets it, so there is no use installing it on other hosts. For classification on dest lport, we match using reg7. reg7 is set on all hosts during the time packet passes through L2 app. We can classify the packet right away on any of the hosts and forward it to the first SF, saving 2 hops of going to dest node then to the first SF. ''' if self.source_port is not None: return self.source_port.is_local return True @property def is_dispatch_local(self): '''Should the flow classifier dispatch flows be installed locally. For classification on source lport, we match using reg6, so we can dispatch the packet anywhere, and it will be forwarded. No loop will be created because no app will set reg6 again. For classification on dest lport, we match using reg7, so we have to forward the packet all the way to the destination host, and mark it as 'already done SFC', so it won't get stuck in a loop. The has to be done on the destination host because the mark gets lost in transit. ''' if self.dest_port is not None: return self.dest_port.is_local return True
class SecurityGroupRule(mf.ModelBase, mixins.BasicEvents, mixins.Topic, mixins.Version): direction = df_fields.EnumField(RULE_DIRECTION, required=True) ethertype = df_fields.EnumField(RULE_ETHERTYPE, required=True) port_range_max = fields.IntField() port_range_min = fields.IntField() protocol = df_fields.IpProto() remote_group_id = fields.StringField() remote_ip_prefix = df_fields.IpNetworkField() security_group_id = fields.StringField()
class OvsPort(mf.ModelBase, mixins.BasicEvents, mixins.Name): table_name = 'ovs_port' ofport = fields.IntField() admin_state = df_fields.EnumField(('up', 'down')) lport = df_fields.ReferenceField(l2.LogicalPort) type = df_fields.EnumField(( constants.OVS_BRIDGE_INTERFACE, constants.OVS_PATCH_INTERFACE, constants.OVS_VM_INTERFACE, constants.OVS_TUNNEL_INTERFACE, constants.OVS_UNKNOWN_INTERFACE, ), ) peer = fields.StringField() peer_bridge = fields.StringField() mac_in_use = df_fields.MacAddressField() attached_mac = df_fields.MacAddressField() tunnel_type = fields.StringField() @classmethod def from_idl_row(cls, row): res = cls( id=str(row.uuid), name=row.name, type=_get_interface_type(row), ) if row.ofport: res.ofport = int(row.ofport[0]) if row.mac_in_use: res.mac_in_use = row.mac_in_use[0] if row.admin_state: res.admin_state = row.admin_state[0] if res.type == constants.OVS_PATCH_INTERFACE: res.peer = row.options['peer'] res.peer_bridge = row.external_ids['peer_bridge'] if res.type == constants.OVS_TUNNEL_INTERFACE: res.tunnel_type = row.type external_ids = row.external_ids lport_id = external_ids.get('iface-id') if lport_id is not None: res.lport = lport_id attached_mac = external_ids.get('attached-mac') if attached_mac is not None: res.attached_mac = attached_mac return res
class PortBinding(models.Base): type = df_fields.EnumField((BINDING_CHASSIS, BINDING_VTEP), required=True) chassis = df_fields.ReferenceField(core.Chassis) vtep_address = df_fields.IpAddressField() @property def ip(self): if self.type == BINDING_CHASSIS: return self.chassis.ip elif self.type == BINDING_VTEP: return self.vtep_address return None @property def is_local(self): if self.type == BINDING_CHASSIS: return self.chassis.id == cfg.CONF.host return False def __deepcopy__(self, memo): return PortBinding( type=self.type, chassis=copy.deepcopy(self.chassis, memo), vtep_address=self.vtep_address, )
class PortPair(mf.ModelBase, mixins.BasicEvents, mixins.Topic, mixins.Name): table_name = 'sfc_portpair' ingress_port = df_fields.ReferenceField(l2.LogicalPort) egress_port = df_fields.ReferenceField(l2.LogicalPort) correlation_mechanism = df_fields.EnumField([CORR_NONE, CORR_MPLS]) weight = fields.FloatField()
class ChildPortSegmentation(mf.ModelBase, mixins.Topic, mixins.BasicEvents): table_name = 'child_port_segmentation' parent = df_fields.ReferenceField(l2.LogicalPort, required=True) port = df_fields.ReferenceField(l2.LogicalPort, required=True) segmentation_type = df_fields.EnumField(SUPPORTED_SEGMENTATION_TYPES, required=True) segmentation_id = fields.IntField(required=True)
class LogicalPort(mf.ModelBase, mixins.Name, mixins.Version, mixins.Topic, mixins.UniqueKey, mixins.BasicEvents): table_name = "lport" ips = df_fields.ListOfField(df_fields.IpAddressField()) subnets = df_fields.ReferenceListField(Subnet) macs = df_fields.ListOfField(df_fields.MacAddressField()) enabled = fields.BoolField() binding = fields.EmbeddedField(PortBinding) lswitch = df_fields.ReferenceField(LogicalSwitch) security_groups = df_fields.ReferenceListField(secgroups.SecurityGroup) allowed_address_pairs = fields.ListField(AddressPair) port_security_enabled = fields.BoolField() device_owner = fields.StringField() device_id = fields.StringField() qos_policy = df_fields.ReferenceField(qos.QosPolicy) dhcp_params = fields.EmbeddedField(DhcpParams) binding_vnic_type = df_fields.EnumField(portbindings.VNIC_TYPES) @property def ip(self): try: return self.ips[0] except IndexError: return None @property def mac(self): try: return self.macs[0] except IndexError: return None @property def is_local(self): return port_locator.is_port_local(self) @property def is_remote(self): return port_locator.is_port_remote(self) @property def all_ips(self): ips = set(self.ips) ips.update(pair.ip_address for pair in self.allowed_address_pairs) return ips def __str__(self): data = {} for name in dir(self): if name.startswith('_'): continue cls_definition = getattr(self.__class__, name, None) if isinstance(cls_definition, fields.BaseField): if name in self._set_fields: data[name] = getattr(self, name) elif not cls_definition: # Display only instnaces, not classes data[name] = getattr(self, name) return str(data)
class QosPolicyRule(mf.ModelBase, mixins.BasicEvents): type = df_fields.EnumField((RULE_TYPES), required=True) dscp_mark = fields.IntField() max_kbps = fields.IntField() max_burst_kbps = fields.IntField() direction = df_fields.EnumField(DIRECTIONS) def validate(self): """ Validate the rule. That is, verify dscp_mark is set if type is dscp_marking, and that max_burst_kbps is set if type is bandwidth_limit """ if self.type == RULE_TYPE_DSCP_MARKING: if self.dscp_mark is None: errors.ValidationError("dscp_mark is required if " "type is dscp_marking") elif self.type == RULE_TYPE_BANDWIDTH_LIMIT: if self.max_burst_kbps is None: errors.ValidationError("max_burst_kbps is required if " "type is bandwidth_limit")
class FieldTestModel(mf.ModelBase): enum = df_fields.EnumField(('a', 'b', 'c')) enum_list = df_fields.EnumListField(('a', 'b', 'c')) ipaddr = df_fields.IpAddressField() ipnetwork = df_fields.IpNetworkField() ref = df_fields.ReferenceField(ReffedTestModel) ref_list = df_fields.ReferenceListField(ReffedTestModel) ip_list = df_fields.ListOfField(df_fields.IpAddressField()) def __init__(self, **kwargs): super(FieldTestModel, self).__init__(id='id1', **kwargs)
class PortChain(mf.ModelBase, mixins.BasicEvents, mixins.Topic, mixins.Name): table_name = 'sfc_portchain' protocol = df_fields.EnumField([PROTO_MPLS]) chain_id = fields.IntField() port_pair_groups = df_fields.ReferenceListField(PortPairGroup) flow_classifiers = df_fields.ReferenceListField(FlowClassifier) def find_flow_classifier(self, fc_id): for fc in self.flow_classifiers: if fc.id == fc_id: return fc
class FieldTestModel(mf.ModelBase): enum = df_fields.EnumField(('a', 'b', 'c')) enum_list = df_fields.EnumListField(('a', 'b', 'c')) ipaddr = df_fields.IpAddressField() ipnetwork = df_fields.IpNetworkField() ref = df_fields.ReferenceField(ReffedTestModel) ref_list = df_fields.ReferenceListField(ReffedTestModel) ip_list = df_fields.ListOfField(df_fields.IpAddressField()) port_range = df_fields.PortRangeField() dhcp_opts = df_fields.DhcpOptsDictField() def __init__(self, **kwargs): id = kwargs.pop("id", 'id1') super(FieldTestModel, self).__init__(id=id, **kwargs)
class FloatingIp(mf.ModelBase, mixins.Version, mixins.Topic, mixins.UniqueKey, mixins.Name, mixins.BasicEvents): table_name = 'floatingip' status = df_fields.EnumField( (constants.FLOATINGIP_STATUS_ACTIVE, constants.FLOATINGIP_STATUS_DOWN, constants.FLOATINGIP_STATUS_ERROR)) floating_ip_address = df_fields.IpAddressField() fixed_ip_address = df_fields.IpAddressField() lport = df_fields.ReferenceField(l2.LogicalPort) floating_lport = df_fields.ReferenceField(l2.LogicalPort) lrouter = df_fields.ReferenceField(LogicalRouter) @property def is_local(self): return self.lport is not None and self.lport.is_local
class ChildPortSegmentation(mf.ModelBase, mixins.Topic, mixins.BasicEvents): table_name = 'child_port_segmentation' parent = df_fields.ReferenceField(l2.LogicalPort, required=True) port = df_fields.ReferenceField(l2.LogicalPort, required=True) segmentation_type = df_fields.EnumField(SUPPORTED_SEGMENTATION_TYPES, required=True) segmentation_id = fields.IntField() def validate(self): """ Verify that the correct fields are filled for the correct type. e.g. for VLAN, segmentation_id is not None. """ super(ChildPortSegmentation, self).validate() if self.segmentation_type == n_const.TYPE_VLAN: if self.segmentation_id is None: raise errors.ValidationError("segmentation_id required if " "segmentation_type is " + n_const.TYPE_VLAN)
class LogicalPort(mf.ModelBase, mixins.Name, mixins.Version, mixins.Topic, mixins.UniqueKey): table_name = "lport" ips = df_fields.ListOfField(df_fields.IpAddressField()) subnets = df_fields.ReferenceListField(Subnet) macs = df_fields.ListOfField(df_fields.MacAddressField()) enabled = fields.BoolField() chassis = df_fields.ReferenceField(core.Chassis) lswitch = df_fields.ReferenceField(LogicalSwitch) security_groups = df_fields.ReferenceListField(secgroups.SecurityGroup) allowed_address_pairs = fields.ListField(AddressPair) port_security_enabled = fields.BoolField() device_owner = fields.StringField() device_id = fields.StringField() qos_policy = df_fields.ReferenceField(qos.QosPolicy) remote_vtep = fields.BoolField() extra_dhcp_options = df_fields.IntStringDictField() binding_vnic_type = df_fields.EnumField(portbindings.VNIC_TYPES) def __init__(self, ofport=None, is_local=None, peer_vtep_address=None, **kwargs): super(LogicalPort, self).__init__(**kwargs) self.ofport = ofport self.is_local = is_local self.peer_vtep_address = peer_vtep_address @property def ip(self): try: return self.ips[0] except IndexError: return None @property def mac(self): try: return self.macs[0] except IndexError: return None def is_vm_port(self): """ Return True if the device owner starts with 'compute:' (or is None) """ owner = self.device_owner if not owner or owner.startswith(n_const.DEVICE_OWNER_COMPUTE_PREFIX): return True return False def __str__(self): data = {} for name in dir(self): if name.startswith('_'): continue cls_definition = getattr(self.__class__, name, None) if isinstance(cls_definition, fields.BaseField): if name in self._set_fields: data[name] = getattr(self, name) elif not cls_definition: # Display only instnaces, not classes data[name] = getattr(self, name) return str(data) def emit_created(self): ofport = getattr(self, 'ofport', None) if not ofport: return is_local = getattr(self, 'is_local', None) LOG.info("Adding new logical port = %s", self) if is_local: self.emit_local_created() else: self.emit_remote_created() def emit_updated(self, original_lport): ofport = getattr(self, 'ofport', None) if not ofport: return is_local = getattr(self, 'is_local', None) LOG.info( "Updating %(location)s logical port = %(port)s, " "original port = %(original_port)s", { 'port': self, 'original_port': original_lport, 'location': 'local' if is_local else 'remote' }) if is_local: self.emit_local_updated(original_lport) else: self.emit_remote_updated(original_lport) def emit_deleted(self): is_local = getattr(self, 'is_local', None) ofport = getattr(self, 'ofport', None) if not ofport: return if is_local: self.emit_local_deleted() else: self.emit_remote_deleted()
class Migration(mf.ModelBase, mixins.BasicEvents): table_name = 'migration' dest_chassis = df_fields.ReferenceField(core.Chassis) lport = df_fields.ReferenceField(l2.LogicalPort) status = df_fields.EnumField(MIGRATION_STATUSES, required=True)