@@ -73,6 +73,8 @@ struct InterfaceInner<'b, 'c, 'e> {
7373 neighbor_cache : NeighborCache < ' b > ,
7474 ethernet_addr : EthernetAddress ,
7575 ip_addrs : ManagedSlice < ' c , IpCidr > ,
76+ #[ cfg( feature = "proto-ipv4" ) ]
77+ any_ip : bool ,
7678 routes : Routes < ' e > ,
7779 #[ cfg( feature = "proto-igmp" ) ]
7880 ipv4_multicast_groups : ManagedMap < ' e , Ipv4Address , ( ) > ,
@@ -91,6 +93,8 @@ pub struct InterfaceBuilder <'b, 'c, 'e, DeviceT: for<'d> Device<'d>> {
9193 ethernet_addr : Option < EthernetAddress > ,
9294 neighbor_cache : Option < NeighborCache < ' b > > ,
9395 ip_addrs : ManagedSlice < ' c , IpCidr > ,
96+ #[ cfg( feature = "proto-ipv4" ) ]
97+ any_ip : bool ,
9498 routes : Routes < ' e > ,
9599 /// Does not share storage with `ipv6_multicast_groups` to avoid IPv6 size overhead.
96100 #[ cfg( feature = "proto-igmp" ) ]
@@ -132,6 +136,8 @@ impl<'b, 'c, 'e, DeviceT> InterfaceBuilder<'b, 'c, 'e, DeviceT>
132136 ethernet_addr : None ,
133137 neighbor_cache : None ,
134138 ip_addrs : ManagedSlice :: Borrowed ( & mut [ ] ) ,
139+ #[ cfg( feature = "proto-ipv4" ) ]
140+ any_ip : false ,
135141 routes : Routes :: new ( ManagedMap :: Borrowed ( & mut [ ] ) ) ,
136142 #[ cfg( feature = "proto-igmp" ) ]
137143 ipv4_multicast_groups : ManagedMap :: Borrowed ( & mut [ ] ) ,
@@ -169,6 +175,25 @@ impl<'b, 'c, 'e, DeviceT> InterfaceBuilder<'b, 'c, 'e, DeviceT>
169175 self
170176 }
171177
178+ /// Enable or disable the AnyIP capability, allowing packets to be received
179+ /// locally on IPv4 addresses other than the interface's configured [ip_addrs].
180+ /// When AnyIP is enabled and a route prefix in [routes] specifies one of
181+ /// the interface's [ip_addrs] as its gateway, the interface will accept
182+ /// packets addressed to that prefix.
183+ ///
184+ /// # IPv6
185+ ///
186+ /// This option is not available or required for IPv6 as packets sent to
187+ /// the interface are not filtered by IPv6 address.
188+ ///
189+ /// [routes]: struct.EthernetInterface.html#method.routes
190+ /// [ip_addrs]: struct.EthernetInterface.html#method.ip_addrs
191+ #[ cfg( feature = "proto-ipv4" ) ]
192+ pub fn any_ip ( mut self , enabled : bool ) -> Self {
193+ self . any_ip = enabled;
194+ self
195+ }
196+
172197 /// Set the IP routes the interface will use. See also
173198 /// [routes].
174199 ///
@@ -225,6 +250,8 @@ impl<'b, 'c, 'e, DeviceT> InterfaceBuilder<'b, 'c, 'e, DeviceT>
225250 inner : InterfaceInner {
226251 ethernet_addr, device_capabilities, neighbor_cache,
227252 ip_addrs : self . ip_addrs ,
253+ #[ cfg( feature = "proto-ipv4" ) ]
254+ any_ip : self . any_ip ,
228255 routes : self . routes ,
229256 #[ cfg( feature = "proto-igmp" ) ]
230257 ipv4_multicast_groups : self . ipv4_multicast_groups ,
@@ -916,7 +943,15 @@ impl<'b, 'c, 'e> InterfaceInner<'b, 'c, 'e> {
916943
917944 if !self . has_ip_addr ( ipv4_repr. dst_addr ) && !self . has_multicast_group ( ipv4_repr. dst_addr ) {
918945 // Ignore IP packets not directed at us or any of the multicast groups
919- return Ok ( Packet :: None )
946+ // If AnyIP is enabled, also check if the packet is routed locally.
947+ if !self . any_ip {
948+ return Ok ( Packet :: None ) ;
949+ } else if match self . routes . lookup ( & IpAddress :: Ipv4 ( ipv4_repr. dst_addr ) , timestamp) {
950+ Some ( router_addr) => !self . has_ip_addr ( router_addr) ,
951+ None => true ,
952+ } {
953+ return Ok ( Packet :: None ) ;
954+ }
920955 }
921956
922957 match ipv4_repr. protocol {
0 commit comments