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 InterfaceProperties, IpDeviceAddr, IpExt, Marks, Mms, SendFrameErrorReason,
18 StrongDeviceIdentifier, TxMetadata as _, TxMetadataBindingsTypes, WeakDeviceIdentifier,
19};
20use netstack3_filter::{
21 self as filter, DynTransportSerializer, DynamicTransportSerializer, FilterBindingsContext,
22 FilterHandler as _, FilterIpExt, RawIpBody, SocketEgressFilterResult, SocketOpsFilter,
23 SocketOpsFilterBindingContext, TransportPacketSerializer,
24};
25use netstack3_trace::trace_duration;
26use packet::{BufferMut, PacketConstraints, SerializeError};
27use packet_formats::ip::DscpAndEcn;
28use thiserror::Error;
29
30use crate::internal::base::{
31 FilterHandlerProvider, IpDeviceMtuContext, IpLayerIpExt, IpLayerPacketMetadata,
32 IpPacketDestination, IpSendFrameError, IpSendFrameErrorReason, ResolveRouteError,
33 SendIpPacketMeta,
34};
35use crate::internal::counters::IpCounters;
36use crate::internal::device::state::IpDeviceStateIpExt;
37use crate::internal::routing::PacketOrigin;
38use crate::internal::routing::rules::RuleInput;
39use crate::internal::types::{InternalForwarding, ResolvedRoute, RoutableIpAddr};
40use crate::{HopLimits, NextHop};
41
42pub struct IpSocketArgs<'a, D: StrongDeviceIdentifier, I: IpExt, O> {
44 pub device: Option<EitherDeviceId<&'a D, &'a D::Weak>>,
46 pub local_ip: Option<IpDeviceAddr<I::Addr>>,
49 pub remote_ip: RoutableIpAddr<I::Addr>,
51 pub proto: I::Proto,
53 pub options: &'a O,
55}
56pub trait IpSocketHandler<I: IpExt + FilterIpExt, BC: TxMetadataBindingsTypes>:
58 DeviceIdContext<AnyDevice>
59{
60 fn new_ip_socket<O>(
75 &mut self,
76 bindings_ctx: &mut BC,
77 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
78 ) -> Result<IpSock<I, Self::WeakDeviceId>, IpSockCreationError>
79 where
80 O: RouteResolutionOptions<I>;
81
82 fn send_ip_packet<S, O>(
95 &mut self,
96 bindings_ctx: &mut BC,
97 socket: &IpSock<I, Self::WeakDeviceId>,
98 body: S,
99 options: &O,
100 tx_metadata: BC::TxMetadata,
101 ) -> Result<(), IpSockSendError>
102 where
103 S: TransportPacketSerializer<I>,
104 S::Buffer: BufferMut,
105 O: SendOptions<I> + RouteResolutionOptions<I>;
106
107 fn confirm_reachable<O>(
113 &mut self,
114 bindings_ctx: &mut BC,
115 socket: &IpSock<I, Self::WeakDeviceId>,
116 options: &O,
117 ) where
118 O: RouteResolutionOptions<I>;
119
120 fn send_oneshot_ip_packet_with_fallible_serializer<S, E, F, O>(
143 &mut self,
144 bindings_ctx: &mut BC,
145 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
146 tx_metadata: BC::TxMetadata,
147 get_body_from_src_ip: F,
148 ) -> Result<(), SendOneShotIpPacketError<E>>
149 where
150 S: TransportPacketSerializer<I>,
151 S::Buffer: BufferMut,
152 F: FnOnce(IpDeviceAddr<I::Addr>) -> Result<S, E>,
153 O: SendOptions<I> + RouteResolutionOptions<I>,
154 {
155 let options = args.options;
156 let tmp = self
157 .new_ip_socket(bindings_ctx, args)
158 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })?;
159 let packet = get_body_from_src_ip(*tmp.local_ip())
160 .map_err(SendOneShotIpPacketError::SerializeError)?;
161 self.send_ip_packet(bindings_ctx, &tmp, packet, options, tx_metadata)
162 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })
163 }
164
165 fn send_oneshot_ip_packet_with_dyn_fallible_serializer<S, E, F, O>(
171 &mut self,
172 bindings_ctx: &mut BC,
173 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
174 tx_metadata: BC::TxMetadata,
175 get_body_from_src_ip: F,
176 ) -> Result<(), SendOneShotIpPacketError<E>>
177 where
178 S: DynamicTransportSerializer<I>,
179 F: FnOnce(IpDeviceAddr<I::Addr>) -> Result<S, E>,
180 O: SendOptions<I> + RouteResolutionOptions<I>,
181 {
182 let options = args.options;
183 let tmp = self
184 .new_ip_socket(bindings_ctx, args)
185 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })?;
186 let mut packet = get_body_from_src_ip(*tmp.local_ip())
187 .map_err(SendOneShotIpPacketError::SerializeError)?;
188 self.send_ip_packet(
189 bindings_ctx,
190 &tmp,
191 DynTransportSerializer::new(&mut packet),
192 options,
193 tx_metadata,
194 )
195 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })
196 }
197
198 fn send_oneshot_ip_packet<S, F, O>(
200 &mut self,
201 bindings_ctx: &mut BC,
202 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
203 tx_metadata: BC::TxMetadata,
204 get_body_from_src_ip: F,
205 ) -> Result<(), IpSockCreateAndSendError>
206 where
207 S: TransportPacketSerializer<I>,
208 S::Buffer: BufferMut,
209 F: FnOnce(IpDeviceAddr<I::Addr>) -> S,
210 O: SendOptions<I> + RouteResolutionOptions<I>,
211 {
212 self.send_oneshot_ip_packet_with_fallible_serializer(
213 bindings_ctx,
214 args,
215 tx_metadata,
216 |ip| Ok::<_, Infallible>(get_body_from_src_ip(ip)),
217 )
218 .map_err(|err| match err {
219 SendOneShotIpPacketError::CreateAndSendError { err } => err,
220 })
221 }
222
223 fn send_oneshot_ip_packet_with_dyn_serializer<S, F, O>(
229 &mut self,
230 bindings_ctx: &mut BC,
231 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
232 tx_metadata: BC::TxMetadata,
233 get_body_from_src_ip: F,
234 ) -> Result<(), IpSockCreateAndSendError>
235 where
236 S: DynamicTransportSerializer<I>,
237 F: FnOnce(IpDeviceAddr<I::Addr>) -> S,
238 O: SendOptions<I> + RouteResolutionOptions<I>,
239 {
240 self.send_oneshot_ip_packet_with_dyn_fallible_serializer(
241 bindings_ctx,
242 args,
243 tx_metadata,
244 |ip| Ok::<_, Infallible>(get_body_from_src_ip(ip)),
245 )
246 .map_err(|err| match err {
247 SendOneShotIpPacketError::CreateAndSendError { err } => err,
248 })
249 }
250}
251
252#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
254pub enum IpSockSendError {
255 #[error("a maximum transmission unit (MTU) was exceeded")]
260 Mtu,
261 #[error("the socket is currently unroutable: {0}")]
263 Unroutable(#[from] ResolveRouteError),
264 #[error("illegal loopback address")]
267 IllegalLoopbackAddress,
268 #[error("broadcast send is not enabled for the socket")]
270 BroadcastNotAllowed,
271}
272
273impl From<SerializeError<Infallible>> for IpSockSendError {
274 fn from(err: SerializeError<Infallible>) -> IpSockSendError {
275 match err {
276 SerializeError::SizeLimitExceeded => IpSockSendError::Mtu,
277 }
278 }
279}
280
281impl IpSockSendError {
282 fn from_ip_send_frame(e: IpSendFrameErrorReason) -> Result<(), Self> {
287 match e {
288 IpSendFrameErrorReason::Device(d) => Self::from_send_frame(d),
289 IpSendFrameErrorReason::IllegalLoopbackAddress => Err(Self::IllegalLoopbackAddress),
290 }
291 }
292
293 fn from_send_frame(e: SendFrameErrorReason) -> Result<(), Self> {
298 match e {
299 SendFrameErrorReason::Alloc | SendFrameErrorReason::QueueFull => Ok(()),
300 SendFrameErrorReason::SizeConstraintsViolation => Err(Self::Mtu),
301 }
302 }
303}
304
305#[derive(Error, Copy, Clone, Debug)]
307pub enum IpSockCreateAndSendError {
308 #[error("cannot send via temporary socket: {0}")]
310 Send(#[from] IpSockSendError),
311 #[error("the temporary socket could not be created: {0}")]
313 Create(#[from] IpSockCreationError),
314}
315
316#[derive(Debug)]
319#[allow(missing_docs)]
320pub enum SendOneShotIpPacketError<E> {
321 CreateAndSendError { err: IpSockCreateAndSendError },
322 SerializeError(E),
323}
324
325#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
327pub enum MmsError {
328 #[error("cannot find the device: {0}")]
331 NoDevice(#[from] ResolveRouteError),
332 #[error("invalid MTU: {0:?}")]
335 MTUTooSmall(Mtu),
336}
337
338pub trait DeviceIpSocketHandler<I: IpExt, BC>: DeviceIdContext<AnyDevice> {
340 fn get_mms<O: RouteResolutionOptions<I>>(
346 &mut self,
347 bindings_ctx: &mut BC,
348 ip_sock: &IpSock<I, Self::WeakDeviceId>,
349 options: &O,
350 ) -> Result<Mms, MmsError>;
351}
352
353#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
355pub enum IpSockCreationError {
356 #[error("a route cannot be determined: {0}")]
358 Route(#[from] ResolveRouteError),
359}
360
361#[derive(Clone, Debug)]
363#[cfg_attr(test, derive(PartialEq))]
364pub struct IpSock<I: IpExt, D> {
365 definition: IpSockDefinition<I, D>,
369}
370
371impl<I: IpExt, D> IpSock<I, D> {
372 #[cfg(any(test, feature = "testutils"))]
374 pub fn definition(&self) -> &IpSockDefinition<I, D> {
375 &self.definition
376 }
377}
378
379#[derive(Clone, Debug, PartialEq)]
383pub struct IpSockDefinition<I: IpExt, D> {
384 pub remote_ip: SocketIpAddr<I::Addr>,
386 pub local_ip: IpDeviceAddr<I::Addr>,
397 pub device: Option<D>,
399 pub proto: I::Proto,
401}
402
403impl<I: IpExt, D> IpSock<I, D> {
404 pub fn local_ip(&self) -> &IpDeviceAddr<I::Addr> {
406 &self.definition.local_ip
407 }
408 pub fn remote_ip(&self) -> &SocketIpAddr<I::Addr> {
410 &self.definition.remote_ip
411 }
412 pub fn device(&self) -> Option<&D> {
414 self.definition.device.as_ref()
415 }
416 pub fn proto(&self) -> I::Proto {
418 self.definition.proto
419 }
420}
421
422pub trait IpSocketBindingsContext<D>:
429 InstantContext
430 + FilterBindingsContext<D>
431 + TxMetadataBindingsTypes
432 + SocketOpsFilterBindingContext<D>
433{
434}
435impl<
436 D,
437 BC: InstantContext
438 + FilterBindingsContext<D>
439 + TxMetadataBindingsTypes
440 + SocketOpsFilterBindingContext<D>,
441> IpSocketBindingsContext<D> for BC
442{
443}
444
445pub trait IpSocketContext<I, BC>:
450 DeviceIdContext<AnyDevice, DeviceId: InterfaceProperties<BC::DeviceClass>>
451 + FilterHandlerProvider<I, BC>
452where
453 I: IpDeviceStateIpExt + IpExt + FilterIpExt,
454 BC: IpSocketBindingsContext<Self::DeviceId>,
455{
456 fn lookup_route(
461 &mut self,
462 bindings_ctx: &mut BC,
463 device: Option<&Self::DeviceId>,
464 src_ip: Option<IpDeviceAddr<I::Addr>>,
465 dst_ip: RoutableIpAddr<I::Addr>,
466 transparent: bool,
467 marks: &Marks,
468 ) -> Result<ResolvedRoute<I, Self::DeviceId>, ResolveRouteError>;
469
470 fn send_ip_packet<S>(
472 &mut self,
473 bindings_ctx: &mut BC,
474 meta: SendIpPacketMeta<I, &Self::DeviceId, SpecifiedAddr<I::Addr>>,
475 body: S,
476 packet_metadata: IpLayerPacketMetadata<I, Self::WeakAddressId, BC>,
477 ) -> Result<(), IpSendFrameError<S>>
478 where
479 S: TransportPacketSerializer<I>,
480 S::Buffer: BufferMut;
481
482 fn get_loopback_device(&mut self) -> Option<Self::DeviceId>;
484
485 fn confirm_reachable(
491 &mut self,
492 bindings_ctx: &mut BC,
493 dst: SpecifiedAddr<I::Addr>,
494 input: RuleInput<'_, I, Self::DeviceId>,
495 );
496}
497
498pub trait UseIpSocketHandlerBlanket {}
503
504impl<I, BC, CC> IpSocketHandler<I, BC> for CC
505where
506 I: IpLayerIpExt + IpDeviceStateIpExt,
507 BC: IpSocketBindingsContext<Self::DeviceId>,
508 CC: IpSocketContext<I, BC> + CounterContext<IpCounters<I>> + UseIpSocketHandlerBlanket,
509 CC::DeviceId: netstack3_base::InterfaceProperties<BC::DeviceClass>,
510{
511 fn new_ip_socket<O>(
512 &mut self,
513 bindings_ctx: &mut BC,
514 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
515 ) -> Result<IpSock<I, CC::WeakDeviceId>, IpSockCreationError>
516 where
517 O: RouteResolutionOptions<I>,
518 {
519 let IpSocketArgs { device, local_ip, remote_ip, proto, options } = args;
520 let device = device
521 .as_ref()
522 .map(|d| d.as_strong_ref().ok_or(ResolveRouteError::Unreachable))
523 .transpose()?;
524 let device = device.as_ref().map(|d| d.as_ref());
525
526 let resolved_route = self.lookup_route(
531 bindings_ctx,
532 device,
533 local_ip,
534 remote_ip,
535 options.transparent(),
536 options.marks(),
537 )?;
538 Ok(new_ip_socket(device, resolved_route, remote_ip, proto))
539 }
540
541 fn send_ip_packet<S, O>(
542 &mut self,
543 bindings_ctx: &mut BC,
544 ip_sock: &IpSock<I, CC::WeakDeviceId>,
545 body: S,
546 options: &O,
547 tx_metadata: BC::TxMetadata,
548 ) -> Result<(), IpSockSendError>
549 where
550 S: TransportPacketSerializer<I>,
551 S::Buffer: BufferMut,
552 O: SendOptions<I> + RouteResolutionOptions<I>,
553 {
554 send_ip_packet(self, bindings_ctx, ip_sock, body, options, tx_metadata)
555 }
556
557 fn confirm_reachable<O>(
558 &mut self,
559 bindings_ctx: &mut BC,
560 socket: &IpSock<I, CC::WeakDeviceId>,
561 options: &O,
562 ) where
563 O: RouteResolutionOptions<I>,
564 {
565 let bound_device = socket.device().and_then(|weak| weak.upgrade());
566 let bound_device = bound_device.as_ref();
567 let bound_address = Some((*socket.local_ip()).into());
568 let destination = (*socket.remote_ip()).into();
569 IpSocketContext::confirm_reachable(
570 self,
571 bindings_ctx,
572 destination,
573 RuleInput {
574 packet_origin: PacketOrigin::Local { bound_address, bound_device },
575 marks: options.marks(),
576 },
577 )
578 }
579}
580
581pub trait RouteResolutionOptions<I: Ip> {
593 fn transparent(&self) -> bool;
598
599 fn marks(&self) -> &Marks;
601}
602
603pub trait SendOptions<I: IpExt> {
611 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8>;
617
618 fn multicast_loop(&self) -> bool;
621
622 fn allow_broadcast(&self) -> Option<I::BroadcastMarker>;
624
625 fn dscp_and_ecn(&self) -> DscpAndEcn;
627
628 fn mtu(&self) -> Mtu;
633}
634
635#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
637pub struct DefaultIpSocketOptions;
638
639impl<I: IpExt> SendOptions<I> for DefaultIpSocketOptions {
640 fn hop_limit(&self, _destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
641 None
642 }
643
644 fn multicast_loop(&self) -> bool {
645 false
646 }
647
648 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
649 None
650 }
651
652 fn dscp_and_ecn(&self) -> DscpAndEcn {
653 DscpAndEcn::default()
654 }
655
656 fn mtu(&self) -> Mtu {
657 Mtu::no_limit()
658 }
659}
660
661impl<I: Ip> RouteResolutionOptions<I> for DefaultIpSocketOptions {
662 fn transparent(&self) -> bool {
663 false
664 }
665
666 fn marks(&self) -> &Marks {
667 &Marks::UNMARKED
668 }
669}
670
671#[allow(missing_docs)]
679pub trait DelegatedSendOptions<I: IpExt>: OptionDelegationMarker {
680 fn delegate(&self) -> &impl SendOptions<I> {
682 &DefaultIpSocketOptions
683 }
684
685 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
686 self.delegate().hop_limit(destination)
687 }
688
689 fn multicast_loop(&self) -> bool {
690 self.delegate().multicast_loop()
691 }
692
693 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
694 self.delegate().allow_broadcast()
695 }
696
697 fn dscp_and_ecn(&self) -> DscpAndEcn {
698 self.delegate().dscp_and_ecn()
699 }
700
701 fn mtu(&self) -> Mtu {
702 self.delegate().mtu()
703 }
704}
705
706impl<O: DelegatedSendOptions<I> + OptionDelegationMarker, I: IpExt> SendOptions<I> for O {
707 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
708 self.hop_limit(destination)
709 }
710
711 fn multicast_loop(&self) -> bool {
712 self.multicast_loop()
713 }
714
715 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
716 self.allow_broadcast()
717 }
718
719 fn dscp_and_ecn(&self) -> DscpAndEcn {
720 self.dscp_and_ecn()
721 }
722
723 fn mtu(&self) -> Mtu {
724 self.mtu()
725 }
726}
727
728#[allow(missing_docs)]
736pub trait DelegatedRouteResolutionOptions<I: Ip>: OptionDelegationMarker {
737 fn delegate(&self) -> &impl RouteResolutionOptions<I> {
739 &DefaultIpSocketOptions
740 }
741
742 fn transparent(&self) -> bool {
743 self.delegate().transparent()
744 }
745
746 fn marks(&self) -> &Marks {
747 self.delegate().marks()
748 }
749}
750
751impl<O: DelegatedRouteResolutionOptions<I> + OptionDelegationMarker, I: IpExt>
752 RouteResolutionOptions<I> for O
753{
754 fn transparent(&self) -> bool {
755 self.transparent()
756 }
757
758 fn marks(&self) -> &Marks {
759 self.marks()
760 }
761}
762
763pub trait OptionDelegationMarker {}
768
769#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
771pub struct SocketHopLimits<I: Ip> {
772 pub unicast: Option<NonZeroU8>,
774 pub multicast: Option<NonZeroU8>,
778 pub version: IpVersionMarker<I>,
782}
783
784impl<I: Ip> SocketHopLimits<I> {
785 pub fn set_unicast(value: Option<NonZeroU8>) -> impl FnOnce(&mut Self) {
787 move |limits| limits.unicast = value
788 }
789
790 pub fn set_multicast(value: Option<NonZeroU8>) -> impl FnOnce(&mut Self) {
792 move |limits| limits.multicast = value
793 }
794
795 pub fn get_limits_with_defaults(&self, defaults: &HopLimits) -> HopLimits {
797 let Self { unicast, multicast, version: _ } = self;
798 HopLimits {
799 unicast: unicast.unwrap_or(defaults.unicast),
800 multicast: multicast.unwrap_or(defaults.multicast),
801 }
802 }
803
804 pub fn hop_limit_for_dst(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
806 let Self { unicast, multicast, version: _ } = self;
807 if destination.is_multicast() { *multicast } else { *unicast }
808 }
809}
810
811fn new_ip_socket<I, D>(
812 requested_device: Option<&D>,
813 route: ResolvedRoute<I, D>,
814 remote_ip: SocketIpAddr<I::Addr>,
815 proto: I::Proto,
816) -> IpSock<I, D::Weak>
817where
818 I: IpExt,
819 D: StrongDeviceIdentifier,
820{
821 let ResolvedRoute {
825 src_addr,
826 device: route_device,
827 local_delivery_device,
828 next_hop: _,
829 internal_forwarding: _,
830 } = route;
831
832 let socket_device = (src_addr.as_ref().must_have_zone() || remote_ip.as_ref().must_have_zone())
835 .then(|| {
836 local_delivery_device.unwrap_or(route_device)
840 })
841 .as_ref()
842 .or(requested_device)
843 .map(|d| d.downgrade());
844
845 let definition =
846 IpSockDefinition { local_ip: src_addr, remote_ip, device: socket_device, proto };
847 IpSock { definition }
848}
849
850fn send_ip_packet<I, S, BC, CC, O>(
851 core_ctx: &mut CC,
852 bindings_ctx: &mut BC,
853 socket: &IpSock<I, CC::WeakDeviceId>,
854 mut body: S,
855 options: &O,
856 tx_metadata: BC::TxMetadata,
857) -> Result<(), IpSockSendError>
858where
859 I: IpExt + IpDeviceStateIpExt + FilterIpExt,
860 S: TransportPacketSerializer<I>,
861 S::Buffer: BufferMut,
862 BC: IpSocketBindingsContext<CC::DeviceId>,
863 CC: IpSocketContext<I, BC> + CounterContext<IpCounters<I>>,
864 CC::DeviceId: netstack3_base::InterfaceProperties<BC::DeviceClass>,
865 O: SendOptions<I> + RouteResolutionOptions<I>,
866{
867 trace_duration!("ip::send_packet");
868
869 fn resolve<
872 I: IpExt + IpDeviceStateIpExt + FilterIpExt,
873 CC: IpSocketContext<I, BC>,
874 BC: IpSocketBindingsContext<CC::DeviceId>,
875 >(
876 core_ctx: &mut CC,
877 bindings_ctx: &mut BC,
878 device: &Option<CC::WeakDeviceId>,
879 local_ip: IpDeviceAddr<I::Addr>,
880 remote_ip: RoutableIpAddr<I::Addr>,
881 transparent: bool,
882 marks: &Marks,
883 ) -> Result<ResolvedRoute<I, CC::DeviceId>, IpSockSendError> {
884 let device = match device.as_ref().map(|d| d.upgrade()) {
885 Some(Some(device)) => Some(device),
886 Some(None) => return Err(ResolveRouteError::Unreachable.into()),
887 None => None,
888 };
889 let route = core_ctx
890 .lookup_route(
891 bindings_ctx,
892 device.as_ref(),
893 Some(local_ip),
894 remote_ip,
895 transparent,
896 marks,
897 )
898 .map_err(|e| IpSockSendError::Unroutable(e))?;
899 assert_eq!(local_ip, route.src_addr);
900 Ok(route)
901 }
902
903 let IpSock {
904 definition: IpSockDefinition { remote_ip, local_ip, device: socket_device, proto },
905 } = socket;
906 let ResolvedRoute {
907 src_addr: local_ip,
908 device: mut egress_device,
909 mut next_hop,
910 mut local_delivery_device,
911 mut internal_forwarding,
912 } = resolve(
913 core_ctx,
914 bindings_ctx,
915 socket_device,
916 *local_ip,
917 *remote_ip,
918 options.transparent(),
919 options.marks(),
920 )?;
921
922 if matches!(next_hop, NextHop::Broadcast(_)) && options.allow_broadcast().is_none() {
923 return Err(IpSockSendError::BroadcastNotAllowed);
924 }
925
926 let previous_dst = remote_ip.addr();
927 let mut packet = filter::TxPacket::new(local_ip.addr(), remote_ip.addr(), *proto, &mut body);
928 let mut packet_metadata =
929 IpLayerPacketMetadata::from_tx_metadata_and_marks(tx_metadata, *options.marks());
930
931 match core_ctx.filter_handler().local_egress_hook(
932 bindings_ctx,
933 &mut packet,
934 &egress_device,
935 &mut packet_metadata,
936 ) {
937 filter::Verdict::Stop(filter::DropOrReject::Drop) => {
938 packet_metadata.acknowledge_drop();
939 return Ok(());
940 }
941 filter::Verdict::Stop(filter::DropOrReject::Reject(_reject_type)) => {
942 packet_metadata.acknowledge_drop();
944 return Ok(());
945 }
946 filter::Verdict::Proceed(filter::Accept) => {}
947 }
948
949 let Some(mut local_ip) = IpDeviceAddr::new(packet.src_addr()) else {
950 packet_metadata.acknowledge_drop();
951 return Err(IpSockSendError::Unroutable(ResolveRouteError::NoSrcAddr));
952 };
953 let Some(remote_ip) = RoutableIpAddr::new(packet.dst_addr()) else {
954 packet_metadata.acknowledge_drop();
955 return Err(IpSockSendError::Unroutable(ResolveRouteError::Unreachable));
956 };
957
958 if remote_ip.addr() != previous_dst {
961 let ResolvedRoute {
962 src_addr: new_local_ip,
963 device: new_device,
964 next_hop: new_next_hop,
965 local_delivery_device: new_local_delivery_device,
966 internal_forwarding: new_internal_forwarding,
967 } = match resolve(
968 core_ctx,
969 bindings_ctx,
970 socket_device,
971 local_ip,
972 remote_ip,
973 options.transparent(),
974 options.marks(),
975 ) {
976 Ok(r) => r,
977 Err(err) => {
978 packet_metadata.acknowledge_drop();
979 return Err(err);
980 }
981 };
982 local_ip = new_local_ip;
983 egress_device = new_device;
984 next_hop = new_next_hop;
985 local_delivery_device = new_local_delivery_device;
986 internal_forwarding = new_internal_forwarding;
987 }
988
989 match internal_forwarding {
991 InternalForwarding::Used(ingress_device) => {
992 match core_ctx.filter_handler().forwarding_hook(
993 &mut packet,
994 &ingress_device,
995 &egress_device,
996 &mut packet_metadata,
997 ) {
998 filter::Verdict::Stop(filter::DropOrReject::Drop) => {
999 packet_metadata.acknowledge_drop();
1000 return Ok(());
1001 }
1002 filter::Verdict::Stop(filter::DropOrReject::Reject(_reject_type)) => {
1003 packet_metadata.acknowledge_drop();
1005 return Ok(());
1006 }
1007 filter::Verdict::Proceed(filter::Accept) => {}
1008 }
1009 }
1010 InternalForwarding::NotUsed => {}
1011 }
1012
1013 if let Some(socket_cookie) = packet_metadata.tx_metadata().socket_cookie() {
1014 let egress_filter_result = bindings_ctx.socket_ops_filter().on_egress(
1015 &packet,
1016 &egress_device,
1017 socket_cookie,
1018 packet_metadata.marks(),
1019 );
1020
1021 match egress_filter_result {
1023 SocketEgressFilterResult::Pass { congestion: _ } => (),
1024 SocketEgressFilterResult::Drop { congestion: _ } => {
1025 core_ctx.counters().socket_egress_filter_dropped.increment();
1026 packet_metadata.acknowledge_drop();
1027 return Ok(());
1028 }
1029 }
1030 }
1031
1032 let loopback_packet = (!egress_device.is_loopback()
1037 && ((options.multicast_loop() && remote_ip.addr().is_multicast())
1038 || next_hop.is_broadcast()))
1039 .then(|| body.serialize_new_buf(PacketConstraints::UNCONSTRAINED, packet::new_buf_vec))
1040 .transpose()?
1041 .map(|buf| RawIpBody::new(*proto, local_ip.addr(), remote_ip.addr(), buf));
1042
1043 let destination = match &local_delivery_device {
1044 Some(d) => IpPacketDestination::Loopback(d),
1045 None => IpPacketDestination::from_next_hop(next_hop, remote_ip.into()),
1046 };
1047 let ttl = options.hop_limit(&remote_ip.into());
1048 let meta = SendIpPacketMeta {
1049 device: &egress_device,
1050 src_ip: local_ip.into(),
1051 dst_ip: remote_ip.into(),
1052 destination,
1053 ttl,
1054 proto: *proto,
1055 mtu: options.mtu(),
1056 dscp_and_ecn: options.dscp_and_ecn(),
1057 };
1058 IpSocketContext::send_ip_packet(core_ctx, bindings_ctx, meta, body, packet_metadata).or_else(
1059 |IpSendFrameError { serializer: _, error }| IpSockSendError::from_ip_send_frame(error),
1060 )?;
1061
1062 match (loopback_packet, core_ctx.get_loopback_device()) {
1063 (Some(loopback_packet), Some(loopback_device)) => {
1064 let meta = SendIpPacketMeta {
1065 device: &loopback_device,
1066 src_ip: local_ip.into(),
1067 dst_ip: remote_ip.into(),
1068 destination: IpPacketDestination::Loopback(&egress_device),
1069 ttl,
1070 proto: *proto,
1071 mtu: options.mtu(),
1072 dscp_and_ecn: options.dscp_and_ecn(),
1073 };
1074 let packet_metadata = IpLayerPacketMetadata::default();
1075
1076 IpSocketContext::send_ip_packet(
1079 core_ctx,
1080 bindings_ctx,
1081 meta,
1082 loopback_packet,
1083 packet_metadata,
1084 )
1085 .unwrap_or_else(|IpSendFrameError { serializer: _, error }| {
1086 error!("failed to send loopback packet: {error:?}")
1087 });
1088 }
1089 (Some(_loopback_packet), None) => {
1090 error!("can't send a loopback packet without the loopback device")
1091 }
1092 _ => (),
1093 }
1094
1095 Ok(())
1096}
1097
1098pub trait UseDeviceIpSocketHandlerBlanket {}
1103
1104impl<I, BC, CC> DeviceIpSocketHandler<I, BC> for CC
1105where
1106 I: IpLayerIpExt + IpDeviceStateIpExt,
1107 BC: IpSocketBindingsContext<CC::DeviceId>,
1108 CC: IpDeviceMtuContext<I> + IpSocketContext<I, BC> + UseDeviceIpSocketHandlerBlanket,
1109{
1110 fn get_mms<O: RouteResolutionOptions<I>>(
1111 &mut self,
1112 bindings_ctx: &mut BC,
1113 ip_sock: &IpSock<I, Self::WeakDeviceId>,
1114 options: &O,
1115 ) -> Result<Mms, MmsError> {
1116 let IpSockDefinition { remote_ip, local_ip, device, proto: _ } = &ip_sock.definition;
1117 let device = device
1118 .as_ref()
1119 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
1120 .transpose()?;
1121
1122 let ResolvedRoute {
1123 src_addr: _,
1124 local_delivery_device: _,
1125 device,
1126 next_hop: _,
1127 internal_forwarding: _,
1128 } = self
1129 .lookup_route(
1130 bindings_ctx,
1131 device.as_ref(),
1132 Some(*local_ip),
1133 *remote_ip,
1134 options.transparent(),
1135 options.marks(),
1136 )
1137 .map_err(MmsError::NoDevice)?;
1138 let mtu = self.get_mtu(&device);
1139 Mms::from_mtu::<I>(mtu, 0 ).ok_or(MmsError::MTUTooSmall(mtu))
1142 }
1143}
1144
1145pub(crate) mod ipv6_source_address_selection {
1147 use net_types::ip::{AddrSubnet, IpAddress as _};
1148
1149 use super::*;
1150
1151 use netstack3_base::Ipv6DeviceAddr;
1152
1153 pub struct SasCandidate<D> {
1155 pub addr_sub: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1157 pub assigned: bool,
1159 pub deprecated: bool,
1161 pub temporary: bool,
1163 pub device: D,
1165 }
1166
1167 pub fn select_ipv6_source_address<
1180 'a,
1181 D: PartialEq,
1182 A,
1183 I: Iterator<Item = A>,
1184 F: FnMut(&A) -> SasCandidate<D>,
1185 >(
1186 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1187 outbound_device: &D,
1188 addresses: I,
1189 mut get_candidate: F,
1190 ) -> Option<A> {
1191 addresses
1203 .map(|item| {
1204 let candidate = get_candidate(&item);
1205 (item, candidate)
1206 })
1207 .filter(|(_, candidate)| candidate.assigned)
1210 .max_by(|(_, a), (_, b)| {
1211 select_ipv6_source_address_cmp(remote_ip, outbound_device, a, b)
1212 })
1213 .map(|(item, _candidate)| item)
1214 }
1215
1216 fn select_ipv6_source_address_cmp<D: PartialEq>(
1218 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1219 outbound_device: &D,
1220 a: &SasCandidate<D>,
1221 b: &SasCandidate<D>,
1222 ) -> Ordering {
1223 let SasCandidate {
1225 addr_sub: a_addr_sub,
1226 assigned: a_assigned,
1227 deprecated: a_deprecated,
1228 temporary: a_temporary,
1229 device: a_device,
1230 } = a;
1231 let SasCandidate {
1232 addr_sub: b_addr_sub,
1233 assigned: b_assigned,
1234 deprecated: b_deprecated,
1235 temporary: b_temporary,
1236 device: b_device,
1237 } = b;
1238
1239 let a_addr = a_addr_sub.addr().into_specified();
1240 let b_addr = b_addr_sub.addr().into_specified();
1241
1242 if let Some(remote_ip) = remote_ip {
1246 debug_assert!(!(a_addr == remote_ip && b_addr == remote_ip));
1247 }
1248
1249 debug_assert!(a_assigned);
1252 debug_assert!(b_assigned);
1253
1254 rule_1(remote_ip, a_addr, b_addr)
1255 .then_with(|| rule_2(remote_ip, a_addr, b_addr))
1256 .then_with(|| rule_3(*a_deprecated, *b_deprecated))
1257 .then_with(|| rule_5(outbound_device, a_device, b_device))
1258 .then_with(|| rule_7(*a_temporary, *b_temporary))
1259 .then_with(|| rule_8(remote_ip, *a_addr_sub, *b_addr_sub))
1260 }
1261
1262 fn rule_1(
1264 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1265 a: SpecifiedAddr<Ipv6Addr>,
1266 b: SpecifiedAddr<Ipv6Addr>,
1267 ) -> Ordering {
1268 let remote_ip = match remote_ip {
1269 Some(remote_ip) => remote_ip,
1270 None => return Ordering::Equal,
1271 };
1272 if (a == remote_ip) != (b == remote_ip) {
1273 if a == remote_ip { Ordering::Greater } else { Ordering::Less }
1285 } else {
1286 Ordering::Equal
1287 }
1288 }
1289
1290 fn rule_2(
1291 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1292 a: SpecifiedAddr<Ipv6Addr>,
1293 b: SpecifiedAddr<Ipv6Addr>,
1294 ) -> Ordering {
1295 let remote_scope = match remote_ip {
1298 Some(remote_ip) => remote_ip.scope().multicast_scope_id(),
1299 None => return Ordering::Equal,
1300 };
1301 let a_scope = a.scope().multicast_scope_id();
1302 let b_scope = b.scope().multicast_scope_id();
1303 if a_scope < b_scope {
1304 if a_scope < remote_scope { Ordering::Less } else { Ordering::Greater }
1305 } else if a_scope > b_scope {
1306 if b_scope < remote_scope { Ordering::Greater } else { Ordering::Less }
1307 } else {
1308 Ordering::Equal
1309 }
1310 }
1311
1312 fn rule_3(a_deprecated: bool, b_deprecated: bool) -> Ordering {
1313 match (a_deprecated, b_deprecated) {
1314 (true, false) => Ordering::Less,
1315 (true, true) | (false, false) => Ordering::Equal,
1316 (false, true) => Ordering::Greater,
1317 }
1318 }
1319
1320 fn rule_5<D: PartialEq>(outbound_device: &D, a_device: &D, b_device: &D) -> Ordering {
1321 if (a_device == outbound_device) != (b_device == outbound_device) {
1322 if a_device == outbound_device { Ordering::Greater } else { Ordering::Less }
1324 } else {
1325 Ordering::Equal
1326 }
1327 }
1328
1329 fn rule_7(a_temporary: bool, b_temporary: bool) -> Ordering {
1331 match (a_temporary, b_temporary) {
1332 (true, false) => Ordering::Greater,
1333 (true, true) | (false, false) => Ordering::Equal,
1334 (false, true) => Ordering::Less,
1335 }
1336 }
1337
1338 fn rule_8(
1339 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1340 a: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1341 b: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1342 ) -> Ordering {
1343 let remote_ip = match remote_ip {
1344 Some(remote_ip) => remote_ip,
1345 None => return Ordering::Equal,
1346 };
1347 fn common_prefix_len(
1357 src: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1358 dst: SpecifiedAddr<Ipv6Addr>,
1359 ) -> u8 {
1360 core::cmp::min(src.addr().common_prefix_len(&dst), src.subnet().prefix())
1361 }
1362
1363 common_prefix_len(a, remote_ip).cmp(&common_prefix_len(b, remote_ip))
1375 }
1376
1377 #[cfg(test)]
1378 mod tests {
1379 use net_declare::net_ip_v6;
1380
1381 use super::*;
1382
1383 #[test]
1384 fn test_select_ipv6_source_address() {
1385 let remote = SpecifiedAddr::new(net_ip_v6!("2001:0db8:1::")).unwrap();
1389 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1390 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1391 let link_local_remote = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:42")).unwrap();
1392 let link_local = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:4")).unwrap();
1393 let dev0 = &0;
1394 let dev1 = &1;
1395 let dev2 = &2;
1396
1397 assert_eq!(rule_1(Some(remote), remote, local0), Ordering::Greater);
1399 assert_eq!(rule_1(Some(remote), local0, remote), Ordering::Less);
1400 assert_eq!(rule_1(Some(remote), local0, local1), Ordering::Equal);
1401 assert_eq!(rule_1(None, local0, local1), Ordering::Equal);
1402
1403 assert_eq!(rule_2(Some(remote), local0, local1), Ordering::Equal);
1405 assert_eq!(rule_2(Some(remote), local1, local0), Ordering::Equal);
1406 assert_eq!(rule_2(Some(remote), local0, link_local), Ordering::Greater);
1407 assert_eq!(rule_2(Some(remote), link_local, local0), Ordering::Less);
1408 assert_eq!(rule_2(Some(link_local_remote), local0, link_local), Ordering::Less);
1409 assert_eq!(rule_2(Some(link_local_remote), link_local, local0), Ordering::Greater);
1410 assert_eq!(rule_1(None, local0, link_local), Ordering::Equal);
1411
1412 assert_eq!(rule_3(false, true), Ordering::Greater);
1414 assert_eq!(rule_3(true, false), Ordering::Less);
1415 assert_eq!(rule_3(true, true), Ordering::Equal);
1416 assert_eq!(rule_3(false, false), Ordering::Equal);
1417
1418 assert_eq!(rule_5(dev0, dev0, dev2), Ordering::Greater);
1420 assert_eq!(rule_5(dev0, dev2, dev0), Ordering::Less);
1421 assert_eq!(rule_5(dev0, dev0, dev0), Ordering::Equal);
1422 assert_eq!(rule_5(dev0, dev2, dev2), Ordering::Equal);
1423
1424 assert_eq!(rule_7(true, false), Ordering::Greater);
1426 assert_eq!(rule_7(false, true), Ordering::Less);
1427 assert_eq!(rule_7(true, true), Ordering::Equal);
1428 assert_eq!(rule_7(false, false), Ordering::Equal);
1429
1430 {
1432 let new_addr_entry = |addr, prefix_len| AddrSubnet::new(addr, prefix_len).unwrap();
1433
1434 let remote = SpecifiedAddr::new(net_ip_v6!("1111::")).unwrap();
1440 let local0 = new_addr_entry(net_ip_v6!("1110::"), 64);
1442 let local1 = new_addr_entry(net_ip_v6!("1100::"), 64);
1444
1445 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Greater);
1446 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Less);
1447 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1448 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1449 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1450
1451 let local0 = new_addr_entry(net_ip_v6!("1110::"), 8);
1456 let local1 = new_addr_entry(net_ip_v6!("1100::"), 8);
1458
1459 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Equal);
1460 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Equal);
1461 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1462 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1463 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1464 }
1465
1466 {
1467 let new_addr_entry = |addr, device| SasCandidate {
1468 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1469 deprecated: false,
1470 assigned: true,
1471 temporary: false,
1472 device,
1473 };
1474
1475 assert_eq!(
1477 select_ipv6_source_address_cmp(
1478 Some(remote),
1479 dev0,
1480 &new_addr_entry(*local0, *dev1),
1481 &new_addr_entry(*local1, *dev2),
1482 ),
1483 Ordering::Equal
1484 );
1485 }
1486 }
1487
1488 #[test]
1489 fn test_select_ipv6_source_address_no_remote() {
1490 let dev0 = &0;
1493 let dev1 = &1;
1494 let dev2 = &2;
1495
1496 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1497 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1498
1499 let new_addr_entry = |addr, deprecated, device| SasCandidate {
1500 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1501 deprecated,
1502 assigned: true,
1503 temporary: false,
1504 device,
1505 };
1506
1507 assert_eq!(
1509 select_ipv6_source_address_cmp(
1510 None,
1511 dev0,
1512 &new_addr_entry(*local0, false, *dev1),
1513 &new_addr_entry(*local1, true, *dev2),
1514 ),
1515 Ordering::Greater
1516 );
1517
1518 assert_eq!(
1520 select_ipv6_source_address_cmp(
1521 None,
1522 dev0,
1523 &new_addr_entry(*local0, false, *dev0),
1524 &new_addr_entry(*local1, false, *dev1),
1525 ),
1526 Ordering::Greater
1527 );
1528 }
1529 }
1530}
1531
1532#[cfg(any(test, feature = "testutils"))]
1534pub(crate) mod testutil {
1535 use alloc::boxed::Box;
1536 use alloc::vec::Vec;
1537 use core::num::NonZeroUsize;
1538
1539 use derivative::Derivative;
1540 use net_types::ip::{GenericOverIp, IpAddr, IpAddress, Ipv4, Ipv4Addr, Ipv6, Subnet};
1541 use net_types::{MulticastAddr, Witness as _};
1542 use netstack3_base::testutil::{FakeCoreCtx, FakeStrongDeviceId, FakeWeakDeviceId};
1543 use netstack3_base::{SendFrameContext, SendFrameError};
1544 use netstack3_filter::Tuple;
1545 use netstack3_hashmap::HashMap;
1546
1547 use super::*;
1548 use crate::internal::base::{
1549 BaseTransportIpContext, DEFAULT_HOP_LIMITS, HopLimits, MulticastMembershipHandler,
1550 };
1551 use crate::internal::routing::testutil::FakeIpRoutingCtx;
1552 use crate::internal::routing::{self, RoutingTable};
1553 use crate::internal::types::{Destination, Entry, Metric, RawMetric};
1554
1555 #[derive(Derivative, GenericOverIp)]
1558 #[generic_over_ip(I, Ip)]
1559 #[derivative(Default(bound = ""))]
1560 pub struct FakeIpSocketCtx<I: Ip, D> {
1561 pub(crate) table: RoutingTable<I, D>,
1562 forwarding: FakeIpRoutingCtx<D>,
1563 devices: HashMap<D, FakeDeviceState<I>>,
1564 }
1565
1566 pub trait InnerFakeIpSocketCtx<I: Ip, D> {
1569 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D>;
1571 }
1572
1573 impl<I: Ip, D> InnerFakeIpSocketCtx<I, D> for FakeIpSocketCtx<I, D> {
1574 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1575 self
1576 }
1577 }
1578
1579 impl<I: IpExt, D: FakeStrongDeviceId, BC> BaseTransportIpContext<I, BC> for FakeIpSocketCtx<I, D> {
1580 fn get_default_hop_limits(&mut self, device: Option<&D>) -> HopLimits {
1581 device.map_or(DEFAULT_HOP_LIMITS, |device| {
1582 let hop_limit = self.get_device_state(device).default_hop_limit;
1583 HopLimits { unicast: hop_limit, multicast: DEFAULT_HOP_LIMITS.multicast }
1584 })
1585 }
1586
1587 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1588
1589 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1590 &mut self,
1591 addr: SpecifiedAddr<I::Addr>,
1592 cb: F,
1593 ) -> O {
1594 cb(Box::new(self.devices.iter().filter_map(move |(device, state)| {
1595 state.addresses.contains(&addr).then(|| device.clone())
1596 })))
1597 }
1598
1599 fn get_original_destination(&mut self, _tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1600 unimplemented!()
1601 }
1602 }
1603
1604 impl<I: IpExt, D: FakeStrongDeviceId> DeviceIdContext<AnyDevice> for FakeIpSocketCtx<I, D> {
1605 type DeviceId = D;
1606 type WeakDeviceId = D::Weak;
1607 }
1608
1609 impl<I, State, D, Meta, BC> IpSocketHandler<I, BC> for FakeCoreCtx<State, Meta, D>
1610 where
1611 I: IpExt + FilterIpExt,
1612 State: InnerFakeIpSocketCtx<I, D>,
1613 D: FakeStrongDeviceId,
1614 BC: TxMetadataBindingsTypes,
1615 FakeCoreCtx<State, Meta, D>:
1616 SendFrameContext<BC, SendIpPacketMeta<I, Self::DeviceId, SpecifiedAddr<I::Addr>>>,
1617 {
1618 fn new_ip_socket<O>(
1619 &mut self,
1620 _bindings_ctx: &mut BC,
1621 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
1622 ) -> Result<IpSock<I, Self::WeakDeviceId>, IpSockCreationError>
1623 where
1624 O: RouteResolutionOptions<I>,
1625 {
1626 self.state.fake_ip_socket_ctx_mut().new_ip_socket(args)
1627 }
1628
1629 fn send_ip_packet<S, O>(
1630 &mut self,
1631 bindings_ctx: &mut BC,
1632 socket: &IpSock<I, Self::WeakDeviceId>,
1633 body: S,
1634 options: &O,
1635 _tx_meta: BC::TxMetadata,
1638 ) -> Result<(), IpSockSendError>
1639 where
1640 S: TransportPacketSerializer<I>,
1641 S::Buffer: BufferMut,
1642 O: SendOptions<I> + RouteResolutionOptions<I>,
1643 {
1644 let meta = self.state.fake_ip_socket_ctx_mut().resolve_send_meta(socket, options)?;
1645 self.send_frame(bindings_ctx, meta, body).or_else(
1646 |SendFrameError { serializer: _, error }| IpSockSendError::from_send_frame(error),
1647 )
1648 }
1649
1650 fn confirm_reachable<O>(
1651 &mut self,
1652 _bindings_ctx: &mut BC,
1653 _socket: &IpSock<I, Self::WeakDeviceId>,
1654 _options: &O,
1655 ) {
1656 }
1657 }
1658
1659 impl<I: IpExt, D: FakeStrongDeviceId, BC> MulticastMembershipHandler<I, BC>
1660 for FakeIpSocketCtx<I, D>
1661 {
1662 fn join_multicast_group(
1663 &mut self,
1664 _bindings_ctx: &mut BC,
1665 device: &Self::DeviceId,
1666 addr: MulticastAddr<<I as Ip>::Addr>,
1667 ) {
1668 let value = self.get_device_state_mut(device).multicast_groups.entry(addr).or_insert(0);
1669 *value = value.checked_add(1).unwrap();
1670 }
1671
1672 fn leave_multicast_group(
1673 &mut self,
1674 _bindings_ctx: &mut BC,
1675 device: &Self::DeviceId,
1676 addr: MulticastAddr<<I as Ip>::Addr>,
1677 ) {
1678 let value = self
1679 .get_device_state_mut(device)
1680 .multicast_groups
1681 .get_mut(&addr)
1682 .unwrap_or_else(|| panic!("no entry for {addr} on {device:?}"));
1683 *value = value.checked_sub(1).unwrap();
1684 }
1685
1686 fn select_device_for_multicast_group(
1687 &mut self,
1688 addr: MulticastAddr<<I as Ip>::Addr>,
1689 _marks: &Marks,
1690 ) -> Result<Self::DeviceId, ResolveRouteError> {
1691 let remote_ip = SocketIpAddr::new_from_multicast(addr);
1692 self.lookup_route(None, None, remote_ip, false)
1693 .map(|ResolvedRoute { device, .. }| device)
1694 }
1695 }
1696
1697 impl<I, BC, D, State, Meta> BaseTransportIpContext<I, BC> for FakeCoreCtx<State, Meta, D>
1698 where
1699 I: IpExt + FilterIpExt,
1700 D: FakeStrongDeviceId,
1701 State: InnerFakeIpSocketCtx<I, D>,
1702 BC: TxMetadataBindingsTypes,
1703 Self: IpSocketHandler<I, BC, DeviceId = D, WeakDeviceId = FakeWeakDeviceId<D>>,
1704 {
1705 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1706
1707 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1708 &mut self,
1709 addr: SpecifiedAddr<I::Addr>,
1710 cb: F,
1711 ) -> O {
1712 BaseTransportIpContext::<I, BC>::with_devices_with_assigned_addr(
1713 self.state.fake_ip_socket_ctx_mut(),
1714 addr,
1715 cb,
1716 )
1717 }
1718
1719 fn get_default_hop_limits(&mut self, device: Option<&Self::DeviceId>) -> HopLimits {
1720 BaseTransportIpContext::<I, BC>::get_default_hop_limits(
1721 self.state.fake_ip_socket_ctx_mut(),
1722 device,
1723 )
1724 }
1725
1726 fn get_original_destination(&mut self, tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1727 BaseTransportIpContext::<I, BC>::get_original_destination(
1728 self.state.fake_ip_socket_ctx_mut(),
1729 tuple,
1730 )
1731 }
1732 }
1733
1734 #[derive(Derivative)]
1736 #[derivative(Default(bound = ""))]
1737 pub struct FakeDualStackIpSocketCtx<D> {
1738 v4: FakeIpSocketCtx<Ipv4, D>,
1739 v6: FakeIpSocketCtx<Ipv6, D>,
1740 }
1741
1742 impl<D: FakeStrongDeviceId> FakeDualStackIpSocketCtx<D> {
1743 pub fn new<A: Into<SpecifiedAddr<IpAddr>>>(
1745 devices: impl IntoIterator<Item = FakeDeviceConfig<D, A>>,
1746 ) -> Self {
1747 let partition =
1748 |v: Vec<A>| -> (Vec<SpecifiedAddr<Ipv4Addr>>, Vec<SpecifiedAddr<Ipv6Addr>>) {
1749 v.into_iter().fold((Vec::new(), Vec::new()), |(mut v4, mut v6), i| {
1750 match IpAddr::from(i.into()) {
1751 IpAddr::V4(a) => v4.push(a),
1752 IpAddr::V6(a) => v6.push(a),
1753 }
1754 (v4, v6)
1755 })
1756 };
1757
1758 let (v4, v6): (Vec<_>, Vec<_>) = devices
1759 .into_iter()
1760 .map(|FakeDeviceConfig { device, local_ips, remote_ips }| {
1761 let (local_v4, local_v6) = partition(local_ips);
1762 let (remote_v4, remote_v6) = partition(remote_ips);
1763 (
1764 FakeDeviceConfig {
1765 device: device.clone(),
1766 local_ips: local_v4,
1767 remote_ips: remote_v4,
1768 },
1769 FakeDeviceConfig { device, local_ips: local_v6, remote_ips: remote_v6 },
1770 )
1771 })
1772 .unzip();
1773 Self { v4: FakeIpSocketCtx::new(v4), v6: FakeIpSocketCtx::new(v6) }
1774 }
1775
1776 pub fn inner_mut<I: Ip>(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1778 I::map_ip_out(self, |s| &mut s.v4, |s| &mut s.v6)
1779 }
1780
1781 fn inner<I: Ip>(&self) -> &FakeIpSocketCtx<I, D> {
1782 I::map_ip_out(self, |s| &s.v4, |s| &s.v6)
1783 }
1784
1785 pub fn add_route(&mut self, device: D, ip: SpecifiedAddr<IpAddr>) {
1787 match IpAddr::from(ip) {
1788 IpAddr::V4(ip) => {
1789 routing::testutil::add_on_link_routing_entry(&mut self.v4.table, ip, device)
1790 }
1791 IpAddr::V6(ip) => {
1792 routing::testutil::add_on_link_routing_entry(&mut self.v6.table, ip, device)
1793 }
1794 }
1795 }
1796
1797 pub fn add_subnet_route<A: IpAddress>(&mut self, device: D, subnet: Subnet<A>) {
1799 let entry = Entry {
1800 subnet,
1801 device,
1802 gateway: None,
1803 metric: Metric::ExplicitMetric(RawMetric(0)),
1804 };
1805 A::Version::map_ip::<_, ()>(
1806 entry,
1807 |entry_v4| {
1808 let _ = routing::testutil::add_entry(&mut self.v4.table, entry_v4)
1809 .expect("Failed to add route");
1810 },
1811 |entry_v6| {
1812 let _ = routing::testutil::add_entry(&mut self.v6.table, entry_v6)
1813 .expect("Failed to add route");
1814 },
1815 );
1816 }
1817
1818 pub fn get_device_state_mut<I: IpExt>(&mut self, device: &D) -> &mut FakeDeviceState<I> {
1820 self.inner_mut::<I>().get_device_state_mut(device)
1821 }
1822
1823 pub fn multicast_memberships<I: IpExt>(
1825 &self,
1826 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
1827 self.inner::<I>().multicast_memberships()
1828 }
1829 }
1830
1831 impl<I: IpExt, S: InnerFakeIpSocketCtx<I, D>, Meta, D: FakeStrongDeviceId, BC>
1832 MulticastMembershipHandler<I, BC> for FakeCoreCtx<S, Meta, D>
1833 {
1834 fn join_multicast_group(
1835 &mut self,
1836 bindings_ctx: &mut BC,
1837 device: &Self::DeviceId,
1838 addr: MulticastAddr<<I as Ip>::Addr>,
1839 ) {
1840 MulticastMembershipHandler::<I, BC>::join_multicast_group(
1841 self.state.fake_ip_socket_ctx_mut(),
1842 bindings_ctx,
1843 device,
1844 addr,
1845 )
1846 }
1847
1848 fn leave_multicast_group(
1849 &mut self,
1850 bindings_ctx: &mut BC,
1851 device: &Self::DeviceId,
1852 addr: MulticastAddr<<I as Ip>::Addr>,
1853 ) {
1854 MulticastMembershipHandler::<I, BC>::leave_multicast_group(
1855 self.state.fake_ip_socket_ctx_mut(),
1856 bindings_ctx,
1857 device,
1858 addr,
1859 )
1860 }
1861
1862 fn select_device_for_multicast_group(
1863 &mut self,
1864 addr: MulticastAddr<<I as Ip>::Addr>,
1865 marks: &Marks,
1866 ) -> Result<Self::DeviceId, ResolveRouteError> {
1867 MulticastMembershipHandler::<I, BC>::select_device_for_multicast_group(
1868 self.state.fake_ip_socket_ctx_mut(),
1869 addr,
1870 marks,
1871 )
1872 }
1873 }
1874
1875 impl<I: Ip, D, State: InnerFakeIpSocketCtx<I, D>, Meta> InnerFakeIpSocketCtx<I, D>
1876 for FakeCoreCtx<State, Meta, D>
1877 {
1878 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1879 self.state.fake_ip_socket_ctx_mut()
1880 }
1881 }
1882
1883 impl<I: Ip, D: FakeStrongDeviceId> InnerFakeIpSocketCtx<I, D> for FakeDualStackIpSocketCtx<D> {
1884 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1885 self.inner_mut::<I>()
1886 }
1887 }
1888
1889 #[derive(Clone, GenericOverIp)]
1891 #[generic_over_ip()]
1892 pub struct FakeDeviceConfig<D, A> {
1893 pub device: D,
1895 pub local_ips: Vec<A>,
1897 pub remote_ips: Vec<A>,
1899 }
1900
1901 pub struct FakeDeviceState<I: Ip> {
1903 pub default_hop_limit: NonZeroU8,
1905 pub addresses: Vec<SpecifiedAddr<I::Addr>>,
1907 pub multicast_groups: HashMap<MulticastAddr<I::Addr>, usize>,
1909 }
1910
1911 impl<I: Ip> FakeDeviceState<I> {
1912 pub fn is_in_multicast_group(&self, addr: &MulticastAddr<I::Addr>) -> bool {
1914 self.multicast_groups.get(addr).is_some_and(|v| *v != 0)
1915 }
1916 }
1917
1918 impl<I: IpExt, D: FakeStrongDeviceId> FakeIpSocketCtx<I, D> {
1919 pub fn new(
1922 device_configs: impl IntoIterator<Item = FakeDeviceConfig<D, SpecifiedAddr<I::Addr>>>,
1923 ) -> Self {
1924 let mut table = RoutingTable::default();
1925 let mut devices = HashMap::default();
1926 for FakeDeviceConfig { device, local_ips, remote_ips } in device_configs {
1927 for addr in remote_ips {
1928 routing::testutil::add_on_link_routing_entry(&mut table, addr, device.clone())
1929 }
1930 let state = FakeDeviceState {
1931 default_hop_limit: DEFAULT_HOP_LIMITS.unicast,
1932 addresses: local_ips,
1933 multicast_groups: Default::default(),
1934 };
1935 assert!(
1936 devices.insert(device.clone(), state).is_none(),
1937 "duplicate entries for {device:?}",
1938 );
1939 }
1940
1941 Self { table, devices, forwarding: Default::default() }
1942 }
1943
1944 pub fn get_device_state(&self, device: &D) -> &FakeDeviceState<I> {
1946 self.devices.get(device).unwrap_or_else(|| panic!("no device {device:?}"))
1947 }
1948
1949 pub fn get_device_state_mut(&mut self, device: &D) -> &mut FakeDeviceState<I> {
1951 self.devices.get_mut(device).unwrap_or_else(|| panic!("no device {device:?}"))
1952 }
1953
1954 pub(crate) fn multicast_memberships(
1955 &self,
1956 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
1957 self.devices
1958 .iter()
1959 .map(|(device, state)| {
1960 state.multicast_groups.iter().filter_map(|(group, count)| {
1961 NonZeroUsize::new(*count).map(|count| ((device.clone(), *group), count))
1962 })
1963 })
1964 .flatten()
1965 .collect()
1966 }
1967
1968 fn new_ip_socket<O>(
1969 &mut self,
1970 args: IpSocketArgs<'_, D, I, O>,
1971 ) -> Result<IpSock<I, D::Weak>, IpSockCreationError>
1972 where
1973 O: RouteResolutionOptions<I>,
1974 {
1975 let IpSocketArgs { device, local_ip, remote_ip, proto, options } = args;
1976 let device = device
1977 .as_ref()
1978 .map(|d| d.as_strong_ref().ok_or(ResolveRouteError::Unreachable))
1979 .transpose()?;
1980 let device = device.as_ref().map(|d| d.as_ref());
1981 let resolved_route =
1982 self.lookup_route(device, local_ip, remote_ip, options.transparent())?;
1983 Ok(new_ip_socket(device, resolved_route, remote_ip, proto))
1984 }
1985
1986 fn lookup_route(
1987 &mut self,
1988 device: Option<&D>,
1989 local_ip: Option<IpDeviceAddr<I::Addr>>,
1990 addr: RoutableIpAddr<I::Addr>,
1991 transparent: bool,
1992 ) -> Result<ResolvedRoute<I, D>, ResolveRouteError> {
1993 let Self { table, devices, forwarding } = self;
1994 let (destination, ()) = table
1995 .lookup_filter_map(forwarding, device, addr.addr(), |_, d| match &local_ip {
1996 None => Some(()),
1997 Some(local_ip) => {
1998 if transparent {
1999 return Some(());
2000 }
2001 devices.get(d).and_then(|state| {
2002 state.addresses.contains(local_ip.as_ref()).then_some(())
2003 })
2004 }
2005 })
2006 .next()
2007 .ok_or(ResolveRouteError::Unreachable)?;
2008
2009 let Destination { device, next_hop } = destination;
2010 let mut addrs = devices.get(device).unwrap().addresses.iter();
2011 let local_ip = match local_ip {
2012 None => {
2013 let addr = addrs.next().ok_or(ResolveRouteError::NoSrcAddr)?;
2014 IpDeviceAddr::new(addr.get()).expect("not valid device addr")
2015 }
2016 Some(local_ip) => {
2017 if !transparent {
2018 assert!(
2021 addrs.any(|a| a.get() == local_ip.addr()),
2022 "didn't find IP {:?} in {:?}",
2023 local_ip,
2024 addrs.collect::<Vec<_>>()
2025 );
2026 }
2027 local_ip
2028 }
2029 };
2030
2031 Ok(ResolvedRoute {
2032 src_addr: local_ip,
2033 device: device.clone(),
2034 local_delivery_device: None,
2035 next_hop,
2036 internal_forwarding: InternalForwarding::NotUsed,
2039 })
2040 }
2041
2042 fn resolve_send_meta<O>(
2043 &mut self,
2044 socket: &IpSock<I, D::Weak>,
2045 options: &O,
2046 ) -> Result<SendIpPacketMeta<I, D, SpecifiedAddr<I::Addr>>, IpSockSendError>
2047 where
2048 O: SendOptions<I> + RouteResolutionOptions<I>,
2049 {
2050 let IpSockDefinition { remote_ip, local_ip, device, proto } = &socket.definition;
2051 let device = device
2052 .as_ref()
2053 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
2054 .transpose()?;
2055 let ResolvedRoute {
2056 src_addr,
2057 device,
2058 next_hop,
2059 local_delivery_device: _,
2060 internal_forwarding: _,
2061 } = self.lookup_route(
2062 device.as_ref(),
2063 Some(*local_ip),
2064 *remote_ip,
2065 options.transparent(),
2066 )?;
2067
2068 let remote_ip: &SpecifiedAddr<_> = remote_ip.as_ref();
2069
2070 let destination = IpPacketDestination::from_next_hop(next_hop, *remote_ip);
2071 Ok(SendIpPacketMeta {
2072 device,
2073 src_ip: src_addr.into(),
2074 dst_ip: *remote_ip,
2075 destination,
2076 proto: *proto,
2077 ttl: options.hop_limit(remote_ip),
2078 mtu: options.mtu(),
2079 dscp_and_ecn: DscpAndEcn::default(),
2080 })
2081 }
2082 }
2083}