diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2013-09-03 18:19:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-09-04 14:53:21 -0400 |
commit | 2b7c121f82b47ba5efac1ef47355376d1f8d6980 (patch) | |
tree | be901749cef8a7d65ad9ecccd5704e55fe975afc | |
parent | cc7f7ab758f66a9110c8e737c3de3e9f5fc209b5 (diff) |
net: ipv6: mld: refactor query processing into v1/v2 functions
Make igmp6_event_query() a bit easier to read by refactoring code
parts into mld_process_v1() and mld_process_v2().
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 | 89 |
1 files changed, 56 insertions, 33 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index beb76b7989a7..04399cb71e14 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1218,6 +1218,55 @@ static void mld_update_qri(struct inet6_dev *idev, | |||
1218 | idev->mc_qri = msecs_to_jiffies(mldv2_mrc(mlh2)); | 1218 | idev->mc_qri = msecs_to_jiffies(mldv2_mrc(mlh2)); |
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | static int mld_process_v1(struct inet6_dev *idev, struct mld_msg *mld, | ||
1222 | unsigned long *max_delay) | ||
1223 | { | ||
1224 | unsigned long mldv1_md; | ||
1225 | |||
1226 | /* Ignore v1 queries */ | ||
1227 | if (mld_in_v2_mode_only(idev)) | ||
1228 | return -EINVAL; | ||
1229 | |||
1230 | /* MLDv1 router present */ | ||
1231 | mldv1_md = ntohs(mld->mld_maxdelay); | ||
1232 | *max_delay = max(msecs_to_jiffies(mldv1_md), 1UL); | ||
1233 | |||
1234 | mld_set_v1_mode(idev); | ||
1235 | |||
1236 | /* cancel MLDv2 report timer */ | ||
1237 | idev->mc_gq_running = 0; | ||
1238 | if (del_timer(&idev->mc_gq_timer)) | ||
1239 | __in6_dev_put(idev); | ||
1240 | |||
1241 | /* cancel the interface change timer */ | ||
1242 | idev->mc_ifc_count = 0; | ||
1243 | if (del_timer(&idev->mc_ifc_timer)) | ||
1244 | __in6_dev_put(idev); | ||
1245 | |||
1246 | /* clear deleted report items */ | ||
1247 | mld_clear_delrec(idev); | ||
1248 | |||
1249 | return 0; | ||
1250 | } | ||
1251 | |||
1252 | static int mld_process_v2(struct inet6_dev *idev, struct mld2_query *mld, | ||
1253 | unsigned long *max_delay) | ||
1254 | { | ||
1255 | /* hosts need to stay in MLDv1 mode, discard MLDv2 queries */ | ||
1256 | if (mld_in_v1_mode(idev)) | ||
1257 | return -EINVAL; | ||
1258 | |||
1259 | *max_delay = max(msecs_to_jiffies(mldv2_mrc(mld)), 1UL); | ||
1260 | |||
1261 | mld_update_qrv(idev, mld); | ||
1262 | mld_update_qi(idev, mld); | ||
1263 | mld_update_qri(idev, mld); | ||
1264 | |||
1265 | idev->mc_maxdelay = *max_delay; | ||
1266 | |||
1267 | return 0; | ||
1268 | } | ||
1269 | |||
1221 | /* called with rcu_read_lock() */ | 1270 | /* called with rcu_read_lock() */ |
1222 | int igmp6_event_query(struct sk_buff *skb) | 1271 | int igmp6_event_query(struct sk_buff *skb) |
1223 | { | 1272 | { |
@@ -1229,7 +1278,7 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1229 | struct mld_msg *mld; | 1278 | struct mld_msg *mld; |
1230 | int group_type; | 1279 | int group_type; |
1231 | int mark = 0; | 1280 | int mark = 0; |
1232 | int len; | 1281 | int len, err; |
1233 | 1282 | ||
1234 | if (!pskb_may_pull(skb, sizeof(struct in6_addr))) | 1283 | if (!pskb_may_pull(skb, sizeof(struct in6_addr))) |
1235 | return -EINVAL; | 1284 | return -EINVAL; |
@@ -1255,47 +1304,21 @@ int igmp6_event_query(struct sk_buff *skb) | |||
1255 | return -EINVAL; | 1304 | return -EINVAL; |
1256 | 1305 | ||
1257 | if (len == MLD_V1_QUERY_LEN) { | 1306 | if (len == MLD_V1_QUERY_LEN) { |
1258 | unsigned long mldv1_md; | 1307 | err = mld_process_v1(idev, mld, &max_delay); |
1259 | 1308 | if (err < 0) | |
1260 | /* Ignore v1 queries */ | 1309 | return err; |
1261 | if (mld_in_v2_mode_only(idev)) | ||
1262 | return 0; | ||
1263 | |||
1264 | /* MLDv1 router present */ | ||
1265 | mldv1_md = ntohs(mld->mld_maxdelay); | ||
1266 | max_delay = max(msecs_to_jiffies(mldv1_md), 1UL); | ||
1267 | |||
1268 | mld_set_v1_mode(idev); | ||
1269 | |||
1270 | /* cancel MLDv2 report timer */ | ||
1271 | idev->mc_gq_running = 0; | ||
1272 | if (del_timer(&idev->mc_gq_timer)) | ||
1273 | __in6_dev_put(idev); | ||
1274 | |||
1275 | /* cancel the interface change timer */ | ||
1276 | idev->mc_ifc_count = 0; | ||
1277 | if (del_timer(&idev->mc_ifc_timer)) | ||
1278 | __in6_dev_put(idev); | ||
1279 | /* clear deleted report items */ | ||
1280 | mld_clear_delrec(idev); | ||
1281 | } else if (len >= MLD_V2_QUERY_LEN_MIN) { | 1310 | } else if (len >= MLD_V2_QUERY_LEN_MIN) { |
1282 | int srcs_offset = sizeof(struct mld2_query) - | 1311 | int srcs_offset = sizeof(struct mld2_query) - |
1283 | sizeof(struct icmp6hdr); | 1312 | sizeof(struct icmp6hdr); |
1284 | 1313 | ||
1285 | /* hosts need to stay in MLDv1 mode, discard MLDv2 queries */ | ||
1286 | if (mld_in_v1_mode(idev)) | ||
1287 | return 0; | ||
1288 | if (!pskb_may_pull(skb, srcs_offset)) | 1314 | if (!pskb_may_pull(skb, srcs_offset)) |
1289 | return -EINVAL; | 1315 | return -EINVAL; |
1290 | 1316 | ||
1291 | mlh2 = (struct mld2_query *)skb_transport_header(skb); | 1317 | mlh2 = (struct mld2_query *)skb_transport_header(skb); |
1292 | 1318 | ||
1293 | max_delay = max(msecs_to_jiffies(mldv2_mrc(mlh2)), 1UL); | 1319 | err = mld_process_v2(idev, mlh2, &max_delay); |
1294 | idev->mc_maxdelay = max_delay; | 1320 | if (err < 0) |
1295 | 1321 | return err; | |
1296 | mld_update_qrv(idev, mlh2); | ||
1297 | mld_update_qi(idev, mlh2); | ||
1298 | mld_update_qri(idev, mlh2); | ||
1299 | 1322 | ||
1300 | if (group_type == IPV6_ADDR_ANY) { /* general query */ | 1323 | if (group_type == IPV6_ADDR_ANY) { /* general query */ |
1301 | if (mlh2->mld2q_nsrcs) | 1324 | if (mlh2->mld2q_nsrcs) |