diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2013-09-03 18:19:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-09-04 14:53:20 -0400 |
commit | 58c0ecfd8d9871cfa35bcdbf3e7b3ee9ca62ea67 (patch) | |
tree | e499cc587c7609380ca9c8bf75fab219d4c4e22d | |
parent | e3f5b17047dec4acd8957dad053e70d87f18d97e (diff) |
net: ipv6: mld: implement RFC3810 MLDv2 mode only
RFC3810, 10. Security Considerations says under subsection 10.1.
Query Message:
A forged Version 1 Query message will put MLDv2 listeners on that
link in MLDv1 Host Compatibility Mode. This scenario can be avoided
by providing MLDv2 hosts with a configuration option to ignore
Version 1 messages completely.
Hence, implement a MLDv2-only mode that will ignore MLDv1 traffic:
echo 2 > /proc/sys/net/ipv6/conf/ethX/force_mld_version or
echo 2 > /proc/sys/net/ipv6/conf/all/force_mld_version
Note that <all> device has a higher precedence as it was previously
also the case in the macro MLD_V1_SEEN() that would "short-circuit"
if condition on <all> case.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv6/mcast.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 005b22fd6bcb..c916568d838a 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1112,11 +1112,34 @@ static bool mld_marksources(struct ifmcaddr6 *pmc, int nsrcs, | |||
1112 | return true; | 1112 | return true; |
1113 | } | 1113 | } |
1114 | 1114 | ||
1115 | static int mld_force_mld_version(const struct inet6_dev *idev) | ||
1116 | { | ||
1117 | /* Normally, both are 0 here. If enforcement to a particular is | ||
1118 | * being used, individual device enforcement will have a lower | ||
1119 | * precedence over 'all' device (.../conf/all/force_mld_version). | ||
1120 | */ | ||
1121 | |||
1122 | if (dev_net(idev->dev)->ipv6.devconf_all->force_mld_version != 0) | ||
1123 | return dev_net(idev->dev)->ipv6.devconf_all->force_mld_version; | ||
1124 | else | ||
1125 | return idev->cnf.force_mld_version; | ||
1126 | } | ||
1127 | |||
1128 | static bool mld_in_v2_mode_only(const struct inet6_dev *idev) | ||
1129 | { | ||
1130 | return mld_force_mld_version(idev) == 2; | ||
1131 | } | ||
1132 | |||
1133 | static bool mld_in_v1_mode_only(const struct inet6_dev *idev) | ||
1134 | { | ||
1135 | return mld_force_mld_version(idev) == 1; | ||
1136 | } | ||
1137 | |||
1115 | static bool mld_in_v1_mode(const struct inet6_dev *idev) | 1138 | static bool mld_in_v1_mode(const struct inet6_dev *idev) |
1116 | { | 1139 | { |
1117 | if (dev_net(idev->dev)->ipv6.devconf_all->force_mld_version == 1) | 1140 | if (mld_in_v2_mode_only(idev)) |
1118 | return true; | 1141 | return false; |
1119 | if (idev->cnf.force_mld_version == 1) | 1142 | if (mld_in_v1_mode_only(idev)) |
1120 | return true; | 1143 | return true; |
1121 | if (idev->mc_v1_seen && time_before(jiffies, idev->mc_v1_seen)) | 1144 | if (idev->mc_v1_seen && time_before(jiffies, idev->mc_v1_seen)) |
1122 | return true; | 1145 | return true; |
@@ -1223,7 +1246,6 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1223 | return -EINVAL; | 1246 | return -EINVAL; |
1224 | 1247 | ||
1225 | idev = __in6_dev_get(skb->dev); | 1248 | idev = __in6_dev_get(skb->dev); |
1226 | |||
1227 | if (idev == NULL) | 1249 | if (idev == NULL) |
1228 | return 0; | 1250 | return 0; |
1229 | 1251 | ||
@@ -1236,6 +1258,10 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1236 | return -EINVAL; | 1258 | return -EINVAL; |
1237 | 1259 | ||
1238 | if (len == MLD_V1_QUERY_LEN) { | 1260 | if (len == MLD_V1_QUERY_LEN) { |
1261 | /* Ignore v1 queries */ | ||
1262 | if (mld_in_v2_mode_only(idev)) | ||
1263 | return 0; | ||
1264 | |||
1239 | /* MLDv1 router present */ | 1265 | /* MLDv1 router present */ |
1240 | max_delay = msecs_to_jiffies(ntohs(mld->mld_maxdelay)); | 1266 | max_delay = msecs_to_jiffies(ntohs(mld->mld_maxdelay)); |
1241 | 1267 | ||