1use {
8 fidl_fuchsia_hardware_network as fhardware_network, fidl_fuchsia_net as fnet,
9 fidl_fuchsia_net_interfaces_admin as fnet_interfaces_admin, fidl_fuchsia_net_tun as fnet_tun,
10};
11
12use assert_matches::assert_matches;
13
14pub fn create_tun_device(
17) -> (fnet_tun::DeviceProxy, fidl::endpoints::ClientEnd<fhardware_network::DeviceMarker>) {
18 create_tun_device_with(fnet_tun::DeviceConfig::default())
19}
20
21pub fn create_tun_device_with(
23 device_config: fnet_tun::DeviceConfig,
24) -> (fnet_tun::DeviceProxy, fidl::endpoints::ClientEnd<fhardware_network::DeviceMarker>) {
25 let tun_ctl = fuchsia_component::client::connect_to_protocol::<fnet_tun::ControlMarker>()
26 .expect("connect to protocol");
27 let (tun_dev, tun_dev_server_end) = fidl::endpoints::create_proxy::<fnet_tun::DeviceMarker>();
28 tun_ctl.create_device(&device_config, tun_dev_server_end).expect("create tun device");
29 let (netdevice_client_end, netdevice_server_end) =
30 fidl::endpoints::create_endpoints::<fhardware_network::DeviceMarker>();
31 tun_dev.get_device(netdevice_server_end).expect("get device");
32 (tun_dev, netdevice_client_end)
33}
34
35pub fn install_device(
38 realm: &netemul::TestRealm<'_>,
39 device: fidl::endpoints::ClientEnd<fhardware_network::DeviceMarker>,
40) -> fnet_interfaces_admin::DeviceControlProxy {
41 let (admin_device_control, server_end) =
42 fidl::endpoints::create_proxy::<fnet_interfaces_admin::DeviceControlMarker>();
43 let installer = realm
44 .connect_to_protocol::<fnet_interfaces_admin::InstallerMarker>()
45 .expect("connect to protocol");
46 installer.install_device(device, server_end).expect("install device");
47 admin_device_control
48}
49
50pub async fn create_tun_port_with(
53 tun_device: &fnet_tun::DeviceProxy,
54 id: u8,
55 rx_frame_types: impl IntoIterator<Item = fhardware_network::FrameType>,
56 tx_frame_types: impl IntoIterator<Item = fhardware_network::FrameType>,
57 mac: Option<fnet::MacAddress>,
58) -> (fnet_tun::PortProxy, fhardware_network::PortProxy) {
59 let (port, server_end) = fidl::endpoints::create_proxy::<fnet_tun::PortMarker>();
60 let rx_types = rx_frame_types.into_iter().collect();
61 let tx_types = tx_frame_types
62 .into_iter()
63 .map(|frame_type| fhardware_network::FrameTypeSupport {
64 type_: frame_type,
65 features: fhardware_network::FRAME_FEATURES_RAW,
66 supported_flags: fhardware_network::TxFlags::empty(),
67 })
68 .collect();
69 tun_device
70 .add_port(
71 &fnet_tun::DevicePortConfig {
72 base: Some(fnet_tun::BasePortConfig {
73 id: Some(id),
74 rx_types: Some(rx_types),
75 tx_types: Some(tx_types),
76 mtu: Some(netemul::DEFAULT_MTU.into()),
77 ..Default::default()
78 }),
79 mac,
80 ..Default::default()
81 },
82 server_end,
83 )
84 .expect("add port");
85
86 let (network_port, server_end) =
87 fidl::endpoints::create_proxy::<fhardware_network::PortMarker>();
88 port.get_port(server_end).expect("get port");
89
90 (port, network_port)
91}
92
93pub async fn create_ip_tun_port(
96 tun_device: &fnet_tun::DeviceProxy,
97 id: u8,
98) -> (fnet_tun::PortProxy, fhardware_network::PortProxy) {
99 const IP_FRAME_TYPES: [fhardware_network::FrameType; 2] =
100 [fhardware_network::FrameType::Ipv4, fhardware_network::FrameType::Ipv6];
101 create_tun_port_with(tun_device, id, IP_FRAME_TYPES, IP_FRAME_TYPES, None).await
102}
103
104pub async fn add_pure_ip_interface(
107 network_port: &fhardware_network::PortProxy,
108 admin_device_control: &fnet_interfaces_admin::DeviceControlProxy,
109 interface_name: &str,
110) -> fnet_interfaces_admin::ControlProxy {
111 let fhardware_network::PortInfo { id, .. } = network_port.get_info().await.expect("get info");
112 let port_id = id.expect("port id");
113
114 let (admin_control, server_end) =
115 fidl::endpoints::create_proxy::<fnet_interfaces_admin::ControlMarker>();
116
117 let () = admin_device_control
118 .create_interface(
119 &port_id,
120 server_end,
121 &fnet_interfaces_admin::Options {
122 name: Some(interface_name.to_string()),
123 ..Default::default()
124 },
125 )
126 .expect("create interface");
127 admin_control
128}
129
130pub async fn create_eth_tun_port(
133 tun_device: &fnet_tun::DeviceProxy,
134 id: u8,
135 mac: fnet::MacAddress,
136) -> (fnet_tun::PortProxy, fhardware_network::PortProxy) {
137 const ETH_FRAME_TYPES: [fhardware_network::FrameType; 1] =
138 [fhardware_network::FrameType::Ethernet];
139 create_tun_port_with(tun_device, id, ETH_FRAME_TYPES, ETH_FRAME_TYPES, Some(mac)).await
140}
141
142pub const TUN_DEFAULT_PORT_ID: u8 = 0;
144
145pub async fn create_eth_tun_pair(
147) -> (fnet_tun::DevicePairProxy, fhardware_network::PortProxy, fhardware_network::PortProxy) {
148 create_tun_pair_with(
149 fnet_tun::DevicePairConfig::default(),
150 fnet_tun::DevicePairPortConfig {
151 base: Some(fnet_tun::BasePortConfig {
152 id: Some(TUN_DEFAULT_PORT_ID),
153 mtu: Some(netemul::DEFAULT_MTU.into()),
154 rx_types: Some(vec![fhardware_network::FrameType::Ethernet]),
155 tx_types: Some(vec![fhardware_network::FrameTypeSupport {
156 type_: fhardware_network::FrameType::Ethernet,
157 features: 0,
158 supported_flags: fhardware_network::TxFlags::empty(),
159 }]),
160 ..Default::default()
161 }),
162 mac_left: Some(fnet::MacAddress { octets: crate::constants::eth::MAC_ADDR.bytes() }),
163 mac_right: Some(fnet::MacAddress { octets: crate::constants::eth::MAC_ADDR2.bytes() }),
164 ..Default::default()
165 },
166 )
167 .await
168}
169
170pub async fn create_tun_pair_with(
174 dev_pair_config: fnet_tun::DevicePairConfig,
175 dev_pair_port_config: fnet_tun::DevicePairPortConfig,
176) -> (fnet_tun::DevicePairProxy, fhardware_network::PortProxy, fhardware_network::PortProxy) {
177 let tun_ctl = fuchsia_component::client::connect_to_protocol::<fnet_tun::ControlMarker>()
178 .expect("connect to protocol");
179 let (tun_dev_pair, tun_dev_pair_server_end) =
180 fidl::endpoints::create_proxy::<fnet_tun::DevicePairMarker>();
181 tun_ctl.create_pair(&dev_pair_config, tun_dev_pair_server_end).expect("create tun device pair");
182
183 let port_id = assert_matches!(dev_pair_port_config, fnet_tun::DevicePairPortConfig {
184 base: Some(fnet_tun::BasePortConfig {
185 id: Some(id),
186 ..
187 }),
188 ..
189 } => id);
190 tun_dev_pair
191 .add_port(&dev_pair_port_config)
192 .await
193 .expect("add port FIDL call")
194 .map_err(zx::Status::from_raw)
195 .expect("add port");
196
197 let (left_port, left_port_server_end) =
198 fidl::endpoints::create_proxy::<fhardware_network::PortMarker>();
199 let (right_port, right_port_server_end) =
200 fidl::endpoints::create_proxy::<fhardware_network::PortMarker>();
201 tun_dev_pair.get_left_port(port_id, left_port_server_end).expect("get left port");
202 tun_dev_pair.get_right_port(port_id, right_port_server_end).expect("get right port");
203
204 (tun_dev_pair, left_port, right_port)
205}