Skip to content

Commit 26b59e5

Browse files
fliqqsrwestphal
authored andcommitted
igmp: import initial IGMPv2 implementation
This is a work-in-progress implementation of the IGMPv2 protocol. Signed-off-by: fliqqs <[email protected]>
1 parent 5065366 commit 26b59e5

31 files changed

+4014
-11
lines changed

Cargo.lock

Lines changed: 18 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

holo-daemon/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ yang3.workspace = true
3333
holo-interface = { path = "../holo-interface", optional = true }
3434
holo-bfd = { path = "../holo-bfd", optional = true }
3535
holo-bgp = { path = "../holo-bgp", optional = true }
36+
holo-igmp = { path = "../holo-igmp", optional = true }
3637
holo-isis = { path = "../holo-isis", optional = true }
3738
holo-keychain = { path = "../holo-keychain", optional = true }
3839
holo-ldp = { path = "../holo-ldp", optional = true }
@@ -71,6 +72,7 @@ base = [
7172
protocols = [
7273
"bfd",
7374
"bgp",
75+
"igmp",
7476
"isis",
7577
"ldp",
7678
"ospf",
@@ -88,6 +90,7 @@ system = ["dep:holo-system"]
8890
# Protocols
8991
bfd = ["dep:holo-bfd", "holo-routing/bfd"]
9092
bgp = ["dep:holo-bgp", "holo-routing/bgp"]
93+
igmp = ["dep:holo-igmp", "holo-routing/igmp"]
9194
isis = ["dep:holo-isis", "holo-routing/isis"]
9295
ldp = ["dep:holo-ldp", "holo-routing/ldp"]
9396
ospf = ["dep:holo-ospf", "holo-routing/ospf"]

holo-igmp/Cargo.toml

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,43 @@ license.workspace = true
66
edition.workspace = true
77

88
[dependencies]
9-
internet-checksum.workspace = true
10-
holo-utils = { path = "../holo-utils" }
11-
holo-protocol = { path = "../holo-protocol" }
12-
serde.workspace = true
13-
serde_json.workspace = true
9+
async-trait.workspace = true
10+
bitflags.workspace = true
1411
bytes.workspace = true
12+
chrono.workspace = true
13+
derive-new.workspace = true
14+
enum-as-inner.workspace = true
15+
generational-arena.workspace = true
16+
internet-checksum.workspace = true
17+
ipnetwork.workspace = true
18+
itertools.workspace = true
19+
libc.workspace = true
1520
num-derive.workspace = true
1621
num-traits.workspace = true
22+
rand.workspace = true
23+
serde.workspace = true
24+
serde_json.workspace = true
25+
serde_with.workspace = true
26+
tokio.workspace = true
27+
tracing.workspace = true
28+
yang3.workspace = true
29+
30+
holo-northbound = { path = "../holo-northbound" }
31+
holo-protocol = { path = "../holo-protocol" }
32+
holo-utils = { path = "../holo-utils" }
33+
holo-yang = { path = "../holo-yang" }
1734

1835
[dev-dependencies]
1936
const-addrs.workspace = true
20-
criterion.workspace = true
21-
maplit.workspace = true
2237
yang3 = { workspace = true, features = ["bundled"] }
2338

39+
holo-igmp = { path = ".", features = ["testing"] }
2440
holo-protocol = { path = "../holo-protocol", features = ["testing"] }
25-
holo-utils = { path = "../holo-utils", features = ["testing"] }
41+
holo-utils = { path = "../holo-utils", features = ["testing"] }
42+
43+
[lints]
44+
workspace = true
45+
46+
[features]
47+
default = []
48+
testing = []

holo-igmp/LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2023 The Holo Core Contributors
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

holo-igmp/src/debug.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// Copyright (c) The Holo Core Contributors
3+
//
4+
// SPDX-License-Identifier: MIT
5+
//
6+
7+
use holo_utils::ibus::IbusMsg;
8+
use tracing::{debug, debug_span};
9+
10+
// IGMP debug messages.
11+
#[derive(Debug)]
12+
pub enum Debug<'a> {
13+
IbusRx(&'a IbusMsg),
14+
}
15+
16+
// ===== impl Debug =====
17+
18+
impl Debug<'_> {
19+
// Log debug message using the tracing API.
20+
pub(crate) fn log(&self) {
21+
match self {
22+
Debug::IbusRx(msg) => {
23+
// Parent span(s): igmp-instance
24+
debug_span!("internal-bus").in_scope(|| {
25+
debug_span!("input").in_scope(|| {
26+
let data = serde_json::to_string(&msg).unwrap();
27+
debug!(%data, "{}", self);
28+
})
29+
})
30+
}
31+
}
32+
}
33+
}
34+
35+
impl std::fmt::Display for Debug<'_> {
36+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37+
match self {
38+
Debug::IbusRx(..) => {
39+
write!(f, "message")
40+
}
41+
}
42+
}
43+
}

