1use core::cmp::Ordering;
8use core::convert::Infallible;
9use core::num::NonZeroU8;
10
11use log::{debug, error};
12use net_types::ip::{Ip, IpVersionMarker, Ipv6Addr, Mtu};
13use net_types::{MulticastAddress, ScopeableAddress, SpecifiedAddr, Witness as _};
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, PacketBuilder as _, PacketConstraints, SerializeError, Serializer};
27use packet_formats::ip::{DscpAndEcn, IpPacketBuilder as _};
28use thiserror::Error;
29
30use crate::icmp::IcmpErrorHandler;
31use crate::internal::base::{
32 FilterHandlerProvider, IpDeviceMtuContext, IpLayerIpExt, IpLayerPacketMetadata,
33 IpPacketDestination, IpSendFrameError, IpSendFrameErrorReason, ResolveRouteError,
34 SendIpPacketMeta, reject_type_to_icmpv4_error, reject_type_to_icmpv6_error,
35};
36use crate::internal::counters::IpCounters;
37use crate::internal::device::state::IpDeviceStateIpExt;
38use crate::internal::routing::PacketOrigin;
39use crate::internal::routing::rules::RuleInput;
40use crate::internal::types::{InternalForwarding, ResolvedRoute, RoutableIpAddr};
41use crate::{HopLimits, NextHop};
42
43pub struct IpSocketArgs<'a, D: StrongDeviceIdentifier, I: IpExt, O> {
45 pub device: Option<EitherDeviceId<&'a D, &'a D::Weak>>,
47 pub local_ip: Option<IpDeviceAddr<I::Addr>>,
50 pub remote_ip: RoutableIpAddr<I::Addr>,
52 pub proto: I::Proto,
54 pub options: &'a O,
56}
57pub trait IpSocketHandler<I: IpExt + FilterIpExt, BC: TxMetadataBindingsTypes>:
59 DeviceIdContext<AnyDevice>
60{
61 fn new_ip_socket<O>(
76 &mut self,
77 bindings_ctx: &mut BC,
78 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
79 ) -> Result<IpSock<I, Self::WeakDeviceId>, IpSockCreationError>
80 where
81 O: RouteResolutionOptions<I>;
82
83 fn send_ip_packet<S, O>(
96 &mut self,
97 bindings_ctx: &mut BC,
98 socket: &IpSock<I, Self::WeakDeviceId>,
99 body: S,
100 options: &O,
101 tx_metadata: BC::TxMetadata,
102 ) -> Result<(), IpSockSendError>
103 where
104 S: TransportPacketSerializer<I>,
105 S::Buffer: BufferMut,
106 O: SendOptions<I> + RouteResolutionOptions<I>;
107
108 fn confirm_reachable<O>(
114 &mut self,
115 bindings_ctx: &mut BC,
116 socket: &IpSock<I, Self::WeakDeviceId>,
117 options: &O,
118 ) where
119 O: RouteResolutionOptions<I>;
120
121 fn send_oneshot_ip_packet_with_fallible_serializer<S, E, F, O>(
144 &mut self,
145 bindings_ctx: &mut BC,
146 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
147 tx_metadata: BC::TxMetadata,
148 get_body_from_src_ip: F,
149 ) -> Result<(), SendOneShotIpPacketError<E>>
150 where
151 S: TransportPacketSerializer<I>,
152 S::Buffer: BufferMut,
153 F: FnOnce(IpDeviceAddr<I::Addr>) -> Result<S, E>,
154 O: SendOptions<I> + RouteResolutionOptions<I>,
155 {
156 let options = args.options;
157 let tmp = self
158 .new_ip_socket(bindings_ctx, args)
159 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })?;
160 let packet = get_body_from_src_ip(*tmp.local_ip())
161 .map_err(SendOneShotIpPacketError::SerializeError)?;
162 self.send_ip_packet(bindings_ctx, &tmp, packet, options, tx_metadata)
163 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })
164 }
165
166 fn send_oneshot_ip_packet_with_dyn_fallible_serializer<S, E, F, O>(
172 &mut self,
173 bindings_ctx: &mut BC,
174 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
175 tx_metadata: BC::TxMetadata,
176 get_body_from_src_ip: F,
177 ) -> Result<(), SendOneShotIpPacketError<E>>
178 where
179 S: DynamicTransportSerializer<I>,
180 F: FnOnce(IpDeviceAddr<I::Addr>) -> Result<S, E>,
181 O: SendOptions<I> + RouteResolutionOptions<I>,
182 {
183 let options = args.options;
184 let tmp = self
185 .new_ip_socket(bindings_ctx, args)
186 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })?;
187 let mut packet = get_body_from_src_ip(*tmp.local_ip())
188 .map_err(SendOneShotIpPacketError::SerializeError)?;
189 self.send_ip_packet(
190 bindings_ctx,
191 &tmp,
192 DynTransportSerializer::new(&mut packet),
193 options,
194 tx_metadata,
195 )
196 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })
197 }
198
199 fn send_oneshot_ip_packet<S, F, O>(
201 &mut self,
202 bindings_ctx: &mut BC,
203 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
204 tx_metadata: BC::TxMetadata,
205 get_body_from_src_ip: F,
206 ) -> Result<(), IpSockCreateAndSendError>
207 where
208 S: TransportPacketSerializer<I>,
209 S::Buffer: BufferMut,
210 F: FnOnce(IpDeviceAddr<I::Addr>) -> S,
211 O: SendOptions<I> + RouteResolutionOptions<I>,
212 {
213 self.send_oneshot_ip_packet_with_fallible_serializer(
214 bindings_ctx,
215 args,
216 tx_metadata,
217 |ip| Ok::<_, Infallible>(get_body_from_src_ip(ip)),
218 )
219 .map_err(|err| match err {
220 SendOneShotIpPacketError::CreateAndSendError { err } => err,
221 })
222 }
223
224 fn send_oneshot_ip_packet_with_dyn_serializer<S, F, O>(
230 &mut self,
231 bindings_ctx: &mut BC,
232 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
233 tx_metadata: BC::TxMetadata,
234 get_body_from_src_ip: F,
235 ) -> Result<(), IpSockCreateAndSendError>
236 where
237 S: DynamicTransportSerializer<I>,
238 F: FnOnce(IpDeviceAddr<I::Addr>) -> S,
239 O: SendOptions<I> + RouteResolutionOptions<I>,
240 {
241 self.send_oneshot_ip_packet_with_dyn_fallible_serializer(
242 bindings_ctx,
243 args,
244 tx_metadata,
245 |ip| Ok::<_, Infallible>(get_body_from_src_ip(ip)),
246 )
247 .map_err(|err| match err {
248 SendOneShotIpPacketError::CreateAndSendError { err } => err,
249 })
250 }
251}
252
253#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
255pub enum IpSockSendError {
256 #[error("a maximum transmission unit (MTU) was exceeded")]
261 Mtu,
262 #[error("the socket is currently unroutable: {0}")]
264 Unroutable(#[from] ResolveRouteError),
265 #[error("illegal loopback address")]
268 IllegalLoopbackAddress,
269 #[error("broadcast send is not enabled for the socket")]
271 BroadcastNotAllowed,
272}
273
274impl From<SerializeError<Infallible>> for IpSockSendError {
275 fn from(err: SerializeError<Infallible>) -> IpSockSendError {
276 match err {
277 SerializeError::SizeLimitExceeded => IpSockSendError::Mtu,
278 }
279 }
280}
281
282impl IpSockSendError {
283 fn from_ip_send_frame(e: IpSendFrameErrorReason) -> Result<(), Self> {
288 match e {
289 IpSendFrameErrorReason::Device(d) => Self::from_send_frame(d),
290 IpSendFrameErrorReason::IllegalLoopbackAddress => Err(Self::IllegalLoopbackAddress),
291 }
292 }
293
294 fn from_send_frame(e: SendFrameErrorReason) -> Result<(), Self> {
299 match e {
300 SendFrameErrorReason::Alloc | SendFrameErrorReason::QueueFull => Ok(()),
301 SendFrameErrorReason::SizeConstraintsViolation => Err(Self::Mtu),
302 }
303 }
304}
305
306#[derive(Error, Copy, Clone, Debug)]
308pub enum IpSockCreateAndSendError {
309 #[error("cannot send via temporary socket: {0}")]
311 Send(#[from] IpSockSendError),
312 #[error("the temporary socket could not be created: {0}")]
314 Create(#[from] IpSockCreationError),
315}
316
317#[derive(Debug)]
320#[allow(missing_docs)]
321pub enum SendOneShotIpPacketError<E> {
322 CreateAndSendError { err: IpSockCreateAndSendError },
323 SerializeError(E),
324}
325
326#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
328pub enum MmsError {
329 #[error("cannot find the device: {0}")]
332 NoDevice(#[from] ResolveRouteError),
333 #[error("invalid MTU: {0:?}")]
336 MTUTooSmall(Mtu),
337}
338
339pub trait DeviceIpSocketHandler<I: IpExt, BC>: DeviceIdContext<AnyDevice> {
341 fn get_mms<O: RouteResolutionOptions<I>>(
347 &mut self,
348 bindings_ctx: &mut BC,
349 ip_sock: &IpSock<I, Self::WeakDeviceId>,
350 options: &O,
351 ) -> Result<Mms, MmsError>;
352}
353
354#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
356pub enum IpSockCreationError {
357 #[error("a route cannot be determined: {0}")]
359 Route(#[from] ResolveRouteError),
360}
361
362#[derive(Clone, Debug)]
364#[cfg_attr(test, derive(PartialEq))]
365pub struct IpSock<I: IpExt, D> {
366 definition: IpSockDefinition<I, D>,
370}
371
372impl<I: IpExt, D> IpSock<I, D> {
373 #[cfg(any(test, feature = "testutils"))]
375 pub fn definition(&self) -> &IpSockDefinition<I, D> {
376 &self.definition
377 }
378}
379
380#[derive(Clone, Debug, PartialEq)]
384pub struct IpSockDefinition<I: IpExt, D> {
385 pub remote_ip: SocketIpAddr<I::Addr>,
387 pub local_ip: IpDeviceAddr<I::Addr>,
398 pub device: Option<D>,
400 pub proto: I::Proto,
402}
403
404impl<I: IpExt, D> IpSock<I, D> {
405 pub fn local_ip(&self) -> &IpDeviceAddr<I::Addr> {
407 &self.definition.local_ip
408 }
409 pub fn remote_ip(&self) -> &SocketIpAddr<I::Addr> {
411 &self.definition.remote_ip
412 }
413 pub fn device(&self) -> Option<&D> {
415 self.definition.device.as_ref()
416 }
417 pub fn proto(&self) -> I::Proto {
419 self.definition.proto
420 }
421}
422
423pub trait IpSocketBindingsContext<D>:
430 InstantContext
431 + FilterBindingsContext<D>
432 + TxMetadataBindingsTypes
433 + SocketOpsFilterBindingContext<D>
434{
435}
436impl<
437 D,
438 BC: InstantContext
439 + FilterBindingsContext<D>
440 + TxMetadataBindingsTypes
441 + SocketOpsFilterBindingContext<D>,
442> IpSocketBindingsContext<D> for BC
443{
444}
445
446pub trait IpSocketContext<I, BC>:
451 DeviceIdContext<AnyDevice, DeviceId: InterfaceProperties<BC::DeviceClass>>
452 + FilterHandlerProvider<I, BC>
453 + IcmpErrorHandler<I, BC>
454where
455 I: IpLayerIpExt,
456 BC: IpSocketBindingsContext<Self::DeviceId>,
457{
458 fn lookup_route(
463 &mut self,
464 bindings_ctx: &mut BC,
465 device: Option<&Self::DeviceId>,
466 src_ip: Option<IpDeviceAddr<I::Addr>>,
467 dst_ip: RoutableIpAddr<I::Addr>,
468 transparent: bool,
469 marks: &Marks,
470 ) -> Result<ResolvedRoute<I, Self::DeviceId>, ResolveRouteError>;
471
472 fn send_ip_packet<S>(
474 &mut self,
475 bindings_ctx: &mut BC,
476 meta: SendIpPacketMeta<I, &Self::DeviceId, SpecifiedAddr<I::Addr>>,
477 body: S,
478 packet_metadata: IpLayerPacketMetadata<I, Self::WeakAddressId, BC>,
479 ) -> Result<(), IpSendFrameError<S>>
480 where
481 S: TransportPacketSerializer<I>,
482 S::Buffer: BufferMut;
483
484 fn get_loopback_device(&mut self) -> Option<Self::DeviceId>;
486
487 fn confirm_reachable(
493 &mut self,
494 bindings_ctx: &mut BC,
495 dst: SpecifiedAddr<I::Addr>,
496 input: RuleInput<'_, I, Self::DeviceId>,
497 );
498}
499
500pub trait UseIpSocketHandlerBlanket {}
505
506impl<I, BC, CC> IpSocketHandler<I, BC> for CC
507where
508 I: IpLayerIpExt + IpDeviceStateIpExt,
509 BC: IpSocketBindingsContext<Self::DeviceId>,
510 CC: IpSocketContext<I, BC> + CounterContext<IpCounters<I>> + UseIpSocketHandlerBlanket,
511 CC::DeviceId: netstack3_base::InterfaceProperties<BC::DeviceClass>,
512{
513 fn new_ip_socket<O>(
514 &mut self,
515 bindings_ctx: &mut BC,
516 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
517 ) -> Result<IpSock<I, CC::WeakDeviceId>, IpSockCreationError>
518 where
519 O: RouteResolutionOptions<I>,
520 {
521 let IpSocketArgs { device, local_ip, remote_ip, proto, options } = args;
522 let device = device
523 .as_ref()
524 .map(|d| d.as_strong_ref().ok_or(ResolveRouteError::Unreachable))
525 .transpose()?;
526 let device = device.as_ref().map(|d| d.as_ref());
527
528 let resolved_route = self.lookup_route(
533 bindings_ctx,
534 device,
535 local_ip,
536 remote_ip,
537 options.transparent(),
538 options.marks(),
539 )?;
540 Ok(new_ip_socket(device, resolved_route, remote_ip, proto))
541 }
542
543 fn send_ip_packet<S, O>(
544 &mut self,
545 bindings_ctx: &mut BC,
546 ip_sock: &IpSock<I, CC::WeakDeviceId>,
547 body: S,
548 options: &O,
549 tx_metadata: BC::TxMetadata,
550 ) -> Result<(), IpSockSendError>
551 where
552 S: TransportPacketSerializer<I>,
553 S::Buffer: BufferMut,
554 O: SendOptions<I> + RouteResolutionOptions<I>,
555 {
556 send_ip_packet(self, bindings_ctx, ip_sock, body, options, tx_metadata)
557 }
558
559 fn confirm_reachable<O>(
560 &mut self,
561 bindings_ctx: &mut BC,
562 socket: &IpSock<I, CC::WeakDeviceId>,
563 options: &O,
564 ) where
565 O: RouteResolutionOptions<I>,
566 {
567 let bound_device = socket.device().and_then(|weak| weak.upgrade());
568 let bound_device = bound_device.as_ref();
569 let bound_address = Some((*socket.local_ip()).into());
570 let destination = (*socket.remote_ip()).into();
571 IpSocketContext::confirm_reachable(
572 self,
573 bindings_ctx,
574 destination,
575 RuleInput {
576 packet_origin: PacketOrigin::Local { bound_address, bound_device },
577 marks: options.marks(),
578 },
579 )
580 }
581}
582
583pub trait RouteResolutionOptions<I: Ip> {
595 fn transparent(&self) -> bool;
600
601 fn marks(&self) -> &Marks;
603}
604
605pub trait SendOptions<I: IpExt> {
613 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8>;
619
620 fn multicast_loop(&self) -> bool;
623
624 fn allow_broadcast(&self) -> Option<I::BroadcastMarker>;
626
627 fn dscp_and_ecn(&self) -> DscpAndEcn;
629
630 fn mtu(&self) -> Mtu;
635}
636
637#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
639pub struct DefaultIpSocketOptions;
640
641impl<I: IpExt> SendOptions<I> for DefaultIpSocketOptions {
642 fn hop_limit(&self, _destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
643 None
644 }
645
646 fn multicast_loop(&self) -> bool {
647 false
648 }
649
650 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
651 None
652 }
653
654 fn dscp_and_ecn(&self) -> DscpAndEcn {
655 DscpAndEcn::default()
656 }
657
658 fn mtu(&self) -> Mtu {
659 Mtu::no_limit()
660 }
661}
662
663impl<I: Ip> RouteResolutionOptions<I> for DefaultIpSocketOptions {
664 fn transparent(&self) -> bool {
665 false
666 }
667
668 fn marks(&self) -> &Marks {
669 &Marks::UNMARKED
670 }
671}
672
673#[allow(missing_docs)]
681pub trait DelegatedSendOptions<I: IpExt>: OptionDelegationMarker {
682 fn delegate(&self) -> &impl SendOptions<I> {
684 &DefaultIpSocketOptions
685 }
686
687 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
688 self.delegate().hop_limit(destination)
689 }
690
691 fn multicast_loop(&self) -> bool {
692 self.delegate().multicast_loop()
693 }
694
695 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
696 self.delegate().allow_broadcast()
697 }
698
699 fn dscp_and_ecn(&self) -> DscpAndEcn {
700 self.delegate().dscp_and_ecn()
701 }
702
703 fn mtu(&self) -> Mtu {
704 self.delegate().mtu()
705 }
706}
707
708impl<O: DelegatedSendOptions<I> + OptionDelegationMarker, I: IpExt> SendOptions<I> for O {
709 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
710 self.hop_limit(destination)
711 }
712
713 fn multicast_loop(&self) -> bool {
714 self.multicast_loop()
715 }
716
717 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
718 self.allow_broadcast()
719 }
720
721 fn dscp_and_ecn(&self) -> DscpAndEcn {
722 self.dscp_and_ecn()
723 }
724
725 fn mtu(&self) -> Mtu {
726 self.mtu()
727 }
728}
729
730#[allow(missing_docs)]
738pub trait DelegatedRouteResolutionOptions<I: Ip>: OptionDelegationMarker {
739 fn delegate(&self) -> &impl RouteResolutionOptions<I> {
741 &DefaultIpSocketOptions
742 }
743
744 fn transparent(&self) -> bool {
745 self.delegate().transparent()
746 }
747
748 fn marks(&self) -> &Marks {
749 self.delegate().marks()
750 }
751}
752
753impl<O: DelegatedRouteResolutionOptions<I> + OptionDelegationMarker, I: IpExt>
754 RouteResolutionOptions<I> for O
755{
756 fn transparent(&self) -> bool {
757 self.transparent()
758 }
759
760 fn marks(&self) -> &Marks {
761 self.marks()
762 }
763}
764
765pub trait OptionDelegationMarker {}
770
771#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
773pub struct SocketHopLimits<I: Ip> {
774 pub unicast: Option<NonZeroU8>,
776 pub multicast: Option<NonZeroU8>,
780 pub version: IpVersionMarker<I>,
784}
785
786impl<I: Ip> SocketHopLimits<I> {
787 pub fn set_unicast(value: Option<NonZeroU8>) -> impl FnOnce(&mut Self) {
789 move |limits| limits.unicast = value
790 }
791
792 pub fn set_multicast(value: Option<NonZeroU8>) -> impl FnOnce(&mut Self) {
794 move |limits| limits.multicast = value
795 }
796
797 pub fn get_limits_with_defaults(&self, defaults: &HopLimits) -> HopLimits {
799 let Self { unicast, multicast, version: _ } = self;
800 HopLimits {
801 unicast: unicast.unwrap_or(defaults.unicast),
802 multicast: multicast.unwrap_or(defaults.multicast),
803 }
804 }
805
806 pub fn hop_limit_for_dst(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
808 let Self { unicast, multicast, version: _ } = self;
809 if destination.is_multicast() { *multicast } else { *unicast }
810 }
811}
812
813fn new_ip_socket<I, D>(
814 requested_device: Option<&D>,
815 route: ResolvedRoute<I, D>,
816 remote_ip: SocketIpAddr<I::Addr>,
817 proto: I::Proto,
818) -> IpSock<I, D::Weak>
819where
820 I: IpExt,
821 D: StrongDeviceIdentifier,
822{
823 let ResolvedRoute {
827 src_addr,
828 device: route_device,
829 local_delivery_device,
830 next_hop: _,
831 internal_forwarding: _,
832 } = route;
833
834 let socket_device = (src_addr.as_ref().must_have_zone() || remote_ip.as_ref().must_have_zone())
837 .then(|| {
838 local_delivery_device.unwrap_or(route_device)
842 })
843 .as_ref()
844 .or(requested_device)
845 .map(|d| d.downgrade());
846
847 let definition =
848 IpSockDefinition { local_ip: src_addr, remote_ip, device: socket_device, proto };
849 IpSock { definition }
850}
851
852fn send_ip_packet<I, S, BC, CC, O>(
853 core_ctx: &mut CC,
854 bindings_ctx: &mut BC,
855 socket: &IpSock<I, CC::WeakDeviceId>,
856 mut body: S,
857 options: &O,
858 tx_metadata: BC::TxMetadata,
859) -> Result<(), IpSockSendError>
860where
861 I: IpLayerIpExt,
862 S: TransportPacketSerializer<I>,
863 S::Buffer: BufferMut,
864 BC: IpSocketBindingsContext<CC::DeviceId>,
865 CC: IpSocketContext<I, BC> + CounterContext<IpCounters<I>>,
866 CC::DeviceId: netstack3_base::InterfaceProperties<BC::DeviceClass>,
867 O: SendOptions<I> + RouteResolutionOptions<I>,
868{
869 trace_duration!("ip::send_packet");
870
871 fn resolve<
874 I: IpLayerIpExt,
875 CC: IpSocketContext<I, BC>,
876 BC: IpSocketBindingsContext<CC::DeviceId>,
877 >(
878 core_ctx: &mut CC,
879 bindings_ctx: &mut BC,
880 device: &Option<CC::WeakDeviceId>,
881 local_ip: IpDeviceAddr<I::Addr>,
882 remote_ip: RoutableIpAddr<I::Addr>,
883 transparent: bool,
884 marks: &Marks,
885 ) -> Result<ResolvedRoute<I, CC::DeviceId>, IpSockSendError> {
886 let device = match device.as_ref().map(|d| d.upgrade()) {
887 Some(Some(device)) => Some(device),
888 Some(None) => return Err(ResolveRouteError::Unreachable.into()),
889 None => None,
890 };
891 let route = core_ctx
892 .lookup_route(
893 bindings_ctx,
894 device.as_ref(),
895 Some(local_ip),
896 remote_ip,
897 transparent,
898 marks,
899 )
900 .map_err(|e| IpSockSendError::Unroutable(e))?;
901 assert_eq!(local_ip, route.src_addr);
902 Ok(route)
903 }
904
905 let IpSock {
906 definition: IpSockDefinition { remote_ip, local_ip, device: socket_device, proto },
907 } = socket;
908 let ResolvedRoute {
909 src_addr: local_ip,
910 device: mut egress_device,
911 mut next_hop,
912 mut local_delivery_device,
913 mut internal_forwarding,
914 } = resolve(
915 core_ctx,
916 bindings_ctx,
917 socket_device,
918 *local_ip,
919 *remote_ip,
920 options.transparent(),
921 options.marks(),
922 )?;
923
924 if matches!(next_hop, NextHop::Broadcast(_)) && options.allow_broadcast().is_none() {
925 return Err(IpSockSendError::BroadcastNotAllowed);
926 }
927
928 let previous_dst = remote_ip.addr();
929 let mut packet = filter::TxPacket::new(local_ip.addr(), remote_ip.addr(), *proto, &mut body);
930 let mut packet_metadata =
931 IpLayerPacketMetadata::from_tx_metadata_and_marks(tx_metadata, *options.marks());
932
933 let filter_result = core_ctx.filter_handler().local_egress_hook(
934 bindings_ctx,
935 &mut packet,
936 &egress_device,
937 &mut packet_metadata,
938 );
939 match filter_result {
940 filter::Verdict::Stop(filter::DropOrReject::Drop) => {
941 packet_metadata.acknowledge_drop();
942 return Ok(());
943 }
944 filter::Verdict::Stop(filter::DropOrReject::Reject(reject_type)) => {
945 packet_metadata.acknowledge_drop();
946
947 let Some(icmp_error): Option<I::IcmpError> = I::map_ip_out(
948 reject_type,
949 |reject_type| reject_type_to_icmpv4_error(reject_type),
950 |reject_type| reject_type_to_icmpv6_error(reject_type),
951 ) else {
952 debug!("Unsupported reject type: {:?}", reject_type);
953 return Ok(());
954 };
955
956 let src_ip = SocketIpAddr::new_from_witness(local_ip.into_inner().get());
957 let dst_ip = *remote_ip;
958 let ttl = options.hop_limit(&dst_ip.into()).map(|v| v.into()).unwrap_or(1);
959 let packet_builder = I::PacketBuilder::new(
960 src_ip.into_inner().get(),
961 dst_ip.into_inner().get(),
962 ttl,
963 *proto,
964 );
965 let header_len = packet_builder.constraints().header_len();
966 let ip_frame = packet_builder.wrap_body(body);
967 let packet = match ip_frame
968 .serialize_outer(packet::NoReuseBufferProvider(packet::new_buf_vec))
969 {
970 Ok(packet) => packet,
971 Err((error, _frame)) => {
972 debug!("Failed to serialize packet {:?}", error);
973 return Ok(());
974 }
975 };
976
977 core_ctx.send_icmp_error_message(
981 bindings_ctx,
982 None,
983 None,
984 src_ip,
985 dst_ip,
986 packet,
987 icmp_error,
988 header_len,
989 *proto,
990 &options.marks(),
991 );
992
993 return Ok(());
994 }
995 filter::Verdict::Proceed(filter::Accept) => {}
996 }
997
998 let Some(mut local_ip) = IpDeviceAddr::new(packet.src_addr()) else {
999 packet_metadata.acknowledge_drop();
1000 return Err(IpSockSendError::Unroutable(ResolveRouteError::NoSrcAddr));
1001 };
1002 let Some(remote_ip) = RoutableIpAddr::new(packet.dst_addr()) else {
1003 packet_metadata.acknowledge_drop();
1004 return Err(IpSockSendError::Unroutable(ResolveRouteError::Unreachable));
1005 };
1006
1007 if remote_ip.addr() != previous_dst {
1010 let ResolvedRoute {
1011 src_addr: new_local_ip,
1012 device: new_device,
1013 next_hop: new_next_hop,
1014 local_delivery_device: new_local_delivery_device,
1015 internal_forwarding: new_internal_forwarding,
1016 } = match resolve(
1017 core_ctx,
1018 bindings_ctx,
1019 socket_device,
1020 local_ip,
1021 remote_ip,
1022 options.transparent(),
1023 options.marks(),
1024 ) {
1025 Ok(r) => r,
1026 Err(err) => {
1027 packet_metadata.acknowledge_drop();
1028 return Err(err);
1029 }
1030 };
1031 local_ip = new_local_ip;
1032 egress_device = new_device;
1033 next_hop = new_next_hop;
1034 local_delivery_device = new_local_delivery_device;
1035 internal_forwarding = new_internal_forwarding;
1036 }
1037
1038 match internal_forwarding {
1040 InternalForwarding::Used(ingress_device) => {
1041 match core_ctx.filter_handler().forwarding_hook(
1042 &mut packet,
1043 &ingress_device,
1044 &egress_device,
1045 &mut packet_metadata,
1046 ) {
1047 filter::Verdict::Stop(filter::DropOrReject::Drop) => {
1048 packet_metadata.acknowledge_drop();
1049 return Ok(());
1050 }
1051 filter::Verdict::Stop(filter::DropOrReject::Reject(_reject_type)) => {
1052 packet_metadata.acknowledge_drop();
1054 return Ok(());
1055 }
1056 filter::Verdict::Proceed(filter::Accept) => {}
1057 }
1058 }
1059 InternalForwarding::NotUsed => {}
1060 }
1061
1062 if let Some(socket_cookie) = packet_metadata.tx_metadata().socket_cookie() {
1063 let egress_filter_result = bindings_ctx.socket_ops_filter().on_egress(
1064 &packet,
1065 &egress_device,
1066 socket_cookie,
1067 packet_metadata.marks(),
1068 );
1069
1070 match egress_filter_result {
1072 SocketEgressFilterResult::Pass { congestion: _ } => (),
1073 SocketEgressFilterResult::Drop { congestion: _ } => {
1074 core_ctx.counters().socket_egress_filter_dropped.increment();
1075 packet_metadata.acknowledge_drop();
1076 return Ok(());
1077 }
1078 }
1079 }
1080
1081 let loopback_packet = (!egress_device.is_loopback()
1086 && ((options.multicast_loop() && remote_ip.addr().is_multicast())
1087 || next_hop.is_broadcast()))
1088 .then(|| body.serialize_new_buf(PacketConstraints::UNCONSTRAINED, packet::new_buf_vec))
1089 .transpose()?
1090 .map(|buf| RawIpBody::new(*proto, local_ip.addr(), remote_ip.addr(), buf));
1091
1092 let destination = match &local_delivery_device {
1093 Some(d) => IpPacketDestination::Loopback(d),
1094 None => IpPacketDestination::from_next_hop(next_hop, remote_ip.into()),
1095 };
1096 let ttl = options.hop_limit(&remote_ip.into());
1097 let meta = SendIpPacketMeta {
1098 device: &egress_device,
1099 src_ip: local_ip.into(),
1100 dst_ip: remote_ip.into(),
1101 destination,
1102 ttl,
1103 proto: *proto,
1104 mtu: options.mtu(),
1105 dscp_and_ecn: options.dscp_and_ecn(),
1106 };
1107 IpSocketContext::send_ip_packet(core_ctx, bindings_ctx, meta, body, packet_metadata).or_else(
1108 |IpSendFrameError { serializer: _, error }| IpSockSendError::from_ip_send_frame(error),
1109 )?;
1110
1111 match (loopback_packet, core_ctx.get_loopback_device()) {
1112 (Some(loopback_packet), Some(loopback_device)) => {
1113 let meta = SendIpPacketMeta {
1114 device: &loopback_device,
1115 src_ip: local_ip.into(),
1116 dst_ip: remote_ip.into(),
1117 destination: IpPacketDestination::Loopback(&egress_device),
1118 ttl,
1119 proto: *proto,
1120 mtu: options.mtu(),
1121 dscp_and_ecn: options.dscp_and_ecn(),
1122 };
1123 let packet_metadata = IpLayerPacketMetadata::default();
1124
1125 IpSocketContext::send_ip_packet(
1128 core_ctx,
1129 bindings_ctx,
1130 meta,
1131 loopback_packet,
1132 packet_metadata,
1133 )
1134 .unwrap_or_else(|IpSendFrameError { serializer: _, error }| {
1135 error!("failed to send loopback packet: {error:?}")
1136 });
1137 }
1138 (Some(_loopback_packet), None) => {
1139 error!("can't send a loopback packet without the loopback device")
1140 }
1141 _ => (),
1142 }
1143
1144 Ok(())
1145}
1146
1147pub trait UseDeviceIpSocketHandlerBlanket {}
1152
1153impl<I, BC, CC> DeviceIpSocketHandler<I, BC> for CC
1154where
1155 I: IpLayerIpExt + IpDeviceStateIpExt,
1156 BC: IpSocketBindingsContext<CC::DeviceId>,
1157 CC: IpDeviceMtuContext<I> + IpSocketContext<I, BC> + UseDeviceIpSocketHandlerBlanket,
1158{
1159 fn get_mms<O: RouteResolutionOptions<I>>(
1160 &mut self,
1161 bindings_ctx: &mut BC,
1162 ip_sock: &IpSock<I, Self::WeakDeviceId>,
1163 options: &O,
1164 ) -> Result<Mms, MmsError> {
1165 let IpSockDefinition { remote_ip, local_ip, device, proto: _ } = &ip_sock.definition;
1166 let device = device
1167 .as_ref()
1168 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
1169 .transpose()?;
1170
1171 let ResolvedRoute {
1172 src_addr: _,
1173 local_delivery_device: _,
1174 device,
1175 next_hop: _,
1176 internal_forwarding: _,
1177 } = self
1178 .lookup_route(
1179 bindings_ctx,
1180 device.as_ref(),
1181 Some(*local_ip),
1182 *remote_ip,
1183 options.transparent(),
1184 options.marks(),
1185 )
1186 .map_err(MmsError::NoDevice)?;
1187 let mtu = self.get_mtu(&device);
1188 Mms::from_mtu::<I>(mtu, 0 ).ok_or(MmsError::MTUTooSmall(mtu))
1191 }
1192}
1193
1194pub(crate) mod ipv6_source_address_selection {
1196 use net_types::ip::{AddrSubnet, IpAddress as _};
1197
1198 use super::*;
1199
1200 use netstack3_base::Ipv6DeviceAddr;
1201
1202 pub struct SasCandidate<D> {
1204 pub addr_sub: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1206 pub assigned: bool,
1208 pub deprecated: bool,
1210 pub temporary: bool,
1212 pub device: D,
1214 }
1215
1216 pub fn select_ipv6_source_address<
1229 'a,
1230 D: PartialEq,
1231 A,
1232 I: Iterator<Item = A>,
1233 F: FnMut(&A) -> SasCandidate<D>,
1234 >(
1235 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1236 outbound_device: &D,
1237 addresses: I,
1238 mut get_candidate: F,
1239 ) -> Option<A> {
1240 addresses
1252 .map(|item| {
1253 let candidate = get_candidate(&item);
1254 (item, candidate)
1255 })
1256 .filter(|(_, candidate)| candidate.assigned)
1259 .max_by(|(_, a), (_, b)| {
1260 select_ipv6_source_address_cmp(remote_ip, outbound_device, a, b)
1261 })
1262 .map(|(item, _candidate)| item)
1263 }
1264
1265 fn select_ipv6_source_address_cmp<D: PartialEq>(
1267 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1268 outbound_device: &D,
1269 a: &SasCandidate<D>,
1270 b: &SasCandidate<D>,
1271 ) -> Ordering {
1272 let SasCandidate {
1274 addr_sub: a_addr_sub,
1275 assigned: a_assigned,
1276 deprecated: a_deprecated,
1277 temporary: a_temporary,
1278 device: a_device,
1279 } = a;
1280 let SasCandidate {
1281 addr_sub: b_addr_sub,
1282 assigned: b_assigned,
1283 deprecated: b_deprecated,
1284 temporary: b_temporary,
1285 device: b_device,
1286 } = b;
1287
1288 let a_addr = a_addr_sub.addr().into_specified();
1289 let b_addr = b_addr_sub.addr().into_specified();
1290
1291 if let Some(remote_ip) = remote_ip {
1295 debug_assert!(!(a_addr == remote_ip && b_addr == remote_ip));
1296 }
1297
1298 debug_assert!(a_assigned);
1301 debug_assert!(b_assigned);
1302
1303 rule_1(remote_ip, a_addr, b_addr)
1304 .then_with(|| rule_2(remote_ip, a_addr, b_addr))
1305 .then_with(|| rule_3(*a_deprecated, *b_deprecated))
1306 .then_with(|| rule_5(outbound_device, a_device, b_device))
1307 .then_with(|| rule_7(*a_temporary, *b_temporary))
1308 .then_with(|| rule_8(remote_ip, *a_addr_sub, *b_addr_sub))
1309 }
1310
1311 fn rule_1(
1313 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1314 a: SpecifiedAddr<Ipv6Addr>,
1315 b: SpecifiedAddr<Ipv6Addr>,
1316 ) -> Ordering {
1317 let remote_ip = match remote_ip {
1318 Some(remote_ip) => remote_ip,
1319 None => return Ordering::Equal,
1320 };
1321 if (a == remote_ip) != (b == remote_ip) {
1322 if a == remote_ip { Ordering::Greater } else { Ordering::Less }
1334 } else {
1335 Ordering::Equal
1336 }
1337 }
1338
1339 fn rule_2(
1340 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1341 a: SpecifiedAddr<Ipv6Addr>,
1342 b: SpecifiedAddr<Ipv6Addr>,
1343 ) -> Ordering {
1344 let remote_scope = match remote_ip {
1347 Some(remote_ip) => remote_ip.scope().multicast_scope_id(),
1348 None => return Ordering::Equal,
1349 };
1350 let a_scope = a.scope().multicast_scope_id();
1351 let b_scope = b.scope().multicast_scope_id();
1352 if a_scope < b_scope {
1353 if a_scope < remote_scope { Ordering::Less } else { Ordering::Greater }
1354 } else if a_scope > b_scope {
1355 if b_scope < remote_scope { Ordering::Greater } else { Ordering::Less }
1356 } else {
1357 Ordering::Equal
1358 }
1359 }
1360
1361 fn rule_3(a_deprecated: bool, b_deprecated: bool) -> Ordering {
1362 match (a_deprecated, b_deprecated) {
1363 (true, false) => Ordering::Less,
1364 (true, true) | (false, false) => Ordering::Equal,
1365 (false, true) => Ordering::Greater,
1366 }
1367 }
1368
1369 fn rule_5<D: PartialEq>(outbound_device: &D, a_device: &D, b_device: &D) -> Ordering {
1370 if (a_device == outbound_device) != (b_device == outbound_device) {
1371 if a_device == outbound_device { Ordering::Greater } else { Ordering::Less }
1373 } else {
1374 Ordering::Equal
1375 }
1376 }
1377
1378 fn rule_7(a_temporary: bool, b_temporary: bool) -> Ordering {
1380 match (a_temporary, b_temporary) {
1381 (true, false) => Ordering::Greater,
1382 (true, true) | (false, false) => Ordering::Equal,
1383 (false, true) => Ordering::Less,
1384 }
1385 }
1386
1387 fn rule_8(
1388 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1389 a: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1390 b: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1391 ) -> Ordering {
1392 let remote_ip = match remote_ip {
1393 Some(remote_ip) => remote_ip,
1394 None => return Ordering::Equal,
1395 };
1396 fn common_prefix_len(
1406 src: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1407 dst: SpecifiedAddr<Ipv6Addr>,
1408 ) -> u8 {
1409 core::cmp::min(src.addr().common_prefix_len(&dst), src.subnet().prefix())
1410 }
1411
1412 common_prefix_len(a, remote_ip).cmp(&common_prefix_len(b, remote_ip))
1424 }
1425
1426 #[cfg(test)]
1427 mod tests {
1428 use net_declare::net_ip_v6;
1429
1430 use super::*;
1431
1432 #[test]
1433 fn test_select_ipv6_source_address() {
1434 let remote = SpecifiedAddr::new(net_ip_v6!("2001:0db8:1::")).unwrap();
1438 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1439 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1440 let link_local_remote = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:42")).unwrap();
1441 let link_local = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:4")).unwrap();
1442 let dev0 = &0;
1443 let dev1 = &1;
1444 let dev2 = &2;
1445
1446 assert_eq!(rule_1(Some(remote), remote, local0), Ordering::Greater);
1448 assert_eq!(rule_1(Some(remote), local0, remote), Ordering::Less);
1449 assert_eq!(rule_1(Some(remote), local0, local1), Ordering::Equal);
1450 assert_eq!(rule_1(None, local0, local1), Ordering::Equal);
1451
1452 assert_eq!(rule_2(Some(remote), local0, local1), Ordering::Equal);
1454 assert_eq!(rule_2(Some(remote), local1, local0), Ordering::Equal);
1455 assert_eq!(rule_2(Some(remote), local0, link_local), Ordering::Greater);
1456 assert_eq!(rule_2(Some(remote), link_local, local0), Ordering::Less);
1457 assert_eq!(rule_2(Some(link_local_remote), local0, link_local), Ordering::Less);
1458 assert_eq!(rule_2(Some(link_local_remote), link_local, local0), Ordering::Greater);
1459 assert_eq!(rule_1(None, local0, link_local), Ordering::Equal);
1460
1461 assert_eq!(rule_3(false, true), Ordering::Greater);
1463 assert_eq!(rule_3(true, false), Ordering::Less);
1464 assert_eq!(rule_3(true, true), Ordering::Equal);
1465 assert_eq!(rule_3(false, false), Ordering::Equal);
1466
1467 assert_eq!(rule_5(dev0, dev0, dev2), Ordering::Greater);
1469 assert_eq!(rule_5(dev0, dev2, dev0), Ordering::Less);
1470 assert_eq!(rule_5(dev0, dev0, dev0), Ordering::Equal);
1471 assert_eq!(rule_5(dev0, dev2, dev2), Ordering::Equal);
1472
1473 assert_eq!(rule_7(true, false), Ordering::Greater);
1475 assert_eq!(rule_7(false, true), Ordering::Less);
1476 assert_eq!(rule_7(true, true), Ordering::Equal);
1477 assert_eq!(rule_7(false, false), Ordering::Equal);
1478
1479 {
1481 let new_addr_entry = |addr, prefix_len| AddrSubnet::new(addr, prefix_len).unwrap();
1482
1483 let remote = SpecifiedAddr::new(net_ip_v6!("1111::")).unwrap();
1489 let local0 = new_addr_entry(net_ip_v6!("1110::"), 64);
1491 let local1 = new_addr_entry(net_ip_v6!("1100::"), 64);
1493
1494 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Greater);
1495 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Less);
1496 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1497 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1498 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1499
1500 let local0 = new_addr_entry(net_ip_v6!("1110::"), 8);
1505 let local1 = new_addr_entry(net_ip_v6!("1100::"), 8);
1507
1508 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Equal);
1509 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Equal);
1510 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1511 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1512 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1513 }
1514
1515 {
1516 let new_addr_entry = |addr, device| SasCandidate {
1517 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1518 deprecated: false,
1519 assigned: true,
1520 temporary: false,
1521 device,
1522 };
1523
1524 assert_eq!(
1526 select_ipv6_source_address_cmp(
1527 Some(remote),
1528 dev0,
1529 &new_addr_entry(*local0, *dev1),
1530 &new_addr_entry(*local1, *dev2),
1531 ),
1532 Ordering::Equal
1533 );
1534 }
1535 }
1536
1537 #[test]
1538 fn test_select_ipv6_source_address_no_remote() {
1539 let dev0 = &0;
1542 let dev1 = &1;
1543 let dev2 = &2;
1544
1545 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1546 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1547
1548 let new_addr_entry = |addr, deprecated, device| SasCandidate {
1549 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1550 deprecated,
1551 assigned: true,
1552 temporary: false,
1553 device,
1554 };
1555
1556 assert_eq!(
1558 select_ipv6_source_address_cmp(
1559 None,
1560 dev0,
1561 &new_addr_entry(*local0, false, *dev1),
1562 &new_addr_entry(*local1, true, *dev2),
1563 ),
1564 Ordering::Greater
1565 );
1566
1567 assert_eq!(
1569 select_ipv6_source_address_cmp(
1570 None,
1571 dev0,
1572 &new_addr_entry(*local0, false, *dev0),
1573 &new_addr_entry(*local1, false, *dev1),
1574 ),
1575 Ordering::Greater
1576 );
1577 }
1578 }
1579}
1580
1581#[cfg(any(test, feature = "testutils"))]
1583pub(crate) mod testutil {
1584 use alloc::boxed::Box;
1585 use alloc::vec::Vec;
1586 use core::num::NonZeroUsize;
1587
1588 use crate::internal::types::RoutePreference;
1589 use derivative::Derivative;
1590 use net_types::ip::{GenericOverIp, IpAddr, IpAddress, Ipv4, Ipv4Addr, Ipv6, Subnet};
1591 use net_types::{MulticastAddr, Witness as _};
1592 use netstack3_base::testutil::{FakeCoreCtx, FakeStrongDeviceId, FakeWeakDeviceId};
1593 use netstack3_base::{SendFrameContext, SendFrameError};
1594 use netstack3_filter::Tuple;
1595 use netstack3_hashmap::HashMap;
1596
1597 use super::*;
1598 use crate::internal::base::{
1599 BaseTransportIpContext, DEFAULT_HOP_LIMITS, HopLimits, MulticastMembershipHandler,
1600 };
1601 use crate::internal::routing::testutil::FakeIpRoutingCtx;
1602 use crate::internal::routing::{self, RoutingTable};
1603 use crate::internal::types::{Destination, Entry, Metric, RawMetric};
1604
1605 #[derive(Derivative, GenericOverIp)]
1608 #[generic_over_ip(I, Ip)]
1609 #[derivative(Default(bound = ""))]
1610 pub struct FakeIpSocketCtx<I: Ip, D> {
1611 pub(crate) table: RoutingTable<I, D>,
1612 forwarding: FakeIpRoutingCtx<D>,
1613 devices: HashMap<D, FakeDeviceState<I>>,
1614 }
1615
1616 pub trait InnerFakeIpSocketCtx<I: Ip, D> {
1619 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D>;
1621 }
1622
1623 impl<I: Ip, D> InnerFakeIpSocketCtx<I, D> for FakeIpSocketCtx<I, D> {
1624 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1625 self
1626 }
1627 }
1628
1629 impl<I: IpExt, D: FakeStrongDeviceId, BC> BaseTransportIpContext<I, BC> for FakeIpSocketCtx<I, D> {
1630 fn get_default_hop_limits(&mut self, device: Option<&D>) -> HopLimits {
1631 device.map_or(DEFAULT_HOP_LIMITS, |device| {
1632 let hop_limit = self.get_device_state(device).default_hop_limit;
1633 HopLimits { unicast: hop_limit, multicast: DEFAULT_HOP_LIMITS.multicast }
1634 })
1635 }
1636
1637 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1638
1639 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1640 &mut self,
1641 addr: SpecifiedAddr<I::Addr>,
1642 cb: F,
1643 ) -> O {
1644 cb(Box::new(self.devices.iter().filter_map(move |(device, state)| {
1645 state.addresses.contains(&addr).then(|| device.clone())
1646 })))
1647 }
1648
1649 fn get_original_destination(&mut self, _tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1650 unimplemented!()
1651 }
1652 }
1653
1654 impl<I: IpExt, D: FakeStrongDeviceId> DeviceIdContext<AnyDevice> for FakeIpSocketCtx<I, D> {
1655 type DeviceId = D;
1656 type WeakDeviceId = D::Weak;
1657 }
1658
1659 impl<I, State, D, Meta, BC> IpSocketHandler<I, BC> for FakeCoreCtx<State, Meta, D>
1660 where
1661 I: IpExt + FilterIpExt,
1662 State: InnerFakeIpSocketCtx<I, D>,
1663 D: FakeStrongDeviceId,
1664 BC: TxMetadataBindingsTypes,
1665 FakeCoreCtx<State, Meta, D>:
1666 SendFrameContext<BC, SendIpPacketMeta<I, Self::DeviceId, SpecifiedAddr<I::Addr>>>,
1667 {
1668 fn new_ip_socket<O>(
1669 &mut self,
1670 _bindings_ctx: &mut BC,
1671 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
1672 ) -> Result<IpSock<I, Self::WeakDeviceId>, IpSockCreationError>
1673 where
1674 O: RouteResolutionOptions<I>,
1675 {
1676 self.state.fake_ip_socket_ctx_mut().new_ip_socket(args)
1677 }
1678
1679 fn send_ip_packet<S, O>(
1680 &mut self,
1681 bindings_ctx: &mut BC,
1682 socket: &IpSock<I, Self::WeakDeviceId>,
1683 body: S,
1684 options: &O,
1685 _tx_meta: BC::TxMetadata,
1688 ) -> Result<(), IpSockSendError>
1689 where
1690 S: TransportPacketSerializer<I>,
1691 S::Buffer: BufferMut,
1692 O: SendOptions<I> + RouteResolutionOptions<I>,
1693 {
1694 let meta = self.state.fake_ip_socket_ctx_mut().resolve_send_meta(socket, options)?;
1695 self.send_frame(bindings_ctx, meta, body).or_else(
1696 |SendFrameError { serializer: _, error }| IpSockSendError::from_send_frame(error),
1697 )
1698 }
1699
1700 fn confirm_reachable<O>(
1701 &mut self,
1702 _bindings_ctx: &mut BC,
1703 _socket: &IpSock<I, Self::WeakDeviceId>,
1704 _options: &O,
1705 ) {
1706 }
1707 }
1708
1709 impl<I: IpExt, D: FakeStrongDeviceId, BC> MulticastMembershipHandler<I, BC>
1710 for FakeIpSocketCtx<I, D>
1711 {
1712 fn join_multicast_group(
1713 &mut self,
1714 _bindings_ctx: &mut BC,
1715 device: &Self::DeviceId,
1716 addr: MulticastAddr<<I as Ip>::Addr>,
1717 ) {
1718 let value = self.get_device_state_mut(device).multicast_groups.entry(addr).or_insert(0);
1719 *value = value.checked_add(1).unwrap();
1720 }
1721
1722 fn leave_multicast_group(
1723 &mut self,
1724 _bindings_ctx: &mut BC,
1725 device: &Self::DeviceId,
1726 addr: MulticastAddr<<I as Ip>::Addr>,
1727 ) {
1728 let value = self
1729 .get_device_state_mut(device)
1730 .multicast_groups
1731 .get_mut(&addr)
1732 .unwrap_or_else(|| panic!("no entry for {addr} on {device:?}"));
1733 *value = value.checked_sub(1).unwrap();
1734 }
1735
1736 fn select_device_for_multicast_group(
1737 &mut self,
1738 addr: MulticastAddr<<I as Ip>::Addr>,
1739 _marks: &Marks,
1740 ) -> Result<Self::DeviceId, ResolveRouteError> {
1741 let remote_ip = SocketIpAddr::new_from_multicast(addr);
1742 self.lookup_route(None, None, remote_ip, false)
1743 .map(|ResolvedRoute { device, .. }| device)
1744 }
1745 }
1746
1747 impl<I, BC, D, State, Meta> BaseTransportIpContext<I, BC> for FakeCoreCtx<State, Meta, D>
1748 where
1749 I: IpExt + FilterIpExt,
1750 D: FakeStrongDeviceId,
1751 State: InnerFakeIpSocketCtx<I, D>,
1752 BC: TxMetadataBindingsTypes,
1753 Self: IpSocketHandler<I, BC, DeviceId = D, WeakDeviceId = FakeWeakDeviceId<D>>,
1754 {
1755 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1756
1757 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1758 &mut self,
1759 addr: SpecifiedAddr<I::Addr>,
1760 cb: F,
1761 ) -> O {
1762 BaseTransportIpContext::<I, BC>::with_devices_with_assigned_addr(
1763 self.state.fake_ip_socket_ctx_mut(),
1764 addr,
1765 cb,
1766 )
1767 }
1768
1769 fn get_default_hop_limits(&mut self, device: Option<&Self::DeviceId>) -> HopLimits {
1770 BaseTransportIpContext::<I, BC>::get_default_hop_limits(
1771 self.state.fake_ip_socket_ctx_mut(),
1772 device,
1773 )
1774 }
1775
1776 fn get_original_destination(&mut self, tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1777 BaseTransportIpContext::<I, BC>::get_original_destination(
1778 self.state.fake_ip_socket_ctx_mut(),
1779 tuple,
1780 )
1781 }
1782 }
1783
1784 #[derive(Derivative)]
1786 #[derivative(Default(bound = ""))]
1787 pub struct FakeDualStackIpSocketCtx<D> {
1788 v4: FakeIpSocketCtx<Ipv4, D>,
1789 v6: FakeIpSocketCtx<Ipv6, D>,
1790 }
1791
1792 impl<D: FakeStrongDeviceId> FakeDualStackIpSocketCtx<D> {
1793 pub fn new<A: Into<SpecifiedAddr<IpAddr>>>(
1795 devices: impl IntoIterator<Item = FakeDeviceConfig<D, A>>,
1796 ) -> Self {
1797 let partition =
1798 |v: Vec<A>| -> (Vec<SpecifiedAddr<Ipv4Addr>>, Vec<SpecifiedAddr<Ipv6Addr>>) {
1799 v.into_iter().fold((Vec::new(), Vec::new()), |(mut v4, mut v6), i| {
1800 match IpAddr::from(i.into()) {
1801 IpAddr::V4(a) => v4.push(a),
1802 IpAddr::V6(a) => v6.push(a),
1803 }
1804 (v4, v6)
1805 })
1806 };
1807
1808 let (v4, v6): (Vec<_>, Vec<_>) = devices
1809 .into_iter()
1810 .map(|FakeDeviceConfig { device, local_ips, remote_ips }| {
1811 let (local_v4, local_v6) = partition(local_ips);
1812 let (remote_v4, remote_v6) = partition(remote_ips);
1813 (
1814 FakeDeviceConfig {
1815 device: device.clone(),
1816 local_ips: local_v4,
1817 remote_ips: remote_v4,
1818 },
1819 FakeDeviceConfig { device, local_ips: local_v6, remote_ips: remote_v6 },
1820 )
1821 })
1822 .unzip();
1823 Self { v4: FakeIpSocketCtx::new(v4), v6: FakeIpSocketCtx::new(v6) }
1824 }
1825
1826 pub fn inner_mut<I: Ip>(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1828 I::map_ip_out(self, |s| &mut s.v4, |s| &mut s.v6)
1829 }
1830
1831 fn inner<I: Ip>(&self) -> &FakeIpSocketCtx<I, D> {
1832 I::map_ip_out(self, |s| &s.v4, |s| &s.v6)
1833 }
1834
1835 pub fn add_route(&mut self, device: D, ip: SpecifiedAddr<IpAddr>) {
1837 match IpAddr::from(ip) {
1838 IpAddr::V4(ip) => {
1839 routing::testutil::add_on_link_routing_entry(&mut self.v4.table, ip, device)
1840 }
1841 IpAddr::V6(ip) => {
1842 routing::testutil::add_on_link_routing_entry(&mut self.v6.table, ip, device)
1843 }
1844 }
1845 }
1846
1847 pub fn add_subnet_route<A: IpAddress>(&mut self, device: D, subnet: Subnet<A>) {
1849 let entry = Entry {
1850 subnet,
1851 device,
1852 gateway: None,
1853 metric: Metric::ExplicitMetric(RawMetric(0)),
1854 route_preference: RoutePreference::Medium,
1855 };
1856 A::Version::map_ip::<_, ()>(
1857 entry,
1858 |entry_v4| {
1859 let _ = routing::testutil::add_entry(&mut self.v4.table, entry_v4)
1860 .expect("Failed to add route");
1861 },
1862 |entry_v6| {
1863 let _ = routing::testutil::add_entry(&mut self.v6.table, entry_v6)
1864 .expect("Failed to add route");
1865 },
1866 );
1867 }
1868
1869 pub fn get_device_state_mut<I: IpExt>(&mut self, device: &D) -> &mut FakeDeviceState<I> {
1871 self.inner_mut::<I>().get_device_state_mut(device)
1872 }
1873
1874 pub fn multicast_memberships<I: IpExt>(
1876 &self,
1877 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
1878 self.inner::<I>().multicast_memberships()
1879 }
1880 }
1881
1882 impl<I: IpExt, S: InnerFakeIpSocketCtx<I, D>, Meta, D: FakeStrongDeviceId, BC>
1883 MulticastMembershipHandler<I, BC> for FakeCoreCtx<S, Meta, D>
1884 {
1885 fn join_multicast_group(
1886 &mut self,
1887 bindings_ctx: &mut BC,
1888 device: &Self::DeviceId,
1889 addr: MulticastAddr<<I as Ip>::Addr>,
1890 ) {
1891 MulticastMembershipHandler::<I, BC>::join_multicast_group(
1892 self.state.fake_ip_socket_ctx_mut(),
1893 bindings_ctx,
1894 device,
1895 addr,
1896 )
1897 }
1898
1899 fn leave_multicast_group(
1900 &mut self,
1901 bindings_ctx: &mut BC,
1902 device: &Self::DeviceId,
1903 addr: MulticastAddr<<I as Ip>::Addr>,
1904 ) {
1905 MulticastMembershipHandler::<I, BC>::leave_multicast_group(
1906 self.state.fake_ip_socket_ctx_mut(),
1907 bindings_ctx,
1908 device,
1909 addr,
1910 )
1911 }
1912
1913 fn select_device_for_multicast_group(
1914 &mut self,
1915 addr: MulticastAddr<<I as Ip>::Addr>,
1916 marks: &Marks,
1917 ) -> Result<Self::DeviceId, ResolveRouteError> {
1918 MulticastMembershipHandler::<I, BC>::select_device_for_multicast_group(
1919 self.state.fake_ip_socket_ctx_mut(),
1920 addr,
1921 marks,
1922 )
1923 }
1924 }
1925
1926 impl<I: Ip, D, State: InnerFakeIpSocketCtx<I, D>, Meta> InnerFakeIpSocketCtx<I, D>
1927 for FakeCoreCtx<State, Meta, D>
1928 {
1929 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1930 self.state.fake_ip_socket_ctx_mut()
1931 }
1932 }
1933
1934 impl<I: Ip, D: FakeStrongDeviceId> InnerFakeIpSocketCtx<I, D> for FakeDualStackIpSocketCtx<D> {
1935 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1936 self.inner_mut::<I>()
1937 }
1938 }
1939
1940 #[derive(Clone, GenericOverIp)]
1942 #[generic_over_ip()]
1943 pub struct FakeDeviceConfig<D, A> {
1944 pub device: D,
1946 pub local_ips: Vec<A>,
1948 pub remote_ips: Vec<A>,
1950 }
1951
1952 pub struct FakeDeviceState<I: Ip> {
1954 pub default_hop_limit: NonZeroU8,
1956 pub addresses: Vec<SpecifiedAddr<I::Addr>>,
1958 pub multicast_groups: HashMap<MulticastAddr<I::Addr>, usize>,
1960 }
1961
1962 impl<I: Ip> FakeDeviceState<I> {
1963 pub fn is_in_multicast_group(&self, addr: &MulticastAddr<I::Addr>) -> bool {
1965 self.multicast_groups.get(addr).is_some_and(|v| *v != 0)
1966 }
1967 }
1968
1969 impl<I: IpExt, D: FakeStrongDeviceId> FakeIpSocketCtx<I, D> {
1970 pub fn new(
1973 device_configs: impl IntoIterator<Item = FakeDeviceConfig<D, SpecifiedAddr<I::Addr>>>,
1974 ) -> Self {
1975 let mut table = RoutingTable::default();
1976 let mut devices = HashMap::default();
1977 for FakeDeviceConfig { device, local_ips, remote_ips } in device_configs {
1978 for addr in remote_ips {
1979 routing::testutil::add_on_link_routing_entry(&mut table, addr, device.clone())
1980 }
1981 let state = FakeDeviceState {
1982 default_hop_limit: DEFAULT_HOP_LIMITS.unicast,
1983 addresses: local_ips,
1984 multicast_groups: Default::default(),
1985 };
1986 assert!(
1987 devices.insert(device.clone(), state).is_none(),
1988 "duplicate entries for {device:?}",
1989 );
1990 }
1991
1992 Self { table, devices, forwarding: Default::default() }
1993 }
1994
1995 pub fn get_device_state(&self, device: &D) -> &FakeDeviceState<I> {
1997 self.devices.get(device).unwrap_or_else(|| panic!("no device {device:?}"))
1998 }
1999
2000 pub fn get_device_state_mut(&mut self, device: &D) -> &mut FakeDeviceState<I> {
2002 self.devices.get_mut(device).unwrap_or_else(|| panic!("no device {device:?}"))
2003 }
2004
2005 pub(crate) fn multicast_memberships(
2006 &self,
2007 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
2008 self.devices
2009 .iter()
2010 .map(|(device, state)| {
2011 state.multicast_groups.iter().filter_map(|(group, count)| {
2012 NonZeroUsize::new(*count).map(|count| ((device.clone(), *group), count))
2013 })
2014 })
2015 .flatten()
2016 .collect()
2017 }
2018
2019 fn new_ip_socket<O>(
2020 &mut self,
2021 args: IpSocketArgs<'_, D, I, O>,
2022 ) -> Result<IpSock<I, D::Weak>, IpSockCreationError>
2023 where
2024 O: RouteResolutionOptions<I>,
2025 {
2026 let IpSocketArgs { device, local_ip, remote_ip, proto, options } = args;
2027 let device = device
2028 .as_ref()
2029 .map(|d| d.as_strong_ref().ok_or(ResolveRouteError::Unreachable))
2030 .transpose()?;
2031 let device = device.as_ref().map(|d| d.as_ref());
2032 let resolved_route =
2033 self.lookup_route(device, local_ip, remote_ip, options.transparent())?;
2034 Ok(new_ip_socket(device, resolved_route, remote_ip, proto))
2035 }
2036
2037 fn lookup_route(
2038 &mut self,
2039 device: Option<&D>,
2040 local_ip: Option<IpDeviceAddr<I::Addr>>,
2041 addr: RoutableIpAddr<I::Addr>,
2042 transparent: bool,
2043 ) -> Result<ResolvedRoute<I, D>, ResolveRouteError> {
2044 let Self { table, devices, forwarding } = self;
2045 let (destination, ()) = table
2046 .lookup_filter_map(forwarding, device, addr.addr(), |_, d| match &local_ip {
2047 None => Some(()),
2048 Some(local_ip) => {
2049 if transparent {
2050 return Some(());
2051 }
2052 devices.get(d).and_then(|state| {
2053 state.addresses.contains(local_ip.as_ref()).then_some(())
2054 })
2055 }
2056 })
2057 .next()
2058 .ok_or(ResolveRouteError::Unreachable)?;
2059
2060 let Destination { device, next_hop } = destination;
2061 let mut addrs = devices.get(device).unwrap().addresses.iter();
2062 let local_ip = match local_ip {
2063 None => {
2064 let addr = addrs.next().ok_or(ResolveRouteError::NoSrcAddr)?;
2065 IpDeviceAddr::new(addr.get()).expect("not valid device addr")
2066 }
2067 Some(local_ip) => {
2068 if !transparent {
2069 assert!(
2072 addrs.any(|a| a.get() == local_ip.addr()),
2073 "didn't find IP {:?} in {:?}",
2074 local_ip,
2075 addrs.collect::<Vec<_>>()
2076 );
2077 }
2078 local_ip
2079 }
2080 };
2081
2082 Ok(ResolvedRoute {
2083 src_addr: local_ip,
2084 device: device.clone(),
2085 local_delivery_device: None,
2086 next_hop,
2087 internal_forwarding: InternalForwarding::NotUsed,
2090 })
2091 }
2092
2093 fn resolve_send_meta<O>(
2094 &mut self,
2095 socket: &IpSock<I, D::Weak>,
2096 options: &O,
2097 ) -> Result<SendIpPacketMeta<I, D, SpecifiedAddr<I::Addr>>, IpSockSendError>
2098 where
2099 O: SendOptions<I> + RouteResolutionOptions<I>,
2100 {
2101 let IpSockDefinition { remote_ip, local_ip, device, proto } = &socket.definition;
2102 let device = device
2103 .as_ref()
2104 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
2105 .transpose()?;
2106 let ResolvedRoute {
2107 src_addr,
2108 device,
2109 next_hop,
2110 local_delivery_device: _,
2111 internal_forwarding: _,
2112 } = self.lookup_route(
2113 device.as_ref(),
2114 Some(*local_ip),
2115 *remote_ip,
2116 options.transparent(),
2117 )?;
2118
2119 let remote_ip: &SpecifiedAddr<_> = remote_ip.as_ref();
2120
2121 let destination = IpPacketDestination::from_next_hop(next_hop, *remote_ip);
2122 Ok(SendIpPacketMeta {
2123 device,
2124 src_ip: src_addr.into(),
2125 dst_ip: *remote_ip,
2126 destination,
2127 proto: *proto,
2128 ttl: options.hop_limit(remote_ip),
2129 mtu: options.mtu(),
2130 dscp_and_ecn: DscpAndEcn::default(),
2131 })
2132 }
2133 }
2134}