File wicked2nm-1.2.1.obscpio of Package wicked2nm

07070100000000000081A4000000000000000000000001689C733A0000CE53000000000000000000000000000000000000001B00000000wicked2nm-1.2.1/Cargo.lock# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4

[[package]]
name = "addr2line"
version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
dependencies = [
 "gimli",
]

[[package]]
name = "adler2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"

[[package]]
name = "agama-network"
version = "0.1.0"
source = "git+https://github.com/agama-project/agama#06c86349b1785aaad1074582d030e86f6c6ef88d"
dependencies = [
 "agama-utils",
 "anyhow",
 "async-trait",
 "cidr",
 "futures-util",
 "macaddr",
 "pin-project",
 "semver",
 "serde",
 "serde_with",
 "strum 0.27.2",
 "thiserror",
 "tokio",
 "tokio-stream",
 "tokio-test",
 "tracing",
 "utoipa",
 "uuid",
 "zbus",
]

[[package]]
name = "agama-utils"
version = "0.1.0"
source = "git+https://github.com/agama-project/agama#06c86349b1785aaad1074582d030e86f6c6ef88d"
dependencies = [
 "serde_json",
 "utoipa",
 "zbus",
 "zvariant",
]

[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
 "memchr",
]

[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"

[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
 "libc",
]

[[package]]
name = "anstream"
version = "0.6.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
dependencies = [
 "anstyle",
 "anstyle-parse",
 "anstyle-query",
 "anstyle-wincon",
 "colorchoice",
 "is_terminal_polyfill",
 "utf8parse",
]

[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"

[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
 "utf8parse",
]

[[package]]
name = "anstyle-query"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
dependencies = [
 "windows-sys 0.59.0",
]

[[package]]
name = "anstyle-wincon"
version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
dependencies = [
 "anstyle",
 "once_cell_polyfill",
 "windows-sys 0.59.0",
]

[[package]]
name = "anyhow"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"

[[package]]
name = "async-broadcast"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
dependencies = [
 "event-listener",
 "event-listener-strategy",
 "futures-core",
 "pin-project-lite",
]

[[package]]
name = "async-channel"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
dependencies = [
 "concurrent-queue",
 "event-listener-strategy",
 "futures-core",
 "pin-project-lite",
]

[[package]]
name = "async-executor"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa"
dependencies = [
 "async-task",
 "concurrent-queue",
 "fastrand",
 "futures-lite",
 "pin-project-lite",
 "slab",
]

[[package]]
name = "async-io"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca"
dependencies = [
 "async-lock",
 "cfg-if",
 "concurrent-queue",
 "futures-io",
 "futures-lite",
 "parking",
 "polling",
 "rustix",
 "slab",
 "windows-sys 0.60.2",
]

[[package]]
name = "async-lock"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
dependencies = [
 "event-listener",
 "event-listener-strategy",
 "pin-project-lite",
]

[[package]]
name = "async-process"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65daa13722ad51e6ab1a1b9c01299142bc75135b337923cfa10e79bbbd669f00"
dependencies = [
 "async-channel",
 "async-io",
 "async-lock",
 "async-signal",
 "async-task",
 "blocking",
 "cfg-if",
 "event-listener",
 "futures-lite",
 "rustix",
]

[[package]]
name = "async-recursion"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "async-signal"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f567af260ef69e1d52c2b560ce0ea230763e6fbb9214a85d768760a920e3e3c1"
dependencies = [
 "async-io",
 "async-lock",
 "atomic-waker",
 "cfg-if",
 "futures-core",
 "futures-io",
 "rustix",
 "signal-hook-registry",
 "slab",
 "windows-sys 0.60.2",
]

[[package]]
name = "async-stream"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
dependencies = [
 "async-stream-impl",
 "futures-core",
 "pin-project-lite",
]

[[package]]
name = "async-stream-impl"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "async-task"
version = "4.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"

[[package]]
name = "async-trait"
version = "0.1.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"

[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"

[[package]]
name = "backtrace"
version = "0.3.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
dependencies = [
 "addr2line",
 "cfg-if",
 "libc",
 "miniz_oxide",
 "object",
 "rustc-demangle",
 "windows-targets 0.52.6",
]

[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"

[[package]]
name = "bitflags"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"

[[package]]
name = "blocking"
version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
dependencies = [
 "async-channel",
 "async-task",
 "futures-io",
 "futures-lite",
 "piper",
]

[[package]]
name = "bstr"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
dependencies = [
 "memchr",
 "serde",
]

[[package]]
name = "bumpalo"
version = "3.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"

[[package]]
name = "bytes"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"

[[package]]
name = "cc"
version = "1.2.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
dependencies = [
 "shlex",
]

[[package]]
name = "cfg-if"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"

[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"

[[package]]
name = "chrono"
version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
dependencies = [
 "android-tzdata",
 "iana-time-zone",
 "num-traits",
 "serde",
 "windows-link",
]

[[package]]
name = "cidr"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd1b64030216239a2e7c364b13cd96a2097ebf0dfe5025f2dedee14a23f2ab60"
dependencies = [
 "serde",
]

[[package]]
name = "clap"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
dependencies = [
 "clap_builder",
 "clap_derive",
]

[[package]]
name = "clap_builder"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
dependencies = [
 "anstream",
 "anstyle",
 "clap_lex",
 "strsim",
 "terminal_size",
]

[[package]]
name = "clap_derive"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
dependencies = [
 "heck 0.5.0",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "clap_lex"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"

[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"

[[package]]
name = "concurrent-queue"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
 "crossbeam-utils",
]

[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"

[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"

[[package]]
name = "darling"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
dependencies = [
 "darling_core",
 "darling_macro",
]

[[package]]
name = "darling_core"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
dependencies = [
 "fnv",
 "ident_case",
 "proc-macro2",
 "quote",
 "strsim",
 "syn",
]

[[package]]
name = "darling_macro"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
 "darling_core",
 "quote",
 "syn",
]

[[package]]
name = "deranged"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
dependencies = [
 "powerfmt",
 "serde",
]

[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"

[[package]]
name = "dyn-clone"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005"

[[package]]
name = "endi"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"

[[package]]
name = "enumflags2"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
dependencies = [
 "enumflags2_derive",
 "serde",
]

[[package]]
name = "enumflags2_derive"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"

[[package]]
name = "errno"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [
 "libc",
 "windows-sys 0.60.2",
]

[[package]]
name = "event-listener"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae"
dependencies = [
 "concurrent-queue",
 "parking",
 "pin-project-lite",
]

[[package]]
name = "event-listener-strategy"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
dependencies = [
 "event-listener",
 "pin-project-lite",
]

[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"

[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"

[[package]]
name = "futures-core"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"

[[package]]
name = "futures-io"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"

[[package]]
name = "futures-lite"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532"
dependencies = [
 "fastrand",
 "futures-core",
 "futures-io",
 "parking",
 "pin-project-lite",
]

[[package]]
name = "futures-task"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"

[[package]]
name = "futures-util"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
 "futures-core",
 "futures-task",
 "pin-project-lite",
 "pin-utils",
]

[[package]]
name = "getrandom"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
 "cfg-if",
 "libc",
 "r-efi",
 "wasi 0.14.2+wasi-0.2.4",
]

[[package]]
name = "gimli"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"

[[package]]
name = "globset"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5"
dependencies = [
 "aho-corasick",
 "bstr",
 "regex-automata",
 "regex-syntax",
]

[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"

[[package]]
name = "hashbrown"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"

[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"

[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"

[[package]]
name = "hermit-abi"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"

[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"

[[package]]
name = "iana-time-zone"
version = "0.1.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
dependencies = [
 "android_system_properties",
 "core-foundation-sys",
 "iana-time-zone-haiku",
 "js-sys",
 "log",
 "wasm-bindgen",
 "windows-core",
]

[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
 "cc",
]

[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"

[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
 "autocfg",
 "hashbrown 0.12.3",
 "serde",
]

[[package]]
name = "indexmap"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
dependencies = [
 "equivalent",
 "hashbrown 0.15.4",
 "serde",
]

[[package]]
name = "io-uring"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
dependencies = [
 "bitflags",
 "cfg-if",
 "libc",
]

[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"

[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"

[[package]]
name = "js-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
 "once_cell",
 "wasm-bindgen",
]

[[package]]
name = "libc"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"

[[package]]
name = "linux-raw-sys"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"

[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"

[[package]]
name = "macaddr"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baee0bbc17ce759db233beb01648088061bf678383130602a298e6998eedb2d8"
dependencies = [
 "serde",
]

[[package]]
name = "memchr"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"

[[package]]
name = "memoffset"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
 "autocfg",
]

[[package]]
name = "miniz_oxide"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [
 "adler2",
]

[[package]]
name = "mio"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
dependencies = [
 "libc",
 "wasi 0.11.1+wasi-snapshot-preview1",
 "windows-sys 0.59.0",
]

[[package]]
name = "nix"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
 "bitflags",
 "cfg-if",
 "cfg_aliases",
 "libc",
 "memoffset",
]

[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"

[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
 "autocfg",
]

[[package]]
name = "num_threads"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
dependencies = [
 "libc",
]

[[package]]
name = "object"
version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
 "memchr",
]

[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"

[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"

[[package]]
name = "ordered-stream"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
dependencies = [
 "futures-core",
 "pin-project-lite",
]

[[package]]
name = "parking"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"

[[package]]
name = "pin-project"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
dependencies = [
 "pin-project-internal",
]

[[package]]
name = "pin-project-internal"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"

[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"

[[package]]
name = "piper"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
dependencies = [
 "atomic-waker",
 "fastrand",
 "futures-io",
]

[[package]]
name = "polling"
version = "3.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ee9b2fa7a4517d2c91ff5bc6c297a427a96749d15f98fcdbb22c05571a4d4b7"
dependencies = [
 "cfg-if",
 "concurrent-queue",
 "hermit-abi",
 "pin-project-lite",
 "rustix",
 "windows-sys 0.60.2",
]

[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"

[[package]]
name = "proc-macro-crate"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35"
dependencies = [
 "toml_edit",
]

[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
 "unicode-ident",
]

[[package]]
name = "quick-xml"
version = "0.28.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1"
dependencies = [
 "memchr",
 "serde",
]

[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
 "proc-macro2",
]

[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"

[[package]]
name = "ref-cast"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf"
dependencies = [
 "ref-cast-impl",
]

[[package]]
name = "ref-cast-impl"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
 "aho-corasick",
 "memchr",
 "regex-automata",
 "regex-syntax",
]

[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
 "aho-corasick",
 "memchr",
 "regex-syntax",
]

[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"

[[package]]
name = "rustc-demangle"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"

[[package]]
name = "rustix"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
dependencies = [
 "bitflags",
 "errno",
 "libc",
 "linux-raw-sys",
 "windows-sys 0.60.2",
]

[[package]]
name = "rustversion"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"

[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"

[[package]]
name = "schemars"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f"
dependencies = [
 "dyn-clone",
 "ref-cast",
 "serde",
 "serde_json",
]

[[package]]
name = "schemars"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0"
dependencies = [
 "dyn-clone",
 "ref-cast",
 "serde",
 "serde_json",
]

[[package]]
name = "semver"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"

[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
 "serde_derive",
]

[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "serde_ignored"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b516445dac1e3535b6d658a7b528d771153dfb272ed4180ca4617a20550365ff"
dependencies = [
 "serde",
]

[[package]]
name = "serde_json"
version = "1.0.141"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
dependencies = [
 "itoa",
 "memchr",
 "ryu",
 "serde",
]

[[package]]
name = "serde_path_to_error"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
dependencies = [
 "itoa",
 "serde",
]

[[package]]
name = "serde_repr"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "serde_with"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5"
dependencies = [
 "base64",
 "chrono",
 "hex",
 "indexmap 1.9.3",
 "indexmap 2.10.0",
 "schemars 0.9.0",
 "schemars 1.0.4",
 "serde",
 "serde_derive",
 "serde_json",
 "serde_with_macros",
 "time",
]

[[package]]
name = "serde_with_macros"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f"
dependencies = [
 "darling",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
 "indexmap 2.10.0",
 "itoa",
 "ryu",
 "serde",
 "unsafe-libyaml",
]

[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"

[[package]]
name = "signal-hook-registry"
version = "1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
dependencies = [
 "libc",
]

[[package]]
name = "simplelog"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0"
dependencies = [
 "log",
 "termcolor",
 "time",
]

[[package]]
name = "slab"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"

[[package]]
name = "socket2"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
 "libc",
 "windows-sys 0.52.0",
]

[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"

[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"

[[package]]
name = "strum"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"

[[package]]
name = "strum"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
dependencies = [
 "strum_macros 0.27.2",
]

[[package]]
name = "strum_macros"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
dependencies = [
 "heck 0.4.1",
 "proc-macro2",
 "quote",
 "rustversion",
 "syn",
]

[[package]]
name = "strum_macros"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
dependencies = [
 "heck 0.5.0",
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "syn"
version = "2.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
dependencies = [
 "proc-macro2",
 "quote",
 "unicode-ident",
]

[[package]]
name = "tempfile"
version = "3.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
dependencies = [
 "fastrand",
 "getrandom",
 "once_cell",
 "rustix",
 "windows-sys 0.59.0",
]

[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
 "winapi-util",
]

[[package]]
name = "terminal_size"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed"
dependencies = [
 "rustix",
 "windows-sys 0.59.0",
]

[[package]]
name = "thiserror"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
 "thiserror-impl",
]

[[package]]
name = "thiserror-impl"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "time"
version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
dependencies = [
 "deranged",
 "itoa",
 "libc",
 "num-conv",
 "num_threads",
 "powerfmt",
 "serde",
 "time-core",
 "time-macros",
]

[[package]]
name = "time-core"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"

[[package]]
name = "time-macros"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
dependencies = [
 "num-conv",
 "time-core",
]

[[package]]
name = "tokio"
version = "1.46.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
dependencies = [
 "backtrace",
 "bytes",
 "io-uring",
 "libc",
 "mio",
 "pin-project-lite",
 "signal-hook-registry",
 "slab",
 "socket2",
 "tokio-macros",
 "tracing",
 "windows-sys 0.52.0",
]

[[package]]
name = "tokio-macros"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "tokio-stream"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
dependencies = [
 "futures-core",
 "pin-project-lite",
 "tokio",
]

[[package]]
name = "tokio-test"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7"
dependencies = [
 "async-stream",
 "bytes",
 "futures-core",
 "tokio",
 "tokio-stream",
]

[[package]]
name = "toml_datetime"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"

[[package]]
name = "toml_edit"
version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
 "indexmap 2.10.0",
 "toml_datetime",
 "winnow",
]

[[package]]
name = "tracing"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
 "pin-project-lite",
 "tracing-attributes",
 "tracing-core",
]

[[package]]
name = "tracing-attributes"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "tracing-core"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
dependencies = [
 "once_cell",
]

[[package]]
name = "uds_windows"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
dependencies = [
 "memoffset",
 "tempfile",
 "winapi",
]

[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"

[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"

[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"

[[package]]
name = "utoipa"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fcc29c80c21c31608227e0912b2d7fddba57ad76b606890627ba8ee7964e993"
dependencies = [
 "indexmap 2.10.0",
 "serde",
 "serde_json",
 "utoipa-gen",
]

[[package]]
name = "utoipa-gen"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d79d08d92ab8af4c5e8a6da20c47ae3f61a0f1dabc1997cdf2d082b757ca08b"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
 "uuid",
]

[[package]]
name = "uuid"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
dependencies = [
 "getrandom",
 "js-sys",
 "serde",
 "wasm-bindgen",
]

[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"

[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
 "wit-bindgen-rt",
]

[[package]]
name = "wasm-bindgen"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
 "cfg-if",
 "once_cell",
 "rustversion",
 "wasm-bindgen-macro",
]

[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
 "bumpalo",
 "log",
 "proc-macro2",
 "quote",
 "syn",
 "wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
 "quote",
 "wasm-bindgen-macro-support",
]

[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
 "wasm-bindgen-backend",
 "wasm-bindgen-shared",
]

[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
 "unicode-ident",
]

[[package]]
name = "wicked2nm"
version = "1.1.0"
dependencies = [
 "agama-network",
 "anyhow",
 "cidr",
 "clap",
 "dotenv",
 "globset",
 "log",
 "macaddr",
 "quick-xml",
 "regex",
 "serde",
 "serde_ignored",
 "serde_json",
 "serde_path_to_error",
 "serde_with",
 "serde_yaml",
 "simplelog",
 "strum 0.25.0",
 "strum_macros 0.25.3",
 "tokio",
 "uuid",
]

[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
 "winapi-i686-pc-windows-gnu",
 "winapi-x86_64-pc-windows-gnu",
]

[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"

[[package]]
name = "winapi-util"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
 "windows-sys 0.59.0",
]

[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

[[package]]
name = "windows-core"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
 "windows-implement",
 "windows-interface",
 "windows-link",
 "windows-result",
 "windows-strings",
]

[[package]]
name = "windows-implement"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "windows-link"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"

[[package]]
name = "windows-result"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
 "windows-link",
]

[[package]]
name = "windows-strings"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
 "windows-link",
]

[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
 "windows-targets 0.52.6",
]

[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
 "windows-targets 0.52.6",
]

[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
 "windows-targets 0.53.2",
]

[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
 "windows_aarch64_gnullvm 0.52.6",
 "windows_aarch64_msvc 0.52.6",
 "windows_i686_gnu 0.52.6",
 "windows_i686_gnullvm 0.52.6",
 "windows_i686_msvc 0.52.6",
 "windows_x86_64_gnu 0.52.6",
 "windows_x86_64_gnullvm 0.52.6",
 "windows_x86_64_msvc 0.52.6",
]

[[package]]
name = "windows-targets"
version = "0.53.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
dependencies = [
 "windows_aarch64_gnullvm 0.53.0",
 "windows_aarch64_msvc 0.53.0",
 "windows_i686_gnu 0.53.0",
 "windows_i686_gnullvm 0.53.0",
 "windows_i686_msvc 0.53.0",
 "windows_x86_64_gnu 0.53.0",
 "windows_x86_64_gnullvm 0.53.0",
 "windows_x86_64_msvc 0.53.0",
]

[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"

[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"

[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"

[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"

[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"

[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"

[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"

[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"

[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"

[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"

[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"

[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"

[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"

[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"

[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"

[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"

[[package]]
name = "winnow"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
dependencies = [
 "memchr",
]

[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
 "bitflags",
]

[[package]]
name = "zbus"
version = "5.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bb4f9a464286d42851d18a605f7193b8febaf5b0919d71c6399b7b26e5b0aad"
dependencies = [
 "async-broadcast",
 "async-executor",
 "async-io",
 "async-lock",
 "async-process",
 "async-recursion",
 "async-task",
 "async-trait",
 "blocking",
 "enumflags2",
 "event-listener",
 "futures-core",
 "futures-lite",
 "hex",
 "nix",
 "ordered-stream",
 "serde",
 "serde_repr",
 "tokio",
 "tracing",
 "uds_windows",
 "windows-sys 0.59.0",
 "winnow",
 "zbus_macros",
 "zbus_names",
 "zvariant",
]

[[package]]
name = "zbus_macros"
version = "5.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef9859f68ee0c4ee2e8cde84737c78e3f4c54f946f2a38645d0d4c7a95327659"
dependencies = [
 "proc-macro-crate",
 "proc-macro2",
 "quote",
 "syn",
 "zbus_names",
 "zvariant",
 "zvariant_utils",
]

[[package]]
name = "zbus_names"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97"
dependencies = [
 "serde",
 "static_assertions",
 "winnow",
 "zvariant",
]

[[package]]
name = "zvariant"
version = "5.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91b3680bb339216abd84714172b5138a4edac677e641ef17e1d8cb1b3ca6e6f"
dependencies = [
 "endi",
 "enumflags2",
 "serde",
 "winnow",
 "zvariant_derive",
 "zvariant_utils",
]

[[package]]
name = "zvariant_derive"
version = "5.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a8c68501be459a8dbfffbe5d792acdd23b4959940fc87785fb013b32edbc208"
dependencies = [
 "proc-macro-crate",
 "proc-macro2",
 "quote",
 "syn",
 "zvariant_utils",
]

[[package]]
name = "zvariant_utils"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34"
dependencies = [
 "proc-macro2",
 "quote",
 "serde",
 "static_assertions",
 "syn",
 "winnow",
]
07070100000001000081A4000000000000000000000001689C733A000003CF000000000000000000000000000000000000001B00000000wicked2nm-1.2.1/Cargo.toml[package]
name = "wicked2nm"
version = "1.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.91"
serde_yaml = "0.9.17"
quick-xml = { version = "0.28.2", features = ["serialize"] }
agama-network = { git = "https://github.com/agama-project/agama" }
regex = "1.9.5"
cidr = { version = "0.3.1", features = ["serde"] }
clap = { version = "4.1.4", features = ["derive", "wrap_help", "env"] }
anyhow = "1.0.71"
log = "0.4"
simplelog = "0.12.1"
strum = "0.25.0"
strum_macros = "0.25.2"
serde_with = "3.3.0"
tokio = { version = "1.44.2", features = ["macros", "rt-multi-thread"] }
serde_ignored = "0.1.9"
uuid = { version = "1.3.4", features = ["v4"] }
macaddr = "1.0"
dotenv = "0.15.0"
serde_path_to_error = "0.1.16"
globset = { version = "0.4.16", default-features = false }

[[bin]]
name = "wicked2nm"
path = "src/main.rs"
07070100000002000081A4000000000000000000000001689C733A000046AC000000000000000000000000000000000000001800000000wicked2nm-1.2.1/LICENSE                    GNU GENERAL PUBLIC LICENSE
                       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

                    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

                            NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) year name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.

  <signature of Ty Coon>, 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
07070100000003000081A4000000000000000000000001689C733A0000098E000000000000000000000000000000000000001A00000000wicked2nm-1.2.1/README.md# Wicked to NetworkManager migration
This project creates a `wicked2nm` binary which is able to parse wicked xml
configs and send them to a NetworkManager dbus service.
## Installation
`wicked2nm` is available in openSUSE tumbleweed `zypper in wicked2nm`.

There is also a package that includes all the latest changes available at
https://build.opensuse.org/package/show/home:jcronenberg:migrate-wicked/wicked2nm.
## Usage
### On system
If both `wicked` and `NetworkManager` are available `wicked2nm` can be run on the system directly simply with:
```bash
wicked show-config > wicked.xml
wicked2nm migrate wicked.xml
```
More detailed instructions how a migration can work here:
```bash
# NetworkManager-config-server is required as otherwise NM will immediately add connections for all interfaces, resulting in duplicates.
# NetworkManager-config-server can be removed after the migration is done.
zypper in wicked2nm NetworkManager NetworkManager-config-server
# If NetworkManager-config-server is not available you can also manually add the drop-in configuration.
echo -e "[main]\nno-auto-default=*" > /etc/NetworkManager/conf.d/10-server.conf

# You can test beforehand whether there are errors or warnings.
wicked show-config | wicked2nm migrate --dry-run -

# WARNING: Run this as root, wicked will shut down the interfaces and they will only come up again once the migration is done.
# This oneliner shuts down wicked, starts NM and runs the migration, if anything went wrong it starts wicked again.
systemctl disable --now wicked \
    && (systemctl enable --now NetworkManager && wicked show-config | wicked2nm migrate --continue-migration --activate-connections -) \
    || (systemctl disable --now NetworkManager; systemctl enable --now wicked)
```
### Via container
`wicked2nm` can also be run via a container.
```bash
podman run -v /etc/sysconfig/network:/etc/sysconfig/network registry.opensuse.org/home/jcronenberg/migrate-wicked/containers/opensuse/wicked2nm:latest
```
This will create `*.nmconnection` files inside `/etc/sysconfig/network/NM-migrated`.  
See also the [Container's README](https://build.opensuse.org/projects/home:jcronenberg:migrate-wicked/packages/wicked2nm-container/files/README?expand=1)
for further infos.
## Architecture
`wicked2nm` uses agama as a library to communicate the parsed network state to NetworkManager
but the binary is completely independent of any agama services and can be run standalone.
07070100000004000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001400000000wicked2nm-1.2.1/src07070100000005000081A4000000000000000000000001689C733A00003728000000000000000000000000000000000000001C00000000wicked2nm-1.2.1/src/bond.rsuse agama_network::model::{self};
use agama_network::types::BondMode as AgamaBondMode;
use serde::{Deserialize, Deserializer, Serialize};
use serde_with::{skip_serializing_none, DeserializeFromStr, SerializeDisplay};
use std::collections::HashMap;
use strum_macros::{Display, EnumString};

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab_case")]
pub enum FailOverMac {
    None,
    Active,
    Follow,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab_case")]
pub enum XmitHashPolicy {
    Layer2,
    Layer23,
    Layer34,
    Encap23,
    Encap34,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab_case")]
pub enum LacpRate {
    Slow,
    Fast,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab_case")]
pub enum AdSelect {
    Stable,
    Bandwidth,
    Count,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab_case")]
pub enum PrimaryReselect {
    Always,
    Better,
    Failure,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab_case")]
pub enum WickedBondMode {
    BalanceRr = 0,
    ActiveBackup,
    BalanceXor,
    Broadcast,
    #[strum(serialize = "ieee802-3ad")]
    IEEE8023ad,
    BalanceTlb,
    BalanceAlb,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Bond {
    pub mode: WickedBondMode,
    pub miimon: Option<Miimon>,
    pub arpmon: Option<ArpMon>,
    /* only on mode=[802.3ad, balance_xor] */
    pub xmit_hash_policy: Option<XmitHashPolicy>,
    /* only on mode=balance_rr */
    pub packets_per_slave: Option<u32>,
    /* only on mode=balance_tlb */
    pub tlb_dynamic_lb: Option<bool>,
    /* only on mode=802.3ad */
    pub lacp_rate: Option<LacpRate>,
    /* only on mode=802.3ad */
    pub ad_select: Option<AdSelect>,
    /* only on mode=802.3ad */
    pub ad_user_port_key: Option<u32>,
    /* only on mode=802.3ad */
    pub ad_actor_sys_prio: Option<u32>,
    /* only on mode=802.3ad */
    pub ad_actor_system: Option<String>,
    /* only on mode=802.3ad */
    pub min_links: Option<u32>,
    /* only on mode=active-backup */
    pub primary_reselect: Option<PrimaryReselect>,
    /* only on mode=active-backup */
    pub fail_over_mac: Option<FailOverMac>,
    /* only on mode=active-backup */
    pub num_grat_arp: Option<u32>,
    /* only on mode=active-backup */
    pub num_unsol_na: Option<u32>,
    /* only on mode=[balance_tlb|balance_alb] */
    pub lp_interval: Option<u32>,
    /* only on mode=[active-backup|balance_tlb|balance_alb] */
    pub primary: Option<String>,
    /* only on mode=[balance_tlb|balance_alb|balance_RR|active-backup] */
    pub resend_igmp: Option<u32>,
    pub all_slaves_active: Option<bool>,
    pub address: Option<String>,
}

#[derive(Debug, PartialEq, Default, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab_case")]
pub enum CarrierDetect {
    Ioctl = 0,
    #[default]
    Netif = 1,
}

#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Miimon {
    pub frequency: u32,
    #[serde(rename = "carrier-detect")]
    pub carrier_detect: CarrierDetect,
    pub downdelay: Option<u32>,
    pub updelay: Option<u32>,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab_case")]
pub enum ArpValidateTargets {
    Any = 0,
    All = 1,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "snake_case")]
pub enum ArpValidate {
    None = 0,
    Active = 1,
    Backup = 2,
    All = 3,
    Filter = 4,
    FilterActive = 5,
    FilterBackup = 6,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct ArpMon {
    pub interval: u32,
    pub validate: ArpValidate,
    #[serde(rename = "validate-targets")]
    pub validate_targets: Option<ArpValidateTargets>,
    #[serde(deserialize_with = "unwrap_arpmon_targets")]
    pub targets: Vec<String>,
}

fn unwrap_arpmon_targets<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
    D: Deserializer<'de>,
{
    #[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
    pub struct ArpMonTargetAddressV4 {
        #[serde(rename = "ipv4-address")]
        pub ipv4_address: Vec<String>,
    }
    Ok(ArpMonTargetAddressV4::deserialize(deserializer)?.ipv4_address)
}

impl From<&WickedBondMode> for AgamaBondMode {
    fn from(bondmode: &WickedBondMode) -> AgamaBondMode {
        match bondmode {
            WickedBondMode::BalanceRr => AgamaBondMode::RoundRobin,
            WickedBondMode::ActiveBackup => AgamaBondMode::ActiveBackup,
            WickedBondMode::BalanceXor => AgamaBondMode::BalanceXOR,
            WickedBondMode::Broadcast => AgamaBondMode::Broadcast,
            WickedBondMode::IEEE8023ad => AgamaBondMode::LACP,
            WickedBondMode::BalanceTlb => AgamaBondMode::BalanceTLB,
            WickedBondMode::BalanceAlb => AgamaBondMode::BalanceALB,
        }
    }
}

impl XmitHashPolicy {
    fn to_agama(&self) -> String {
        match self {
            XmitHashPolicy::Layer2 => String::from("layer2"),
            XmitHashPolicy::Layer23 => String::from("layer2+3"),
            XmitHashPolicy::Layer34 => String::from("layer3+4"),
            XmitHashPolicy::Encap23 => String::from("encap2+3"),
            XmitHashPolicy::Encap34 => String::from("encap3+4"),
        }
    }
}

impl From<&Bond> for model::ConnectionConfig {
    fn from(bond: &Bond) -> model::ConnectionConfig {
        let mut h: HashMap<String, String> = HashMap::new();

        if let Some(p) = &bond.primary {
            h.insert(String::from("primary"), p.clone());
        }

        if let Some(m) = &bond.miimon {
            h.insert(String::from("miimon"), format!("{}", m.frequency));
            h.insert(
                String::from("use_carrier"),
                match m.carrier_detect {
                    CarrierDetect::Ioctl => 0,
                    CarrierDetect::Netif => 1,
                }
                .to_string(),
            );
            if let Some(v) = m.downdelay {
                h.insert(String::from("downdelay"), v.to_string());
            }
            if let Some(v) = m.updelay {
                h.insert(String::from("updelay"), v.to_string());
            }
        }

        if let Some(a) = &bond.arpmon {
            h.insert(String::from("arp_interval"), format!("{}", a.interval));
            h.insert(String::from("arp_validate"), a.validate.to_string());

            if !a.targets.is_empty() {
                let sv = a
                    .targets
                    .iter()
                    .map(|c| c.as_ref())
                    .collect::<Vec<&str>>()
                    .join(",");
                h.insert(String::from("arp_ip_target"), sv);
            }

            if let Some(v) = &a.validate_targets {
                h.insert(String::from("arp_all_targets"), v.to_string());
            }
        }

        if let Some(fom) = &bond.fail_over_mac {
            h.insert(String::from("fail_over_mac"), fom.to_string());
        }

        if let Some(v) = &bond.xmit_hash_policy {
            h.insert(String::from("xmit_hash_policy"), v.to_agama());
        }

        if let Some(v) = &bond.packets_per_slave {
            h.insert(String::from("packets_per_slave"), v.to_string());
        }

        if let Some(v) = &bond.tlb_dynamic_lb {
            h.insert(
                String::from("tlb_dynamic_lb"),
                if *v { 1.to_string() } else { 0.to_string() },
            );
        }

        if let Some(v) = &bond.lacp_rate {
            h.insert(String::from("lacp_rate"), v.to_string());
        }

        if let Some(v) = &bond.ad_select {
            h.insert(String::from("ad_select"), v.to_string());
        }
        if let Some(v) = &bond.ad_user_port_key {
            h.insert(String::from("ad_user_port_key"), v.to_string());
        }
        if let Some(v) = &bond.ad_actor_sys_prio {
            h.insert(String::from("ad_actor_sys_prio"), v.to_string());
        }
        if let Some(v) = &bond.ad_actor_system {
            h.insert(String::from("ad_actor_system"), v.clone());
        }
        if let Some(v) = &bond.min_links {
            h.insert(String::from("min_links"), v.to_string());
        }
        if let Some(v) = &bond.primary_reselect {
            h.insert(String::from("primary_reselect"), v.to_string());
        }
        if let Some(v) = &bond.num_grat_arp {
            h.insert(String::from("num_grat_arp"), v.to_string());
        }
        if let Some(v) = &bond.num_unsol_na {
            h.insert(String::from("num_unsol_na"), v.to_string());
        }
        if let Some(v) = &bond.lp_interval {
            h.insert(String::from("lp_interval"), v.to_string());
        }
        if let Some(v) = &bond.resend_igmp {
            h.insert(String::from("resend_igmp"), v.to_string());
        }
        if let Some(v) = &bond.all_slaves_active {
            h.insert(
                String::from("all_slaves_active"),
                if *v { 1.to_string() } else { 0.to_string() },
            );
        }

        model::ConnectionConfig::Bond(model::BondConfig {
            options: model::BondOptions(h),
            mode: AgamaBondMode::from(&bond.mode),
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::interface::*;
    use crate::MIGRATION_SETTINGS;

    #[allow(dead_code)]
    fn setup_default_migration_settings() {
        let _ = MIGRATION_SETTINGS.set(crate::MigrationSettings::default());
    }

    #[test]
    fn test_bond_options() {
        setup_default_migration_settings();
        let bond_interface = Interface {
            bond: Some(Bond {
                mode: WickedBondMode::IEEE8023ad,
                xmit_hash_policy: Some(XmitHashPolicy::Encap34),
                fail_over_mac: Some(FailOverMac::Active),
                packets_per_slave: Some(23),
                tlb_dynamic_lb: Some(true),
                lacp_rate: Some(LacpRate::Slow),
                ad_select: Some(AdSelect::Bandwidth),
                ad_user_port_key: Some(42),
                ad_actor_sys_prio: Some(5),
                ad_actor_system: Some(String::from("00:de:ad:be:ef:00")),
                min_links: Some(3),
                primary_reselect: Some(PrimaryReselect::Better),
                num_grat_arp: Some(7),
                num_unsol_na: Some(13),
                lp_interval: Some(17),
                resend_igmp: Some(19),
                all_slaves_active: Some(true),
                miimon: Some(Miimon {
                    frequency: 42,
                    carrier_detect: CarrierDetect::Netif,
                    downdelay: Some(23),
                    updelay: Some(5),
                }),
                arpmon: Some(ArpMon {
                    interval: 23,
                    validate: ArpValidate::FilterBackup,
                    validate_targets: Some(ArpValidateTargets::Any),
                    targets: vec![String::from("1.2.3.4"), String::from("4.3.2.1")],
                }),
                address: Some(String::from("02:11:22:33:44:55")),
                primary: Some(String::from("en0")),
            }),
            ..Default::default()
        };

        let connection: &model::Connection =
            &bond_interface.to_connection(&None).unwrap().connections[0];
        assert!(matches!(
            connection.config,
            model::ConnectionConfig::Bond(_)
        ));
        assert_eq!(
            connection.custom_mac_address.to_string(),
            "02:11:22:33:44:55"
        );

        if let model::ConnectionConfig::Bond(bond) = &connection.config {
            assert_eq!(bond.mode, AgamaBondMode::LACP);
            let s = HashMap::from([
                ("xmit_hash_policy", String::from("encap3+4")),
                ("packets_per_slave", 23.to_string()),
                ("tlb_dynamic_lb", 1.to_string()),
                ("lacp_rate", String::from("slow")),
                ("ad_select", String::from("bandwidth")),
                ("ad_user_port_key", 42.to_string()),
                ("ad_actor_sys_prio", 5.to_string()),
                ("ad_actor_system", String::from("00:de:ad:be:ef:00")),
                ("min_links", 3.to_string()),
                ("primary_reselect", String::from("better")),
                ("fail_over_mac", String::from("active")),
                ("num_grat_arp", 7.to_string()),
                ("num_unsol_na", 13.to_string()),
                ("lp_interval", 17.to_string()),
                ("resend_igmp", 19.to_string()),
                ("all_slaves_active", 1.to_string()),
                // miimon
                ("miimon", 42.to_string()),
                ("use_carrier", 1.to_string()),
                ("downdelay", 23.to_string()),
                ("updelay", 5.to_string()),
                // arpmon
                ("arp_validate", String::from("filter_backup")),
                ("arp_all_targets", String::from("any")),
                ("arp_ip_target", String::from("1.2.3.4,4.3.2.1")),
                ("arp_interval", 23.to_string()),
                ("primary", String::from("en0")),
            ]);

            for (k, v) in s.iter() {
                assert!(
                    bond.options.0.contains_key(*k),
                    "Missing key '{}' in bond hash {:?}",
                    *k,
                    bond.options.0
                );
                assert_eq!(
                    bond.options.0.get(*k).unwrap(),
                    v,
                    "Unexpected value '{}' in key '{}'",
                    *k,
                    v
                );
            }
        }
    }
}
07070100000006000081A4000000000000000000000001689C733A00000442000000000000000000000000000000000000001E00000000wicked2nm-1.2.1/src/bridge.rsuse agama_network::model;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;

#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Bridge {
    #[serde(default)]
    pub stp: bool,
    pub priority: Option<u16>,
    pub forward_delay: Option<f32>,
    pub hello_time: Option<f32>,
    pub max_age: Option<f32>,
    pub aging_time: Option<f32>, // wicked uses US english, but kernel and nm UK (ageing)
    pub address: Option<String>,
}

impl From<&Bridge> for model::ConnectionConfig {
    fn from(bridge: &Bridge) -> model::ConnectionConfig {
        model::ConnectionConfig::Bridge(model::BridgeConfig {
            stp: Some(bridge.stp),
            priority: bridge.priority.map(|v| v as u32),
            forward_delay: bridge.forward_delay.map(|v| v.round() as u32),
            hello_time: bridge.hello_time.map(|v| v.round() as u32),
            max_age: bridge.max_age.map(|v| v.round() as u32),
            ageing_time: bridge.aging_time.map(|v| v.round() as u32),
        })
    }
}
07070100000007000081A4000000000000000000000001689C733A00001268000000000000000000000000000000000000002200000000wicked2nm-1.2.1/src/infiniband.rsuse agama_network::model::{self, InfinibandConfig, InfinibandTransportMode};
use serde::{Deserialize, Deserializer, Serialize};
use serde_with::skip_serializing_none;
use std::str::FromStr;

#[skip_serializing_none]
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Infiniband {
    pub mode: Option<String>,
    pub multicast: Option<String>,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct InfinibandChild {
    pub device: String,
    #[serde(deserialize_with = "deserialize_pkey")]
    pub pkey: u16,
    pub mode: Option<String>,
    pub multicast: Option<String>,
}

fn deserialize_pkey<'de, D>(deserializer: D) -> Result<u16, D::Error>
where
    D: Deserializer<'de>,
{
    let pkey_string: String = String::deserialize(deserializer)?;
    let pkey_string: &str = pkey_string.trim_start_matches("0x");
    Ok(u16::from_str_radix(pkey_string, 16).unwrap())
}

impl From<&Infiniband> for model::ConnectionConfig {
    fn from(value: &Infiniband) -> Self {
        model::ConnectionConfig::Infiniband(InfinibandConfig {
            transport_mode: InfinibandTransportMode::from_str(
                value
                    .mode
                    .as_ref()
                    .unwrap_or(&"datagram".to_string())
                    .as_str(),
            )
            .unwrap(),
            ..Default::default()
        })
    }
}

impl From<&InfinibandChild> for model::ConnectionConfig {
    fn from(value: &InfinibandChild) -> Self {
        model::ConnectionConfig::Infiniband(InfinibandConfig {
            p_key: Some(value.pkey as i32),
            parent: Some(value.device.clone()),
            transport_mode: InfinibandTransportMode::from_str(
                value
                    .mode
                    .as_ref()
                    .unwrap_or(&"datagram".to_string())
                    .as_str(),
            )
            .unwrap(),
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::interface::*;
    use crate::MIGRATION_SETTINGS;

    #[allow(dead_code)]
    fn setup_default_migration_settings() {
        let _ = MIGRATION_SETTINGS.set(crate::MigrationSettings::default());
    }

    #[test]
    fn test_infiniband_migration() {
        setup_default_migration_settings();
        let infiniband_interface = Interface {
            infiniband: Some(Infiniband {
                mode: Some("datagram".to_string()),
                multicast: Some("allowed".to_string()),
            }),
            ..Default::default()
        };

        let connections = infiniband_interface.to_connection(&None);
        assert!(connections.is_ok());
        let connection = &connections.unwrap().connections[0];
        let model::ConnectionConfig::Infiniband(infiniband) = &connection.config else {
            panic!()
        };
        assert_eq!(
            infiniband.transport_mode,
            InfinibandTransportMode::from_str("datagram").unwrap()
        );
    }

    #[test]
    fn test_infiniband_child_migration() {
        setup_default_migration_settings();
        let infiniband_child_interface = Interface {
            infiniband_child: Some(InfinibandChild {
                mode: Some("datagram".to_string()),
                multicast: Some("allowed".to_string()),
                pkey: 0x8001,
                device: "ib0".to_string(),
            }),
            ..Default::default()
        };

        let connections = infiniband_child_interface.to_connection(&None);
        assert!(connections.is_ok());

        // Check multicast warning is generated
        assert_eq!(connections.as_ref().unwrap().warnings.len(), 1);
        assert_eq!(
            connections.as_ref().unwrap().warnings[0].to_string(),
            "Infiniband multicast isn't supported by NetworkManager"
        );

        let connection = &connections.unwrap().connections[0];
        let model::ConnectionConfig::Infiniband(infiniband_child) = &connection.config else {
            panic!()
        };
        assert_eq!(
            infiniband_child.transport_mode,
            InfinibandTransportMode::from_str("datagram").unwrap()
        );
        assert_eq!(infiniband_child.p_key, Some(0x8001));
        assert_eq!(infiniband_child.parent, Some("ib0".to_string()));
    }

    #[test]
    fn test_deserialize_pkey() {
        let xml = r##"
                  <interface-child>
                    <pkey>0x8001</pkey>
                    <device>ib0</device>
                  </interface-child>
                  "##;
        let infiniband_child = quick_xml::de::from_str::<InfinibandChild>(xml).unwrap();
        assert_eq!(infiniband_child.pkey, 0x8001);
    }
}
07070100000008000081A4000000000000000000000001689C733A0000814C000000000000000000000000000000000000002100000000wicked2nm-1.2.1/src/interface.rsuse crate::bond::Bond;
use crate::bridge::Bridge;
use crate::infiniband::{Infiniband, InfinibandChild};
use crate::netconfig_dhcp::{HostnameOption, NetconfigDhcp};
use crate::ovs::OvsBridge;
use crate::tuntap::Tap;
use crate::tuntap::Tun;
use crate::vlan::Vlan;
use crate::wireless::Wireless;
use crate::MIGRATION_SETTINGS;
use agama_network::model::{
    self, Dhcp4Settings, Dhcp6Settings, IpConfig, IpRoute, Ipv4Method, Ipv6Method, MacAddress,
};
use agama_network::types::Status;
use anyhow::anyhow;
use cidr::IpInet;
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, skip_serializing_none, DeserializeFromStr, SerializeDisplay};
use std::{net::IpAddr, str::FromStr};
use strum_macros::{Display, EnumString};

#[skip_serializing_none]
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Interface {
    pub name: String,
    pub firewall: Firewall,
    pub link: Link,
    pub ipv4: Ipv4,
    #[serde(rename = "ipv4-static")]
    pub ipv4_static: Option<Ipv4Static>,
    #[serde(rename = "ipv4-dhcp")]
    pub ipv4_dhcp: Option<Ipv4Dhcp>,
    pub ipv6: Ipv6,
    #[serde(rename = "ipv6-static")]
    pub ipv6_static: Option<Ipv6Static>,
    #[serde(rename = "ipv6-dhcp")]
    pub ipv6_dhcp: Option<Ipv6Dhcp>,
    #[serde(rename = "ipv6-auto")]
    pub ipv6_auto: Option<Ipv6Auto>,
    pub dummy: Option<Dummy>,
    pub ethernet: Option<Ethernet>,
    pub bond: Option<Bond>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub wireless: Option<Wireless>,
    #[serde(rename = "@origin")]
    pub origin: String,
    pub vlan: Option<Vlan>,
    pub bridge: Option<Bridge>,
    pub infiniband: Option<Infiniband>,
    #[serde(rename = "infiniband-child")]
    pub infiniband_child: Option<InfinibandChild>,
    pub tun: Option<Tun>,
    pub tap: Option<Tap>,
    #[serde(rename = "ovs-bridge")]
    pub ovs_bridge: Option<OvsBridge>,
    pub control: Control,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Firewall {
    pub zone: Option<String>,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone)]
#[serde(default)]
pub struct Link {
    pub master: Option<String>,
    pub mtu: Option<u32>,
    pub port: Option<LinkPort>,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
#[serde(rename_all = "kebab-case")]
pub struct LinkPort {
    #[serde(rename = "@type")]
    pub port_type: LinkPortType,
    pub priority: Option<u32>,
    pub path_cost: Option<u32>,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display, Clone)]
#[strum(serialize_all = "kebab-case")]
pub enum LinkPortType {
    Bridge,
    Bond,
    OvsBridge,
}

fn default_true() -> bool {
    true
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Ipv4 {
    #[serde(default = "default_true")]
    pub enabled: bool,
    // ignored
    #[serde(rename = "arp-verify", default = "default_true")]
    pub arp_verify: bool,
}

impl Default for Ipv4 {
    fn default() -> Self {
        Self {
            enabled: true,
            arp_verify: true,
        }
    }
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Ipv6 {
    #[serde(default = "default_true")]
    pub enabled: bool,
    pub privacy: Option<Ip6Privacy>,
    // ignored
    #[serde(rename = "accept-redirects", default)]
    pub accept_redirects: bool,
}

#[derive(
    Debug, PartialEq, Default, SerializeDisplay, DeserializeFromStr, EnumString, Clone, Display,
)]
#[strum(serialize_all = "kebab-case")]
pub enum Ip6Privacy {
    Disable = 0,
    #[default]
    PreferPublic = 1,
    PreferTemporary = 2,
}

impl Default for Ipv6 {
    fn default() -> Self {
        Self {
            enabled: true,
            privacy: None,
            accept_redirects: false,
        }
    }
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Ipv4Static {
    #[serde(rename = "address")]
    pub addresses: Option<Vec<Address>>,
    #[serde(rename = "route")]
    pub routes: Option<Vec<Route>>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Ipv4Dhcp {
    pub enabled: bool,
    // ignored
    #[serde(default = "default_flags")]
    pub flags: String,
    // ignored
    #[serde(default = "default_v4_update")]
    pub update: String,
    pub hostname: Option<String>,
    // ignored
    #[serde(rename = "defer-timeout", default = "default_defer_timeout")]
    pub defer_timeout: u32,
    // ignored
    #[serde(rename = "recover-lease", default = "default_true")]
    pub recover_lease: bool,
    #[serde(rename = "release-lease", default)]
    pub release_lease: bool,
}

fn default_flags() -> String {
    "group".to_string()
}

fn default_v4_update() -> String {
    "default-route,dns,nis,ntp,nds,mtu,tz,boot".to_string()
}

fn default_defer_timeout() -> u32 {
    15_u32
}

impl Default for Ipv4Dhcp {
    fn default() -> Self {
        Self {
            enabled: true,
            flags: default_flags(),
            update: default_v4_update(),
            hostname: None,
            defer_timeout: default_defer_timeout(),
            recover_lease: true,
            release_lease: false,
        }
    }
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Ipv6Static {
    #[serde(rename = "address")]
    pub addresses: Option<Vec<Address>>,
    #[serde(rename = "route")]
    pub routes: Option<Vec<Route>>,
}

#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Address {
    pub local: String,
}

#[serde_as]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct Ipv6Dhcp {
    pub enabled: bool,
    pub mode: String,
    // ignored
    #[serde(default = "default_flags")]
    pub flags: String,
    // ignored
    #[serde(default = "default_v6_dhcp_update")]
    pub update: String,
    // ignored
    #[serde(rename = "rapid-commit", default = "default_true")]
    pub rapid_commit: bool,
    pub hostname: Option<String>,
    // ignored
    #[serde(rename = "defer-timeout", default = "default_defer_timeout")]
    pub defer_timeout: u32,
    // ignored
    #[serde(rename = "recover-lease", default = "default_true")]
    pub recover_lease: bool,
    // ignored
    #[serde(rename = "refresh-lease", default)]
    pub refresh_lease: bool,
    #[serde(rename = "release-lease", default)]
    pub release_lease: bool,
}

fn default_v6_dhcp_update() -> String {
    "dns,nis,ntp,tz,boot".to_string()
}

impl Default for Ipv6Dhcp {
    fn default() -> Self {
        Self {
            enabled: true,
            mode: String::from("auto"),
            flags: default_flags(),
            update: default_v6_dhcp_update(),
            rapid_commit: true,
            hostname: None,
            defer_timeout: default_defer_timeout(),
            recover_lease: true,
            refresh_lease: false,
            release_lease: false,
        }
    }
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct Ipv6Auto {
    pub enabled: bool,
    // ignored
    #[serde(default = "default_v6_dhcp_update")]
    pub update: String,
}

fn default_v6_auto_update() -> String {
    "dns".to_string()
}

impl Default for Ipv6Auto {
    fn default() -> Self {
        Self {
            enabled: true,
            update: default_v6_auto_update(),
        }
    }
}

#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Dummy {
    pub address: Option<String>,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Route {
    pub destination: Option<String>,
    #[serde(rename = "nexthop")]
    pub nexthops: Option<Vec<Nexthop>>,
    pub priority: Option<u32>,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Ethernet {
    pub address: Option<String>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Nexthop {
    pub gateway: String,
}

#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Control {
    #[serde(default)]
    pub mode: ControlMode,
    // ignored
    #[serde(rename = "boot-stage")]
    pub boot_stage: Option<String>,
    // ignored
    pub persistent: Option<String>,
}

#[derive(
    Debug, PartialEq, Default, SerializeDisplay, DeserializeFromStr, EnumString, Clone, Display,
)]
#[strum(serialize_all = "snake_case")]
pub enum ControlMode {
    #[default]
    Manual,
    Off,
    Boot,
    Hotplug,
}

impl From<ControlMode> for bool {
    fn from(value: ControlMode) -> Self {
        match value {
            ControlMode::Manual => false,
            ControlMode::Off => false,
            ControlMode::Boot => true,
            ControlMode::Hotplug => true,
        }
    }
}

pub struct ConnectionResult {
    pub connections: Vec<model::Connection>,
    pub warnings: Vec<anyhow::Error>,
}

pub struct IpConfigResult {
    ip_config: IpConfig,
    warnings: Vec<anyhow::Error>,
}

impl From<&LinkPort> for model::PortConfig {
    fn from(port: &LinkPort) -> Self {
        match port.port_type {
            LinkPortType::Bridge => model::PortConfig::Bridge(model::BridgePortConfig {
                priority: port.priority,
                path_cost: port.path_cost,
            }),
            LinkPortType::Bond => model::PortConfig::None,
            LinkPortType::OvsBridge => model::PortConfig::OvsBridge(model::OvsBridgePortConfig {}),
        }
    }
}

impl Interface {
    fn to_ovs_port_name(&self) -> String {
        format!("{}-port", self.name)
    }

    fn to_ovs_bridge_name(&self) -> String {
        format!("{}-bridge", self.name)
    }

    pub fn to_connection(
        &self,
        netconfig_dhcp: &Option<NetconfigDhcp>,
    ) -> Result<ConnectionResult, anyhow::Error> {
        let settings = MIGRATION_SETTINGS.get().unwrap();
        let ip_config = self.to_ip_config(netconfig_dhcp)?;
        let mut warnings = ip_config.warnings;
        let mut connections: Vec<model::Connection> = vec![];
        warnings.append(&mut check_ignored(self));
        let mut connection = model::Connection {
            id: self.name.clone(),
            firewall_zone: self.firewall.zone.clone(),
            interface: Some(self.name.clone()),
            ip_config: ip_config.ip_config,
            status: Status::Down,
            mtu: self.link.mtu.unwrap_or_default(),
            autoconnect: self.control.mode.clone().into(),
            ..Default::default()
        };

        if let Some(port) = &self.link.port {
            connection.port_config = port.into();
            if let LinkPortType::OvsBridge = port.port_type {
                let con_ovs_port = model::Connection {
                    id: self.to_ovs_port_name(),
                    interface: Some(self.to_ovs_port_name()),
                    autoconnect: self.control.mode.clone().into(),
                    config: model::ConnectionConfig::OvsPort(model::OvsPortConfig::default()),
                    ..Default::default()
                };
                connection.controller = Some(con_ovs_port.uuid);
                connections.push(con_ovs_port);
            }
        }

        if settings.activate_connections {
            connection.status = if connection.autoconnect {
                Status::Up
            } else {
                Status::Down
            };
        }

        if let Some(ethernet) = &self.ethernet {
            connection.custom_mac_address = MacAddress::try_from(&ethernet.address)?;
            connection.config = model::ConnectionConfig::Ethernet;
            connections.push(connection);
        } else if let Some(dummy) = &self.dummy {
            connection.custom_mac_address = MacAddress::try_from(&dummy.address)?;
            connection.config = model::ConnectionConfig::Dummy;
            connections.push(connection);
        } else if let Some(bond) = &self.bond {
            connection.custom_mac_address = MacAddress::try_from(&bond.address)?;
            connection.config = bond.into();
            connections.push(connection);
        } else if let Some(vlan) = &self.vlan {
            connection.custom_mac_address = MacAddress::try_from(&vlan.address)?;
            connection.config = vlan.into();
            connections.push(connection);
        } else if let Some(bridge) = &self.bridge {
            connection.custom_mac_address = MacAddress::try_from(&bridge.address)?;
            connection.config = bridge.into();
            connections.push(connection);
        } else if let Some(wireless) = &self.wireless {
            if let Some(networks) = &wireless.networks {
                if networks.len() > 1 {
                    log::info!("{} has multiple networks defined, these will be split into different connections in NM", connection.id);
                }
                for (i, network) in networks.iter().enumerate() {
                    let mut wireless_connection = connection.clone();
                    if networks.len() > 1 {
                        wireless_connection.id.push_str(&format!("-{i}"));
                    }
                    wireless_connection.config = network.try_into()?;
                    if let Some(wpa_eap) = &network.wpa_eap {
                        wireless_connection.ieee_8021x_config = Some(wpa_eap.try_into()?);
                    }
                    connections.push(wireless_connection);
                }
            }
        } else if let Some(infiniband) = &self.infiniband {
            if infiniband.multicast.is_some() {
                warnings.push(anyhow::anyhow!(
                    "Infiniband multicast isn't supported by NetworkManager"
                ));
            }
            connection.config = infiniband.into();
            connections.push(connection)
        } else if let Some(infiniband_child) = &self.infiniband_child {
            if infiniband_child.multicast.is_some() {
                warnings.push(anyhow::anyhow!(
                    "Infiniband multicast isn't supported by NetworkManager"
                ));
            }
            connection.config = infiniband_child.into();
            connections.push(connection)
        } else if let Some(tun) = &self.tun {
            connection.config = tun.into();
            connections.push(connection)
        } else if let Some(tap) = &self.tap {
            connection.config = tap.into();
            connections.push(connection)
        } else if let Some(ovs_bridge) = &self.ovs_bridge {
            let mut vlan_tag: Option<u16> = None;
            let mut controller_uuid = None;

            if let Some(vlan) = &ovs_bridge.vlan {
                vlan_tag = Some(vlan.tag);
            } else {
                let con_ovs_bridge = model::Connection {
                    id: self.to_ovs_bridge_name(),
                    interface: Some(self.to_ovs_bridge_name()),
                    autoconnect: self.control.mode.clone().into(),
                    config: model::ConnectionConfig::OvsBridge(model::OvsBridgeConfig::default()),
                    ..Default::default()
                };
                controller_uuid = Some(con_ovs_bridge.uuid);
                connections.push(con_ovs_bridge);
            }

            let con_ovs_port = model::Connection {
                id: self.to_ovs_port_name(),
                interface: Some(self.to_ovs_port_name()),
                autoconnect: self.control.mode.clone().into(),
                config: model::ConnectionConfig::OvsPort(model::OvsPortConfig { tag: vlan_tag }),
                controller: controller_uuid,
                ..Default::default()
            };

            connection.config = model::ConnectionConfig::OvsInterface(model::OvsInterfaceConfig {
                interface_type: model::OvsInterfaceType::Internal,
            });
            connection.controller = Some(con_ovs_port.uuid);

            connections.push(con_ovs_port);
            connections.push(connection);
        } else {
            connections.push(connection);
        }

        Ok(ConnectionResult {
            connections,
            warnings,
        })
    }

    pub fn to_ip_config(
        &self,
        netconfig_dhcp: &Option<NetconfigDhcp>,
    ) -> Result<IpConfigResult, anyhow::Error> {
        let mut connection_result = IpConfigResult {
            ip_config: IpConfig {
                ..Default::default()
            },
            warnings: vec![],
        };
        let method4 = if self.ipv4_static.is_some() {
            Ipv4Method::Manual
        } else if !self.ipv4.enabled {
            Ipv4Method::Disabled
        } else if self.ipv4_dhcp.is_some() {
            Ipv4Method::Auto
        } else {
            Ipv4Method::Disabled
        };
        let method6 = if self.ipv6_static.is_some() {
            Ipv6Method::Manual
        } else if self.ipv6_dhcp.is_some() && self.ipv6_dhcp.as_ref().unwrap().mode == "managed" {
            Ipv6Method::Dhcp
        } else if !self.ipv6.enabled {
            Ipv6Method::Disabled
        } else {
            Ipv6Method::Auto
        };

        let mut addresses: Vec<IpInet> = vec![];
        let mut routes4: Vec<IpRoute> = vec![];
        let mut routes6: Vec<IpRoute> = vec![];
        if let Some(ipv4_static) = &self.ipv4_static {
            if let Some(addresses_in) = &ipv4_static.addresses {
                for addr in addresses_in {
                    addresses.push(match IpInet::from_str(addr.local.as_str()) {
                        Ok(address) => address,
                        Err(e) => {
                            anyhow::bail!("Failed to parse address \"{}\": {}", addr.local, e)
                        }
                    });
                }
            }
            if let Some(routes) = &ipv4_static.routes {
                for route in routes {
                    routes4.push(match route.try_into() {
                        Ok(route) => route,
                        Err(e) => {
                            connection_result.warnings.push(e);
                            continue;
                        }
                    });
                }
            }
        }
        if let Some(ipv6_static) = &self.ipv6_static {
            if let Some(addresses_in) = &ipv6_static.addresses {
                for addr in addresses_in {
                    addresses.push(match IpInet::from_str(addr.local.as_str()) {
                        Ok(address) => address,
                        Err(e) => {
                            anyhow::bail!("Failed to parse address \"{}\": {}", addr.local, e)
                        }
                    });
                }
            }
            if let Some(routes) = &ipv6_static.routes {
                for route in routes {
                    routes6.push(match route.try_into() {
                        Ok(route) => route,
                        Err(e) => {
                            connection_result.warnings.push(e);
                            continue;
                        }
                    });
                }
            }
        }

        let mut dhcp4_settings: Option<Dhcp4Settings> = None;
        if let Some(ipv4_dhcp) = &self.ipv4_dhcp {
            let mut dhcp_settings = Dhcp4Settings::default();
            if let Some(hostname) = &ipv4_dhcp.hostname {
                dhcp_settings.send_hostname = Some(true);
                if let Some(netconfig_dhcp) = netconfig_dhcp {
                    if netconfig_dhcp.dhclient_hostname_option != HostnameOption::Auto {
                        dhcp_settings.hostname = Some(hostname.clone());
                    }
                } else {
                    dhcp_settings.hostname = Some(hostname.clone());
                }
            } else {
                dhcp_settings.send_hostname = Some(false);
            }
            dhcp_settings.send_release = Some(ipv4_dhcp.release_lease);
            dhcp4_settings = Some(dhcp_settings);
        }

        let mut dhcp6_settings: Option<Dhcp6Settings> = None;
        if let Some(ipv6_dhcp) = &self.ipv6_dhcp {
            let mut dhcp_settings = Dhcp6Settings::default();
            if let Some(hostname) = &ipv6_dhcp.hostname {
                dhcp_settings.send_hostname = Some(true);
                if let Some(netconfig_dhcp) = netconfig_dhcp {
                    if netconfig_dhcp.dhclient6_hostname_option != HostnameOption::Auto {
                        dhcp_settings.hostname = Some(hostname.clone());
                    }
                } else {
                    dhcp_settings.hostname = Some(hostname.clone());
                }
            } else {
                dhcp_settings.send_hostname = Some(false);
            }
            dhcp_settings.send_release = Some(ipv6_dhcp.release_lease);
            dhcp6_settings = Some(dhcp_settings);
        }

        let mut ip6_privacy: Option<i32> = None;
        if let Some(privacy) = &self.ipv6.privacy {
            ip6_privacy = Some(privacy.clone() as i32);
        }

        connection_result.ip_config = IpConfig {
            addresses,
            method4,
            method6,
            routes4,
            routes6,
            dhcp4_settings,
            dhcp6_settings,
            ip6_privacy,
            ..Default::default()
        };
        Ok(connection_result)
    }
}

impl TryFrom<&Route> for IpRoute {
    type Error = anyhow::Error;
    fn try_from(route: &Route) -> Result<Self, Self::Error> {
        let mut next_hop: Option<IpAddr> = None;
        if let Some(nexthops) = &route.nexthops {
            if nexthops.len() > 1 {
                return Err(anyhow::anyhow!(
                    "Multipath routing isn't natively supported by NetworkManager"
                ));
            } else {
                next_hop = Some(IpAddr::from_str(&nexthops[0].gateway).unwrap());
            }
        }
        let destination = if route.destination.is_some() {
            IpInet::from_str(route.destination.clone().unwrap().as_str())?
        } else if next_hop.is_some() {
            // default route
            let default_ip = if next_hop.unwrap().is_ipv4() {
                IpAddr::from_str("0.0.0.0")?
            } else {
                IpAddr::from_str("::")?
            };
            IpInet::new(default_ip, 0)?
        } else {
            return Err(anyhow::anyhow!("Error occurred when parsing a route"));
        };
        let metric = route.priority;
        Ok(IpRoute {
            destination,
            next_hop,
            metric,
        })
    }
}

fn check_ignored(interface: &Interface) -> Vec<anyhow::Error> {
    let mut warnings: Vec<anyhow::Error> = vec![];

    let ipv4 = &interface.ipv4;
    let ipv4_default = Ipv4::default();
    if ipv4.arp_verify != ipv4_default.arp_verify {
        warnings.push(anyhow!(
            "Unhandled field in interface {}: {}",
            interface.name,
            stringify!(ipv4.arp_verify)
        ));
    }

    let ipv6 = &interface.ipv6;
    let ipv6_default = Ipv6::default();
    if ipv6.accept_redirects != ipv6_default.accept_redirects {
        warnings.push(anyhow!(
            "Unhandled field in interface {}: {}",
            interface.name,
            stringify!(ipv6.accept_redirects)
        ));
    }

    if let Some(ipv4_dhcp) = &interface.ipv4_dhcp {
        let ipv4_dhcp_default = Ipv4Dhcp::default();
        if ipv4_dhcp.flags != ipv4_dhcp_default.flags {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv4_dhcp.flags)
            ));
        }
        if ipv4_dhcp.update != ipv4_dhcp_default.update {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv4_dhcp.update)
            ));
        }
        if ipv4_dhcp.defer_timeout != ipv4_dhcp_default.defer_timeout {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv4_dhcp.defer_timeout)
            ));
        }
        if ipv4_dhcp.recover_lease != ipv4_dhcp_default.recover_lease {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv4_dhcp.recover_lease)
            ));
        }
    }

    if let Some(ipv6_dhcp) = &interface.ipv6_dhcp {
        let ipv6_dhcp_default = Ipv6Dhcp::default();
        if ipv6_dhcp.flags != ipv6_dhcp_default.flags {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv6_dhcp.flags)
            ));
        }

        if ipv6_dhcp.update != ipv6_dhcp_default.update {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv6_dhcp.update)
            ));
        }
        if ipv6_dhcp.rapid_commit != ipv6_dhcp_default.rapid_commit {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv6_dhcp.rapid_commit)
            ));
        }
        if ipv6_dhcp.defer_timeout != ipv6_dhcp_default.defer_timeout {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv6_dhcp.defer_timeout)
            ));
        }
        if ipv6_dhcp.recover_lease != ipv6_dhcp_default.recover_lease {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv6_dhcp.recover_lease)
            ));
        }
        if ipv6_dhcp.refresh_lease != ipv6_dhcp_default.refresh_lease {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv6_dhcp.refresh_lease)
            ));
        }
    }
    if let Some(ipv6_auto) = &interface.ipv6_auto {
        let ipv6_auto_default = Ipv6Auto::default();
        if ipv6_auto.update != ipv6_auto_default.update {
            warnings.push(anyhow!(
                "Unhandled field in interface {}: {}",
                interface.name,
                stringify!(ipv6_auto.update)
            ));
        }
    }

    warnings
}

#[cfg(test)]
mod tests {
    use super::*;

    #[allow(dead_code)]
    fn setup_default_migration_settings() {
        let _ = MIGRATION_SETTINGS.set(crate::MigrationSettings::default());
    }

    #[test]
    fn test_static_interface_to_connection() {
        setup_default_migration_settings();
        let static_interface = Interface {
            ipv4: Ipv4::default(),
            ipv4_static: Some(Ipv4Static {
                addresses: Some(vec![Address {
                    local: "127.0.0.1/8".to_string(),
                }]),
                routes: Some(vec![Route {
                    nexthops: Some(vec![Nexthop {
                        gateway: "127.0.0.1".to_string(),
                    }]),
                    ..Default::default()
                }]),
            }),
            ipv6: Ipv6::default(),
            ipv6_static: Some(Ipv6Static {
                addresses: Some(vec![Address {
                    local: "::1/128".to_string(),
                }]),
                routes: Some(vec![Route {
                    nexthops: Some(vec![Nexthop {
                        gateway: "::1".to_string(),
                    }]),
                    ..Default::default()
                }]),
            }),
            ..Default::default()
        };

        let static_connection: model::Connection =
            static_interface.to_connection(&None).unwrap().connections[0].to_owned();
        assert_eq!(static_connection.ip_config.method4, Ipv4Method::Manual);
        assert_eq!(
            static_connection.ip_config.addresses[0].to_string(),
            "127.0.0.1/8"
        );
        assert_eq!(static_connection.ip_config.method6, Ipv6Method::Manual);
        assert_eq!(static_connection.ip_config.addresses[1].to_string(), "::1");
        assert_eq!(
            static_connection.ip_config.addresses[1]
                .network_length()
                .to_string(),
            "128"
        );
        assert!(static_connection.ip_config.routes4.len() == 1);
        assert_eq!(
            static_connection.ip_config.routes4[0]
                .destination
                .to_string(),
            "0.0.0.0/0"
        );
        assert_eq!(
            static_connection.ip_config.routes4[0]
                .next_hop
                .unwrap()
                .to_string(),
            "127.0.0.1"
        );
        assert!(static_connection.ip_config.routes6.len() == 1);
        assert_eq!(
            static_connection.ip_config.routes6[0]
                .destination
                .to_string(),
            "::/0"
        );
        assert_eq!(
            static_connection.ip_config.routes6[0]
                .next_hop
                .unwrap()
                .to_string(),
            "::1"
        );
    }

    #[test]
    fn test_dhcp_interface_to_connection() {
        setup_default_migration_settings();
        let static_interface = Interface {
            ipv4_dhcp: Some(Ipv4Dhcp {
                enabled: true,
                ..Default::default()
            }),
            ..Default::default()
        };

        let static_connection: model::Connection =
            static_interface.to_connection(&None).unwrap().connections[0].to_owned();
        assert_eq!(static_connection.ip_config.method4, Ipv4Method::Auto);
        assert_eq!(static_connection.ip_config.method6, Ipv6Method::Auto);
        assert_eq!(static_connection.ip_config.addresses.len(), 0);
    }

    #[test]
    fn test_dummy_interface_to_connection() {
        setup_default_migration_settings();
        let dummy_interface = Interface {
            dummy: Some(Dummy {
                address: Some("12:34:56:78:9A:BC".to_string()),
            }),
            ..Default::default()
        };

        let connection: &model::Connection =
            &dummy_interface.to_connection(&None).unwrap().connections[0];
        assert!(matches!(connection.config, model::ConnectionConfig::Dummy));
        assert_eq!(
            connection.custom_mac_address.to_string(),
            "12:34:56:78:9A:BC"
        );

        let dummy_interface = Interface {
            dummy: Some(Dummy {
                ..Default::default()
            }),
            ..Default::default()
        };

        let connection: &model::Connection =
            &dummy_interface.to_connection(&None).unwrap().connections[0];
        assert!(matches!(connection.config, model::ConnectionConfig::Dummy));
        assert_eq!(dummy_interface.dummy.unwrap().address, None);
        assert!(matches!(connection.custom_mac_address, MacAddress::Unset));
    }

    #[test]
    fn test_firewall_zone_to_connection() {
        setup_default_migration_settings();
        let ifc = Interface {
            firewall: Firewall {
                zone: Some("topsecret".to_string()),
            },
            ..Default::default()
        };

        let con: model::Connection = ifc.to_connection(&None).unwrap().connections[0].to_owned();
        assert_eq!(con.firewall_zone, Some("topsecret".to_string()));
    }

    #[test]
    fn test_startmode_to_connection() {
        setup_default_migration_settings();
        let mut ifc = Interface::default();

        let con: model::Connection = ifc.to_connection(&None).unwrap().connections[0].to_owned();
        assert!(!con.autoconnect);

        ifc.control.mode = ControlMode::Boot;
        let con: model::Connection = ifc.to_connection(&None).unwrap().connections[0].to_owned();
        assert!(con.autoconnect);
    }

    #[test]
    fn test_ignored_default() {
        let ifc = Interface::default();
        assert!(check_ignored(&ifc).is_empty());

        let ifc = Interface {
            ipv4_dhcp: Some(Ipv4Dhcp {
                flags: String::from("123"),
                update: String::from("456"),
                defer_timeout: 0,
                recover_lease: false,
                ..Default::default()
            }),
            ipv6_dhcp: Some(Ipv6Dhcp {
                flags: String::from("123"),
                update: String::from("456"),
                rapid_commit: false,
                defer_timeout: 0,
                recover_lease: false,
                refresh_lease: true,
                ..Default::default()
            }),
            ipv6_auto: Some(Ipv6Auto {
                update: String::from("123"),
                ..Default::default()
            }),
            ..Default::default()
        };
        assert!(check_ignored(&ifc).len() == 11);
    }
}
07070100000009000081A4000000000000000000000001689C733A00001BA6000000000000000000000000000000000000001C00000000wicked2nm-1.2.1/src/main.rsmod bond;
mod bridge;
mod infiniband;
mod interface;
mod migrate;
mod netconfig;
mod netconfig_dhcp;
mod ovs;
mod reader;
mod tuntap;
mod vlan;
mod wireless;

use clap::builder::TypedValueParser;
use clap::{Args, Parser, Subcommand};
use log::*;
use migrate::migrate;
use reader::read as wicked_read;
use serde::Serialize;
use simplelog::ConfigBuilder;
use std::process::{ExitCode, Termination};
use tokio::sync::OnceCell;

use crate::interface::Interface;
use crate::netconfig::Netconfig;

#[derive(Parser)]
#[command(name = "wicked2nm", version, about, long_about = None)]
struct Cli {
    #[clap(flatten)]
    global_opts: GlobalOpts,

    #[command(subcommand)]
    pub command: Commands,
}

#[derive(Debug, Args)]
struct GlobalOpts {
    #[arg(long, global = true, default_value_t = LevelFilter::Info, value_parser = clap::builder::PossibleValuesParser::new(["TRACE", "DEBUG", "INFO", "WARN", "ERROR"]).map(|s| s.parse::<LevelFilter>().unwrap()),)]
    pub log_level: LevelFilter,

    #[arg(long, global = true, env = "W2NM_WITHOUT_NETCONFIG")]
    pub without_netconfig: bool,

    #[arg(long, global = true, default_value_t = String::from("/etc/sysconfig/network/config"), env = "W2NM_NETCONFIG_PATH")]
    pub netconfig_path: String,

    #[arg(long, global = true, default_value_t = String::from("/etc/sysconfig/network/dhcp"), env = "W2NM_NETCONFIG_DHCP_PATH")]
    pub netconfig_dhcp_path: String,
}

#[derive(Subcommand)]
pub enum Commands {
    /// Shows the current xml wicked configuration
    Show {
        /// Format output
        #[arg(value_enum, short, long, default_value_t = Format::Json)]
        format: Format,

        /// Wicked XML files or directories where the wicked xml configs are located.
        /// Can also be "-" to read from stdin
        paths: Vec<String>,
    },
    /// Migrate wicked state at path
    Migrate {
        /// Wicked XML files or directories where the wicked xml configs are located.
        /// Can also be "-" to read from stdin
        paths: Vec<String>,

        /// Continue migration if warnings are encountered
        #[arg(short, long, global = true, env = "W2NM_CONTINUE_MIGRATION")]
        continue_migration: bool,

        /// Run migration without sending connections to NetworkManager (can be run without NetworkManager installed)
        #[arg(long, global = true, env = "W2NM_DRY_RUN")]
        dry_run: bool,

        /// Activate connections that are marked as autostart immediately
        #[arg(long, global = true, env = "W2NM_ACTIVATE_CONNECTIONS")]
        activate_connections: bool,
    },
}

/// Supported output formats
#[derive(clap::ValueEnum, Clone)]
pub enum Format {
    Json,
    PrettyJson,
    Yaml,
    Xml,
    Text,
}

async fn run_command(cli: Cli) -> anyhow::Result<()> {
    match cli.command {
        Commands::Show { paths, format } => {
            MIGRATION_SETTINGS
                .set(MigrationSettings {
                    continue_migration: true,
                    dry_run: false,
                    activate_connections: true,
                    with_netconfig: !cli.global_opts.without_netconfig,
                    netconfig_path: cli.global_opts.netconfig_path,
                    netconfig_dhcp_path: cli.global_opts.netconfig_dhcp_path,
                })
                .expect("MIGRATION_SETTINGS was set too early");

            let interfaces_result = wicked_read(paths)?;

            #[derive(Debug, Serialize)]
            struct WickedConfig {
                interface: Vec<Interface>,
                netconfig: Option<Netconfig>,
            }
            let show_output = WickedConfig {
                interface: interfaces_result.interfaces,
                netconfig: interfaces_result.netconfig,
            };

            let output = match format {
                Format::Json => serde_json::to_string(&show_output)?,
                Format::PrettyJson => serde_json::to_string_pretty(&show_output)?,
                Format::Yaml => serde_yaml::to_string(&show_output)?,
                Format::Xml => quick_xml::se::to_string_with_root("wicked-config", &show_output)?,
                Format::Text => format!("{show_output:?}"),
            };
            println!("{output}");
            Ok(())
        }
        Commands::Migrate {
            paths,
            continue_migration,
            dry_run,
            activate_connections,
        } => {
            MIGRATION_SETTINGS
                .set(MigrationSettings {
                    continue_migration,
                    dry_run,
                    activate_connections,
                    with_netconfig: !cli.global_opts.without_netconfig,
                    netconfig_path: cli.global_opts.netconfig_path,
                    netconfig_dhcp_path: cli.global_opts.netconfig_dhcp_path,
                })
                .expect("MIGRATION_SETTINGS was set too early");

            log::debug!(
                "Running migration with MigrationSettings: {:#?}",
                MIGRATION_SETTINGS.get().unwrap()
            );

            let interfaces_result = wicked_read(paths)?;

            if !continue_migration && interfaces_result.warning.is_some() {
                return Err(interfaces_result.warning.unwrap());
            }

            match migrate(
                interfaces_result.interfaces,
                interfaces_result.netconfig,
                interfaces_result.netconfig_dhcp,
            )
            .await
            {
                Ok(()) => Ok(()),
                Err(e) => Err(anyhow::anyhow!("Migration failed: {}", e)),
            }
        }
    }
}

/// Represents the result of execution.
pub enum CliResult {
    /// Successful execution.
    Ok = 0,
    /// Something went wrong.
    Error = 1,
}

impl Termination for CliResult {
    fn report(self) -> ExitCode {
        ExitCode::from(self as u8)
    }
}

#[derive(Debug)]
struct MigrationSettings {
    continue_migration: bool,
    dry_run: bool,
    activate_connections: bool,
    with_netconfig: bool,
    netconfig_path: String,
    netconfig_dhcp_path: String,
}

impl Default for MigrationSettings {
    fn default() -> Self {
        MigrationSettings {
            continue_migration: false,
            dry_run: false,
            activate_connections: true,
            with_netconfig: false,
            netconfig_path: "".to_string(),
            netconfig_dhcp_path: "".to_string(),
        }
    }
}

static MIGRATION_SETTINGS: OnceCell<MigrationSettings> = OnceCell::const_new();

#[tokio::main]
async fn main() -> CliResult {
    let cli = Cli::parse();

    let config = ConfigBuilder::new()
        .set_time_level(LevelFilter::Off)
        .add_filter_allow("wicked2nm".to_string())
        .build();

    simplelog::TermLogger::init(
        cli.global_opts.log_level,
        config,
        simplelog::TerminalMode::Stderr,
        simplelog::ColorChoice::Auto,
    )
    .unwrap();

    if let Err(error) = run_command(cli).await {
        log::error!("{error}");
        return CliResult::Error;
    }

    CliResult::Ok
}
0707010000000A000081A4000000000000000000000001689C733A00002539000000000000000000000000000000000000001F00000000wicked2nm-1.2.1/src/migrate.rsuse crate::interface::{Interface, Link, LinkPort, LinkPortType};
use crate::netconfig::{apply_dns_policy, Netconfig};
use crate::netconfig_dhcp::NetconfigDhcp;
use crate::MIGRATION_SETTINGS;
use agama_network::model::{
    Connection, ConnectionConfig, GeneralState, IpConfig, MatchConfig, StateConfig,
};
use agama_network::{model, Adapter, NetworkManagerAdapter, NetworkState};
use cidr::IpInet;
use std::fmt;
use std::str::FromStr;
use std::{collections::HashMap, error::Error};
use uuid::Uuid;

#[derive(Debug)]
struct ParentMatch {
    uuid: Uuid,
    tag: Option<u16>,
}

impl From<Uuid> for ParentMatch {
    fn from(value: Uuid) -> Self {
        ParentMatch {
            uuid: value,
            tag: None,
        }
    }
}

impl fmt::Display for ParentMatch {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.tag {
            Some(tag_value) => write!(f, "{}(tag: {tag_value})", self.uuid),
            None => write!(f, "{}", self.uuid),
        }
    }
}

fn get_parentmatch_ovsbridge(
    parent_connection: &Connection,
    connections: &[Connection],
) -> Option<ParentMatch> {
    let bridge_port = connections
        .iter()
        .find(|c| Some(c.uuid) == parent_connection.controller)?;

    let ConnectionConfig::OvsPort(config) = &bridge_port.config else {
        return None;
    };

    let bridge = connections
        .iter()
        .find(|c| Some(c.uuid) == bridge_port.controller)?;

    Some(ParentMatch {
        uuid: bridge.uuid,
        tag: config.tag,
    })
}

fn update_parent_connection(
    connections: &mut [Connection],
    parents: &mut HashMap<Uuid, Link>,
) -> Result<(), anyhow::Error> {
    let settings = MIGRATION_SETTINGS.get().unwrap();
    let mut parent_uuids: HashMap<Uuid, ParentMatch> = HashMap::new();

    for (port_uuid, parent) in parents.iter() {
        let Some(parent_con) = connections.iter().find(|c| c.interface == parent.master) else {
            log::warn!(
                "Missing parent connection with interface {} for port {port_uuid}",
                parent.clone().master.unwrap()
            );
            if !settings.continue_migration {
                anyhow::bail!("Migration of {port_uuid} failed because of warnings, use the `--continue-migration` flag to ignore");
            }
            continue;
        };

        let Some(port) = &parent.port else {
            continue;
        };

        if let Some(parent_match) = match port.port_type {
            LinkPortType::OvsBridge => get_parentmatch_ovsbridge(parent_con, connections),
            _ => Some(ParentMatch::from(parent_con.uuid)),
        } {
            parent_uuids.insert(*port_uuid, parent_match);
        }
    }

    for (port_uuid, parent_match) in parent_uuids {
        let Some(connection) = connections.iter_mut().find(|c| c.uuid == port_uuid) else {
            anyhow::bail!(
                "Unexpected failure - missing port connection {port_uuid} from parent {parent_match}"
            );
        };

        connection.controller = Some(parent_match.uuid);

        if let Some(vlan_tag) = parent_match.tag {
            if let ConnectionConfig::OvsPort(config) = &mut connection.config {
                config.tag = Some(vlan_tag);
            }
        }

        parents.remove(&port_uuid);
    }

    Ok(())
}

fn create_lo_connection() -> Connection {
    Connection {
        id: "lo".to_string(),
        ip_config: IpConfig {
            method4: model::Ipv4Method::Manual,
            method6: model::Ipv6Method::Manual,
            addresses: vec![
                IpInet::from_str("127.0.0.1/8").unwrap(),
                IpInet::from_str("::1/128").unwrap(),
            ],
            ..Default::default()
        },
        interface: Some("lo".to_string()),
        match_config: MatchConfig::default(),
        config: model::ConnectionConfig::Loopback,
        ..Default::default()
    }
}

pub async fn migrate(
    interfaces: Vec<Interface>,
    netconfig: Option<Netconfig>,
    netconfig_dhcp: Option<NetconfigDhcp>,
) -> Result<(), Box<dyn Error>> {
    let settings = MIGRATION_SETTINGS.get().unwrap();
    let mut parents: HashMap<Uuid, Link> = HashMap::new();
    let mut connections: Vec<Connection> = vec![];

    for interface in interfaces {
        let connection_result = interface.to_connection(&netconfig_dhcp)?;
        if !connection_result.warnings.is_empty() {
            for connection_error in &connection_result.warnings {
                log::warn!("{connection_error}");
            }
            if !settings.continue_migration {
                return Err(anyhow::anyhow!(
                    "Migration of {} failed because of warnings, use the `--continue-migration` flag to ignore",
                    connection_result.connections[0].id
                )
                .into());
            }
        }

        for connection in connection_result.connections {
            if connection.controller.is_none() {
                if interface.link.master.is_some() {
                    parents.insert(connection.uuid, interface.link.clone());
                } else if let Some(ovs_bridge) = &interface.ovs_bridge {
                    //  This "if let" handles the special port handling of ovs-bridge
                    //  which is NOT defined via the `<link>` field but inside the
                    //  `<ovs-bridge>` tag like (aka "fake bridge", see man 5 ifcfg-ovs-bridge):
                    //
                    //   <ovs-bridge>
                    //    <vlan>
                    //      <parent>ovsbrA</parent>
                    //      <tag>10</tag>
                    //    </vlan>
                    //   </ovs-bridge>
                    //
                    //  The `vlan tag` is set in the corresponding ovs-port and needs to
                    //  be inherited to the ports of this "fake bridge" (see:
                    //  update_parent_connection() )
                    //
                    if let Some(vlan) = &ovs_bridge.vlan {
                        let link = Link {
                            master: Some(vlan.parent.clone()),
                            port: Some(LinkPort {
                                port_type: LinkPortType::OvsBridge,
                                priority: None,
                                path_cost: None,
                            }),
                            ..Default::default()
                        };
                        parents.insert(connection.uuid, link);
                    }
                }
            }
            connections.push(connection);
        }
    }

    loop {
        // This loop is needed, as we need to map the "ovs-port" of a "fake bridge"
        // to the "ovs-bridge" first. And then link all "ovs-ports" from the fakebridge
        // to the same "ovs-bridge".
        //
        let len = parents.len();
        update_parent_connection(&mut connections, &mut parents)?;
        if parents.is_empty() {
            break;
        }

        if len == parents.len() {
            let connections = connections
                .iter()
                .filter(|c| parents.contains_key(&c.uuid))
                .map(|c| c.id.as_str())
                .collect::<Vec<&str>>()
                .join("\n");
            return Err(anyhow::anyhow!(
                "Unexpected error, port connection is missing controller: {connections}"
            )
            .into());
        }
    }

    let mut state = NetworkState::new(GeneralState::default(), vec![], vec![], vec![]);
    for connection in &connections {
        state.add_connection(connection.clone())?;
    }

    if settings.dry_run {
        for connection in state.connections {
            log::debug!("{connection:#?}");
        }
        return Ok(());
    }
    let nm = NetworkManagerAdapter::from_system().await?;

    if let Some(netconfig) = netconfig {
        let current_state = nm.read(StateConfig::default()).await?;
        let mut loopback = match current_state.get_connection("lo") {
            Some(lo) => lo.clone(),
            None => create_lo_connection(),
        };
        loopback.ip_config.nameservers = match netconfig.static_dns_servers() {
            Ok(nameservers) => nameservers,
            Err(e) => {
                let msg = format!("Error when parsing static DNS servers: {e}");
                if !settings.continue_migration {
                    return Err(anyhow::anyhow!(
                        "{}, use the `--continue-migration` flag to ignore",
                        msg
                    )
                    .into());
                } else {
                    log::warn!("{msg}");
                    vec![]
                }
            }
        };
        if let Some(static_dns_searchlist) = &netconfig.static_dns_searchlist {
            loopback.ip_config.dns_searchlist = static_dns_searchlist.clone();
        }

        state.add_connection(loopback)?;

        apply_dns_policy(&netconfig, &mut state)?;

        // When a connection didn't get a dns priority it means it wasn't matched by the netconfig policy,
        // so ignore-auto-dns should be set to true.
        for con in state.connections.iter_mut() {
            if con.id != "lo"
                && con.ip_config.dns_priority4.is_none()
                && con.ip_config.dns_priority6.is_none()
            {
                con.ip_config.ignore_auto_dns = true;
            }
        }
    }

    nm.write(&state).await?;
    Ok(())
}
0707010000000B000081A4000000000000000000000001689C733A0000317D000000000000000000000000000000000000002100000000wicked2nm-1.2.1/src/netconfig.rsuse agama_network::{model::Connection, NetworkState};
use globset::Glob;
use serde::{Deserialize, Serialize};
use std::{net::IpAddr, path::Path, str::FromStr};

#[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct Netconfig {
    pub static_dns_servers: Option<Vec<String>>,
    pub static_dns_searchlist: Option<Vec<String>>,
    pub dns_policy: Vec<String>,
}

impl Netconfig {
    pub fn static_dns_servers(&self) -> Result<Vec<IpAddr>, std::net::AddrParseError> {
        if let Some(static_dns_servers) = &self.static_dns_servers {
            static_dns_servers
                .iter()
                .map(|x| IpAddr::from_str(x))
                .collect()
        } else {
            Ok(vec![])
        }
    }
}

pub fn read_netconfig(path: impl AsRef<Path>) -> Result<Option<Netconfig>, anyhow::Error> {
    if let Err(e) = dotenv::from_filename(path) {
        return Err(e.into());
    };
    handle_netconfig_values()
}

fn handle_netconfig_values() -> Result<Option<Netconfig>, anyhow::Error> {
    let mut netconfig = Netconfig::default();
    if let Ok(dns_policy) = dotenv::var("NETCONFIG_DNS_POLICY") {
        if dns_policy == "auto" {
            netconfig.dns_policy = vec!["STATIC".to_string(), "*".to_string()];
        } else if !dns_policy.is_empty() {
            if dns_policy.contains(&"STATIC_FALLBACK".to_string()) {
                anyhow::bail!("NETCONFIG_DNS_POLICY \"STATIC_FALLBACK\" is not supported");
            }

            netconfig.dns_policy = dns_policy.split(' ').map(|s| s.to_string()).collect();
        }
    }
    if let Ok(static_dns_servers) = dotenv::var("NETCONFIG_DNS_STATIC_SERVERS") {
        if !static_dns_servers.is_empty() {
            netconfig.static_dns_servers = Some(
                static_dns_servers
                    .split(' ')
                    .map(|s| s.to_string())
                    .collect::<Vec<String>>(),
            );
        }
    }
    if let Ok(static_dns_searchlist) = dotenv::var("NETCONFIG_DNS_STATIC_SEARCHLIST") {
        if !static_dns_searchlist.is_empty() {
            netconfig.static_dns_searchlist = Some(
                static_dns_searchlist
                    .split(' ')
                    .map(|s| s.to_string())
                    .collect::<Vec<String>>(),
            );
        }
    }
    Ok(Some(netconfig))
}

pub fn apply_dns_policy(
    netconfig: &Netconfig,
    nm_state: &mut NetworkState,
) -> Result<(), anyhow::Error> {
    // Start at 10 because 0 is special global default in NM
    // and increase by 10 to give room for future changes.
    let mut i: i32 = 10;
    for policy in &netconfig.dns_policy {
        match policy.as_str() {
            "" => continue,
            "STATIC" => {
                let Some(loopback) = nm_state.get_connection_mut("lo") else {
                    anyhow::bail!("Failed to get loopback connection");
                };
                loopback.ip_config.dns_priority4 = Some(i);
                loopback.ip_config.dns_priority6 = Some(i);
            }
            _ => {
                let glob = Glob::new(policy)?.compile_matcher();
                for con in nm_state
                    .connections
                    .iter_mut()
                    .filter(|c| {
                        c.interface
                            .as_ref()
                            .is_some_and(|c_iface| glob.is_match(c_iface))
                            && c.ip_config.dns_priority4.is_none()
                            && c.ip_config.dns_priority6.is_none()
                    })
                    .collect::<Vec<&mut Connection>>()
                {
                    con.ip_config.dns_priority4 = Some(i);
                    con.ip_config.dns_priority6 = Some(i);
                }
            }
        }

        i += 10;
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use agama_network::model::Connection;

    use super::*;
    use std::env;

    #[test]
    fn test_handle_netconfig_values() {
        env::set_var("NETCONFIG_DNS_POLICY", "STATIC_FALLBACK NetworkManager");
        assert!(handle_netconfig_values().is_err());

        env::set_var("NETCONFIG_DNS_POLICY", "STATIC_FALLBACK");
        assert!(handle_netconfig_values().is_err());

        env::set_var("NETCONFIG_DNS_POLICY", "");
        env::set_var(
            "NETCONFIG_DNS_STATIC_SERVERS",
            "192.168.0.10 192.168.1.10 2001:db8::10",
        );
        env::set_var("NETCONFIG_DNS_STATIC_SEARCHLIST", "suse.com suse.de");
        assert!(handle_netconfig_values()
            .unwrap()
            .unwrap()
            .dns_policy
            .is_empty());

        env::set_var("NETCONFIG_DNS_POLICY", "STATIC");
        assert_eq!(
            handle_netconfig_values().unwrap(),
            Some(Netconfig {
                static_dns_servers: Some(vec![
                    "192.168.0.10".to_string(),
                    "192.168.1.10".to_string(),
                    "2001:db8::10".to_string()
                ]),
                static_dns_searchlist: Some(vec!["suse.com".to_string(), "suse.de".to_string()]),
                dns_policy: vec!["STATIC".to_string()]
            })
        );

        env::set_var("NETCONFIG_DNS_POLICY", "");
        env::set_var("NETCONFIG_DNS_STATIC_SERVERS", "");
        env::set_var("NETCONFIG_DNS_STATIC_SEARCHLIST", "");
        assert_eq!(
            handle_netconfig_values().unwrap(),
            Some(Netconfig {
                static_dns_servers: None,
                static_dns_searchlist: None,
                ..Default::default()
            })
        );

        env::set_var("NETCONFIG_DNS_POLICY", "auto");
        assert_eq!(
            handle_netconfig_values().unwrap().unwrap().dns_policy,
            vec!["STATIC".to_string(), "*".to_string(),]
        );

        env::set_var("NETCONFIG_DNS_POLICY", "STATIC eth* ppp?");
        assert_eq!(
            handle_netconfig_values().unwrap().unwrap().dns_policy,
            vec!["STATIC".to_string(), "eth*".to_string(), "ppp?".to_string()]
        );
    }

    #[test]
    fn test_apply_dns_policy() {
        let netconfig = Netconfig {
            dns_policy: vec![
                "STATIC".to_string(),
                "e???".to_string(),
                "ppp?".to_string(),
                "eth0.??".to_string(),
                "eth*".to_string(),
                "wlan?".to_string(),
            ],
            ..Default::default()
        };
        let mut nm_state = NetworkState::default();
        // Should match with e???
        assert!(nm_state
            .add_connection(Connection {
                id: "eth0".to_string(),
                interface: Some("eth0".to_string()),
                ..Default::default()
            })
            .is_ok());
        // Should match with eth0.??
        assert!(nm_state
            .add_connection(Connection {
                id: "eth0.11".to_string(),
                interface: Some("eth0.11".to_string()),
                ..Default::default()
            })
            .is_ok());
        // Should match with eth*
        assert!(nm_state
            .add_connection(Connection {
                id: "eth0211".to_string(),
                interface: Some("eth0211".to_string()),
                ..Default::default()
            })
            .is_ok());
        // Should not match
        assert!(nm_state
            .add_connection(Connection {
                id: "neth0".to_string(),
                interface: Some("neth0".to_string()),
                ..Default::default()
            })
            .is_ok());
        // Should match with ppp?
        assert!(nm_state
            .add_connection(Connection {
                id: "ppp0".to_string(),
                interface: Some("ppp0".to_string()),
                ..Default::default()
            })
            .is_ok());
        // Should not match
        assert!(nm_state
            .add_connection(Connection {
                id: "en0".to_string(),
                interface: Some("en0".to_string()),
                ..Default::default()
            })
            .is_ok());
        // Should match with wlan?
        assert!(nm_state
            .add_connection(Connection {
                id: "wlan0-0".to_string(),
                interface: Some("wlan0".to_string()),
                ..Default::default()
            })
            .is_ok());
        // Should match with wlan?
        assert!(nm_state
            .add_connection(Connection {
                id: "wlan0-1".to_string(),
                interface: Some("wlan0".to_string()),
                ..Default::default()
            })
            .is_ok());
        // Missing loopback
        assert!(apply_dns_policy(&netconfig, &mut nm_state).is_err());

        assert!(nm_state
            .add_connection(Connection {
                id: "lo".to_string(),
                config: agama_network::model::ConnectionConfig::Loopback,
                ..Default::default()
            })
            .is_ok());
        assert!(apply_dns_policy(&netconfig, &mut nm_state).is_ok());
        assert_eq!(
            nm_state
                .get_connection("lo")
                .unwrap()
                .ip_config
                .dns_priority4,
            Some(10)
        );
        assert_eq!(
            nm_state
                .get_connection("lo")
                .unwrap()
                .ip_config
                .dns_priority6,
            Some(10)
        );
        assert_eq!(
            nm_state
                .get_connection("eth0")
                .unwrap()
                .ip_config
                .dns_priority4,
            Some(20)
        );
        assert_eq!(
            nm_state
                .get_connection("eth0")
                .unwrap()
                .ip_config
                .dns_priority6,
            Some(20)
        );
        assert_eq!(
            nm_state
                .get_connection("eth0.11")
                .unwrap()
                .ip_config
                .dns_priority4,
            Some(40)
        );
        assert_eq!(
            nm_state
                .get_connection("eth0.11")
                .unwrap()
                .ip_config
                .dns_priority6,
            Some(40)
        );
        assert_eq!(
            nm_state
                .get_connection("eth0211")
                .unwrap()
                .ip_config
                .dns_priority4,
            Some(50)
        );
        assert_eq!(
            nm_state
                .get_connection("eth0211")
                .unwrap()
                .ip_config
                .dns_priority6,
            Some(50)
        );
        assert_eq!(
            nm_state
                .get_connection("neth0")
                .unwrap()
                .ip_config
                .dns_priority4,
            None
        );
        assert_eq!(
            nm_state
                .get_connection("neth0")
                .unwrap()
                .ip_config
                .dns_priority6,
            None
        );
        assert_eq!(
            nm_state
                .get_connection("ppp0")
                .unwrap()
                .ip_config
                .dns_priority4,
            Some(30)
        );
        assert_eq!(
            nm_state
                .get_connection("ppp0")
                .unwrap()
                .ip_config
                .dns_priority6,
            Some(30)
        );
        assert_eq!(
            nm_state
                .get_connection("wlan0-0")
                .unwrap()
                .ip_config
                .dns_priority4,
            Some(60)
        );
        assert_eq!(
            nm_state
                .get_connection("wlan0-0")
                .unwrap()
                .ip_config
                .dns_priority6,
            Some(60)
        );
        assert_eq!(
            nm_state
                .get_connection("wlan0-1")
                .unwrap()
                .ip_config
                .dns_priority4,
            Some(60)
        );
        assert_eq!(
            nm_state
                .get_connection("wlan0-1")
                .unwrap()
                .ip_config
                .dns_priority6,
            Some(60)
        );
        assert_eq!(
            nm_state
                .get_connection("en0")
                .unwrap()
                .ip_config
                .dns_priority4,
            None
        );
        assert_eq!(
            nm_state
                .get_connection("en0")
                .unwrap()
                .ip_config
                .dns_priority6,
            None
        );
    }
}
0707010000000C000081A4000000000000000000000001689C733A000004F8000000000000000000000000000000000000002600000000wicked2nm-1.2.1/src/netconfig_dhcp.rsuse serde::Serialize;
use std::path::Path;

#[derive(Debug, Default, PartialEq, Serialize)]
pub struct NetconfigDhcp {
    pub dhclient_hostname_option: HostnameOption,
    pub dhclient6_hostname_option: HostnameOption,
}

#[derive(Default, Debug, PartialEq, Serialize)]
pub enum HostnameOption {
    #[default]
    Empty,
    Auto,
    Value(String),
}

impl From<String> for HostnameOption {
    fn from(s: String) -> Self {
        match s.as_str() {
            "" => Self::Empty,
            "AUTO" => Self::Auto,
            _ => Self::Value(s),
        }
    }
}

pub fn read_netconfig_dhcp(path: impl AsRef<Path>) -> Result<NetconfigDhcp, anyhow::Error> {
    if let Err(e) = dotenv::from_filename(path) {
        return Err(e.into());
    };
    Ok(handle_netconfig_dhcp_values())
}

fn handle_netconfig_dhcp_values() -> NetconfigDhcp {
    let mut netconfig_dhcp = NetconfigDhcp::default();
    if let Ok(dhclient_hostname_option) = dotenv::var("DHCLIENT_HOSTNAME_OPTION") {
        netconfig_dhcp.dhclient_hostname_option = dhclient_hostname_option.into();
    }
    if let Ok(dhclient6_hostname_option) = dotenv::var("DHCLIENT6_HOSTNAME_OPTION") {
        netconfig_dhcp.dhclient6_hostname_option = dhclient6_hostname_option.into();
    }
    netconfig_dhcp
}
0707010000000D000081A4000000000000000000000001689C733A00000156000000000000000000000000000000000000001B00000000wicked2nm-1.2.1/src/ovs.rsuse serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;

#[skip_serializing_none()]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct OvsBridge {
    pub vlan: Option<OvsBridgeVlan>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct OvsBridgeVlan {
    pub parent: String,
    pub tag: u16,
}
0707010000000E000081A4000000000000000000000001689C733A00002C17000000000000000000000000000000000000001E00000000wicked2nm-1.2.1/src/reader.rsuse crate::interface::Interface;
use crate::netconfig::{read_netconfig, Netconfig};
use crate::netconfig_dhcp::{read_netconfig_dhcp, NetconfigDhcp};
use crate::MIGRATION_SETTINGS;

use regex::Regex;
use std::fs::{self, read_dir};
use std::io::{self};
use std::path::{Path, PathBuf};

pub struct InterfacesResult {
    pub interfaces: Vec<Interface>,
    pub netconfig: Option<Netconfig>,
    pub netconfig_dhcp: Option<NetconfigDhcp>,
    pub warning: Option<anyhow::Error>,
}

pub fn read_xml_file(path: PathBuf) -> Result<InterfacesResult, anyhow::Error> {
    let contents = match fs::read_to_string(path.clone()) {
        Ok(contents) => contents,
        Err(e) => {
            return Err(anyhow::anyhow!(
                "Couldn't read {}: {}",
                path.as_path().display(),
                e
            ))
        }
    };
    deserialize_xml(contents)
}

pub fn deserialize_xml(contents: String) -> Result<InterfacesResult, anyhow::Error> {
    let replaced_string = replace_colons(contents.as_str());
    let deserializer = &mut quick_xml::de::Deserializer::from_str(replaced_string.as_str());
    let mut unhandled_fields = vec![];
    let interfaces: Vec<Interface> = match serde_ignored::deserialize(deserializer, |path| {
        unhandled_fields.push(path.to_string())
    }) {
        Ok(interfaces) => interfaces,
        Err(e) => {
            let deserializer2 =
                &mut quick_xml::de::Deserializer::from_str(replaced_string.as_str());
            let res: Result<Vec<Interface>, _> = serde_path_to_error::deserialize(deserializer2);
            if let Err(path_error) = res {
                log::error!("Error at {}: {}", path_error.path(), e);
            }
            return Err(e.into());
        }
    };
    let mut result = InterfacesResult {
        interfaces,
        netconfig: None,
        netconfig_dhcp: None,
        warning: None,
    };
    if !unhandled_fields.is_empty() {
        for unused_str in unhandled_fields {
            let split_str = unused_str.split_once('.').unwrap();
            log::warn!(
                "Unhandled field in interface {}: {}",
                result.interfaces[split_str.0.parse::<usize>().unwrap()].name,
                split_str.1
            );
        }
        result.warning = Some(anyhow::anyhow!(
            "Unhandled fields, use the `--continue-migration` flag to ignore"
        ))
    }
    Ok(result)
}

fn replace_colons(colon_string: &str) -> String {
    let re = Regex::new(r"<([\/]?)(\w+):(\w+)\b").unwrap();
    let replaced = re.replace_all(colon_string, "<$1$2-$3").to_string();
    replaced
}

// https://stackoverflow.com/a/76820878
fn recurse_files(path: impl AsRef<Path>) -> std::io::Result<Vec<PathBuf>> {
    let mut buf = vec![];
    let entries = read_dir(path)?;

    for entry in entries {
        let entry = entry?;
        let meta = entry.metadata()?;

        if meta.is_dir() {
            let mut subdir = recurse_files(entry.path())?;
            buf.append(&mut subdir);
        }

        if meta.is_file() {
            buf.push(entry.path());
        }
    }

    Ok(buf)
}

pub fn read(paths: Vec<String>) -> Result<InterfacesResult, anyhow::Error> {
    let settings = MIGRATION_SETTINGS.get().unwrap();

    let mut result = if paths.len() == 1 && paths[0] == "-" {
        deserialize_xml(io::read_to_string(io::stdin())?)?
    } else {
        read_files(paths)?
    };

    if settings.with_netconfig {
        match read_netconfig(settings.netconfig_path.clone()) {
            Ok(netconfig) => result.netconfig = netconfig,
            Err(e) => {
                let msg = format!(
                    "Failed to read netconfig at {}: {}",
                    settings.netconfig_path, e
                );
                if !settings.continue_migration {
                    anyhow::bail!("{}, use the `--continue-migration` flag to ignore", msg);
                };
                log::warn!("{msg}");
            }
        };
        match read_netconfig_dhcp(settings.netconfig_dhcp_path.clone()) {
            Ok(netconfig_dhcp) => result.netconfig_dhcp = Some(netconfig_dhcp),
            Err(e) => {
                let msg = format!(
                    "Failed to read netconfig_dhcp at {}: {}",
                    settings.netconfig_dhcp_path, e
                );
                if !settings.continue_migration {
                    anyhow::bail!("{}, use the `--continue-migration` flag to ignore", msg);
                };
                log::warn!("{msg}");
            }
        };
    }

    // Filter loopback as it doesn't need to be migrated
    result.interfaces.retain(|interface| interface.name != "lo");

    Ok(result)
}

fn read_files(file_paths: Vec<String>) -> Result<InterfacesResult, anyhow::Error> {
    let mut result = InterfacesResult {
        interfaces: vec![],
        netconfig: None,
        netconfig_dhcp: None,
        warning: None,
    };

    for path in file_paths {
        let path: PathBuf = path.into();
        if path.is_dir() {
            let files = recurse_files(path)?;
            for file in files {
                match file.extension() {
                    None => continue,
                    Some(ext) => {
                        if !ext.eq("xml") {
                            continue;
                        }
                    }
                }
                let mut read_xml = read_xml_file(file)?;
                if result.warning.is_none() && read_xml.warning.is_some() {
                    result.warning = read_xml.warning
                }
                result.interfaces.append(&mut read_xml.interfaces);
            }
        } else {
            let mut read_xml = read_xml_file(path)?;
            if result.warning.is_none() && read_xml.warning.is_some() {
                result.warning = read_xml.warning
            }
            result.interfaces.append(&mut read_xml.interfaces);
        }
    }
    Ok(result)
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::bond::*;

    #[test]
    fn test_bond_options_from_xml() {
        let xml = r##"
            <interface>
                <name>bond0</name>
                <bond>
                    <mode>active-backup</mode>
                    <xmit-hash-policy>layer34</xmit-hash-policy>
                    <fail-over-mac>none</fail-over-mac>
                    <packets-per-slave>1</packets-per-slave>
                    <tlb-dynamic-lb>true</tlb-dynamic-lb>
                    <lacp-rate>slow</lacp-rate>
                    <ad-select>bandwidth</ad-select>
                    <ad-user-port-key>5</ad-user-port-key>
                    <ad-actor-sys-prio>7</ad-actor-sys-prio>
                    <ad-actor-system>00:de:ad:be:ef:00</ad-actor-system>
                    <min-links>11</min-links>
                    <primary-reselect>better</primary-reselect>
                    <num-grat-arp>13</num-grat-arp>
                    <num-unsol-na>17</num-unsol-na>
                    <lp-interval>19</lp-interval>
                    <resend-igmp>23</resend-igmp>
                    <all-slaves-active>true</all-slaves-active>
                    <miimon>
                        <frequency>23</frequency>
                        <updelay>27</updelay>
                        <downdelay>31</downdelay>
                        <carrier-detect>ioctl</carrier-detect>
                    </miimon>
                    <arpmon>
                        <interval>23</interval>
                        <validate>filter_backup</validate>
                        <validate-targets>any</validate-targets>
                        <targets>
                            <ipv4-address>1.2.3.4</ipv4-address>
                            <ipv4-address>4.3.2.1</ipv4-address>
                        </targets>
                    </arpmon>
                    <address>02:11:22:33:44:55</address>
                    <primary>en0</primary>
                </bond>
            </interface>
            "##;
        let ifc = deserialize_xml(xml.to_string())
            .unwrap()
            .interfaces
            .pop()
            .unwrap();
        assert!(ifc.bond.is_some());
        let bond = ifc.bond.unwrap();

        assert_eq!(
            bond,
            Bond {
                mode: WickedBondMode::ActiveBackup,
                xmit_hash_policy: Some(XmitHashPolicy::Layer34),
                fail_over_mac: Some(FailOverMac::None),
                packets_per_slave: Some(1),
                tlb_dynamic_lb: Some(true),
                lacp_rate: Some(LacpRate::Slow),
                ad_select: Some(AdSelect::Bandwidth),
                ad_user_port_key: Some(5),
                ad_actor_sys_prio: Some(7),
                ad_actor_system: Some(String::from("00:de:ad:be:ef:00")),
                min_links: Some(11),
                primary_reselect: Some(PrimaryReselect::Better),
                num_grat_arp: Some(13),
                num_unsol_na: Some(17),
                lp_interval: Some(19),
                resend_igmp: Some(23),
                all_slaves_active: Some(true),
                miimon: Some(Miimon {
                    frequency: 23,
                    carrier_detect: CarrierDetect::Ioctl,
                    downdelay: Some(31),
                    updelay: Some(27),
                }),
                arpmon: Some(ArpMon {
                    interval: 23,
                    validate: ArpValidate::FilterBackup,
                    validate_targets: Some(ArpValidateTargets::Any),
                    targets: vec![String::from("1.2.3.4"), String::from("4.3.2.1")]
                }),
                address: Some(String::from("02:11:22:33:44:55")),
                primary: Some(String::from("en0")),
            }
        );
    }

    /// This test check that the default for stp from wicked is False.
    #[test]
    fn test_bridge_default_stp() {
        let xml = r##"
            <interface>
              <name>br0</name>
              <bridge>
                <ports>
                  <port>
                    <device>en0</device>
                  </port>
                </ports>
              </bridge>
            </interface>
            "##;
        let ifc = deserialize_xml(xml.to_string())
            .unwrap()
            .interfaces
            .pop()
            .unwrap();
        assert!(ifc.bridge.is_some());
        assert!(!ifc.bridge.unwrap().stp);
    }

    #[test]
    fn test_broken_xml() {
        let xml = r##"
            <interface>
                <name>eth1</name>
                <ipv4:static>
                  <address>127.0.0.1</>
                </ipv4:static>
            </interface>
            "##;
        let err = deserialize_xml(xml.to_string());
        assert!(err.is_err());
    }

    #[test]
    fn test_xml_firewall_zone() {
        let xml = r##"
            <interface>
                <name>eth1</name>
                <firewall>
                    <zone>foo</zone>
                </firewall>
            </interface>
            "##;

        let ifc = deserialize_xml(xml.to_string())
            .unwrap()
            .interfaces
            .pop()
            .unwrap();
        assert_eq!(ifc.firewall.zone, Some("foo".to_string()));
    }
}
0707010000000F000081A4000000000000000000000001689C733A0000045E000000000000000000000000000000000000001E00000000wicked2nm-1.2.1/src/tuntap.rsuse agama_network::model;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;

#[skip_serializing_none]
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Tun {
    pub owner: Option<u32>,
    pub group: Option<u32>,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Tap {
    pub owner: Option<u32>,
    pub group: Option<u32>,
}

impl From<&Tun> for model::ConnectionConfig {
    fn from(tuntap: &Tun) -> model::ConnectionConfig {
        model::ConnectionConfig::Tun(model::TunConfig {
            mode: model::TunMode::Tun,
            group: tuntap.group.map(|v| v.to_string()),
            owner: tuntap.owner.map(|v| v.to_string()),
        })
    }
}

impl From<&Tap> for model::ConnectionConfig {
    fn from(tuntap: &Tap) -> model::ConnectionConfig {
        model::ConnectionConfig::Tun(model::TunConfig {
            mode: model::TunMode::Tap,
            group: tuntap.group.map(|v| v.to_string()),
            owner: tuntap.owner.map(|v| v.to_string()),
        })
    }
}
07070100000010000081A4000000000000000000000001689C733A00000B2C000000000000000000000000000000000000001C00000000wicked2nm-1.2.1/src/vlan.rsuse agama_network::model;
use serde::{Deserialize, Serialize};
use serde_with::{skip_serializing_none, DeserializeFromStr, SerializeDisplay};
use strum_macros::{Display, EnumString};

#[derive(
    Debug, Clone, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display, Default,
)]
#[strum(serialize_all = "kebab_case")]
pub enum WickedVlanProtocol {
    #[default]
    #[strum(serialize = "ieee802-1Q")]
    Ieee802_1Q,
    Ieee802Ad,
}

#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Vlan {
    pub device: String,
    pub address: Option<String>,
    #[serde(default)]
    pub protocol: WickedVlanProtocol,
    pub tag: u16,
}

impl From<&Vlan> for model::ConnectionConfig {
    fn from(vlan: &Vlan) -> model::ConnectionConfig {
        model::ConnectionConfig::Vlan(model::VlanConfig {
            parent: vlan.device.clone(),
            id: (vlan.tag as u32),
            protocol: (&vlan.protocol).into(),
        })
    }
}

impl From<&WickedVlanProtocol> for model::VlanProtocol {
    fn from(v: &WickedVlanProtocol) -> model::VlanProtocol {
        match v {
            WickedVlanProtocol::Ieee802_1Q => model::VlanProtocol::IEEE802_1Q,
            WickedVlanProtocol::Ieee802Ad => model::VlanProtocol::IEEE802_1ad,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::interface::*;
    use crate::MIGRATION_SETTINGS;

    #[allow(dead_code)]
    fn setup_default_migration_settings() {
        let _ = MIGRATION_SETTINGS.set(crate::MigrationSettings::default());
    }

    #[test]
    fn test_vlan_protocol() {
        setup_default_migration_settings();
        let v: WickedVlanProtocol = Default::default();
        assert_eq!(v, WickedVlanProtocol::Ieee802_1Q);
        assert_eq!(v.to_string(), String::from("ieee802-1Q"));
        let v = WickedVlanProtocol::Ieee802Ad;
        assert_eq!(v.to_string(), String::from("ieee802-ad"));
    }

    #[test]
    fn test_vlan_interface() {
        setup_default_migration_settings();
        let vlan_interface = Interface {
            vlan: Some(Vlan {
                device: String::from("en0"),
                tag: 10,
                protocol: WickedVlanProtocol::Ieee802Ad,
                address: Some(String::from("02:11:22:33:44:55")),
            }),
            ..Default::default()
        };

        let ifc = vlan_interface.to_connection(&None);

        assert!(ifc.is_ok());
        let ifc = &ifc.unwrap().connections[0];
        assert!(matches!(ifc.config, model::ConnectionConfig::Vlan(_)));
        if let model::ConnectionConfig::Vlan(v) = &ifc.config {
            assert_eq!(v.id, 10);
            assert_eq!(v.protocol, model::VlanProtocol::IEEE802_1ad);
            assert_eq!(v.parent, "en0");
        }

        assert_eq!(ifc.custom_mac_address.to_string(), "02:11:22:33:44:55");
    }
}
07070100000011000081A4000000000000000000000001689C733A00006BF5000000000000000000000000000000000000002000000000wicked2nm-1.2.1/src/wireless.rsuse crate::MIGRATION_SETTINGS;
use agama_network::model::{self, WEPAuthAlg, WEPKeyType, WEPSecurity};
use agama_network::types::SSID;
use anyhow::anyhow;
use macaddr::MacAddr6;
use serde::{Deserialize, Deserializer, Serialize};
use serde_with::formats::CommaSeparator;
use serde_with::StringWithSeparator;
use serde_with::{serde_as, skip_serializing_none, DeserializeFromStr, SerializeDisplay};
use std::str::FromStr;
use strum_macros::{Display, EnumString};

#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Wireless {
    #[serde(rename = "ap-scan")]
    pub ap_scan: u32,
    #[serde(default)]
    #[serde(deserialize_with = "unwrap_wireless_networks")]
    pub networks: Option<Vec<Network>>,
}

#[serde_as]
#[skip_serializing_none]
#[derive(Debug, PartialEq, Serialize, Deserialize, Default)]
pub struct Network {
    pub essid: String,
    #[serde(rename = "scan-ssid")]
    pub scan_ssid: bool,
    pub mode: WickedWirelessMode,
    #[serde(rename = "wpa-psk")]
    pub wpa_psk: Option<WpaPsk>,
    #[serde(default)]
    #[serde(rename = "key-management")]
    #[serde_as(as = "StringWithSeparator::<CommaSeparator, String>")]
    pub key_management: Vec<String>,
    pub channel: Option<u32>,
    #[serde(rename = "access-point")]
    pub access_point: Option<String>,
    pub wep: Option<Wep>,
    #[serde(rename = "wpa-eap")]
    pub wpa_eap: Option<WpaEap>,
}

#[derive(Default, Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "kebab-case")]
pub enum WickedWirelessMode {
    AdHoc = 0,
    #[default]
    Infrastructure = 1,
    AP = 2,
}

impl From<&WickedWirelessMode> for model::WirelessMode {
    fn from(value: &WickedWirelessMode) -> Self {
        match value {
            WickedWirelessMode::AdHoc => model::WirelessMode::AdHoc,
            WickedWirelessMode::Infrastructure => model::WirelessMode::Infra,
            WickedWirelessMode::AP => model::WirelessMode::AP,
        }
    }
}

#[serde_as]
#[derive(Debug, PartialEq, Serialize, Deserialize, Default)]
pub struct WpaPsk {
    pub passphrase: String,
    #[serde(rename = "auth-proto", skip_serializing_if = "Vec::is_empty", default)]
    #[serde_as(as = "StringWithSeparator::<CommaSeparator, EapAuthProto>")]
    pub auth_proto: Vec<EapAuthProto>,
    #[serde(
        rename = "pairwise-cipher",
        skip_serializing_if = "Vec::is_empty",
        default
    )]
    #[serde_as(as = "StringWithSeparator::<CommaSeparator, EapPairwiseCipher>")]
    pub pairwise_cipher: Vec<EapPairwiseCipher>,
    #[serde(
        rename = "group-cipher",
        skip_serializing_if = "Vec::is_empty",
        default
    )]
    #[serde_as(as = "StringWithSeparator::<CommaSeparator, EapGroupCipher>")]
    pub group_cipher: Vec<EapGroupCipher>,
    pub pmf: Option<Pmf>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Wep {
    #[serde(rename = "auth-algo")]
    pub auth_algo: String,
    #[serde(rename = "default-key")]
    pub default_key: u32,
    pub key: Vec<String>,
}

#[serde_as]
#[derive(Debug, PartialEq, Serialize, Deserialize, Default)]
pub struct WpaEap {
    pub method: WickedEapMethods,
    pub identity: Option<String>,
    pub phase1: Option<Phase1>,
    pub phase2: Option<Phase2>,
    pub anonid: Option<String>,
    pub tls: Option<EapTLS>,
    #[serde(rename = "auth-proto", skip_serializing_if = "Vec::is_empty", default)]
    #[serde_as(as = "StringWithSeparator::<CommaSeparator, EapAuthProto>")]
    pub auth_proto: Vec<EapAuthProto>,
    #[serde(
        rename = "pairwise-cipher",
        skip_serializing_if = "Vec::is_empty",
        default
    )]
    #[serde_as(as = "StringWithSeparator::<CommaSeparator, EapPairwiseCipher>")]
    pub pairwise_cipher: Vec<EapPairwiseCipher>,
    #[serde(
        rename = "group-cipher",
        skip_serializing_if = "Vec::is_empty",
        default
    )]
    #[serde_as(as = "StringWithSeparator::<CommaSeparator, EapGroupCipher>")]
    pub group_cipher: Vec<EapGroupCipher>,
    pub pmf: Option<Pmf>,
}

impl TryFrom<&WpaEap> for model::IEEE8021XConfig {
    type Error = anyhow::Error;

    fn try_from(value: &WpaEap) -> Result<Self, Self::Error> {
        let eap: Vec<model::EAPMethod> = vec![value.method.try_into()?];
        let mut config = model::IEEE8021XConfig {
            eap,
            identity: value.identity.clone(),
            anonymous_identity: value.anonid.clone(),
            ..Default::default()
        };

        if let Some(phase1) = &value.phase1 {
            if let Some(peap_label) = phase1.peap_label {
                config.peap_label = peap_label;
            }
            if let Some(peap_version) = phase1.peap_version {
                config.peap_version = Some(peap_version.to_string());
            }
        }

        if let Some(phase2) = &value.phase2 {
            if let Some(method) = phase2.method {
                config.phase2_auth = Some(method.try_into()?);
            }
            if let Some(password) = &phase2.password {
                config.password = Some(password.to_string());
            }
        }

        if let Some(tls) = &value.tls {
            if let Some(ca_cert) = &tls.ca_cert {
                config.ca_cert = Some(wicked_cert_to_path(ca_cert)?);
            }
            if let Some(client_cert) = &tls.client_cert {
                config.client_cert = Some(wicked_cert_to_path(client_cert)?);
            }
            if let Some(client_key) = &tls.client_key {
                config.private_key = Some(wicked_cert_to_path(client_key)?);
            }
            config.private_key_password = tls.client_key_passwd.clone();
        }

        Ok(config)
    }
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Phase1 {
    #[serde(rename = "peap-version")]
    pub peap_version: Option<u32>,
    #[serde(rename = "peap-label")]
    pub peap_label: Option<bool>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Phase2 {
    pub method: Option<WickedEapMethods>,
    pub password: Option<String>,
}

#[derive(
    Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display, Clone, Copy,
)]
#[strum(serialize_all = "lowercase")]
pub enum Pmf {
    Disabled = 1,
    Optional = 2,
    Required = 3,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "snake_case")]
pub enum EapAuthProto {
    Wpa,
    Rsn,
}

impl From<&EapAuthProto> for model::WPAProtocolVersion {
    fn from(value: &EapAuthProto) -> Self {
        match value {
            EapAuthProto::Wpa => Self::Wpa,
            EapAuthProto::Rsn => Self::Rsn,
        }
    }
}

#[derive(
    Debug,
    PartialEq,
    SerializeDisplay,
    DeserializeFromStr,
    EnumString,
    Display,
    Clone,
    Copy,
    Default,
)]
#[strum(serialize_all = "snake_case")]
pub enum WickedEapMethods {
    Wpa,
    #[default]
    None,
    Md5,
    Tls,
    Pap,
    Chap,
    Mschap,
    Mschapv2,
    Peap,
    Ttls,
    Gtc,
    Otp,
    Leap,
    Psk,
    Pax,
    Sake,
    Gpsk,
    Wsc,
    Ikev2,
    Tnc,
    Fast,
    Aka,
    AkaPrime,
    Sim,
}

impl TryFrom<WickedEapMethods> for model::EAPMethod {
    type Error = anyhow::Error;

    fn try_from(value: WickedEapMethods) -> Result<Self, Self::Error> {
        match value {
            WickedEapMethods::Leap => Ok(Self::LEAP),
            WickedEapMethods::Md5 => Ok(Self::MD5),
            WickedEapMethods::Tls => Ok(Self::TLS),
            WickedEapMethods::Peap => Ok(Self::PEAP),
            WickedEapMethods::Ttls => Ok(Self::TTLS),
            WickedEapMethods::Fast => Ok(Self::FAST),
            _ => Err(anyhow!("Invalid EAP (outer) method")),
        }
    }
}

impl TryFrom<WickedEapMethods> for model::Phase2AuthMethod {
    type Error = anyhow::Error;

    fn try_from(value: WickedEapMethods) -> Result<Self, Self::Error> {
        match value {
            WickedEapMethods::Pap => Ok(Self::PAP),
            WickedEapMethods::Chap => Ok(Self::CHAP),
            WickedEapMethods::Mschap => Ok(Self::MSCHAP),
            WickedEapMethods::Mschapv2 => Ok(Self::MSCHAPV2),
            WickedEapMethods::Gtc => Ok(Self::GTC),
            WickedEapMethods::Otp => Ok(Self::OTP),
            WickedEapMethods::Md5 => Ok(Self::MD5),
            WickedEapMethods::Tls => Ok(Self::TLS),
            _ => Err(anyhow!("Invalid phase 2 (inner) method")),
        }
    }
}

#[allow(non_camel_case_types)]
#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "SCREAMING-KEBAB-CASE")]
pub enum EapPairwiseCipher {
    Tkip,
    Ccmp,
    Ccmp_256,
    Gcmp,
    Gcmp_256,
}

impl TryFrom<&EapPairwiseCipher> for model::PairwiseAlgorithm {
    type Error = anyhow::Error;

    fn try_from(value: &EapPairwiseCipher) -> Result<Self, Self::Error> {
        match value {
            EapPairwiseCipher::Ccmp => Ok(Self::Ccmp),
            EapPairwiseCipher::Tkip => Ok(Self::Tkip),
            _ => Err(anyhow!("EAP pairwise chipher not supported, leaving empty")),
        }
    }
}

#[allow(non_camel_case_types)]
#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "SCREAMING-KEBAB-CASE")]
pub enum EapGroupCipher {
    Tkip,
    Ccmp,
    Ccmp_256,
    Gcmp,
    Gcmp_256,
    Wep104,
    Wep40,
}

impl TryFrom<&EapGroupCipher> for model::GroupAlgorithm {
    type Error = anyhow::Error;

    fn try_from(value: &EapGroupCipher) -> Result<Self, Self::Error> {
        match value {
            EapGroupCipher::Ccmp => Ok(Self::Ccmp),
            EapGroupCipher::Tkip => Ok(Self::Tkip),
            EapGroupCipher::Wep104 => Ok(Self::Wep104),
            EapGroupCipher::Wep40 => Ok(Self::Wep40),
            _ => Err(anyhow!("EAP group cipher not supported, leaving empty")),
        }
    }
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct EapTLS {
    #[serde(rename = "ca-cert")]
    pub ca_cert: Option<WickedCertificate>,
    #[serde(rename = "client-cert")]
    pub client_cert: Option<WickedCertificate>,
    #[serde(rename = "client-key")]
    pub client_key: Option<WickedCertificate>,
    #[serde(rename = "client-key-passwd")]
    pub client_key_passwd: Option<String>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct WickedCertificate {
    #[serde(rename = "$value")]
    pub cert: String,
    #[serde(rename = "@type")]
    pub cert_type: WickedCertType,
}

#[derive(Debug, PartialEq, SerializeDisplay, DeserializeFromStr, EnumString, Display)]
#[strum(serialize_all = "lowercase")]
pub enum WickedCertType {
    Path,
    File,
    Hex,
}

fn wicked_cert_to_path(wicked_cert: &WickedCertificate) -> Result<String, anyhow::Error> {
    if wicked_cert.cert_type == WickedCertType::Hex {
        return Err(anyhow!("Hex certificate type is currently not supported"));
    } else if wicked_cert.cert_type == WickedCertType::File {
        log::info!("Certificate type 'file' may not work as intended");
    }
    Ok(wicked_cert.cert.clone())
}

fn common_settings_to_config(
    auth_protos: &[EapAuthProto],
    pairwise_ciphers: &[EapPairwiseCipher],
    group_ciphers: &[EapGroupCipher],
    pmf: &Option<Pmf>,
    config: &mut model::WirelessConfig,
) {
    config.wpa_protocol_versions = auth_protos
        .iter()
        .map(|x| x.into())
        .collect::<Vec<model::WPAProtocolVersion>>();

    let mut pairwise_algorithms: Vec<model::PairwiseAlgorithm> = vec![];
    for pairwise_cipher in pairwise_ciphers {
        match model::PairwiseAlgorithm::try_from(pairwise_cipher) {
            Ok(algo) => pairwise_algorithms.push(algo),
            Err(e) => {
                log::info!("{e}");
                pairwise_algorithms = vec![];
                break;
            }
        }
    }
    config.pairwise_algorithms = pairwise_algorithms;

    let mut group_algorithms: Vec<model::GroupAlgorithm> = vec![];
    for group_cipher in group_ciphers {
        match model::GroupAlgorithm::try_from(group_cipher) {
            Ok(algo) => group_algorithms.push(algo),
            Err(e) => {
                log::info!("{e}");
                group_algorithms = vec![];
                break;
            }
        }
    }
    config.group_algorithms = group_algorithms;

    if let Some(pmf) = pmf {
        config.pmf = *pmf as i32;
    }
}

fn unwrap_wireless_networks<'de, D>(deserializer: D) -> Result<Option<Vec<Network>>, D::Error>
where
    D: Deserializer<'de>,
{
    #[derive(Debug, PartialEq, Default, Serialize, Deserialize)]
    struct Networks {
        network: Vec<Network>,
    }
    Ok(Some(Networks::deserialize(deserializer)?.network))
}

fn all(array: &[String], needle: &[&str]) -> bool {
    if array.is_empty() {
        return false;
    }

    array.iter().all(|x| needle.iter().any(|&y| x == y))
}

fn any(array: &[String], needle: &[&str]) -> bool {
    if array.is_empty() {
        return false;
    }

    array.iter().any(|x| needle.iter().any(|&y| x == y))
}

fn guess_wireless_security_protocol(
    network: &Network,
) -> Result<model::SecurityProtocol, anyhow::Error> {
    let mgmt = &network.key_management;

    let result = if any(mgmt, &["wpa-eap", "wpa-eap-sha256"]) {
        model::SecurityProtocol::WPA2Enterprise
    } else if any(mgmt, &["wpa-eap-suite-b-192", "wpa-eap-suite-b"]) {
        model::SecurityProtocol::WPA3Only
    } else if any(mgmt, &["wpa-psk", "wpa-psk-sha256"]) {
        model::SecurityProtocol::WPA2
    } else if any(mgmt, &["sae", "ft-sae"]) {
        model::SecurityProtocol::WPA3Personal
    } else if any(mgmt, &["owe"]) {
        model::SecurityProtocol::OWE
    } else if any(mgmt, &["none"]) {
        model::SecurityProtocol::WEP
    } else if network.wpa_eap.is_some() {
        model::SecurityProtocol::WPA2Enterprise
    } else if network.wpa_psk.is_some() {
        model::SecurityProtocol::WPA2
    } else {
        model::SecurityProtocol::WEP
    };
    log::warn!(
        "Unsupported key-management protocol(s) '{}' guessing '{}'",
        mgmt.join(","),
        result
    );
    Ok(result)
}

fn wireless_security_protocol(network: &Network) -> Result<model::SecurityProtocol, anyhow::Error> {
    let mgmt = &network.key_management;

    if all(mgmt, &["sae", "ft-sae"]) {
        Ok(model::SecurityProtocol::WPA3Personal)
    } else if all(mgmt, &["wpa-psk", "wpa-psk-sha256", "sae", "ft-sae"]) {
        Ok(model::SecurityProtocol::WPA2)
    } else if all(mgmt, &["wpa-eap-suite-b-192", "wpa-eap-suite-b"]) {
        Ok(model::SecurityProtocol::WPA3Only)
    } else if all(
        mgmt,
        &[
            "wpa-eap",
            "wpa-eap-sha256",
            "wpa-eap-suite-b-192",
            "wpa-eap-suite-b",
        ],
    ) {
        Ok(model::SecurityProtocol::WPA2Enterprise)
    } else if all(mgmt, &["owe"]) {
        Ok(model::SecurityProtocol::OWE)
    } else if all(mgmt, &["none"]) {
        Ok(model::SecurityProtocol::WEP)
    } else if mgmt.is_empty() {
        if network.wpa_eap.is_some() {
            Ok(model::SecurityProtocol::WPA2Enterprise)
        } else if network.wpa_psk.is_some() {
            Ok(model::SecurityProtocol::WPA2)
        } else {
            Ok(model::SecurityProtocol::WEP)
        }
    } else {
        Err(anyhow!(
            "Unrecognized key-management protocol(s): {}",
            mgmt.join(",")
        ))
    }
}

impl TryFrom<&Network> for model::ConnectionConfig {
    type Error = anyhow::Error;

    fn try_from(network: &Network) -> Result<Self, Self::Error> {
        let settings = MIGRATION_SETTINGS.get().unwrap();
        let mut config = model::WirelessConfig {
            ssid: SSID(network.essid.as_bytes().to_vec()),
            hidden: network.scan_ssid,
            ..Default::default()
        };

        let mut sec = wireless_security_protocol(network);
        if sec.is_err() && settings.continue_migration {
            sec = guess_wireless_security_protocol(network);
        }
        config.security = sec?;

        if let Some(wpa_psk) = &network.wpa_psk {
            config.password = Some(wpa_psk.passphrase.clone());

            common_settings_to_config(
                &wpa_psk.auth_proto,
                &wpa_psk.pairwise_cipher,
                &wpa_psk.group_cipher,
                &wpa_psk.pmf,
                &mut config,
            );
        }
        if let Some(channel) = network.channel {
            config.channel = channel;
            if channel <= 14 {
                config.band = Some(model::WirelessBand::BG);
            } else {
                config.band = Some(model::WirelessBand::A);
            }
            log::warn!(
                "NetworkManager requires setting a band for wireless when a channel is set. The band has been set to \"{}\". This may in certain regions be incorrect.",
                config.band.unwrap()
            );
        }
        if let Some(access_point) = &network.access_point {
            config.bssid = Some(MacAddr6::from_str(access_point)?);
        }

        if let Some(wep) = &network.wep {
            // filter out `s:`, `h:`, `:`, and `-` of wep keys
            let keys: Vec<String> = wep
                .key
                .clone()
                .into_iter()
                .map(|mut x| {
                    x = x.replace("s:", "");
                    x = x.replace("h:", "");
                    x = x.replace(':', "");
                    x.replace('-', "")
                })
                .collect();
            let wep_security = WEPSecurity {
                auth_alg: WEPAuthAlg::try_from(wep.auth_algo.as_str())?,
                wep_key_type: WEPKeyType::Key,
                keys,
                wep_key_index: wep.default_key,
            };
            config.wep_security = Some(wep_security);
        }

        if let Some(wpa_eap) = &network.wpa_eap {
            common_settings_to_config(
                &wpa_eap.auth_proto,
                &wpa_eap.pairwise_cipher,
                &wpa_eap.group_cipher,
                &wpa_eap.pmf,
                &mut config,
            );
        }

        config.mode = (&network.mode).into();
        Ok(model::ConnectionConfig::Wireless(config))
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::interface::*;
    use crate::MIGRATION_SETTINGS;

    #[allow(dead_code)]
    fn setup_default_migration_settings() {
        let _ = MIGRATION_SETTINGS.set(crate::MigrationSettings {
            continue_migration: false,
            dry_run: false,
            activate_connections: true,
            with_netconfig: false,
            netconfig_path: "".to_string(),
            netconfig_dhcp_path: "".to_string(),
        });
    }

    #[test]
    fn test_wireless_bands() {
        setup_default_migration_settings();
        let mut wireless_interface = Interface {
            wireless: Some(Wireless {
                networks: Some(vec![Network {
                    channel: Some(0),
                    essid: "testssid".to_string(),
                    scan_ssid: false,
                    mode: WickedWirelessMode::AP,
                    wpa_psk: None,
                    key_management: vec!["wpa-psk".to_string()],
                    access_point: None,
                    wep: None,
                    wpa_eap: None,
                }]),
                ap_scan: 0,
            }),
            ..Default::default()
        };
        let connections = wireless_interface.to_connection(&None);
        assert!(connections.is_ok());
        let connection = &connections.unwrap().connections[0];
        let model::ConnectionConfig::Wireless(wireless) = &connection.config else {
            panic!()
        };
        assert_eq!(wireless.band, Some("bg".try_into().unwrap()));

        wireless_interface
            .wireless
            .as_mut()
            .unwrap()
            .networks
            .as_mut()
            .unwrap()[0]
            .channel = Some(32);
        let ifc = wireless_interface.to_connection(&None);
        assert!(ifc.is_ok());
        let ifc = &ifc.unwrap().connections[0];
        let model::ConnectionConfig::Wireless(wireless) = &ifc.config else {
            panic!()
        };
        assert_eq!(wireless.band, Some("a".try_into().unwrap()));
    }

    #[test]
    fn test_wireless_migration() {
        setup_default_migration_settings();
        let wireless_interface = Interface {
            wireless: Some(Wireless {
                networks: Some(vec![Network {
                    essid: "testssid".to_string(),
                    scan_ssid: true,
                    mode: WickedWirelessMode::Infrastructure,
                    wpa_psk: Some(WpaPsk {
                        passphrase: "testpassword".to_string(),
                        ..Default::default()
                    }),
                    key_management: vec!["wpa-psk".to_string()],
                    channel: Some(14),
                    access_point: Some("12:34:56:78:9A:BC".to_string()),
                    wep: Some(Wep {
                        auth_algo: "open".to_string(),
                        default_key: 1,
                        key: vec!["01020304ff".to_string(), "s:hello".to_string()],
                    }),
                    wpa_eap: None,
                }]),
                ap_scan: 0,
            }),
            ..Default::default()
        };
        let connections = wireless_interface.to_connection(&None);
        assert!(connections.is_ok());
        let connection = &connections.unwrap().connections[0];
        let model::ConnectionConfig::Wireless(wireless) = &connection.config else {
            panic!()
        };
        assert_eq!(wireless.ssid, SSID("testssid".as_bytes().to_vec()));
        assert!(wireless.hidden);
        assert_eq!(wireless.mode, model::WirelessMode::Infra);
        assert_eq!(wireless.password, Some("testpassword".to_string()));
        assert_eq!(wireless.security, model::SecurityProtocol::WPA2);
        assert_eq!(
            wireless.bssid,
            Some(MacAddr6::from_str("12:34:56:78:9A:BC").unwrap())
        );
        assert_eq!(
            wireless.wep_security,
            Some(WEPSecurity {
                auth_alg: WEPAuthAlg::Open,
                wep_key_type: WEPKeyType::Key,
                keys: vec!["01020304ff".to_string(), "hello".to_string()],
                wep_key_index: 1,
            })
        );
        assert_eq!(wireless.band, Some("bg".try_into().unwrap()));
    }

    #[test]
    fn wireless_security_protocol_strict() {
        setup_default_migration_settings();

        let mut net = Network {
            ..Default::default()
        };

        net.key_management = vec![];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WEP
        );

        net.key_management = vec![];
        net.wpa_eap = Some(WpaEap {
            ..Default::default()
        });

        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2Enterprise
        );

        net.wpa_eap = None;
        net.wpa_psk = Some(WpaPsk {
            ..Default::default()
        });
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2
        );

        net.wpa_psk = None;
        net.key_management = vec!["wpa-psk".to_string()];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2
        );
        net.key_management = vec!["sae".to_string(), "wpa-psk".to_string()];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2
        );
        net.key_management = vec!["sae".to_string()];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA3Personal
        );

        net.key_management = vec!["wpa-eap".to_string()];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2Enterprise
        );
        net.key_management = vec!["wpa-eap".to_string(), "wpa-eap-suite-b".to_string()];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2Enterprise
        );
        net.key_management = vec!["wpa-eap-suite-b".to_string()];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA3Only
        );

        net.key_management = vec!["owe".to_string()];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::OWE
        );

        net.key_management = vec!["none".to_string()];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WEP
        );

        net.key_management = vec!["none".to_string(), "wpa-psk".to_string()];
        assert!(wireless_security_protocol(&net).is_err());
        net.key_management = vec!["wpa-eap".to_string(), "wpa-psk".to_string()];
        assert!(wireless_security_protocol(&net).is_err());
        net.key_management = vec!["wpa-eap".to_string(), "sae".to_string()];
        assert!(wireless_security_protocol(&net).is_err());
        net.key_management = vec!["wpa-eap-suite-b".to_string(), "sae".to_string()];
        assert!(wireless_security_protocol(&net).is_err());
        net.key_management = vec!["wpa-eap-suite-b".to_string(), "owe".to_string()];
        assert!(wireless_security_protocol(&net).is_err());
        net.key_management = vec!["wpa-psk".to_string(), "owe".to_string()];
        assert!(wireless_security_protocol(&net).is_err());
    }

    #[test]
    fn wireless_security_protocol_continue_migration() {
        setup_default_migration_settings();

        let mut net = Network {
            ..Default::default()
        };

        net.key_management = vec![];
        assert_eq!(
            wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WEP
        );

        net.key_management = vec![];
        net.wpa_eap = Some(WpaEap {
            ..Default::default()
        });

        net.key_management = vec!["none".to_string(), "wpa-psk".to_string()];
        assert_eq!(
            guess_wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2
        );
        net.key_management = vec!["wpa-eap".to_string(), "wpa-psk".to_string()];
        assert_eq!(
            guess_wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2Enterprise
        );
        net.key_management = vec!["wpa-eap".to_string(), "sae".to_string()];
        assert_eq!(
            guess_wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2Enterprise
        );
        net.key_management = vec!["wpa-eap-suite-b".to_string(), "sae".to_string()];
        assert_eq!(
            guess_wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA3Only
        );
        net.key_management = vec!["wpa-eap-suite-b".to_string(), "owe".to_string()];
        assert_eq!(
            guess_wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA3Only
        );
        net.key_management = vec!["wpa-psk".to_string(), "owe".to_string()];
        assert_eq!(
            guess_wireless_security_protocol(&net).unwrap(),
            model::SecurityProtocol::WPA2
        );
    }
}
07070100000012000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001600000000wicked2nm-1.2.1/tests07070100000013000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002900000000wicked2nm-1.2.1/tests/bond_active-backup07070100000014000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/bond_active-backup/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.52
07070100000015000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/bond_active-backup/netconfig07070100000016000081A4000000000000000000000001689C733A0000001A000000000000000000000000000000000000003A00000000wicked2nm-1.2.1/tests/bond_active-backup/netconfig/configCHECK_DUPLICATE_IP="yes"

07070100000017000081A4000000000000000000000001689C733A00000038000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/bond_active-backup/netconfig/dhcpDHCLIENT_WAIT_AT_BOOT="15"
DHCLIENT6_WAIT_AT_BOOT="15"

07070100000018000081A4000000000000000000000001689C733A000000CD000000000000000000000000000000000000003F00000000wicked2nm-1.2.1/tests/bond_active-backup/netconfig/ifcfg-bond0STARTMODE=auto
BOOTPROTO=dhcp
BONDING_MASTER=yes
BONDING_SLAVE_1=en0
BONDING_SLAVE_2=en1
BONDING_MODULE_OPTS='mode=active-backup miimon=100 primary=en0'
LLADDR='02:00:33:44:55:11'
FIREWALL=yes
ZONE=public
07070100000019000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003C00000000wicked2nm-1.2.1/tests/bond_active-backup/system-connections0707010000001A000081A4000000000000000000000001689C733A00000212000000000000000000000000000000000000004F00000000wicked2nm-1.2.1/tests/bond_active-backup/system-connections/bond0.nmconnection[connection]
id=bond0
uuid=17e25c83-3b11-49d1-9096-38e97c0fd065
type=bond
autoconnect-ports=1
interface-name=bond0
zone=public

[ethernet]
cloned-mac-address=02:00:33:44:55:11

