mirror of
https://github.com/apache/nuttx.git
synced 2026-05-18 00:34:10 +08:00
forward: Add IFF_NOSRC_FORWARD and IFF_NODST_FORWARD flags.
* IFF_NOSRC_FORWARD: Controls whether device prohibits forwarding packets inputs * IFF_NODST_FORWARD: Controls whether device prohibits forwarding packets outputs This allows users to selectively enable/disable forwarding on specific devices, improving network flexibility and security. Signed-off-by: zhaohaiyang1 <zhaohaiyang1@xiaomi.com>
This commit is contained in:
+38
-30
@@ -63,41 +63,49 @@
|
||||
#define IFF_NOTRAILERS (1 << 17) /* Avoid use of trailers. */
|
||||
#define IFF_PROMISC (1 << 18) /* Receive all packets. */
|
||||
#define IFF_ALLMULTI (1 << 19) /* Receive all multicast packets. */
|
||||
#define IFF_NOSRC_FORWARD (1 << 20) /* Device prohibits forwarding packets inputs */
|
||||
#define IFF_NODST_FORWARD (1 << 21) /* Device prohibits forwarding packets outputs */
|
||||
|
||||
/* Interface flag helpers */
|
||||
|
||||
#define IFF_SET_UP(f) do { (f) |= IFF_UP; } while (0)
|
||||
#define IFF_SET_RUNNING(f) do { (f) |= IFF_RUNNING; } while (0)
|
||||
#define IFF_SET_NOARP(f) do { (f) |= IFF_NOARP; } while (0)
|
||||
#define IFF_SET_NAT(f) do { (f) |= IFF_NAT; } while (0)
|
||||
#define IFF_SET_LOOPBACK(f) do { (f) |= IFF_LOOPBACK; } while (0)
|
||||
#define IFF_SET_POINTOPOINT(f) do { (f) |= IFF_POINTOPOINT; } while (0)
|
||||
#define IFF_SET_MULTICAST(f) do { (f) |= IFF_MULTICAST; } while (0)
|
||||
#define IFF_SET_BROADCAST(f) do { (f) |= IFF_BROADCAST; } while (0)
|
||||
#define IFF_SET_SLAVE(f) do { (f) |= IFF_SLAVE; } while (0)
|
||||
#define IFF_SET_DYNAMIC(f) do { (f) |= IFF_DYNAMIC; } while (0)
|
||||
#define IFF_SET_UP(f) do { (f) |= IFF_UP; } while (0)
|
||||
#define IFF_SET_RUNNING(f) do { (f) |= IFF_RUNNING; } while (0)
|
||||
#define IFF_SET_NOARP(f) do { (f) |= IFF_NOARP; } while (0)
|
||||
#define IFF_SET_NAT(f) do { (f) |= IFF_NAT; } while (0)
|
||||
#define IFF_SET_LOOPBACK(f) do { (f) |= IFF_LOOPBACK; } while (0)
|
||||
#define IFF_SET_POINTOPOINT(f) do { (f) |= IFF_POINTOPOINT; } while (0)
|
||||
#define IFF_SET_MULTICAST(f) do { (f) |= IFF_MULTICAST; } while (0)
|
||||
#define IFF_SET_BROADCAST(f) do { (f) |= IFF_BROADCAST; } while (0)
|
||||
#define IFF_SET_SLAVE(f) do { (f) |= IFF_SLAVE; } while (0)
|
||||
#define IFF_SET_DYNAMIC(f) do { (f) |= IFF_DYNAMIC; } while (0)
|
||||
#define IFF_SET_NOSRC_FORWARD(f) do { (f) |= IFF_NOSRC_FORWARD; } while (0)
|
||||
#define IFF_SET_NODST_FORWARD(f) do { (f) |= IFF_NODST_FORWARD; } while (0)
|
||||
|
||||
#define IFF_CLR_UP(f) do { (f) &= ~IFF_UP; } while (0)
|
||||
#define IFF_CLR_RUNNING(f) do { (f) &= ~IFF_RUNNING; } while (0)
|
||||
#define IFF_CLR_NOARP(f) do { (f) &= ~IFF_NOARP; } while (0)
|
||||
#define IFF_CLR_NAT(f) do { (f) &= ~IFF_NAT; } while (0)
|
||||
#define IFF_CLR_LOOPBACK(f) do { (f) &= ~IFF_LOOPBACK; } while (0)
|
||||
#define IFF_CLR_POINTOPOINT(f) do { (f) &= ~IFF_POINTOPOINT; } while (0)
|
||||
#define IFF_CLR_MULTICAST(f) do { (f) &= ~IFF_MULTICAST; } while (0)
|
||||
#define IFF_CLR_BROADCAST(f) do { (f) &= ~IFF_BROADCAST; } while (0)
|
||||
#define IFF_CLR_SLAVE(f) do { (f) &= ~IFF_SLAVE; } while (0)
|
||||
#define IFF_CLR_DYNAMIC(f) do { (f) &= ~IFF_DYNAMIC; } while (0)
|
||||
#define IFF_CLR_UP(f) do { (f) &= ~IFF_UP; } while (0)
|
||||
#define IFF_CLR_RUNNING(f) do { (f) &= ~IFF_RUNNING; } while (0)
|
||||
#define IFF_CLR_NOARP(f) do { (f) &= ~IFF_NOARP; } while (0)
|
||||
#define IFF_CLR_NAT(f) do { (f) &= ~IFF_NAT; } while (0)
|
||||
#define IFF_CLR_LOOPBACK(f) do { (f) &= ~IFF_LOOPBACK; } while (0)
|
||||
#define IFF_CLR_POINTOPOINT(f) do { (f) &= ~IFF_POINTOPOINT; } while (0)
|
||||
#define IFF_CLR_MULTICAST(f) do { (f) &= ~IFF_MULTICAST; } while (0)
|
||||
#define IFF_CLR_BROADCAST(f) do { (f) &= ~IFF_BROADCAST; } while (0)
|
||||
#define IFF_CLR_SLAVE(f) do { (f) &= ~IFF_SLAVE; } while (0)
|
||||
#define IFF_CLR_DYNAMIC(f) do { (f) &= ~IFF_DYNAMIC; } while (0)
|
||||
#define IFF_CLR_NOSRC_FORWARD(f) do { (f) &= ~IFF_NOSRC_FORWARD; } while (0)
|
||||
#define IFF_CLR_NODST_FORWARD(f) do { (f) &= ~IFF_NODST_FORWARD; } while (0)
|
||||
|
||||
#define IFF_IS_UP(f) (((f) & IFF_UP) != 0)
|
||||
#define IFF_IS_RUNNING(f) (((f) & IFF_RUNNING) != 0)
|
||||
#define IFF_IS_NOARP(f) (((f) & IFF_NOARP) != 0)
|
||||
#define IFF_IS_NAT(f) (((f) & IFF_NAT) != 0)
|
||||
#define IFF_IS_LOOPBACK(f) (((f) & IFF_LOOPBACK) != 0)
|
||||
#define IFF_IS_POINTOPOINT(f) (((f) & IFF_POINTOPOINT) != 0)
|
||||
#define IFF_IS_MULTICAST(f) (((f) & IFF_MULTICAST) != 0)
|
||||
#define IFF_IS_BROADCAST(f) (((f) & IFF_BROADCAST) != 0)
|
||||
#define IFF_IS_SLAVE(f) (((f) & IFF_SLAVE) != 0)
|
||||
#define IFF_IS_DYNAMIC(f) (((f) & IFF_DYNAMIC) != 0)
|
||||
#define IFF_IS_UP(f) (((f) & IFF_UP) != 0)
|
||||
#define IFF_IS_RUNNING(f) (((f) & IFF_RUNNING) != 0)
|
||||
#define IFF_IS_NOARP(f) (((f) & IFF_NOARP) != 0)
|
||||
#define IFF_IS_NAT(f) (((f) & IFF_NAT) != 0)
|
||||
#define IFF_IS_LOOPBACK(f) (((f) & IFF_LOOPBACK) != 0)
|
||||
#define IFF_IS_POINTOPOINT(f) (((f) & IFF_POINTOPOINT) != 0)
|
||||
#define IFF_IS_MULTICAST(f) (((f) & IFF_MULTICAST) != 0)
|
||||
#define IFF_IS_BROADCAST(f) (((f) & IFF_BROADCAST) != 0)
|
||||
#define IFF_IS_SLAVE(f) (((f) & IFF_SLAVE) != 0)
|
||||
#define IFF_IS_DYNAMIC(f) (((f) & IFF_DYNAMIC) != 0)
|
||||
#define IFF_IS_NOSRC_FORWARD(f) (((f) & IFF_NOSRC_FORWARD) != 0)
|
||||
#define IFF_IS_NODST_FORWARD(f) (((f) & IFF_NODST_FORWARD) != 0)
|
||||
|
||||
/* We only need to manage the IPv6 bit if both IPv6 and IPv4 are supported.
|
||||
* Otherwise, we can save a few bytes by ignoring it.
|
||||
|
||||
@@ -217,6 +217,14 @@ static int ipv4_dev_forward(FAR struct net_driver_s *dev,
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
if (IFF_IS_NODST_FORWARD(fwddev->d_flags))
|
||||
{
|
||||
nwarn("WARNING: IP forwarding disabled on destination device %s\n",
|
||||
fwddev->d_ifname);
|
||||
ret = -EOPNOTSUPP;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_IPFILTER
|
||||
/* Do filter before forwarding, to make sure we drop silently before
|
||||
* replying any other errors.
|
||||
@@ -465,6 +473,14 @@ int ipv4_forward(FAR struct net_driver_s *dev, FAR struct ipv4_hdr_s *ipv4)
|
||||
int icmp_reply_code;
|
||||
#endif /* CONFIG_NET_ICMP */
|
||||
|
||||
if (IFF_IS_NOSRC_FORWARD(dev->d_flags))
|
||||
{
|
||||
nwarn("WARNING: IP forwarding disabled on source device %s\n",
|
||||
dev->d_ifname);
|
||||
ret = -EOPNOTSUPP;
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Search for a device that can forward this packet. */
|
||||
|
||||
destipaddr = net_ip4addr_conv32(ipv4->destipaddr);
|
||||
@@ -512,7 +528,7 @@ int ipv4_forward(FAR struct net_driver_s *dev, FAR struct ipv4_hdr_s *ipv4)
|
||||
|
||||
#endif
|
||||
|
||||
nwarn("WARNING: Packet forwarding to same device not supportedN\n");
|
||||
nwarn("WARNING: Packet forwarding to same device not supported\n");
|
||||
ret = -ENOSYS;
|
||||
goto drop;
|
||||
}
|
||||
@@ -547,6 +563,11 @@ drop:
|
||||
icmp_reply_code = ICMP_EXC_TTL;
|
||||
goto reply;
|
||||
|
||||
case -EOPNOTSUPP:
|
||||
icmp_reply_type = ICMP_DEST_UNREACHABLE;
|
||||
icmp_reply_code = ICMP_HOST_UNREACH;
|
||||
goto reply;
|
||||
|
||||
default:
|
||||
break; /* We don't know how to reply, just go on (to drop). */
|
||||
}
|
||||
@@ -600,11 +621,24 @@ reply:
|
||||
void ipv4_forward_broadcast(FAR struct net_driver_s *dev,
|
||||
FAR struct ipv4_hdr_s *ipv4)
|
||||
{
|
||||
/* Check if source device supports IP forwarding capability.
|
||||
* Broadcast/multicast forwarding is only allowed if the receiving
|
||||
* device has SRC_FORWARD enabled. This is consistent with the unicast
|
||||
* forwarding policy enforced in ipv4_forward().
|
||||
*/
|
||||
|
||||
if (IFF_IS_NOSRC_FORWARD(dev->d_flags))
|
||||
{
|
||||
nwarn("WARNING: IP broadcast forwarding disabled "
|
||||
"on source device %s\n", dev->d_ifname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't bother if the TTL would expire */
|
||||
|
||||
if (ipv4->ttl > 1)
|
||||
{
|
||||
/* Forward the the broadcast/multicast packet to all devices except,
|
||||
/* Forward the broadcast/multicast packet to all devices except,
|
||||
* of course, the device that received the packet.
|
||||
*/
|
||||
|
||||
|
||||
@@ -340,6 +340,16 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev,
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
/* Check if destination device supports IP forwarding capability */
|
||||
|
||||
if (IFF_IS_NODST_FORWARD(fwddev->d_flags))
|
||||
{
|
||||
nwarn("WARNING: IP forwarding disabled on destination device %s\n",
|
||||
fwddev->d_ifname);
|
||||
ret = -EOPNOTSUPP;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_IPFILTER
|
||||
/* Do filter before forwarding, to make sure we drop silently before
|
||||
* replying any other errors.
|
||||
@@ -603,6 +613,16 @@ int ipv6_forward(FAR struct net_driver_s *dev, FAR struct ipv6_hdr_s *ipv6)
|
||||
int icmpv6_reply_data;
|
||||
#endif /* CONFIG_NET_ICMP */
|
||||
|
||||
/* Check if source device supports IP forwarding capability */
|
||||
|
||||
if (IFF_IS_NOSRC_FORWARD(dev->d_flags))
|
||||
{
|
||||
nwarn("WARNING: IP forwarding disabled on source device %s\n",
|
||||
dev->d_ifname);
|
||||
ret = -EOPNOTSUPP;
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Search for a device that can forward this packet. */
|
||||
|
||||
fwddev = netdev_findby_ripv6addr(ipv6->srcipaddr, ipv6->destipaddr);
|
||||
@@ -718,6 +738,12 @@ drop:
|
||||
icmpv6_reply_data = 0;
|
||||
goto reply;
|
||||
|
||||
case -EOPNOTSUPP:
|
||||
icmpv6_reply_type = ICMPv6_DEST_UNREACHABLE;
|
||||
icmpv6_reply_code = ICMPv6_ADDR_UNREACH;
|
||||
icmpv6_reply_data = 0;
|
||||
goto reply;
|
||||
|
||||
default:
|
||||
break; /* We don't know how to reply, just go on (to drop). */
|
||||
}
|
||||
@@ -771,11 +797,24 @@ reply:
|
||||
void ipv6_forward_broadcast(FAR struct net_driver_s *dev,
|
||||
FAR struct ipv6_hdr_s *ipv6)
|
||||
{
|
||||
/* Check if source device supports IP forwarding capability.
|
||||
* Broadcast/multicast forwarding is only allowed if the receiving
|
||||
* device has SRC_FORWARD enabled. This is consistent with the unicast
|
||||
* forwarding policy enforced in ipv6_forward().
|
||||
*/
|
||||
|
||||
if (IFF_IS_NOSRC_FORWARD(dev->d_flags))
|
||||
{
|
||||
nwarn("WARNING: IP broadcast forwarding disabled "
|
||||
"on source device %s\n", dev->d_ifname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't bother if the TTL would expire */
|
||||
|
||||
if (ipv6->ttl > 1)
|
||||
{
|
||||
/* Forward the the broadcast/multicast packet to all devices except,
|
||||
/* Forward the broadcast/multicast packet to all devices except,
|
||||
* of course, the device that received the packet.
|
||||
*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user