[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20190330184726.3672-1-ssuryaextr@gmail.com>
Date: Sat, 30 Mar 2019 14:47:26 -0400
From: Stephen Suryaputra <ssuryaextr@...il.com>
To: netdev@...r.kernel.org
Cc: Stephen Suryaputra <ssuryaextr@...il.com>
Subject: [PATCH net-next] ipv4: Add ability to filter LSRR or SSRR
Support use cases where source routing is allowed but only loose or
strict. Add source_router_filter netdev configuration to be used
when allow_source_router is set to control which types can be processed.
Signed-off-by: Stephen Suryaputra <ssuryaextr@...il.com>
---
Documentation/networking/ip-sysctl.txt | 7 +++++++
include/linux/inetdevice.h | 6 ++++++
include/uapi/linux/ip.h | 1 +
net/ipv4/devinet.c | 2 ++
net/ipv4/ip_input.c | 3 +++
5 files changed, 19 insertions(+)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 5eedc6941ce5..a6a7f4660f78 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1164,6 +1164,13 @@ accept_source_route - BOOLEAN
default TRUE (router)
FALSE (host)
+source_route_filter - INTEGER
+ 0 - No filter.
+ 1 - Drop packets with Strict SRR option.
+ 2 - Drop packets with Loose SRR option.
+ Default value is 0. The values from conf/{all,interface} are used when
+ checking whether to drop or not on the {interface}.
+
accept_local - BOOLEAN
Accept packets with local source addresses. In combination with
suitable routing, this can be used to direct packets between two
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index a64f21a97369..8ee2d3d507db 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -100,6 +100,12 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
#define IN_DEV_SRC_VMARK(in_dev) IN_DEV_ORCONF((in_dev), SRC_VMARK)
#define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \
ACCEPT_SOURCE_ROUTE)
+#define IN_DEV_FILTER_SSRR(in_dev) \
+ ((IPV4_DEVCONF_ALL(dev_net(in_dev->dev), SOURCE_ROUTE_FILTER) == 1) || \
+ (IN_DEV_CONF_GET(in_dev, SOURCE_ROUTE_FILTER) == 1))
+#define IN_DEV_FILTER_LSRR(in_dev) \
+ ((IPV4_DEVCONF_ALL(dev_net(in_dev->dev), SOURCE_ROUTE_FILTER) == 2) || \
+ (IN_DEV_CONF_GET(in_dev, SOURCE_ROUTE_FILTER) == 2))
#define IN_DEV_ACCEPT_LOCAL(in_dev) IN_DEV_ORCONF((in_dev), ACCEPT_LOCAL)
#define IN_DEV_BOOTP_RELAY(in_dev) IN_DEV_ANDCONF((in_dev), BOOTP_RELAY)
diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
index e42d13b55cf3..b256ca8cef60 100644
--- a/include/uapi/linux/ip.h
+++ b/include/uapi/linux/ip.h
@@ -169,6 +169,7 @@ enum
IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
IPV4_DEVCONF_DROP_GRATUITOUS_ARP,
IPV4_DEVCONF_BC_FORWARDING,
+ IPV4_DEVCONF_SOURCE_ROUTE_FILTER,
__IPV4_DEVCONF_MAX
};
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index eb514f312e6f..25dd87acd61a 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -2462,6 +2462,8 @@ static struct devinet_sysctl_table {
DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
"accept_source_route"),
+ DEVINET_SYSCTL_RW_ENTRY(SOURCE_ROUTE_FILTER,
+ "source_route_filter"),
DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index ecce2dc78f17..f2cac23218be 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -295,6 +295,9 @@ static inline bool ip_rcv_options(struct sk_buff *skb)
&iph->daddr);
goto drop;
}
+ if ((opt->is_strictroute && IN_DEV_FILTER_SSRR(in_dev)) ||
+ (!opt->is_strictroute && IN_DEV_FILTER_LSRR(in_dev)))
+ goto drop;
}
if (ip_options_rcv_srr(skb))
--
2.17.1
Powered by blists - more mailing lists