diff options
Diffstat (limited to 'net/bridge/br_multicast.c')
| -rw-r--r-- | net/bridge/br_multicast.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index fd96a8dc97f4..eaa0e1bae49b 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -49,22 +49,23 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get( | |||
| 49 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | 49 | static struct net_bridge_mdb_entry *br_mdb_ip_get( |
| 50 | struct net_bridge_mdb_htable *mdb, __be32 dst) | 50 | struct net_bridge_mdb_htable *mdb, __be32 dst) |
| 51 | { | 51 | { |
| 52 | if (!mdb) | ||
| 53 | return NULL; | ||
| 54 | |||
| 52 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); | 55 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); |
| 53 | } | 56 | } |
| 54 | 57 | ||
| 55 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, | 58 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, |
| 56 | struct sk_buff *skb) | 59 | struct sk_buff *skb) |
| 57 | { | 60 | { |
| 58 | struct net_bridge_mdb_htable *mdb = br->mdb; | 61 | if (br->multicast_disabled) |
| 59 | |||
| 60 | if (!mdb || br->multicast_disabled) | ||
| 61 | return NULL; | 62 | return NULL; |
| 62 | 63 | ||
| 63 | switch (skb->protocol) { | 64 | switch (skb->protocol) { |
| 64 | case htons(ETH_P_IP): | 65 | case htons(ETH_P_IP): |
| 65 | if (BR_INPUT_SKB_CB(skb)->igmp) | 66 | if (BR_INPUT_SKB_CB(skb)->igmp) |
| 66 | break; | 67 | break; |
| 67 | return br_mdb_ip_get(mdb, ip_hdr(skb)->daddr); | 68 | return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr); |
| 68 | } | 69 | } |
| 69 | 70 | ||
| 70 | return NULL; | 71 | return NULL; |
| @@ -722,11 +723,11 @@ static int br_multicast_igmp3_report(struct net_bridge *br, | |||
| 722 | if (!pskb_may_pull(skb, len)) | 723 | if (!pskb_may_pull(skb, len)) |
| 723 | return -EINVAL; | 724 | return -EINVAL; |
| 724 | 725 | ||
| 725 | grec = (void *)(skb->data + len); | 726 | grec = (void *)(skb->data + len - sizeof(*grec)); |
| 726 | group = grec->grec_mca; | 727 | group = grec->grec_mca; |
| 727 | type = grec->grec_type; | 728 | type = grec->grec_type; |
| 728 | 729 | ||
| 729 | len += grec->grec_nsrcs * 4; | 730 | len += ntohs(grec->grec_nsrcs) * 4; |
| 730 | if (!pskb_may_pull(skb, len)) | 731 | if (!pskb_may_pull(skb, len)) |
| 731 | return -EINVAL; | 732 | return -EINVAL; |
| 732 | 733 | ||
| @@ -851,8 +852,8 @@ static int br_multicast_query(struct net_bridge *br, | |||
| 851 | if (ih3->nsrcs) | 852 | if (ih3->nsrcs) |
| 852 | goto out; | 853 | goto out; |
| 853 | 854 | ||
| 854 | max_delay = ih3->code ? 1 : | 855 | max_delay = ih3->code ? |
| 855 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE); | 856 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; |
| 856 | } | 857 | } |
| 857 | 858 | ||
| 858 | if (!group) | 859 | if (!group) |
| @@ -956,9 +957,6 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
| 956 | unsigned offset; | 957 | unsigned offset; |
| 957 | int err; | 958 | int err; |
| 958 | 959 | ||
| 959 | BR_INPUT_SKB_CB(skb)->igmp = 0; | ||
| 960 | BR_INPUT_SKB_CB(skb)->mrouters_only = 0; | ||
| 961 | |||
| 962 | /* We treat OOM as packet loss for now. */ | 960 | /* We treat OOM as packet loss for now. */ |
| 963 | if (!pskb_may_pull(skb, sizeof(*iph))) | 961 | if (!pskb_may_pull(skb, sizeof(*iph))) |
| 964 | return -EINVAL; | 962 | return -EINVAL; |
| @@ -990,7 +988,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
| 990 | 988 | ||
| 991 | err = pskb_trim_rcsum(skb2, len); | 989 | err = pskb_trim_rcsum(skb2, len); |
| 992 | if (err) | 990 | if (err) |
| 993 | return err; | 991 | goto err_out; |
| 994 | } | 992 | } |
| 995 | 993 | ||
| 996 | len -= ip_hdrlen(skb2); | 994 | len -= ip_hdrlen(skb2); |
| @@ -1012,7 +1010,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
| 1012 | case CHECKSUM_NONE: | 1010 | case CHECKSUM_NONE: |
| 1013 | skb2->csum = 0; | 1011 | skb2->csum = 0; |
| 1014 | if (skb_checksum_complete(skb2)) | 1012 | if (skb_checksum_complete(skb2)) |
| 1015 | return -EINVAL; | 1013 | goto out; |
| 1016 | } | 1014 | } |
| 1017 | 1015 | ||
| 1018 | err = 0; | 1016 | err = 0; |
| @@ -1039,6 +1037,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
| 1039 | 1037 | ||
| 1040 | out: | 1038 | out: |
| 1041 | __skb_push(skb2, offset); | 1039 | __skb_push(skb2, offset); |
| 1040 | err_out: | ||
| 1042 | if (skb2 != skb) | 1041 | if (skb2 != skb) |
| 1043 | kfree_skb(skb2); | 1042 | kfree_skb(skb2); |
| 1044 | return err; | 1043 | return err; |
| @@ -1047,6 +1046,9 @@ out: | |||
| 1047 | int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, | 1046 | int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, |
| 1048 | struct sk_buff *skb) | 1047 | struct sk_buff *skb) |
| 1049 | { | 1048 | { |
| 1049 | BR_INPUT_SKB_CB(skb)->igmp = 0; | ||
| 1050 | BR_INPUT_SKB_CB(skb)->mrouters_only = 0; | ||
| 1051 | |||
| 1050 | if (br->multicast_disabled) | 1052 | if (br->multicast_disabled) |
| 1051 | return 0; | 1053 | return 0; |
| 1052 | 1054 | ||
