* [PATCH v4 4/7] ipv6 addrconf: add new sysctl 'router_solicitation_max_interval'
From: Maciej Żenczykowski @ 2016-09-25 11:03 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474801390-6891-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
Accessible via:
/proc/sys/net/ipv6/conf/*/router_solicitation_max_interval
For now we default it to the same value as the normal interval.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/linux/ipv6.h | 1 +
include/net/addrconf.h | 1 +
include/uapi/linux/ipv6.h | 1 +
net/ipv6/addrconf.c | 11 +++++++++++
4 files changed, 14 insertions(+)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index c6dbcd84a2c7..7e9a789be5e0 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -18,6 +18,7 @@ struct ipv6_devconf {
__s32 dad_transmits;
__s32 rtr_solicits;
__s32 rtr_solicit_interval;
+ __s32 rtr_solicit_max_interval;
__s32 rtr_solicit_delay;
__s32 force_mld_version;
__s32 mldv1_unsolicited_report_interval;
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 9826d3a9464c..275e5af4c2f4 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -3,6 +3,7 @@
#define MAX_RTR_SOLICITATIONS 3
#define RTR_SOLICITATION_INTERVAL (4*HZ)
+#define RTR_SOLICITATION_MAX_INTERVAL (4*HZ)
#define MIN_VALID_LIFETIME (2*3600) /* 2 hours */
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 395876060f50..8c2772340c3f 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -177,6 +177,7 @@ enum {
DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
DEVCONF_DROP_UNSOLICITED_NA,
DEVCONF_KEEP_ADDR_ON_DOWN,
+ DEVCONF_RTR_SOLICIT_MAX_INTERVAL,
DEVCONF_MAX
};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6c63bf06fbcf..255be34cdbce 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -187,6 +187,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
.dad_transmits = 1,
.rtr_solicits = MAX_RTR_SOLICITATIONS,
.rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
+ .rtr_solicit_max_interval = RTR_SOLICITATION_MAX_INTERVAL,
.rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
.use_tempaddr = 0,
.temp_valid_lft = TEMP_VALID_LIFETIME,
@@ -232,6 +233,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
.dad_transmits = 1,
.rtr_solicits = MAX_RTR_SOLICITATIONS,
.rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
+ .rtr_solicit_max_interval = RTR_SOLICITATION_MAX_INTERVAL,
.rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
.use_tempaddr = 0,
.temp_valid_lft = TEMP_VALID_LIFETIME,
@@ -4891,6 +4893,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
array[DEVCONF_RTR_SOLICIT_INTERVAL] =
jiffies_to_msecs(cnf->rtr_solicit_interval);
+ array[DEVCONF_RTR_SOLICIT_MAX_INTERVAL] =
+ jiffies_to_msecs(cnf->rtr_solicit_max_interval);
array[DEVCONF_RTR_SOLICIT_DELAY] =
jiffies_to_msecs(cnf->rtr_solicit_delay);
array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
@@ -5771,6 +5775,13 @@ static const struct ctl_table addrconf_sysctl[] = {
.proc_handler = proc_dointvec_jiffies,
},
{
+ .procname = "router_solicitation_max_interval",
+ .data = &ipv6_devconf.rtr_solicit_max_interval,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_jiffies,
+ },
+ {
.procname = "router_solicitation_delay",
.data = &ipv6_devconf.rtr_solicit_delay,
.maxlen = sizeof(int),
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v4 5/7] ipv6 addrconf: implement RFC7559 router solicitation backoff
From: Maciej Żenczykowski @ 2016-09-25 11:03 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474801390-6891-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This implements:
https://tools.ietf.org/html/rfc7559
Backoff is performed according to RFC3315 section 14:
https://tools.ietf.org/html/rfc3315#section-14
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/net/if_inet6.h | 1 +
net/ipv6/addrconf.c | 31 +++++++++++++++++++++++++++----
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 1c8b6820b694..515352c6280a 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -201,6 +201,7 @@ struct inet6_dev {
struct ipv6_devstat stats;
struct timer_list rs_timer;
+ __s32 rs_interval; /* in jiffies */
__u8 rs_probes;
__u8 addr_gen_mode;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 255be34cdbce..6384a1cde056 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -112,6 +112,24 @@ static inline u32 cstamp_delta(unsigned long cstamp)
return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
}
+static inline s32 rfc3315_s14_backoff_init(s32 initial)
+{
+ u32 r = (9 << 20) / 10 + (prandom_u32() % ((2 << 20) / 10 + 1));
+ s32 v = initial * (u64)r >> 20; /* ~ multiply by 0.9 .. 1.1 */
+ return v;
+}
+
+static inline s32 rfc3315_s14_backoff_update(s32 cur, s32 ceiling)
+{
+ u32 r = (19 << 20) / 10 + (prandom_u32() % ((2 << 20) / 10 + 1));
+ s32 v = cur * (u64)r >> 20; /* ~ multiply by 1.9 .. 2.1 */
+ if (v > ceiling) {
+ r -= 1 << 20;
+ v = ceiling * (u64)r >> 20; /* ~ multiply by 0.9 .. 1.1 */
+ }
+ return v;
+}
+
#ifdef CONFIG_SYSCTL
static int addrconf_sysctl_register(struct inet6_dev *idev);
static void addrconf_sysctl_unregister(struct inet6_dev *idev);
@@ -3698,11 +3716,13 @@ static void addrconf_rs_timer(unsigned long data)
goto put;
write_lock(&idev->lock);
+ idev->rs_interval = rfc3315_s14_backoff_update(
+ idev->rs_interval, idev->cnf.rtr_solicit_max_interval);
/* The wait after the last probe can be shorter */
addrconf_mod_rs_timer(idev, (idev->rs_probes ==
idev->cnf.rtr_solicits) ?
idev->cnf.rtr_solicit_delay :
- idev->cnf.rtr_solicit_interval);
+ idev->rs_interval);
} else {
/*
* Note: we do not support deprecated "all on-link"
@@ -3973,10 +3993,11 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
write_lock_bh(&ifp->idev->lock);
spin_lock(&ifp->lock);
+ ifp->idev->rs_interval = rfc3315_s14_backoff_init(
+ ifp->idev->cnf.rtr_solicit_interval);
ifp->idev->rs_probes = 1;
ifp->idev->if_flags |= IF_RS_SENT;
- addrconf_mod_rs_timer(ifp->idev,
- ifp->idev->cnf.rtr_solicit_interval);
+ addrconf_mod_rs_timer(ifp->idev, ifp->idev->rs_interval);
spin_unlock(&ifp->lock);
write_unlock_bh(&ifp->idev->lock);
}
@@ -5132,8 +5153,10 @@ update_lft:
if (update_rs) {
idev->if_flags |= IF_RS_SENT;
+ idev->rs_interval = rfc3315_s14_backoff_init(
+ idev->cnf.rtr_solicit_interval);
idev->rs_probes = 1;
- addrconf_mod_rs_timer(idev, idev->cnf.rtr_solicit_interval);
+ addrconf_mod_rs_timer(idev, idev->rs_interval);
}
/* Well, that's kinda nasty ... */
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v4 3/7] ipv6 addrconf: rtr_solicits == -1 means unlimited
From: Maciej Żenczykowski @ 2016-09-25 11:03 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474801390-6891-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This allows setting /proc/sys/net/ipv6/conf/*/router_solicitations
to -1 meaning an unlimited number of retransmits.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/addrconf.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3a835495fb53..6c63bf06fbcf 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3687,7 +3687,7 @@ static void addrconf_rs_timer(unsigned long data)
if (idev->if_flags & IF_RA_RCVD)
goto out;
- if (idev->rs_probes++ < idev->cnf.rtr_solicits) {
+ if (idev->rs_probes++ < idev->cnf.rtr_solicits || idev->cnf.rtr_solicits == -1) {
write_unlock(&idev->lock);
if (!ipv6_get_lladdr(dev, &lladdr, IFA_F_TENTATIVE))
ndisc_send_rs(dev, &lladdr,
@@ -3949,7 +3949,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
send_mld = ifp->scope == IFA_LINK && ipv6_lonely_lladdr(ifp);
send_rs = send_mld &&
ipv6_accept_ra(ifp->idev) &&
- ifp->idev->cnf.rtr_solicits > 0 &&
+ ifp->idev->cnf.rtr_solicits != 0 &&
(dev->flags&IFF_LOOPBACK) == 0;
read_unlock_bh(&ifp->idev->lock);
@@ -5099,7 +5099,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
return -EINVAL;
if (!ipv6_accept_ra(idev))
return -EINVAL;
- if (idev->cnf.rtr_solicits <= 0)
+ if (idev->cnf.rtr_solicits == 0)
return -EINVAL;
write_lock_bh(&idev->lock);
@@ -5699,6 +5699,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
return ret;
}
+static int minus_one = -1;
static int one = 1;
static int two_five_five = 255;
@@ -5759,7 +5760,8 @@ static const struct ctl_table addrconf_sysctl[] = {
.data = &ipv6_devconf.rtr_solicits,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &minus_one,
},
{
.procname = "router_solicitation_interval",
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v4 2/7] ipv6 addrconf: remove addrconf_sysctl_hop_limit()
From: Maciej Żenczykowski @ 2016-09-25 11:03 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474801390-6891-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
replace with extra1/2 magic
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/addrconf.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 11fa1a5564d4..3a835495fb53 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5467,20 +5467,6 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
}
static
-int addrconf_sysctl_hop_limit(struct ctl_table *ctl, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
-{
- struct ctl_table lctl;
- int min_hl = 1, max_hl = 255;
-
- lctl = *ctl;
- lctl.extra1 = &min_hl;
- lctl.extra2 = &max_hl;
-
- return proc_dointvec_minmax(&lctl, write, buffer, lenp, ppos);
-}
-
-static
int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -5713,6 +5699,9 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
return ret;
}
+static int one = 1;
+static int two_five_five = 255;
+
static const struct ctl_table addrconf_sysctl[] = {
{
.procname = "forwarding",
@@ -5726,7 +5715,9 @@ static const struct ctl_table addrconf_sysctl[] = {
.data = &ipv6_devconf.hop_limit,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = addrconf_sysctl_hop_limit,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &one,
+ .extra2 = &two_five_five,
},
{
.procname = "mtu",
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v4 0/7] implement rfc7559 ipv6 router solicitation backoff
From: Maciej Żenczykowski @ 2016-09-25 11:03 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <20160925.060423.854801855957024790.davem@davemloft.net>
Hi,
This patch series implements RFC7559 style backoff of IPv6 router
solicitation requests.
Patches 1 and 2 are minor cleanup and stand on their own.
Patch 3 allows a (potentially) infinite number of RS'es to be sent
when the rtr_solicits sysctl is set to -1 (this depends on patch 1).
Patch 4 is just boilerplate to add a new sysctl for the maximum
backoff period.
Patch 5 implements the backoff algorithm (and depends on the previous
patches).
Patches 6 and 7 switch the defaults over to enable this by default.
[PATCH v4 1/7] ipv6 addrconf: enable use of proc_dointvec_minmax in
[PATCH v4 2/7] ipv6 addrconf: remove addrconf_sysctl_hop_limit()
[PATCH v4 3/7] ipv6 addrconf: rtr_solicits == -1 means unlimited
[PATCH v4 4/7] ipv6 addrconf: add new sysctl
[PATCH v4 5/7] ipv6 addrconf: implement RFC7559 router solicitation
[PATCH v4 6/7] ipv6 addrconf: change default
[PATCH v4 7/7] ipv6 addrconf: change default MAX_RTR_SOLICITATIONS
Changes v3->v4:
added subject line to cover letter
Changes v2->v3:
added cover letter
Changes v1->v2:
avoid 64-bit divisions to fix 32-bit build errors
^ permalink raw reply
* [PATCH v4 1/7] ipv6 addrconf: enable use of proc_dointvec_minmax in addrconf_sysctl
From: Maciej Żenczykowski @ 2016-09-25 11:03 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474801390-6891-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/addrconf.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 2f1f5d439788..11fa1a5564d4 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6044,8 +6044,14 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
for (i = 0; table[i].data; i++) {
table[i].data += (char *)p - (char *)&ipv6_devconf;
- table[i].extra1 = idev; /* embedded; no ref */
- table[i].extra2 = net;
+ /* If one of these is already set, then it is not safe to
+ * overwrite either of them: this makes proc_dointvec_minmax
+ * usable.
+ */
+ if (!table[i].extra1 && !table[i].extra2) {
+ table[i].extra1 = idev; /* embedded; no ref */
+ table[i].extra2 = net;
+ }
}
snprintf(path, sizeof(path), "net/ipv6/conf/%s", dev_name);
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v3 7/7] ipv6 addrconf: change default MAX_RTR_SOLICITATIONS from 3 to -1 (unlimited)
From: Maciej Żenczykowski @ 2016-09-25 10:52 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474800749-2306-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This changes:
/proc/sys/net/ipv6/conf/all/router_solicitations
/proc/sys/net/ipv6/conf/default/router_solicitations
from 3 to unlimited.
This is the https://tools.ietf.org/html/rfc7559 recommended default.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/net/addrconf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 8f3677269f9a..f2d072787947 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -1,7 +1,7 @@
#ifndef _ADDRCONF_H
#define _ADDRCONF_H
-#define MAX_RTR_SOLICITATIONS 3
+#define MAX_RTR_SOLICITATIONS -1 /* unlimited */
#define RTR_SOLICITATION_INTERVAL (4*HZ)
#define RTR_SOLICITATION_MAX_INTERVAL (3600*HZ) /* 1 hour */
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v3 6/7] ipv6 addrconf: change default RTR_SOLICITATION_MAX_INTERVAL from 4s to 1h
From: Maciej Żenczykowski @ 2016-09-25 10:52 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474800749-2306-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This changes:
/proc/sys/net/ipv6/conf/all/router_solicitation_max_interval
/proc/sys/net/ipv6/conf/default/router_solicitation_max_interval
from 4 seconds to 1 hour.
This is the https://tools.ietf.org/html/rfc7559 recommended default.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/net/addrconf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 275e5af4c2f4..8f3677269f9a 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -3,7 +3,7 @@
#define MAX_RTR_SOLICITATIONS 3
#define RTR_SOLICITATION_INTERVAL (4*HZ)
-#define RTR_SOLICITATION_MAX_INTERVAL (4*HZ)
+#define RTR_SOLICITATION_MAX_INTERVAL (3600*HZ) /* 1 hour */
#define MIN_VALID_LIFETIME (2*3600) /* 2 hours */
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v3 5/7] ipv6 addrconf: implement RFC7559 router solicitation backoff
From: Maciej Żenczykowski @ 2016-09-25 10:52 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474800749-2306-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This implements:
https://tools.ietf.org/html/rfc7559
Backoff is performed according to RFC3315 section 14:
https://tools.ietf.org/html/rfc3315#section-14
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/net/if_inet6.h | 1 +
net/ipv6/addrconf.c | 31 +++++++++++++++++++++++++++----
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 1c8b6820b694..515352c6280a 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -201,6 +201,7 @@ struct inet6_dev {
struct ipv6_devstat stats;
struct timer_list rs_timer;
+ __s32 rs_interval; /* in jiffies */
__u8 rs_probes;
__u8 addr_gen_mode;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 255be34cdbce..6384a1cde056 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -112,6 +112,24 @@ static inline u32 cstamp_delta(unsigned long cstamp)
return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
}
+static inline s32 rfc3315_s14_backoff_init(s32 initial)
+{
+ u32 r = (9 << 20) / 10 + (prandom_u32() % ((2 << 20) / 10 + 1));
+ s32 v = initial * (u64)r >> 20; /* ~ multiply by 0.9 .. 1.1 */
+ return v;
+}
+
+static inline s32 rfc3315_s14_backoff_update(s32 cur, s32 ceiling)
+{
+ u32 r = (19 << 20) / 10 + (prandom_u32() % ((2 << 20) / 10 + 1));
+ s32 v = cur * (u64)r >> 20; /* ~ multiply by 1.9 .. 2.1 */
+ if (v > ceiling) {
+ r -= 1 << 20;
+ v = ceiling * (u64)r >> 20; /* ~ multiply by 0.9 .. 1.1 */
+ }
+ return v;
+}
+
#ifdef CONFIG_SYSCTL
static int addrconf_sysctl_register(struct inet6_dev *idev);
static void addrconf_sysctl_unregister(struct inet6_dev *idev);
@@ -3698,11 +3716,13 @@ static void addrconf_rs_timer(unsigned long data)
goto put;
write_lock(&idev->lock);
+ idev->rs_interval = rfc3315_s14_backoff_update(
+ idev->rs_interval, idev->cnf.rtr_solicit_max_interval);
/* The wait after the last probe can be shorter */
addrconf_mod_rs_timer(idev, (idev->rs_probes ==
idev->cnf.rtr_solicits) ?
idev->cnf.rtr_solicit_delay :
- idev->cnf.rtr_solicit_interval);
+ idev->rs_interval);
} else {
/*
* Note: we do not support deprecated "all on-link"
@@ -3973,10 +3993,11 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
write_lock_bh(&ifp->idev->lock);
spin_lock(&ifp->lock);
+ ifp->idev->rs_interval = rfc3315_s14_backoff_init(
+ ifp->idev->cnf.rtr_solicit_interval);
ifp->idev->rs_probes = 1;
ifp->idev->if_flags |= IF_RS_SENT;
- addrconf_mod_rs_timer(ifp->idev,
- ifp->idev->cnf.rtr_solicit_interval);
+ addrconf_mod_rs_timer(ifp->idev, ifp->idev->rs_interval);
spin_unlock(&ifp->lock);
write_unlock_bh(&ifp->idev->lock);
}
@@ -5132,8 +5153,10 @@ update_lft:
if (update_rs) {
idev->if_flags |= IF_RS_SENT;
+ idev->rs_interval = rfc3315_s14_backoff_init(
+ idev->cnf.rtr_solicit_interval);
idev->rs_probes = 1;
- addrconf_mod_rs_timer(idev, idev->cnf.rtr_solicit_interval);
+ addrconf_mod_rs_timer(idev, idev->rs_interval);
}
/* Well, that's kinda nasty ... */
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v3 4/7] ipv6 addrconf: add new sysctl 'router_solicitation_max_interval'
From: Maciej Żenczykowski @ 2016-09-25 10:52 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474800749-2306-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
Accessible via:
/proc/sys/net/ipv6/conf/*/router_solicitation_max_interval
For now we default it to the same value as the normal interval.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/linux/ipv6.h | 1 +
include/net/addrconf.h | 1 +
include/uapi/linux/ipv6.h | 1 +
net/ipv6/addrconf.c | 11 +++++++++++
4 files changed, 14 insertions(+)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index c6dbcd84a2c7..7e9a789be5e0 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -18,6 +18,7 @@ struct ipv6_devconf {
__s32 dad_transmits;
__s32 rtr_solicits;
__s32 rtr_solicit_interval;
+ __s32 rtr_solicit_max_interval;
__s32 rtr_solicit_delay;
__s32 force_mld_version;
__s32 mldv1_unsolicited_report_interval;
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 9826d3a9464c..275e5af4c2f4 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -3,6 +3,7 @@
#define MAX_RTR_SOLICITATIONS 3
#define RTR_SOLICITATION_INTERVAL (4*HZ)
+#define RTR_SOLICITATION_MAX_INTERVAL (4*HZ)
#define MIN_VALID_LIFETIME (2*3600) /* 2 hours */
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 395876060f50..8c2772340c3f 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -177,6 +177,7 @@ enum {
DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
DEVCONF_DROP_UNSOLICITED_NA,
DEVCONF_KEEP_ADDR_ON_DOWN,
+ DEVCONF_RTR_SOLICIT_MAX_INTERVAL,
DEVCONF_MAX
};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6c63bf06fbcf..255be34cdbce 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -187,6 +187,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
.dad_transmits = 1,
.rtr_solicits = MAX_RTR_SOLICITATIONS,
.rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
+ .rtr_solicit_max_interval = RTR_SOLICITATION_MAX_INTERVAL,
.rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
.use_tempaddr = 0,
.temp_valid_lft = TEMP_VALID_LIFETIME,
@@ -232,6 +233,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
.dad_transmits = 1,
.rtr_solicits = MAX_RTR_SOLICITATIONS,
.rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
+ .rtr_solicit_max_interval = RTR_SOLICITATION_MAX_INTERVAL,
.rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
.use_tempaddr = 0,
.temp_valid_lft = TEMP_VALID_LIFETIME,
@@ -4891,6 +4893,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
array[DEVCONF_RTR_SOLICIT_INTERVAL] =
jiffies_to_msecs(cnf->rtr_solicit_interval);
+ array[DEVCONF_RTR_SOLICIT_MAX_INTERVAL] =
+ jiffies_to_msecs(cnf->rtr_solicit_max_interval);
array[DEVCONF_RTR_SOLICIT_DELAY] =
jiffies_to_msecs(cnf->rtr_solicit_delay);
array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
@@ -5771,6 +5775,13 @@ static const struct ctl_table addrconf_sysctl[] = {
.proc_handler = proc_dointvec_jiffies,
},
{
+ .procname = "router_solicitation_max_interval",
+ .data = &ipv6_devconf.rtr_solicit_max_interval,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_jiffies,
+ },
+ {
.procname = "router_solicitation_delay",
.data = &ipv6_devconf.rtr_solicit_delay,
.maxlen = sizeof(int),
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v3 3/7] ipv6 addrconf: rtr_solicits == -1 means unlimited
From: Maciej Żenczykowski @ 2016-09-25 10:52 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474800749-2306-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This allows setting /proc/sys/net/ipv6/conf/*/router_solicitations
to -1 meaning an unlimited number of retransmits.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/addrconf.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3a835495fb53..6c63bf06fbcf 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3687,7 +3687,7 @@ static void addrconf_rs_timer(unsigned long data)
if (idev->if_flags & IF_RA_RCVD)
goto out;
- if (idev->rs_probes++ < idev->cnf.rtr_solicits) {
+ if (idev->rs_probes++ < idev->cnf.rtr_solicits || idev->cnf.rtr_solicits == -1) {
write_unlock(&idev->lock);
if (!ipv6_get_lladdr(dev, &lladdr, IFA_F_TENTATIVE))
ndisc_send_rs(dev, &lladdr,
@@ -3949,7 +3949,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
send_mld = ifp->scope == IFA_LINK && ipv6_lonely_lladdr(ifp);
send_rs = send_mld &&
ipv6_accept_ra(ifp->idev) &&
- ifp->idev->cnf.rtr_solicits > 0 &&
+ ifp->idev->cnf.rtr_solicits != 0 &&
(dev->flags&IFF_LOOPBACK) == 0;
read_unlock_bh(&ifp->idev->lock);
@@ -5099,7 +5099,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
return -EINVAL;
if (!ipv6_accept_ra(idev))
return -EINVAL;
- if (idev->cnf.rtr_solicits <= 0)
+ if (idev->cnf.rtr_solicits == 0)
return -EINVAL;
write_lock_bh(&idev->lock);
@@ -5699,6 +5699,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
return ret;
}
+static int minus_one = -1;
static int one = 1;
static int two_five_five = 255;
@@ -5759,7 +5760,8 @@ static const struct ctl_table addrconf_sysctl[] = {
.data = &ipv6_devconf.rtr_solicits,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &minus_one,
},
{
.procname = "router_solicitation_interval",
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v3 2/7] ipv6 addrconf: remove addrconf_sysctl_hop_limit()
From: Maciej Żenczykowski @ 2016-09-25 10:52 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474800749-2306-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
replace with extra1/2 magic
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/addrconf.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 11fa1a5564d4..3a835495fb53 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5467,20 +5467,6 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
}
static
-int addrconf_sysctl_hop_limit(struct ctl_table *ctl, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
-{
- struct ctl_table lctl;
- int min_hl = 1, max_hl = 255;
-
- lctl = *ctl;
- lctl.extra1 = &min_hl;
- lctl.extra2 = &max_hl;
-
- return proc_dointvec_minmax(&lctl, write, buffer, lenp, ppos);
-}
-
-static
int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -5713,6 +5699,9 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
return ret;
}
+static int one = 1;
+static int two_five_five = 255;
+
static const struct ctl_table addrconf_sysctl[] = {
{
.procname = "forwarding",
@@ -5726,7 +5715,9 @@ static const struct ctl_table addrconf_sysctl[] = {
.data = &ipv6_devconf.hop_limit,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = addrconf_sysctl_hop_limit,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &one,
+ .extra2 = &two_five_five,
},
{
.procname = "mtu",
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v3 1/7] ipv6 addrconf: enable use of proc_dointvec_minmax in addrconf_sysctl
From: Maciej Żenczykowski @ 2016-09-25 10:52 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474800749-2306-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/addrconf.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 2f1f5d439788..11fa1a5564d4 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6044,8 +6044,14 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
for (i = 0; table[i].data; i++) {
table[i].data += (char *)p - (char *)&ipv6_devconf;
- table[i].extra1 = idev; /* embedded; no ref */
- table[i].extra2 = net;
+ /* If one of these is already set, then it is not safe to
+ * overwrite either of them: this makes proc_dointvec_minmax
+ * usable.
+ */
+ if (!table[i].extra1 && !table[i].extra2) {
+ table[i].extra1 = idev; /* embedded; no ref */
+ table[i].extra2 = net;
+ }
}
snprintf(path, sizeof(path), "net/ipv6/conf/%s", dev_name);
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* (unknown),
From: Maciej Żenczykowski @ 2016-09-25 10:52 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <20160925.060423.854801855957024790.davem@davemloft.net>
Hi,
This patch series implements RFC7559 style backoff of IPv6 router
solicitation requests.
Patches 1 and 2 are minor cleanup and stand on their own.
Patch 3 allows a (potentially) infinite number of RS'es to be sent
when the rtr_solicits sysctl is set to -1 (this depends on patch 1).
Patch 4 is just boilerplate to add a new sysctl for the maximum
backoff period.
Patch 5 implements the backoff algorithm (and depends on the previous
patches).
Patches 6 and 7 switch the defaults over to enable this by default.
[PATCH v3 1/7] ipv6 addrconf: enable use of proc_dointvec_minmax in
[PATCH v3 2/7] ipv6 addrconf: remove addrconf_sysctl_hop_limit()
[PATCH v3 3/7] ipv6 addrconf: rtr_solicits == -1 means unlimited
[PATCH v3 4/7] ipv6 addrconf: add new sysctl
[PATCH v3 5/7] ipv6 addrconf: implement RFC7559 router solicitation
[PATCH v3 6/7] ipv6 addrconf: change default
[PATCH v3 7/7] ipv6 addrconf: change default MAX_RTR_SOLICITATIONS
Changes v2->v3:
none
Changes v1->v2:
avoid 64-bit divisions to fix 32-bit build errors
^ permalink raw reply
* Re: [patch net-next v2 3/6] mlxsw: spectrum_router: Use FIB notifications instead of switchdev calls
From: Jiri Pirko @ 2016-09-25 10:42 UTC (permalink / raw)
To: Ido Schimmel
Cc: netdev, davem, idosch, eladr, yotamg, nogahf, ogerlitz, roopa,
nikolay, linville, andy, f.fainelli, dsa, jhs, vivien.didelot,
andrew, ivecera, kaber, john
In-Reply-To: <20160925102208.GA20792@splinter>
Sun, Sep 25, 2016 at 12:22:08PM CEST, idosch@idosch.org wrote:
>On Fri, Sep 23, 2016 at 11:22:12AM +0200, Jiri Pirko wrote:
>> From: Jiri Pirko <jiri@mellanox.com>
>>
>> Until now, in order to offload a FIB entry to HW we use switchdev op.
>> However that has limits. Mainly in case we need to make the HW aware of
>> all route prefixes configured in kernel. HW needs to know those in order
>> to properly trap appropriate packets and pass the to kernel to do
>> the forwarding. Abort mechanism is now handled within the mlxsw driver.
>>
>> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
>
>[...]
>
>> static int
>> mlxsw_sp_router_fib4_entry_init(struct mlxsw_sp *mlxsw_sp,
>> - const struct switchdev_obj_ipv4_fib *fib4,
>> + const struct fib_entry_notifier_info *fen_info,
>> struct mlxsw_sp_fib_entry *fib_entry)
>> {
>> - struct fib_info *fi = fib4->fi;
>> + struct fib_info *fi = fen_info->fi;
>> + struct mlxsw_sp_rif *r;
>> + int nhsel;
>>
>> - if (fib4->type == RTN_LOCAL || fib4->type == RTN_BROADCAST) {
>> + if (fen_info->type == RTN_LOCAL || fen_info->type == RTN_BROADCAST) {
>> fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
>> return 0;
>> }
>> - if (fib4->type != RTN_UNICAST)
>> + if (fen_info->type != RTN_UNICAST)
>> return -EINVAL;
>>
>> - if (fi->fib_scope != RT_SCOPE_UNIVERSE) {
>> - struct mlxsw_sp_rif *r;
>> + for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
>> + const struct fib_nh *nh = &fi->fib_nh[nhsel];
>> +
>> + if (!nh->nh_dev)
>> + continue;
>> + r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, nh->nh_dev);
>> + if (!r) {
>> + /* In case router interface is not found for
>> + * at least one of the nexthops, that means
>> + * the nexthop points to some device unrelated
>> + * to us. Set trap and pass the packets for
>> + * this prefix to kernel.
>> + */
>> + fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
>> + return 0;
>> + }
>> + }
>>
>> + if (fi->fib_scope != RT_SCOPE_UNIVERSE) {
>> fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
>> - r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, fi->fib_dev);
>> - if (!r)
>> - return -EINVAL;
>> fib_entry->rif = r->rif;
>> return 0;
>> }
>> +
>> fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE;
>> return mlxsw_sp_nexthop_group_get(mlxsw_sp, fib_entry, fi);
>> }
>
>[...]
>
>> +static int mlxsw_sp_router_fib4_add(struct mlxsw_sp *mlxsw_sp,
>> + struct fib_entry_notifier_info *fen_info)
>> {
>> - struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
>> - struct mlxsw_sp_router_fib4_add_info *info;
>> struct mlxsw_sp_fib_entry *fib_entry;
>> struct mlxsw_sp_vr *vr;
>> int err;
>>
>> - info = switchdev_trans_item_dequeue(trans);
>> - fib_entry = info->fib_entry;
>> - kfree(info);
>> + if (mlxsw_sp->router.aborted)
>> + return 0;
>> +
>> + fib_entry = mlxsw_sp_fib_entry_get(mlxsw_sp, fen_info);
>> + if (IS_ERR(fib_entry)) {
>> + dev_warn(mlxsw_sp->bus_info->dev, "Failed to get FIB4 entry being added.\n");
>> + return PTR_ERR(fib_entry);
>> + }
>>
>> if (fib_entry->ref_count != 1)
>> - return 0;
>> + goto skip_add;
>>
>> vr = fib_entry->vr;
>> err = mlxsw_sp_fib_entry_insert(vr->fib, fib_entry);
>> - if (err)
>> + if (err) {
>> + dev_warn(mlxsw_sp->bus_info->dev, "Failed to insert FIB4 entry being added.\n");
>> goto err_fib_entry_insert;
>> - err = mlxsw_sp_fib_entry_update(mlxsw_sp_port->mlxsw_sp, fib_entry);
>> + }
>> + err = mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
>> if (err)
>> goto err_fib_entry_add;
>> +
>> +skip_add:
>> + fib_info_offload_inc(fen_info->fi);
>
>This is called for every FIB that is added on the system. Even those
>going via management ports, so all the routes are marked as offloaded.
>Tested to make sure I'm not talking nonsense ^^
>
>$ ip r s
>default via 10.209.0.1 dev eno1
>10.209.0.0/23 dev eno1 proto kernel scope link src 10.209.1.6
>169.254.0.0/16 dev eno1 scope link metric 1002
>
>$ sudo ip r a 1.1.1.0/24 dev eno1
>$ ip r s
>default via 10.209.0.1 dev eno1
>1.1.1.0/24 dev eno1 scope link offload
>10.209.0.0/23 dev eno1 proto kernel scope link src 10.209.1.6
>169.254.0.0/16 dev eno1 scope link metric 1002
>
>I think we should only call fib_info_offload_inc() in
>mlxsw_sp_router_fib4_entry_init() if fib_entry->type !=
>MLXSW_SP_FIB_ENTRY_TRAP. It'll also solve another problem (see below).
Hmm, that makes sense. Will do that.
>
>> return 0;
>>
>> err_fib_entry_add:
>> @@ -1899,29 +1814,22 @@ err_fib_entry_insert:
>> return err;
>> }
>
>[...]
>
>> +static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp)
>> +{
>> + struct mlxsw_resources *resources;
>> + struct mlxsw_sp_fib_entry *fib_entry;
>> + struct mlxsw_sp_fib_entry *tmp;
>> + struct mlxsw_sp_vr *vr;
>> + int i;
>> + int err;
>> +
>> + resources = mlxsw_core_resources_get(mlxsw_sp->core);
>> + for (i = 0; i < resources->max_virtual_routers; i++) {
>> + vr = &mlxsw_sp->router.vrs[i];
>> + if (!vr->used)
>> + continue;
>> +
>> + list_for_each_entry_safe(fib_entry, tmp,
>> + &vr->fib->entry_list, list) {
>> + bool do_break = &tmp->list == &vr->fib->entry_list;
>> +
>> + fib_info_offload_dec(fib_entry->fi);
>
>We call fib_info_offload_inc() multiple times for an already existing
>FIB entry, but in abort we only call fib_info_offload_dec() once per
>entry.
>
>If we inc / dec in fib4_entry_init/fini, then this counter is called
>once per entry (upon creation / destruction).
Okay. Will do.
>
>> + mlxsw_sp_fib_entry_del(mlxsw_sp, fib_entry);
>> + mlxsw_sp_fib_entry_remove(fib_entry->vr->fib,
>> + fib_entry);
>> + mlxsw_sp_fib_entry_put_all(mlxsw_sp, fib_entry);
>> + if (do_break)
>> + break;
>> + }
>> + }
>> + mlxsw_sp->router.aborted = true;
>> + err = mlxsw_sp_router_set_abort_trap(mlxsw_sp);
>> + if (err)
>> + dev_warn(mlxsw_sp->bus_info->dev, "Failed to set abort trap.\n");
>> +}
>
>Besides that the patch looks really good to me.
Thanks for review.
>
>Thanks!
^ permalink raw reply
* Re: [patch net-next v2 3/6] mlxsw: spectrum_router: Use FIB notifications instead of switchdev calls
From: Ido Schimmel @ 2016-09-25 10:22 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, idosch, eladr, yotamg, nogahf, ogerlitz, roopa,
nikolay, linville, andy, f.fainelli, dsa, jhs, vivien.didelot,
andrew, ivecera, kaber, john
In-Reply-To: <1474622535-4002-4-git-send-email-jiri@resnulli.us>
On Fri, Sep 23, 2016 at 11:22:12AM +0200, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
>
> Until now, in order to offload a FIB entry to HW we use switchdev op.
> However that has limits. Mainly in case we need to make the HW aware of
> all route prefixes configured in kernel. HW needs to know those in order
> to properly trap appropriate packets and pass the to kernel to do
> the forwarding. Abort mechanism is now handled within the mlxsw driver.
>
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
[...]
> static int
> mlxsw_sp_router_fib4_entry_init(struct mlxsw_sp *mlxsw_sp,
> - const struct switchdev_obj_ipv4_fib *fib4,
> + const struct fib_entry_notifier_info *fen_info,
> struct mlxsw_sp_fib_entry *fib_entry)
> {
> - struct fib_info *fi = fib4->fi;
> + struct fib_info *fi = fen_info->fi;
> + struct mlxsw_sp_rif *r;
> + int nhsel;
>
> - if (fib4->type == RTN_LOCAL || fib4->type == RTN_BROADCAST) {
> + if (fen_info->type == RTN_LOCAL || fen_info->type == RTN_BROADCAST) {
> fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
> return 0;
> }
> - if (fib4->type != RTN_UNICAST)
> + if (fen_info->type != RTN_UNICAST)
> return -EINVAL;
>
> - if (fi->fib_scope != RT_SCOPE_UNIVERSE) {
> - struct mlxsw_sp_rif *r;
> + for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
> + const struct fib_nh *nh = &fi->fib_nh[nhsel];
> +
> + if (!nh->nh_dev)
> + continue;
> + r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, nh->nh_dev);
> + if (!r) {
> + /* In case router interface is not found for
> + * at least one of the nexthops, that means
> + * the nexthop points to some device unrelated
> + * to us. Set trap and pass the packets for
> + * this prefix to kernel.
> + */
> + fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_TRAP;
> + return 0;
> + }
> + }
>
> + if (fi->fib_scope != RT_SCOPE_UNIVERSE) {
> fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_LOCAL;
> - r = mlxsw_sp_rif_find_by_dev(mlxsw_sp, fi->fib_dev);
> - if (!r)
> - return -EINVAL;
> fib_entry->rif = r->rif;
> return 0;
> }
> +
> fib_entry->type = MLXSW_SP_FIB_ENTRY_TYPE_REMOTE;
> return mlxsw_sp_nexthop_group_get(mlxsw_sp, fib_entry, fi);
> }
[...]
> +static int mlxsw_sp_router_fib4_add(struct mlxsw_sp *mlxsw_sp,
> + struct fib_entry_notifier_info *fen_info)
> {
> - struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
> - struct mlxsw_sp_router_fib4_add_info *info;
> struct mlxsw_sp_fib_entry *fib_entry;
> struct mlxsw_sp_vr *vr;
> int err;
>
> - info = switchdev_trans_item_dequeue(trans);
> - fib_entry = info->fib_entry;
> - kfree(info);
> + if (mlxsw_sp->router.aborted)
> + return 0;
> +
> + fib_entry = mlxsw_sp_fib_entry_get(mlxsw_sp, fen_info);
> + if (IS_ERR(fib_entry)) {
> + dev_warn(mlxsw_sp->bus_info->dev, "Failed to get FIB4 entry being added.\n");
> + return PTR_ERR(fib_entry);
> + }
>
> if (fib_entry->ref_count != 1)
> - return 0;
> + goto skip_add;
>
> vr = fib_entry->vr;
> err = mlxsw_sp_fib_entry_insert(vr->fib, fib_entry);
> - if (err)
> + if (err) {
> + dev_warn(mlxsw_sp->bus_info->dev, "Failed to insert FIB4 entry being added.\n");
> goto err_fib_entry_insert;
> - err = mlxsw_sp_fib_entry_update(mlxsw_sp_port->mlxsw_sp, fib_entry);
> + }
> + err = mlxsw_sp_fib_entry_update(mlxsw_sp, fib_entry);
> if (err)
> goto err_fib_entry_add;
> +
> +skip_add:
> + fib_info_offload_inc(fen_info->fi);
This is called for every FIB that is added on the system. Even those
going via management ports, so all the routes are marked as offloaded.
Tested to make sure I'm not talking nonsense ^^
$ ip r s
default via 10.209.0.1 dev eno1
10.209.0.0/23 dev eno1 proto kernel scope link src 10.209.1.6
169.254.0.0/16 dev eno1 scope link metric 1002
$ sudo ip r a 1.1.1.0/24 dev eno1
$ ip r s
default via 10.209.0.1 dev eno1
1.1.1.0/24 dev eno1 scope link offload
10.209.0.0/23 dev eno1 proto kernel scope link src 10.209.1.6
169.254.0.0/16 dev eno1 scope link metric 1002
I think we should only call fib_info_offload_inc() in
mlxsw_sp_router_fib4_entry_init() if fib_entry->type !=
MLXSW_SP_FIB_ENTRY_TRAP. It'll also solve another problem (see below).
> return 0;
>
> err_fib_entry_add:
> @@ -1899,29 +1814,22 @@ err_fib_entry_insert:
> return err;
> }
[...]
> +static void mlxsw_sp_router_fib4_abort(struct mlxsw_sp *mlxsw_sp)
> +{
> + struct mlxsw_resources *resources;
> + struct mlxsw_sp_fib_entry *fib_entry;
> + struct mlxsw_sp_fib_entry *tmp;
> + struct mlxsw_sp_vr *vr;
> + int i;
> + int err;
> +
> + resources = mlxsw_core_resources_get(mlxsw_sp->core);
> + for (i = 0; i < resources->max_virtual_routers; i++) {
> + vr = &mlxsw_sp->router.vrs[i];
> + if (!vr->used)
> + continue;
> +
> + list_for_each_entry_safe(fib_entry, tmp,
> + &vr->fib->entry_list, list) {
> + bool do_break = &tmp->list == &vr->fib->entry_list;
> +
> + fib_info_offload_dec(fib_entry->fi);
We call fib_info_offload_inc() multiple times for an already existing
FIB entry, but in abort we only call fib_info_offload_dec() once per
entry.
If we inc / dec in fib4_entry_init/fini, then this counter is called
once per entry (upon creation / destruction).
> + mlxsw_sp_fib_entry_del(mlxsw_sp, fib_entry);
> + mlxsw_sp_fib_entry_remove(fib_entry->vr->fib,
> + fib_entry);
> + mlxsw_sp_fib_entry_put_all(mlxsw_sp, fib_entry);
> + if (do_break)
> + break;
> + }
> + }
> + mlxsw_sp->router.aborted = true;
> + err = mlxsw_sp_router_set_abort_trap(mlxsw_sp);
> + if (err)
> + dev_warn(mlxsw_sp->bus_info->dev, "Failed to set abort trap.\n");
> +}
Besides that the patch looks really good to me.
Thanks!
^ permalink raw reply
* Re: [PATCH v2 1/7] ipv6 addrconf: enable use of proc_dointvec_minmax in addrconf_sysctl
From: David Miller @ 2016-09-25 10:04 UTC (permalink / raw)
To: zenczykowski; +Cc: maze, netdev, ek, lorenzo
In-Reply-To: <1474797596-13320-1-git-send-email-zenczykowski@gmail.com>
This is missing an appropriate "[PATCH v2 0/7] ..." cover letter that
explains at a high level what this patch series is doing, why it is
doing it, and how it is doing it.
You'll have to submit a v3 with this fixed.
^ permalink raw reply
* Re: [net-next 00/15][pull request] 40GbE Intel Wired LAN Driver Updates 2016-09-24
From: David Miller @ 2016-09-25 10:01 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev, nhorman, sassmann, jogreene, guru.anbalagane
In-Reply-To: <1474785769-54665-1-git-send-email-jeffrey.t.kirsher@intel.com>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Sat, 24 Sep 2016 23:42:34 -0700
> This series contains updates to i40e and i40evf only.
Pulled, thanks Jeff.
^ permalink raw reply
* [PATCH v2 7/7] ipv6 addrconf: change default MAX_RTR_SOLICITATIONS from 3 to -1 (unlimited)
From: Maciej Żenczykowski @ 2016-09-25 9:59 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474797596-13320-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This changes:
/proc/sys/net/ipv6/conf/all/router_solicitations
/proc/sys/net/ipv6/conf/default/router_solicitations
from 3 to unlimited.
This is the https://tools.ietf.org/html/rfc7559 recommended default.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/net/addrconf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 8f3677269f9a..f2d072787947 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -1,7 +1,7 @@
#ifndef _ADDRCONF_H
#define _ADDRCONF_H
-#define MAX_RTR_SOLICITATIONS 3
+#define MAX_RTR_SOLICITATIONS -1 /* unlimited */
#define RTR_SOLICITATION_INTERVAL (4*HZ)
#define RTR_SOLICITATION_MAX_INTERVAL (3600*HZ) /* 1 hour */
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v2 6/7] ipv6 addrconf: change default RTR_SOLICITATION_MAX_INTERVAL from 4s to 1h
From: Maciej Żenczykowski @ 2016-09-25 9:59 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474797596-13320-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This changes:
/proc/sys/net/ipv6/conf/all/router_solicitation_max_interval
/proc/sys/net/ipv6/conf/default/router_solicitation_max_interval
from 4 seconds to 1 hour.
This is the https://tools.ietf.org/html/rfc7559 recommended default.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/net/addrconf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 275e5af4c2f4..8f3677269f9a 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -3,7 +3,7 @@
#define MAX_RTR_SOLICITATIONS 3
#define RTR_SOLICITATION_INTERVAL (4*HZ)
-#define RTR_SOLICITATION_MAX_INTERVAL (4*HZ)
+#define RTR_SOLICITATION_MAX_INTERVAL (3600*HZ) /* 1 hour */
#define MIN_VALID_LIFETIME (2*3600) /* 2 hours */
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v2 5/7] ipv6 addrconf: implement RFC7559 router solicitation backoff
From: Maciej Żenczykowski @ 2016-09-25 9:59 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474797596-13320-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This implements:
https://tools.ietf.org/html/rfc7559
Backoff is performed according to RFC3315 section 14:
https://tools.ietf.org/html/rfc3315#section-14
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/net/if_inet6.h | 1 +
net/ipv6/addrconf.c | 31 +++++++++++++++++++++++++++----
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 1c8b6820b694..515352c6280a 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -201,6 +201,7 @@ struct inet6_dev {
struct ipv6_devstat stats;
struct timer_list rs_timer;
+ __s32 rs_interval; /* in jiffies */
__u8 rs_probes;
__u8 addr_gen_mode;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 255be34cdbce..6384a1cde056 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -112,6 +112,24 @@ static inline u32 cstamp_delta(unsigned long cstamp)
return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
}
+static inline s32 rfc3315_s14_backoff_init(s32 initial)
+{
+ u32 r = (9 << 20) / 10 + (prandom_u32() % ((2 << 20) / 10 + 1));
+ s32 v = initial * (u64)r >> 20; /* ~ multiply by 0.9 .. 1.1 */
+ return v;
+}
+
+static inline s32 rfc3315_s14_backoff_update(s32 cur, s32 ceiling)
+{
+ u32 r = (19 << 20) / 10 + (prandom_u32() % ((2 << 20) / 10 + 1));
+ s32 v = cur * (u64)r >> 20; /* ~ multiply by 1.9 .. 2.1 */
+ if (v > ceiling) {
+ r -= 1 << 20;
+ v = ceiling * (u64)r >> 20; /* ~ multiply by 0.9 .. 1.1 */
+ }
+ return v;
+}
+
#ifdef CONFIG_SYSCTL
static int addrconf_sysctl_register(struct inet6_dev *idev);
static void addrconf_sysctl_unregister(struct inet6_dev *idev);
@@ -3698,11 +3716,13 @@ static void addrconf_rs_timer(unsigned long data)
goto put;
write_lock(&idev->lock);
+ idev->rs_interval = rfc3315_s14_backoff_update(
+ idev->rs_interval, idev->cnf.rtr_solicit_max_interval);
/* The wait after the last probe can be shorter */
addrconf_mod_rs_timer(idev, (idev->rs_probes ==
idev->cnf.rtr_solicits) ?
idev->cnf.rtr_solicit_delay :
- idev->cnf.rtr_solicit_interval);
+ idev->rs_interval);
} else {
/*
* Note: we do not support deprecated "all on-link"
@@ -3973,10 +3993,11 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
write_lock_bh(&ifp->idev->lock);
spin_lock(&ifp->lock);
+ ifp->idev->rs_interval = rfc3315_s14_backoff_init(
+ ifp->idev->cnf.rtr_solicit_interval);
ifp->idev->rs_probes = 1;
ifp->idev->if_flags |= IF_RS_SENT;
- addrconf_mod_rs_timer(ifp->idev,
- ifp->idev->cnf.rtr_solicit_interval);
+ addrconf_mod_rs_timer(ifp->idev, ifp->idev->rs_interval);
spin_unlock(&ifp->lock);
write_unlock_bh(&ifp->idev->lock);
}
@@ -5132,8 +5153,10 @@ update_lft:
if (update_rs) {
idev->if_flags |= IF_RS_SENT;
+ idev->rs_interval = rfc3315_s14_backoff_init(
+ idev->cnf.rtr_solicit_interval);
idev->rs_probes = 1;
- addrconf_mod_rs_timer(idev, idev->cnf.rtr_solicit_interval);
+ addrconf_mod_rs_timer(idev, idev->rs_interval);
}
/* Well, that's kinda nasty ... */
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v2 4/7] ipv6 addrconf: add new sysctl 'router_solicitation_max_interval'
From: Maciej Żenczykowski @ 2016-09-25 9:59 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474797596-13320-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
Accessible via:
/proc/sys/net/ipv6/conf/*/router_solicitation_max_interval
For now we default it to the same value as the normal interval.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
include/linux/ipv6.h | 1 +
include/net/addrconf.h | 1 +
include/uapi/linux/ipv6.h | 1 +
net/ipv6/addrconf.c | 11 +++++++++++
4 files changed, 14 insertions(+)
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index c6dbcd84a2c7..7e9a789be5e0 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -18,6 +18,7 @@ struct ipv6_devconf {
__s32 dad_transmits;
__s32 rtr_solicits;
__s32 rtr_solicit_interval;
+ __s32 rtr_solicit_max_interval;
__s32 rtr_solicit_delay;
__s32 force_mld_version;
__s32 mldv1_unsolicited_report_interval;
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 9826d3a9464c..275e5af4c2f4 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -3,6 +3,7 @@
#define MAX_RTR_SOLICITATIONS 3
#define RTR_SOLICITATION_INTERVAL (4*HZ)
+#define RTR_SOLICITATION_MAX_INTERVAL (4*HZ)
#define MIN_VALID_LIFETIME (2*3600) /* 2 hours */
diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
index 395876060f50..8c2772340c3f 100644
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -177,6 +177,7 @@ enum {
DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
DEVCONF_DROP_UNSOLICITED_NA,
DEVCONF_KEEP_ADDR_ON_DOWN,
+ DEVCONF_RTR_SOLICIT_MAX_INTERVAL,
DEVCONF_MAX
};
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6c63bf06fbcf..255be34cdbce 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -187,6 +187,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
.dad_transmits = 1,
.rtr_solicits = MAX_RTR_SOLICITATIONS,
.rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
+ .rtr_solicit_max_interval = RTR_SOLICITATION_MAX_INTERVAL,
.rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
.use_tempaddr = 0,
.temp_valid_lft = TEMP_VALID_LIFETIME,
@@ -232,6 +233,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
.dad_transmits = 1,
.rtr_solicits = MAX_RTR_SOLICITATIONS,
.rtr_solicit_interval = RTR_SOLICITATION_INTERVAL,
+ .rtr_solicit_max_interval = RTR_SOLICITATION_MAX_INTERVAL,
.rtr_solicit_delay = MAX_RTR_SOLICITATION_DELAY,
.use_tempaddr = 0,
.temp_valid_lft = TEMP_VALID_LIFETIME,
@@ -4891,6 +4893,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
array[DEVCONF_RTR_SOLICIT_INTERVAL] =
jiffies_to_msecs(cnf->rtr_solicit_interval);
+ array[DEVCONF_RTR_SOLICIT_MAX_INTERVAL] =
+ jiffies_to_msecs(cnf->rtr_solicit_max_interval);
array[DEVCONF_RTR_SOLICIT_DELAY] =
jiffies_to_msecs(cnf->rtr_solicit_delay);
array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
@@ -5771,6 +5775,13 @@ static const struct ctl_table addrconf_sysctl[] = {
.proc_handler = proc_dointvec_jiffies,
},
{
+ .procname = "router_solicitation_max_interval",
+ .data = &ipv6_devconf.rtr_solicit_max_interval,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_jiffies,
+ },
+ {
.procname = "router_solicitation_delay",
.data = &ipv6_devconf.rtr_solicit_delay,
.maxlen = sizeof(int),
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v2 3/7] ipv6 addrconf: rtr_solicits == -1 means unlimited
From: Maciej Żenczykowski @ 2016-09-25 9:59 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474797596-13320-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
This allows setting /proc/sys/net/ipv6/conf/*/router_solicitations
to -1 meaning an unlimited number of retransmits.
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/addrconf.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3a835495fb53..6c63bf06fbcf 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3687,7 +3687,7 @@ static void addrconf_rs_timer(unsigned long data)
if (idev->if_flags & IF_RA_RCVD)
goto out;
- if (idev->rs_probes++ < idev->cnf.rtr_solicits) {
+ if (idev->rs_probes++ < idev->cnf.rtr_solicits || idev->cnf.rtr_solicits == -1) {
write_unlock(&idev->lock);
if (!ipv6_get_lladdr(dev, &lladdr, IFA_F_TENTATIVE))
ndisc_send_rs(dev, &lladdr,
@@ -3949,7 +3949,7 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
send_mld = ifp->scope == IFA_LINK && ipv6_lonely_lladdr(ifp);
send_rs = send_mld &&
ipv6_accept_ra(ifp->idev) &&
- ifp->idev->cnf.rtr_solicits > 0 &&
+ ifp->idev->cnf.rtr_solicits != 0 &&
(dev->flags&IFF_LOOPBACK) == 0;
read_unlock_bh(&ifp->idev->lock);
@@ -5099,7 +5099,7 @@ static int inet6_set_iftoken(struct inet6_dev *idev, struct in6_addr *token)
return -EINVAL;
if (!ipv6_accept_ra(idev))
return -EINVAL;
- if (idev->cnf.rtr_solicits <= 0)
+ if (idev->cnf.rtr_solicits == 0)
return -EINVAL;
write_lock_bh(&idev->lock);
@@ -5699,6 +5699,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
return ret;
}
+static int minus_one = -1;
static int one = 1;
static int two_five_five = 255;
@@ -5759,7 +5760,8 @@ static const struct ctl_table addrconf_sysctl[] = {
.data = &ipv6_devconf.rtr_solicits,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &minus_one,
},
{
.procname = "router_solicitation_interval",
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v2 2/7] ipv6 addrconf: remove addrconf_sysctl_hop_limit()
From: Maciej Żenczykowski @ 2016-09-25 9:59 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <1474797596-13320-1-git-send-email-zenczykowski@gmail.com>
From: Maciej Żenczykowski <maze@google.com>
replace with extra1/2 magic
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/addrconf.c | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 11fa1a5564d4..3a835495fb53 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5467,20 +5467,6 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
}
static
-int addrconf_sysctl_hop_limit(struct ctl_table *ctl, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
-{
- struct ctl_table lctl;
- int min_hl = 1, max_hl = 255;
-
- lctl = *ctl;
- lctl.extra1 = &min_hl;
- lctl.extra2 = &max_hl;
-
- return proc_dointvec_minmax(&lctl, write, buffer, lenp, ppos);
-}
-
-static
int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -5713,6 +5699,9 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
return ret;
}
+static int one = 1;
+static int two_five_five = 255;
+
static const struct ctl_table addrconf_sysctl[] = {
{
.procname = "forwarding",
@@ -5726,7 +5715,9 @@ static const struct ctl_table addrconf_sysctl[] = {
.data = &ipv6_devconf.hop_limit,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = addrconf_sysctl_hop_limit,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &one,
+ .extra2 = &two_five_five,
},
{
.procname = "mtu",
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
* [PATCH v2 1/7] ipv6 addrconf: enable use of proc_dointvec_minmax in addrconf_sysctl
From: Maciej Żenczykowski @ 2016-09-25 9:59 UTC (permalink / raw)
To: Maciej Żenczykowski, David S . Miller
Cc: netdev, Erik Kline, Lorenzo Colitti
In-Reply-To: <20160925.053302.1895311145903319224.davem@davemloft.net>
From: Maciej Żenczykowski <maze@google.com>
Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
net/ipv6/addrconf.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 2f1f5d439788..11fa1a5564d4 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -6044,8 +6044,14 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name,
for (i = 0; table[i].data; i++) {
table[i].data += (char *)p - (char *)&ipv6_devconf;
- table[i].extra1 = idev; /* embedded; no ref */
- table[i].extra2 = net;
+ /* If one of these is already set, then it is not safe to
+ * overwrite either of them: this makes proc_dointvec_minmax
+ * usable.
+ */
+ if (!table[i].extra1 && !table[i].extra2) {
+ table[i].extra1 = idev; /* embedded; no ref */
+ table[i].extra2 = net;
+ }
}
snprintf(path, sizeof(path), "net/ipv6/conf/%s", dev_name);
--
2.8.0.rc3.226.g39d4020
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox