diff options
author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2010-04-17 23:42:07 -0400 |
---|---|---|
committer | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2010-04-23 00:35:55 -0400 |
commit | 8ef2a9a59854994bace13b5c4f7edc2c8d4d124e (patch) | |
tree | ef123540d1bb398ec1c6cc9b713425e1da8b5f04 /net/bridge/br_multicast.c | |
parent | 6e7cb8370760ec17e10098399822292def8d84f3 (diff) |
bridge br_multicast: Make functions less ipv4 dependent.
Introduce struct br_ip{} to store ip address and protocol
and make functions more generic so that we can support
both IPv4 and IPv6 with less pain.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r-- | net/bridge/br_multicast.c | 197 |
1 files changed, 141 insertions, 56 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 81bfdfe14ce5..64a3e4f74348 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -27,48 +27,86 @@ | |||
27 | 27 | ||
28 | #include "br_private.h" | 28 | #include "br_private.h" |
29 | 29 | ||
30 | static inline int br_ip_hash(struct net_bridge_mdb_htable *mdb, __be32 ip) | 30 | static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b) |
31 | { | ||
32 | if (a->proto != b->proto) | ||
33 | return 0; | ||
34 | switch (a->proto) { | ||
35 | case htons(ETH_P_IP): | ||
36 | return a->u.ip4 == b->u.ip4; | ||
37 | } | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static inline int __br_ip4_hash(struct net_bridge_mdb_htable *mdb, __be32 ip) | ||
31 | { | 42 | { |
32 | return jhash_1word(mdb->secret, (__force u32)ip) & (mdb->max - 1); | 43 | return jhash_1word(mdb->secret, (__force u32)ip) & (mdb->max - 1); |
33 | } | 44 | } |
34 | 45 | ||
46 | static inline int br_ip_hash(struct net_bridge_mdb_htable *mdb, | ||
47 | struct br_ip *ip) | ||
48 | { | ||
49 | switch (ip->proto) { | ||
50 | case htons(ETH_P_IP): | ||
51 | return __br_ip4_hash(mdb, ip->u.ip4); | ||
52 | } | ||
53 | return 0; | ||
54 | } | ||
55 | |||
35 | static struct net_bridge_mdb_entry *__br_mdb_ip_get( | 56 | static struct net_bridge_mdb_entry *__br_mdb_ip_get( |
36 | struct net_bridge_mdb_htable *mdb, __be32 dst, int hash) | 57 | struct net_bridge_mdb_htable *mdb, struct br_ip *dst, int hash) |
37 | { | 58 | { |
38 | struct net_bridge_mdb_entry *mp; | 59 | struct net_bridge_mdb_entry *mp; |
39 | struct hlist_node *p; | 60 | struct hlist_node *p; |
40 | 61 | ||
41 | hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { | 62 | hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { |
42 | if (dst == mp->addr) | 63 | if (br_ip_equal(&mp->addr, dst)) |
43 | return mp; | 64 | return mp; |
44 | } | 65 | } |
45 | 66 | ||
46 | return NULL; | 67 | return NULL; |
47 | } | 68 | } |
48 | 69 | ||
49 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | 70 | static struct net_bridge_mdb_entry *br_mdb_ip4_get( |
50 | struct net_bridge_mdb_htable *mdb, __be32 dst) | 71 | struct net_bridge_mdb_htable *mdb, __be32 dst) |
51 | { | 72 | { |
52 | if (!mdb) | 73 | struct br_ip br_dst; |
53 | return NULL; | 74 | |
75 | br_dst.u.ip4 = dst; | ||
76 | br_dst.proto = htons(ETH_P_IP); | ||
54 | 77 | ||
78 | return __br_mdb_ip_get(mdb, &br_dst, __br_ip4_hash(mdb, dst)); | ||
79 | } | ||
80 | |||
81 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | ||
82 | struct net_bridge_mdb_htable *mdb, struct br_ip *dst) | ||
83 | { | ||
55 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); | 84 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); |
56 | } | 85 | } |
57 | 86 | ||
58 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, | 87 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, |
59 | struct sk_buff *skb) | 88 | struct sk_buff *skb) |
60 | { | 89 | { |
61 | if (br->multicast_disabled) | 90 | struct net_bridge_mdb_htable *mdb = br->mdb; |
91 | struct br_ip ip; | ||
92 | |||
93 | if (!mdb || br->multicast_disabled) | ||
94 | return NULL; | ||
95 | |||
96 | if (BR_INPUT_SKB_CB(skb)->igmp) | ||
62 | return NULL; | 97 | return NULL; |
63 | 98 | ||
99 | ip.proto = skb->protocol; | ||
100 | |||
64 | switch (skb->protocol) { | 101 | switch (skb->protocol) { |
65 | case htons(ETH_P_IP): | 102 | case htons(ETH_P_IP): |
66 | if (BR_INPUT_SKB_CB(skb)->igmp) | 103 | ip.u.ip4 = ip_hdr(skb)->daddr; |
67 | break; | 104 | break; |
68 | return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr); | 105 | default: |
106 | return NULL; | ||
69 | } | 107 | } |
70 | 108 | ||
71 | return NULL; | 109 | return br_mdb_ip_get(mdb, &ip); |
72 | } | 110 | } |
73 | 111 | ||
74 | static void br_mdb_free(struct rcu_head *head) | 112 | static void br_mdb_free(struct rcu_head *head) |
@@ -95,7 +133,7 @@ static int br_mdb_copy(struct net_bridge_mdb_htable *new, | |||
95 | for (i = 0; i < old->max; i++) | 133 | for (i = 0; i < old->max; i++) |
96 | hlist_for_each_entry(mp, p, &old->mhash[i], hlist[old->ver]) | 134 | hlist_for_each_entry(mp, p, &old->mhash[i], hlist[old->ver]) |
97 | hlist_add_head(&mp->hlist[new->ver], | 135 | hlist_add_head(&mp->hlist[new->ver], |
98 | &new->mhash[br_ip_hash(new, mp->addr)]); | 136 | &new->mhash[br_ip_hash(new, &mp->addr)]); |
99 | 137 | ||
100 | if (!elasticity) | 138 | if (!elasticity) |
101 | return 0; | 139 | return 0; |
@@ -163,7 +201,7 @@ static void br_multicast_del_pg(struct net_bridge *br, | |||
163 | struct net_bridge_port_group *p; | 201 | struct net_bridge_port_group *p; |
164 | struct net_bridge_port_group **pp; | 202 | struct net_bridge_port_group **pp; |
165 | 203 | ||
166 | mp = br_mdb_ip_get(mdb, pg->addr); | 204 | mp = br_mdb_ip_get(mdb, &pg->addr); |
167 | if (WARN_ON(!mp)) | 205 | if (WARN_ON(!mp)) |
168 | return; | 206 | return; |
169 | 207 | ||
@@ -249,8 +287,8 @@ out: | |||
249 | return 0; | 287 | return 0; |
250 | } | 288 | } |
251 | 289 | ||
252 | static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br, | 290 | static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br, |
253 | __be32 group) | 291 | __be32 group) |
254 | { | 292 | { |
255 | struct sk_buff *skb; | 293 | struct sk_buff *skb; |
256 | struct igmphdr *ih; | 294 | struct igmphdr *ih; |
@@ -314,12 +352,22 @@ out: | |||
314 | return skb; | 352 | return skb; |
315 | } | 353 | } |
316 | 354 | ||
355 | static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br, | ||
356 | struct br_ip *addr) | ||
357 | { | ||
358 | switch (addr->proto) { | ||
359 | case htons(ETH_P_IP): | ||
360 | return br_ip4_multicast_alloc_query(br, addr->u.ip4); | ||
361 | } | ||
362 | return NULL; | ||
363 | } | ||
364 | |||
317 | static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp) | 365 | static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp) |
318 | { | 366 | { |
319 | struct net_bridge *br = mp->br; | 367 | struct net_bridge *br = mp->br; |
320 | struct sk_buff *skb; | 368 | struct sk_buff *skb; |
321 | 369 | ||
322 | skb = br_multicast_alloc_query(br, mp->addr); | 370 | skb = br_multicast_alloc_query(br, &mp->addr); |
323 | if (!skb) | 371 | if (!skb) |
324 | goto timer; | 372 | goto timer; |
325 | 373 | ||
@@ -353,7 +401,7 @@ static void br_multicast_send_port_group_query(struct net_bridge_port_group *pg) | |||
353 | struct net_bridge *br = port->br; | 401 | struct net_bridge *br = port->br; |
354 | struct sk_buff *skb; | 402 | struct sk_buff *skb; |
355 | 403 | ||
356 | skb = br_multicast_alloc_query(br, pg->addr); | 404 | skb = br_multicast_alloc_query(br, &pg->addr); |
357 | if (!skb) | 405 | if (!skb) |
358 | goto timer; | 406 | goto timer; |
359 | 407 | ||
@@ -383,8 +431,8 @@ out: | |||
383 | } | 431 | } |
384 | 432 | ||
385 | static struct net_bridge_mdb_entry *br_multicast_get_group( | 433 | static struct net_bridge_mdb_entry *br_multicast_get_group( |
386 | struct net_bridge *br, struct net_bridge_port *port, __be32 group, | 434 | struct net_bridge *br, struct net_bridge_port *port, |
387 | int hash) | 435 | struct br_ip *group, int hash) |
388 | { | 436 | { |
389 | struct net_bridge_mdb_htable *mdb = br->mdb; | 437 | struct net_bridge_mdb_htable *mdb = br->mdb; |
390 | struct net_bridge_mdb_entry *mp; | 438 | struct net_bridge_mdb_entry *mp; |
@@ -396,9 +444,8 @@ static struct net_bridge_mdb_entry *br_multicast_get_group( | |||
396 | 444 | ||
397 | hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { | 445 | hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { |
398 | count++; | 446 | count++; |
399 | if (unlikely(group == mp->addr)) { | 447 | if (unlikely(br_ip_equal(group, &mp->addr))) |
400 | return mp; | 448 | return mp; |
401 | } | ||
402 | } | 449 | } |
403 | 450 | ||
404 | elasticity = 0; | 451 | elasticity = 0; |
@@ -463,7 +510,8 @@ err: | |||
463 | } | 510 | } |
464 | 511 | ||
465 | static struct net_bridge_mdb_entry *br_multicast_new_group( | 512 | static struct net_bridge_mdb_entry *br_multicast_new_group( |
466 | struct net_bridge *br, struct net_bridge_port *port, __be32 group) | 513 | struct net_bridge *br, struct net_bridge_port *port, |
514 | struct br_ip *group) | ||
467 | { | 515 | { |
468 | struct net_bridge_mdb_htable *mdb = br->mdb; | 516 | struct net_bridge_mdb_htable *mdb = br->mdb; |
469 | struct net_bridge_mdb_entry *mp; | 517 | struct net_bridge_mdb_entry *mp; |
@@ -496,7 +544,7 @@ rehash: | |||
496 | goto out; | 544 | goto out; |
497 | 545 | ||
498 | mp->br = br; | 546 | mp->br = br; |
499 | mp->addr = group; | 547 | mp->addr = *group; |
500 | setup_timer(&mp->timer, br_multicast_group_expired, | 548 | setup_timer(&mp->timer, br_multicast_group_expired, |
501 | (unsigned long)mp); | 549 | (unsigned long)mp); |
502 | setup_timer(&mp->query_timer, br_multicast_group_query_expired, | 550 | setup_timer(&mp->query_timer, br_multicast_group_query_expired, |
@@ -510,7 +558,8 @@ out: | |||
510 | } | 558 | } |
511 | 559 | ||
512 | static int br_multicast_add_group(struct net_bridge *br, | 560 | static int br_multicast_add_group(struct net_bridge *br, |
513 | struct net_bridge_port *port, __be32 group) | 561 | struct net_bridge_port *port, |
562 | struct br_ip *group) | ||
514 | { | 563 | { |
515 | struct net_bridge_mdb_entry *mp; | 564 | struct net_bridge_mdb_entry *mp; |
516 | struct net_bridge_port_group *p; | 565 | struct net_bridge_port_group *p; |
@@ -518,9 +567,6 @@ static int br_multicast_add_group(struct net_bridge *br, | |||
518 | unsigned long now = jiffies; | 567 | unsigned long now = jiffies; |
519 | int err; | 568 | int err; |
520 | 569 | ||
521 | if (ipv4_is_local_multicast(group)) | ||
522 | return 0; | ||
523 | |||
524 | spin_lock(&br->multicast_lock); | 570 | spin_lock(&br->multicast_lock); |
525 | if (!netif_running(br->dev) || | 571 | if (!netif_running(br->dev) || |
526 | (port && port->state == BR_STATE_DISABLED)) | 572 | (port && port->state == BR_STATE_DISABLED)) |
@@ -549,7 +595,7 @@ static int br_multicast_add_group(struct net_bridge *br, | |||
549 | if (unlikely(!p)) | 595 | if (unlikely(!p)) |
550 | goto err; | 596 | goto err; |
551 | 597 | ||
552 | p->addr = group; | 598 | p->addr = *group; |
553 | p->port = port; | 599 | p->port = port; |
554 | p->next = *pp; | 600 | p->next = *pp; |
555 | hlist_add_head(&p->mglist, &port->mglist); | 601 | hlist_add_head(&p->mglist, &port->mglist); |
@@ -570,6 +616,21 @@ err: | |||
570 | return err; | 616 | return err; |
571 | } | 617 | } |
572 | 618 | ||
619 | static int br_ip4_multicast_add_group(struct net_bridge *br, | ||
620 | struct net_bridge_port *port, | ||
621 | __be32 group) | ||
622 | { | ||
623 | struct br_ip br_group; | ||
624 | |||
625 | if (ipv4_is_local_multicast(group)) | ||
626 | return 0; | ||
627 | |||
628 | br_group.u.ip4 = group; | ||
629 | br_group.proto = htons(ETH_P_IP); | ||
630 | |||
631 | return br_multicast_add_group(br, port, &br_group); | ||
632 | } | ||
633 | |||
573 | static void br_multicast_router_expired(unsigned long data) | 634 | static void br_multicast_router_expired(unsigned long data) |
574 | { | 635 | { |
575 | struct net_bridge_port *port = (void *)data; | 636 | struct net_bridge_port *port = (void *)data; |
@@ -591,19 +652,15 @@ static void br_multicast_local_router_expired(unsigned long data) | |||
591 | { | 652 | { |
592 | } | 653 | } |
593 | 654 | ||
594 | static void br_multicast_send_query(struct net_bridge *br, | 655 | static void __br_multicast_send_query(struct net_bridge *br, |
595 | struct net_bridge_port *port, u32 sent) | 656 | struct net_bridge_port *port, |
657 | struct br_ip *ip) | ||
596 | { | 658 | { |
597 | unsigned long time; | ||
598 | struct sk_buff *skb; | 659 | struct sk_buff *skb; |
599 | 660 | ||
600 | if (!netif_running(br->dev) || br->multicast_disabled || | 661 | skb = br_multicast_alloc_query(br, ip); |
601 | timer_pending(&br->multicast_querier_timer)) | ||
602 | return; | ||
603 | |||
604 | skb = br_multicast_alloc_query(br, 0); | ||
605 | if (!skb) | 662 | if (!skb) |
606 | goto timer; | 663 | return; |
607 | 664 | ||
608 | if (port) { | 665 | if (port) { |
609 | __skb_push(skb, sizeof(struct ethhdr)); | 666 | __skb_push(skb, sizeof(struct ethhdr)); |
@@ -612,8 +669,23 @@ static void br_multicast_send_query(struct net_bridge *br, | |||
612 | dev_queue_xmit); | 669 | dev_queue_xmit); |
613 | } else | 670 | } else |
614 | netif_rx(skb); | 671 | netif_rx(skb); |
672 | } | ||
673 | |||
674 | static void br_multicast_send_query(struct net_bridge *br, | ||
675 | struct net_bridge_port *port, u32 sent) | ||
676 | { | ||
677 | unsigned long time; | ||
678 | struct br_ip br_group; | ||
679 | |||
680 | if (!netif_running(br->dev) || br->multicast_disabled || | ||
681 | timer_pending(&br->multicast_querier_timer)) | ||
682 | return; | ||
683 | |||
684 | br_group.u.ip4 = 0; | ||
685 | br_group.proto = htons(ETH_P_IP); | ||
686 | |||
687 | __br_multicast_send_query(br, port, &br_group); | ||
615 | 688 | ||
616 | timer: | ||
617 | time = jiffies; | 689 | time = jiffies; |
618 | time += sent < br->multicast_startup_query_count ? | 690 | time += sent < br->multicast_startup_query_count ? |
619 | br->multicast_startup_query_interval : | 691 | br->multicast_startup_query_interval : |
@@ -698,9 +770,9 @@ void br_multicast_disable_port(struct net_bridge_port *port) | |||
698 | spin_unlock(&br->multicast_lock); | 770 | spin_unlock(&br->multicast_lock); |
699 | } | 771 | } |
700 | 772 | ||
701 | static int br_multicast_igmp3_report(struct net_bridge *br, | 773 | static int br_ip4_multicast_igmp3_report(struct net_bridge *br, |
702 | struct net_bridge_port *port, | 774 | struct net_bridge_port *port, |
703 | struct sk_buff *skb) | 775 | struct sk_buff *skb) |
704 | { | 776 | { |
705 | struct igmpv3_report *ih; | 777 | struct igmpv3_report *ih; |
706 | struct igmpv3_grec *grec; | 778 | struct igmpv3_grec *grec; |
@@ -745,7 +817,7 @@ static int br_multicast_igmp3_report(struct net_bridge *br, | |||
745 | continue; | 817 | continue; |
746 | } | 818 | } |
747 | 819 | ||
748 | err = br_multicast_add_group(br, port, group); | 820 | err = br_ip4_multicast_add_group(br, port, group); |
749 | if (err) | 821 | if (err) |
750 | break; | 822 | break; |
751 | } | 823 | } |
@@ -800,7 +872,7 @@ timer: | |||
800 | 872 | ||
801 | static void br_multicast_query_received(struct net_bridge *br, | 873 | static void br_multicast_query_received(struct net_bridge *br, |
802 | struct net_bridge_port *port, | 874 | struct net_bridge_port *port, |
803 | __be32 saddr) | 875 | int saddr) |
804 | { | 876 | { |
805 | if (saddr) | 877 | if (saddr) |
806 | mod_timer(&br->multicast_querier_timer, | 878 | mod_timer(&br->multicast_querier_timer, |
@@ -811,9 +883,9 @@ static void br_multicast_query_received(struct net_bridge *br, | |||
811 | br_multicast_mark_router(br, port); | 883 | br_multicast_mark_router(br, port); |
812 | } | 884 | } |
813 | 885 | ||
814 | static int br_multicast_query(struct net_bridge *br, | 886 | static int br_ip4_multicast_query(struct net_bridge *br, |
815 | struct net_bridge_port *port, | 887 | struct net_bridge_port *port, |
816 | struct sk_buff *skb) | 888 | struct sk_buff *skb) |
817 | { | 889 | { |
818 | struct iphdr *iph = ip_hdr(skb); | 890 | struct iphdr *iph = ip_hdr(skb); |
819 | struct igmphdr *ih = igmp_hdr(skb); | 891 | struct igmphdr *ih = igmp_hdr(skb); |
@@ -831,7 +903,7 @@ static int br_multicast_query(struct net_bridge *br, | |||
831 | (port && port->state == BR_STATE_DISABLED)) | 903 | (port && port->state == BR_STATE_DISABLED)) |
832 | goto out; | 904 | goto out; |
833 | 905 | ||
834 | br_multicast_query_received(br, port, iph->saddr); | 906 | br_multicast_query_received(br, port, !!iph->saddr); |
835 | 907 | ||
836 | group = ih->group; | 908 | group = ih->group; |
837 | 909 | ||
@@ -859,7 +931,7 @@ static int br_multicast_query(struct net_bridge *br, | |||
859 | if (!group) | 931 | if (!group) |
860 | goto out; | 932 | goto out; |
861 | 933 | ||
862 | mp = br_mdb_ip_get(br->mdb, group); | 934 | mp = br_mdb_ip4_get(br->mdb, group); |
863 | if (!mp) | 935 | if (!mp) |
864 | goto out; | 936 | goto out; |
865 | 937 | ||
@@ -885,7 +957,7 @@ out: | |||
885 | 957 | ||
886 | static void br_multicast_leave_group(struct net_bridge *br, | 958 | static void br_multicast_leave_group(struct net_bridge *br, |
887 | struct net_bridge_port *port, | 959 | struct net_bridge_port *port, |
888 | __be32 group) | 960 | struct br_ip *group) |
889 | { | 961 | { |
890 | struct net_bridge_mdb_htable *mdb; | 962 | struct net_bridge_mdb_htable *mdb; |
891 | struct net_bridge_mdb_entry *mp; | 963 | struct net_bridge_mdb_entry *mp; |
@@ -893,9 +965,6 @@ static void br_multicast_leave_group(struct net_bridge *br, | |||
893 | unsigned long now; | 965 | unsigned long now; |
894 | unsigned long time; | 966 | unsigned long time; |
895 | 967 | ||
896 | if (ipv4_is_local_multicast(group)) | ||
897 | return; | ||
898 | |||
899 | spin_lock(&br->multicast_lock); | 968 | spin_lock(&br->multicast_lock); |
900 | if (!netif_running(br->dev) || | 969 | if (!netif_running(br->dev) || |
901 | (port && port->state == BR_STATE_DISABLED) || | 970 | (port && port->state == BR_STATE_DISABLED) || |
@@ -946,6 +1015,22 @@ out: | |||
946 | spin_unlock(&br->multicast_lock); | 1015 | spin_unlock(&br->multicast_lock); |
947 | } | 1016 | } |
948 | 1017 | ||
1018 | static void br_ip4_multicast_leave_group(struct net_bridge *br, | ||
1019 | struct net_bridge_port *port, | ||
1020 | __be32 group) | ||
1021 | { | ||
1022 | struct br_ip br_group; | ||
1023 | |||
1024 | if (ipv4_is_local_multicast(group)) | ||
1025 | return; | ||
1026 | |||
1027 | br_group.u.ip4 = group; | ||
1028 | br_group.proto = htons(ETH_P_IP); | ||
1029 | |||
1030 | br_multicast_leave_group(br, port, &br_group); | ||
1031 | } | ||
1032 | |||
1033 | |||
949 | static int br_multicast_ipv4_rcv(struct net_bridge *br, | 1034 | static int br_multicast_ipv4_rcv(struct net_bridge *br, |
950 | struct net_bridge_port *port, | 1035 | struct net_bridge_port *port, |
951 | struct sk_buff *skb) | 1036 | struct sk_buff *skb) |
@@ -1023,16 +1108,16 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
1023 | case IGMP_HOST_MEMBERSHIP_REPORT: | 1108 | case IGMP_HOST_MEMBERSHIP_REPORT: |
1024 | case IGMPV2_HOST_MEMBERSHIP_REPORT: | 1109 | case IGMPV2_HOST_MEMBERSHIP_REPORT: |
1025 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; | 1110 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; |
1026 | err = br_multicast_add_group(br, port, ih->group); | 1111 | err = br_ip4_multicast_add_group(br, port, ih->group); |
1027 | break; | 1112 | break; |
1028 | case IGMPV3_HOST_MEMBERSHIP_REPORT: | 1113 | case IGMPV3_HOST_MEMBERSHIP_REPORT: |
1029 | err = br_multicast_igmp3_report(br, port, skb2); | 1114 | err = br_ip4_multicast_igmp3_report(br, port, skb2); |
1030 | break; | 1115 | break; |
1031 | case IGMP_HOST_MEMBERSHIP_QUERY: | 1116 | case IGMP_HOST_MEMBERSHIP_QUERY: |
1032 | err = br_multicast_query(br, port, skb2); | 1117 | err = br_ip4_multicast_query(br, port, skb2); |
1033 | break; | 1118 | break; |
1034 | case IGMP_HOST_LEAVE_MESSAGE: | 1119 | case IGMP_HOST_LEAVE_MESSAGE: |
1035 | br_multicast_leave_group(br, port, ih->group); | 1120 | br_ip4_multicast_leave_group(br, port, ih->group); |
1036 | break; | 1121 | break; |
1037 | } | 1122 | } |
1038 | 1123 | ||