Upgrade to 2.2.2
Resolves: RHBZ#1985629 RHBZ#2111398 RHBZ#2113871 RHBZ#2128415 RHBZ#2152101 Signed-off-by: Gris Ge <fge@redhat.com>
This commit is contained in:
		
							parent
							
								
									7992a44c2d
								
							
						
					
					
						commit
						6b175c0bdf
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -143,3 +143,6 @@ | ||||
| /nmstate-2.2.2-alpha.20221201.c8c776e9.tar.gz | ||||
| /nmstate-2.2.2-alpha.20221201.c8c776e9.tar.gz.asc | ||||
| /nmstate-vendor-2.2.2.20221201.c8c776e9.tar.xz | ||||
| /nmstate-2.2.2.tar.gz | ||||
| /nmstate-2.2.2.tar.gz.asc | ||||
| /nmstate-vendor-2.2.2.tar.xz | ||||
|  | ||||
							
								
								
									
										304
									
								
								BZ_2111398-ovs-add-support-for-port-trunks.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								BZ_2111398-ovs-add-support-for-port-trunks.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,304 @@ | ||||
| From dce5073432b4d7ce9bb0f3322c9970a714ae44a6 Mon Sep 17 00:00:00 2001 | ||||
| From: Beniamino Galvani <bgalvani@redhat.com> | ||||
| Date: Wed, 23 Nov 2022 10:26:35 +0100 | ||||
| Subject: [PATCH] ovs: add support for port trunks | ||||
| 
 | ||||
| This commit adds support for the "trunk-tags" property in ovs ports. | ||||
| 
 | ||||
| Example: | ||||
| 
 | ||||
| ```yml | ||||
|   - name: ovs0 | ||||
|     type: ovs-interface | ||||
|     state: up | ||||
|   - name: ovs-br0 | ||||
|     type: ovs-bridge | ||||
|     state: up | ||||
|     bridge: | ||||
|       port: | ||||
|         - name: ovs0 | ||||
|           vlan: | ||||
|             mode: trunk | ||||
|             trunk-tags: | ||||
|               - id-range: | ||||
|                   min: 20 | ||||
|                   max: 22 | ||||
|               - id-range: | ||||
|                   min: 30 | ||||
|                   max: 32 | ||||
|               - id: 40 | ||||
| ``` | ||||
| 
 | ||||
| The property is implemented in NM via "ovs-port.trunks" and | ||||
| corresponds to the "trunks" property of ports in ovs: | ||||
| 
 | ||||
| ``` | ||||
|     Bridge ovs-br0 | ||||
|         Port ovs0 | ||||
|             trunks: [20, 21, 22, 30, 31, 32, 40] | ||||
|             Interface ovs0 | ||||
|                 type: internal | ||||
| 
 | ||||
| ``` | ||||
| 
 | ||||
| Signed-off-by: Beniamino Galvani <bgalvani@redhat.com> | ||||
| Signed-off-by: Gris Ge <fge@redhat.com> | ||||
| ---
 | ||||
|  rust/src/lib/nm/nm_dbus/connection/conn.rs | 38 ++++++++++++++++++++++ | ||||
|  rust/src/lib/nm/nm_dbus/connection/mod.rs  |  2 +- | ||||
|  rust/src/lib/nm/nm_dbus/connection/ovs.rs  | 24 +++++++++++++- | ||||
|  rust/src/lib/nm/nm_dbus/mod.rs             |  2 +- | ||||
|  rust/src/lib/nm/query/ovs.rs               | 32 +++++++++++++++--- | ||||
|  rust/src/lib/nm/settings/ovs.rs            | 25 +++++++++++--- | ||||
|  6 files changed, 111 insertions(+), 12 deletions(-) | ||||
| 
 | ||||
| diff --git a/rust/src/lib/nm/nm_dbus/connection/conn.rs b/rust/src/lib/nm/nm_dbus/connection/conn.rs
 | ||||
| index 673bc597..69784fed 100644
 | ||||
| --- a/rust/src/lib/nm/nm_dbus/connection/conn.rs
 | ||||
| +++ b/rust/src/lib/nm/nm_dbus/connection/conn.rs
 | ||||
