Skip to content

Commit

Permalink
iproute2: implement add/del mdb entry
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Cong Wang authored and Stephen Hemminger committed Dec 12, 2012
1 parent 1556e29 commit 9dca676
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
76 changes: 76 additions & 0 deletions bridge/mdb.c
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 8 additions & 0 deletions include/linux/if_bridge.h
Expand Up @@ -157,6 +157,7 @@ enum {
#define MDBA_ROUTER_MAX (__MDBA_ROUTER_MAX - 1)

struct br_port_msg {
__u8 family;
__u32 ifindex;
};

Expand All @@ -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 */
4 changes: 4 additions & 0 deletions include/linux/rtnetlink.h
Expand Up @@ -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

Expand Down

0 comments on commit 9dca676

Please sign in to comment.