1use core::cmp::Ordering;
8use core::convert::Infallible;
9use core::num::NonZeroU8;
10
11use log::error;
12use net_types::ip::{Ip, IpVersionMarker, Ipv6Addr, Mtu};
13use net_types::{MulticastAddress, ScopeableAddress, SpecifiedAddr};
14use netstack3_base::socket::{SocketIpAddr, SocketIpAddrExt as _};
15use netstack3_base::{
16 AnyDevice, CounterContext, DeviceIdContext, DeviceIdentifier, EitherDeviceId, InstantContext,
17 IpDeviceAddr, IpExt, Marks, Mms, SendFrameErrorReason, StrongDeviceIdentifier,
18 TxMetadataBindingsTypes, WeakDeviceIdentifier,
19};
20use netstack3_filter::{
21 self as filter, FilterBindingsContext, FilterHandler as _, FilterIpExt, InterfaceProperties,
22 RawIpBody, TransportPacketSerializer,
23};
24use netstack3_trace::trace_duration;
25use packet::{BufferMut, PacketConstraints, SerializeError};
26use packet_formats::ip::DscpAndEcn;
27use thiserror::Error;
28
29use crate::internal::base::{
30 FilterHandlerProvider, IpDeviceMtuContext, IpLayerIpExt, IpLayerPacketMetadata,
31 IpPacketDestination, IpSendFrameError, IpSendFrameErrorReason, ResolveRouteError,
32 SendIpPacketMeta,
33};
34use crate::internal::counters::IpCounters;
35use crate::internal::device::state::IpDeviceStateIpExt;
36use crate::internal::routing::rules::RuleInput;
37use crate::internal::routing::PacketOrigin;
38use crate::internal::types::{InternalForwarding, ResolvedRoute, RoutableIpAddr};
39use crate::{HopLimits, NextHop};
40
41pub trait IpSocketHandler<I: IpExt + FilterIpExt, BC: TxMetadataBindingsTypes>:
43 DeviceIdContext<AnyDevice>
44{
45 fn new_ip_socket<O>(
60 &mut self,
61 bindings_ctx: &mut BC,
62 device: Option<EitherDeviceId<&Self::DeviceId, &Self::WeakDeviceId>>,
63 local_ip: Option<IpDeviceAddr<I::Addr>>,
64 remote_ip: SocketIpAddr<I::Addr>,
65 proto: I::Proto,
66 options: &O,
67 ) -> Result<IpSock<I, Self::WeakDeviceId>, IpSockCreationError>
68 where
69 O: RouteResolutionOptions<I>;
70
71 fn send_ip_packet<S, O>(
84 &mut self,
85 bindings_ctx: &mut BC,
86 socket: &IpSock<I, Self::WeakDeviceId>,
87 body: S,
88 options: &O,
89 tx_metadata: BC::TxMetadata,
90 ) -> Result<(), IpSockSendError>
91 where
92 S: TransportPacketSerializer<I>,
93 S::Buffer: BufferMut,
94 O: SendOptions<I> + RouteResolutionOptions<I>;
95
96 fn confirm_reachable<O>(
102 &mut self,
103 bindings_ctx: &mut BC,
104 socket: &IpSock<I, Self::WeakDeviceId>,
105 options: &O,
106 ) where
107 O: RouteResolutionOptions<I>;
108
109 fn send_oneshot_ip_packet_with_fallible_serializer<S, E, F, O>(
132 &mut self,
133 bindings_ctx: &mut BC,
134 device: Option<EitherDeviceId<&Self::DeviceId, &Self::WeakDeviceId>>,
135 local_ip: Option<IpDeviceAddr<I::Addr>>,
136 remote_ip: RoutableIpAddr<I::Addr>,
137 proto: I::Proto,
138 options: &O,
139 tx_metadata: BC::TxMetadata,
140 get_body_from_src_ip: F,
141 ) -> Result<(), SendOneShotIpPacketError<E>>
142 where
143 S: TransportPacketSerializer<I>,
144 S::Buffer: BufferMut,
145 F: FnOnce(IpDeviceAddr<I::Addr>) -> Result<S, E>,
146 O: SendOptions<I> + RouteResolutionOptions<I>,
147 {
148 let tmp = self
149 .new_ip_socket(bindings_ctx, device, local_ip, remote_ip, proto, options)
150 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })?;
151 let packet = get_body_from_src_ip(*tmp.local_ip())
152 .map_err(SendOneShotIpPacketError::SerializeError)?;
153 self.send_ip_packet(bindings_ctx, &tmp, packet, options, tx_metadata)
154 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })
155 }
156
157 fn send_oneshot_ip_packet<S, F, O>(
159 &mut self,
160 bindings_ctx: &mut BC,
161 device: Option<EitherDeviceId<&Self::DeviceId, &Self::WeakDeviceId>>,
162 local_ip: Option<IpDeviceAddr<I::Addr>>,
163 remote_ip: SocketIpAddr<I::Addr>,
164 proto: I::Proto,
165 options: &O,
166 tx_metadata: BC::TxMetadata,
167 get_body_from_src_ip: F,
168 ) -> Result<(), IpSockCreateAndSendError>
169 where
170 S: TransportPacketSerializer<I>,
171 S::Buffer: BufferMut,
172 F: FnOnce(IpDeviceAddr<I::Addr>) -> S,
173 O: SendOptions<I> + RouteResolutionOptions<I>,
174 {
175 self.send_oneshot_ip_packet_with_fallible_serializer(
176 bindings_ctx,
177 device,
178 local_ip,
179 remote_ip,
180 proto,
181 options,
182 tx_metadata,
183 |ip| Ok::<_, Infallible>(get_body_from_src_ip(ip)),
184 )
185 .map_err(|err| match err {
186 SendOneShotIpPacketError::CreateAndSendError { err } => err,
187 })
188 }
189}
190
191#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
193pub enum IpSockSendError {
194 #[error("a maximum transmission unit (MTU) was exceeded")]
199 Mtu,
200 #[error("the socket is currently unroutable: {0}")]
202 Unroutable(#[from] ResolveRouteError),
203 #[error("illegal loopback address")]
206 IllegalLoopbackAddress,
207 #[error("Broadcast send is not enabled for the socket")]
209 BroadcastNotAllowed,
210}
211
212impl From<SerializeError<Infallible>> for IpSockSendError {
213 fn from(err: SerializeError<Infallible>) -> IpSockSendError {
214 match err {
215 SerializeError::SizeLimitExceeded => IpSockSendError::Mtu,
216 }
217 }
218}
219
220impl IpSockSendError {
221 fn from_ip_send_frame(e: IpSendFrameErrorReason) -> Result<(), Self> {
226 match e {
227 IpSendFrameErrorReason::Device(d) => Self::from_send_frame(d),
228 IpSendFrameErrorReason::IllegalLoopbackAddress => Err(Self::IllegalLoopbackAddress),
229 }
230 }
231
232 fn from_send_frame(e: SendFrameErrorReason) -> Result<(), Self> {
237 match e {
238 SendFrameErrorReason::Alloc | SendFrameErrorReason::QueueFull => Ok(()),
239 SendFrameErrorReason::SizeConstraintsViolation => Err(Self::Mtu),
240 }
241 }
242}
243
244#[derive(Error, Copy, Clone, Debug)]
246pub enum IpSockCreateAndSendError {
247 #[error("cannot send via temporary socket: {0}")]
249 Send(#[from] IpSockSendError),
250 #[error("the temporary socket could not be created: {0}")]
252 Create(#[from] IpSockCreationError),
253}
254
255#[derive(Debug)]
258#[allow(missing_docs)]
259pub enum SendOneShotIpPacketError<E> {
260 CreateAndSendError { err: IpSockCreateAndSendError },
261 SerializeError(E),
262}
263
264#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
266pub enum MmsError {
267 #[error("cannot find the device: {0}")]
270 NoDevice(#[from] ResolveRouteError),
271 #[error("invalid MTU: {0:?}")]
274 MTUTooSmall(Mtu),
275}
276
277pub trait DeviceIpSocketHandler<I: IpExt, BC>: DeviceIdContext<AnyDevice> {
279 fn get_mms<O: RouteResolutionOptions<I>>(
285 &mut self,
286 bindings_ctx: &mut BC,
287 ip_sock: &IpSock<I, Self::WeakDeviceId>,
288 options: &O,
289 ) -> Result<Mms, MmsError>;
290}
291
292#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
294pub enum IpSockCreationError {
295 #[error("a route cannot be determined: {0}")]
297 Route(#[from] ResolveRouteError),
298}
299
300#[derive(Clone, Debug)]
302#[cfg_attr(test, derive(PartialEq))]
303pub struct IpSock<I: IpExt, D> {
304 definition: IpSockDefinition<I, D>,
308}
309
310impl<I: IpExt, D> IpSock<I, D> {
311 #[cfg(any(test, feature = "testutils"))]
313 pub fn definition(&self) -> &IpSockDefinition<I, D> {
314 &self.definition
315 }
316}
317
318#[derive(Clone, Debug, PartialEq)]
322pub struct IpSockDefinition<I: IpExt, D> {
323 pub remote_ip: SocketIpAddr<I::Addr>,
325 pub local_ip: IpDeviceAddr<I::Addr>,
336 pub device: Option<D>,
338 pub proto: I::Proto,
340}
341
342impl<I: IpExt, D> IpSock<I, D> {
343 pub fn local_ip(&self) -> &IpDeviceAddr<I::Addr> {
345 &self.definition.local_ip
346 }
347 pub fn remote_ip(&self) -> &SocketIpAddr<I::Addr> {
349 &self.definition.remote_ip
350 }
351 pub fn device(&self) -> Option<&D> {
353 self.definition.device.as_ref()
354 }
355 pub fn proto(&self) -> I::Proto {
357 self.definition.proto
358 }
359}
360
361pub trait IpSocketBindingsContext:
368 InstantContext + FilterBindingsContext + TxMetadataBindingsTypes
369{
370}
371impl<BC: InstantContext + FilterBindingsContext + TxMetadataBindingsTypes> IpSocketBindingsContext
372 for BC
373{
374}
375
376pub trait IpSocketContext<I, BC: IpSocketBindingsContext>:
381 DeviceIdContext<AnyDevice, DeviceId: InterfaceProperties<BC::DeviceClass>>
382 + FilterHandlerProvider<I, BC>
383where
384 I: IpDeviceStateIpExt + IpExt + FilterIpExt,
385{
386 fn lookup_route(
391 &mut self,
392 bindings_ctx: &mut BC,
393 device: Option<&Self::DeviceId>,
394 src_ip: Option<IpDeviceAddr<I::Addr>>,
395 dst_ip: RoutableIpAddr<I::Addr>,
396 transparent: bool,
397 marks: &Marks,
398 ) -> Result<ResolvedRoute<I, Self::DeviceId>, ResolveRouteError>;
399
400 fn send_ip_packet<S>(
402 &mut self,
403 bindings_ctx: &mut BC,
404 meta: SendIpPacketMeta<I, &Self::DeviceId, SpecifiedAddr<I::Addr>>,
405 body: S,
406 packet_metadata: IpLayerPacketMetadata<I, Self::WeakAddressId, BC>,
407 ) -> Result<(), IpSendFrameError<S>>
408 where
409 S: TransportPacketSerializer<I>,
410 S::Buffer: BufferMut;
411
412 fn get_loopback_device(&mut self) -> Option<Self::DeviceId>;
414
415 fn confirm_reachable(
421 &mut self,
422 bindings_ctx: &mut BC,
423 dst: SpecifiedAddr<I::Addr>,
424 input: RuleInput<'_, I, Self::DeviceId>,
425 );
426}
427
428pub trait UseIpSocketHandlerBlanket {}
433
434impl<I, BC, CC> IpSocketHandler<I, BC> for CC
435where
436 I: IpLayerIpExt + IpDeviceStateIpExt,
437 BC: IpSocketBindingsContext,
438 CC: IpSocketContext<I, BC> + CounterContext<IpCounters<I>> + UseIpSocketHandlerBlanket,
439 CC::DeviceId: filter::InterfaceProperties<BC::DeviceClass>,
440{
441 fn new_ip_socket<O>(
442 &mut self,
443 bindings_ctx: &mut BC,
444 device: Option<EitherDeviceId<&CC::DeviceId, &CC::WeakDeviceId>>,
445 local_ip: Option<IpDeviceAddr<I::Addr>>,
446 remote_ip: SocketIpAddr<I::Addr>,
447 proto: I::Proto,
448 options: &O,
449 ) -> Result<IpSock<I, CC::WeakDeviceId>, IpSockCreationError>
450 where
451 O: RouteResolutionOptions<I>,
452 {
453 let device = device
454 .as_ref()
455 .map(|d| d.as_strong_ref().ok_or(ResolveRouteError::Unreachable))
456 .transpose()?;
457 let device = device.as_ref().map(|d| d.as_ref());
458
459 let resolved_route = self.lookup_route(
464 bindings_ctx,
465 device,
466 local_ip,
467 remote_ip,
468 options.transparent(),
469 options.marks(),
470 )?;
471 Ok(new_ip_socket(device, resolved_route, remote_ip, proto))
472 }
473
474 fn send_ip_packet<S, O>(
475 &mut self,
476 bindings_ctx: &mut BC,
477 ip_sock: &IpSock<I, CC::WeakDeviceId>,
478 body: S,
479 options: &O,
480 tx_metadata: BC::TxMetadata,
481 ) -> Result<(), IpSockSendError>
482 where
483 S: TransportPacketSerializer<I>,
484 S::Buffer: BufferMut,
485 O: SendOptions<I> + RouteResolutionOptions<I>,
486 {
487 send_ip_packet(self, bindings_ctx, ip_sock, body, options, tx_metadata)
488 }
489
490 fn confirm_reachable<O>(
491 &mut self,
492 bindings_ctx: &mut BC,
493 socket: &IpSock<I, CC::WeakDeviceId>,
494 options: &O,
495 ) where
496 O: RouteResolutionOptions<I>,
497 {
498 let bound_device = socket.device().and_then(|weak| weak.upgrade());
499 let bound_device = bound_device.as_ref();
500 let bound_address = Some((*socket.local_ip()).into());
501 let destination = (*socket.remote_ip()).into();
502 IpSocketContext::confirm_reachable(
503 self,
504 bindings_ctx,
505 destination,
506 RuleInput {
507 packet_origin: PacketOrigin::Local { bound_address, bound_device },
508 marks: options.marks(),
509 },
510 )
511 }
512}
513
514pub trait RouteResolutionOptions<I: Ip> {
526 fn transparent(&self) -> bool;
531
532 fn marks(&self) -> &Marks;
534}
535
536pub trait SendOptions<I: IpExt> {
544 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8>;
550
551 fn multicast_loop(&self) -> bool;
554
555 fn allow_broadcast(&self) -> Option<I::BroadcastMarker>;
557
558 fn dscp_and_ecn(&self) -> DscpAndEcn;
560
561 fn mtu(&self) -> Mtu;
566}
567
568#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
570pub struct DefaultIpSocketOptions;
571
572impl<I: IpExt> SendOptions<I> for DefaultIpSocketOptions {
573 fn hop_limit(&self, _destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
574 None
575 }
576
577 fn multicast_loop(&self) -> bool {
578 false
579 }
580
581 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
582 None
583 }
584
585 fn dscp_and_ecn(&self) -> DscpAndEcn {
586 DscpAndEcn::default()
587 }
588
589 fn mtu(&self) -> Mtu {
590 Mtu::no_limit()
591 }
592}
593
594impl<I: Ip> RouteResolutionOptions<I> for DefaultIpSocketOptions {
595 fn transparent(&self) -> bool {
596 false
597 }
598
599 fn marks(&self) -> &Marks {
600 &Marks::UNMARKED
601 }
602}
603
604#[allow(missing_docs)]
612pub trait DelegatedSendOptions<I: IpExt>: OptionDelegationMarker {
613 fn delegate(&self) -> &impl SendOptions<I> {
615 &DefaultIpSocketOptions
616 }
617
618 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
619 self.delegate().hop_limit(destination)
620 }
621
622 fn multicast_loop(&self) -> bool {
623 self.delegate().multicast_loop()
624 }
625
626 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
627 self.delegate().allow_broadcast()
628 }
629
630 fn dscp_and_ecn(&self) -> DscpAndEcn {
631 self.delegate().dscp_and_ecn()
632 }
633
634 fn mtu(&self) -> Mtu {
635 self.delegate().mtu()
636 }
637}
638
639impl<O: DelegatedSendOptions<I> + OptionDelegationMarker, I: IpExt> SendOptions<I> for O {
640 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
641 self.hop_limit(destination)
642 }
643
644 fn multicast_loop(&self) -> bool {
645 self.multicast_loop()
646 }
647
648 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
649 self.allow_broadcast()
650 }
651
652 fn dscp_and_ecn(&self) -> DscpAndEcn {
653 self.dscp_and_ecn()
654 }
655
656 fn mtu(&self) -> Mtu {
657 self.mtu()
658 }
659}
660
661#[allow(missing_docs)]
669pub trait DelegatedRouteResolutionOptions<I: Ip>: OptionDelegationMarker {
670 fn delegate(&self) -> &impl RouteResolutionOptions<I> {
672 &DefaultIpSocketOptions
673 }
674
675 fn transparent(&self) -> bool {
676 self.delegate().transparent()
677 }
678
679 fn marks(&self) -> &Marks {
680 self.delegate().marks()
681 }
682}
683
684impl<O: DelegatedRouteResolutionOptions<I> + OptionDelegationMarker, I: IpExt>
685 RouteResolutionOptions<I> for O
686{
687 fn transparent(&self) -> bool {
688 self.transparent()
689 }
690
691 fn marks(&self) -> &Marks {
692 self.marks()
693 }
694}
695
696pub trait OptionDelegationMarker {}
701
702#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
704pub struct SocketHopLimits<I: Ip> {
705 pub unicast: Option<NonZeroU8>,
707 pub multicast: Option<NonZeroU8>,
711 pub version: IpVersionMarker<I>,
715}
716
717impl<I: Ip> SocketHopLimits<I> {
718 pub fn set_unicast(value: Option<NonZeroU8>) -> impl FnOnce(&mut Self) {
720 move |limits| limits.unicast = value
721 }
722
723 pub fn set_multicast(value: Option<NonZeroU8>) -> impl FnOnce(&mut Self) {
725 move |limits| limits.multicast = value
726 }
727
728 pub fn get_limits_with_defaults(&self, defaults: &HopLimits) -> HopLimits {
730 let Self { unicast, multicast, version: _ } = self;
731 HopLimits {
732 unicast: unicast.unwrap_or(defaults.unicast),
733 multicast: multicast.unwrap_or(defaults.multicast),
734 }
735 }
736
737 pub fn hop_limit_for_dst(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
739 let Self { unicast, multicast, version: _ } = self;
740 if destination.is_multicast() {
741 *multicast
742 } else {
743 *unicast
744 }
745 }
746}
747
748fn new_ip_socket<I, D>(
749 requested_device: Option<&D>,
750 route: ResolvedRoute<I, D>,
751 remote_ip: SocketIpAddr<I::Addr>,
752 proto: I::Proto,
753) -> IpSock<I, D::Weak>
754where
755 I: IpExt,
756 D: StrongDeviceIdentifier,
757{
758 let ResolvedRoute {
762 src_addr,
763 device: route_device,
764 local_delivery_device,
765 next_hop: _,
766 internal_forwarding: _,
767 } = route;
768
769 let socket_device = (src_addr.as_ref().must_have_zone() || remote_ip.as_ref().must_have_zone())
772 .then(|| {
773 local_delivery_device.unwrap_or(route_device)
777 })
778 .as_ref()
779 .or(requested_device)
780 .map(|d| d.downgrade());
781
782 let definition =
783 IpSockDefinition { local_ip: src_addr, remote_ip, device: socket_device, proto };
784 IpSock { definition }
785}
786
787fn send_ip_packet<I, S, BC, CC, O>(
788 core_ctx: &mut CC,
789 bindings_ctx: &mut BC,
790 socket: &IpSock<I, CC::WeakDeviceId>,
791 mut body: S,
792 options: &O,
793 tx_metadata: BC::TxMetadata,
794) -> Result<(), IpSockSendError>
795where
796 I: IpExt + IpDeviceStateIpExt + FilterIpExt,
797 S: TransportPacketSerializer<I>,
798 S::Buffer: BufferMut,
799 BC: IpSocketBindingsContext,
800 CC: IpSocketContext<I, BC>,
801 CC::DeviceId: filter::InterfaceProperties<BC::DeviceClass>,
802 O: SendOptions<I> + RouteResolutionOptions<I>,
803{
804 trace_duration!(c"ip::send_packet");
805
806 fn resolve<
809 I: IpExt + IpDeviceStateIpExt + FilterIpExt,
810 CC: IpSocketContext<I, BC>,
811 BC: IpSocketBindingsContext,
812 >(
813 core_ctx: &mut CC,
814 bindings_ctx: &mut BC,
815 device: &Option<CC::WeakDeviceId>,
816 local_ip: IpDeviceAddr<I::Addr>,
817 remote_ip: RoutableIpAddr<I::Addr>,
818 transparent: bool,
819 marks: &Marks,
820 ) -> Result<ResolvedRoute<I, CC::DeviceId>, IpSockSendError> {
821 let device = match device.as_ref().map(|d| d.upgrade()) {
822 Some(Some(device)) => Some(device),
823 Some(None) => return Err(ResolveRouteError::Unreachable.into()),
824 None => None,
825 };
826 let route = core_ctx
827 .lookup_route(
828 bindings_ctx,
829 device.as_ref(),
830 Some(local_ip),
831 remote_ip,
832 transparent,
833 marks,
834 )
835 .map_err(|e| IpSockSendError::Unroutable(e))?;
836 assert_eq!(local_ip, route.src_addr);
837 Ok(route)
838 }
839
840 let IpSock {
841 definition: IpSockDefinition { remote_ip, local_ip, device: socket_device, proto },
842 } = socket;
843 let ResolvedRoute {
844 src_addr: local_ip,
845 device: mut egress_device,
846 mut next_hop,
847 mut local_delivery_device,
848 mut internal_forwarding,
849 } = resolve(
850 core_ctx,
851 bindings_ctx,
852 socket_device,
853 *local_ip,
854 *remote_ip,
855 options.transparent(),
856 options.marks(),
857 )?;
858
859 if matches!(next_hop, NextHop::Broadcast(_)) && options.allow_broadcast().is_none() {
860 return Err(IpSockSendError::BroadcastNotAllowed);
861 }
862
863 let previous_dst = remote_ip.addr();
864 let mut packet = filter::TxPacket::new(local_ip.addr(), remote_ip.addr(), *proto, &mut body);
865 let mut packet_metadata =
866 IpLayerPacketMetadata::from_tx_metadata_and_marks(tx_metadata, *options.marks());
867
868 match core_ctx.filter_handler().local_egress_hook(
869 bindings_ctx,
870 &mut packet,
871 &egress_device,
872 &mut packet_metadata,
873 ) {
874 filter::Verdict::Drop => {
875 packet_metadata.acknowledge_drop();
876 return Ok(());
877 }
878 filter::Verdict::Accept(()) => {}
879 }
880
881 let Some(mut local_ip) = IpDeviceAddr::new(packet.src_addr()) else {
882 packet_metadata.acknowledge_drop();
883 return Err(IpSockSendError::Unroutable(ResolveRouteError::NoSrcAddr));
884 };
885 let Some(remote_ip) = RoutableIpAddr::new(packet.dst_addr()) else {
886 packet_metadata.acknowledge_drop();
887 return Err(IpSockSendError::Unroutable(ResolveRouteError::Unreachable));
888 };
889
890 if remote_ip.addr() != previous_dst {
893 let ResolvedRoute {
894 src_addr: new_local_ip,
895 device: new_device,
896 next_hop: new_next_hop,
897 local_delivery_device: new_local_delivery_device,
898 internal_forwarding: new_internal_forwarding,
899 } = match resolve(
900 core_ctx,
901 bindings_ctx,
902 socket_device,
903 local_ip,
904 remote_ip,
905 options.transparent(),
906 options.marks(),
907 ) {
908 Ok(r) => r,
909 Err(err) => {
910 packet_metadata.acknowledge_drop();
911 return Err(err);
912 }
913 };
914 local_ip = new_local_ip;
915 egress_device = new_device;
916 next_hop = new_next_hop;
917 local_delivery_device = new_local_delivery_device;
918 internal_forwarding = new_internal_forwarding;
919 }
920
921 match internal_forwarding {
923 InternalForwarding::Used(ingress_device) => {
924 match core_ctx.filter_handler().forwarding_hook(
925 &mut packet,
926 &ingress_device,
927 &egress_device,
928 &mut packet_metadata,
929 ) {
930 filter::Verdict::Drop => {
931 packet_metadata.acknowledge_drop();
932 return Ok(());
933 }
934 filter::Verdict::Accept(()) => {}
935 }
936 }
937 InternalForwarding::NotUsed => {}
938 }
939
940 let loopback_packet = (!egress_device.is_loopback()
945 && ((options.multicast_loop() && remote_ip.addr().is_multicast())
946 || next_hop.is_broadcast()))
947 .then(|| body.serialize_new_buf(PacketConstraints::UNCONSTRAINED, packet::new_buf_vec))
948 .transpose()?
949 .map(|buf| RawIpBody::new(*proto, local_ip.addr(), remote_ip.addr(), buf));
950
951 let destination = match &local_delivery_device {
952 Some(d) => IpPacketDestination::Loopback(d),
953 None => IpPacketDestination::from_next_hop(next_hop, remote_ip.into()),
954 };
955 let ttl = options.hop_limit(&remote_ip.into());
956 let meta = SendIpPacketMeta {
957 device: &egress_device,
958 src_ip: local_ip.into(),
959 dst_ip: remote_ip.into(),
960 destination,
961 ttl,
962 proto: *proto,
963 mtu: options.mtu(),
964 dscp_and_ecn: options.dscp_and_ecn(),
965 };
966 IpSocketContext::send_ip_packet(core_ctx, bindings_ctx, meta, body, packet_metadata).or_else(
967 |IpSendFrameError { serializer: _, error }| IpSockSendError::from_ip_send_frame(error),
968 )?;
969
970 match (loopback_packet, core_ctx.get_loopback_device()) {
971 (Some(loopback_packet), Some(loopback_device)) => {
972 let meta = SendIpPacketMeta {
973 device: &loopback_device,
974 src_ip: local_ip.into(),
975 dst_ip: remote_ip.into(),
976 destination: IpPacketDestination::Loopback(&egress_device),
977 ttl,
978 proto: *proto,
979 mtu: options.mtu(),
980 dscp_and_ecn: options.dscp_and_ecn(),
981 };
982 let packet_metadata = IpLayerPacketMetadata::default();
983
984 IpSocketContext::send_ip_packet(
987 core_ctx,
988 bindings_ctx,
989 meta,
990 loopback_packet,
991 packet_metadata,
992 )
993 .unwrap_or_else(|IpSendFrameError { serializer: _, error }| {
994 error!("failed to send loopback packet: {error:?}")
995 });
996 }
997 (Some(_loopback_packet), None) => {
998 error!("can't send a loopback packet without the loopback device")
999 }
1000 _ => (),
1001 }
1002
1003 Ok(())
1004}
1005
1006pub trait UseDeviceIpSocketHandlerBlanket {}
1011
1012impl<I, BC, CC> DeviceIpSocketHandler<I, BC> for CC
1013where
1014 I: IpLayerIpExt + IpDeviceStateIpExt,
1015 BC: IpSocketBindingsContext,
1016 CC: IpDeviceMtuContext<I> + IpSocketContext<I, BC> + UseDeviceIpSocketHandlerBlanket,
1017{
1018 fn get_mms<O: RouteResolutionOptions<I>>(
1019 &mut self,
1020 bindings_ctx: &mut BC,
1021 ip_sock: &IpSock<I, Self::WeakDeviceId>,
1022 options: &O,
1023 ) -> Result<Mms, MmsError> {
1024 let IpSockDefinition { remote_ip, local_ip, device, proto: _ } = &ip_sock.definition;
1025 let device = device
1026 .as_ref()
1027 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
1028 .transpose()?;
1029
1030 let ResolvedRoute {
1031 src_addr: _,
1032 local_delivery_device: _,
1033 device,
1034 next_hop: _,
1035 internal_forwarding: _,
1036 } = self
1037 .lookup_route(
1038 bindings_ctx,
1039 device.as_ref(),
1040 Some(*local_ip),
1041 *remote_ip,
1042 options.transparent(),
1043 options.marks(),
1044 )
1045 .map_err(MmsError::NoDevice)?;
1046 let mtu = self.get_mtu(&device);
1047 Mms::from_mtu::<I>(mtu, 0 ).ok_or(MmsError::MTUTooSmall(mtu))
1050 }
1051}
1052
1053pub(crate) mod ipv6_source_address_selection {
1055 use net_types::ip::{AddrSubnet, IpAddress as _};
1056
1057 use super::*;
1058
1059 use netstack3_base::Ipv6DeviceAddr;
1060
1061 pub struct SasCandidate<D> {
1063 pub addr_sub: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1065 pub assigned: bool,
1067 pub deprecated: bool,
1069 pub temporary: bool,
1071 pub device: D,
1073 }
1074
1075 pub fn select_ipv6_source_address<
1088 'a,
1089 D: PartialEq,
1090 A,
1091 I: Iterator<Item = A>,
1092 F: FnMut(&A) -> SasCandidate<D>,
1093 >(
1094 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1095 outbound_device: &D,
1096 addresses: I,
1097 mut get_candidate: F,
1098 ) -> Option<A> {
1099 addresses
1111 .map(|item| {
1112 let candidate = get_candidate(&item);
1113 (item, candidate)
1114 })
1115 .filter(|(_, candidate)| candidate.assigned)
1118 .max_by(|(_, a), (_, b)| {
1119 select_ipv6_source_address_cmp(remote_ip, outbound_device, a, b)
1120 })
1121 .map(|(item, _candidate)| item)
1122 }
1123
1124 fn select_ipv6_source_address_cmp<D: PartialEq>(
1126 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1127 outbound_device: &D,
1128 a: &SasCandidate<D>,
1129 b: &SasCandidate<D>,
1130 ) -> Ordering {
1131 let SasCandidate {
1133 addr_sub: a_addr_sub,
1134 assigned: a_assigned,
1135 deprecated: a_deprecated,
1136 temporary: a_temporary,
1137 device: a_device,
1138 } = a;
1139 let SasCandidate {
1140 addr_sub: b_addr_sub,
1141 assigned: b_assigned,
1142 deprecated: b_deprecated,
1143 temporary: b_temporary,
1144 device: b_device,
1145 } = b;
1146
1147 let a_addr = a_addr_sub.addr().into_specified();
1148 let b_addr = b_addr_sub.addr().into_specified();
1149
1150 if let Some(remote_ip) = remote_ip {
1154 debug_assert!(!(a_addr == remote_ip && b_addr == remote_ip));
1155 }
1156
1157 debug_assert!(a_assigned);
1160 debug_assert!(b_assigned);
1161
1162 rule_1(remote_ip, a_addr, b_addr)
1163 .then_with(|| rule_2(remote_ip, a_addr, b_addr))
1164 .then_with(|| rule_3(*a_deprecated, *b_deprecated))
1165 .then_with(|| rule_5(outbound_device, a_device, b_device))
1166 .then_with(|| rule_7(*a_temporary, *b_temporary))
1167 .then_with(|| rule_8(remote_ip, *a_addr_sub, *b_addr_sub))
1168 }
1169
1170 fn rule_1(
1172 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1173 a: SpecifiedAddr<Ipv6Addr>,
1174 b: SpecifiedAddr<Ipv6Addr>,
1175 ) -> Ordering {
1176 let remote_ip = match remote_ip {
1177 Some(remote_ip) => remote_ip,
1178 None => return Ordering::Equal,
1179 };
1180 if (a == remote_ip) != (b == remote_ip) {
1181 if a == remote_ip {
1193 Ordering::Greater
1194 } else {
1195 Ordering::Less
1196 }
1197 } else {
1198 Ordering::Equal
1199 }
1200 }
1201
1202 fn rule_2(
1203 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1204 a: SpecifiedAddr<Ipv6Addr>,
1205 b: SpecifiedAddr<Ipv6Addr>,
1206 ) -> Ordering {
1207 let remote_scope = match remote_ip {
1210 Some(remote_ip) => remote_ip.scope().multicast_scope_id(),
1211 None => return Ordering::Equal,
1212 };
1213 let a_scope = a.scope().multicast_scope_id();
1214 let b_scope = b.scope().multicast_scope_id();
1215 if a_scope < b_scope {
1216 if a_scope < remote_scope {
1217 Ordering::Less
1218 } else {
1219 Ordering::Greater
1220 }
1221 } else if a_scope > b_scope {
1222 if b_scope < remote_scope {
1223 Ordering::Greater
1224 } else {
1225 Ordering::Less
1226 }
1227 } else {
1228 Ordering::Equal
1229 }
1230 }
1231
1232 fn rule_3(a_deprecated: bool, b_deprecated: bool) -> Ordering {
1233 match (a_deprecated, b_deprecated) {
1234 (true, false) => Ordering::Less,
1235 (true, true) | (false, false) => Ordering::Equal,
1236 (false, true) => Ordering::Greater,
1237 }
1238 }
1239
1240 fn rule_5<D: PartialEq>(outbound_device: &D, a_device: &D, b_device: &D) -> Ordering {
1241 if (a_device == outbound_device) != (b_device == outbound_device) {
1242 if a_device == outbound_device {
1244 Ordering::Greater
1245 } else {
1246 Ordering::Less
1247 }
1248 } else {
1249 Ordering::Equal
1250 }
1251 }
1252
1253 fn rule_7(a_temporary: bool, b_temporary: bool) -> Ordering {
1255 match (a_temporary, b_temporary) {
1256 (true, false) => Ordering::Greater,
1257 (true, true) | (false, false) => Ordering::Equal,
1258 (false, true) => Ordering::Less,
1259 }
1260 }
1261
1262 fn rule_8(
1263 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1264 a: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1265 b: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1266 ) -> Ordering {
1267 let remote_ip = match remote_ip {
1268 Some(remote_ip) => remote_ip,
1269 None => return Ordering::Equal,
1270 };
1271 fn common_prefix_len(
1281 src: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1282 dst: SpecifiedAddr<Ipv6Addr>,
1283 ) -> u8 {
1284 core::cmp::min(src.addr().common_prefix_len(&dst), src.subnet().prefix())
1285 }
1286
1287 common_prefix_len(a, remote_ip).cmp(&common_prefix_len(b, remote_ip))
1299 }
1300
1301 #[cfg(test)]
1302 mod tests {
1303 use net_declare::net_ip_v6;
1304
1305 use super::*;
1306
1307 #[test]
1308 fn test_select_ipv6_source_address() {
1309 let remote = SpecifiedAddr::new(net_ip_v6!("2001:0db8:1::")).unwrap();
1313 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1314 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1315 let link_local_remote = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:42")).unwrap();
1316 let link_local = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:4")).unwrap();
1317 let dev0 = &0;
1318 let dev1 = &1;
1319 let dev2 = &2;
1320
1321 assert_eq!(rule_1(Some(remote), remote, local0), Ordering::Greater);
1323 assert_eq!(rule_1(Some(remote), local0, remote), Ordering::Less);
1324 assert_eq!(rule_1(Some(remote), local0, local1), Ordering::Equal);
1325 assert_eq!(rule_1(None, local0, local1), Ordering::Equal);
1326
1327 assert_eq!(rule_2(Some(remote), local0, local1), Ordering::Equal);
1329 assert_eq!(rule_2(Some(remote), local1, local0), Ordering::Equal);
1330 assert_eq!(rule_2(Some(remote), local0, link_local), Ordering::Greater);
1331 assert_eq!(rule_2(Some(remote), link_local, local0), Ordering::Less);
1332 assert_eq!(rule_2(Some(link_local_remote), local0, link_local), Ordering::Less);
1333 assert_eq!(rule_2(Some(link_local_remote), link_local, local0), Ordering::Greater);
1334 assert_eq!(rule_1(None, local0, link_local), Ordering::Equal);
1335
1336 assert_eq!(rule_3(false, true), Ordering::Greater);
1338 assert_eq!(rule_3(true, false), Ordering::Less);
1339 assert_eq!(rule_3(true, true), Ordering::Equal);
1340 assert_eq!(rule_3(false, false), Ordering::Equal);
1341
1342 assert_eq!(rule_5(dev0, dev0, dev2), Ordering::Greater);
1344 assert_eq!(rule_5(dev0, dev2, dev0), Ordering::Less);
1345 assert_eq!(rule_5(dev0, dev0, dev0), Ordering::Equal);
1346 assert_eq!(rule_5(dev0, dev2, dev2), Ordering::Equal);
1347
1348 assert_eq!(rule_7(true, false), Ordering::Greater);
1350 assert_eq!(rule_7(false, true), Ordering::Less);
1351 assert_eq!(rule_7(true, true), Ordering::Equal);
1352 assert_eq!(rule_7(false, false), Ordering::Equal);
1353
1354 {
1356 let new_addr_entry = |addr, prefix_len| AddrSubnet::new(addr, prefix_len).unwrap();
1357
1358 let remote = SpecifiedAddr::new(net_ip_v6!("1111::")).unwrap();
1364 let local0 = new_addr_entry(net_ip_v6!("1110::"), 64);
1366 let local1 = new_addr_entry(net_ip_v6!("1100::"), 64);
1368
1369 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Greater);
1370 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Less);
1371 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1372 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1373 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1374
1375 let local0 = new_addr_entry(net_ip_v6!("1110::"), 8);
1380 let local1 = new_addr_entry(net_ip_v6!("1100::"), 8);
1382
1383 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Equal);
1384 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Equal);
1385 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1386 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1387 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1388 }
1389
1390 {
1391 let new_addr_entry = |addr, device| SasCandidate {
1392 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1393 deprecated: false,
1394 assigned: true,
1395 temporary: false,
1396 device,
1397 };
1398
1399 assert_eq!(
1401 select_ipv6_source_address_cmp(
1402 Some(remote),
1403 dev0,
1404 &new_addr_entry(*local0, *dev1),
1405 &new_addr_entry(*local1, *dev2),
1406 ),
1407 Ordering::Equal
1408 );
1409 }
1410 }
1411
1412 #[test]
1413 fn test_select_ipv6_source_address_no_remote() {
1414 let dev0 = &0;
1417 let dev1 = &1;
1418 let dev2 = &2;
1419
1420 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1421 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1422
1423 let new_addr_entry = |addr, deprecated, device| SasCandidate {
1424 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1425 deprecated,
1426 assigned: true,
1427 temporary: false,
1428 device,
1429 };
1430
1431 assert_eq!(
1433 select_ipv6_source_address_cmp(
1434 None,
1435 dev0,
1436 &new_addr_entry(*local0, false, *dev1),
1437 &new_addr_entry(*local1, true, *dev2),
1438 ),
1439 Ordering::Greater
1440 );
1441
1442 assert_eq!(
1444 select_ipv6_source_address_cmp(
1445 None,
1446 dev0,
1447 &new_addr_entry(*local0, false, *dev0),
1448 &new_addr_entry(*local1, false, *dev1),
1449 ),
1450 Ordering::Greater
1451 );
1452 }
1453 }
1454}
1455
1456#[cfg(any(test, feature = "testutils"))]
1458pub(crate) mod testutil {
1459 use alloc::boxed::Box;
1460 use alloc::collections::HashMap;
1461 use alloc::vec::Vec;
1462 use core::num::NonZeroUsize;
1463
1464 use derivative::Derivative;
1465 use net_types::ip::{GenericOverIp, IpAddr, IpAddress, Ipv4, Ipv4Addr, Ipv6, Subnet};
1466 use net_types::{MulticastAddr, Witness as _};
1467 use netstack3_base::testutil::{FakeCoreCtx, FakeStrongDeviceId, FakeWeakDeviceId};
1468 use netstack3_base::{SendFrameContext, SendFrameError};
1469 use netstack3_filter::Tuple;
1470
1471 use super::*;
1472 use crate::internal::base::{
1473 BaseTransportIpContext, HopLimits, MulticastMembershipHandler, DEFAULT_HOP_LIMITS,
1474 };
1475 use crate::internal::routing::testutil::FakeIpRoutingCtx;
1476 use crate::internal::routing::{self, RoutingTable};
1477 use crate::internal::types::{Destination, Entry, Metric, RawMetric};
1478
1479 #[derive(Derivative, GenericOverIp)]
1482 #[generic_over_ip(I, Ip)]
1483 #[derivative(Default(bound = ""))]
1484 pub struct FakeIpSocketCtx<I: Ip, D> {
1485 pub(crate) table: RoutingTable<I, D>,
1486 forwarding: FakeIpRoutingCtx<D>,
1487 devices: HashMap<D, FakeDeviceState<I>>,
1488 }
1489
1490 pub trait InnerFakeIpSocketCtx<I: Ip, D> {
1493 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D>;
1495 }
1496
1497 impl<I: Ip, D> InnerFakeIpSocketCtx<I, D> for FakeIpSocketCtx<I, D> {
1498 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1499 self
1500 }
1501 }
1502
1503 impl<I: IpExt, D: FakeStrongDeviceId, BC> BaseTransportIpContext<I, BC> for FakeIpSocketCtx<I, D> {
1504 fn get_default_hop_limits(&mut self, device: Option<&D>) -> HopLimits {
1505 device.map_or(DEFAULT_HOP_LIMITS, |device| {
1506 let hop_limit = self.get_device_state(device).default_hop_limit;
1507 HopLimits { unicast: hop_limit, multicast: DEFAULT_HOP_LIMITS.multicast }
1508 })
1509 }
1510
1511 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1512
1513 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1514 &mut self,
1515 addr: SpecifiedAddr<I::Addr>,
1516 cb: F,
1517 ) -> O {
1518 cb(Box::new(self.devices.iter().filter_map(move |(device, state)| {
1519 state.addresses.contains(&addr).then(|| device.clone())
1520 })))
1521 }
1522
1523 fn get_original_destination(&mut self, _tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1524 unimplemented!()
1525 }
1526 }
1527
1528 impl<I: IpExt, D: FakeStrongDeviceId> DeviceIdContext<AnyDevice> for FakeIpSocketCtx<I, D> {
1529 type DeviceId = D;
1530 type WeakDeviceId = D::Weak;
1531 }
1532
1533 impl<I, State, D, Meta, BC> IpSocketHandler<I, BC> for FakeCoreCtx<State, Meta, D>
1534 where
1535 I: IpExt + FilterIpExt,
1536 State: InnerFakeIpSocketCtx<I, D>,
1537 D: FakeStrongDeviceId,
1538 BC: TxMetadataBindingsTypes,
1539 FakeCoreCtx<State, Meta, D>:
1540 SendFrameContext<BC, SendIpPacketMeta<I, Self::DeviceId, SpecifiedAddr<I::Addr>>>,
1541 {
1542 fn new_ip_socket<O>(
1543 &mut self,
1544 _bindings_ctx: &mut BC,
1545 device: Option<EitherDeviceId<&Self::DeviceId, &Self::WeakDeviceId>>,
1546 local_ip: Option<IpDeviceAddr<I::Addr>>,
1547 remote_ip: SocketIpAddr<I::Addr>,
1548 proto: I::Proto,
1549 options: &O,
1550 ) -> Result<IpSock<I, Self::WeakDeviceId>, IpSockCreationError>
1551 where
1552 O: RouteResolutionOptions<I>,
1553 {
1554 self.state.fake_ip_socket_ctx_mut().new_ip_socket(
1555 device,
1556 local_ip,
1557 remote_ip,
1558 proto,
1559 options.transparent(),
1560 )
1561 }
1562
1563 fn send_ip_packet<S, O>(
1564 &mut self,
1565 bindings_ctx: &mut BC,
1566 socket: &IpSock<I, Self::WeakDeviceId>,
1567 body: S,
1568 options: &O,
1569 _tx_meta: BC::TxMetadata,
1572 ) -> Result<(), IpSockSendError>
1573 where
1574 S: TransportPacketSerializer<I>,
1575 S::Buffer: BufferMut,
1576 O: SendOptions<I> + RouteResolutionOptions<I>,
1577 {
1578 let meta = self.state.fake_ip_socket_ctx_mut().resolve_send_meta(socket, options)?;
1579 self.send_frame(bindings_ctx, meta, body).or_else(
1580 |SendFrameError { serializer: _, error }| IpSockSendError::from_send_frame(error),
1581 )
1582 }
1583
1584 fn confirm_reachable<O>(
1585 &mut self,
1586 _bindings_ctx: &mut BC,
1587 _socket: &IpSock<I, Self::WeakDeviceId>,
1588 _options: &O,
1589 ) {
1590 }
1591 }
1592
1593 impl<I: IpExt, D: FakeStrongDeviceId, BC> MulticastMembershipHandler<I, BC>
1594 for FakeIpSocketCtx<I, D>
1595 {
1596 fn join_multicast_group(
1597 &mut self,
1598 _bindings_ctx: &mut BC,
1599 device: &Self::DeviceId,
1600 addr: MulticastAddr<<I as Ip>::Addr>,
1601 ) {
1602 let value = self.get_device_state_mut(device).multicast_groups.entry(addr).or_insert(0);
1603 *value = value.checked_add(1).unwrap();
1604 }
1605
1606 fn leave_multicast_group(
1607 &mut self,
1608 _bindings_ctx: &mut BC,
1609 device: &Self::DeviceId,
1610 addr: MulticastAddr<<I as Ip>::Addr>,
1611 ) {
1612 let value = self
1613 .get_device_state_mut(device)
1614 .multicast_groups
1615 .get_mut(&addr)
1616 .unwrap_or_else(|| panic!("no entry for {addr} on {device:?}"));
1617 *value = value.checked_sub(1).unwrap();
1618 }
1619
1620 fn select_device_for_multicast_group(
1621 &mut self,
1622 addr: MulticastAddr<<I as Ip>::Addr>,
1623 _marks: &Marks,
1624 ) -> Result<Self::DeviceId, ResolveRouteError> {
1625 let remote_ip = SocketIpAddr::new_from_multicast(addr);
1626 self.lookup_route(None, None, remote_ip, false)
1627 .map(|ResolvedRoute { device, .. }| device)
1628 }
1629 }
1630
1631 impl<I, BC, D, State, Meta> BaseTransportIpContext<I, BC> for FakeCoreCtx<State, Meta, D>
1632 where
1633 I: IpExt + FilterIpExt,
1634 D: FakeStrongDeviceId,
1635 State: InnerFakeIpSocketCtx<I, D>,
1636 BC: TxMetadataBindingsTypes,
1637 Self: IpSocketHandler<I, BC, DeviceId = D, WeakDeviceId = FakeWeakDeviceId<D>>,
1638 {
1639 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1640
1641 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1642 &mut self,
1643 addr: SpecifiedAddr<I::Addr>,
1644 cb: F,
1645 ) -> O {
1646 BaseTransportIpContext::<I, BC>::with_devices_with_assigned_addr(
1647 self.state.fake_ip_socket_ctx_mut(),
1648 addr,
1649 cb,
1650 )
1651 }
1652
1653 fn get_default_hop_limits(&mut self, device: Option<&Self::DeviceId>) -> HopLimits {
1654 BaseTransportIpContext::<I, BC>::get_default_hop_limits(
1655 self.state.fake_ip_socket_ctx_mut(),
1656 device,
1657 )
1658 }
1659
1660 fn get_original_destination(&mut self, tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1661 BaseTransportIpContext::<I, BC>::get_original_destination(
1662 self.state.fake_ip_socket_ctx_mut(),
1663 tuple,
1664 )
1665 }
1666 }
1667
1668 #[derive(Derivative)]
1670 #[derivative(Default(bound = ""))]
1671 pub struct FakeDualStackIpSocketCtx<D> {
1672 v4: FakeIpSocketCtx<Ipv4, D>,
1673 v6: FakeIpSocketCtx<Ipv6, D>,
1674 }
1675
1676 impl<D: FakeStrongDeviceId> FakeDualStackIpSocketCtx<D> {
1677 pub fn new<A: Into<SpecifiedAddr<IpAddr>>>(
1679 devices: impl IntoIterator<Item = FakeDeviceConfig<D, A>>,
1680 ) -> Self {
1681 let partition =
1682 |v: Vec<A>| -> (Vec<SpecifiedAddr<Ipv4Addr>>, Vec<SpecifiedAddr<Ipv6Addr>>) {
1683 v.into_iter().fold((Vec::new(), Vec::new()), |(mut v4, mut v6), i| {
1684 match IpAddr::from(i.into()) {
1685 IpAddr::V4(a) => v4.push(a),
1686 IpAddr::V6(a) => v6.push(a),
1687 }
1688 (v4, v6)
1689 })
1690 };
1691
1692 let (v4, v6): (Vec<_>, Vec<_>) = devices
1693 .into_iter()
1694 .map(|FakeDeviceConfig { device, local_ips, remote_ips }| {
1695 let (local_v4, local_v6) = partition(local_ips);
1696 let (remote_v4, remote_v6) = partition(remote_ips);
1697 (
1698 FakeDeviceConfig {
1699 device: device.clone(),
1700 local_ips: local_v4,
1701 remote_ips: remote_v4,
1702 },
1703 FakeDeviceConfig { device, local_ips: local_v6, remote_ips: remote_v6 },
1704 )
1705 })
1706 .unzip();
1707 Self { v4: FakeIpSocketCtx::new(v4), v6: FakeIpSocketCtx::new(v6) }
1708 }
1709
1710 pub fn inner_mut<I: Ip>(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1712 I::map_ip_out(self, |s| &mut s.v4, |s| &mut s.v6)
1713 }
1714
1715 fn inner<I: Ip>(&self) -> &FakeIpSocketCtx<I, D> {
1716 I::map_ip_out(self, |s| &s.v4, |s| &s.v6)
1717 }
1718
1719 pub fn add_route(&mut self, device: D, ip: SpecifiedAddr<IpAddr>) {
1721 match IpAddr::from(ip) {
1722 IpAddr::V4(ip) => {
1723 routing::testutil::add_on_link_routing_entry(&mut self.v4.table, ip, device)
1724 }
1725 IpAddr::V6(ip) => {
1726 routing::testutil::add_on_link_routing_entry(&mut self.v6.table, ip, device)
1727 }
1728 }
1729 }
1730
1731 pub fn add_subnet_route<A: IpAddress>(&mut self, device: D, subnet: Subnet<A>) {
1733 let entry = Entry {
1734 subnet,
1735 device,
1736 gateway: None,
1737 metric: Metric::ExplicitMetric(RawMetric(0)),
1738 };
1739 A::Version::map_ip::<_, ()>(
1740 entry,
1741 |entry_v4| {
1742 let _ = routing::testutil::add_entry(&mut self.v4.table, entry_v4)
1743 .expect("Failed to add route");
1744 },
1745 |entry_v6| {
1746 let _ = routing::testutil::add_entry(&mut self.v6.table, entry_v6)
1747 .expect("Failed to add route");
1748 },
1749 );
1750 }
1751
1752 pub fn get_device_state_mut<I: IpExt>(&mut self, device: &D) -> &mut FakeDeviceState<I> {
1754 self.inner_mut::<I>().get_device_state_mut(device)
1755 }
1756
1757 pub fn multicast_memberships<I: IpExt>(
1759 &self,
1760 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
1761 self.inner::<I>().multicast_memberships()
1762 }
1763 }
1764
1765 impl<I: IpExt, S: InnerFakeIpSocketCtx<I, D>, Meta, D: FakeStrongDeviceId, BC>
1766 MulticastMembershipHandler<I, BC> for FakeCoreCtx<S, Meta, D>
1767 {
1768 fn join_multicast_group(
1769 &mut self,
1770 bindings_ctx: &mut BC,
1771 device: &Self::DeviceId,
1772 addr: MulticastAddr<<I as Ip>::Addr>,
1773 ) {
1774 MulticastMembershipHandler::<I, BC>::join_multicast_group(
1775 self.state.fake_ip_socket_ctx_mut(),
1776 bindings_ctx,
1777 device,
1778 addr,
1779 )
1780 }
1781
1782 fn leave_multicast_group(
1783 &mut self,
1784 bindings_ctx: &mut BC,
1785 device: &Self::DeviceId,
1786 addr: MulticastAddr<<I as Ip>::Addr>,
1787 ) {
1788 MulticastMembershipHandler::<I, BC>::leave_multicast_group(
1789 self.state.fake_ip_socket_ctx_mut(),
1790 bindings_ctx,
1791 device,
1792 addr,
1793 )
1794 }
1795
1796 fn select_device_for_multicast_group(
1797 &mut self,
1798 addr: MulticastAddr<<I as Ip>::Addr>,
1799 marks: &Marks,
1800 ) -> Result<Self::DeviceId, ResolveRouteError> {
1801 MulticastMembershipHandler::<I, BC>::select_device_for_multicast_group(
1802 self.state.fake_ip_socket_ctx_mut(),
1803 addr,
1804 marks,
1805 )
1806 }
1807 }
1808
1809 impl<I: Ip, D, State: InnerFakeIpSocketCtx<I, D>, Meta> InnerFakeIpSocketCtx<I, D>
1810 for FakeCoreCtx<State, Meta, D>
1811 {
1812 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1813 self.state.fake_ip_socket_ctx_mut()
1814 }
1815 }
1816
1817 impl<I: Ip, D: FakeStrongDeviceId> InnerFakeIpSocketCtx<I, D> for FakeDualStackIpSocketCtx<D> {
1818 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1819 self.inner_mut::<I>()
1820 }
1821 }
1822
1823 #[derive(Clone, GenericOverIp)]
1825 #[generic_over_ip()]
1826 pub struct FakeDeviceConfig<D, A> {
1827 pub device: D,
1829 pub local_ips: Vec<A>,
1831 pub remote_ips: Vec<A>,
1833 }
1834
1835 pub struct FakeDeviceState<I: Ip> {
1837 pub default_hop_limit: NonZeroU8,
1839 pub addresses: Vec<SpecifiedAddr<I::Addr>>,
1841 pub multicast_groups: HashMap<MulticastAddr<I::Addr>, usize>,
1843 }
1844
1845 impl<I: Ip> FakeDeviceState<I> {
1846 pub fn is_in_multicast_group(&self, addr: &MulticastAddr<I::Addr>) -> bool {
1848 self.multicast_groups.get(addr).is_some_and(|v| *v != 0)
1849 }
1850 }
1851
1852 impl<I: IpExt, D: FakeStrongDeviceId> FakeIpSocketCtx<I, D> {
1853 pub fn new(
1856 device_configs: impl IntoIterator<Item = FakeDeviceConfig<D, SpecifiedAddr<I::Addr>>>,
1857 ) -> Self {
1858 let mut table = RoutingTable::default();
1859 let mut devices = HashMap::default();
1860 for FakeDeviceConfig { device, local_ips, remote_ips } in device_configs {
1861 for addr in remote_ips {
1862 routing::testutil::add_on_link_routing_entry(&mut table, addr, device.clone())
1863 }
1864 let state = FakeDeviceState {
1865 default_hop_limit: DEFAULT_HOP_LIMITS.unicast,
1866 addresses: local_ips,
1867 multicast_groups: Default::default(),
1868 };
1869 assert!(
1870 devices.insert(device.clone(), state).is_none(),
1871 "duplicate entries for {device:?}",
1872 );
1873 }
1874
1875 Self { table, devices, forwarding: Default::default() }
1876 }
1877
1878 pub fn get_device_state(&self, device: &D) -> &FakeDeviceState<I> {
1880 self.devices.get(device).unwrap_or_else(|| panic!("no device {device:?}"))
1881 }
1882
1883 pub fn get_device_state_mut(&mut self, device: &D) -> &mut FakeDeviceState<I> {
1885 self.devices.get_mut(device).unwrap_or_else(|| panic!("no device {device:?}"))
1886 }
1887
1888 pub(crate) fn multicast_memberships(
1889 &self,
1890 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
1891 self.devices
1892 .iter()
1893 .map(|(device, state)| {
1894 state.multicast_groups.iter().filter_map(|(group, count)| {
1895 NonZeroUsize::new(*count).map(|count| ((device.clone(), *group), count))
1896 })
1897 })
1898 .flatten()
1899 .collect()
1900 }
1901
1902 fn new_ip_socket(
1903 &mut self,
1904 device: Option<EitherDeviceId<&D, &D::Weak>>,
1905 local_ip: Option<IpDeviceAddr<I::Addr>>,
1906 remote_ip: SocketIpAddr<I::Addr>,
1907 proto: I::Proto,
1908 transparent: bool,
1909 ) -> Result<IpSock<I, D::Weak>, IpSockCreationError> {
1910 let device = device
1911 .as_ref()
1912 .map(|d| d.as_strong_ref().ok_or(ResolveRouteError::Unreachable))
1913 .transpose()?;
1914 let device = device.as_ref().map(|d| d.as_ref());
1915 let resolved_route = self.lookup_route(device, local_ip, remote_ip, transparent)?;
1916 Ok(new_ip_socket(device, resolved_route, remote_ip, proto))
1917 }
1918
1919 fn lookup_route(
1920 &mut self,
1921 device: Option<&D>,
1922 local_ip: Option<IpDeviceAddr<I::Addr>>,
1923 addr: RoutableIpAddr<I::Addr>,
1924 transparent: bool,
1925 ) -> Result<ResolvedRoute<I, D>, ResolveRouteError> {
1926 let Self { table, devices, forwarding } = self;
1927 let (destination, ()) = table
1928 .lookup_filter_map(forwarding, device, addr.addr(), |_, d| match &local_ip {
1929 None => Some(()),
1930 Some(local_ip) => {
1931 if transparent {
1932 return Some(());
1933 }
1934 devices.get(d).and_then(|state| {
1935 state.addresses.contains(local_ip.as_ref()).then_some(())
1936 })
1937 }
1938 })
1939 .next()
1940 .ok_or(ResolveRouteError::Unreachable)?;
1941
1942 let Destination { device, next_hop } = destination;
1943 let mut addrs = devices.get(device).unwrap().addresses.iter();
1944 let local_ip = match local_ip {
1945 None => {
1946 let addr = addrs.next().ok_or(ResolveRouteError::NoSrcAddr)?;
1947 IpDeviceAddr::new(addr.get()).expect("not valid device addr")
1948 }
1949 Some(local_ip) => {
1950 if !transparent {
1951 assert!(
1954 addrs.any(|a| a.get() == local_ip.addr()),
1955 "didn't find IP {:?} in {:?}",
1956 local_ip,
1957 addrs.collect::<Vec<_>>()
1958 );
1959 }
1960 local_ip
1961 }
1962 };
1963
1964 Ok(ResolvedRoute {
1965 src_addr: local_ip,
1966 device: device.clone(),
1967 local_delivery_device: None,
1968 next_hop,
1969 internal_forwarding: InternalForwarding::NotUsed,
1972 })
1973 }
1974
1975 fn resolve_send_meta<O>(
1976 &mut self,
1977 socket: &IpSock<I, D::Weak>,
1978 options: &O,
1979 ) -> Result<SendIpPacketMeta<I, D, SpecifiedAddr<I::Addr>>, IpSockSendError>
1980 where
1981 O: SendOptions<I> + RouteResolutionOptions<I>,
1982 {
1983 let IpSockDefinition { remote_ip, local_ip, device, proto } = &socket.definition;
1984 let device = device
1985 .as_ref()
1986 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
1987 .transpose()?;
1988 let ResolvedRoute {
1989 src_addr,
1990 device,
1991 next_hop,
1992 local_delivery_device: _,
1993 internal_forwarding: _,
1994 } = self.lookup_route(
1995 device.as_ref(),
1996 Some(*local_ip),
1997 *remote_ip,
1998 options.transparent(),
1999 )?;
2000
2001 let remote_ip: &SpecifiedAddr<_> = remote_ip.as_ref();
2002
2003 let destination = IpPacketDestination::from_next_hop(next_hop, *remote_ip);
2004 Ok(SendIpPacketMeta {
2005 device,
2006 src_ip: src_addr.into(),
2007 dst_ip: *remote_ip,
2008 destination,
2009 proto: *proto,
2010 ttl: options.hop_limit(remote_ip),
2011 mtu: options.mtu(),
2012 dscp_and_ecn: DscpAndEcn::default(),
2013 })
2014 }
2015 }
2016}