[bond]
miimon=100
mode=active-backup
primary=en0
use_carrier=1

[match]

[ipv4]
dhcp-send-hostname-deprecated=false
dhcp-send-hostname=0
dhcp-send-release=0
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
dhcp-send-hostname-deprecated=false
dhcp-send-hostname=0
dhcp-send-release=0
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
0707010000001B000081A4000000000000000000000001689C733A00000094000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/bond_active-backup/system-connections/en0.nmconnection[connection]
id=en0
uuid=38d979e6-aa0e-4bae-8cff-a6dda281d0c7
type=ethernet
controller=bond0
interface-name=en0
port-type=bond

[ethernet]

[match]
0707010000001C000081A4000000000000000000000001689C733A00000094000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/bond_active-backup/system-connections/en1.nmconnection[connection]
id=en1
uuid=9269bbb4-a771-406f-ba66-3f65ed15634c
type=ethernet
controller=bond0
interface-name=en1
port-type=bond

[ethernet]

[match]
0707010000001D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/bond_active-backup/wicked_xml0707010000001E000081A4000000000000000000000001689C733A00000754000000000000000000000000000000000000003F00000000wicked2nm-1.2.1/tests/bond_active-backup/wicked_xml/config.xml<interface origin="compat:suse:/tests/bond_active-backup/netconfig/ifcfg-bond0">
  <name>bond0</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall>
    <zone>public</zone>
  </firewall>
  <bond>
    <mode>active-backup</mode>
    <miimon>
      <frequency>100</frequency>
      <carrier-detect>netif</carrier-detect>
    </miimon>
    <primary>en0</primary>
    <address>02:00:33:44:55:11</address>
  </bond>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <defer-timeout>15</defer-timeout>
    <recover-lease>true</recover-lease>
    <release-lease>false</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <defer-timeout>15</defer-timeout>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
