all: bridge
-bridge: $(BROBJ) $(LIBNETLINK)
+bridge: $(BROBJ) $(LIBNETLINK)
$(QUIET_LINK)$(CC) $^ $(LDFLAGS) $(LDLIBS) -o $@
install: all
clean:
rm -f $(BROBJ) bridge
-
#include "rt_names.h"
#include "utils.h"
-static unsigned int filter_index, filter_vlan;
+static unsigned int filter_index, filter_vlan, filter_state;
json_writer_t *jw_global;
" [ self ] [ master ] [ use ] [ router ]\n"
" [ local | static | dynamic ] [ dst IPADDR ] [ vlan VID ]\n"
" [ port PORT] [ vni VNI ] [ via DEV ]\n");
- fprintf(stderr, " bridge fdb [ show [ br BRDEV ] [ brport DEV ] [ vlan VID ] ]\n");
+ fprintf(stderr, " bridge fdb [ show [ br BRDEV ] [ brport DEV ] [ vlan VID ] [ state STATE ] ]\n");
exit(-1);
}
return buf;
}
+static int state_a2n(unsigned int *s, const char *arg)
+{
+ if (matches(arg, "permanent") == 0)
+ *s = NUD_PERMANENT;
+ else if (matches(arg, "static") == 0 || matches(arg, "temp") == 0)
+ *s = NUD_NOARP;
+ else if (matches(arg, "stale") == 0)
+ *s = NUD_STALE;
+ else if (matches(arg, "reachable") == 0 || matches(arg, "dynamic") == 0)
+ *s = NUD_REACHABLE;
+ else if (strcmp(arg, "all") == 0)
+ *s = ~0;
+ else if (get_unsigned(s, arg, 0))
+ return -1;
+
+ return 0;
+}
+
static void start_json_fdb_flags_array(bool *fdb_flags)
{
if (*fdb_flags)
if (filter_index && filter_index != r->ndm_ifindex)
return 0;
+ if (filter_state && !(r->ndm_state & filter_state))
+ return 0;
+
parse_rtattr(tb, NDA_MAX, NDA_RTA(r),
n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
if (filter_vlan)
duparg("vlan", *argv);
filter_vlan = atoi(*argv);
+ } else if (strcmp(*argv, "state") == 0) {
+ unsigned int state;
+
+ NEXT_ARG();
+ if (state_a2n(&state, *argv))
+ invarg("invalid state", *argv);
+ filter_state |= state;
} else {
if (matches(*argv, "help") == 0)
usage();
9 audit
10 fiblookup
11 connector
-12 nft
+12 nft
13 ip6fw
14 dec-rt
15 uevent
18 scsi-trans
19 ecryptfs
20 rdma
-21 crypto
+21 crypto
--- /dev/null
+Each file in this directory is an rt_protos configuration file. iproute2
+commands scan this directory processing all files that end in '.conf'.
Each file in this directory is an rt_tables configuration file. iproute2
commands scan this directory processing all files that end in '.conf'.
-
if (p->flags & IP6_TNL_F_RCV_DSCP_COPY)
printf(" dscp inherit");
- if (p->proto == IPPROTO_GRE) {
- if ((p->i_flags & GRE_KEY) && (p->o_flags & GRE_KEY) && p->o_key == p->i_key)
- printf(" key %u", ntohl(p->i_key));
- else if ((p->i_flags | p->o_flags) & GRE_KEY) {
- if (p->i_flags & GRE_KEY)
- printf(" ikey %u", ntohl(p->i_key));
- if (p->o_flags & GRE_KEY)
- printf(" okey %u", ntohl(p->o_key));
- }
+ if ((p->i_flags & GRE_KEY) && (p->o_flags & GRE_KEY) &&
+ p->o_key == p->i_key)
+ printf(" key %u", ntohl(p->i_key));
+ else {
+ if (p->i_flags & GRE_KEY)
+ printf(" ikey %u", ntohl(p->i_key));
+ if (p->o_flags & GRE_KEY)
+ printf(" okey %u", ntohl(p->o_key));
+ }
+ if (p->proto == IPPROTO_GRE) {
if (p->i_flags & GRE_SEQ)
printf("%s Drop packets out of sequence.", _SL_);
if (p->i_flags & GRE_CSUM)
if (prog_fd < 0) {
fprintf(stderr, "Failed to load BPF prog: '%s'\n",
strerror(errno));
- fprintf(stderr, "Kernel compiled with CGROUP_BPF enabled?\n");
+
+ if (errno != EPERM) {
+ fprintf(stderr,
+ "Kernel compiled with CGROUP_BPF enabled?\n");
+ }
goto out;
}
clean:
rm -f $(NLOBJ) $(UTILOBJ) $(ADDLIB) libnetlink.a libutil.a
-
if (mount("none", mnt, CGROUP2_FS_NAME, 0, NULL)) {
/* EBUSY means already mounted */
- if (errno != EBUSY) {
+ if (errno == EBUSY)
+ goto out;
+
+ if (errno == ENODEV) {
fprintf(stderr,
"Failed to mount cgroup2. Are CGROUPS enabled in your kernel?\n");
- free(mnt);
- return NULL;
+ } else {
+ fprintf(stderr,
+ "Failed to mount cgroup2: %s\n",
+ strerror(errno));
}
+ free(mnt);
+ return NULL;
}
+out:
return mnt;
}
if (mkdir(dir, mode) != 0) {
fprintf(stderr,
- "mkdir failed for %s: %s",
+ "mkdir failed for %s: %s\n",
dir, strerror(errno));
goto out;
}
static void rtnl_rtprot_initialize(void)
{
+ struct dirent *de;
+ DIR *d;
+
rtnl_rtprot_init = 1;
rtnl_tab_initialize(CONFDIR "/rt_protos",
rtnl_rtprot_tab, 256);
+
+ d = opendir(CONFDIR "/rt_protos.d");
+ if (!d)
+ return;
+
+ while ((de = readdir(d)) != NULL) {
+ char path[PATH_MAX];
+ size_t len;
+
+ if (*de->d_name == '.')
+ continue;
+
+ /* only consider filenames ending in '.conf' */
+ len = strlen(de->d_name);
+ if (len <= 5)
+ continue;
+ if (strcmp(de->d_name + len - 5, ".conf"))
+ continue;
+
+ snprintf(path, sizeof(path), CONFDIR "/rt_protos.d/%s",
+ de->d_name);
+ rtnl_tab_initialize(path, rtnl_rtprot_tab, 256);
+ }
+ closedir(d);
}
const char *rtnl_rtprot_n2a(int id, char *buf, int len)
static unsigned long res;
struct rtnl_hash_entry *entry;
char *end;
- __u32 i;
+ unsigned long i;
if (cache && strcmp(cache, arg) == 0) {
*id = res;
.br
void *jarg)
.sp
-int rtnl_listen(struct rtnl_handle *rtnl,
+int rtnl_listen(struct rtnl_handle *rtnl,
int (*handler)(struct sockaddr_nl *, struct rtnl_ctrl_data *,
struct nlmsghdr *n, void *),
void *jarg)
.sp
-int rtnl_from_file(FILE *rtnl,
+int rtnl_from_file(FILE *rtnl,
int (*handler)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
void *jarg)
.sp
.sp
int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen)
.SH DESCRIPTION
-libnetlink provides a higher level interface to
-.BR rtnetlink(7).
+libnetlink provides a higher level interface to
+.BR rtnetlink(7).
The read functions return 0 on success and a negative errno on failure.
The send functions return the amount of data sent, or -1 on error.
-.TP
+.TP
rtnl_open
Open a rtnetlink socket and save the state into the
.B rth
-handle. This handle is passed to all subsequent calls.
+handle. This handle is passed to all subsequent calls.
.B subscriptions
is a bitmap of the rtnetlink multicast groups the socket will be
a member of.
.TP
rtnl_wilddump_request
-Request a full dump of the
+Request a full dump of the
.B type
database for
.B family
addresses.
.B type
-is a rtnetlink message type.
+is a rtnetlink message type.
.\" XXX
.TP
rtnl_dump_request
-Request a full dump of the
-.B type
-data buffer into
+Request a full dump of the
+.B type
+data buffer into
.B buf
with maximum length of
.B len.
.B filter
callback checks if the received message is wanted. It gets the source
address of the message, the message itself and
-.B arg1
+.B arg1
as arguments. 0 as return means that the filter passed, a negative
value is returned
by
-.I rtnl_dump_filter
-in case of error. NULL for
+.I rtnl_dump_filter
+in case of error. NULL for
.I filter
means to not use a filter.
.B junk
.TP
rtnl_listen
-Receive netlink data after a request and pass it to
+Receive netlink data after a request and pass it to
.I handler.
.B handler
is a callback that gets the message source address, anscillary data, the message
.TP
rtnl_from_file
-Works like
-.I rtnl_listen,
+Works like
+.I rtnl_listen,
but reads a netlink message bundle from the file
.B file
and passes the messages to
.BR netlink(3)
on how to generate a rtnetlink message. The following utility functions
require a continuous buffer that already contains a netlink message header
-and a rtnetlink request.
+and a rtnetlink request.
.TP
rtnl_send
.B n,
which is part of a buffer of length
.B maxlen.
-.B data
+.B data
is copied.
.TP
ip-address.8
ip-link.8
ip-route.8
-
.ti -8
.BR "bridge fdb" " [ " show " ] [ "
.B dev
-.IR DEV " ]"
+.IR DEV " ] [ "
+.B br
+.IR BRDEV " ] [ "
+.B brport
+.IR DEV " ] [ "
+.B vlan
+.IR VID " ] [ "
+.B state
+.IR STATE " ]"
.ti -8
.BR "bridge mdb" " { " add " | " del " } "
# tc filter add dev eth0 parent ffff: prio 2 protocol 0xdead \\
u32 match u32 0 0 flowid 1:1 \\
action ife decode reclassify
-# tc filter add dev eth0 parent ffff: priod 3 protocol ip \\
+# tc filter add dev eth0 parent ffff: prio 3 protocol ip \\
u32 match ip protocol 0xff flowid 1:1 \\
action continue
.EE
HOSTCC ?= $(CC)
CCOPTS = $(CBUILD_CFLAGS)
-LDLIBS += -lm
+LDLIBS += -lm
all: $(DISTGEN) $(DISTDATA)
.orig_opts = original_opts,
.opts = original_opts,
.exit_err = NULL,
+#if (XTABLES_VERSION_CODE >= 11)
+ .compat_rev = xtables_compatible_revision,
+#endif
};
/*