Added new procfs flag to toggle the automatic addition of prefix
routes on a per device basis. The new flag is accept_ra_prefix_route.

A value of 0 for the flag maybe used in some forwarding scenarios
when a userspace daemon is managing the routing.
Manual deletion of the kernel installed route was not sufficient as
kernel was adding back the route.

Defaults to 1 as to not break existing behavior.

Signed-off-by: Subash Abhinov Kasiviswanathan <subas...@codeaurora.org>
---
 Documentation/networking/ip-sysctl.rst | 10 ++++++++++
 include/linux/ipv6.h                   |  1 +
 include/uapi/linux/ipv6.h              |  1 +
 net/ipv6/addrconf.c                    | 16 +++++++++++++---
 4 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.rst 
b/Documentation/networking/ip-sysctl.rst
index c7952ac..9f0d92d 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -2022,6 +2022,16 @@ accept_ra_mtu - BOOLEAN
                - enabled if accept_ra is enabled.
                - disabled if accept_ra is disabled.
 
+accept_ra_prefix_route - BOOLEAN
+       Apply the prefix route based on the RA. If disabled, kernel
+       does not install the route. This can be used if a userspace
+       daemon is managing the routing.
+
+       Functional default:
+
+               - enabled if accept_ra_prefix_route is enabled
+               - disabled if accept_ra_prefix_route is disabled
+
 accept_redirects - BOOLEAN
        Accept Redirects.
 
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 70b2ad3..ae81f7d 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -76,6 +76,7 @@ struct ipv6_devconf {
        __s32           disable_policy;
        __s32           ndisc_tclass;
        __s32           rpl_seg_enabled;
+       __s32           accept_ra_prefix_route;
 
        struct ctl_table_header *sysctl_header;
 };
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 70603775..194b272 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -190,6 +190,7 @@ enum {
        DEVCONF_NDISC_TCLASS,
        DEVCONF_RPL_SEG_ENABLED,
        DEVCONF_RA_DEFRTR_METRIC,
+       DEVCONF_ACCEPT_RA_PREFIX_ROUTE,
        DEVCONF_MAX
 };
 
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f2337fb..5ddef05 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -237,6 +237,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
        .addr_gen_mode          = IN6_ADDR_GEN_MODE_EUI64,
        .disable_policy         = 0,
        .rpl_seg_enabled        = 0,
+       .accept_ra_prefix_route = 1,
 };
 
 static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -293,6 +294,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly 
= {
        .addr_gen_mode          = IN6_ADDR_GEN_MODE_EUI64,
        .disable_policy         = 0,
        .rpl_seg_enabled        = 0,
+       .accept_ra_prefix_route = 1,
 };
 
 /* Check if link is ready: is it up and is a valid qdisc available */
@@ -2750,9 +2752,10 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 
*opt, int len, bool sllao)
                                flags |= RTF_EXPIRES;
                                expires = jiffies_to_clock_t(rt_expires);
                        }
-                       addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
-                                             0, dev, expires, flags,
-                                             GFP_ATOMIC);
+                       if (dev->ip6_ptr->cnf.accept_ra_prefix_route) {
+                               addrconf_prefix_route(&pinfo->prefix, 
pinfo->prefix_len,
+                                                     0, dev, expires, flags, 
GFP_ATOMIC);
+                       }
                }
                fib6_info_release(rt);
        }
@@ -6859,6 +6862,13 @@ static const struct ctl_table addrconf_sysctl[] = {
        {
                .procname       = "seg6_enabled",
                .data           = &ipv6_devconf.seg6_enabled,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
+       {
+               .procname       = "accept_ra_prefix_route",
+               .data           = &ipv6_devconf.accept_ra_prefix_route,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

Reply via email to