2017-11-25 04:21:35 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2012-12-12 08:46:22 +08:00
|
|
|
/*
|
|
|
|
* Get mdb table with netlink
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <linux/if_bridge.h>
|
|
|
|
#include <linux/if_ether.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
|
|
|
|
#include "libnetlink.h"
|
|
|
|
#include "br_common.h"
|
|
|
|
#include "rt_names.h"
|
|
|
|
#include "utils.h"
|
2018-02-21 03:24:05 +08:00
|
|
|
#include "json_print.h"
|
2012-12-12 08:46:22 +08:00
|
|
|
|
|
|
|
#ifndef MDBA_RTA
|
|
|
|
#define MDBA_RTA(r) \
|
2016-03-22 02:56:01 +08:00
|
|
|
((struct rtattr *)(((char *)(r)) + NLMSG_ALIGN(sizeof(struct br_port_msg))))
|
2012-12-12 08:46:22 +08:00
|
|
|
#endif
|
|
|
|
|
2016-04-11 23:45:15 +08:00
|
|
|
static unsigned int filter_index, filter_vlan;
|
2012-12-12 08:46:22 +08:00
|
|
|
|
|
|
|
static void usage(void)
|
|
|
|
{
|
treewide: refactor help messages
Every tool in the iproute2 package have one or more function to show
an help message to the user. Some of these functions print the help
line by line with a series of printf call, e.g. ip/xfrm_state.c does
60 fprintf calls.
If we group all the calls to a single one and just concatenate strings,
we save a lot of libc calls and thus object size. The size difference
of the compiled binaries calculated with bloat-o-meter is:
ip/ip:
add/remove: 0/0 grow/shrink: 5/15 up/down: 103/-4796 (-4693)
Total: Before=672591, After=667898, chg -0.70%
ip/rtmon:
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-54 (-54)
Total: Before=48879, After=48825, chg -0.11%
tc/tc:
add/remove: 0/2 grow/shrink: 31/10 up/down: 882/-6133 (-5251)
Total: Before=351912, After=346661, chg -1.49%
bridge/bridge:
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-459 (-459)
Total: Before=70502, After=70043, chg -0.65%
misc/lnstat:
add/remove: 0/1 grow/shrink: 1/0 up/down: 48/-486 (-438)
Total: Before=9960, After=9522, chg -4.40%
tipc/tipc:
add/remove: 0/0 grow/shrink: 1/1 up/down: 18/-62 (-44)
Total: Before=79182, After=79138, chg -0.06%
While at it, indent some strings which were starting at column 0,
and use tabs where possible, to have a consistent style across helps.
Signed-off-by: Matteo Croce <mcroce@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
2019-05-17 21:38:28 +08:00
|
|
|
fprintf(stderr,
|
2020-10-08 21:50:19 +08:00
|
|
|
"Usage: bridge mdb { add | del } dev DEV port PORT grp GROUP [src SOURCE] [permanent | temp] [vid VID]\n"
|
treewide: refactor help messages
Every tool in the iproute2 package have one or more function to show
an help message to the user. Some of these functions print the help
line by line with a series of printf call, e.g. ip/xfrm_state.c does
60 fprintf calls.
If we group all the calls to a single one and just concatenate strings,
we save a lot of libc calls and thus object size. The size difference
of the compiled binaries calculated with bloat-o-meter is:
ip/ip:
add/remove: 0/0 grow/shrink: 5/15 up/down: 103/-4796 (-4693)
Total: Before=672591, After=667898, chg -0.70%
ip/rtmon:
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-54 (-54)
Total: Before=48879, After=48825, chg -0.11%
tc/tc:
add/remove: 0/2 grow/shrink: 31/10 up/down: 882/-6133 (-5251)
Total: Before=351912, After=346661, chg -1.49%
bridge/bridge:
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-459 (-459)
Total: Before=70502, After=70043, chg -0.65%
misc/lnstat:
add/remove: 0/1 grow/shrink: 1/0 up/down: 48/-486 (-438)
Total: Before=9960, After=9522, chg -4.40%
tipc/tipc:
add/remove: 0/0 grow/shrink: 1/1 up/down: 18/-62 (-44)
Total: Before=79182, After=79138, chg -0.06%
While at it, indent some strings which were starting at column 0,
and use tabs where possible, to have a consistent style across helps.
Signed-off-by: Matteo Croce <mcroce@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
2019-05-17 21:38:28 +08:00
|
|
|
" bridge mdb {show} [ dev DEV ] [ vid VID ]\n");
|
2012-12-12 08:46:22 +08:00
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
2016-03-14 18:04:46 +08:00
|
|
|
static bool is_temp_mcast_rtr(__u8 type)
|
|
|
|
{
|
|
|
|
return type == MDB_RTR_TYPE_TEMP_QUERY || type == MDB_RTR_TYPE_TEMP;
|
|
|
|
}
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
static const char *format_timer(__u32 ticks)
|
|
|
|
{
|
|
|
|
struct timeval tv;
|
|
|
|
static char tbuf[32];
|
|
|
|
|
|
|
|
__jiffies_to_tv(&tv, ticks);
|
|
|
|
snprintf(tbuf, sizeof(tbuf), "%4lu.%.2lu",
|
|
|
|
(unsigned long)tv.tv_sec,
|
|
|
|
(unsigned long)tv.tv_usec / 10000);
|
|
|
|
|
|
|
|
return tbuf;
|
|
|
|
}
|
|
|
|
|
2016-03-14 18:04:46 +08:00
|
|
|
static void __print_router_port_stats(FILE *f, struct rtattr *pattr)
|
|
|
|
{
|
|
|
|
struct rtattr *tb[MDBA_ROUTER_PATTR_MAX + 1];
|
|
|
|
|
|
|
|
parse_rtattr(tb, MDBA_ROUTER_PATTR_MAX, MDB_RTR_RTA(RTA_DATA(pattr)),
|
|
|
|
RTA_PAYLOAD(pattr) - RTA_ALIGN(sizeof(uint32_t)));
|
2018-02-21 03:24:05 +08:00
|
|
|
|
2016-03-14 18:04:46 +08:00
|
|
|
if (tb[MDBA_ROUTER_PATTR_TIMER]) {
|
2018-02-21 03:24:05 +08:00
|
|
|
__u32 timer = rta_getattr_u32(tb[MDBA_ROUTER_PATTR_TIMER]);
|
|
|
|
|
|
|
|
print_string(PRINT_ANY, "timer", " %s",
|
|
|
|
format_timer(timer));
|
2016-03-14 18:04:46 +08:00
|
|
|
}
|
2018-02-21 03:24:05 +08:00
|
|
|
|
2016-03-14 18:04:46 +08:00
|
|
|
if (tb[MDBA_ROUTER_PATTR_TYPE]) {
|
2018-02-21 03:24:05 +08:00
|
|
|
__u8 type = rta_getattr_u8(tb[MDBA_ROUTER_PATTR_TYPE]);
|
|
|
|
|
|
|
|
print_string(PRINT_ANY, "type", " %s",
|
|
|
|
is_temp_mcast_rtr(type) ? "temp" : "permanent");
|
2016-03-14 18:04:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
static void br_print_router_ports(FILE *f, struct rtattr *attr,
|
|
|
|
const char *brifname)
|
2012-12-12 08:46:22 +08:00
|
|
|
{
|
2018-02-21 03:24:05 +08:00
|
|
|
int rem = RTA_PAYLOAD(attr);
|
2012-12-12 08:46:22 +08:00
|
|
|
struct rtattr *i;
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
if (is_json_context())
|
|
|
|
open_json_array(PRINT_JSON, brifname);
|
|
|
|
else if (!show_stats)
|
|
|
|
fprintf(f, "router ports on %s: ", brifname);
|
|
|
|
|
|
|
|
for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
|
|
|
|
uint32_t *port_ifindex = RTA_DATA(i);
|
|
|
|
const char *port_ifname = ll_index_to_name(*port_ifindex);
|
|
|
|
|
|
|
|
if (is_json_context()) {
|
|
|
|
open_json_object(NULL);
|
|
|
|
print_string(PRINT_JSON, "port", NULL, port_ifname);
|
|
|
|
|
bridge: this patch adds json support for bridge mdb show
This patch adds json output to bridge mdb show
Normal Output:
$ bridge -d -s mdb show
dev br0 port swp3 grp 239.0.0.1 temp vid 128 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 64 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1024 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 256 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 1 172.26
router ports on br0: swp4 0.00 permanent
router ports on br0: swp5 0.00 permanent
Json Output:
$ bridge -d -s -j mdb show
{
"mdb": [{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 128,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 64,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1024,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 256,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 1,
"timer": " 166.74"
}
],
"router": {
"br0": [{
"port": "swp4",
"timer": " 0.00",
"type": "permanent"
},{
"port": "swp5",
"timer": " 0.00",
"type": "permanent"
}
]
}
}
Signed-off-by: Nikhil Gajendrakumar <nikhil@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
2017-07-08 06:24:16 +08:00
|
|
|
if (show_stats)
|
|
|
|
__print_router_port_stats(f, i);
|
2018-02-21 03:24:05 +08:00
|
|
|
close_json_object();
|
|
|
|
} else if (show_stats) {
|
|
|
|
fprintf(f, "router ports on %s: %s",
|
|
|
|
brifname, port_ifname);
|
|
|
|
|
|
|
|
__print_router_port_stats(f, i);
|
bridge: this patch adds json support for bridge mdb show
This patch adds json output to bridge mdb show
Normal Output:
$ bridge -d -s mdb show
dev br0 port swp3 grp 239.0.0.1 temp vid 128 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 64 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1024 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 256 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 1 172.26
router ports on br0: swp4 0.00 permanent
router ports on br0: swp5 0.00 permanent
Json Output:
$ bridge -d -s -j mdb show
{
"mdb": [{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 128,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 64,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1024,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 256,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 1,
"timer": " 166.74"
}
],
"router": {
"br0": [{
"port": "swp4",
"timer": " 0.00",
"type": "permanent"
},{
"port": "swp5",
"timer": " 0.00",
"type": "permanent"
}
]
}
}
Signed-off-by: Nikhil Gajendrakumar <nikhil@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
2017-07-08 06:24:16 +08:00
|
|
|
fprintf(f, "\n");
|
2018-02-21 03:24:05 +08:00
|
|
|
} else {
|
|
|
|
fprintf(f, "%s ", port_ifname);
|
|
|
|
}
|
2012-12-12 08:46:22 +08:00
|
|
|
}
|
2018-09-12 09:39:44 +08:00
|
|
|
|
|
|
|
if (!show_stats)
|
|
|
|
print_nl();
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
close_json_array(PRINT_JSON, NULL);
|
bridge: this patch adds json support for bridge mdb show
This patch adds json output to bridge mdb show
Normal Output:
$ bridge -d -s mdb show
dev br0 port swp3 grp 239.0.0.1 temp vid 128 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 64 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1024 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 256 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 1 172.26
router ports on br0: swp4 0.00 permanent
router ports on br0: swp5 0.00 permanent
Json Output:
$ bridge -d -s -j mdb show
{
"mdb": [{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 128,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 64,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1024,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 256,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 1,
"timer": " 166.74"
}
],
"router": {
"br0": [{
"port": "swp4",
"timer": " 0.00",
"type": "permanent"
},{
"port": "swp5",
"timer": " 0.00",
"type": "permanent"
}
]
}
}
Signed-off-by: Nikhil Gajendrakumar <nikhil@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
2017-07-08 06:24:16 +08:00
|
|
|
}
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
static void print_mdb_entry(FILE *f, int ifindex, const struct br_mdb_entry *e,
|
2016-02-22 22:16:13 +08:00
|
|
|
struct nlmsghdr *n, struct rtattr **tb)
|
2012-12-12 08:46:22 +08:00
|
|
|
{
|
2020-10-08 21:50:19 +08:00
|
|
|
const void *grp, *src;
|
2012-12-12 08:46:22 +08:00
|
|
|
SPRINT_BUF(abuf);
|
2018-02-21 03:24:05 +08:00
|
|
|
const char *dev;
|
2015-07-15 23:45:20 +08:00
|
|
|
int af;
|
|
|
|
|
2016-04-11 23:45:15 +08:00
|
|
|
if (filter_vlan && e->vid != filter_vlan)
|
|
|
|
return;
|
2018-02-21 03:24:05 +08:00
|
|
|
|
2015-07-15 23:45:20 +08:00
|
|
|
af = e->addr.proto == htons(ETH_P_IP) ? AF_INET : AF_INET6;
|
2020-10-08 21:50:19 +08:00
|
|
|
grp = af == AF_INET ? (const void *)&e->addr.u.ip4 :
|
2015-07-15 23:45:20 +08:00
|
|
|
(const void *)&e->addr.u.ip6;
|
2018-02-21 03:24:05 +08:00
|
|
|
dev = ll_index_to_name(ifindex);
|
|
|
|
|
|
|
|
open_json_object(NULL);
|
|
|
|
|
2019-05-30 01:52:42 +08:00
|
|
|
print_int(PRINT_JSON, "index", NULL, ifindex);
|
|
|
|
print_color_string(PRINT_ANY, COLOR_IFNAME, "dev", "dev %s", dev);
|
|
|
|
print_string(PRINT_ANY, "port", " port %s",
|
2018-02-21 03:24:05 +08:00
|
|
|
ll_index_to_name(e->ifindex));
|
bridge: this patch adds json support for bridge mdb show
This patch adds json output to bridge mdb show
Normal Output:
$ bridge -d -s mdb show
dev br0 port swp3 grp 239.0.0.1 temp vid 128 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 64 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1024 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 256 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 1 172.26
router ports on br0: swp4 0.00 permanent
router ports on br0: swp5 0.00 permanent
Json Output:
$ bridge -d -s -j mdb show
{
"mdb": [{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 128,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 64,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1024,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 256,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 1,
"timer": " 166.74"
}
],
"router": {
"br0": [{
"port": "swp4",
"timer": " 0.00",
"type": "permanent"
},{
"port": "swp5",
"timer": " 0.00",
"type": "permanent"
}
]
}
}
Signed-off-by: Nikhil Gajendrakumar <nikhil@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
2017-07-08 06:24:16 +08:00
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
print_color_string(PRINT_ANY, ifa_family_color(af),
|
2019-05-30 01:52:42 +08:00
|
|
|
"grp", " grp %s",
|
2020-10-08 21:50:19 +08:00
|
|
|
inet_ntop(af, grp, abuf, sizeof(abuf)));
|
|
|
|
if (tb && tb[MDBA_MDB_EATTR_SOURCE]) {
|
|
|
|
src = (const void *)RTA_DATA(tb[MDBA_MDB_EATTR_SOURCE]);
|
|
|
|
print_color_string(PRINT_ANY, ifa_family_color(af),
|
|
|
|
"src", " src %s",
|
|
|
|
inet_ntop(af, src, abuf, sizeof(abuf)));
|
|
|
|
}
|
2019-05-30 01:52:42 +08:00
|
|
|
print_string(PRINT_ANY, "state", " %s",
|
2018-02-21 03:24:05 +08:00
|
|
|
(e->state & MDB_PERMANENT) ? "permanent" : "temp");
|
|
|
|
|
|
|
|
open_json_array(PRINT_JSON, "flags");
|
|
|
|
if (e->flags & MDB_FLAGS_OFFLOAD)
|
2019-05-30 01:52:42 +08:00
|
|
|
print_string(PRINT_ANY, NULL, " %s", "offload");
|
2020-10-08 21:50:20 +08:00
|
|
|
if (e->flags & MDB_FLAGS_FAST_LEAVE)
|
|
|
|
print_string(PRINT_ANY, NULL, " %s", "fast_leave");
|
2020-10-08 21:50:21 +08:00
|
|
|
if (e->flags & MDB_FLAGS_STAR_EXCL)
|
|
|
|
print_string(PRINT_ANY, NULL, " %s", "added_by_star_ex");
|
|
|
|
if (e->flags & MDB_FLAGS_BLOCKED)
|
|
|
|
print_string(PRINT_ANY, NULL, " %s", "blocked");
|
2018-02-21 03:24:05 +08:00
|
|
|
close_json_array(PRINT_JSON, NULL);
|
|
|
|
|
|
|
|
if (e->vid)
|
|
|
|
print_uint(PRINT_ANY, "vid", " vid %u", e->vid);
|
|
|
|
|
|
|
|
if (show_stats && tb && tb[MDBA_MDB_EATTR_TIMER]) {
|
|
|
|
__u32 timer = rta_getattr_u32(tb[MDBA_MDB_EATTR_TIMER]);
|
|
|
|
|
|
|
|
print_string(PRINT_ANY, "timer", " %s",
|
|
|
|
format_timer(timer));
|
2016-02-22 22:16:13 +08:00
|
|
|
}
|
2018-09-12 09:39:44 +08:00
|
|
|
|
|
|
|
print_nl();
|
2018-02-21 03:24:05 +08:00
|
|
|
close_json_object();
|
2012-12-12 08:46:22 +08:00
|
|
|
}
|
|
|
|
|
2015-07-30 17:30:32 +08:00
|
|
|
static void br_print_mdb_entry(FILE *f, int ifindex, struct rtattr *attr,
|
|
|
|
struct nlmsghdr *n)
|
2012-12-12 08:46:22 +08:00
|
|
|
{
|
2016-02-22 22:16:13 +08:00
|
|
|
struct rtattr *etb[MDBA_MDB_EATTR_MAX + 1];
|
|
|
|
struct br_mdb_entry *e;
|
2012-12-12 08:46:22 +08:00
|
|
|
struct rtattr *i;
|
|
|
|
int rem;
|
|
|
|
|
|
|
|
rem = RTA_PAYLOAD(attr);
|
|
|
|
for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
|
|
|
|
e = RTA_DATA(i);
|
2016-02-22 22:16:13 +08:00
|
|
|
parse_rtattr(etb, MDBA_MDB_EATTR_MAX, MDB_RTA(RTA_DATA(i)),
|
|
|
|
RTA_PAYLOAD(i) - RTA_ALIGN(sizeof(*e)));
|
|
|
|
print_mdb_entry(f, ifindex, e, n, etb);
|
2012-12-12 08:46:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
static void print_mdb_entries(FILE *fp, struct nlmsghdr *n,
|
|
|
|
int ifindex, struct rtattr *mdb)
|
|
|
|
{
|
|
|
|
int rem = RTA_PAYLOAD(mdb);
|
|
|
|
struct rtattr *i;
|
|
|
|
|
|
|
|
for (i = RTA_DATA(mdb); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
|
|
|
|
br_print_mdb_entry(fp, ifindex, i, n);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void print_router_entries(FILE *fp, struct nlmsghdr *n,
|
|
|
|
int ifindex, struct rtattr *router)
|
|
|
|
{
|
|
|
|
const char *brifname = ll_index_to_name(ifindex);
|
|
|
|
|
|
|
|
if (n->nlmsg_type == RTM_GETMDB) {
|
|
|
|
if (show_details)
|
|
|
|
br_print_router_ports(fp, router, brifname);
|
|
|
|
} else {
|
|
|
|
struct rtattr *i = RTA_DATA(router);
|
|
|
|
uint32_t *port_ifindex = RTA_DATA(i);
|
2018-09-06 21:14:46 +08:00
|
|
|
const char *port_name = ll_index_to_name(*port_ifindex);
|
2018-02-21 03:24:05 +08:00
|
|
|
|
|
|
|
if (is_json_context()) {
|
|
|
|
open_json_array(PRINT_JSON, brifname);
|
|
|
|
open_json_object(NULL);
|
|
|
|
|
|
|
|
print_string(PRINT_JSON, "port", NULL,
|
2018-09-06 21:14:46 +08:00
|
|
|
port_name);
|
2018-02-21 03:24:05 +08:00
|
|
|
close_json_object();
|
|
|
|
close_json_array(PRINT_JSON, NULL);
|
|
|
|
} else {
|
|
|
|
fprintf(fp, "router port dev %s master %s\n",
|
2018-09-06 21:14:46 +08:00
|
|
|
port_name, brifname);
|
2018-02-21 03:24:05 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
bridge: mdb: restore valid json output
Since the commit below mdb's json output has been invalid and also with
changed format. Restore it to a valid json like the previous format.
Also takes care of a double "Deleted" print when monitoring for changes.
Example bridge -p -d -j mdb show:
[ {
"mdb": [ {
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::1:fffb:1939",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::1:ffd0:f61f",
"state": "temp",
"flags": [ ]
} ],
"router": {
"virbr0": [ {
"port": "vnet1"
},{
"port": "vnet0"
} ],
"virbr1": [ {
"port": "vnet5"
} ]
}
} ]
Fixes: c7c1a1ef51ae ("bridge: colorize output and use JSON print library")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
2019-04-12 23:30:55 +08:00
|
|
|
static int __parse_mdb_nlmsg(struct nlmsghdr *n, struct rtattr **tb)
|
2012-12-12 08:46:22 +08:00
|
|
|
{
|
|
|
|
struct br_port_msg *r = NLMSG_DATA(n);
|
|
|
|
int len = n->nlmsg_len;
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
if (n->nlmsg_type != RTM_GETMDB &&
|
|
|
|
n->nlmsg_type != RTM_NEWMDB &&
|
|
|
|
n->nlmsg_type != RTM_DELMDB) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"Not RTM_GETMDB, RTM_NEWMDB or RTM_DELMDB: %08x %08x %08x\n",
|
2012-12-12 08:46:22 +08:00
|
|
|
n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
len -= NLMSG_LENGTH(sizeof(*r));
|
|
|
|
if (len < 0) {
|
|
|
|
fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filter_index && filter_index != r->ifindex)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
parse_rtattr(tb, MDBA_MAX, MDBA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
|
|
|
|
bridge: mdb: restore valid json output
Since the commit below mdb's json output has been invalid and also with
changed format. Restore it to a valid json like the previous format.
Also takes care of a double "Deleted" print when monitoring for changes.
Example bridge -p -d -j mdb show:
[ {
"mdb": [ {
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::1:fffb:1939",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::1:ffd0:f61f",
"state": "temp",
"flags": [ ]
} ],
"router": {
"virbr0": [ {
"port": "vnet1"
},{
"port": "vnet0"
} ],
"virbr1": [ {
"port": "vnet5"
} ]
}
} ]
Fixes: c7c1a1ef51ae ("bridge: colorize output and use JSON print library")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
2019-04-12 23:30:55 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int print_mdbs(struct nlmsghdr *n, void *arg)
|
|
|
|
{
|
|
|
|
struct br_port_msg *r = NLMSG_DATA(n);
|
|
|
|
struct rtattr *tb[MDBA_MAX+1];
|
|
|
|
FILE *fp = arg;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = __parse_mdb_nlmsg(n, tb);
|
|
|
|
if (ret != 1)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (tb[MDBA_MDB])
|
|
|
|
print_mdb_entries(fp, n, r->ifindex, tb[MDBA_MDB]);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int print_rtrs(struct nlmsghdr *n, void *arg)
|
|
|
|
{
|
|
|
|
struct br_port_msg *r = NLMSG_DATA(n);
|
|
|
|
struct rtattr *tb[MDBA_MAX+1];
|
|
|
|
FILE *fp = arg;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = __parse_mdb_nlmsg(n, tb);
|
|
|
|
if (ret != 1)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (tb[MDBA_ROUTER])
|
|
|
|
print_router_entries(fp, n, r->ifindex, tb[MDBA_ROUTER]);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int print_mdb_mon(struct nlmsghdr *n, void *arg)
|
|
|
|
{
|
|
|
|
struct br_port_msg *r = NLMSG_DATA(n);
|
|
|
|
struct rtattr *tb[MDBA_MAX+1];
|
|
|
|
FILE *fp = arg;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = __parse_mdb_nlmsg(n, tb);
|
|
|
|
if (ret != 1)
|
|
|
|
return ret;
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
if (n->nlmsg_type == RTM_DELMDB)
|
|
|
|
print_bool(PRINT_ANY, "deleted", "Deleted ", true);
|
2012-12-12 08:46:22 +08:00
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
if (tb[MDBA_MDB])
|
|
|
|
print_mdb_entries(fp, n, r->ifindex, tb[MDBA_MDB]);
|
2012-12-12 08:46:22 +08:00
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
if (tb[MDBA_ROUTER])
|
|
|
|
print_router_entries(fp, n, r->ifindex, tb[MDBA_ROUTER]);
|
2015-10-16 05:53:17 +08:00
|
|
|
|
2012-12-12 08:46:22 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mdb_show(int argc, char **argv)
|
|
|
|
{
|
|
|
|
char *filter_dev = NULL;
|
|
|
|
|
|
|
|
while (argc > 0) {
|
|
|
|
if (strcmp(*argv, "dev") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
if (filter_dev)
|
|
|
|
duparg("dev", *argv);
|
|
|
|
filter_dev = *argv;
|
2016-04-11 23:45:15 +08:00
|
|
|
} else if (strcmp(*argv, "vid") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
if (filter_vlan)
|
|
|
|
duparg("vid", *argv);
|
|
|
|
filter_vlan = atoi(*argv);
|
2012-12-12 08:46:22 +08:00
|
|
|
}
|
|
|
|
argc--; argv++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filter_dev) {
|
2018-01-20 00:44:03 +08:00
|
|
|
filter_index = ll_name_to_index(filter_dev);
|
2018-03-07 16:40:36 +08:00
|
|
|
if (!filter_index)
|
|
|
|
return nodev(filter_dev);
|
2012-12-12 08:46:22 +08:00
|
|
|
}
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
new_json_obj(json);
|
bridge: mdb: restore valid json output
Since the commit below mdb's json output has been invalid and also with
changed format. Restore it to a valid json like the previous format.
Also takes care of a double "Deleted" print when monitoring for changes.
Example bridge -p -d -j mdb show:
[ {
"mdb": [ {
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::1:fffb:1939",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::1:ffd0:f61f",
"state": "temp",
"flags": [ ]
} ],
"router": {
"virbr0": [ {
"port": "vnet1"
},{
"port": "vnet0"
} ],
"virbr1": [ {
"port": "vnet5"
} ]
}
} ]
Fixes: c7c1a1ef51ae ("bridge: colorize output and use JSON print library")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
2019-04-12 23:30:55 +08:00
|
|
|
open_json_object(NULL);
|
2018-02-21 03:24:05 +08:00
|
|
|
|
bridge: mdb: restore valid json output
Since the commit below mdb's json output has been invalid and also with
changed format. Restore it to a valid json like the previous format.
Also takes care of a double "Deleted" print when monitoring for changes.
Example bridge -p -d -j mdb show:
[ {
"mdb": [ {
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::1:fffb:1939",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::1:ffd0:f61f",
"state": "temp",
"flags": [ ]
} ],
"router": {
"virbr0": [ {
"port": "vnet1"
},{
"port": "vnet0"
} ],
"virbr1": [ {
"port": "vnet5"
} ]
}
} ]
Fixes: c7c1a1ef51ae ("bridge: colorize output and use JSON print library")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
2019-04-12 23:30:55 +08:00
|
|
|
/* get mdb entries */
|
2018-09-30 01:44:18 +08:00
|
|
|
if (rtnl_mdbdump_req(&rth, PF_BRIDGE) < 0) {
|
bridge: this patch adds json support for bridge mdb show
This patch adds json output to bridge mdb show
Normal Output:
$ bridge -d -s mdb show
dev br0 port swp3 grp 239.0.0.1 temp vid 128 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 64 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1024 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 256 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 1 172.26
router ports on br0: swp4 0.00 permanent
router ports on br0: swp5 0.00 permanent
Json Output:
$ bridge -d -s -j mdb show
{
"mdb": [{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 128,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 64,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1024,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 256,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 1,
"timer": " 166.74"
}
],
"router": {
"br0": [{
"port": "swp4",
"timer": " 0.00",
"type": "permanent"
},{
"port": "swp5",
"timer": " 0.00",
"type": "permanent"
}
]
}
}
Signed-off-by: Nikhil Gajendrakumar <nikhil@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
2017-07-08 06:24:16 +08:00
|
|
|
perror("Cannot send dump request");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: restore valid json output
Since the commit below mdb's json output has been invalid and also with
changed format. Restore it to a valid json like the previous format.
Also takes care of a double "Deleted" print when monitoring for changes.
Example bridge -p -d -j mdb show:
[ {
"mdb": [ {
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::1:fffb:1939",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::1:ffd0:f61f",
"state": "temp",
"flags": [ ]
} ],
"router": {
"virbr0": [ {
"port": "vnet1"
},{
"port": "vnet0"
} ],
"virbr1": [ {
"port": "vnet5"
} ]
}
} ]
Fixes: c7c1a1ef51ae ("bridge: colorize output and use JSON print library")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
2019-04-12 23:30:55 +08:00
|
|
|
open_json_array(PRINT_JSON, "mdb");
|
|
|
|
if (rtnl_dump_filter(&rth, print_mdbs, stdout) < 0) {
|
bridge: this patch adds json support for bridge mdb show
This patch adds json output to bridge mdb show
Normal Output:
$ bridge -d -s mdb show
dev br0 port swp3 grp 239.0.0.1 temp vid 128 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 64 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1024 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 256 172.26
dev br0 port swp2 grp 239.0.0.2 temp vid 1 172.26
dev br0 port swp3 grp 239.0.0.1 temp vid 1 172.26
router ports on br0: swp4 0.00 permanent
router ports on br0: swp5 0.00 permanent
Json Output:
$ bridge -d -s -j mdb show
{
"mdb": [{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 128,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 64,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1024,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 256,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp2",
"grp": "239.0.0.2",
"state": "temp",
"vid": 1,
"timer": " 166.74"
},{
"dev": "br0",
"port": "swp3",
"grp": "239.0.0.1",
"state": "temp",
"vid": 1,
"timer": " 166.74"
}
],
"router": {
"br0": [{
"port": "swp4",
"timer": " 0.00",
"type": "permanent"
},{
"port": "swp5",
"timer": " 0.00",
"type": "permanent"
}
]
}
}
Signed-off-by: Nikhil Gajendrakumar <nikhil@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
2017-07-08 06:24:16 +08:00
|
|
|
fprintf(stderr, "Dump terminated\n");
|
|
|
|
return -1;
|
|
|
|
}
|
bridge: mdb: restore valid json output
Since the commit below mdb's json output has been invalid and also with
changed format. Restore it to a valid json like the previous format.
Also takes care of a double "Deleted" print when monitoring for changes.
Example bridge -p -d -j mdb show:
[ {
"mdb": [ {
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::1:fffb:1939",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::1:ffd0:f61f",
"state": "temp",
"flags": [ ]
} ],
"router": {
"virbr0": [ {
"port": "vnet1"
},{
"port": "vnet0"
} ],
"virbr1": [ {
"port": "vnet5"
} ]
}
} ]
Fixes: c7c1a1ef51ae ("bridge: colorize output and use JSON print library")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
2019-04-12 23:30:55 +08:00
|
|
|
close_json_array(PRINT_JSON, NULL);
|
|
|
|
|
|
|
|
/* get router ports */
|
|
|
|
if (rtnl_mdbdump_req(&rth, PF_BRIDGE) < 0) {
|
|
|
|
perror("Cannot send dump request");
|
|
|
|
return -1;
|
|
|
|
}
|
2012-12-12 08:46:22 +08:00
|
|
|
|
bridge: mdb: restore valid json output
Since the commit below mdb's json output has been invalid and also with
changed format. Restore it to a valid json like the previous format.
Also takes care of a double "Deleted" print when monitoring for changes.
Example bridge -p -d -j mdb show:
[ {
"mdb": [ {
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 4,
"dev": "virbr0",
"port": "vnet2",
"grp": "ff02::1:fffb:1939",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::202",
"state": "temp",
"flags": [ ]
},{
"index": 6,
"dev": "virbr1",
"port": "vnet7",
"grp": "ff02::1:ffd0:f61f",
"state": "temp",
"flags": [ ]
} ],
"router": {
"virbr0": [ {
"port": "vnet1"
},{
"port": "vnet0"
} ],
"virbr1": [ {
"port": "vnet5"
} ]
}
} ]
Fixes: c7c1a1ef51ae ("bridge: colorize output and use JSON print library")
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
2019-04-12 23:30:55 +08:00
|
|
|
open_json_object("router");
|
|
|
|
if (rtnl_dump_filter(&rth, print_rtrs, stdout) < 0) {
|
|
|
|
fprintf(stderr, "Dump terminated\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
close_json_object();
|
|
|
|
|
|
|
|
close_json_object();
|
2018-02-21 03:24:05 +08:00
|
|
|
delete_json_obj();
|
|
|
|
fflush(stdout);
|
2012-12-12 08:46:22 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-12-12 06:23:09 +08:00
|
|
|
static int mdb_modify(int cmd, int flags, int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct {
|
2016-03-22 02:56:01 +08:00
|
|
|
struct nlmsghdr n;
|
2012-12-12 06:23:09 +08:00
|
|
|
struct br_port_msg bpm;
|
2016-03-22 02:56:01 +08:00
|
|
|
char buf[1024];
|
2016-07-18 22:48:42 +08:00
|
|
|
} req = {
|
|
|
|
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct br_port_msg)),
|
|
|
|
.n.nlmsg_flags = NLM_F_REQUEST | flags,
|
|
|
|
.n.nlmsg_type = cmd,
|
|
|
|
.bpm.family = PF_BRIDGE,
|
|
|
|
};
|
2020-10-08 21:50:19 +08:00
|
|
|
char *d = NULL, *p = NULL, *grp = NULL, *src = NULL;
|
2016-07-18 22:48:42 +08:00
|
|
|
struct br_mdb_entry entry = {};
|
2015-07-15 23:45:20 +08:00
|
|
|
short vid = 0;
|
2012-12-12 06:23:09 +08:00
|
|
|
|
|
|
|
while (argc > 0) {
|
|
|
|
if (strcmp(*argv, "dev") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
d = *argv;
|
|
|
|
} else if (strcmp(*argv, "grp") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
grp = *argv;
|
2012-12-21 02:54:19 +08:00
|
|
|
} else if (strcmp(*argv, "port") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
p = *argv;
|
|
|
|
} else if (strcmp(*argv, "permanent") == 0) {
|
|
|
|
if (cmd == RTM_NEWMDB)
|
|
|
|
entry.state |= MDB_PERMANENT;
|
|
|
|
} else if (strcmp(*argv, "temp") == 0) {
|
|
|
|
;/* nothing */
|
2015-07-15 23:45:20 +08:00
|
|
|
} else if (strcmp(*argv, "vid") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
vid = atoi(*argv);
|
2020-10-08 21:50:19 +08:00
|
|
|
} else if (strcmp(*argv, "src") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
src = *argv;
|
2012-12-12 06:23:09 +08:00
|
|
|
} else {
|
|
|
|
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");
|
2015-03-18 10:26:32 +08:00
|
|
|
return -1;
|
2012-12-12 06:23:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
req.bpm.ifindex = ll_name_to_index(d);
|
2018-03-07 16:40:36 +08:00
|
|
|
if (!req.bpm.ifindex)
|
|
|
|
return nodev(d);
|
2012-12-12 06:23:09 +08:00
|
|
|
|
|
|
|
entry.ifindex = ll_name_to_index(p);
|
2018-03-07 16:40:36 +08:00
|
|
|
if (!entry.ifindex)
|
|
|
|
return nodev(p);
|
2012-12-12 06:23:09 +08:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2015-07-15 23:45:20 +08:00
|
|
|
entry.vid = vid;
|
2012-12-12 06:23:09 +08:00
|
|
|
addattr_l(&req.n, sizeof(req), MDBA_SET_ENTRY, &entry, sizeof(entry));
|
2020-10-08 21:50:19 +08:00
|
|
|
if (src) {
|
|
|
|
struct rtattr *nest = addattr_nest(&req.n, sizeof(req),
|
|
|
|
MDBA_SET_ENTRY_ATTRS);
|
|
|
|
struct in6_addr src_ip6;
|
|
|
|
__be32 src_ip4;
|
|
|
|
|
|
|
|
nest->rta_type |= NLA_F_NESTED;
|
|
|
|
if (!inet_pton(AF_INET, src, &src_ip4)) {
|
|
|
|
if (!inet_pton(AF_INET6, src, &src_ip6)) {
|
|
|
|
fprintf(stderr, "Invalid source address \"%s\"\n", src);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
addattr_l(&req.n, sizeof(req), MDBE_ATTR_SOURCE, &src_ip6, sizeof(src_ip6));
|
|
|
|
} else {
|
|
|
|
addattr32(&req.n, sizeof(req), MDBE_ATTR_SOURCE, src_ip4);
|
|
|
|
}
|
|
|
|
addattr_nest_end(&req.n, nest);
|
|
|
|
}
|
2012-12-12 06:23:09 +08:00
|
|
|
|
lib/libnetlink: update rtnl_talk to support malloc buff at run time
This is an update for 460c03f3f3cc ("iplink: double the buffer size also in
iplink_get()"). After update, we will not need to double the buffer size
every time when VFs number increased.
With call like rtnl_talk(&rth, &req.n, NULL, 0), we can simply remove the
length parameter.
With call like rtnl_talk(&rth, nlh, nlh, sizeof(req), I add a new variable
answer to avoid overwrite data in nlh, because it may has more info after
nlh. also this will avoid nlh buffer not enough issue.
We need to free answer after using.
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2017-10-26 09:41:47 +08:00
|
|
|
if (rtnl_talk(&rth, &req.n, NULL) < 0)
|
2015-03-18 10:26:32 +08:00
|
|
|
return -1;
|
2012-12-12 06:23:09 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-12-12 08:46:22 +08:00
|
|
|
int do_mdb(int argc, char **argv)
|
|
|
|
{
|
|
|
|
ll_init_map(&rth);
|
|
|
|
|
|
|
|
if (argc > 0) {
|
2012-12-12 06:23:09 +08:00
|
|
|
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);
|
|
|
|
|
2012-12-12 08:46:22 +08:00
|
|
|
if (matches(*argv, "show") == 0 ||
|
|
|
|
matches(*argv, "lst") == 0 ||
|
|
|
|
matches(*argv, "list") == 0)
|
|
|
|
return mdb_show(argc-1, argv+1);
|
|
|
|
if (matches(*argv, "help") == 0)
|
|
|
|
usage();
|
|
|
|
} else
|
|
|
|
return mdb_show(0, NULL);
|
|
|
|
|
|
|
|
fprintf(stderr, "Command \"%s\" is unknown, try \"bridge mdb help\".\n", *argv);
|
|
|
|
exit(-1);
|
|
|
|
}
|