1use core::cmp::Ordering;
8use core::num::NonZeroU8;
9
10use log::{debug, error};
11use net_types::ip::{Ip, IpVersionMarker, Ipv6Addr, Mtu};
12use net_types::{MulticastAddress, ScopeableAddress, SpecifiedAddr, Witness as _};
13use netstack3_base::socket::{SocketIpAddr, SocketIpAddrExt as _};
14use netstack3_base::{
15 AnyDevice, CounterContext, DeviceIdContext, DeviceIdentifier, EitherDeviceId, InstantContext,
16 InterfaceProperties, IpDeviceAddr, IpExt, Marks, Mms, NetworkSerializationContext, PacketType,
17 SendFrameErrorReason, StrongDeviceIdentifier, TxMetadata, TxMetadataBindingsTypes,
18 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::{
27 BufferMut, NestablePacketBuilder as _, PacketConstraints, SerializeError, Serializer,
28};
29use packet_formats::ip::{DscpAndEcn, IpPacketBuilder as _};
30use thiserror::Error;
31
32use crate::icmp::IcmpErrorHandler;
33use crate::internal::base::{
34 FilterHandlerProvider, IpDeviceMtuContext, IpLayerIpExt, IpLayerPacketMetadata,
35 IpPacketDestination, IpSendFrameError, IpSendFrameErrorReason, ResolveRouteError,
36 SendIpPacketMeta, SplitMulticastPacketMetadata, reject_type_to_icmpv4_error,
37 reject_type_to_icmpv6_error,
38};
39use crate::internal::counters::IpCounters;
40use crate::internal::device::state::IpDeviceStateIpExt;
41use crate::internal::gso::MaybeSegmentableTransportSerializer;
42use crate::internal::routing::PacketOrigin;
43use crate::internal::routing::rules::RuleInput;
44use crate::internal::types::{InternalForwarding, ResolvedRoute, RoutableIpAddr};
45use crate::{HopLimits, NextHop};
46
47pub struct IpSocketArgs<'a, D: StrongDeviceIdentifier, I: IpExt, O> {
49 pub device: Option<EitherDeviceId<&'a D, &'a D::Weak>>,
51 pub local_ip: Option<IpDeviceAddr<I::Addr>>,
54 pub remote_ip: RoutableIpAddr<I::Addr>,
56 pub proto: I::Proto,
58 pub options: &'a O,
60}
61pub trait IpSocketHandler<I: IpExt + FilterIpExt, BC: TxMetadataBindingsTypes>:
63 DeviceIdContext<AnyDevice>
64{
65 fn new_ip_socket<O>(
80 &mut self,
81 bindings_ctx: &mut BC,
82 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
83 ) -> Result<IpSock<I, Self::WeakDeviceId>, IpSockCreationError>
84 where
85 O: RouteResolutionOptions<I>;
86
87 fn send_ip_packet<S, O>(
100 &mut self,
101 bindings_ctx: &mut BC,
102 socket: &IpSock<I, Self::WeakDeviceId>,
103 body: S,
104 options: &O,
105 tx_metadata: BC::TxMetadata,
106 ) -> Result<(), IpSockSendError>
107 where
108 S: TransportPacketSerializer<I> + MaybeSegmentableTransportSerializer,
109 S::Buffer: BufferMut,
110 O: SendOptions<I> + RouteResolutionOptions<I>;
111
112 fn confirm_reachable<O>(
118 &mut self,
119 bindings_ctx: &mut BC,
120 socket: &IpSock<I, Self::WeakDeviceId>,
121 options: &O,
122 ) where
123 O: RouteResolutionOptions<I>;
124
125 fn send_oneshot_ip_packet_with_fallible_serializer<S, E, F, O>(
148 &mut self,
149 bindings_ctx: &mut BC,
150 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
151 tx_metadata: BC::TxMetadata,
152 get_body_from_src_ip: F,
153 ) -> Result<(), SendOneShotIpPacketError<E>>
154 where
155 S: TransportPacketSerializer<I> + MaybeSegmentableTransportSerializer,
156 S::Buffer: BufferMut,
157 F: FnOnce(IpDeviceAddr<I::Addr>) -> Result<S, E>,
158 O: SendOptions<I> + RouteResolutionOptions<I>,
159 {
160 let options = args.options;
161 let tmp = self
162 .new_ip_socket(bindings_ctx, args)
163 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })?;
164 let packet = get_body_from_src_ip(*tmp.local_ip())
165 .map_err(SendOneShotIpPacketError::SerializeError)?;
166 self.send_ip_packet(bindings_ctx, &tmp, packet, options, tx_metadata)
167 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })
168 }
169
170 fn send_oneshot_ip_packet_with_dyn_fallible_serializer<S, E, F, O>(
176 &mut self,
177 bindings_ctx: &mut BC,
178 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
179 tx_metadata: BC::TxMetadata,
180 get_body_from_src_ip: F,
181 ) -> Result<(), SendOneShotIpPacketError<E>>
182 where
183 S: DynamicTransportSerializer<I>,
184 F: FnOnce(IpDeviceAddr<I::Addr>) -> Result<S, E>,
185 O: SendOptions<I> + RouteResolutionOptions<I>,
186 {
187 let options = args.options;
188 let tmp = self
189 .new_ip_socket(bindings_ctx, args)
190 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })?;
191 let mut packet = get_body_from_src_ip(*tmp.local_ip())
192 .map_err(SendOneShotIpPacketError::SerializeError)?;
193 self.send_ip_packet(
194 bindings_ctx,
195 &tmp,
196 DynTransportSerializer::new(&mut packet),
197 options,
198 tx_metadata,
199 )
200 .map_err(|err| SendOneShotIpPacketError::CreateAndSendError { err: err.into() })
201 }
202
203 fn send_oneshot_ip_packet<S, F, O>(
205 &mut self,
206 bindings_ctx: &mut BC,
207 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
208 tx_metadata: BC::TxMetadata,
209 get_body_from_src_ip: F,
210 ) -> Result<(), IpSockCreateAndSendError>
211 where
212 S: TransportPacketSerializer<I> + MaybeSegmentableTransportSerializer,
213 S::Buffer: BufferMut,
214 F: FnOnce(IpDeviceAddr<I::Addr>) -> S,
215 O: SendOptions<I> + RouteResolutionOptions<I>,
216 {
217 self.send_oneshot_ip_packet_with_fallible_serializer(
218 bindings_ctx,
219 args,
220 tx_metadata,
221 |ip| Ok::<_, !>(get_body_from_src_ip(ip)),
222 )
223 .map_err(|err| match err {
224 SendOneShotIpPacketError::CreateAndSendError { err } => err,
225 })
226 }
227
228 fn send_oneshot_ip_packet_with_dyn_serializer<S, F, O>(
234 &mut self,
235 bindings_ctx: &mut BC,
236 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
237 tx_metadata: BC::TxMetadata,
238 get_body_from_src_ip: F,
239 ) -> Result<(), IpSockCreateAndSendError>
240 where
241 S: DynamicTransportSerializer<I>,
242 F: FnOnce(IpDeviceAddr<I::Addr>) -> S,
243 O: SendOptions<I> + RouteResolutionOptions<I>,
244 {
245 self.send_oneshot_ip_packet_with_dyn_fallible_serializer(
246 bindings_ctx,
247 args,
248 tx_metadata,
249 |ip| Ok::<_, !>(get_body_from_src_ip(ip)),
250 )
251 .map_err(|err| match err {
252 SendOneShotIpPacketError::CreateAndSendError { err } => err,
253 })
254 }
255}
256
257#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
259pub enum IpSockSendError {
260 #[error("a maximum transmission unit (MTU) was exceeded")]
265 Mtu,
266 #[error("the socket is currently unroutable: {0}")]
268 Unroutable(#[from] ResolveRouteError),
269 #[error("illegal loopback address")]
272 IllegalLoopbackAddress,
273 #[error("broadcast send is not enabled for the socket")]
275 BroadcastNotAllowed,
276}
277
278impl From<SerializeError<!>> for IpSockSendError {
279 fn from(err: SerializeError<!>) -> IpSockSendError {
280 match err {
281 SerializeError::SizeLimitExceeded => IpSockSendError::Mtu,
282 }
283 }
284}
285
286impl IpSockSendError {
287 fn from_ip_send_frame(e: IpSendFrameErrorReason) -> Result<(), Self> {
292 match e {
293 IpSendFrameErrorReason::Device(d) => Self::from_send_frame(d),
294 IpSendFrameErrorReason::IllegalLoopbackAddress => Err(Self::IllegalLoopbackAddress),
295 }
296 }
297
298 fn from_send_frame(e: SendFrameErrorReason) -> Result<(), Self> {
303 match e {
304 SendFrameErrorReason::Alloc
305 | SendFrameErrorReason::QueueFull
306 | SendFrameErrorReason::AddressResolutionFailed => Ok(()),
307 SendFrameErrorReason::SizeConstraintsViolation => Err(Self::Mtu),
308 }
309 }
310}
311
312#[derive(Error, Copy, Clone, Debug)]
314pub enum IpSockCreateAndSendError {
315 #[error("cannot send via temporary socket: {0}")]
317 Send(#[from] IpSockSendError),
318 #[error("the temporary socket could not be created: {0}")]
320 Create(#[from] IpSockCreationError),
321}
322
323#[derive(Debug)]
326#[allow(missing_docs)]
327pub enum SendOneShotIpPacketError<E> {
328 CreateAndSendError { err: IpSockCreateAndSendError },
329 SerializeError(E),
330}
331
332#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
334pub enum MmsError {
335 #[error("cannot find the device: {0}")]
338 NoDevice(#[from] ResolveRouteError),
339 #[error("invalid MTU: {0:?}")]
342 MTUTooSmall(Mtu),
343}
344
345pub trait DeviceIpSocketHandler<I: IpExt, BC>: DeviceIdContext<AnyDevice> {
347 fn get_mms<O: RouteResolutionOptions<I>>(
353 &mut self,
354 bindings_ctx: &mut BC,
355 ip_sock: &IpSock<I, Self::WeakDeviceId>,
356 options: &O,
357 ) -> Result<Mms, MmsError>;
358}
359
360#[derive(Error, Copy, Clone, Debug, Eq, PartialEq)]
362pub enum IpSockCreationError {
363 #[error("a route cannot be determined: {0}")]
365 Route(#[from] ResolveRouteError),
366}
367
368#[derive(Clone, Debug)]
370#[cfg_attr(test, derive(PartialEq))]
371pub struct IpSock<I: IpExt, D> {
372 definition: IpSockDefinition<I, D>,
376}
377
378impl<I: IpExt, D> IpSock<I, D> {
379 #[cfg(any(test, feature = "testutils"))]
381 pub fn definition(&self) -> &IpSockDefinition<I, D> {
382 &self.definition
383 }
384}
385
386#[derive(Clone, Debug, PartialEq)]
390pub struct IpSockDefinition<I: IpExt, D> {
391 pub remote_ip: SocketIpAddr<I::Addr>,
393 pub local_ip: IpDeviceAddr<I::Addr>,
404 pub device: Option<D>,
406 pub proto: I::Proto,
408}
409
410impl<I: IpExt, D> IpSock<I, D> {
411 pub fn local_ip(&self) -> &IpDeviceAddr<I::Addr> {
413 &self.definition.local_ip
414 }
415 pub fn remote_ip(&self) -> &SocketIpAddr<I::Addr> {
417 &self.definition.remote_ip
418 }
419 pub fn device(&self) -> Option<&D> {
421 self.definition.device.as_ref()
422 }
423 pub fn proto(&self) -> I::Proto {
425 self.definition.proto
426 }
427}
428
429pub trait IpSocketBindingsContext<D>:
436 InstantContext
437 + FilterBindingsContext<D>
438 + TxMetadataBindingsTypes
439 + SocketOpsFilterBindingContext<D>
440{
441}
442impl<
443 D,
444 BC: InstantContext
445 + FilterBindingsContext<D>
446 + TxMetadataBindingsTypes
447 + SocketOpsFilterBindingContext<D>,
448> IpSocketBindingsContext<D> for BC
449{
450}
451
452pub trait IpSocketContext<I, BC>:
457 DeviceIdContext<AnyDevice, DeviceId: InterfaceProperties<BC::DeviceClass>>
458 + FilterHandlerProvider<I, BC>
459 + IcmpErrorHandler<I, BC>
460where
461 I: IpLayerIpExt,
462 BC: IpSocketBindingsContext<Self::DeviceId>,
463{
464 fn lookup_route(
469 &mut self,
470 bindings_ctx: &mut BC,
471 device: Option<&Self::DeviceId>,
472 src_ip: Option<IpDeviceAddr<I::Addr>>,
473 dst_ip: RoutableIpAddr<I::Addr>,
474 transparent: bool,
475 marks: &Marks,
476 ) -> Result<ResolvedRoute<I, Self::DeviceId>, ResolveRouteError>;
477
478 fn send_ip_packet<S>(
480 &mut self,
481 bindings_ctx: &mut BC,
482 meta: SendIpPacketMeta<I, &Self::DeviceId, SpecifiedAddr<I::Addr>>,
483 body: S,
484 packet_metadata: IpLayerPacketMetadata<I, Self::WeakAddressId, BC>,
485 ) -> Result<(), IpSendFrameError<S>>
486 where
487 S: TransportPacketSerializer<I> + MaybeSegmentableTransportSerializer,
488 S::Buffer: BufferMut;
489
490 fn get_loopback_device(&mut self) -> Option<Self::DeviceId>;
492
493 fn confirm_reachable(
499 &mut self,
500 bindings_ctx: &mut BC,
501 dst: SpecifiedAddr<I::Addr>,
502 input: RuleInput<'_, I, Self::DeviceId>,
503 );
504}
505
506pub trait UseIpSocketHandlerBlanket {}
511
512impl<I, BC, CC> IpSocketHandler<I, BC> for CC
513where
514 I: IpLayerIpExt + IpDeviceStateIpExt,
515 BC: IpSocketBindingsContext<Self::DeviceId>,
516 CC: IpSocketContext<I, BC> + CounterContext<IpCounters<I>> + UseIpSocketHandlerBlanket,
517 CC::DeviceId: netstack3_base::InterfaceProperties<BC::DeviceClass>,
518{
519 fn new_ip_socket<O>(
520 &mut self,
521 bindings_ctx: &mut BC,
522 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
523 ) -> Result<IpSock<I, CC::WeakDeviceId>, IpSockCreationError>
524 where
525 O: RouteResolutionOptions<I>,
526 {
527 let IpSocketArgs { device, local_ip, remote_ip, proto, options } = args;
528 let device = device
529 .as_ref()
530 .map(|d| d.as_strong_ref().ok_or(ResolveRouteError::Unreachable))
531 .transpose()?;
532 let device = device.as_ref().map(|d| d.as_ref());
533
534 let resolved_route = self.lookup_route(
539 bindings_ctx,
540 device,
541 local_ip,
542 remote_ip,
543 options.transparent(),
544 options.marks(),
545 )?;
546 Ok(new_ip_socket(device, resolved_route, remote_ip, proto))
547 }
548
549 fn send_ip_packet<S, O>(
550 &mut self,
551 bindings_ctx: &mut BC,
552 ip_sock: &IpSock<I, CC::WeakDeviceId>,
553 body: S,
554 options: &O,
555 tx_metadata: BC::TxMetadata,
556 ) -> Result<(), IpSockSendError>
557 where
558 S: TransportPacketSerializer<I> + MaybeSegmentableTransportSerializer,
559 S::Buffer: BufferMut,
560 O: SendOptions<I> + RouteResolutionOptions<I>,
561 {
562 send_ip_packet(self, bindings_ctx, ip_sock, body, options, tx_metadata)
563 }
564
565 fn confirm_reachable<O>(
566 &mut self,
567 bindings_ctx: &mut BC,
568 socket: &IpSock<I, CC::WeakDeviceId>,
569 options: &O,
570 ) where
571 O: RouteResolutionOptions<I>,
572 {
573 let bound_device = socket.device().and_then(|weak| weak.upgrade());
574 let bound_device = bound_device.as_ref();
575 let bound_address = Some((*socket.local_ip()).into());
576 let destination = (*socket.remote_ip()).into();
577 IpSocketContext::confirm_reachable(
578 self,
579 bindings_ctx,
580 destination,
581 RuleInput {
582 packet_origin: PacketOrigin::Local { bound_address, bound_device },
583 marks: options.marks(),
584 },
585 )
586 }
587}
588
589pub trait RouteResolutionOptions<I: Ip> {
601 fn transparent(&self) -> bool;
606
607 fn marks(&self) -> &Marks;
609}
610
611pub trait SendOptions<I: IpExt> {
619 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8>;
625
626 fn multicast_loop(&self) -> bool;
629
630 fn allow_broadcast(&self) -> Option<I::BroadcastMarker>;
632
633 fn dscp_and_ecn(&self) -> DscpAndEcn;
635
636 fn mtu(&self) -> Mtu;
641}
642
643#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
645pub struct DefaultIpSocketOptions;
646
647impl<I: IpExt> SendOptions<I> for DefaultIpSocketOptions {
648 fn hop_limit(&self, _destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
649 None
650 }
651
652 fn multicast_loop(&self) -> bool {
653 false
654 }
655
656 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
657 None
658 }
659
660 fn dscp_and_ecn(&self) -> DscpAndEcn {
661 DscpAndEcn::default()
662 }
663
664 fn mtu(&self) -> Mtu {
665 Mtu::no_limit()
666 }
667}
668
669impl<I: Ip> RouteResolutionOptions<I> for DefaultIpSocketOptions {
670 fn transparent(&self) -> bool {
671 false
672 }
673
674 fn marks(&self) -> &Marks {
675 &Marks::UNMARKED
676 }
677}
678
679#[allow(missing_docs)]
687pub trait DelegatedSendOptions<I: IpExt>: OptionDelegationMarker {
688 fn delegate(&self) -> &impl SendOptions<I> {
690 &DefaultIpSocketOptions
691 }
692
693 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
694 self.delegate().hop_limit(destination)
695 }
696
697 fn multicast_loop(&self) -> bool {
698 self.delegate().multicast_loop()
699 }
700
701 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
702 self.delegate().allow_broadcast()
703 }
704
705 fn dscp_and_ecn(&self) -> DscpAndEcn {
706 self.delegate().dscp_and_ecn()
707 }
708
709 fn mtu(&self) -> Mtu {
710 self.delegate().mtu()
711 }
712}
713
714impl<O: DelegatedSendOptions<I> + OptionDelegationMarker, I: IpExt> SendOptions<I> for O {
715 fn hop_limit(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
716 self.hop_limit(destination)
717 }
718
719 fn multicast_loop(&self) -> bool {
720 self.multicast_loop()
721 }
722
723 fn allow_broadcast(&self) -> Option<I::BroadcastMarker> {
724 self.allow_broadcast()
725 }
726
727 fn dscp_and_ecn(&self) -> DscpAndEcn {
728 self.dscp_and_ecn()
729 }
730
731 fn mtu(&self) -> Mtu {
732 self.mtu()
733 }
734}
735
736#[allow(missing_docs)]
744pub trait DelegatedRouteResolutionOptions<I: Ip>: OptionDelegationMarker {
745 fn delegate(&self) -> &impl RouteResolutionOptions<I> {
747 &DefaultIpSocketOptions
748 }
749
750 fn transparent(&self) -> bool {
751 self.delegate().transparent()
752 }
753
754 fn marks(&self) -> &Marks {
755 self.delegate().marks()
756 }
757}
758
759impl<O: DelegatedRouteResolutionOptions<I> + OptionDelegationMarker, I: IpExt>
760 RouteResolutionOptions<I> for O
761{
762 fn transparent(&self) -> bool {
763 self.transparent()
764 }
765
766 fn marks(&self) -> &Marks {
767 self.marks()
768 }
769}
770
771pub trait OptionDelegationMarker {}
776
777#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
779pub struct SocketHopLimits<I: Ip> {
780 pub unicast: Option<NonZeroU8>,
782 pub multicast: Option<NonZeroU8>,
786 pub version: IpVersionMarker<I>,
790}
791
792impl<I: Ip> SocketHopLimits<I> {
793 pub fn set_unicast(value: Option<NonZeroU8>) -> impl FnOnce(&mut Self) {
795 move |limits| limits.unicast = value
796 }
797
798 pub fn set_multicast(value: Option<NonZeroU8>) -> impl FnOnce(&mut Self) {
800 move |limits| limits.multicast = value
801 }
802
803 pub fn get_limits_with_defaults(&self, defaults: &HopLimits) -> HopLimits {
805 let Self { unicast, multicast, version: _ } = self;
806 HopLimits {
807 unicast: unicast.unwrap_or(defaults.unicast),
808 multicast: multicast.unwrap_or(defaults.multicast),
809 }
810 }
811
812 pub fn hop_limit_for_dst(&self, destination: &SpecifiedAddr<I::Addr>) -> Option<NonZeroU8> {
814 let Self { unicast, multicast, version: _ } = self;
815 if destination.is_multicast() { *multicast } else { *unicast }
816 }
817}
818
819fn new_ip_socket<I, D>(
820 requested_device: Option<&D>,
821 route: ResolvedRoute<I, D>,
822 remote_ip: SocketIpAddr<I::Addr>,
823 proto: I::Proto,
824) -> IpSock<I, D::Weak>
825where
826 I: IpExt,
827 D: StrongDeviceIdentifier,
828{
829 let ResolvedRoute {
833 src_addr,
834 device: route_device,
835 local_delivery_device,
836 next_hop: _,
837 internal_forwarding: _,
838 } = route;
839
840 let socket_device = (src_addr.as_ref().must_have_zone() || remote_ip.as_ref().must_have_zone())
843 .then(|| {
844 local_delivery_device.unwrap_or(route_device)
848 })
849 .as_ref()
850 .or(requested_device)
851 .map(|d| d.downgrade());
852
853 let definition =
854 IpSockDefinition { local_ip: src_addr, remote_ip, device: socket_device, proto };
855 IpSock { definition }
856}
857
858fn send_ip_packet<I, S, BC, CC, O>(
859 core_ctx: &mut CC,
860 bindings_ctx: &mut BC,
861 socket: &IpSock<I, CC::WeakDeviceId>,
862 mut body: S,
863 options: &O,
864 tx_metadata: BC::TxMetadata,
865) -> Result<(), IpSockSendError>
866where
867 I: IpLayerIpExt,
868 S: TransportPacketSerializer<I> + MaybeSegmentableTransportSerializer,
869 S::Buffer: BufferMut,
870 BC: IpSocketBindingsContext<CC::DeviceId>,
871 CC: IpSocketContext<I, BC> + CounterContext<IpCounters<I>>,
872 CC::DeviceId: netstack3_base::InterfaceProperties<BC::DeviceClass>,
873 O: SendOptions<I> + RouteResolutionOptions<I>,
874{
875 trace_duration!("ip::send_packet");
876
877 fn resolve<
880 I: IpLayerIpExt,
881 CC: IpSocketContext<I, BC>,
882 BC: IpSocketBindingsContext<CC::DeviceId>,
883 >(
884 core_ctx: &mut CC,
885 bindings_ctx: &mut BC,
886 device: &Option<CC::WeakDeviceId>,
887 local_ip: IpDeviceAddr<I::Addr>,
888 remote_ip: RoutableIpAddr<I::Addr>,
889 transparent: bool,
890 marks: &Marks,
891 ) -> Result<ResolvedRoute<I, CC::DeviceId>, IpSockSendError> {
892 let device = match device.as_ref().map(|d| d.upgrade()) {
893 Some(Some(device)) => Some(device),
894 Some(None) => return Err(ResolveRouteError::Unreachable.into()),
895 None => None,
896 };
897 let route = core_ctx
898 .lookup_route(
899 bindings_ctx,
900 device.as_ref(),
901 Some(local_ip),
902 remote_ip,
903 transparent,
904 marks,
905 )
906 .map_err(|e| IpSockSendError::Unroutable(e))?;
907 assert_eq!(local_ip, route.src_addr);
908 Ok(route)
909 }
910
911 let IpSock {
912 definition: IpSockDefinition { remote_ip, local_ip, device: socket_device, proto },
913 } = socket;
914 let ResolvedRoute {
915 src_addr: local_ip,
916 device: mut egress_device,
917 mut next_hop,
918 mut local_delivery_device,
919 mut internal_forwarding,
920 } = resolve(
921 core_ctx,
922 bindings_ctx,
923 socket_device,
924 *local_ip,
925 *remote_ip,
926 options.transparent(),
927 options.marks(),
928 )?;
929
930 if matches!(next_hop, NextHop::Broadcast(_)) && options.allow_broadcast().is_none() {
931 return Err(IpSockSendError::BroadcastNotAllowed);
932 }
933
934 let previous_dst = remote_ip.addr();
935 let mut packet = filter::TxPacket::new(local_ip.addr(), remote_ip.addr(), *proto, &mut body);
936 let gso_info = None;
939 let mut packet_metadata =
940 IpLayerPacketMetadata::new_local_tx(tx_metadata, *options.marks(), gso_info);
941
942 let filter_result = core_ctx.filter_handler().local_egress_hook(
943 bindings_ctx,
944 &mut packet,
945 &egress_device,
946 &mut packet_metadata,
947 );
948 match filter_result {
949 filter::Verdict::Stop(filter::DropOrReject::Drop) => {
950 packet_metadata.acknowledge_drop();
951 return Ok(());
952 }
953 filter::Verdict::Stop(filter::DropOrReject::Reject(reject_type)) => {
954 packet_metadata.acknowledge_drop();
955
956 let Some(icmp_error): Option<I::IcmpError> = I::map_ip_out(
957 reject_type,
958 |reject_type| reject_type_to_icmpv4_error(reject_type),
959 |reject_type| reject_type_to_icmpv6_error(reject_type),
960 ) else {
961 debug!("Unsupported reject type: {:?}", reject_type);
962 return Ok(());
963 };
964
965 let src_ip = SocketIpAddr::new_from_witness(local_ip.into_inner().get());
966 let dst_ip = *remote_ip;
967 let ttl = options.hop_limit(&dst_ip.into()).map(|v| v.into()).unwrap_or(1);
968 let packet_builder = I::PacketBuilder::new(
969 src_ip.into_inner().get(),
970 dst_ip.into_inner().get(),
971 ttl,
972 *proto,
973 );
974 let header_len = packet_builder.constraints().header_len();
975 let ip_frame = packet_builder.wrap_body(body);
976 let packet = match ip_frame.serialize_outer(
977 &mut NetworkSerializationContext::default(),
978 packet::NoReuseBufferProvider(packet::new_buf_vec),
979 ) {
980 Ok(packet) => packet,
981 Err((error, _frame)) => {
982 debug!("Failed to serialize packet {:?}", error);
983 return Ok(());
984 }
985 };
986
987 core_ctx.send_icmp_error_message(
991 bindings_ctx,
992 None,
993 None,
994 src_ip,
995 dst_ip,
996 packet,
997 icmp_error,
998 header_len,
999 *proto,
1000 &options.marks(),
1001 );
1002
1003 return Ok(());
1004 }
1005 filter::Verdict::Proceed(filter::Accept) => {}
1006 }
1007
1008 let Some(mut local_ip) = IpDeviceAddr::new(packet.src_addr()) else {
1009 packet_metadata.acknowledge_drop();
1010 return Err(IpSockSendError::Unroutable(ResolveRouteError::NoSrcAddr));
1011 };
1012 let Some(remote_ip) = RoutableIpAddr::new(packet.dst_addr()) else {
1013 packet_metadata.acknowledge_drop();
1014 return Err(IpSockSendError::Unroutable(ResolveRouteError::Unreachable));
1015 };
1016
1017 if remote_ip.addr() != previous_dst {
1020 let ResolvedRoute {
1021 src_addr: new_local_ip,
1022 device: new_device,
1023 next_hop: new_next_hop,
1024 local_delivery_device: new_local_delivery_device,
1025 internal_forwarding: new_internal_forwarding,
1026 } = match resolve(
1027 core_ctx,
1028 bindings_ctx,
1029 socket_device,
1030 local_ip,
1031 remote_ip,
1032 options.transparent(),
1033 options.marks(),
1034 ) {
1035 Ok(r) => r,
1036 Err(err) => {
1037 packet_metadata.acknowledge_drop();
1038 return Err(err);
1039 }
1040 };
1041 local_ip = new_local_ip;
1042 egress_device = new_device;
1043 next_hop = new_next_hop;
1044 local_delivery_device = new_local_delivery_device;
1045 internal_forwarding = new_internal_forwarding;
1046 }
1047
1048 match internal_forwarding {
1050 InternalForwarding::Used(ingress_device) => {
1051 match core_ctx.filter_handler().forwarding_hook(
1052 &mut packet,
1053 &ingress_device,
1054 &egress_device,
1055 &mut packet_metadata,
1056 ) {
1057 filter::Verdict::Stop(filter::DropOrReject::Drop) => {
1058 packet_metadata.acknowledge_drop();
1059 return Ok(());
1060 }
1061 filter::Verdict::Stop(filter::DropOrReject::Reject(_reject_type)) => {
1062 packet_metadata.acknowledge_drop();
1064 return Ok(());
1065 }
1066 filter::Verdict::Proceed(filter::Accept) => {}
1067 }
1068 }
1069 InternalForwarding::NotUsed => {}
1070 }
1071
1072 if let Some(socket_info) = packet_metadata.tx_metadata().socket_info() {
1073 let egress_filter_result = bindings_ctx.socket_ops_filter().on_egress(
1074 &packet,
1075 &egress_device,
1076 socket_info,
1077 packet_metadata.marks(),
1078 packet_metadata.gso_info(),
1079 );
1080
1081 match egress_filter_result {
1083 SocketEgressFilterResult::Pass { congestion: _ } => (),
1084 SocketEgressFilterResult::Drop { congestion: _ } => {
1085 core_ctx.counters().socket_egress_filter_dropped.increment();
1086 packet_metadata.acknowledge_drop();
1087 return Ok(());
1088 }
1089 }
1090 }
1091
1092 let loopback_packet_and_meta = if !egress_device.is_loopback()
1097 && ((options.multicast_loop() && remote_ip.addr().is_multicast())
1098 || next_hop.is_broadcast())
1099 {
1100 let body_copy = body.serialize_new_buf(
1101 &mut NetworkSerializationContext::default(),
1102 PacketConstraints::UNCONSTRAINED,
1103 packet::new_buf_vec,
1104 )?;
1105 let mut loopback_metadata;
1106 SplitMulticastPacketMetadata { primary: packet_metadata, secondary: loopback_metadata } =
1107 packet_metadata.split_for_multicast();
1108 loopback_metadata.set_packet_type(PacketType::Loopback);
1109 Some((
1110 RawIpBody::new(*proto, local_ip.addr(), remote_ip.addr(), body_copy),
1111 loopback_metadata,
1112 ))
1113 } else {
1114 None
1115 };
1116
1117 let destination = match &local_delivery_device {
1118 Some(d) => IpPacketDestination::Loopback(d),
1119 None => IpPacketDestination::from_next_hop(next_hop, remote_ip.into()),
1120 };
1121 let ttl = options.hop_limit(&remote_ip.into());
1122 let meta = SendIpPacketMeta {
1123 device: &egress_device,
1124 src_ip: local_ip.into(),
1125 dst_ip: remote_ip.into(),
1126 destination,
1127 ttl,
1128 proto: *proto,
1129 mtu: options.mtu(),
1130 dscp_and_ecn: options.dscp_and_ecn(),
1131 };
1132 let result =
1133 IpSocketContext::send_ip_packet(core_ctx, bindings_ctx, meta, body, packet_metadata)
1134 .or_else(|IpSendFrameError { serializer: _, error }| {
1135 IpSockSendError::from_ip_send_frame(error)
1136 });
1137
1138 match (result, loopback_packet_and_meta, core_ctx.get_loopback_device()) {
1139 (Ok(()), Some((loopback_packet, packet_metadata)), Some(loopback_device)) => {
1140 let meta = SendIpPacketMeta {
1141 device: &loopback_device,
1142 src_ip: local_ip.into(),
1143 dst_ip: remote_ip.into(),
1144 destination: IpPacketDestination::Loopback(&egress_device),
1145 ttl,
1146 proto: *proto,
1147 mtu: options.mtu(),
1148 dscp_and_ecn: options.dscp_and_ecn(),
1149 };
1150
1151 IpSocketContext::send_ip_packet(
1154 core_ctx,
1155 bindings_ctx,
1156 meta,
1157 loopback_packet,
1158 packet_metadata,
1159 )
1160 .unwrap_or_else(|IpSendFrameError { serializer: _, error }| {
1161 error!("failed to send loopback packet: {error:?}")
1162 });
1163 }
1164 (Ok(()), Some((_loopback_packet, packet_metadata)), None) => {
1165 error!("can't send a loopback packet without the loopback device");
1166 packet_metadata.acknowledge_drop();
1167 }
1168 (Err(_), Some((_loopback_packet, packet_metadata)), _) => {
1169 packet_metadata.acknowledge_drop();
1171 }
1172 (_, None, _) => (),
1173 }
1174
1175 result
1176}
1177
1178pub trait UseDeviceIpSocketHandlerBlanket {}
1183
1184impl<I, BC, CC> DeviceIpSocketHandler<I, BC> for CC
1185where
1186 I: IpLayerIpExt + IpDeviceStateIpExt,
1187 BC: IpSocketBindingsContext<CC::DeviceId>,
1188 CC: IpDeviceMtuContext<I> + IpSocketContext<I, BC> + UseDeviceIpSocketHandlerBlanket,
1189{
1190 fn get_mms<O: RouteResolutionOptions<I>>(
1191 &mut self,
1192 bindings_ctx: &mut BC,
1193 ip_sock: &IpSock<I, Self::WeakDeviceId>,
1194 options: &O,
1195 ) -> Result<Mms, MmsError> {
1196 let IpSockDefinition { remote_ip, local_ip, device, proto: _ } = &ip_sock.definition;
1197 let device = device
1198 .as_ref()
1199 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
1200 .transpose()?;
1201
1202 let ResolvedRoute {
1203 src_addr: _,
1204 local_delivery_device: _,
1205 device,
1206 next_hop: _,
1207 internal_forwarding: _,
1208 } = self
1209 .lookup_route(
1210 bindings_ctx,
1211 device.as_ref(),
1212 Some(*local_ip),
1213 *remote_ip,
1214 options.transparent(),
1215 options.marks(),
1216 )
1217 .map_err(MmsError::NoDevice)?;
1218 let mtu = self.get_mtu(&device);
1219 Mms::from_mtu::<I>(mtu, 0 ).ok_or(MmsError::MTUTooSmall(mtu))
1222 }
1223}
1224
1225pub(crate) mod ipv6_source_address_selection {
1227 use net_types::ip::{AddrSubnet, IpAddress as _};
1228
1229 use super::*;
1230
1231 use netstack3_base::Ipv6DeviceAddr;
1232
1233 pub struct SasCandidate<D> {
1235 pub addr_sub: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1237 pub assigned: bool,
1239 pub deprecated: bool,
1241 pub temporary: bool,
1243 pub device: D,
1245 }
1246
1247 pub fn select_ipv6_source_address<
1260 'a,
1261 D: PartialEq,
1262 A,
1263 I: Iterator<Item = A>,
1264 F: FnMut(&A) -> SasCandidate<D>,
1265 >(
1266 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1267 outbound_device: &D,
1268 addresses: I,
1269 mut get_candidate: F,
1270 ) -> Option<A> {
1271 addresses
1283 .map(|item| {
1284 let candidate = get_candidate(&item);
1285 (item, candidate)
1286 })
1287 .filter(|(_, candidate)| candidate.assigned)
1290 .max_by(|(_, a), (_, b)| {
1291 select_ipv6_source_address_cmp(remote_ip, outbound_device, a, b)
1292 })
1293 .map(|(item, _candidate)| item)
1294 }
1295
1296 fn select_ipv6_source_address_cmp<D: PartialEq>(
1298 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1299 outbound_device: &D,
1300 a: &SasCandidate<D>,
1301 b: &SasCandidate<D>,
1302 ) -> Ordering {
1303 let SasCandidate {
1305 addr_sub: a_addr_sub,
1306 assigned: a_assigned,
1307 deprecated: a_deprecated,
1308 temporary: a_temporary,
1309 device: a_device,
1310 } = a;
1311 let SasCandidate {
1312 addr_sub: b_addr_sub,
1313 assigned: b_assigned,
1314 deprecated: b_deprecated,
1315 temporary: b_temporary,
1316 device: b_device,
1317 } = b;
1318
1319 let a_addr = a_addr_sub.addr().into_specified();
1320 let b_addr = b_addr_sub.addr().into_specified();
1321
1322 if let Some(remote_ip) = remote_ip {
1326 debug_assert!(!(a_addr == remote_ip && b_addr == remote_ip));
1327 }
1328
1329 debug_assert!(a_assigned);
1332 debug_assert!(b_assigned);
1333
1334 rule_1(remote_ip, a_addr, b_addr)
1335 .then_with(|| rule_2(remote_ip, a_addr, b_addr))
1336 .then_with(|| rule_3(*a_deprecated, *b_deprecated))
1337 .then_with(|| rule_5(outbound_device, a_device, b_device))
1338 .then_with(|| rule_7(*a_temporary, *b_temporary))
1339 .then_with(|| rule_8(remote_ip, *a_addr_sub, *b_addr_sub))
1340 }
1341
1342 fn rule_1(
1344 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1345 a: SpecifiedAddr<Ipv6Addr>,
1346 b: SpecifiedAddr<Ipv6Addr>,
1347 ) -> Ordering {
1348 let remote_ip = match remote_ip {
1349 Some(remote_ip) => remote_ip,
1350 None => return Ordering::Equal,
1351 };
1352 if (a == remote_ip) != (b == remote_ip) {
1353 if a == remote_ip { Ordering::Greater } else { Ordering::Less }
1365 } else {
1366 Ordering::Equal
1367 }
1368 }
1369
1370 fn rule_2(
1371 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1372 a: SpecifiedAddr<Ipv6Addr>,
1373 b: SpecifiedAddr<Ipv6Addr>,
1374 ) -> Ordering {
1375 let remote_scope = match remote_ip {
1378 Some(remote_ip) => remote_ip.scope().multicast_scope_id(),
1379 None => return Ordering::Equal,
1380 };
1381 let a_scope = a.scope().multicast_scope_id();
1382 let b_scope = b.scope().multicast_scope_id();
1383 if a_scope < b_scope {
1384 if a_scope < remote_scope { Ordering::Less } else { Ordering::Greater }
1385 } else if a_scope > b_scope {
1386 if b_scope < remote_scope { Ordering::Greater } else { Ordering::Less }
1387 } else {
1388 Ordering::Equal
1389 }
1390 }
1391
1392 fn rule_3(a_deprecated: bool, b_deprecated: bool) -> Ordering {
1393 match (a_deprecated, b_deprecated) {
1394 (true, false) => Ordering::Less,
1395 (true, true) | (false, false) => Ordering::Equal,
1396 (false, true) => Ordering::Greater,
1397 }
1398 }
1399
1400 fn rule_5<D: PartialEq>(outbound_device: &D, a_device: &D, b_device: &D) -> Ordering {
1401 if (a_device == outbound_device) != (b_device == outbound_device) {
1402 if a_device == outbound_device { Ordering::Greater } else { Ordering::Less }
1404 } else {
1405 Ordering::Equal
1406 }
1407 }
1408
1409 fn rule_7(a_temporary: bool, b_temporary: bool) -> Ordering {
1411 match (a_temporary, b_temporary) {
1412 (true, false) => Ordering::Greater,
1413 (true, true) | (false, false) => Ordering::Equal,
1414 (false, true) => Ordering::Less,
1415 }
1416 }
1417
1418 fn rule_8(
1419 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1420 a: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1421 b: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1422 ) -> Ordering {
1423 let remote_ip = match remote_ip {
1424 Some(remote_ip) => remote_ip,
1425 None => return Ordering::Equal,
1426 };
1427 fn common_prefix_len(
1437 src: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1438 dst: SpecifiedAddr<Ipv6Addr>,
1439 ) -> u8 {
1440 core::cmp::min(src.addr().common_prefix_len(&dst), src.subnet().prefix())
1441 }
1442
1443 common_prefix_len(a, remote_ip).cmp(&common_prefix_len(b, remote_ip))
1455 }
1456
1457 #[cfg(test)]
1458 mod tests {
1459 use net_declare::net_ip_v6;
1460
1461 use super::*;
1462
1463 #[test]
1464 fn test_select_ipv6_source_address() {
1465 let remote = SpecifiedAddr::new(net_ip_v6!("2001:0db8:1::")).unwrap();
1469 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1470 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1471 let link_local_remote = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:42")).unwrap();
1472 let link_local = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:4")).unwrap();
1473 let dev0 = &0;
1474 let dev1 = &1;
1475 let dev2 = &2;
1476
1477 assert_eq!(rule_1(Some(remote), remote, local0), Ordering::Greater);
1479 assert_eq!(rule_1(Some(remote), local0, remote), Ordering::Less);
1480 assert_eq!(rule_1(Some(remote), local0, local1), Ordering::Equal);
1481 assert_eq!(rule_1(None, local0, local1), Ordering::Equal);
1482
1483 assert_eq!(rule_2(Some(remote), local0, local1), Ordering::Equal);
1485 assert_eq!(rule_2(Some(remote), local1, local0), Ordering::Equal);
1486 assert_eq!(rule_2(Some(remote), local0, link_local), Ordering::Greater);
1487 assert_eq!(rule_2(Some(remote), link_local, local0), Ordering::Less);
1488 assert_eq!(rule_2(Some(link_local_remote), local0, link_local), Ordering::Less);
1489 assert_eq!(rule_2(Some(link_local_remote), link_local, local0), Ordering::Greater);
1490 assert_eq!(rule_1(None, local0, link_local), Ordering::Equal);
1491
1492 assert_eq!(rule_3(false, true), Ordering::Greater);
1494 assert_eq!(rule_3(true, false), Ordering::Less);
1495 assert_eq!(rule_3(true, true), Ordering::Equal);
1496 assert_eq!(rule_3(false, false), Ordering::Equal);
1497
1498 assert_eq!(rule_5(dev0, dev0, dev2), Ordering::Greater);
1500 assert_eq!(rule_5(dev0, dev2, dev0), Ordering::Less);
1501 assert_eq!(rule_5(dev0, dev0, dev0), Ordering::Equal);
1502 assert_eq!(rule_5(dev0, dev2, dev2), Ordering::Equal);
1503
1504 assert_eq!(rule_7(true, false), Ordering::Greater);
1506 assert_eq!(rule_7(false, true), Ordering::Less);
1507 assert_eq!(rule_7(true, true), Ordering::Equal);
1508 assert_eq!(rule_7(false, false), Ordering::Equal);
1509
1510 {
1512 let new_addr_entry = |addr, prefix_len| AddrSubnet::new(addr, prefix_len).unwrap();
1513
1514 let remote = SpecifiedAddr::new(net_ip_v6!("1111::")).unwrap();
1520 let local0 = new_addr_entry(net_ip_v6!("1110::"), 64);
1522 let local1 = new_addr_entry(net_ip_v6!("1100::"), 64);
1524
1525 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Greater);
1526 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Less);
1527 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1528 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1529 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1530
1531 let local0 = new_addr_entry(net_ip_v6!("1110::"), 8);
1536 let local1 = new_addr_entry(net_ip_v6!("1100::"), 8);
1538
1539 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Equal);
1540 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Equal);
1541 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1542 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1543 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1544 }
1545
1546 {
1547 let new_addr_entry = |addr, device| SasCandidate {
1548 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1549 deprecated: false,
1550 assigned: true,
1551 temporary: false,
1552 device,
1553 };
1554
1555 assert_eq!(
1557 select_ipv6_source_address_cmp(
1558 Some(remote),
1559 dev0,
1560 &new_addr_entry(*local0, *dev1),
1561 &new_addr_entry(*local1, *dev2),
1562 ),
1563 Ordering::Equal
1564 );
1565 }
1566 }
1567
1568 #[test]
1569 fn test_select_ipv6_source_address_no_remote() {
1570 let dev0 = &0;
1573 let dev1 = &1;
1574 let dev2 = &2;
1575
1576 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1577 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1578
1579 let new_addr_entry = |addr, deprecated, device| SasCandidate {
1580 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1581 deprecated,
1582 assigned: true,
1583 temporary: false,
1584 device,
1585 };
1586
1587 assert_eq!(
1589 select_ipv6_source_address_cmp(
1590 None,
1591 dev0,
1592 &new_addr_entry(*local0, false, *dev1),
1593 &new_addr_entry(*local1, true, *dev2),
1594 ),
1595 Ordering::Greater
1596 );
1597
1598 assert_eq!(
1600 select_ipv6_source_address_cmp(
1601 None,
1602 dev0,
1603 &new_addr_entry(*local0, false, *dev0),
1604 &new_addr_entry(*local1, false, *dev1),
1605 ),
1606 Ordering::Greater
1607 );
1608 }
1609 }
1610}
1611
1612#[cfg(any(test, feature = "testutils"))]
1614pub(crate) mod testutil {
1615 use alloc::boxed::Box;
1616 use alloc::vec::Vec;
1617 use core::num::NonZeroUsize;
1618
1619 use crate::internal::types::RoutePreference;
1620 use derivative::Derivative;
1621 use net_types::MulticastAddr;
1622 use net_types::ip::{GenericOverIp, IpAddr, IpAddress, Ipv4, Ipv4Addr, Ipv6, Subnet};
1623 use netstack3_base::testutil::{FakeCoreCtx, FakeStrongDeviceId, FakeWeakDeviceId};
1624 use netstack3_base::{SendFrameContext, SendFrameError};
1625 use netstack3_filter::Tuple;
1626 use netstack3_hashmap::HashMap;
1627
1628 use super::*;
1629 use crate::internal::base::{
1630 BaseTransportIpContext, DEFAULT_HOP_LIMITS, HopLimits, MulticastMembershipHandler,
1631 };
1632 use crate::internal::routing::testutil::FakeIpRoutingCtx;
1633 use crate::internal::routing::{self, RoutingTable};
1634 use crate::internal::types::{Destination, Entry, Metric, RawMetric};
1635
1636 #[derive(Derivative, GenericOverIp)]
1639 #[generic_over_ip(I, Ip)]
1640 #[derivative(Default(bound = ""))]
1641 pub struct FakeIpSocketCtx<I: Ip, D> {
1642 pub(crate) table: RoutingTable<I, D>,
1643 forwarding: FakeIpRoutingCtx<D>,
1644 devices: HashMap<D, FakeDeviceState<I>>,
1645 }
1646
1647 pub trait InnerFakeIpSocketCtx<I: Ip, D> {
1650 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D>;
1652 }
1653
1654 impl<I: Ip, D> InnerFakeIpSocketCtx<I, D> for FakeIpSocketCtx<I, D> {
1655 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1656 self
1657 }
1658 }
1659
1660 impl<I: IpExt, D: FakeStrongDeviceId, BC> BaseTransportIpContext<I, BC> for FakeIpSocketCtx<I, D> {
1661 fn get_default_hop_limits(&mut self, device: Option<&D>) -> HopLimits {
1662 device.map_or(DEFAULT_HOP_LIMITS, |device| {
1663 let hop_limit = self.get_device_state(device).default_hop_limit;
1664 HopLimits { unicast: hop_limit, multicast: DEFAULT_HOP_LIMITS.multicast }
1665 })
1666 }
1667
1668 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1669
1670 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1671 &mut self,
1672 addr: SpecifiedAddr<I::Addr>,
1673 cb: F,
1674 ) -> O {
1675 cb(Box::new(self.devices.iter().filter_map(move |(device, state)| {
1676 state.addresses.contains(&addr).then(|| device.clone())
1677 })))
1678 }
1679
1680 fn get_original_destination(&mut self, _tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1681 unimplemented!()
1682 }
1683 }
1684
1685 impl<I: IpExt, D: FakeStrongDeviceId> DeviceIdContext<AnyDevice> for FakeIpSocketCtx<I, D> {
1686 type DeviceId = D;
1687 type WeakDeviceId = D::Weak;
1688 }
1689
1690 impl<I, State, D, Meta, BC> IpSocketHandler<I, BC> for FakeCoreCtx<State, Meta, D>
1691 where
1692 I: IpExt + FilterIpExt,
1693 State: InnerFakeIpSocketCtx<I, D>,
1694 D: FakeStrongDeviceId,
1695 BC: TxMetadataBindingsTypes,
1696 FakeCoreCtx<State, Meta, D>:
1697 SendFrameContext<BC, SendIpPacketMeta<I, Self::DeviceId, SpecifiedAddr<I::Addr>>>,
1698 {
1699 fn new_ip_socket<O>(
1700 &mut self,
1701 _bindings_ctx: &mut BC,
1702 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
1703 ) -> Result<IpSock<I, Self::WeakDeviceId>, IpSockCreationError>
1704 where
1705 O: RouteResolutionOptions<I>,
1706 {
1707 self.state.fake_ip_socket_ctx_mut().new_ip_socket(args)
1708 }
1709
1710 fn send_ip_packet<S, O>(
1711 &mut self,
1712 bindings_ctx: &mut BC,
1713 socket: &IpSock<I, Self::WeakDeviceId>,
1714 body: S,
1715 options: &O,
1716 _tx_meta: BC::TxMetadata,
1719 ) -> Result<(), IpSockSendError>
1720 where
1721 S: TransportPacketSerializer<I> + MaybeSegmentableTransportSerializer,
1722 S::Buffer: BufferMut,
1723 O: SendOptions<I> + RouteResolutionOptions<I>,
1724 {
1725 let meta = self.state.fake_ip_socket_ctx_mut().resolve_send_meta(socket, options)?;
1726 self.send_frame(bindings_ctx, meta, body).or_else(
1727 |SendFrameError { serializer: _, error }| IpSockSendError::from_send_frame(error),
1728 )
1729 }
1730
1731 fn confirm_reachable<O>(
1732 &mut self,
1733 _bindings_ctx: &mut BC,
1734 _socket: &IpSock<I, Self::WeakDeviceId>,
1735 _options: &O,
1736 ) {
1737 }
1738 }
1739
1740 impl<I: IpExt, D: FakeStrongDeviceId, BC> MulticastMembershipHandler<I, BC>
1741 for FakeIpSocketCtx<I, D>
1742 {
1743 fn join_multicast_group(
1744 &mut self,
1745 _bindings_ctx: &mut BC,
1746 device: &Self::DeviceId,
1747 addr: MulticastAddr<<I as Ip>::Addr>,
1748 ) {
1749 let value = self.get_device_state_mut(device).multicast_groups.entry(addr).or_insert(0);
1750 *value = value.checked_add(1).unwrap();
1751 }
1752
1753 fn leave_multicast_group(
1754 &mut self,
1755 _bindings_ctx: &mut BC,
1756 device: &Self::DeviceId,
1757 addr: MulticastAddr<<I as Ip>::Addr>,
1758 ) {
1759 let value = self
1760 .get_device_state_mut(device)
1761 .multicast_groups
1762 .get_mut(&addr)
1763 .unwrap_or_else(|| panic!("no entry for {addr} on {device:?}"));
1764 *value = value.checked_sub(1).unwrap();
1765 }
1766
1767 fn select_device_for_multicast_group(
1768 &mut self,
1769 addr: MulticastAddr<<I as Ip>::Addr>,
1770 _marks: &Marks,
1771 ) -> Result<Self::DeviceId, ResolveRouteError> {
1772 let remote_ip = SocketIpAddr::new_from_multicast(addr);
1773 self.lookup_route(None, None, remote_ip, false)
1774 .map(|ResolvedRoute { device, .. }| device)
1775 }
1776 }
1777
1778 impl<I, BC, D, State, Meta> BaseTransportIpContext<I, BC> for FakeCoreCtx<State, Meta, D>
1779 where
1780 I: IpExt + FilterIpExt,
1781 D: FakeStrongDeviceId,
1782 State: InnerFakeIpSocketCtx<I, D>,
1783 BC: TxMetadataBindingsTypes,
1784 Self: IpSocketHandler<I, BC, DeviceId = D, WeakDeviceId = FakeWeakDeviceId<D>>,
1785 {
1786 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1787
1788 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1789 &mut self,
1790 addr: SpecifiedAddr<I::Addr>,
1791 cb: F,
1792 ) -> O {
1793 BaseTransportIpContext::<I, BC>::with_devices_with_assigned_addr(
1794 self.state.fake_ip_socket_ctx_mut(),
1795 addr,
1796 cb,
1797 )
1798 }
1799
1800 fn get_default_hop_limits(&mut self, device: Option<&Self::DeviceId>) -> HopLimits {
1801 BaseTransportIpContext::<I, BC>::get_default_hop_limits(
1802 self.state.fake_ip_socket_ctx_mut(),
1803 device,
1804 )
1805 }
1806
1807 fn get_original_destination(&mut self, tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1808 BaseTransportIpContext::<I, BC>::get_original_destination(
1809 self.state.fake_ip_socket_ctx_mut(),
1810 tuple,
1811 )
1812 }
1813 }
1814
1815 #[derive(Derivative)]
1817 #[derivative(Default(bound = ""))]
1818 pub struct FakeDualStackIpSocketCtx<D> {
1819 v4: FakeIpSocketCtx<Ipv4, D>,
1820 v6: FakeIpSocketCtx<Ipv6, D>,
1821 }
1822
1823 impl<D: FakeStrongDeviceId> FakeDualStackIpSocketCtx<D> {
1824 pub fn new<A: Into<SpecifiedAddr<IpAddr>>>(
1826 devices: impl IntoIterator<Item = FakeDeviceConfig<D, A>>,
1827 ) -> Self {
1828 let partition =
1829 |v: Vec<A>| -> (Vec<SpecifiedAddr<Ipv4Addr>>, Vec<SpecifiedAddr<Ipv6Addr>>) {
1830 v.into_iter().fold((Vec::new(), Vec::new()), |(mut v4, mut v6), i| {
1831 match IpAddr::from(i.into()) {
1832 IpAddr::V4(a) => v4.push(a),
1833 IpAddr::V6(a) => v6.push(a),
1834 }
1835 (v4, v6)
1836 })
1837 };
1838
1839 let (v4, v6): (Vec<_>, Vec<_>) = devices
1840 .into_iter()
1841 .map(|FakeDeviceConfig { device, local_ips, remote_ips }| {
1842 let (local_v4, local_v6) = partition(local_ips);
1843 let (remote_v4, remote_v6) = partition(remote_ips);
1844 (
1845 FakeDeviceConfig {
1846 device: device.clone(),
1847 local_ips: local_v4,
1848 remote_ips: remote_v4,
1849 },
1850 FakeDeviceConfig { device, local_ips: local_v6, remote_ips: remote_v6 },
1851 )
1852 })
1853 .unzip();
1854 Self { v4: FakeIpSocketCtx::new(v4), v6: FakeIpSocketCtx::new(v6) }
1855 }
1856
1857 pub fn inner_mut<I: Ip>(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1859 I::map_ip_out(self, |s| &mut s.v4, |s| &mut s.v6)
1860 }
1861
1862 fn inner<I: Ip>(&self) -> &FakeIpSocketCtx<I, D> {
1863 I::map_ip_out(self, |s| &s.v4, |s| &s.v6)
1864 }
1865
1866 pub fn add_route(&mut self, device: D, ip: SpecifiedAddr<IpAddr>) {
1868 match IpAddr::from(ip) {
1869 IpAddr::V4(ip) => {
1870 routing::testutil::add_on_link_routing_entry(&mut self.v4.table, ip, device)
1871 }
1872 IpAddr::V6(ip) => {
1873 routing::testutil::add_on_link_routing_entry(&mut self.v6.table, ip, device)
1874 }
1875 }
1876 }
1877
1878 pub fn add_subnet_route<A: IpAddress>(&mut self, device: D, subnet: Subnet<A>) {
1880 let entry = Entry {
1881 subnet,
1882 device,
1883 gateway: None,
1884 metric: Metric::ExplicitMetric(RawMetric(0)),
1885 route_preference: RoutePreference::Medium,
1886 };
1887 A::Version::map_ip::<_, ()>(
1888 entry,
1889 |entry_v4| {
1890 let _ = routing::testutil::add_entry(&mut self.v4.table, entry_v4)
1891 .expect("Failed to add route");
1892 },
1893 |entry_v6| {
1894 let _ = routing::testutil::add_entry(&mut self.v6.table, entry_v6)
1895 .expect("Failed to add route");
1896 },
1897 );
1898 }
1899
1900 pub fn get_device_state_mut<I: IpExt>(&mut self, device: &D) -> &mut FakeDeviceState<I> {
1902 self.inner_mut::<I>().get_device_state_mut(device)
1903 }
1904
1905 pub fn multicast_memberships<I: IpExt>(
1907 &self,
1908 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
1909 self.inner::<I>().multicast_memberships()
1910 }
1911 }
1912
1913 impl<I: IpExt, S: InnerFakeIpSocketCtx<I, D>, Meta, D: FakeStrongDeviceId, BC>
1914 MulticastMembershipHandler<I, BC> for FakeCoreCtx<S, Meta, D>
1915 {
1916 fn join_multicast_group(
1917 &mut self,
1918 bindings_ctx: &mut BC,
1919 device: &Self::DeviceId,
1920 addr: MulticastAddr<<I as Ip>::Addr>,
1921 ) {
1922 MulticastMembershipHandler::<I, BC>::join_multicast_group(
1923 self.state.fake_ip_socket_ctx_mut(),
1924 bindings_ctx,
1925 device,
1926 addr,
1927 )
1928 }
1929
1930 fn leave_multicast_group(
1931 &mut self,
1932 bindings_ctx: &mut BC,
1933 device: &Self::DeviceId,
1934 addr: MulticastAddr<<I as Ip>::Addr>,
1935 ) {
1936 MulticastMembershipHandler::<I, BC>::leave_multicast_group(
1937 self.state.fake_ip_socket_ctx_mut(),
1938 bindings_ctx,
1939 device,
1940 addr,
1941 )
1942 }
1943
1944 fn select_device_for_multicast_group(
1945 &mut self,
1946 addr: MulticastAddr<<I as Ip>::Addr>,
1947 marks: &Marks,
1948 ) -> Result<Self::DeviceId, ResolveRouteError> {
1949 MulticastMembershipHandler::<I, BC>::select_device_for_multicast_group(
1950 self.state.fake_ip_socket_ctx_mut(),
1951 addr,
1952 marks,
1953 )
1954 }
1955 }
1956
1957 impl<I: Ip, D, State: InnerFakeIpSocketCtx<I, D>, Meta> InnerFakeIpSocketCtx<I, D>
1958 for FakeCoreCtx<State, Meta, D>
1959 {
1960 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1961 self.state.fake_ip_socket_ctx_mut()
1962 }
1963 }
1964
1965 impl<I: Ip, D: FakeStrongDeviceId> InnerFakeIpSocketCtx<I, D> for FakeDualStackIpSocketCtx<D> {
1966 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1967 self.inner_mut::<I>()
1968 }
1969 }
1970
1971 #[derive(Clone, GenericOverIp)]
1973 #[generic_over_ip()]
1974 pub struct FakeDeviceConfig<D, A> {
1975 pub device: D,
1977 pub local_ips: Vec<A>,
1979 pub remote_ips: Vec<A>,
1981 }
1982
1983 pub struct FakeDeviceState<I: Ip> {
1985 pub default_hop_limit: NonZeroU8,
1987 pub addresses: Vec<SpecifiedAddr<I::Addr>>,
1989 pub multicast_groups: HashMap<MulticastAddr<I::Addr>, usize>,
1991 }
1992
1993 impl<I: Ip> FakeDeviceState<I> {
1994 pub fn is_in_multicast_group(&self, addr: &MulticastAddr<I::Addr>) -> bool {
1996 self.multicast_groups.get(addr).is_some_and(|v| *v != 0)
1997 }
1998 }
1999
2000 impl<I: IpExt, D: FakeStrongDeviceId> FakeIpSocketCtx<I, D> {
2001 pub fn new(
2004 device_configs: impl IntoIterator<Item = FakeDeviceConfig<D, SpecifiedAddr<I::Addr>>>,
2005 ) -> Self {
2006 let mut table = RoutingTable::default();
2007 let mut devices = HashMap::default();
2008 for FakeDeviceConfig { device, local_ips, remote_ips } in device_configs {
2009 for addr in remote_ips {
2010 routing::testutil::add_on_link_routing_entry(&mut table, addr, device.clone())
2011 }
2012 let state = FakeDeviceState {
2013 default_hop_limit: DEFAULT_HOP_LIMITS.unicast,
2014 addresses: local_ips,
2015 multicast_groups: Default::default(),
2016 };
2017 assert!(
2018 devices.insert(device.clone(), state).is_none(),
2019 "duplicate entries for {device:?}",
2020 );
2021 }
2022
2023 Self { table, devices, forwarding: Default::default() }
2024 }
2025
2026 pub fn get_device_state(&self, device: &D) -> &FakeDeviceState<I> {
2028 self.devices.get(device).unwrap_or_else(|| panic!("no device {device:?}"))
2029 }
2030
2031 pub fn get_device_state_mut(&mut self, device: &D) -> &mut FakeDeviceState<I> {
2033 self.devices.get_mut(device).unwrap_or_else(|| panic!("no device {device:?}"))
2034 }
2035
2036 pub(crate) fn multicast_memberships(
2037 &self,
2038 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
2039 self.devices
2040 .iter()
2041 .map(|(device, state)| {
2042 state.multicast_groups.iter().filter_map(|(group, count)| {
2043 NonZeroUsize::new(*count).map(|count| ((device.clone(), *group), count))
2044 })
2045 })
2046 .flatten()
2047 .collect()
2048 }
2049
2050 fn new_ip_socket<O>(
2051 &mut self,
2052 args: IpSocketArgs<'_, D, I, O>,
2053 ) -> Result<IpSock<I, D::Weak>, IpSockCreationError>
2054 where
2055 O: RouteResolutionOptions<I>,
2056 {
2057 let IpSocketArgs { device, local_ip, remote_ip, proto, options } = args;
2058 let device = device
2059 .as_ref()
2060 .map(|d| d.as_strong_ref().ok_or(ResolveRouteError::Unreachable))
2061 .transpose()?;
2062 let device = device.as_ref().map(|d| d.as_ref());
2063 let resolved_route =
2064 self.lookup_route(device, local_ip, remote_ip, options.transparent())?;
2065 Ok(new_ip_socket(device, resolved_route, remote_ip, proto))
2066 }
2067
2068 fn lookup_route(
2069 &mut self,
2070 device: Option<&D>,
2071 local_ip: Option<IpDeviceAddr<I::Addr>>,
2072 addr: RoutableIpAddr<I::Addr>,
2073 transparent: bool,
2074 ) -> Result<ResolvedRoute<I, D>, ResolveRouteError> {
2075 let Self { table, devices, forwarding } = self;
2076 let (destination, ()) = table
2077 .lookup_filter_map(forwarding, device, addr.addr(), |_, d| match &local_ip {
2078 None => Some(()),
2079 Some(local_ip) => {
2080 if transparent {
2081 return Some(());
2082 }
2083 devices.get(d).and_then(|state| {
2084 state.addresses.contains(local_ip.as_ref()).then_some(())
2085 })
2086 }
2087 })
2088 .next()
2089 .ok_or(ResolveRouteError::Unreachable)?;
2090
2091 let Destination { device, next_hop } = destination;
2092 let mut addrs = devices.get(device).unwrap().addresses.iter();
2093 let local_ip = match local_ip {
2094 None => {
2095 let addr = addrs.next().ok_or(ResolveRouteError::NoSrcAddr)?;
2096 IpDeviceAddr::new(addr.get()).expect("not valid device addr")
2097 }
2098 Some(local_ip) => {
2099 if !transparent {
2100 assert!(
2103 addrs.any(|a| a.get() == local_ip.addr()),
2104 "didn't find IP {:?} in {:?}",
2105 local_ip,
2106 addrs.collect::<Vec<_>>()
2107 );
2108 }
2109 local_ip
2110 }
2111 };
2112
2113 Ok(ResolvedRoute {
2114 src_addr: local_ip,
2115 device: device.clone(),
2116 local_delivery_device: None,
2117 next_hop,
2118 internal_forwarding: InternalForwarding::NotUsed,
2121 })
2122 }
2123
2124 fn resolve_send_meta<O>(
2125 &mut self,
2126 socket: &IpSock<I, D::Weak>,
2127 options: &O,
2128 ) -> Result<SendIpPacketMeta<I, D, SpecifiedAddr<I::Addr>>, IpSockSendError>
2129 where
2130 O: SendOptions<I> + RouteResolutionOptions<I>,
2131 {
2132 let IpSockDefinition { remote_ip, local_ip, device, proto } = &socket.definition;
2133 let device = device
2134 .as_ref()
2135 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
2136 .transpose()?;
2137 let ResolvedRoute {
2138 src_addr,
2139 device,
2140 next_hop,
2141 local_delivery_device: _,
2142 internal_forwarding: _,
2143 } = self.lookup_route(
2144 device.as_ref(),
2145 Some(*local_ip),
2146 *remote_ip,
2147 options.transparent(),
2148 )?;
2149
2150 let remote_ip: &SpecifiedAddr<_> = remote_ip.as_ref();
2151
2152 let destination = IpPacketDestination::from_next_hop(next_hop, *remote_ip);
2153 Ok(SendIpPacketMeta {
2154 device,
2155 src_ip: src_addr.into(),
2156 dst_ip: *remote_ip,
2157 destination,
2158 proto: *proto,
2159 ttl: options.hop_limit(remote_ip),
2160 mtu: options.mtu(),
2161 dscp_and_ecn: DscpAndEcn::default(),
2162 })
2163 }
2164 }
2165}