]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
iproute2: implement add/del mdb entry
authorCong Wang <amwang@redhat.com>
Tue, 11 Dec 2012 22:23:09 +0000 (22:23 +0000)
committerStephen Hemminger <shemminger@vyatta.com>
Wed, 12 Dec 2012 18:27:46 +0000 (10:27 -0800)
This patch implements:

bridge mdb { add | del } dev DEV port PORT grp GROUP

Cc: Stephen Hemminger <shemminger@vyatta.com>
Cc: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Cong Wang <amwang@redhat.com>
bridge/mdb.c
include/linux/if_bridge.h
include/linux/rtnetlink.h

index 390d7f614882789f2a566bdd442e069e6724cd23..4d8a8966d8dbc6d13166d36004cf55a08a4726ca 100644 (file)
@@ -28,6 +28,7 @@ int filter_index;
 
 static void usage(void)
 {
+       fprintf(stderr, "Usage: bridge mdb { add | del } dev DEV port PORT grp GROUP\n");
        fprintf(stderr, "       bridge mdb {show} [ dev DEV ]\n");
        exit(-1);
 }
@@ -153,11 +154,86 @@ static int mdb_show(int argc, char **argv)
        return 0;
 }
 
+static int mdb_modify(int cmd, int flags, int argc, char **argv)
+{
+       struct {
+               struct nlmsghdr         n;
+               struct br_port_msg      bpm;
+               char                    buf[1024];
+       } req;
+       struct br_mdb_entry entry;
+       char *d = NULL, *p = NULL, *grp = NULL;
+
+       memset(&req, 0, sizeof(req));
+       memset(&entry, 0, sizeof(entry));
+
+       req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct br_port_msg));
+       req.n.nlmsg_flags = NLM_F_REQUEST|flags;
+       req.n.nlmsg_type = cmd;
+       req.bpm.family = PF_BRIDGE;
+
+       while (argc > 0) {
+               if (strcmp(*argv, "dev") == 0) {
+                       NEXT_ARG();
+                       d = *argv;
+               } else if (strcmp(*argv, "grp") == 0) {
+                       NEXT_ARG();
+                       grp = *argv;
+               } else {
+                       if (strcmp(*argv, "port") == 0) {
+                               NEXT_ARG();
+                               p = *argv;
+                       }
+                       if (matches(*argv, "help") == 0)
+                               usage();
+               }
+               argc--; argv++;
+       }
+
+       if (d == NULL || grp == NULL || p == NULL) {
+               fprintf(stderr, "Device, group address and port name are required arguments.\n");
+               exit(-1);
+       }
+
+       req.bpm.ifindex = ll_name_to_index(d);
+       if (req.bpm.ifindex == 0) {
+               fprintf(stderr, "Cannot find device \"%s\"\n", d);
+               return -1;
+       }
+
+       entry.ifindex = ll_name_to_index(p);
+       if (entry.ifindex == 0) {
+               fprintf(stderr, "Cannot find device \"%s\"\n", p);
+               return -1;
+       }
+
+       if (!inet_pton(AF_INET, grp, &entry.addr.u.ip4)) {
+               if (!inet_pton(AF_INET6, grp, &entry.addr.u.ip6)) {
+                       fprintf(stderr, "Invalid address \"%s\"\n", grp);
+                       return -1;
+               } else
+                       entry.addr.proto = htons(ETH_P_IPV6);
+       } else
+               entry.addr.proto = htons(ETH_P_IP);
+
+       addattr_l(&req.n, sizeof(req), MDBA_SET_ENTRY, &entry, sizeof(entry));
+
+       if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
+               exit(2);
+
+       return 0;
+}
+
 int do_mdb(int argc, char **argv)
 {
        ll_init_map(&rth);
 
        if (argc > 0) {
+               if (matches(*argv, "add") == 0)
+                       return mdb_modify(RTM_NEWMDB, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
+               if (matches(*argv, "delete") == 0)
+                       return mdb_modify(RTM_DELMDB, 0, argc-1, argv+1);
+
                if (matches(*argv, "show") == 0 ||
                    matches(*argv, "lst") == 0 ||
                    matches(*argv, "list") == 0)
index 151a8bbe581d5b976ec09a422919fd213351df9e..b3b6a67e77585c4d24ca5264215d7914d37ca78f 100644 (file)
@@ -157,6 +157,7 @@ enum {
 #define MDBA_ROUTER_MAX (__MDBA_ROUTER_MAX - 1)
 
 struct br_port_msg {
+       __u8  family;
        __u32 ifindex;
 };
 
@@ -171,4 +172,11 @@ struct br_mdb_entry {
        } addr;
 };
 
+enum {
+       MDBA_SET_ENTRY_UNSPEC,
+       MDBA_SET_ENTRY,
+       __MDBA_SET_ENTRY_MAX,
+};
+#define MDBA_SET_ENTRY_MAX (__MDBA_SET_ENTRY_MAX - 1)
+
 #endif /* _LINUX_IF_BRIDGE_H */
index c82a159de7e33e70badcda25c162c38d4c8228a9..3ea85dcedc17a8ec2b7ba2ff142f3f735994a5fa 100644 (file)
@@ -125,6 +125,10 @@ enum {
        RTM_GETNETCONF = 82,
 #define RTM_GETNETCONF RTM_GETNETCONF
 
+       RTM_NEWMDB = 84,
+#define RTM_NEWMDB RTM_NEWMDB
+       RTM_DELMDB = 85,
+#define RTM_DELMDB RTM_DELMDB
        RTM_GETMDB = 86,
 #define RTM_GETMDB RTM_GETMDB