Merge branch 'strict-updates' into iproute2-next
Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
commit
6267d9533b
62
bridge/fdb.c
62
bridge/fdb.c
|
|
@ -30,7 +30,7 @@
|
||||||
#include "rt_names.h"
|
#include "rt_names.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static unsigned int filter_index, filter_vlan, filter_state;
|
static unsigned int filter_index, filter_vlan, filter_state, filter_master;
|
||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
|
|
@ -256,20 +256,49 @@ int print_fdb(struct nlmsghdr *n, void *arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fdb_linkdump_filter(struct nlmsghdr *nlh, int reqlen)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (filter_index) {
|
||||||
|
struct ifinfomsg *ifm = NLMSG_DATA(nlh);
|
||||||
|
|
||||||
|
ifm->ifi_index = filter_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_master) {
|
||||||
|
err = addattr32(nlh, reqlen, IFLA_MASTER, filter_master);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fdb_dump_filter(struct nlmsghdr *nlh, int reqlen)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (filter_index) {
|
||||||
|
struct ndmsg *ndm = NLMSG_DATA(nlh);
|
||||||
|
|
||||||
|
ndm->ndm_ifindex = filter_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_master) {
|
||||||
|
err = addattr32(nlh, reqlen, NDA_MASTER, filter_master);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int fdb_show(int argc, char **argv)
|
static int fdb_show(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct {
|
|
||||||
struct nlmsghdr n;
|
|
||||||
struct ndmsg ndm;
|
|
||||||
char buf[256];
|
|
||||||
} req = {
|
|
||||||
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)),
|
|
||||||
.ndm.ndm_family = PF_BRIDGE,
|
|
||||||
};
|
|
||||||
|
|
||||||
char *filter_dev = NULL;
|
char *filter_dev = NULL;
|
||||||
char *br = NULL;
|
char *br = NULL;
|
||||||
int msg_size = sizeof(struct ndmsg);
|
int rc;
|
||||||
|
|
||||||
while (argc > 0) {
|
while (argc > 0) {
|
||||||
if ((strcmp(*argv, "brport") == 0) || strcmp(*argv, "dev") == 0) {
|
if ((strcmp(*argv, "brport") == 0) || strcmp(*argv, "dev") == 0) {
|
||||||
|
|
@ -304,8 +333,7 @@ static int fdb_show(int argc, char **argv)
|
||||||
fprintf(stderr, "Cannot find bridge device \"%s\"\n", br);
|
fprintf(stderr, "Cannot find bridge device \"%s\"\n", br);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
addattr32(&req.n, sizeof(req), IFLA_MASTER, br_ifindex);
|
filter_master = br_ifindex;
|
||||||
msg_size += RTA_LENGTH(4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*we'll keep around filter_dev for older kernels */
|
/*we'll keep around filter_dev for older kernels */
|
||||||
|
|
@ -313,10 +341,14 @@ static int fdb_show(int argc, char **argv)
|
||||||
filter_index = ll_name_to_index(filter_dev);
|
filter_index = ll_name_to_index(filter_dev);
|
||||||
if (!filter_index)
|
if (!filter_index)
|
||||||
return nodev(filter_dev);
|
return nodev(filter_dev);
|
||||||
req.ndm.ndm_ifindex = filter_index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtnl_dump_request(&rth, RTM_GETNEIGH, &req.ndm, msg_size) < 0) {
|
if (rth.flags & RTNL_HANDLE_F_STRICT_CHK)
|
||||||
|
rc = rtnl_neighdump_req(&rth, PF_BRIDGE, fdb_dump_filter);
|
||||||
|
else
|
||||||
|
rc = rtnl_linkdump_req_filter_fn(&rth, PF_BRIDGE,
|
||||||
|
fdb_linkdump_filter);
|
||||||
|
if (rc < 0) {
|
||||||
perror("Cannot send dump request");
|
perror("Cannot send dump request");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ struct rtnl_handle {
|
||||||
FILE *dump_fp;
|
FILE *dump_fp;
|
||||||
#define RTNL_HANDLE_F_LISTEN_ALL_NSID 0x01
|
#define RTNL_HANDLE_F_LISTEN_ALL_NSID 0x01
|
||||||
#define RTNL_HANDLE_F_SUPPRESS_NLERR 0x02
|
#define RTNL_HANDLE_F_SUPPRESS_NLERR 0x02
|
||||||
|
#define RTNL_HANDLE_F_STRICT_CHK 0x04
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,7 +61,8 @@ int rtnl_routedump_req(struct rtnl_handle *rth, int family,
|
||||||
__attribute__((warn_unused_result));
|
__attribute__((warn_unused_result));
|
||||||
int rtnl_ruledump_req(struct rtnl_handle *rth, int family)
|
int rtnl_ruledump_req(struct rtnl_handle *rth, int family)
|
||||||
__attribute__((warn_unused_result));
|
__attribute__((warn_unused_result));
|
||||||
int rtnl_neighdump_req(struct rtnl_handle *rth, int family)
|
int rtnl_neighdump_req(struct rtnl_handle *rth, int family,
|
||||||
|
req_filter_fn_t filter_fn)
|
||||||
__attribute__((warn_unused_result));
|
__attribute__((warn_unused_result));
|
||||||
int rtnl_neightbldump_req(struct rtnl_handle *rth, int family)
|
int rtnl_neightbldump_req(struct rtnl_handle *rth, int family)
|
||||||
__attribute__((warn_unused_result));
|
__attribute__((warn_unused_result));
|
||||||
|
|
|
||||||
42
ip/ipneigh.c
42
ip/ipneigh.c
|
|
@ -41,6 +41,7 @@ static struct
|
||||||
int flushe;
|
int flushe;
|
||||||
int master;
|
int master;
|
||||||
int protocol;
|
int protocol;
|
||||||
|
__u8 ndm_flags;
|
||||||
} filter;
|
} filter;
|
||||||
|
|
||||||
static void usage(void) __attribute__((noreturn));
|
static void usage(void) __attribute__((noreturn));
|
||||||
|
|
@ -408,16 +409,29 @@ void ipneigh_reset_filter(int ifindex)
|
||||||
filter.index = ifindex;
|
filter.index = ifindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ipneigh_dump_filter(struct nlmsghdr *nlh, int reqlen)
|
||||||
|
{
|
||||||
|
struct ndmsg *ndm = NLMSG_DATA(nlh);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
ndm->ndm_flags = filter.ndm_flags;
|
||||||
|
|
||||||
|
if (filter.index) {
|
||||||
|
err = addattr32(nlh, reqlen, NDA_IFINDEX, filter.index);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (filter.master) {
|
||||||
|
err = addattr32(nlh, reqlen, NDA_MASTER, filter.master);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int do_show_or_flush(int argc, char **argv, int flush)
|
static int do_show_or_flush(int argc, char **argv, int flush)
|
||||||
{
|
{
|
||||||
struct {
|
|
||||||
struct nlmsghdr n;
|
|
||||||
struct ndmsg ndm;
|
|
||||||
char buf[256];
|
|
||||||
} req = {
|
|
||||||
.n.nlmsg_type = RTM_GETNEIGH,
|
|
||||||
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)),
|
|
||||||
};
|
|
||||||
char *filter_dev = NULL;
|
char *filter_dev = NULL;
|
||||||
int state_given = 0;
|
int state_given = 0;
|
||||||
|
|
||||||
|
|
@ -448,7 +462,6 @@ static int do_show_or_flush(int argc, char **argv, int flush)
|
||||||
ifindex = ll_name_to_index(*argv);
|
ifindex = ll_name_to_index(*argv);
|
||||||
if (!ifindex)
|
if (!ifindex)
|
||||||
invarg("Device does not exist\n", *argv);
|
invarg("Device does not exist\n", *argv);
|
||||||
addattr32(&req.n, sizeof(req), NDA_MASTER, ifindex);
|
|
||||||
filter.master = ifindex;
|
filter.master = ifindex;
|
||||||
} else if (strcmp(*argv, "vrf") == 0) {
|
} else if (strcmp(*argv, "vrf") == 0) {
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
|
@ -459,7 +472,6 @@ static int do_show_or_flush(int argc, char **argv, int flush)
|
||||||
invarg("Not a valid VRF name\n", *argv);
|
invarg("Not a valid VRF name\n", *argv);
|
||||||
if (!name_is_vrf(*argv))
|
if (!name_is_vrf(*argv))
|
||||||
invarg("Not a valid VRF name\n", *argv);
|
invarg("Not a valid VRF name\n", *argv);
|
||||||
addattr32(&req.n, sizeof(req), NDA_MASTER, ifindex);
|
|
||||||
filter.master = ifindex;
|
filter.master = ifindex;
|
||||||
} else if (strcmp(*argv, "unused") == 0) {
|
} else if (strcmp(*argv, "unused") == 0) {
|
||||||
filter.unused_only = 1;
|
filter.unused_only = 1;
|
||||||
|
|
@ -482,7 +494,7 @@ static int do_show_or_flush(int argc, char **argv, int flush)
|
||||||
state = 0x100;
|
state = 0x100;
|
||||||
filter.state |= state;
|
filter.state |= state;
|
||||||
} else if (strcmp(*argv, "proxy") == 0) {
|
} else if (strcmp(*argv, "proxy") == 0) {
|
||||||
req.ndm.ndm_flags = NTF_PROXY;
|
filter.ndm_flags = NTF_PROXY;
|
||||||
} else if (matches(*argv, "protocol") == 0) {
|
} else if (matches(*argv, "protocol") == 0) {
|
||||||
__u32 prot;
|
__u32 prot;
|
||||||
|
|
||||||
|
|
@ -513,11 +525,8 @@ static int do_show_or_flush(int argc, char **argv, int flush)
|
||||||
filter.index = ll_name_to_index(filter_dev);
|
filter.index = ll_name_to_index(filter_dev);
|
||||||
if (!filter.index)
|
if (!filter.index)
|
||||||
return nodev(filter_dev);
|
return nodev(filter_dev);
|
||||||
addattr32(&req.n, sizeof(req), NDA_IFINDEX, filter.index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req.ndm.ndm_family = filter.family;
|
|
||||||
|
|
||||||
if (flush) {
|
if (flush) {
|
||||||
int round = 0;
|
int round = 0;
|
||||||
char flushb[4096-512];
|
char flushb[4096-512];
|
||||||
|
|
@ -527,7 +536,8 @@ static int do_show_or_flush(int argc, char **argv, int flush)
|
||||||
filter.flushe = sizeof(flushb);
|
filter.flushe = sizeof(flushb);
|
||||||
|
|
||||||
while (round < MAX_ROUNDS) {
|
while (round < MAX_ROUNDS) {
|
||||||
if (rtnl_dump_request_n(&rth, &req.n) < 0) {
|
if (rtnl_neighdump_req(&rth, filter.family,
|
||||||
|
ipneigh_dump_filter) < 0) {
|
||||||
perror("Cannot send dump request");
|
perror("Cannot send dump request");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
@ -560,7 +570,7 @@ static int do_show_or_flush(int argc, char **argv, int flush)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtnl_dump_request_n(&rth, &req.n) < 0) {
|
if (rtnl_neighdump_req(&rth, filter.family, ipneigh_dump_filter) < 0) {
|
||||||
perror("Cannot send dump request");
|
perror("Cannot send dump request");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,8 +166,11 @@ void rtnl_set_strict_dump(struct rtnl_handle *rth)
|
||||||
{
|
{
|
||||||
int one = 1;
|
int one = 1;
|
||||||
|
|
||||||
setsockopt(rth->fd, SOL_NETLINK, NETLINK_GET_STRICT_CHK,
|
if (setsockopt(rth->fd, SOL_NETLINK, NETLINK_GET_STRICT_CHK,
|
||||||
&one, sizeof(one));
|
&one, sizeof(one)) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rth->flags |= RTNL_HANDLE_F_STRICT_CHK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtnl_close(struct rtnl_handle *rth)
|
void rtnl_close(struct rtnl_handle *rth)
|
||||||
|
|
@ -327,11 +330,13 @@ int rtnl_ruledump_req(struct rtnl_handle *rth, int family)
|
||||||
return send(rth->fd, &req, sizeof(req), 0);
|
return send(rth->fd, &req, sizeof(req), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtnl_neighdump_req(struct rtnl_handle *rth, int family)
|
int rtnl_neighdump_req(struct rtnl_handle *rth, int family,
|
||||||
|
req_filter_fn_t filter_fn)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
struct ndmsg ndm;
|
struct ndmsg ndm;
|
||||||
|
char buf[256];
|
||||||
} req = {
|
} req = {
|
||||||
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)),
|
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)),
|
||||||
.nlh.nlmsg_type = RTM_GETNEIGH,
|
.nlh.nlmsg_type = RTM_GETNEIGH,
|
||||||
|
|
@ -340,6 +345,14 @@ int rtnl_neighdump_req(struct rtnl_handle *rth, int family)
|
||||||
.ndm.ndm_family = family,
|
.ndm.ndm_family = family,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (filter_fn) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = filter_fn(&req.nlh, sizeof(req));
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
return send(rth->fd, &req, sizeof(req), 0);
|
return send(rth->fd, &req, sizeof(req), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -424,7 +424,7 @@ static int do_one_request(struct nlmsghdr *n)
|
||||||
|
|
||||||
static void load_initial_table(void)
|
static void load_initial_table(void)
|
||||||
{
|
{
|
||||||
if (rtnl_neighdump_req(&rth, AF_INET) < 0) {
|
if (rtnl_neighdump_req(&rth, AF_INET, NULL) < 0) {
|
||||||
perror("dump request failed");
|
perror("dump request failed");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue