summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-07-24 15:26:31 (GMT)
committerThomas Haller <thaller@redhat.com>2023-07-24 15:26:36 (GMT)
commit881afd58cb1e6a402c9e85c043a584d06c28e613 (patch)
treeb786b0aaf1cf9096be2a8bc98e1abd7af9c386c4
parentcbafad9ddf24caef5230fef715d34f0539603be0 (diff)
parent336b15dc087c7d8a945ef954fd40da59ef8c7f81 (diff)
downloadlibnl-881afd58cb1e6a402c9e85c043a584d06c28e613.zip
libnl-881afd58cb1e6a402c9e85c043a584d06c28e613.tar.gz
libnl-881afd58cb1e6a402c9e85c043a584d06c28e613.tar.bz2
route/link: merge branch 'abuibrahim:main' with additions
The patch from #342 with follow-ups. https://github.com/thom311/libnl/pull/342
-rw-r--r--include/linux-private/linux/ipv6.h17
-rw-r--r--include/netlink/route/link/inet6.h4
-rw-r--r--lib/route/link/inet6.c41
-rw-r--r--libnl-route-3.sym1
4 files changed, 57 insertions, 6 deletions
diff --git a/include/linux-private/linux/ipv6.h b/include/linux-private/linux/ipv6.h
index 769b4a3..fcf05a6 100644
--- a/include/linux-private/linux/ipv6.h
+++ b/include/linux-private/linux/ipv6.h
@@ -4,6 +4,7 @@
#include <linux/libc-compat.h>
#include <linux/types.h>
+#include <linux/stddef.h>
#include <linux/in6.h>
#include <asm/byteorder.h>
@@ -40,6 +41,7 @@ struct in6_ifreq {
#define IPV6_SRCRT_STRICT 0x01 /* Deprecated; will be removed */
#define IPV6_SRCRT_TYPE_0 0 /* Deprecated; will be removed */
#define IPV6_SRCRT_TYPE_2 2 /* IPv6 type 2 Routing Header */
+#define IPV6_SRCRT_TYPE_3 3 /* RPL Segment Routing with IPv6 */
#define IPV6_SRCRT_TYPE_4 4 /* Segment Routing with IPv6 */
/*
@@ -79,7 +81,7 @@ struct ipv6_opt_hdr {
struct rt0_hdr {
struct ipv6_rt_hdr rt_hdr;
__u32 reserved;
- struct in6_addr addr[0];
+ struct in6_addr addr[];
#define rt0_type rt_hdr.type
};
@@ -129,8 +131,10 @@ struct ipv6hdr {
__u8 nexthdr;
__u8 hop_limit;
- struct in6_addr saddr;
- struct in6_addr daddr;
+ __struct_group(/* no tag */, addrs, /* no attrs */,
+ struct in6_addr saddr;
+ struct in6_addr daddr;
+ );
};
@@ -187,6 +191,13 @@ enum {
DEVCONF_DISABLE_POLICY,
DEVCONF_ACCEPT_RA_RT_INFO_MIN_PLEN,
DEVCONF_NDISC_TCLASS,
+ DEVCONF_RPL_SEG_ENABLED,
+ DEVCONF_RA_DEFRTR_METRIC,
+ DEVCONF_IOAM6_ENABLED,
+ DEVCONF_IOAM6_ID,
+ DEVCONF_IOAM6_ID_WIDE,
+ DEVCONF_NDISC_EVICT_NOCARRIER,
+ DEVCONF_ACCEPT_UNTRACKED_NA,
DEVCONF_MAX
};
diff --git a/include/netlink/route/link/inet6.h b/include/netlink/route/link/inet6.h
index cf257ca..b9229e2 100644
--- a/include/netlink/route/link/inet6.h
+++ b/include/netlink/route/link/inet6.h
@@ -36,6 +36,10 @@ extern int rtnl_link_inet6_get_flags(struct rtnl_link *,
extern int rtnl_link_inet6_set_flags(struct rtnl_link *,
uint32_t);
+extern int rtnl_link_inet6_get_conf(struct rtnl_link *,
+ unsigned int,
+ uint32_t *);
+
/* Link Flags Translations */
extern char * rtnl_link_inet6_flags2str(int, char *, size_t);
extern int rtnl_link_inet6_str2flags(const char *);
diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c
index afcbbce..08b29a8 100644
--- a/lib/route/link/inet6.c
+++ b/lib/route/link/inet6.c
@@ -21,6 +21,7 @@ struct inet6_data
struct ifla_cacheinfo i6_cacheinfo;
uint32_t i6_conf[DEVCONF_MAX];
struct in6_addr i6_token;
+ uint8_t i6_conf_len;
uint8_t i6_addr_gen_mode;
};
@@ -165,9 +166,13 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
nla_memcpy(&i6->i6_cacheinfo, tb[IFLA_INET6_CACHEINFO],
sizeof(i6->i6_cacheinfo));
- if (tb[IFLA_INET6_CONF])
+ if (tb[IFLA_INET6_CONF]) {
+ i6->i6_conf_len = min(ARRAY_SIZE(i6->i6_conf),
+ nla_len(tb[IFLA_INET6_CONF]) /
+ sizeof(i6->i6_conf[0]));
nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF],
- sizeof(i6->i6_conf));
+ sizeof(i6->i6_conf[0]) * i6->i6_conf_len);
+ }
if (tb[IFLA_INET6_TOKEN])
nla_memcpy(&i6->i6_token, tb[IFLA_INET6_TOKEN],
@@ -351,7 +356,7 @@ static void inet6_dump_details(struct rtnl_link *link,
nl_dump_line(p, " devconf:\n");
nl_dump_line(p, " ");
- for (i = 0; i < DEVCONF_MAX; i++) {
+ for (i = 0; i < (int) i6->i6_conf_len; i++) {
char buf2[64];
uint32_t value = i6->i6_conf[i];
int x, offset;
@@ -689,6 +694,36 @@ int rtnl_link_inet6_set_addr_gen_mode(struct rtnl_link *link, uint8_t mode)
return 0;
}
+/**
+ * Get value of a ipv6 link configuration setting
+ * @arg link Link object
+ * @arg cfgid Configuration identifier
+ * @arg res Result pointer
+ *
+ * Stores the value of the specified configuration setting in the provided
+ * result pointer.
+ *
+ * @return 0 on success or a negative error code.
+ * @return -NLE_RANGE cfgid is out of range or not provided by kernel.
+ * @return -NLE_NOATTR configuration setting not available
+ */
+int rtnl_link_inet6_get_conf(struct rtnl_link *link, unsigned int cfgid,
+ uint32_t *res)
+{
+ struct inet6_data *id;
+
+ if (!(id = rtnl_link_af_data(link, &inet6_ops)))
+ return -NLE_NOATTR;
+
+ if (cfgid >= id->i6_conf_len)
+ return -NLE_RANGE;
+
+ *res = id->i6_conf[cfgid];
+
+ return 0;
+}
+
+
static void __init inet6_init(void)
{
rtnl_link_af_register(&inet6_ops);
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index 5e37acf..01c8e1c 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -1283,4 +1283,5 @@ global:
rtnl_link_bridge_set_vlan_filtering;
rtnl_link_bridge_set_vlan_protocol;
rtnl_link_bridge_set_vlan_stats_enabled;
+ rtnl_link_inet6_get_conf;
} libnl_3_7;