net: bridge: extend the process of special frames
[linux-2.6-microblaze.git] / net / bridge / br_mrp.c
index b36689e..f94d72b 100644 (file)
@@ -6,6 +6,13 @@
 static const u8 mrp_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x1 };
 static const u8 mrp_in_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x3 };
 
+static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
+
+static struct br_frame_type mrp_frame_type __read_mostly = {
+       .type = cpu_to_be16(ETH_P_MRP),
+       .frame_handler = br_mrp_process,
+};
+
 static bool br_mrp_is_ring_port(struct net_bridge_port *p_port,
                                struct net_bridge_port *s_port,
                                struct net_bridge_port *port)
@@ -445,6 +452,9 @@ static void br_mrp_del_impl(struct net_bridge *br, struct br_mrp *mrp)
 
        list_del_rcu(&mrp->list);
        kfree_rcu(mrp, rcu);
+
+       if (list_empty(&br->mrp_list))
+               br_del_frame(br, &mrp_frame_type);
 }
 
 /* Adds a new MRP instance.
@@ -493,6 +503,9 @@ int br_mrp_add(struct net_bridge *br, struct br_mrp_instance *instance)
        spin_unlock_bh(&br->lock);
        rcu_assign_pointer(mrp->s_port, p);
 
+       if (list_empty(&br->mrp_list))
+               br_add_frame(br, &mrp_frame_type);
+
        INIT_DELAYED_WORK(&mrp->test_work, br_mrp_test_work_expired);
        INIT_DELAYED_WORK(&mrp->in_test_work, br_mrp_in_test_work_expired);
        list_add_tail_rcu(&mrp->list, &br->mrp_list);
@@ -1172,15 +1185,13 @@ no_forward:
  * normal forwarding.
  * note: already called with rcu_read_lock
  */
-int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
+static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
 {
        /* If there is no MRP instance do normal forwarding */
        if (likely(!(p->flags & BR_MRP_AWARE)))
                goto out;
 
-       if (unlikely(skb->protocol == htons(ETH_P_MRP)))
-               return br_mrp_rcv(p, skb, p->dev);
-
+       return br_mrp_rcv(p, skb, p->dev);
 out:
        return 0;
 }