holo-igmp/src/error.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//
2+
// Copyright (c) The Holo Core Contributors
3+
//
4+
// SPDX-License-Identifier: MIT
5+
//
6+
7+
use tracing::warn;
8+
9+
// IGMP errors.
10+
#[derive(Debug)]
11+
pub enum Error {
12+
// I/O errors
13+
IoError(IoError),
14+
}
15+
16+
// IGMP I/O errors.
17+
#[derive(Debug)]
18+
pub enum IoError {
19+
SocketError(std::io::Error),
20+
RecvError(std::io::Error),
21+
SendError(std::io::Error),
22+
}
23+
24+
// ===== impl Error =====
25+
26+
impl Error {
27+
pub(crate) fn log(&self) {
28+
match self {
29+
Error::IoError(error) => {
30+
error.log();
31+
}
32+
}
33+
}
34+
}
35+
36+
impl std::fmt::Display for Error {
37+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38+
match self {
39+
Error::IoError(error) => error.fmt(f),
40+
}
41+
}
42+
}
43+
44+
impl std::error::Error for Error {
45+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
46+
match self {
47+
Error::IoError(error) => Some(error),
48+
//_ => None,
49+
}
50+
}
51+
}
52+
53+
impl From<IoError> for Error {
54+
fn from(error: IoError) -> Error {
55+
Error::IoError(error)
56+
}
57+
}
58+
59+
// ===== impl IoError =====
60+
61+
impl IoError {
62+
pub(crate) fn log(&self) {
63+
match self {
64+
IoError::SocketError(error) => {
65+
warn!(error = %with_source(error), "{}", self);
66+
}
67+
IoError::RecvError(error) | IoError::SendError(error) => {
68+
warn!(error = %with_source(error), "{}", self);
69+
}
70+
}
71+
}
72+
}
73+
74+
impl std::fmt::Display for IoError {
75+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76+
match self {
77+
IoError::SocketError(..) => {
78+
write!(f, "failed to create raw IP socket")
79+
}
80+
IoError::RecvError(..) => {
81+
write!(f, "failed to receive IP packet")
82+
}
83+
IoError::SendError(..) => {
84+
write!(f, "failed to send IP packet")
85+
}
86+
}
87+
}
88+
}
89+
90+
impl std::error::Error for IoError {}
91+
92+
// ===== global functions =====
93+
94+
fn with_source<E: std::error::Error>(error: E) -> String {
95+
if let Some(source) = error.source() {
96+
format!("{} ({})", error, with_source(source))
97+
} else {
98+
error.to_string()
99+
}
100+
}

holo-igmp/src/events.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// Copyright (c) The Holo Core Contributors
3+
//
4+
// SPDX-License-Identifier: MIT
5+
//
6+
7+
use crate::error::Error;
8+
use crate::instance::Instance;
9+
use crate::packet::{DecodeResult, Packet};
10+
11+
// ===== TCP connection request =====
12+
13+
pub(crate) fn process_packet(
14+
_instance: &mut Instance,
15+
_packet: DecodeResult<Packet>,
16+
) -> Result<(), Error> {
17+
// TODO
18+
19+
Ok(())
20+
}

holo-igmp/src/ibus/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//
2+
// Copyright (c) The Holo Core Contributors
3+
//
4+
// SPDX-License-Identifier: MIT
5+
//
6+
7+
pub mod rx;
8+
pub mod tx;

holo-igmp/src/ibus/rx.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//
2+
// Copyright (c) The Holo Core Contributors
3+
//
4+
// SPDX-License-Identifier: MIT
5+
//

holo-igmp/src/ibus/tx.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//
2+
// Copyright (c) The Holo Core Contributors
3+
//
4+
// SPDX-License-Identifier: MIT
5+
//

0 commit comments

Comments
 (0)