* [PATCH] Allow user to set metric on default route learned via Router Advertisement.
@ 2020-12-30 8:46 Praveen Chaudhary
0 siblings, 0 replies; 4+ messages in thread
From: Praveen Chaudhary @ 2020-12-30 8:46 UTC (permalink / raw)
To: davem, kuba, corbet, kuznet, yoshfuji, netdev, linux-doc, linux-kernel
Allow user to set metric on default route learned via Router Advertisement.
Not: RFC 4191 does not say anything for metric for IPv6 default route.
Fix:
For IPv4, default route is learned via DHCPv4 and user is allowed to change
metric using config etc/network/interfaces. But for IPv6, default route can
be learned via RA, for which, currently a fixed metric value 1024 is used.
Ideally, user should be able to configure metric on default route for IPv6
similar to IPv4. This fix adds sysctl for the same.
Logs:
----------------------------------------------------------------
For IPv4:
----------------------------------------------------------------
Config in etc/network/interfaces
----------------------------------------------------------------
```
auto eth0
iface eth0 inet dhcp
metric 4261413864
```
IPv4 Kernel Route Table:
----------------------------------------------------------------
```
$ sudo route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.11.44.1 0.0.0.0 UG -33553432 0 0 eth0
```
FRR Table, if default route is learned via routing protocol too.
----------------------------------------------------------------
```
# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, P - PIM, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
> - selected route, * - FIB route
S>* 0.0.0.0/0 [20/0] is directly connected, eth0, 00:00:03
K 0.0.0.0/0 [254/1000] via 172.21.47.1, eth0, 6d08h51m
```
----------------------------------------------------------------
i.e. User can prefer Default Router learned via Routing Protocol,
Similar behavior is not possible for IPv6, without this fix.
----------------------------------------------------------------
After fix [for IPv6]:
----------------------------------------------------------------
```
sudo sysctl -w net.ipv6.conf.eth0.net.ipv6.conf.eth0.accept_ra_defrtr_metric=0x770003e9
```
IP monitor:
----------------------------------------------------------------
```
default via fe80::be16:65ff:feb3:ce8e dev eth0 proto ra metric 1996489705 pref high
```
Kernel IPv6 routing table
----------------------------------------------------------------
```
Destination Next Hop Flag Met Ref Use If
::/0 fe80::be16:65ff:feb3:ce8e UGDAe 1996489705 0
0 eth0
```
FRR Routing Table, if default route is learned via routing protocol.
----------------------------------------------------------------
# show ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
> - selected route, * - FIB route
S>* ::/0 [20/0] is directly connected, eth0, 00:00:06
K ::/0 [119/1001] via fe80::be16:65ff:feb3:ce8e, eth0, 6d07h43m
----------------------------------------------------------------
Praveen Chaudhary (1):
Allow user to set metric on default route learned via Router
Advertisement.
Documentation/networking/ip-sysctl.rst | 8 ++++++++
include/linux/ipv6.h | 1 +
include/net/ip6_route.h | 3 ++-
include/uapi/linux/ipv6.h | 1 +
include/uapi/linux/sysctl.h | 1 +
net/ipv6/addrconf.c | 10 ++++++++++
net/ipv6/ndisc.c | 15 +++++++++++----
net/ipv6/route.c | 8 +++++---
8 files changed, 39 insertions(+), 8 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Allow user to set metric on default route learned via Router Advertisement.
2020-12-30 8:48 Praveen Chaudhary
2020-12-30 8:48 ` Praveen Chaudhary
@ 2020-12-30 16:41 ` Andrew Lunn
1 sibling, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2020-12-30 16:41 UTC (permalink / raw)
To: Praveen Chaudhary
Cc: davem, kuba, corbet, kuznet, yoshfuji, netdev, linux-doc, linux-kernel
On Wed, Dec 30, 2020 at 12:48:32AM -0800, Praveen Chaudhary wrote:
> Allow user to set metric on default route learned via Router Advertisement.
> Not: RFC 4191 does not say anything for metric for IPv6 default route.
Hi Praveen
Please take a look at
https://www.kernel.org/doc/html/latest/process/submitting-patches.html
and
https://www.kernel.org/doc/html/latest/networking/netdev-FAQ.html
In particular, you should be using git format-patch, which will
correctly number your patches, make use of a version number inside the
[PATCH v0 net-next] subject part, and please indicate which tree this
is for.
Andrew
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH] Allow user to set metric on default route learned via Router Advertisement.
2020-12-30 8:48 Praveen Chaudhary
@ 2020-12-30 8:48 ` Praveen Chaudhary
2020-12-30 16:41 ` Andrew Lunn
1 sibling, 0 replies; 4+ messages in thread
From: Praveen Chaudhary @ 2020-12-30 8:48 UTC (permalink / raw)
To: davem, kuba, corbet, kuznet, yoshfuji, netdev, linux-doc, linux-kernel
Cc: Zhenggen Xu
Fix:
For IPv4, default route is learned via DHCPv4 and user is allowed to change
metric using config etc/network/interfaces. But for IPv6, default route can
be learned via RA, for which, currently a fixed metric value 1024 is used.
Ideally, user should be able to configure metric on default route for IPv6
similar to IPv4. This fix adds sysctl for the same.
Signed-off-by: Praveen Chaudhary<pchaudhary@linkedin.com>
Signed-off-by: Zhenggen Xu<zxu1@linkedin.com>
---
Documentation/networking/ip-sysctl.rst | 8 ++++++++
include/linux/ipv6.h | 1 +
include/net/ip6_route.h | 3 ++-
include/uapi/linux/ipv6.h | 1 +
include/uapi/linux/sysctl.h | 1 +
net/ipv6/addrconf.c | 10 ++++++++++
net/ipv6/ndisc.c | 15 +++++++++++----
net/ipv6/route.c | 8 +++++---
8 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index dd2b12a..073c1f3 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -1871,6 +1871,14 @@ accept_ra_defrtr - BOOLEAN
- 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.
+ * Ignored, if accept_ra_defrtr is enabled.
+
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 dda61d1..19af90c 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 2a52777..a470bda 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -174,7 +174,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 13e8751..945de5d 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -189,6 +189,7 @@ enum {
DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN,
DEVCONF_NDISC_TCLASS,
DEVCONF_RPL_SEG_ENABLED,
+ DEVCONF_ACCEPT_RA_DEFRTR_METRIC,
DEVCONF_MAX
};
diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h
index 458179d..5e79c19 100644
--- a/include/uapi/linux/sysctl.h
+++ b/include/uapi/linux/sysctl.h
@@ -571,6 +571,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/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index eff2cac..702ec4a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -205,6 +205,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,
@@ -260,6 +261,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,
@@ -5475,6 +5477,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
@@ -6668,6 +6671,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 7671747..05f7f24 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1180,6 +1180,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
unsigned int pref = 0;
__u32 old_if_flags;
bool send_ifinfo_notify = false;
+ unsigned int defrtr_usr_metric = 0;
__u8 *opt = (__u8 *)(ra_msg + 1);
@@ -1303,18 +1304,24 @@ static void ndisc_router_discovery(struct sk_buff *skb)
return;
}
}
- if (rt && lifetime == 0) {
+
+ defrtr_usr_metric = in6_dev->cnf.accept_ra_defrtr_metric;
+ /* default metric is IP6_RT_PRIO_USER */
+ if (defrtr_usr_metric == 0)
+ defrtr_usr_metric = IP6_RT_PRIO_USER;
+ /* delete the route if lifetime is 0 or if new metric is needed */
+ if (rt && (lifetime == 0 || rt->rt6i_metric != defrtr_usr_metric)) {
ip6_del_rt(net, rt, false);
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 188e114..249b211 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4252,11 +4252,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,
+ 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),
@@ -4266,7 +4267,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)) {
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH] Allow user to set metric on default route learned via Router Advertisement.
@ 2020-12-30 8:48 Praveen Chaudhary
2020-12-30 8:48 ` Praveen Chaudhary
2020-12-30 16:41 ` Andrew Lunn
0 siblings, 2 replies; 4+ messages in thread
From: Praveen Chaudhary @ 2020-12-30 8:48 UTC (permalink / raw)
To: davem, kuba, corbet, kuznet, yoshfuji, netdev, linux-doc, linux-kernel
Allow user to set metric on default route learned via Router Advertisement.
Not: RFC 4191 does not say anything for metric for IPv6 default route.
Fix:
For IPv4, default route is learned via DHCPv4 and user is allowed to change
metric using config etc/network/interfaces. But for IPv6, default route can
be learned via RA, for which, currently a fixed metric value 1024 is used.
Ideally, user should be able to configure metric on default route for IPv6
similar to IPv4. This fix adds sysctl for the same.
Logs:
----------------------------------------------------------------
For IPv4:
----------------------------------------------------------------
Config in etc/network/interfaces
----------------------------------------------------------------
```
auto eth0
iface eth0 inet dhcp
metric 4261413864
```
IPv4 Kernel Route Table:
----------------------------------------------------------------
```
$ sudo route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.11.44.1 0.0.0.0 UG -33553432 0 0 eth0
```
FRR Table, if default route is learned via routing protocol too.
----------------------------------------------------------------
```
# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, P - PIM, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
> - selected route, * - FIB route
S>* 0.0.0.0/0 [20/0] is directly connected, eth0, 00:00:03
K 0.0.0.0/0 [254/1000] via 172.21.47.1, eth0, 6d08h51m
```
----------------------------------------------------------------
i.e. User can prefer Default Router learned via Routing Protocol,
Similar behavior is not possible for IPv6, without this fix.
----------------------------------------------------------------
After fix [for IPv6]:
----------------------------------------------------------------
```
sudo sysctl -w net.ipv6.conf.eth0.net.ipv6.conf.eth0.accept_ra_defrtr_metric=0x770003e9
```
IP monitor:
----------------------------------------------------------------
```
default via fe80::be16:65ff:feb3:ce8e dev eth0 proto ra metric 1996489705 pref high
```
Kernel IPv6 routing table
----------------------------------------------------------------
```
Destination Next Hop Flag Met Ref Use If
::/0 fe80::be16:65ff:feb3:ce8e UGDAe 1996489705 0
0 eth0
```
FRR Routing Table, if default route is learned via routing protocol.
----------------------------------------------------------------
# show ipv6 route
Codes: K - kernel route, C - connected, S - static, R - RIPng,
O - OSPFv3, I - IS-IS, B - BGP, N - NHRP, T - Table,
v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
> - selected route, * - FIB route
S>* ::/0 [20/0] is directly connected, eth0, 00:00:06
K ::/0 [119/1001] via fe80::be16:65ff:feb3:ce8e, eth0, 6d07h43m
----------------------------------------------------------------
Praveen Chaudhary (1):
Allow user to set metric on default route learned via Router
Advertisement.
Documentation/networking/ip-sysctl.rst | 8 ++++++++
include/linux/ipv6.h | 1 +
include/net/ip6_route.h | 3 ++-
include/uapi/linux/ipv6.h | 1 +
include/uapi/linux/sysctl.h | 1 +
net/ipv6/addrconf.c | 10 ++++++++++
net/ipv6/ndisc.c | 15 +++++++++++----
net/ipv6/route.c | 8 +++++---
8 files changed, 39 insertions(+), 8 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-12-30 16:42 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-30 8:46 [PATCH] Allow user to set metric on default route learned via Router Advertisement Praveen Chaudhary
2020-12-30 8:48 Praveen Chaudhary
2020-12-30 8:48 ` Praveen Chaudhary
2020-12-30 16:41 ` Andrew Lunn
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.