From 9cd9440515a0c4002f5d790cd8a20502282c23a9 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 10 Dec 2024 13:28:23 +0100 Subject: [PATCH 1/2] buildroot: Bump to latest 2024.02.x-kkit for iproute2 6.12.0 --- buildroot | 2 +- ...add-mcast_flood_always-bridge-option.patch | 114 ++++++++++++++++++ ...-accept-symbolic-names-also-for-show.patch | 32 +++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 patches/iproute2/6.12.0/0001-iplink_bridge-add-mcast_flood_always-bridge-option.patch create mode 100644 patches/iproute2/6.12.0/0002-ipaddress-accept-symbolic-names-also-for-show.patch diff --git a/buildroot b/buildroot index 897bb2cf4..80d4761b4 160000 --- a/buildroot +++ b/buildroot @@ -1 +1 @@ -Subproject commit 897bb2cf43668b136af6ec04574b86bc3c2d55c9 +Subproject commit 80d4761b488cfceb682d52ffd26a3e19af732e3e diff --git a/patches/iproute2/6.12.0/0001-iplink_bridge-add-mcast_flood_always-bridge-option.patch b/patches/iproute2/6.12.0/0001-iplink_bridge-add-mcast_flood_always-bridge-option.patch new file mode 100644 index 000000000..f9a980624 --- /dev/null +++ b/patches/iproute2/6.12.0/0001-iplink_bridge-add-mcast_flood_always-bridge-option.patch @@ -0,0 +1,114 @@ +From dfd52e38ab402822aa4011039efa00e9d183d6a6 Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +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 +Signed-off-by: Tobias Waldekranz +--- + 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 + diff --git a/patches/iproute2/6.12.0/0002-ipaddress-accept-symbolic-names-also-for-show.patch b/patches/iproute2/6.12.0/0002-ipaddress-accept-symbolic-names-also-for-show.patch new file mode 100644 index 000000000..eda954099 --- /dev/null +++ b/patches/iproute2/6.12.0/0002-ipaddress-accept-symbolic-names-also-for-show.patch @@ -0,0 +1,32 @@ +From a035696129b543952e8105c27689ed4f9312eb3b Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Mon, 20 May 2024 21:35:11 +0200 +Subject: [PATCH 2/2] ipaddress: accept symbolic names also for show +Organization: Addiva Elektronik + +This is a follow-up to 709063e, which in turn was a follow-up to +bdb8d85, to add support for 'ip addr show proto static', where +'static' is defined in /etc/iproute2/rt_addrprotos. + +Signed-off-by: Joachim Wiberg +Signed-off-by: Tobias Waldekranz +--- + ip/ipaddress.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ip/ipaddress.c b/ip/ipaddress.c +index 4e1f934f..437072f9 100644 +--- a/ip/ipaddress.c ++++ b/ip/ipaddress.c +@@ -2224,7 +2224,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) + __u8 proto; + + NEXT_ARG(); +- if (get_u8(&proto, *argv, 0)) ++ if (rtnl_addrprot_a2n(&proto, *argv)) + invarg("\"proto\" value is invalid\n", *argv); + filter.have_proto = true; + filter.proto = proto; +-- +2.43.0 + From 1863297b5ae80e1b7be92f6cdd1ffa6cb194e4a8 Mon Sep 17 00:00:00 2001 From: Tobias Waldekranz Date: Tue, 10 Dec 2024 14:33:23 +0100 Subject: [PATCH 2/2] package/iproute2: Remove patches for outdated versions --- .../0001-ip-support-ip-address-protocol.patch | 267 ------------------ ...0002-ipaddress-accept-symbolic-names.patch | 105 ------- ...add-mcast_flood_always-bridge-option.patch | 175 ------------ .../0004-bridge-mdb-Add-replace-support.patch | 101 ------- ...add-mcast_flood_always-bridge-option.patch | 175 ------------ ...-accept-symbolic-names-also-for-show.patch | 31 -- 6 files changed, 854 deletions(-) delete mode 100644 patches/iproute2/6.1.0/0001-ip-support-ip-address-protocol.patch delete mode 100644 patches/iproute2/6.1.0/0002-ipaddress-accept-symbolic-names.patch delete mode 100644 patches/iproute2/6.1.0/0003-iplink_bridge-add-mcast_flood_always-bridge-option.patch delete mode 100644 patches/iproute2/6.1.0/0004-bridge-mdb-Add-replace-support.patch delete mode 100644 patches/iproute2/6.7.0/0001-iplink_bridge-add-mcast_flood_always-bridge-option.patch delete mode 100644 patches/iproute2/6.7.0/0002-ipaddress-accept-symbolic-names-also-for-show.patch diff --git a/patches/iproute2/6.1.0/0001-ip-support-ip-address-protocol.patch b/patches/iproute2/6.1.0/0001-ip-support-ip-address-protocol.patch deleted file mode 100644 index c6f5eab0b..000000000 --- a/patches/iproute2/6.1.0/0001-ip-support-ip-address-protocol.patch +++ /dev/null @@ -1,267 +0,0 @@ -From bdb8d8549ed97a02935c8fb00ece05030f2f91ad Mon Sep 17 00:00:00 2001 -From: Petr Machata -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: 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: 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 -Signed-off-by: David Ahern ---- - 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 - - 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 diff --git a/patches/iproute2/6.1.0/0002-ipaddress-accept-symbolic-names.patch b/patches/iproute2/6.1.0/0002-ipaddress-accept-symbolic-names.patch deleted file mode 100644 index a02bc5735..000000000 --- a/patches/iproute2/6.1.0/0002-ipaddress-accept-symbolic-names.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 709063e8368aeed56fd5775c10d33ca4dc8990a5 Mon Sep 17 00:00:00 2001 -From: Stephen Hemminger -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 -Signed-off-by: Joachim Wiberg ---- - 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 - - 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 - diff --git a/patches/iproute2/6.1.0/0003-iplink_bridge-add-mcast_flood_always-bridge-option.patch b/patches/iproute2/6.1.0/0003-iplink_bridge-add-mcast_flood_always-bridge-option.patch deleted file mode 100644 index cb0fe5dde..000000000 --- a/patches/iproute2/6.1.0/0003-iplink_bridge-add-mcast_flood_always-bridge-option.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 5a2ab621675d39dc9ecbd4d65d5c7a424248cd11 Mon Sep 17 00:00:00 2001 -From: Joachim Wiberg -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 ---- - 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 - diff --git a/patches/iproute2/6.1.0/0004-bridge-mdb-Add-replace-support.patch b/patches/iproute2/6.1.0/0004-bridge-mdb-Add-replace-support.patch deleted file mode 100644 index c3a11ecbd..000000000 --- a/patches/iproute2/6.1.0/0004-bridge-mdb-Add-replace-support.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 8557acdc7218cbaf2b9d70ecfa118c05f988ed77 Mon Sep 17 00:00:00 2001 -From: Ido Schimmel -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 -Reviewed-by: Nikolay Aleksandrov -Signed-off-by: David Ahern -Signed-off-by: Joachim Wiberg ---- - 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 - diff --git a/patches/iproute2/6.7.0/0001-iplink_bridge-add-mcast_flood_always-bridge-option.patch b/patches/iproute2/6.7.0/0001-iplink_bridge-add-mcast_flood_always-bridge-option.patch deleted file mode 100644 index 8fd9666d6..000000000 --- a/patches/iproute2/6.7.0/0001-iplink_bridge-add-mcast_flood_always-bridge-option.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 50fafdc63dc3d6152e2494cc693871e9bd04bfe5 Mon Sep 17 00:00:00 2001 -From: Joachim Wiberg -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 ---- - 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 - diff --git a/patches/iproute2/6.7.0/0002-ipaddress-accept-symbolic-names-also-for-show.patch b/patches/iproute2/6.7.0/0002-ipaddress-accept-symbolic-names-also-for-show.patch deleted file mode 100644 index c4215839b..000000000 --- a/patches/iproute2/6.7.0/0002-ipaddress-accept-symbolic-names-also-for-show.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 226a8b532fc074165ba76d71c4488629daed2625 Mon Sep 17 00:00:00 2001 -From: Joachim Wiberg -Date: Mon, 20 May 2024 21:35:11 +0200 -Subject: [PATCH 2/2] ipaddress: accept symbolic names also for show -Organization: Addiva Elektronik - -This is a follow-up to 709063e, which in turn was a follow-up to -bdb8d85, to add support for 'ip addr show proto static', where -'static' is defined in /etc/iproute2/rt_addrprotos. - -Signed-off-by: Joachim Wiberg ---- - 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 ---- 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) - __u8 proto; - - NEXT_ARG(); -- if (get_u8(&proto, *argv, 0)) -+ if (rtnl_addrprot_a2n(&proto, *argv)) - invarg("\"proto\" value is invalid\n", *argv); - filter.have_proto = true; - filter.proto = proto; --- -2.34.1 -