+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 *lh;
+ struct net_bridge *br;
+
+ br = (struct net_bridge *) ptr;
+
+ spin_lock_bh(&br->mcl_lock);
+ list_for_each_safe_rcu(lh, tmp, &br->mc_list) {
+ dst = (struct net_bridge_mc_fdb_entry *) list_entry(lh, struct net_bridge_mc_fdb_entry, list);
+ if (jiffies > dst->tstamp) {
+ list_del_rcu(&dst->list);
+ kfree(dst);
+ }
+ }
+ spin_unlock_bh(&br->mcl_lock);
+
+ mod_timer(&br->igmp_timer, jiffies + TIMER_CHECK_TIMEOUT*HZ);
+}
+
+void addr_debug(unsigned char *dest)
+{
+#define NUM2PRINT 50
+ char buf[NUM2PRINT * 3 + 1]; /* 3 chars per byte */
+ int i = 0;
+ for (i = 0; i < 6 && i < NUM2PRINT; i++) {
+ sprintf(buf + i * 3, "%2.2x ", 0xff & dest[i]);
+ }
+ printk("%s ", buf);
+}
+
+
+#if defined(CONFIG_MIPS_BRCM)
+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)
+{
+ struct net_bridge_mc_fdb_entry *dst;
+ struct list_head *lh;
+ int status = 0;
+ struct sk_buff *skb2;
+ struct net_bridge_port *p;
+
+ if (!snooping)
+ return 0;
+
+ if (skb->data[9] == 0x2) {
+ // For proxy; need to add some intelligence here
+ if (!br->proxy) {
+ if (skb->data[24] == 0x16)
+ 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
+ ;
+ }
+ return status;
+ }
+
+ /*
+ if (clone) {
+ struct sk_buff *skb3;
+
+ if ((skb3 = skb_clone(skb, GFP_ATOMIC)) == NULL) {
+ br->statistics.tx_dropped++;
+ return;
+ }
+
+ skb = skb3;
+ }
+ */
+
+ list_for_each_rcu(lh, &br->mc_list) {
+ dst = (struct net_bridge_mc_fdb_entry *) list_entry(lh, struct net_bridge_mc_fdb_entry, list);
+ if (!memcmp(&dst->addr, dest, ETH_ALEN)) {
+ if (!dst->dst->dirty) {
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+ if (forward)
+ br_forward(dst->dst, skb2);
+ else
+ br_deliver(dst->dst, skb2);
+ }
+ dst->dst->dirty = 1;
+ status = 1;
+ }
+ }
+ if (status) {
+ list_for_each_entry_rcu(p, &br->port_list, list) {
+ p->dirty = 0;
+ }
+ }
+
+ if ((!forward) && (status))
+ kfree_skb(skb);
+
+ return status;
+}
+#endif
+