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