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_interfaces_admin as fnet_interfaces_admin, fidl_fuchsia_net_root as fnet_root,
15    fidl_fuchsia_net_routes_admin as fnet_routes_admin,
16};
17
18use crate::{impl_responder, FidlRouteIpExt, Responder, TableId};
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,
48    >;
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_interfaces_admin::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 `new_route_set` on either the `RouteTableV4`
413/// or `RouteTableV6` proxy.
414pub fn new_route_set<I: Ip + FidlRouteAdminIpExt>(
415    route_table_proxy: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
416) -> Result<<I::RouteSetMarker as ProtocolMarker>::Proxy, RouteSetCreationError> {
417    let (route_set_proxy, route_set_server_end) =
418        fidl::endpoints::create_proxy::<I::RouteSetMarker>();
419
420    #[derive(GenericOverIp)]
421    #[generic_over_ip(I, Ip)]
422    struct NewRouteSetInput<'a, I: FidlRouteAdminIpExt> {
423        route_set_server_end: fidl::endpoints::ServerEnd<I::RouteSetMarker>,
424        route_table_proxy: &'a <I::RouteTableMarker as ProtocolMarker>::Proxy,
425    }
426    let result = I::map_ip_in(
427        NewRouteSetInput::<'_, I> { route_set_server_end, route_table_proxy },
428        |NewRouteSetInput { route_set_server_end, route_table_proxy }| {
429            route_table_proxy.new_route_set(route_set_server_end)
430        },
431        |NewRouteSetInput { route_set_server_end, route_table_proxy }| {
432            route_table_proxy.new_route_set(route_set_server_end)
433        },
434    );
435
436    result.map_err(RouteSetCreationError::RouteSet)?;
437    Ok(route_set_proxy)
438}
439
440/// Dispatches `global_route_set` on either the `RoutesV4` or `RoutesV6` in
441/// fuchsia.net.root.
442pub fn new_global_route_set<I: Ip + FidlRouteAdminIpExt>(
443    route_table_proxy: &<I::GlobalRouteTableMarker as ProtocolMarker>::Proxy,
444) -> Result<<I::RouteSetMarker as ProtocolMarker>::Proxy, RouteSetCreationError> {
445    let (route_set_proxy, route_set_server_end) =
446        fidl::endpoints::create_proxy::<I::RouteSetMarker>();
447
448    #[derive(GenericOverIp)]
449    #[generic_over_ip(I, Ip)]
450    struct NewRouteSetInput<'a, I: FidlRouteAdminIpExt> {
451        route_set_server_end: fidl::endpoints::ServerEnd<I::RouteSetMarker>,
452        route_table_proxy: &'a <I::GlobalRouteTableMarker as ProtocolMarker>::Proxy,
453    }
454    let result = I::map_ip_in(
455        NewRouteSetInput::<'_, I> { route_set_server_end, route_table_proxy },
456        |NewRouteSetInput { route_set_server_end, route_table_proxy }| {
457            route_table_proxy.global_route_set(route_set_server_end)
458        },
459        |NewRouteSetInput { route_set_server_end, route_table_proxy }| {
460            route_table_proxy.global_route_set(route_set_server_end)
461        },
462    );
463
464    result.map_err(RouteSetCreationError::RouteSet)?;
465    Ok(route_set_proxy)
466}
467
468/// Dispatches `add_route` on either the `RouteSetV4` or `RouteSetV6` proxy.
469pub async fn add_route<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
470    route_set: &<I::RouteSetMarker as ProtocolMarker>::Proxy,
471    route: &I::Route,
472) -> Result<Result<bool, fnet_routes_admin::RouteSetError>, fidl::Error> {
473    #[derive(GenericOverIp)]
474    #[generic_over_ip(I, Ip)]
475    struct AddRouteInput<'a, I: FidlRouteAdminIpExt + FidlRouteIpExt> {
476        route_set: &'a <I::RouteSetMarker as ProtocolMarker>::Proxy,
477        route: &'a I::Route,
478    }
479
480    I::map_ip_in(
481        AddRouteInput { route_set, route },
482        |AddRouteInput { route_set, route }| Either::Left(route_set.add_route(route)),
483        |AddRouteInput { route_set, route }| Either::Right(route_set.add_route(route)),
484    )
485    .await
486}
487
488/// Dispatches `remove_route` on either the `RouteSetV4` or `RouteSetV6` proxy.
489pub async fn remove_route<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
490    route_set: &<I::RouteSetMarker as ProtocolMarker>::Proxy,
491    route: &I::Route,
492) -> Result<Result<bool, fnet_routes_admin::RouteSetError>, fidl::Error> {
493    #[derive(GenericOverIp)]
494    #[generic_over_ip(I, Ip)]
495    struct RemoveRouteInput<'a, I: FidlRouteAdminIpExt + FidlRouteIpExt> {
496        route_set: &'a <I::RouteSetMarker as ProtocolMarker>::Proxy,
497        route: &'a I::Route,
498    }
499
500    I::map_ip_in(
501        RemoveRouteInput { route_set, route },
502        |RemoveRouteInput { route_set, route }| Either::Left(route_set.remove_route(route)),
503        |RemoveRouteInput { route_set, route }| Either::Right(route_set.remove_route(route)),
504    )
505    .await
506}
507
508/// Dispatches `authenticate_for_interface` on either the `RouteSetV4` or
509/// `RouteSetV6` proxy.
510pub async fn authenticate_for_interface<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
511    route_set: &<I::RouteSetMarker as ProtocolMarker>::Proxy,
512    credential: fnet_interfaces_admin::ProofOfInterfaceAuthorization,
513) -> Result<Result<(), fnet_routes_admin::AuthenticateForInterfaceError>, fidl::Error> {
514    #[derive(GenericOverIp)]
515    #[generic_over_ip(I, Ip)]
516    struct AuthenticateForInterfaceInput<'a, I: FidlRouteAdminIpExt + FidlRouteIpExt> {
517        route_set: &'a <I::RouteSetMarker as ProtocolMarker>::Proxy,
518        credential: fnet_interfaces_admin::ProofOfInterfaceAuthorization,
519    }
520
521    I::map_ip_in(
522        AuthenticateForInterfaceInput { route_set, credential },
523        |AuthenticateForInterfaceInput { route_set, credential }| {
524            Either::Left(route_set.authenticate_for_interface(credential))
525        },
526        |AuthenticateForInterfaceInput { route_set, credential }| {
527            Either::Right(route_set.authenticate_for_interface(credential))
528        },
529    )
530    .await
531}
532
533#[derive(GenericOverIp)]
534#[generic_over_ip(I, Ip)]
535struct RouteTableProxy<'a, I: FidlRouteAdminIpExt + FidlRouteIpExt> {
536    route_table: &'a <I::RouteTableMarker as ProtocolMarker>::Proxy,
537}
538
539/// Dispatches `detach` on either the `RouteTableV4` or `RouteTableV6` proxy.
540pub async fn detach_route_table<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
541    route_table: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
542) -> Result<(), fidl::Error> {
543    let IpInvariant(result) = net_types::map_ip_twice!(
544        I,
545        RouteTableProxy { route_table },
546        |RouteTableProxy { route_table }| { IpInvariant(route_table.detach()) }
547    );
548
549    result
550}
551
552/// Dispatches `remove` on either the `RouteTableV4` or `RouteTableV6` proxy.
553pub async fn remove_route_table<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
554    route_table: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
555) -> Result<Result<(), fnet_routes_admin::BaseRouteTableRemoveError>, fidl::Error> {
556    let IpInvariant(result_fut) = net_types::map_ip_twice!(
557        I,
558        RouteTableProxy { route_table },
559        |RouteTableProxy { route_table }| { IpInvariant(route_table.remove()) }
560    );
561
562    result_fut.await
563}
564
565/// Dispatches `get_table_id` on either the `RouteTableV4` or `RouteTableV6`
566/// proxy.
567pub async fn get_table_id<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
568    route_table: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
569) -> Result<TableId, fidl::Error> {
570    let IpInvariant(result_fut) = net_types::map_ip_twice!(
571        I,
572        RouteTableProxy { route_table },
573        |RouteTableProxy { route_table }| IpInvariant(route_table.get_table_id()),
574    );
575
576    result_fut.await.map(TableId::new)
577}
578
579/// Dispatches `get_authorization_for_route_table` on either the `RouteTableV4`
580/// or `RouteTableV6` proxy.
581pub async fn get_authorization_for_route_table<I: Ip + FidlRouteAdminIpExt + FidlRouteIpExt>(
582    route_table: &<I::RouteTableMarker as ProtocolMarker>::Proxy,
583) -> Result<fnet_routes_admin::GrantForRouteTableAuthorization, fidl::Error> {
584    let IpInvariant(result_fut) = net_types::map_ip_twice!(
585        I,
586        RouteTableProxy { route_table },
587        |RouteTableProxy { route_table }| IpInvariant(
588            route_table.get_authorization_for_route_table()
589        ),
590    );
591
592    result_fut.await
593}
594
595/// GenericOverIp version of RouteSetV{4, 6}Request.
596#[derive(GenericOverIp, Debug)]
597#[generic_over_ip(I, Ip)]
598pub enum RouteSetRequest<I: FidlRouteAdminIpExt> {
599    /// Adds a route to the route set.
600    AddRoute {
601        /// The route to add.
602        route: Result<
603            crate::Route<I>,
604            crate::FidlConversionError<crate::RoutePropertiesRequiredFields>,
605        >,
606        /// The responder for this request.
607        responder: I::AddRouteResponder,
608    },
609    /// Removes a route from the route set.
610    RemoveRoute {
611        /// The route to add.
612        route: Result<
613            crate::Route<I>,
614            crate::FidlConversionError<crate::RoutePropertiesRequiredFields>,
615        >,
616        /// The responder for this request.
617        responder: I::RemoveRouteResponder,
618    },
619    /// Authenticates the route set for managing routes on an interface.
620    AuthenticateForInterface {
621        /// The credential proving authorization for this interface.
622        credential: fnet_interfaces_admin::ProofOfInterfaceAuthorization,
623        /// The responder for this request.
624        responder: I::RouteSetAuthenticateForInterfaceResponder,
625    },
626}
627
628impl From<fnet_routes_admin::RouteSetV4Request> for RouteSetRequest<Ipv4> {
629    fn from(value: fnet_routes_admin::RouteSetV4Request) -> Self {
630        match value {
631            fnet_routes_admin::RouteSetV4Request::AddRoute { route, responder } => {
632                RouteSetRequest::AddRoute { route: route.try_into(), responder }
633            }
634            fnet_routes_admin::RouteSetV4Request::RemoveRoute { route, responder } => {
635                RouteSetRequest::RemoveRoute { route: route.try_into(), responder }
636            }
637            fnet_routes_admin::RouteSetV4Request::AuthenticateForInterface {
638                credential,
639                responder,
640            } => RouteSetRequest::AuthenticateForInterface { credential, responder },
641        }
642    }
643}
644
645impl From<fnet_routes_admin::RouteSetV6Request> for RouteSetRequest<Ipv6> {
646    fn from(value: fnet_routes_admin::RouteSetV6Request) -> Self {
647        match value {
648            fnet_routes_admin::RouteSetV6Request::AddRoute { route, responder } => {
649                RouteSetRequest::AddRoute { route: route.try_into(), responder }
650            }
651            fnet_routes_admin::RouteSetV6Request::RemoveRoute { route, responder } => {
652                RouteSetRequest::RemoveRoute { route: route.try_into(), responder }
653            }
654            fnet_routes_admin::RouteSetV6Request::AuthenticateForInterface {
655                credential,
656                responder,
657            } => RouteSetRequest::AuthenticateForInterface { credential, responder },
658        }
659    }
660}
661
662/// GenericOverIp version of RouteTableV{4, 6}Request.
663#[derive(GenericOverIp, derivative::Derivative)]
664#[derivative(Debug(bound = ""))]
665#[generic_over_ip(I, Ip)]
666pub enum RouteTableRequest<I: FidlRouteAdminIpExt> {
667    /// Gets the table ID for the table
668    GetTableId {
669        /// Responder for the request.
670        responder: I::RouteTableGetTableIdResponder,
671    },
672    /// Detaches the table lifetime from the channel.
673    Detach {
674        /// Control handle to the protocol.
675        control_handle: I::RouteTableControlHandle,
676    },
677    /// Removes the table.
678    Remove {
679        /// Responder to the request.
680        responder: I::RouteTableRemoveResponder,
681    },
682    /// Gets the authorization for the route table.
683    GetAuthorizationForRouteTable {
684        /// Responder to the request.
685        responder: I::RouteTableGetAuthorizationResponder,
686    },
687    /// Creates a new route set for the table.
688    NewRouteSet {
689        /// The server end of the route set protocol.
690        route_set: fidl::endpoints::ServerEnd<I::RouteSetMarker>,
691        /// Control handle to the protocol.
692        control_handle: I::RouteTableControlHandle,
693    },
694}
695
696impl From<fnet_routes_admin::RouteTableV4Request> for RouteTableRequest<Ipv4> {
697    fn from(value: fnet_routes_admin::RouteTableV4Request) -> Self {
698        match value {
699            fnet_routes_admin::RouteTableV4Request::NewRouteSet { route_set, control_handle } => {
700                RouteTableRequest::NewRouteSet { route_set, control_handle }
701            }
702            fnet_routes_admin::RouteTableV4Request::GetTableId { responder } => {
703                RouteTableRequest::GetTableId { responder }
704            }
705
706            fnet_routes_admin::RouteTableV4Request::Detach { control_handle } => {
707                RouteTableRequest::Detach { control_handle }
708            }
709
710            fnet_routes_admin::RouteTableV4Request::Remove { responder } => {
711                RouteTableRequest::Remove { responder }
712            }
713            fnet_routes_admin::RouteTableV4Request::GetAuthorizationForRouteTable { responder } => {
714                RouteTableRequest::GetAuthorizationForRouteTable { responder }
715            }
716        }
717    }
718}
719
720impl From<fnet_routes_admin::RouteTableV6Request> for RouteTableRequest<Ipv6> {
721    fn from(value: fnet_routes_admin::RouteTableV6Request) -> Self {
722        match value {
723            fnet_routes_admin::RouteTableV6Request::NewRouteSet { route_set, control_handle } => {
724                RouteTableRequest::NewRouteSet { route_set, control_handle }
725            }
726            fnet_routes_admin::RouteTableV6Request::GetTableId { responder } => {
727                RouteTableRequest::GetTableId { responder }
728            }
729
730            fnet_routes_admin::RouteTableV6Request::Detach { control_handle } => {
731                RouteTableRequest::Detach { control_handle }
732            }
733
734            fnet_routes_admin::RouteTableV6Request::Remove { responder } => {
735                RouteTableRequest::Remove { responder }
736            }
737            fnet_routes_admin::RouteTableV6Request::GetAuthorizationForRouteTable { responder } => {
738                RouteTableRequest::GetAuthorizationForRouteTable { responder }
739            }
740        }
741    }
742}