Skip to content

Commit

Permalink
ip6_ra_metric
Browse files Browse the repository at this point in the history
  • Loading branch information
Praveen Chaudhary committed Dec 23, 2020
1 parent 1823653 commit c102a6b
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 0 deletions.
179 changes: 179 additions & 0 deletions patch/msft-kernel-ipv6-ra-metric-sysctl.patch
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)) {
1 change: 1 addition & 0 deletions patch/series
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ e1000-Do-not-perform-reset-in-reset_task-if-we-are-a.patch
0004-dt-bindings-hwmon-Add-missing-documentation-for-lm75.patch
0005-dt-bindings-hwmon-Add-tmp75b-to-lm75.txt.patch
0006-device-tree-bindinds-add-NXP-PCT2075-as-compatible-d.patch
msft-kernel-ipv6-ra-metric-sysctl.patch
#
# (Marvell)
# 0042-Marvell-a385-Micron-4G-flash-support.patch
Expand Down

0 comments on commit c102a6b

Please sign in to comment.