<interface origin="compat:suse:/tests/bond_active-backup/netconfig/ifcfg-bond0">
  <name>en0</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>bond0</master>
    <port type="bond"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bond_active-backup/netconfig/ifcfg-bond0">
  <name>en1</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>bond0</master>
    <port type="bond"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
0707010000001F000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002A00000000wicked2nm-1.2.1/tests/bond_active-backup207070100000020000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002E00000000wicked2nm-1.2.1/tests/bond_active-backup2/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.46
07070100000021000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/bond_active-backup2/netconfig07070100000022000081A4000000000000000000000001689C733A0000001A000000000000000000000000000000000000003B00000000wicked2nm-1.2.1/tests/bond_active-backup2/netconfig/configCHECK_DUPLICATE_IP="yes"

07070100000023000081A4000000000000000000000001689C733A00000038000000000000000000000000000000000000003900000000wicked2nm-1.2.1/tests/bond_active-backup2/netconfig/dhcpDHCLIENT_WAIT_AT_BOOT="15"
DHCLIENT6_WAIT_AT_BOOT="15"

07070100000024000081A4000000000000000000000001689C733A000000CD000000000000000000000000000000000000004000000000wicked2nm-1.2.1/tests/bond_active-backup2/netconfig/ifcfg-bond0STARTMODE=auto
BOOTPROTO=dhcp
BONDING_MASTER=yes
BONDING_SLAVE_1=en0
BONDING_SLAVE_2=en1
BONDING_MODULE_OPTS='mode=active-backup miimon=100 primary=en0'
LLADDR='02:00:33:44:55:11'
FIREWALL=yes
ZONE=public
07070100000025000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003D00000000wicked2nm-1.2.1/tests/bond_active-backup2/system-connections07070100000026000081A4000000000000000000000001689C733A000001AB000000000000000000000000000000000000005000000000wicked2nm-1.2.1/tests/bond_active-backup2/system-connections/bond0.nmconnection[connection]
id=bond0
uuid=17e25c83-3b11-49d1-9096-38e97c0fd065
type=bond
autoconnect-slaves=1
interface-name=bond0
zone=public

