diff -Nru iproute2-6.1.0/debian/changelog iproute2-6.1.0/debian/changelog --- iproute2-6.1.0/debian/changelog 2023-02-14 09:10:06.000000000 +0000 +++ iproute2-6.1.0/debian/changelog 2023-10-13 13:41:31.000000000 +0000 @@ -1,3 +1,11 @@ +iproute2 (6.1.0-1ubuntu3) mantic; urgency=medium + + * Support IP address protocol (LP: #2039280): + - d/p/0002-ip-Support-IP-address-protocol.patch, + d/p/0003-ipaddress-accept-symbolic-names.patch. + + -- Paolo Pisati Fri, 13 Oct 2023 13:41:31 +0000 + iproute2 (6.1.0-1ubuntu2) lunar; urgency=medium * d/patches/0001-ip-fix-UB-in-strncpy-e.g.-truncated-ip-route-output.patch: diff -Nru iproute2-6.1.0/debian/patches/0002-ip-Support-IP-address-protocol.patch iproute2-6.1.0/debian/patches/0002-ip-Support-IP-address-protocol.patch --- iproute2-6.1.0/debian/patches/0002-ip-Support-IP-address-protocol.patch 1970-01-01 00:00:00.000000000 +0000 +++ iproute2-6.1.0/debian/patches/0002-ip-Support-IP-address-protocol.patch 2023-10-13 13:38:12.000000000 +0000 @@ -0,0 +1,268 @@ +From c5dee027b927196eacb5a32dd70f8b22918e17e3 Mon Sep 17 00:00:00 2001 +From: Petr Machata +Date: Mon, 27 Mar 2023 18:12:05 +0200 +Subject: [PATCH 1/2] 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 6358650d..e96d80f3 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 c4cb1bcb..4a20ec3c 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 5e833482..d1e47eb8 100644 +--- a/ip/ipaddress.c ++++ b/ip/ipaddress.c +@@ -62,11 +62,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" +@@ -75,7 +77,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); +@@ -1561,6 +1565,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; +@@ -1668,6 +1675,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", +@@ -2189,6 +2204,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(); +@@ -2513,6 +2536,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 b976471d..3862f0a6 100644 +--- a/lib/rt_names.c ++++ b/lib/rt_names.c +@@ -230,6 +230,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", +-- +2.40.1 + diff -Nru iproute2-6.1.0/debian/patches/0003-ipaddress-accept-symbolic-names.patch iproute2-6.1.0/debian/patches/0003-ipaddress-accept-symbolic-names.patch --- iproute2-6.1.0/debian/patches/0003-ipaddress-accept-symbolic-names.patch 1970-01-01 00:00:00.000000000 +0000 +++ iproute2-6.1.0/debian/patches/0003-ipaddress-accept-symbolic-names.patch 2023-10-13 13:39:08.000000000 +0000 @@ -0,0 +1,103 @@ +From 0f89fc7af611f3a622737ae7ae8eae08beacc00e Mon Sep 17 00:00:00 2001 +From: Stephen Hemminger +Date: Fri, 2 Jun 2023 08:51:53 -0700 +Subject: [PATCH 2/2] ipaddress: accept symbolic names + +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 +--- + 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 d1e47eb8..15d26c79 100644 +--- a/ip/ipaddress.c ++++ b/ip/ipaddress.c +@@ -2540,7 +2540,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 3862f0a6..9999f253 100644 +--- a/lib/rt_names.c ++++ b/lib/rt_names.c +@@ -246,9 +246,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(); +@@ -259,27 +259,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.40.1 + diff -Nru iproute2-6.1.0/debian/patches/series iproute2-6.1.0/debian/patches/series --- iproute2-6.1.0/debian/patches/series 2023-02-14 09:10:01.000000000 +0000 +++ iproute2-6.1.0/debian/patches/series 2023-10-13 13:40:31.000000000 +0000 @@ -2,3 +2,5 @@ 1000-ubuntu-poc-fan-driver.patch 1001-ubuntu-poc-fan-driver-v3.patch 1002-ubuntu-poc-fan-driver-vxlan.patch +0002-ip-Support-IP-address-protocol.patch +0003-ipaddress-accept-symbolic-names.patch