Skip to main content

fidl_fuchsia_net_routes_ext_fdomain/
admin.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Extensions for fuchsia.net.routes.admin.
6
7use std::fmt::Debug;
8
9use flex_client::ProxyHasDomain as _;
10use flex_client::fidl::{DiscoverableProtocolMarker, ProtocolMarker};
11use flex_fuchsia_net_resources as fnet_resources;
12use flex_fuchsia_net_root as fnet_root;
13use flex_fuchsia_net_routes_admin as fnet_routes_admin;
14use futures::future::Either;
15use net_types::ip::{GenericOverIp, Ip, IpInvariant, Ipv4, Ipv6};
16use thiserror::Error;
17
18use crate::{FidlRouteIpExt, Responder, TableId, impl_responder};
19
20/// Route set creation errors.
21#[derive(Clone, Debug, Error)]
22pub enum RouteSetCreationError {
23    /// Proxy creation failed.
24    #[error("failed to create proxy: {0}")]
25    CreateProxy(fidl::Error),
26    /// Route set creation failed.
27    #[error("failed to create route set: {0}")]
28    RouteSet(fidl::Error),
29}
30
31/// Route table creation errors.
32#[derive(Clone, Debug, Error)]
33pub enum RouteTableCreationError {
34    /// Proxy creation failed.
35    #[error("failed to create proxy: {0}")]
36    CreateProxy(fidl::Error),
37    /// Route table creation failed.
38    #[error("failed to create route set: {0}")]
39    RouteTable(fidl::Error),
40}
41
42/// Admin extension for the `fuchsia.net.routes.admin` FIDL API.
43pub trait FidlRouteAdminIpExt: Ip {
44    /// The "route table" protocol to use for this IP version.
45    type RouteTableMarker: DiscoverableProtocolMarker<
46            RequestStream = Self::RouteTableRequestStream,
47            Proxy: Clone + Debug,
48        > + Unpin
49        + std::fmt::Debug;
50    /// The "root set" protocol to use for this IP version.
51    type GlobalRouteTableMarker: DiscoverableProtocolMarker;
52    /// The "route set" protocol to use for this IP version.
53    type RouteSetMarker: ProtocolMarker<RequestStream = Self::RouteSetRequestStream>
54        + std::fmt::Debug;
55    /// The "route table provider" protocol to use for this IP version.
56    type RouteTableProviderMarker: DiscoverableProtocolMarker<Proxy: Clone>;
57    /// The request stream for the route set protocol.
58    type RouteSetRequestStream: flex_client::fidl::RequestStream<Ok: Send, ControlHandle: Send>;
59    /// The request stream for the route table protocol.
60    type RouteTableRequestStream: flex_client::fidl::RequestStream<Ok: Send, ControlHandle: Send>;
61    /// The responder for AddRoute requests.
62    type AddRouteResponder: Responder<Payload = Result<bool, fnet_routes_admin::RouteSetError>>;
63    /// The responder for RemoveRoute requests.
64    type RemoveRouteResponder: Responder<Payload = Result<bool, fnet_routes_admin::RouteSetError>>;
65    /// The responder for AuthenticateForInterface requests.
66    type RouteSetAuthenticateForInterfaceResponder: Responder<
67        Payload = Result<(), fnet_routes_admin::AuthenticateForInterfaceError>,
68    >;
69    /// The responder for GetTableId requests.
70    type RouteTableGetTableIdResponder: Responder<Payload = u32>;
71    /// The responder for RemoveRequests.
72    type RouteTableRemoveResponder: Responder<
73        Payload = Result<(), fnet_routes_admin::BaseRouteTableRemoveError>,
74    >;
75    /// The responder for GetAuthorizationForRouteTable requests.
76    type RouteTableGetAuthorizationResponder: Responder<
77        Payload = fnet_routes_admin::GrantForRouteTableAuthorization,
78    >;
79    /// The control handle for RouteTable protocols.
80    type RouteTableControlHandle: flex_client::fidl::ControlHandle + Debug;
81
82    /// The control handle for RouteTableProvider protocols.
83    type RouteTableProviderControlHandle: flex_client::fidl::ControlHandle + Debug;
84
85    /// The responder for the GetInterfaceLocalTable method.
86    type GetInterfaceLocalTableResponder: Responder<
87        Payload = Result<
88            flex_client::fidl::ClientEnd<Self::RouteTableMarker>,
89            fnet_routes_admin::GetInterfaceLocalTableError,
90        >,
91    >;
92
93    /// Turns a FIDL route table provider request into the extension type.
94    fn into_route_table_provider_request(
95        request: flex_client::fidl::Request<Self::RouteTableProviderMarker>,
96    ) -> RouteTableProviderRequest<Self>;
97
98    /// Turns a FIDL route set request into the extension type.
99    fn into_route_set_request(
100        request: flex_client::fidl::Request<Self::RouteSetMarker>,
101    ) -> RouteSetRequest<Self>;
102
103    /// Turns a FIDL route table request into the extension type.
104    fn into_route_table_request(
105        request: flex_client::fidl::Request<Self::RouteTableMarker>,
106    ) -> RouteTableRequest<Self>;
107
108    /// Turns a FIDL route set request stream item into a Result of the extension type.
109    fn into_route_set_request_result(
110        request: <Self::RouteSetRequestStream as futures::Stream>::Item,
111    ) -> Result<RouteSetRequest<Self>, fidl::Error>;
112
113    /// Turns a FIDL route table request stream item into a Result of the extension type.
114    fn into_route_table_request_result(
115        request: <Self::RouteTableRequestStream as futures::Stream>::Item,
116    ) -> Result<RouteTableRequest<Self>, fidl::Error>;
117}
118
119impl FidlRouteAdminIpExt for Ipv4 {
120    type RouteTableMarker = fnet_routes_admin::RouteTableV4Marker;
121    type GlobalRouteTableMarker = fnet_root::RoutesV4Marker;
122    type RouteSetMarker = fnet_routes_admin::RouteSetV4Marker;
123    type RouteTableProviderMarker = fnet_routes_admin::RouteTableProviderV4Marker;
124    type RouteSetRequestStream = fnet_routes_admin::RouteSetV4RequestStream;
125    type RouteTableRequestStream = fnet_routes_admin::RouteTableV4RequestStream;
126    type AddRouteResponder = fnet_routes_admin::RouteSetV4AddRouteResponder;
127    type RemoveRouteResponder = fnet_routes_admin::RouteSetV4RemoveRouteResponder;
128    type RouteSetAuthenticateForInterfaceResponder =
129        fnet_routes_admin::RouteSetV4AuthenticateForInterfaceResponder;
130    type RouteTableGetTableIdResponder = fnet_routes_admin::RouteTableV4GetTableIdResponder;
131    type RouteTableRemoveResponder = fnet_routes_admin::RouteTableV4RemoveResponder;
132    type RouteTableGetAuthorizationResponder =
133        fnet_routes_admin::RouteTableV4GetAuthorizationForRouteTableResponder;
134    type RouteTableControlHandle = fnet_routes_admin::RouteTableV4ControlHandle;
135    type RouteTableProviderControlHandle = fnet_routes_admin::RouteTableProviderV4ControlHandle;
136    type GetInterfaceLocalTableResponder =
137        fnet_routes_admin::RouteTableProviderV4GetInterfaceLocalTableResponder;
138
139    fn into_route_table_provider_request(
140        request: flex_client::fidl::Request<Self::RouteTableProviderMarker>,
141    ) -> RouteTableProviderRequest<Ipv4> {
142        RouteTableProviderRequest::from(request)
143    }
144
145    fn into_route_set_request(
146        request: flex_client::fidl::Request<Self::RouteSetMarker>,
147    ) -> RouteSetRequest<Self> {
148        RouteSetRequest::from(request)
149    }
150
151    fn into_route_table_request(
152        request: flex_client::fidl::Request<Self::RouteTableMarker>,
153    ) -> RouteTableRequest<Self> {
154        RouteTableRequest::from(request)
155    }
156
157    fn into_route_set_request_result(
158        request: <Self::RouteSetRequestStream as futures::Stream>::Item,
159    ) -> Result<RouteSetRequest<Self>, fidl::Error> {
160        request.map(RouteSetRequest::from)
161    }
162
163    fn into_route_table_request_result(
164        request: <Self::RouteTableRequestStream as futures::Stream>::Item,
165    ) -> Result<RouteTableRequest<Self>, fidl::Error> {
166        request.map(RouteTableRequest::from)
167    }
168}
169
170impl FidlRouteAdminIpExt for Ipv6 {
171    type RouteTableMarker = fnet_routes_admin::RouteTableV6Marker;
172    type GlobalRouteTableMarker = fnet_root::RoutesV6Marker;
173    type RouteSetMarker = fnet_routes_admin::RouteSetV6Marker;
174    type RouteTableProviderMarker = fnet_routes_admin::RouteTableProviderV6Marker;
175    type RouteSetRequestStream = fnet_routes_admin::RouteSetV6RequestStream;
176    type RouteTableRequestStream = fnet_routes_admin::RouteTableV6RequestStream;
177    type AddRouteResponder = fnet_routes_admin::RouteSetV6AddRouteResponder;
178    type RemoveRouteResponder = fnet_routes_admin::RouteSetV6RemoveRouteResponder;
179    type RouteSetAuthenticateForInterfaceResponder =
180        fnet_routes_admin::RouteSetV6AuthenticateForInterfaceResponder;
181    type RouteTableGetTableIdResponder = fnet_routes_admin::RouteTableV6GetTableIdResponder;
182    type RouteTableRemoveResponder = fnet_routes_admin::RouteTableV6RemoveResponder;
183    type RouteTableGetAuthorizationResponder =
184        fnet_routes_admin::RouteTableV6GetAuthorizationForRouteTableResponder;
185    type RouteTableControlHandle = fnet_routes_admin::RouteTableV6ControlHandle;
186    type RouteTableProviderControlHandle = fnet_routes_admin::RouteTableProviderV6ControlHandle;
187    type GetInterfaceLocalTableResponder =
188        fnet_routes_admin::RouteTableProviderV6GetInterfaceLocalTableResponder;
189
190    fn into_route_table_provider_request(
191        request: flex_client::fidl::Request<Self::RouteTableProviderMarker>,
192    ) -> RouteTableProviderRequest<Ipv6> {
193        RouteTableProviderRequest::from(request)
194    }
195
196    fn into_route_set_request(
197        request: flex_client::fidl::Request<Self::RouteSetMarker>,
198    ) -> RouteSetRequest<Self> {
199        RouteSetRequest::from(request)
200    }
201
202    fn into_route_table_request(
203        request: flex_client::fidl::Request<Self::RouteTableMarker>,
204    ) -> RouteTableRequest<Self> {
205        RouteTableRequest::from(request)
206    }
207
208    fn into_route_set_request_result(
209        request: <Self::RouteSetRequestStream as futures::Stream>::Item,
210    ) -> Result<RouteSetRequest<Self>, fidl::Error> {
211        request.map(RouteSetRequest::from)
212    }
213
214    fn into_route_table_request_result(
215        request: <Self::RouteTableRequestStream as futures::Stream>::Item,
216    ) -> Result<RouteTableRequest<Self>, fidl::Error> {
217        request.map(RouteTableRequest::from)
218    }
219}
220
221impl_responder!(
222    fnet_routes_admin::RouteSetV4AddRouteResponder,
223    Result<bool, fnet_routes_admin::RouteSetError>,
224);
225impl_responder!(
226    fnet_routes_admin::RouteSetV4RemoveRouteResponder,
227    Result<bool, fnet_routes_admin::RouteSetError>,
228);
229impl_responder!(
230    fnet_routes_admin::RouteSetV6AddRouteResponder,
231    Result<bool, fnet_routes_admin::RouteSetError>,
232);
233impl_responder!(
234    fnet_routes_admin::RouteSetV6RemoveRouteResponder,
235    Result<bool, fnet_routes_admin::RouteSetError>,
236);
237impl_responder!(
238    fnet_routes_admin::RouteSetV4AuthenticateForInterfaceResponder,
239    Result<(), fnet_routes_admin::AuthenticateForInterfaceError>,
240);
241impl_responder!(
242    fnet_routes_admin::RouteSetV6AuthenticateForInterfaceResponder,
243    Result<(), fnet_routes_admin::AuthenticateForInterfaceError>,
244);
245impl_responder!(fnet_routes_admin::RouteTableV4GetTableIdResponder, u32,);
246impl_responder!(fnet_routes_admin::RouteTableV6GetTableIdResponder, u32,);
247impl_responder!(
248    fnet_routes_admin::RouteTableV4RemoveResponder,
249    Result<(), fnet_routes_admin::BaseRouteTableRemoveError>,
250);
251impl_responder!(
252    fnet_routes_admin::RouteTableV6RemoveResponder,
253    Result<(), fnet_routes_admin::BaseRouteTableRemoveError>,
254);
255impl_responder!(
256    fnet_routes_admin::RouteTableV4GetAuthorizationForRouteTableResponder,
257    fnet_routes_admin::GrantForRouteTableAuthorization,
258);
259impl_responder!(
260    fnet_routes_admin::RouteTableV6GetAuthorizationForRouteTableResponder,
261    fnet_routes_admin::GrantForRouteTableAuthorization,
262);
263impl_responder!(
264    fnet_routes_admin::RouteTableProviderV4GetInterfaceLocalTableResponder,
265    Result<
266        flex_client::fidl::ClientEnd<fnet_routes_admin::RouteTableV4Marker>,
267        fnet_routes_admin::GetInterfaceLocalTableError,
268    >,
269);
270impl_responder!(
271    fnet_routes_admin::RouteTableProviderV6GetInterfaceLocalTableResponder,
272    Result<
273        flex_client::fidl::ClientEnd<fnet_routes_admin::RouteTableV6Marker>,
274        fnet_routes_admin::GetInterfaceLocalTableError,
275    >,
276);
277
278/// Options for creating route tables.
279#[derive(Clone, Debug, GenericOverIp)]
280#[generic_over_ip(I, Ip)]
281pub struct RouteTableOptions<I: Ip> {
282    /// Optional name for the table.
283    pub name: Option<String>,
284    /// Marker for the IP version.
285    pub _marker: std::marker::PhantomData<I>,
286}
287
288impl From<RouteTableOptions<Ipv4>> for fnet_routes_admin::RouteTableOptionsV4 {
289    fn from(val: RouteTableOptions<Ipv4>) -> Self {
290        let RouteTableOptions { name, _marker } = val;
291        Self { name, __source_breaking: fidl::marker::SourceBreaking }
292    }
293}
294
295impl From<RouteTableOptions<Ipv6>> for fnet_routes_admin::RouteTableOptionsV6 {
296    fn from(val: RouteTableOptions<Ipv6>) -> Self {
297        let RouteTableOptions { name, _marker } = val;
298        Self { name, __source_breaking: fidl::marker::SourceBreaking }
299    }
300}
301
302impl From<fnet_routes_admin::RouteTableOptionsV4> for RouteTableOptions<Ipv4> {
303    fn from(val: fnet_routes_admin::RouteTableOptionsV4) -> Self {
304        let fnet_routes_admin::RouteTableOptionsV4 { name, __source_breaking: _ } = val;
305        Self { name, _marker: std::marker::PhantomData }
306    }
307}
308
309impl From<fnet_routes_admin::RouteTableOptionsV6> for RouteTableOptions<Ipv6> {
310    fn from(val: fnet_routes_admin::RouteTableOptionsV6) -> Self {
311        let fnet_routes_admin::RouteTableOptionsV6 { name, __source_breaking: _ } = val;
312        Self { name, _marker: std::marker::PhantomData }
313    }
314}
315
316/// GenericOverIp version of RouteTableProviderV{4, 6}Request.
317#[derive(derivative::Derivative, GenericOverIp)]
318#[derivative(Debug(bound = ""))]
319#[generic_over_ip(I, Ip)]
320pub enum RouteTableProviderRequest<I: Ip + FidlRouteAdminIpExt> {
321    /// Request to create a new route table.
322    NewRouteTable {
323        /// The server end of the RouteTable request
324        provider: flex_client::fidl::ServerEnd<I::RouteTableMarker>,
325        /// The creation options.
326        options: RouteTableOptions<I>,
327        /// The control handle for the protocol.
328        control_handle: I::RouteTableProviderControlHandle,
329    },
330    /// Request to get the interface-local route table.
331    GetInterfaceLocalTable {
332        /// The credentials for the interface.
333        credential: fnet_resources::ProofOfInterfaceAuthorization,
334        /// Responder to return the local table.
335        responder: I::GetInterfaceLocalTableResponder,
336    },
337}
338
339impl From<fnet_routes_admin::RouteTableProviderV4Request> for RouteTableProviderRequest<Ipv4> {
340    fn from(val: fnet_routes_admin::RouteTableProviderV4Request) -> Self {
341        match val {
342            fnet_routes_admin::RouteTableProviderV4Request::NewRouteTable {
343                provider,
344                options,
345                control_handle,
346            } => Self::NewRouteTable { provider, options: options.into(), control_handle },
347            fnet_routes_admin::RouteTableProviderV4Request::GetInterfaceLocalTable {
348                credential,
349                responder,
350            } => Self::GetInterfaceLocalTable { credential, responder },
351        }
352    }
353}
354
355impl From<fnet_routes_admin::RouteTableProviderV6Request> for RouteTableProviderRequest<Ipv6> {
356    fn from(val: fnet_routes_admin::RouteTableProviderV6Request) -> Self {
357        match val {
358            fnet_routes_admin::RouteTableProviderV6Request::NewRouteTable {
359                provider,
360                options,
361                control_handle,
362            } => Self::NewRouteTable { provider, options: options.into(), control_handle },
363            fnet_routes_admin::RouteTableProviderV6Request::GetInterfaceLocalTable {
364                credential,
365                responder,
366            } => Self::GetInterfaceLocalTable { credential, responder },
367        }
368    }
369}
370
371/// Dispatches `new_route_table` on either the `RouteTableProviderV4`
372/// or `RouteTableProviderV6` proxy.
373pub fn new_route_table<I: Ip + FidlRouteAdminIpExt>(
374    route_table_provider_proxy: &<I::RouteTableProviderMarker as ProtocolMarker>::Proxy,
375    name: Option<String>,
376) -> Result<<I::RouteTableMarker as ProtocolMarker>::Proxy, RouteTableCreationError> {
377    let (route_table_proxy, route_table_server_end) =
378        route_table_provider_proxy.domain().create_proxy::<I::RouteTableMarker>();
379
380    #[derive(GenericOverIp)]
381    #[generic_over_ip(I, Ip)]
382    struct NewRouteTableInput<'a, I: FidlRouteAdminIpExt> {
383        route_table_server_end: flex_client::fidl::ServerEnd<I::RouteTableMarker>,
384        route_table_provider_proxy: &'a <I::RouteTableProviderMarker as ProtocolMarker>::Proxy,
385        name: Option<String>,
386    }
387
388    let result = I::map_ip_in(
389        NewRouteTableInput::<'_, I> { route_table_server_end, route_table_provider_proxy, name },
390        |NewRouteTableInput { route_table_server_end, route_table_provider_proxy, name }| {
391            route_table_provider_proxy.new_route_table(
392                route_table_server_end,
393                &fnet_routes_admin::RouteTableOptionsV4 {
394                    name,
395                    ..fnet_routes_admin::RouteTableOptionsV4::default()
396                },
397            )
398        },
399        |NewRouteTableInput { route_table_server_end, route_table_provider_proxy, name }| {
400            route_table_provider_proxy.new_route_table(
401                route_table_server_end,
402                &fnet_routes_admin::RouteTableOptionsV6 {
403                    name,
404                    ..fnet_routes_admin::RouteTableOptionsV6::default()
405                },
406            )
407        },
408    );
409
410    result.map_err(RouteTableCreationError::RouteTable)?;
411    Ok(route_table_proxy)
412}
413
414/// Dispatches `get_interface_local_table` on either the `RouteTableProviderV4`
415/// or `RouteTableProviderV6` proxy.
416pub async fn get_interface_local_table<I: Ip + FidlRouteAdminIpExt>(
417    route_table_provider_proxy: &<I::RouteTableProviderMarker as ProtocolMarker>::Proxy,
418    credential: fnet_resources::ProofOfInterfaceAuthorization,
419) -> Result<
420    Result<
421        <I::RouteTableMarker as ProtocolMarker>::Proxy,
422        fnet_routes_admin::GetInterfaceLocalTableError,
423    >,
424    fidl::Error,
425> {
426    #[derive(GenericOverIp)]
427    #[generic_over_ip(I, Ip)]
428    struct Input<'a, I: FidlRouteAdminIpExt> {
429        route_table_provider_proxy: &'a <I::RouteTableProviderMarker as ProtocolMarker>::Proxy,
430        credential: fnet_resources::ProofOfInterfaceAuthorization,
431    }
432
433    #[derive(GenericOverIp)]
434    #[generic_over_ip(I, Ip)]
435    struct Output<I: FidlRouteAdminIpExt>(
436        fidl::client::QueryResponseFut<
437            Result<
438                flex_client::fidl::ClientEnd<I::RouteTableMarker>,
439                fnet_routes_admin::GetInterfaceLocalTableError,
440            >,
441            flex_client::Dialect,
442        >,
443    );
444
445    let Output(fut) = I::map_ip::<Input<'_, I>, Output<I>>(
446        Input::<'_, I> { route_table_provider_proxy, credential },
447        |Input { route_table_provider_proxy, credential }| {
448            Output::<Ipv4>(route_table_provider_proxy.get_interface_local_table(credential))
449        },
450        |Input { route_table_provider_proxy, credential }| {
451            Output::<Ipv6>(route_table_provider_proxy.get_interface_local_table(credential))
452        },
453    );
454
455    fut.await.map(|r| r.map(|client_end| client_end.into_proxy()))
456}
457
458/// Dispatches `new_route_set` on either the `RouteTableV4`
459/// or `RouteTableV6` proxy.
460pub fn new_route_set<I: Ip + FidlRouteAdminIpExt>(
461    route_table_proxy: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
462) -> Result<<I::RouteSetMarker as ProtocolMarker>::Proxy, RouteSetCreationError> {
463    let (route_set_proxy, route_set_server_end) =
464        route_table_proxy.domain().create_proxy::<I::RouteSetMarker>();
465
466    #[derive(GenericOverIp)]
467    #[generic_over_ip(I, Ip)]
468    struct NewRouteSetInput<'a, I: FidlRouteAdminIpExt> {
469        route_set_server_end: flex_client::fidl::ServerEnd<I::RouteSetMarker>,
470        route_table_proxy: &'a <I::RouteTableMarker as ProtocolMarker>::Proxy,
471    }
472    let result = I::map_ip_in(
473        NewRouteSetInput::<'_, I> { route_set_server_end, route_table_proxy },
474        |NewRouteSetInput { route_set_server_end, route_table_proxy }| {
475            route_table_proxy.new_route_set(route_set_server_end)
476        },
477        |NewRouteSetInput { route_set_server_end, route_table_proxy }| {
478            route_table_proxy.new_route_set(route_set_server_end)
479        },
480    );
481
482    result.map_err(RouteSetCreationError::RouteSet)?;
483    Ok(route_set_proxy)
484}
485
486/// Dispatches `global_route_set` on either the `RoutesV4` or `RoutesV6` in
487/// fuchsia.net.root.
488pub fn new_global_route_set<I: Ip + FidlRouteAdminIpExt>(
489    route_table_proxy: &<I::GlobalRouteTableMarker as ProtocolMarker>::Proxy,
490) -> Result<<I::RouteSetMarker as ProtocolMarker>::Proxy, RouteSetCreationError> {
491    let (route_set_proxy, route_set_server_end) =
492        route_table_proxy.domain().create_proxy::<I::RouteSetMarker>();
493
494    #[derive(GenericOverIp)]
495    #[generic_over_ip(I, Ip)]
496    struct NewRouteSetInput<'a, I: FidlRouteAdminIpExt> {
497        route_set_server_end: flex_client::fidl::ServerEnd<I::RouteSetMarker>,
498        route_table_proxy: &'a <I::GlobalRouteTableMarker as ProtocolMarker>::Proxy,
499    }
500    let result = I::map_ip_in(
501        NewRouteSetInput::<'_, I> { route_set_server_end, route_table_proxy },
502        |NewRouteSetInput { route_set_server_end, route_table_proxy }| {
503            route_table_proxy.global_route_set(route_set_server_end)
504        },
505        |NewRouteSetInput { route_set_server_end, route_table_proxy }| {
506            route_table_proxy.global_route_set(route_set_server_end)
507        },
508    );
509
510    result.map_err(RouteSetCreationError::RouteSet)?;
511    Ok(route_set_proxy)
512}
513
514/// Dispatches `add_route` on either the `RouteSetV4` or `RouteSetV6` proxy.
515pub async fn add_route<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
516    route_set: &<I::RouteSetMarker as ProtocolMarker>::Proxy,
517    route: &I::Route,
518) -> Result<Result<bool, fnet_routes_admin::RouteSetError>, fidl::Error> {
519    #[derive(GenericOverIp)]
520    #[generic_over_ip(I, Ip)]
521    struct AddRouteInput<'a, I: FidlRouteAdminIpExt + FidlRouteIpExt> {
522        route_set: &'a <I::RouteSetMarker as ProtocolMarker>::Proxy,
523        route: &'a I::Route,
524    }
525
526    I::map_ip_in(
527        AddRouteInput { route_set, route },
528        |AddRouteInput { route_set, route }| Either::Left(route_set.add_route(route)),
529        |AddRouteInput { route_set, route }| Either::Right(route_set.add_route(route)),
530    )
531    .await
532}
533
534/// Dispatches `remove_route` on either the `RouteSetV4` or `RouteSetV6` proxy.
535pub async fn remove_route<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
536    route_set: &<I::RouteSetMarker as ProtocolMarker>::Proxy,
537    route: &I::Route,
538) -> Result<Result<bool, fnet_routes_admin::RouteSetError>, fidl::Error> {
539    #[derive(GenericOverIp)]
540    #[generic_over_ip(I, Ip)]
541    struct RemoveRouteInput<'a, I: FidlRouteAdminIpExt + FidlRouteIpExt> {
542        route_set: &'a <I::RouteSetMarker as ProtocolMarker>::Proxy,
543        route: &'a I::Route,
544    }
545
546    I::map_ip_in(
547        RemoveRouteInput { route_set, route },
548        |RemoveRouteInput { route_set, route }| Either::Left(route_set.remove_route(route)),
549        |RemoveRouteInput { route_set, route }| Either::Right(route_set.remove_route(route)),
550    )
551    .await
552}
553
554/// Dispatches `authenticate_for_interface` on either the `RouteSetV4` or
555/// `RouteSetV6` proxy.
556pub async fn authenticate_for_interface<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
557    route_set: &<I::RouteSetMarker as ProtocolMarker>::Proxy,
558    credential: fnet_resources::ProofOfInterfaceAuthorization,
559) -> Result<Result<(), fnet_routes_admin::AuthenticateForInterfaceError>, fidl::Error> {
560    #[derive(GenericOverIp)]
561    #[generic_over_ip(I, Ip)]
562    struct AuthenticateForInterfaceInput<'a, I: FidlRouteAdminIpExt + FidlRouteIpExt> {
563        route_set: &'a <I::RouteSetMarker as ProtocolMarker>::Proxy,
564        credential: fnet_resources::ProofOfInterfaceAuthorization,
565    }
566
567    I::map_ip_in(
568        AuthenticateForInterfaceInput { route_set, credential },
569        |AuthenticateForInterfaceInput { route_set, credential }| {
570            Either::Left(route_set.authenticate_for_interface(credential))
571        },
572        |AuthenticateForInterfaceInput { route_set, credential }| {
573            Either::Right(route_set.authenticate_for_interface(credential))
574        },
575    )
576    .await
577}
578
579#[derive(GenericOverIp)]
580#[generic_over_ip(I, Ip)]
581struct RouteTableProxy<'a, I: FidlRouteAdminIpExt + FidlRouteIpExt> {
582    route_table: &'a <I::RouteTableMarker as ProtocolMarker>::Proxy,
583}
584
585/// Dispatches `detach` on either the `RouteTableV4` or `RouteTableV6` proxy.
586pub async fn detach_route_table<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
587    route_table: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
588) -> Result<(), fidl::Error> {
589    let IpInvariant(result) = net_types::map_ip_twice!(
590        I,
591        RouteTableProxy { route_table },
592        |RouteTableProxy { route_table }| { IpInvariant(route_table.detach()) }
593    );
594
595    result
596}
597
598/// Dispatches `remove` on either the `RouteTableV4` or `RouteTableV6` proxy.
599pub async fn remove_route_table<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
600    route_table: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
601) -> Result<Result<(), fnet_routes_admin::BaseRouteTableRemoveError>, fidl::Error> {
602    let IpInvariant(result_fut) = net_types::map_ip_twice!(
603        I,
604        RouteTableProxy { route_table },
605        |RouteTableProxy { route_table }| { IpInvariant(route_table.remove()) }
606    );
607
608    result_fut.await
609}
610
611/// Dispatches `get_table_id` on either the `RouteTableV4` or `RouteTableV6`
612/// proxy.
613pub async fn get_table_id<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
614    route_table: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
615) -> Result<TableId, fidl::Error> {
616    let IpInvariant(result_fut) = net_types::map_ip_twice!(
617        I,
618        RouteTableProxy { route_table },
619        |RouteTableProxy { route_table }| IpInvariant(route_table.get_table_id()),
620    );
621
622    result_fut.await.map(TableId::new)
623}
624
625/// Dispatches `get_authorization_for_route_table` on either the `RouteTableV4`
626/// or `RouteTableV6` proxy.
627pub async fn get_authorization_for_route_table<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
628    route_table: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
629) -> Result<fnet_routes_admin::GrantForRouteTableAuthorization, fidl::Error> {
630    let IpInvariant(result_fut) = net_types::map_ip_twice!(
631        I,
632        RouteTableProxy { route_table },
633        |RouteTableProxy { route_table }| IpInvariant(
634            route_table.get_authorization_for_route_table()
635        ),
636    );
637
638    result_fut.await
639}
640
641/// GenericOverIp version of RouteSetV{4, 6}Request.
642#[derive(GenericOverIp, Debug)]
643#[generic_over_ip(I, Ip)]
644pub enum RouteSetRequest<I: FidlRouteAdminIpExt> {
645    /// Adds a route to the route set.
646    AddRoute {
647        /// The route to add.
648        route: Result<
649            crate::Route<I>,
650            crate::FidlConversionError<crate::RoutePropertiesRequiredFields>,
651        >,
652        /// The responder for this request.
653        responder: I::AddRouteResponder,
654    },
655    /// Removes a route from the route set.
656    RemoveRoute {
657        /// The route to add.
658        route: Result<
659            crate::Route<I>,
660            crate::FidlConversionError<crate::RoutePropertiesRequiredFields>,
661        >,
662        /// The responder for this request.
663        responder: I::RemoveRouteResponder,
664    },
665    /// Authenticates the route set for managing routes on an interface.
666    AuthenticateForInterface {
667        /// The credential proving authorization for this interface.
668        credential: fnet_resources::ProofOfInterfaceAuthorization,
669        /// The responder for this request.
670        responder: I::RouteSetAuthenticateForInterfaceResponder,
671    },
672}
673
674impl From<fnet_routes_admin::RouteSetV4Request> for RouteSetRequest<Ipv4> {
675    fn from(value: fnet_routes_admin::RouteSetV4Request) -> Self {
676        match value {
677            fnet_routes_admin::RouteSetV4Request::AddRoute { route, responder } => {
678                RouteSetRequest::AddRoute { route: route.try_into(), responder }
679            }
680            fnet_routes_admin::RouteSetV4Request::RemoveRoute { route, responder } => {
681                RouteSetRequest::RemoveRoute { route: route.try_into(), responder }
682            }
683            fnet_routes_admin::RouteSetV4Request::AuthenticateForInterface {
684                credential,
685                responder,
686            } => RouteSetRequest::AuthenticateForInterface { credential, responder },
687        }
688    }
689}
690
691impl From<fnet_routes_admin::RouteSetV6Request> for RouteSetRequest<Ipv6> {
692    fn from(value: fnet_routes_admin::RouteSetV6Request) -> Self {
693        match value {
694            fnet_routes_admin::RouteSetV6Request::AddRoute { route, responder } => {
695                RouteSetRequest::AddRoute { route: route.try_into(), responder }
696            }
697            fnet_routes_admin::RouteSetV6Request::RemoveRoute { route, responder } => {
698                RouteSetRequest::RemoveRoute { route: route.try_into(), responder }
699            }
700            fnet_routes_admin::RouteSetV6Request::AuthenticateForInterface {
701                credential,
702                responder,
703            } => RouteSetRequest::AuthenticateForInterface { credential, responder },
704        }
705    }
706}
707
708/// GenericOverIp version of RouteTableV{4, 6}Request.
709#[derive(GenericOverIp, derivative::Derivative)]
710#[derivative(Debug(bound = ""))]
711#[generic_over_ip(I, Ip)]
712pub enum RouteTableRequest<I: FidlRouteAdminIpExt> {
713    /// Gets the table ID for the table
714    GetTableId {
715        /// Responder for the request.
716        responder: I::RouteTableGetTableIdResponder,
717    },
718    /// Detaches the table lifetime from the channel.
719    Detach {
720        /// Control handle to the protocol.
721        control_handle: I::RouteTableControlHandle,
722    },
723    /// Removes the table.
724    Remove {
725        /// Responder to the request.
726        responder: I::RouteTableRemoveResponder,
727    },
728    /// Gets the authorization for the route table.
729    GetAuthorizationForRouteTable {
730        /// Responder to the request.
731        responder: I::RouteTableGetAuthorizationResponder,
732    },
733    /// Creates a new route set for the table.
734    NewRouteSet {
735        /// The server end of the route set protocol.
736        route_set: flex_client::fidl::ServerEnd<I::RouteSetMarker>,
737        /// Control handle to the protocol.
738        control_handle: I::RouteTableControlHandle,
739    },
740}
741
742impl From<fnet_routes_admin::RouteTableV4Request> for RouteTableRequest<Ipv4> {
743    fn from(value: fnet_routes_admin::RouteTableV4Request) -> Self {
744        match value {
745            fnet_routes_admin::RouteTableV4Request::NewRouteSet { route_set, control_handle } => {
746                RouteTableRequest::NewRouteSet { route_set, control_handle }
747            }
748            fnet_routes_admin::RouteTableV4Request::GetTableId { responder } => {
749                RouteTableRequest::GetTableId { responder }
750            }
751
752            fnet_routes_admin::RouteTableV4Request::Detach { control_handle } => {
753                RouteTableRequest::Detach { control_handle }
754            }
755
756            fnet_routes_admin::RouteTableV4Request::Remove { responder } => {
757                RouteTableRequest::Remove { responder }
758            }
759            fnet_routes_admin::RouteTableV4Request::GetAuthorizationForRouteTable { responder } => {
760                RouteTableRequest::GetAuthorizationForRouteTable { responder }
761            }
762        }
763    }
764}
765
766impl From<fnet_routes_admin::RouteTableV6Request> for RouteTableRequest<Ipv6> {
767    fn from(value: fnet_routes_admin::RouteTableV6Request) -> Self {
768        match value {
769            fnet_routes_admin::RouteTableV6Request::NewRouteSet { route_set, control_handle } => {
770                RouteTableRequest::NewRouteSet { route_set, control_handle }
771            }
772            fnet_routes_admin::RouteTableV6Request::GetTableId { responder } => {
773                RouteTableRequest::GetTableId { responder }
774            }
775
776            fnet_routes_admin::RouteTableV6Request::Detach { control_handle } => {
777                RouteTableRequest::Detach { control_handle }
778            }
779
780            fnet_routes_admin::RouteTableV6Request::Remove { responder } => {
781                RouteTableRequest::Remove { responder }
782            }
783            fnet_routes_admin::RouteTableV6Request::GetAuthorizationForRouteTable { responder } => {
784                RouteTableRequest::GetAuthorizationForRouteTable { responder }
785            }
786        }
787    }
788}