-
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.
- Loading branch information
Praveen Chaudhary
committed
Dec 23, 2020
1 parent
1823653
commit c102a6b
Showing
2 changed files
with
180 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,179 @@ | ||
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt | ||
index 7eb9366..8f0dfc8 100644 | ||
--- a/Documentation/networking/ip-sysctl.txt | ||
+++ b/Documentation/networking/ip-sysctl.txt | ||
@@ -1537,6 +1537,12 @@ accept_ra_defrtr - BOOLEAN | ||
Functional default: enabled if accept_ra is enabled. | ||
disabled if accept_ra is disabled. | ||
|
||
+accept_ra_defrtr_metric - INTEGER | ||
+ Metric for default router learned in Router Advertisement. | ||
+ | ||
+ Functional default: 0 if accept_ra_defrtr is enabled. | ||
+ -1 if accept_ra_defrtr is disabled. | ||
+ | ||
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 8415bf1..0add3f6 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; | ||
+ __s32 accept_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 5e26d61..a543ebf 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, | ||
+ unsigned int 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 9c0f4a9..93449ac 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_ACCEPT_RA_DEFRTR_METRIC, | ||
DEVCONF_MAX | ||
}; | ||
|
||
diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h | ||
index d71013f..f1f37ab 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_ACCEPT_RA_DEFRTR_METRIC=28, | ||
__NET_IPV6_MAX | ||
}; | ||
|
||
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c | ||
index 07148b4..082be0e 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_ACCEPT_RA_DEFRTR_METRIC, "accept_ra_defrtr_metric" }, | ||
{} | ||
}; | ||
|
||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c | ||
index 627cd24..2dfc9d9 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, | ||
+ .accept_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, | ||
+ .accept_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_ACCEPT_RA_DEFRTR_METRIC] = cnf->accept_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 | ||
@@ -6348,6 +6351,13 @@ static const struct ctl_table addrconf_sysctl[] = { | ||
.proc_handler = proc_dointvec, | ||
}, | ||
{ | ||
+ .procname = "accept_ra_defrtr_metric", | ||
+ .data = &ipv6_devconf.accept_ra_defrtr_metric, | ||
+ .maxlen = sizeof(int), | ||
+ .mode = 0644, | ||
+ .proc_handler = proc_dointvec, | ||
+ }, | ||
+ { | ||
.procname = "accept_ra_min_hop_limit", | ||
.data = &ipv6_devconf.accept_ra_min_hop_limit, | ||
.maxlen = sizeof(int), | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c | ||
index 673a4a9..546e8d5 100644 | ||
--- a/net/ipv6/ndisc.c | ||
+++ b/net/ipv6/ndisc.c | ||
@@ -1287,18 +1287,21 @@ static void ndisc_router_discovery(struct sk_buff *skb) | ||
return; | ||
} | ||
} | ||
- if (rt && lifetime == 0) { | ||
+ /* delete the route if lifetime is 0 or if metric is changed */ | ||
+ unsigned int defrtr_usr_metric = in6_dev->cnf.accept_ra_defrtr_metric; | ||
+ if (rt && (lifetime == 0 || | ||
+ (defrtr_usr_metric && rt->rt6i_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 9c36a74..2194834 100644 | ||
--- a/net/ipv6/route.c | ||
+++ b/net/ipv6/route.c | ||
@@ -3608,11 +3608,11 @@ 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, unsigned int 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 ? 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), | ||
@@ -3622,7 +3622,8 @@ struct fib6_info *rt6_add_dflt_router(struct net *net, | ||
.fc_nlinfo.nlh = NULL, | ||
.fc_nlinfo.nl_net = net, | ||
}; | ||
- | ||
+ ND_PRINTK(3, info, "RA: metric: %d for dev: %s\n", | ||
+ cfg.fc_metric, dev->name); | ||
cfg.fc_gateway = *gwaddr; | ||
|
||
if (!ip6_route_add(&cfg, GFP_ATOMIC, NULL)) { |
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