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>
|
bridge: mdb: Add UDP destination port support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the UDP destination port of VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST_PORT' and 'MDBA_MDB_EATTR_DST_PORT'
attributes in request and response messages, respectively.
Use the keyword "dst_port" instead of "port" as the latter is already
used to specify the net device associated with the MDB entry.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 dst_port 1234
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 dst_port 1234 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"dst_port": 1234,
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:23 +08:00
|
|
|
#include <netdb.h>
|
2023-07-21 04:37:26 +08:00
|
|
|
#include <limits.h>
|
2012-12-12 08:46:22 +08:00
|
|
|
|
|
|
|
#include "libnetlink.h"
|
2021-04-18 20:01:37 +08:00
|
|
|
#include "utils.h"
|
2012-12-12 08:46:22 +08:00
|
|
|
#include "br_common.h"
|
|
|
|
#include "rt_names.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,
|
2022-12-16 01:52:30 +08:00
|
|
|
"Usage: bridge mdb { add | del | replace } dev DEV port PORT grp GROUP [src SOURCE] [permanent | temp] [vid VID]\n"
|
bridge: mdb: Add underlay destination IP support
Allow user space to program and view VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST' and 'MDBA_MDB_EATTR_DST' attributes
in request and response messages, respectively.
The attributes encode the IP address of the destination VXLAN tunnel
endpoint where multicast receivers for the specified multicast flow
reside.
Multiple destinations can be added for each flow.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 192.0.2.1
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 192.0.2.1 0.00
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "192.0.2.1",
"timer": " 0.00"
},{
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:22 +08:00
|
|
|
" [ filter_mode { include | exclude } ] [ source_list SOURCE_LIST ] [ proto PROTO ] [ dst IPADDR ]\n"
|
bridge: mdb: Add outgoing interface support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the outgoing interface of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_IFINDEX' and 'MDBA_MDB_EATTR_IFINDEX'
attributes in request and response messages, respectively.
The outgoing interface will be forced during the underlay route lookup
and is required when the underlay destination IP is multicast, as the
multicast routing tables are not consulted.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 via dummy10
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 via dummy10 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 10,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"via": "dummy10",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:26 +08:00
|
|
|
" [ dst_port DST_PORT ] [ vni VNI ] [ src_vni SRC_VNI ] [ via DEV ]\n"
|
bridge: mdb: Add get support
Implement MDB get functionality, allowing user space to query a single
MDB entry from the kernel instead of dumping all the entries. Example
usage:
# bridge mdb add dev br0 port swp1 grp 239.1.1.1 vid 10
# bridge mdb add dev br0 port swp2 grp 239.1.1.1 vid 10
# bridge mdb add dev br0 port swp2 grp 239.1.1.5 vid 10
# bridge mdb get dev br0 grp 239.1.1.1 vid 10
dev br0 port swp1 grp 239.1.1.1 temp vid 10
dev br0 port swp2 grp 239.1.1.1 temp vid 10
# bridge -j -p mdb get dev br0 grp 239.1.1.1 vid 10
[ {
"index": 10,
"dev": "br0",
"port": "swp1",
"grp": "239.1.1.1",
"state": "temp",
"flags": [ ],
"vid": 10
},{
"index": 10,
"dev": "br0",
"port": "swp2",
"grp": "239.1.1.1",
"state": "temp",
"flags": [ ],
"vid": 10
} ]
# bridge mdb get dev br0 grp 239.1.1.1 vid 20
Error: bridge: MDB entry not found.
# bridge mdb get dev br0 grp 239.1.1.2 vid 10
Error: bridge: MDB entry not found.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: David Ahern <dsahern@kernel.org>
2023-11-01 15:45:10 +08:00
|
|
|
" bridge mdb {show} [ dev DEV ] [ vid VID ]\n"
|
2023-12-26 23:30:13 +08:00
|
|
|
" bridge mdb get dev DEV grp GROUP [ src SOURCE ] [ vid VID ] [ src_vni SRC_VNI ]\n"
|
|
|
|
" bridge mdb flush dev DEV [ port PORT ] [ vid VID ] [ src_vni SRC_VNI ] [ proto PROTO ]\n"
|
|
|
|
" [ [no]permanent ] [ dst IPADDR ] [ dst_port DST_PORT ] [ vni VNI ]\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;
|
|
|
|
}
|
|
|
|
|
2020-10-08 21:50:23 +08:00
|
|
|
static const char *format_timer(__u32 ticks, int align)
|
2018-02-21 03:24:05 +08:00
|
|
|
{
|
|
|
|
struct timeval tv;
|
|
|
|
static char tbuf[32];
|
|
|
|
|
|
|
|
__jiffies_to_tv(&tv, ticks);
|
2020-10-08 21:50:23 +08:00
|
|
|
if (align)
|
|
|
|
snprintf(tbuf, sizeof(tbuf), "%4lu.%.2lu",
|
|
|
|
(unsigned long)tv.tv_sec,
|
|
|
|
(unsigned long)tv.tv_usec / 10000);
|
|
|
|
else
|
|
|
|
snprintf(tbuf, sizeof(tbuf), "%lu.%.2lu",
|
|
|
|
(unsigned long)tv.tv_sec,
|
|
|
|
(unsigned long)tv.tv_usec / 10000);
|
2018-02-21 03:24:05 +08:00
|
|
|
|
|
|
|
return tbuf;
|
|
|
|
}
|
|
|
|
|
2021-08-28 19:08:05 +08:00
|
|
|
void br_print_router_port_stats(struct rtattr *pattr)
|
2016-03-14 18:04:46 +08:00
|
|
|
{
|
|
|
|
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",
|
2020-10-08 21:50:23 +08:00
|
|
|
format_timer(timer, 1));
|
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)
|
2021-08-28 19:08:05 +08:00
|
|
|
br_print_router_port_stats(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);
|
|
|
|
|
2021-08-28 19:08:05 +08:00
|
|
|
br_print_router_port_stats(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
|
|
|
}
|
|
|
|
|
2020-10-08 21:50:23 +08:00
|
|
|
static void print_src_entry(struct rtattr *src_attr, int af, const char *sep)
|
|
|
|
{
|
|
|
|
struct rtattr *stb[MDBA_MDB_SRCATTR_MAX + 1];
|
|
|
|
SPRINT_BUF(abuf);
|
|
|
|
const char *addr;
|
|
|
|
__u32 timer_val;
|
|
|
|
|
|
|
|
parse_rtattr_nested(stb, MDBA_MDB_SRCATTR_MAX, src_attr);
|
|
|
|
if (!stb[MDBA_MDB_SRCATTR_ADDRESS] || !stb[MDBA_MDB_SRCATTR_TIMER])
|
|
|
|
return;
|
|
|
|
|
|
|
|
addr = inet_ntop(af, RTA_DATA(stb[MDBA_MDB_SRCATTR_ADDRESS]), abuf,
|
|
|
|
sizeof(abuf));
|
|
|
|
if (!addr)
|
|
|
|
return;
|
|
|
|
timer_val = rta_getattr_u32(stb[MDBA_MDB_SRCATTR_TIMER]);
|
|
|
|
|
|
|
|
open_json_object(NULL);
|
|
|
|
print_string(PRINT_FP, NULL, "%s", sep);
|
|
|
|
print_color_string(PRINT_ANY, ifa_family_color(af),
|
|
|
|
"address", "%s", addr);
|
|
|
|
print_string(PRINT_ANY, "timer", "/%s", format_timer(timer_val, 0));
|
|
|
|
close_json_object();
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add underlay destination IP support
Allow user space to program and view VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST' and 'MDBA_MDB_EATTR_DST' attributes
in request and response messages, respectively.
The attributes encode the IP address of the destination VXLAN tunnel
endpoint where multicast receivers for the specified multicast flow
reside.
Multiple destinations can be added for each flow.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 192.0.2.1
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 192.0.2.1 0.00
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "192.0.2.1",
"timer": " 0.00"
},{
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:22 +08:00
|
|
|
static void print_dst(const struct rtattr *dst_attr)
|
|
|
|
{
|
|
|
|
SPRINT_BUF(abuf);
|
|
|
|
int af = AF_INET;
|
|
|
|
const void *dst;
|
|
|
|
|
|
|
|
if (RTA_PAYLOAD(dst_attr) == sizeof(struct in6_addr))
|
|
|
|
af = AF_INET6;
|
|
|
|
|
|
|
|
dst = (const void *)RTA_DATA(dst_attr);
|
|
|
|
print_color_string(PRINT_ANY, ifa_family_color(af),
|
|
|
|
"dst", " dst %s",
|
|
|
|
inet_ntop(af, dst, abuf, sizeof(abuf)));
|
|
|
|
}
|
|
|
|
|
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;
|
2020-11-25 22:36:39 +08:00
|
|
|
const char *addr;
|
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
|
|
|
|
2020-11-25 22:36:39 +08:00
|
|
|
if (!e->addr.proto) {
|
|
|
|
af = AF_PACKET;
|
|
|
|
grp = &e->addr.u.mac_addr;
|
|
|
|
} else if (e->addr.proto == htons(ETH_P_IP)) {
|
|
|
|
af = AF_INET;
|
|
|
|
grp = &e->addr.u.ip4;
|
|
|
|
} else {
|
|
|
|
af = AF_INET6;
|
|
|
|
grp = &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
|
|
|
|
2020-11-25 22:36:39 +08:00
|
|
|
/* The ETH_ALEN argument is ignored for all cases but AF_PACKET */
|
|
|
|
addr = rt_addr_n2a_r(af, ETH_ALEN, grp, abuf, sizeof(abuf));
|
|
|
|
if (!addr)
|
|
|
|
return;
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
print_color_string(PRINT_ANY, ifa_family_color(af),
|
2020-11-25 22:36:39 +08:00
|
|
|
"grp", " grp %s", addr);
|
|
|
|
|
2020-10-08 21:50:19 +08:00
|
|
|
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");
|
2020-10-08 21:50:23 +08:00
|
|
|
if (show_details && tb) {
|
|
|
|
if (tb[MDBA_MDB_EATTR_GROUP_MODE]) {
|
|
|
|
__u8 mode = rta_getattr_u8(tb[MDBA_MDB_EATTR_GROUP_MODE]);
|
2018-02-21 03:24:05 +08:00
|
|
|
|
2020-10-08 21:50:23 +08:00
|
|
|
print_string(PRINT_ANY, "filter_mode", " filter_mode %s",
|
|
|
|
mode == MCAST_INCLUDE ? "include" :
|
|
|
|
"exclude");
|
|
|
|
}
|
|
|
|
if (tb[MDBA_MDB_EATTR_SRC_LIST]) {
|
|
|
|
struct rtattr *i, *attr = tb[MDBA_MDB_EATTR_SRC_LIST];
|
|
|
|
const char *sep = " ";
|
|
|
|
int rem;
|
|
|
|
|
|
|
|
open_json_array(PRINT_ANY, is_json_context() ?
|
|
|
|
"source_list" :
|
|
|
|
" source_list");
|
|
|
|
rem = RTA_PAYLOAD(attr);
|
|
|
|
for (i = RTA_DATA(attr); RTA_OK(i, rem);
|
|
|
|
i = RTA_NEXT(i, rem)) {
|
|
|
|
print_src_entry(i, af, sep);
|
|
|
|
sep = ",";
|
|
|
|
}
|
|
|
|
close_json_array(PRINT_JSON, NULL);
|
|
|
|
}
|
2020-10-08 21:50:24 +08:00
|
|
|
if (tb[MDBA_MDB_EATTR_RTPROT]) {
|
|
|
|
__u8 rtprot = rta_getattr_u8(tb[MDBA_MDB_EATTR_RTPROT]);
|
|
|
|
SPRINT_BUF(rtb);
|
|
|
|
|
2023-02-06 22:21:52 +08:00
|
|
|
print_string(PRINT_ANY, "protocol", " proto %s",
|
2020-10-08 21:50:24 +08:00
|
|
|
rtnl_rtprot_n2a(rtprot, rtb, sizeof(rtb)));
|
|
|
|
}
|
2020-10-08 21:50:22 +08:00
|
|
|
}
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
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);
|
|
|
|
|
bridge: mdb: Add underlay destination IP support
Allow user space to program and view VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST' and 'MDBA_MDB_EATTR_DST' attributes
in request and response messages, respectively.
The attributes encode the IP address of the destination VXLAN tunnel
endpoint where multicast receivers for the specified multicast flow
reside.
Multiple destinations can be added for each flow.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 192.0.2.1
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 192.0.2.1 0.00
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "192.0.2.1",
"timer": " 0.00"
},{
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:22 +08:00
|
|
|
if (tb[MDBA_MDB_EATTR_DST])
|
|
|
|
print_dst(tb[MDBA_MDB_EATTR_DST]);
|
|
|
|
|
bridge: mdb: Add UDP destination port support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the UDP destination port of VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST_PORT' and 'MDBA_MDB_EATTR_DST_PORT'
attributes in request and response messages, respectively.
Use the keyword "dst_port" instead of "port" as the latter is already
used to specify the net device associated with the MDB entry.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 dst_port 1234
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 dst_port 1234 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"dst_port": 1234,
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:23 +08:00
|
|
|
if (tb[MDBA_MDB_EATTR_DST_PORT])
|
|
|
|
print_uint(PRINT_ANY, "dst_port", " dst_port %u",
|
|
|
|
rta_getattr_u16(tb[MDBA_MDB_EATTR_DST_PORT]));
|
|
|
|
|
bridge: mdb: Add destination VNI support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the destination VNI of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_VNI' and 'MDBA_MDB_EATTR_VNI' attributes in
request and response messages, respectively.
This is useful when ingress replication (IR) is used and the destination
VXLAN tunnel endpoint (VTEP) is not a member of the source broadcast
domain (BD). In this case, the ingress VTEP should transmit the packet
using the VNI of the Supplementary Broadcast Domain (SBD) in which all
the VTEPs are member of [1].
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 vni 1111
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 vni 1111 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"vni": 1111,
"timer": " 0.00"
} ],
"router": {}
} ]
[1] https://datatracker.ietf.org/doc/html/draft-ietf-bess-evpn-irb-mcast#section-3.2.2
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:24 +08:00
|
|
|
if (tb[MDBA_MDB_EATTR_VNI])
|
|
|
|
print_uint(PRINT_ANY, "vni", " vni %u",
|
|
|
|
rta_getattr_u32(tb[MDBA_MDB_EATTR_VNI]));
|
|
|
|
|
bridge: mdb: Add source VNI support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the source VNI of VXLAN MDB entries. Specifically, add support
for the 'MDBE_ATTR_SRC_VNI' and 'MDBA_MDB_EATTR_SRC_VNI' attributes in
request and response messages, respectively.
The source VNI is only relevant when the VXLAN device is in external
mode, where multiple VNIs can be multiplexed over a single VXLAN device.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 src_vni 2222
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 src_vni 2222 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 16,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"src_vni": 2222,
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:25 +08:00
|
|
|
if (tb[MDBA_MDB_EATTR_SRC_VNI])
|
|
|
|
print_uint(PRINT_ANY, "src_vni", " src_vni %u",
|
|
|
|
rta_getattr_u32(tb[MDBA_MDB_EATTR_SRC_VNI]));
|
|
|
|
|
bridge: mdb: Add outgoing interface support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the outgoing interface of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_IFINDEX' and 'MDBA_MDB_EATTR_IFINDEX'
attributes in request and response messages, respectively.
The outgoing interface will be forced during the underlay route lookup
and is required when the underlay destination IP is multicast, as the
multicast routing tables are not consulted.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 via dummy10
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 via dummy10 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 10,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"via": "dummy10",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:26 +08:00
|
|
|
if (tb[MDBA_MDB_EATTR_IFINDEX]) {
|
|
|
|
unsigned int ifindex;
|
|
|
|
|
|
|
|
ifindex = rta_getattr_u32(tb[MDBA_MDB_EATTR_IFINDEX]);
|
|
|
|
print_string(PRINT_ANY, "via", " via %s",
|
|
|
|
ll_index_to_name(ifindex));
|
|
|
|
}
|
|
|
|
|
2018-02-21 03:24:05 +08:00
|
|
|
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",
|
2020-10-08 21:50:23 +08:00
|
|
|
format_timer(timer, 1));
|
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);
|
2020-10-08 21:50:23 +08:00
|
|
|
parse_rtattr_flags(etb, MDBA_MDB_EATTR_MAX, MDB_RTA(RTA_DATA(i)),
|
|
|
|
RTA_PAYLOAD(i) - RTA_ALIGN(sizeof(*e)),
|
|
|
|
NLA_F_NESTED);
|
2016-02-22 22:16:13 +08:00
|
|
|
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;
|
|
|
|
|
2022-09-22 14:19:35 +08:00
|
|
|
print_headers(fp, "[MDB]");
|
|
|
|
|
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");
|
2023-05-11 08:37:26 +08:00
|
|
|
delete_json_obj();
|
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
|
|
|
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");
|
2023-05-11 08:37:26 +08:00
|
|
|
delete_json_obj();
|
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
|
|
|
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");
|
2023-05-11 08:37:26 +08:00
|
|
|
delete_json_obj();
|
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;
|
|
|
|
}
|
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");
|
2023-05-11 08:37:26 +08:00
|
|
|
delete_json_obj();
|
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;
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-11-25 22:36:39 +08:00
|
|
|
static int mdb_parse_grp(const char *grp, struct br_mdb_entry *e)
|
|
|
|
{
|
|
|
|
if (inet_pton(AF_INET, grp, &e->addr.u.ip4)) {
|
|
|
|
e->addr.proto = htons(ETH_P_IP);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (inet_pton(AF_INET6, grp, &e->addr.u.ip6)) {
|
|
|
|
e->addr.proto = htons(ETH_P_IPV6);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (ll_addr_a2n((char *)e->addr.u.mac_addr, sizeof(e->addr.u.mac_addr),
|
|
|
|
grp) == ETH_ALEN) {
|
|
|
|
e->addr.proto = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-12-16 01:52:26 +08:00
|
|
|
static int mdb_parse_src(struct nlmsghdr *n, int maxlen, const char *src)
|
|
|
|
{
|
|
|
|
struct in6_addr src_ip6;
|
|
|
|
__be32 src_ip4;
|
|
|
|
|
|
|
|
if (inet_pton(AF_INET, src, &src_ip4)) {
|
|
|
|
addattr32(n, maxlen, MDBE_ATTR_SOURCE, src_ip4);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (inet_pton(AF_INET6, src, &src_ip6)) {
|
|
|
|
addattr_l(n, maxlen, MDBE_ATTR_SOURCE, &src_ip6,
|
|
|
|
sizeof(src_ip6));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-12-16 01:52:27 +08:00
|
|
|
static int mdb_parse_mode(struct nlmsghdr *n, int maxlen, const char *mode)
|
|
|
|
{
|
|
|
|
if (strcmp(mode, "include") == 0) {
|
|
|
|
addattr8(n, maxlen, MDBE_ATTR_GROUP_MODE, MCAST_INCLUDE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(mode, "exclude") == 0) {
|
|
|
|
addattr8(n, maxlen, MDBE_ATTR_GROUP_MODE, MCAST_EXCLUDE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add source list support
Allow user space to specify the source list of (*, G) entries by adding
the 'MDBE_ATTR_SRC_LIST' attribute to the 'MDBA_SET_ENTRY_ATTRS' nest.
Example:
# bridge mdb add dev br0 port dummy10 grp 239.1.1.1 temp source_list 198.51.100.1,198.51.100.2 filter_mode exclude
# bridge -d -s mdb show
dev br0 port dummy10 grp 239.1.1.1 src 198.51.100.2 temp filter_mode include proto static blocked 0.00
dev br0 port dummy10 grp 239.1.1.1 src 198.51.100.1 temp filter_mode include proto static blocked 0.00
dev br0 port dummy10 grp 239.1.1.1 temp filter_mode exclude source_list 198.51.100.2/0.00,198.51.100.1/0.00 proto static 256.42
# bridge -j -p -d -s mdb show
[ {
"mdb": [ {
"index": 10,
"dev": "br0",
"port": "dummy10",
"grp": "239.1.1.1",
"src": "198.51.100.2",
"state": "temp",
"filter_mode": "include",
"protocol": "static",
"flags": [ "blocked" ],
"timer": " 0.00"
},{
"index": 10,
"dev": "br0",
"port": "dummy10",
"grp": "239.1.1.1",
"src": "198.51.100.1",
"state": "temp",
"filter_mode": "include",
"protocol": "static",
"flags": [ "blocked" ],
"timer": " 0.00"
},{
},{
"index": 10,
"dev": "br0",
"port": "dummy10",
"grp": "239.1.1.1",
"state": "temp",
"filter_mode": "exclude",
"source_list": [ {
"address": "198.51.100.2",
"timer": "0.00"
},{
"address": "198.51.100.1",
"timer": "0.00"
} ],
"protocol": "static",
"flags": [ ],
"timer": " 251.19"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: David Ahern <dsahern@kernel.org>
2022-12-16 01:52:28 +08:00
|
|
|
static int mdb_parse_src_entry(struct nlmsghdr *n, int maxlen, char *src_entry)
|
|
|
|
{
|
|
|
|
struct in6_addr src_ip6;
|
|
|
|
struct rtattr *nest;
|
|
|
|
__be32 src_ip4;
|
|
|
|
|
|
|
|
nest = addattr_nest(n, maxlen, MDBE_SRC_LIST_ENTRY | NLA_F_NESTED);
|
|
|
|
|
|
|
|
if (inet_pton(AF_INET, src_entry, &src_ip4))
|
|
|
|
addattr32(n, maxlen, MDBE_SRCATTR_ADDRESS, src_ip4);
|
|
|
|
else if (inet_pton(AF_INET6, src_entry, &src_ip6))
|
|
|
|
addattr_l(n, maxlen, MDBE_SRCATTR_ADDRESS, &src_ip6,
|
|
|
|
sizeof(src_ip6));
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
addattr_nest_end(n, nest);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mdb_parse_src_list(struct nlmsghdr *n, int maxlen, char *src_list)
|
|
|
|
{
|
|
|
|
struct rtattr *nest;
|
|
|
|
char *sep;
|
|
|
|
|
|
|
|
nest = addattr_nest(n, maxlen, MDBE_ATTR_SRC_LIST | NLA_F_NESTED);
|
|
|
|
|
|
|
|
do {
|
|
|
|
sep = strchr(src_list, ',');
|
|
|
|
if (sep)
|
|
|
|
*sep = '\0';
|
|
|
|
|
|
|
|
if (mdb_parse_src_entry(n, maxlen, src_list)) {
|
|
|
|
fprintf(stderr, "Invalid source entry \"%s\" in source list\n",
|
|
|
|
src_list);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
src_list = sep + 1;
|
|
|
|
} while (sep);
|
|
|
|
|
|
|
|
addattr_nest_end(n, nest);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-12-16 01:52:29 +08:00
|
|
|
static int mdb_parse_proto(struct nlmsghdr *n, int maxlen, const char *proto)
|
|
|
|
{
|
|
|
|
__u32 proto_id;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = rtnl_rtprot_a2n(&proto_id, proto);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
addattr8(n, maxlen, MDBE_ATTR_RTPROT, proto_id);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add underlay destination IP support
Allow user space to program and view VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST' and 'MDBA_MDB_EATTR_DST' attributes
in request and response messages, respectively.
The attributes encode the IP address of the destination VXLAN tunnel
endpoint where multicast receivers for the specified multicast flow
reside.
Multiple destinations can be added for each flow.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 192.0.2.1
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 192.0.2.1 0.00
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "192.0.2.1",
"timer": " 0.00"
},{
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:22 +08:00
|
|
|
static int mdb_parse_dst(struct nlmsghdr *n, int maxlen, const char *dst)
|
|
|
|
{
|
|
|
|
struct in6_addr dst_ip6;
|
|
|
|
__be32 dst_ip4;
|
|
|
|
|
|
|
|
if (inet_pton(AF_INET, dst, &dst_ip4)) {
|
|
|
|
addattr32(n, maxlen, MDBE_ATTR_DST, dst_ip4);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (inet_pton(AF_INET6, dst, &dst_ip6)) {
|
|
|
|
addattr_l(n, maxlen, MDBE_ATTR_DST, &dst_ip6,
|
|
|
|
sizeof(dst_ip6));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add UDP destination port support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the UDP destination port of VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST_PORT' and 'MDBA_MDB_EATTR_DST_PORT'
attributes in request and response messages, respectively.
Use the keyword "dst_port" instead of "port" as the latter is already
used to specify the net device associated with the MDB entry.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 dst_port 1234
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 dst_port 1234 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"dst_port": 1234,
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:23 +08:00
|
|
|
static int mdb_parse_dst_port(struct nlmsghdr *n, int maxlen,
|
|
|
|
const char *dst_port)
|
|
|
|
{
|
|
|
|
unsigned long port;
|
|
|
|
char *endptr;
|
|
|
|
|
|
|
|
port = strtoul(dst_port, &endptr, 0);
|
|
|
|
if (endptr && *endptr) {
|
|
|
|
struct servent *pse;
|
|
|
|
|
|
|
|
pse = getservbyname(dst_port, "udp");
|
|
|
|
if (!pse)
|
|
|
|
return -1;
|
|
|
|
port = ntohs(pse->s_port);
|
|
|
|
} else if (port > USHRT_MAX) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
addattr16(n, maxlen, MDBE_ATTR_DST_PORT, port);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add destination VNI support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the destination VNI of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_VNI' and 'MDBA_MDB_EATTR_VNI' attributes in
request and response messages, respectively.
This is useful when ingress replication (IR) is used and the destination
VXLAN tunnel endpoint (VTEP) is not a member of the source broadcast
domain (BD). In this case, the ingress VTEP should transmit the packet
using the VNI of the Supplementary Broadcast Domain (SBD) in which all
the VTEPs are member of [1].
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 vni 1111
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 vni 1111 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"vni": 1111,
"timer": " 0.00"
} ],
"router": {}
} ]
[1] https://datatracker.ietf.org/doc/html/draft-ietf-bess-evpn-irb-mcast#section-3.2.2
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:24 +08:00
|
|
|
static int mdb_parse_vni(struct nlmsghdr *n, int maxlen, const char *vni,
|
|
|
|
int attr_type)
|
|
|
|
{
|
|
|
|
unsigned long vni_num;
|
|
|
|
char *endptr;
|
|
|
|
|
|
|
|
vni_num = strtoul(vni, &endptr, 0);
|
|
|
|
if ((endptr && *endptr) || vni_num == ULONG_MAX)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
addattr32(n, maxlen, attr_type, vni_num);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add outgoing interface support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the outgoing interface of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_IFINDEX' and 'MDBA_MDB_EATTR_IFINDEX'
attributes in request and response messages, respectively.
The outgoing interface will be forced during the underlay route lookup
and is required when the underlay destination IP is multicast, as the
multicast routing tables are not consulted.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 via dummy10
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 via dummy10 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 10,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"via": "dummy10",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:26 +08:00
|
|
|
static int mdb_parse_dev(struct nlmsghdr *n, int maxlen, const char *dev)
|
|
|
|
{
|
|
|
|
unsigned int ifindex;
|
|
|
|
|
|
|
|
ifindex = ll_name_to_index(dev);
|
|
|
|
if (!ifindex)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
addattr32(n, maxlen, MDBE_ATTR_IFINDEX, ifindex);
|
|
|
|
|
|
|
|
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,
|
|
|
|
};
|
2022-12-16 01:52:27 +08:00
|
|
|
char *d = NULL, *p = NULL, *grp = NULL, *src = NULL, *mode = NULL;
|
bridge: mdb: Add outgoing interface support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the outgoing interface of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_IFINDEX' and 'MDBA_MDB_EATTR_IFINDEX'
attributes in request and response messages, respectively.
The outgoing interface will be forced during the underlay route lookup
and is required when the underlay destination IP is multicast, as the
multicast routing tables are not consulted.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 via dummy10
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 via dummy10 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 10,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"via": "dummy10",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:26 +08:00
|
|
|
char *dst_port = NULL, *vni = NULL, *src_vni = NULL, *via = NULL;
|
bridge: mdb: Add underlay destination IP support
Allow user space to program and view VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST' and 'MDBA_MDB_EATTR_DST' attributes
in request and response messages, respectively.
The attributes encode the IP address of the destination VXLAN tunnel
endpoint where multicast receivers for the specified multicast flow
reside.
Multiple destinations can be added for each flow.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 192.0.2.1
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 192.0.2.1 0.00
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "192.0.2.1",
"timer": " 0.00"
},{
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:22 +08:00
|
|
|
char *src_list = NULL, *proto = NULL, *dst = NULL;
|
2016-07-18 22:48:42 +08:00
|
|
|
struct br_mdb_entry entry = {};
|
2022-12-16 01:52:25 +08:00
|
|
|
bool set_attrs = false;
|
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;
|
2022-12-16 01:52:25 +08:00
|
|
|
set_attrs = true;
|
2022-12-16 01:52:27 +08:00
|
|
|
} else if (strcmp(*argv, "filter_mode") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
mode = *argv;
|
|
|
|
set_attrs = true;
|
bridge: mdb: Add source list support
Allow user space to specify the source list of (*, G) entries by adding
the 'MDBE_ATTR_SRC_LIST' attribute to the 'MDBA_SET_ENTRY_ATTRS' nest.
Example:
# bridge mdb add dev br0 port dummy10 grp 239.1.1.1 temp source_list 198.51.100.1,198.51.100.2 filter_mode exclude
# bridge -d -s mdb show
dev br0 port dummy10 grp 239.1.1.1 src 198.51.100.2 temp filter_mode include proto static blocked 0.00
dev br0 port dummy10 grp 239.1.1.1 src 198.51.100.1 temp filter_mode include proto static blocked 0.00
dev br0 port dummy10 grp 239.1.1.1 temp filter_mode exclude source_list 198.51.100.2/0.00,198.51.100.1/0.00 proto static 256.42
# bridge -j -p -d -s mdb show
[ {
"mdb": [ {
"index": 10,
"dev": "br0",
"port": "dummy10",
"grp": "239.1.1.1",
"src": "198.51.100.2",
"state": "temp",
"filter_mode": "include",
"protocol": "static",
"flags": [ "blocked" ],
"timer": " 0.00"
},{
"index": 10,
"dev": "br0",
"port": "dummy10",
"grp": "239.1.1.1",
"src": "198.51.100.1",
"state": "temp",
"filter_mode": "include",
"protocol": "static",
"flags": [ "blocked" ],
"timer": " 0.00"
},{
},{
"index": 10,
"dev": "br0",
"port": "dummy10",
"grp": "239.1.1.1",
"state": "temp",
"filter_mode": "exclude",
"source_list": [ {
"address": "198.51.100.2",
"timer": "0.00"
},{
"address": "198.51.100.1",
"timer": "0.00"
} ],
"protocol": "static",
"flags": [ ],
"timer": " 251.19"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: David Ahern <dsahern@kernel.org>
2022-12-16 01:52:28 +08:00
|
|
|
} else if (strcmp(*argv, "source_list") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
src_list = *argv;
|
|
|
|
set_attrs = true;
|
2022-12-16 01:52:29 +08:00
|
|
|
} else if (strcmp(*argv, "proto") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
proto = *argv;
|
|
|
|
set_attrs = true;
|
bridge: mdb: Add underlay destination IP support
Allow user space to program and view VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST' and 'MDBA_MDB_EATTR_DST' attributes
in request and response messages, respectively.
The attributes encode the IP address of the destination VXLAN tunnel
endpoint where multicast receivers for the specified multicast flow
reside.
Multiple destinations can be added for each flow.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 192.0.2.1
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 192.0.2.1 0.00
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "192.0.2.1",
"timer": " 0.00"
},{
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:22 +08:00
|
|
|
} else if (strcmp(*argv, "dst") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
dst = *argv;
|
|
|
|
set_attrs = true;
|
bridge: mdb: Add UDP destination port support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the UDP destination port of VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST_PORT' and 'MDBA_MDB_EATTR_DST_PORT'
attributes in request and response messages, respectively.
Use the keyword "dst_port" instead of "port" as the latter is already
used to specify the net device associated with the MDB entry.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 dst_port 1234
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 dst_port 1234 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"dst_port": 1234,
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:23 +08:00
|
|
|
} else if (strcmp(*argv, "dst_port") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
dst_port = *argv;
|
|
|
|
set_attrs = true;
|
bridge: mdb: Add destination VNI support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the destination VNI of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_VNI' and 'MDBA_MDB_EATTR_VNI' attributes in
request and response messages, respectively.
This is useful when ingress replication (IR) is used and the destination
VXLAN tunnel endpoint (VTEP) is not a member of the source broadcast
domain (BD). In this case, the ingress VTEP should transmit the packet
using the VNI of the Supplementary Broadcast Domain (SBD) in which all
the VTEPs are member of [1].
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 vni 1111
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 vni 1111 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"vni": 1111,
"timer": " 0.00"
} ],
"router": {}
} ]
[1] https://datatracker.ietf.org/doc/html/draft-ietf-bess-evpn-irb-mcast#section-3.2.2
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:24 +08:00
|
|
|
} else if (strcmp(*argv, "vni") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
vni = *argv;
|
|
|
|
set_attrs = true;
|
bridge: mdb: Add source VNI support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the source VNI of VXLAN MDB entries. Specifically, add support
for the 'MDBE_ATTR_SRC_VNI' and 'MDBA_MDB_EATTR_SRC_VNI' attributes in
request and response messages, respectively.
The source VNI is only relevant when the VXLAN device is in external
mode, where multiple VNIs can be multiplexed over a single VXLAN device.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 src_vni 2222
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 src_vni 2222 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 16,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"src_vni": 2222,
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:25 +08:00
|
|
|
} else if (strcmp(*argv, "src_vni") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
src_vni = *argv;
|
|
|
|
set_attrs = true;
|
bridge: mdb: Add outgoing interface support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the outgoing interface of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_IFINDEX' and 'MDBA_MDB_EATTR_IFINDEX'
attributes in request and response messages, respectively.
The outgoing interface will be forced during the underlay route lookup
and is required when the underlay destination IP is multicast, as the
multicast routing tables are not consulted.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 via dummy10
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 via dummy10 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 10,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"via": "dummy10",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:26 +08:00
|
|
|
} else if (strcmp(*argv, "via") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
via = *argv;
|
|
|
|
set_attrs = true;
|
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
|
|
|
|
2020-11-25 22:36:39 +08:00
|
|
|
if (mdb_parse_grp(grp, &entry)) {
|
|
|
|
fprintf(stderr, "Invalid address \"%s\"\n", grp);
|
|
|
|
return -1;
|
|
|
|
}
|
2012-12-12 06:23:09 +08:00
|
|
|
|
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));
|
2022-12-16 01:52:25 +08:00
|
|
|
if (set_attrs) {
|
2020-10-08 21:50:19 +08:00
|
|
|
struct rtattr *nest = addattr_nest(&req.n, sizeof(req),
|
|
|
|
MDBA_SET_ENTRY_ATTRS);
|
|
|
|
|
|
|
|
nest->rta_type |= NLA_F_NESTED;
|
2022-12-16 01:52:26 +08:00
|
|
|
|
|
|
|
if (src && mdb_parse_src(&req.n, sizeof(req), src)) {
|
|
|
|
fprintf(stderr, "Invalid source address \"%s\"\n", src);
|
|
|
|
return -1;
|
2020-10-08 21:50:19 +08:00
|
|
|
}
|
2022-12-16 01:52:26 +08:00
|
|
|
|
2022-12-16 01:52:27 +08:00
|
|
|
if (mode && mdb_parse_mode(&req.n, sizeof(req), mode)) {
|
|
|
|
fprintf(stderr, "Invalid filter mode \"%s\"\n", mode);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add source list support
Allow user space to specify the source list of (*, G) entries by adding
the 'MDBE_ATTR_SRC_LIST' attribute to the 'MDBA_SET_ENTRY_ATTRS' nest.
Example:
# bridge mdb add dev br0 port dummy10 grp 239.1.1.1 temp source_list 198.51.100.1,198.51.100.2 filter_mode exclude
# bridge -d -s mdb show
dev br0 port dummy10 grp 239.1.1.1 src 198.51.100.2 temp filter_mode include proto static blocked 0.00
dev br0 port dummy10 grp 239.1.1.1 src 198.51.100.1 temp filter_mode include proto static blocked 0.00
dev br0 port dummy10 grp 239.1.1.1 temp filter_mode exclude source_list 198.51.100.2/0.00,198.51.100.1/0.00 proto static 256.42
# bridge -j -p -d -s mdb show
[ {
"mdb": [ {
"index": 10,
"dev": "br0",
"port": "dummy10",
"grp": "239.1.1.1",
"src": "198.51.100.2",
"state": "temp",
"filter_mode": "include",
"protocol": "static",
"flags": [ "blocked" ],
"timer": " 0.00"
},{
"index": 10,
"dev": "br0",
"port": "dummy10",
"grp": "239.1.1.1",
"src": "198.51.100.1",
"state": "temp",
"filter_mode": "include",
"protocol": "static",
"flags": [ "blocked" ],
"timer": " 0.00"
},{
},{
"index": 10,
"dev": "br0",
"port": "dummy10",
"grp": "239.1.1.1",
"state": "temp",
"filter_mode": "exclude",
"source_list": [ {
"address": "198.51.100.2",
"timer": "0.00"
},{
"address": "198.51.100.1",
"timer": "0.00"
} ],
"protocol": "static",
"flags": [ ],
"timer": " 251.19"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: David Ahern <dsahern@kernel.org>
2022-12-16 01:52:28 +08:00
|
|
|
if (src_list && mdb_parse_src_list(&req.n, sizeof(req),
|
|
|
|
src_list))
|
|
|
|
return -1;
|
|
|
|
|
2022-12-16 01:52:29 +08:00
|
|
|
if (proto && mdb_parse_proto(&req.n, sizeof(req), proto)) {
|
|
|
|
fprintf(stderr, "Invalid protocol value \"%s\"\n",
|
|
|
|
proto);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add underlay destination IP support
Allow user space to program and view VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST' and 'MDBA_MDB_EATTR_DST' attributes
in request and response messages, respectively.
The attributes encode the IP address of the destination VXLAN tunnel
endpoint where multicast receivers for the specified multicast flow
reside.
Multiple destinations can be added for each flow.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 192.0.2.1
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 192.0.2.1 0.00
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "192.0.2.1",
"timer": " 0.00"
},{
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:22 +08:00
|
|
|
if (dst && mdb_parse_dst(&req.n, sizeof(req), dst)) {
|
|
|
|
fprintf(stderr, "Invalid underlay destination address \"%s\"\n",
|
|
|
|
dst);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add UDP destination port support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the UDP destination port of VXLAN MDB entries. Specifically,
add support for the 'MDBE_ATTR_DST_PORT' and 'MDBA_MDB_EATTR_DST_PORT'
attributes in request and response messages, respectively.
Use the keyword "dst_port" instead of "port" as the latter is already
used to specify the net device associated with the MDB entry.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 dst_port 1234
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 dst_port 1234 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"dst_port": 1234,
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:23 +08:00
|
|
|
if (dst_port && mdb_parse_dst_port(&req.n, sizeof(req),
|
|
|
|
dst_port)) {
|
|
|
|
fprintf(stderr, "Invalid destination port \"%s\"\n", dst_port);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add destination VNI support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the destination VNI of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_VNI' and 'MDBA_MDB_EATTR_VNI' attributes in
request and response messages, respectively.
This is useful when ingress replication (IR) is used and the destination
VXLAN tunnel endpoint (VTEP) is not a member of the source broadcast
domain (BD). In this case, the ingress VTEP should transmit the packet
using the VNI of the Supplementary Broadcast Domain (SBD) in which all
the VTEPs are member of [1].
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 vni 1111
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 vni 1111 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 15,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"vni": 1111,
"timer": " 0.00"
} ],
"router": {}
} ]
[1] https://datatracker.ietf.org/doc/html/draft-ietf-bess-evpn-irb-mcast#section-3.2.2
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:24 +08:00
|
|
|
if (vni && mdb_parse_vni(&req.n, sizeof(req), vni,
|
|
|
|
MDBE_ATTR_VNI)) {
|
|
|
|
fprintf(stderr, "Invalid destination VNI \"%s\"\n",
|
|
|
|
vni);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add source VNI support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the source VNI of VXLAN MDB entries. Specifically, add support
for the 'MDBE_ATTR_SRC_VNI' and 'MDBA_MDB_EATTR_SRC_VNI' attributes in
request and response messages, respectively.
The source VNI is only relevant when the VXLAN device is in external
mode, where multiple VNIs can be multiplexed over a single VXLAN device.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 src_vni 2222
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 src_vni 2222 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 16,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"src_vni": 2222,
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:25 +08:00
|
|
|
if (src_vni && mdb_parse_vni(&req.n, sizeof(req), src_vni,
|
|
|
|
MDBE_ATTR_SRC_VNI)) {
|
|
|
|
fprintf(stderr, "Invalid source VNI \"%s\"\n", src_vni);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add outgoing interface support
In a similar fashion to VXLAN FDB entries, allow user space to program
and view the outgoing interface of VXLAN MDB entries. Specifically, add
support for the 'MDBE_ATTR_IFINDEX' and 'MDBA_MDB_EATTR_IFINDEX'
attributes in request and response messages, respectively.
The outgoing interface will be forced during the underlay route lookup
and is required when the underlay destination IP is multicast, as the
multicast routing tables are not consulted.
Example:
# bridge mdb add dev vxlan0 port vxlan0 grp 239.1.1.1 permanent dst 198.51.100.1 via dummy10
$ bridge -d -s mdb show
dev vxlan0 port vxlan0 grp 239.1.1.1 permanent filter_mode exclude proto static dst 198.51.100.1 via dummy10 0.00
$ bridge -d -s -j -p mdb show
[ {
"mdb": [ {
"index": 10,
"dev": "vxlan0",
"port": "vxlan0",
"grp": "239.1.1.1",
"state": "permanent",
"filter_mode": "exclude",
"protocol": "static",
"flags": [ ],
"dst": "198.51.100.1",
"via": "dummy10",
"timer": " 0.00"
} ],
"router": {}
} ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
2023-03-21 21:01:26 +08:00
|
|
|
if (via && mdb_parse_dev(&req.n, sizeof(req), via))
|
|
|
|
return nodev(via);
|
|
|
|
|
2020-10-08 21:50:19 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
bridge: mdb: Add get support
Implement MDB get functionality, allowing user space to query a single
MDB entry from the kernel instead of dumping all the entries. Example
usage:
# bridge mdb add dev br0 port swp1 grp 239.1.1.1 vid 10
# bridge mdb add dev br0 port swp2 grp 239.1.1.1 vid 10
# bridge mdb add dev br0 port swp2 grp 239.1.1.5 vid 10
# bridge mdb get dev br0 grp 239.1.1.1 vid 10
dev br0 port swp1 grp 239.1.1.1 temp vid 10
dev br0 port swp2 grp 239.1.1.1 temp vid 10
# bridge -j -p mdb get dev br0 grp 239.1.1.1 vid 10
[ {
"index": 10,
"dev": "br0",
"port": "swp1",
"grp": "239.1.1.1",
"state": "temp",
"flags": [ ],
"vid": 10
},{
"index": 10,
"dev": "br0",
"port": "swp2",
"grp": "239.1.1.1",
"state": "temp",
"flags": [ ],
"vid": 10
} ]
# bridge mdb get dev br0 grp 239.1.1.1 vid 20
Error: bridge: MDB entry not found.
# bridge mdb get dev br0 grp 239.1.1.2 vid 10
Error: bridge: MDB entry not found.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: David Ahern <dsahern@kernel.org>
2023-11-01 15:45:10 +08:00
|
|
|
static int mdb_get(int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct {
|
|
|
|
struct nlmsghdr n;
|
|
|
|
struct br_port_msg bpm;
|
|
|
|
char buf[1024];
|
|
|
|
} req = {
|
|
|
|
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct br_port_msg)),
|
|
|
|
.n.nlmsg_flags = NLM_F_REQUEST,
|
|
|
|
.n.nlmsg_type = RTM_GETMDB,
|
|
|
|
.bpm.family = PF_BRIDGE,
|
|
|
|
};
|
|
|
|
char *d = NULL, *grp = NULL, *src = NULL, *src_vni = NULL;
|
|
|
|
struct br_mdb_entry entry = {};
|
|
|
|
struct nlmsghdr *answer;
|
|
|
|
bool get_attrs = false;
|
|
|
|
short vid = 0;
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
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, "vid") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
vid = atoi(*argv);
|
|
|
|
} else if (strcmp(*argv, "src") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
src = *argv;
|
|
|
|
get_attrs = true;
|
|
|
|
} else if (strcmp(*argv, "src_vni") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
src_vni = *argv;
|
|
|
|
get_attrs = true;
|
|
|
|
} else {
|
|
|
|
if (strcmp(*argv, "help") == 0)
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
argc--; argv++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d == NULL || grp == NULL) {
|
|
|
|
fprintf(stderr, "Device and group address are required arguments.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
req.bpm.ifindex = ll_name_to_index(d);
|
|
|
|
if (!req.bpm.ifindex)
|
|
|
|
return nodev(d);
|
|
|
|
|
|
|
|
if (mdb_parse_grp(grp, &entry)) {
|
|
|
|
fprintf(stderr, "Invalid address \"%s\"\n", grp);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
entry.vid = vid;
|
|
|
|
addattr_l(&req.n, sizeof(req), MDBA_GET_ENTRY, &entry, sizeof(entry));
|
|
|
|
if (get_attrs) {
|
|
|
|
struct rtattr *nest = addattr_nest(&req.n, sizeof(req),
|
|
|
|
MDBA_GET_ENTRY_ATTRS);
|
|
|
|
|
|
|
|
nest->rta_type |= NLA_F_NESTED;
|
|
|
|
|
|
|
|
if (src && mdb_parse_src(&req.n, sizeof(req), src)) {
|
|
|
|
fprintf(stderr, "Invalid source address \"%s\"\n", src);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src_vni && mdb_parse_vni(&req.n, sizeof(req), src_vni,
|
|
|
|
MDBE_ATTR_SRC_VNI)) {
|
|
|
|
fprintf(stderr, "Invalid source VNI \"%s\"\n", src_vni);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
addattr_nest_end(&req.n, nest);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rtnl_talk(&rth, &req.n, &answer) < 0)
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
new_json_obj(json);
|
|
|
|
|
|
|
|
if (print_mdbs(answer, stdout) < 0)
|
|
|
|
ret = -1;
|
|
|
|
|
|
|
|
delete_json_obj();
|
|
|
|
free(answer);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2023-12-26 23:30:13 +08:00
|
|
|
static int mdb_flush(int argc, char **argv)
|
|
|
|
{
|
|
|
|
struct {
|
|
|
|
struct nlmsghdr n;
|
|
|
|
struct br_port_msg bpm;
|
|
|
|
char buf[1024];
|
|
|
|
} req = {
|
|
|
|
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct br_port_msg)),
|
|
|
|
.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_BULK,
|
|
|
|
.n.nlmsg_type = RTM_DELMDB,
|
|
|
|
.bpm.family = PF_BRIDGE,
|
|
|
|
};
|
|
|
|
char *d = NULL, *p = NULL, *src_vni = NULL, *proto = NULL, *dst = NULL;
|
|
|
|
char *dst_port = NULL, *vni = NULL;
|
|
|
|
struct br_mdb_entry entry = {};
|
|
|
|
unsigned short state_mask = 0;
|
|
|
|
bool set_attrs = false;
|
|
|
|
short vid = 0;
|
|
|
|
|
|
|
|
while (argc > 0) {
|
|
|
|
if (strcmp(*argv, "dev") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
d = *argv;
|
|
|
|
} else if (strcmp(*argv, "port") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
p = *argv;
|
|
|
|
} else if (strcmp(*argv, "vid") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
vid = atoi(*argv);
|
|
|
|
} else if (strcmp(*argv, "src_vni") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
src_vni = *argv;
|
|
|
|
set_attrs = true;
|
|
|
|
} else if (strcmp(*argv, "proto") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
proto = *argv;
|
|
|
|
set_attrs = true;
|
|
|
|
} else if (strcmp(*argv, "permanent") == 0) {
|
|
|
|
entry.state |= MDB_PERMANENT;
|
|
|
|
state_mask |= MDB_PERMANENT;
|
|
|
|
set_attrs = true;
|
|
|
|
} else if (strcmp(*argv, "nopermanent") == 0) {
|
|
|
|
entry.state &= ~MDB_PERMANENT;
|
|
|
|
state_mask |= MDB_PERMANENT;
|
|
|
|
set_attrs = true;
|
|
|
|
} else if (strcmp(*argv, "dst") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
dst = *argv;
|
|
|
|
set_attrs = true;
|
|
|
|
} else if (strcmp(*argv, "dst_port") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
dst_port = *argv;
|
|
|
|
set_attrs = true;
|
|
|
|
} else if (strcmp(*argv, "vni") == 0) {
|
|
|
|
NEXT_ARG();
|
|
|
|
vni = *argv;
|
|
|
|
set_attrs = true;
|
|
|
|
} else {
|
|
|
|
if (strcmp(*argv, "help") == 0)
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
argc--; argv++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d == NULL) {
|
|
|
|
fprintf(stderr, "Device is a required argument.\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
req.bpm.ifindex = ll_name_to_index(d);
|
|
|
|
if (!req.bpm.ifindex)
|
|
|
|
return nodev(d);
|
|
|
|
|
|
|
|
if (p) {
|
|
|
|
entry.ifindex = ll_name_to_index(p);
|
|
|
|
if (!entry.ifindex)
|
|
|
|
return nodev(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
entry.vid = vid;
|
|
|
|
addattr_l(&req.n, sizeof(req), MDBA_SET_ENTRY, &entry, sizeof(entry));
|
|
|
|
if (set_attrs) {
|
|
|
|
struct rtattr *nest = addattr_nest(&req.n, sizeof(req),
|
|
|
|
MDBA_SET_ENTRY_ATTRS);
|
|
|
|
|
|
|
|
nest->rta_type |= NLA_F_NESTED;
|
|
|
|
|
|
|
|
if (proto && mdb_parse_proto(&req.n, sizeof(req), proto)) {
|
|
|
|
fprintf(stderr, "Invalid protocol value \"%s\"\n",
|
|
|
|
proto);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dst && mdb_parse_dst(&req.n, sizeof(req), dst)) {
|
|
|
|
fprintf(stderr, "Invalid underlay destination address \"%s\"\n",
|
|
|
|
dst);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dst_port && mdb_parse_dst_port(&req.n, sizeof(req),
|
|
|
|
dst_port)) {
|
|
|
|
fprintf(stderr, "Invalid destination port \"%s\"\n", dst_port);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vni && mdb_parse_vni(&req.n, sizeof(req), vni,
|
|
|
|
MDBE_ATTR_VNI)) {
|
|
|
|
fprintf(stderr, "Invalid destination VNI \"%s\"\n",
|
|
|
|
vni);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src_vni && mdb_parse_vni(&req.n, sizeof(req), src_vni,
|
|
|
|
MDBE_ATTR_SRC_VNI)) {
|
|
|
|
fprintf(stderr, "Invalid source VNI \"%s\"\n", src_vni);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state_mask)
|
|
|
|
addattr8(&req.n, sizeof(req), MDBE_ATTR_STATE_MASK,
|
|
|
|
state_mask);
|
|
|
|
|
|
|
|
addattr_nest_end(&req.n, nest);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rtnl_talk(&rth, &req.n, NULL) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-12-12 08:46:22 +08:00
|
|
|
int do_mdb(int argc, char **argv)
|
|
|
|
{
|
|
|
|
ll_init_map(&rth);
|
2022-09-22 14:19:35 +08:00
|
|
|
timestamp = 0;
|
2012-12-12 08:46:22 +08:00
|
|
|
|
|
|
|
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);
|
2022-12-16 01:52:30 +08:00
|
|
|
if (strcmp(*argv, "replace") == 0)
|
|
|
|
return mdb_modify(RTM_NEWMDB, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1);
|
2012-12-12 06:23:09 +08:00
|
|
|
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);
|
bridge: mdb: Add get support
Implement MDB get functionality, allowing user space to query a single
MDB entry from the kernel instead of dumping all the entries. Example
usage:
# bridge mdb add dev br0 port swp1 grp 239.1.1.1 vid 10
# bridge mdb add dev br0 port swp2 grp 239.1.1.1 vid 10
# bridge mdb add dev br0 port swp2 grp 239.1.1.5 vid 10
# bridge mdb get dev br0 grp 239.1.1.1 vid 10
dev br0 port swp1 grp 239.1.1.1 temp vid 10
dev br0 port swp2 grp 239.1.1.1 temp vid 10
# bridge -j -p mdb get dev br0 grp 239.1.1.1 vid 10
[ {
"index": 10,
"dev": "br0",
"port": "swp1",
"grp": "239.1.1.1",
"state": "temp",
"flags": [ ],
"vid": 10
},{
"index": 10,
"dev": "br0",
"port": "swp2",
"grp": "239.1.1.1",
"state": "temp",
"flags": [ ],
"vid": 10
} ]
# bridge mdb get dev br0 grp 239.1.1.1 vid 20
Error: bridge: MDB entry not found.
# bridge mdb get dev br0 grp 239.1.1.2 vid 10
Error: bridge: MDB entry not found.
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: David Ahern <dsahern@kernel.org>
2023-11-01 15:45:10 +08:00
|
|
|
if (strcmp(*argv, "get") == 0)
|
|
|
|
return mdb_get(argc-1, argv+1);
|
2023-12-26 23:30:13 +08:00
|
|
|
if (strcmp(*argv, "flush") == 0)
|
|
|
|
return mdb_flush(argc-1, argv+1);
|
2012-12-12 08:46:22 +08:00
|
|
|
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);
|
|
|
|
}
|