-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: sylvain-pierrot <sylvain.pierrot@etu.umontpellier.fr>
- Loading branch information
1 parent
c0528ed
commit 8629b22
Showing
10 changed files
with
187 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,137 @@ | ||
use std::net::{IpAddr, Ipv4Addr}; | ||
|
||
use futures::stream::TryStreamExt; | ||
use rtnetlink::{new_connection, Error, Handle}; | ||
|
||
pub fn host_bridge(tap_name: String, bridge_name: String) { | ||
let (connection, handle, _) = new_connection().unwrap(); | ||
tokio::spawn(connection); | ||
use super::xx_netmask_width; | ||
|
||
futures::executor::block_on(async { | ||
let _ = create_bridge_if_not_exist(handle.clone(), bridge_name.clone()).await; | ||
let _ = attach_link_to_bridge(handle, tap_name, bridge_name).await; | ||
}) | ||
#[derive(Clone)] | ||
pub struct Bridge { | ||
name: String, | ||
handle: Handle, | ||
} | ||
|
||
async fn create_bridge_if_not_exist(handle: Handle, name: String) -> Result<(), Error> { | ||
let mut bridge_names = handle.link().get().match_name(name.clone()).execute(); | ||
|
||
match bridge_names.try_next().await? { | ||
Some(_) => Ok(()), | ||
None => handle | ||
.link() | ||
.add() | ||
.bridge(name) | ||
.execute() | ||
.await | ||
.map_err(|_| Error::RequestFailed), | ||
impl Bridge { | ||
pub fn new(name: String) -> Self { | ||
let (connection, handle, _) = new_connection().unwrap(); | ||
tokio::spawn(connection); | ||
|
||
let br = Self { name, handle }; | ||
let _ = br.create_bridge_if_not_exist(); | ||
|
||
br | ||
} | ||
} | ||
|
||
async fn attach_link_to_bridge( | ||
handle: Handle, | ||
link_name: String, | ||
master_name: String, | ||
) -> Result<(), Error> { | ||
let mut link_names = handle.link().get().match_name(link_name.clone()).execute(); | ||
let mut master_names = handle | ||
.link() | ||
.get() | ||
.match_name(master_name.clone()) | ||
.execute(); | ||
|
||
let link_index = match link_names.try_next().await? { | ||
Some(link) => link.header.index, | ||
None => panic!(), | ||
}; | ||
let master_index = match master_names.try_next().await? { | ||
Some(link) => link.header.index, | ||
None => panic!(), | ||
}; | ||
|
||
let _ = handle | ||
.link() | ||
.set(link_index) | ||
.controller(master_index) | ||
.execute() | ||
.await | ||
.map_err(|_| Error::RequestFailed); | ||
|
||
Ok(()) | ||
fn create_bridge_if_not_exist(&self) { | ||
futures::executor::block_on(async { | ||
let mut bridge_names = self | ||
.handle | ||
.link() | ||
.get() | ||
.match_name(self.name.clone()) | ||
.execute(); | ||
|
||
let _ = match bridge_names.try_next().await { | ||
Ok(_) => Ok(()), | ||
Err(_) => self | ||
.handle | ||
.link() | ||
.add() | ||
.bridge(self.name.clone()) | ||
.execute() | ||
.await | ||
.map_err(|_| Error::RequestFailed), | ||
}; | ||
}); | ||
} | ||
|
||
pub fn set_addr(&self, addr: Ipv4Addr, netmask: Ipv4Addr) { | ||
futures::executor::block_on(async { | ||
let mut bridge_names = self | ||
.handle | ||
.link() | ||
.get() | ||
.match_name(self.name.clone()) | ||
.execute(); | ||
|
||
let bridge_index = match bridge_names.try_next().await { | ||
Ok(Some(link)) => link.header.index, | ||
Ok(None) => panic!(), | ||
Err(_) => panic!(), | ||
}; | ||
|
||
let prefix_len = xx_netmask_width(netmask.octets()); | ||
|
||
let _ = self | ||
.handle | ||
.address() | ||
.add(bridge_index, IpAddr::V4(addr), prefix_len) | ||
.execute() | ||
.await | ||
.map_err(|_| Error::RequestFailed); | ||
}); | ||
} | ||
|
||
pub fn set_up(&self) { | ||
futures::executor::block_on(async { | ||
let mut bridge_names = self | ||
.handle | ||
.link() | ||
.get() | ||
.match_name(self.name.clone()) | ||
.execute(); | ||
|
||
let bridge_index = match bridge_names.try_next().await { | ||
Ok(Some(link)) => link.header.index, | ||
Ok(None) => panic!(), | ||
Err(_) => panic!(), | ||
}; | ||
|
||
let _ = self | ||
.handle | ||
.link() | ||
.set(bridge_index) | ||
.up() | ||
.execute() | ||
.await | ||
.map_err(|_| Error::RequestFailed); | ||
}); | ||
} | ||
|
||
pub fn attach_link(&self, link_name: String) { | ||
futures::executor::block_on(async { | ||
let mut link_names = self | ||
.handle | ||
.link() | ||
.get() | ||
.match_name(link_name.clone()) | ||
.execute(); | ||
let mut master_names = self | ||
.handle | ||
.link() | ||
.get() | ||
.match_name(self.name.clone()) | ||
.execute(); | ||
|
||
let link_index = match link_names.try_next().await { | ||
Ok(Some(link)) => link.header.index, | ||
Ok(None) => panic!(), | ||
Err(_) => panic!(), | ||
}; | ||
let master_index = match master_names.try_next().await { | ||
Ok(Some(link)) => link.header.index, | ||
Ok(None) => panic!(), | ||
Err(_) => panic!(), | ||
}; | ||
|
||
let _ = self | ||
.handle | ||
.link() | ||
.set(link_index) | ||
.controller(master_index) | ||
.execute() | ||
.await | ||
.map_err(|_| Error::RequestFailed); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use std::net::Ipv4Addr; | ||
|
||
use super::xx_netmask_width; | ||
|
||
pub fn iptables_ip_masq(network: Ipv4Addr, netmask: Ipv4Addr) { | ||
let prefix_len = xx_netmask_width(netmask.octets()); | ||
let source = format!("{}/{}", network.to_string(), prefix_len); | ||
|
||
let ipt = iptables::new(false).unwrap(); | ||
let rule = format!("-s {} ! -o br0 -j MASQUERADE", source); | ||
|
||
let exists = ipt.exists("nat", "POSTROUTING", rule.as_str()).unwrap(); | ||
if !exists { | ||
let _ = ipt.insert_unique("nat", "POSTROUTING", rule.as_str(), 1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters