diff options
Diffstat (limited to 'net/ipv4/igmp.c')
-rw-r--r-- | net/ipv4/igmp.c | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 0017ccb01d6d..063721302ebf 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -35,7 +35,7 @@ | |||
35 | * | 35 | * |
36 | * Chih-Jen Chang : Tried to revise IGMP to Version 2 | 36 | * Chih-Jen Chang : Tried to revise IGMP to Version 2 |
37 | * Tsu-Sheng Tsao E-mail: chihjenc@scf.usc.edu and tsusheng@scf.usc.edu | 37 | * Tsu-Sheng Tsao E-mail: chihjenc@scf.usc.edu and tsusheng@scf.usc.edu |
38 | * The enhancements are mainly based on Steve Deering's | 38 | * The enhancements are mainly based on Steve Deering's |
39 | * ipmulti-3.5 source code. | 39 | * ipmulti-3.5 source code. |
40 | * Chih-Jen Chang : Added the igmp_get_mrouter_info and | 40 | * Chih-Jen Chang : Added the igmp_get_mrouter_info and |
41 | * Tsu-Sheng Tsao igmp_set_mrouter_info to keep track of | 41 | * Tsu-Sheng Tsao igmp_set_mrouter_info to keep track of |
@@ -49,11 +49,11 @@ | |||
49 | * Alan Cox : Stop IGMP from 0.0.0.0 being accepted. | 49 | * Alan Cox : Stop IGMP from 0.0.0.0 being accepted. |
50 | * Alan Cox : Use GFP_ATOMIC in the right places. | 50 | * Alan Cox : Use GFP_ATOMIC in the right places. |
51 | * Christian Daudt : igmp timer wasn't set for local group | 51 | * Christian Daudt : igmp timer wasn't set for local group |
52 | * memberships but was being deleted, | 52 | * memberships but was being deleted, |
53 | * which caused a "del_timer() called | 53 | * which caused a "del_timer() called |
54 | * from %p with timer not initialized\n" | 54 | * from %p with timer not initialized\n" |
55 | * message (960131). | 55 | * message (960131). |
56 | * Christian Daudt : removed del_timer from | 56 | * Christian Daudt : removed del_timer from |
57 | * igmp_timer_expire function (960205). | 57 | * igmp_timer_expire function (960205). |
58 | * Christian Daudt : igmp_heard_report now only calls | 58 | * Christian Daudt : igmp_heard_report now only calls |
59 | * igmp_timer_expire if tm->running is | 59 | * igmp_timer_expire if tm->running is |
@@ -455,6 +455,8 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, | |||
455 | skb = add_grhead(skb, pmc, type, &pgr); | 455 | skb = add_grhead(skb, pmc, type, &pgr); |
456 | first = 0; | 456 | first = 0; |
457 | } | 457 | } |
458 | if (!skb) | ||
459 | return NULL; | ||
458 | psrc = (__be32 *)skb_put(skb, sizeof(__be32)); | 460 | psrc = (__be32 *)skb_put(skb, sizeof(__be32)); |
459 | *psrc = psf->sf_inaddr; | 461 | *psrc = psf->sf_inaddr; |
460 | scount++; stotal++; | 462 | scount++; stotal++; |
@@ -716,7 +718,7 @@ static void igmp_ifc_event(struct in_device *in_dev) | |||
716 | { | 718 | { |
717 | if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) | 719 | if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) |
718 | return; | 720 | return; |
719 | in_dev->mr_ifc_count = in_dev->mr_qrv ? in_dev->mr_qrv : | 721 | in_dev->mr_ifc_count = in_dev->mr_qrv ? in_dev->mr_qrv : |
720 | IGMP_Unsolicited_Report_Count; | 722 | IGMP_Unsolicited_Report_Count; |
721 | igmp_ifc_start_timer(in_dev, 1); | 723 | igmp_ifc_start_timer(in_dev, 1); |
722 | } | 724 | } |
@@ -836,7 +838,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, | |||
836 | if (len == 8) { | 838 | if (len == 8) { |
837 | if (ih->code == 0) { | 839 | if (ih->code == 0) { |
838 | /* Alas, old v1 router presents here. */ | 840 | /* Alas, old v1 router presents here. */ |
839 | 841 | ||
840 | max_delay = IGMP_Query_Response_Interval; | 842 | max_delay = IGMP_Query_Response_Interval; |
841 | in_dev->mr_v1_seen = jiffies + | 843 | in_dev->mr_v1_seen = jiffies + |
842 | IGMP_V1_Router_Present_Timeout; | 844 | IGMP_V1_Router_Present_Timeout; |
@@ -858,10 +860,10 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, | |||
858 | } else { /* v3 */ | 860 | } else { /* v3 */ |
859 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) | 861 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) |
860 | return; | 862 | return; |
861 | 863 | ||
862 | ih3 = (struct igmpv3_query *) skb->h.raw; | 864 | ih3 = (struct igmpv3_query *) skb->h.raw; |
863 | if (ih3->nsrcs) { | 865 | if (ih3->nsrcs) { |
864 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query) | 866 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query) |
865 | + ntohs(ih3->nsrcs)*sizeof(__be32))) | 867 | + ntohs(ih3->nsrcs)*sizeof(__be32))) |
866 | return; | 868 | return; |
867 | ih3 = (struct igmpv3_query *) skb->h.raw; | 869 | ih3 = (struct igmpv3_query *) skb->h.raw; |
@@ -907,7 +909,7 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, | |||
907 | else | 909 | else |
908 | im->gsquery = mark; | 910 | im->gsquery = mark; |
909 | changed = !im->gsquery || | 911 | changed = !im->gsquery || |
910 | igmp_marksources(im, ntohs(ih3->nsrcs), ih3->srcs); | 912 | igmp_marksources(im, ntohs(ih3->nsrcs), ih3->srcs); |
911 | spin_unlock_bh(&im->lock); | 913 | spin_unlock_bh(&im->lock); |
912 | if (changed) | 914 | if (changed) |
913 | igmp_mod_timer(im, max_delay); | 915 | igmp_mod_timer(im, max_delay); |
@@ -1255,9 +1257,9 @@ out: | |||
1255 | void ip_mc_dec_group(struct in_device *in_dev, __be32 addr) | 1257 | void ip_mc_dec_group(struct in_device *in_dev, __be32 addr) |
1256 | { | 1258 | { |
1257 | struct ip_mc_list *i, **ip; | 1259 | struct ip_mc_list *i, **ip; |
1258 | 1260 | ||
1259 | ASSERT_RTNL(); | 1261 | ASSERT_RTNL(); |
1260 | 1262 | ||
1261 | for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) { | 1263 | for (ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next) { |
1262 | if (i->multiaddr==addr) { | 1264 | if (i->multiaddr==addr) { |
1263 | if (--i->users == 0) { | 1265 | if (--i->users == 0) { |
@@ -1434,7 +1436,7 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode, | |||
1434 | #ifdef CONFIG_IP_MULTICAST | 1436 | #ifdef CONFIG_IP_MULTICAST |
1435 | if (psf->sf_oldin && | 1437 | if (psf->sf_oldin && |
1436 | !IGMP_V1_SEEN(in_dev) && !IGMP_V2_SEEN(in_dev)) { | 1438 | !IGMP_V1_SEEN(in_dev) && !IGMP_V2_SEEN(in_dev)) { |
1437 | psf->sf_crcount = in_dev->mr_qrv ? in_dev->mr_qrv : | 1439 | psf->sf_crcount = in_dev->mr_qrv ? in_dev->mr_qrv : |
1438 | IGMP_Unsolicited_Report_Count; | 1440 | IGMP_Unsolicited_Report_Count; |
1439 | psf->sf_next = pmc->tomb; | 1441 | psf->sf_next = pmc->tomb; |
1440 | pmc->tomb = psf; | 1442 | pmc->tomb = psf; |
@@ -1498,7 +1500,7 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode, | |||
1498 | /* filter mode change */ | 1500 | /* filter mode change */ |
1499 | pmc->sfmode = MCAST_INCLUDE; | 1501 | pmc->sfmode = MCAST_INCLUDE; |
1500 | #ifdef CONFIG_IP_MULTICAST | 1502 | #ifdef CONFIG_IP_MULTICAST |
1501 | pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : | 1503 | pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : |
1502 | IGMP_Unsolicited_Report_Count; | 1504 | IGMP_Unsolicited_Report_Count; |
1503 | in_dev->mr_ifc_count = pmc->crcount; | 1505 | in_dev->mr_ifc_count = pmc->crcount; |
1504 | for (psf=pmc->sources; psf; psf = psf->sf_next) | 1506 | for (psf=pmc->sources; psf; psf = psf->sf_next) |
@@ -1677,7 +1679,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, | |||
1677 | #ifdef CONFIG_IP_MULTICAST | 1679 | #ifdef CONFIG_IP_MULTICAST |
1678 | /* else no filters; keep old mode for reports */ | 1680 | /* else no filters; keep old mode for reports */ |
1679 | 1681 | ||
1680 | pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : | 1682 | pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : |
1681 | IGMP_Unsolicited_Report_Count; | 1683 | IGMP_Unsolicited_Report_Count; |
1682 | in_dev->mr_ifc_count = pmc->crcount; | 1684 | in_dev->mr_ifc_count = pmc->crcount; |
1683 | for (psf=pmc->sources; psf; psf = psf->sf_next) | 1685 | for (psf=pmc->sources; psf; psf = psf->sf_next) |
@@ -1871,7 +1873,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct | |||
1871 | } else if (pmc->sfmode != omode) { | 1873 | } else if (pmc->sfmode != omode) { |
1872 | /* allow mode switches for empty-set filters */ | 1874 | /* allow mode switches for empty-set filters */ |
1873 | ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 0, NULL, 0); | 1875 | ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 0, NULL, 0); |
1874 | ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, pmc->sfmode, 0, | 1876 | ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, pmc->sfmode, 0, |
1875 | NULL, 0); | 1877 | NULL, 0); |
1876 | pmc->sfmode = omode; | 1878 | pmc->sfmode = omode; |
1877 | } | 1879 | } |
@@ -1897,7 +1899,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct | |||
1897 | } | 1899 | } |
1898 | 1900 | ||
1899 | /* update the interface filter */ | 1901 | /* update the interface filter */ |
1900 | ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, omode, 1, | 1902 | ip_mc_del_src(in_dev, &mreqs->imr_multiaddr, omode, 1, |
1901 | &mreqs->imr_sourceaddr, 1); | 1903 | &mreqs->imr_sourceaddr, 1); |
1902 | 1904 | ||
1903 | for (j=i+1; j<psl->sl_count; j++) | 1905 | for (j=i+1; j<psl->sl_count; j++) |
@@ -1947,7 +1949,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct | |||
1947 | psl->sl_count++; | 1949 | psl->sl_count++; |
1948 | err = 0; | 1950 | err = 0; |
1949 | /* update the interface list */ | 1951 | /* update the interface list */ |
1950 | ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 1, | 1952 | ip_mc_add_src(in_dev, &mreqs->imr_multiaddr, omode, 1, |
1951 | &mreqs->imr_sourceaddr, 1); | 1953 | &mreqs->imr_sourceaddr, 1); |
1952 | done: | 1954 | done: |
1953 | rtnl_unlock(); | 1955 | rtnl_unlock(); |
@@ -2262,7 +2264,7 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) | |||
2262 | struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); | 2264 | struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); |
2263 | 2265 | ||
2264 | for (state->dev = dev_base, state->in_dev = NULL; | 2266 | for (state->dev = dev_base, state->in_dev = NULL; |
2265 | state->dev; | 2267 | state->dev; |
2266 | state->dev = state->dev->next) { | 2268 | state->dev = state->dev->next) { |
2267 | struct in_device *in_dev; | 2269 | struct in_device *in_dev; |
2268 | in_dev = in_dev_get(state->dev); | 2270 | in_dev = in_dev_get(state->dev); |
@@ -2344,7 +2346,7 @@ static void igmp_mc_seq_stop(struct seq_file *seq, void *v) | |||
2344 | static int igmp_mc_seq_show(struct seq_file *seq, void *v) | 2346 | static int igmp_mc_seq_show(struct seq_file *seq, void *v) |
2345 | { | 2347 | { |
2346 | if (v == SEQ_START_TOKEN) | 2348 | if (v == SEQ_START_TOKEN) |
2347 | seq_puts(seq, | 2349 | seq_puts(seq, |
2348 | "Idx\tDevice : Count Querier\tGroup Users Timer\tReporter\n"); | 2350 | "Idx\tDevice : Count Querier\tGroup Users Timer\tReporter\n"); |
2349 | else { | 2351 | else { |
2350 | struct ip_mc_list *im = (struct ip_mc_list *)v; | 2352 | struct ip_mc_list *im = (struct ip_mc_list *)v; |
@@ -2401,7 +2403,7 @@ out_kfree: | |||
2401 | goto out; | 2403 | goto out; |
2402 | } | 2404 | } |
2403 | 2405 | ||
2404 | static struct file_operations igmp_mc_seq_fops = { | 2406 | static const struct file_operations igmp_mc_seq_fops = { |
2405 | .owner = THIS_MODULE, | 2407 | .owner = THIS_MODULE, |
2406 | .open = igmp_mc_seq_open, | 2408 | .open = igmp_mc_seq_open, |
2407 | .read = seq_read, | 2409 | .read = seq_read, |
@@ -2424,7 +2426,7 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) | |||
2424 | struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); | 2426 | struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); |
2425 | 2427 | ||
2426 | for (state->dev = dev_base, state->idev = NULL, state->im = NULL; | 2428 | for (state->dev = dev_base, state->idev = NULL, state->im = NULL; |
2427 | state->dev; | 2429 | state->dev; |
2428 | state->dev = state->dev->next) { | 2430 | state->dev = state->dev->next) { |
2429 | struct in_device *idev; | 2431 | struct in_device *idev; |
2430 | idev = in_dev_get(state->dev); | 2432 | idev = in_dev_get(state->dev); |
@@ -2529,7 +2531,7 @@ static int igmp_mcf_seq_show(struct seq_file *seq, void *v) | |||
2529 | struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); | 2531 | struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); |
2530 | 2532 | ||
2531 | if (v == SEQ_START_TOKEN) { | 2533 | if (v == SEQ_START_TOKEN) { |
2532 | seq_printf(seq, | 2534 | seq_printf(seq, |
2533 | "%3s %6s " | 2535 | "%3s %6s " |
2534 | "%10s %10s %6s %6s\n", "Idx", | 2536 | "%10s %10s %6s %6s\n", "Idx", |
2535 | "Device", "MCA", | 2537 | "Device", "MCA", |
@@ -2537,8 +2539,8 @@ static int igmp_mcf_seq_show(struct seq_file *seq, void *v) | |||
2537 | } else { | 2539 | } else { |
2538 | seq_printf(seq, | 2540 | seq_printf(seq, |
2539 | "%3d %6.6s 0x%08x " | 2541 | "%3d %6.6s 0x%08x " |
2540 | "0x%08x %6lu %6lu\n", | 2542 | "0x%08x %6lu %6lu\n", |
2541 | state->dev->ifindex, state->dev->name, | 2543 | state->dev->ifindex, state->dev->name, |
2542 | ntohl(state->im->multiaddr), | 2544 | ntohl(state->im->multiaddr), |
2543 | ntohl(psf->sf_inaddr), | 2545 | ntohl(psf->sf_inaddr), |
2544 | psf->sf_count[MCAST_INCLUDE], | 2546 | psf->sf_count[MCAST_INCLUDE], |
@@ -2575,7 +2577,7 @@ out_kfree: | |||
2575 | goto out; | 2577 | goto out; |
2576 | } | 2578 | } |
2577 | 2579 | ||
2578 | static struct file_operations igmp_mcf_seq_fops = { | 2580 | static const struct file_operations igmp_mcf_seq_fops = { |
2579 | .owner = THIS_MODULE, | 2581 | .owner = THIS_MODULE, |
2580 | .open = igmp_mcf_seq_open, | 2582 | .open = igmp_mcf_seq_open, |
2581 | .read = seq_read, | 2583 | .read = seq_read, |