diff options
author | Thomas Haller <thaller@redhat.com> | 2023-07-24 15:26:31 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-07-24 15:26:36 (GMT) |
commit | 881afd58cb1e6a402c9e85c043a584d06c28e613 (patch) | |
tree | b786b0aaf1cf9096be2a8bc98e1abd7af9c386c4 | |
parent | cbafad9ddf24caef5230fef715d34f0539603be0 (diff) | |
parent | 336b15dc087c7d8a945ef954fd40da59ef8c7f81 (diff) | |
download | libnl-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.h | 17 | ||||
-rw-r--r-- | include/netlink/route/link/inet6.h | 4 | ||||
-rw-r--r-- | lib/route/link/inet6.c | 41 | ||||
-rw-r--r-- | libnl-route-3.sym | 1 |
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; |