1use core::cmp::Ordering;
8use core::num::NonZeroU8;
9
10use log::{debug, error};
11use net_types::ip::{Ip, IpVersionMarker, Ipv6Addr, Mtu};
12use net_types::{MulticastAddress, ScopeableAddress, SpecifiedAddr, Witness as _};
13use netstack3_base::socket::{SocketIpAddr, SocketIpAddrExt as _};
14use netstack3_base::{
15 AnyDevice, CounterContext, DeviceIdContext, DeviceIdentifier, EitherDeviceId, InstantContext,
16 InterfaceProperties, IpDeviceAddr, IpExt, Marks, Mms, NetworkSerializationContext,
17 SendFrameErrorReason, StrongDeviceIdentifier, TxMetadata, TxMetadataBindingsTypes,
18 WeakDeviceIdentifier,
19};
20use netstack3_filter::{
21 self as filter, DynTransportSerializer, DynamicTransportSerializer, FilterBindingsContext,
22 FilterHandler as _, FilterIpExt, RawIpBody, SocketEgressFilterResult, SocketOpsFilter,
23 SocketOpsFilterBindingContext, TransportPacketSerializer,
24};
25use netstack3_trace::trace_duration;
26use packet::{
27 BufferMut, NestablePacketBuilder as _, PacketConstraints, SerializeError, Serializer,
28};
29use packet_formats::ip::{DscpAndEcn, IpPacketBuilder as _};
30use thiserror::Error;
31
32use crate::icmp::IcmpErrorHandler;
33use crate::internal::base::{
34 FilterHandlerProvider, IpDeviceMtuContext, IpLayerIpExt, IpLayerPacketMetadata,
35 IpPacketDestination, IpSendFrameError, IpSendFrameErrorReason, ResolveRouteError,
36 SendIpPacketMeta, SplitMulticastPacketMetadata, reject_type_to_icmpv4_error,
37 reject_type_to_icmpv6_error,
38};
39use crate::internal::counters::IpCounters;
40use crate::internal::device::state::IpDeviceStateIpExt;
41use crate::internal::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::<_, !>(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::<_, !>(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<!>> for IpSockSendError {
278 fn from(err: SerializeError<!>) -> 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 gso_info = None;
938 let mut packet_metadata =
939 IpLayerPacketMetadata::new_local_tx(tx_metadata, *options.marks(), gso_info);
940
941 let filter_result = core_ctx.filter_handler().local_egress_hook(
942 bindings_ctx,
943 &mut packet,
944 &egress_device,
945 &mut packet_metadata,
946 );
947 match filter_result {
948 filter::Verdict::Stop(filter::DropOrReject::Drop) => {
949 packet_metadata.acknowledge_drop();
950 return Ok(());
951 }
952 filter::Verdict::Stop(filter::DropOrReject::Reject(reject_type)) => {
953 packet_metadata.acknowledge_drop();
954
955 let Some(icmp_error): Option<I::IcmpError> = I::map_ip_out(
956 reject_type,
957 |reject_type| reject_type_to_icmpv4_error(reject_type),
958 |reject_type| reject_type_to_icmpv6_error(reject_type),
959 ) else {
960 debug!("Unsupported reject type: {:?}", reject_type);
961 return Ok(());
962 };
963
964 let src_ip = SocketIpAddr::new_from_witness(local_ip.into_inner().get());
965 let dst_ip = *remote_ip;
966 let ttl = options.hop_limit(&dst_ip.into()).map(|v| v.into()).unwrap_or(1);
967 let packet_builder = I::PacketBuilder::new(
968 src_ip.into_inner().get(),
969 dst_ip.into_inner().get(),
970 ttl,
971 *proto,
972 );
973 let header_len = packet_builder.constraints().header_len();
974 let ip_frame = packet_builder.wrap_body(body);
975 let packet = match ip_frame.serialize_outer(
976 &mut NetworkSerializationContext::default(),
977 packet::NoReuseBufferProvider(packet::new_buf_vec),
978 ) {
979 Ok(packet) => packet,
980 Err((error, _frame)) => {
981 debug!("Failed to serialize packet {:?}", error);
982 return Ok(());
983 }
984 };
985
986 core_ctx.send_icmp_error_message(
990 bindings_ctx,
991 None,
992 None,
993 src_ip,
994 dst_ip,
995 packet,
996 icmp_error,
997 header_len,
998 *proto,
999 &options.marks(),
1000 );
1001
1002 return Ok(());
1003 }
1004 filter::Verdict::Proceed(filter::Accept) => {}
1005 }
1006
1007 let Some(mut local_ip) = IpDeviceAddr::new(packet.src_addr()) else {
1008 packet_metadata.acknowledge_drop();
1009 return Err(IpSockSendError::Unroutable(ResolveRouteError::NoSrcAddr));
1010 };
1011 let Some(remote_ip) = RoutableIpAddr::new(packet.dst_addr()) else {
1012 packet_metadata.acknowledge_drop();
1013 return Err(IpSockSendError::Unroutable(ResolveRouteError::Unreachable));
1014 };
1015
1016 if remote_ip.addr() != previous_dst {
1019 let ResolvedRoute {
1020 src_addr: new_local_ip,
1021 device: new_device,
1022 next_hop: new_next_hop,
1023 local_delivery_device: new_local_delivery_device,
1024 internal_forwarding: new_internal_forwarding,
1025 } = match resolve(
1026 core_ctx,
1027 bindings_ctx,
1028 socket_device,
1029 local_ip,
1030 remote_ip,
1031 options.transparent(),
1032 options.marks(),
1033 ) {
1034 Ok(r) => r,
1035 Err(err) => {
1036 packet_metadata.acknowledge_drop();
1037 return Err(err);
1038 }
1039 };
1040 local_ip = new_local_ip;
1041 egress_device = new_device;
1042 next_hop = new_next_hop;
1043 local_delivery_device = new_local_delivery_device;
1044 internal_forwarding = new_internal_forwarding;
1045 }
1046
1047 match internal_forwarding {
1049 InternalForwarding::Used(ingress_device) => {
1050 match core_ctx.filter_handler().forwarding_hook(
1051 &mut packet,
1052 &ingress_device,
1053 &egress_device,
1054 &mut packet_metadata,
1055 ) {
1056 filter::Verdict::Stop(filter::DropOrReject::Drop) => {
1057 packet_metadata.acknowledge_drop();
1058 return Ok(());
1059 }
1060 filter::Verdict::Stop(filter::DropOrReject::Reject(_reject_type)) => {
1061 packet_metadata.acknowledge_drop();
1063 return Ok(());
1064 }
1065 filter::Verdict::Proceed(filter::Accept) => {}
1066 }
1067 }
1068 InternalForwarding::NotUsed => {}
1069 }
1070
1071 if let Some(socket_info) = packet_metadata.tx_metadata().socket_info() {
1072 let egress_filter_result = bindings_ctx.socket_ops_filter().on_egress(
1073 &packet,
1074 &egress_device,
1075 socket_info,
1076 packet_metadata.marks(),
1077 );
1078
1079 match egress_filter_result {
1081 SocketEgressFilterResult::Pass { congestion: _ } => (),
1082 SocketEgressFilterResult::Drop { congestion: _ } => {
1083 core_ctx.counters().socket_egress_filter_dropped.increment();
1084 packet_metadata.acknowledge_drop();
1085 return Ok(());
1086 }
1087 }
1088 }
1089
1090 let loopback_packet_and_meta = if !egress_device.is_loopback()
1095 && ((options.multicast_loop() && remote_ip.addr().is_multicast())
1096 || next_hop.is_broadcast())
1097 {
1098 let body_copy = body.serialize_new_buf(
1099 &mut NetworkSerializationContext::default(),
1100 PacketConstraints::UNCONSTRAINED,
1101 packet::new_buf_vec,
1102 )?;
1103 let loopback_metadata;
1104 SplitMulticastPacketMetadata { primary: packet_metadata, secondary: loopback_metadata } =
1105 packet_metadata.split_for_multicast();
1106 Some((
1107 RawIpBody::new(*proto, local_ip.addr(), remote_ip.addr(), body_copy),
1108 loopback_metadata,
1109 ))
1110 } else {
1111 None
1112 };
1113
1114 let destination = match &local_delivery_device {
1115 Some(d) => IpPacketDestination::Loopback(d),
1116 None => IpPacketDestination::from_next_hop(next_hop, remote_ip.into()),
1117 };
1118 let ttl = options.hop_limit(&remote_ip.into());
1119 let meta = SendIpPacketMeta {
1120 device: &egress_device,
1121 src_ip: local_ip.into(),
1122 dst_ip: remote_ip.into(),
1123 destination,
1124 ttl,
1125 proto: *proto,
1126 mtu: options.mtu(),
1127 dscp_and_ecn: options.dscp_and_ecn(),
1128 };
1129 let result =
1130 IpSocketContext::send_ip_packet(core_ctx, bindings_ctx, meta, body, packet_metadata)
1131 .or_else(|IpSendFrameError { serializer: _, error }| {
1132 IpSockSendError::from_ip_send_frame(error)
1133 });
1134
1135 match (result, loopback_packet_and_meta, core_ctx.get_loopback_device()) {
1136 (Ok(()), Some((loopback_packet, packet_metadata)), Some(loopback_device)) => {
1137 let meta = SendIpPacketMeta {
1138 device: &loopback_device,
1139 src_ip: local_ip.into(),
1140 dst_ip: remote_ip.into(),
1141 destination: IpPacketDestination::Loopback(&egress_device),
1142 ttl,
1143 proto: *proto,
1144 mtu: options.mtu(),
1145 dscp_and_ecn: options.dscp_and_ecn(),
1146 };
1147
1148 IpSocketContext::send_ip_packet(
1151 core_ctx,
1152 bindings_ctx,
1153 meta,
1154 loopback_packet,
1155 packet_metadata,
1156 )
1157 .unwrap_or_else(|IpSendFrameError { serializer: _, error }| {
1158 error!("failed to send loopback packet: {error:?}")
1159 });
1160 }
1161 (Ok(()), Some((_loopback_packet, packet_metadata)), None) => {
1162 error!("can't send a loopback packet without the loopback device");
1163 packet_metadata.acknowledge_drop();
1164 }
1165 (Err(_), Some((_loopback_packet, packet_metadata)), _) => {
1166 packet_metadata.acknowledge_drop();
1168 }
1169 (_, None, _) => (),
1170 }
1171
1172 result
1173}
1174
1175pub trait UseDeviceIpSocketHandlerBlanket {}
1180
1181impl<I, BC, CC> DeviceIpSocketHandler<I, BC> for CC
1182where
1183 I: IpLayerIpExt + IpDeviceStateIpExt,
1184 BC: IpSocketBindingsContext<CC::DeviceId>,
1185 CC: IpDeviceMtuContext<I> + IpSocketContext<I, BC> + UseDeviceIpSocketHandlerBlanket,
1186{
1187 fn get_mms<O: RouteResolutionOptions<I>>(
1188 &mut self,
1189 bindings_ctx: &mut BC,
1190 ip_sock: &IpSock<I, Self::WeakDeviceId>,
1191 options: &O,
1192 ) -> Result<Mms, MmsError> {
1193 let IpSockDefinition { remote_ip, local_ip, device, proto: _ } = &ip_sock.definition;
1194 let device = device
1195 .as_ref()
1196 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
1197 .transpose()?;
1198
1199 let ResolvedRoute {
1200 src_addr: _,
1201 local_delivery_device: _,
1202 device,
1203 next_hop: _,
1204 internal_forwarding: _,
1205 } = self
1206 .lookup_route(
1207 bindings_ctx,
1208 device.as_ref(),
1209 Some(*local_ip),
1210 *remote_ip,
1211 options.transparent(),
1212 options.marks(),
1213 )
1214 .map_err(MmsError::NoDevice)?;
1215 let mtu = self.get_mtu(&device);
1216 Mms::from_mtu::<I>(mtu, 0 ).ok_or(MmsError::MTUTooSmall(mtu))
1219 }
1220}
1221
1222pub(crate) mod ipv6_source_address_selection {
1224 use net_types::ip::{AddrSubnet, IpAddress as _};
1225
1226 use super::*;
1227
1228 use netstack3_base::Ipv6DeviceAddr;
1229
1230 pub struct SasCandidate<D> {
1232 pub addr_sub: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1234 pub assigned: bool,
1236 pub deprecated: bool,
1238 pub temporary: bool,
1240 pub device: D,
1242 }
1243
1244 pub fn select_ipv6_source_address<
1257 'a,
1258 D: PartialEq,
1259 A,
1260 I: Iterator<Item = A>,
1261 F: FnMut(&A) -> SasCandidate<D>,
1262 >(
1263 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1264 outbound_device: &D,
1265 addresses: I,
1266 mut get_candidate: F,
1267 ) -> Option<A> {
1268 addresses
1280 .map(|item| {
1281 let candidate = get_candidate(&item);
1282 (item, candidate)
1283 })
1284 .filter(|(_, candidate)| candidate.assigned)
1287 .max_by(|(_, a), (_, b)| {
1288 select_ipv6_source_address_cmp(remote_ip, outbound_device, a, b)
1289 })
1290 .map(|(item, _candidate)| item)
1291 }
1292
1293 fn select_ipv6_source_address_cmp<D: PartialEq>(
1295 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1296 outbound_device: &D,
1297 a: &SasCandidate<D>,
1298 b: &SasCandidate<D>,
1299 ) -> Ordering {
1300 let SasCandidate {
1302 addr_sub: a_addr_sub,
1303 assigned: a_assigned,
1304 deprecated: a_deprecated,
1305 temporary: a_temporary,
1306 device: a_device,
1307 } = a;
1308 let SasCandidate {
1309 addr_sub: b_addr_sub,
1310 assigned: b_assigned,
1311 deprecated: b_deprecated,
1312 temporary: b_temporary,
1313 device: b_device,
1314 } = b;
1315
1316 let a_addr = a_addr_sub.addr().into_specified();
1317 let b_addr = b_addr_sub.addr().into_specified();
1318
1319 if let Some(remote_ip) = remote_ip {
1323 debug_assert!(!(a_addr == remote_ip && b_addr == remote_ip));
1324 }
1325
1326 debug_assert!(a_assigned);
1329 debug_assert!(b_assigned);
1330
1331 rule_1(remote_ip, a_addr, b_addr)
1332 .then_with(|| rule_2(remote_ip, a_addr, b_addr))
1333 .then_with(|| rule_3(*a_deprecated, *b_deprecated))
1334 .then_with(|| rule_5(outbound_device, a_device, b_device))
1335 .then_with(|| rule_7(*a_temporary, *b_temporary))
1336 .then_with(|| rule_8(remote_ip, *a_addr_sub, *b_addr_sub))
1337 }
1338
1339 fn rule_1(
1341 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1342 a: SpecifiedAddr<Ipv6Addr>,
1343 b: SpecifiedAddr<Ipv6Addr>,
1344 ) -> Ordering {
1345 let remote_ip = match remote_ip {
1346 Some(remote_ip) => remote_ip,
1347 None => return Ordering::Equal,
1348 };
1349 if (a == remote_ip) != (b == remote_ip) {
1350 if a == remote_ip { Ordering::Greater } else { Ordering::Less }
1362 } else {
1363 Ordering::Equal
1364 }
1365 }
1366
1367 fn rule_2(
1368 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1369 a: SpecifiedAddr<Ipv6Addr>,
1370 b: SpecifiedAddr<Ipv6Addr>,
1371 ) -> Ordering {
1372 let remote_scope = match remote_ip {
1375 Some(remote_ip) => remote_ip.scope().multicast_scope_id(),
1376 None => return Ordering::Equal,
1377 };
1378 let a_scope = a.scope().multicast_scope_id();
1379 let b_scope = b.scope().multicast_scope_id();
1380 if a_scope < b_scope {
1381 if a_scope < remote_scope { Ordering::Less } else { Ordering::Greater }
1382 } else if a_scope > b_scope {
1383 if b_scope < remote_scope { Ordering::Greater } else { Ordering::Less }
1384 } else {
1385 Ordering::Equal
1386 }
1387 }
1388
1389 fn rule_3(a_deprecated: bool, b_deprecated: bool) -> Ordering {
1390 match (a_deprecated, b_deprecated) {
1391 (true, false) => Ordering::Less,
1392 (true, true) | (false, false) => Ordering::Equal,
1393 (false, true) => Ordering::Greater,
1394 }
1395 }
1396
1397 fn rule_5<D: PartialEq>(outbound_device: &D, a_device: &D, b_device: &D) -> Ordering {
1398 if (a_device == outbound_device) != (b_device == outbound_device) {
1399 if a_device == outbound_device { Ordering::Greater } else { Ordering::Less }
1401 } else {
1402 Ordering::Equal
1403 }
1404 }
1405
1406 fn rule_7(a_temporary: bool, b_temporary: bool) -> Ordering {
1408 match (a_temporary, b_temporary) {
1409 (true, false) => Ordering::Greater,
1410 (true, true) | (false, false) => Ordering::Equal,
1411 (false, true) => Ordering::Less,
1412 }
1413 }
1414
1415 fn rule_8(
1416 remote_ip: Option<SpecifiedAddr<Ipv6Addr>>,
1417 a: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1418 b: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1419 ) -> Ordering {
1420 let remote_ip = match remote_ip {
1421 Some(remote_ip) => remote_ip,
1422 None => return Ordering::Equal,
1423 };
1424 fn common_prefix_len(
1434 src: AddrSubnet<Ipv6Addr, Ipv6DeviceAddr>,
1435 dst: SpecifiedAddr<Ipv6Addr>,
1436 ) -> u8 {
1437 core::cmp::min(src.addr().common_prefix_len(&dst), src.subnet().prefix())
1438 }
1439
1440 common_prefix_len(a, remote_ip).cmp(&common_prefix_len(b, remote_ip))
1452 }
1453
1454 #[cfg(test)]
1455 mod tests {
1456 use net_declare::net_ip_v6;
1457
1458 use super::*;
1459
1460 #[test]
1461 fn test_select_ipv6_source_address() {
1462 let remote = SpecifiedAddr::new(net_ip_v6!("2001:0db8:1::")).unwrap();
1466 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1467 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1468 let link_local_remote = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:42")).unwrap();
1469 let link_local = SpecifiedAddr::new(net_ip_v6!("fe80::1:2:4")).unwrap();
1470 let dev0 = &0;
1471 let dev1 = &1;
1472 let dev2 = &2;
1473
1474 assert_eq!(rule_1(Some(remote), remote, local0), Ordering::Greater);
1476 assert_eq!(rule_1(Some(remote), local0, remote), Ordering::Less);
1477 assert_eq!(rule_1(Some(remote), local0, local1), Ordering::Equal);
1478 assert_eq!(rule_1(None, local0, local1), Ordering::Equal);
1479
1480 assert_eq!(rule_2(Some(remote), local0, local1), Ordering::Equal);
1482 assert_eq!(rule_2(Some(remote), local1, local0), Ordering::Equal);
1483 assert_eq!(rule_2(Some(remote), local0, link_local), Ordering::Greater);
1484 assert_eq!(rule_2(Some(remote), link_local, local0), Ordering::Less);
1485 assert_eq!(rule_2(Some(link_local_remote), local0, link_local), Ordering::Less);
1486 assert_eq!(rule_2(Some(link_local_remote), link_local, local0), Ordering::Greater);
1487 assert_eq!(rule_1(None, local0, link_local), Ordering::Equal);
1488
1489 assert_eq!(rule_3(false, true), Ordering::Greater);
1491 assert_eq!(rule_3(true, false), Ordering::Less);
1492 assert_eq!(rule_3(true, true), Ordering::Equal);
1493 assert_eq!(rule_3(false, false), Ordering::Equal);
1494
1495 assert_eq!(rule_5(dev0, dev0, dev2), Ordering::Greater);
1497 assert_eq!(rule_5(dev0, dev2, dev0), Ordering::Less);
1498 assert_eq!(rule_5(dev0, dev0, dev0), Ordering::Equal);
1499 assert_eq!(rule_5(dev0, dev2, dev2), Ordering::Equal);
1500
1501 assert_eq!(rule_7(true, false), Ordering::Greater);
1503 assert_eq!(rule_7(false, true), Ordering::Less);
1504 assert_eq!(rule_7(true, true), Ordering::Equal);
1505 assert_eq!(rule_7(false, false), Ordering::Equal);
1506
1507 {
1509 let new_addr_entry = |addr, prefix_len| AddrSubnet::new(addr, prefix_len).unwrap();
1510
1511 let remote = SpecifiedAddr::new(net_ip_v6!("1111::")).unwrap();
1517 let local0 = new_addr_entry(net_ip_v6!("1110::"), 64);
1519 let local1 = new_addr_entry(net_ip_v6!("1100::"), 64);
1521
1522 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Greater);
1523 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Less);
1524 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1525 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1526 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1527
1528 let local0 = new_addr_entry(net_ip_v6!("1110::"), 8);
1533 let local1 = new_addr_entry(net_ip_v6!("1100::"), 8);
1535
1536 assert_eq!(rule_8(Some(remote), local0, local1), Ordering::Equal);
1537 assert_eq!(rule_8(Some(remote), local1, local0), Ordering::Equal);
1538 assert_eq!(rule_8(Some(remote), local0, local0), Ordering::Equal);
1539 assert_eq!(rule_8(Some(remote), local1, local1), Ordering::Equal);
1540 assert_eq!(rule_8(None, local0, local1), Ordering::Equal);
1541 }
1542
1543 {
1544 let new_addr_entry = |addr, device| SasCandidate {
1545 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1546 deprecated: false,
1547 assigned: true,
1548 temporary: false,
1549 device,
1550 };
1551
1552 assert_eq!(
1554 select_ipv6_source_address_cmp(
1555 Some(remote),
1556 dev0,
1557 &new_addr_entry(*local0, *dev1),
1558 &new_addr_entry(*local1, *dev2),
1559 ),
1560 Ordering::Equal
1561 );
1562 }
1563 }
1564
1565 #[test]
1566 fn test_select_ipv6_source_address_no_remote() {
1567 let dev0 = &0;
1570 let dev1 = &1;
1571 let dev2 = &2;
1572
1573 let local0 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:2::")).unwrap();
1574 let local1 = SpecifiedAddr::new(net_ip_v6!("2001:0db8:3::")).unwrap();
1575
1576 let new_addr_entry = |addr, deprecated, device| SasCandidate {
1577 addr_sub: AddrSubnet::new(addr, 128).unwrap(),
1578 deprecated,
1579 assigned: true,
1580 temporary: false,
1581 device,
1582 };
1583
1584 assert_eq!(
1586 select_ipv6_source_address_cmp(
1587 None,
1588 dev0,
1589 &new_addr_entry(*local0, false, *dev1),
1590 &new_addr_entry(*local1, true, *dev2),
1591 ),
1592 Ordering::Greater
1593 );
1594
1595 assert_eq!(
1597 select_ipv6_source_address_cmp(
1598 None,
1599 dev0,
1600 &new_addr_entry(*local0, false, *dev0),
1601 &new_addr_entry(*local1, false, *dev1),
1602 ),
1603 Ordering::Greater
1604 );
1605 }
1606 }
1607}
1608
1609#[cfg(any(test, feature = "testutils"))]
1611pub(crate) mod testutil {
1612 use alloc::boxed::Box;
1613 use alloc::vec::Vec;
1614 use core::num::NonZeroUsize;
1615
1616 use crate::internal::types::RoutePreference;
1617 use derivative::Derivative;
1618 use net_types::MulticastAddr;
1619 use net_types::ip::{GenericOverIp, IpAddr, IpAddress, Ipv4, Ipv4Addr, Ipv6, Subnet};
1620 use netstack3_base::testutil::{FakeCoreCtx, FakeStrongDeviceId, FakeWeakDeviceId};
1621 use netstack3_base::{SendFrameContext, SendFrameError};
1622 use netstack3_filter::Tuple;
1623 use netstack3_hashmap::HashMap;
1624
1625 use super::*;
1626 use crate::internal::base::{
1627 BaseTransportIpContext, DEFAULT_HOP_LIMITS, HopLimits, MulticastMembershipHandler,
1628 };
1629 use crate::internal::routing::testutil::FakeIpRoutingCtx;
1630 use crate::internal::routing::{self, RoutingTable};
1631 use crate::internal::types::{Destination, Entry, Metric, RawMetric};
1632
1633 #[derive(Derivative, GenericOverIp)]
1636 #[generic_over_ip(I, Ip)]
1637 #[derivative(Default(bound = ""))]
1638 pub struct FakeIpSocketCtx<I: Ip, D> {
1639 pub(crate) table: RoutingTable<I, D>,
1640 forwarding: FakeIpRoutingCtx<D>,
1641 devices: HashMap<D, FakeDeviceState<I>>,
1642 }
1643
1644 pub trait InnerFakeIpSocketCtx<I: Ip, D> {
1647 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D>;
1649 }
1650
1651 impl<I: Ip, D> InnerFakeIpSocketCtx<I, D> for FakeIpSocketCtx<I, D> {
1652 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1653 self
1654 }
1655 }
1656
1657 impl<I: IpExt, D: FakeStrongDeviceId, BC> BaseTransportIpContext<I, BC> for FakeIpSocketCtx<I, D> {
1658 fn get_default_hop_limits(&mut self, device: Option<&D>) -> HopLimits {
1659 device.map_or(DEFAULT_HOP_LIMITS, |device| {
1660 let hop_limit = self.get_device_state(device).default_hop_limit;
1661 HopLimits { unicast: hop_limit, multicast: DEFAULT_HOP_LIMITS.multicast }
1662 })
1663 }
1664
1665 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1666
1667 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1668 &mut self,
1669 addr: SpecifiedAddr<I::Addr>,
1670 cb: F,
1671 ) -> O {
1672 cb(Box::new(self.devices.iter().filter_map(move |(device, state)| {
1673 state.addresses.contains(&addr).then(|| device.clone())
1674 })))
1675 }
1676
1677 fn get_original_destination(&mut self, _tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1678 unimplemented!()
1679 }
1680 }
1681
1682 impl<I: IpExt, D: FakeStrongDeviceId> DeviceIdContext<AnyDevice> for FakeIpSocketCtx<I, D> {
1683 type DeviceId = D;
1684 type WeakDeviceId = D::Weak;
1685 }
1686
1687 impl<I, State, D, Meta, BC> IpSocketHandler<I, BC> for FakeCoreCtx<State, Meta, D>
1688 where
1689 I: IpExt + FilterIpExt,
1690 State: InnerFakeIpSocketCtx<I, D>,
1691 D: FakeStrongDeviceId,
1692 BC: TxMetadataBindingsTypes,
1693 FakeCoreCtx<State, Meta, D>:
1694 SendFrameContext<BC, SendIpPacketMeta<I, Self::DeviceId, SpecifiedAddr<I::Addr>>>,
1695 {
1696 fn new_ip_socket<O>(
1697 &mut self,
1698 _bindings_ctx: &mut BC,
1699 args: IpSocketArgs<'_, Self::DeviceId, I, O>,
1700 ) -> Result<IpSock<I, Self::WeakDeviceId>, IpSockCreationError>
1701 where
1702 O: RouteResolutionOptions<I>,
1703 {
1704 self.state.fake_ip_socket_ctx_mut().new_ip_socket(args)
1705 }
1706
1707 fn send_ip_packet<S, O>(
1708 &mut self,
1709 bindings_ctx: &mut BC,
1710 socket: &IpSock<I, Self::WeakDeviceId>,
1711 body: S,
1712 options: &O,
1713 _tx_meta: BC::TxMetadata,
1716 ) -> Result<(), IpSockSendError>
1717 where
1718 S: TransportPacketSerializer<I>,
1719 S::Buffer: BufferMut,
1720 O: SendOptions<I> + RouteResolutionOptions<I>,
1721 {
1722 let meta = self.state.fake_ip_socket_ctx_mut().resolve_send_meta(socket, options)?;
1723 self.send_frame(bindings_ctx, meta, body).or_else(
1724 |SendFrameError { serializer: _, error }| IpSockSendError::from_send_frame(error),
1725 )
1726 }
1727
1728 fn confirm_reachable<O>(
1729 &mut self,
1730 _bindings_ctx: &mut BC,
1731 _socket: &IpSock<I, Self::WeakDeviceId>,
1732 _options: &O,
1733 ) {
1734 }
1735 }
1736
1737 impl<I: IpExt, D: FakeStrongDeviceId, BC> MulticastMembershipHandler<I, BC>
1738 for FakeIpSocketCtx<I, D>
1739 {
1740 fn join_multicast_group(
1741 &mut self,
1742 _bindings_ctx: &mut BC,
1743 device: &Self::DeviceId,
1744 addr: MulticastAddr<<I as Ip>::Addr>,
1745 ) {
1746 let value = self.get_device_state_mut(device).multicast_groups.entry(addr).or_insert(0);
1747 *value = value.checked_add(1).unwrap();
1748 }
1749
1750 fn leave_multicast_group(
1751 &mut self,
1752 _bindings_ctx: &mut BC,
1753 device: &Self::DeviceId,
1754 addr: MulticastAddr<<I as Ip>::Addr>,
1755 ) {
1756 let value = self
1757 .get_device_state_mut(device)
1758 .multicast_groups
1759 .get_mut(&addr)
1760 .unwrap_or_else(|| panic!("no entry for {addr} on {device:?}"));
1761 *value = value.checked_sub(1).unwrap();
1762 }
1763
1764 fn select_device_for_multicast_group(
1765 &mut self,
1766 addr: MulticastAddr<<I as Ip>::Addr>,
1767 _marks: &Marks,
1768 ) -> Result<Self::DeviceId, ResolveRouteError> {
1769 let remote_ip = SocketIpAddr::new_from_multicast(addr);
1770 self.lookup_route(None, None, remote_ip, false)
1771 .map(|ResolvedRoute { device, .. }| device)
1772 }
1773 }
1774
1775 impl<I, BC, D, State, Meta> BaseTransportIpContext<I, BC> for FakeCoreCtx<State, Meta, D>
1776 where
1777 I: IpExt + FilterIpExt,
1778 D: FakeStrongDeviceId,
1779 State: InnerFakeIpSocketCtx<I, D>,
1780 BC: TxMetadataBindingsTypes,
1781 Self: IpSocketHandler<I, BC, DeviceId = D, WeakDeviceId = FakeWeakDeviceId<D>>,
1782 {
1783 type DevicesWithAddrIter<'a> = Box<dyn Iterator<Item = D> + 'a>;
1784
1785 fn with_devices_with_assigned_addr<O, F: FnOnce(Self::DevicesWithAddrIter<'_>) -> O>(
1786 &mut self,
1787 addr: SpecifiedAddr<I::Addr>,
1788 cb: F,
1789 ) -> O {
1790 BaseTransportIpContext::<I, BC>::with_devices_with_assigned_addr(
1791 self.state.fake_ip_socket_ctx_mut(),
1792 addr,
1793 cb,
1794 )
1795 }
1796
1797 fn get_default_hop_limits(&mut self, device: Option<&Self::DeviceId>) -> HopLimits {
1798 BaseTransportIpContext::<I, BC>::get_default_hop_limits(
1799 self.state.fake_ip_socket_ctx_mut(),
1800 device,
1801 )
1802 }
1803
1804 fn get_original_destination(&mut self, tuple: &Tuple<I>) -> Option<(I::Addr, u16)> {
1805 BaseTransportIpContext::<I, BC>::get_original_destination(
1806 self.state.fake_ip_socket_ctx_mut(),
1807 tuple,
1808 )
1809 }
1810 }
1811
1812 #[derive(Derivative)]
1814 #[derivative(Default(bound = ""))]
1815 pub struct FakeDualStackIpSocketCtx<D> {
1816 v4: FakeIpSocketCtx<Ipv4, D>,
1817 v6: FakeIpSocketCtx<Ipv6, D>,
1818 }
1819
1820 impl<D: FakeStrongDeviceId> FakeDualStackIpSocketCtx<D> {
1821 pub fn new<A: Into<SpecifiedAddr<IpAddr>>>(
1823 devices: impl IntoIterator<Item = FakeDeviceConfig<D, A>>,
1824 ) -> Self {
1825 let partition =
1826 |v: Vec<A>| -> (Vec<SpecifiedAddr<Ipv4Addr>>, Vec<SpecifiedAddr<Ipv6Addr>>) {
1827 v.into_iter().fold((Vec::new(), Vec::new()), |(mut v4, mut v6), i| {
1828 match IpAddr::from(i.into()) {
1829 IpAddr::V4(a) => v4.push(a),
1830 IpAddr::V6(a) => v6.push(a),
1831 }
1832 (v4, v6)
1833 })
1834 };
1835
1836 let (v4, v6): (Vec<_>, Vec<_>) = devices
1837 .into_iter()
1838 .map(|FakeDeviceConfig { device, local_ips, remote_ips }| {
1839 let (local_v4, local_v6) = partition(local_ips);
1840 let (remote_v4, remote_v6) = partition(remote_ips);
1841 (
1842 FakeDeviceConfig {
1843 device: device.clone(),
1844 local_ips: local_v4,
1845 remote_ips: remote_v4,
1846 },
1847 FakeDeviceConfig { device, local_ips: local_v6, remote_ips: remote_v6 },
1848 )
1849 })
1850 .unzip();
1851 Self { v4: FakeIpSocketCtx::new(v4), v6: FakeIpSocketCtx::new(v6) }
1852 }
1853
1854 pub fn inner_mut<I: Ip>(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1856 I::map_ip_out(self, |s| &mut s.v4, |s| &mut s.v6)
1857 }
1858
1859 fn inner<I: Ip>(&self) -> &FakeIpSocketCtx<I, D> {
1860 I::map_ip_out(self, |s| &s.v4, |s| &s.v6)
1861 }
1862
1863 pub fn add_route(&mut self, device: D, ip: SpecifiedAddr<IpAddr>) {
1865 match IpAddr::from(ip) {
1866 IpAddr::V4(ip) => {
1867 routing::testutil::add_on_link_routing_entry(&mut self.v4.table, ip, device)
1868 }
1869 IpAddr::V6(ip) => {
1870 routing::testutil::add_on_link_routing_entry(&mut self.v6.table, ip, device)
1871 }
1872 }
1873 }
1874
1875 pub fn add_subnet_route<A: IpAddress>(&mut self, device: D, subnet: Subnet<A>) {
1877 let entry = Entry {
1878 subnet,
1879 device,
1880 gateway: None,
1881 metric: Metric::ExplicitMetric(RawMetric(0)),
1882 route_preference: RoutePreference::Medium,
1883 };
1884 A::Version::map_ip::<_, ()>(
1885 entry,
1886 |entry_v4| {
1887 let _ = routing::testutil::add_entry(&mut self.v4.table, entry_v4)
1888 .expect("Failed to add route");
1889 },
1890 |entry_v6| {
1891 let _ = routing::testutil::add_entry(&mut self.v6.table, entry_v6)
1892 .expect("Failed to add route");
1893 },
1894 );
1895 }
1896
1897 pub fn get_device_state_mut<I: IpExt>(&mut self, device: &D) -> &mut FakeDeviceState<I> {
1899 self.inner_mut::<I>().get_device_state_mut(device)
1900 }
1901
1902 pub fn multicast_memberships<I: IpExt>(
1904 &self,
1905 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
1906 self.inner::<I>().multicast_memberships()
1907 }
1908 }
1909
1910 impl<I: IpExt, S: InnerFakeIpSocketCtx<I, D>, Meta, D: FakeStrongDeviceId, BC>
1911 MulticastMembershipHandler<I, BC> for FakeCoreCtx<S, Meta, D>
1912 {
1913 fn join_multicast_group(
1914 &mut self,
1915 bindings_ctx: &mut BC,
1916 device: &Self::DeviceId,
1917 addr: MulticastAddr<<I as Ip>::Addr>,
1918 ) {
1919 MulticastMembershipHandler::<I, BC>::join_multicast_group(
1920 self.state.fake_ip_socket_ctx_mut(),
1921 bindings_ctx,
1922 device,
1923 addr,
1924 )
1925 }
1926
1927 fn leave_multicast_group(
1928 &mut self,
1929 bindings_ctx: &mut BC,
1930 device: &Self::DeviceId,
1931 addr: MulticastAddr<<I as Ip>::Addr>,
1932 ) {
1933 MulticastMembershipHandler::<I, BC>::leave_multicast_group(
1934 self.state.fake_ip_socket_ctx_mut(),
1935 bindings_ctx,
1936 device,
1937 addr,
1938 )
1939 }
1940
1941 fn select_device_for_multicast_group(
1942 &mut self,
1943 addr: MulticastAddr<<I as Ip>::Addr>,
1944 marks: &Marks,
1945 ) -> Result<Self::DeviceId, ResolveRouteError> {
1946 MulticastMembershipHandler::<I, BC>::select_device_for_multicast_group(
1947 self.state.fake_ip_socket_ctx_mut(),
1948 addr,
1949 marks,
1950 )
1951 }
1952 }
1953
1954 impl<I: Ip, D, State: InnerFakeIpSocketCtx<I, D>, Meta> InnerFakeIpSocketCtx<I, D>
1955 for FakeCoreCtx<State, Meta, D>
1956 {
1957 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1958 self.state.fake_ip_socket_ctx_mut()
1959 }
1960 }
1961
1962 impl<I: Ip, D: FakeStrongDeviceId> InnerFakeIpSocketCtx<I, D> for FakeDualStackIpSocketCtx<D> {
1963 fn fake_ip_socket_ctx_mut(&mut self) -> &mut FakeIpSocketCtx<I, D> {
1964 self.inner_mut::<I>()
1965 }
1966 }
1967
1968 #[derive(Clone, GenericOverIp)]
1970 #[generic_over_ip()]
1971 pub struct FakeDeviceConfig<D, A> {
1972 pub device: D,
1974 pub local_ips: Vec<A>,
1976 pub remote_ips: Vec<A>,
1978 }
1979
1980 pub struct FakeDeviceState<I: Ip> {
1982 pub default_hop_limit: NonZeroU8,
1984 pub addresses: Vec<SpecifiedAddr<I::Addr>>,
1986 pub multicast_groups: HashMap<MulticastAddr<I::Addr>, usize>,
1988 }
1989
1990 impl<I: Ip> FakeDeviceState<I> {
1991 pub fn is_in_multicast_group(&self, addr: &MulticastAddr<I::Addr>) -> bool {
1993 self.multicast_groups.get(addr).is_some_and(|v| *v != 0)
1994 }
1995 }
1996
1997 impl<I: IpExt, D: FakeStrongDeviceId> FakeIpSocketCtx<I, D> {
1998 pub fn new(
2001 device_configs: impl IntoIterator<Item = FakeDeviceConfig<D, SpecifiedAddr<I::Addr>>>,
2002 ) -> Self {
2003 let mut table = RoutingTable::default();
2004 let mut devices = HashMap::default();
2005 for FakeDeviceConfig { device, local_ips, remote_ips } in device_configs {
2006 for addr in remote_ips {
2007 routing::testutil::add_on_link_routing_entry(&mut table, addr, device.clone())
2008 }
2009 let state = FakeDeviceState {
2010 default_hop_limit: DEFAULT_HOP_LIMITS.unicast,
2011 addresses: local_ips,
2012 multicast_groups: Default::default(),
2013 };
2014 assert!(
2015 devices.insert(device.clone(), state).is_none(),
2016 "duplicate entries for {device:?}",
2017 );
2018 }
2019
2020 Self { table, devices, forwarding: Default::default() }
2021 }
2022
2023 pub fn get_device_state(&self, device: &D) -> &FakeDeviceState<I> {
2025 self.devices.get(device).unwrap_or_else(|| panic!("no device {device:?}"))
2026 }
2027
2028 pub fn get_device_state_mut(&mut self, device: &D) -> &mut FakeDeviceState<I> {
2030 self.devices.get_mut(device).unwrap_or_else(|| panic!("no device {device:?}"))
2031 }
2032
2033 pub(crate) fn multicast_memberships(
2034 &self,
2035 ) -> HashMap<(D, MulticastAddr<I::Addr>), NonZeroUsize> {
2036 self.devices
2037 .iter()
2038 .map(|(device, state)| {
2039 state.multicast_groups.iter().filter_map(|(group, count)| {
2040 NonZeroUsize::new(*count).map(|count| ((device.clone(), *group), count))
2041 })
2042 })
2043 .flatten()
2044 .collect()
2045 }
2046
2047 fn new_ip_socket<O>(
2048 &mut self,
2049 args: IpSocketArgs<'_, D, I, O>,
2050 ) -> Result<IpSock<I, D::Weak>, IpSockCreationError>
2051 where
2052 O: RouteResolutionOptions<I>,
2053 {
2054 let IpSocketArgs { device, local_ip, remote_ip, proto, options } = args;
2055 let device = device
2056 .as_ref()
2057 .map(|d| d.as_strong_ref().ok_or(ResolveRouteError::Unreachable))
2058 .transpose()?;
2059 let device = device.as_ref().map(|d| d.as_ref());
2060 let resolved_route =
2061 self.lookup_route(device, local_ip, remote_ip, options.transparent())?;
2062 Ok(new_ip_socket(device, resolved_route, remote_ip, proto))
2063 }
2064
2065 fn lookup_route(
2066 &mut self,
2067 device: Option<&D>,
2068 local_ip: Option<IpDeviceAddr<I::Addr>>,
2069 addr: RoutableIpAddr<I::Addr>,
2070 transparent: bool,
2071 ) -> Result<ResolvedRoute<I, D>, ResolveRouteError> {
2072 let Self { table, devices, forwarding } = self;
2073 let (destination, ()) = table
2074 .lookup_filter_map(forwarding, device, addr.addr(), |_, d| match &local_ip {
2075 None => Some(()),
2076 Some(local_ip) => {
2077 if transparent {
2078 return Some(());
2079 }
2080 devices.get(d).and_then(|state| {
2081 state.addresses.contains(local_ip.as_ref()).then_some(())
2082 })
2083 }
2084 })
2085 .next()
2086 .ok_or(ResolveRouteError::Unreachable)?;
2087
2088 let Destination { device, next_hop } = destination;
2089 let mut addrs = devices.get(device).unwrap().addresses.iter();
2090 let local_ip = match local_ip {
2091 None => {
2092 let addr = addrs.next().ok_or(ResolveRouteError::NoSrcAddr)?;
2093 IpDeviceAddr::new(addr.get()).expect("not valid device addr")
2094 }
2095 Some(local_ip) => {
2096 if !transparent {
2097 assert!(
2100 addrs.any(|a| a.get() == local_ip.addr()),
2101 "didn't find IP {:?} in {:?}",
2102 local_ip,
2103 addrs.collect::<Vec<_>>()
2104 );
2105 }
2106 local_ip
2107 }
2108 };
2109
2110 Ok(ResolvedRoute {
2111 src_addr: local_ip,
2112 device: device.clone(),
2113 local_delivery_device: None,
2114 next_hop,
2115 internal_forwarding: InternalForwarding::NotUsed,
2118 })
2119 }
2120
2121 fn resolve_send_meta<O>(
2122 &mut self,
2123 socket: &IpSock<I, D::Weak>,
2124 options: &O,
2125 ) -> Result<SendIpPacketMeta<I, D, SpecifiedAddr<I::Addr>>, IpSockSendError>
2126 where
2127 O: SendOptions<I> + RouteResolutionOptions<I>,
2128 {
2129 let IpSockDefinition { remote_ip, local_ip, device, proto } = &socket.definition;
2130 let device = device
2131 .as_ref()
2132 .map(|d| d.upgrade().ok_or(ResolveRouteError::Unreachable))
2133 .transpose()?;
2134 let ResolvedRoute {
2135 src_addr,
2136 device,
2137 next_hop,
2138 local_delivery_device: _,
2139 internal_forwarding: _,
2140 } = self.lookup_route(
2141 device.as_ref(),
2142 Some(*local_ip),
2143 *remote_ip,
2144 options.transparent(),
2145 )?;
2146
2147 let remote_ip: &SpecifiedAddr<_> = remote_ip.as_ref();
2148
2149 let destination = IpPacketDestination::from_next_hop(next_hop, *remote_ip);
2150 Ok(SendIpPacketMeta {
2151 device,
2152 src_ip: src_addr.into(),
2153 dst_ip: *remote_ip,
2154 destination,
2155 proto: *proto,
2156 ttl: options.hop_limit(remote_ip),
2157 mtu: options.mtu(),
2158 dscp_and_ecn: DscpAndEcn::default(),
2159 })
2160 }
2161 }
2162}