Skip to main content

nmstate/nm/nm_dbus/gen_conf/
route_rule.rs

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