doc: Add document for DNS, Route and RouteRule

Signed-off-by: Gris Ge <fge@redhat.com>
This commit is contained in:
Gris Ge 2022-11-08 15:27:18 +08:00 committed by Fernando Fernández Mancera
parent a9cee09dfe
commit 13fb417349
3 changed files with 111 additions and 0 deletions

View File

@ -12,14 +12,42 @@ const DEFAULT_DNS_PRIORITY: i32 = 40;
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(deny_unknown_fields)]
/// DNS resolver state. Example partial yaml output of [NetworkState] with
/// static DNS config:
/// ```yaml
/// ---
/// dns-resolver:
/// running:
/// server:
/// - 2001:db8:1::250
/// - 192.0.2.250
/// search:
/// - example.org
/// - example.net
/// config:
/// search:
/// - example.org
/// - example.net
/// server:
/// - 2001:db8:1::250
/// - 192.0.2.250
/// ```
pub struct DnsState {
#[serde(skip_serializing_if = "Option::is_none")]
/// The running effective state. The DNS server might be from DHCP(IPv6
/// autoconf) or manual setup.
/// Ignored when applying state.
pub running: Option<DnsClientState>,
#[serde(skip_serializing_if = "Option::is_none")]
/// The static saved DNS resolver config.
/// When applying, if this not mentioned(None), current static DNS config
/// will be preserved as it was. If defined(Some), will override current
/// static DNS config.
pub config: Option<DnsClientState>,
}
impl DnsState {
/// [DnsState] with empty static DNS resolver config.
pub fn new() -> Self {
Self::default()
}
@ -71,10 +99,15 @@ impl DnsState {
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(deny_unknown_fields)]
/// DNS Client state
pub struct DnsClientState {
#[serde(skip_serializing_if = "Option::is_none")]
/// Name server IP address list.
/// To remove all existing servers, please use `Some(Vec::new())`.
pub server: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Search list for host-name lookup.
/// To remove all existing search, please use `Some(Vec::new())`.
pub search: Option<Vec<String>>,
#[serde(skip)]
// Lower is better

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
use std::collections::{hash_map::Entry, HashMap, HashSet};
use log::{debug, error};
@ -11,10 +13,42 @@ use crate::{
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(deny_unknown_fields)]
/// IP routing status
pub struct Routes {
#[serde(skip_serializing_if = "Option::is_none")]
/// Running effected routes containing route from universe or link scope,
/// and only from these protocols:
/// * boot (often used by `iproute` command)
/// * static
/// * ra
/// * dhcp
/// * mrouted
/// * keepalived
/// * babel
///
/// Ignored when applying.
pub running: Option<Vec<RouteEntry>>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Static routes containing route from universe or link scope,
/// and only from these protocols:
/// * boot (often used by `iproute` command)
/// * static
///
/// When applying, `None` means preserve current routes.
/// This property is not overriding but adding specified routes to
/// existing routes. To delete a route entry, please [RouteEntry.state] as
/// [RouteState::Absent]. Any property of absent [RouteEntry] set to
/// `None` means wildcard. For example, this [crate::NetworkState] could
/// remove all routes next hop to interface eth1(showing in yaml):
/// ```yaml
/// routes:
/// config:
/// - next-hop-interface: eth1
/// state: absent
/// ```
///
/// To change a route entry, you need to delete old one and add new one(can
/// be in single transaction).
pub config: Option<Vec<RouteEntry>>,
}
@ -23,6 +57,7 @@ impl Routes {
Self::default()
}
/// TODO: hide it, internal only
pub fn validate(&self) -> Result<(), NmstateError> {
// All desire non-absent route should have next hop interface
if let Some(config_routes) = self.config.as_ref() {
@ -160,6 +195,7 @@ impl Routes {
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum RouteState {
/// Mark a route entry as absent to remove it.
Absent,
}
@ -173,32 +209,43 @@ impl Default for RouteState {
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
#[serde(deny_unknown_fields)]
/// Route entry
pub struct RouteEntry {
#[serde(skip_serializing_if = "Option::is_none")]
/// Only used for delete route when applying.
pub state: Option<RouteState>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Route destination address or network
pub destination: Option<String>,
#[serde(
skip_serializing_if = "Option::is_none",
rename = "next-hop-interface"
)]
/// Route next hop interface name.
/// Serialize and deserialize to/from `next-hop-interface`.
pub next_hop_iface: Option<String>,
#[serde(
skip_serializing_if = "Option::is_none",
rename = "next-hop-address"
)]
/// Route next hop IP address.
/// Serialize and deserialize to/from `next-hop-address`.
pub next_hop_addr: Option<String>,
#[serde(
skip_serializing_if = "Option::is_none",
default,
deserialize_with = "crate::deserializer::option_i64_or_string"
)]
/// Route metric. [RouteEntry::USE_DEFAULT_METRIC] for default
/// setting of network backend.
pub metric: Option<i64>,
#[serde(
skip_serializing_if = "Option::is_none",
default,
deserialize_with = "crate::deserializer::option_u32_or_string"
)]
/// Route table id. [RouteEntry::USE_DEFAULT_ROUTE_TABLE] for main
/// route table 254.
pub table_id: Option<u32>,
}

