Merge pull request #864 from kernelkit/iproute2-6.12

Bump iproute2 to 6.12
This commit is contained in:
Joachim Wiberg
2024-12-10 15:15:21 +01:00
committed by GitHub
8 changed files with 120 additions and 828 deletions
@@ -1,267 +0,0 @@
From bdb8d8549ed97a02935c8fb00ece05030f2f91ad Mon Sep 17 00:00:00 2001
From: Petr Machata <petrm@nvidia.com>
Date: Mon, 27 Mar 2023 18:12:05 +0200
Subject: ip: Support IP address protocol
IPv4 and IPv6 addresses can be assigned a protocol value that indicates the
provenance of the IP address. The attribute is modeled after ip route
protocols, and essentially allows the administrator or userspace stack to
tag addresses in some way that makes sense to the actor in question.
Support for this feature was merged with commit 47f0bd503210 ("net: Add new
protocol attribute to IP addresses"), for kernel 5.18.
In this patch, add support for setting the protocol attribute at IP address
addition, replacement, and listing requests.
An example session with the feature in action:
# ip address add dev d 192.0.2.1/28 proto 0xab
# ip address show dev d
26: d: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 06:29:74:fd:1f:eb brd ff:ff:ff:ff:ff:ff
inet 192.0.2.1/28 scope global proto 0xab d
valid_lft forever preferred_lft forever
# ip address replace dev d 192.0.2.1/28 proto 0x11
# ip address show dev d
26: d: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 06:29:74:fd:1f:eb brd ff:ff:ff:ff:ff:ff
inet 192.0.2.1/28 scope global proto 0x11 d
valid_lft forever preferred_lft forever
A JSON dump. The protocol value is always provided as a string, even in
numeric mode, to provide a consistent interface.
# ip -j address show dev d | jq
[
{
"ifindex": 26,
"ifname": "d",
"flags": [
"BROADCAST",
"NOARP"
],
"mtu": 1500,
"qdisc": "noop",
"operstate": "DOWN",
"group": "default",
"txqlen": 1000,
"link_type": "ether",
"address": "06:29:74:fd:1f:eb",
"broadcast": "ff:ff:ff:ff:ff:ff",
"addr_info": [
{
"family": "inet",
"local": "192.0.2.1",
"prefixlen": 28,
"scope": "global",
"protocol": "0x11",
"label": "d",
"valid_life_time": 4294967295,
"preferred_life_time": 4294967295
}
]
}
]
Signed-off-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
---
include/rt_names.h | 2 ++
ip/ip_common.h | 2 ++
ip/ipaddress.c | 34 ++++++++++++++++++++++++++++--
lib/rt_names.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/include/rt_names.h b/include/rt_names.h
index 6358650db..e96d80f30 100644
--- a/include/rt_names.h
+++ b/include/rt_names.h
@@ -5,6 +5,7 @@
#include <asm/types.h>
const char *rtnl_rtprot_n2a(int id, char *buf, int len);
+const char *rtnl_addrprot_n2a(int id, char *buf, int len);
const char *rtnl_rtscope_n2a(int id, char *buf, int len);
const char *rtnl_rttable_n2a(__u32 id, char *buf, int len);
const char *rtnl_rtrealm_n2a(int id, char *buf, int len);
@@ -13,6 +14,7 @@ const char *rtnl_dsfield_get_name(int id);
const char *rtnl_group_n2a(int id, char *buf, int len);
int rtnl_rtprot_a2n(__u32 *id, const char *arg);
+int rtnl_addrprot_a2n(__u32 *id, const char *arg);
int rtnl_rtscope_a2n(__u32 *id, const char *arg);
int rtnl_rttable_a2n(__u32 *id, const char *arg);
int rtnl_rtrealm_a2n(__u32 *id, const char *arg);
diff --git a/ip/ip_common.h b/ip/ip_common.h
index c4cb1bcb1..4a20ec3cb 100644
--- a/ip/ip_common.h
+++ b/ip/ip_common.h
@@ -28,6 +28,8 @@ struct link_filter {
char *kind;
char *slave_kind;
int target_nsid;
+ bool have_proto;
+ int proto;
};
const char *get_ip_lib_dir(void);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 9ba814380..41055c43e 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -57,11 +57,13 @@ static void usage(void)
" ip address [ show [ dev IFNAME ] [ scope SCOPE-ID ] [ master DEVICE ]\n"
" [ nomaster ]\n"
" [ type TYPE ] [ to PREFIX ] [ FLAG-LIST ]\n"
- " [ label LABEL ] [up] [ vrf NAME ] ]\n"
+ " [ label LABEL ] [up] [ vrf NAME ]\n"
+ " [ proto ADDRPROTO ] ]\n"
" ip address {showdump|restore}\n"
"IFADDR := PREFIX | ADDR peer PREFIX\n"
" [ broadcast ADDR ] [ anycast ADDR ]\n"
" [ label IFNAME ] [ scope SCOPE-ID ] [ metric METRIC ]\n"
+ " [ proto ADDRPROTO ]\n"
"SCOPE-ID := [ host | link | global | NUMBER ]\n"
"FLAG-LIST := [ FLAG-LIST ] FLAG\n"
"FLAG := [ permanent | dynamic | secondary | primary |\n"
@@ -70,7 +72,9 @@ static void usage(void)
"CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n"
"CONFFLAG := [ home | nodad | mngtmpaddr | noprefixroute | autojoin ]\n"
"LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n"
- "LFT := forever | SECONDS\n");
+ "LFT := forever | SECONDS\n"
+ "ADDRPROTO := [ NAME | NUMBER ]\n"
+ );
iplink_types_usage();
exit(-1);
@@ -1568,6 +1572,9 @@ int print_addrinfo(struct nlmsghdr *n, void *arg)
if (filter.family && filter.family != ifa->ifa_family)
return 0;
+ if (filter.have_proto && rta_tb[IFA_PROTO] &&
+ filter.proto != rta_getattr_u8(rta_tb[IFA_PROTO]))
+ return 0;
if (ifa_label_match_rta(ifa->ifa_index, rta_tb[IFA_LABEL]))
return 0;
@@ -1675,6 +1682,14 @@ int print_addrinfo(struct nlmsghdr *n, void *arg)
print_ifa_flags(fp, ifa, ifa_flags);
+ if (rta_tb[IFA_PROTO]) {
+ __u8 proto = rta_getattr_u8(rta_tb[IFA_PROTO]);
+
+ if (proto || is_json_context())
+ print_string(PRINT_ANY, "protocol", "proto %s ",
+ rtnl_addrprot_n2a(proto, b1, sizeof(b1)));
+ }
+
if (rta_tb[IFA_LABEL])
print_string(PRINT_ANY,
"label",
@@ -2196,6 +2211,14 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
} else {
filter.kind = *argv;
}
+ } else if (strcmp(*argv, "proto") == 0) {
+ __u8 proto;
+
+ NEXT_ARG();
+ if (get_u8(&proto, *argv, 0))
+ invarg("\"proto\" value is invalid\n", *argv);
+ filter.have_proto = true;
+ filter.proto = proto;
} else {
if (strcmp(*argv, "dev") == 0)
NEXT_ARG();
@@ -2520,6 +2543,13 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
} else {
ifa_flags |= flag_data->mask;
}
+ } else if (strcmp(*argv, "proto") == 0) {
+ __u8 proto;
+
+ NEXT_ARG();
+ if (get_u8(&proto, *argv, 0))
+ invarg("\"proto\" value is invalid\n", *argv);
+ addattr8(&req.n, sizeof(req), IFA_PROTO, proto);
} else {
if (strcmp(*argv, "local") == 0)
NEXT_ARG();
diff --git a/lib/rt_names.c b/lib/rt_names.c
index 2432224ac..51d11fd05 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -226,6 +226,68 @@ int rtnl_rtprot_a2n(__u32 *id, const char *arg)
}
+static char *rtnl_addrprot_tab[256] = {
+ [IFAPROT_UNSPEC] = "unspec",
+ [IFAPROT_KERNEL_LO] = "kernel_lo",
+ [IFAPROT_KERNEL_RA] = "kernel_ra",
+ [IFAPROT_KERNEL_LL] = "kernel_ll",
+};
+static bool rtnl_addrprot_tab_initialized;
+
+static void rtnl_addrprot_initialize(void)
+{
+ rtnl_tab_initialize(CONFDIR "/rt_addrprotos",
+ rtnl_addrprot_tab,
+ ARRAY_SIZE(rtnl_addrprot_tab));
+ rtnl_addrprot_tab_initialized = true;
+}
+
+const char *rtnl_addrprot_n2a(int id, char *buf, int len)
+{
+ if (id < 0 || id >= 256 || numeric)
+ goto numeric;
+ if (!rtnl_addrprot_tab_initialized)
+ rtnl_addrprot_initialize();
+ if (rtnl_addrprot_tab[id])
+ return rtnl_addrprot_tab[id];
+numeric:
+ snprintf(buf, len, "%#x", id);
+ return buf;
+}
+
+int rtnl_addrprot_a2n(__u32 *id, const char *arg)
+{
+ static char *cache;
+ static unsigned long res;
+ char *end;
+ int i;
+
+ if (cache && strcmp(cache, arg) == 0) {
+ *id = res;
+ return 0;
+ }
+
+ if (!rtnl_addrprot_tab_initialized)
+ rtnl_addrprot_initialize();
+
+ for (i = 0; i < 256; i++) {
+ if (rtnl_addrprot_tab[i] &&
+ strcmp(rtnl_addrprot_tab[i], arg) == 0) {
+ cache = rtnl_addrprot_tab[i];
+ res = i;
+ *id = res;
+ return 0;
+ }
+ }
+
+ res = strtoul(arg, &end, 0);
+ if (!end || end == arg || *end || res > 255)
+ return -1;
+ *id = res;
+ return 0;
+}
+
+
static char *rtnl_rtscope_tab[256] = {
[RT_SCOPE_UNIVERSE] = "global",
[RT_SCOPE_NOWHERE] = "nowhere",
--
cgit
@@ -1,105 +0,0 @@
From 709063e8368aeed56fd5775c10d33ca4dc8990a5 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Fri, 2 Jun 2023 08:51:53 -0700
Subject: [PATCH] ipaddress: accept symbolic names
Organization: Addiva Elektronik
The function rtnl_addproto_a2n() was defined but never used.
Use it to allow for symbolic names, and fix the function signatures
so protocol value is consistently __u8.
Fixes: bdb8d8549ed9 ("ip: Support IP address protocol")
Cc: petrm@nvidia.com
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
include/rt_names.h | 4 ++--
ip/ipaddress.c | 2 +-
lib/rt_names.c | 18 +++++-------------
3 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/include/rt_names.h b/include/rt_names.h
index e96d80f3..02750307 100644
--- a/include/rt_names.h
+++ b/include/rt_names.h
@@ -5,7 +5,7 @@
#include <asm/types.h>
const char *rtnl_rtprot_n2a(int id, char *buf, int len);
-const char *rtnl_addrprot_n2a(int id, char *buf, int len);
+const char *rtnl_addrprot_n2a(__u8 id, char *buf, int len);
const char *rtnl_rtscope_n2a(int id, char *buf, int len);
const char *rtnl_rttable_n2a(__u32 id, char *buf, int len);
const char *rtnl_rtrealm_n2a(int id, char *buf, int len);
@@ -14,7 +14,7 @@ const char *rtnl_dsfield_get_name(int id);
const char *rtnl_group_n2a(int id, char *buf, int len);
int rtnl_rtprot_a2n(__u32 *id, const char *arg);
-int rtnl_addrprot_a2n(__u32 *id, const char *arg);
+int rtnl_addrprot_a2n(__u8 *id, const char *arg);
int rtnl_rtscope_a2n(__u32 *id, const char *arg);
int rtnl_rttable_a2n(__u32 *id, const char *arg);
int rtnl_rtrealm_a2n(__u32 *id, const char *arg);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index c428dd3d..7accbf7d 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -2547,7 +2547,7 @@ static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
__u8 proto;
NEXT_ARG();
- if (get_u8(&proto, *argv, 0))
+ if (rtnl_addrprot_a2n(&proto, *argv))
invarg("\"proto\" value is invalid\n", *argv);
addattr8(&req.n, sizeof(req), IFA_PROTO, proto);
} else {
diff --git a/lib/rt_names.c b/lib/rt_names.c
index 51d11fd0..b441e98f 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -242,9 +242,9 @@ static void rtnl_addrprot_initialize(void)
rtnl_addrprot_tab_initialized = true;
}
-const char *rtnl_addrprot_n2a(int id, char *buf, int len)
+const char *rtnl_addrprot_n2a(__u8 id, char *buf, int len)
{
- if (id < 0 || id >= 256 || numeric)
+ if (numeric)
goto numeric;
if (!rtnl_addrprot_tab_initialized)
rtnl_addrprot_initialize();
@@ -255,27 +255,19 @@ numeric:
return buf;
}
-int rtnl_addrprot_a2n(__u32 *id, const char *arg)
+int rtnl_addrprot_a2n(__u8 *id, const char *arg)
{
- static char *cache;
- static unsigned long res;
+ unsigned long res;
char *end;
int i;
- if (cache && strcmp(cache, arg) == 0) {
- *id = res;
- return 0;
- }
-
if (!rtnl_addrprot_tab_initialized)
rtnl_addrprot_initialize();
for (i = 0; i < 256; i++) {
if (rtnl_addrprot_tab[i] &&
strcmp(rtnl_addrprot_tab[i], arg) == 0) {
- cache = rtnl_addrprot_tab[i];
- res = i;
- *id = res;
+ *id = i;
return 0;
}
}
--
2.34.1
@@ -1,175 +0,0 @@
From 5a2ab621675d39dc9ecbd4d65d5c7a424248cd11 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 09:41:46 +0100
Subject: [PATCH] iplink_bridge: add mcast_flood_always bridge option
Organization: Addiva Elektronik
- Break out boolopt handling to simplify parsing and setting
- Add set/get support for mcast_flood_always
- Add get support for mst_enabled
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
include/uapi/linux/if_bridge.h | 1 +
ip/iplink_bridge.c | 75 +++++++++++++++++++++++++---------
man/man8/ip-link.8.in | 12 ++++++
3 files changed, 68 insertions(+), 20 deletions(-)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index f6d58238..aaab505d 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -777,6 +777,7 @@ enum br_boolopt_id {
BR_BOOLOPT_NO_LL_LEARN,
BR_BOOLOPT_MCAST_VLAN_SNOOPING,
BR_BOOLOPT_MST_ENABLE,
+ BR_BOOLOPT_MCAST_FLOOD_ALWAYS,
BR_BOOLOPT_MAX
};
diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c
index 8b0c1422..8d4a6bb2 100644
--- a/ip/iplink_bridge.c
+++ b/ip/iplink_bridge.c
@@ -43,6 +43,7 @@ static void print_explain(FILE *f)
" [ vlan_default_pvid VLAN_DEFAULT_PVID ]\n"
" [ vlan_stats_enabled VLAN_STATS_ENABLED ]\n"
" [ vlan_stats_per_port VLAN_STATS_PER_PORT ]\n"
+ " [ mcast_flood_always ENABLED ]\n"
" [ mcast_snooping MULTICAST_SNOOPING ]\n"
" [ mcast_vlan_snooping MULTICAST_VLAN_SNOOPING ]\n"
" [ mcast_router MULTICAST_ROUTER ]\n"
@@ -82,6 +83,18 @@ void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len)
snprintf(buf, len, "%.2x%.2x.%s", id->prio[0], id->prio[1], eaddr);
}
+static void set_boolopt(struct br_boolopt_multi *bm, enum br_boolopt_id opt,
+ bool set)
+{
+ __u32 bit = 1 << opt;
+
+ bm->optmask |= 1 << opt;
+ if (set)
+ bm->optval |= bit;
+ else
+ bm->optval &= ~bit;
+}
+
static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
@@ -216,17 +229,21 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
addattr8(n, 1024, IFLA_BR_MCAST_SNOOPING, mcast_snoop);
} else if (strcmp(*argv, "mcast_vlan_snooping") == 0) {
- __u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
- __u8 mcast_vlan_snooping;
+ __u8 val;
NEXT_ARG();
- if (get_u8(&mcast_vlan_snooping, *argv, 0))
+ if (get_u8(&val, *argv, 0))
invarg("invalid mcast_vlan_snooping", *argv);
- bm.optmask |= 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
- if (mcast_vlan_snooping)
- bm.optval |= mcvl_bit;
- else
- bm.optval &= ~mcvl_bit;
+
+ set_boolopt(&bm, BR_BOOLOPT_MCAST_VLAN_SNOOPING, val);
+ } else if (strcmp(*argv, "mcast_flood_always") == 0) {
+ __u8 val;
+
+ NEXT_ARG();
+ if (get_u8(&val, *argv, 0))
+ invarg("invalid mcast_flood_always", *argv);
+
+ set_boolopt(&bm, BR_BOOLOPT_MCAST_FLOOD_ALWAYS, val);
} else if (matches(*argv, "mcast_query_use_ifaddr") == 0) {
__u8 mcast_qui;
@@ -590,21 +607,39 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING]));
if (tb[IFLA_BR_MULTI_BOOLOPT]) {
- __u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
- __u32 no_ll_learn_bit = 1 << BR_BOOLOPT_NO_LL_LEARN;
struct br_boolopt_multi *bm;
+ int opt;
bm = RTA_DATA(tb[IFLA_BR_MULTI_BOOLOPT]);
- if (bm->optmask & no_ll_learn_bit)
- print_uint(PRINT_ANY,
- "no_linklocal_learn",
- "no_linklocal_learn %u ",
- !!(bm->optval & no_ll_learn_bit));
- if (bm->optmask & mcvl_bit)
- print_uint(PRINT_ANY,
- "mcast_vlan_snooping",
- "mcast_vlan_snooping %u ",
- !!(bm->optval & mcvl_bit));
+ for (opt = 0; opt < BR_BOOLOPT_MAX; opt++) {
+ __u32 bit = 1 << opt;
+ __u32 val = !!(bm->optval & bit);
+
+ if (!(bm->optmask & bit))
+ continue;
+
+ switch (opt) {
+ case BR_BOOLOPT_NO_LL_LEARN:
+ print_uint(PRINT_ANY,
+ "no_linklocal_learn",
+ "no_linklocal_learn %u ", val);
+ break;
+ case BR_BOOLOPT_MCAST_VLAN_SNOOPING:
+ print_uint(PRINT_ANY,
+ "mcast_vlan_snooping",
+ "mcast_vlan_snooping %u ", val);
+ break;
+ case BR_BOOLOPT_MST_ENABLE:
+ print_uint(PRINT_ANY,
+ "mst_enabled",
+ "mst_enabled %u ", val);
+ break;
+ case BR_BOOLOPT_MCAST_FLOOD_ALWAYS:
+ print_uint(PRINT_ANY,
+ "mcast_flood_always",
+ "mcast_flood_always %u ", val);
+ }
+ }
}
if (tb[IFLA_BR_MCAST_ROUTER])
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 6c72e122..4730e73a 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -1590,6 +1590,8 @@ the following additional arguments are supported:
] [
.BI vlan_stats_per_port " VLAN_STATS_PER_PORT "
] [
+.BI mcast_flood_always " ENABLED "
+] [
.BI mcast_snooping " MULTICAST_SNOOPING "
] [
.BI mcast_vlan_snooping " MULTICAST_VLAN_SNOOPING "
@@ -1718,6 +1720,16 @@ or disable
.RI ( VLAN_STATS_PER_PORT " == 0) "
per-VLAN per-port stats accounting. Can be changed only when there are no port VLANs configured.
+.BI mcast_flood_always " ENABLED "
+- always
+.RI ( ENABLED " > 0) "
+flood unknown multicast according to per-port
+.BI mcast_flood
+settings. By default
+.RI ( ENABLED " == 0). "
+the bridge only floods until it has learned of a querier, or takes on
+the role itself.
+
.BI mcast_snooping " MULTICAST_SNOOPING "
- turn multicast snooping on
.RI ( MULTICAST_SNOOPING " > 0) "
--
2.34.1
@@ -1,101 +0,0 @@
From 8557acdc7218cbaf2b9d70ecfa118c05f988ed77 Mon Sep 17 00:00:00 2001
From: Ido Schimmel <idosch@nvidia.com>
Date: Thu, 15 Dec 2022 19:52:30 +0200
Subject: [PATCH] bridge: mdb: Add replace support
Organization: Addiva Elektronik
Allow user space to replace MDB port group entries by specifying the
'NLM_F_REPLACE' flag in the netlink message header.
Examples:
# bridge mdb replace dev br0 port dummy10 grp 239.1.1.1 permanent source_list 192.0.2.1,192.0.2.2 filter_mode include
# bridge -d -s mdb show
dev br0 port dummy10 grp 239.1.1.1 src 192.0.2.2 permanent filter_mode include proto static 0.00
dev br0 port dummy10 grp 239.1.1.1 src 192.0.2.1 permanent filter_mode include proto static 0.00
dev br0 port dummy10 grp 239.1.1.1 permanent filter_mode include source_list 192.0.2.2/0.00,192.0.2.1/0.00 proto static 0.00
# bridge mdb replace dev br0 port dummy10 grp 239.1.1.1 permanent source_list 192.0.2.1,192.0.2.3 filter_mode exclude proto zebra
# bridge -d -s mdb show
dev br0 port dummy10 grp 239.1.1.1 src 192.0.2.3 permanent filter_mode include proto zebra blocked 0.00
dev br0 port dummy10 grp 239.1.1.1 src 192.0.2.1 permanent filter_mode include proto zebra blocked 0.00
dev br0 port dummy10 grp 239.1.1.1 permanent filter_mode exclude source_list 192.0.2.3/0.00,192.0.2.1/0.00 proto zebra 0.00
# bridge mdb replace dev br0 port dummy10 grp 239.1.1.1 temp source_list 192.0.2.4,192.0.2.3 filter_mode include proto bgp
# bridge -d -s mdb show
dev br0 port dummy10 grp 239.1.1.1 src 192.0.2.4 temp filter_mode include proto bgp 0.00
dev br0 port dummy10 grp 239.1.1.1 src 192.0.2.3 temp filter_mode include proto bgp 0.00
dev br0 port dummy10 grp 239.1.1.1 temp filter_mode include source_list 192.0.2.4/259.44,192.0.2.3/259.44 proto bgp 0.00
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
bridge/mdb.c | 4 +++-
man/man8/bridge.8 | 13 ++++++++++---
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/bridge/mdb.c b/bridge/mdb.c
index d3afc900..60cf0066 100644
--- a/bridge/mdb.c
+++ b/bridge/mdb.c
@@ -31,7 +31,7 @@ static unsigned int filter_index, filter_vlan;
static void usage(void)
{
fprintf(stderr,
- "Usage: bridge mdb { add | del } dev DEV port PORT grp GROUP [src SOURCE] [permanent | temp] [vid VID]\n"
+ "Usage: bridge mdb { add | del | replace } dev DEV port PORT grp GROUP [src SOURCE] [permanent | temp] [vid VID]\n"
" bridge mdb {show} [ dev DEV ] [ vid VID ]\n");
exit(-1);
}
@@ -571,6 +571,8 @@ int do_mdb(int argc, char **argv)
if (argc > 0) {
if (matches(*argv, "add") == 0)
return mdb_modify(RTM_NEWMDB, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
+ if (strcmp(*argv, "replace") == 0)
+ return mdb_modify(RTM_NEWMDB, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1);
if (matches(*argv, "delete") == 0)
return mdb_modify(RTM_DELMDB, 0, argc-1, argv+1);
diff --git a/man/man8/bridge.8 b/man/man8/bridge.8
index d4df772e..5bf15deb 100644
--- a/man/man8/bridge.8
+++ b/man/man8/bridge.8
@@ -126,7 +126,7 @@ bridge \- show / manipulate bridge addresses and devices
.BR [no]sticky " ] [ " [no]offloaded " ]"
.ti -8
-.BR "bridge mdb" " { " add " | " del " } "
+.BR "bridge mdb" " { " add " | " del " | " replace " } "
.B dev
.I DEV
.B port
@@ -873,8 +873,8 @@ if "no" is prepended then only entries without offloaded flag will be deleted.
objects contain known IP or L2 multicast group addresses on a link.
.P
-The corresponding commands display mdb entries, add new entries,
-and delete old ones.
+The corresponding commands display mdb entries, add new entries, replace
+entries and delete old ones.
.SS bridge mdb add - add a new multicast group database entry
@@ -919,6 +919,13 @@ This command removes an existing mdb entry.
The arguments are the same as with
.BR "bridge mdb add" .
+.SS bridge mdb replace - replace a multicast group database entry
+If no matching entry is found, a new one will be created instead.
+
+.PP
+The arguments are the same as with
+.BR "bridge mdb add" .
+
.SS bridge mdb show - list multicast group database entries
This command displays the current multicast group membership table. The table
--
2.34.1
@@ -0,0 +1,114 @@
From dfd52e38ab402822aa4011039efa00e9d183d6a6 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 09:41:46 +0100
Subject: [PATCH 1/2] iplink_bridge: add mcast_flood_always bridge option
Organization: Addiva Elektronik
- Break out boolopt handling to simplify parsing and setting
- Add set/get support for mcast_flood_always
- Add get support for mst_enabled
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
include/uapi/linux/if_bridge.h | 1 +
ip/iplink_bridge.c | 19 +++++++++++++++++++
man/man8/ip-link.8.in | 12 ++++++++++++
3 files changed, 32 insertions(+)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index c206cf6d..84ef4233 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -830,6 +830,7 @@ enum br_boolopt_id {
BR_BOOLOPT_NO_LL_LEARN,
BR_BOOLOPT_MCAST_VLAN_SNOOPING,
BR_BOOLOPT_MST_ENABLE,
+ BR_BOOLOPT_MCAST_FLOOD_ALWAYS,
BR_BOOLOPT_MAX
};
diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c
index f01ffe15..2a489b7b 100644
--- a/ip/iplink_bridge.c
+++ b/ip/iplink_bridge.c
@@ -41,6 +41,7 @@ static void print_explain(FILE *f)
" [ vlan_default_pvid VLAN_DEFAULT_PVID ]\n"
" [ vlan_stats_enabled VLAN_STATS_ENABLED ]\n"
" [ vlan_stats_per_port VLAN_STATS_PER_PORT ]\n"
+ " [ mcast_flood_always ENABLED ]\n"
" [ mcast_snooping MULTICAST_SNOOPING ]\n"
" [ mcast_vlan_snooping MULTICAST_VLAN_SNOOPING ]\n"
" [ mcast_router MULTICAST_ROUTER ]\n"
@@ -245,6 +246,18 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
bm.optval |= mcvl_bit;
else
bm.optval &= ~mcvl_bit;
+ } else if (strcmp(*argv, "mcast_flood_always") == 0) {
+ __u32 mcfl_bit = 1 << BR_BOOLOPT_MCAST_FLOOD_ALWAYS;
+ __u8 mcast_flood_always;
+
+ NEXT_ARG();
+ if (get_u8(&mcast_flood_always, *argv, 0))
+ invarg("invalid mcast_flood_always", *argv);
+ bm.optmask |= mcfl_bit;
+ if (mcast_flood_always)
+ bm.optval |= mcfl_bit;
+ else
+ bm.optval &= ~mcfl_bit;
} else if (matches(*argv, "mcast_query_use_ifaddr") == 0) {
__u8 mcast_qui;
@@ -623,6 +636,7 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
__u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
__u32 no_ll_learn_bit = 1 << BR_BOOLOPT_NO_LL_LEARN;
__u32 mst_bit = 1 << BR_BOOLOPT_MST_ENABLE;
+ __u32 mcfl_bit = 1 << BR_BOOLOPT_MCAST_FLOOD_ALWAYS;
struct br_boolopt_multi *bm;
bm = RTA_DATA(tb[IFLA_BR_MULTI_BOOLOPT]);
@@ -641,6 +655,11 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
"mst_enabled",
"mst_enabled %u ",
!!(bm->optval & mst_bit));
+ if (bm->optmask & mcfl_bit)
+ print_uint(PRINT_ANY,
+ "mcast_flood_always",
+ "mcast_flood_always %u ",
+ !!(bm->optval & mcfl_bit));
}
if (tb[IFLA_BR_MCAST_ROUTER])
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index eabca490..ba0a5304 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -1703,6 +1703,8 @@ the following additional arguments are supported:
] [
.BI vlan_stats_per_port " VLAN_STATS_PER_PORT "
] [
+.BI mcast_flood_always " ENABLED "
+] [
.BI mcast_snooping " MULTICAST_SNOOPING "
] [
.BI mcast_vlan_snooping " MULTICAST_VLAN_SNOOPING "
@@ -1851,6 +1853,16 @@ or disable
.RI ( VLAN_STATS_PER_PORT " == 0) "
per-VLAN per-port stats accounting. Can be changed only when there are no port VLANs configured.
+.BI mcast_flood_always " ENABLED "
+- always
+.RI ( ENABLED " > 0) "
+flood unknown multicast according to per-port
+.BI mcast_flood
+settings. By default
+.RI ( ENABLED " == 0). "
+the bridge only floods until it has learned of a querier, or takes on
+the role itself.
+
.BI mcast_snooping " MULTICAST_SNOOPING "
- turn multicast snooping on
.RI ( MULTICAST_SNOOPING " > 0) "
--
2.43.0
@@ -1,4 +1,4 @@
From 226a8b532fc074165ba76d71c4488629daed2625 Mon Sep 17 00:00:00 2001
From a035696129b543952e8105c27689ed4f9312eb3b Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 20 May 2024 21:35:11 +0200
Subject: [PATCH 2/2] ipaddress: accept symbolic names also for show
@@ -9,15 +9,16 @@ bdb8d85, to add support for 'ip addr show proto static', where
'static' is defined in /etc/iproute2/rt_addrprotos.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
ip/ipaddress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index e536912f..19900157 100644
index 4e1f934f..437072f9 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -2217,7 +2217,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
@@ -2224,7 +2224,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action)
__u8 proto;
NEXT_ARG();
@@ -27,5 +28,5 @@ index e536912f..19900157 100644
filter.have_proto = true;
filter.proto = proto;
--
2.34.1
2.43.0
@@ -1,175 +0,0 @@
From 50fafdc63dc3d6152e2494cc693871e9bd04bfe5 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 5 Mar 2024 09:41:46 +0100
Subject: [PATCH 1/2] iplink_bridge: add mcast_flood_always bridge option
Organization: Addiva Elektronik
- Break out boolopt handling to simplify parsing and setting
- Add set/get support for mcast_flood_always
- Add get support for mst_enabled
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
include/uapi/linux/if_bridge.h | 1 +
ip/iplink_bridge.c | 75 +++++++++++++++++++++++++---------
man/man8/ip-link.8.in | 12 ++++++
3 files changed, 68 insertions(+), 20 deletions(-)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index adb75f7d..611ab413 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -829,6 +829,7 @@ enum br_boolopt_id {
BR_BOOLOPT_NO_LL_LEARN,
BR_BOOLOPT_MCAST_VLAN_SNOOPING,
BR_BOOLOPT_MST_ENABLE,
+ BR_BOOLOPT_MCAST_FLOOD_ALWAYS,
BR_BOOLOPT_MAX
};
diff --git a/ip/iplink_bridge.c b/ip/iplink_bridge.c
index 6b70ffbb..c83f55b0 100644
--- a/ip/iplink_bridge.c
+++ b/ip/iplink_bridge.c
@@ -40,6 +40,7 @@ static void print_explain(FILE *f)
" [ vlan_default_pvid VLAN_DEFAULT_PVID ]\n"
" [ vlan_stats_enabled VLAN_STATS_ENABLED ]\n"
" [ vlan_stats_per_port VLAN_STATS_PER_PORT ]\n"
+ " [ mcast_flood_always ENABLED ]\n"
" [ mcast_snooping MULTICAST_SNOOPING ]\n"
" [ mcast_vlan_snooping MULTICAST_VLAN_SNOOPING ]\n"
" [ mcast_router MULTICAST_ROUTER ]\n"
@@ -79,6 +80,18 @@ void br_dump_bridge_id(const struct ifla_bridge_id *id, char *buf, size_t len)
snprintf(buf, len, "%.2x%.2x.%s", id->prio[0], id->prio[1], eaddr);
}
+static void set_boolopt(struct br_boolopt_multi *bm, enum br_boolopt_id opt,
+ bool set)
+{
+ __u32 bit = 1 << opt;
+
+ bm->optmask |= 1 << opt;
+ if (set)
+ bm->optval |= bit;
+ else
+ bm->optval &= ~bit;
+}
+
static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
struct nlmsghdr *n)
{
@@ -221,17 +234,21 @@ static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
addattr8(n, 1024, IFLA_BR_MCAST_SNOOPING, mcast_snoop);
} else if (strcmp(*argv, "mcast_vlan_snooping") == 0) {
- __u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
- __u8 mcast_vlan_snooping;
+ __u8 val;
NEXT_ARG();
- if (get_u8(&mcast_vlan_snooping, *argv, 0))
+ if (get_u8(&val, *argv, 0))
invarg("invalid mcast_vlan_snooping", *argv);
- bm.optmask |= 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
- if (mcast_vlan_snooping)
- bm.optval |= mcvl_bit;
- else
- bm.optval &= ~mcvl_bit;
+
+ set_boolopt(&bm, BR_BOOLOPT_MCAST_VLAN_SNOOPING, val);
+ } else if (strcmp(*argv, "mcast_flood_always") == 0) {
+ __u8 val;
+
+ NEXT_ARG();
+ if (get_u8(&val, *argv, 0))
+ invarg("invalid mcast_flood_always", *argv);
+
+ set_boolopt(&bm, BR_BOOLOPT_MCAST_FLOOD_ALWAYS, val);
} else if (matches(*argv, "mcast_query_use_ifaddr") == 0) {
__u8 mcast_qui;
@@ -607,21 +624,39 @@ static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
rta_getattr_u8(tb[IFLA_BR_MCAST_SNOOPING]));
if (tb[IFLA_BR_MULTI_BOOLOPT]) {
- __u32 mcvl_bit = 1 << BR_BOOLOPT_MCAST_VLAN_SNOOPING;
- __u32 no_ll_learn_bit = 1 << BR_BOOLOPT_NO_LL_LEARN;
struct br_boolopt_multi *bm;
+ int opt;
bm = RTA_DATA(tb[IFLA_BR_MULTI_BOOLOPT]);
- if (bm->optmask & no_ll_learn_bit)
- print_uint(PRINT_ANY,
- "no_linklocal_learn",
- "no_linklocal_learn %u ",
- !!(bm->optval & no_ll_learn_bit));
- if (bm->optmask & mcvl_bit)
- print_uint(PRINT_ANY,
- "mcast_vlan_snooping",
- "mcast_vlan_snooping %u ",
- !!(bm->optval & mcvl_bit));
+ for (opt = 0; opt < BR_BOOLOPT_MAX; opt++) {
+ __u32 bit = 1 << opt;
+ __u32 val = !!(bm->optval & bit);
+
+ if (!(bm->optmask & bit))
+ continue;
+
+ switch (opt) {
+ case BR_BOOLOPT_NO_LL_LEARN:
+ print_uint(PRINT_ANY,
+ "no_linklocal_learn",
+ "no_linklocal_learn %u ", val);
+ break;
+ case BR_BOOLOPT_MCAST_VLAN_SNOOPING:
+ print_uint(PRINT_ANY,
+ "mcast_vlan_snooping",
+ "mcast_vlan_snooping %u ", val);
+ break;
+ case BR_BOOLOPT_MST_ENABLE:
+ print_uint(PRINT_ANY,
+ "mst_enabled",
+ "mst_enabled %u ", val);
+ break;
+ case BR_BOOLOPT_MCAST_FLOOD_ALWAYS:
+ print_uint(PRINT_ANY,
+ "mcast_flood_always",
+ "mcast_flood_always %u ", val);
+ }
+ }
}
if (tb[IFLA_BR_MCAST_ROUTER])
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index 6764a9ad..8f77c5ad 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -1642,6 +1642,8 @@ the following additional arguments are supported:
] [
.BI vlan_stats_per_port " VLAN_STATS_PER_PORT "
] [
+.BI mcast_flood_always " ENABLED "
+] [
.BI mcast_snooping " MULTICAST_SNOOPING "
] [
.BI mcast_vlan_snooping " MULTICAST_VLAN_SNOOPING "
@@ -1778,6 +1780,16 @@ or disable
.RI ( VLAN_STATS_PER_PORT " == 0) "
per-VLAN per-port stats accounting. Can be changed only when there are no port VLANs configured.
+.BI mcast_flood_always " ENABLED "
+- always
+.RI ( ENABLED " > 0) "
+flood unknown multicast according to per-port
+.BI mcast_flood
+settings. By default
+.RI ( ENABLED " == 0). "
+the bridge only floods until it has learned of a querier, or takes on
+the role itself.
+
.BI mcast_snooping " MULTICAST_SNOOPING "
- turn multicast snooping on
.RI ( MULTICAST_SNOOPING " > 0) "
--
2.34.1