ofproto-dpif: Add mcast snooping db show and flush cmds
authorFlavio Leitner <fbl@redhat.com>
Thu, 19 Jun 2014 01:14:33 +0000 (22:14 -0300)
committerBen Pfaff <blp@nicira.com>
Tue, 24 Jun 2014 18:17:08 +0000 (11:17 -0700)
This patch adds the command 'ovs-appctl mdb/show bridge'
to show learned groups on a bridge from the multicast
snooping database.

It also adds the command 'ovs-appctl mdb/flush [bridge]'
to flush learned groups on a bridge or on all bridges.

Acked-by: Thomas Graf <tgraf@redhat.com>
Acked-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Flavio Leitner <fbl@redhat.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
ofproto/ofproto-dpif.c
vswitchd/ovs-vswitchd.8.in

index d623ee7..8c130e1 100644 (file)
@@ -3883,6 +3883,36 @@ ofproto_unixctl_fdb_flush(struct unixctl_conn *conn, int argc,
     unixctl_command_reply(conn, "table successfully flushed");
 }
 
+static void
+ofproto_unixctl_mcast_snooping_flush(struct unixctl_conn *conn, int argc,
+                                     const char *argv[], void *aux OVS_UNUSED)
+{
+    struct ofproto_dpif *ofproto;
+
+    if (argc > 1) {
+        ofproto = ofproto_dpif_lookup(argv[1]);
+        if (!ofproto) {
+            unixctl_command_reply_error(conn, "no such bridge");
+            return;
+        }
+
+        if (!mcast_snooping_enabled(ofproto->ms)) {
+            unixctl_command_reply_error(conn, "multicast snooping is disabled");
+            return;
+        }
+        mcast_snooping_mdb_flush(ofproto->ms);
+    } else {
+        HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
+            if (!mcast_snooping_enabled(ofproto->ms)) {
+                continue;
+            }
+            mcast_snooping_mdb_flush(ofproto->ms);
+        }
+    }
+
+    unixctl_command_reply(conn, "table successfully flushed");
+}
+
 static struct ofport_dpif *
 ofbundle_get_a_port(const struct ofbundle *bundle)
 {
@@ -3921,6 +3951,61 @@ ofproto_unixctl_fdb_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
     ds_destroy(&ds);
 }
 
+static void
+ofproto_unixctl_mcast_snooping_show(struct unixctl_conn *conn,
+                                    int argc OVS_UNUSED,
+                                    const char *argv[],
+                                    void *aux OVS_UNUSED)
+{
+    struct ds ds = DS_EMPTY_INITIALIZER;
+    const struct ofproto_dpif *ofproto;
+    const struct ofbundle *bundle;
+    const struct mcast_group *grp;
+    struct mcast_group_bundle *b;
+    struct mcast_mrouter_bundle *mrouter;
+
+    ofproto = ofproto_dpif_lookup(argv[1]);
+    if (!ofproto) {
+        unixctl_command_reply_error(conn, "no such bridge");
+        return;
+    }
+
+    if (!mcast_snooping_enabled(ofproto->ms)) {
+        unixctl_command_reply_error(conn, "multicast snooping is disabled");
+        return;
+    }
+
+    ds_put_cstr(&ds, " port  VLAN  GROUP                Age\n");
+    ovs_rwlock_rdlock(&ofproto->ms->rwlock);
+    LIST_FOR_EACH (grp, group_node, &ofproto->ms->group_lru) {
+        LIST_FOR_EACH(b, bundle_node, &grp->bundle_lru) {
+            char name[OFP_MAX_PORT_NAME_LEN];
+
+            bundle = b->port;
+            ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
+                                   name, sizeof name);
+            ds_put_format(&ds, "%5s  %4d  "IP_FMT"         %3d\n",
+                          name, grp->vlan, IP_ARGS(grp->ip4),
+                          mcast_bundle_age(ofproto->ms, b));
+        }
+    }
+
+    /* ports connected to multicast routers */
+    LIST_FOR_EACH(mrouter, mrouter_node, &ofproto->ms->mrouter_lru) {
+        char name[OFP_MAX_PORT_NAME_LEN];
+
+        bundle = mrouter->port;
+        ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
+                               name, sizeof name);
+            ds_put_format(&ds, "%5s  %4d  querier             %3d\n",
+                      name, mrouter->vlan,
+                      mcast_mrouter_age(ofproto->ms, mrouter));
+    }
+    ovs_rwlock_unlock(&ofproto->ms->rwlock);
+    unixctl_command_reply(conn, ds_cstr(&ds));
+    ds_destroy(&ds);
+}
+
 struct trace_ctx {
     struct xlate_out xout;
     struct xlate_in xin;
@@ -4601,6 +4686,10 @@ ofproto_dpif_unixctl_init(void)
                              ofproto_unixctl_fdb_flush, NULL);
     unixctl_command_register("fdb/show", "bridge", 1, 1,
                              ofproto_unixctl_fdb_show, NULL);
+    unixctl_command_register("mdb/flush", "[bridge]", 0, 1,
+                             ofproto_unixctl_mcast_snooping_flush, NULL);
+    unixctl_command_register("mdb/show", "bridge", 1, 1,
+                             ofproto_unixctl_mcast_snooping_show, NULL);
     unixctl_command_register("dpif/dump-dps", "", 0, 0,
                              ofproto_unixctl_dpif_dump_dps, NULL);
     unixctl_command_register("dpif/show", "", 0, 0, ofproto_unixctl_dpif_show,
index e9dc483..e5713e7 100644 (file)
@@ -140,6 +140,13 @@ if no \fIbridge\fR is given.
 Lists each MAC address/VLAN pair learned by the specified \fIbridge\fR,
 along with the port on which it was learned and the age of the entry,
 in seconds.
+.IP "\fBmdb/flush\fR [\fIbridge\fR]"
+Flushes \fIbridge\fR multicast snooping table, or all snooping tables
+if no \fIbridge\fR is given.
+.IP "\fBmdb/show\fR \fIbridge\fR"
+Lists each multicast group/VLAN pair learned by the specified \fIbridge\fR,
+along with the port on which it was learned and the age of the entry,
+in seconds.
 .IP "\fBbridge/reconnect\fR [\fIbridge\fR]"
 Makes \fIbridge\fR drop all of its OpenFlow controller connections and
 reconnect.  If \fIbridge\fR is not specified, then all bridges drop