View File

@ -11,8 +11,23 @@ use crate::{
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
#[non_exhaustive]
#[serde(deny_unknown_fields)]
/// Routing rules
pub struct RouteRules {
#[serde(skip_serializing_if = "Option::is_none")]
/// When applying, `None` means preserve existing route rules.
/// Nmstate is using partial editing for route rule, which means
/// desired route rules only append to existing instead of overriding.
/// To delete any route rule, please set [crate::RouteRuleEntry.state] to
/// [RouteRuleState::Absent]. Any property set to None in absent route rule
/// means wildcard. For example, this [crate::NetworkState] will delete all
/// route rule looking up route table 500:
/// ```yml
/// ---
/// route-rules:
/// config:
/// - state: absent
/// route-table: 500
/// ```
pub config: Option<Vec<RouteRuleEntry>>,
}
@ -34,6 +49,7 @@ impl RouteRules {
// * desired absent route rule is removed unless another matching rule been
// added.
// * desired static rule exists.
/// TODO: Hide it, internal use only
pub fn verify(&self, current: &Self) -> Result<(), NmstateError> {
if let Some(rules) = self.config.as_ref() {
let mut rules = rules.clone();
@ -191,6 +207,7 @@ impl RouteRules {
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum RouteRuleState {
/// Used for delete route rule
Absent,
}
@ -206,16 +223,23 @@ impl Default for RouteRuleState {
#[serde(deny_unknown_fields)]
pub struct RouteRuleEntry {
#[serde(skip_serializing_if = "Option::is_none")]
/// Indicate this is normal route rule or absent route rule.
pub state: Option<RouteRuleState>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Source prefix to match.
/// Serialize and deserialize to/from `ip-from`.
pub ip_from: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
/// Destination prefix to match.
/// Serialize and deserialize to/from `ip-to`.
pub ip_to: Option<String>,
#[serde(
skip_serializing_if = "Option::is_none",
default,
deserialize_with = "crate::deserializer::option_i64_or_string"
)]
/// Priority of this route rule.
/// Bigger number means lower priority.
pub priority: Option<i64>,
#[serde(
skip_serializing_if = "Option::is_none",
@ -223,6 +247,8 @@ pub struct RouteRuleEntry {
default,
deserialize_with = "crate::deserializer::option_u32_or_string"
)]
/// The routing table ID to lookup if the rule selector matches.
/// Serialize and deserialize to/from `route-table`.
pub table_id: Option<u32>,
#[serde(
skip_serializing_if = "Option::is_none",
@ -230,6 +256,7 @@ pub struct RouteRuleEntry {
deserialize_with = "crate::deserializer::option_u32_or_string",
serialize_with = "crate::serializer::option_u32_as_hex"
)]
/// Select the fwmark value to match
pub fwmark: Option<u32>,
#[serde(
skip_serializing_if = "Option::is_none",
@ -237,12 +264,16 @@ pub struct RouteRuleEntry {
deserialize_with = "crate::deserializer::option_u32_or_string",
serialize_with = "crate::serializer::option_u32_as_hex"
)]
/// Select the fwmask value to match
pub fwmask: Option<u32>,
}
impl RouteRuleEntry {
/// Let network backend choose the default priority.
pub const USE_DEFAULT_PRIORITY: i64 = -1;
/// Use main route table 254.
pub const USE_DEFAULT_ROUTE_TABLE: u32 = 0;
/// Default route table main(254).
pub const DEFAULR_ROUTE_TABLE_ID: u32 = 254;
pub fn new() -> Self {