mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 05:13:01 +02:00
Add a pristine upstream patch which includes protocol info in ip the ip command. More info: https://git.kernel.org/pub/scm/network/iproute2/iproute2-next.git/commit/?id=bdb8d85
268 lines
8.1 KiB
Diff
268 lines
8.1 KiB
Diff
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
|