rtnetlink & address family problem
Subsystems (2)
PATCH 1/1 rtnetlink & address family problem
Hi,
running 'ip -6 addr flush dev eth0' on a kernel without IPv6 support flushes *all* addresses from the interface, even those IPv4 ones, because the unsupported protocol is substituted by PF_UNSPEC. IMHO it should better return with an error EAFNOSUPPORT.
Attached patch fixes it. Please apply.
BTW Credits to Jan Kara <[email protected]> for discovering and analysing this bug.
Michal Ludvig
Signature · 3 lines
SUSE Labs [email protected] (+420) 296.542.396 http://www.suse.cz Personal homepage http://www.logix.cz/michal
# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet
# 2004/12/03 18:06:31+01:00 [email protected]
# Return EAFNOSUPPORT if requested operation on unsupported family.
#
# Signed-off-by: Michal Ludvig <[email protected]>
#
# net/core/rtnetlink.c # 2004/12/03 18:05:49+01:00 [email protected] +4 -2 # Return EAFNOSUPPORT if requested operation on unsupported family. # diff -Nru a/net/core/rtnetlink.c b/net/core/rtnetlink.c --- a/net/core/rtnetlink.c 2004-12-03 18:30:33 +01:00 +++ b/net/core/rtnetlink.c 2004-12-03 18:30:33 +01:00 @@ -477,8 +477,10 @@ }
link_tab = rtnetlink_links[family];
- if (link_tab == NULL)
- link_tab = rtnetlink_links[PF_UNSPEC];
+ if (link_tab == NULL) {
+ *errp = -EAFNOSUPPORT;
+ return -1;
+ }
link = &link_tab[type];
sz_idx = type>>2;
I think this patch will break more than it fixes. You need to do a lot more testing to verify it doesnt. Actually you should probably fix whats being invoked for the ifa messages when PF_UNSPEC is selected to check that it only flushes v6 addresses when V6 is on and reject when it is not compiled in.
cheers,
jamal
Quoted 13 lines · Michal Ludvig
Hi,
running 'ip -6 addr flush dev eth0' on a kernel without IPv6 support flushes *all* addresses from the interface, even those IPv4 ones, because the unsupported protocol is substituted by
PF_UNSPEC. IMHO it should better return with an error EAFNOSUPPORT.Attached patch fixes it. Please apply.
BTW Credits to Jan Kara <[email protected]> for discovering and analysing this bug.
Michal Ludvig
* Michal Ludvig <[email protected]> 2004-12-03 18:43
Quoted 11 lines
running 'ip -6 addr flush dev eth0' on a kernel without IPv6 support flushes *all* addresses from the interface, even those IPv4 ones, because the unsupported protocol is substituted by
PF_UNSPEC. IMHO it should better return with an error EAFNOSUPPORT.diff -Nru
a/net/core/rtnetlink.cb/net/core/rtnetlink.cnet/core/rtnetlink.c +0
-0@@ -477,8 +477,10 @@ }
net/core/rtnetlink.c line 486
Quoted 10 lines
net/core/rtnetlink.c +4
-2link_tab = rtnetlink_links[family]; -if (link_tab ==NULL ) - link_tab = rtnetlink_links[PF_UNSPEC ]; +if (link_tab ==NULL ) { + *errp = -EAFNOSUPPORT ; +return -1 ; + } link = &link_tab[type]; sz_idx = type>>2 ;
Your patch would fix this issue but might break various things. The actual problem is that iproute2 doesn't check the family in its filter. It blindly assumes that the kernel only returns addresses of the kind it has requested. I can understand if you think the current behaviour is wrong but we shouldn't change it in the middle of a stable tree.
ip/ipaddress.c +2 -0
@@ -330,6 +330,8 @@return 0 ; } } +if (filter.family && filter.family != ifa->ifa_family) +return 0 ;if (filter.flushb) {struct nlmsghdr *fn;
Quoted 5 lines · Thomas Graf
Your patch would fix this issue but might break various things. The actual problem is that iproute2 doesn't check the family in its filter. It blindly assumes that the kernel only returns addresses of the kind it has requested. I can understand if you think the current behaviour is wrong but we shouldn't change it in the middle of a stable tree.
Why would it be wrong? The PF_UNSPEC is there for a purpose.
If user space decides it wants to flush ipv4 addresses blindly that user spaces fault. The patch you attached seems legit. did you verify it?
BTW, Stephen - are you still updating iproute2?
cheers,
jamal
* jamal <[email protected]> 2004-12-06 21:27
Quoted 9 lines · Thomas Graf
Quoted 6 lines
Your patch would fix this issue but might break various things. The actual problem is that iproute2 doesn't check the family in its filter. It blindly assumes that the kernel only returns addresses of the kind it has requested. I can understand if you think the current behaviour is wrong but we shouldn't change it in the middle of a stable tree.
Why would it be wrong? The
PF_UNSPECis there for a purpose.
I don't think it is wrong myself but I understand if someone does. If one sends a GETADDR request for PF_INET6 one might expect to either receive all ipv6 addresses or none and to only receive all addresess of any type if PF_UNSPEC was specified.
Quoted 2 lines
If user space decides it wants to flush ipv4 addresses blindly that user spaces fault. The patch you attached seems legit. did you verify it?
Not yet, it probably has to be applied to iproute.c as well. I'll have a look at it and do some testing.
Quoted 9 lines · Thomas Graf
* jamal <[email protected]> 2004-12-06 21:27
Quoted 8 lines · Thomas Graf
Quoted 6 lines
Your patch would fix this issue but might break various things. The actual problem is that iproute2 doesn't check the family in its filter. It blindly assumes that the kernel only returns addresses of the kind it has requested. I can understand if you think the current behaviour is wrong but we shouldn't change it in the middle of a stable tree.
Quoted 8 lines
Quoted 1 line
Why would it be wrong? The
PF_UNSPECis there for a purpose.I don't think it is wrong myself but I understand if someone does.
If
one sends a GETADDR request forPF_INET6one might expect to either receive all ipv6 addresses or none and to only receive all addresess of any type ifPF_UNSPECwas specified.
Thats debatable.
Its user space that issues the flushing after a response from the kernel. It happens to be flushing IPV4 addresses.
Thats why your filter in ip is the answer.
BTW, did the gnet_stats patches to iproute2 ever get merged? If you have cycles, can you please look at that hang being reported using older tc with 2.6.10-rc3?
cheers,
jamal
Quoted 10 lines
Quoted 5 lines
I don't think it is wrong myself but I understand if someone does. If one sends a GETADDR request for
PF_INET6one might expect to either receive all ipv6 addresses or none and to only receive all addresess of any type ifPF_UNSPECwas specified.Thats debatable.
Its user space that issues the flushing after a response from the kernel. It happens to be flushing IPV4 addresses.
Thats why your filter in ip is the answer.
Agreed.
Quoted 1 line
BTW, did the
gnet_statspatches to iproute2 ever get merged?
Not sure, I will check that.
Quoted 2 lines
If you have cycles, can you please look at that hang being reported using older tc with 2.6.10-rc3?
It's not really related to the gnet_stats code. stats_lock isn't set in the action code when using an older iproute2. I haven't tested this case because it was marked as broken anyway. I compiled an older version of iproute2 and will look into it today.
Quoted 3 lines · Thomas Graf
It's not really related to the
gnet_statscode.stats_lockisn't set in the action code when using an older iproute2. I haven't tested this case because it was marked as broken anyway.
Can you ping my memory on this? Is this tc with initial support for actions or something much older than that.
cheers,
jamal
* jamal <[email protected]> 2004-12-07 08:20
Quoted 8 lines · Thomas Graf
Quoted 4 lines
It's not really related to the
gnet_statscode.stats_lockisn't set in the action code when using an older iproute2. I haven't tested this case because it was marked as broken anyway.Can you ping my memory on this? Is this tc with initial support for actions or something much older than that.
I'm not sure, I'm testing with a version having no action support at all. It should be fairly easy to find the bug once I have the time to really look into it. I'm still getting interrupted all the time at the moment.
All actions created via tcf_hash_create, tcf_police_locate, and tcf_act_police_locate should be fine. There must be some bogus path related to older tc versions.
* Thomas Graf <[email protected]> 2004-12-07 15:10
Quoted 7 lines
* jamal <[email protected]> 2004-12-07 08:20
Quoted 6 lines · Thomas Graf
Quoted 4 lines
It's not really related to the
gnet_statscode.stats_lockisn't set in the action code when using an older iproute2. I haven't tested this case because it was marked as broken anyway.
Quoted 7 lines
Quoted 2 lines
Can you ping my memory on this? Is this tc with initial support for actions or something much older than that.
I'm not sure, I'm testing with a version having no action support at all. It should be fairly easy to find the bug once I have the time to really look into it. I'm still getting interrupted all the time at the moment.
One major problem is that the tc_dump_action path doesn't take care of TCA_OLD_COMPAT resulting in calling tcf_action_copy_stats for policers which is a bad thing since their a->priv is set to tcf_police instead of the generic header and thus causes random behaviour.
One solution would be to make tcf_police compatible to tca_gen.
Thoughts?
include/net/act_api.h +30 -25
@@ -8,15 +8,42 @@#include <net/sch_generic.h> #include <net/pkt_sched.h> +#ifdef CONFIG_NET_CLS_ACT + +#define ACT_P_CREATED 1 +#define ACT_P_DELETED 1 +#define tca_gen (name) \ +struct tcf_##name *next; \ + u32 index; \ + int refcnt; \ + int bindcnt; \ + u32 capab; \ + int action; \ + struct tcf_t tm; \ + struct gnet_stats_basic bstats; \ + struct gnet_stats_queue qstats; \ + struct gnet_stats_rate_est rate_est; \ + spinlock_t *stats_lock; \ + spinlock_t lock + +#endif +struct tcf_police { +#ifdef CONFIG_NET_CLS_ACT +tca_gen (police); +#else struct tcf_police *next;int refcnt; -#ifdef CONFIG_NET_CLS_ACT -int bindcnt; -#endif u32 index;int action; +spinlock_t lock; +struct gnet_stats_basic bstats; +struct gnet_stats_queue qstats; +struct gnet_stats_rate_est rate_est; +spinlock_t *stats_lock; +#endif +int result;u32 ewma_rate;u32 burst;
@@ -24,34 +51,12 @@u32 toks;u32 ptoks;psched_time_t t_c; -spinlock_t lock;struct qdisc_rate_table *R_tab;struct qdisc_rate_table *P_tab; - -struct gnet_stats_basic bstats; -struct gnet_stats_queue qstats; -struct gnet_stats_rate_est rate_est; -spinlock_t *stats_lock; }; #ifdef CONFIG_NET_CLS_ACT -#define ACT_P_CREATED 1 -#define ACT_P_DELETED 1 -#define tca_gen(name) \ -struct tcf_##name *next; \ - u32 index; \ - int refcnt; \ - int bindcnt; \ - u32 capab; \ - int action; \ - struct tcf_t tm; \ - struct gnet_stats_basic bstats; \ - struct gnet_stats_queue qstats; \ - struct gnet_stats_rate_est rate_est; \ - spinlock_t *stats_lock; \ - spinlock_t lock - struct tcf_act_hdr { tca_gen(act_hdr);
Quoted 3 lines
BTW, did the
gnet_statspatches to iproute2 ever get merged? If you have cycles, can you please look at that hang being reported using older tc with 2.6.10-rc3?
They're not in bk://developer.osdl.org/iproute2 so I guess not. I've put a iproute2 including all my changes into a tarball at:
http://people.suug.ch/~tgr/iproute2/iproute2-2.6.9-tgr.tar.gz
Quoted 1 line · On Tue, 7 Dec 2004 18:52:59 +0100 Thomas Graf <[email protected]> wrote:
http://people.suug.ch/~tgr/iproute2/iproute2-2.6.9-tgr.tar.gz
Thanks, I'm behind on iproute2