| @@ -442,3 +442,41 @@ pub(crate) fn nm_con_get_from_obj_path(
 | ||||
|      } | ||||
|      Ok(nm_conn) | ||||
|  } | ||||
| +
 | ||||
| +#[derive(Debug, Clone, PartialEq, Default, Deserialize)]
 | ||||
| +#[serde(try_from = "DbusDictionary")]
 | ||||
| +#[non_exhaustive]
 | ||||
| +pub struct NmRange {
 | ||||
| +    pub start: u64,
 | ||||
| +    pub end: u64,
 | ||||
| +    _other: DbusDictionary,
 | ||||
| +}
 | ||||
| +
 | ||||
| +impl TryFrom<DbusDictionary> for NmRange {
 | ||||
| +    type Error = NmError;
 | ||||
| +    fn try_from(mut v: DbusDictionary) -> Result<Self, Self::Error> {
 | ||||
| +        Ok(Self {
 | ||||
| +            start: _from_map!(v, "start", u64::try_from)?.unwrap_or_default(),
 | ||||
| +            end: _from_map!(v, "end", u64::try_from)?.unwrap_or_default(),
 | ||||
| +            _other: v,
 | ||||
| +        })
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +
 | ||||
| +impl NmRange {
 | ||||
| +    pub fn to_value(&self) -> Result<zvariant::Value, NmError> {
 | ||||
| +        let mut ret = zvariant::Dict::new(
 | ||||
| +            zvariant::Signature::from_str_unchecked("s"),
 | ||||
| +            zvariant::Signature::from_str_unchecked("v"),
 | ||||
| +        );
 | ||||
| +        ret.append(
 | ||||
| +            zvariant::Value::new("start"),
 | ||||
| +            zvariant::Value::new(zvariant::Value::U64(self.start)),
 | ||||
| +        )?;
 | ||||
| +        ret.append(
 | ||||
| +            zvariant::Value::new("end"),
 | ||||
| +            zvariant::Value::new(zvariant::Value::U64(self.end)),
 | ||||
| +        )?;
 | ||||
| +        Ok(zvariant::Value::Dict(ret))
 | ||||
| +    }
 | ||||
| +}
 | ||||
| diff --git a/rust/src/lib/nm/nm_dbus/connection/mod.rs b/rust/src/lib/nm/nm_dbus/connection/mod.rs
 | ||||
| index 04f2ee49..57504f77 100644
 | ||||
| --- a/rust/src/lib/nm/nm_dbus/connection/mod.rs
 | ||||
| +++ b/rust/src/lib/nm/nm_dbus/connection/mod.rs
 | ||||
| @@ -42,7 +42,7 @@ pub use self::bridge::{
 | ||||
|      NmSettingBridge, NmSettingBridgePort, NmSettingBridgeVlanRange, | ||||
|  }; | ||||
|  pub use self::conn::{ | ||||
| -    NmConnection, NmSettingConnection, NmSettingsConnectionFlag,
 | ||||
| +    NmConnection, NmRange, NmSettingConnection, NmSettingsConnectionFlag,
 | ||||
|  }; | ||||
|  pub use self::ethtool::NmSettingEthtool; | ||||
|  pub use self::ieee8021x::NmSetting8021X; | ||||
| diff --git a/rust/src/lib/nm/nm_dbus/connection/ovs.rs b/rust/src/lib/nm/nm_dbus/connection/ovs.rs
 | ||||
| index 2221c003..b728d88f 100644
 | ||||
| --- a/rust/src/lib/nm/nm_dbus/connection/ovs.rs
 | ||||
| +++ b/rust/src/lib/nm/nm_dbus/connection/ovs.rs
 | ||||
| @@ -5,7 +5,7 @@ use std::convert::TryFrom;
 | ||||
|   | ||||
|  use serde::Deserialize; | ||||
|   | ||||
| -use super::super::{connection::DbusDictionary, NmError, ToDbusValue};
 | ||||
| +use super::super::{connection::DbusDictionary, NmError, NmRange, ToDbusValue};
 | ||||
|   | ||||
|  #[derive(Debug, Clone, PartialEq, Default, Deserialize)] | ||||
|  #[serde(try_from = "DbusDictionary")] | ||||
| @@ -71,6 +71,7 @@ pub struct NmSettingOvsPort {
 | ||||
|      pub down_delay: Option<u32>, | ||||
|      pub tag: Option<u32>, | ||||
|      pub vlan_mode: Option<String>, | ||||
| +    pub trunks: Option<Vec<NmRange>>,
 | ||||
|      pub lacp: Option<String>, | ||||
|      _other: HashMap<String, zvariant::OwnedValue>, | ||||
|  } | ||||
| @@ -85,11 +86,23 @@ impl TryFrom<DbusDictionary> for NmSettingOvsPort {
 | ||||
|              tag: _from_map!(v, "tag", u32::try_from)?, | ||||
|              vlan_mode: _from_map!(v, "vlan-mode", String::try_from)?, | ||||
|              lacp: _from_map!(v, "lacp", String::try_from)?, | ||||
| +            trunks: _from_map!(v, "trunks", own_value_to_trunks)?,
 | ||||
|              _other: v, | ||||
|          }) | ||||
|      } | ||||
|  } | ||||
|   | ||||
| +fn own_value_to_trunks(
 | ||||
| +    value: zvariant::OwnedValue,
 | ||||
| +) -> Result<Vec<NmRange>, NmError> {
 | ||||
| +    let mut ret = Vec::new();
 | ||||
| +    let raw_ranges = Vec::<DbusDictionary>::try_from(value)?;
 | ||||
| +    for raw_range in raw_ranges {
 | ||||
| +        ret.push(NmRange::try_from(raw_range)?);
 | ||||
| +    }
 | ||||
| +    Ok(ret)
 | ||||
| +}
 | ||||
| +
 | ||||
|  impl ToDbusValue for NmSettingOvsPort { | ||||
|      fn to_value(&self) -> Result<HashMap<&str, zvariant::Value>, NmError> { | ||||
|          let mut ret = HashMap::new(); | ||||
| @@ -111,6 +124,15 @@ impl ToDbusValue for NmSettingOvsPort {
 | ||||
|          if let Some(v) = self.lacp.as_ref() { | ||||
|              ret.insert("lacp", zvariant::Value::new(v)); | ||||
|          } | ||||
| +        if let Some(v) = self.trunks.as_ref() {
 | ||||
| +            let mut trunk_values = zvariant::Array::new(
 | ||||
| +                zvariant::Signature::from_str_unchecked("a{sv}"),
 | ||||
| +            );
 | ||||
| +            for range in v {
 | ||||
| +                trunk_values.append(range.to_value()?)?;
 | ||||
| +            }
 | ||||
| +            ret.insert("trunks", zvariant::Value::Array(trunk_values));
 | ||||
| +        }
 | ||||
|          ret.extend(self._other.iter().map(|(key, value)| { | ||||
|              (key.as_str(), zvariant::Value::from(value.clone())) | ||||
|          })); | ||||
| diff --git a/rust/src/lib/nm/nm_dbus/mod.rs b/rust/src/lib/nm/nm_dbus/mod.rs
 | ||||
| index 5e408be5..053d92a0 100644
 | ||||
| --- a/rust/src/lib/nm/nm_dbus/mod.rs
 | ||||
| +++ b/rust/src/lib/nm/nm_dbus/mod.rs
 | ||||
| @@ -26,7 +26,7 @@ pub use self::active_connection::{
 | ||||
|      NmActiveConnection, NM_ACTIVATION_STATE_FLAG_EXTERNAL, | ||||
|  }; | ||||
|  pub use self::connection::{ | ||||
| -    NmConnection, NmIpRoute, NmIpRouteRule, NmIpRouteRuleAction,
 | ||||
| +    NmConnection, NmIpRoute, NmIpRouteRule, NmIpRouteRuleAction, NmRange,
 | ||||
|      NmSetting8021X, NmSettingBond, NmSettingBridge, NmSettingBridgePort, | ||||
|      NmSettingBridgeVlanRange, NmSettingConnection, NmSettingEthtool, | ||||
|      NmSettingInfiniBand, NmSettingIp, NmSettingIpMethod, NmSettingLoopback, | ||||
| diff --git a/rust/src/lib/nm/query/ovs.rs b/rust/src/lib/nm/query/ovs.rs
 | ||||
| index 30bfc160..33b82150 100644
 | ||||
| --- a/rust/src/lib/nm/query/ovs.rs
 | ||||
| +++ b/rust/src/lib/nm/query/ovs.rs
 | ||||
| @@ -3,15 +3,16 @@
 | ||||
|  use std::convert::TryFrom; | ||||
|   | ||||
|  use super::super::{ | ||||
| -    nm_dbus::NmConnection,
 | ||||
| +    nm_dbus::{NmConnection, NmRange},
 | ||||
|      settings::{get_exist_profile, NM_SETTING_OVS_PORT_SETTING_NAME}, | ||||
|  }; | ||||
|   | ||||
|  use crate::{ | ||||
| -    BridgePortVlanConfig, BridgePortVlanMode, Interface, InterfaceType,
 | ||||
| -    Interfaces, NmstateError, OvsBridgeBondConfig, OvsBridgeBondMode,
 | ||||
| -    OvsBridgeBondPortConfig, OvsBridgeConfig, OvsBridgeOptions,
 | ||||
| -    OvsBridgePortConfig, OvsDpdkConfig, OvsPatchConfig,
 | ||||
| +    BridgePortTunkTag, BridgePortVlanConfig, BridgePortVlanMode,
 | ||||
| +    BridgePortVlanRange, Interface, InterfaceType, Interfaces, NmstateError,
 | ||||
| +    OvsBridgeBondConfig, OvsBridgeBondMode, OvsBridgeBondPortConfig,
 | ||||
| +    OvsBridgeConfig, OvsBridgeOptions, OvsBridgePortConfig, OvsDpdkConfig,
 | ||||
| +    OvsPatchConfig,
 | ||||
|  }; | ||||
|   | ||||
|  pub(crate) fn nm_ovs_bridge_conf_get( | ||||
| @@ -202,6 +203,16 @@ fn get_vlan_info(nm_conn: &NmConnection) -> Option<BridgePortVlanConfig> {
 | ||||
|                          return None; | ||||
|                      } | ||||
|                  }), | ||||
| +                trunk_tags: match port_conf.trunks.as_deref() {
 | ||||
| +                    Some(trunks) => {
 | ||||
| +                        let mut ret = Vec::new();
 | ||||
| +                        for t in trunks {
 | ||||
| +                            ret.push(nm_range_to_trunk_tag(t));
 | ||||
| +                        }
 | ||||
| +                        Some(ret)
 | ||||
| +                    }
 | ||||
| +                    _ => None,
 | ||||
| +                },
 | ||||
|                  ..Default::default() | ||||
|              }); | ||||
|          } | ||||
| @@ -209,6 +220,17 @@ fn get_vlan_info(nm_conn: &NmConnection) -> Option<BridgePortVlanConfig> {
 | ||||
|      None | ||||
|  } | ||||
|   | ||||
| +fn nm_range_to_trunk_tag(range: &NmRange) -> BridgePortTunkTag {
 | ||||
| +    if range.start == range.end {
 | ||||
| +        BridgePortTunkTag::Id(range.start as u16)
 | ||||
| +    } else {
 | ||||
| +        BridgePortTunkTag::IdRange(BridgePortVlanRange {
 | ||||
| +            min: range.start as u16,
 | ||||
| +            max: range.end as u16,
 | ||||
| +        })
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +
 | ||||
|  pub(crate) fn get_ovs_patch_config( | ||||
|      nm_conn: &NmConnection, | ||||
|  ) -> Option<OvsPatchConfig> { | ||||
| diff --git a/rust/src/lib/nm/settings/ovs.rs b/rust/src/lib/nm/settings/ovs.rs
 | ||||
| index 3d3b3c5a..dd71d8a7 100644
 | ||||
| --- a/rust/src/lib/nm/settings/ovs.rs
 | ||||
| +++ b/rust/src/lib/nm/settings/ovs.rs
 | ||||
| @@ -4,15 +4,16 @@ use std::collections::HashMap;
 | ||||
|  use std::iter::FromIterator; | ||||
|   | ||||
|  use super::super::nm_dbus::{ | ||||
| -    NmConnection, NmSettingOvsDpdk, NmSettingOvsExtIds, NmSettingOvsIface,
 | ||||
| -    NmSettingOvsPatch,
 | ||||
| +    NmConnection, NmRange, NmSettingOvsDpdk, NmSettingOvsExtIds,
 | ||||
| +    NmSettingOvsIface, NmSettingOvsPatch,
 | ||||
|  }; | ||||
|   | ||||
|  use super::connection::gen_nm_conn_setting; | ||||
|   | ||||
|  use crate::{ | ||||
| -    BaseInterface, Interface, InterfaceType, NmstateError, OvsBridgeBondMode,
 | ||||
| -    OvsBridgeInterface, OvsBridgePortConfig, OvsInterface, UnknownInterface,
 | ||||
| +    BaseInterface, BridgePortTunkTag, Interface, InterfaceType, NmstateError,
 | ||||
| +    OvsBridgeBondMode, OvsBridgeInterface, OvsBridgePortConfig, OvsInterface,
 | ||||
| +    UnknownInterface,
 | ||||
|  }; | ||||
|   | ||||
|  pub(crate) fn create_ovs_port_nm_conn( | ||||
| @@ -66,11 +67,27 @@ pub(crate) fn create_ovs_port_nm_conn(
 | ||||
|          if let Some(vlan_mode) = vlan_conf.mode { | ||||
|              nm_ovs_port_set.vlan_mode = Some(vlan_mode.to_string()); | ||||
|          } | ||||
| +        if let Some(trunk_tags) = &vlan_conf.trunk_tags {
 | ||||
| +            let mut ret = Vec::new();
 | ||||
| +            for trunk_tag in trunk_tags.as_slice() {
 | ||||
| +                ret.push(trunk_tag_to_nm_range(trunk_tag));
 | ||||
| +            }
 | ||||
| +            nm_ovs_port_set.trunks = Some(ret);
 | ||||
| +        }
 | ||||
|      } | ||||
| +
 | ||||
|      nm_conn.ovs_port = Some(nm_ovs_port_set); | ||||
|      Ok(nm_conn) | ||||
|  } | ||||
|   | ||||
| +fn trunk_tag_to_nm_range(trunk_tag: &BridgePortTunkTag) -> NmRange {
 | ||||
| +    let mut ret = NmRange::default();
 | ||||
| +    let (vid_min, vid_max) = trunk_tag.get_vlan_tag_range();
 | ||||
| +    ret.start = vid_min.into();
 | ||||
| +    ret.end = vid_max.into();
 | ||||
| +    ret
 | ||||
| +}
 | ||||
| +
 | ||||
|  pub(crate) fn get_ovs_port_name( | ||||
|      ovs_br_iface: &OvsBridgeInterface, | ||||
|      ovs_iface_name: &str, | ||||
| -- 
 | ||||
| 2.39.0 | ||||
| 
 | ||||
							
								
								
									
										14
									
								
								nmstate.spec
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								nmstate.spec
									
									
									
									
									
								
							| @ -4,14 +4,15 @@ | ||||
| 
 | ||||
| Name:           nmstate | ||||
| Version:        2.2.2 | ||||
| Release:        0.alpha.20221201%{?dist} | ||||
| Release:        1%{?dist} | ||||
| Summary:        Declarative network manager API | ||||
| License:        LGPLv2+ | ||||
| URL:            https://github.com/%{srcname}/%{srcname} | ||||
| Source0:        https://github.com/nmstate/nmstate/releases/download/v%{version}/nmstate-%{version}-alpha.20221201.c8c776e9.tar.gz | ||||
| Source1:        https://github.com/nmstate/nmstate/releases/download/v%{version}/nmstate-%{version}-alpha.20221201.c8c776e9.tar.gz.asc | ||||
| Source0:        https://github.com/nmstate/nmstate/releases/download/v%{version}/nmstate-%{version}.tar.gz | ||||
| Source1:        https://github.com/nmstate/nmstate/releases/download/v%{version}/nmstate-%{version}.tar.gz.asc | ||||
| Source2:        https://nmstate.io/nmstate.gpg | ||||
| Source3:        https://github.com/nmstate/nmstate/releases/download/v%{version}/nmstate-vendor-%{version}.20221201.c8c776e9.tar.xz | ||||
| Source3:        https://github.com/nmstate/nmstate/releases/download/v%{version}/nmstate-vendor-%{version}.tar.xz | ||||
| Patch1:         BZ_2111398-ovs-add-support-for-port-trunks.patch | ||||
| BuildRequires:  python3-devel | ||||
| BuildRequires:  python3-setuptools | ||||
| BuildRequires:  gnupg2 | ||||
| @ -77,7 +78,7 @@ This package contains the Python 3 library for Nmstate. | ||||
| %prep | ||||
| gpg2 --import --import-options import-export,import-minimal %{SOURCE2} > ./gpgkey-mantainers.gpg | ||||
| gpgv2 --keyring ./gpgkey-mantainers.gpg %{SOURCE1} %{SOURCE0} | ||||
| %setup -q | ||||
| %autosetup -p1 | ||||
| 
 | ||||
| pushd rust | ||||
| # Source3 is vendored dependencies | ||||
| @ -150,6 +151,9 @@ popd | ||||
| /sbin/ldconfig | ||||
| 
 | ||||
| %changelog | ||||
| * Wed Dec 14 2022 Gris Ge <fge@redhat.com> - 2.2.2-1 | ||||
| - Upgrade to 2.2.2 | ||||
| 
 | ||||
| * Thu Dec 01 2022 Fernando Fernandez Mancera <ferferna@redhat.com> - 2.2.2-0.alpha.20221201.c8c776e9 | ||||
| - Upgrade to 2.2.2-0.alpha.20221201.c8c776e9 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										8
									
								
								sources
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								sources
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| SHA512 (nmstate-2.2.2-alpha.20221201.c8c776e9.tar.gz) = 1747c4c30022771bd8d6d2c1fffb13552a9064abcb943ce3196dff857ad373948016c75a48aa8a40973fa42c90556a821f50f1643969cee90c90a47137d6d146 | ||||
| SHA512 (nmstate-2.2.2-alpha.20221201.c8c776e9.tar.gz.asc) = addbffdf4b6a426a9b73fd8c5b328c3e3c2c5241c7992acaf8b0679373ffd8b273861a7b073da2050c683c5033e81c62266001899488041a2dabcc634e29f13c | ||||
| SHA512 (nmstate-vendor-2.2.2.20221201.c8c776e9.tar.xz) = 27e59a1cafb1b795de3c826b416dcbeb6f68c71103b69b0884d5fdb8d65961427e5d1a42ce4edb90412dcdc0269c4f0293d4c3b3dc859e00737de4ba5172391a | ||||
| SHA512 (nmstate.gpg) = 2e211f2268a412036d71b90bb37aab5a30c1a69a9ff85debbad703bc018183890b4a3e38b00b96b4d8392dc739e8cdec0d891e220c04d61289c384f1bbbef5cb | ||||
| SHA512 (nmstate-2.2.2.tar.gz) = 9e20b4f944596e0cf46b470a2a1a4bfcd4fa7a114fd9517b17507cdfd5c1203f81c6bfd730f877c67eb80cae0cc87633ba66185f74d69fc92a7c03a9e195f315 | ||||
| SHA512 (nmstate-2.2.2.tar.gz.asc) = 8167aabab9214b31a56ba986e961ec7b7e6f2513dd69c4c7cc37eea2d80d49329683c6c39c37d5f7c52512a0a6800f505e7de545b9d58c33d8c65c8902944d9e | ||||
| SHA512 (nmstate-vendor-2.2.2.tar.xz) = 0e7314e50a5ddc963c4bb71b07d2ab76938e2f4c9b7238032582c781aee66402490278dec9ad75cfe842623a257904c55d0f8d3be2427e63f634dc7f93fc8f5b | ||||
| SHA512 (nmstate.gpg) = 91c6b1d8aef4944520d4bdd4e90121bbbbaf772444f5eb6081cee81e17b21b66798437cdc09a117c6fc77c54d798aaa30400857aa090cb2102b47841f45cf6eb | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user