-
Notifications
You must be signed in to change notification settings - Fork 172
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Praveen Chaudhary<[email protected]>
- Loading branch information
Praveen Chaudhary
committed
Jan 19, 2021
1 parent
79ab859
commit a3bcfed
Showing
2 changed files
with
188 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt | ||
index 7eb936642..e0faaa97b 100644 | ||
--- a/Documentation/networking/ip-sysctl.txt | ||
+++ b/Documentation/networking/ip-sysctl.txt | ||
@@ -1537,6 +1537,19 @@ accept_ra_defrtr - BOOLEAN | ||
Functional default: enabled if accept_ra is enabled. | ||
disabled if accept_ra is disabled. | ||
|
||
+ra_defrtr_metric - INTEGER | ||
+ Route metric for default route learned in Router Advertisement. This value | ||
+ will be assigned as metric for the default route learned via IPv6 Router | ||
+ Advertisement. Takes affect only if accept_ra_defrtr is enabled. | ||
+ | ||
+ Possible values are: | ||
+ 0: | ||
+ default value will be used for route metric | ||
+ i.e. IP6_RT_PRIO_USER 1024. | ||
+ 1 to 0xFFFFFFFF: | ||
+ current value will be used for route metric. | ||
+ | ||
+ | ||
accept_ra_from_local - BOOLEAN | ||
Accept RA with source-address that is found on local machine | ||
if the RA is otherwise proper and able to be accepted. | ||
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h | ||
index 8415bf1a9..ab98f5fa2 100644 | ||
--- a/include/linux/ipv6.h | ||
+++ b/include/linux/ipv6.h | ||
@@ -31,6 +31,7 @@ struct ipv6_devconf { | ||
__s32 max_desync_factor; | ||
__s32 max_addresses; | ||
__s32 accept_ra_defrtr; | ||
+ __u32 ra_defrtr_metric; | ||
__s32 accept_ra_min_hop_limit; | ||
__s32 accept_ra_pinfo; | ||
__s32 ignore_routes_with_linkdown; | ||
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h | ||
index 5e26d6186..7087fb5e5 100644 | ||
--- a/include/net/ip6_route.h | ||
+++ b/include/net/ip6_route.h | ||
@@ -153,7 +153,8 @@ struct fib6_info *rt6_get_dflt_router(struct net *net, | ||
struct net_device *dev); | ||
struct fib6_info *rt6_add_dflt_router(struct net *net, | ||
const struct in6_addr *gwaddr, | ||
- struct net_device *dev, unsigned int pref); | ||
+ struct net_device *dev, unsigned int pref, | ||
+ u32 defrtr_usr_metric); | ||
|
||
void rt6_purge_dflt_routers(struct net *net); | ||
|
||
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h | ||
index 9c0f4a92b..481616cc2 100644 | ||
--- a/include/uapi/linux/ipv6.h | ||
+++ b/include/uapi/linux/ipv6.h | ||
@@ -187,6 +187,7 @@ enum { | ||
DEVCONF_DISABLE_POLICY, | ||
DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN, | ||
DEVCONF_NDISC_TCLASS, | ||
+ DEVCONF_RA_DEFRTR_METRIC, | ||
DEVCONF_MAX | ||
}; | ||
|
||
diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h | ||
index d71013fff..42fb25093 100644 | ||
--- a/include/uapi/linux/sysctl.h | ||
+++ b/include/uapi/linux/sysctl.h | ||
@@ -570,6 +570,7 @@ enum { | ||
NET_IPV6_ACCEPT_SOURCE_ROUTE=25, | ||
NET_IPV6_ACCEPT_RA_FROM_LOCAL=26, | ||
NET_IPV6_ACCEPT_RA_RT_INFO_MIN_PLEN=27, | ||
+ NET_IPV6_RA_DEFRTR_METRIC=28, | ||
__NET_IPV6_MAX | ||
}; | ||
|
||
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c | ||
index 07148b497..67b5ef45b 100644 | ||
--- a/kernel/sysctl_binary.c | ||
+++ b/kernel/sysctl_binary.c | ||
@@ -525,6 +525,7 @@ static const struct bin_table bin_net_ipv6_conf_var_table[] = { | ||
{ CTL_INT, NET_IPV6_PROXY_NDP, "proxy_ndp" }, | ||
{ CTL_INT, NET_IPV6_ACCEPT_SOURCE_ROUTE, "accept_source_route" }, | ||
{ CTL_INT, NET_IPV6_ACCEPT_RA_FROM_LOCAL, "accept_ra_from_local" }, | ||
+ { CTL_INT, NET_IPV6_RA_DEFRTR_METRIC, "ra_defrtr_metric" }, | ||
{} | ||
}; | ||
|
||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c | ||
index 627cd24b7..2f68947c2 100644 | ||
--- a/net/ipv6/addrconf.c | ||
+++ b/net/ipv6/addrconf.c | ||
@@ -209,6 +209,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { | ||
.max_desync_factor = MAX_DESYNC_FACTOR, | ||
.max_addresses = IPV6_MAX_ADDRESSES, | ||
.accept_ra_defrtr = 1, | ||
+ .ra_defrtr_metric = 0, | ||
.accept_ra_from_local = 0, | ||
.accept_ra_min_hop_limit= 1, | ||
.accept_ra_pinfo = 1, | ||
@@ -263,6 +264,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { | ||
.max_desync_factor = MAX_DESYNC_FACTOR, | ||
.max_addresses = IPV6_MAX_ADDRESSES, | ||
.accept_ra_defrtr = 1, | ||
+ .ra_defrtr_metric = 0, | ||
.accept_ra_from_local = 0, | ||
.accept_ra_min_hop_limit= 1, | ||
.accept_ra_pinfo = 1, | ||
@@ -5199,6 +5201,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, | ||
array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor; | ||
array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses; | ||
array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr; | ||
+ array[DEVCONF_RA_DEFRTR_METRIC] = cnf->ra_defrtr_metric; | ||
array[DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT] = cnf->accept_ra_min_hop_limit; | ||
array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo; | ||
#ifdef CONFIG_IPV6_ROUTER_PREF | ||
@@ -6347,6 +6350,13 @@ static const struct ctl_table addrconf_sysctl[] = { | ||
.mode = 0644, | ||
.proc_handler = proc_dointvec, | ||
}, | ||
+ { | ||
+ .procname = "ra_defrtr_metric", | ||
+ .data = &ipv6_devconf.ra_defrtr_metric, | ||
+ .maxlen = sizeof(u32), | ||
+ .mode = 0644, | ||
+ .proc_handler = proc_douintvec, | ||
+ }, | ||
{ | ||
.procname = "accept_ra_min_hop_limit", | ||
.data = &ipv6_devconf.accept_ra_min_hop_limit, | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c | ||
index 673a4a932..c350a16dd 100644 | ||
--- a/net/ipv6/ndisc.c | ||
+++ b/net/ipv6/ndisc.c | ||
@@ -1156,6 +1156,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) | ||
struct neighbour *neigh = NULL; | ||
struct inet6_dev *in6_dev; | ||
struct fib6_info *rt = NULL; | ||
+ u32 defrtr_usr_metric; | ||
struct net *net; | ||
int lifetime; | ||
struct ndisc_options ndopts; | ||
@@ -1287,18 +1288,23 @@ static void ndisc_router_discovery(struct sk_buff *skb) | ||
return; | ||
} | ||
} | ||
- if (rt && lifetime == 0) { | ||
+ /* Set default route metric if specified by user */ | ||
+ defrtr_usr_metric = in6_dev->cnf.ra_defrtr_metric; | ||
+ if (defrtr_usr_metric == 0) | ||
+ defrtr_usr_metric = IP6_RT_PRIO_USER; | ||
+ /* delete the route if lifetime is 0 or if metric needs change */ | ||
+ if (rt && ((lifetime == 0) || (rt->fib6_metric != defrtr_usr_metric))) { | ||
ip6_del_rt(net, rt); | ||
rt = NULL; | ||
} | ||
|
||
- ND_PRINTK(3, info, "RA: rt: %p lifetime: %d, for dev: %s\n", | ||
- rt, lifetime, skb->dev->name); | ||
+ ND_PRINTK(3, info, "RA: rt: %p lifetime: %d, metric: %d, for dev: %s\n", | ||
+ rt, lifetime, defrtr_usr_metric, skb->dev->name); | ||
if (!rt && lifetime) { | ||
ND_PRINTK(3, info, "RA: adding default router\n"); | ||
|
||
rt = rt6_add_dflt_router(net, &ipv6_hdr(skb)->saddr, | ||
- skb->dev, pref); | ||
+ skb->dev, pref, defrtr_usr_metric); | ||
if (!rt) { | ||
ND_PRINTK(0, err, | ||
"RA: %s failed to add default route\n", | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c | ||
index 9c36a743d..8b3fddc50 100644 | ||
--- a/net/ipv6/route.c | ||
+++ b/net/ipv6/route.c | ||
@@ -3608,11 +3608,12 @@ struct fib6_info *rt6_get_dflt_router(struct net *net, | ||
struct fib6_info *rt6_add_dflt_router(struct net *net, | ||
const struct in6_addr *gwaddr, | ||
struct net_device *dev, | ||
- unsigned int pref) | ||
+ unsigned int pref, | ||
+ u32 defrtr_usr_metric) | ||
{ | ||
struct fib6_config cfg = { | ||
.fc_table = l3mdev_fib_table(dev) ? : RT6_TABLE_DFLT, | ||
- .fc_metric = IP6_RT_PRIO_USER, | ||
+ .fc_metric = defrtr_usr_metric ? : IP6_RT_PRIO_USER, | ||
.fc_ifindex = dev->ifindex, | ||
.fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | | ||
RTF_UP | RTF_EXPIRES | RTF_PREF(pref), |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters