nmstate/nm/nm_dbus/gen_conf/
route_rule.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use log::warn;
4use std::collections::HashMap;
5
6use super::super::NmIpRouteRule;
7
8const DEFAULT_ROUTE_TABLE: u32 = 254;
9const AF_INET: i32 = 2;
10
11impl NmIpRouteRule {
12    pub(crate) fn to_keyfile(&self) -> HashMap<String, String> {
13        let mut ret = HashMap::new();
14        if let Some(priority) = self.priority.as_ref() {
15            let mut keys = Vec::new();
16            let prio_str = format!("priority {priority}");
17            keys.push(prio_str);
18
19            let to_str = match (self.to.as_ref(), self.to_len.as_ref()) {
20                (Some(t), Some(t_len)) => format!("to {t}/{t_len}"),
21                (Some(t), None) => format!("to {t}"),
22                _ => "".to_string(),
23            };
24            if !to_str.is_empty() {
25                keys.push(to_str);
26            }
27
28            let mut from_str =
29                match (self.from.as_ref(), self.from_len.as_ref()) {
30                    (Some(f), Some(f_len)) => format!("from {f}/{f_len}"),
31                    (Some(f), None) => format!("from {f}"),
32                    _ => "".to_string(),
33                };
34            from_str = if self.from.is_none() && self.to.is_none() {
35                if let Some(family) = self.family {
36                    if family == AF_INET {
37                        "from 0.0.0.0/0".to_string()
38                    } else {
39                        "from ::/0".to_string()
40                    }
41                } else {
42                    warn!(
43                        "Neither from, to or family specified on route rule. \
44                         Assuming IPv4."
45                    );
46                    "from 0.0.0.0/0".to_string()
47                }
48            } else {
49                from_str
50            };
51            if !from_str.is_empty() {
52                keys.push(from_str);
53            }
54            if let Some(iif) = self.iifname.as_ref() {
55                keys.push(format!("iif {iif}"));
56            }
57            if let Some(v) = self.suppress_prefixlength {
58                keys.push(format!("suppress_prefixlength {v}"));
59            }
60            if let Some(action) = self.action.as_ref() {
61                keys.push(format!("type {action}"));
62            }
63
64            let mut table_str = format!("table {DEFAULT_ROUTE_TABLE}");
65            if let Some(table) = self.table {
66                table_str = format!("table {table}");
67            }
68            keys.push(table_str);
69
70            let fwmark_line = match (self.fw_mark, self.fw_mask) {
71                (Some(mark), Some(mask)) => format!("fwmark {mark}/{mask}"),
72                (Some(mark), None) => format!("fwmark {mark}"),
73                _ => "".to_string(),
74            };
75            if !fwmark_line.is_empty() {
76                keys.push(fwmark_line);
77            }
78
79            let rl_line = keys.join(" ");
80            ret.insert("".to_string(), rl_line);
81        }
82        ret
83    }
84}