[ethernet]
cloned-mac-address=02:00:33:44:55:11

[bond]
miimon=100
mode=active-backup
primary=en0
use_carrier=1

[match]

[ipv4]
dhcp-send-hostname=false
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
dhcp-send-hostname=false
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000027000081A4000000000000000000000001689C733A00000091000000000000000000000000000000000000004E00000000wicked2nm-1.2.1/tests/bond_active-backup2/system-connections/en0.nmconnection[connection]
id=en0
uuid=38d979e6-aa0e-4bae-8cff-a6dda281d0c7
type=ethernet
interface-name=en0
master=bond0
slave-type=bond

[ethernet]

[match]
07070100000028000081A4000000000000000000000001689C733A00000091000000000000000000000000000000000000004E00000000wicked2nm-1.2.1/tests/bond_active-backup2/system-connections/en1.nmconnection[connection]
id=en1
uuid=9269bbb4-a771-406f-ba66-3f65ed15634c
type=ethernet
interface-name=en1
master=bond0
slave-type=bond

[ethernet]

[match]
07070100000029000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/bond_active-backup2/wicked_xml0707010000002A000081A4000000000000000000000001689C733A00000757000000000000000000000000000000000000004000000000wicked2nm-1.2.1/tests/bond_active-backup2/wicked_xml/config.xml<interface origin="compat:suse:/tests/bond_active-backup2/netconfig/ifcfg-bond0">
  <name>bond0</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall>
    <zone>public</zone>
  </firewall>
  <bond>
    <mode>active-backup</mode>
    <miimon>
      <frequency>100</frequency>
      <carrier-detect>netif</carrier-detect>
    </miimon>
    <primary>en0</primary>
    <address>02:00:33:44:55:11</address>
  </bond>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <defer-timeout>15</defer-timeout>
    <recover-lease>true</recover-lease>
    <release-lease>false</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <defer-timeout>15</defer-timeout>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
<interface origin="compat:suse:/tests/bond_active-backup2/netconfig/ifcfg-bond0">
  <name>en0</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>bond0</master>
    <port type="bond"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bond_active-backup2/netconfig/ifcfg-bond0">
  <name>en1</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>bond0</master>
    <port type="bond"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
0707010000002B000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002700000000wicked2nm-1.2.1/tests/bond_ieee802_3ad0707010000002C000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.46
0707010000002D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/netconfig0707010000002E000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/netconfig/config0707010000002F000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/netconfig/dhcp07070100000030000081A4000000000000000000000001689C733A00000108000000000000000000000000000000000000003D00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/netconfig/ifcfg-bond0STARTMODE='auto'
BOOTPROTO='static'
IPADDR4='10.161.72.11/24'
IPADDR6='2620:113:80c0:8200::11/64'
BONDING_MASTER='yes'
BONDING_SLAVE_0='sfp1'
BONDING_SLAVE_1='sfp2'
BONDING_MODULE_OPTS='mode=802.3ad miimon=100 xmit_hash_policy=layer2+3'
LLADDR='3c:fd:fe:a5:be:cc'
07070100000031000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003A00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/system-connections07070100000032000081A4000000000000000000000001689C733A000001B4000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/system-connections/bond0.nmconnection[connection]
id=bond0
uuid=099bb601-dc24-4111-a5c0-f0d947033f46
type=bond
autoconnect-ports=1
interface-name=bond0

[ethernet]
cloned-mac-address=3C:FD:FE:A5:BE:CC

[bond]
miimon=100
mode=802.3ad
use_carrier=1
xmit_hash_policy=layer2+3

[match]

[ipv4]
address1=10.161.72.11/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
address1=2620:113:80c0:8200::11/64
ignore-auto-dns=true
ip6-privacy=1
method=manual

[proxy]
07070100000033000081A4000000000000000000000001689C733A00000096000000000000000000000000000000000000004C00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/system-connections/sfp1.nmconnection[connection]
id=sfp1
uuid=43fb1e44-9f5c-43f1-9372-9c0f42eb3473
type=ethernet
controller=bond0
interface-name=sfp1
port-type=bond

[ethernet]

[match]
07070100000034000081A4000000000000000000000001689C733A00000096000000000000000000000000000000000000004C00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/system-connections/sfp2.nmconnection[connection]
id=sfp2
uuid=2a076505-fbc4-4edf-a934-8fb0e835a9ac
type=ethernet
controller=bond0
interface-name=sfp2
port-type=bond

[ethernet]

[match]
07070100000035000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/wicked_xml07070100000036000081A4000000000000000000000001689C733A00000580000000000000000000000000000000000000003D00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad/wicked_xml/config.xml<interface origin="compat:suse:/tests/bond_ieee802_3ad/netconfig/ifcfg-bond0">
  <name>bond0</name>
  <control>
    <mode>boot</mode>
  </control>
  <bond>
    <mode>ieee802-3ad</mode>
    <miimon>
      <frequency>100</frequency>
      <carrier-detect>netif</carrier-detect>
    </miimon>
    <xmit-hash-policy>layer23</xmit-hash-policy>
    <address>3c:fd:fe:a5:be:cc</address>
  </bond>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.161.72.11/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2620:113:80c0:8200::11/64</local>
    </address>
  </ipv6:static>
</interface>
<interface origin="compat:suse:/tests/bond_ieee802_3ad/netconfig/ifcfg-bond0">
  <name>sfp1</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>bond0</master>
    <port type="bond"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bond_ieee802_3ad/netconfig/ifcfg-bond0">
  <name>sfp2</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>bond0</master>
    <port type="bond"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
07070100000037000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002800000000wicked2nm-1.2.1/tests/bond_ieee802_3ad207070100000038000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002C00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.46
07070100000039000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/netconfig0707010000003A000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003900000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/netconfig/config0707010000003B000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003700000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/netconfig/dhcp0707010000003C000081A4000000000000000000000001689C733A00000108000000000000000000000000000000000000003E00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/netconfig/ifcfg-bond0STARTMODE='auto'
BOOTPROTO='static'
IPADDR4='10.161.72.11/24'
IPADDR6='2620:113:80c0:8200::11/64'
BONDING_MASTER='yes'
BONDING_SLAVE_0='sfp1'
BONDING_SLAVE_1='sfp2'
BONDING_MODULE_OPTS='mode=802.3ad miimon=100 xmit_hash_policy=layer2+3'
LLADDR='3c:fd:fe:a5:be:cc'
0707010000003D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003B00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/system-connections0707010000003E000081A4000000000000000000000001689C733A000001B5000000000000000000000000000000000000004E00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/system-connections/bond0.nmconnection[connection]
id=bond0
uuid=099bb601-dc24-4111-a5c0-f0d947033f46
type=bond
autoconnect-slaves=1
interface-name=bond0

[ethernet]
cloned-mac-address=3C:FD:FE:A5:BE:CC

[bond]
miimon=100
mode=802.3ad
use_carrier=1
xmit_hash_policy=layer2+3

[match]

[ipv4]
address1=10.161.72.11/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
address1=2620:113:80c0:8200::11/64
ignore-auto-dns=true
ip6-privacy=1
method=manual

[proxy]
0707010000003F000081A4000000000000000000000001689C733A00000093000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/system-connections/sfp1.nmconnection[connection]
id=sfp1
uuid=43fb1e44-9f5c-43f1-9372-9c0f42eb3473
type=ethernet
interface-name=sfp1
master=bond0
slave-type=bond

[ethernet]

[match]
07070100000040000081A4000000000000000000000001689C733A00000093000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/system-connections/sfp2.nmconnection[connection]
id=sfp2
uuid=2a076505-fbc4-4edf-a934-8fb0e835a9ac
type=ethernet
interface-name=sfp2
master=bond0
slave-type=bond

[ethernet]

[match]
07070100000041000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/wicked_xml07070100000042000081A4000000000000000000000001689C733A00000583000000000000000000000000000000000000003E00000000wicked2nm-1.2.1/tests/bond_ieee802_3ad2/wicked_xml/config.xml<interface origin="compat:suse:/tests/bond_ieee802_3ad2/netconfig/ifcfg-bond0">
  <name>bond0</name>
  <control>
    <mode>boot</mode>
  </control>
  <bond>
    <mode>ieee802-3ad</mode>
    <miimon>
      <frequency>100</frequency>
      <carrier-detect>netif</carrier-detect>
    </miimon>
    <xmit-hash-policy>layer23</xmit-hash-policy>
    <address>3c:fd:fe:a5:be:cc</address>
  </bond>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.161.72.11/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2620:113:80c0:8200::11/64</local>
    </address>
  </ipv6:static>
</interface>
<interface origin="compat:suse:/tests/bond_ieee802_3ad2/netconfig/ifcfg-bond0">
  <name>sfp1</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>bond0</master>
    <port type="bond"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bond_ieee802_3ad2/netconfig/ifcfg-bond0">
  <name>sfp2</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>bond0</master>
    <port type="bond"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
07070100000043000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001E00000000wicked2nm-1.2.1/tests/bridge107070100000044000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002200000000wicked2nm-1.2.1/tests/bridge1/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.46
07070100000045000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002800000000wicked2nm-1.2.1/tests/bridge1/netconfig07070100000046000081A4000000000000000000000001689C733A0000001A000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/bridge1/netconfig/configCHECK_DUPLICATE_IP="yes"

07070100000047000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/bridge1/netconfig/dhcp07070100000048000081A4000000000000000000000001689C733A00000112000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/bridge1/netconfig/ifcfg-br0STARTMODE='auto'
BOOTPROTO='static'
IPADDR4='10.0.0.1/24'
BRIDGE='yes'
BRIDGE_STP='off'
BRIDGE_PRIORITY="5"
BRIDGE_FORWARDDELAY='3.2'
BRIDGE_HELLOTIME="1.1"
BRIDGE_AGEINGTIME="1.2"
BRIDGE_MAXAGE="40.3"
BRIDGE_PORTS='en0 en1'
BRIDGE_PORTPRIORITIES="9 0"
BRIDGE_PATHCOSTS="2"
07070100000049000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/bridge1/system-connections0707010000004A000081A4000000000000000000000001689C733A00000171000000000000000000000000000000000000004200000000wicked2nm-1.2.1/tests/bridge1/system-connections/br0.nmconnection[connection]
id=br0
uuid=c1960284-68f5-4294-b1b7-f865ac5a4994
type=bridge
autoconnect-ports=1
interface-name=br0

[ethernet]

[bridge]
ageing-time=1
forward-delay=3
hello-time=1
max-age=40
priority=5
stp=false

[match]

[ipv4]
address1=10.0.0.1/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
0707010000004B000081A4000000000000000000000001689C733A000000BA000000000000000000000000000000000000004200000000wicked2nm-1.2.1/tests/bridge1/system-connections/en0.nmconnection[connection]
id=en0
uuid=4c941c30-b610-470a-b24a-5a6c73ab6710
type=ethernet
controller=br0
interface-name=en0
port-type=bridge

[ethernet]

[bridge-port]
path-cost=2
priority=9

[match]
0707010000004C000081A4000000000000000000000001689C733A000000AE000000000000000000000000000000000000004200000000wicked2nm-1.2.1/tests/bridge1/system-connections/en1.nmconnection[connection]
id=en1
uuid=f760dace-c275-4983-ab36-51c8e9642dfc
type=ethernet
controller=br0
interface-name=en1
port-type=bridge

[ethernet]

[bridge-port]
priority=0

[match]
0707010000004D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002900000000wicked2nm-1.2.1/tests/bridge1/wicked_xml0707010000004E000081A4000000000000000000000001689C733A00000558000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/bridge1/wicked_xml/config.xml<interface origin="compat:suse:/tests/bridge1/netconfig/ifcfg-br0">
  <name>br0</name>
  <control>
    <mode>boot</mode>
  </control>
  <bridge>
    <stp>false</stp>
    <priority>5</priority>
    <forward-delay>3.20</forward-delay>
    <aging-time>1.20</aging-time>
    <hello-time>1.10</hello-time>
    <max-age>40.30</max-age>
  </bridge>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.0.0.1/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bridge1/netconfig/ifcfg-br0">
  <name>en0</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>br0</master>
    <port type="bridge">
      <priority>9</priority>
      <path-cost>2</path-cost>
    </port>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bridge1/netconfig/ifcfg-br0">
  <name>en1</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>br0</master>
    <port type="bridge">
      <priority>0</priority>
    </port>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
0707010000004F000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001E00000000wicked2nm-1.2.1/tests/bridge207070100000050000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002200000000wicked2nm-1.2.1/tests/bridge2/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.46
07070100000051000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002800000000wicked2nm-1.2.1/tests/bridge2/netconfig07070100000052000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/bridge2/netconfig/config07070100000053000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/bridge2/netconfig/dhcp07070100000054000081A4000000000000000000000001689C733A000000CC000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/bridge2/netconfig/ifcfg-br99STARTMODE='auto'
BOOTPROTO='static'
IPADDR4='10.161.72.11/24'
IPADDR6='2620:113:80c0:8200::11/64'
LLADDR='3c:fd:fe:a5:be:cc'
BRIDGE='yes'
BRIDGE_STP='off'
BRIDGE_FORWARDDELAY='0'
BRIDGE_PORTS='eth8 eth9'
07070100000055000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/bridge2/system-connections07070100000056000081A4000000000000000000000001689C733A00000190000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/bridge2/system-connections/br99.nmconnection[connection]
id=br99
uuid=bbd5f9fa-7905-4d8e-a319-34cbb4b77872
type=bridge
autoconnect-ports=1
interface-name=br99

[ethernet]
cloned-mac-address=3C:FD:FE:A5:BE:CC

[bridge]
forward-delay=0
stp=false

[match]

[ipv4]
address1=10.161.72.11/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
address1=2620:113:80c0:8200::11/64
ignore-auto-dns=true
ip6-privacy=1
method=manual

[proxy]
07070100000057000081A4000000000000000000000001689C733A000000A6000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/bridge2/system-connections/eth8.nmconnection[connection]
id=eth8
uuid=18cb882a-33ef-49ac-a9dd-151a9e014fb1
type=ethernet
controller=br99
interface-name=eth8
port-type=bridge

[ethernet]

[bridge-port]

[match]
07070100000058000081A4000000000000000000000001689C733A000000A6000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/bridge2/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=faea58e2-d243-4a36-a40d-897c3741e7c9
type=ethernet
controller=br99
interface-name=eth9
port-type=bridge

[ethernet]

[bridge-port]

[match]
07070100000059000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002900000000wicked2nm-1.2.1/tests/bridge2/wicked_xml0707010000005A000081A4000000000000000000000001689C733A000004ED000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/bridge2/wicked_xml/config.xml<interface origin="compat:suse:/tests/bridge2/netconfig/ifcfg-br99">
  <name>br99</name>
  <control>
    <mode>boot</mode>
  </control>
  <bridge>
    <stp>false</stp>
    <forward-delay>0.00</forward-delay>
    <address>3c:fd:fe:a5:be:cc</address>
  </bridge>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.161.72.11/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2620:113:80c0:8200::11/64</local>
    </address>
  </ipv6:static>
</interface>
<interface origin="compat:suse:/tests/bridge2/netconfig/ifcfg-br99">
  <name>eth8</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>br99</master>
    <port type="bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bridge2/netconfig/ifcfg-br99">
  <name>eth9</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>br99</master>
    <port type="bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
0707010000005B000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001E00000000wicked2nm-1.2.1/tests/bridge30707010000005C000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002200000000wicked2nm-1.2.1/tests/bridge3/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.46
0707010000005D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002800000000wicked2nm-1.2.1/tests/bridge3/netconfig0707010000005E000081A4000000000000000000000001689C733A0000001A000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/bridge3/netconfig/configCHECK_DUPLICATE_IP="yes"

0707010000005F000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/bridge3/netconfig/dhcp07070100000060000081A4000000000000000000000001689C733A00000112000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/bridge3/netconfig/ifcfg-br0STARTMODE='auto'
BOOTPROTO='static'
IPADDR4='10.0.0.1/24'
BRIDGE='yes'
BRIDGE_STP='off'
BRIDGE_PRIORITY="5"
BRIDGE_FORWARDDELAY='3.2'
BRIDGE_HELLOTIME="1.1"
BRIDGE_AGEINGTIME="1.2"
BRIDGE_MAXAGE="40.3"
BRIDGE_PORTS='en0 en1'
BRIDGE_PORTPRIORITIES="9 0"
BRIDGE_PATHCOSTS="2"
07070100000061000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/bridge3/system-connections07070100000062000081A4000000000000000000000001689C733A00000172000000000000000000000000000000000000004200000000wicked2nm-1.2.1/tests/bridge3/system-connections/br0.nmconnection[connection]
id=br0
uuid=c1960284-68f5-4294-b1b7-f865ac5a4994
type=bridge
autoconnect-slaves=1
interface-name=br0

[ethernet]

[bridge]
ageing-time=1
forward-delay=3
hello-time=1
max-age=40
priority=5
stp=false

[match]

[ipv4]
address1=10.0.0.1/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000063000081A4000000000000000000000001689C733A000000B7000000000000000000000000000000000000004200000000wicked2nm-1.2.1/tests/bridge3/system-connections/en0.nmconnection[connection]
id=en0
uuid=4c941c30-b610-470a-b24a-5a6c73ab6710
type=ethernet
interface-name=en0
master=br0
slave-type=bridge

[ethernet]

[bridge-port]
path-cost=2
priority=9

[match]
07070100000064000081A4000000000000000000000001689C733A000000AB000000000000000000000000000000000000004200000000wicked2nm-1.2.1/tests/bridge3/system-connections/en1.nmconnection[connection]
id=en1
uuid=f760dace-c275-4983-ab36-51c8e9642dfc
type=ethernet
interface-name=en1
master=br0
slave-type=bridge

[ethernet]

[bridge-port]
priority=0

[match]
07070100000065000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002900000000wicked2nm-1.2.1/tests/bridge3/wicked_xml07070100000066000081A4000000000000000000000001689C733A00000558000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/bridge3/wicked_xml/config.xml<interface origin="compat:suse:/tests/bridge3/netconfig/ifcfg-br0">
  <name>br0</name>
  <control>
    <mode>boot</mode>
  </control>
  <bridge>
    <stp>false</stp>
    <priority>5</priority>
    <forward-delay>3.20</forward-delay>
    <aging-time>1.20</aging-time>
    <hello-time>1.10</hello-time>
    <max-age>40.30</max-age>
  </bridge>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.0.0.1/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bridge3/netconfig/ifcfg-br0">
  <name>en0</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>br0</master>
    <port type="bridge">
      <priority>9</priority>
      <path-cost>2</path-cost>
    </port>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bridge3/netconfig/ifcfg-br0">
  <name>en1</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>br0</master>
    <port type="bridge">
      <priority>0</priority>
    </port>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
07070100000067000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001E00000000wicked2nm-1.2.1/tests/bridge407070100000068000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002200000000wicked2nm-1.2.1/tests/bridge4/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.46
07070100000069000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002800000000wicked2nm-1.2.1/tests/bridge4/netconfig0707010000006A000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/bridge4/netconfig/config0707010000006B000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/bridge4/netconfig/dhcp0707010000006C000081A4000000000000000000000001689C733A000000CC000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/bridge4/netconfig/ifcfg-br99STARTMODE='auto'
BOOTPROTO='static'
IPADDR4='10.161.72.11/24'
IPADDR6='2620:113:80c0:8200::11/64'
LLADDR='3c:fd:fe:a5:be:cc'
BRIDGE='yes'
BRIDGE_STP='off'
BRIDGE_FORWARDDELAY='0'
BRIDGE_PORTS='eth8 eth9'
0707010000006D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/bridge4/system-connections0707010000006E000081A4000000000000000000000001689C733A00000191000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/bridge4/system-connections/br99.nmconnection[connection]
id=br99
uuid=bbd5f9fa-7905-4d8e-a319-34cbb4b77872
type=bridge
autoconnect-slaves=1
interface-name=br99

[ethernet]
cloned-mac-address=3C:FD:FE:A5:BE:CC

[bridge]
forward-delay=0
stp=false

[match]

[ipv4]
address1=10.161.72.11/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
address1=2620:113:80c0:8200::11/64
ignore-auto-dns=true
ip6-privacy=1
method=manual

[proxy]
0707010000006F000081A4000000000000000000000001689C733A000000A3000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/bridge4/system-connections/eth8.nmconnection[connection]
id=eth8
uuid=18cb882a-33ef-49ac-a9dd-151a9e014fb1
type=ethernet
interface-name=eth8
master=br99
slave-type=bridge

[ethernet]

[bridge-port]

[match]
07070100000070000081A4000000000000000000000001689C733A000000A3000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/bridge4/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=faea58e2-d243-4a36-a40d-897c3741e7c9
type=ethernet
interface-name=eth9
master=br99
slave-type=bridge

[ethernet]

[bridge-port]

[match]
07070100000071000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002900000000wicked2nm-1.2.1/tests/bridge4/wicked_xml07070100000072000081A4000000000000000000000001689C733A000004ED000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/bridge4/wicked_xml/config.xml<interface origin="compat:suse:/tests/bridge4/netconfig/ifcfg-br99">
  <name>br99</name>
  <control>
    <mode>boot</mode>
  </control>
  <bridge>
    <stp>false</stp>
    <forward-delay>0.00</forward-delay>
    <address>3c:fd:fe:a5:be:cc</address>
  </bridge>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.161.72.11/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2620:113:80c0:8200::11/64</local>
    </address>
  </ipv6:static>
</interface>
<interface origin="compat:suse:/tests/bridge4/netconfig/ifcfg-br99">
  <name>eth8</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>br99</master>
    <port type="bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/bridge4/netconfig/ifcfg-br99">
  <name>eth9</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <link>
    <master>br99</master>
    <port type="bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
07070100000073000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001C00000000wicked2nm-1.2.1/tests/dummy07070100000074000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/dummy/system-connections07070100000075000081A4000000000000000000000001689C733A0000012F000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/dummy/system-connections/dummy0.nmconnection[connection]
id=dummy0
uuid=d5c90a99-bde4-4c92-884c-d8208d8fb6da
type=dummy
interface-name=dummy0

[ethernet]
cloned-mac-address=12:34:56:78:9A:BC

[dummy]

[match]

[ipv4]
address1=10.0.0.100/24
method=manual

[ipv6]
addr-gen-mode=default
address1=2001:db8:1::1/64
ip6-privacy=1
method=manual

[proxy]
07070100000076000081A4000000000000000000000001689C733A0000010A000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/dummy/system-connections/dummy1.nmconnection[connection]
id=dummy1
uuid=b551cd5a-d139-4297-a79f-d7dd33a97879
type=dummy
interface-name=dummy1

[ethernet]

[dummy]

[match]

[ipv4]
address1=10.0.0.101/24
method=manual

[ipv6]
addr-gen-mode=default
address1=2001:db8:1::2/64
ip6-privacy=1
method=manual

[proxy]
07070100000077000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002700000000wicked2nm-1.2.1/tests/dummy/wicked_xml07070100000078000081A4000000000000000000000001689C733A00000495000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/dummy/wicked_xml/dummy.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-dummy0">
  <name>dummy0</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <dummy>
    <address>12:34:56:78:9A:BC</address>
  </dummy>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.0.0.100/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2001:db8:1::1/64</local>
    </address>
  </ipv6:static>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-dummy1">
  <name>dummy1</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <dummy/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.0.0.101/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2001:db8:1::2/64</local>
    </address>
  </ipv6:static>
</interface>
07070100000079000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/ethernet_mac_address0707010000007A000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003E00000000wicked2nm-1.2.1/tests/ethernet_mac_address/system-connections0707010000007B000081A4000000000000000000000001689C733A0000010C000000000000000000000000000000000000005000000000wicked2nm-1.2.1/tests/ethernet_mac_address/system-connections/eth8.nmconnection[connection]
id=eth8
uuid=4935f592-3e86-491b-847b-2ce4f180001c
type=ethernet
interface-name=eth8

[ethernet]
cloned-mac-address=12:34:56:78:9A:BC

[match]

[ipv4]
address1=192.168.100.5/24
method=manual

[ipv6]
addr-gen-mode=default
ip6-privacy=1
method=auto

[proxy]
0707010000007C000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/ethernet_mac_address/wicked_xml0707010000007D000081A4000000000000000000000001689C733A00000227000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/ethernet_mac_address/wicked_xml/ipv4_static.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth8">
  <name>eth8</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <ethernet>
    <address>12:34:56:78:9a:bc</address>
  </ethernet>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:static>
    <address>
      <local>192.168.100.5/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
</interface>
0707010000007E000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002400000000wicked2nm-1.2.1/tests/firewall_zone0707010000007F000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003700000000wicked2nm-1.2.1/tests/firewall_zone/system-connections07070100000080000081A4000000000000000000000001689C733A000000D0000000000000000000000000000000000000004900000000wicked2nm-1.2.1/tests/firewall_zone/system-connections/eth8.nmconnection[connection]
id=eth8
uuid=17dad0f7-8cad-411a-9ae4-af22f8feb67c
type=ethernet
interface-name=eth8
zone=topsecret

[ethernet]

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=auto

[proxy]
07070100000081000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/firewall_zone/wicked_xml07070100000082000081A4000000000000000000000001689C733A000000D3000000000000000000000000000000000000004100000000wicked2nm-1.2.1/tests/firewall_zone/wicked_xml/firewall_zone.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth8">
  <name>eth8</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall>
    <zone>topsecret</zone>
  </firewall>
  <link/>
</interface>
07070100000083000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001F00000000wicked2nm-1.2.1/tests/hostname07070100000084000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002300000000wicked2nm-1.2.1/tests/hostname/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.52
07070100000085000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002900000000wicked2nm-1.2.1/tests/hostname/netconfig07070100000086000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003000000000wicked2nm-1.2.1/tests/hostname/netconfig/config07070100000087000081A4000000000000000000000001689C733A00000055000000000000000000000000000000000000002E00000000wicked2nm-1.2.1/tests/hostname/netconfig/dhcpDHCLIENT_HOSTNAME_OPTION=test-hostname-v4
DHCLIENT6_HOSTNAME_OPTION=test-hostname-v6
07070100000088000081A4000000000000000000000001689C733A0000001E000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/hostname/netconfig/ifcfg-eth9STARTMODE=auto
BOOTPROTO=dhcp
07070100000089000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/hostname/system-connections0707010000008A000081A4000000000000000000000001689C733A00000185000000000000000000000000000000000000004400000000wicked2nm-1.2.1/tests/hostname/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=34bf6f22-3770-4071-acb7-e7987d3e68af
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dhcp-hostname=test-hostname-v4
dhcp-send-hostname=1
dhcp-send-release=0
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
dhcp-hostname=test-hostname-v6
dhcp-send-hostname=1
dhcp-send-release=0
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
0707010000008B000081A4000000000000000000000001689C733A000000EF000000000000000000000000000000000000004200000000wicked2nm-1.2.1/tests/hostname/system-connections/lo.nmconnection[connection]
id=lo
uuid=bc3985a9-38c6-4fee-a125-4bce7fc00322
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
method=manual

[proxy]
0707010000008C000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002A00000000wicked2nm-1.2.1/tests/hostname/wicked_xml0707010000008D000081A4000000000000000000000001689C733A0000038A000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/hostname/wicked_xml/config.xml<interface origin="compat:suse:/tests/hostname/netconfig/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <hostname>test-hostname-v4</hostname>
    <recover-lease>true</recover-lease>
    <release-lease>false</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <hostname>test-hostname-v6</hostname>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
0707010000008E000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002000000000wicked2nm-1.2.1/tests/hostname20707010000008F000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002400000000wicked2nm-1.2.1/tests/hostname2/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.52
07070100000090000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002A00000000wicked2nm-1.2.1/tests/hostname2/netconfig07070100000091000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/hostname2/netconfig/config07070100000092000081A4000000000000000000000001689C733A00000035000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/hostname2/netconfig/dhcpDHCLIENT_HOSTNAME_OPTION=
DHCLIENT6_HOSTNAME_OPTION=
07070100000093000081A4000000000000000000000001689C733A0000001E000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/hostname2/netconfig/ifcfg-eth9STARTMODE=auto
BOOTPROTO=dhcp
07070100000094000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/hostname2/system-connections07070100000095000081A4000000000000000000000001689C733A0000018F000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/hostname2/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=8b05ac79-3c20-4147-8324-d3afc262159a
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dhcp-send-hostname-deprecated=false
dhcp-send-hostname=0
dhcp-send-release=0
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
dhcp-send-hostname-deprecated=false
dhcp-send-hostname=0
dhcp-send-release=0
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000096000081A4000000000000000000000001689C733A000000EF000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/hostname2/system-connections/lo.nmconnection[connection]
id=lo
uuid=c3185cb3-4a60-4620-8640-831d500c5eac
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
method=manual

[proxy]
07070100000097000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/hostname2/wicked_xml07070100000098000081A4000000000000000000000001689C733A00000337000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/hostname2/wicked_xml/config.xml<interface origin="compat:suse:/tests/hostname2/netconfig/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <recover-lease>true</recover-lease>
    <release-lease>false</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
07070100000099000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002000000000wicked2nm-1.2.1/tests/hostname30707010000009A000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002400000000wicked2nm-1.2.1/tests/hostname3/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.52
0707010000009B000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002A00000000wicked2nm-1.2.1/tests/hostname3/netconfig0707010000009C000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/hostname3/netconfig/config0707010000009D000081A4000000000000000000000001689C733A00000055000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/hostname3/netconfig/dhcpDHCLIENT_HOSTNAME_OPTION=test-hostname-v4
DHCLIENT6_HOSTNAME_OPTION=test-hostname-v6
0707010000009E000081A4000000000000000000000001689C733A0000001E000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/hostname3/netconfig/ifcfg-eth9STARTMODE=auto
BOOTPROTO=dhcp
0707010000009F000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/hostname3/system-connections070701000000A0000081A4000000000000000000000001689C733A00000133000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/hostname3/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=34bf6f22-3770-4071-acb7-e7987d3e68af
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dhcp-hostname=test-hostname-v4
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
dhcp-hostname=test-hostname-v6
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
070701000000A1000081A4000000000000000000000001689C733A000000EF000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/hostname3/system-connections/lo.nmconnection[connection]
id=lo
uuid=bc3985a9-38c6-4fee-a125-4bce7fc00322
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
method=manual

