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