#if defined(CONFIG_MIPS_BRCM)
#include <linux/if_vlan.h>
#include <linux/timer.h>
+#include <linux/igmp.h>
#endif
#include "br_private.h"
+#if defined(CONFIG_MIPS_BRCM)
+#define SNOOPING_BLOCKING_MODE 2
+#endif
+
const unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
static int br_pass_frame_up_finish(struct sk_buff *skb)
br_pass_frame_up_finish);
}
-extern void addr_debug();
-
void query_timeout(unsigned long ptr)
{
struct net_bridge_mc_fdb_entry *dst;
- struct net_bridge_mc_fdb_entry *tmp = NULL;
+ struct list_head *tmp;
struct list_head *lh;
struct net_bridge *br;
#if defined(CONFIG_MIPS_BRCM)
-addr_conv(unsigned char *in, char * out)
+void addr_conv(unsigned char *in, char * out)
{
sprintf(out, "%02x%02x%02x%02x%02x%02x", in[0], in[1], in[2], in[3], in[4], in[5]);
}
-mc_forward(struct net_bridge *br, struct sk_buff *skb, unsigned char *dest,int forward, int clone)
+mac_addr upnp_addr = {{0x01, 0x00, 0x5e, 0x7f, 0xff, 0xfa}};
+mac_addr sys1_addr = {{0x01, 0x00, 0x5e, 0x00, 0x00, 0x01}};
+mac_addr sys2_addr = {{0x01, 0x00, 0x5e, 0x00, 0x00, 0x02}};
+mac_addr ospf1_addr = {{0x01, 0x00, 0x5e, 0x00, 0x00, 0x05}};
+mac_addr ospf2_addr = {{0x01, 0x00, 0x5e, 0x00, 0x00, 0x06}};
+mac_addr ripv2_addr = {{0x01, 0x00, 0x5e, 0x00, 0x00, 0x09}};
+mac_addr sys_addr = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
+
+int control_filter(unsigned char *dest)
+{
+ if ((!memcmp(dest, &upnp_addr, ETH_ALEN)) ||
+ (!memcmp(dest, &sys1_addr, ETH_ALEN)) ||
+ (!memcmp(dest, &sys2_addr, ETH_ALEN)) ||
+ (!memcmp(dest, &ospf1_addr, ETH_ALEN)) ||
+ (!memcmp(dest, &ospf2_addr, ETH_ALEN)) ||
+ (!memcmp(dest, &sys_addr, ETH_ALEN)) ||
+ (!memcmp(dest, &ripv2_addr, ETH_ALEN)))
+ return 0;
+ else
+ return 1;
+}
+
+int mc_forward(struct net_bridge *br, struct sk_buff *skb, unsigned char *dest,int forward, int clone)
{
struct net_bridge_mc_fdb_entry *dst;
struct list_head *lh;
int status = 0;
struct sk_buff *skb2;
struct net_bridge_port *p;
+ unsigned char tmp[6];
if (!snooping)
return 0;
- if (skb->data[9] == 0x2) {
+ if ((snooping == SNOOPING_BLOCKING_MODE) && control_filter(dest))
+ status = 1;
+
+ if (skb->data[9] == IPPROTO_IGMP) {
// For proxy; need to add some intelligence here
if (!br->proxy) {
- if (skb->data[24] == 0x16)
+ if (skb->data[24] == IGMPV2_HOST_MEMBERSHIP_REPORT &&
+ skb->protocol == __constant_htons(ETH_P_IP))
br_mc_fdb_add(br, skb->dev->br_port, dest, skb->mac.ethernet->h_source);
- else if (skb->data[24] == 0x17) {
- dest[0] = 0x01;
- dest[1] = 0x00;
- dest[2] = 0x5e;
- dest[3] = 0x7F & skb->data[29];
- dest[4] = skb->data[30];
- dest[5] = skb->data[31];
- br_mc_fdb_remove(br, skb->dev->br_port, dest, skb->mac.ethernet->h_source);
+ else if (skb->data[24] == IGMP_HOST_LEAVE_MESSAGE) {
+ tmp[0] = 0x01;
+ tmp[1] = 0x00;
+ tmp[2] = 0x5e;
+ tmp[3] = 0x7F & skb->data[29];
+ tmp[4] = skb->data[30];
+ tmp[5] = skb->data[31];
+ br_mc_fdb_remove(br, skb->dev->br_port, tmp, skb->mac.ethernet->h_source);
}
else
;
if (dest[0] & 1) {
#if defined(CONFIG_MIPS_BRCM)
if (snooping && br->proxy) {
- if (skb->data[9] == 0x2) {
+ if (skb->data[9] == IPPROTO_IGMP) {
char destS[16];
char srcS[16];
- if (skb->data[24] == 0x17) {
+ if (skb->data[24] == IGMP_HOST_LEAVE_MESSAGE) {
unsigned char tmp[6];
tmp[0] = 0x01;