[proxy]
070701000000A2000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/hostname3/wicked_xml070701000000A3000081A4000000000000000000000001689C733A0000038B000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/hostname3/wicked_xml/config.xml<interface origin="compat:suse:/tests/hostname3/netconfig/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <hostname>test-hostname-v4</hostname>
    <recover-lease>true</recover-lease>
    <release-lease>false</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <hostname>test-hostname-v6</hostname>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
070701000000A4000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002000000000wicked2nm-1.2.1/tests/hostname4070701000000A5000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002400000000wicked2nm-1.2.1/tests/hostname4/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.52
070701000000A6000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002A00000000wicked2nm-1.2.1/tests/hostname4/netconfig070701000000A7000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/hostname4/netconfig/config070701000000A8000081A4000000000000000000000001689C733A00000035000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/hostname4/netconfig/dhcpDHCLIENT_HOSTNAME_OPTION=
DHCLIENT6_HOSTNAME_OPTION=
070701000000A9000081A4000000000000000000000001689C733A0000001E000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/hostname4/netconfig/ifcfg-eth9STARTMODE=auto
BOOTPROTO=dhcp
070701000000AA000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/hostname4/system-connections070701000000AB000081A4000000000000000000000001689C733A00000127000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/hostname4/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=8b05ac79-3c20-4147-8324-d3afc262159a
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dhcp-send-hostname=false
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
dhcp-send-hostname=false
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
070701000000AC000081A4000000000000000000000001689C733A000000EF000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/hostname4/system-connections/lo.nmconnection[connection]
id=lo
uuid=c3185cb3-4a60-4620-8640-831d500c5eac
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
method=manual

[proxy]
070701000000AD000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/hostname4/wicked_xml070701000000AE000081A4000000000000000000000001689C733A00000337000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/hostname4/wicked_xml/config.xml<interface origin="compat:suse:/tests/hostname4/netconfig/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <recover-lease>true</recover-lease>
    <release-lease>false</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
070701000000AF000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002100000000wicked2nm-1.2.1/tests/infiniband070701000000B0000081A4000000000000000000000001689C733A00000065000000000000000000000000000000000000002500000000wicked2nm-1.2.1/tests/infiniband/ENVW2NM_CONTINUE_MIGRATION=true
W2NM_WITHOUT_NETCONFIG=true
W2NM_NETCONFIG_PATH=
TEST_EXPECT_FAIL=false
070701000000B1000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/infiniband/system-connections070701000000B2000081A4000000000000000000000001689C733A00000101000000000000000000000000000000000000004A00000000wicked2nm-1.2.1/tests/infiniband/system-connections/ib0.8001.nmconnection[connection]
id=ib0.8001
uuid=9b67f665-65f9-46a5-a8f2-312a25c76848
type=infiniband
interface-name=ib0.8001

[infiniband]
p-key=32769
parent=ib0
transport-mode=connected

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000000B3000081A4000000000000000000000001689C733A00000100000000000000000000000000000000000000004A00000000wicked2nm-1.2.1/tests/infiniband/system-connections/ib0.8002.nmconnection[connection]
id=ib0.8002
uuid=01ee4005-008c-487e-a288-13bc1aca0d71
type=infiniband
interface-name=ib0.8002

[infiniband]
p-key=32770
parent=ib0
transport-mode=datagram

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000000B4000081A4000000000000000000000001689C733A000000DF000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/infiniband/system-connections/ib0.nmconnection[connection]
id=ib0
uuid=e700a7e8-3598-4554-a8d8-8f1f494573f7
type=infiniband
interface-name=ib0

[infiniband]
transport-mode=datagram

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000000B5000081A4000000000000000000000001689C733A000000DF000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/infiniband/system-connections/ib1.nmconnection[connection]
id=ib1
uuid=d0364ba4-f028-42b1-9bfd-c584db341c59
type=infiniband
interface-name=ib1

[infiniband]
transport-mode=datagram

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000000B6000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002C00000000wicked2nm-1.2.1/tests/infiniband/wicked_xml070701000000B7000081A4000000000000000000000001689C733A0000059D000000000000000000000000000000000000003B00000000wicked2nm-1.2.1/tests/infiniband/wicked_xml/infiniband.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-ib0">
  <name>ib0</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <infiniband/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-ib0.8001">
  <name>ib0.8001</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <infiniband:child>
    <device>ib0</device>
    <pkey>0x8001</pkey>
    <mode>connected</mode>
    <multicast>allowed</multicast>
  </infiniband:child>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-ib0.8002">
  <name>ib0.8002</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <infiniband:child>
    <device>ib0</device>
    <pkey>0x8002</pkey>
  </infiniband:child>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-ib1">
  <name>ib1</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <infiniband>
    <mode>datagram</mode>
    <multicast>disallowed</multicast>
  </infiniband>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
070701000000B8000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002200000000wicked2nm-1.2.1/tests/ipv4+6_dhcp070701000000B9000081A4000000000000000000000001689C733A00000013000000000000000000000000000000000000002600000000wicked2nm-1.2.1/tests/ipv4+6_dhcp/ENVNM_VERSION_ge=1.52
070701000000BA000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002C00000000wicked2nm-1.2.1/tests/ipv4+6_dhcp/netconfig070701000000BB000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/ipv4+6_dhcp/netconfig/config070701000000BC000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/ipv4+6_dhcp/netconfig/dhcp070701000000BD000081A4000000000000000000000001689C733A0000001E000000000000000000000000000000000000003700000000wicked2nm-1.2.1/tests/ipv4+6_dhcp/netconfig/ifcfg-eth9STARTMODE=auto
BOOTPROTO=dhcp
070701000000BE000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/ipv4+6_dhcp/system-connections070701000000BF000081A4000000000000000000000001689C733A00000165000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/ipv4+6_dhcp/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=a123047b-232e-4b86-9f69-851e7690deaa
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dhcp-send-hostname-deprecated=false
dhcp-send-hostname=0
dhcp-send-release=0
method=auto

[ipv6]
addr-gen-mode=default
dhcp-send-hostname-deprecated=false
dhcp-send-hostname=0
dhcp-send-release=0
ip6-privacy=1
method=auto

[proxy]
070701000000C0000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/ipv4+6_dhcp/wicked_xml070701000000C1000081A4000000000000000000000001689C733A00000339000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/ipv4+6_dhcp/wicked_xml/config.xml<interface origin="compat:suse:/tests/ipv4+6_dhcp/netconfig/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <recover-lease>true</recover-lease>
    <release-lease>false</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
070701000000C2000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002300000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2070701000000C3000081A4000000000000000000000001689C733A00000013000000000000000000000000000000000000002700000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2/ENVNM_VERSION_lt=1.52
070701000000C4000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2/netconfig070701000000C5000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2/netconfig/config070701000000C6000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2/netconfig/dhcp070701000000C7000081A4000000000000000000000001689C733A0000001E000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2/netconfig/ifcfg-eth9STARTMODE=auto
BOOTPROTO=dhcp
070701000000C8000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2/system-connections070701000000C9000081A4000000000000000000000001689C733A000000FD000000000000000000000000000000000000004800000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=a123047b-232e-4b86-9f69-851e7690deaa
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dhcp-send-hostname=false
method=auto

[ipv6]
addr-gen-mode=default
dhcp-send-hostname=false
ip6-privacy=1
method=auto

[proxy]
070701000000CA000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002E00000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2/wicked_xml070701000000CB000081A4000000000000000000000001689C733A0000033A000000000000000000000000000000000000003900000000wicked2nm-1.2.1/tests/ipv4+6_dhcp2/wicked_xml/config.xml<interface origin="compat:suse:/tests/ipv4+6_dhcp2/netconfig/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <recover-lease>true</recover-lease>
    <release-lease>false</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
070701000000CC000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002200000000wicked2nm-1.2.1/tests/ipv4_static070701000000CD000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/ipv4_static/system-connections070701000000CE000081A4000000000000000000000001689C733A00000101000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/ipv4_static/system-connections/eth8.nmconnection[connection]
id=eth8
uuid=4935f592-3e86-491b-847b-2ce4f180001c
type=ethernet
interface-name=eth8

[ethernet]

[match]

[ipv4]
address1=192.168.100.5/24
address2=192.168.101.5/24
method=manual

[ipv6]
addr-gen-mode=default
ip6-privacy=1
method=auto

[proxy]
070701000000CF000081A4000000000000000000000001689C733A00000101000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/ipv4_static/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=da886e32-22a9-4d83-8c04-421ec59d274b
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
address1=192.168.100.5/24
address2=192.168.101.5/24
method=manual

[ipv6]
addr-gen-mode=default
ip6-privacy=1
method=auto

[proxy]
070701000000D0000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/ipv4_static/wicked_xml070701000000D1000081A4000000000000000000000001689C733A00000414000000000000000000000000000000000000003D00000000wicked2nm-1.2.1/tests/ipv4_static/wicked_xml/ipv4_static.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth8">
  <name>eth8</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:static>
    <address>
      <local>192.168.100.5/24</local>
    </address>
    <address>
      <local>192.168.101.5/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:static>
    <address>
      <local>192.168.100.5/24</local>
    </address>
    <address>
      <local>192.168.101.5/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
</interface>
070701000000D2000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002000000000wicked2nm-1.2.1/tests/ipv6_auto070701000000D3000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002A00000000wicked2nm-1.2.1/tests/ipv6_auto/netconfig070701000000D4000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/ipv6_auto/netconfig/config070701000000D5000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/ipv6_auto/netconfig/dhcp070701000000D6000081A4000000000000000000000001689C733A0000001F000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/ipv6_auto/netconfig/ifcfg-eth7STARTMODE=auto
BOOTPROTO=auto6
070701000000D7000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/ipv6_auto/system-connections070701000000D8000081A4000000000000000000000001689C733A000000CF000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/ipv6_auto/system-connections/eth7.nmconnection[connection]
id=eth7
uuid=85378eec-2abb-4cbb-a3d3-69c10921b2e0
type=ethernet
interface-name=eth7

[ethernet]

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
ip6-privacy=1
method=auto

[proxy]
070701000000D9000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/ipv6_auto/wicked_xml070701000000DA000081A4000000000000000000000001689C733A00000176000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/ipv6_auto/wicked_xml/config.xml<interface origin="compat:suse:/tests/ipv6_auto/netconfig/ifcfg-eth7">
  <name>eth7</name>
  <control>
    <mode>boot</mode>
  </control>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:auto>
    <enabled>true</enabled>
    <update>dns</update>
  </ipv6:auto>
</interface>
070701000000DB000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002000000000wicked2nm-1.2.1/tests/ipv6_dhcp070701000000DC000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002400000000wicked2nm-1.2.1/tests/ipv6_dhcp/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.52
070701000000DD000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002A00000000wicked2nm-1.2.1/tests/ipv6_dhcp/netconfig070701000000DE000081A4000000000000000000000001689C733A0000003D000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/ipv6_dhcp/netconfig/configDHCLIENT_HOSTNAME_OPTION=AUTO
DHCLIENT6_HOSTNAME_OPTION=AUTO
070701000000DF000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/ipv6_dhcp/netconfig/dhcp070701000000E0000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/ipv6_dhcp/system-connections070701000000E1000081A4000000000000000000000001689C733A00000122000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/ipv6_dhcp/system-connections/eth5.nmconnection[connection]
id=eth5
uuid=ee291fe1-7dd3-4376-9c63-4228fab9df27
type=ethernet
interface-name=eth5

[ethernet]

[match]

[ipv4]
ignore-auto-dns=true
method=disabled

[ipv6]
addr-gen-mode=default
dhcp-send-hostname=1
dhcp-send-release=0
ignore-auto-dns=true
ip6-privacy=1
method=dhcp

[proxy]
070701000000E2000081A4000000000000000000000001689C733A00000122000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/ipv6_dhcp/system-connections/eth6.nmconnection[connection]
id=eth6
uuid=ee291fe1-7dd3-4376-9c63-4228fab9df27
type=ethernet
interface-name=eth6

[ethernet]

[match]

[ipv4]
ignore-auto-dns=true
method=disabled

[ipv6]
addr-gen-mode=default
dhcp-send-hostname=1
dhcp-send-release=0
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
070701000000E3000081A4000000000000000000000001689C733A000000EF000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/ipv6_dhcp/system-connections/lo.nmconnection[connection]
id=lo
uuid=401d49c9-e948-4207-8558-93b2760a428c
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
method=manual

[proxy]
070701000000E4000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/ipv6_dhcp/wicked_xml070701000000E5000081A4000000000000000000000001689C733A000005B9000000000000000000000000000000000000003900000000wicked2nm-1.2.1/tests/ipv6_dhcp/wicked_xml/ipv6_dhcp.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth6">
  <name>eth6</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <hostname>dev3</hostname>
    <defer-timeout>15</defer-timeout>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth5">
  <name>eth5</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>managed</mode>
    <rapid-commit>true</rapid-commit>
    <hostname>dev3</hostname>
    <defer-timeout>15</defer-timeout>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
070701000000E6000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002100000000wicked2nm-1.2.1/tests/ipv6_dhcp2070701000000E7000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002500000000wicked2nm-1.2.1/tests/ipv6_dhcp2/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.52
070701000000E8000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/ipv6_dhcp2/netconfig070701000000E9000081A4000000000000000000000001689C733A0000003D000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/ipv6_dhcp2/netconfig/configDHCLIENT_HOSTNAME_OPTION=AUTO
DHCLIENT6_HOSTNAME_OPTION=AUTO
070701000000EA000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003000000000wicked2nm-1.2.1/tests/ipv6_dhcp2/netconfig/dhcp070701000000EB000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/ipv6_dhcp2/system-connections070701000000EC000081A4000000000000000000000001689C733A000000F9000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/ipv6_dhcp2/system-connections/eth5.nmconnection[connection]
id=eth5
uuid=ee291fe1-7dd3-4376-9c63-4228fab9df27
type=ethernet
interface-name=eth5

[ethernet]

[match]

[ipv4]
ignore-auto-dns=true
method=disabled

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=dhcp

[proxy]
070701000000ED000081A4000000000000000000000001689C733A000000F9000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/ipv6_dhcp2/system-connections/eth6.nmconnection[connection]
id=eth6
uuid=ee291fe1-7dd3-4376-9c63-4228fab9df27
type=ethernet
interface-name=eth6

[ethernet]

[match]

[ipv4]
ignore-auto-dns=true
method=disabled

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
070701000000EE000081A4000000000000000000000001689C733A000000EF000000000000000000000000000000000000004400000000wicked2nm-1.2.1/tests/ipv6_dhcp2/system-connections/lo.nmconnection[connection]
id=lo
uuid=401d49c9-e948-4207-8558-93b2760a428c
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
method=manual

[proxy]
070701000000EF000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002C00000000wicked2nm-1.2.1/tests/ipv6_dhcp2/wicked_xml070701000000F0000081A4000000000000000000000001689C733A000005B9000000000000000000000000000000000000003A00000000wicked2nm-1.2.1/tests/ipv6_dhcp2/wicked_xml/ipv6_dhcp.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth6">
  <name>eth6</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <hostname>dev3</hostname>
    <defer-timeout>15</defer-timeout>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth5">
  <name>eth5</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>managed</mode>
    <rapid-commit>true</rapid-commit>
    <hostname>dev3</hostname>
    <defer-timeout>15</defer-timeout>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>false</release-lease>
  </ipv6:dhcp>
</interface>
070701000000F1000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002200000000wicked2nm-1.2.1/tests/ipv6_static070701000000F2000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/ipv6_static/system-connections070701000000F3000081A4000000000000000000000001689C733A00000109000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/ipv6_static/system-connections/eth5.nmconnection[connection]
id=eth5
uuid=79dac508-d8ae-4bae-82bc-8590c9e501cd
type=ethernet
interface-name=eth5

[ethernet]

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
address1=2001:db8:0:1::5/64
address2=2001:db8:0:2::5/64
ip6-privacy=1
method=manual

[proxy]
070701000000F4000081A4000000000000000000000001689C733A00000109000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/ipv6_static/system-connections/eth6.nmconnection[connection]
id=eth6
uuid=f429f20c-8e87-4e84-8380-4fbcc1bcd371
type=ethernet
interface-name=eth6

[ethernet]

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
address1=2001:db8:0:1::5/64
address2=2001:db8:0:2::5/64
ip6-privacy=1
method=manual

[proxy]
070701000000F5000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/ipv6_static/wicked_xml070701000000F6000081A4000000000000000000000001689C733A00000438000000000000000000000000000000000000003D00000000wicked2nm-1.2.1/tests/ipv6_static/wicked_xml/ipv6_static.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth5">
  <name>eth5</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2001:db8:0:1::5/64</local>
    </address>
    <address>
      <local>2001:db8:0:2::5/64</local>
    </address>
  </ipv6:static>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth6">
  <name>eth6</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv6>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2001:db8:0:1::5/64</local>
    </address>
    <address>
      <local>2001:db8:0:2::5/64</local>
    </address>
  </ipv6:static>
</interface>
070701000000F7000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001A00000000wicked2nm-1.2.1/tests/mtu070701000000F8000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/mtu/system-connections070701000000F9000081A4000000000000000000000001689C733A000000CE000000000000000000000000000000000000003F00000000wicked2nm-1.2.1/tests/mtu/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=c8666266-940a-4c15-96ed-8565170ff322
type=ethernet
interface-name=eth9

[ethernet]
mtu=1500

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000000FA000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002500000000wicked2nm-1.2.1/tests/mtu/wicked_xml070701000000FB000081A4000000000000000000000001689C733A00000128000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/mtu/wicked_xml/mtu.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link>
    <mtu>1500</mtu>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
070701000000FC000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003000000000wicked2nm-1.2.1/tests/multipath_routing_failure070701000000FD000081A4000000000000000000000001689C733A00000065000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/multipath_routing_failure/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=true
W2NM_NETCONFIG_PATH=
TEST_EXPECT_FAIL=true
070701000000FE000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003B00000000wicked2nm-1.2.1/tests/multipath_routing_failure/wicked_xml070701000000FF000081A4000000000000000000000001689C733A0000043B000000000000000000000000000000000000004E00000000wicked2nm-1.2.1/tests/multipath_routing_failure/wicked_xml/single_gateway.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:static>
    <address>
      <local>192.168.101.5/24</local>
    </address>
    <address>
      <local>192.168.102.5/24</local>
    </address>
    <route>
      <destination>192.168.101.0/24</destination>
    </route>
    <route>
      <destination>192.168.102.0/24</destination>
    </route>
    <route>
      <nexthop>
        <gateway>192.168.102.1</gateway>
      </nexthop>
      <nexthop>
        <gateway>192.168.102.2</gateway>
      </nexthop>
      <priority>1</priority>
    </route>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2001:db8:1::5/64</local>
    </address>
    <route>
      <nexthop>
        <gateway>2001:db8:1::1</gateway>
      </nexthop>
      <priority>1</priority>
    </route>
  </ipv6:static>
</interface>
07070100000100000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002000000000wicked2nm-1.2.1/tests/netconfig07070100000101000081A4000000000000000000000001689C733A000000A3000000000000000000000000000000000000002400000000wicked2nm-1.2.1/tests/netconfig/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
07070100000102000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002A00000000wicked2nm-1.2.1/tests/netconfig/netconfig07070100000103000081A4000000000000000000000001689C733A00000095000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/netconfig/netconfig/configNETCONFIG_DNS_POLICY="auto"
NETCONFIG_DNS_STATIC_SEARCHLIST="suse.de suse.com"
NETCONFIG_DNS_STATIC_SERVERS="192.168.0.10 192.168.1.10 2001:db8::10"
07070100000104000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/netconfig/netconfig/dhcp07070100000105000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/netconfig/system-connections07070100000106000081A4000000000000000000000001689C733A000000E5000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/netconfig/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=71735c72-06c3-4016-aafb-1bdb181bd533
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dns-priority=20
method=disabled

[ipv6]
addr-gen-mode=default
dns-priority=20
method=disabled

[proxy]
07070100000107000081A4000000000000000000000001689C733A0000017A000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/netconfig/system-connections/lo.nmconnection[connection]
id=lo
uuid=e722f75b-6207-4339-ae65-2f40cd4569e8
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
dns=192.168.0.10;192.168.1.10;
dns-priority=10
dns-search=suse.de;suse.com;
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
dns=2001:db8::10;
dns-priority=10
dns-search=suse.de;suse.com;
method=manual

[proxy]
07070100000108000081A4000000000000000000000001689C733A000000E7000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/netconfig/system-connections/test1.nmconnection[connection]
id=test1
uuid=1df2ab05-b3a4-45f1-8940-478f72e14a4a
type=ethernet
interface-name=test1

[ethernet]

[match]

[ipv4]
dns-priority=20
method=disabled

[ipv6]
addr-gen-mode=default
dns-priority=20
method=disabled

[proxy]
07070100000109000081A4000000000000000000000001689C733A000000E9000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/netconfig/system-connections/test12.nmconnection[connection]
id=test12
uuid=5b5acc9f-c241-442f-8206-5b40571fd2ce
type=ethernet
interface-name=test12

[ethernet]

[match]

[ipv4]
dns-priority=20
method=disabled

[ipv6]
addr-gen-mode=default
dns-priority=20
method=disabled

[proxy]
0707010000010A000081A4000000000000000000000001689C733A000000EB000000000000000000000000000000000000004800000000wicked2nm-1.2.1/tests/netconfig/system-connections/test123.nmconnection[connection]
id=test123
uuid=ba0a9eeb-f8ae-4cd7-bec4-4385102e4234
type=ethernet
interface-name=test123

[ethernet]

[match]

[ipv4]
dns-priority=20
method=disabled

[ipv6]
addr-gen-mode=default
dns-priority=20
method=disabled

[proxy]
0707010000010B000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/netconfig/wicked_xml0707010000010C000081A4000000000000000000000001689C733A00000438000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/netconfig/wicked_xml/basic.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-test1">
  <name>test1</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-test12">
  <name>test12</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-test123">
  <name>test123</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
0707010000010D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002100000000wicked2nm-1.2.1/tests/netconfig20707010000010E000081A4000000000000000000000001689C733A000000A3000000000000000000000000000000000000002500000000wicked2nm-1.2.1/tests/netconfig2/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
0707010000010F000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/netconfig2/netconfig07070100000110000081A4000000000000000000000001689C733A000000AF000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/netconfig2/netconfig/configNETCONFIG_DNS_POLICY="eth* est* STATIC test? test???"
NETCONFIG_DNS_STATIC_SEARCHLIST="suse.de suse.com"
NETCONFIG_DNS_STATIC_SERVERS="192.168.0.10 192.168.1.10 2001:db8::10"
07070100000111000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003000000000wicked2nm-1.2.1/tests/netconfig2/netconfig/dhcp07070100000112000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/netconfig2/system-connections07070100000113000081A4000000000000000000000001689C733A000000E5000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/netconfig2/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=d1391dba-0131-4425-8ddf-3a8742fbc91f
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dns-priority=10
method=disabled

[ipv6]
addr-gen-mode=default
dns-priority=10
method=disabled

[proxy]
07070100000114000081A4000000000000000000000001689C733A0000017A000000000000000000000000000000000000004400000000wicked2nm-1.2.1/tests/netconfig2/system-connections/lo.nmconnection[connection]
id=lo
uuid=e81cfda7-ecbe-4d04-b7bc-312933550318
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
dns=192.168.0.10;192.168.1.10;
dns-priority=30
dns-search=suse.de;suse.com;
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
dns=2001:db8::10;
dns-priority=30
dns-search=suse.de;suse.com;
method=manual

[proxy]
07070100000115000081A4000000000000000000000001689C733A000000E7000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/netconfig2/system-connections/test1.nmconnection[connection]
id=test1
uuid=b6003272-745f-4b05-bab6-afc988f2f638
type=ethernet
interface-name=test1

[ethernet]

[match]

[ipv4]
dns-priority=40
method=disabled

[ipv6]
addr-gen-mode=default
dns-priority=40
method=disabled

[proxy]
07070100000116000081A4000000000000000000000001689C733A000000F3000000000000000000000000000000000000004800000000wicked2nm-1.2.1/tests/netconfig2/system-connections/test12.nmconnection[connection]
id=test12
uuid=7b9b2560-bcb9-49be-877e-cb63148122dc
type=ethernet
interface-name=test12

[ethernet]

[match]

[ipv4]
ignore-auto-dns=true
method=disabled

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
method=disabled

[proxy]
07070100000117000081A4000000000000000000000001689C733A000000EB000000000000000000000000000000000000004900000000wicked2nm-1.2.1/tests/netconfig2/system-connections/test123.nmconnection[connection]
id=test123
uuid=aac0a124-d27f-4b3d-aec9-85087239c188
type=ethernet
interface-name=test123

[ethernet]

[match]

[ipv4]
dns-priority=50
method=disabled

[ipv6]
addr-gen-mode=default
dns-priority=50
method=disabled

[proxy]
07070100000118000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002C00000000wicked2nm-1.2.1/tests/netconfig2/wicked_xml07070100000119000081A4000000000000000000000001689C733A00000438000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/netconfig2/wicked_xml/basic.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-test1">
  <name>test1</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-test12">
  <name>test12</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-test123">
  <name>test123</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
0707010000011A000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002200000000wicked2nm-1.2.1/tests/ovs-bridge10707010000011B000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002400000000wicked2nm-1.2.1/tests/ovs-bridge1.10707010000011C000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002800000000wicked2nm-1.2.1/tests/ovs-bridge1.1/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.46
0707010000011D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002E00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/netconfig0707010000011E000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/ovs-bridge1.1/netconfig/config0707010000011F000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/ovs-bridge1.1/netconfig/dhcp07070100000120000081A4000000000000000000000001689C733A0000009C000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/ovs-bridge1.1/netconfig/ifcfg-br0STARTMODE='auto'
BOOTPROTO='static'
IPADDR4='10.0.2.2/15'
ZONE=internal
OVS_BRIDGE='yes'

OVS_BRIDGE_PORT_DEVICE_0='tap10'
OVS_BRIDGE_PORT_DEVICE_1='tap20'
07070100000121000081A4000000000000000000000001689C733A0000005F000000000000000000000000000000000000003A00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/netconfig/ifcfg-tap10BOOTPROTO='none'
STARTMODE='auto'
TUNNEL='tap'
TUNNEL_SET_GROUP='root'
TUNNEL_SET_OWNER='root'
07070100000122000081A4000000000000000000000001689C733A0000005F000000000000000000000000000000000000003A00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/netconfig/ifcfg-tap20BOOTPROTO='none'
STARTMODE='auto'
TUNNEL='tap'
TUNNEL_SET_GROUP='root'
TUNNEL_SET_OWNER='root'
07070100000123000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003700000000wicked2nm-1.2.1/tests/ovs-bridge1.1/system-connections07070100000124000081A4000000000000000000000001689C733A0000010B000000000000000000000000000000000000004F00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/system-connections/br0-bridge.nmconnection[connection]
id=br0-bridge
uuid=f288debb-d493-4ac2-aa3f-a6d9ec25e010
type=ovs-bridge
autoconnect-ports=1
interface-name=br0-bridge

[ovs-bridge]

[match]

[ipv4]
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
method=auto

[proxy]
07070100000125000081A4000000000000000000000001689C733A000000BD000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/system-connections/br0-port.nmconnection[connection]
id=br0-port
uuid=81d6fe12-2cf3-4f42-b794-6d634bd15891
type=ovs-port
autoconnect-ports=1
controller=br0-bridge
interface-name=br0-port
port-type=ovs-bridge

[ovs-port]

[match]
07070100000126000081A4000000000000000000000001689C733A00000149000000000000000000000000000000000000004800000000wicked2nm-1.2.1/tests/ovs-bridge1.1/system-connections/br0.nmconnection[connection]
id=br0
uuid=ac6f4b40-35f7-4c33-ba32-cd54121ede83
type=ovs-interface
controller=br0-port
interface-name=br0
port-type=ovs-port

[ovs-interface]
type=internal

[match]

[ipv4]
address1=10.0.2.2/15
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000127000081A4000000000000000000000001689C733A000000C1000000000000000000000000000000000000004F00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/system-connections/tap10-port.nmconnection[connection]
id=tap10-port
uuid=20ec90cb-e4e1-4478-997c-b118aea2df78
type=ovs-port
autoconnect-ports=1
controller=br0-bridge
interface-name=tap10-port
port-type=ovs-bridge

[ovs-port]

[match]
07070100000128000081A4000000000000000000000001689C733A000000CB000000000000000000000000000000000000004A00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/system-connections/tap10.nmconnection[connection]
id=tap10
uuid=d0407883-1a3d-4822-8b09-0e730871ebd6
type=tun
controller=tap10-port
interface-name=tap10
port-type=ovs-port

[ovs-interface]
type=system

[tun]
group=0
mode=2
owner=0

[match]
07070100000129000081A4000000000000000000000001689C733A000000C1000000000000000000000000000000000000004F00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/system-connections/tap20-port.nmconnection[connection]
id=tap20-port
uuid=803545de-c926-44b2-9f82-810feddc7f05
type=ovs-port
autoconnect-ports=1
controller=br0-bridge
interface-name=tap20-port
port-type=ovs-bridge

[ovs-port]

[match]
0707010000012A000081A4000000000000000000000001689C733A000000CB000000000000000000000000000000000000004A00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/system-connections/tap20.nmconnection[connection]
id=tap20
uuid=7cf60862-d5a2-426c-a6c6-5c8496d0e82b
type=tun
controller=tap20-port
interface-name=tap20
port-type=ovs-port

[ovs-interface]
type=system

[tun]
group=0
mode=2
owner=0

[match]
0707010000012B000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/wicked_xml0707010000012C000081A4000000000000000000000001689C733A00000499000000000000000000000000000000000000003A00000000wicked2nm-1.2.1/tests/ovs-bridge1.1/wicked_xml/config.xml<interface origin="compat:suse:/tests/ovs-bridge1.1/netconfig/ifcfg-br0">
  <name>br0</name>
  <control>
    <mode>boot</mode>
  </control>
  <ovs-bridge/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.0.2.2/15</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge1.1/netconfig/ifcfg-tap10">
  <name>tap10</name>
  <control>
    <mode>boot</mode>
  </control>
  <tap>
    <owner>0</owner>
    <group>0</group>
  </tap>
  <link>
    <master>br0</master>
    <port type="ovs-bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge1.1/netconfig/ifcfg-tap20">
  <name>tap20</name>
  <control>
    <mode>boot</mode>
  </control>
  <tap>
    <owner>0</owner>
    <group>0</group>
  </tap>
  <link>
    <master>br0</master>
    <port type="ovs-bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
0707010000012D000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002600000000wicked2nm-1.2.1/tests/ovs-bridge1/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.46
0707010000012E000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002C00000000wicked2nm-1.2.1/tests/ovs-bridge1/netconfig0707010000012F000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/ovs-bridge1/netconfig/config07070100000130000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/ovs-bridge1/netconfig/dhcp07070100000131000081A4000000000000000000000001689C733A0000009C000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/ovs-bridge1/netconfig/ifcfg-br0STARTMODE='auto'
BOOTPROTO='static'
IPADDR4='10.0.2.2/15'
ZONE=internal
OVS_BRIDGE='yes'

OVS_BRIDGE_PORT_DEVICE_0='tap10'
OVS_BRIDGE_PORT_DEVICE_1='tap20'
07070100000132000081A4000000000000000000000001689C733A0000005F000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/ovs-bridge1/netconfig/ifcfg-tap10BOOTPROTO='none'
STARTMODE='auto'
TUNNEL='tap'
TUNNEL_SET_GROUP='root'
TUNNEL_SET_OWNER='root'
07070100000133000081A4000000000000000000000001689C733A0000005F000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/ovs-bridge1/netconfig/ifcfg-tap20BOOTPROTO='none'
STARTMODE='auto'
TUNNEL='tap'
TUNNEL_SET_GROUP='root'
TUNNEL_SET_OWNER='root'
07070100000134000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/ovs-bridge1/system-connections07070100000135000081A4000000000000000000000001689C733A0000010C000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/ovs-bridge1/system-connections/br0-bridge.nmconnection[connection]
id=br0-bridge
uuid=ff797ef9-bf7f-4ecb-9f8a-d3833afec08e
type=ovs-bridge
autoconnect-slaves=1
interface-name=br0-bridge

[ovs-bridge]

[match]

[ipv4]
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
method=auto

[proxy]
07070100000136000081A4000000000000000000000001689C733A000000BB000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/ovs-bridge1/system-connections/br0-port.nmconnection[connection]
id=br0-port
uuid=0867d65a-221c-4ae4-b548-4e6592af8ff3
type=ovs-port
autoconnect-slaves=1
interface-name=br0-port
master=br0-bridge
slave-type=ovs-bridge

[ovs-port]

[match]
07070100000137000081A4000000000000000000000001689C733A00000146000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/ovs-bridge1/system-connections/br0.nmconnection[connection]
id=br0
uuid=0986f097-506d-40c5-9ca7-a76d168ba99c
type=ovs-interface
interface-name=br0
master=br0-port
slave-type=ovs-port

[ovs-interface]
type=internal

[match]

[ipv4]
address1=10.0.2.2/15
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000138000081A4000000000000000000000001689C733A000000BF000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/ovs-bridge1/system-connections/tap10-port.nmconnection[connection]
id=tap10-port
uuid=23bfdab0-d696-44cc-9659-f97717766615
type=ovs-port
autoconnect-slaves=1
interface-name=tap10-port
master=br0-bridge
slave-type=ovs-bridge

[ovs-port]

[match]
07070100000139000081A4000000000000000000000001689C733A000000C8000000000000000000000000000000000000004800000000wicked2nm-1.2.1/tests/ovs-bridge1/system-connections/tap10.nmconnection[connection]
id=tap10
uuid=6c26d745-6fd1-45fe-98bf-00bcc31770f1
type=tun
interface-name=tap10
master=tap10-port
slave-type=ovs-port

[ovs-interface]
type=system

[tun]
group=0
mode=2
owner=0

[match]
0707010000013A000081A4000000000000000000000001689C733A000000BF000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/ovs-bridge1/system-connections/tap20-port.nmconnection[connection]
id=tap20-port
uuid=b9abd61f-0c79-41be-a385-23dfefdc05c3
type=ovs-port
autoconnect-slaves=1
interface-name=tap20-port
master=br0-bridge
slave-type=ovs-bridge

[ovs-port]

[match]
0707010000013B000081A4000000000000000000000001689C733A000000C8000000000000000000000000000000000000004800000000wicked2nm-1.2.1/tests/ovs-bridge1/system-connections/tap20.nmconnection[connection]
id=tap20
uuid=02b1f005-abc6-437c-a064-172f850ede65
type=tun
interface-name=tap20
master=tap20-port
slave-type=ovs-port

[ovs-interface]
type=system

[tun]
group=0
mode=2
owner=0

[match]
0707010000013C000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/ovs-bridge1/wicked_xml0707010000013D000081A4000000000000000000000001689C733A00000493000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/ovs-bridge1/wicked_xml/config.xml<interface origin="compat:suse:/tests/ovs-bridge1/netconfig/ifcfg-br0">
  <name>br0</name>
  <control>
    <mode>boot</mode>
  </control>
  <ovs-bridge/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.0.2.2/15</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge1/netconfig/ifcfg-tap10">
  <name>tap10</name>
  <control>
    <mode>boot</mode>
  </control>
  <tap>
    <owner>0</owner>
    <group>0</group>
  </tap>
  <link>
    <master>br0</master>
    <port type="ovs-bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge1/netconfig/ifcfg-tap20">
  <name>tap20</name>
  <control>
    <mode>boot</mode>
  </control>
  <tap>
    <owner>0</owner>
    <group>0</group>
  </tap>
  <link>
    <master>br0</master>
    <port type="ovs-bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
