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