0707010000013E000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002200000000wicked2nm-1.2.1/tests/ovs-bridge20707010000013F000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002400000000wicked2nm-1.2.1/tests/ovs-bridge2.107070100000140000081A4000000000000000000000001689C733A000000D6000000000000000000000000000000000000002800000000wicked2nm-1.2.1/tests/ovs-bridge2.1/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
W2NM_ACTIVATE_CONNECTIONS=false
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.46
07070100000141000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002E00000000wicked2nm-1.2.1/tests/ovs-bridge2.1/netconfig07070100000142000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/ovs-bridge2.1/netconfig/config07070100000143000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/ovs-bridge2.1/netconfig/dhcp07070100000144000081A4000000000000000000000001689C733A00000022000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/ovs-bridge2.1/netconfig/ifcfg-en0STARTMODE='auto'
BOOTPROTO='none'
07070100000145000081A4000000000000000000000001689C733A00000022000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/ovs-bridge2.1/netconfig/ifcfg-en1STARTMODE='auto'
BOOTPROTO='none'
07070100000146000081A4000000000000000000000001689C733A0000007A000000000000000000000000000000000000003B00000000wicked2nm-1.2.1/tests/ovs-bridge2.1/netconfig/ifcfg-ovsbrASTARTMODE='auto'
BOOTPROTO='static'
ZONE=trusted
IPADDR='198.18.10.10/24'
OVS_BRIDGE='yes'
OVS_BRIDGE_PORT_DEVICE_1='en0'
07070100000147000081A4000000000000000000000001689C733A000000A5000000000000000000000000000000000000003B00000000wicked2nm-1.2.1/tests/ovs-bridge2.1/netconfig/ifcfg-ovsbrBSTARTMODE='auto'
BOOTPROTO='static'
IPADDR='198.18.11.10/24'
OVS_BRIDGE='yes'
OVS_BRIDGE_VLAN_PARENT='ovsbrA'
OVS_BRIDGE_VLAN_TAG='10'

OVS_BRIDGE_PORT_DEVICE_1=en1
07070100000148000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003700000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections07070100000149000081A4000000000000000000000001689C733A000000C0000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections/en0-port.nmconnection[connection]
id=en0-port
uuid=f3d21162-ff2f-457e-ba65-740aaee4b8e8
type=ovs-port
autoconnect-ports=1
controller=ovsbrA-bridge
interface-name=en0-port
port-type=ovs-bridge

[ovs-port]

[match]
0707010000014A000081A4000000000000000000000001689C733A000000B8000000000000000000000000000000000000004800000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections/en0.nmconnection[connection]
id=en0
uuid=377c12d0-a12c-4c96-9dfa-501f7ee4e0e3
type=ethernet
controller=en0-port
interface-name=en0
port-type=ovs-port

[ethernet]

[ovs-interface]
type=system

[match]
0707010000014B000081A4000000000000000000000001689C733A000000C7000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections/en1-port.nmconnection[connection]
id=en1-port
uuid=2205d992-3374-4aad-8d10-363694ec8efa
type=ovs-port
autoconnect-ports=1
controller=ovsbrA-bridge
interface-name=en1-port
port-type=ovs-bridge

[ovs-port]
tag=10

[match]
0707010000014C000081A4000000000000000000000001689C733A000000B8000000000000000000000000000000000000004800000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections/en1.nmconnection[connection]
id=en1
uuid=3ca9734d-f315-4c5d-a53a-f7bb90a15a23
type=ethernet
controller=en1-port
interface-name=en1
port-type=ovs-port

[ethernet]

[ovs-interface]
type=system

[match]
0707010000014D000081A4000000000000000000000001689C733A00000111000000000000000000000000000000000000005200000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections/ovsbrA-bridge.nmconnection[connection]
id=ovsbrA-bridge
uuid=49f44de0-99b1-4868-af2a-6e99b7ad2171
type=ovs-bridge
autoconnect-ports=1
interface-name=ovsbrA-bridge

[ovs-bridge]

[match]

[ipv4]
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
method=auto

[proxy]
0707010000014E000081A4000000000000000000000001689C733A000000C6000000000000000000000000000000000000005000000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections/ovsbrA-port.nmconnection[connection]
id=ovsbrA-port
uuid=94cbbcc9-0639-4655-b067-3a453cb13e55
type=ovs-port
autoconnect-ports=1
controller=ovsbrA-bridge
interface-name=ovsbrA-port
port-type=ovs-bridge

[ovs-port]

[match]
0707010000014F000081A4000000000000000000000001689C733A00000156000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections/ovsbrA.nmconnection[connection]
id=ovsbrA
uuid=d0656477-9a76-424e-ae34-906217bfcb1a
type=ovs-interface
controller=ovsbrA-port
interface-name=ovsbrA
port-type=ovs-port

[ovs-interface]
type=internal

[match]

[ipv4]
address1=198.18.10.10/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000150000081A4000000000000000000000001689C733A000000CD000000000000000000000000000000000000005000000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections/ovsbrB-port.nmconnection[connection]
id=ovsbrB-port
uuid=8c95d17c-4dbf-4c58-a2c2-ffda25dc463e
type=ovs-port
autoconnect-ports=1
controller=ovsbrA-bridge
interface-name=ovsbrB-port
port-type=ovs-bridge

[ovs-port]
tag=10

[match]
07070100000151000081A4000000000000000000000001689C733A00000156000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/ovs-bridge2.1/system-connections/ovsbrB.nmconnection[connection]
id=ovsbrB
uuid=02f29edd-a249-45e5-a699-528388facd41
type=ovs-interface
controller=ovsbrB-port
interface-name=ovsbrB
port-type=ovs-port

[ovs-interface]
type=internal

[match]

[ipv4]
address1=198.18.11.10/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000152000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/ovs-bridge2.1/wicked_xml07070100000153000081A4000000000000000000000001689C733A00000622000000000000000000000000000000000000003A00000000wicked2nm-1.2.1/tests/ovs-bridge2.1/wicked_xml/config.xml<interface origin="compat:suse:/tests/ovs-bridge2.1/netconfig/ifcfg-en0">
  <name>en0</name>
  <control>
    <mode>boot</mode>
  </control>
  <link>
    <master>ovsbrA</master>
    <port type="ovs-bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge2.1/netconfig/ifcfg-en1">
  <name>en1</name>
  <control>
    <mode>boot</mode>
  </control>
  <link>
    <master>ovsbrB</master>
    <port type="ovs-bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge2.1/netconfig/ifcfg-ovsbrA">
  <name>ovsbrA</name>
  <control>
    <mode>boot</mode>
  </control>
  <ovs-bridge/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>198.18.10.10/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge2.1/netconfig/ifcfg-ovsbrB">
  <name>ovsbrB</name>
  <control>
    <mode>boot</mode>
  </control>
  <ovs-bridge>
    <vlan>
      <parent>ovsbrA</parent>
      <tag>10</tag>
    </vlan>
  </ovs-bridge>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>198.18.11.10/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
</interface>
07070100000154000081A4000000000000000000000001689C733A000000D6000000000000000000000000000000000000002600000000wicked2nm-1.2.1/tests/ovs-bridge2/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
W2NM_ACTIVATE_CONNECTIONS=false
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.46
07070100000155000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002C00000000wicked2nm-1.2.1/tests/ovs-bridge2/netconfig07070100000156000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/ovs-bridge2/netconfig/config07070100000157000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003100000000wicked2nm-1.2.1/tests/ovs-bridge2/netconfig/dhcp07070100000158000081A4000000000000000000000001689C733A00000022000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/ovs-bridge2/netconfig/ifcfg-en0STARTMODE='auto'
BOOTPROTO='none'
07070100000159000081A4000000000000000000000001689C733A00000022000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/ovs-bridge2/netconfig/ifcfg-en1STARTMODE='auto'
BOOTPROTO='none'
0707010000015A000081A4000000000000000000000001689C733A0000007A000000000000000000000000000000000000003900000000wicked2nm-1.2.1/tests/ovs-bridge2/netconfig/ifcfg-ovsbrASTARTMODE='auto'
BOOTPROTO='static'
ZONE=trusted
IPADDR='198.18.10.10/24'
OVS_BRIDGE='yes'
OVS_BRIDGE_PORT_DEVICE_1='en0'
0707010000015B000081A4000000000000000000000001689C733A000000A5000000000000000000000000000000000000003900000000wicked2nm-1.2.1/tests/ovs-bridge2/netconfig/ifcfg-ovsbrBSTARTMODE='auto'
BOOTPROTO='static'
IPADDR='198.18.11.10/24'
OVS_BRIDGE='yes'
OVS_BRIDGE_VLAN_PARENT='ovsbrA'
OVS_BRIDGE_VLAN_TAG='10'

OVS_BRIDGE_PORT_DEVICE_1=en1
0707010000015C000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections0707010000015D000081A4000000000000000000000001689C733A000000BE000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections/en0-port.nmconnection[connection]
id=en0-port
uuid=20232292-14c6-42cc-9936-1198672187c8
type=ovs-port
autoconnect-slaves=1
interface-name=en0-port
master=ovsbrA-bridge
slave-type=ovs-bridge

[ovs-port]

[match]
0707010000015E000081A4000000000000000000000001689C733A000000B5000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections/en0.nmconnection[connection]
id=en0
uuid=e1211fdb-7139-401e-bf62-037f10ed86cf
type=ethernet
interface-name=en0
master=en0-port
slave-type=ovs-port

[ethernet]

[ovs-interface]
type=system

[match]
0707010000015F000081A4000000000000000000000001689C733A000000C5000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections/en1-port.nmconnection[connection]
id=en1-port
uuid=1cbc73d9-86a3-4f28-b688-afb4c5518b50
type=ovs-port
autoconnect-slaves=1
interface-name=en1-port
master=ovsbrA-bridge
slave-type=ovs-bridge

[ovs-port]
tag=10

[match]
07070100000160000081A4000000000000000000000001689C733A000000B5000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections/en1.nmconnection[connection]
id=en1
uuid=d18dc48d-68ec-494e-ba56-08653161e9dc
type=ethernet
interface-name=en1
master=en1-port
slave-type=ovs-port

[ethernet]

[ovs-interface]
type=system

[match]
07070100000161000081A4000000000000000000000001689C733A00000112000000000000000000000000000000000000005000000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections/ovsbrA-bridge.nmconnection[connection]
id=ovsbrA-bridge
uuid=bdec49eb-00e9-4779-a954-16c73e5f6dd3
type=ovs-bridge
autoconnect-slaves=1
interface-name=ovsbrA-bridge

[ovs-bridge]

[match]

[ipv4]
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
method=auto

[proxy]
07070100000162000081A4000000000000000000000001689C733A000000C4000000000000000000000000000000000000004E00000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections/ovsbrA-port.nmconnection[connection]
id=ovsbrA-port
uuid=629711e6-4e92-495b-85f4-5d330d199cae
type=ovs-port
autoconnect-slaves=1
interface-name=ovsbrA-port
master=ovsbrA-bridge
slave-type=ovs-bridge

[ovs-port]

[match]
07070100000163000081A4000000000000000000000001689C733A00000153000000000000000000000000000000000000004900000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections/ovsbrA.nmconnection[connection]
id=ovsbrA
uuid=0dff0c56-ae5c-4767-bb4e-47f518b0d724
type=ovs-interface
interface-name=ovsbrA
master=ovsbrA-port
slave-type=ovs-port

[ovs-interface]
type=internal

[match]

[ipv4]
address1=198.18.10.10/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000164000081A4000000000000000000000001689C733A000000CB000000000000000000000000000000000000004E00000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections/ovsbrB-port.nmconnection[connection]
id=ovsbrB-port
uuid=3708e33e-8790-4904-88fd-bbca6575e376
type=ovs-port
autoconnect-slaves=1
interface-name=ovsbrB-port
master=ovsbrA-bridge
slave-type=ovs-bridge

[ovs-port]
tag=10

[match]
07070100000165000081A4000000000000000000000001689C733A00000153000000000000000000000000000000000000004900000000wicked2nm-1.2.1/tests/ovs-bridge2/system-connections/ovsbrB.nmconnection[connection]
id=ovsbrB
uuid=a70f84aa-09c4-40cf-ba73-7e04c8406683
type=ovs-interface
interface-name=ovsbrB
master=ovsbrB-port
slave-type=ovs-port

[ovs-interface]
type=internal

[match]

[ipv4]
address1=198.18.11.10/24
ignore-auto-dns=true
method=manual

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000166000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/ovs-bridge2/wicked_xml07070100000167000081A4000000000000000000000001689C733A0000061A000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/ovs-bridge2/wicked_xml/config.xml<interface origin="compat:suse:/tests/ovs-bridge2/netconfig/ifcfg-en0">
  <name>en0</name>
  <control>
    <mode>boot</mode>
  </control>
  <link>
    <master>ovsbrA</master>
    <port type="ovs-bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge2/netconfig/ifcfg-en1">
  <name>en1</name>
  <control>
    <mode>boot</mode>
  </control>
  <link>
    <master>ovsbrB</master>
    <port type="ovs-bridge"/>
  </link>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge2/netconfig/ifcfg-ovsbrA">
  <name>ovsbrA</name>
  <control>
    <mode>boot</mode>
  </control>
  <ovs-bridge/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>198.18.10.10/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
</interface>
<interface origin="compat:suse:/tests/ovs-bridge2/netconfig/ifcfg-ovsbrB">
  <name>ovsbrB</name>
  <control>
    <mode>boot</mode>
  </control>
  <ovs-bridge>
    <vlan>
      <parent>ovsbrA</parent>
      <tag>10</tag>
    </vlan>
  </ovs-bridge>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:static>
    <address>
      <local>198.18.11.10/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
</interface>
07070100000168000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001D00000000wicked2nm-1.2.1/tests/routes07070100000169000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003000000000wicked2nm-1.2.1/tests/routes/system-connections0707010000016A000081A4000000000000000000000001689C733A00000241000000000000000000000000000000000000004200000000wicked2nm-1.2.1/tests/routes/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=e7736944-bd8b-4da3-8be9-84b333b2ccfa
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
address1=192.168.101.5/24
address2=192.168.102.5/24
method=manual
route1=192.168.101.0/24,192.168.101.1
route2=192.168.102.0/24,192.168.102.1,1
route3=192.168.102.0/24,192.168.102.2,2
route4=192.168.103.0/24,192.168.101.1
route5=192.168.104.0/24,192.168.102.1
route6=0.0.0.0/0,192.168.102.1,1

[ipv6]
addr-gen-mode=default
address1=2001:db8:1::5/64
ip6-privacy=1
method=manual
route1=::/0,2001:db8:1::1
route2=2001:db8:1::/64,2001:db8:1::1,1

[proxy]
0707010000016B000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002800000000wicked2nm-1.2.1/tests/routes/wicked_xml0707010000016C000081A4000000000000000000000001689C733A00000741000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/routes/wicked_xml/routes.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:static>
    <address>
      <local>192.168.101.5/24</local>
    </address>
    <address>
      <local>192.168.102.5/24</local>
    </address>
    <route>
      <destination>192.168.101.0/24</destination>
      <nexthop>
        <gateway>192.168.101.1</gateway>
      </nexthop>
    </route>
    <route>
      <destination>192.168.102.0/24</destination>
      <nexthop>
        <gateway>192.168.102.1</gateway>
      </nexthop>
      <priority>1</priority>
    </route>
    <route>
      <destination>192.168.102.0/24</destination>
      <nexthop>
        <gateway>192.168.102.2</gateway>
      </nexthop>
      <priority>2</priority>
    </route>
    <route>
      <destination>192.168.103.0/24</destination>
      <nexthop>
        <gateway>192.168.101.1</gateway>
      </nexthop>
    </route>
    <route>
      <destination>192.168.104.0/24</destination>
      <nexthop>
        <gateway>192.168.102.1</gateway>
      </nexthop>
    </route>
    <route>
      <nexthop>
        <gateway>192.168.102.1</gateway>
      </nexthop>
      <priority>1</priority>
    </route>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
  <ipv6:static>
    <address>
      <local>2001:db8:1::5/64</local>
    </address>
    <route>
      <nexthop>
        <gateway>2001:db8:1::1</gateway>
      </nexthop>
    </route>
    <route>
      <destination>2001:db8:1::/64</destination>
      <nexthop>
        <gateway>2001:db8:1::1</gateway>
      </nexthop>
      <priority>1</priority>
    </route>
  </ipv6:static>
</interface>
0707010000016D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002300000000wicked2nm-1.2.1/tests/send_release0707010000016E000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002700000000wicked2nm-1.2.1/tests/send_release/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_ge=1.52
0707010000016F000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/send_release/netconfig07070100000170000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/send_release/netconfig/config07070100000171000081A4000000000000000000000001689C733A00000043000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/send_release/netconfig/dhcpDHCLIENT_RELEASE_BEFORE_QUIT=yes
DHCLIENT6_RELEASE_BEFORE_QUIT=yes
07070100000172000081A4000000000000000000000001689C733A0000001E000000000000000000000000000000000000003800000000wicked2nm-1.2.1/tests/send_release/netconfig/ifcfg-eth9STARTMODE=auto
BOOTPROTO=dhcp
07070100000173000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/send_release/system-connections07070100000174000081A4000000000000000000000001689C733A0000018F000000000000000000000000000000000000004800000000wicked2nm-1.2.1/tests/send_release/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=068f01ea-be4d-4400-9596-8d84784d5d17
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dhcp-send-hostname-deprecated=false
dhcp-send-hostname=0
dhcp-send-release=1
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
dhcp-send-hostname-deprecated=false
dhcp-send-hostname=0
dhcp-send-release=1
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000175000081A4000000000000000000000001689C733A000000EF000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/send_release/system-connections/lo.nmconnection[connection]
id=lo
uuid=3896cf4e-6f4c-4e26-af71-d6875a4891cc
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
method=manual

[proxy]
07070100000176000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002E00000000wicked2nm-1.2.1/tests/send_release/wicked_xml07070100000177000081A4000000000000000000000001689C733A00000338000000000000000000000000000000000000003900000000wicked2nm-1.2.1/tests/send_release/wicked_xml/config.xml<interface origin="compat:suse:/tests/send_release/netconfig/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <recover-lease>true</recover-lease>
    <release-lease>true</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>true</release-lease>
  </ipv6:dhcp>
</interface>
07070100000178000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002400000000wicked2nm-1.2.1/tests/send_release207070100000179000081A4000000000000000000000001689C733A000000B6000000000000000000000000000000000000002800000000wicked2nm-1.2.1/tests/send_release2/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
NM_VERSION_lt=1.52
0707010000017A000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002E00000000wicked2nm-1.2.1/tests/send_release2/netconfig0707010000017B000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003500000000wicked2nm-1.2.1/tests/send_release2/netconfig/config0707010000017C000081A4000000000000000000000001689C733A00000043000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/send_release2/netconfig/dhcpDHCLIENT_RELEASE_BEFORE_QUIT=yes
DHCLIENT6_RELEASE_BEFORE_QUIT=yes
0707010000017D000081A4000000000000000000000001689C733A0000001E000000000000000000000000000000000000003900000000wicked2nm-1.2.1/tests/send_release2/netconfig/ifcfg-eth9STARTMODE=auto
BOOTPROTO=dhcp
0707010000017E000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003700000000wicked2nm-1.2.1/tests/send_release2/system-connections0707010000017F000081A4000000000000000000000001689C733A00000127000000000000000000000000000000000000004900000000wicked2nm-1.2.1/tests/send_release2/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=068f01ea-be4d-4400-9596-8d84784d5d17
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
dhcp-send-hostname=false
ignore-auto-dns=true
method=auto

[ipv6]
addr-gen-mode=default
dhcp-send-hostname=false
ignore-auto-dns=true
ip6-privacy=1
method=auto

[proxy]
07070100000180000081A4000000000000000000000001689C733A000000EF000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/send_release2/system-connections/lo.nmconnection[connection]
id=lo
uuid=3896cf4e-6f4c-4e26-af71-d6875a4891cc
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
method=manual

[proxy]
07070100000181000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/send_release2/wicked_xml07070100000182000081A4000000000000000000000001689C733A00000339000000000000000000000000000000000000003A00000000wicked2nm-1.2.1/tests/send_release2/wicked_xml/config.xml<interface origin="compat:suse:/tests/send_release2/netconfig/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv4:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>default-route,dns,nis,ntp,nds,mtu,tz,boot</update>
    <recover-lease>true</recover-lease>
    <release-lease>true</release-lease>
  </ipv4:dhcp>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
  </ipv6>
  <ipv6:dhcp>
    <enabled>true</enabled>
    <flags>group</flags>
    <update>dns,nis,ntp,tz,boot</update>
    <mode>auto</mode>
    <rapid-commit>true</rapid-commit>
    <recover-lease>true</recover-lease>
    <refresh-lease>false</refresh-lease>
    <release-lease>true</release-lease>
  </ipv6:dhcp>
</interface>
07070100000183000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002000000000wicked2nm-1.2.1/tests/startmode07070100000184000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003300000000wicked2nm-1.2.1/tests/startmode/system-connections07070100000185000081A4000000000000000000000001689C733A000000E5000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/startmode/system-connections/startmode0.nmconnection[connection]
id=startmode0
uuid=9c634f1a-166b-4c91-b1b5-df831add1623
type=dummy
autoconnect=false
interface-name=startmode0

[ethernet]

[dummy]

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=auto

[proxy]
07070100000186000081A4000000000000000000000001689C733A000000D3000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/startmode/system-connections/startmode1.nmconnection[connection]
id=startmode1
uuid=43c52f71-5298-4147-9950-f41ed65f9093
type=dummy
interface-name=startmode1

[ethernet]

[dummy]

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=auto

[proxy]
07070100000187000081A4000000000000000000000001689C733A000000E5000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/startmode/system-connections/startmode2.nmconnection[connection]
id=startmode2
uuid=37374441-f8c1-495f-abf5-33dd859b1691
type=dummy
autoconnect=false
interface-name=startmode2

[ethernet]

[dummy]

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=auto

[proxy]
07070100000188000081A4000000000000000000000001689C733A000000D3000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/startmode/system-connections/startmode3.nmconnection[connection]
id=startmode3
uuid=4cddd65e-11ca-4f75-bc01-cc2f62336681
type=dummy
interface-name=startmode3

[ethernet]

[dummy]

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=auto

[proxy]
07070100000189000081A4000000000000000000000001689C733A000000D3000000000000000000000000000000000000004B00000000wicked2nm-1.2.1/tests/startmode/system-connections/startmode4.nmconnection[connection]
id=startmode4
uuid=5571cf47-8af8-4218-9b61-3f0506e3595b
type=dummy
interface-name=startmode4

[ethernet]

[dummy]

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=auto

[proxy]
0707010000018A000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/startmode/wicked_xml0707010000018B000081A4000000000000000000000001689C733A000005EB000000000000000000000000000000000000003900000000wicked2nm-1.2.1/tests/startmode/wicked_xml/startmode.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-startmode0">
  <name>startmode0</name>
  <control>
    <mode>manual</mode>
  </control>
  <firewall/>
  <dummy/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-startmode1">
  <name>startmode1</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <dummy/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-startmode2">
  <name>startmode2</name>
  <control>
    <mode>off</mode>
  </control>
  <firewall/>
  <dummy/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-startmode3">
  <name>startmode3</name>
  <control>
    <mode>hotplug</mode>
  </control>
  <firewall/>
  <dummy/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-startmode4">
  <name>startmode4</name>
  <control>
    <mode>boot</mode>
    <boot-stage>localfs</boot-stage>
    <persistent>true</persistent>
  </control>
  <firewall/>
  <dummy/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
  </ipv4>
  <ipv6>
    <enabled>true</enabled>
  </ipv6>
</interface>
0707010000018C000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002100000000wicked2nm-1.2.1/tests/static_dns0707010000018D000081A4000000000000000000000001689C733A000000A3000000000000000000000000000000000000002500000000wicked2nm-1.2.1/tests/static_dns/ENVW2NM_CONTINUE_MIGRATION=false
W2NM_WITHOUT_NETCONFIG=false
W2NM_NETCONFIG_PATH=./netconfig/config
W2NM_NETCONFIG_DHCP_PATH=./netconfig/dhcp
TEST_EXPECT_FAIL=false
0707010000018E000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002B00000000wicked2nm-1.2.1/tests/static_dns/netconfig0707010000018F000081A4000000000000000000000001689C733A0000263C000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/static_dns/netconfig/config## Path:	Network/General
## Description:	Global network configuration
#
# Note: 
# Most of the options can and should be overridden by per-interface
# settings in the ifcfg-* files.
#
# Note: The ISC dhclient started by the NetworkManager is not using any
# of these options -- NetworkManager is not using any sysconfig settings.
#

## Type:        yesno
## Default:     yes
# If ifup should check if an IPv4 address is already in use, set this to yes.
#
# Make sure that packet sockets (CONFIG_PACKET) are supported in the kernel,
# since this feature uses arp, which depends on that.
# Also be aware that this takes one second per interface; consider that when
# setting up a lot of interfaces. 
CHECK_DUPLICATE_IP="yes"

## Type:        list(auto,yes,no)
## Default:     auto
# If ifup should send a gratuitous ARP to inform the receivers about its
# IPv4 addresses. Default is to send gratuitous ARP, when duplicate IPv4
# address check is enabled and the check were successful.
#
# Make sure that packet sockets (CONFIG_PACKET) are supported in the kernel,
# since this feature uses arp, which depends on that.
SEND_GRATUITOUS_ARP="auto"

## Type:        yesno
## Default:     no
# Switch on/off debug messages for all network configuration stuff. If set to no
# most scripts can enable it locally with "-o debug".
DEBUG="no"

## Type:	integer
## Default:	30
#
# Some interfaces need some time to come up or come asynchronously via hotplug.
# WAIT_FOR_INTERFACES is a global wait for all mandatory interfaces in
# seconds. If empty no wait occurs.
#
WAIT_FOR_INTERFACES="30"

## Type:	yesno
## Default:	yes
#
# With this variable you can determine if the SuSEfirewall when enabled
# should get started when network interfaces are started.
FIREWALL="yes"

## Type:	int
## Default:	30
#
# When using NetworkManager you may define a timeout to wait for NetworkManager
# to connect in NetworkManager-wait-online.service.  Other network services
# may require the system to have a valid network setup in order to succeed.
#
# This variable has no effect if NetworkManager is disabled.
#
NM_ONLINE_TIMEOUT="30"

## Type:        string
## Default:     "dns-resolver dns-bind ntp-runtime nis"
#
# This variable defines the start order of netconfig modules installed
# in the /etc/netconfig.d and /usr/libexec/netconfig/netconfig.d/ directories.
#
# To disable the execution of a module, don't remove it from the list
# but prepend it with a minus sign, "-ntp-runtime".
#
NETCONFIG_MODULES_ORDER="dns-resolver dns-bind dns-dnsmasq nis ntp-runtime"

## Type:        yesno
## Default:     no
#
# Enable netconfig verbose reporting.
#
NETCONFIG_VERBOSE="no"

## Type:	yesno
## Default:	no
#
# This variable enables netconfig to always force a replace of modified
# files and automatically enables the -f | --force-replace parameter.
#
# The purpose is to use it as workaround, when some other tool trashes
# the files, e.g. /etc/resolv.conf and you observe messages like this
# in your logs on in "netconfig update" output:
# ATTENTION: You have modified /etc/resolv.conf. Leaving it untouched.
#
# Please do not forget to also report a bug as we have a system policy
# to use netconfig.
#
NETCONFIG_FORCE_REPLACE="no"

## Type:        string
## Default:     "auto"
#
# Defines the DNS merge policy as documented in netconfig(8) manual page.
# Set to "" to disable DNS configuration.
#
NETCONFIG_DNS_POLICY="STATIC"

## Type:        string(resolver,bind,dnsmasq,)
## Default:     "resolver"
#
# Defines the name of the DNS forwarder that has to be configured.
# Currently implemented are "bind", "dnsmasq" and "resolver", that
# causes to write the name server IP addresses to /etc/resolv.conf
# only (no forwarder). Empty string defaults to "resolver".
#
NETCONFIG_DNS_FORWARDER="resolver"

## Type:        yesno
## Default:     yes
#
# When enabled (default) in forwarder mode ("bind", "dnsmasq"),
# netconfig writes an explicit localhost nameserver address to the
# /etc/resolv.conf, followed by the policy resolved name server list
# as fallback for the moments, when the local forwarder is stopped.
#
NETCONFIG_DNS_FORWARDER_FALLBACK="yes"

## Type:        string
## Default:     ""
#
# List of DNS domain names used for host-name lookup.
# It is written as search list into the /etc/resolv.conf file.
#
NETCONFIG_DNS_STATIC_SEARCHLIST="suse.de suse.com"

## Type:        string
## Default:     ""
#
# List of DNS nameserver IP addresses to use for host-name lookup.
# When the NETCONFIG_DNS_FORWARDER variable is set to "resolver",
# the name servers are written directly to /etc/resolv.conf.
# Otherwise, the nameserver are written into a forwarder specific
# configuration file and the /etc/resolv.conf does not contain any
# nameservers causing the glibc to use the name server on the local
# machine (the forwarder). See also netconfig(8) manual page.
#
NETCONFIG_DNS_STATIC_SERVERS="192.168.0.10 192.168.1.10 2001:db8::10"

## Type:        string
## Default:     "auto"
#
# Allows to specify a custom DNS service ranking list, that is which
# services provide preferred (e.g. vpn services), and which services
# fallback settings (e.g. avahi).
# Preferred service names have to be prepended with a "+", fallback
# service names with a "-" character. The special default value
# "auto" enables the current build-in service ranking list -- see the
# netconfig(8) manual page -- "none" or "" disables the ranking.
#
NETCONFIG_DNS_RANKING="auto"

## Type:        string
## Default:     ""
#
# Allows to specify options to use when writing the /etc/resolv.conf,
# for example:
# 	"debug attempts:1 timeout:10"
# See resolv.conf(5) manual page for details.
#
NETCONFIG_DNS_RESOLVER_OPTIONS=""

## Type:        string
## Default:     ""
#
# Allows to specify a sortlist to use when writing the /etc/resolv.conf,
# for example:
# 	130.155.160.0/255.255.240.0 130.155.0.0"
# See resolv.conf(5) manual page for details.
#
NETCONFIG_DNS_RESOLVER_SORTLIST=""

## Type:        string
## Default:     "auto"
#
# Defines the NTP merge policy as documented in netconfig(8) manual page.
# Set to "" to disable NTP configuration.
#
NETCONFIG_NTP_POLICY="auto"

## Type:        string
## Default:     ""
#
# List of NTP servers.
#
NETCONFIG_NTP_STATIC_SERVERS=""

## Type:        string
## Default:     "auto"
#
# Defines the NIS merge policy as documented in netconfig(8) manual page.
# Set to "" to disable NIS configuration.
#
NETCONFIG_NIS_POLICY="auto"

## Type:        string(yes,no,)
## Default:     "yes"
#
# Defines whether to set the default NIS domain. When enabled and no domain
# is provided dynamically or in static settings, /etc/defaultdomain is used.
# Valid values are:
#  - "no" or ""         netconfig does not set the domainname
#  - "yes"              netconfig sets the domainname according to the
#                       NIS policy using settings provided by the first
#                       interface and service that provided it.
#  - "<interface name>" as yes, but only using settings from interface.
#
NETCONFIG_NIS_SETDOMAINNAME="yes"

## Type:        string
## Default:     ""
#
# Defines a default NIS domain.
#
# Further domain can be specified by adding a "_<number>" suffix to
# the NETCONFIG_NIS_STATIC_DOMAIN and NETCONFIG_NIS_STATIC_SERVERS
# variables, e.g.: NETCONFIG_NIS_STATIC_DOMAIN_1="second".
#
NETCONFIG_NIS_STATIC_DOMAIN=""

## Type:        string
## Default:     ""
#
# Defines a list of NIS servers for the default NIS domain or the
# domain specified with same "_<number>" suffix.
#
NETCONFIG_NIS_STATIC_SERVERS=""

## Type:	string
## Default:	''
#
# Set this variable global variable to the ISO / IEC 3166 alpha2
# country code specifying the wireless regulatory domain to set.
# When not empty, ifup-wireless will be set in the wpa_supplicant
# config or via 'iw reg set' command.
#
# Note: This option requires a wpa driver supporting it, like
# the 'nl80211' driver used by default since openSUSE 11.3.
# When you notice problems with your hardware, please file a
# bug report and set e.g. WIRELESS_WPA_DRIVER='wext' (the old
# default driver) in the ifcfg file.
# See also "/usr/sbin/wpa_supplicant --help" for the list of
# available wpa drivers.
#
WIRELESS_REGULATORY_DOMAIN=''
## Type:        integer
## Default:     ""
#
# How log to wait for IPv6 autoconfig in ifup when requested with
# the auto6 or +auto6 tag in BOOTPROTO variable.
# When unset, a wicked built-in default defer time (10sec) is used.
#
AUTO6_WAIT_AT_BOOT=""

## Type:        list(all,dns,none,"")
## Default:     ""
#
# Whether to update system (DNS) settings from IPv6 RA when requested
# with the auto6 or +auto6 tag in BOOTPROTO variable.
# Defaults to update if autoconf sysctl (address autoconf) is enabled.
#
AUTO6_UPDATE=""

## Type:        list(auto,yes,no)
## Default:     "auto"
#
# Permits to specify/modify a global ifcfg default. Use with care!
#
# This settings breaks rules for many things, which require carrier
# before they can start, e.g. L2 link protocols, link authentication,
# ipv4 duplicate address detection, ipv6 duplicate detection will
# happen "post-mortem" and maybe even cause to disable ipv6 at all.
# See also "man ifcfg" for further information.
#
LINK_REQUIRED="auto"

## Type:        string
## Default:     ""
#
# Allows to specify a comma separated list of debug facilities used
# by wicked. Negated facility names can be prepended by a "-", e.g.:
#   "all,-events,-socket,-objectmodel,xpath,xml,dbus"
#
# When set, wicked debug level is automatically enabled.
# For a complete list of facility names, see: "wicked --debug help".
#
WICKED_DEBUG=""

## Type:        list("",error,warning,notice,info,debug,debug1,debug2,debug3)
## Default:     ""
#
# Allows to specify wicked debug level. Default level is "notice".
#
WICKED_LOG_LEVEL=""
07070100000190000081A4000000000000000000000001689C733A00000000000000000000000000000000000000000000003000000000wicked2nm-1.2.1/tests/static_dns/netconfig/dhcp07070100000191000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003400000000wicked2nm-1.2.1/tests/static_dns/system-connections07070100000192000081A4000000000000000000000001689C733A000000EF000000000000000000000000000000000000004600000000wicked2nm-1.2.1/tests/static_dns/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=5e734b30-8000-4889-894e-61c7a185b835
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
ignore-auto-dns=true
method=disabled

[ipv6]
addr-gen-mode=default
ignore-auto-dns=true
method=disabled

[proxy]
07070100000193000081A4000000000000000000000001689C733A0000017A000000000000000000000000000000000000004400000000wicked2nm-1.2.1/tests/static_dns/system-connections/lo.nmconnection[connection]
id=lo
uuid=8711628a-f044-4516-a5b4-bb19f4f9f8fd
type=loopback
interface-name=lo

[ethernet]

[loopback]

[match]

[ipv4]
address1=127.0.0.1/8
dns=192.168.0.10;192.168.1.10;
dns-priority=10
dns-search=suse.de;suse.com;
method=manual

[ipv6]
addr-gen-mode=default
address1=::1/128
dns=2001:db8::10;
dns-priority=10
dns-search=suse.de;suse.com;
method=manual

[proxy]
07070100000194000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002C00000000wicked2nm-1.2.1/tests/static_dns/wicked_xml07070100000195000081A4000000000000000000000001689C733A0000010B000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/static_dns/wicked_xml/basic.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
07070100000196000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001A00000000wicked2nm-1.2.1/tests/tap07070100000197000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/tap/system-connections07070100000198000081A4000000000000000000000001689C733A000000CE000000000000000000000000000000000000003F00000000wicked2nm-1.2.1/tests/tap/system-connections/tap9.nmconnection[connection]
id=tap9
uuid=059e4e35-8b7a-4fae-a2bd-7d172c5c4e94
type=tun
interface-name=tap9

[tun]
group=0
mode=2
owner=0

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=auto

[proxy]
07070100000199000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002500000000wicked2nm-1.2.1/tests/tap/wicked_xml0707010000019A000081A4000000000000000000000001689C733A000000E6000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/tap/wicked_xml/tun.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-tap9">
  <name>tap9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <tap>
    <owner>0</owner>
    <group>0</group>
  </tap>
  <link/>
</interface>
0707010000019B000081ED000000000000000000000001689C733A00002469000000000000000000000000000000000000001E00000000wicked2nm-1.2.1/tests/test.sh#!/bin/bash
RED='\033[0;31m'
GREEN='\033[0;32m'
BOLD='\033[1m'
NC='\033[0m'
FAILED_TESTS=()
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd $SCRIPT_DIR
MIGRATE_WICKED_BIN="$SCRIPT_DIR/../target/debug/wicked2nm"
TEST_DIRS=${TEST_DIRS:-$(ls -d */ | sed 's#/##')}
NO_CLEANUP=${NO_CLEANUP:-0}
NO_WICKED=${NO_WICKED:-0}
NM_CLEANUP=${NM_CLEANUP:-0}
FORCE=${FORCE:-0}
LOG_LEVEL=1
TEST_STDIN=true
NM_VERSION=$(NetworkManager --version)
KEEP_CONNECTIONS=()
CONNECTIONS=()

error_msg() {
  log_error "Error for test $1:$2"
}

log_error() {
  [ $LOG_LEVEL -gt 0 ] && echo -e "${RED}$@${NC}"
}

log_verbose() {
    [ $LOG_LEVEL -gt 1 ] && echo -e "$@"
}

keep_connection() {
    local con=$1
    local element

    for element in "${KEEP_CONNECTIONS[@]}"; do
        if [[ "$element" == "$con" ]]; then
            return 0 # Found
        fi
    done
    return 1 # Not found
}

refresh_connections() {
    local filename 

    CONNECTIONS=()
    while IFS= read -r -d '' filename ; do
        [[ "$filename" != *".nmconnection" ]] && continue
        uuid=$(grep '^uuid=' "$filename" -m 1 | cut -d=  -f2)
        con_name=$(grep '^id=' "$filename" -m 1 | cut -d=  -f2)
        keep_connection "$con_name" && continue
        keep_connection "$uuid" && continue
        CONNECTIONS+=("$con_name")
    done < <(find "/etc/NetworkManager/system-connections/" -maxdepth 1 -type f -print0)
}

nm_cleanup() {
    refresh_connections

    for con in "${CONNECTIONS[@]}"; do
        IFS=: read NAME UUID XXX < <(nmcli -t -f NAME,UUID c s | grep -P '(^|:)'"$con"'($|:)')
        [[ -z "$UUID" ]] && continue;

        echo "nmcli con delete $UUID ($NAME)"
        nmcli con delete "$UUID"
        while nmcli -t -f UUID c s | grep -P "^$UUID$" >/dev/null; do
          echo " -> Wait for $NAME($UUID) deletion"
            sleep 1 
        done
    done
}

nm_version_greater_equal() {
    printf '%s\n%s\n' "$1" "$NM_VERSION" | sort --check=quiet --version-sort
}

print_help()
{
  echo "Usage:"
  echo "   ./test [ARGUMENTS] [TEST_DIRS]"
  echo ""
  echo "Arguments:"
  echo "  -v|--verbose            Be more verbose"
  echo "  --debug                 Prints out all commands executed"
  echo "  -q|--quiet              Be less verbose"
  echo "  --nm-cleanup            Cleanup current NetworkManager config before start"
  echo "  -f|--force              Force decision (e.g. cleanup Connections)"
  echo "  -k|--keep-connection    Connections will not be removed with --nm-cleanup"
  echo "  --no-cleanup            Do not cleanup NetworkManger after test"
  echo "  --no-wicked             If set, ifcfg tests do not fail when wicked isn't available"
  echo "  -h|--help               Print this help"
}

POSITIONAL_ARGS=()

while [[ $# -gt 0 ]]; do
  opt=$1; 
  shift;
  case $opt in
    -v|--verbose)
      LOG_LEVEL=$((LOG_LEVEL + 1))
      ;;
    --debug)
      set -x
      ;;
    --binary)
      MIGRATE_WICKED_BIN=$1; shift
      ;;
    --no-wicked)
      NO_WICKED=1;
      ;;
    -k|--keep-connection)
      KEEP_CONNECTIONS+=("$1")
      shift;
      ;;
    --nm-cleanup)
      NM_CLEANUP=1
      ;;
    -f|--force)
      FORCE=1
      ;;
    --no-cleanup)
      NO_CLEANUP=1
      ;;
    -q|--quiet)
      [ $LOG_LEVEL -gt 0 ] && LOG_LEVEL=$((LOG_LEVEL - 1))
      ;;
    -h|--help)
      print_help
      exit 0;
      ;;
    -*|--*)
      echo "Unknown option $opt"
      exit 1
      ;;
    *)
      POSITIONAL_ARGS+=("$opt") # save positional arg
      ;;
  esac
done

if [ ${#POSITIONAL_ARGS[@]} -gt 0 ]; then
  TEST_STDIN=false
  TEST_DIRS=()
  for pos_arg in "${POSITIONAL_ARGS[@]}"; do
      if [[ "$pos_arg" == "stdin" ]]; then
          TEST_STDIN=true
      else
          TEST_DIRS+=("$pos_arg")
      fi
  done
fi

if [[ $NM_CLEANUP -gt 0 ]]; then
    refresh_connections
    if [ ${#CONNECTIONS[@]} -gt 0 ]; then
        echo -e "The following connections will be deleted:"
        for c in "${CONNECTIONS[@]}"; do echo "  $c"; done | sort
        if [ "$FORCE" -ne 1 ]; then
          read -p "Do you want to continue? [y/N] " continue_cleanup
          if [ "$continue_cleanup" != "y" ]; then
              exit 1
          fi
        fi
        nm_cleanup
    fi
fi

refresh_connections
if [[ ${#CONNECTIONS[@]} -gt 0 ]]; then
    echo -e "${RED}There are already NM connections. You may be running this script on a live system, which is highly discouraged!${NC}"
    exit 1
fi

if [ ! -f $MIGRATE_WICKED_BIN ]; then
    echo -e "${RED}No wicked2nm binary found${NC}"
    exit 1
fi

for test_dir in ${TEST_DIRS}; do
    if [ ! -d "$SCRIPT_DIR/$test_dir" ]; then
        echo -e "${RED}[ERROR]${NC} Directory ${BOLD}$test_dir${NC} doesn't exists!"
        FAILED_TESTS+=("${test_dir}::test-dir-exists")
        continue
    fi

    echo -e "${BOLD}Testing ${test_dir}${NC}"

    cd $SCRIPT_DIR/$test_dir

    # Apply environment variables of test
    export W2NM_CONTINUE_MIGRATION=false
    export W2NM_WITHOUT_NETCONFIG=true
    export W2NM_NETCONFIG_PATH=
    export W2NM_NETCONFIG_DHCP_PATH=
    NM_VERSION_lt=
    NM_VERSION_ge=
    TEST_EXPECT_FAIL=false
    if [ -f  ./ENV ]; then
       set -a && source ./ENV
       set +a
    fi

    if [ -n "$NM_VERSION_ge" ] && ! nm_version_greater_equal "$NM_VERSION_ge"; then
        echo "NM version too low, skipping..."
        continue
    fi
    if [ -n "$NM_VERSION_lt" ] && nm_version_greater_equal "$NM_VERSION_lt"; then
        echo "NM version too high, skipping..."
        continue
    fi

    if ls -1 ./netconfig/ifcfg-* >/dev/null 2>&1 && [ $NO_WICKED -eq 0 ]; then
        err_log="$SCRIPT_DIR/$test_dir/wicked_show_config_error.log"
        cfg_out="$SCRIPT_DIR/$test_dir/wicked_xml/config.xml"
        if ! command -v wicked >/dev/null ; then
            error_msg "$test_dir" "missing wicked executable"
            FAILED_TESTS+=("${test_dir}::wicked-show-config")
            continue
        fi

        wicked show-config --ifconfig compat:./netconfig \
            > "$cfg_out" \
            2> "$err_log"

        if [ $? -ne 0 ] || [ -s "$err_log" ]; then
            err_msg="'wicked show-config' failed"
            [ -s "$err_log" ] && err_msg+=" see $err_log"

            error_msg "$test_dir" "$err_msg"
            FAILED_TESTS+=("${test_dir}::wicked-show-config")
            continue
        fi

        # https://unix.stackexchange.com/a/209744
        regex_esc_test_dir="$(printf '%s' "$test_dir" | sed 's/[\/.[\(*^$+?{|]/\\&/g')"
        sed -i -E 's/[^:]+(\/tests\/'"$regex_esc_test_dir"')/\1/' "$cfg_out"
    fi

    log_verbose "RUN: $MIGRATE_WICKED_BIN show $test_dir/wicked_xml"
    $MIGRATE_WICKED_BIN show ./wicked_xml
    if [ $? -ne 0 ] && [ "$TEST_EXPECT_FAIL" = false ]; then
        error_msg ${test_dir} "show failed"
        FAILED_TESTS+=("${test_dir}::show")
    fi

    log_verbose "RUN: $MIGRATE_WICKED_BIN migrate $test_dir/wicked_xml"
    $MIGRATE_WICKED_BIN migrate ./wicked_xml
    if [ $? -ne 0 ] && [ "$TEST_EXPECT_FAIL" = false ]; then
        error_msg ${test_dir} "migration failed"
        FAILED_TESTS+=("${test_dir}::migrate")
        continue
    elif [ $? -ne 0 ] && [ "$TEST_EXPECT_FAIL" = true ]; then
        echo -e "${GREEN}Migration for $test_dir failed as expected${NC}"
    fi

    if [ -d "./system-connections" ]; then
      for cmp_file in $(ls -1 ./system-connections/); do
          a="./system-connections/$cmp_file"
          b="/etc/NetworkManager/system-connections/${cmp_file}"
          diff_cmd="diff --unified=0 --color=always -I uuid -I timestamp $a $b"
          log_verbose "RUN: $diff_cmd"
          if $diff_cmd; then
              echo -e "${GREEN}Migration for connection ${cmp_file/\.nmconnection/} successful${NC}"
          else
              diff_cmd="diff  -I uuid -I timestamp --color=always $a $b"
              log_verbose "RUN: $diff_cmd\n$($diff_cmd)\n"
              error_msg ${test_dir} "$cmp_file didn't match"
              FAILED_TESTS+=("${test_dir}::compare_config::${cmp_file}")
          fi
      done
    fi

    [ "$NO_CLEANUP" -gt 0 ] || nm_cleanup
done

if $TEST_STDIN; then
    echo -e "${BOLD}Testing stdin show${NC}"
    cat <<EOF | $MIGRATE_WICKED_BIN show --without-netconfig - | grep "192.168.100.5" &>/dev/null
<interface>
  <ipv4:static>
    <address>
      <local>192.168.100.5/24</local>
    </address>
  </ipv4:static>
</interface>
EOF
    if [ $? -ne 0 ]; then
        error_msg "stdin" "show failed"
        FAILED_TESTS+=("stdin::show")
    else
        echo -e "${GREEN}stdin show successful${NC}"
    fi

    echo -e "${BOLD}Testing stdin migrate${NC}"
    cat <<EOF | $MIGRATE_WICKED_BIN migrate --without-netconfig --dry-run --log-level DEBUG - 2>&1 | grep "192.168.100.5" &>/dev/null
<interface>
  <ipv4:static>
    <address>
      <local>192.168.100.5/24</local>
    </address>
  </ipv4:static>
</interface>
EOF
    if [ $? -ne 0 ]; then
        error_msg "stdin" "migrate failed"
        FAILED_TESTS+=("stdin::migrate")
    else
        echo -e "${GREEN}stdin migrate successful${NC}"
    fi
fi

echo -e "\n${BOLD}Result:${NC}"

if [ ${#FAILED_TESTS[@]} -eq 0 ]; then
    echo -e "${GREEN}All tests successful${NC}"
else
    echo -e "${RED}Failed test cases:"
    for testcase in "${FAILED_TESTS[@]}"; do
        echo "  $testcase"
    done
    echo -n -e "${NC}"
    exit 1
fi
0707010000019C000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001A00000000wicked2nm-1.2.1/tests/tun0707010000019D000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/tun/system-connections0707010000019E000081A4000000000000000000000001689C733A000000C7000000000000000000000000000000000000003F00000000wicked2nm-1.2.1/tests/tun/system-connections/tun9.nmconnection[connection]
id=tun9
uuid=d06fb4af-cda0-4314-9a7e-c337d636d6d6
type=tun
interface-name=tun9

[tun]
group=0
owner=0

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=auto

[proxy]
0707010000019F000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002500000000wicked2nm-1.2.1/tests/tun/wicked_xml070701000001A0000081A4000000000000000000000001689C733A000000E6000000000000000000000000000000000000002D00000000wicked2nm-1.2.1/tests/tun/wicked_xml/tun.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-tun9">
  <name>tun9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <tun>
    <owner>0</owner>
    <group>0</group>
  </tun>
  <link/>
</interface>
070701000001A1000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001B00000000wicked2nm-1.2.1/tests/vlan070701000001A2000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002E00000000wicked2nm-1.2.1/tests/vlan/system-connections070701000001A3000081A4000000000000000000000001689C733A0000013B000000000000000000000000000000000000004300000000wicked2nm-1.2.1/tests/vlan/system-connections/eth9.10.nmconnection[connection]
id=eth9.10
uuid=91726373-17de-4fbc-b794-91f2e13127aa
type=vlan
interface-name=eth9.10

[ethernet]
cloned-mac-address=DE:EA:DD:BE:EE:FF

[vlan]
flags=0
id=10
parent=eth9
protocol=802.1Q

[match]

[ipv4]
address1=10.1.0.1/24
method=manual

[ipv6]
addr-gen-mode=default
ip6-privacy=1
method=auto

[proxy]
070701000001A4000081A4000000000000000000000001689C733A000000E7000000000000000000000000000000000000004000000000wicked2nm-1.2.1/tests/vlan/system-connections/eth9.nmconnection[connection]
id=eth9
uuid=413aa828-9cb9-4dfe-8b16-8774fbe2d9f4
type=ethernet
interface-name=eth9

[ethernet]

[match]

[ipv4]
address1=192.168.100.5/24
method=manual

[ipv6]
addr-gen-mode=default
ip6-privacy=1
method=auto

[proxy]
070701000001A5000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002600000000wicked2nm-1.2.1/tests/vlan/wicked_xml070701000001A6000081A4000000000000000000000001689C733A000001E3000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/vlan/wicked_xml/eth9.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth9">
  <name>eth9</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:static>
    <address>
      <local>192.168.100.5/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
</interface>
070701000001A7000081A4000000000000000000000001689C733A00000270000000000000000000000000000000000000002F00000000wicked2nm-1.2.1/tests/vlan/wicked_xml/vlan.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-eth9.10">
  <name>eth9.10</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <vlan>
    <device>eth9</device>
    <address>de:ea:dd:be:ee:ff</address>
    <protocol>ieee802-1Q</protocol>
    <tag>10</tag>
  </vlan>
  <link/>
  <ipv4>
    <enabled>true</enabled>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv4:static>
    <address>
      <local>10.1.0.1/24</local>
    </address>
  </ipv4:static>
  <ipv6>
    <enabled>true</enabled>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
</interface>
070701000001A8000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000001F00000000wicked2nm-1.2.1/tests/wireless070701000001A9000081A4000000000000000000000001689C733A00000065000000000000000000000000000000000000002300000000wicked2nm-1.2.1/tests/wireless/ENVW2NM_CONTINUE_MIGRATION=true
W2NM_WITHOUT_NETCONFIG=true
W2NM_NETCONFIG_PATH=
TEST_EXPECT_FAIL=false
070701000001AA000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003200000000wicked2nm-1.2.1/tests/wireless/system-connections070701000001AB000081A4000000000000000000000001689C733A0000017D000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan0-0.nmconnection[connection]
id=wlan0-0
uuid=2a262d6e-ccba-4afb-a190-ec08d0175c56
type=wifi
autoconnect=false
interface-name=wlan0

[wifi]
band=a
bssid=12:34:56:78:9A:BC
channel=100
hidden=true
mode=adhoc
ssid=example_ssid

[wifi-security]
group=ccmp;
key-mgmt=wpa-psk
pairwise=ccmp;
pmf=2
psk=example_passwd

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001AC000081A4000000000000000000000001689C733A00000154000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan0-1.nmconnection[connection]
id=wlan0-1
uuid=e05ab8eb-9905-4746-b81a-54e190b16354
type=wifi
autoconnect=false
interface-name=wlan0

[wifi]
hidden=true
mode=adhoc
ssid=example_ssid2

[wifi-security]
group=ccmp;
key-mgmt=wpa-psk
pairwise=ccmp;
pmf=2
psk=example_passwd2

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001AD000081A4000000000000000000000001689C733A00000189000000000000000000000000000000000000004500000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan1.nmconnection[connection]
id=wlan1
uuid=9d48ef42-2c96-4e43-8ab6-6c66385efdb6
type=wifi
autoconnect=false
interface-name=wlan1

[wifi]
bssid=12:34:56:78:9A:BC
mode=infrastructure
ssid=wep_1

[wifi-security]
auth-alg=shared
key-mgmt=none
wep-key-type=1
wep-key0=hello
wep-key1=5b73215e232f4c577c5073455d
wep-tx-keyidx=1

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001AE000081A4000000000000000000000001689C733A000000ED000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan2-0.nmconnection[connection]
id=wlan2-0
uuid=81ea2b2d-e6bb-4897-aded-de95eb298de5
type=wifi
interface-name=wlan2

[wifi]
hidden=true
mode=infrastructure
ssid=open_1

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001AF000081A4000000000000000000000001689C733A000000E1000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan2-1.nmconnection[connection]
id=wlan2-1
uuid=30a3966f-3005-4cab-bc0d-48b47d2d2ce6
type=wifi
interface-name=wlan2

[wifi]
mode=infrastructure
ssid=open_2

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001B0000081A4000000000000000000000001689C733A00000121000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan3-0.nmconnection[connection]
id=wlan3-0
uuid=899c6026-3000-4ca2-8526-216471cef61a
type=wifi
interface-name=wlan3

[wifi]
hidden=true
mode=infrastructure
ssid=psk_1

[wifi-security]
key-mgmt=wpa-psk
psk=total_geheim!!

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001B1000081A4000000000000000000000001689C733A00000115000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan3-1.nmconnection[connection]
id=wlan3-1
uuid=f2465ff2-fc04-46ff-88be-b14805f0e972
type=wifi
interface-name=wlan3

[wifi]
mode=infrastructure
ssid=psk_2

[wifi-security]
key-mgmt=wpa-psk
psk=total_geheim!!

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001B2000081A4000000000000000000000001689C733A00000111000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan3-2.nmconnection[connection]
id=wlan3-2
uuid=8676060a-0b82-4207-b0a2-a3420992ac2c
type=wifi
interface-name=wlan3

[wifi]
mode=infrastructure
ssid=psk_3

[wifi-security]
key-mgmt=sae
psk=total_geheim!!

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001B3000081A4000000000000000000000001689C733A00000115000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan3-3.nmconnection[connection]
id=wlan3-3
uuid=c2f7bf46-9d1c-4dc0-b347-ac8973d1feb9
type=wifi
interface-name=wlan3

[wifi]
mode=infrastructure
ssid=psk_4

[wifi-security]
key-mgmt=wpa-psk
psk=total_geheim!!

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001B4000081A4000000000000000000000001689C733A00000189000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan4-0.nmconnection[connection]
id=wlan4-0
uuid=10de7698-31f0-4af8-a55f-a4526f6693de
type=wifi
interface-name=wlan4

[wifi]
hidden=true
mode=infrastructure
ssid=eap_1

[wifi-security]
key-mgmt=wpa-eap

[802-1x]
anonymous-identity=anonymous
eap=peap;
identity=tester
password=test1234
phase1-peaplabel=0
phase2-auth=mschapv2

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001B5000081A4000000000000000000000001689C733A00000189000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan4-1.nmconnection[connection]
id=wlan4-1
uuid=2b177278-d460-4c93-95bb-c01bfca3782f
type=wifi
interface-name=wlan4

[wifi]
hidden=true
mode=infrastructure
ssid=eap_2

[wifi-security]
key-mgmt=wpa-eap

[802-1x]
anonymous-identity=anonymous
eap=peap;
identity=tester
password=test1234
phase1-peaplabel=0
phase2-auth=mschapv2

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001B6000081A4000000000000000000000001689C733A00000195000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan4-2.nmconnection[connection]
id=wlan4-2
uuid=06236476-7fdb-4d3d-97e6-a24ec71fbf44
type=wifi
interface-name=wlan4

[wifi]
hidden=true
mode=infrastructure
ssid=eap_3

[wifi-security]
key-mgmt=wpa-eap-suite-b-192

[802-1x]
anonymous-identity=anonymous
eap=peap;
identity=tester
password=test1234
phase1-peaplabel=0
phase2-auth=mschapv2

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001B7000081A4000000000000000000000001689C733A00000189000000000000000000000000000000000000004700000000wicked2nm-1.2.1/tests/wireless/system-connections/wlan4-3.nmconnection[connection]
id=wlan4-3
uuid=f8adfd38-7127-4a25-bddd-a65e8add0887
type=wifi
interface-name=wlan4

[wifi]
hidden=true
mode=infrastructure
ssid=eap_4

[wifi-security]
key-mgmt=wpa-eap

[802-1x]
anonymous-identity=anonymous
eap=peap;
identity=tester
password=test1234
phase1-peaplabel=0
phase2-auth=mschapv2

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001B8000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002A00000000wicked2nm-1.2.1/tests/wireless/wicked_xml070701000001B9000081A4000000000000000000000001689C733A000019E9000000000000000000000000000000000000003700000000wicked2nm-1.2.1/tests/wireless/wicked_xml/wireless.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-wlan0">
  <name>wlan0</name>
  <control>
    <mode>manual</mode>
  </control>
  <firewall/>
  <wireless>
    <ap-scan>1</ap-scan>
    <networks>
      <network>
        <essid>example_ssid</essid>
        <channel>100</channel>
        <access-point>12:34:56:78:9A:BC</access-point>
        <scan-ssid>true</scan-ssid>
        <mode>ad-hoc</mode>
        <key-management>wpa-psk,wpa-psk-sha256,sae</key-management>
        <wpa-psk>
          <passphrase>example_passwd</passphrase>
          <pairwise-cipher>CCMP</pairwise-cipher>
          <group-cipher>CCMP</group-cipher>
          <pmf>optional</pmf>
        </wpa-psk>
      </network>
      <network>
        <essid>example_ssid2</essid>
        <scan-ssid>true</scan-ssid>
        <mode>ad-hoc</mode>
        <key-management>wpa-psk,wpa-psk-sha256,sae</key-management>
        <wpa-psk>
          <passphrase>example_passwd2</passphrase>
          <pairwise-cipher>CCMP</pairwise-cipher>
          <group-cipher>CCMP</group-cipher>
          <pmf>optional</pmf>
        </wpa-psk>
      </network>
    </networks>
  </wireless>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-wlan1">
  <name>wlan1</name>
  <control>
    <mode>manual</mode>
  </control>
  <firewall/>
  <wireless>
    <ap-scan>1</ap-scan>
    <networks>
      <network>
        <essid>wep_1</essid>
        <scan-ssid>false</scan-ssid>
        <mode>infrastructure</mode>
        <access-point>12:34:56:78:9a:bc</access-point>
        <key-management>none</key-management>
        <wep>
          <auth-algo>shared</auth-algo>
          <default-key>1</default-key>
          <key>s:hello</key>
          <key>5b73215e232f4c577c5073455d</key>
        </wep>
      </network>
    </networks>
  </wireless>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-wlan2">
  <name>wlan2</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <wireless>
    <ap-scan>1</ap-scan>
    <networks>
      <network>
        <essid>open_1</essid>
        <scan-ssid>true</scan-ssid>
        <mode>infrastructure</mode>
      </network>
      <network>
        <essid>open_2</essid>
        <scan-ssid>false</scan-ssid>
        <mode>infrastructure</mode>
        <key-management>none</key-management>
      </network>
    </networks>
  </wireless>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-wlan3">
  <name>wlan3</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <wireless>
    <ap-scan>1</ap-scan>
    <networks>
      <network>
        <essid>psk_1</essid>
        <scan-ssid>true</scan-ssid>
        <mode>infrastructure</mode>
        <wpa-psk>
          <passphrase>total_geheim!!</passphrase>
        </wpa-psk>
      </network>
      <network>
        <essid>psk_2</essid>
        <scan-ssid>false</scan-ssid>
        <mode>infrastructure</mode>
        <key-management>wpa-psk</key-management>
        <wpa-psk>
          <passphrase>total_geheim!!</passphrase>
        </wpa-psk>
      </network>
      <network>
        <essid>psk_3</essid>
        <scan-ssid>false</scan-ssid>
        <mode>infrastructure</mode>
        <key-management>sae</key-management>
        <wpa-psk>
          <passphrase>total_geheim!!</passphrase>
        </wpa-psk>
      </network>
      <network>
        <essid>psk_4</essid>
        <scan-ssid>false</scan-ssid>
        <mode>infrastructure</mode>
        <key-management>none,wpa-psk</key-management>
        <wpa-psk>
          <passphrase>total_geheim!!</passphrase>
        </wpa-psk>
      </network>
    </networks>
  </wireless>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-wlan4">
  <name>wlan4</name>
  <control>
    <mode>boot</mode>
  </control>
  <firewall/>
  <wireless>
    <ap-scan>1</ap-scan>
    <wpa-driver>nl80211</wpa-driver>
    <networks>
      <network>
        <essid>eap_1</essid>
        <scan-ssid>true</scan-ssid>
        <mode>infrastructure</mode>
        <wpa-eap>
          <method>peap</method>
          <identity>tester</identity>
          <phase1>
            <peap-label>false</peap-label>
          </phase1>
          <phase2>
            <method>mschapv2</method>
            <password>test1234</password>
          </phase2>
          <anonid>anonymous</anonid>
          <tls/>
        </wpa-eap>
      </network>
      <network>
        <essid>eap_2</essid>
        <scan-ssid>true</scan-ssid>
        <mode>infrastructure</mode>
        <key-management>wpa-eap</key-management>
        <wpa-eap>
          <method>peap</method>
          <identity>tester</identity>
          <phase1>
            <peap-label>false</peap-label>
          </phase1>
          <phase2>
            <method>mschapv2</method>
            <password>test1234</password>
          </phase2>
          <anonid>anonymous</anonid>
          <tls/>
        </wpa-eap>
      </network>
      <network>
        <essid>eap_3</essid>
        <scan-ssid>true</scan-ssid>
        <mode>infrastructure</mode>
        <key-management>wpa-eap-suite-b</key-management>
        <wpa-eap>
          <method>peap</method>
          <identity>tester</identity>
          <phase1>
            <peap-label>false</peap-label>
          </phase1>
          <phase2>
            <method>mschapv2</method>
            <password>test1234</password>
          </phase2>
          <anonid>anonymous</anonid>
          <tls/>
        </wpa-eap>
      </network>
      <network>
        <essid>eap_4</essid>
        <scan-ssid>true</scan-ssid>
        <mode>infrastructure</mode>
        <key-management>wpa-psk,wpa-eap</key-management>
        <wpa-eap>
          <method>peap</method>
          <identity>tester</identity>
          <phase1>
            <peap-label>false</peap-label>
          </phase1>
          <phase2>
            <method>mschapv2</method>
            <password>test1234</password>
          </phase2>
          <anonid>anonymous</anonid>
          <tls/>
        </wpa-eap>
      </network>
    </networks>
  </wireless>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
070701000001BA000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002300000000wicked2nm-1.2.1/tests/wireless_eap070701000001BB000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/wireless_eap/system-connections070701000001BC000081A4000000000000000000000001689C733A00000241000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/wireless_eap/system-connections/wlan_eap0.nmconnection[connection]
id=wlan_eap0
uuid=62c02744-5807-445b-9636-421b1162e000
type=wifi
autoconnect=false
interface-name=wlan_eap0

[wifi]
bssid=12:34:56:78:9A:BC
hidden=true
mode=ap
ssid=test

[wifi-security]
group=tkip;wep40;
key-mgmt=wpa-eap
pairwise=tkip;
proto=wpa;rsn;

[802-1x]
ca-cert=/etc/sysconfig/network/./ca_cert
client-cert=/etc/sysconfig/network/./client_cert
eap=tls;
identity=test
phase1-peaplabel=0
private-key=/etc/sysconfig/network/./client_key
private-key-password=testclientpw

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
method=disabled

[proxy]
070701000001BD000081A4000000000000000000000001689C733A000001AF000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/wireless_eap/system-connections/wlan_eap1.nmconnection[connection]
id=wlan_eap1
uuid=f16a2831-d858-4d0c-8799-5262884c50cc
type=wifi
autoconnect=false
interface-name=wlan_eap1

[wifi]
hidden=true
mode=infrastructure
ssid=example_ssid

[wifi-security]
key-mgmt=wpa-eap
pmf=1

[802-1x]
anonymous-identity=bob
eap=md5;
identity=alice
password=test_pw
phase1-peaplabel=0
phase2-auth=mschapv2

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
ip6-privacy=1
method=auto

[proxy]
070701000001BE000081A4000000000000000000000001689C733A000001B9000000000000000000000000000000000000004D00000000wicked2nm-1.2.1/tests/wireless_eap/system-connections/wlan_eap2.nmconnection[connection]
id=wlan_eap2
uuid=36eca905-1ac0-42f2-873d-f2ed783f2ce6
type=wifi
autoconnect=false
interface-name=wlan_eap2

[wifi]
hidden=true
mode=infrastructure
ssid=example_ssid2

[wifi-security]
key-mgmt=wpa-eap
pairwise=ccmp;tkip;
pmf=3

[802-1x]
eap=peap;
identity=bob
password=test_pw
phase1-peaplabel=1
phase1-peapver=1
phase2-auth=chap

[match]

[ipv4]
method=disabled

[ipv6]
addr-gen-mode=default
ip6-privacy=1
method=auto

[proxy]
070701000001BF000041ED000000000000000000000002689C733A00000000000000000000000000000000000000000000002E00000000wicked2nm-1.2.1/tests/wireless_eap/wicked_xml070701000001C0000081A4000000000000000000000001689C733A00000C62000000000000000000000000000000000000003600000000wicked2nm-1.2.1/tests/wireless_eap/wicked_xml/eap.xml<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-wlan_eap0">
  <name>wlan_eap0</name>
  <control>
    <mode>manual</mode>
  </control>
  <firewall/>
  <wireless>
    <ap-scan>1</ap-scan>
    <networks>
      <network>
        <essid>test</essid>
        <scan-ssid>true</scan-ssid>
        <mode>ap</mode>
        <access-point>12:34:56:78:9a:bc</access-point>
        <key-management>wpa-eap</key-management>
        <wpa-eap>
          <method>tls</method>
          <auth-proto>wpa,rsn</auth-proto>
          <pairwise-cipher>TKIP</pairwise-cipher>
          <group-cipher>TKIP,WEP40</group-cipher>
          <identity>test</identity>
          <tls>
            <ca-cert type="path">/etc/sysconfig/network/./ca_cert</ca-cert>
            <client-cert type="file">/etc/sysconfig/network/./client_cert</client-cert>
            <client-key type="path">/etc/sysconfig/network/./client_key</client-key>
            <client-key-passwd>testclientpw</client-key-passwd>
          </tls>
        </wpa-eap>
      </network>
    </networks>
  </wireless>
  <link/>
  <ipv4>
    <enabled>false</enabled>
  </ipv4>
  <ipv6>
    <enabled>false</enabled>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-wlan_eap1">
  <name>wlan_eap1</name>
  <control>
    <mode>manual</mode>
  </control>
  <firewall/>
  <wireless>
    <ap-scan>1</ap-scan>
    <networks>
      <network>
        <essid>example_ssid</essid>
        <scan-ssid>true</scan-ssid>
        <mode>infrastructure</mode>
        <key-management>wpa-eap</key-management>
        <wpa-eap>
          <method>md5</method>
          <pairwise-cipher>CCMP-256</pairwise-cipher>
          <pmf>disabled</pmf>
          <identity>alice</identity>
          <anonid>bob</anonid>
          <phase2>
            <method>mschapv2</method>
            <password>test_pw</password>
          </phase2>
        </wpa-eap>
      </network>
    </networks>
  </wireless>
  <link/>
  <ipv4>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv6>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
</interface>
<interface origin="compat:suse:/etc/sysconfig/network/ifcfg-wlan_eap2">
  <name>wlan_eap2</name>
  <control>
    <mode>manual</mode>
  </control>
  <firewall/>
  <wireless>
    <ap-scan>1</ap-scan>
    <networks>
      <network>
        <essid>example_ssid2</essid>
        <scan-ssid>true</scan-ssid>
        <mode>infrastructure</mode>
        <key-management>wpa-eap</key-management>
        <wpa-eap>
          <method>peap</method>
          <pairwise-cipher>CCMP,TKIP</pairwise-cipher>
          <pmf>required</pmf>
          <identity>bob</identity>
          <phase1>
            <peap-version>1</peap-version>
            <peap-label>true</peap-label>
          </phase1>
          <phase2>
            <method>chap</method>
            <password>test_pw</password>
          </phase2>
        </wpa-eap>
      </network>
    </networks>
  </wireless>
  <link/>
  <ipv4>
    <arp-verify>true</arp-verify>
  </ipv4>
  <ipv6>
    <privacy>prefer-public</privacy>
    <accept-redirects>false</accept-redirects>
  </ipv6>
</interface>
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!761 blocks
openSUSE Build Service is sponsored by