diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9d3bea3 --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: GPL-2.0 + +CC=gcc +CFLAGS=-std=gnu11 -O2 -W -Wall -Wextra -Wno-unused-parameter -Wshadow +ifeq ("$(DEBUG)","1") + CFLAGS += -g -fsanitize=address -fsanitize=leak -static-libasan +endif + +include $(wildcard *.d) + +GEN_SRCS=$(wildcard generated/*.c) +GENERATED=$(patsubst %.c,%.o,${GEN_SRCS}) + +all: ynl.a + +generated: + $(MAKE) -C $@ + +ynl.a: ynl.o generated + @echo -e "\tAR $@" + @ar rcs $@ ynl.o $(GENERATED) + +clean: + rm -f *.o *.d *~ + $(MAKE) -C generated $@ + +distclean: clean + rm -f *.a + +%.o: %.c + @echo -e "\tCC $@" + @$(COMPILE.c) -MMD -c -o $@ $< + +.PHONY: all clean generated +.DEFAULT_GOAL=all diff --git a/Makefile.deps b/Makefile.deps new file mode 100644 index 0000000..c760d9c --- /dev/null +++ b/Makefile.deps @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0 + +# Try to include uAPI headers from the kernel uapi/ path. +# Most code under tools/ requires the respective kernel uAPI headers +# to be copied to tools/include. The duplication is annoying. +# All the family headers should be self-contained. We avoid the copying +# by selectively including just the uAPI header of the family directly +# from the kernel sources. + +UAPI_PATH:=../uapi/ + +# scripts/headers_install.sh strips "_UAPI" from header guards so we +# need the explicit -D matching what's in /usr, to avoid multiple definitions. + +get_hdr_inc=-D$(1) -include $(UAPI_PATH)/linux/$(2) + +CFLAGS_devlink:=$(call get_hdr_inc,_LINUX_DEVLINK_H_,devlink.h) +CFLAGS_dpll:=$(call get_hdr_inc,_LINUX_DPLL_H,dpll.h) +CFLAGS_ethtool:=$(call get_hdr_inc,_LINUX_ETHTOOL_NETLINK_H_,ethtool_netlink.h) +CFLAGS_handshake:=$(call get_hdr_inc,_LINUX_HANDSHAKE_H,handshake.h) +CFLAGS_mptcp_pm:=$(call get_hdr_inc,_LINUX_MPTCP_PM_H,mptcp_pm.h) +CFLAGS_netdev:=$(call get_hdr_inc,_LINUX_NETDEV_H,netdev.h) +CFLAGS_nfsd:=$(call get_hdr_inc,_LINUX_NFSD_NETLINK_H,nfsd_netlink.h) +CFLAGS_ovs_datapath:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h) +CFLAGS_ovs_flow:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h) +CFLAGS_ovs_vport:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h) +CFLAGS_psp:=$(call get_hdr_inc,_LINUX_PSP_H,psp.h) diff --git a/README.md b/README.md index 0ad0be0..883f72b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,19 @@ # ynl-c -Standalone copy of generated YNL C lib + +Standalone copy of generated YNL C lib. + +Development happens in the Linux kernel: + +https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/tools/net/ynl/ + +This repo contains just the C parts, excluding all Python and +scripts, even the code generator which generated the code. + +Basic intro: + +https://docs.kernel.org/next/userspace-api/netlink/intro-specs.html#ynl-lib + +Using the library +================= + +Building the library generates an archive for static linking called ``ynl.a``. diff --git a/generated/Makefile b/generated/Makefile new file mode 100644 index 0000000..472851a --- /dev/null +++ b/generated/Makefile @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0 + +CC=gcc +CFLAGS=-std=gnu11 -O2 -W -Wall -Wextra -Wno-unused-parameter -Wshadow \ + -I../ -idirafter $(UAPI_PATH) +ifeq ("$(DEBUG)","1") + CFLAGS += -g -fsanitize=address -fsanitize=leak -static-libasan +endif + +include ../Makefile.deps + +SRCS=$(wildcard *.c) +HDRS=$(wildcard *.h) +OBJS=$(patsubst %-user.c,%-user.o,${SRCS}) + +all: $(OBJS) + +%-user.o: %-user.c %-user.h + @echo -e "\tCC $@" + @$(COMPILE.c) $(CFLAGS_$*) -o $@ $< + +clean: + rm -f *.o + +.PHONY: all clean +.DEFAULT_GOAL: all diff --git a/generated/devlink-user.c b/generated/devlink-user.c new file mode 100644 index 0000000..22607b1 --- /dev/null +++ b/generated/devlink-user.c @@ -0,0 +1,7253 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/devlink.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "devlink-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const devlink_op_strmap[] = { + [3] = "get", + // skip "port-get", duplicate reply value + [DEVLINK_CMD_PORT_NEW] = "port-new", + [13] = "sb-get", + [17] = "sb-pool-get", + [21] = "sb-port-pool-get", + [25] = "sb-tc-pool-bind-get", + [DEVLINK_CMD_ESWITCH_GET] = "eswitch-get", + [DEVLINK_CMD_DPIPE_TABLE_GET] = "dpipe-table-get", + [DEVLINK_CMD_DPIPE_ENTRIES_GET] = "dpipe-entries-get", + [DEVLINK_CMD_DPIPE_HEADERS_GET] = "dpipe-headers-get", + [DEVLINK_CMD_RESOURCE_DUMP] = "resource-dump", + [DEVLINK_CMD_RELOAD] = "reload", + [DEVLINK_CMD_PARAM_GET] = "param-get", + [DEVLINK_CMD_REGION_GET] = "region-get", + [DEVLINK_CMD_REGION_NEW] = "region-new", + [DEVLINK_CMD_REGION_READ] = "region-read", + [DEVLINK_CMD_PORT_PARAM_GET] = "port-param-get", + [DEVLINK_CMD_INFO_GET] = "info-get", + [DEVLINK_CMD_HEALTH_REPORTER_GET] = "health-reporter-get", + [DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET] = "health-reporter-dump-get", + [63] = "trap-get", + [67] = "trap-group-get", + [71] = "trap-policer-get", + [76] = "rate-get", + [80] = "linecard-get", + [DEVLINK_CMD_SELFTESTS_GET] = "selftests-get", +}; + +const char *devlink_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(devlink_op_strmap)) + return NULL; + return devlink_op_strmap[op]; +} + +static const char * const devlink_sb_pool_type_strmap[] = { + [0] = "ingress", + [1] = "egress", +}; + +const char *devlink_sb_pool_type_str(enum devlink_sb_pool_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_sb_pool_type_strmap)) + return NULL; + return devlink_sb_pool_type_strmap[value]; +} + +static const char * const devlink_port_type_strmap[] = { + [0] = "notset", + [1] = "auto", + [2] = "eth", + [3] = "ib", +}; + +const char *devlink_port_type_str(enum devlink_port_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_port_type_strmap)) + return NULL; + return devlink_port_type_strmap[value]; +} + +static const char * const devlink_port_flavour_strmap[] = { + [0] = "physical", + [1] = "cpu", + [2] = "dsa", + [3] = "pci_pf", + [4] = "pci_vf", + [5] = "virtual", + [6] = "unused", + [7] = "pci_sf", +}; + +const char *devlink_port_flavour_str(enum devlink_port_flavour value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_port_flavour_strmap)) + return NULL; + return devlink_port_flavour_strmap[value]; +} + +static const char * const devlink_port_fn_state_strmap[] = { + [0] = "inactive", + [1] = "active", +}; + +const char *devlink_port_fn_state_str(enum devlink_port_fn_state value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_port_fn_state_strmap)) + return NULL; + return devlink_port_fn_state_strmap[value]; +} + +static const char * const devlink_port_fn_opstate_strmap[] = { + [0] = "detached", + [1] = "attached", +}; + +const char *devlink_port_fn_opstate_str(enum devlink_port_fn_opstate value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_port_fn_opstate_strmap)) + return NULL; + return devlink_port_fn_opstate_strmap[value]; +} + +static const char * const devlink_port_fn_attr_cap_strmap[] = { + [0] = "roce-bit", + [1] = "migratable-bit", + [2] = "ipsec-crypto-bit", + [3] = "ipsec-packet-bit", +}; + +const char *devlink_port_fn_attr_cap_str(enum devlink_port_fn_attr_cap value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_port_fn_attr_cap_strmap)) + return NULL; + return devlink_port_fn_attr_cap_strmap[value]; +} + +static const char * const devlink_rate_type_strmap[] = { + [0] = "leaf", + [1] = "node", +}; + +const char *devlink_rate_type_str(enum devlink_rate_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_rate_type_strmap)) + return NULL; + return devlink_rate_type_strmap[value]; +} + +static const char * const devlink_sb_threshold_type_strmap[] = { + [0] = "static", + [1] = "dynamic", +}; + +const char *devlink_sb_threshold_type_str(enum devlink_sb_threshold_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_sb_threshold_type_strmap)) + return NULL; + return devlink_sb_threshold_type_strmap[value]; +} + +static const char * const devlink_eswitch_mode_strmap[] = { + [0] = "legacy", + [1] = "switchdev", +}; + +const char *devlink_eswitch_mode_str(enum devlink_eswitch_mode value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_eswitch_mode_strmap)) + return NULL; + return devlink_eswitch_mode_strmap[value]; +} + +static const char * const devlink_eswitch_inline_mode_strmap[] = { + [0] = "none", + [1] = "link", + [2] = "network", + [3] = "transport", +}; + +const char * +devlink_eswitch_inline_mode_str(enum devlink_eswitch_inline_mode value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_eswitch_inline_mode_strmap)) + return NULL; + return devlink_eswitch_inline_mode_strmap[value]; +} + +static const char * const devlink_eswitch_encap_mode_strmap[] = { + [0] = "none", + [1] = "basic", +}; + +const char * +devlink_eswitch_encap_mode_str(enum devlink_eswitch_encap_mode value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_eswitch_encap_mode_strmap)) + return NULL; + return devlink_eswitch_encap_mode_strmap[value]; +} + +static const char * const devlink_dpipe_header_id_strmap[] = { + [0] = "ethernet", + [1] = "ipv4", + [2] = "ipv6", +}; + +const char *devlink_dpipe_header_id_str(enum devlink_dpipe_header_id value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_dpipe_header_id_strmap)) + return NULL; + return devlink_dpipe_header_id_strmap[value]; +} + +static const char * const devlink_dpipe_match_type_strmap[] = { + [0] = "field-exact", +}; + +const char *devlink_dpipe_match_type_str(enum devlink_dpipe_match_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_dpipe_match_type_strmap)) + return NULL; + return devlink_dpipe_match_type_strmap[value]; +} + +static const char * const devlink_dpipe_action_type_strmap[] = { + [0] = "field-modify", +}; + +const char *devlink_dpipe_action_type_str(enum devlink_dpipe_action_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_dpipe_action_type_strmap)) + return NULL; + return devlink_dpipe_action_type_strmap[value]; +} + +static const char * const devlink_dpipe_field_mapping_type_strmap[] = { + [0] = "none", + [1] = "ifindex", +}; + +const char * +devlink_dpipe_field_mapping_type_str(enum devlink_dpipe_field_mapping_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_dpipe_field_mapping_type_strmap)) + return NULL; + return devlink_dpipe_field_mapping_type_strmap[value]; +} + +static const char * const devlink_resource_unit_strmap[] = { + [0] = "entry", +}; + +const char *devlink_resource_unit_str(enum devlink_resource_unit value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_resource_unit_strmap)) + return NULL; + return devlink_resource_unit_strmap[value]; +} + +static const char * const devlink_reload_action_strmap[] = { + [1] = "driver-reinit", + [2] = "fw-activate", +}; + +const char *devlink_reload_action_str(enum devlink_reload_action value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_reload_action_strmap)) + return NULL; + return devlink_reload_action_strmap[value]; +} + +static const char * const devlink_param_cmode_strmap[] = { + [0] = "runtime", + [1] = "driverinit", + [2] = "permanent", +}; + +const char *devlink_param_cmode_str(enum devlink_param_cmode value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_param_cmode_strmap)) + return NULL; + return devlink_param_cmode_strmap[value]; +} + +static const char * const devlink_flash_overwrite_strmap[] = { + [0] = "settings-bit", + [1] = "identifiers-bit", +}; + +const char *devlink_flash_overwrite_str(enum devlink_flash_overwrite value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_flash_overwrite_strmap)) + return NULL; + return devlink_flash_overwrite_strmap[value]; +} + +static const char * const devlink_trap_action_strmap[] = { + [0] = "drop", + [1] = "trap", + [2] = "mirror", +}; + +const char *devlink_trap_action_str(enum devlink_trap_action value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_trap_action_strmap)) + return NULL; + return devlink_trap_action_strmap[value]; +} + +static const char * const devlink_trap_type_strmap[] = { + [0] = "drop", + [1] = "exception", + [2] = "control", +}; + +const char *devlink_trap_type_str(enum devlink_trap_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(devlink_trap_type_strmap)) + return NULL; + return devlink_trap_type_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr devlink_dl_dpipe_match_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_MATCH_TYPE] = { .name = "dpipe-match-type", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_HEADER_ID] = { .name = "dpipe-header-id", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_HEADER_GLOBAL] = { .name = "dpipe-header-global", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_DPIPE_HEADER_INDEX] = { .name = "dpipe-header-index", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_FIELD_ID] = { .name = "dpipe-field-id", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_match_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_match_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_match_value_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_MATCH] = { .name = "dpipe-match", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_match_nest, }, + [DEVLINK_ATTR_DPIPE_VALUE] = { .name = "dpipe-value", .type = YNL_PT_BINARY,}, + [DEVLINK_ATTR_DPIPE_VALUE_MASK] = { .name = "dpipe-value-mask", .type = YNL_PT_BINARY,}, + [DEVLINK_ATTR_DPIPE_VALUE_MAPPING] = { .name = "dpipe-value-mapping", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_match_value_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_match_value_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_action_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_ACTION_TYPE] = { .name = "dpipe-action-type", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_HEADER_ID] = { .name = "dpipe-header-id", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_HEADER_GLOBAL] = { .name = "dpipe-header-global", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_DPIPE_HEADER_INDEX] = { .name = "dpipe-header-index", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_FIELD_ID] = { .name = "dpipe-field-id", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_action_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_action_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_action_value_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_ACTION] = { .name = "dpipe-action", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_action_nest, }, + [DEVLINK_ATTR_DPIPE_VALUE] = { .name = "dpipe-value", .type = YNL_PT_BINARY,}, + [DEVLINK_ATTR_DPIPE_VALUE_MASK] = { .name = "dpipe-value-mask", .type = YNL_PT_BINARY,}, + [DEVLINK_ATTR_DPIPE_VALUE_MAPPING] = { .name = "dpipe-value-mapping", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_action_value_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_action_value_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_field_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_FIELD_NAME] = { .name = "dpipe-field-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_DPIPE_FIELD_ID] = { .name = "dpipe-field-id", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH] = { .name = "dpipe-field-bitwidth", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE] = { .name = "dpipe-field-mapping-type", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_field_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_field_policy, +}; + +struct ynl_policy_attr devlink_dl_resource_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_RESOURCE_NAME] = { .name = "resource-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_RESOURCE_ID] = { .name = "resource-id", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE] = { .name = "resource-size", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE_NEW] = { .name = "resource-size-new", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE_VALID] = { .name = "resource-size-valid", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_RESOURCE_SIZE_MIN] = { .name = "resource-size-min", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE_MAX] = { .name = "resource-size-max", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE_GRAN] = { .name = "resource-size-gran", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_UNIT] = { .name = "resource-unit", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_RESOURCE_OCC] = { .name = "resource-occ", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest devlink_dl_resource_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_resource_policy, +}; + +struct ynl_policy_attr devlink_dl_param_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_PARAM_NAME] = { .name = "param-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_PARAM_GENERIC] = { .name = "param-generic", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_PARAM_TYPE] = { .name = "param-type", .type = YNL_PT_U8, }, +}; + +struct ynl_policy_nest devlink_dl_param_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_param_policy, +}; + +struct ynl_policy_attr devlink_dl_region_snapshot_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .name = "region-snapshot-id", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest devlink_dl_region_snapshot_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_region_snapshot_policy, +}; + +struct ynl_policy_attr devlink_dl_region_chunk_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_REGION_CHUNK_DATA] = { .name = "region-chunk-data", .type = YNL_PT_BINARY,}, + [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .name = "region-chunk-addr", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest devlink_dl_region_chunk_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_region_chunk_policy, +}; + +struct ynl_policy_attr devlink_dl_info_version_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, }, +}; + +struct ynl_policy_nest devlink_dl_info_version_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_info_version_policy, +}; + +struct ynl_policy_attr devlink_dl_fmsg_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_FMSG_OBJ_NEST_START] = { .name = "fmsg-obj-nest-start", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_FMSG_PAIR_NEST_START] = { .name = "fmsg-pair-nest-start", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_FMSG_ARR_NEST_START] = { .name = "fmsg-arr-nest-start", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_FMSG_NEST_END] = { .name = "fmsg-nest-end", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_FMSG_OBJ_NAME] = { .name = "fmsg-obj-name", .type = YNL_PT_NUL_STR, }, +}; + +struct ynl_policy_nest devlink_dl_fmsg_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_fmsg_policy, +}; + +struct ynl_policy_attr devlink_dl_health_reporter_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .name = "health-reporter-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_HEALTH_REPORTER_STATE] = { .name = "health-reporter-state", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT] = { .name = "health-reporter-err-count", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT] = { .name = "health-reporter-recover-count", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .name = "health-reporter-graceful-period", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .name = "health-reporter-auto-recover", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS] = { .name = "health-reporter-dump-ts", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS] = { .name = "health-reporter-dump-ts-ns", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .name = "health-reporter-auto-dump", .type = YNL_PT_U8, }, +}; + +struct ynl_policy_nest devlink_dl_health_reporter_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_health_reporter_policy, +}; + +struct ynl_policy_attr devlink_dl_attr_stats_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_STATS_RX_PACKETS] = { .name = "stats-rx-packets", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_STATS_RX_BYTES] = { .name = "stats-rx-bytes", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_STATS_RX_DROPPED] = { .name = "stats-rx-dropped", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest devlink_dl_attr_stats_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_attr_stats_policy, +}; + +struct ynl_policy_attr devlink_dl_trap_metadata_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT] = { .name = "trap-metadata-type-in-port", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE] = { .name = "trap-metadata-type-fa-cookie", .type = YNL_PT_FLAG, }, +}; + +struct ynl_policy_nest devlink_dl_trap_metadata_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_trap_metadata_policy, +}; + +struct ynl_policy_attr devlink_dl_port_function_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = { + [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .name = "hw-addr", .type = YNL_PT_BINARY,}, + [DEVLINK_PORT_FN_ATTR_STATE] = { .name = "state", .type = YNL_PT_U8, }, + [DEVLINK_PORT_FN_ATTR_OPSTATE] = { .name = "opstate", .type = YNL_PT_U8, }, + [DEVLINK_PORT_FN_ATTR_CAPS] = { .name = "caps", .type = YNL_PT_BITFIELD32, }, +}; + +struct ynl_policy_nest devlink_dl_port_function_nest = { + .max_attr = DEVLINK_PORT_FUNCTION_ATTR_MAX, + .table = devlink_dl_port_function_policy, +}; + +struct ynl_policy_attr devlink_dl_reload_stats_entry_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest devlink_dl_reload_stats_entry_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_reload_stats_entry_policy, +}; + +struct ynl_policy_attr devlink_dl_reload_act_stats_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, }, +}; + +struct ynl_policy_nest devlink_dl_reload_act_stats_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_reload_act_stats_policy, +}; + +struct ynl_policy_attr devlink_dl_linecard_supported_types_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_LINECARD_TYPE] = { .name = "linecard-type", .type = YNL_PT_NUL_STR, }, +}; + +struct ynl_policy_nest devlink_dl_linecard_supported_types_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_linecard_supported_types_policy, +}; + +struct ynl_policy_attr devlink_dl_selftest_id_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = { + [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .name = "flash", .type = YNL_PT_FLAG, }, +}; + +struct ynl_policy_nest devlink_dl_selftest_id_nest = { + .max_attr = DEVLINK_ATTR_SELFTEST_ID_MAX, + .table = devlink_dl_selftest_id_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_table_matches_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_MATCH] = { .name = "dpipe-match", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_match_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_table_matches_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_table_matches_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_table_actions_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_ACTION] = { .name = "dpipe-action", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_action_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_table_actions_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_table_actions_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_entry_match_values_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_MATCH_VALUE] = { .name = "dpipe-match-value", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_match_value_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_entry_match_values_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_entry_match_values_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_entry_action_values_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_ACTION_VALUE] = { .name = "dpipe-action-value", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_action_value_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_entry_action_values_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_entry_action_values_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_header_fields_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_FIELD] = { .name = "dpipe-field", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_field_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_header_fields_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_header_fields_policy, +}; + +struct ynl_policy_attr devlink_dl_resource_list_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_RESOURCE] = { .name = "resource", .type = YNL_PT_NEST, .nest = &devlink_dl_resource_nest, }, +}; + +struct ynl_policy_nest devlink_dl_resource_list_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_resource_list_policy, +}; + +struct ynl_policy_attr devlink_dl_region_snapshots_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_REGION_SNAPSHOT] = { .name = "region-snapshot", .type = YNL_PT_NEST, .nest = &devlink_dl_region_snapshot_nest, }, +}; + +struct ynl_policy_nest devlink_dl_region_snapshots_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_region_snapshots_policy, +}; + +struct ynl_policy_attr devlink_dl_region_chunks_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_REGION_CHUNK] = { .name = "region-chunk", .type = YNL_PT_NEST, .nest = &devlink_dl_region_chunk_nest, }, +}; + +struct ynl_policy_nest devlink_dl_region_chunks_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_region_chunks_policy, +}; + +struct ynl_policy_attr devlink_dl_reload_act_info_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, }, +}; + +struct ynl_policy_nest devlink_dl_reload_act_info_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_reload_act_info_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_table_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .name = "dpipe-table-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_DPIPE_TABLE_SIZE] = { .name = "dpipe-table-size", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_DPIPE_TABLE_MATCHES] = { .name = "dpipe-table-matches", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_table_matches_nest, }, + [DEVLINK_ATTR_DPIPE_TABLE_ACTIONS] = { .name = "dpipe-table-actions", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_table_actions_nest, }, + [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .name = "dpipe-table-counters-enabled", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID] = { .name = "dpipe-table-resource-id", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS] = { .name = "dpipe-table-resource-units", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_table_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_table_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_entry_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_ENTRY_INDEX] = { .name = "dpipe-entry-index", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES] = { .name = "dpipe-entry-match-values", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_entry_match_values_nest, }, + [DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES] = { .name = "dpipe-entry-action-values", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_entry_action_values_nest, }, + [DEVLINK_ATTR_DPIPE_ENTRY_COUNTER] = { .name = "dpipe-entry-counter", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_entry_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_entry_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_header_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_HEADER_NAME] = { .name = "dpipe-header-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_DPIPE_HEADER_ID] = { .name = "dpipe-header-id", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_HEADER_GLOBAL] = { .name = "dpipe-header-global", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_DPIPE_HEADER_FIELDS] = { .name = "dpipe-header-fields", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_header_fields_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_header_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_header_policy, +}; + +struct ynl_policy_attr devlink_dl_reload_stats_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, }, +}; + +struct ynl_policy_nest devlink_dl_reload_stats_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_reload_stats_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_tables_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_TABLE] = { .name = "dpipe-table", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_table_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_tables_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_tables_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_entries_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_ENTRY] = { .name = "dpipe-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_entry_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_entries_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_entries_policy, +}; + +struct ynl_policy_attr devlink_dl_dpipe_headers_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_DPIPE_HEADER] = { .name = "dpipe-header", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_header_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dpipe_headers_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dpipe_headers_policy, +}; + +struct ynl_policy_attr devlink_dl_dev_stats_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, }, + [DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, }, +}; + +struct ynl_policy_nest devlink_dl_dev_stats_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_dl_dev_stats_policy, +}; + +struct ynl_policy_attr devlink_policy[DEVLINK_ATTR_MAX + 1] = { + [DEVLINK_ATTR_BUS_NAME] = { .name = "bus-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_DEV_NAME] = { .name = "dev-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_PORT_INDEX] = { .name = "port-index", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_PORT_TYPE] = { .name = "port-type", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_PORT_DESIRED_TYPE] = { .name = "port-desired-type", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_PORT_NETDEV_IFINDEX] = { .name = "port-netdev-ifindex", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_PORT_NETDEV_NAME] = { .name = "port-netdev-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_PORT_IBDEV_NAME] = { .name = "port-ibdev-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .name = "port-split-count", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_PORT_SPLIT_GROUP] = { .name = "port-split-group", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_SB_INDEX] = { .name = "sb-index", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_SB_SIZE] = { .name = "sb-size", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_SB_INGRESS_POOL_COUNT] = { .name = "sb-ingress-pool-count", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_SB_EGRESS_POOL_COUNT] = { .name = "sb-egress-pool-count", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_SB_INGRESS_TC_COUNT] = { .name = "sb-ingress-tc-count", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_SB_EGRESS_TC_COUNT] = { .name = "sb-egress-tc-count", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_SB_POOL_INDEX] = { .name = "sb-pool-index", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_SB_POOL_TYPE] = { .name = "sb-pool-type", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_SB_POOL_SIZE] = { .name = "sb-pool-size", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .name = "sb-pool-threshold-type", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_SB_THRESHOLD] = { .name = "sb-threshold", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_SB_TC_INDEX] = { .name = "sb-tc-index", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_SB_OCC_CUR] = { .name = "sb-occ-cur", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_SB_OCC_MAX] = { .name = "sb-occ-max", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_ESWITCH_MODE] = { .name = "eswitch-mode", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .name = "eswitch-inline-mode", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_DPIPE_TABLES] = { .name = "dpipe-tables", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_tables_nest, }, + [DEVLINK_ATTR_DPIPE_TABLE] = { .name = "dpipe-table", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_table_nest, }, + [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .name = "dpipe-table-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_DPIPE_TABLE_SIZE] = { .name = "dpipe-table-size", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_DPIPE_TABLE_MATCHES] = { .name = "dpipe-table-matches", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_table_matches_nest, }, + [DEVLINK_ATTR_DPIPE_TABLE_ACTIONS] = { .name = "dpipe-table-actions", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_table_actions_nest, }, + [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .name = "dpipe-table-counters-enabled", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_DPIPE_ENTRIES] = { .name = "dpipe-entries", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_entries_nest, }, + [DEVLINK_ATTR_DPIPE_ENTRY] = { .name = "dpipe-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_entry_nest, }, + [DEVLINK_ATTR_DPIPE_ENTRY_INDEX] = { .name = "dpipe-entry-index", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES] = { .name = "dpipe-entry-match-values", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_entry_match_values_nest, }, + [DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES] = { .name = "dpipe-entry-action-values", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_entry_action_values_nest, }, + [DEVLINK_ATTR_DPIPE_ENTRY_COUNTER] = { .name = "dpipe-entry-counter", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_DPIPE_MATCH] = { .name = "dpipe-match", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_match_nest, }, + [DEVLINK_ATTR_DPIPE_MATCH_VALUE] = { .name = "dpipe-match-value", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_match_value_nest, }, + [DEVLINK_ATTR_DPIPE_MATCH_TYPE] = { .name = "dpipe-match-type", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_ACTION] = { .name = "dpipe-action", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_action_nest, }, + [DEVLINK_ATTR_DPIPE_ACTION_VALUE] = { .name = "dpipe-action-value", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_action_value_nest, }, + [DEVLINK_ATTR_DPIPE_ACTION_TYPE] = { .name = "dpipe-action-type", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_VALUE] = { .name = "dpipe-value", .type = YNL_PT_BINARY,}, + [DEVLINK_ATTR_DPIPE_VALUE_MASK] = { .name = "dpipe-value-mask", .type = YNL_PT_BINARY,}, + [DEVLINK_ATTR_DPIPE_VALUE_MAPPING] = { .name = "dpipe-value-mapping", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_HEADERS] = { .name = "dpipe-headers", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_headers_nest, }, + [DEVLINK_ATTR_DPIPE_HEADER] = { .name = "dpipe-header", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_header_nest, }, + [DEVLINK_ATTR_DPIPE_HEADER_NAME] = { .name = "dpipe-header-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_DPIPE_HEADER_ID] = { .name = "dpipe-header-id", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_HEADER_FIELDS] = { .name = "dpipe-header-fields", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_header_fields_nest, }, + [DEVLINK_ATTR_DPIPE_HEADER_GLOBAL] = { .name = "dpipe-header-global", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_DPIPE_HEADER_INDEX] = { .name = "dpipe-header-index", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_FIELD] = { .name = "dpipe-field", .type = YNL_PT_NEST, .nest = &devlink_dl_dpipe_field_nest, }, + [DEVLINK_ATTR_DPIPE_FIELD_NAME] = { .name = "dpipe-field-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_DPIPE_FIELD_ID] = { .name = "dpipe-field-id", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH] = { .name = "dpipe-field-bitwidth", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE] = { .name = "dpipe-field-mapping-type", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .name = "eswitch-encap-mode", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_RESOURCE_LIST] = { .name = "resource-list", .type = YNL_PT_NEST, .nest = &devlink_dl_resource_list_nest, }, + [DEVLINK_ATTR_RESOURCE] = { .name = "resource", .type = YNL_PT_NEST, .nest = &devlink_dl_resource_nest, }, + [DEVLINK_ATTR_RESOURCE_NAME] = { .name = "resource-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_RESOURCE_ID] = { .name = "resource-id", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE] = { .name = "resource-size", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE_NEW] = { .name = "resource-size-new", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE_VALID] = { .name = "resource-size-valid", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_RESOURCE_SIZE_MIN] = { .name = "resource-size-min", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE_MAX] = { .name = "resource-size-max", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_SIZE_GRAN] = { .name = "resource-size-gran", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RESOURCE_UNIT] = { .name = "resource-unit", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_RESOURCE_OCC] = { .name = "resource-occ", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID] = { .name = "dpipe-table-resource-id", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS] = { .name = "dpipe-table-resource-units", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_PORT_FLAVOUR] = { .name = "port-flavour", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_PORT_NUMBER] = { .name = "port-number", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER] = { .name = "port-split-subport-number", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_PARAM] = { .name = "param", .type = YNL_PT_NEST, .nest = &devlink_dl_param_nest, }, + [DEVLINK_ATTR_PARAM_NAME] = { .name = "param-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_PARAM_GENERIC] = { .name = "param-generic", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_PARAM_TYPE] = { .name = "param-type", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .name = "param-value-cmode", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_REGION_NAME] = { .name = "region-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_REGION_SIZE] = { .name = "region-size", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_REGION_SNAPSHOTS] = { .name = "region-snapshots", .type = YNL_PT_NEST, .nest = &devlink_dl_region_snapshots_nest, }, + [DEVLINK_ATTR_REGION_SNAPSHOT] = { .name = "region-snapshot", .type = YNL_PT_NEST, .nest = &devlink_dl_region_snapshot_nest, }, + [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .name = "region-snapshot-id", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_REGION_CHUNKS] = { .name = "region-chunks", .type = YNL_PT_NEST, .nest = &devlink_dl_region_chunks_nest, }, + [DEVLINK_ATTR_REGION_CHUNK] = { .name = "region-chunk", .type = YNL_PT_NEST, .nest = &devlink_dl_region_chunk_nest, }, + [DEVLINK_ATTR_REGION_CHUNK_DATA] = { .name = "region-chunk-data", .type = YNL_PT_BINARY,}, + [DEVLINK_ATTR_REGION_CHUNK_ADDR] = { .name = "region-chunk-addr", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_REGION_CHUNK_LEN] = { .name = "region-chunk-len", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_INFO_DRIVER_NAME] = { .name = "info-driver-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_INFO_SERIAL_NUMBER] = { .name = "info-serial-number", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_INFO_VERSION_FIXED] = { .name = "info-version-fixed", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, }, + [DEVLINK_ATTR_INFO_VERSION_RUNNING] = { .name = "info-version-running", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, }, + [DEVLINK_ATTR_INFO_VERSION_STORED] = { .name = "info-version-stored", .type = YNL_PT_NEST, .nest = &devlink_dl_info_version_nest, }, + [DEVLINK_ATTR_INFO_VERSION_NAME] = { .name = "info-version-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_INFO_VERSION_VALUE] = { .name = "info-version-value", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_SB_POOL_CELL_SIZE] = { .name = "sb-pool-cell-size", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_FMSG] = { .name = "fmsg", .type = YNL_PT_NEST, .nest = &devlink_dl_fmsg_nest, }, + [DEVLINK_ATTR_FMSG_OBJ_NEST_START] = { .name = "fmsg-obj-nest-start", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_FMSG_PAIR_NEST_START] = { .name = "fmsg-pair-nest-start", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_FMSG_ARR_NEST_START] = { .name = "fmsg-arr-nest-start", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_FMSG_NEST_END] = { .name = "fmsg-nest-end", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_FMSG_OBJ_NAME] = { .name = "fmsg-obj-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE] = { .name = "fmsg-obj-value-type", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_HEALTH_REPORTER] = { .name = "health-reporter", .type = YNL_PT_NEST, .nest = &devlink_dl_health_reporter_nest, }, + [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .name = "health-reporter-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_HEALTH_REPORTER_STATE] = { .name = "health-reporter-state", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT] = { .name = "health-reporter-err-count", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT] = { .name = "health-reporter-recover-count", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS] = { .name = "health-reporter-dump-ts", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .name = "health-reporter-graceful-period", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .name = "health-reporter-auto-recover", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .name = "flash-update-file-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .name = "flash-update-component", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG] = { .name = "flash-update-status-msg", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE] = { .name = "flash-update-status-done", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL] = { .name = "flash-update-status-total", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .name = "port-pci-pf-number", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_PORT_PCI_VF_NUMBER] = { .name = "port-pci-vf-number", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_STATS] = { .name = "stats", .type = YNL_PT_NEST, .nest = &devlink_dl_attr_stats_nest, }, + [DEVLINK_ATTR_TRAP_NAME] = { .name = "trap-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_TRAP_ACTION] = { .name = "trap-action", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_TRAP_TYPE] = { .name = "trap-type", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_TRAP_GENERIC] = { .name = "trap-generic", .type = YNL_PT_FLAG, }, + [DEVLINK_ATTR_TRAP_METADATA] = { .name = "trap-metadata", .type = YNL_PT_NEST, .nest = &devlink_dl_trap_metadata_nest, }, + [DEVLINK_ATTR_TRAP_GROUP_NAME] = { .name = "trap-group-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_RELOAD_FAILED] = { .name = "reload-failed", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS] = { .name = "health-reporter-dump-ts-ns", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_NETNS_FD] = { .name = "netns-fd", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_NETNS_PID] = { .name = "netns-pid", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_NETNS_ID] = { .name = "netns-id", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP] = { .name = "health-reporter-auto-dump", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_TRAP_POLICER_ID] = { .name = "trap-policer-id", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .name = "trap-policer-rate", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .name = "trap-policer-burst", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_PORT_FUNCTION] = { .name = "port-function", .type = YNL_PT_NEST, .nest = &devlink_dl_port_function_nest, }, + [DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER] = { .name = "info-board-serial-number", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_PORT_LANES] = { .name = "port-lanes", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_PORT_SPLITTABLE] = { .name = "port-splittable", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_PORT_EXTERNAL] = { .name = "port-external", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_PORT_CONTROLLER_NUMBER] = { .name = "port-controller-number", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT] = { .name = "flash-update-status-timeout", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] = { .name = "flash-update-overwrite-mask", .type = YNL_PT_BITFIELD32, }, + [DEVLINK_ATTR_RELOAD_ACTION] = { .name = "reload-action", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED] = { .name = "reload-actions-performed", .type = YNL_PT_BITFIELD32, }, + [DEVLINK_ATTR_RELOAD_LIMITS] = { .name = "reload-limits", .type = YNL_PT_BITFIELD32, }, + [DEVLINK_ATTR_DEV_STATS] = { .name = "dev-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_dev_stats_nest, }, + [DEVLINK_ATTR_RELOAD_STATS] = { .name = "reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, }, + [DEVLINK_ATTR_RELOAD_STATS_ENTRY] = { .name = "reload-stats-entry", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_entry_nest, }, + [DEVLINK_ATTR_RELOAD_STATS_LIMIT] = { .name = "reload-stats-limit", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_RELOAD_STATS_VALUE] = { .name = "reload-stats-value", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_REMOTE_RELOAD_STATS] = { .name = "remote-reload-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_stats_nest, }, + [DEVLINK_ATTR_RELOAD_ACTION_INFO] = { .name = "reload-action-info", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_info_nest, }, + [DEVLINK_ATTR_RELOAD_ACTION_STATS] = { .name = "reload-action-stats", .type = YNL_PT_NEST, .nest = &devlink_dl_reload_act_stats_nest, }, + [DEVLINK_ATTR_PORT_PCI_SF_NUMBER] = { .name = "port-pci-sf-number", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_RATE_TYPE] = { .name = "rate-type", .type = YNL_PT_U16, }, + [DEVLINK_ATTR_RATE_TX_SHARE] = { .name = "rate-tx-share", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RATE_TX_MAX] = { .name = "rate-tx-max", .type = YNL_PT_U64, }, + [DEVLINK_ATTR_RATE_NODE_NAME] = { .name = "rate-node-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .name = "rate-parent-node-name", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_REGION_MAX_SNAPSHOTS] = { .name = "region-max-snapshots", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_LINECARD_INDEX] = { .name = "linecard-index", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_LINECARD_STATE] = { .name = "linecard-state", .type = YNL_PT_U8, }, + [DEVLINK_ATTR_LINECARD_TYPE] = { .name = "linecard-type", .type = YNL_PT_NUL_STR, }, + [DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES] = { .name = "linecard-supported-types", .type = YNL_PT_NEST, .nest = &devlink_dl_linecard_supported_types_nest, }, + [DEVLINK_ATTR_SELFTESTS] = { .name = "selftests", .type = YNL_PT_NEST, .nest = &devlink_dl_selftest_id_nest, }, + [DEVLINK_ATTR_RATE_TX_PRIORITY] = { .name = "rate-tx-priority", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_RATE_TX_WEIGHT] = { .name = "rate-tx-weight", .type = YNL_PT_U32, }, + [DEVLINK_ATTR_REGION_DIRECT] = { .name = "region-direct", .type = YNL_PT_FLAG, }, +}; + +struct ynl_policy_nest devlink_nest = { + .max_attr = DEVLINK_ATTR_MAX, + .table = devlink_policy, +}; + +/* Common nested types */ +void devlink_dl_dpipe_match_free(struct devlink_dl_dpipe_match *obj) +{ +} + +int devlink_dl_dpipe_match_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_match *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_MATCH_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_match_type = 1; + dst->dpipe_match_type = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_DPIPE_HEADER_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_header_id = 1; + dst->dpipe_header_id = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_DPIPE_HEADER_GLOBAL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_header_global = 1; + dst->dpipe_header_global = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_DPIPE_HEADER_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_header_index = 1; + dst->dpipe_header_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_DPIPE_FIELD_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_field_id = 1; + dst->dpipe_field_id = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void +devlink_dl_dpipe_match_value_free(struct devlink_dl_dpipe_match_value *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_match; i++) + devlink_dl_dpipe_match_free(&obj->dpipe_match[i]); + free(obj->dpipe_match); + free(obj->dpipe_value); + free(obj->dpipe_value_mask); +} + +int devlink_dl_dpipe_match_value_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_match_value *dst = yarg->data; + unsigned int n_dpipe_match = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_match) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-match-value.dpipe-match)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_MATCH) { + n_dpipe_match++; + } else if (type == DEVLINK_ATTR_DPIPE_VALUE) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.dpipe_value_len = len; + dst->dpipe_value = malloc(len); + memcpy(dst->dpipe_value, ynl_attr_data(attr), len); + } else if (type == DEVLINK_ATTR_DPIPE_VALUE_MASK) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.dpipe_value_mask_len = len; + dst->dpipe_value_mask = malloc(len); + memcpy(dst->dpipe_value_mask, ynl_attr_data(attr), len); + } else if (type == DEVLINK_ATTR_DPIPE_VALUE_MAPPING) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_value_mapping = 1; + dst->dpipe_value_mapping = ynl_attr_get_u32(attr); + } + } + + if (n_dpipe_match) { + dst->dpipe_match = calloc(n_dpipe_match, sizeof(*dst->dpipe_match)); + dst->n_dpipe_match = n_dpipe_match; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_match_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_MATCH) { + parg.data = &dst->dpipe_match[i]; + if (devlink_dl_dpipe_match_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void devlink_dl_dpipe_action_free(struct devlink_dl_dpipe_action *obj) +{ +} + +int devlink_dl_dpipe_action_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_action *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_ACTION_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_action_type = 1; + dst->dpipe_action_type = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_DPIPE_HEADER_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_header_id = 1; + dst->dpipe_header_id = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_DPIPE_HEADER_GLOBAL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_header_global = 1; + dst->dpipe_header_global = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_DPIPE_HEADER_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_header_index = 1; + dst->dpipe_header_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_DPIPE_FIELD_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_field_id = 1; + dst->dpipe_field_id = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void +devlink_dl_dpipe_action_value_free(struct devlink_dl_dpipe_action_value *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_action; i++) + devlink_dl_dpipe_action_free(&obj->dpipe_action[i]); + free(obj->dpipe_action); + free(obj->dpipe_value); + free(obj->dpipe_value_mask); +} + +int devlink_dl_dpipe_action_value_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_action_value *dst = yarg->data; + unsigned int n_dpipe_action = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_action) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-action-value.dpipe-action)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_ACTION) { + n_dpipe_action++; + } else if (type == DEVLINK_ATTR_DPIPE_VALUE) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.dpipe_value_len = len; + dst->dpipe_value = malloc(len); + memcpy(dst->dpipe_value, ynl_attr_data(attr), len); + } else if (type == DEVLINK_ATTR_DPIPE_VALUE_MASK) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.dpipe_value_mask_len = len; + dst->dpipe_value_mask = malloc(len); + memcpy(dst->dpipe_value_mask, ynl_attr_data(attr), len); + } else if (type == DEVLINK_ATTR_DPIPE_VALUE_MAPPING) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_value_mapping = 1; + dst->dpipe_value_mapping = ynl_attr_get_u32(attr); + } + } + + if (n_dpipe_action) { + dst->dpipe_action = calloc(n_dpipe_action, sizeof(*dst->dpipe_action)); + dst->n_dpipe_action = n_dpipe_action; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_action_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_ACTION) { + parg.data = &dst->dpipe_action[i]; + if (devlink_dl_dpipe_action_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void devlink_dl_dpipe_field_free(struct devlink_dl_dpipe_field *obj) +{ + free(obj->dpipe_field_name); +} + +int devlink_dl_dpipe_field_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_field *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_FIELD_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dpipe_field_name_len = len; + dst->dpipe_field_name = malloc(len + 1); + memcpy(dst->dpipe_field_name, ynl_attr_get_str(attr), len); + dst->dpipe_field_name[len] = 0; + } else if (type == DEVLINK_ATTR_DPIPE_FIELD_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_field_id = 1; + dst->dpipe_field_id = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_field_bitwidth = 1; + dst->dpipe_field_bitwidth = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_field_mapping_type = 1; + dst->dpipe_field_mapping_type = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void devlink_dl_resource_free(struct devlink_dl_resource *obj) +{ + free(obj->resource_name); +} + +int devlink_dl_resource_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_resource *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_RESOURCE_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.resource_name_len = len; + dst->resource_name = malloc(len + 1); + memcpy(dst->resource_name, ynl_attr_get_str(attr), len); + dst->resource_name[len] = 0; + } else if (type == DEVLINK_ATTR_RESOURCE_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_id = 1; + dst->resource_id = ynl_attr_get_u64(attr); + } else if (type == DEVLINK_ATTR_RESOURCE_SIZE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_size = 1; + dst->resource_size = ynl_attr_get_u64(attr); + } else if (type == DEVLINK_ATTR_RESOURCE_SIZE_NEW) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_size_new = 1; + dst->resource_size_new = ynl_attr_get_u64(attr); + } else if (type == DEVLINK_ATTR_RESOURCE_SIZE_VALID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_size_valid = 1; + dst->resource_size_valid = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_RESOURCE_SIZE_MIN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_size_min = 1; + dst->resource_size_min = ynl_attr_get_u64(attr); + } else if (type == DEVLINK_ATTR_RESOURCE_SIZE_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_size_max = 1; + dst->resource_size_max = ynl_attr_get_u64(attr); + } else if (type == DEVLINK_ATTR_RESOURCE_SIZE_GRAN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_size_gran = 1; + dst->resource_size_gran = ynl_attr_get_u64(attr); + } else if (type == DEVLINK_ATTR_RESOURCE_UNIT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_unit = 1; + dst->resource_unit = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_RESOURCE_OCC) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_occ = 1; + dst->resource_occ = ynl_attr_get_u64(attr); + } + } + + return 0; +} + +void devlink_dl_param_free(struct devlink_dl_param *obj) +{ + free(obj->param_name); +} + +void devlink_dl_region_snapshot_free(struct devlink_dl_region_snapshot *obj) +{ +} + +void devlink_dl_region_chunk_free(struct devlink_dl_region_chunk *obj) +{ + free(obj->region_chunk_data); +} + +void devlink_dl_info_version_free(struct devlink_dl_info_version *obj) +{ + free(obj->info_version_name); + free(obj->info_version_value); +} + +int devlink_dl_info_version_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_info_version *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_INFO_VERSION_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.info_version_name_len = len; + dst->info_version_name = malloc(len + 1); + memcpy(dst->info_version_name, ynl_attr_get_str(attr), len); + dst->info_version_name[len] = 0; + } else if (type == DEVLINK_ATTR_INFO_VERSION_VALUE) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.info_version_value_len = len; + dst->info_version_value = malloc(len + 1); + memcpy(dst->info_version_value, ynl_attr_get_str(attr), len); + dst->info_version_value[len] = 0; + } + } + + return 0; +} + +void devlink_dl_fmsg_free(struct devlink_dl_fmsg *obj) +{ + free(obj->fmsg_obj_name); +} + +int devlink_dl_fmsg_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_fmsg *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_FMSG_OBJ_NEST_START) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.fmsg_obj_nest_start = 1; + } else if (type == DEVLINK_ATTR_FMSG_PAIR_NEST_START) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.fmsg_pair_nest_start = 1; + } else if (type == DEVLINK_ATTR_FMSG_ARR_NEST_START) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.fmsg_arr_nest_start = 1; + } else if (type == DEVLINK_ATTR_FMSG_NEST_END) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.fmsg_nest_end = 1; + } else if (type == DEVLINK_ATTR_FMSG_OBJ_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.fmsg_obj_name_len = len; + dst->fmsg_obj_name = malloc(len + 1); + memcpy(dst->fmsg_obj_name, ynl_attr_get_str(attr), len); + dst->fmsg_obj_name[len] = 0; + } + } + + return 0; +} + +void devlink_dl_health_reporter_free(struct devlink_dl_health_reporter *obj) +{ + free(obj->health_reporter_name); +} + +void devlink_dl_attr_stats_free(struct devlink_dl_attr_stats *obj) +{ +} + +void devlink_dl_trap_metadata_free(struct devlink_dl_trap_metadata *obj) +{ +} + +void devlink_dl_port_function_free(struct devlink_dl_port_function *obj) +{ + free(obj->hw_addr); +} + +int devlink_dl_port_function_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct devlink_dl_port_function *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.hw_addr_len) + ynl_attr_put(nlh, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, obj->hw_addr, obj->_present.hw_addr_len); + if (obj->_present.state) + ynl_attr_put_u8(nlh, DEVLINK_PORT_FN_ATTR_STATE, obj->state); + if (obj->_present.opstate) + ynl_attr_put_u8(nlh, DEVLINK_PORT_FN_ATTR_OPSTATE, obj->opstate); + if (obj->_present.caps) + ynl_attr_put(nlh, DEVLINK_PORT_FN_ATTR_CAPS, &obj->caps, sizeof(struct nla_bitfield32)); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +void +devlink_dl_reload_stats_entry_free(struct devlink_dl_reload_stats_entry *obj) +{ +} + +int devlink_dl_reload_stats_entry_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_reload_stats_entry *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_STATS_LIMIT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.reload_stats_limit = 1; + dst->reload_stats_limit = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_RELOAD_STATS_VALUE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.reload_stats_value = 1; + dst->reload_stats_value = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void devlink_dl_reload_act_stats_free(struct devlink_dl_reload_act_stats *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_reload_stats_entry; i++) + devlink_dl_reload_stats_entry_free(&obj->reload_stats_entry[i]); + free(obj->reload_stats_entry); +} + +int devlink_dl_reload_act_stats_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_reload_act_stats *dst = yarg->data; + unsigned int n_reload_stats_entry = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->reload_stats_entry) + return ynl_error_parse(yarg, "attribute already present (dl-reload-act-stats.reload-stats-entry)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_STATS_ENTRY) { + n_reload_stats_entry++; + } + } + + if (n_reload_stats_entry) { + dst->reload_stats_entry = calloc(n_reload_stats_entry, sizeof(*dst->reload_stats_entry)); + dst->n_reload_stats_entry = n_reload_stats_entry; + i = 0; + parg.rsp_policy = &devlink_dl_reload_stats_entry_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_RELOAD_STATS_ENTRY) { + parg.data = &dst->reload_stats_entry[i]; + if (devlink_dl_reload_stats_entry_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void +devlink_dl_linecard_supported_types_free(struct devlink_dl_linecard_supported_types *obj) +{ + free(obj->linecard_type); +} + +void devlink_dl_selftest_id_free(struct devlink_dl_selftest_id *obj) +{ +} + +int devlink_dl_selftest_id_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct devlink_dl_selftest_id *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.flash) + ynl_attr_put(nlh, DEVLINK_ATTR_SELFTEST_ID_FLASH, NULL, 0); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +void +devlink_dl_dpipe_table_matches_free(struct devlink_dl_dpipe_table_matches *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_match; i++) + devlink_dl_dpipe_match_free(&obj->dpipe_match[i]); + free(obj->dpipe_match); +} + +int devlink_dl_dpipe_table_matches_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_table_matches *dst = yarg->data; + unsigned int n_dpipe_match = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_match) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-table-matches.dpipe-match)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_MATCH) { + n_dpipe_match++; + } + } + + if (n_dpipe_match) { + dst->dpipe_match = calloc(n_dpipe_match, sizeof(*dst->dpipe_match)); + dst->n_dpipe_match = n_dpipe_match; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_match_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_MATCH) { + parg.data = &dst->dpipe_match[i]; + if (devlink_dl_dpipe_match_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void +devlink_dl_dpipe_table_actions_free(struct devlink_dl_dpipe_table_actions *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_action; i++) + devlink_dl_dpipe_action_free(&obj->dpipe_action[i]); + free(obj->dpipe_action); +} + +int devlink_dl_dpipe_table_actions_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_table_actions *dst = yarg->data; + unsigned int n_dpipe_action = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_action) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-table-actions.dpipe-action)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_ACTION) { + n_dpipe_action++; + } + } + + if (n_dpipe_action) { + dst->dpipe_action = calloc(n_dpipe_action, sizeof(*dst->dpipe_action)); + dst->n_dpipe_action = n_dpipe_action; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_action_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_ACTION) { + parg.data = &dst->dpipe_action[i]; + if (devlink_dl_dpipe_action_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void +devlink_dl_dpipe_entry_match_values_free(struct devlink_dl_dpipe_entry_match_values *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_match_value; i++) + devlink_dl_dpipe_match_value_free(&obj->dpipe_match_value[i]); + free(obj->dpipe_match_value); +} + +int devlink_dl_dpipe_entry_match_values_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_entry_match_values *dst = yarg->data; + unsigned int n_dpipe_match_value = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_match_value) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-entry-match-values.dpipe-match-value)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_MATCH_VALUE) { + n_dpipe_match_value++; + } + } + + if (n_dpipe_match_value) { + dst->dpipe_match_value = calloc(n_dpipe_match_value, sizeof(*dst->dpipe_match_value)); + dst->n_dpipe_match_value = n_dpipe_match_value; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_match_value_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_MATCH_VALUE) { + parg.data = &dst->dpipe_match_value[i]; + if (devlink_dl_dpipe_match_value_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void +devlink_dl_dpipe_entry_action_values_free(struct devlink_dl_dpipe_entry_action_values *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_action_value; i++) + devlink_dl_dpipe_action_value_free(&obj->dpipe_action_value[i]); + free(obj->dpipe_action_value); +} + +int devlink_dl_dpipe_entry_action_values_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_entry_action_values *dst = yarg->data; + unsigned int n_dpipe_action_value = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_action_value) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-entry-action-values.dpipe-action-value)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_ACTION_VALUE) { + n_dpipe_action_value++; + } + } + + if (n_dpipe_action_value) { + dst->dpipe_action_value = calloc(n_dpipe_action_value, sizeof(*dst->dpipe_action_value)); + dst->n_dpipe_action_value = n_dpipe_action_value; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_action_value_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_ACTION_VALUE) { + parg.data = &dst->dpipe_action_value[i]; + if (devlink_dl_dpipe_action_value_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void +devlink_dl_dpipe_header_fields_free(struct devlink_dl_dpipe_header_fields *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_field; i++) + devlink_dl_dpipe_field_free(&obj->dpipe_field[i]); + free(obj->dpipe_field); +} + +int devlink_dl_dpipe_header_fields_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_header_fields *dst = yarg->data; + unsigned int n_dpipe_field = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_field) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-header-fields.dpipe-field)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_FIELD) { + n_dpipe_field++; + } + } + + if (n_dpipe_field) { + dst->dpipe_field = calloc(n_dpipe_field, sizeof(*dst->dpipe_field)); + dst->n_dpipe_field = n_dpipe_field; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_field_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_FIELD) { + parg.data = &dst->dpipe_field[i]; + if (devlink_dl_dpipe_field_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void devlink_dl_resource_list_free(struct devlink_dl_resource_list *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_resource; i++) + devlink_dl_resource_free(&obj->resource[i]); + free(obj->resource); +} + +int devlink_dl_resource_list_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_resource_list *dst = yarg->data; + unsigned int n_resource = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->resource) + return ynl_error_parse(yarg, "attribute already present (dl-resource-list.resource)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_RESOURCE) { + n_resource++; + } + } + + if (n_resource) { + dst->resource = calloc(n_resource, sizeof(*dst->resource)); + dst->n_resource = n_resource; + i = 0; + parg.rsp_policy = &devlink_dl_resource_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_RESOURCE) { + parg.data = &dst->resource[i]; + if (devlink_dl_resource_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void devlink_dl_region_snapshots_free(struct devlink_dl_region_snapshots *obj) +{ + devlink_dl_region_snapshot_free(&obj->region_snapshot); +} + +void devlink_dl_region_chunks_free(struct devlink_dl_region_chunks *obj) +{ + devlink_dl_region_chunk_free(&obj->region_chunk); +} + +void devlink_dl_reload_act_info_free(struct devlink_dl_reload_act_info *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_reload_action_stats; i++) + devlink_dl_reload_act_stats_free(&obj->reload_action_stats[i]); + free(obj->reload_action_stats); +} + +int devlink_dl_reload_act_info_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_reload_act_info *dst = yarg->data; + unsigned int n_reload_action_stats = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->reload_action_stats) + return ynl_error_parse(yarg, "attribute already present (dl-reload-act-info.reload-action-stats)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_ACTION) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.reload_action = 1; + dst->reload_action = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_RELOAD_ACTION_STATS) { + n_reload_action_stats++; + } + } + + if (n_reload_action_stats) { + dst->reload_action_stats = calloc(n_reload_action_stats, sizeof(*dst->reload_action_stats)); + dst->n_reload_action_stats = n_reload_action_stats; + i = 0; + parg.rsp_policy = &devlink_dl_reload_act_stats_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_STATS) { + parg.data = &dst->reload_action_stats[i]; + if (devlink_dl_reload_act_stats_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void devlink_dl_dpipe_table_free(struct devlink_dl_dpipe_table *obj) +{ + free(obj->dpipe_table_name); + devlink_dl_dpipe_table_matches_free(&obj->dpipe_table_matches); + devlink_dl_dpipe_table_actions_free(&obj->dpipe_table_actions); +} + +int devlink_dl_dpipe_table_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_table *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_TABLE_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dpipe_table_name_len = len; + dst->dpipe_table_name = malloc(len + 1); + memcpy(dst->dpipe_table_name, ynl_attr_get_str(attr), len); + dst->dpipe_table_name[len] = 0; + } else if (type == DEVLINK_ATTR_DPIPE_TABLE_SIZE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_table_size = 1; + dst->dpipe_table_size = ynl_attr_get_u64(attr); + } else if (type == DEVLINK_ATTR_DPIPE_TABLE_MATCHES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_table_matches = 1; + + parg.rsp_policy = &devlink_dl_dpipe_table_matches_nest; + parg.data = &dst->dpipe_table_matches; + if (devlink_dl_dpipe_table_matches_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == DEVLINK_ATTR_DPIPE_TABLE_ACTIONS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_table_actions = 1; + + parg.rsp_policy = &devlink_dl_dpipe_table_actions_nest; + parg.data = &dst->dpipe_table_actions; + if (devlink_dl_dpipe_table_actions_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_table_counters_enabled = 1; + dst->dpipe_table_counters_enabled = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_table_resource_id = 1; + dst->dpipe_table_resource_id = ynl_attr_get_u64(attr); + } else if (type == DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_table_resource_units = 1; + dst->dpipe_table_resource_units = ynl_attr_get_u64(attr); + } + } + + return 0; +} + +void devlink_dl_dpipe_entry_free(struct devlink_dl_dpipe_entry *obj) +{ + devlink_dl_dpipe_entry_match_values_free(&obj->dpipe_entry_match_values); + devlink_dl_dpipe_entry_action_values_free(&obj->dpipe_entry_action_values); +} + +int devlink_dl_dpipe_entry_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_entry *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_ENTRY_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_entry_index = 1; + dst->dpipe_entry_index = ynl_attr_get_u64(attr); + } else if (type == DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_entry_match_values = 1; + + parg.rsp_policy = &devlink_dl_dpipe_entry_match_values_nest; + parg.data = &dst->dpipe_entry_match_values; + if (devlink_dl_dpipe_entry_match_values_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_entry_action_values = 1; + + parg.rsp_policy = &devlink_dl_dpipe_entry_action_values_nest; + parg.data = &dst->dpipe_entry_action_values; + if (devlink_dl_dpipe_entry_action_values_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == DEVLINK_ATTR_DPIPE_ENTRY_COUNTER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_entry_counter = 1; + dst->dpipe_entry_counter = ynl_attr_get_u64(attr); + } + } + + return 0; +} + +void devlink_dl_dpipe_header_free(struct devlink_dl_dpipe_header *obj) +{ + free(obj->dpipe_header_name); + devlink_dl_dpipe_header_fields_free(&obj->dpipe_header_fields); +} + +int devlink_dl_dpipe_header_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_header *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_HEADER_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dpipe_header_name_len = len; + dst->dpipe_header_name = malloc(len + 1); + memcpy(dst->dpipe_header_name, ynl_attr_get_str(attr), len); + dst->dpipe_header_name[len] = 0; + } else if (type == DEVLINK_ATTR_DPIPE_HEADER_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_header_id = 1; + dst->dpipe_header_id = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_DPIPE_HEADER_GLOBAL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_header_global = 1; + dst->dpipe_header_global = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_DPIPE_HEADER_FIELDS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_header_fields = 1; + + parg.rsp_policy = &devlink_dl_dpipe_header_fields_nest; + parg.data = &dst->dpipe_header_fields; + if (devlink_dl_dpipe_header_fields_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return 0; +} + +void devlink_dl_reload_stats_free(struct devlink_dl_reload_stats *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_reload_action_info; i++) + devlink_dl_reload_act_info_free(&obj->reload_action_info[i]); + free(obj->reload_action_info); +} + +int devlink_dl_reload_stats_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_reload_stats *dst = yarg->data; + unsigned int n_reload_action_info = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->reload_action_info) + return ynl_error_parse(yarg, "attribute already present (dl-reload-stats.reload-action-info)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_ACTION_INFO) { + n_reload_action_info++; + } + } + + if (n_reload_action_info) { + dst->reload_action_info = calloc(n_reload_action_info, sizeof(*dst->reload_action_info)); + dst->n_reload_action_info = n_reload_action_info; + i = 0; + parg.rsp_policy = &devlink_dl_reload_act_info_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_RELOAD_ACTION_INFO) { + parg.data = &dst->reload_action_info[i]; + if (devlink_dl_reload_act_info_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void devlink_dl_dpipe_tables_free(struct devlink_dl_dpipe_tables *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_table; i++) + devlink_dl_dpipe_table_free(&obj->dpipe_table[i]); + free(obj->dpipe_table); +} + +int devlink_dl_dpipe_tables_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_tables *dst = yarg->data; + unsigned int n_dpipe_table = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_table) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-tables.dpipe-table)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_TABLE) { + n_dpipe_table++; + } + } + + if (n_dpipe_table) { + dst->dpipe_table = calloc(n_dpipe_table, sizeof(*dst->dpipe_table)); + dst->n_dpipe_table = n_dpipe_table; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_table_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_TABLE) { + parg.data = &dst->dpipe_table[i]; + if (devlink_dl_dpipe_table_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void devlink_dl_dpipe_entries_free(struct devlink_dl_dpipe_entries *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_entry; i++) + devlink_dl_dpipe_entry_free(&obj->dpipe_entry[i]); + free(obj->dpipe_entry); +} + +int devlink_dl_dpipe_entries_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_entries *dst = yarg->data; + unsigned int n_dpipe_entry = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_entry) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-entries.dpipe-entry)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_ENTRY) { + n_dpipe_entry++; + } + } + + if (n_dpipe_entry) { + dst->dpipe_entry = calloc(n_dpipe_entry, sizeof(*dst->dpipe_entry)); + dst->n_dpipe_entry = n_dpipe_entry; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_entry_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_ENTRY) { + parg.data = &dst->dpipe_entry[i]; + if (devlink_dl_dpipe_entry_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void devlink_dl_dpipe_headers_free(struct devlink_dl_dpipe_headers *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_dpipe_header; i++) + devlink_dl_dpipe_header_free(&obj->dpipe_header[i]); + free(obj->dpipe_header); +} + +int devlink_dl_dpipe_headers_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dpipe_headers *dst = yarg->data; + unsigned int n_dpipe_header = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->dpipe_header) + return ynl_error_parse(yarg, "attribute already present (dl-dpipe-headers.dpipe-header)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_DPIPE_HEADER) { + n_dpipe_header++; + } + } + + if (n_dpipe_header) { + dst->dpipe_header = calloc(n_dpipe_header, sizeof(*dst->dpipe_header)); + dst->n_dpipe_header = n_dpipe_header; + i = 0; + parg.rsp_policy = &devlink_dl_dpipe_header_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_DPIPE_HEADER) { + parg.data = &dst->dpipe_header[i]; + if (devlink_dl_dpipe_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void devlink_dl_dev_stats_free(struct devlink_dl_dev_stats *obj) +{ + devlink_dl_reload_stats_free(&obj->reload_stats); + devlink_dl_reload_stats_free(&obj->remote_reload_stats); +} + +int devlink_dl_dev_stats_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct devlink_dl_dev_stats *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_RELOAD_STATS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.reload_stats = 1; + + parg.rsp_policy = &devlink_dl_reload_stats_nest; + parg.data = &dst->reload_stats; + if (devlink_dl_reload_stats_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == DEVLINK_ATTR_REMOTE_RELOAD_STATS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.remote_reload_stats = 1; + + parg.rsp_policy = &devlink_dl_reload_stats_nest; + parg.data = &dst->remote_reload_stats; + if (devlink_dl_reload_stats_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return 0; +} + +/* ============== DEVLINK_CMD_GET ============== */ +/* DEVLINK_CMD_GET - do */ +void devlink_get_req_free(struct devlink_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_get_rsp_free(struct devlink_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + devlink_dl_dev_stats_free(&rsp->dev_stats); + free(rsp); +} + +int devlink_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_RELOAD_FAILED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.reload_failed = 1; + dst->reload_failed = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_DEV_STATS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dev_stats = 1; + + parg.rsp_policy = &devlink_dl_dev_stats_nest; + parg.data = &dst->dev_stats; + if (devlink_dl_dev_stats_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_get_rsp * +devlink_get(struct ynl_sock *ys, struct devlink_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_get_rsp_parse; + yrs.rsp_cmd = 3; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_GET - dump */ +void devlink_get_list_free(struct devlink_get_list *rsp) +{ + struct devlink_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + devlink_dl_dev_stats_free(&rsp->obj.dev_stats); + free(rsp); + } +} + +struct devlink_get_list *devlink_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_get_list); + yds.cb = devlink_get_rsp_parse; + yds.rsp_cmd = 3; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_PORT_GET ============== */ +/* DEVLINK_CMD_PORT_GET - do */ +void devlink_port_get_req_free(struct devlink_port_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_port_get_rsp_free(struct devlink_port_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_port_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_port_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_port_get_rsp * +devlink_port_get(struct ynl_sock *ys, struct devlink_port_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_port_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_port_get_rsp_parse; + yrs.rsp_cmd = 7; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_port_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_PORT_GET - dump */ +int devlink_port_get_rsp_dump_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_port_get_rsp_dump *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +void devlink_port_get_req_dump_free(struct devlink_port_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_port_get_rsp_list_free(struct devlink_port_get_rsp_list *rsp) +{ + struct devlink_port_get_rsp_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp); + } +} + +struct devlink_port_get_rsp_list * +devlink_port_get_dump(struct ynl_sock *ys, + struct devlink_port_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_port_get_rsp_list); + yds.cb = devlink_port_get_rsp_dump_parse; + yds.rsp_cmd = 7; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_PORT_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_port_get_rsp_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_PORT_SET ============== */ +/* DEVLINK_CMD_PORT_SET - do */ +void devlink_port_set_req_free(struct devlink_port_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + devlink_dl_port_function_free(&req->port_function); + free(req); +} + +int devlink_port_set(struct ynl_sock *ys, struct devlink_port_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.port_type) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_PORT_TYPE, req->port_type); + if (req->_present.port_function) + devlink_dl_port_function_put(nlh, DEVLINK_ATTR_PORT_FUNCTION, &req->port_function); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_PORT_NEW ============== */ +/* DEVLINK_CMD_PORT_NEW - do */ +void devlink_port_new_req_free(struct devlink_port_new_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_port_new_rsp_free(struct devlink_port_new_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_port_new_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_port_new_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_port_new_rsp * +devlink_port_new(struct ynl_sock *ys, struct devlink_port_new_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_port_new_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_NEW, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.port_flavour) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_PORT_FLAVOUR, req->port_flavour); + if (req->_present.port_pci_pf_number) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, req->port_pci_pf_number); + if (req->_present.port_pci_sf_number) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_PCI_SF_NUMBER, req->port_pci_sf_number); + if (req->_present.port_controller_number) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, req->port_controller_number); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_port_new_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_PORT_NEW; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_port_new_rsp_free(rsp); + return NULL; +} + +/* ============== DEVLINK_CMD_PORT_DEL ============== */ +/* DEVLINK_CMD_PORT_DEL - do */ +void devlink_port_del_req_free(struct devlink_port_del_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_port_del(struct ynl_sock *ys, struct devlink_port_del_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_DEL, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_PORT_SPLIT ============== */ +/* DEVLINK_CMD_PORT_SPLIT - do */ +void devlink_port_split_req_free(struct devlink_port_split_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_port_split(struct ynl_sock *ys, struct devlink_port_split_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_SPLIT, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.port_split_count) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_SPLIT_COUNT, req->port_split_count); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_PORT_UNSPLIT ============== */ +/* DEVLINK_CMD_PORT_UNSPLIT - do */ +void devlink_port_unsplit_req_free(struct devlink_port_unsplit_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_port_unsplit(struct ynl_sock *ys, + struct devlink_port_unsplit_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_UNSPLIT, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_SB_GET ============== */ +/* DEVLINK_CMD_SB_GET - do */ +void devlink_sb_get_req_free(struct devlink_sb_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_sb_get_rsp_free(struct devlink_sb_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_sb_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_sb_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_SB_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sb_index = 1; + dst->sb_index = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_sb_get_rsp * +devlink_sb_get(struct ynl_sock *ys, struct devlink_sb_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_sb_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.sb_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_sb_get_rsp_parse; + yrs.rsp_cmd = 13; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_sb_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_SB_GET - dump */ +void devlink_sb_get_req_dump_free(struct devlink_sb_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_sb_get_list_free(struct devlink_sb_get_list *rsp) +{ + struct devlink_sb_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp); + } +} + +struct devlink_sb_get_list * +devlink_sb_get_dump(struct ynl_sock *ys, struct devlink_sb_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_sb_get_list); + yds.cb = devlink_sb_get_rsp_parse; + yds.rsp_cmd = 13; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_sb_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_SB_POOL_GET ============== */ +/* DEVLINK_CMD_SB_POOL_GET - do */ +void devlink_sb_pool_get_req_free(struct devlink_sb_pool_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_sb_pool_get_rsp_free(struct devlink_sb_pool_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_sb_pool_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_sb_pool_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_SB_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sb_index = 1; + dst->sb_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_SB_POOL_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sb_pool_index = 1; + dst->sb_pool_index = ynl_attr_get_u16(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_sb_pool_get_rsp * +devlink_sb_pool_get(struct ynl_sock *ys, struct devlink_sb_pool_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_sb_pool_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_POOL_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.sb_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index); + if (req->_present.sb_pool_index) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX, req->sb_pool_index); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_sb_pool_get_rsp_parse; + yrs.rsp_cmd = 17; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_sb_pool_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_SB_POOL_GET - dump */ +void +devlink_sb_pool_get_req_dump_free(struct devlink_sb_pool_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_sb_pool_get_list_free(struct devlink_sb_pool_get_list *rsp) +{ + struct devlink_sb_pool_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp); + } +} + +struct devlink_sb_pool_get_list * +devlink_sb_pool_get_dump(struct ynl_sock *ys, + struct devlink_sb_pool_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_sb_pool_get_list); + yds.cb = devlink_sb_pool_get_rsp_parse; + yds.rsp_cmd = 17; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_POOL_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_sb_pool_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_SB_POOL_SET ============== */ +/* DEVLINK_CMD_SB_POOL_SET - do */ +void devlink_sb_pool_set_req_free(struct devlink_sb_pool_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_sb_pool_set(struct ynl_sock *ys, + struct devlink_sb_pool_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_POOL_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.sb_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index); + if (req->_present.sb_pool_index) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX, req->sb_pool_index); + if (req->_present.sb_pool_threshold_type) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE, req->sb_pool_threshold_type); + if (req->_present.sb_pool_size) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_POOL_SIZE, req->sb_pool_size); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_SB_PORT_POOL_GET ============== */ +/* DEVLINK_CMD_SB_PORT_POOL_GET - do */ +void +devlink_sb_port_pool_get_req_free(struct devlink_sb_port_pool_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void +devlink_sb_port_pool_get_rsp_free(struct devlink_sb_port_pool_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_sb_port_pool_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_sb_port_pool_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_SB_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sb_index = 1; + dst->sb_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_SB_POOL_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sb_pool_index = 1; + dst->sb_pool_index = ynl_attr_get_u16(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_sb_port_pool_get_rsp * +devlink_sb_port_pool_get(struct ynl_sock *ys, + struct devlink_sb_port_pool_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_sb_port_pool_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_PORT_POOL_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.sb_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index); + if (req->_present.sb_pool_index) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX, req->sb_pool_index); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_sb_port_pool_get_rsp_parse; + yrs.rsp_cmd = 21; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_sb_port_pool_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_SB_PORT_POOL_GET - dump */ +void +devlink_sb_port_pool_get_req_dump_free(struct devlink_sb_port_pool_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void +devlink_sb_port_pool_get_list_free(struct devlink_sb_port_pool_get_list *rsp) +{ + struct devlink_sb_port_pool_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp); + } +} + +struct devlink_sb_port_pool_get_list * +devlink_sb_port_pool_get_dump(struct ynl_sock *ys, + struct devlink_sb_port_pool_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_sb_port_pool_get_list); + yds.cb = devlink_sb_port_pool_get_rsp_parse; + yds.rsp_cmd = 21; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_PORT_POOL_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_sb_port_pool_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_SB_PORT_POOL_SET ============== */ +/* DEVLINK_CMD_SB_PORT_POOL_SET - do */ +void +devlink_sb_port_pool_set_req_free(struct devlink_sb_port_pool_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_sb_port_pool_set(struct ynl_sock *ys, + struct devlink_sb_port_pool_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_PORT_POOL_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.sb_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index); + if (req->_present.sb_pool_index) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX, req->sb_pool_index); + if (req->_present.sb_threshold) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_THRESHOLD, req->sb_threshold); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_SB_TC_POOL_BIND_GET ============== */ +/* DEVLINK_CMD_SB_TC_POOL_BIND_GET - do */ +void +devlink_sb_tc_pool_bind_get_req_free(struct devlink_sb_tc_pool_bind_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void +devlink_sb_tc_pool_bind_get_rsp_free(struct devlink_sb_tc_pool_bind_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_sb_tc_pool_bind_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_sb_tc_pool_bind_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_SB_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sb_index = 1; + dst->sb_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_SB_POOL_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sb_pool_type = 1; + dst->sb_pool_type = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_SB_TC_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sb_tc_index = 1; + dst->sb_tc_index = ynl_attr_get_u16(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_sb_tc_pool_bind_get_rsp * +devlink_sb_tc_pool_bind_get(struct ynl_sock *ys, + struct devlink_sb_tc_pool_bind_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_sb_tc_pool_bind_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_TC_POOL_BIND_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.sb_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index); + if (req->_present.sb_pool_type) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_SB_POOL_TYPE, req->sb_pool_type); + if (req->_present.sb_tc_index) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_SB_TC_INDEX, req->sb_tc_index); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_sb_tc_pool_bind_get_rsp_parse; + yrs.rsp_cmd = 25; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_sb_tc_pool_bind_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_SB_TC_POOL_BIND_GET - dump */ +void +devlink_sb_tc_pool_bind_get_req_dump_free(struct devlink_sb_tc_pool_bind_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void +devlink_sb_tc_pool_bind_get_list_free(struct devlink_sb_tc_pool_bind_get_list *rsp) +{ + struct devlink_sb_tc_pool_bind_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp); + } +} + +struct devlink_sb_tc_pool_bind_get_list * +devlink_sb_tc_pool_bind_get_dump(struct ynl_sock *ys, + struct devlink_sb_tc_pool_bind_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_sb_tc_pool_bind_get_list); + yds.cb = devlink_sb_tc_pool_bind_get_rsp_parse; + yds.rsp_cmd = 25; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SB_TC_POOL_BIND_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_sb_tc_pool_bind_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_SB_TC_POOL_BIND_SET ============== */ +/* DEVLINK_CMD_SB_TC_POOL_BIND_SET - do */ +void +devlink_sb_tc_pool_bind_set_req_free(struct devlink_sb_tc_pool_bind_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_sb_tc_pool_bind_set(struct ynl_sock *ys, + struct devlink_sb_tc_pool_bind_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_TC_POOL_BIND_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.sb_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index); + if (req->_present.sb_pool_index) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_SB_POOL_INDEX, req->sb_pool_index); + if (req->_present.sb_pool_type) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_SB_POOL_TYPE, req->sb_pool_type); + if (req->_present.sb_tc_index) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_SB_TC_INDEX, req->sb_tc_index); + if (req->_present.sb_threshold) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_THRESHOLD, req->sb_threshold); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_SB_OCC_SNAPSHOT ============== */ +/* DEVLINK_CMD_SB_OCC_SNAPSHOT - do */ +void devlink_sb_occ_snapshot_req_free(struct devlink_sb_occ_snapshot_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_sb_occ_snapshot(struct ynl_sock *ys, + struct devlink_sb_occ_snapshot_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_OCC_SNAPSHOT, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.sb_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_SB_OCC_MAX_CLEAR ============== */ +/* DEVLINK_CMD_SB_OCC_MAX_CLEAR - do */ +void +devlink_sb_occ_max_clear_req_free(struct devlink_sb_occ_max_clear_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_sb_occ_max_clear(struct ynl_sock *ys, + struct devlink_sb_occ_max_clear_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SB_OCC_MAX_CLEAR, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.sb_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_SB_INDEX, req->sb_index); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_ESWITCH_GET ============== */ +/* DEVLINK_CMD_ESWITCH_GET - do */ +void devlink_eswitch_get_req_free(struct devlink_eswitch_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_eswitch_get_rsp_free(struct devlink_eswitch_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_eswitch_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_eswitch_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_ESWITCH_MODE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.eswitch_mode = 1; + dst->eswitch_mode = ynl_attr_get_u16(attr); + } else if (type == DEVLINK_ATTR_ESWITCH_INLINE_MODE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.eswitch_inline_mode = 1; + dst->eswitch_inline_mode = ynl_attr_get_u8(attr); + } else if (type == DEVLINK_ATTR_ESWITCH_ENCAP_MODE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.eswitch_encap_mode = 1; + dst->eswitch_encap_mode = ynl_attr_get_u8(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_eswitch_get_rsp * +devlink_eswitch_get(struct ynl_sock *ys, struct devlink_eswitch_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_eswitch_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_ESWITCH_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_eswitch_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_ESWITCH_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_eswitch_get_rsp_free(rsp); + return NULL; +} + +/* ============== DEVLINK_CMD_ESWITCH_SET ============== */ +/* DEVLINK_CMD_ESWITCH_SET - do */ +void devlink_eswitch_set_req_free(struct devlink_eswitch_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_eswitch_set(struct ynl_sock *ys, + struct devlink_eswitch_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_ESWITCH_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.eswitch_mode) + ynl_attr_put_u16(nlh, DEVLINK_ATTR_ESWITCH_MODE, req->eswitch_mode); + if (req->_present.eswitch_inline_mode) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_ESWITCH_INLINE_MODE, req->eswitch_inline_mode); + if (req->_present.eswitch_encap_mode) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, req->eswitch_encap_mode); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_DPIPE_TABLE_GET ============== */ +/* DEVLINK_CMD_DPIPE_TABLE_GET - do */ +void devlink_dpipe_table_get_req_free(struct devlink_dpipe_table_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->dpipe_table_name); + free(req); +} + +void devlink_dpipe_table_get_rsp_free(struct devlink_dpipe_table_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + devlink_dl_dpipe_tables_free(&rsp->dpipe_tables); + free(rsp); +} + +int devlink_dpipe_table_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_dpipe_table_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_DPIPE_TABLES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_tables = 1; + + parg.rsp_policy = &devlink_dl_dpipe_tables_nest; + parg.data = &dst->dpipe_tables; + if (devlink_dl_dpipe_tables_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_dpipe_table_get_rsp * +devlink_dpipe_table_get(struct ynl_sock *ys, + struct devlink_dpipe_table_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_dpipe_table_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_DPIPE_TABLE_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.dpipe_table_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DPIPE_TABLE_NAME, req->dpipe_table_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_dpipe_table_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_DPIPE_TABLE_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_dpipe_table_get_rsp_free(rsp); + return NULL; +} + +/* ============== DEVLINK_CMD_DPIPE_ENTRIES_GET ============== */ +/* DEVLINK_CMD_DPIPE_ENTRIES_GET - do */ +void +devlink_dpipe_entries_get_req_free(struct devlink_dpipe_entries_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->dpipe_table_name); + free(req); +} + +void +devlink_dpipe_entries_get_rsp_free(struct devlink_dpipe_entries_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + devlink_dl_dpipe_entries_free(&rsp->dpipe_entries); + free(rsp); +} + +int devlink_dpipe_entries_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_dpipe_entries_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_DPIPE_ENTRIES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_entries = 1; + + parg.rsp_policy = &devlink_dl_dpipe_entries_nest; + parg.data = &dst->dpipe_entries; + if (devlink_dl_dpipe_entries_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_dpipe_entries_get_rsp * +devlink_dpipe_entries_get(struct ynl_sock *ys, + struct devlink_dpipe_entries_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_dpipe_entries_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_DPIPE_ENTRIES_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.dpipe_table_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DPIPE_TABLE_NAME, req->dpipe_table_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_dpipe_entries_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_dpipe_entries_get_rsp_free(rsp); + return NULL; +} + +/* ============== DEVLINK_CMD_DPIPE_HEADERS_GET ============== */ +/* DEVLINK_CMD_DPIPE_HEADERS_GET - do */ +void +devlink_dpipe_headers_get_req_free(struct devlink_dpipe_headers_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void +devlink_dpipe_headers_get_rsp_free(struct devlink_dpipe_headers_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + devlink_dl_dpipe_headers_free(&rsp->dpipe_headers); + free(rsp); +} + +int devlink_dpipe_headers_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_dpipe_headers_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_DPIPE_HEADERS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dpipe_headers = 1; + + parg.rsp_policy = &devlink_dl_dpipe_headers_nest; + parg.data = &dst->dpipe_headers; + if (devlink_dl_dpipe_headers_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_dpipe_headers_get_rsp * +devlink_dpipe_headers_get(struct ynl_sock *ys, + struct devlink_dpipe_headers_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_dpipe_headers_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_DPIPE_HEADERS_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_dpipe_headers_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_DPIPE_HEADERS_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_dpipe_headers_get_rsp_free(rsp); + return NULL; +} + +/* ============== DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET ============== */ +/* DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET - do */ +void +devlink_dpipe_table_counters_set_req_free(struct devlink_dpipe_table_counters_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->dpipe_table_name); + free(req); +} + +int devlink_dpipe_table_counters_set(struct ynl_sock *ys, + struct devlink_dpipe_table_counters_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.dpipe_table_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DPIPE_TABLE_NAME, req->dpipe_table_name); + if (req->_present.dpipe_table_counters_enabled) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, req->dpipe_table_counters_enabled); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_RESOURCE_SET ============== */ +/* DEVLINK_CMD_RESOURCE_SET - do */ +void devlink_resource_set_req_free(struct devlink_resource_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_resource_set(struct ynl_sock *ys, + struct devlink_resource_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_RESOURCE_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.resource_id) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_RESOURCE_ID, req->resource_id); + if (req->_present.resource_size) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_RESOURCE_SIZE, req->resource_size); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_RESOURCE_DUMP ============== */ +/* DEVLINK_CMD_RESOURCE_DUMP - do */ +void devlink_resource_dump_req_free(struct devlink_resource_dump_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_resource_dump_rsp_free(struct devlink_resource_dump_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + devlink_dl_resource_list_free(&rsp->resource_list); + free(rsp); +} + +int devlink_resource_dump_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_resource_dump_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_RESOURCE_LIST) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.resource_list = 1; + + parg.rsp_policy = &devlink_dl_resource_list_nest; + parg.data = &dst->resource_list; + if (devlink_dl_resource_list_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_resource_dump_rsp * +devlink_resource_dump(struct ynl_sock *ys, + struct devlink_resource_dump_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_resource_dump_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_RESOURCE_DUMP, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_resource_dump_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_RESOURCE_DUMP; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_resource_dump_rsp_free(rsp); + return NULL; +} + +/* ============== DEVLINK_CMD_RELOAD ============== */ +/* DEVLINK_CMD_RELOAD - do */ +void devlink_reload_req_free(struct devlink_reload_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_reload_rsp_free(struct devlink_reload_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_reload_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_reload_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.reload_actions_performed = 1; + memcpy(&dst->reload_actions_performed, ynl_attr_data(attr), sizeof(struct nla_bitfield32)); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_reload_rsp * +devlink_reload(struct ynl_sock *ys, struct devlink_reload_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_reload_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_RELOAD, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.reload_action) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_RELOAD_ACTION, req->reload_action); + if (req->_present.reload_limits) + ynl_attr_put(nlh, DEVLINK_ATTR_RELOAD_LIMITS, &req->reload_limits, sizeof(struct nla_bitfield32)); + if (req->_present.netns_pid) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_NETNS_PID, req->netns_pid); + if (req->_present.netns_fd) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_NETNS_FD, req->netns_fd); + if (req->_present.netns_id) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_NETNS_ID, req->netns_id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_reload_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_RELOAD; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_reload_rsp_free(rsp); + return NULL; +} + +/* ============== DEVLINK_CMD_PARAM_GET ============== */ +/* DEVLINK_CMD_PARAM_GET - do */ +void devlink_param_get_req_free(struct devlink_param_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->param_name); + free(req); +} + +void devlink_param_get_rsp_free(struct devlink_param_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp->param_name); + free(rsp); +} + +int devlink_param_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_param_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PARAM_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.param_name_len = len; + dst->param_name = malloc(len + 1); + memcpy(dst->param_name, ynl_attr_get_str(attr), len); + dst->param_name[len] = 0; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_param_get_rsp * +devlink_param_get(struct ynl_sock *ys, struct devlink_param_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_param_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PARAM_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.param_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_PARAM_NAME, req->param_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_param_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_PARAM_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_param_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_PARAM_GET - dump */ +void devlink_param_get_req_dump_free(struct devlink_param_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_param_get_list_free(struct devlink_param_get_list *rsp) +{ + struct devlink_param_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp->obj.param_name); + free(rsp); + } +} + +struct devlink_param_get_list * +devlink_param_get_dump(struct ynl_sock *ys, + struct devlink_param_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_param_get_list); + yds.cb = devlink_param_get_rsp_parse; + yds.rsp_cmd = DEVLINK_CMD_PARAM_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_PARAM_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_param_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_PARAM_SET ============== */ +/* DEVLINK_CMD_PARAM_SET - do */ +void devlink_param_set_req_free(struct devlink_param_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->param_name); + free(req); +} + +int devlink_param_set(struct ynl_sock *ys, struct devlink_param_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PARAM_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.param_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_PARAM_NAME, req->param_name); + if (req->_present.param_type) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_TYPE, req->param_type); + if (req->_present.param_value_cmode) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_PARAM_VALUE_CMODE, req->param_value_cmode); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_REGION_GET ============== */ +/* DEVLINK_CMD_REGION_GET - do */ +void devlink_region_get_req_free(struct devlink_region_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->region_name); + free(req); +} + +void devlink_region_get_rsp_free(struct devlink_region_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp->region_name); + free(rsp); +} + +int devlink_region_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_region_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_REGION_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.region_name_len = len; + dst->region_name = malloc(len + 1); + memcpy(dst->region_name, ynl_attr_get_str(attr), len); + dst->region_name[len] = 0; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_region_get_rsp * +devlink_region_get(struct ynl_sock *ys, struct devlink_region_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_region_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_REGION_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.region_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_REGION_NAME, req->region_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_region_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_REGION_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_region_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_REGION_GET - dump */ +void devlink_region_get_req_dump_free(struct devlink_region_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_region_get_list_free(struct devlink_region_get_list *rsp) +{ + struct devlink_region_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp->obj.region_name); + free(rsp); + } +} + +struct devlink_region_get_list * +devlink_region_get_dump(struct ynl_sock *ys, + struct devlink_region_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_region_get_list); + yds.cb = devlink_region_get_rsp_parse; + yds.rsp_cmd = DEVLINK_CMD_REGION_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_REGION_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_region_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_REGION_NEW ============== */ +/* DEVLINK_CMD_REGION_NEW - do */ +void devlink_region_new_req_free(struct devlink_region_new_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->region_name); + free(req); +} + +void devlink_region_new_rsp_free(struct devlink_region_new_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp->region_name); + free(rsp); +} + +int devlink_region_new_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_region_new_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_REGION_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.region_name_len = len; + dst->region_name = malloc(len + 1); + memcpy(dst->region_name, ynl_attr_get_str(attr), len); + dst->region_name[len] = 0; + } else if (type == DEVLINK_ATTR_REGION_SNAPSHOT_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.region_snapshot_id = 1; + dst->region_snapshot_id = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_region_new_rsp * +devlink_region_new(struct ynl_sock *ys, struct devlink_region_new_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_region_new_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_REGION_NEW, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.region_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_REGION_NAME, req->region_name); + if (req->_present.region_snapshot_id) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_REGION_SNAPSHOT_ID, req->region_snapshot_id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_region_new_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_REGION_NEW; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_region_new_rsp_free(rsp); + return NULL; +} + +/* ============== DEVLINK_CMD_REGION_DEL ============== */ +/* DEVLINK_CMD_REGION_DEL - do */ +void devlink_region_del_req_free(struct devlink_region_del_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->region_name); + free(req); +} + +int devlink_region_del(struct ynl_sock *ys, struct devlink_region_del_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_REGION_DEL, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.region_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_REGION_NAME, req->region_name); + if (req->_present.region_snapshot_id) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_REGION_SNAPSHOT_ID, req->region_snapshot_id); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_REGION_READ ============== */ +/* DEVLINK_CMD_REGION_READ - dump */ +int devlink_region_read_rsp_dump_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_region_read_rsp_dump *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_REGION_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.region_name_len = len; + dst->region_name = malloc(len + 1); + memcpy(dst->region_name, ynl_attr_get_str(attr), len); + dst->region_name[len] = 0; + } + } + + return YNL_PARSE_CB_OK; +} + +void +devlink_region_read_req_dump_free(struct devlink_region_read_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->region_name); + free(req); +} + +void +devlink_region_read_rsp_list_free(struct devlink_region_read_rsp_list *rsp) +{ + struct devlink_region_read_rsp_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp->obj.region_name); + free(rsp); + } +} + +struct devlink_region_read_rsp_list * +devlink_region_read_dump(struct ynl_sock *ys, + struct devlink_region_read_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_region_read_rsp_list); + yds.cb = devlink_region_read_rsp_dump_parse; + yds.rsp_cmd = DEVLINK_CMD_REGION_READ; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_REGION_READ, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.region_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_REGION_NAME, req->region_name); + if (req->_present.region_snapshot_id) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_REGION_SNAPSHOT_ID, req->region_snapshot_id); + if (req->_present.region_direct) + ynl_attr_put(nlh, DEVLINK_ATTR_REGION_DIRECT, NULL, 0); + if (req->_present.region_chunk_addr) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_REGION_CHUNK_ADDR, req->region_chunk_addr); + if (req->_present.region_chunk_len) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_REGION_CHUNK_LEN, req->region_chunk_len); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_region_read_rsp_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_PORT_PARAM_GET ============== */ +/* DEVLINK_CMD_PORT_PARAM_GET - do */ +void devlink_port_param_get_req_free(struct devlink_port_param_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_port_param_get_rsp_free(struct devlink_port_param_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_port_param_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_port_param_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_port_param_get_rsp * +devlink_port_param_get(struct ynl_sock *ys, + struct devlink_port_param_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_port_param_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_PARAM_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_port_param_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_PORT_PARAM_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_port_param_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_PORT_PARAM_GET - dump */ +void devlink_port_param_get_list_free(struct devlink_port_param_get_list *rsp) +{ + struct devlink_port_param_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp); + } +} + +struct devlink_port_param_get_list * +devlink_port_param_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_port_param_get_list); + yds.cb = devlink_port_param_get_rsp_parse; + yds.rsp_cmd = DEVLINK_CMD_PORT_PARAM_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_PORT_PARAM_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_port_param_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_PORT_PARAM_SET ============== */ +/* DEVLINK_CMD_PORT_PARAM_SET - do */ +void devlink_port_param_set_req_free(struct devlink_port_param_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_port_param_set(struct ynl_sock *ys, + struct devlink_port_param_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_PORT_PARAM_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_INFO_GET ============== */ +/* DEVLINK_CMD_INFO_GET - do */ +void devlink_info_get_req_free(struct devlink_info_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_info_get_rsp_free(struct devlink_info_get_rsp *rsp) +{ + unsigned int i; + + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp->info_driver_name); + free(rsp->info_serial_number); + for (i = 0; i < rsp->n_info_version_fixed; i++) + devlink_dl_info_version_free(&rsp->info_version_fixed[i]); + free(rsp->info_version_fixed); + for (i = 0; i < rsp->n_info_version_running; i++) + devlink_dl_info_version_free(&rsp->info_version_running[i]); + free(rsp->info_version_running); + for (i = 0; i < rsp->n_info_version_stored; i++) + devlink_dl_info_version_free(&rsp->info_version_stored[i]); + free(rsp->info_version_stored); + free(rsp); +} + +int devlink_info_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + unsigned int n_info_version_running = 0; + unsigned int n_info_version_stored = 0; + unsigned int n_info_version_fixed = 0; + struct devlink_info_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + dst = yarg->data; + parg.ys = yarg->ys; + + if (dst->info_version_fixed) + return ynl_error_parse(yarg, "attribute already present (devlink.info-version-fixed)"); + if (dst->info_version_running) + return ynl_error_parse(yarg, "attribute already present (devlink.info-version-running)"); + if (dst->info_version_stored) + return ynl_error_parse(yarg, "attribute already present (devlink.info-version-stored)"); + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_INFO_DRIVER_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.info_driver_name_len = len; + dst->info_driver_name = malloc(len + 1); + memcpy(dst->info_driver_name, ynl_attr_get_str(attr), len); + dst->info_driver_name[len] = 0; + } else if (type == DEVLINK_ATTR_INFO_SERIAL_NUMBER) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.info_serial_number_len = len; + dst->info_serial_number = malloc(len + 1); + memcpy(dst->info_serial_number, ynl_attr_get_str(attr), len); + dst->info_serial_number[len] = 0; + } else if (type == DEVLINK_ATTR_INFO_VERSION_FIXED) { + n_info_version_fixed++; + } else if (type == DEVLINK_ATTR_INFO_VERSION_RUNNING) { + n_info_version_running++; + } else if (type == DEVLINK_ATTR_INFO_VERSION_STORED) { + n_info_version_stored++; + } + } + + if (n_info_version_fixed) { + dst->info_version_fixed = calloc(n_info_version_fixed, sizeof(*dst->info_version_fixed)); + dst->n_info_version_fixed = n_info_version_fixed; + i = 0; + parg.rsp_policy = &devlink_dl_info_version_nest; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_INFO_VERSION_FIXED) { + parg.data = &dst->info_version_fixed[i]; + if (devlink_dl_info_version_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + if (n_info_version_running) { + dst->info_version_running = calloc(n_info_version_running, sizeof(*dst->info_version_running)); + dst->n_info_version_running = n_info_version_running; + i = 0; + parg.rsp_policy = &devlink_dl_info_version_nest; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_INFO_VERSION_RUNNING) { + parg.data = &dst->info_version_running[i]; + if (devlink_dl_info_version_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + if (n_info_version_stored) { + dst->info_version_stored = calloc(n_info_version_stored, sizeof(*dst->info_version_stored)); + dst->n_info_version_stored = n_info_version_stored; + i = 0; + parg.rsp_policy = &devlink_dl_info_version_nest; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == DEVLINK_ATTR_INFO_VERSION_STORED) { + parg.data = &dst->info_version_stored[i]; + if (devlink_dl_info_version_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_info_get_rsp * +devlink_info_get(struct ynl_sock *ys, struct devlink_info_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_info_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_info_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_INFO_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_info_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_INFO_GET - dump */ +void devlink_info_get_list_free(struct devlink_info_get_list *rsp) +{ + struct devlink_info_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + unsigned int i; + + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp->obj.info_driver_name); + free(rsp->obj.info_serial_number); + for (i = 0; i < rsp->obj.n_info_version_fixed; i++) + devlink_dl_info_version_free(&rsp->obj.info_version_fixed[i]); + free(rsp->obj.info_version_fixed); + for (i = 0; i < rsp->obj.n_info_version_running; i++) + devlink_dl_info_version_free(&rsp->obj.info_version_running[i]); + free(rsp->obj.info_version_running); + for (i = 0; i < rsp->obj.n_info_version_stored; i++) + devlink_dl_info_version_free(&rsp->obj.info_version_stored[i]); + free(rsp->obj.info_version_stored); + free(rsp); + } +} + +struct devlink_info_get_list *devlink_info_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_info_get_list); + yds.cb = devlink_info_get_rsp_parse; + yds.rsp_cmd = DEVLINK_CMD_INFO_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_INFO_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_info_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_GET ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_GET - do */ +void +devlink_health_reporter_get_req_free(struct devlink_health_reporter_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->health_reporter_name); + free(req); +} + +void +devlink_health_reporter_get_rsp_free(struct devlink_health_reporter_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp->health_reporter_name); + free(rsp); +} + +int devlink_health_reporter_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_health_reporter_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_HEALTH_REPORTER_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.health_reporter_name_len = len; + dst->health_reporter_name = malloc(len + 1); + memcpy(dst->health_reporter_name, ynl_attr_get_str(attr), len); + dst->health_reporter_name[len] = 0; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_health_reporter_get_rsp * +devlink_health_reporter_get(struct ynl_sock *ys, + struct devlink_health_reporter_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_health_reporter_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.health_reporter_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, req->health_reporter_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_health_reporter_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_HEALTH_REPORTER_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_health_reporter_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_HEALTH_REPORTER_GET - dump */ +void +devlink_health_reporter_get_req_dump_free(struct devlink_health_reporter_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void +devlink_health_reporter_get_list_free(struct devlink_health_reporter_get_list *rsp) +{ + struct devlink_health_reporter_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp->obj.health_reporter_name); + free(rsp); + } +} + +struct devlink_health_reporter_get_list * +devlink_health_reporter_get_dump(struct ynl_sock *ys, + struct devlink_health_reporter_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_health_reporter_get_list); + yds.cb = devlink_health_reporter_get_rsp_parse; + yds.rsp_cmd = DEVLINK_CMD_HEALTH_REPORTER_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_health_reporter_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_SET ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_SET - do */ +void +devlink_health_reporter_set_req_free(struct devlink_health_reporter_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->health_reporter_name); + free(req); +} + +int devlink_health_reporter_set(struct ynl_sock *ys, + struct devlink_health_reporter_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.health_reporter_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, req->health_reporter_name); + if (req->_present.health_reporter_graceful_period) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD, req->health_reporter_graceful_period); + if (req->_present.health_reporter_auto_recover) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER, req->health_reporter_auto_recover); + if (req->_present.health_reporter_auto_dump) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, req->health_reporter_auto_dump); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_RECOVER ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_RECOVER - do */ +void +devlink_health_reporter_recover_req_free(struct devlink_health_reporter_recover_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->health_reporter_name); + free(req); +} + +int devlink_health_reporter_recover(struct ynl_sock *ys, + struct devlink_health_reporter_recover_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_RECOVER, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.health_reporter_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, req->health_reporter_name); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE - do */ +void +devlink_health_reporter_diagnose_req_free(struct devlink_health_reporter_diagnose_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->health_reporter_name); + free(req); +} + +int devlink_health_reporter_diagnose(struct ynl_sock *ys, + struct devlink_health_reporter_diagnose_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.health_reporter_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, req->health_reporter_name); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET - dump */ +int devlink_health_reporter_dump_get_rsp_dump_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_health_reporter_dump_get_rsp_dump *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_FMSG) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.fmsg = 1; + + parg.rsp_policy = &devlink_dl_fmsg_nest; + parg.data = &dst->fmsg; + if (devlink_dl_fmsg_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +void +devlink_health_reporter_dump_get_req_dump_free(struct devlink_health_reporter_dump_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->health_reporter_name); + free(req); +} + +void +devlink_health_reporter_dump_get_rsp_list_free(struct devlink_health_reporter_dump_get_rsp_list *rsp) +{ + struct devlink_health_reporter_dump_get_rsp_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + devlink_dl_fmsg_free(&rsp->obj.fmsg); + free(rsp); + } +} + +struct devlink_health_reporter_dump_get_rsp_list * +devlink_health_reporter_dump_get_dump(struct ynl_sock *ys, + struct devlink_health_reporter_dump_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_health_reporter_dump_get_rsp_list); + yds.cb = devlink_health_reporter_dump_get_rsp_dump_parse; + yds.rsp_cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.health_reporter_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, req->health_reporter_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_health_reporter_dump_get_rsp_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR - do */ +void +devlink_health_reporter_dump_clear_req_free(struct devlink_health_reporter_dump_clear_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->health_reporter_name); + free(req); +} + +int devlink_health_reporter_dump_clear(struct ynl_sock *ys, + struct devlink_health_reporter_dump_clear_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.health_reporter_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, req->health_reporter_name); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_FLASH_UPDATE ============== */ +/* DEVLINK_CMD_FLASH_UPDATE - do */ +void devlink_flash_update_req_free(struct devlink_flash_update_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->flash_update_file_name); + free(req->flash_update_component); + free(req); +} + +int devlink_flash_update(struct ynl_sock *ys, + struct devlink_flash_update_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_FLASH_UPDATE, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.flash_update_file_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME, req->flash_update_file_name); + if (req->_present.flash_update_component_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, req->flash_update_component); + if (req->_present.flash_update_overwrite_mask) + ynl_attr_put(nlh, DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK, &req->flash_update_overwrite_mask, sizeof(struct nla_bitfield32)); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_TRAP_GET ============== */ +/* DEVLINK_CMD_TRAP_GET - do */ +void devlink_trap_get_req_free(struct devlink_trap_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->trap_name); + free(req); +} + +void devlink_trap_get_rsp_free(struct devlink_trap_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp->trap_name); + free(rsp); +} + +int devlink_trap_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_trap_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_TRAP_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.trap_name_len = len; + dst->trap_name = malloc(len + 1); + memcpy(dst->trap_name, ynl_attr_get_str(attr), len); + dst->trap_name[len] = 0; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_trap_get_rsp * +devlink_trap_get(struct ynl_sock *ys, struct devlink_trap_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_trap_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.trap_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_TRAP_NAME, req->trap_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_trap_get_rsp_parse; + yrs.rsp_cmd = 63; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_trap_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_TRAP_GET - dump */ +void devlink_trap_get_req_dump_free(struct devlink_trap_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_trap_get_list_free(struct devlink_trap_get_list *rsp) +{ + struct devlink_trap_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp->obj.trap_name); + free(rsp); + } +} + +struct devlink_trap_get_list * +devlink_trap_get_dump(struct ynl_sock *ys, + struct devlink_trap_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_trap_get_list); + yds.cb = devlink_trap_get_rsp_parse; + yds.rsp_cmd = 63; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_TRAP_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_trap_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_TRAP_SET ============== */ +/* DEVLINK_CMD_TRAP_SET - do */ +void devlink_trap_set_req_free(struct devlink_trap_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->trap_name); + free(req); +} + +int devlink_trap_set(struct ynl_sock *ys, struct devlink_trap_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.trap_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_TRAP_NAME, req->trap_name); + if (req->_present.trap_action) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_TRAP_ACTION, req->trap_action); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_TRAP_GROUP_GET ============== */ +/* DEVLINK_CMD_TRAP_GROUP_GET - do */ +void devlink_trap_group_get_req_free(struct devlink_trap_group_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->trap_group_name); + free(req); +} + +void devlink_trap_group_get_rsp_free(struct devlink_trap_group_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp->trap_group_name); + free(rsp); +} + +int devlink_trap_group_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_trap_group_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_TRAP_GROUP_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.trap_group_name_len = len; + dst->trap_group_name = malloc(len + 1); + memcpy(dst->trap_group_name, ynl_attr_get_str(attr), len); + dst->trap_group_name[len] = 0; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_trap_group_get_rsp * +devlink_trap_group_get(struct ynl_sock *ys, + struct devlink_trap_group_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_trap_group_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_GROUP_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.trap_group_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_TRAP_GROUP_NAME, req->trap_group_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_trap_group_get_rsp_parse; + yrs.rsp_cmd = 67; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_trap_group_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_TRAP_GROUP_GET - dump */ +void +devlink_trap_group_get_req_dump_free(struct devlink_trap_group_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_trap_group_get_list_free(struct devlink_trap_group_get_list *rsp) +{ + struct devlink_trap_group_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp->obj.trap_group_name); + free(rsp); + } +} + +struct devlink_trap_group_get_list * +devlink_trap_group_get_dump(struct ynl_sock *ys, + struct devlink_trap_group_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_trap_group_get_list); + yds.cb = devlink_trap_group_get_rsp_parse; + yds.rsp_cmd = 67; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_TRAP_GROUP_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_trap_group_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_TRAP_GROUP_SET ============== */ +/* DEVLINK_CMD_TRAP_GROUP_SET - do */ +void devlink_trap_group_set_req_free(struct devlink_trap_group_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->trap_group_name); + free(req); +} + +int devlink_trap_group_set(struct ynl_sock *ys, + struct devlink_trap_group_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_GROUP_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.trap_group_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_TRAP_GROUP_NAME, req->trap_group_name); + if (req->_present.trap_action) + ynl_attr_put_u8(nlh, DEVLINK_ATTR_TRAP_ACTION, req->trap_action); + if (req->_present.trap_policer_id) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_TRAP_POLICER_ID, req->trap_policer_id); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_TRAP_POLICER_GET ============== */ +/* DEVLINK_CMD_TRAP_POLICER_GET - do */ +void +devlink_trap_policer_get_req_free(struct devlink_trap_policer_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void +devlink_trap_policer_get_rsp_free(struct devlink_trap_policer_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_trap_policer_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_trap_policer_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_TRAP_POLICER_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.trap_policer_id = 1; + dst->trap_policer_id = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_trap_policer_get_rsp * +devlink_trap_policer_get(struct ynl_sock *ys, + struct devlink_trap_policer_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_trap_policer_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_POLICER_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.trap_policer_id) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_TRAP_POLICER_ID, req->trap_policer_id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_trap_policer_get_rsp_parse; + yrs.rsp_cmd = 71; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_trap_policer_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_TRAP_POLICER_GET - dump */ +void +devlink_trap_policer_get_req_dump_free(struct devlink_trap_policer_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void +devlink_trap_policer_get_list_free(struct devlink_trap_policer_get_list *rsp) +{ + struct devlink_trap_policer_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp); + } +} + +struct devlink_trap_policer_get_list * +devlink_trap_policer_get_dump(struct ynl_sock *ys, + struct devlink_trap_policer_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_trap_policer_get_list); + yds.cb = devlink_trap_policer_get_rsp_parse; + yds.rsp_cmd = 71; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_TRAP_POLICER_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_trap_policer_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_TRAP_POLICER_SET ============== */ +/* DEVLINK_CMD_TRAP_POLICER_SET - do */ +void +devlink_trap_policer_set_req_free(struct devlink_trap_policer_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_trap_policer_set(struct ynl_sock *ys, + struct devlink_trap_policer_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_TRAP_POLICER_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.trap_policer_id) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_TRAP_POLICER_ID, req->trap_policer_id); + if (req->_present.trap_policer_rate) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_TRAP_POLICER_RATE, req->trap_policer_rate); + if (req->_present.trap_policer_burst) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_TRAP_POLICER_BURST, req->trap_policer_burst); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_TEST ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_TEST - do */ +void +devlink_health_reporter_test_req_free(struct devlink_health_reporter_test_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->health_reporter_name); + free(req); +} + +int devlink_health_reporter_test(struct ynl_sock *ys, + struct devlink_health_reporter_test_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_HEALTH_REPORTER_TEST, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.health_reporter_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, req->health_reporter_name); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_RATE_GET ============== */ +/* DEVLINK_CMD_RATE_GET - do */ +void devlink_rate_get_req_free(struct devlink_rate_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->rate_node_name); + free(req); +} + +void devlink_rate_get_rsp_free(struct devlink_rate_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp->rate_node_name); + free(rsp); +} + +int devlink_rate_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_rate_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_PORT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_index = 1; + dst->port_index = ynl_attr_get_u32(attr); + } else if (type == DEVLINK_ATTR_RATE_NODE_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.rate_node_name_len = len; + dst->rate_node_name = malloc(len + 1); + memcpy(dst->rate_node_name, ynl_attr_get_str(attr), len); + dst->rate_node_name[len] = 0; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_rate_get_rsp * +devlink_rate_get(struct ynl_sock *ys, struct devlink_rate_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_rate_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_RATE_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + if (req->_present.rate_node_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_RATE_NODE_NAME, req->rate_node_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_rate_get_rsp_parse; + yrs.rsp_cmd = 76; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_rate_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_RATE_GET - dump */ +void devlink_rate_get_req_dump_free(struct devlink_rate_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_rate_get_list_free(struct devlink_rate_get_list *rsp) +{ + struct devlink_rate_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp->obj.rate_node_name); + free(rsp); + } +} + +struct devlink_rate_get_list * +devlink_rate_get_dump(struct ynl_sock *ys, + struct devlink_rate_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_rate_get_list); + yds.cb = devlink_rate_get_rsp_parse; + yds.rsp_cmd = 76; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_RATE_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_rate_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_RATE_SET ============== */ +/* DEVLINK_CMD_RATE_SET - do */ +void devlink_rate_set_req_free(struct devlink_rate_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->rate_node_name); + free(req->rate_parent_node_name); + free(req); +} + +int devlink_rate_set(struct ynl_sock *ys, struct devlink_rate_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_RATE_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.rate_node_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_RATE_NODE_NAME, req->rate_node_name); + if (req->_present.rate_tx_share) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_RATE_TX_SHARE, req->rate_tx_share); + if (req->_present.rate_tx_max) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_RATE_TX_MAX, req->rate_tx_max); + if (req->_present.rate_tx_priority) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_RATE_TX_PRIORITY, req->rate_tx_priority); + if (req->_present.rate_tx_weight) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_RATE_TX_WEIGHT, req->rate_tx_weight); + if (req->_present.rate_parent_node_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_RATE_PARENT_NODE_NAME, req->rate_parent_node_name); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_RATE_NEW ============== */ +/* DEVLINK_CMD_RATE_NEW - do */ +void devlink_rate_new_req_free(struct devlink_rate_new_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->rate_node_name); + free(req->rate_parent_node_name); + free(req); +} + +int devlink_rate_new(struct ynl_sock *ys, struct devlink_rate_new_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_RATE_NEW, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.rate_node_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_RATE_NODE_NAME, req->rate_node_name); + if (req->_present.rate_tx_share) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_RATE_TX_SHARE, req->rate_tx_share); + if (req->_present.rate_tx_max) + ynl_attr_put_u64(nlh, DEVLINK_ATTR_RATE_TX_MAX, req->rate_tx_max); + if (req->_present.rate_tx_priority) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_RATE_TX_PRIORITY, req->rate_tx_priority); + if (req->_present.rate_tx_weight) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_RATE_TX_WEIGHT, req->rate_tx_weight); + if (req->_present.rate_parent_node_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_RATE_PARENT_NODE_NAME, req->rate_parent_node_name); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_RATE_DEL ============== */ +/* DEVLINK_CMD_RATE_DEL - do */ +void devlink_rate_del_req_free(struct devlink_rate_del_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->rate_node_name); + free(req); +} + +int devlink_rate_del(struct ynl_sock *ys, struct devlink_rate_del_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_RATE_DEL, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.rate_node_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_RATE_NODE_NAME, req->rate_node_name); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_LINECARD_GET ============== */ +/* DEVLINK_CMD_LINECARD_GET - do */ +void devlink_linecard_get_req_free(struct devlink_linecard_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_linecard_get_rsp_free(struct devlink_linecard_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_linecard_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_linecard_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == DEVLINK_ATTR_LINECARD_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.linecard_index = 1; + dst->linecard_index = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_linecard_get_rsp * +devlink_linecard_get(struct ynl_sock *ys, struct devlink_linecard_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_linecard_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_LINECARD_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.linecard_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_LINECARD_INDEX, req->linecard_index); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_linecard_get_rsp_parse; + yrs.rsp_cmd = 80; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_linecard_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_LINECARD_GET - dump */ +void +devlink_linecard_get_req_dump_free(struct devlink_linecard_get_req_dump *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_linecard_get_list_free(struct devlink_linecard_get_list *rsp) +{ + struct devlink_linecard_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp); + } +} + +struct devlink_linecard_get_list * +devlink_linecard_get_dump(struct ynl_sock *ys, + struct devlink_linecard_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_linecard_get_list); + yds.cb = devlink_linecard_get_rsp_parse; + yds.rsp_cmd = 80; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_LINECARD_GET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_linecard_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_LINECARD_SET ============== */ +/* DEVLINK_CMD_LINECARD_SET - do */ +void devlink_linecard_set_req_free(struct devlink_linecard_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req->linecard_type); + free(req); +} + +int devlink_linecard_set(struct ynl_sock *ys, + struct devlink_linecard_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_LINECARD_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.linecard_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_LINECARD_INDEX, req->linecard_index); + if (req->_present.linecard_type_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_LINECARD_TYPE, req->linecard_type); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_SELFTESTS_GET ============== */ +/* DEVLINK_CMD_SELFTESTS_GET - do */ +void devlink_selftests_get_req_free(struct devlink_selftests_get_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +void devlink_selftests_get_rsp_free(struct devlink_selftests_get_rsp *rsp) +{ + free(rsp->bus_name); + free(rsp->dev_name); + free(rsp); +} + +int devlink_selftests_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct devlink_selftests_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DEVLINK_ATTR_BUS_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.bus_name_len = len; + dst->bus_name = malloc(len + 1); + memcpy(dst->bus_name, ynl_attr_get_str(attr), len); + dst->bus_name[len] = 0; + } else if (type == DEVLINK_ATTR_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } + } + + return YNL_PARSE_CB_OK; +} + +struct devlink_selftests_get_rsp * +devlink_selftests_get(struct ynl_sock *ys, + struct devlink_selftests_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct devlink_selftests_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SELFTESTS_GET, 1); + ys->req_policy = &devlink_nest; + yrs.yarg.rsp_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = devlink_selftests_get_rsp_parse; + yrs.rsp_cmd = DEVLINK_CMD_SELFTESTS_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + devlink_selftests_get_rsp_free(rsp); + return NULL; +} + +/* DEVLINK_CMD_SELFTESTS_GET - dump */ +void devlink_selftests_get_list_free(struct devlink_selftests_get_list *rsp) +{ + struct devlink_selftests_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.bus_name); + free(rsp->obj.dev_name); + free(rsp); + } +} + +struct devlink_selftests_get_list * +devlink_selftests_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &devlink_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct devlink_selftests_get_list); + yds.cb = devlink_selftests_get_rsp_parse; + yds.rsp_cmd = DEVLINK_CMD_SELFTESTS_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DEVLINK_CMD_SELFTESTS_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + devlink_selftests_get_list_free(yds.first); + return NULL; +} + +/* ============== DEVLINK_CMD_SELFTESTS_RUN ============== */ +/* DEVLINK_CMD_SELFTESTS_RUN - do */ +void devlink_selftests_run_req_free(struct devlink_selftests_run_req *req) +{ + free(req->bus_name); + free(req->dev_name); + devlink_dl_selftest_id_free(&req->selftests); + free(req); +} + +int devlink_selftests_run(struct ynl_sock *ys, + struct devlink_selftests_run_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_SELFTESTS_RUN, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.selftests) + devlink_dl_selftest_id_put(nlh, DEVLINK_ATTR_SELFTESTS, &req->selftests); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DEVLINK_CMD_NOTIFY_FILTER_SET ============== */ +/* DEVLINK_CMD_NOTIFY_FILTER_SET - do */ +void +devlink_notify_filter_set_req_free(struct devlink_notify_filter_set_req *req) +{ + free(req->bus_name); + free(req->dev_name); + free(req); +} + +int devlink_notify_filter_set(struct ynl_sock *ys, + struct devlink_notify_filter_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DEVLINK_CMD_NOTIFY_FILTER_SET, 1); + ys->req_policy = &devlink_nest; + + if (req->_present.bus_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_BUS_NAME, req->bus_name); + if (req->_present.dev_name_len) + ynl_attr_put_str(nlh, DEVLINK_ATTR_DEV_NAME, req->dev_name); + if (req->_present.port_index) + ynl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_INDEX, req->port_index); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +const struct ynl_family ynl_devlink_family = { + .name = "devlink", + .hdr_len = sizeof(struct genlmsghdr), +}; diff --git a/generated/devlink-user.h b/generated/devlink-user.h new file mode 100644 index 0000000..b54ee40 --- /dev/null +++ b/generated/devlink-user.h @@ -0,0 +1,5410 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/devlink.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_DEVLINK_GEN_H +#define _LINUX_DEVLINK_GEN_H + +#include +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_devlink_family; + +/* Enums */ +const char *devlink_op_str(int op); +const char *devlink_sb_pool_type_str(enum devlink_sb_pool_type value); +const char *devlink_port_type_str(enum devlink_port_type value); +const char *devlink_port_flavour_str(enum devlink_port_flavour value); +const char *devlink_port_fn_state_str(enum devlink_port_fn_state value); +const char *devlink_port_fn_opstate_str(enum devlink_port_fn_opstate value); +const char *devlink_port_fn_attr_cap_str(enum devlink_port_fn_attr_cap value); +const char *devlink_rate_type_str(enum devlink_rate_type value); +const char * +devlink_sb_threshold_type_str(enum devlink_sb_threshold_type value); +const char *devlink_eswitch_mode_str(enum devlink_eswitch_mode value); +const char * +devlink_eswitch_inline_mode_str(enum devlink_eswitch_inline_mode value); +const char * +devlink_eswitch_encap_mode_str(enum devlink_eswitch_encap_mode value); +const char *devlink_dpipe_header_id_str(enum devlink_dpipe_header_id value); +const char *devlink_dpipe_match_type_str(enum devlink_dpipe_match_type value); +const char * +devlink_dpipe_action_type_str(enum devlink_dpipe_action_type value); +const char * +devlink_dpipe_field_mapping_type_str(enum devlink_dpipe_field_mapping_type value); +const char *devlink_resource_unit_str(enum devlink_resource_unit value); +const char *devlink_reload_action_str(enum devlink_reload_action value); +const char *devlink_param_cmode_str(enum devlink_param_cmode value); +const char *devlink_flash_overwrite_str(enum devlink_flash_overwrite value); +const char *devlink_trap_action_str(enum devlink_trap_action value); +const char *devlink_trap_type_str(enum devlink_trap_type value); + +/* Common nested types */ +struct devlink_dl_dpipe_match { + struct { + __u32 dpipe_match_type:1; + __u32 dpipe_header_id:1; + __u32 dpipe_header_global:1; + __u32 dpipe_header_index:1; + __u32 dpipe_field_id:1; + } _present; + + enum devlink_dpipe_match_type dpipe_match_type; + enum devlink_dpipe_header_id dpipe_header_id; + __u8 dpipe_header_global; + __u32 dpipe_header_index; + __u32 dpipe_field_id; +}; + +struct devlink_dl_dpipe_match_value { + struct { + __u32 dpipe_value_len; + __u32 dpipe_value_mask_len; + __u32 dpipe_value_mapping:1; + } _present; + + unsigned int n_dpipe_match; + struct devlink_dl_dpipe_match *dpipe_match; + void *dpipe_value; + void *dpipe_value_mask; + __u32 dpipe_value_mapping; +}; + +struct devlink_dl_dpipe_action { + struct { + __u32 dpipe_action_type:1; + __u32 dpipe_header_id:1; + __u32 dpipe_header_global:1; + __u32 dpipe_header_index:1; + __u32 dpipe_field_id:1; + } _present; + + enum devlink_dpipe_action_type dpipe_action_type; + enum devlink_dpipe_header_id dpipe_header_id; + __u8 dpipe_header_global; + __u32 dpipe_header_index; + __u32 dpipe_field_id; +}; + +struct devlink_dl_dpipe_action_value { + struct { + __u32 dpipe_value_len; + __u32 dpipe_value_mask_len; + __u32 dpipe_value_mapping:1; + } _present; + + unsigned int n_dpipe_action; + struct devlink_dl_dpipe_action *dpipe_action; + void *dpipe_value; + void *dpipe_value_mask; + __u32 dpipe_value_mapping; +}; + +struct devlink_dl_dpipe_field { + struct { + __u32 dpipe_field_name_len; + __u32 dpipe_field_id:1; + __u32 dpipe_field_bitwidth:1; + __u32 dpipe_field_mapping_type:1; + } _present; + + char *dpipe_field_name; + __u32 dpipe_field_id; + __u32 dpipe_field_bitwidth; + enum devlink_dpipe_field_mapping_type dpipe_field_mapping_type; +}; + +struct devlink_dl_resource { + struct { + __u32 resource_name_len; + __u32 resource_id:1; + __u32 resource_size:1; + __u32 resource_size_new:1; + __u32 resource_size_valid:1; + __u32 resource_size_min:1; + __u32 resource_size_max:1; + __u32 resource_size_gran:1; + __u32 resource_unit:1; + __u32 resource_occ:1; + } _present; + + char *resource_name; + __u64 resource_id; + __u64 resource_size; + __u64 resource_size_new; + __u8 resource_size_valid; + __u64 resource_size_min; + __u64 resource_size_max; + __u64 resource_size_gran; + enum devlink_resource_unit resource_unit; + __u64 resource_occ; +}; + +struct devlink_dl_param { + struct { + __u32 param_name_len; + __u32 param_generic:1; + __u32 param_type:1; + } _present; + + char *param_name; + __u8 param_type; +}; + +struct devlink_dl_region_snapshot { + struct { + __u32 region_snapshot_id:1; + } _present; + + __u32 region_snapshot_id; +}; + +struct devlink_dl_region_chunk { + struct { + __u32 region_chunk_data_len; + __u32 region_chunk_addr:1; + } _present; + + void *region_chunk_data; + __u64 region_chunk_addr; +}; + +struct devlink_dl_info_version { + struct { + __u32 info_version_name_len; + __u32 info_version_value_len; + } _present; + + char *info_version_name; + char *info_version_value; +}; + +struct devlink_dl_fmsg { + struct { + __u32 fmsg_obj_nest_start:1; + __u32 fmsg_pair_nest_start:1; + __u32 fmsg_arr_nest_start:1; + __u32 fmsg_nest_end:1; + __u32 fmsg_obj_name_len; + } _present; + + char *fmsg_obj_name; +}; + +struct devlink_dl_health_reporter { + struct { + __u32 health_reporter_name_len; + __u32 health_reporter_state:1; + __u32 health_reporter_err_count:1; + __u32 health_reporter_recover_count:1; + __u32 health_reporter_graceful_period:1; + __u32 health_reporter_auto_recover:1; + __u32 health_reporter_dump_ts:1; + __u32 health_reporter_dump_ts_ns:1; + __u32 health_reporter_auto_dump:1; + } _present; + + char *health_reporter_name; + __u8 health_reporter_state; + __u64 health_reporter_err_count; + __u64 health_reporter_recover_count; + __u64 health_reporter_graceful_period; + __u8 health_reporter_auto_recover; + __u64 health_reporter_dump_ts; + __u64 health_reporter_dump_ts_ns; + __u8 health_reporter_auto_dump; +}; + +struct devlink_dl_attr_stats { + struct { + __u32 stats_rx_packets:1; + __u32 stats_rx_bytes:1; + __u32 stats_rx_dropped:1; + } _present; + + __u64 stats_rx_packets; + __u64 stats_rx_bytes; + __u64 stats_rx_dropped; +}; + +struct devlink_dl_trap_metadata { + struct { + __u32 trap_metadata_type_in_port:1; + __u32 trap_metadata_type_fa_cookie:1; + } _present; +}; + +struct devlink_dl_port_function { + struct { + __u32 hw_addr_len; + __u32 state:1; + __u32 opstate:1; + __u32 caps:1; + } _present; + + void *hw_addr; + enum devlink_port_fn_state state; + enum devlink_port_fn_opstate opstate; + struct nla_bitfield32 caps; +}; + +struct devlink_dl_reload_stats_entry { + struct { + __u32 reload_stats_limit:1; + __u32 reload_stats_value:1; + } _present; + + __u8 reload_stats_limit; + __u32 reload_stats_value; +}; + +struct devlink_dl_reload_act_stats { + unsigned int n_reload_stats_entry; + struct devlink_dl_reload_stats_entry *reload_stats_entry; +}; + +struct devlink_dl_linecard_supported_types { + struct { + __u32 linecard_type_len; + } _present; + + char *linecard_type; +}; + +struct devlink_dl_selftest_id { + struct { + __u32 flash:1; + } _present; +}; + +struct devlink_dl_dpipe_table_matches { + unsigned int n_dpipe_match; + struct devlink_dl_dpipe_match *dpipe_match; +}; + +struct devlink_dl_dpipe_table_actions { + unsigned int n_dpipe_action; + struct devlink_dl_dpipe_action *dpipe_action; +}; + +struct devlink_dl_dpipe_entry_match_values { + unsigned int n_dpipe_match_value; + struct devlink_dl_dpipe_match_value *dpipe_match_value; +}; + +struct devlink_dl_dpipe_entry_action_values { + unsigned int n_dpipe_action_value; + struct devlink_dl_dpipe_action_value *dpipe_action_value; +}; + +struct devlink_dl_dpipe_header_fields { + unsigned int n_dpipe_field; + struct devlink_dl_dpipe_field *dpipe_field; +}; + +struct devlink_dl_resource_list { + unsigned int n_resource; + struct devlink_dl_resource *resource; +}; + +struct devlink_dl_region_snapshots { + struct { + __u32 region_snapshot:1; + } _present; + + struct devlink_dl_region_snapshot region_snapshot; +}; + +struct devlink_dl_region_chunks { + struct { + __u32 region_chunk:1; + } _present; + + struct devlink_dl_region_chunk region_chunk; +}; + +struct devlink_dl_reload_act_info { + struct { + __u32 reload_action:1; + } _present; + + enum devlink_reload_action reload_action; + unsigned int n_reload_action_stats; + struct devlink_dl_reload_act_stats *reload_action_stats; +}; + +struct devlink_dl_dpipe_table { + struct { + __u32 dpipe_table_name_len; + __u32 dpipe_table_size:1; + __u32 dpipe_table_matches:1; + __u32 dpipe_table_actions:1; + __u32 dpipe_table_counters_enabled:1; + __u32 dpipe_table_resource_id:1; + __u32 dpipe_table_resource_units:1; + } _present; + + char *dpipe_table_name; + __u64 dpipe_table_size; + struct devlink_dl_dpipe_table_matches dpipe_table_matches; + struct devlink_dl_dpipe_table_actions dpipe_table_actions; + __u8 dpipe_table_counters_enabled; + __u64 dpipe_table_resource_id; + __u64 dpipe_table_resource_units; +}; + +struct devlink_dl_dpipe_entry { + struct { + __u32 dpipe_entry_index:1; + __u32 dpipe_entry_match_values:1; + __u32 dpipe_entry_action_values:1; + __u32 dpipe_entry_counter:1; + } _present; + + __u64 dpipe_entry_index; + struct devlink_dl_dpipe_entry_match_values dpipe_entry_match_values; + struct devlink_dl_dpipe_entry_action_values dpipe_entry_action_values; + __u64 dpipe_entry_counter; +}; + +struct devlink_dl_dpipe_header { + struct { + __u32 dpipe_header_name_len; + __u32 dpipe_header_id:1; + __u32 dpipe_header_global:1; + __u32 dpipe_header_fields:1; + } _present; + + char *dpipe_header_name; + enum devlink_dpipe_header_id dpipe_header_id; + __u8 dpipe_header_global; + struct devlink_dl_dpipe_header_fields dpipe_header_fields; +}; + +struct devlink_dl_reload_stats { + unsigned int n_reload_action_info; + struct devlink_dl_reload_act_info *reload_action_info; +}; + +struct devlink_dl_dpipe_tables { + unsigned int n_dpipe_table; + struct devlink_dl_dpipe_table *dpipe_table; +}; + +struct devlink_dl_dpipe_entries { + unsigned int n_dpipe_entry; + struct devlink_dl_dpipe_entry *dpipe_entry; +}; + +struct devlink_dl_dpipe_headers { + unsigned int n_dpipe_header; + struct devlink_dl_dpipe_header *dpipe_header; +}; + +struct devlink_dl_dev_stats { + struct { + __u32 reload_stats:1; + __u32 remote_reload_stats:1; + } _present; + + struct devlink_dl_reload_stats reload_stats; + struct devlink_dl_reload_stats remote_reload_stats; +}; + +/* ============== DEVLINK_CMD_GET ============== */ +/* DEVLINK_CMD_GET - do */ +struct devlink_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_get_req *devlink_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_get_req)); +} +void devlink_get_req_free(struct devlink_get_req *req); + +static inline void +devlink_get_req_set_bus_name(struct devlink_get_req *req, const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_get_req_set_dev_name(struct devlink_get_req *req, const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 reload_failed:1; + __u32 dev_stats:1; + } _present; + + char *bus_name; + char *dev_name; + __u8 reload_failed; + struct devlink_dl_dev_stats dev_stats; +}; + +void devlink_get_rsp_free(struct devlink_get_rsp *rsp); + +/* + * Get devlink instances. + */ +struct devlink_get_rsp * +devlink_get(struct ynl_sock *ys, struct devlink_get_req *req); + +/* DEVLINK_CMD_GET - dump */ +struct devlink_get_list { + struct devlink_get_list *next; + struct devlink_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_get_list_free(struct devlink_get_list *rsp); + +struct devlink_get_list *devlink_get_dump(struct ynl_sock *ys); + +/* ============== DEVLINK_CMD_PORT_GET ============== */ +/* DEVLINK_CMD_PORT_GET - do */ +struct devlink_port_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +static inline struct devlink_port_get_req *devlink_port_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_port_get_req)); +} +void devlink_port_get_req_free(struct devlink_port_get_req *req); + +static inline void +devlink_port_get_req_set_bus_name(struct devlink_port_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_port_get_req_set_dev_name(struct devlink_port_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_port_get_req_set_port_index(struct devlink_port_get_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} + +struct devlink_port_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +void devlink_port_get_rsp_free(struct devlink_port_get_rsp *rsp); + +/* + * Get devlink port instances. + */ +struct devlink_port_get_rsp * +devlink_port_get(struct ynl_sock *ys, struct devlink_port_get_req *req); + +/* DEVLINK_CMD_PORT_GET - dump */ +struct devlink_port_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_port_get_req_dump * +devlink_port_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_port_get_req_dump)); +} +void devlink_port_get_req_dump_free(struct devlink_port_get_req_dump *req); + +static inline void +devlink_port_get_req_dump_set_bus_name(struct devlink_port_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_port_get_req_dump_set_dev_name(struct devlink_port_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_port_get_rsp_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +struct devlink_port_get_rsp_list { + struct devlink_port_get_rsp_list *next; + struct devlink_port_get_rsp_dump obj __attribute__((aligned(8))); +}; + +void devlink_port_get_rsp_list_free(struct devlink_port_get_rsp_list *rsp); + +struct devlink_port_get_rsp_list * +devlink_port_get_dump(struct ynl_sock *ys, + struct devlink_port_get_req_dump *req); + +/* ============== DEVLINK_CMD_PORT_SET ============== */ +/* DEVLINK_CMD_PORT_SET - do */ +struct devlink_port_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 port_type:1; + __u32 port_function:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + enum devlink_port_type port_type; + struct devlink_dl_port_function port_function; +}; + +static inline struct devlink_port_set_req *devlink_port_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_port_set_req)); +} +void devlink_port_set_req_free(struct devlink_port_set_req *req); + +static inline void +devlink_port_set_req_set_bus_name(struct devlink_port_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_port_set_req_set_dev_name(struct devlink_port_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_port_set_req_set_port_index(struct devlink_port_set_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_port_set_req_set_port_type(struct devlink_port_set_req *req, + enum devlink_port_type port_type) +{ + req->_present.port_type = 1; + req->port_type = port_type; +} +static inline void +devlink_port_set_req_set_port_function_hw_addr(struct devlink_port_set_req *req, + const void *hw_addr, size_t len) +{ + free(req->port_function.hw_addr); + req->port_function._present.hw_addr_len = len; + req->port_function.hw_addr = malloc(req->port_function._present.hw_addr_len); + memcpy(req->port_function.hw_addr, hw_addr, req->port_function._present.hw_addr_len); +} +static inline void +devlink_port_set_req_set_port_function_state(struct devlink_port_set_req *req, + enum devlink_port_fn_state state) +{ + req->_present.port_function = 1; + req->port_function._present.state = 1; + req->port_function.state = state; +} +static inline void +devlink_port_set_req_set_port_function_opstate(struct devlink_port_set_req *req, + enum devlink_port_fn_opstate opstate) +{ + req->_present.port_function = 1; + req->port_function._present.opstate = 1; + req->port_function.opstate = opstate; +} +static inline void +devlink_port_set_req_set_port_function_caps(struct devlink_port_set_req *req, + struct nla_bitfield32 *caps) +{ + req->_present.port_function = 1; + req->port_function._present.caps = 1; + memcpy(&req->port_function.caps, caps, sizeof(struct nla_bitfield32)); +} + +/* + * Set devlink port instances. + */ +int devlink_port_set(struct ynl_sock *ys, struct devlink_port_set_req *req); + +/* ============== DEVLINK_CMD_PORT_NEW ============== */ +/* DEVLINK_CMD_PORT_NEW - do */ +struct devlink_port_new_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 port_flavour:1; + __u32 port_pci_pf_number:1; + __u32 port_pci_sf_number:1; + __u32 port_controller_number:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + enum devlink_port_flavour port_flavour; + __u16 port_pci_pf_number; + __u32 port_pci_sf_number; + __u32 port_controller_number; +}; + +static inline struct devlink_port_new_req *devlink_port_new_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_port_new_req)); +} +void devlink_port_new_req_free(struct devlink_port_new_req *req); + +static inline void +devlink_port_new_req_set_bus_name(struct devlink_port_new_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_port_new_req_set_dev_name(struct devlink_port_new_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_port_new_req_set_port_index(struct devlink_port_new_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_port_new_req_set_port_flavour(struct devlink_port_new_req *req, + enum devlink_port_flavour port_flavour) +{ + req->_present.port_flavour = 1; + req->port_flavour = port_flavour; +} +static inline void +devlink_port_new_req_set_port_pci_pf_number(struct devlink_port_new_req *req, + __u16 port_pci_pf_number) +{ + req->_present.port_pci_pf_number = 1; + req->port_pci_pf_number = port_pci_pf_number; +} +static inline void +devlink_port_new_req_set_port_pci_sf_number(struct devlink_port_new_req *req, + __u32 port_pci_sf_number) +{ + req->_present.port_pci_sf_number = 1; + req->port_pci_sf_number = port_pci_sf_number; +} +static inline void +devlink_port_new_req_set_port_controller_number(struct devlink_port_new_req *req, + __u32 port_controller_number) +{ + req->_present.port_controller_number = 1; + req->port_controller_number = port_controller_number; +} + +struct devlink_port_new_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +void devlink_port_new_rsp_free(struct devlink_port_new_rsp *rsp); + +/* + * Create devlink port instances. + */ +struct devlink_port_new_rsp * +devlink_port_new(struct ynl_sock *ys, struct devlink_port_new_req *req); + +/* ============== DEVLINK_CMD_PORT_DEL ============== */ +/* DEVLINK_CMD_PORT_DEL - do */ +struct devlink_port_del_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +static inline struct devlink_port_del_req *devlink_port_del_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_port_del_req)); +} +void devlink_port_del_req_free(struct devlink_port_del_req *req); + +static inline void +devlink_port_del_req_set_bus_name(struct devlink_port_del_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_port_del_req_set_dev_name(struct devlink_port_del_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_port_del_req_set_port_index(struct devlink_port_del_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} + +/* + * Delete devlink port instances. + */ +int devlink_port_del(struct ynl_sock *ys, struct devlink_port_del_req *req); + +/* ============== DEVLINK_CMD_PORT_SPLIT ============== */ +/* DEVLINK_CMD_PORT_SPLIT - do */ +struct devlink_port_split_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 port_split_count:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + __u32 port_split_count; +}; + +static inline struct devlink_port_split_req *devlink_port_split_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_port_split_req)); +} +void devlink_port_split_req_free(struct devlink_port_split_req *req); + +static inline void +devlink_port_split_req_set_bus_name(struct devlink_port_split_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_port_split_req_set_dev_name(struct devlink_port_split_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_port_split_req_set_port_index(struct devlink_port_split_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_port_split_req_set_port_split_count(struct devlink_port_split_req *req, + __u32 port_split_count) +{ + req->_present.port_split_count = 1; + req->port_split_count = port_split_count; +} + +/* + * Split devlink port instances. + */ +int devlink_port_split(struct ynl_sock *ys, struct devlink_port_split_req *req); + +/* ============== DEVLINK_CMD_PORT_UNSPLIT ============== */ +/* DEVLINK_CMD_PORT_UNSPLIT - do */ +struct devlink_port_unsplit_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +static inline struct devlink_port_unsplit_req * +devlink_port_unsplit_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_port_unsplit_req)); +} +void devlink_port_unsplit_req_free(struct devlink_port_unsplit_req *req); + +static inline void +devlink_port_unsplit_req_set_bus_name(struct devlink_port_unsplit_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_port_unsplit_req_set_dev_name(struct devlink_port_unsplit_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_port_unsplit_req_set_port_index(struct devlink_port_unsplit_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} + +/* + * Unplit devlink port instances. + */ +int devlink_port_unsplit(struct ynl_sock *ys, + struct devlink_port_unsplit_req *req); + +/* ============== DEVLINK_CMD_SB_GET ============== */ +/* DEVLINK_CMD_SB_GET - do */ +struct devlink_sb_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 sb_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 sb_index; +}; + +static inline struct devlink_sb_get_req *devlink_sb_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_get_req)); +} +void devlink_sb_get_req_free(struct devlink_sb_get_req *req); + +static inline void +devlink_sb_get_req_set_bus_name(struct devlink_sb_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_get_req_set_dev_name(struct devlink_sb_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_sb_get_req_set_sb_index(struct devlink_sb_get_req *req, __u32 sb_index) +{ + req->_present.sb_index = 1; + req->sb_index = sb_index; +} + +struct devlink_sb_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 sb_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 sb_index; +}; + +void devlink_sb_get_rsp_free(struct devlink_sb_get_rsp *rsp); + +/* + * Get shared buffer instances. + */ +struct devlink_sb_get_rsp * +devlink_sb_get(struct ynl_sock *ys, struct devlink_sb_get_req *req); + +/* DEVLINK_CMD_SB_GET - dump */ +struct devlink_sb_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_sb_get_req_dump * +devlink_sb_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_get_req_dump)); +} +void devlink_sb_get_req_dump_free(struct devlink_sb_get_req_dump *req); + +static inline void +devlink_sb_get_req_dump_set_bus_name(struct devlink_sb_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_get_req_dump_set_dev_name(struct devlink_sb_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_sb_get_list { + struct devlink_sb_get_list *next; + struct devlink_sb_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_sb_get_list_free(struct devlink_sb_get_list *rsp); + +struct devlink_sb_get_list * +devlink_sb_get_dump(struct ynl_sock *ys, struct devlink_sb_get_req_dump *req); + +/* ============== DEVLINK_CMD_SB_POOL_GET ============== */ +/* DEVLINK_CMD_SB_POOL_GET - do */ +struct devlink_sb_pool_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 sb_index:1; + __u32 sb_pool_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 sb_index; + __u16 sb_pool_index; +}; + +static inline struct devlink_sb_pool_get_req * +devlink_sb_pool_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_pool_get_req)); +} +void devlink_sb_pool_get_req_free(struct devlink_sb_pool_get_req *req); + +static inline void +devlink_sb_pool_get_req_set_bus_name(struct devlink_sb_pool_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_pool_get_req_set_dev_name(struct devlink_sb_pool_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_sb_pool_get_req_set_sb_index(struct devlink_sb_pool_get_req *req, + __u32 sb_index) +{ + req->_present.sb_index = 1; + req->sb_index = sb_index; +} +static inline void +devlink_sb_pool_get_req_set_sb_pool_index(struct devlink_sb_pool_get_req *req, + __u16 sb_pool_index) +{ + req->_present.sb_pool_index = 1; + req->sb_pool_index = sb_pool_index; +} + +struct devlink_sb_pool_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 sb_index:1; + __u32 sb_pool_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 sb_index; + __u16 sb_pool_index; +}; + +void devlink_sb_pool_get_rsp_free(struct devlink_sb_pool_get_rsp *rsp); + +/* + * Get shared buffer pool instances. + */ +struct devlink_sb_pool_get_rsp * +devlink_sb_pool_get(struct ynl_sock *ys, struct devlink_sb_pool_get_req *req); + +/* DEVLINK_CMD_SB_POOL_GET - dump */ +struct devlink_sb_pool_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_sb_pool_get_req_dump * +devlink_sb_pool_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_pool_get_req_dump)); +} +void +devlink_sb_pool_get_req_dump_free(struct devlink_sb_pool_get_req_dump *req); + +static inline void +devlink_sb_pool_get_req_dump_set_bus_name(struct devlink_sb_pool_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_pool_get_req_dump_set_dev_name(struct devlink_sb_pool_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_sb_pool_get_list { + struct devlink_sb_pool_get_list *next; + struct devlink_sb_pool_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_sb_pool_get_list_free(struct devlink_sb_pool_get_list *rsp); + +struct devlink_sb_pool_get_list * +devlink_sb_pool_get_dump(struct ynl_sock *ys, + struct devlink_sb_pool_get_req_dump *req); + +/* ============== DEVLINK_CMD_SB_POOL_SET ============== */ +/* DEVLINK_CMD_SB_POOL_SET - do */ +struct devlink_sb_pool_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 sb_index:1; + __u32 sb_pool_index:1; + __u32 sb_pool_threshold_type:1; + __u32 sb_pool_size:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 sb_index; + __u16 sb_pool_index; + enum devlink_sb_threshold_type sb_pool_threshold_type; + __u32 sb_pool_size; +}; + +static inline struct devlink_sb_pool_set_req * +devlink_sb_pool_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_pool_set_req)); +} +void devlink_sb_pool_set_req_free(struct devlink_sb_pool_set_req *req); + +static inline void +devlink_sb_pool_set_req_set_bus_name(struct devlink_sb_pool_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_pool_set_req_set_dev_name(struct devlink_sb_pool_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_sb_pool_set_req_set_sb_index(struct devlink_sb_pool_set_req *req, + __u32 sb_index) +{ + req->_present.sb_index = 1; + req->sb_index = sb_index; +} +static inline void +devlink_sb_pool_set_req_set_sb_pool_index(struct devlink_sb_pool_set_req *req, + __u16 sb_pool_index) +{ + req->_present.sb_pool_index = 1; + req->sb_pool_index = sb_pool_index; +} +static inline void +devlink_sb_pool_set_req_set_sb_pool_threshold_type(struct devlink_sb_pool_set_req *req, + enum devlink_sb_threshold_type sb_pool_threshold_type) +{ + req->_present.sb_pool_threshold_type = 1; + req->sb_pool_threshold_type = sb_pool_threshold_type; +} +static inline void +devlink_sb_pool_set_req_set_sb_pool_size(struct devlink_sb_pool_set_req *req, + __u32 sb_pool_size) +{ + req->_present.sb_pool_size = 1; + req->sb_pool_size = sb_pool_size; +} + +/* + * Set shared buffer pool instances. + */ +int devlink_sb_pool_set(struct ynl_sock *ys, + struct devlink_sb_pool_set_req *req); + +/* ============== DEVLINK_CMD_SB_PORT_POOL_GET ============== */ +/* DEVLINK_CMD_SB_PORT_POOL_GET - do */ +struct devlink_sb_port_pool_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 sb_index:1; + __u32 sb_pool_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + __u32 sb_index; + __u16 sb_pool_index; +}; + +static inline struct devlink_sb_port_pool_get_req * +devlink_sb_port_pool_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_port_pool_get_req)); +} +void +devlink_sb_port_pool_get_req_free(struct devlink_sb_port_pool_get_req *req); + +static inline void +devlink_sb_port_pool_get_req_set_bus_name(struct devlink_sb_port_pool_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_port_pool_get_req_set_dev_name(struct devlink_sb_port_pool_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_sb_port_pool_get_req_set_port_index(struct devlink_sb_port_pool_get_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_sb_port_pool_get_req_set_sb_index(struct devlink_sb_port_pool_get_req *req, + __u32 sb_index) +{ + req->_present.sb_index = 1; + req->sb_index = sb_index; +} +static inline void +devlink_sb_port_pool_get_req_set_sb_pool_index(struct devlink_sb_port_pool_get_req *req, + __u16 sb_pool_index) +{ + req->_present.sb_pool_index = 1; + req->sb_pool_index = sb_pool_index; +} + +struct devlink_sb_port_pool_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 sb_index:1; + __u32 sb_pool_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + __u32 sb_index; + __u16 sb_pool_index; +}; + +void +devlink_sb_port_pool_get_rsp_free(struct devlink_sb_port_pool_get_rsp *rsp); + +/* + * Get shared buffer port-pool combinations and threshold. + */ +struct devlink_sb_port_pool_get_rsp * +devlink_sb_port_pool_get(struct ynl_sock *ys, + struct devlink_sb_port_pool_get_req *req); + +/* DEVLINK_CMD_SB_PORT_POOL_GET - dump */ +struct devlink_sb_port_pool_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_sb_port_pool_get_req_dump * +devlink_sb_port_pool_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_port_pool_get_req_dump)); +} +void +devlink_sb_port_pool_get_req_dump_free(struct devlink_sb_port_pool_get_req_dump *req); + +static inline void +devlink_sb_port_pool_get_req_dump_set_bus_name(struct devlink_sb_port_pool_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_port_pool_get_req_dump_set_dev_name(struct devlink_sb_port_pool_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_sb_port_pool_get_list { + struct devlink_sb_port_pool_get_list *next; + struct devlink_sb_port_pool_get_rsp obj __attribute__((aligned(8))); +}; + +void +devlink_sb_port_pool_get_list_free(struct devlink_sb_port_pool_get_list *rsp); + +struct devlink_sb_port_pool_get_list * +devlink_sb_port_pool_get_dump(struct ynl_sock *ys, + struct devlink_sb_port_pool_get_req_dump *req); + +/* ============== DEVLINK_CMD_SB_PORT_POOL_SET ============== */ +/* DEVLINK_CMD_SB_PORT_POOL_SET - do */ +struct devlink_sb_port_pool_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 sb_index:1; + __u32 sb_pool_index:1; + __u32 sb_threshold:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + __u32 sb_index; + __u16 sb_pool_index; + __u32 sb_threshold; +}; + +static inline struct devlink_sb_port_pool_set_req * +devlink_sb_port_pool_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_port_pool_set_req)); +} +void +devlink_sb_port_pool_set_req_free(struct devlink_sb_port_pool_set_req *req); + +static inline void +devlink_sb_port_pool_set_req_set_bus_name(struct devlink_sb_port_pool_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_port_pool_set_req_set_dev_name(struct devlink_sb_port_pool_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_sb_port_pool_set_req_set_port_index(struct devlink_sb_port_pool_set_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_sb_port_pool_set_req_set_sb_index(struct devlink_sb_port_pool_set_req *req, + __u32 sb_index) +{ + req->_present.sb_index = 1; + req->sb_index = sb_index; +} +static inline void +devlink_sb_port_pool_set_req_set_sb_pool_index(struct devlink_sb_port_pool_set_req *req, + __u16 sb_pool_index) +{ + req->_present.sb_pool_index = 1; + req->sb_pool_index = sb_pool_index; +} +static inline void +devlink_sb_port_pool_set_req_set_sb_threshold(struct devlink_sb_port_pool_set_req *req, + __u32 sb_threshold) +{ + req->_present.sb_threshold = 1; + req->sb_threshold = sb_threshold; +} + +/* + * Set shared buffer port-pool combinations and threshold. + */ +int devlink_sb_port_pool_set(struct ynl_sock *ys, + struct devlink_sb_port_pool_set_req *req); + +/* ============== DEVLINK_CMD_SB_TC_POOL_BIND_GET ============== */ +/* DEVLINK_CMD_SB_TC_POOL_BIND_GET - do */ +struct devlink_sb_tc_pool_bind_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 sb_index:1; + __u32 sb_pool_type:1; + __u32 sb_tc_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + __u32 sb_index; + enum devlink_sb_pool_type sb_pool_type; + __u16 sb_tc_index; +}; + +static inline struct devlink_sb_tc_pool_bind_get_req * +devlink_sb_tc_pool_bind_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_tc_pool_bind_get_req)); +} +void +devlink_sb_tc_pool_bind_get_req_free(struct devlink_sb_tc_pool_bind_get_req *req); + +static inline void +devlink_sb_tc_pool_bind_get_req_set_bus_name(struct devlink_sb_tc_pool_bind_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_tc_pool_bind_get_req_set_dev_name(struct devlink_sb_tc_pool_bind_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_sb_tc_pool_bind_get_req_set_port_index(struct devlink_sb_tc_pool_bind_get_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_sb_tc_pool_bind_get_req_set_sb_index(struct devlink_sb_tc_pool_bind_get_req *req, + __u32 sb_index) +{ + req->_present.sb_index = 1; + req->sb_index = sb_index; +} +static inline void +devlink_sb_tc_pool_bind_get_req_set_sb_pool_type(struct devlink_sb_tc_pool_bind_get_req *req, + enum devlink_sb_pool_type sb_pool_type) +{ + req->_present.sb_pool_type = 1; + req->sb_pool_type = sb_pool_type; +} +static inline void +devlink_sb_tc_pool_bind_get_req_set_sb_tc_index(struct devlink_sb_tc_pool_bind_get_req *req, + __u16 sb_tc_index) +{ + req->_present.sb_tc_index = 1; + req->sb_tc_index = sb_tc_index; +} + +struct devlink_sb_tc_pool_bind_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 sb_index:1; + __u32 sb_pool_type:1; + __u32 sb_tc_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + __u32 sb_index; + enum devlink_sb_pool_type sb_pool_type; + __u16 sb_tc_index; +}; + +void +devlink_sb_tc_pool_bind_get_rsp_free(struct devlink_sb_tc_pool_bind_get_rsp *rsp); + +/* + * Get shared buffer port-TC to pool bindings and threshold. + */ +struct devlink_sb_tc_pool_bind_get_rsp * +devlink_sb_tc_pool_bind_get(struct ynl_sock *ys, + struct devlink_sb_tc_pool_bind_get_req *req); + +/* DEVLINK_CMD_SB_TC_POOL_BIND_GET - dump */ +struct devlink_sb_tc_pool_bind_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_sb_tc_pool_bind_get_req_dump * +devlink_sb_tc_pool_bind_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_tc_pool_bind_get_req_dump)); +} +void +devlink_sb_tc_pool_bind_get_req_dump_free(struct devlink_sb_tc_pool_bind_get_req_dump *req); + +static inline void +devlink_sb_tc_pool_bind_get_req_dump_set_bus_name(struct devlink_sb_tc_pool_bind_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_tc_pool_bind_get_req_dump_set_dev_name(struct devlink_sb_tc_pool_bind_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_sb_tc_pool_bind_get_list { + struct devlink_sb_tc_pool_bind_get_list *next; + struct devlink_sb_tc_pool_bind_get_rsp obj __attribute__((aligned(8))); +}; + +void +devlink_sb_tc_pool_bind_get_list_free(struct devlink_sb_tc_pool_bind_get_list *rsp); + +struct devlink_sb_tc_pool_bind_get_list * +devlink_sb_tc_pool_bind_get_dump(struct ynl_sock *ys, + struct devlink_sb_tc_pool_bind_get_req_dump *req); + +/* ============== DEVLINK_CMD_SB_TC_POOL_BIND_SET ============== */ +/* DEVLINK_CMD_SB_TC_POOL_BIND_SET - do */ +struct devlink_sb_tc_pool_bind_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 sb_index:1; + __u32 sb_pool_index:1; + __u32 sb_pool_type:1; + __u32 sb_tc_index:1; + __u32 sb_threshold:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + __u32 sb_index; + __u16 sb_pool_index; + enum devlink_sb_pool_type sb_pool_type; + __u16 sb_tc_index; + __u32 sb_threshold; +}; + +static inline struct devlink_sb_tc_pool_bind_set_req * +devlink_sb_tc_pool_bind_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_tc_pool_bind_set_req)); +} +void +devlink_sb_tc_pool_bind_set_req_free(struct devlink_sb_tc_pool_bind_set_req *req); + +static inline void +devlink_sb_tc_pool_bind_set_req_set_bus_name(struct devlink_sb_tc_pool_bind_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_tc_pool_bind_set_req_set_dev_name(struct devlink_sb_tc_pool_bind_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_sb_tc_pool_bind_set_req_set_port_index(struct devlink_sb_tc_pool_bind_set_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_sb_tc_pool_bind_set_req_set_sb_index(struct devlink_sb_tc_pool_bind_set_req *req, + __u32 sb_index) +{ + req->_present.sb_index = 1; + req->sb_index = sb_index; +} +static inline void +devlink_sb_tc_pool_bind_set_req_set_sb_pool_index(struct devlink_sb_tc_pool_bind_set_req *req, + __u16 sb_pool_index) +{ + req->_present.sb_pool_index = 1; + req->sb_pool_index = sb_pool_index; +} +static inline void +devlink_sb_tc_pool_bind_set_req_set_sb_pool_type(struct devlink_sb_tc_pool_bind_set_req *req, + enum devlink_sb_pool_type sb_pool_type) +{ + req->_present.sb_pool_type = 1; + req->sb_pool_type = sb_pool_type; +} +static inline void +devlink_sb_tc_pool_bind_set_req_set_sb_tc_index(struct devlink_sb_tc_pool_bind_set_req *req, + __u16 sb_tc_index) +{ + req->_present.sb_tc_index = 1; + req->sb_tc_index = sb_tc_index; +} +static inline void +devlink_sb_tc_pool_bind_set_req_set_sb_threshold(struct devlink_sb_tc_pool_bind_set_req *req, + __u32 sb_threshold) +{ + req->_present.sb_threshold = 1; + req->sb_threshold = sb_threshold; +} + +/* + * Set shared buffer port-TC to pool bindings and threshold. + */ +int devlink_sb_tc_pool_bind_set(struct ynl_sock *ys, + struct devlink_sb_tc_pool_bind_set_req *req); + +/* ============== DEVLINK_CMD_SB_OCC_SNAPSHOT ============== */ +/* DEVLINK_CMD_SB_OCC_SNAPSHOT - do */ +struct devlink_sb_occ_snapshot_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 sb_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 sb_index; +}; + +static inline struct devlink_sb_occ_snapshot_req * +devlink_sb_occ_snapshot_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_occ_snapshot_req)); +} +void devlink_sb_occ_snapshot_req_free(struct devlink_sb_occ_snapshot_req *req); + +static inline void +devlink_sb_occ_snapshot_req_set_bus_name(struct devlink_sb_occ_snapshot_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_occ_snapshot_req_set_dev_name(struct devlink_sb_occ_snapshot_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_sb_occ_snapshot_req_set_sb_index(struct devlink_sb_occ_snapshot_req *req, + __u32 sb_index) +{ + req->_present.sb_index = 1; + req->sb_index = sb_index; +} + +/* + * Take occupancy snapshot of shared buffer. + */ +int devlink_sb_occ_snapshot(struct ynl_sock *ys, + struct devlink_sb_occ_snapshot_req *req); + +/* ============== DEVLINK_CMD_SB_OCC_MAX_CLEAR ============== */ +/* DEVLINK_CMD_SB_OCC_MAX_CLEAR - do */ +struct devlink_sb_occ_max_clear_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 sb_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 sb_index; +}; + +static inline struct devlink_sb_occ_max_clear_req * +devlink_sb_occ_max_clear_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_sb_occ_max_clear_req)); +} +void +devlink_sb_occ_max_clear_req_free(struct devlink_sb_occ_max_clear_req *req); + +static inline void +devlink_sb_occ_max_clear_req_set_bus_name(struct devlink_sb_occ_max_clear_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_sb_occ_max_clear_req_set_dev_name(struct devlink_sb_occ_max_clear_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_sb_occ_max_clear_req_set_sb_index(struct devlink_sb_occ_max_clear_req *req, + __u32 sb_index) +{ + req->_present.sb_index = 1; + req->sb_index = sb_index; +} + +/* + * Clear occupancy watermarks of shared buffer. + */ +int devlink_sb_occ_max_clear(struct ynl_sock *ys, + struct devlink_sb_occ_max_clear_req *req); + +/* ============== DEVLINK_CMD_ESWITCH_GET ============== */ +/* DEVLINK_CMD_ESWITCH_GET - do */ +struct devlink_eswitch_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_eswitch_get_req * +devlink_eswitch_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_eswitch_get_req)); +} +void devlink_eswitch_get_req_free(struct devlink_eswitch_get_req *req); + +static inline void +devlink_eswitch_get_req_set_bus_name(struct devlink_eswitch_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_eswitch_get_req_set_dev_name(struct devlink_eswitch_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_eswitch_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 eswitch_mode:1; + __u32 eswitch_inline_mode:1; + __u32 eswitch_encap_mode:1; + } _present; + + char *bus_name; + char *dev_name; + enum devlink_eswitch_mode eswitch_mode; + enum devlink_eswitch_inline_mode eswitch_inline_mode; + enum devlink_eswitch_encap_mode eswitch_encap_mode; +}; + +void devlink_eswitch_get_rsp_free(struct devlink_eswitch_get_rsp *rsp); + +/* + * Get eswitch attributes. + */ +struct devlink_eswitch_get_rsp * +devlink_eswitch_get(struct ynl_sock *ys, struct devlink_eswitch_get_req *req); + +/* ============== DEVLINK_CMD_ESWITCH_SET ============== */ +/* DEVLINK_CMD_ESWITCH_SET - do */ +struct devlink_eswitch_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 eswitch_mode:1; + __u32 eswitch_inline_mode:1; + __u32 eswitch_encap_mode:1; + } _present; + + char *bus_name; + char *dev_name; + enum devlink_eswitch_mode eswitch_mode; + enum devlink_eswitch_inline_mode eswitch_inline_mode; + enum devlink_eswitch_encap_mode eswitch_encap_mode; +}; + +static inline struct devlink_eswitch_set_req * +devlink_eswitch_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_eswitch_set_req)); +} +void devlink_eswitch_set_req_free(struct devlink_eswitch_set_req *req); + +static inline void +devlink_eswitch_set_req_set_bus_name(struct devlink_eswitch_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_eswitch_set_req_set_dev_name(struct devlink_eswitch_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_eswitch_set_req_set_eswitch_mode(struct devlink_eswitch_set_req *req, + enum devlink_eswitch_mode eswitch_mode) +{ + req->_present.eswitch_mode = 1; + req->eswitch_mode = eswitch_mode; +} +static inline void +devlink_eswitch_set_req_set_eswitch_inline_mode(struct devlink_eswitch_set_req *req, + enum devlink_eswitch_inline_mode eswitch_inline_mode) +{ + req->_present.eswitch_inline_mode = 1; + req->eswitch_inline_mode = eswitch_inline_mode; +} +static inline void +devlink_eswitch_set_req_set_eswitch_encap_mode(struct devlink_eswitch_set_req *req, + enum devlink_eswitch_encap_mode eswitch_encap_mode) +{ + req->_present.eswitch_encap_mode = 1; + req->eswitch_encap_mode = eswitch_encap_mode; +} + +/* + * Set eswitch attributes. + */ +int devlink_eswitch_set(struct ynl_sock *ys, + struct devlink_eswitch_set_req *req); + +/* ============== DEVLINK_CMD_DPIPE_TABLE_GET ============== */ +/* DEVLINK_CMD_DPIPE_TABLE_GET - do */ +struct devlink_dpipe_table_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 dpipe_table_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *dpipe_table_name; +}; + +static inline struct devlink_dpipe_table_get_req * +devlink_dpipe_table_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_dpipe_table_get_req)); +} +void devlink_dpipe_table_get_req_free(struct devlink_dpipe_table_get_req *req); + +static inline void +devlink_dpipe_table_get_req_set_bus_name(struct devlink_dpipe_table_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_dpipe_table_get_req_set_dev_name(struct devlink_dpipe_table_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_dpipe_table_get_req_set_dpipe_table_name(struct devlink_dpipe_table_get_req *req, + const char *dpipe_table_name) +{ + free(req->dpipe_table_name); + req->_present.dpipe_table_name_len = strlen(dpipe_table_name); + req->dpipe_table_name = malloc(req->_present.dpipe_table_name_len + 1); + memcpy(req->dpipe_table_name, dpipe_table_name, req->_present.dpipe_table_name_len); + req->dpipe_table_name[req->_present.dpipe_table_name_len] = 0; +} + +struct devlink_dpipe_table_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 dpipe_tables:1; + } _present; + + char *bus_name; + char *dev_name; + struct devlink_dl_dpipe_tables dpipe_tables; +}; + +void devlink_dpipe_table_get_rsp_free(struct devlink_dpipe_table_get_rsp *rsp); + +/* + * Get dpipe table attributes. + */ +struct devlink_dpipe_table_get_rsp * +devlink_dpipe_table_get(struct ynl_sock *ys, + struct devlink_dpipe_table_get_req *req); + +/* ============== DEVLINK_CMD_DPIPE_ENTRIES_GET ============== */ +/* DEVLINK_CMD_DPIPE_ENTRIES_GET - do */ +struct devlink_dpipe_entries_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 dpipe_table_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *dpipe_table_name; +}; + +static inline struct devlink_dpipe_entries_get_req * +devlink_dpipe_entries_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_dpipe_entries_get_req)); +} +void +devlink_dpipe_entries_get_req_free(struct devlink_dpipe_entries_get_req *req); + +static inline void +devlink_dpipe_entries_get_req_set_bus_name(struct devlink_dpipe_entries_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_dpipe_entries_get_req_set_dev_name(struct devlink_dpipe_entries_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_dpipe_entries_get_req_set_dpipe_table_name(struct devlink_dpipe_entries_get_req *req, + const char *dpipe_table_name) +{ + free(req->dpipe_table_name); + req->_present.dpipe_table_name_len = strlen(dpipe_table_name); + req->dpipe_table_name = malloc(req->_present.dpipe_table_name_len + 1); + memcpy(req->dpipe_table_name, dpipe_table_name, req->_present.dpipe_table_name_len); + req->dpipe_table_name[req->_present.dpipe_table_name_len] = 0; +} + +struct devlink_dpipe_entries_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 dpipe_entries:1; + } _present; + + char *bus_name; + char *dev_name; + struct devlink_dl_dpipe_entries dpipe_entries; +}; + +void +devlink_dpipe_entries_get_rsp_free(struct devlink_dpipe_entries_get_rsp *rsp); + +/* + * Get dpipe entries attributes. + */ +struct devlink_dpipe_entries_get_rsp * +devlink_dpipe_entries_get(struct ynl_sock *ys, + struct devlink_dpipe_entries_get_req *req); + +/* ============== DEVLINK_CMD_DPIPE_HEADERS_GET ============== */ +/* DEVLINK_CMD_DPIPE_HEADERS_GET - do */ +struct devlink_dpipe_headers_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_dpipe_headers_get_req * +devlink_dpipe_headers_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_dpipe_headers_get_req)); +} +void +devlink_dpipe_headers_get_req_free(struct devlink_dpipe_headers_get_req *req); + +static inline void +devlink_dpipe_headers_get_req_set_bus_name(struct devlink_dpipe_headers_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_dpipe_headers_get_req_set_dev_name(struct devlink_dpipe_headers_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_dpipe_headers_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 dpipe_headers:1; + } _present; + + char *bus_name; + char *dev_name; + struct devlink_dl_dpipe_headers dpipe_headers; +}; + +void +devlink_dpipe_headers_get_rsp_free(struct devlink_dpipe_headers_get_rsp *rsp); + +/* + * Get dpipe headers attributes. + */ +struct devlink_dpipe_headers_get_rsp * +devlink_dpipe_headers_get(struct ynl_sock *ys, + struct devlink_dpipe_headers_get_req *req); + +/* ============== DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET ============== */ +/* DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET - do */ +struct devlink_dpipe_table_counters_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 dpipe_table_name_len; + __u32 dpipe_table_counters_enabled:1; + } _present; + + char *bus_name; + char *dev_name; + char *dpipe_table_name; + __u8 dpipe_table_counters_enabled; +}; + +static inline struct devlink_dpipe_table_counters_set_req * +devlink_dpipe_table_counters_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_dpipe_table_counters_set_req)); +} +void +devlink_dpipe_table_counters_set_req_free(struct devlink_dpipe_table_counters_set_req *req); + +static inline void +devlink_dpipe_table_counters_set_req_set_bus_name(struct devlink_dpipe_table_counters_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_dpipe_table_counters_set_req_set_dev_name(struct devlink_dpipe_table_counters_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_dpipe_table_counters_set_req_set_dpipe_table_name(struct devlink_dpipe_table_counters_set_req *req, + const char *dpipe_table_name) +{ + free(req->dpipe_table_name); + req->_present.dpipe_table_name_len = strlen(dpipe_table_name); + req->dpipe_table_name = malloc(req->_present.dpipe_table_name_len + 1); + memcpy(req->dpipe_table_name, dpipe_table_name, req->_present.dpipe_table_name_len); + req->dpipe_table_name[req->_present.dpipe_table_name_len] = 0; +} +static inline void +devlink_dpipe_table_counters_set_req_set_dpipe_table_counters_enabled(struct devlink_dpipe_table_counters_set_req *req, + __u8 dpipe_table_counters_enabled) +{ + req->_present.dpipe_table_counters_enabled = 1; + req->dpipe_table_counters_enabled = dpipe_table_counters_enabled; +} + +/* + * Set dpipe counter attributes. + */ +int devlink_dpipe_table_counters_set(struct ynl_sock *ys, + struct devlink_dpipe_table_counters_set_req *req); + +/* ============== DEVLINK_CMD_RESOURCE_SET ============== */ +/* DEVLINK_CMD_RESOURCE_SET - do */ +struct devlink_resource_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 resource_id:1; + __u32 resource_size:1; + } _present; + + char *bus_name; + char *dev_name; + __u64 resource_id; + __u64 resource_size; +}; + +static inline struct devlink_resource_set_req * +devlink_resource_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_resource_set_req)); +} +void devlink_resource_set_req_free(struct devlink_resource_set_req *req); + +static inline void +devlink_resource_set_req_set_bus_name(struct devlink_resource_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_resource_set_req_set_dev_name(struct devlink_resource_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_resource_set_req_set_resource_id(struct devlink_resource_set_req *req, + __u64 resource_id) +{ + req->_present.resource_id = 1; + req->resource_id = resource_id; +} +static inline void +devlink_resource_set_req_set_resource_size(struct devlink_resource_set_req *req, + __u64 resource_size) +{ + req->_present.resource_size = 1; + req->resource_size = resource_size; +} + +/* + * Set resource attributes. + */ +int devlink_resource_set(struct ynl_sock *ys, + struct devlink_resource_set_req *req); + +/* ============== DEVLINK_CMD_RESOURCE_DUMP ============== */ +/* DEVLINK_CMD_RESOURCE_DUMP - do */ +struct devlink_resource_dump_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_resource_dump_req * +devlink_resource_dump_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_resource_dump_req)); +} +void devlink_resource_dump_req_free(struct devlink_resource_dump_req *req); + +static inline void +devlink_resource_dump_req_set_bus_name(struct devlink_resource_dump_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_resource_dump_req_set_dev_name(struct devlink_resource_dump_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_resource_dump_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 resource_list:1; + } _present; + + char *bus_name; + char *dev_name; + struct devlink_dl_resource_list resource_list; +}; + +void devlink_resource_dump_rsp_free(struct devlink_resource_dump_rsp *rsp); + +/* + * Get resource attributes. + */ +struct devlink_resource_dump_rsp * +devlink_resource_dump(struct ynl_sock *ys, + struct devlink_resource_dump_req *req); + +/* ============== DEVLINK_CMD_RELOAD ============== */ +/* DEVLINK_CMD_RELOAD - do */ +struct devlink_reload_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 reload_action:1; + __u32 reload_limits:1; + __u32 netns_pid:1; + __u32 netns_fd:1; + __u32 netns_id:1; + } _present; + + char *bus_name; + char *dev_name; + enum devlink_reload_action reload_action; + struct nla_bitfield32 reload_limits; + __u32 netns_pid; + __u32 netns_fd; + __u32 netns_id; +}; + +static inline struct devlink_reload_req *devlink_reload_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_reload_req)); +} +void devlink_reload_req_free(struct devlink_reload_req *req); + +static inline void +devlink_reload_req_set_bus_name(struct devlink_reload_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_reload_req_set_dev_name(struct devlink_reload_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_reload_req_set_reload_action(struct devlink_reload_req *req, + enum devlink_reload_action reload_action) +{ + req->_present.reload_action = 1; + req->reload_action = reload_action; +} +static inline void +devlink_reload_req_set_reload_limits(struct devlink_reload_req *req, + struct nla_bitfield32 *reload_limits) +{ + req->_present.reload_limits = 1; + memcpy(&req->reload_limits, reload_limits, sizeof(struct nla_bitfield32)); +} +static inline void +devlink_reload_req_set_netns_pid(struct devlink_reload_req *req, + __u32 netns_pid) +{ + req->_present.netns_pid = 1; + req->netns_pid = netns_pid; +} +static inline void +devlink_reload_req_set_netns_fd(struct devlink_reload_req *req, __u32 netns_fd) +{ + req->_present.netns_fd = 1; + req->netns_fd = netns_fd; +} +static inline void +devlink_reload_req_set_netns_id(struct devlink_reload_req *req, __u32 netns_id) +{ + req->_present.netns_id = 1; + req->netns_id = netns_id; +} + +struct devlink_reload_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 reload_actions_performed:1; + } _present; + + char *bus_name; + char *dev_name; + struct nla_bitfield32 reload_actions_performed; +}; + +void devlink_reload_rsp_free(struct devlink_reload_rsp *rsp); + +/* + * Reload devlink. + */ +struct devlink_reload_rsp * +devlink_reload(struct ynl_sock *ys, struct devlink_reload_req *req); + +/* ============== DEVLINK_CMD_PARAM_GET ============== */ +/* DEVLINK_CMD_PARAM_GET - do */ +struct devlink_param_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 param_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *param_name; +}; + +static inline struct devlink_param_get_req *devlink_param_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_param_get_req)); +} +void devlink_param_get_req_free(struct devlink_param_get_req *req); + +static inline void +devlink_param_get_req_set_bus_name(struct devlink_param_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_param_get_req_set_dev_name(struct devlink_param_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_param_get_req_set_param_name(struct devlink_param_get_req *req, + const char *param_name) +{ + free(req->param_name); + req->_present.param_name_len = strlen(param_name); + req->param_name = malloc(req->_present.param_name_len + 1); + memcpy(req->param_name, param_name, req->_present.param_name_len); + req->param_name[req->_present.param_name_len] = 0; +} + +struct devlink_param_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 param_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *param_name; +}; + +void devlink_param_get_rsp_free(struct devlink_param_get_rsp *rsp); + +/* + * Get param instances. + */ +struct devlink_param_get_rsp * +devlink_param_get(struct ynl_sock *ys, struct devlink_param_get_req *req); + +/* DEVLINK_CMD_PARAM_GET - dump */ +struct devlink_param_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_param_get_req_dump * +devlink_param_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_param_get_req_dump)); +} +void devlink_param_get_req_dump_free(struct devlink_param_get_req_dump *req); + +static inline void +devlink_param_get_req_dump_set_bus_name(struct devlink_param_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_param_get_req_dump_set_dev_name(struct devlink_param_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_param_get_list { + struct devlink_param_get_list *next; + struct devlink_param_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_param_get_list_free(struct devlink_param_get_list *rsp); + +struct devlink_param_get_list * +devlink_param_get_dump(struct ynl_sock *ys, + struct devlink_param_get_req_dump *req); + +/* ============== DEVLINK_CMD_PARAM_SET ============== */ +/* DEVLINK_CMD_PARAM_SET - do */ +struct devlink_param_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 param_name_len; + __u32 param_type:1; + __u32 param_value_cmode:1; + } _present; + + char *bus_name; + char *dev_name; + char *param_name; + __u8 param_type; + enum devlink_param_cmode param_value_cmode; +}; + +static inline struct devlink_param_set_req *devlink_param_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_param_set_req)); +} +void devlink_param_set_req_free(struct devlink_param_set_req *req); + +static inline void +devlink_param_set_req_set_bus_name(struct devlink_param_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_param_set_req_set_dev_name(struct devlink_param_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_param_set_req_set_param_name(struct devlink_param_set_req *req, + const char *param_name) +{ + free(req->param_name); + req->_present.param_name_len = strlen(param_name); + req->param_name = malloc(req->_present.param_name_len + 1); + memcpy(req->param_name, param_name, req->_present.param_name_len); + req->param_name[req->_present.param_name_len] = 0; +} +static inline void +devlink_param_set_req_set_param_type(struct devlink_param_set_req *req, + __u8 param_type) +{ + req->_present.param_type = 1; + req->param_type = param_type; +} +static inline void +devlink_param_set_req_set_param_value_cmode(struct devlink_param_set_req *req, + enum devlink_param_cmode param_value_cmode) +{ + req->_present.param_value_cmode = 1; + req->param_value_cmode = param_value_cmode; +} + +/* + * Set param instances. + */ +int devlink_param_set(struct ynl_sock *ys, struct devlink_param_set_req *req); + +/* ============== DEVLINK_CMD_REGION_GET ============== */ +/* DEVLINK_CMD_REGION_GET - do */ +struct devlink_region_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 region_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *region_name; +}; + +static inline struct devlink_region_get_req *devlink_region_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_region_get_req)); +} +void devlink_region_get_req_free(struct devlink_region_get_req *req); + +static inline void +devlink_region_get_req_set_bus_name(struct devlink_region_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_region_get_req_set_dev_name(struct devlink_region_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_region_get_req_set_port_index(struct devlink_region_get_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_region_get_req_set_region_name(struct devlink_region_get_req *req, + const char *region_name) +{ + free(req->region_name); + req->_present.region_name_len = strlen(region_name); + req->region_name = malloc(req->_present.region_name_len + 1); + memcpy(req->region_name, region_name, req->_present.region_name_len); + req->region_name[req->_present.region_name_len] = 0; +} + +struct devlink_region_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 region_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *region_name; +}; + +void devlink_region_get_rsp_free(struct devlink_region_get_rsp *rsp); + +/* + * Get region instances. + */ +struct devlink_region_get_rsp * +devlink_region_get(struct ynl_sock *ys, struct devlink_region_get_req *req); + +/* DEVLINK_CMD_REGION_GET - dump */ +struct devlink_region_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_region_get_req_dump * +devlink_region_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_region_get_req_dump)); +} +void devlink_region_get_req_dump_free(struct devlink_region_get_req_dump *req); + +static inline void +devlink_region_get_req_dump_set_bus_name(struct devlink_region_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_region_get_req_dump_set_dev_name(struct devlink_region_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_region_get_list { + struct devlink_region_get_list *next; + struct devlink_region_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_region_get_list_free(struct devlink_region_get_list *rsp); + +struct devlink_region_get_list * +devlink_region_get_dump(struct ynl_sock *ys, + struct devlink_region_get_req_dump *req); + +/* ============== DEVLINK_CMD_REGION_NEW ============== */ +/* DEVLINK_CMD_REGION_NEW - do */ +struct devlink_region_new_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 region_name_len; + __u32 region_snapshot_id:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *region_name; + __u32 region_snapshot_id; +}; + +static inline struct devlink_region_new_req *devlink_region_new_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_region_new_req)); +} +void devlink_region_new_req_free(struct devlink_region_new_req *req); + +static inline void +devlink_region_new_req_set_bus_name(struct devlink_region_new_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_region_new_req_set_dev_name(struct devlink_region_new_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_region_new_req_set_port_index(struct devlink_region_new_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_region_new_req_set_region_name(struct devlink_region_new_req *req, + const char *region_name) +{ + free(req->region_name); + req->_present.region_name_len = strlen(region_name); + req->region_name = malloc(req->_present.region_name_len + 1); + memcpy(req->region_name, region_name, req->_present.region_name_len); + req->region_name[req->_present.region_name_len] = 0; +} +static inline void +devlink_region_new_req_set_region_snapshot_id(struct devlink_region_new_req *req, + __u32 region_snapshot_id) +{ + req->_present.region_snapshot_id = 1; + req->region_snapshot_id = region_snapshot_id; +} + +struct devlink_region_new_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 region_name_len; + __u32 region_snapshot_id:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *region_name; + __u32 region_snapshot_id; +}; + +void devlink_region_new_rsp_free(struct devlink_region_new_rsp *rsp); + +/* + * Create region snapshot. + */ +struct devlink_region_new_rsp * +devlink_region_new(struct ynl_sock *ys, struct devlink_region_new_req *req); + +/* ============== DEVLINK_CMD_REGION_DEL ============== */ +/* DEVLINK_CMD_REGION_DEL - do */ +struct devlink_region_del_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 region_name_len; + __u32 region_snapshot_id:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *region_name; + __u32 region_snapshot_id; +}; + +static inline struct devlink_region_del_req *devlink_region_del_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_region_del_req)); +} +void devlink_region_del_req_free(struct devlink_region_del_req *req); + +static inline void +devlink_region_del_req_set_bus_name(struct devlink_region_del_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_region_del_req_set_dev_name(struct devlink_region_del_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_region_del_req_set_port_index(struct devlink_region_del_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_region_del_req_set_region_name(struct devlink_region_del_req *req, + const char *region_name) +{ + free(req->region_name); + req->_present.region_name_len = strlen(region_name); + req->region_name = malloc(req->_present.region_name_len + 1); + memcpy(req->region_name, region_name, req->_present.region_name_len); + req->region_name[req->_present.region_name_len] = 0; +} +static inline void +devlink_region_del_req_set_region_snapshot_id(struct devlink_region_del_req *req, + __u32 region_snapshot_id) +{ + req->_present.region_snapshot_id = 1; + req->region_snapshot_id = region_snapshot_id; +} + +/* + * Delete region snapshot. + */ +int devlink_region_del(struct ynl_sock *ys, struct devlink_region_del_req *req); + +/* ============== DEVLINK_CMD_REGION_READ ============== */ +/* DEVLINK_CMD_REGION_READ - dump */ +struct devlink_region_read_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 region_name_len; + __u32 region_snapshot_id:1; + __u32 region_direct:1; + __u32 region_chunk_addr:1; + __u32 region_chunk_len:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *region_name; + __u32 region_snapshot_id; + __u64 region_chunk_addr; + __u64 region_chunk_len; +}; + +static inline struct devlink_region_read_req_dump * +devlink_region_read_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_region_read_req_dump)); +} +void +devlink_region_read_req_dump_free(struct devlink_region_read_req_dump *req); + +static inline void +devlink_region_read_req_dump_set_bus_name(struct devlink_region_read_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_region_read_req_dump_set_dev_name(struct devlink_region_read_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_region_read_req_dump_set_port_index(struct devlink_region_read_req_dump *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_region_read_req_dump_set_region_name(struct devlink_region_read_req_dump *req, + const char *region_name) +{ + free(req->region_name); + req->_present.region_name_len = strlen(region_name); + req->region_name = malloc(req->_present.region_name_len + 1); + memcpy(req->region_name, region_name, req->_present.region_name_len); + req->region_name[req->_present.region_name_len] = 0; +} +static inline void +devlink_region_read_req_dump_set_region_snapshot_id(struct devlink_region_read_req_dump *req, + __u32 region_snapshot_id) +{ + req->_present.region_snapshot_id = 1; + req->region_snapshot_id = region_snapshot_id; +} +static inline void +devlink_region_read_req_dump_set_region_direct(struct devlink_region_read_req_dump *req) +{ + req->_present.region_direct = 1; +} +static inline void +devlink_region_read_req_dump_set_region_chunk_addr(struct devlink_region_read_req_dump *req, + __u64 region_chunk_addr) +{ + req->_present.region_chunk_addr = 1; + req->region_chunk_addr = region_chunk_addr; +} +static inline void +devlink_region_read_req_dump_set_region_chunk_len(struct devlink_region_read_req_dump *req, + __u64 region_chunk_len) +{ + req->_present.region_chunk_len = 1; + req->region_chunk_len = region_chunk_len; +} + +struct devlink_region_read_rsp_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 region_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *region_name; +}; + +struct devlink_region_read_rsp_list { + struct devlink_region_read_rsp_list *next; + struct devlink_region_read_rsp_dump obj __attribute__((aligned(8))); +}; + +void +devlink_region_read_rsp_list_free(struct devlink_region_read_rsp_list *rsp); + +struct devlink_region_read_rsp_list * +devlink_region_read_dump(struct ynl_sock *ys, + struct devlink_region_read_req_dump *req); + +/* ============== DEVLINK_CMD_PORT_PARAM_GET ============== */ +/* DEVLINK_CMD_PORT_PARAM_GET - do */ +struct devlink_port_param_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +static inline struct devlink_port_param_get_req * +devlink_port_param_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_port_param_get_req)); +} +void devlink_port_param_get_req_free(struct devlink_port_param_get_req *req); + +static inline void +devlink_port_param_get_req_set_bus_name(struct devlink_port_param_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_port_param_get_req_set_dev_name(struct devlink_port_param_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_port_param_get_req_set_port_index(struct devlink_port_param_get_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} + +struct devlink_port_param_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +void devlink_port_param_get_rsp_free(struct devlink_port_param_get_rsp *rsp); + +/* + * Get port param instances. + */ +struct devlink_port_param_get_rsp * +devlink_port_param_get(struct ynl_sock *ys, + struct devlink_port_param_get_req *req); + +/* DEVLINK_CMD_PORT_PARAM_GET - dump */ +struct devlink_port_param_get_list { + struct devlink_port_param_get_list *next; + struct devlink_port_param_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_port_param_get_list_free(struct devlink_port_param_get_list *rsp); + +struct devlink_port_param_get_list * +devlink_port_param_get_dump(struct ynl_sock *ys); + +/* ============== DEVLINK_CMD_PORT_PARAM_SET ============== */ +/* DEVLINK_CMD_PORT_PARAM_SET - do */ +struct devlink_port_param_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +static inline struct devlink_port_param_set_req * +devlink_port_param_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_port_param_set_req)); +} +void devlink_port_param_set_req_free(struct devlink_port_param_set_req *req); + +static inline void +devlink_port_param_set_req_set_bus_name(struct devlink_port_param_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_port_param_set_req_set_dev_name(struct devlink_port_param_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_port_param_set_req_set_port_index(struct devlink_port_param_set_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} + +/* + * Set port param instances. + */ +int devlink_port_param_set(struct ynl_sock *ys, + struct devlink_port_param_set_req *req); + +/* ============== DEVLINK_CMD_INFO_GET ============== */ +/* DEVLINK_CMD_INFO_GET - do */ +struct devlink_info_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_info_get_req *devlink_info_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_info_get_req)); +} +void devlink_info_get_req_free(struct devlink_info_get_req *req); + +static inline void +devlink_info_get_req_set_bus_name(struct devlink_info_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_info_get_req_set_dev_name(struct devlink_info_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_info_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 info_driver_name_len; + __u32 info_serial_number_len; + } _present; + + char *bus_name; + char *dev_name; + char *info_driver_name; + char *info_serial_number; + unsigned int n_info_version_fixed; + struct devlink_dl_info_version *info_version_fixed; + unsigned int n_info_version_running; + struct devlink_dl_info_version *info_version_running; + unsigned int n_info_version_stored; + struct devlink_dl_info_version *info_version_stored; +}; + +void devlink_info_get_rsp_free(struct devlink_info_get_rsp *rsp); + +/* + * Get device information, like driver name, hardware and firmware versions etc. + */ +struct devlink_info_get_rsp * +devlink_info_get(struct ynl_sock *ys, struct devlink_info_get_req *req); + +/* DEVLINK_CMD_INFO_GET - dump */ +struct devlink_info_get_list { + struct devlink_info_get_list *next; + struct devlink_info_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_info_get_list_free(struct devlink_info_get_list *rsp); + +struct devlink_info_get_list *devlink_info_get_dump(struct ynl_sock *ys); + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_GET ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_GET - do */ +struct devlink_health_reporter_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 health_reporter_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *health_reporter_name; +}; + +static inline struct devlink_health_reporter_get_req * +devlink_health_reporter_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_health_reporter_get_req)); +} +void +devlink_health_reporter_get_req_free(struct devlink_health_reporter_get_req *req); + +static inline void +devlink_health_reporter_get_req_set_bus_name(struct devlink_health_reporter_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_health_reporter_get_req_set_dev_name(struct devlink_health_reporter_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_health_reporter_get_req_set_port_index(struct devlink_health_reporter_get_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_health_reporter_get_req_set_health_reporter_name(struct devlink_health_reporter_get_req *req, + const char *health_reporter_name) +{ + free(req->health_reporter_name); + req->_present.health_reporter_name_len = strlen(health_reporter_name); + req->health_reporter_name = malloc(req->_present.health_reporter_name_len + 1); + memcpy(req->health_reporter_name, health_reporter_name, req->_present.health_reporter_name_len); + req->health_reporter_name[req->_present.health_reporter_name_len] = 0; +} + +struct devlink_health_reporter_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 health_reporter_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *health_reporter_name; +}; + +void +devlink_health_reporter_get_rsp_free(struct devlink_health_reporter_get_rsp *rsp); + +/* + * Get health reporter instances. + */ +struct devlink_health_reporter_get_rsp * +devlink_health_reporter_get(struct ynl_sock *ys, + struct devlink_health_reporter_get_req *req); + +/* DEVLINK_CMD_HEALTH_REPORTER_GET - dump */ +struct devlink_health_reporter_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +static inline struct devlink_health_reporter_get_req_dump * +devlink_health_reporter_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_health_reporter_get_req_dump)); +} +void +devlink_health_reporter_get_req_dump_free(struct devlink_health_reporter_get_req_dump *req); + +static inline void +devlink_health_reporter_get_req_dump_set_bus_name(struct devlink_health_reporter_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_health_reporter_get_req_dump_set_dev_name(struct devlink_health_reporter_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_health_reporter_get_req_dump_set_port_index(struct devlink_health_reporter_get_req_dump *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} + +struct devlink_health_reporter_get_list { + struct devlink_health_reporter_get_list *next; + struct devlink_health_reporter_get_rsp obj __attribute__((aligned(8))); +}; + +void +devlink_health_reporter_get_list_free(struct devlink_health_reporter_get_list *rsp); + +struct devlink_health_reporter_get_list * +devlink_health_reporter_get_dump(struct ynl_sock *ys, + struct devlink_health_reporter_get_req_dump *req); + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_SET ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_SET - do */ +struct devlink_health_reporter_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 health_reporter_name_len; + __u32 health_reporter_graceful_period:1; + __u32 health_reporter_auto_recover:1; + __u32 health_reporter_auto_dump:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *health_reporter_name; + __u64 health_reporter_graceful_period; + __u8 health_reporter_auto_recover; + __u8 health_reporter_auto_dump; +}; + +static inline struct devlink_health_reporter_set_req * +devlink_health_reporter_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_health_reporter_set_req)); +} +void +devlink_health_reporter_set_req_free(struct devlink_health_reporter_set_req *req); + +static inline void +devlink_health_reporter_set_req_set_bus_name(struct devlink_health_reporter_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_health_reporter_set_req_set_dev_name(struct devlink_health_reporter_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_health_reporter_set_req_set_port_index(struct devlink_health_reporter_set_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_health_reporter_set_req_set_health_reporter_name(struct devlink_health_reporter_set_req *req, + const char *health_reporter_name) +{ + free(req->health_reporter_name); + req->_present.health_reporter_name_len = strlen(health_reporter_name); + req->health_reporter_name = malloc(req->_present.health_reporter_name_len + 1); + memcpy(req->health_reporter_name, health_reporter_name, req->_present.health_reporter_name_len); + req->health_reporter_name[req->_present.health_reporter_name_len] = 0; +} +static inline void +devlink_health_reporter_set_req_set_health_reporter_graceful_period(struct devlink_health_reporter_set_req *req, + __u64 health_reporter_graceful_period) +{ + req->_present.health_reporter_graceful_period = 1; + req->health_reporter_graceful_period = health_reporter_graceful_period; +} +static inline void +devlink_health_reporter_set_req_set_health_reporter_auto_recover(struct devlink_health_reporter_set_req *req, + __u8 health_reporter_auto_recover) +{ + req->_present.health_reporter_auto_recover = 1; + req->health_reporter_auto_recover = health_reporter_auto_recover; +} +static inline void +devlink_health_reporter_set_req_set_health_reporter_auto_dump(struct devlink_health_reporter_set_req *req, + __u8 health_reporter_auto_dump) +{ + req->_present.health_reporter_auto_dump = 1; + req->health_reporter_auto_dump = health_reporter_auto_dump; +} + +/* + * Set health reporter instances. + */ +int devlink_health_reporter_set(struct ynl_sock *ys, + struct devlink_health_reporter_set_req *req); + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_RECOVER ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_RECOVER - do */ +struct devlink_health_reporter_recover_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 health_reporter_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *health_reporter_name; +}; + +static inline struct devlink_health_reporter_recover_req * +devlink_health_reporter_recover_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_health_reporter_recover_req)); +} +void +devlink_health_reporter_recover_req_free(struct devlink_health_reporter_recover_req *req); + +static inline void +devlink_health_reporter_recover_req_set_bus_name(struct devlink_health_reporter_recover_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_health_reporter_recover_req_set_dev_name(struct devlink_health_reporter_recover_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_health_reporter_recover_req_set_port_index(struct devlink_health_reporter_recover_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_health_reporter_recover_req_set_health_reporter_name(struct devlink_health_reporter_recover_req *req, + const char *health_reporter_name) +{ + free(req->health_reporter_name); + req->_present.health_reporter_name_len = strlen(health_reporter_name); + req->health_reporter_name = malloc(req->_present.health_reporter_name_len + 1); + memcpy(req->health_reporter_name, health_reporter_name, req->_present.health_reporter_name_len); + req->health_reporter_name[req->_present.health_reporter_name_len] = 0; +} + +/* + * Recover health reporter instances. + */ +int devlink_health_reporter_recover(struct ynl_sock *ys, + struct devlink_health_reporter_recover_req *req); + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE - do */ +struct devlink_health_reporter_diagnose_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 health_reporter_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *health_reporter_name; +}; + +static inline struct devlink_health_reporter_diagnose_req * +devlink_health_reporter_diagnose_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_health_reporter_diagnose_req)); +} +void +devlink_health_reporter_diagnose_req_free(struct devlink_health_reporter_diagnose_req *req); + +static inline void +devlink_health_reporter_diagnose_req_set_bus_name(struct devlink_health_reporter_diagnose_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_health_reporter_diagnose_req_set_dev_name(struct devlink_health_reporter_diagnose_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_health_reporter_diagnose_req_set_port_index(struct devlink_health_reporter_diagnose_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_health_reporter_diagnose_req_set_health_reporter_name(struct devlink_health_reporter_diagnose_req *req, + const char *health_reporter_name) +{ + free(req->health_reporter_name); + req->_present.health_reporter_name_len = strlen(health_reporter_name); + req->health_reporter_name = malloc(req->_present.health_reporter_name_len + 1); + memcpy(req->health_reporter_name, health_reporter_name, req->_present.health_reporter_name_len); + req->health_reporter_name[req->_present.health_reporter_name_len] = 0; +} + +/* + * Diagnose health reporter instances. + */ +int devlink_health_reporter_diagnose(struct ynl_sock *ys, + struct devlink_health_reporter_diagnose_req *req); + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET - dump */ +struct devlink_health_reporter_dump_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 health_reporter_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *health_reporter_name; +}; + +static inline struct devlink_health_reporter_dump_get_req_dump * +devlink_health_reporter_dump_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_health_reporter_dump_get_req_dump)); +} +void +devlink_health_reporter_dump_get_req_dump_free(struct devlink_health_reporter_dump_get_req_dump *req); + +static inline void +devlink_health_reporter_dump_get_req_dump_set_bus_name(struct devlink_health_reporter_dump_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_health_reporter_dump_get_req_dump_set_dev_name(struct devlink_health_reporter_dump_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_health_reporter_dump_get_req_dump_set_port_index(struct devlink_health_reporter_dump_get_req_dump *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_health_reporter_dump_get_req_dump_set_health_reporter_name(struct devlink_health_reporter_dump_get_req_dump *req, + const char *health_reporter_name) +{ + free(req->health_reporter_name); + req->_present.health_reporter_name_len = strlen(health_reporter_name); + req->health_reporter_name = malloc(req->_present.health_reporter_name_len + 1); + memcpy(req->health_reporter_name, health_reporter_name, req->_present.health_reporter_name_len); + req->health_reporter_name[req->_present.health_reporter_name_len] = 0; +} + +struct devlink_health_reporter_dump_get_rsp_dump { + struct { + __u32 fmsg:1; + } _present; + + struct devlink_dl_fmsg fmsg; +}; + +struct devlink_health_reporter_dump_get_rsp_list { + struct devlink_health_reporter_dump_get_rsp_list *next; + struct devlink_health_reporter_dump_get_rsp_dump obj __attribute__((aligned(8))); +}; + +void +devlink_health_reporter_dump_get_rsp_list_free(struct devlink_health_reporter_dump_get_rsp_list *rsp); + +struct devlink_health_reporter_dump_get_rsp_list * +devlink_health_reporter_dump_get_dump(struct ynl_sock *ys, + struct devlink_health_reporter_dump_get_req_dump *req); + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR - do */ +struct devlink_health_reporter_dump_clear_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 health_reporter_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *health_reporter_name; +}; + +static inline struct devlink_health_reporter_dump_clear_req * +devlink_health_reporter_dump_clear_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_health_reporter_dump_clear_req)); +} +void +devlink_health_reporter_dump_clear_req_free(struct devlink_health_reporter_dump_clear_req *req); + +static inline void +devlink_health_reporter_dump_clear_req_set_bus_name(struct devlink_health_reporter_dump_clear_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_health_reporter_dump_clear_req_set_dev_name(struct devlink_health_reporter_dump_clear_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_health_reporter_dump_clear_req_set_port_index(struct devlink_health_reporter_dump_clear_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_health_reporter_dump_clear_req_set_health_reporter_name(struct devlink_health_reporter_dump_clear_req *req, + const char *health_reporter_name) +{ + free(req->health_reporter_name); + req->_present.health_reporter_name_len = strlen(health_reporter_name); + req->health_reporter_name = malloc(req->_present.health_reporter_name_len + 1); + memcpy(req->health_reporter_name, health_reporter_name, req->_present.health_reporter_name_len); + req->health_reporter_name[req->_present.health_reporter_name_len] = 0; +} + +/* + * Clear dump of health reporter instances. + */ +int devlink_health_reporter_dump_clear(struct ynl_sock *ys, + struct devlink_health_reporter_dump_clear_req *req); + +/* ============== DEVLINK_CMD_FLASH_UPDATE ============== */ +/* DEVLINK_CMD_FLASH_UPDATE - do */ +struct devlink_flash_update_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 flash_update_file_name_len; + __u32 flash_update_component_len; + __u32 flash_update_overwrite_mask:1; + } _present; + + char *bus_name; + char *dev_name; + char *flash_update_file_name; + char *flash_update_component; + struct nla_bitfield32 flash_update_overwrite_mask; +}; + +static inline struct devlink_flash_update_req * +devlink_flash_update_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_flash_update_req)); +} +void devlink_flash_update_req_free(struct devlink_flash_update_req *req); + +static inline void +devlink_flash_update_req_set_bus_name(struct devlink_flash_update_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_flash_update_req_set_dev_name(struct devlink_flash_update_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_flash_update_req_set_flash_update_file_name(struct devlink_flash_update_req *req, + const char *flash_update_file_name) +{ + free(req->flash_update_file_name); + req->_present.flash_update_file_name_len = strlen(flash_update_file_name); + req->flash_update_file_name = malloc(req->_present.flash_update_file_name_len + 1); + memcpy(req->flash_update_file_name, flash_update_file_name, req->_present.flash_update_file_name_len); + req->flash_update_file_name[req->_present.flash_update_file_name_len] = 0; +} +static inline void +devlink_flash_update_req_set_flash_update_component(struct devlink_flash_update_req *req, + const char *flash_update_component) +{ + free(req->flash_update_component); + req->_present.flash_update_component_len = strlen(flash_update_component); + req->flash_update_component = malloc(req->_present.flash_update_component_len + 1); + memcpy(req->flash_update_component, flash_update_component, req->_present.flash_update_component_len); + req->flash_update_component[req->_present.flash_update_component_len] = 0; +} +static inline void +devlink_flash_update_req_set_flash_update_overwrite_mask(struct devlink_flash_update_req *req, + struct nla_bitfield32 *flash_update_overwrite_mask) +{ + req->_present.flash_update_overwrite_mask = 1; + memcpy(&req->flash_update_overwrite_mask, flash_update_overwrite_mask, sizeof(struct nla_bitfield32)); +} + +/* + * Flash update devlink instances. + */ +int devlink_flash_update(struct ynl_sock *ys, + struct devlink_flash_update_req *req); + +/* ============== DEVLINK_CMD_TRAP_GET ============== */ +/* DEVLINK_CMD_TRAP_GET - do */ +struct devlink_trap_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 trap_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *trap_name; +}; + +static inline struct devlink_trap_get_req *devlink_trap_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_trap_get_req)); +} +void devlink_trap_get_req_free(struct devlink_trap_get_req *req); + +static inline void +devlink_trap_get_req_set_bus_name(struct devlink_trap_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_trap_get_req_set_dev_name(struct devlink_trap_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_trap_get_req_set_trap_name(struct devlink_trap_get_req *req, + const char *trap_name) +{ + free(req->trap_name); + req->_present.trap_name_len = strlen(trap_name); + req->trap_name = malloc(req->_present.trap_name_len + 1); + memcpy(req->trap_name, trap_name, req->_present.trap_name_len); + req->trap_name[req->_present.trap_name_len] = 0; +} + +struct devlink_trap_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 trap_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *trap_name; +}; + +void devlink_trap_get_rsp_free(struct devlink_trap_get_rsp *rsp); + +/* + * Get trap instances. + */ +struct devlink_trap_get_rsp * +devlink_trap_get(struct ynl_sock *ys, struct devlink_trap_get_req *req); + +/* DEVLINK_CMD_TRAP_GET - dump */ +struct devlink_trap_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_trap_get_req_dump * +devlink_trap_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_trap_get_req_dump)); +} +void devlink_trap_get_req_dump_free(struct devlink_trap_get_req_dump *req); + +static inline void +devlink_trap_get_req_dump_set_bus_name(struct devlink_trap_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_trap_get_req_dump_set_dev_name(struct devlink_trap_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_trap_get_list { + struct devlink_trap_get_list *next; + struct devlink_trap_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_trap_get_list_free(struct devlink_trap_get_list *rsp); + +struct devlink_trap_get_list * +devlink_trap_get_dump(struct ynl_sock *ys, + struct devlink_trap_get_req_dump *req); + +/* ============== DEVLINK_CMD_TRAP_SET ============== */ +/* DEVLINK_CMD_TRAP_SET - do */ +struct devlink_trap_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 trap_name_len; + __u32 trap_action:1; + } _present; + + char *bus_name; + char *dev_name; + char *trap_name; + enum devlink_trap_action trap_action; +}; + +static inline struct devlink_trap_set_req *devlink_trap_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_trap_set_req)); +} +void devlink_trap_set_req_free(struct devlink_trap_set_req *req); + +static inline void +devlink_trap_set_req_set_bus_name(struct devlink_trap_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_trap_set_req_set_dev_name(struct devlink_trap_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_trap_set_req_set_trap_name(struct devlink_trap_set_req *req, + const char *trap_name) +{ + free(req->trap_name); + req->_present.trap_name_len = strlen(trap_name); + req->trap_name = malloc(req->_present.trap_name_len + 1); + memcpy(req->trap_name, trap_name, req->_present.trap_name_len); + req->trap_name[req->_present.trap_name_len] = 0; +} +static inline void +devlink_trap_set_req_set_trap_action(struct devlink_trap_set_req *req, + enum devlink_trap_action trap_action) +{ + req->_present.trap_action = 1; + req->trap_action = trap_action; +} + +/* + * Set trap instances. + */ +int devlink_trap_set(struct ynl_sock *ys, struct devlink_trap_set_req *req); + +/* ============== DEVLINK_CMD_TRAP_GROUP_GET ============== */ +/* DEVLINK_CMD_TRAP_GROUP_GET - do */ +struct devlink_trap_group_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 trap_group_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *trap_group_name; +}; + +static inline struct devlink_trap_group_get_req * +devlink_trap_group_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_trap_group_get_req)); +} +void devlink_trap_group_get_req_free(struct devlink_trap_group_get_req *req); + +static inline void +devlink_trap_group_get_req_set_bus_name(struct devlink_trap_group_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_trap_group_get_req_set_dev_name(struct devlink_trap_group_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_trap_group_get_req_set_trap_group_name(struct devlink_trap_group_get_req *req, + const char *trap_group_name) +{ + free(req->trap_group_name); + req->_present.trap_group_name_len = strlen(trap_group_name); + req->trap_group_name = malloc(req->_present.trap_group_name_len + 1); + memcpy(req->trap_group_name, trap_group_name, req->_present.trap_group_name_len); + req->trap_group_name[req->_present.trap_group_name_len] = 0; +} + +struct devlink_trap_group_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 trap_group_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *trap_group_name; +}; + +void devlink_trap_group_get_rsp_free(struct devlink_trap_group_get_rsp *rsp); + +/* + * Get trap group instances. + */ +struct devlink_trap_group_get_rsp * +devlink_trap_group_get(struct ynl_sock *ys, + struct devlink_trap_group_get_req *req); + +/* DEVLINK_CMD_TRAP_GROUP_GET - dump */ +struct devlink_trap_group_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_trap_group_get_req_dump * +devlink_trap_group_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_trap_group_get_req_dump)); +} +void +devlink_trap_group_get_req_dump_free(struct devlink_trap_group_get_req_dump *req); + +static inline void +devlink_trap_group_get_req_dump_set_bus_name(struct devlink_trap_group_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_trap_group_get_req_dump_set_dev_name(struct devlink_trap_group_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_trap_group_get_list { + struct devlink_trap_group_get_list *next; + struct devlink_trap_group_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_trap_group_get_list_free(struct devlink_trap_group_get_list *rsp); + +struct devlink_trap_group_get_list * +devlink_trap_group_get_dump(struct ynl_sock *ys, + struct devlink_trap_group_get_req_dump *req); + +/* ============== DEVLINK_CMD_TRAP_GROUP_SET ============== */ +/* DEVLINK_CMD_TRAP_GROUP_SET - do */ +struct devlink_trap_group_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 trap_group_name_len; + __u32 trap_action:1; + __u32 trap_policer_id:1; + } _present; + + char *bus_name; + char *dev_name; + char *trap_group_name; + enum devlink_trap_action trap_action; + __u32 trap_policer_id; +}; + +static inline struct devlink_trap_group_set_req * +devlink_trap_group_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_trap_group_set_req)); +} +void devlink_trap_group_set_req_free(struct devlink_trap_group_set_req *req); + +static inline void +devlink_trap_group_set_req_set_bus_name(struct devlink_trap_group_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_trap_group_set_req_set_dev_name(struct devlink_trap_group_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_trap_group_set_req_set_trap_group_name(struct devlink_trap_group_set_req *req, + const char *trap_group_name) +{ + free(req->trap_group_name); + req->_present.trap_group_name_len = strlen(trap_group_name); + req->trap_group_name = malloc(req->_present.trap_group_name_len + 1); + memcpy(req->trap_group_name, trap_group_name, req->_present.trap_group_name_len); + req->trap_group_name[req->_present.trap_group_name_len] = 0; +} +static inline void +devlink_trap_group_set_req_set_trap_action(struct devlink_trap_group_set_req *req, + enum devlink_trap_action trap_action) +{ + req->_present.trap_action = 1; + req->trap_action = trap_action; +} +static inline void +devlink_trap_group_set_req_set_trap_policer_id(struct devlink_trap_group_set_req *req, + __u32 trap_policer_id) +{ + req->_present.trap_policer_id = 1; + req->trap_policer_id = trap_policer_id; +} + +/* + * Set trap group instances. + */ +int devlink_trap_group_set(struct ynl_sock *ys, + struct devlink_trap_group_set_req *req); + +/* ============== DEVLINK_CMD_TRAP_POLICER_GET ============== */ +/* DEVLINK_CMD_TRAP_POLICER_GET - do */ +struct devlink_trap_policer_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 trap_policer_id:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 trap_policer_id; +}; + +static inline struct devlink_trap_policer_get_req * +devlink_trap_policer_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_trap_policer_get_req)); +} +void +devlink_trap_policer_get_req_free(struct devlink_trap_policer_get_req *req); + +static inline void +devlink_trap_policer_get_req_set_bus_name(struct devlink_trap_policer_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_trap_policer_get_req_set_dev_name(struct devlink_trap_policer_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_trap_policer_get_req_set_trap_policer_id(struct devlink_trap_policer_get_req *req, + __u32 trap_policer_id) +{ + req->_present.trap_policer_id = 1; + req->trap_policer_id = trap_policer_id; +} + +struct devlink_trap_policer_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 trap_policer_id:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 trap_policer_id; +}; + +void +devlink_trap_policer_get_rsp_free(struct devlink_trap_policer_get_rsp *rsp); + +/* + * Get trap policer instances. + */ +struct devlink_trap_policer_get_rsp * +devlink_trap_policer_get(struct ynl_sock *ys, + struct devlink_trap_policer_get_req *req); + +/* DEVLINK_CMD_TRAP_POLICER_GET - dump */ +struct devlink_trap_policer_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_trap_policer_get_req_dump * +devlink_trap_policer_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_trap_policer_get_req_dump)); +} +void +devlink_trap_policer_get_req_dump_free(struct devlink_trap_policer_get_req_dump *req); + +static inline void +devlink_trap_policer_get_req_dump_set_bus_name(struct devlink_trap_policer_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_trap_policer_get_req_dump_set_dev_name(struct devlink_trap_policer_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_trap_policer_get_list { + struct devlink_trap_policer_get_list *next; + struct devlink_trap_policer_get_rsp obj __attribute__((aligned(8))); +}; + +void +devlink_trap_policer_get_list_free(struct devlink_trap_policer_get_list *rsp); + +struct devlink_trap_policer_get_list * +devlink_trap_policer_get_dump(struct ynl_sock *ys, + struct devlink_trap_policer_get_req_dump *req); + +/* ============== DEVLINK_CMD_TRAP_POLICER_SET ============== */ +/* DEVLINK_CMD_TRAP_POLICER_SET - do */ +struct devlink_trap_policer_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 trap_policer_id:1; + __u32 trap_policer_rate:1; + __u32 trap_policer_burst:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 trap_policer_id; + __u64 trap_policer_rate; + __u64 trap_policer_burst; +}; + +static inline struct devlink_trap_policer_set_req * +devlink_trap_policer_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_trap_policer_set_req)); +} +void +devlink_trap_policer_set_req_free(struct devlink_trap_policer_set_req *req); + +static inline void +devlink_trap_policer_set_req_set_bus_name(struct devlink_trap_policer_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_trap_policer_set_req_set_dev_name(struct devlink_trap_policer_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_trap_policer_set_req_set_trap_policer_id(struct devlink_trap_policer_set_req *req, + __u32 trap_policer_id) +{ + req->_present.trap_policer_id = 1; + req->trap_policer_id = trap_policer_id; +} +static inline void +devlink_trap_policer_set_req_set_trap_policer_rate(struct devlink_trap_policer_set_req *req, + __u64 trap_policer_rate) +{ + req->_present.trap_policer_rate = 1; + req->trap_policer_rate = trap_policer_rate; +} +static inline void +devlink_trap_policer_set_req_set_trap_policer_burst(struct devlink_trap_policer_set_req *req, + __u64 trap_policer_burst) +{ + req->_present.trap_policer_burst = 1; + req->trap_policer_burst = trap_policer_burst; +} + +/* + * Get trap policer instances. + */ +int devlink_trap_policer_set(struct ynl_sock *ys, + struct devlink_trap_policer_set_req *req); + +/* ============== DEVLINK_CMD_HEALTH_REPORTER_TEST ============== */ +/* DEVLINK_CMD_HEALTH_REPORTER_TEST - do */ +struct devlink_health_reporter_test_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 health_reporter_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *health_reporter_name; +}; + +static inline struct devlink_health_reporter_test_req * +devlink_health_reporter_test_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_health_reporter_test_req)); +} +void +devlink_health_reporter_test_req_free(struct devlink_health_reporter_test_req *req); + +static inline void +devlink_health_reporter_test_req_set_bus_name(struct devlink_health_reporter_test_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_health_reporter_test_req_set_dev_name(struct devlink_health_reporter_test_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_health_reporter_test_req_set_port_index(struct devlink_health_reporter_test_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_health_reporter_test_req_set_health_reporter_name(struct devlink_health_reporter_test_req *req, + const char *health_reporter_name) +{ + free(req->health_reporter_name); + req->_present.health_reporter_name_len = strlen(health_reporter_name); + req->health_reporter_name = malloc(req->_present.health_reporter_name_len + 1); + memcpy(req->health_reporter_name, health_reporter_name, req->_present.health_reporter_name_len); + req->health_reporter_name[req->_present.health_reporter_name_len] = 0; +} + +/* + * Test health reporter instances. + */ +int devlink_health_reporter_test(struct ynl_sock *ys, + struct devlink_health_reporter_test_req *req); + +/* ============== DEVLINK_CMD_RATE_GET ============== */ +/* DEVLINK_CMD_RATE_GET - do */ +struct devlink_rate_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 rate_node_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *rate_node_name; +}; + +static inline struct devlink_rate_get_req *devlink_rate_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_rate_get_req)); +} +void devlink_rate_get_req_free(struct devlink_rate_get_req *req); + +static inline void +devlink_rate_get_req_set_bus_name(struct devlink_rate_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_rate_get_req_set_dev_name(struct devlink_rate_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_rate_get_req_set_port_index(struct devlink_rate_get_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} +static inline void +devlink_rate_get_req_set_rate_node_name(struct devlink_rate_get_req *req, + const char *rate_node_name) +{ + free(req->rate_node_name); + req->_present.rate_node_name_len = strlen(rate_node_name); + req->rate_node_name = malloc(req->_present.rate_node_name_len + 1); + memcpy(req->rate_node_name, rate_node_name, req->_present.rate_node_name_len); + req->rate_node_name[req->_present.rate_node_name_len] = 0; +} + +struct devlink_rate_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + __u32 rate_node_name_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; + char *rate_node_name; +}; + +void devlink_rate_get_rsp_free(struct devlink_rate_get_rsp *rsp); + +/* + * Get rate instances. + */ +struct devlink_rate_get_rsp * +devlink_rate_get(struct ynl_sock *ys, struct devlink_rate_get_req *req); + +/* DEVLINK_CMD_RATE_GET - dump */ +struct devlink_rate_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_rate_get_req_dump * +devlink_rate_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_rate_get_req_dump)); +} +void devlink_rate_get_req_dump_free(struct devlink_rate_get_req_dump *req); + +static inline void +devlink_rate_get_req_dump_set_bus_name(struct devlink_rate_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_rate_get_req_dump_set_dev_name(struct devlink_rate_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_rate_get_list { + struct devlink_rate_get_list *next; + struct devlink_rate_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_rate_get_list_free(struct devlink_rate_get_list *rsp); + +struct devlink_rate_get_list * +devlink_rate_get_dump(struct ynl_sock *ys, + struct devlink_rate_get_req_dump *req); + +/* ============== DEVLINK_CMD_RATE_SET ============== */ +/* DEVLINK_CMD_RATE_SET - do */ +struct devlink_rate_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 rate_node_name_len; + __u32 rate_tx_share:1; + __u32 rate_tx_max:1; + __u32 rate_tx_priority:1; + __u32 rate_tx_weight:1; + __u32 rate_parent_node_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *rate_node_name; + __u64 rate_tx_share; + __u64 rate_tx_max; + __u32 rate_tx_priority; + __u32 rate_tx_weight; + char *rate_parent_node_name; +}; + +static inline struct devlink_rate_set_req *devlink_rate_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_rate_set_req)); +} +void devlink_rate_set_req_free(struct devlink_rate_set_req *req); + +static inline void +devlink_rate_set_req_set_bus_name(struct devlink_rate_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_rate_set_req_set_dev_name(struct devlink_rate_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_rate_set_req_set_rate_node_name(struct devlink_rate_set_req *req, + const char *rate_node_name) +{ + free(req->rate_node_name); + req->_present.rate_node_name_len = strlen(rate_node_name); + req->rate_node_name = malloc(req->_present.rate_node_name_len + 1); + memcpy(req->rate_node_name, rate_node_name, req->_present.rate_node_name_len); + req->rate_node_name[req->_present.rate_node_name_len] = 0; +} +static inline void +devlink_rate_set_req_set_rate_tx_share(struct devlink_rate_set_req *req, + __u64 rate_tx_share) +{ + req->_present.rate_tx_share = 1; + req->rate_tx_share = rate_tx_share; +} +static inline void +devlink_rate_set_req_set_rate_tx_max(struct devlink_rate_set_req *req, + __u64 rate_tx_max) +{ + req->_present.rate_tx_max = 1; + req->rate_tx_max = rate_tx_max; +} +static inline void +devlink_rate_set_req_set_rate_tx_priority(struct devlink_rate_set_req *req, + __u32 rate_tx_priority) +{ + req->_present.rate_tx_priority = 1; + req->rate_tx_priority = rate_tx_priority; +} +static inline void +devlink_rate_set_req_set_rate_tx_weight(struct devlink_rate_set_req *req, + __u32 rate_tx_weight) +{ + req->_present.rate_tx_weight = 1; + req->rate_tx_weight = rate_tx_weight; +} +static inline void +devlink_rate_set_req_set_rate_parent_node_name(struct devlink_rate_set_req *req, + const char *rate_parent_node_name) +{ + free(req->rate_parent_node_name); + req->_present.rate_parent_node_name_len = strlen(rate_parent_node_name); + req->rate_parent_node_name = malloc(req->_present.rate_parent_node_name_len + 1); + memcpy(req->rate_parent_node_name, rate_parent_node_name, req->_present.rate_parent_node_name_len); + req->rate_parent_node_name[req->_present.rate_parent_node_name_len] = 0; +} + +/* + * Set rate instances. + */ +int devlink_rate_set(struct ynl_sock *ys, struct devlink_rate_set_req *req); + +/* ============== DEVLINK_CMD_RATE_NEW ============== */ +/* DEVLINK_CMD_RATE_NEW - do */ +struct devlink_rate_new_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 rate_node_name_len; + __u32 rate_tx_share:1; + __u32 rate_tx_max:1; + __u32 rate_tx_priority:1; + __u32 rate_tx_weight:1; + __u32 rate_parent_node_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *rate_node_name; + __u64 rate_tx_share; + __u64 rate_tx_max; + __u32 rate_tx_priority; + __u32 rate_tx_weight; + char *rate_parent_node_name; +}; + +static inline struct devlink_rate_new_req *devlink_rate_new_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_rate_new_req)); +} +void devlink_rate_new_req_free(struct devlink_rate_new_req *req); + +static inline void +devlink_rate_new_req_set_bus_name(struct devlink_rate_new_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_rate_new_req_set_dev_name(struct devlink_rate_new_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_rate_new_req_set_rate_node_name(struct devlink_rate_new_req *req, + const char *rate_node_name) +{ + free(req->rate_node_name); + req->_present.rate_node_name_len = strlen(rate_node_name); + req->rate_node_name = malloc(req->_present.rate_node_name_len + 1); + memcpy(req->rate_node_name, rate_node_name, req->_present.rate_node_name_len); + req->rate_node_name[req->_present.rate_node_name_len] = 0; +} +static inline void +devlink_rate_new_req_set_rate_tx_share(struct devlink_rate_new_req *req, + __u64 rate_tx_share) +{ + req->_present.rate_tx_share = 1; + req->rate_tx_share = rate_tx_share; +} +static inline void +devlink_rate_new_req_set_rate_tx_max(struct devlink_rate_new_req *req, + __u64 rate_tx_max) +{ + req->_present.rate_tx_max = 1; + req->rate_tx_max = rate_tx_max; +} +static inline void +devlink_rate_new_req_set_rate_tx_priority(struct devlink_rate_new_req *req, + __u32 rate_tx_priority) +{ + req->_present.rate_tx_priority = 1; + req->rate_tx_priority = rate_tx_priority; +} +static inline void +devlink_rate_new_req_set_rate_tx_weight(struct devlink_rate_new_req *req, + __u32 rate_tx_weight) +{ + req->_present.rate_tx_weight = 1; + req->rate_tx_weight = rate_tx_weight; +} +static inline void +devlink_rate_new_req_set_rate_parent_node_name(struct devlink_rate_new_req *req, + const char *rate_parent_node_name) +{ + free(req->rate_parent_node_name); + req->_present.rate_parent_node_name_len = strlen(rate_parent_node_name); + req->rate_parent_node_name = malloc(req->_present.rate_parent_node_name_len + 1); + memcpy(req->rate_parent_node_name, rate_parent_node_name, req->_present.rate_parent_node_name_len); + req->rate_parent_node_name[req->_present.rate_parent_node_name_len] = 0; +} + +/* + * Create rate instances. + */ +int devlink_rate_new(struct ynl_sock *ys, struct devlink_rate_new_req *req); + +/* ============== DEVLINK_CMD_RATE_DEL ============== */ +/* DEVLINK_CMD_RATE_DEL - do */ +struct devlink_rate_del_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 rate_node_name_len; + } _present; + + char *bus_name; + char *dev_name; + char *rate_node_name; +}; + +static inline struct devlink_rate_del_req *devlink_rate_del_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_rate_del_req)); +} +void devlink_rate_del_req_free(struct devlink_rate_del_req *req); + +static inline void +devlink_rate_del_req_set_bus_name(struct devlink_rate_del_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_rate_del_req_set_dev_name(struct devlink_rate_del_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_rate_del_req_set_rate_node_name(struct devlink_rate_del_req *req, + const char *rate_node_name) +{ + free(req->rate_node_name); + req->_present.rate_node_name_len = strlen(rate_node_name); + req->rate_node_name = malloc(req->_present.rate_node_name_len + 1); + memcpy(req->rate_node_name, rate_node_name, req->_present.rate_node_name_len); + req->rate_node_name[req->_present.rate_node_name_len] = 0; +} + +/* + * Delete rate instances. + */ +int devlink_rate_del(struct ynl_sock *ys, struct devlink_rate_del_req *req); + +/* ============== DEVLINK_CMD_LINECARD_GET ============== */ +/* DEVLINK_CMD_LINECARD_GET - do */ +struct devlink_linecard_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 linecard_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 linecard_index; +}; + +static inline struct devlink_linecard_get_req * +devlink_linecard_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_linecard_get_req)); +} +void devlink_linecard_get_req_free(struct devlink_linecard_get_req *req); + +static inline void +devlink_linecard_get_req_set_bus_name(struct devlink_linecard_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_linecard_get_req_set_dev_name(struct devlink_linecard_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_linecard_get_req_set_linecard_index(struct devlink_linecard_get_req *req, + __u32 linecard_index) +{ + req->_present.linecard_index = 1; + req->linecard_index = linecard_index; +} + +struct devlink_linecard_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 linecard_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 linecard_index; +}; + +void devlink_linecard_get_rsp_free(struct devlink_linecard_get_rsp *rsp); + +/* + * Get line card instances. + */ +struct devlink_linecard_get_rsp * +devlink_linecard_get(struct ynl_sock *ys, struct devlink_linecard_get_req *req); + +/* DEVLINK_CMD_LINECARD_GET - dump */ +struct devlink_linecard_get_req_dump { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_linecard_get_req_dump * +devlink_linecard_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct devlink_linecard_get_req_dump)); +} +void +devlink_linecard_get_req_dump_free(struct devlink_linecard_get_req_dump *req); + +static inline void +devlink_linecard_get_req_dump_set_bus_name(struct devlink_linecard_get_req_dump *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_linecard_get_req_dump_set_dev_name(struct devlink_linecard_get_req_dump *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_linecard_get_list { + struct devlink_linecard_get_list *next; + struct devlink_linecard_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_linecard_get_list_free(struct devlink_linecard_get_list *rsp); + +struct devlink_linecard_get_list * +devlink_linecard_get_dump(struct ynl_sock *ys, + struct devlink_linecard_get_req_dump *req); + +/* ============== DEVLINK_CMD_LINECARD_SET ============== */ +/* DEVLINK_CMD_LINECARD_SET - do */ +struct devlink_linecard_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 linecard_index:1; + __u32 linecard_type_len; + } _present; + + char *bus_name; + char *dev_name; + __u32 linecard_index; + char *linecard_type; +}; + +static inline struct devlink_linecard_set_req * +devlink_linecard_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_linecard_set_req)); +} +void devlink_linecard_set_req_free(struct devlink_linecard_set_req *req); + +static inline void +devlink_linecard_set_req_set_bus_name(struct devlink_linecard_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_linecard_set_req_set_dev_name(struct devlink_linecard_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_linecard_set_req_set_linecard_index(struct devlink_linecard_set_req *req, + __u32 linecard_index) +{ + req->_present.linecard_index = 1; + req->linecard_index = linecard_index; +} +static inline void +devlink_linecard_set_req_set_linecard_type(struct devlink_linecard_set_req *req, + const char *linecard_type) +{ + free(req->linecard_type); + req->_present.linecard_type_len = strlen(linecard_type); + req->linecard_type = malloc(req->_present.linecard_type_len + 1); + memcpy(req->linecard_type, linecard_type, req->_present.linecard_type_len); + req->linecard_type[req->_present.linecard_type_len] = 0; +} + +/* + * Set line card instances. + */ +int devlink_linecard_set(struct ynl_sock *ys, + struct devlink_linecard_set_req *req); + +/* ============== DEVLINK_CMD_SELFTESTS_GET ============== */ +/* DEVLINK_CMD_SELFTESTS_GET - do */ +struct devlink_selftests_get_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +static inline struct devlink_selftests_get_req * +devlink_selftests_get_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_selftests_get_req)); +} +void devlink_selftests_get_req_free(struct devlink_selftests_get_req *req); + +static inline void +devlink_selftests_get_req_set_bus_name(struct devlink_selftests_get_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_selftests_get_req_set_dev_name(struct devlink_selftests_get_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} + +struct devlink_selftests_get_rsp { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + } _present; + + char *bus_name; + char *dev_name; +}; + +void devlink_selftests_get_rsp_free(struct devlink_selftests_get_rsp *rsp); + +/* + * Get device selftest instances. + */ +struct devlink_selftests_get_rsp * +devlink_selftests_get(struct ynl_sock *ys, + struct devlink_selftests_get_req *req); + +/* DEVLINK_CMD_SELFTESTS_GET - dump */ +struct devlink_selftests_get_list { + struct devlink_selftests_get_list *next; + struct devlink_selftests_get_rsp obj __attribute__((aligned(8))); +}; + +void devlink_selftests_get_list_free(struct devlink_selftests_get_list *rsp); + +struct devlink_selftests_get_list * +devlink_selftests_get_dump(struct ynl_sock *ys); + +/* ============== DEVLINK_CMD_SELFTESTS_RUN ============== */ +/* DEVLINK_CMD_SELFTESTS_RUN - do */ +struct devlink_selftests_run_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 selftests:1; + } _present; + + char *bus_name; + char *dev_name; + struct devlink_dl_selftest_id selftests; +}; + +static inline struct devlink_selftests_run_req * +devlink_selftests_run_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_selftests_run_req)); +} +void devlink_selftests_run_req_free(struct devlink_selftests_run_req *req); + +static inline void +devlink_selftests_run_req_set_bus_name(struct devlink_selftests_run_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_selftests_run_req_set_dev_name(struct devlink_selftests_run_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_selftests_run_req_set_selftests_flash(struct devlink_selftests_run_req *req) +{ + req->_present.selftests = 1; + req->selftests._present.flash = 1; +} + +/* + * Run device selftest instances. + */ +int devlink_selftests_run(struct ynl_sock *ys, + struct devlink_selftests_run_req *req); + +/* ============== DEVLINK_CMD_NOTIFY_FILTER_SET ============== */ +/* DEVLINK_CMD_NOTIFY_FILTER_SET - do */ +struct devlink_notify_filter_set_req { + struct { + __u32 bus_name_len; + __u32 dev_name_len; + __u32 port_index:1; + } _present; + + char *bus_name; + char *dev_name; + __u32 port_index; +}; + +static inline struct devlink_notify_filter_set_req * +devlink_notify_filter_set_req_alloc(void) +{ + return calloc(1, sizeof(struct devlink_notify_filter_set_req)); +} +void +devlink_notify_filter_set_req_free(struct devlink_notify_filter_set_req *req); + +static inline void +devlink_notify_filter_set_req_set_bus_name(struct devlink_notify_filter_set_req *req, + const char *bus_name) +{ + free(req->bus_name); + req->_present.bus_name_len = strlen(bus_name); + req->bus_name = malloc(req->_present.bus_name_len + 1); + memcpy(req->bus_name, bus_name, req->_present.bus_name_len); + req->bus_name[req->_present.bus_name_len] = 0; +} +static inline void +devlink_notify_filter_set_req_set_dev_name(struct devlink_notify_filter_set_req *req, + const char *dev_name) +{ + free(req->dev_name); + req->_present.dev_name_len = strlen(dev_name); + req->dev_name = malloc(req->_present.dev_name_len + 1); + memcpy(req->dev_name, dev_name, req->_present.dev_name_len); + req->dev_name[req->_present.dev_name_len] = 0; +} +static inline void +devlink_notify_filter_set_req_set_port_index(struct devlink_notify_filter_set_req *req, + __u32 port_index) +{ + req->_present.port_index = 1; + req->port_index = port_index; +} + +/* + * Set notification messages socket filter. + */ +int devlink_notify_filter_set(struct ynl_sock *ys, + struct devlink_notify_filter_set_req *req); + +#endif /* _LINUX_DEVLINK_GEN_H */ diff --git a/generated/dpll-user.c b/generated/dpll-user.c new file mode 100644 index 0000000..2f7378a --- /dev/null +++ b/generated/dpll-user.c @@ -0,0 +1,1101 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/dpll.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "dpll-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const dpll_op_strmap[] = { + [DPLL_CMD_DEVICE_ID_GET] = "device-id-get", + [DPLL_CMD_DEVICE_GET] = "device-get", + [DPLL_CMD_DEVICE_SET] = "device-set", + [DPLL_CMD_DEVICE_CREATE_NTF] = "device-create-ntf", + [DPLL_CMD_DEVICE_DELETE_NTF] = "device-delete-ntf", + [DPLL_CMD_DEVICE_CHANGE_NTF] = "device-change-ntf", + [DPLL_CMD_PIN_ID_GET] = "pin-id-get", + [DPLL_CMD_PIN_GET] = "pin-get", + [DPLL_CMD_PIN_SET] = "pin-set", + [DPLL_CMD_PIN_CREATE_NTF] = "pin-create-ntf", + [DPLL_CMD_PIN_DELETE_NTF] = "pin-delete-ntf", + [DPLL_CMD_PIN_CHANGE_NTF] = "pin-change-ntf", +}; + +const char *dpll_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(dpll_op_strmap)) + return NULL; + return dpll_op_strmap[op]; +} + +static const char * const dpll_mode_strmap[] = { + [1] = "manual", + [2] = "automatic", +}; + +const char *dpll_mode_str(enum dpll_mode value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(dpll_mode_strmap)) + return NULL; + return dpll_mode_strmap[value]; +} + +static const char * const dpll_lock_status_strmap[] = { + [1] = "unlocked", + [2] = "locked", + [3] = "locked-ho-acq", + [4] = "holdover", +}; + +const char *dpll_lock_status_str(enum dpll_lock_status value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(dpll_lock_status_strmap)) + return NULL; + return dpll_lock_status_strmap[value]; +} + +static const char * const dpll_lock_status_error_strmap[] = { + [1] = "none", + [2] = "undefined", + [3] = "media-down", + [4] = "fractional-frequency-offset-too-high", +}; + +const char *dpll_lock_status_error_str(enum dpll_lock_status_error value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(dpll_lock_status_error_strmap)) + return NULL; + return dpll_lock_status_error_strmap[value]; +} + +static const char * const dpll_type_strmap[] = { + [1] = "pps", + [2] = "eec", +}; + +const char *dpll_type_str(enum dpll_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(dpll_type_strmap)) + return NULL; + return dpll_type_strmap[value]; +} + +static const char * const dpll_pin_type_strmap[] = { + [1] = "mux", + [2] = "ext", + [3] = "synce-eth-port", + [4] = "int-oscillator", + [5] = "gnss", +}; + +const char *dpll_pin_type_str(enum dpll_pin_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(dpll_pin_type_strmap)) + return NULL; + return dpll_pin_type_strmap[value]; +} + +static const char * const dpll_pin_direction_strmap[] = { + [1] = "input", + [2] = "output", +}; + +const char *dpll_pin_direction_str(enum dpll_pin_direction value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(dpll_pin_direction_strmap)) + return NULL; + return dpll_pin_direction_strmap[value]; +} + +static const char * const dpll_pin_state_strmap[] = { + [1] = "connected", + [2] = "disconnected", + [3] = "selectable", +}; + +const char *dpll_pin_state_str(enum dpll_pin_state value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(dpll_pin_state_strmap)) + return NULL; + return dpll_pin_state_strmap[value]; +} + +static const char * const dpll_pin_capabilities_strmap[] = { + [0] = "direction-can-change", + [1] = "priority-can-change", + [2] = "state-can-change", +}; + +const char *dpll_pin_capabilities_str(enum dpll_pin_capabilities value) +{ + value = ffs(value) - 1; + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(dpll_pin_capabilities_strmap)) + return NULL; + return dpll_pin_capabilities_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr dpll_frequency_range_policy[DPLL_A_PIN_MAX + 1] = { + [DPLL_A_PIN_FREQUENCY_MIN] = { .name = "frequency-min", .type = YNL_PT_U64, }, + [DPLL_A_PIN_FREQUENCY_MAX] = { .name = "frequency-max", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest dpll_frequency_range_nest = { + .max_attr = DPLL_A_PIN_MAX, + .table = dpll_frequency_range_policy, +}; + +struct ynl_policy_attr dpll_pin_parent_device_policy[DPLL_A_PIN_MAX + 1] = { + [DPLL_A_PIN_PARENT_ID] = { .name = "parent-id", .type = YNL_PT_U32, }, + [DPLL_A_PIN_DIRECTION] = { .name = "direction", .type = YNL_PT_U32, }, + [DPLL_A_PIN_PRIO] = { .name = "prio", .type = YNL_PT_U32, }, + [DPLL_A_PIN_STATE] = { .name = "state", .type = YNL_PT_U32, }, + [DPLL_A_PIN_PHASE_OFFSET] = { .name = "phase-offset", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest dpll_pin_parent_device_nest = { + .max_attr = DPLL_A_PIN_MAX, + .table = dpll_pin_parent_device_policy, +}; + +struct ynl_policy_attr dpll_pin_parent_pin_policy[DPLL_A_PIN_MAX + 1] = { + [DPLL_A_PIN_PARENT_ID] = { .name = "parent-id", .type = YNL_PT_U32, }, + [DPLL_A_PIN_STATE] = { .name = "state", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest dpll_pin_parent_pin_nest = { + .max_attr = DPLL_A_PIN_MAX, + .table = dpll_pin_parent_pin_policy, +}; + +struct ynl_policy_attr dpll_policy[DPLL_A_MAX + 1] = { + [DPLL_A_ID] = { .name = "id", .type = YNL_PT_U32, }, + [DPLL_A_MODULE_NAME] = { .name = "module-name", .type = YNL_PT_NUL_STR, }, + [DPLL_A_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [DPLL_A_CLOCK_ID] = { .name = "clock-id", .type = YNL_PT_U64, }, + [DPLL_A_MODE] = { .name = "mode", .type = YNL_PT_U32, }, + [DPLL_A_MODE_SUPPORTED] = { .name = "mode-supported", .type = YNL_PT_U32, }, + [DPLL_A_LOCK_STATUS] = { .name = "lock-status", .type = YNL_PT_U32, }, + [DPLL_A_TEMP] = { .name = "temp", .type = YNL_PT_U32, }, + [DPLL_A_TYPE] = { .name = "type", .type = YNL_PT_U32, }, + [DPLL_A_LOCK_STATUS_ERROR] = { .name = "lock-status-error", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest dpll_nest = { + .max_attr = DPLL_A_MAX, + .table = dpll_policy, +}; + +struct ynl_policy_attr dpll_pin_policy[DPLL_A_PIN_MAX + 1] = { + [DPLL_A_PIN_ID] = { .name = "id", .type = YNL_PT_U32, }, + [DPLL_A_PIN_PARENT_ID] = { .name = "parent-id", .type = YNL_PT_U32, }, + [DPLL_A_PIN_MODULE_NAME] = { .name = "module-name", .type = YNL_PT_NUL_STR, }, + [DPLL_A_PIN_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [DPLL_A_PIN_CLOCK_ID] = { .name = "clock-id", .type = YNL_PT_U64, }, + [DPLL_A_PIN_BOARD_LABEL] = { .name = "board-label", .type = YNL_PT_NUL_STR, }, + [DPLL_A_PIN_PANEL_LABEL] = { .name = "panel-label", .type = YNL_PT_NUL_STR, }, + [DPLL_A_PIN_PACKAGE_LABEL] = { .name = "package-label", .type = YNL_PT_NUL_STR, }, + [DPLL_A_PIN_TYPE] = { .name = "type", .type = YNL_PT_U32, }, + [DPLL_A_PIN_DIRECTION] = { .name = "direction", .type = YNL_PT_U32, }, + [DPLL_A_PIN_FREQUENCY] = { .name = "frequency", .type = YNL_PT_U64, }, + [DPLL_A_PIN_FREQUENCY_SUPPORTED] = { .name = "frequency-supported", .type = YNL_PT_NEST, .nest = &dpll_frequency_range_nest, }, + [DPLL_A_PIN_FREQUENCY_MIN] = { .name = "frequency-min", .type = YNL_PT_U64, }, + [DPLL_A_PIN_FREQUENCY_MAX] = { .name = "frequency-max", .type = YNL_PT_U64, }, + [DPLL_A_PIN_PRIO] = { .name = "prio", .type = YNL_PT_U32, }, + [DPLL_A_PIN_STATE] = { .name = "state", .type = YNL_PT_U32, }, + [DPLL_A_PIN_CAPABILITIES] = { .name = "capabilities", .type = YNL_PT_U32, }, + [DPLL_A_PIN_PARENT_DEVICE] = { .name = "parent-device", .type = YNL_PT_NEST, .nest = &dpll_pin_parent_device_nest, }, + [DPLL_A_PIN_PARENT_PIN] = { .name = "parent-pin", .type = YNL_PT_NEST, .nest = &dpll_pin_parent_pin_nest, }, + [DPLL_A_PIN_PHASE_ADJUST_MIN] = { .name = "phase-adjust-min", .type = YNL_PT_U32, }, + [DPLL_A_PIN_PHASE_ADJUST_MAX] = { .name = "phase-adjust-max", .type = YNL_PT_U32, }, + [DPLL_A_PIN_PHASE_ADJUST] = { .name = "phase-adjust", .type = YNL_PT_U32, }, + [DPLL_A_PIN_PHASE_OFFSET] = { .name = "phase-offset", .type = YNL_PT_U64, }, + [DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET] = { .name = "fractional-frequency-offset", .type = YNL_PT_UINT, }, +}; + +struct ynl_policy_nest dpll_pin_nest = { + .max_attr = DPLL_A_PIN_MAX, + .table = dpll_pin_policy, +}; + +/* Common nested types */ +void dpll_frequency_range_free(struct dpll_frequency_range *obj) +{ +} + +int dpll_frequency_range_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct dpll_frequency_range *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DPLL_A_PIN_FREQUENCY_MIN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.frequency_min = 1; + dst->frequency_min = ynl_attr_get_u64(attr); + } else if (type == DPLL_A_PIN_FREQUENCY_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.frequency_max = 1; + dst->frequency_max = ynl_attr_get_u64(attr); + } + } + + return 0; +} + +void dpll_pin_parent_device_free(struct dpll_pin_parent_device *obj) +{ +} + +int dpll_pin_parent_device_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct dpll_pin_parent_device *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.parent_id) + ynl_attr_put_u32(nlh, DPLL_A_PIN_PARENT_ID, obj->parent_id); + if (obj->_present.direction) + ynl_attr_put_u32(nlh, DPLL_A_PIN_DIRECTION, obj->direction); + if (obj->_present.prio) + ynl_attr_put_u32(nlh, DPLL_A_PIN_PRIO, obj->prio); + if (obj->_present.state) + ynl_attr_put_u32(nlh, DPLL_A_PIN_STATE, obj->state); + if (obj->_present.phase_offset) + ynl_attr_put_s64(nlh, DPLL_A_PIN_PHASE_OFFSET, obj->phase_offset); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int dpll_pin_parent_device_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct dpll_pin_parent_device *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DPLL_A_PIN_PARENT_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.parent_id = 1; + dst->parent_id = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_PIN_DIRECTION) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.direction = 1; + dst->direction = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_PIN_PRIO) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.prio = 1; + dst->prio = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_PIN_STATE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.state = 1; + dst->state = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_PIN_PHASE_OFFSET) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.phase_offset = 1; + dst->phase_offset = ynl_attr_get_s64(attr); + } + } + + return 0; +} + +void dpll_pin_parent_pin_free(struct dpll_pin_parent_pin *obj) +{ +} + +int dpll_pin_parent_pin_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct dpll_pin_parent_pin *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.parent_id) + ynl_attr_put_u32(nlh, DPLL_A_PIN_PARENT_ID, obj->parent_id); + if (obj->_present.state) + ynl_attr_put_u32(nlh, DPLL_A_PIN_STATE, obj->state); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int dpll_pin_parent_pin_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct dpll_pin_parent_pin *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == DPLL_A_PIN_PARENT_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.parent_id = 1; + dst->parent_id = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_PIN_STATE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.state = 1; + dst->state = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +/* ============== DPLL_CMD_DEVICE_ID_GET ============== */ +/* DPLL_CMD_DEVICE_ID_GET - do */ +void dpll_device_id_get_req_free(struct dpll_device_id_get_req *req) +{ + free(req->module_name); + free(req); +} + +void dpll_device_id_get_rsp_free(struct dpll_device_id_get_rsp *rsp) +{ + free(rsp); +} + +int dpll_device_id_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct dpll_device_id_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DPLL_A_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct dpll_device_id_get_rsp * +dpll_device_id_get(struct ynl_sock *ys, struct dpll_device_id_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct dpll_device_id_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DPLL_CMD_DEVICE_ID_GET, 1); + ys->req_policy = &dpll_nest; + yrs.yarg.rsp_policy = &dpll_nest; + + if (req->_present.module_name_len) + ynl_attr_put_str(nlh, DPLL_A_MODULE_NAME, req->module_name); + if (req->_present.clock_id) + ynl_attr_put_u64(nlh, DPLL_A_CLOCK_ID, req->clock_id); + if (req->_present.type) + ynl_attr_put_u32(nlh, DPLL_A_TYPE, req->type); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = dpll_device_id_get_rsp_parse; + yrs.rsp_cmd = DPLL_CMD_DEVICE_ID_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + dpll_device_id_get_rsp_free(rsp); + return NULL; +} + +/* ============== DPLL_CMD_DEVICE_GET ============== */ +/* DPLL_CMD_DEVICE_GET - do */ +void dpll_device_get_req_free(struct dpll_device_get_req *req) +{ + free(req); +} + +void dpll_device_get_rsp_free(struct dpll_device_get_rsp *rsp) +{ + free(rsp->module_name); + free(rsp->mode_supported); + free(rsp); +} + +int dpll_device_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + unsigned int n_mode_supported = 0; + struct dpll_device_get_rsp *dst; + const struct nlattr *attr; + int i; + + dst = yarg->data; + + if (dst->mode_supported) + return ynl_error_parse(yarg, "attribute already present (dpll.mode-supported)"); + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DPLL_A_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_MODULE_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.module_name_len = len; + dst->module_name = malloc(len + 1); + memcpy(dst->module_name, ynl_attr_get_str(attr), len); + dst->module_name[len] = 0; + } else if (type == DPLL_A_MODE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.mode = 1; + dst->mode = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_MODE_SUPPORTED) { + n_mode_supported++; + } else if (type == DPLL_A_LOCK_STATUS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.lock_status = 1; + dst->lock_status = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_LOCK_STATUS_ERROR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.lock_status_error = 1; + dst->lock_status_error = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_TEMP) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.temp = 1; + dst->temp = ynl_attr_get_s32(attr); + } else if (type == DPLL_A_CLOCK_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.clock_id = 1; + dst->clock_id = ynl_attr_get_u64(attr); + } else if (type == DPLL_A_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.type = 1; + dst->type = ynl_attr_get_u32(attr); + } + } + + if (n_mode_supported) { + dst->mode_supported = calloc(n_mode_supported, sizeof(*dst->mode_supported)); + dst->n_mode_supported = n_mode_supported; + i = 0; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == DPLL_A_MODE_SUPPORTED) { + dst->mode_supported[i] = ynl_attr_get_u32(attr); + i++; + } + } + } + + return YNL_PARSE_CB_OK; +} + +struct dpll_device_get_rsp * +dpll_device_get(struct ynl_sock *ys, struct dpll_device_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct dpll_device_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DPLL_CMD_DEVICE_GET, 1); + ys->req_policy = &dpll_nest; + yrs.yarg.rsp_policy = &dpll_nest; + + if (req->_present.id) + ynl_attr_put_u32(nlh, DPLL_A_ID, req->id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = dpll_device_get_rsp_parse; + yrs.rsp_cmd = DPLL_CMD_DEVICE_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + dpll_device_get_rsp_free(rsp); + return NULL; +} + +/* DPLL_CMD_DEVICE_GET - dump */ +void dpll_device_get_list_free(struct dpll_device_get_list *rsp) +{ + struct dpll_device_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.module_name); + free(rsp->obj.mode_supported); + free(rsp); + } +} + +struct dpll_device_get_list *dpll_device_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &dpll_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct dpll_device_get_list); + yds.cb = dpll_device_get_rsp_parse; + yds.rsp_cmd = DPLL_CMD_DEVICE_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DPLL_CMD_DEVICE_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + dpll_device_get_list_free(yds.first); + return NULL; +} + +/* DPLL_CMD_DEVICE_GET - notify */ +void dpll_device_get_ntf_free(struct dpll_device_get_ntf *rsp) +{ + free(rsp->obj.module_name); + free(rsp->obj.mode_supported); + free(rsp); +} + +/* ============== DPLL_CMD_DEVICE_SET ============== */ +/* DPLL_CMD_DEVICE_SET - do */ +void dpll_device_set_req_free(struct dpll_device_set_req *req) +{ + free(req); +} + +int dpll_device_set(struct ynl_sock *ys, struct dpll_device_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DPLL_CMD_DEVICE_SET, 1); + ys->req_policy = &dpll_nest; + + if (req->_present.id) + ynl_attr_put_u32(nlh, DPLL_A_ID, req->id); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== DPLL_CMD_PIN_ID_GET ============== */ +/* DPLL_CMD_PIN_ID_GET - do */ +void dpll_pin_id_get_req_free(struct dpll_pin_id_get_req *req) +{ + free(req->module_name); + free(req->board_label); + free(req->panel_label); + free(req->package_label); + free(req); +} + +void dpll_pin_id_get_rsp_free(struct dpll_pin_id_get_rsp *rsp) +{ + free(rsp); +} + +int dpll_pin_id_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct dpll_pin_id_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DPLL_A_PIN_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct dpll_pin_id_get_rsp * +dpll_pin_id_get(struct ynl_sock *ys, struct dpll_pin_id_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct dpll_pin_id_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DPLL_CMD_PIN_ID_GET, 1); + ys->req_policy = &dpll_pin_nest; + yrs.yarg.rsp_policy = &dpll_pin_nest; + + if (req->_present.module_name_len) + ynl_attr_put_str(nlh, DPLL_A_PIN_MODULE_NAME, req->module_name); + if (req->_present.clock_id) + ynl_attr_put_u64(nlh, DPLL_A_PIN_CLOCK_ID, req->clock_id); + if (req->_present.board_label_len) + ynl_attr_put_str(nlh, DPLL_A_PIN_BOARD_LABEL, req->board_label); + if (req->_present.panel_label_len) + ynl_attr_put_str(nlh, DPLL_A_PIN_PANEL_LABEL, req->panel_label); + if (req->_present.package_label_len) + ynl_attr_put_str(nlh, DPLL_A_PIN_PACKAGE_LABEL, req->package_label); + if (req->_present.type) + ynl_attr_put_u32(nlh, DPLL_A_PIN_TYPE, req->type); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = dpll_pin_id_get_rsp_parse; + yrs.rsp_cmd = DPLL_CMD_PIN_ID_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + dpll_pin_id_get_rsp_free(rsp); + return NULL; +} + +/* ============== DPLL_CMD_PIN_GET ============== */ +/* DPLL_CMD_PIN_GET - do */ +void dpll_pin_get_req_free(struct dpll_pin_get_req *req) +{ + free(req); +} + +void dpll_pin_get_rsp_free(struct dpll_pin_get_rsp *rsp) +{ + unsigned int i; + + free(rsp->board_label); + free(rsp->panel_label); + free(rsp->package_label); + for (i = 0; i < rsp->n_frequency_supported; i++) + dpll_frequency_range_free(&rsp->frequency_supported[i]); + free(rsp->frequency_supported); + for (i = 0; i < rsp->n_parent_device; i++) + dpll_pin_parent_device_free(&rsp->parent_device[i]); + free(rsp->parent_device); + for (i = 0; i < rsp->n_parent_pin; i++) + dpll_pin_parent_pin_free(&rsp->parent_pin[i]); + free(rsp->parent_pin); + free(rsp); +} + +int dpll_pin_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + unsigned int n_frequency_supported = 0; + unsigned int n_parent_device = 0; + unsigned int n_parent_pin = 0; + struct dpll_pin_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + dst = yarg->data; + parg.ys = yarg->ys; + + if (dst->frequency_supported) + return ynl_error_parse(yarg, "attribute already present (pin.frequency-supported)"); + if (dst->parent_device) + return ynl_error_parse(yarg, "attribute already present (pin.parent-device)"); + if (dst->parent_pin) + return ynl_error_parse(yarg, "attribute already present (pin.parent-pin)"); + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == DPLL_A_PIN_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_PIN_BOARD_LABEL) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.board_label_len = len; + dst->board_label = malloc(len + 1); + memcpy(dst->board_label, ynl_attr_get_str(attr), len); + dst->board_label[len] = 0; + } else if (type == DPLL_A_PIN_PANEL_LABEL) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.panel_label_len = len; + dst->panel_label = malloc(len + 1); + memcpy(dst->panel_label, ynl_attr_get_str(attr), len); + dst->panel_label[len] = 0; + } else if (type == DPLL_A_PIN_PACKAGE_LABEL) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.package_label_len = len; + dst->package_label = malloc(len + 1); + memcpy(dst->package_label, ynl_attr_get_str(attr), len); + dst->package_label[len] = 0; + } else if (type == DPLL_A_PIN_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.type = 1; + dst->type = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_PIN_FREQUENCY) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.frequency = 1; + dst->frequency = ynl_attr_get_u64(attr); + } else if (type == DPLL_A_PIN_FREQUENCY_SUPPORTED) { + n_frequency_supported++; + } else if (type == DPLL_A_PIN_CAPABILITIES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.capabilities = 1; + dst->capabilities = ynl_attr_get_u32(attr); + } else if (type == DPLL_A_PIN_PARENT_DEVICE) { + n_parent_device++; + } else if (type == DPLL_A_PIN_PARENT_PIN) { + n_parent_pin++; + } else if (type == DPLL_A_PIN_PHASE_ADJUST_MIN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.phase_adjust_min = 1; + dst->phase_adjust_min = ynl_attr_get_s32(attr); + } else if (type == DPLL_A_PIN_PHASE_ADJUST_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.phase_adjust_max = 1; + dst->phase_adjust_max = ynl_attr_get_s32(attr); + } else if (type == DPLL_A_PIN_PHASE_ADJUST) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.phase_adjust = 1; + dst->phase_adjust = ynl_attr_get_s32(attr); + } else if (type == DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.fractional_frequency_offset = 1; + dst->fractional_frequency_offset = ynl_attr_get_sint(attr); + } + } + + if (n_frequency_supported) { + dst->frequency_supported = calloc(n_frequency_supported, sizeof(*dst->frequency_supported)); + dst->n_frequency_supported = n_frequency_supported; + i = 0; + parg.rsp_policy = &dpll_frequency_range_nest; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == DPLL_A_PIN_FREQUENCY_SUPPORTED) { + parg.data = &dst->frequency_supported[i]; + if (dpll_frequency_range_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + if (n_parent_device) { + dst->parent_device = calloc(n_parent_device, sizeof(*dst->parent_device)); + dst->n_parent_device = n_parent_device; + i = 0; + parg.rsp_policy = &dpll_pin_parent_device_nest; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == DPLL_A_PIN_PARENT_DEVICE) { + parg.data = &dst->parent_device[i]; + if (dpll_pin_parent_device_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + if (n_parent_pin) { + dst->parent_pin = calloc(n_parent_pin, sizeof(*dst->parent_pin)); + dst->n_parent_pin = n_parent_pin; + i = 0; + parg.rsp_policy = &dpll_pin_parent_pin_nest; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == DPLL_A_PIN_PARENT_PIN) { + parg.data = &dst->parent_pin[i]; + if (dpll_pin_parent_pin_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return YNL_PARSE_CB_OK; +} + +struct dpll_pin_get_rsp * +dpll_pin_get(struct ynl_sock *ys, struct dpll_pin_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct dpll_pin_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DPLL_CMD_PIN_GET, 1); + ys->req_policy = &dpll_pin_nest; + yrs.yarg.rsp_policy = &dpll_pin_nest; + + if (req->_present.id) + ynl_attr_put_u32(nlh, DPLL_A_PIN_ID, req->id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = dpll_pin_get_rsp_parse; + yrs.rsp_cmd = DPLL_CMD_PIN_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + dpll_pin_get_rsp_free(rsp); + return NULL; +} + +/* DPLL_CMD_PIN_GET - dump */ +void dpll_pin_get_req_dump_free(struct dpll_pin_get_req_dump *req) +{ + free(req); +} + +void dpll_pin_get_list_free(struct dpll_pin_get_list *rsp) +{ + struct dpll_pin_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + unsigned int i; + + rsp = next; + next = rsp->next; + + free(rsp->obj.board_label); + free(rsp->obj.panel_label); + free(rsp->obj.package_label); + for (i = 0; i < rsp->obj.n_frequency_supported; i++) + dpll_frequency_range_free(&rsp->obj.frequency_supported[i]); + free(rsp->obj.frequency_supported); + for (i = 0; i < rsp->obj.n_parent_device; i++) + dpll_pin_parent_device_free(&rsp->obj.parent_device[i]); + free(rsp->obj.parent_device); + for (i = 0; i < rsp->obj.n_parent_pin; i++) + dpll_pin_parent_pin_free(&rsp->obj.parent_pin[i]); + free(rsp->obj.parent_pin); + free(rsp); + } +} + +struct dpll_pin_get_list * +dpll_pin_get_dump(struct ynl_sock *ys, struct dpll_pin_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &dpll_pin_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct dpll_pin_get_list); + yds.cb = dpll_pin_get_rsp_parse; + yds.rsp_cmd = DPLL_CMD_PIN_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, DPLL_CMD_PIN_GET, 1); + ys->req_policy = &dpll_pin_nest; + + if (req->_present.id) + ynl_attr_put_u32(nlh, DPLL_A_PIN_ID, req->id); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + dpll_pin_get_list_free(yds.first); + return NULL; +} + +/* DPLL_CMD_PIN_GET - notify */ +void dpll_pin_get_ntf_free(struct dpll_pin_get_ntf *rsp) +{ + unsigned int i; + + free(rsp->obj.board_label); + free(rsp->obj.panel_label); + free(rsp->obj.package_label); + for (i = 0; i < rsp->obj.n_frequency_supported; i++) + dpll_frequency_range_free(&rsp->obj.frequency_supported[i]); + free(rsp->obj.frequency_supported); + for (i = 0; i < rsp->obj.n_parent_device; i++) + dpll_pin_parent_device_free(&rsp->obj.parent_device[i]); + free(rsp->obj.parent_device); + for (i = 0; i < rsp->obj.n_parent_pin; i++) + dpll_pin_parent_pin_free(&rsp->obj.parent_pin[i]); + free(rsp->obj.parent_pin); + free(rsp); +} + +/* ============== DPLL_CMD_PIN_SET ============== */ +/* DPLL_CMD_PIN_SET - do */ +void dpll_pin_set_req_free(struct dpll_pin_set_req *req) +{ + unsigned int i; + + for (i = 0; i < req->n_parent_device; i++) + dpll_pin_parent_device_free(&req->parent_device[i]); + free(req->parent_device); + for (i = 0; i < req->n_parent_pin; i++) + dpll_pin_parent_pin_free(&req->parent_pin[i]); + free(req->parent_pin); + free(req); +} + +int dpll_pin_set(struct ynl_sock *ys, struct dpll_pin_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, DPLL_CMD_PIN_SET, 1); + ys->req_policy = &dpll_pin_nest; + + if (req->_present.id) + ynl_attr_put_u32(nlh, DPLL_A_PIN_ID, req->id); + if (req->_present.frequency) + ynl_attr_put_u64(nlh, DPLL_A_PIN_FREQUENCY, req->frequency); + if (req->_present.direction) + ynl_attr_put_u32(nlh, DPLL_A_PIN_DIRECTION, req->direction); + if (req->_present.prio) + ynl_attr_put_u32(nlh, DPLL_A_PIN_PRIO, req->prio); + if (req->_present.state) + ynl_attr_put_u32(nlh, DPLL_A_PIN_STATE, req->state); + for (unsigned int i = 0; i < req->n_parent_device; i++) + dpll_pin_parent_device_put(nlh, DPLL_A_PIN_PARENT_DEVICE, &req->parent_device[i]); + for (unsigned int i = 0; i < req->n_parent_pin; i++) + dpll_pin_parent_pin_put(nlh, DPLL_A_PIN_PARENT_PIN, &req->parent_pin[i]); + if (req->_present.phase_adjust) + ynl_attr_put_s32(nlh, DPLL_A_PIN_PHASE_ADJUST, req->phase_adjust); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +static const struct ynl_ntf_info dpll_ntf_info[] = { + [DPLL_CMD_DEVICE_CREATE_NTF] = { + .alloc_sz = sizeof(struct dpll_device_get_ntf), + .cb = dpll_device_get_rsp_parse, + .policy = &dpll_nest, + .free = (void *)dpll_device_get_ntf_free, + }, + [DPLL_CMD_DEVICE_DELETE_NTF] = { + .alloc_sz = sizeof(struct dpll_device_get_ntf), + .cb = dpll_device_get_rsp_parse, + .policy = &dpll_nest, + .free = (void *)dpll_device_get_ntf_free, + }, + [DPLL_CMD_DEVICE_CHANGE_NTF] = { + .alloc_sz = sizeof(struct dpll_device_get_ntf), + .cb = dpll_device_get_rsp_parse, + .policy = &dpll_nest, + .free = (void *)dpll_device_get_ntf_free, + }, + [DPLL_CMD_PIN_CREATE_NTF] = { + .alloc_sz = sizeof(struct dpll_pin_get_ntf), + .cb = dpll_pin_get_rsp_parse, + .policy = &dpll_pin_nest, + .free = (void *)dpll_pin_get_ntf_free, + }, + [DPLL_CMD_PIN_DELETE_NTF] = { + .alloc_sz = sizeof(struct dpll_pin_get_ntf), + .cb = dpll_pin_get_rsp_parse, + .policy = &dpll_pin_nest, + .free = (void *)dpll_pin_get_ntf_free, + }, + [DPLL_CMD_PIN_CHANGE_NTF] = { + .alloc_sz = sizeof(struct dpll_pin_get_ntf), + .cb = dpll_pin_get_rsp_parse, + .policy = &dpll_pin_nest, + .free = (void *)dpll_pin_get_ntf_free, + }, +}; + +const struct ynl_family ynl_dpll_family = { + .name = "dpll", + .hdr_len = sizeof(struct genlmsghdr), + .ntf_info = dpll_ntf_info, + .ntf_info_size = YNL_ARRAY_SIZE(dpll_ntf_info), +}; diff --git a/generated/dpll-user.h b/generated/dpll-user.h new file mode 100644 index 0000000..9055d42 --- /dev/null +++ b/generated/dpll-user.h @@ -0,0 +1,538 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/dpll.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_DPLL_GEN_H +#define _LINUX_DPLL_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_dpll_family; + +/* Enums */ +const char *dpll_op_str(int op); +const char *dpll_mode_str(enum dpll_mode value); +const char *dpll_lock_status_str(enum dpll_lock_status value); +const char *dpll_lock_status_error_str(enum dpll_lock_status_error value); +const char *dpll_type_str(enum dpll_type value); +const char *dpll_pin_type_str(enum dpll_pin_type value); +const char *dpll_pin_direction_str(enum dpll_pin_direction value); +const char *dpll_pin_state_str(enum dpll_pin_state value); +const char *dpll_pin_capabilities_str(enum dpll_pin_capabilities value); + +/* Common nested types */ +struct dpll_frequency_range { + struct { + __u32 frequency_min:1; + __u32 frequency_max:1; + } _present; + + __u64 frequency_min; + __u64 frequency_max; +}; + +struct dpll_pin_parent_device { + struct { + __u32 parent_id:1; + __u32 direction:1; + __u32 prio:1; + __u32 state:1; + __u32 phase_offset:1; + } _present; + + __u32 parent_id; + enum dpll_pin_direction direction; + __u32 prio; + enum dpll_pin_state state; + __s64 phase_offset; +}; + +struct dpll_pin_parent_pin { + struct { + __u32 parent_id:1; + __u32 state:1; + } _present; + + __u32 parent_id; + enum dpll_pin_state state; +}; + +/* ============== DPLL_CMD_DEVICE_ID_GET ============== */ +/* DPLL_CMD_DEVICE_ID_GET - do */ +struct dpll_device_id_get_req { + struct { + __u32 module_name_len; + __u32 clock_id:1; + __u32 type:1; + } _present; + + char *module_name; + __u64 clock_id; + enum dpll_type type; +}; + +static inline struct dpll_device_id_get_req *dpll_device_id_get_req_alloc(void) +{ + return calloc(1, sizeof(struct dpll_device_id_get_req)); +} +void dpll_device_id_get_req_free(struct dpll_device_id_get_req *req); + +static inline void +dpll_device_id_get_req_set_module_name(struct dpll_device_id_get_req *req, + const char *module_name) +{ + free(req->module_name); + req->_present.module_name_len = strlen(module_name); + req->module_name = malloc(req->_present.module_name_len + 1); + memcpy(req->module_name, module_name, req->_present.module_name_len); + req->module_name[req->_present.module_name_len] = 0; +} +static inline void +dpll_device_id_get_req_set_clock_id(struct dpll_device_id_get_req *req, + __u64 clock_id) +{ + req->_present.clock_id = 1; + req->clock_id = clock_id; +} +static inline void +dpll_device_id_get_req_set_type(struct dpll_device_id_get_req *req, + enum dpll_type type) +{ + req->_present.type = 1; + req->type = type; +} + +struct dpll_device_id_get_rsp { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +void dpll_device_id_get_rsp_free(struct dpll_device_id_get_rsp *rsp); + +/* + * Get id of dpll device that matches given attributes + + */ +struct dpll_device_id_get_rsp * +dpll_device_id_get(struct ynl_sock *ys, struct dpll_device_id_get_req *req); + +/* ============== DPLL_CMD_DEVICE_GET ============== */ +/* DPLL_CMD_DEVICE_GET - do */ +struct dpll_device_get_req { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +static inline struct dpll_device_get_req *dpll_device_get_req_alloc(void) +{ + return calloc(1, sizeof(struct dpll_device_get_req)); +} +void dpll_device_get_req_free(struct dpll_device_get_req *req); + +static inline void +dpll_device_get_req_set_id(struct dpll_device_get_req *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} + +struct dpll_device_get_rsp { + struct { + __u32 id:1; + __u32 module_name_len; + __u32 mode:1; + __u32 lock_status:1; + __u32 lock_status_error:1; + __u32 temp:1; + __u32 clock_id:1; + __u32 type:1; + } _present; + + __u32 id; + char *module_name; + enum dpll_mode mode; + unsigned int n_mode_supported; + __u32 *mode_supported; + enum dpll_lock_status lock_status; + enum dpll_lock_status_error lock_status_error; + __s32 temp; + __u64 clock_id; + enum dpll_type type; +}; + +void dpll_device_get_rsp_free(struct dpll_device_get_rsp *rsp); + +/* + * Get list of DPLL devices (dump) or attributes of a single dpll device + + */ +struct dpll_device_get_rsp * +dpll_device_get(struct ynl_sock *ys, struct dpll_device_get_req *req); + +/* DPLL_CMD_DEVICE_GET - dump */ +struct dpll_device_get_list { + struct dpll_device_get_list *next; + struct dpll_device_get_rsp obj __attribute__((aligned(8))); +}; + +void dpll_device_get_list_free(struct dpll_device_get_list *rsp); + +struct dpll_device_get_list *dpll_device_get_dump(struct ynl_sock *ys); + +/* DPLL_CMD_DEVICE_GET - notify */ +struct dpll_device_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct dpll_device_get_ntf *ntf); + struct dpll_device_get_rsp obj __attribute__((aligned(8))); +}; + +void dpll_device_get_ntf_free(struct dpll_device_get_ntf *rsp); + +/* ============== DPLL_CMD_DEVICE_SET ============== */ +/* DPLL_CMD_DEVICE_SET - do */ +struct dpll_device_set_req { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +static inline struct dpll_device_set_req *dpll_device_set_req_alloc(void) +{ + return calloc(1, sizeof(struct dpll_device_set_req)); +} +void dpll_device_set_req_free(struct dpll_device_set_req *req); + +static inline void +dpll_device_set_req_set_id(struct dpll_device_set_req *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} + +/* + * Set attributes for a DPLL device + */ +int dpll_device_set(struct ynl_sock *ys, struct dpll_device_set_req *req); + +/* ============== DPLL_CMD_PIN_ID_GET ============== */ +/* DPLL_CMD_PIN_ID_GET - do */ +struct dpll_pin_id_get_req { + struct { + __u32 module_name_len; + __u32 clock_id:1; + __u32 board_label_len; + __u32 panel_label_len; + __u32 package_label_len; + __u32 type:1; + } _present; + + char *module_name; + __u64 clock_id; + char *board_label; + char *panel_label; + char *package_label; + enum dpll_pin_type type; +}; + +static inline struct dpll_pin_id_get_req *dpll_pin_id_get_req_alloc(void) +{ + return calloc(1, sizeof(struct dpll_pin_id_get_req)); +} +void dpll_pin_id_get_req_free(struct dpll_pin_id_get_req *req); + +static inline void +dpll_pin_id_get_req_set_module_name(struct dpll_pin_id_get_req *req, + const char *module_name) +{ + free(req->module_name); + req->_present.module_name_len = strlen(module_name); + req->module_name = malloc(req->_present.module_name_len + 1); + memcpy(req->module_name, module_name, req->_present.module_name_len); + req->module_name[req->_present.module_name_len] = 0; +} +static inline void +dpll_pin_id_get_req_set_clock_id(struct dpll_pin_id_get_req *req, + __u64 clock_id) +{ + req->_present.clock_id = 1; + req->clock_id = clock_id; +} +static inline void +dpll_pin_id_get_req_set_board_label(struct dpll_pin_id_get_req *req, + const char *board_label) +{ + free(req->board_label); + req->_present.board_label_len = strlen(board_label); + req->board_label = malloc(req->_present.board_label_len + 1); + memcpy(req->board_label, board_label, req->_present.board_label_len); + req->board_label[req->_present.board_label_len] = 0; +} +static inline void +dpll_pin_id_get_req_set_panel_label(struct dpll_pin_id_get_req *req, + const char *panel_label) +{ + free(req->panel_label); + req->_present.panel_label_len = strlen(panel_label); + req->panel_label = malloc(req->_present.panel_label_len + 1); + memcpy(req->panel_label, panel_label, req->_present.panel_label_len); + req->panel_label[req->_present.panel_label_len] = 0; +} +static inline void +dpll_pin_id_get_req_set_package_label(struct dpll_pin_id_get_req *req, + const char *package_label) +{ + free(req->package_label); + req->_present.package_label_len = strlen(package_label); + req->package_label = malloc(req->_present.package_label_len + 1); + memcpy(req->package_label, package_label, req->_present.package_label_len); + req->package_label[req->_present.package_label_len] = 0; +} +static inline void +dpll_pin_id_get_req_set_type(struct dpll_pin_id_get_req *req, + enum dpll_pin_type type) +{ + req->_present.type = 1; + req->type = type; +} + +struct dpll_pin_id_get_rsp { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +void dpll_pin_id_get_rsp_free(struct dpll_pin_id_get_rsp *rsp); + +/* + * Get id of a pin that matches given attributes + + */ +struct dpll_pin_id_get_rsp * +dpll_pin_id_get(struct ynl_sock *ys, struct dpll_pin_id_get_req *req); + +/* ============== DPLL_CMD_PIN_GET ============== */ +/* DPLL_CMD_PIN_GET - do */ +struct dpll_pin_get_req { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +static inline struct dpll_pin_get_req *dpll_pin_get_req_alloc(void) +{ + return calloc(1, sizeof(struct dpll_pin_get_req)); +} +void dpll_pin_get_req_free(struct dpll_pin_get_req *req); + +static inline void +dpll_pin_get_req_set_id(struct dpll_pin_get_req *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} + +struct dpll_pin_get_rsp { + struct { + __u32 id:1; + __u32 board_label_len; + __u32 panel_label_len; + __u32 package_label_len; + __u32 type:1; + __u32 frequency:1; + __u32 capabilities:1; + __u32 phase_adjust_min:1; + __u32 phase_adjust_max:1; + __u32 phase_adjust:1; + __u32 fractional_frequency_offset:1; + } _present; + + __u32 id; + char *board_label; + char *panel_label; + char *package_label; + enum dpll_pin_type type; + __u64 frequency; + unsigned int n_frequency_supported; + struct dpll_frequency_range *frequency_supported; + __u32 capabilities; + unsigned int n_parent_device; + struct dpll_pin_parent_device *parent_device; + unsigned int n_parent_pin; + struct dpll_pin_parent_pin *parent_pin; + __s32 phase_adjust_min; + __s32 phase_adjust_max; + __s32 phase_adjust; + __s64 fractional_frequency_offset; +}; + +void dpll_pin_get_rsp_free(struct dpll_pin_get_rsp *rsp); + +/* + * Get list of pins and its attributes. +- dump request without any attributes given - list all the pins in the + system +- dump request with target dpll - list all the pins registered with + a given dpll device +- do request with target dpll and target pin - single pin attributes + + */ +struct dpll_pin_get_rsp * +dpll_pin_get(struct ynl_sock *ys, struct dpll_pin_get_req *req); + +/* DPLL_CMD_PIN_GET - dump */ +struct dpll_pin_get_req_dump { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +static inline struct dpll_pin_get_req_dump *dpll_pin_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct dpll_pin_get_req_dump)); +} +void dpll_pin_get_req_dump_free(struct dpll_pin_get_req_dump *req); + +static inline void +dpll_pin_get_req_dump_set_id(struct dpll_pin_get_req_dump *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} + +struct dpll_pin_get_list { + struct dpll_pin_get_list *next; + struct dpll_pin_get_rsp obj __attribute__((aligned(8))); +}; + +void dpll_pin_get_list_free(struct dpll_pin_get_list *rsp); + +struct dpll_pin_get_list * +dpll_pin_get_dump(struct ynl_sock *ys, struct dpll_pin_get_req_dump *req); + +/* DPLL_CMD_PIN_GET - notify */ +struct dpll_pin_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct dpll_pin_get_ntf *ntf); + struct dpll_pin_get_rsp obj __attribute__((aligned(8))); +}; + +void dpll_pin_get_ntf_free(struct dpll_pin_get_ntf *rsp); + +/* ============== DPLL_CMD_PIN_SET ============== */ +/* DPLL_CMD_PIN_SET - do */ +struct dpll_pin_set_req { + struct { + __u32 id:1; + __u32 frequency:1; + __u32 direction:1; + __u32 prio:1; + __u32 state:1; + __u32 phase_adjust:1; + } _present; + + __u32 id; + __u64 frequency; + enum dpll_pin_direction direction; + __u32 prio; + enum dpll_pin_state state; + unsigned int n_parent_device; + struct dpll_pin_parent_device *parent_device; + unsigned int n_parent_pin; + struct dpll_pin_parent_pin *parent_pin; + __s32 phase_adjust; +}; + +static inline struct dpll_pin_set_req *dpll_pin_set_req_alloc(void) +{ + return calloc(1, sizeof(struct dpll_pin_set_req)); +} +void dpll_pin_set_req_free(struct dpll_pin_set_req *req); + +static inline void +dpll_pin_set_req_set_id(struct dpll_pin_set_req *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} +static inline void +dpll_pin_set_req_set_frequency(struct dpll_pin_set_req *req, __u64 frequency) +{ + req->_present.frequency = 1; + req->frequency = frequency; +} +static inline void +dpll_pin_set_req_set_direction(struct dpll_pin_set_req *req, + enum dpll_pin_direction direction) +{ + req->_present.direction = 1; + req->direction = direction; +} +static inline void +dpll_pin_set_req_set_prio(struct dpll_pin_set_req *req, __u32 prio) +{ + req->_present.prio = 1; + req->prio = prio; +} +static inline void +dpll_pin_set_req_set_state(struct dpll_pin_set_req *req, + enum dpll_pin_state state) +{ + req->_present.state = 1; + req->state = state; +} +static inline void +__dpll_pin_set_req_set_parent_device(struct dpll_pin_set_req *req, + struct dpll_pin_parent_device *parent_device, + unsigned int n_parent_device) +{ + free(req->parent_device); + req->parent_device = parent_device; + req->n_parent_device = n_parent_device; +} +static inline void +__dpll_pin_set_req_set_parent_pin(struct dpll_pin_set_req *req, + struct dpll_pin_parent_pin *parent_pin, + unsigned int n_parent_pin) +{ + free(req->parent_pin); + req->parent_pin = parent_pin; + req->n_parent_pin = n_parent_pin; +} +static inline void +dpll_pin_set_req_set_phase_adjust(struct dpll_pin_set_req *req, + __s32 phase_adjust) +{ + req->_present.phase_adjust = 1; + req->phase_adjust = phase_adjust; +} + +/* + * Set attributes of a target pin + */ +int dpll_pin_set(struct ynl_sock *ys, struct dpll_pin_set_req *req); + +#endif /* _LINUX_DPLL_GEN_H */ diff --git a/generated/ethtool-user.c b/generated/ethtool-user.c new file mode 100644 index 0000000..5b480a5 --- /dev/null +++ b/generated/ethtool-user.c @@ -0,0 +1,6556 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/ethtool.yaml */ +/* YNL-GEN user source */ +/* YNL-ARG --user-header linux/ethtool_netlink.h --exclude-op stats-get */ + +#include +#include +#include "ethtool-user.h" +#include "ynl.h" +#include + +#include + +#include "linux/ethtool_netlink.h" + +/* Enums */ +static const char * const ethtool_op_strmap[] = { + [ETHTOOL_MSG_STRSET_GET] = "strset-get", + [ETHTOOL_MSG_LINKINFO_GET] = "linkinfo-get", + [3] = "linkinfo-ntf", + [ETHTOOL_MSG_LINKMODES_GET] = "linkmodes-get", + [5] = "linkmodes-ntf", + [ETHTOOL_MSG_LINKSTATE_GET] = "linkstate-get", + [ETHTOOL_MSG_DEBUG_GET] = "debug-get", + [8] = "debug-ntf", + [ETHTOOL_MSG_WOL_GET] = "wol-get", + [10] = "wol-ntf", + [ETHTOOL_MSG_FEATURES_GET] = "features-get", + [ETHTOOL_MSG_FEATURES_SET] = "features-set", + [13] = "features-ntf", + [14] = "privflags-get", + [15] = "privflags-ntf", + [16] = "rings-get", + [17] = "rings-ntf", + [18] = "channels-get", + [19] = "channels-ntf", + [20] = "coalesce-get", + [21] = "coalesce-ntf", + [22] = "pause-get", + [23] = "pause-ntf", + [24] = "eee-get", + [25] = "eee-ntf", + [26] = "tsinfo-get", + [27] = "cable-test-ntf", + [28] = "cable-test-tdr-ntf", + [29] = "tunnel-info-get", + [30] = "fec-get", + [31] = "fec-ntf", + [32] = "module-eeprom-get", + [34] = "phc-vclocks-get", + [35] = "module-get", + [36] = "module-ntf", + [37] = "pse-get", + [ETHTOOL_MSG_RSS_GET] = "rss-get", + [ETHTOOL_MSG_PLCA_GET_CFG] = "plca-get-cfg", + [40] = "plca-get-status", + [41] = "plca-ntf", + [ETHTOOL_MSG_MM_GET] = "mm-get", + [43] = "mm-ntf", +}; + +const char *ethtool_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(ethtool_op_strmap)) + return NULL; + return ethtool_op_strmap[op]; +} + +static const char * const ethtool_udp_tunnel_type_strmap[] = { + [0] = "vxlan", + [1] = "geneve", + [2] = "vxlan-gpe", +}; + +const char *ethtool_udp_tunnel_type_str(int value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(ethtool_udp_tunnel_type_strmap)) + return NULL; + return ethtool_udp_tunnel_type_strmap[value]; +} + +static const char * const ethtool_stringset_strmap[] = { +}; + +const char *ethtool_stringset_str(enum ethtool_stringset value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(ethtool_stringset_strmap)) + return NULL; + return ethtool_stringset_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr ethtool_header_policy[ETHTOOL_A_HEADER_MAX + 1] = { + [ETHTOOL_A_HEADER_DEV_INDEX] = { .name = "dev-index", .type = YNL_PT_U32, }, + [ETHTOOL_A_HEADER_DEV_NAME] = { .name = "dev-name", .type = YNL_PT_NUL_STR, }, + [ETHTOOL_A_HEADER_FLAGS] = { .name = "flags", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_header_nest = { + .max_attr = ETHTOOL_A_HEADER_MAX, + .table = ethtool_header_policy, +}; + +struct ynl_policy_attr ethtool_pause_stat_policy[ETHTOOL_A_PAUSE_STAT_MAX + 1] = { + [ETHTOOL_A_PAUSE_STAT_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [ETHTOOL_A_PAUSE_STAT_TX_FRAMES] = { .name = "tx-frames", .type = YNL_PT_U64, }, + [ETHTOOL_A_PAUSE_STAT_RX_FRAMES] = { .name = "rx-frames", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest ethtool_pause_stat_nest = { + .max_attr = ETHTOOL_A_PAUSE_STAT_MAX, + .table = ethtool_pause_stat_policy, +}; + +struct ynl_policy_attr ethtool_cable_test_tdr_cfg_policy[ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX + 1] = { + [ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST] = { .name = "first", .type = YNL_PT_U32, }, + [ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST] = { .name = "last", .type = YNL_PT_U32, }, + [ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP] = { .name = "step", .type = YNL_PT_U32, }, + [ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR] = { .name = "pair", .type = YNL_PT_U8, }, +}; + +struct ynl_policy_nest ethtool_cable_test_tdr_cfg_nest = { + .max_attr = ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX, + .table = ethtool_cable_test_tdr_cfg_policy, +}; + +struct ynl_policy_attr ethtool_fec_stat_policy[ETHTOOL_A_FEC_STAT_MAX + 1] = { + [ETHTOOL_A_FEC_STAT_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [ETHTOOL_A_FEC_STAT_CORRECTED] = { .name = "corrected", .type = YNL_PT_BINARY,}, + [ETHTOOL_A_FEC_STAT_UNCORR] = { .name = "uncorr", .type = YNL_PT_BINARY,}, + [ETHTOOL_A_FEC_STAT_CORR_BITS] = { .name = "corr-bits", .type = YNL_PT_BINARY,}, +}; + +struct ynl_policy_nest ethtool_fec_stat_nest = { + .max_attr = ETHTOOL_A_FEC_STAT_MAX, + .table = ethtool_fec_stat_policy, +}; + +struct ynl_policy_attr ethtool_mm_stat_policy[ETHTOOL_A_MM_STAT_MAX + 1] = { + [ETHTOOL_A_MM_STAT_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS] = { .name = "reassembly-errors", .type = YNL_PT_U64, }, + [ETHTOOL_A_MM_STAT_SMD_ERRORS] = { .name = "smd-errors", .type = YNL_PT_U64, }, + [ETHTOOL_A_MM_STAT_REASSEMBLY_OK] = { .name = "reassembly-ok", .type = YNL_PT_U64, }, + [ETHTOOL_A_MM_STAT_RX_FRAG_COUNT] = { .name = "rx-frag-count", .type = YNL_PT_U64, }, + [ETHTOOL_A_MM_STAT_TX_FRAG_COUNT] = { .name = "tx-frag-count", .type = YNL_PT_U64, }, + [ETHTOOL_A_MM_STAT_HOLD_COUNT] = { .name = "hold-count", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest ethtool_mm_stat_nest = { + .max_attr = ETHTOOL_A_MM_STAT_MAX, + .table = ethtool_mm_stat_policy, +}; + +struct ynl_policy_attr ethtool_cable_result_policy[ETHTOOL_A_CABLE_RESULT_MAX + 1] = { + [ETHTOOL_A_CABLE_RESULT_PAIR] = { .name = "pair", .type = YNL_PT_U8, }, + [ETHTOOL_A_CABLE_RESULT_CODE] = { .name = "code", .type = YNL_PT_U8, }, +}; + +struct ynl_policy_nest ethtool_cable_result_nest = { + .max_attr = ETHTOOL_A_CABLE_RESULT_MAX, + .table = ethtool_cable_result_policy, +}; + +struct ynl_policy_attr ethtool_cable_fault_length_policy[ETHTOOL_A_CABLE_FAULT_LENGTH_MAX + 1] = { + [ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR] = { .name = "pair", .type = YNL_PT_U8, }, + [ETHTOOL_A_CABLE_FAULT_LENGTH_CM] = { .name = "cm", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_cable_fault_length_nest = { + .max_attr = ETHTOOL_A_CABLE_FAULT_LENGTH_MAX, + .table = ethtool_cable_fault_length_policy, +}; + +struct ynl_policy_attr ethtool_bitset_bit_policy[ETHTOOL_A_BITSET_BIT_MAX + 1] = { + [ETHTOOL_A_BITSET_BIT_INDEX] = { .name = "index", .type = YNL_PT_U32, }, + [ETHTOOL_A_BITSET_BIT_NAME] = { .name = "name", .type = YNL_PT_NUL_STR, }, + [ETHTOOL_A_BITSET_BIT_VALUE] = { .name = "value", .type = YNL_PT_FLAG, }, +}; + +struct ynl_policy_nest ethtool_bitset_bit_nest = { + .max_attr = ETHTOOL_A_BITSET_BIT_MAX, + .table = ethtool_bitset_bit_policy, +}; + +struct ynl_policy_attr ethtool_tunnel_udp_entry_policy[ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX + 1] = { + [ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT] = { .name = "port", .type = YNL_PT_U16, }, + [ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE] = { .name = "type", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_tunnel_udp_entry_nest = { + .max_attr = ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX, + .table = ethtool_tunnel_udp_entry_policy, +}; + +struct ynl_policy_attr ethtool_string_policy[ETHTOOL_A_STRING_MAX + 1] = { + [ETHTOOL_A_STRING_INDEX] = { .name = "index", .type = YNL_PT_U32, }, + [ETHTOOL_A_STRING_VALUE] = { .name = "value", .type = YNL_PT_NUL_STR, }, +}; + +struct ynl_policy_nest ethtool_string_nest = { + .max_attr = ETHTOOL_A_STRING_MAX, + .table = ethtool_string_policy, +}; + +struct ynl_policy_attr ethtool_cable_nest_policy[ETHTOOL_A_CABLE_NEST_MAX + 1] = { + [ETHTOOL_A_CABLE_NEST_RESULT] = { .name = "result", .type = YNL_PT_NEST, .nest = ðtool_cable_result_nest, }, + [ETHTOOL_A_CABLE_NEST_FAULT_LENGTH] = { .name = "fault-length", .type = YNL_PT_NEST, .nest = ðtool_cable_fault_length_nest, }, +}; + +struct ynl_policy_nest ethtool_cable_nest_nest = { + .max_attr = ETHTOOL_A_CABLE_NEST_MAX, + .table = ethtool_cable_nest_policy, +}; + +struct ynl_policy_attr ethtool_bitset_bits_policy[ETHTOOL_A_BITSET_BITS_MAX + 1] = { + [ETHTOOL_A_BITSET_BITS_BIT] = { .name = "bit", .type = YNL_PT_NEST, .nest = ðtool_bitset_bit_nest, }, +}; + +struct ynl_policy_nest ethtool_bitset_bits_nest = { + .max_attr = ETHTOOL_A_BITSET_BITS_MAX, + .table = ethtool_bitset_bits_policy, +}; + +struct ynl_policy_attr ethtool_strings_policy[ETHTOOL_A_STRINGS_MAX + 1] = { + [ETHTOOL_A_STRINGS_STRING] = { .name = "string", .type = YNL_PT_NEST, .nest = ðtool_string_nest, }, +}; + +struct ynl_policy_nest ethtool_strings_nest = { + .max_attr = ETHTOOL_A_STRINGS_MAX, + .table = ethtool_strings_policy, +}; + +struct ynl_policy_attr ethtool_bitset_policy[ETHTOOL_A_BITSET_MAX + 1] = { + [ETHTOOL_A_BITSET_NOMASK] = { .name = "nomask", .type = YNL_PT_FLAG, }, + [ETHTOOL_A_BITSET_SIZE] = { .name = "size", .type = YNL_PT_U32, }, + [ETHTOOL_A_BITSET_BITS] = { .name = "bits", .type = YNL_PT_NEST, .nest = ðtool_bitset_bits_nest, }, +}; + +struct ynl_policy_nest ethtool_bitset_nest = { + .max_attr = ETHTOOL_A_BITSET_MAX, + .table = ethtool_bitset_policy, +}; + +struct ynl_policy_attr ethtool_stringset_policy[ETHTOOL_A_STRINGSET_MAX + 1] = { + [ETHTOOL_A_STRINGSET_ID] = { .name = "id", .type = YNL_PT_U32, }, + [ETHTOOL_A_STRINGSET_COUNT] = { .name = "count", .type = YNL_PT_U32, }, + [ETHTOOL_A_STRINGSET_STRINGS] = { .name = "strings", .type = YNL_PT_NEST, .nest = ðtool_strings_nest, }, +}; + +struct ynl_policy_nest ethtool_stringset_nest = { + .max_attr = ETHTOOL_A_STRINGSET_MAX, + .table = ethtool_stringset_policy, +}; + +struct ynl_policy_attr ethtool_tunnel_udp_table_policy[ETHTOOL_A_TUNNEL_UDP_TABLE_MAX + 1] = { + [ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE] = { .name = "size", .type = YNL_PT_U32, }, + [ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES] = { .name = "types", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY] = { .name = "entry", .type = YNL_PT_NEST, .nest = ðtool_tunnel_udp_entry_nest, }, +}; + +struct ynl_policy_nest ethtool_tunnel_udp_table_nest = { + .max_attr = ETHTOOL_A_TUNNEL_UDP_TABLE_MAX, + .table = ethtool_tunnel_udp_table_policy, +}; + +struct ynl_policy_attr ethtool_stringsets_policy[ETHTOOL_A_STRINGSETS_MAX + 1] = { + [ETHTOOL_A_STRINGSETS_STRINGSET] = { .name = "stringset", .type = YNL_PT_NEST, .nest = ðtool_stringset_nest, }, +}; + +struct ynl_policy_nest ethtool_stringsets_nest = { + .max_attr = ETHTOOL_A_STRINGSETS_MAX, + .table = ethtool_stringsets_policy, +}; + +struct ynl_policy_attr ethtool_tunnel_udp_policy[ETHTOOL_A_TUNNEL_UDP_MAX + 1] = { + [ETHTOOL_A_TUNNEL_UDP_TABLE] = { .name = "table", .type = YNL_PT_NEST, .nest = ðtool_tunnel_udp_table_nest, }, +}; + +struct ynl_policy_nest ethtool_tunnel_udp_nest = { + .max_attr = ETHTOOL_A_TUNNEL_UDP_MAX, + .table = ethtool_tunnel_udp_policy, +}; + +struct ynl_policy_attr ethtool_strset_policy[ETHTOOL_A_STRSET_MAX + 1] = { + [ETHTOOL_A_STRSET_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_STRSET_STRINGSETS] = { .name = "stringsets", .type = YNL_PT_NEST, .nest = ðtool_stringsets_nest, }, + [ETHTOOL_A_STRSET_COUNTS_ONLY] = { .name = "counts-only", .type = YNL_PT_FLAG, }, +}; + +struct ynl_policy_nest ethtool_strset_nest = { + .max_attr = ETHTOOL_A_STRSET_MAX, + .table = ethtool_strset_policy, +}; + +struct ynl_policy_attr ethtool_linkinfo_policy[ETHTOOL_A_LINKINFO_MAX + 1] = { + [ETHTOOL_A_LINKINFO_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_LINKINFO_PORT] = { .name = "port", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKINFO_PHYADDR] = { .name = "phyaddr", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKINFO_TP_MDIX] = { .name = "tp-mdix", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKINFO_TP_MDIX_CTRL] = { .name = "tp-mdix-ctrl", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKINFO_TRANSCEIVER] = { .name = "transceiver", .type = YNL_PT_U8, }, +}; + +struct ynl_policy_nest ethtool_linkinfo_nest = { + .max_attr = ETHTOOL_A_LINKINFO_MAX, + .table = ethtool_linkinfo_policy, +}; + +struct ynl_policy_attr ethtool_linkmodes_policy[ETHTOOL_A_LINKMODES_MAX + 1] = { + [ETHTOOL_A_LINKMODES_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_LINKMODES_AUTONEG] = { .name = "autoneg", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKMODES_OURS] = { .name = "ours", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_LINKMODES_PEER] = { .name = "peer", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_LINKMODES_SPEED] = { .name = "speed", .type = YNL_PT_U32, }, + [ETHTOOL_A_LINKMODES_DUPLEX] = { .name = "duplex", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG] = { .name = "master-slave-cfg", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE] = { .name = "master-slave-state", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKMODES_LANES] = { .name = "lanes", .type = YNL_PT_U32, }, + [ETHTOOL_A_LINKMODES_RATE_MATCHING] = { .name = "rate-matching", .type = YNL_PT_U8, }, +}; + +struct ynl_policy_nest ethtool_linkmodes_nest = { + .max_attr = ETHTOOL_A_LINKMODES_MAX, + .table = ethtool_linkmodes_policy, +}; + +struct ynl_policy_attr ethtool_linkstate_policy[ETHTOOL_A_LINKSTATE_MAX + 1] = { + [ETHTOOL_A_LINKSTATE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_LINKSTATE_LINK] = { .name = "link", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKSTATE_SQI] = { .name = "sqi", .type = YNL_PT_U32, }, + [ETHTOOL_A_LINKSTATE_SQI_MAX] = { .name = "sqi-max", .type = YNL_PT_U32, }, + [ETHTOOL_A_LINKSTATE_EXT_STATE] = { .name = "ext-state", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKSTATE_EXT_SUBSTATE] = { .name = "ext-substate", .type = YNL_PT_U8, }, + [ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT] = { .name = "ext-down-cnt", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_linkstate_nest = { + .max_attr = ETHTOOL_A_LINKSTATE_MAX, + .table = ethtool_linkstate_policy, +}; + +struct ynl_policy_attr ethtool_debug_policy[ETHTOOL_A_DEBUG_MAX + 1] = { + [ETHTOOL_A_DEBUG_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_DEBUG_MSGMASK] = { .name = "msgmask", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, +}; + +struct ynl_policy_nest ethtool_debug_nest = { + .max_attr = ETHTOOL_A_DEBUG_MAX, + .table = ethtool_debug_policy, +}; + +struct ynl_policy_attr ethtool_wol_policy[ETHTOOL_A_WOL_MAX + 1] = { + [ETHTOOL_A_WOL_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_WOL_MODES] = { .name = "modes", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_WOL_SOPASS] = { .name = "sopass", .type = YNL_PT_BINARY,}, +}; + +struct ynl_policy_nest ethtool_wol_nest = { + .max_attr = ETHTOOL_A_WOL_MAX, + .table = ethtool_wol_policy, +}; + +struct ynl_policy_attr ethtool_features_policy[ETHTOOL_A_FEATURES_MAX + 1] = { + [ETHTOOL_A_FEATURES_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_FEATURES_HW] = { .name = "hw", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_FEATURES_WANTED] = { .name = "wanted", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_FEATURES_ACTIVE] = { .name = "active", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_FEATURES_NOCHANGE] = { .name = "nochange", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, +}; + +struct ynl_policy_nest ethtool_features_nest = { + .max_attr = ETHTOOL_A_FEATURES_MAX, + .table = ethtool_features_policy, +}; + +struct ynl_policy_attr ethtool_privflags_policy[ETHTOOL_A_PRIVFLAGS_MAX + 1] = { + [ETHTOOL_A_PRIVFLAGS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_PRIVFLAGS_FLAGS] = { .name = "flags", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, +}; + +struct ynl_policy_nest ethtool_privflags_nest = { + .max_attr = ETHTOOL_A_PRIVFLAGS_MAX, + .table = ethtool_privflags_policy, +}; + +struct ynl_policy_attr ethtool_rings_policy[ETHTOOL_A_RINGS_MAX + 1] = { + [ETHTOOL_A_RINGS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_RINGS_RX_MAX] = { .name = "rx-max", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_RX_MINI_MAX] = { .name = "rx-mini-max", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_RX_JUMBO_MAX] = { .name = "rx-jumbo-max", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_TX_MAX] = { .name = "tx-max", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_RX] = { .name = "rx", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_RX_MINI] = { .name = "rx-mini", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_RX_JUMBO] = { .name = "rx-jumbo", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_TX] = { .name = "tx", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_RX_BUF_LEN] = { .name = "rx-buf-len", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_TCP_DATA_SPLIT] = { .name = "tcp-data-split", .type = YNL_PT_U8, }, + [ETHTOOL_A_RINGS_CQE_SIZE] = { .name = "cqe-size", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_TX_PUSH] = { .name = "tx-push", .type = YNL_PT_U8, }, + [ETHTOOL_A_RINGS_RX_PUSH] = { .name = "rx-push", .type = YNL_PT_U8, }, + [ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN] = { .name = "tx-push-buf-len", .type = YNL_PT_U32, }, + [ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX] = { .name = "tx-push-buf-len-max", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_rings_nest = { + .max_attr = ETHTOOL_A_RINGS_MAX, + .table = ethtool_rings_policy, +}; + +struct ynl_policy_attr ethtool_channels_policy[ETHTOOL_A_CHANNELS_MAX + 1] = { + [ETHTOOL_A_CHANNELS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_CHANNELS_RX_MAX] = { .name = "rx-max", .type = YNL_PT_U32, }, + [ETHTOOL_A_CHANNELS_TX_MAX] = { .name = "tx-max", .type = YNL_PT_U32, }, + [ETHTOOL_A_CHANNELS_OTHER_MAX] = { .name = "other-max", .type = YNL_PT_U32, }, + [ETHTOOL_A_CHANNELS_COMBINED_MAX] = { .name = "combined-max", .type = YNL_PT_U32, }, + [ETHTOOL_A_CHANNELS_RX_COUNT] = { .name = "rx-count", .type = YNL_PT_U32, }, + [ETHTOOL_A_CHANNELS_TX_COUNT] = { .name = "tx-count", .type = YNL_PT_U32, }, + [ETHTOOL_A_CHANNELS_OTHER_COUNT] = { .name = "other-count", .type = YNL_PT_U32, }, + [ETHTOOL_A_CHANNELS_COMBINED_COUNT] = { .name = "combined-count", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_channels_nest = { + .max_attr = ETHTOOL_A_CHANNELS_MAX, + .table = ethtool_channels_policy, +}; + +struct ynl_policy_attr ethtool_coalesce_policy[ETHTOOL_A_COALESCE_MAX + 1] = { + [ETHTOOL_A_COALESCE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_COALESCE_RX_USECS] = { .name = "rx-usecs", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_RX_MAX_FRAMES] = { .name = "rx-max-frames", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_RX_USECS_IRQ] = { .name = "rx-usecs-irq", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ] = { .name = "rx-max-frames-irq", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_USECS] = { .name = "tx-usecs", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_MAX_FRAMES] = { .name = "tx-max-frames", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_USECS_IRQ] = { .name = "tx-usecs-irq", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ] = { .name = "tx-max-frames-irq", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_STATS_BLOCK_USECS] = { .name = "stats-block-usecs", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX] = { .name = "use-adaptive-rx", .type = YNL_PT_U8, }, + [ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX] = { .name = "use-adaptive-tx", .type = YNL_PT_U8, }, + [ETHTOOL_A_COALESCE_PKT_RATE_LOW] = { .name = "pkt-rate-low", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_RX_USECS_LOW] = { .name = "rx-usecs-low", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW] = { .name = "rx-max-frames-low", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_USECS_LOW] = { .name = "tx-usecs-low", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW] = { .name = "tx-max-frames-low", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_PKT_RATE_HIGH] = { .name = "pkt-rate-high", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_RX_USECS_HIGH] = { .name = "rx-usecs-high", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH] = { .name = "rx-max-frames-high", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_USECS_HIGH] = { .name = "tx-usecs-high", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH] = { .name = "tx-max-frames-high", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL] = { .name = "rate-sample-interval", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_USE_CQE_MODE_TX] = { .name = "use-cqe-mode-tx", .type = YNL_PT_U8, }, + [ETHTOOL_A_COALESCE_USE_CQE_MODE_RX] = { .name = "use-cqe-mode-rx", .type = YNL_PT_U8, }, + [ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES] = { .name = "tx-aggr-max-bytes", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES] = { .name = "tx-aggr-max-frames", .type = YNL_PT_U32, }, + [ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS] = { .name = "tx-aggr-time-usecs", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_coalesce_nest = { + .max_attr = ETHTOOL_A_COALESCE_MAX, + .table = ethtool_coalesce_policy, +}; + +struct ynl_policy_attr ethtool_pause_policy[ETHTOOL_A_PAUSE_MAX + 1] = { + [ETHTOOL_A_PAUSE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_PAUSE_AUTONEG] = { .name = "autoneg", .type = YNL_PT_U8, }, + [ETHTOOL_A_PAUSE_RX] = { .name = "rx", .type = YNL_PT_U8, }, + [ETHTOOL_A_PAUSE_TX] = { .name = "tx", .type = YNL_PT_U8, }, + [ETHTOOL_A_PAUSE_STATS] = { .name = "stats", .type = YNL_PT_NEST, .nest = ðtool_pause_stat_nest, }, + [ETHTOOL_A_PAUSE_STATS_SRC] = { .name = "stats-src", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_pause_nest = { + .max_attr = ETHTOOL_A_PAUSE_MAX, + .table = ethtool_pause_policy, +}; + +struct ynl_policy_attr ethtool_eee_policy[ETHTOOL_A_EEE_MAX + 1] = { + [ETHTOOL_A_EEE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_EEE_MODES_OURS] = { .name = "modes-ours", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_EEE_MODES_PEER] = { .name = "modes-peer", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_EEE_ACTIVE] = { .name = "active", .type = YNL_PT_U8, }, + [ETHTOOL_A_EEE_ENABLED] = { .name = "enabled", .type = YNL_PT_U8, }, + [ETHTOOL_A_EEE_TX_LPI_ENABLED] = { .name = "tx-lpi-enabled", .type = YNL_PT_U8, }, + [ETHTOOL_A_EEE_TX_LPI_TIMER] = { .name = "tx-lpi-timer", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_eee_nest = { + .max_attr = ETHTOOL_A_EEE_MAX, + .table = ethtool_eee_policy, +}; + +struct ynl_policy_attr ethtool_tsinfo_policy[ETHTOOL_A_TSINFO_MAX + 1] = { + [ETHTOOL_A_TSINFO_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_TSINFO_TIMESTAMPING] = { .name = "timestamping", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_TSINFO_TX_TYPES] = { .name = "tx-types", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_TSINFO_RX_FILTERS] = { .name = "rx-filters", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_TSINFO_PHC_INDEX] = { .name = "phc-index", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_tsinfo_nest = { + .max_attr = ETHTOOL_A_TSINFO_MAX, + .table = ethtool_tsinfo_policy, +}; + +struct ynl_policy_attr ethtool_cable_test_policy[ETHTOOL_A_CABLE_TEST_MAX + 1] = { + [ETHTOOL_A_CABLE_TEST_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, +}; + +struct ynl_policy_nest ethtool_cable_test_nest = { + .max_attr = ETHTOOL_A_CABLE_TEST_MAX, + .table = ethtool_cable_test_policy, +}; + +struct ynl_policy_attr ethtool_cable_test_ntf_policy[ETHTOOL_A_CABLE_TEST_NTF_MAX + 1] = { + [ETHTOOL_A_CABLE_TEST_NTF_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_CABLE_TEST_NTF_STATUS] = { .name = "status", .type = YNL_PT_U8, }, + [ETHTOOL_A_CABLE_TEST_NTF_NEST] = { .name = "nest", .type = YNL_PT_NEST, .nest = ðtool_cable_nest_nest, }, +}; + +struct ynl_policy_nest ethtool_cable_test_ntf_nest = { + .max_attr = ETHTOOL_A_CABLE_TEST_NTF_MAX, + .table = ethtool_cable_test_ntf_policy, +}; + +struct ynl_policy_attr ethtool_cable_test_tdr_policy[ETHTOOL_A_CABLE_TEST_TDR_MAX + 1] = { + [ETHTOOL_A_CABLE_TEST_TDR_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_CABLE_TEST_TDR_CFG] = { .name = "cfg", .type = YNL_PT_NEST, .nest = ðtool_cable_test_tdr_cfg_nest, }, +}; + +struct ynl_policy_nest ethtool_cable_test_tdr_nest = { + .max_attr = ETHTOOL_A_CABLE_TEST_TDR_MAX, + .table = ethtool_cable_test_tdr_policy, +}; + +struct ynl_policy_attr ethtool_cable_test_tdr_ntf_policy[ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX + 1] = { + [ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS] = { .name = "status", .type = YNL_PT_U8, }, + [ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST] = { .name = "nest", .type = YNL_PT_NEST, .nest = ðtool_cable_nest_nest, }, +}; + +struct ynl_policy_nest ethtool_cable_test_tdr_ntf_nest = { + .max_attr = ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX, + .table = ethtool_cable_test_tdr_ntf_policy, +}; + +struct ynl_policy_attr ethtool_tunnel_info_policy[ETHTOOL_A_TUNNEL_INFO_MAX + 1] = { + [ETHTOOL_A_TUNNEL_INFO_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_TUNNEL_INFO_UDP_PORTS] = { .name = "udp-ports", .type = YNL_PT_NEST, .nest = ðtool_tunnel_udp_nest, }, +}; + +struct ynl_policy_nest ethtool_tunnel_info_nest = { + .max_attr = ETHTOOL_A_TUNNEL_INFO_MAX, + .table = ethtool_tunnel_info_policy, +}; + +struct ynl_policy_attr ethtool_fec_policy[ETHTOOL_A_FEC_MAX + 1] = { + [ETHTOOL_A_FEC_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_FEC_MODES] = { .name = "modes", .type = YNL_PT_NEST, .nest = ðtool_bitset_nest, }, + [ETHTOOL_A_FEC_AUTO] = { .name = "auto", .type = YNL_PT_U8, }, + [ETHTOOL_A_FEC_ACTIVE] = { .name = "active", .type = YNL_PT_U32, }, + [ETHTOOL_A_FEC_STATS] = { .name = "stats", .type = YNL_PT_NEST, .nest = ðtool_fec_stat_nest, }, +}; + +struct ynl_policy_nest ethtool_fec_nest = { + .max_attr = ETHTOOL_A_FEC_MAX, + .table = ethtool_fec_policy, +}; + +struct ynl_policy_attr ethtool_module_eeprom_policy[ETHTOOL_A_MODULE_EEPROM_MAX + 1] = { + [ETHTOOL_A_MODULE_EEPROM_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_MODULE_EEPROM_OFFSET] = { .name = "offset", .type = YNL_PT_U32, }, + [ETHTOOL_A_MODULE_EEPROM_LENGTH] = { .name = "length", .type = YNL_PT_U32, }, + [ETHTOOL_A_MODULE_EEPROM_PAGE] = { .name = "page", .type = YNL_PT_U8, }, + [ETHTOOL_A_MODULE_EEPROM_BANK] = { .name = "bank", .type = YNL_PT_U8, }, + [ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS] = { .name = "i2c-address", .type = YNL_PT_U8, }, + [ETHTOOL_A_MODULE_EEPROM_DATA] = { .name = "data", .type = YNL_PT_BINARY,}, +}; + +struct ynl_policy_nest ethtool_module_eeprom_nest = { + .max_attr = ETHTOOL_A_MODULE_EEPROM_MAX, + .table = ethtool_module_eeprom_policy, +}; + +struct ynl_policy_attr ethtool_phc_vclocks_policy[ETHTOOL_A_PHC_VCLOCKS_MAX + 1] = { + [ETHTOOL_A_PHC_VCLOCKS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_PHC_VCLOCKS_NUM] = { .name = "num", .type = YNL_PT_U32, }, + [ETHTOOL_A_PHC_VCLOCKS_INDEX] = { .name = "index", .type = YNL_PT_BINARY,}, +}; + +struct ynl_policy_nest ethtool_phc_vclocks_nest = { + .max_attr = ETHTOOL_A_PHC_VCLOCKS_MAX, + .table = ethtool_phc_vclocks_policy, +}; + +struct ynl_policy_attr ethtool_module_policy[ETHTOOL_A_MODULE_MAX + 1] = { + [ETHTOOL_A_MODULE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_MODULE_POWER_MODE_POLICY] = { .name = "power-mode-policy", .type = YNL_PT_U8, }, + [ETHTOOL_A_MODULE_POWER_MODE] = { .name = "power-mode", .type = YNL_PT_U8, }, +}; + +struct ynl_policy_nest ethtool_module_nest = { + .max_attr = ETHTOOL_A_MODULE_MAX, + .table = ethtool_module_policy, +}; + +struct ynl_policy_attr ethtool_pse_policy[ETHTOOL_A_PSE_MAX + 1] = { + [ETHTOOL_A_PSE_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_PODL_PSE_ADMIN_STATE] = { .name = "admin-state", .type = YNL_PT_U32, }, + [ETHTOOL_A_PODL_PSE_ADMIN_CONTROL] = { .name = "admin-control", .type = YNL_PT_U32, }, + [ETHTOOL_A_PODL_PSE_PW_D_STATUS] = { .name = "pw-d-status", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_pse_nest = { + .max_attr = ETHTOOL_A_PSE_MAX, + .table = ethtool_pse_policy, +}; + +struct ynl_policy_attr ethtool_rss_policy[ETHTOOL_A_RSS_MAX + 1] = { + [ETHTOOL_A_RSS_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_RSS_CONTEXT] = { .name = "context", .type = YNL_PT_U32, }, + [ETHTOOL_A_RSS_HFUNC] = { .name = "hfunc", .type = YNL_PT_U32, }, + [ETHTOOL_A_RSS_INDIR] = { .name = "indir", .type = YNL_PT_BINARY,}, + [ETHTOOL_A_RSS_HKEY] = { .name = "hkey", .type = YNL_PT_BINARY,}, + [ETHTOOL_A_RSS_INPUT_XFRM] = { .name = "input_xfrm", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_rss_nest = { + .max_attr = ETHTOOL_A_RSS_MAX, + .table = ethtool_rss_policy, +}; + +struct ynl_policy_attr ethtool_plca_policy[ETHTOOL_A_PLCA_MAX + 1] = { + [ETHTOOL_A_PLCA_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_PLCA_VERSION] = { .name = "version", .type = YNL_PT_U16, }, + [ETHTOOL_A_PLCA_ENABLED] = { .name = "enabled", .type = YNL_PT_U8, }, + [ETHTOOL_A_PLCA_STATUS] = { .name = "status", .type = YNL_PT_U8, }, + [ETHTOOL_A_PLCA_NODE_CNT] = { .name = "node-cnt", .type = YNL_PT_U32, }, + [ETHTOOL_A_PLCA_NODE_ID] = { .name = "node-id", .type = YNL_PT_U32, }, + [ETHTOOL_A_PLCA_TO_TMR] = { .name = "to-tmr", .type = YNL_PT_U32, }, + [ETHTOOL_A_PLCA_BURST_CNT] = { .name = "burst-cnt", .type = YNL_PT_U32, }, + [ETHTOOL_A_PLCA_BURST_TMR] = { .name = "burst-tmr", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ethtool_plca_nest = { + .max_attr = ETHTOOL_A_PLCA_MAX, + .table = ethtool_plca_policy, +}; + +struct ynl_policy_attr ethtool_mm_policy[ETHTOOL_A_MM_MAX + 1] = { + [ETHTOOL_A_MM_HEADER] = { .name = "header", .type = YNL_PT_NEST, .nest = ðtool_header_nest, }, + [ETHTOOL_A_MM_PMAC_ENABLED] = { .name = "pmac-enabled", .type = YNL_PT_U8, }, + [ETHTOOL_A_MM_TX_ENABLED] = { .name = "tx-enabled", .type = YNL_PT_U8, }, + [ETHTOOL_A_MM_TX_ACTIVE] = { .name = "tx-active", .type = YNL_PT_U8, }, + [ETHTOOL_A_MM_TX_MIN_FRAG_SIZE] = { .name = "tx-min-frag-size", .type = YNL_PT_U32, }, + [ETHTOOL_A_MM_RX_MIN_FRAG_SIZE] = { .name = "rx-min-frag-size", .type = YNL_PT_U32, }, + [ETHTOOL_A_MM_VERIFY_ENABLED] = { .name = "verify-enabled", .type = YNL_PT_U8, }, + [ETHTOOL_A_MM_VERIFY_STATUS] = { .name = "verify-status", .type = YNL_PT_U8, }, + [ETHTOOL_A_MM_VERIFY_TIME] = { .name = "verify-time", .type = YNL_PT_U32, }, + [ETHTOOL_A_MM_MAX_VERIFY_TIME] = { .name = "max-verify-time", .type = YNL_PT_U32, }, + [ETHTOOL_A_MM_STATS] = { .name = "stats", .type = YNL_PT_NEST, .nest = ðtool_mm_stat_nest, }, +}; + +struct ynl_policy_nest ethtool_mm_nest = { + .max_attr = ETHTOOL_A_MM_MAX, + .table = ethtool_mm_policy, +}; + +/* Common nested types */ +void ethtool_header_free(struct ethtool_header *obj) +{ + free(obj->dev_name); +} + +int ethtool_header_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_header *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.dev_index) + ynl_attr_put_u32(nlh, ETHTOOL_A_HEADER_DEV_INDEX, obj->dev_index); + if (obj->_present.dev_name_len) + ynl_attr_put_str(nlh, ETHTOOL_A_HEADER_DEV_NAME, obj->dev_name); + if (obj->_present.flags) + ynl_attr_put_u32(nlh, ETHTOOL_A_HEADER_FLAGS, obj->flags); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_header_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_header *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_HEADER_DEV_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dev_index = 1; + dst->dev_index = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_HEADER_DEV_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.dev_name_len = len; + dst->dev_name = malloc(len + 1); + memcpy(dst->dev_name, ynl_attr_get_str(attr), len); + dst->dev_name[len] = 0; + } else if (type == ETHTOOL_A_HEADER_FLAGS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.flags = 1; + dst->flags = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void ethtool_pause_stat_free(struct ethtool_pause_stat *obj) +{ +} + +int ethtool_pause_stat_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_pause_stat *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.tx_frames) + ynl_attr_put_u64(nlh, ETHTOOL_A_PAUSE_STAT_TX_FRAMES, obj->tx_frames); + if (obj->_present.rx_frames) + ynl_attr_put_u64(nlh, ETHTOOL_A_PAUSE_STAT_RX_FRAMES, obj->rx_frames); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_pause_stat_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_pause_stat *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_PAUSE_STAT_TX_FRAMES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_frames = 1; + dst->tx_frames = ynl_attr_get_u64(attr); + } else if (type == ETHTOOL_A_PAUSE_STAT_RX_FRAMES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_frames = 1; + dst->rx_frames = ynl_attr_get_u64(attr); + } + } + + return 0; +} + +void ethtool_cable_test_tdr_cfg_free(struct ethtool_cable_test_tdr_cfg *obj) +{ +} + +void ethtool_fec_stat_free(struct ethtool_fec_stat *obj) +{ + free(obj->corrected); + free(obj->uncorr); + free(obj->corr_bits); +} + +int ethtool_fec_stat_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_fec_stat *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.corrected_len) + ynl_attr_put(nlh, ETHTOOL_A_FEC_STAT_CORRECTED, obj->corrected, obj->_present.corrected_len); + if (obj->_present.uncorr_len) + ynl_attr_put(nlh, ETHTOOL_A_FEC_STAT_UNCORR, obj->uncorr, obj->_present.uncorr_len); + if (obj->_present.corr_bits_len) + ynl_attr_put(nlh, ETHTOOL_A_FEC_STAT_CORR_BITS, obj->corr_bits, obj->_present.corr_bits_len); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_fec_stat_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_fec_stat *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_FEC_STAT_CORRECTED) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.corrected_len = len; + dst->corrected = malloc(len); + memcpy(dst->corrected, ynl_attr_data(attr), len); + } else if (type == ETHTOOL_A_FEC_STAT_UNCORR) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.uncorr_len = len; + dst->uncorr = malloc(len); + memcpy(dst->uncorr, ynl_attr_data(attr), len); + } else if (type == ETHTOOL_A_FEC_STAT_CORR_BITS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.corr_bits_len = len; + dst->corr_bits = malloc(len); + memcpy(dst->corr_bits, ynl_attr_data(attr), len); + } + } + + return 0; +} + +void ethtool_mm_stat_free(struct ethtool_mm_stat *obj) +{ +} + +int ethtool_mm_stat_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_mm_stat *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.reassembly_errors = 1; + dst->reassembly_errors = ynl_attr_get_u64(attr); + } else if (type == ETHTOOL_A_MM_STAT_SMD_ERRORS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.smd_errors = 1; + dst->smd_errors = ynl_attr_get_u64(attr); + } else if (type == ETHTOOL_A_MM_STAT_REASSEMBLY_OK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.reassembly_ok = 1; + dst->reassembly_ok = ynl_attr_get_u64(attr); + } else if (type == ETHTOOL_A_MM_STAT_RX_FRAG_COUNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_frag_count = 1; + dst->rx_frag_count = ynl_attr_get_u64(attr); + } else if (type == ETHTOOL_A_MM_STAT_TX_FRAG_COUNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_frag_count = 1; + dst->tx_frag_count = ynl_attr_get_u64(attr); + } else if (type == ETHTOOL_A_MM_STAT_HOLD_COUNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.hold_count = 1; + dst->hold_count = ynl_attr_get_u64(attr); + } + } + + return 0; +} + +void ethtool_cable_result_free(struct ethtool_cable_result *obj) +{ +} + +int ethtool_cable_result_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_cable_result *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_CABLE_RESULT_PAIR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pair = 1; + dst->pair = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_CABLE_RESULT_CODE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.code = 1; + dst->code = ynl_attr_get_u8(attr); + } + } + + return 0; +} + +void ethtool_cable_fault_length_free(struct ethtool_cable_fault_length *obj) +{ +} + +int ethtool_cable_fault_length_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_cable_fault_length *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pair = 1; + dst->pair = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_CABLE_FAULT_LENGTH_CM) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.cm = 1; + dst->cm = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void ethtool_bitset_bit_free(struct ethtool_bitset_bit *obj) +{ + free(obj->name); +} + +int ethtool_bitset_bit_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_bitset_bit *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.index) + ynl_attr_put_u32(nlh, ETHTOOL_A_BITSET_BIT_INDEX, obj->index); + if (obj->_present.name_len) + ynl_attr_put_str(nlh, ETHTOOL_A_BITSET_BIT_NAME, obj->name); + if (obj->_present.value) + ynl_attr_put(nlh, ETHTOOL_A_BITSET_BIT_VALUE, NULL, 0); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_bitset_bit_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_bitset_bit *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_BITSET_BIT_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.index = 1; + dst->index = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_BITSET_BIT_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.name_len = len; + dst->name = malloc(len + 1); + memcpy(dst->name, ynl_attr_get_str(attr), len); + dst->name[len] = 0; + } else if (type == ETHTOOL_A_BITSET_BIT_VALUE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.value = 1; + } + } + + return 0; +} + +void ethtool_tunnel_udp_entry_free(struct ethtool_tunnel_udp_entry *obj) +{ +} + +int ethtool_tunnel_udp_entry_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_tunnel_udp_entry *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port = 1; + dst->port = ynl_attr_get_u16(attr); + } else if (type == ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.type = 1; + dst->type = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void ethtool_string_free(struct ethtool_string *obj) +{ + free(obj->value); +} + +int ethtool_string_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_string *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.index) + ynl_attr_put_u32(nlh, ETHTOOL_A_STRING_INDEX, obj->index); + if (obj->_present.value_len) + ynl_attr_put_str(nlh, ETHTOOL_A_STRING_VALUE, obj->value); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_string_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_string *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_STRING_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.index = 1; + dst->index = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_STRING_VALUE) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.value_len = len; + dst->value = malloc(len + 1); + memcpy(dst->value, ynl_attr_get_str(attr), len); + dst->value[len] = 0; + } + } + + return 0; +} + +void ethtool_cable_nest_free(struct ethtool_cable_nest *obj) +{ + ethtool_cable_result_free(&obj->result); + ethtool_cable_fault_length_free(&obj->fault_length); +} + +int ethtool_cable_nest_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_cable_nest *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_CABLE_NEST_RESULT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.result = 1; + + parg.rsp_policy = ðtool_cable_result_nest; + parg.data = &dst->result; + if (ethtool_cable_result_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_CABLE_NEST_FAULT_LENGTH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.fault_length = 1; + + parg.rsp_policy = ðtool_cable_fault_length_nest; + parg.data = &dst->fault_length; + if (ethtool_cable_fault_length_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return 0; +} + +void ethtool_bitset_bits_free(struct ethtool_bitset_bits *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_bit; i++) + ethtool_bitset_bit_free(&obj->bit[i]); + free(obj->bit); +} + +int ethtool_bitset_bits_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_bitset_bits *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + for (unsigned int i = 0; i < obj->n_bit; i++) + ethtool_bitset_bit_put(nlh, ETHTOOL_A_BITSET_BITS_BIT, &obj->bit[i]); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_bitset_bits_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_bitset_bits *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + unsigned int n_bit = 0; + int i; + + parg.ys = yarg->ys; + + if (dst->bit) + return ynl_error_parse(yarg, "attribute already present (bitset-bits.bit)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_BITSET_BITS_BIT) { + n_bit++; + } + } + + if (n_bit) { + dst->bit = calloc(n_bit, sizeof(*dst->bit)); + dst->n_bit = n_bit; + i = 0; + parg.rsp_policy = ðtool_bitset_bit_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == ETHTOOL_A_BITSET_BITS_BIT) { + parg.data = &dst->bit[i]; + if (ethtool_bitset_bit_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void ethtool_strings_free(struct ethtool_strings *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_string; i++) + ethtool_string_free(&obj->string[i]); + free(obj->string); +} + +int ethtool_strings_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_strings *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + for (unsigned int i = 0; i < obj->n_string; i++) + ethtool_string_put(nlh, ETHTOOL_A_STRINGS_STRING, &obj->string[i]); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_strings_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_strings *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + unsigned int n_string = 0; + int i; + + parg.ys = yarg->ys; + + if (dst->string) + return ynl_error_parse(yarg, "attribute already present (strings.string)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_STRINGS_STRING) { + n_string++; + } + } + + if (n_string) { + dst->string = calloc(n_string, sizeof(*dst->string)); + dst->n_string = n_string; + i = 0; + parg.rsp_policy = ðtool_string_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == ETHTOOL_A_STRINGS_STRING) { + parg.data = &dst->string[i]; + if (ethtool_string_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void ethtool_bitset_free(struct ethtool_bitset *obj) +{ + ethtool_bitset_bits_free(&obj->bits); +} + +int ethtool_bitset_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_bitset *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.nomask) + ynl_attr_put(nlh, ETHTOOL_A_BITSET_NOMASK, NULL, 0); + if (obj->_present.size) + ynl_attr_put_u32(nlh, ETHTOOL_A_BITSET_SIZE, obj->size); + if (obj->_present.bits) + ethtool_bitset_bits_put(nlh, ETHTOOL_A_BITSET_BITS, &obj->bits); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_bitset_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_bitset *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_BITSET_NOMASK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.nomask = 1; + } else if (type == ETHTOOL_A_BITSET_SIZE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.size = 1; + dst->size = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_BITSET_BITS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.bits = 1; + + parg.rsp_policy = ðtool_bitset_bits_nest; + parg.data = &dst->bits; + if (ethtool_bitset_bits_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return 0; +} + +void ethtool_stringset_free(struct ethtool_stringset_ *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_strings; i++) + ethtool_strings_free(&obj->strings[i]); + free(obj->strings); +} + +int ethtool_stringset_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_stringset_ *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.id) + ynl_attr_put_u32(nlh, ETHTOOL_A_STRINGSET_ID, obj->id); + if (obj->_present.count) + ynl_attr_put_u32(nlh, ETHTOOL_A_STRINGSET_COUNT, obj->count); + for (unsigned int i = 0; i < obj->n_strings; i++) + ethtool_strings_put(nlh, ETHTOOL_A_STRINGSET_STRINGS, &obj->strings[i]); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_stringset_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_stringset_ *dst = yarg->data; + unsigned int n_strings = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->strings) + return ynl_error_parse(yarg, "attribute already present (stringset.strings)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_STRINGSET_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_STRINGSET_COUNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.count = 1; + dst->count = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_STRINGSET_STRINGS) { + n_strings++; + } + } + + if (n_strings) { + dst->strings = calloc(n_strings, sizeof(*dst->strings)); + dst->n_strings = n_strings; + i = 0; + parg.rsp_policy = ðtool_strings_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == ETHTOOL_A_STRINGSET_STRINGS) { + parg.data = &dst->strings[i]; + if (ethtool_strings_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void ethtool_tunnel_udp_table_free(struct ethtool_tunnel_udp_table *obj) +{ + unsigned int i; + + ethtool_bitset_free(&obj->types); + for (i = 0; i < obj->n_entry; i++) + ethtool_tunnel_udp_entry_free(&obj->entry[i]); + free(obj->entry); +} + +int ethtool_tunnel_udp_table_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_tunnel_udp_table *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + unsigned int n_entry = 0; + int i; + + parg.ys = yarg->ys; + + if (dst->entry) + return ynl_error_parse(yarg, "attribute already present (tunnel-udp-table.entry)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.size = 1; + dst->size = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.types = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->types; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY) { + n_entry++; + } + } + + if (n_entry) { + dst->entry = calloc(n_entry, sizeof(*dst->entry)); + dst->n_entry = n_entry; + i = 0; + parg.rsp_policy = ðtool_tunnel_udp_entry_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY) { + parg.data = &dst->entry[i]; + if (ethtool_tunnel_udp_entry_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void ethtool_stringsets_free(struct ethtool_stringsets *obj) +{ + unsigned int i; + + for (i = 0; i < obj->n_stringset; i++) + ethtool_stringset_free(&obj->stringset[i]); + free(obj->stringset); +} + +int ethtool_stringsets_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ethtool_stringsets *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + for (unsigned int i = 0; i < obj->n_stringset; i++) + ethtool_stringset_put(nlh, ETHTOOL_A_STRINGSETS_STRINGSET, &obj->stringset[i]); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ethtool_stringsets_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_stringsets *dst = yarg->data; + unsigned int n_stringset = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + parg.ys = yarg->ys; + + if (dst->stringset) + return ynl_error_parse(yarg, "attribute already present (stringsets.stringset)"); + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_STRINGSETS_STRINGSET) { + n_stringset++; + } + } + + if (n_stringset) { + dst->stringset = calloc(n_stringset, sizeof(*dst->stringset)); + dst->n_stringset = n_stringset; + i = 0; + parg.rsp_policy = ðtool_stringset_nest; + ynl_attr_for_each_nested(attr, nested) { + if (ynl_attr_type(attr) == ETHTOOL_A_STRINGSETS_STRINGSET) { + parg.data = &dst->stringset[i]; + if (ethtool_stringset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + + return 0; +} + +void ethtool_tunnel_udp_free(struct ethtool_tunnel_udp *obj) +{ + ethtool_tunnel_udp_table_free(&obj->table); +} + +int ethtool_tunnel_udp_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ethtool_tunnel_udp *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_TUNNEL_UDP_TABLE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.table = 1; + + parg.rsp_policy = ðtool_tunnel_udp_table_nest; + parg.data = &dst->table; + if (ethtool_tunnel_udp_table_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return 0; +} + +/* ============== ETHTOOL_MSG_STRSET_GET ============== */ +/* ETHTOOL_MSG_STRSET_GET - do */ +void ethtool_strset_get_req_free(struct ethtool_strset_get_req *req) +{ + ethtool_header_free(&req->header); + ethtool_stringsets_free(&req->stringsets); + free(req); +} + +void ethtool_strset_get_rsp_free(struct ethtool_strset_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_stringsets_free(&rsp->stringsets); + free(rsp); +} + +int ethtool_strset_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_strset_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_STRSET_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_STRSET_STRINGSETS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.stringsets = 1; + + parg.rsp_policy = ðtool_stringsets_nest; + parg.data = &dst->stringsets; + if (ethtool_stringsets_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_strset_get_rsp * +ethtool_strset_get(struct ynl_sock *ys, struct ethtool_strset_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_strset_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_STRSET_GET, 1); + ys->req_policy = ðtool_strset_nest; + yrs.yarg.rsp_policy = ðtool_strset_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_STRSET_HEADER, &req->header); + if (req->_present.stringsets) + ethtool_stringsets_put(nlh, ETHTOOL_A_STRSET_STRINGSETS, &req->stringsets); + if (req->_present.counts_only) + ynl_attr_put(nlh, ETHTOOL_A_STRSET_COUNTS_ONLY, NULL, 0); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_strset_get_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_STRSET_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_strset_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_STRSET_GET - dump */ +void ethtool_strset_get_req_dump_free(struct ethtool_strset_get_req_dump *req) +{ + ethtool_header_free(&req->header); + ethtool_stringsets_free(&req->stringsets); + free(req); +} + +void ethtool_strset_get_list_free(struct ethtool_strset_get_list *rsp) +{ + struct ethtool_strset_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_stringsets_free(&rsp->obj.stringsets); + free(rsp); + } +} + +struct ethtool_strset_get_list * +ethtool_strset_get_dump(struct ynl_sock *ys, + struct ethtool_strset_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_strset_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_strset_get_list); + yds.cb = ethtool_strset_get_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_STRSET_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_STRSET_GET, 1); + ys->req_policy = ðtool_strset_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_STRSET_HEADER, &req->header); + if (req->_present.stringsets) + ethtool_stringsets_put(nlh, ETHTOOL_A_STRSET_STRINGSETS, &req->stringsets); + if (req->_present.counts_only) + ynl_attr_put(nlh, ETHTOOL_A_STRSET_COUNTS_ONLY, NULL, 0); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_strset_get_list_free(yds.first); + return NULL; +} + +/* ============== ETHTOOL_MSG_LINKINFO_GET ============== */ +/* ETHTOOL_MSG_LINKINFO_GET - do */ +void ethtool_linkinfo_get_req_free(struct ethtool_linkinfo_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_linkinfo_get_rsp_free(struct ethtool_linkinfo_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_linkinfo_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_linkinfo_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_LINKINFO_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_LINKINFO_PORT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port = 1; + dst->port = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKINFO_PHYADDR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.phyaddr = 1; + dst->phyaddr = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKINFO_TP_MDIX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tp_mdix = 1; + dst->tp_mdix = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKINFO_TP_MDIX_CTRL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tp_mdix_ctrl = 1; + dst->tp_mdix_ctrl = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKINFO_TRANSCEIVER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.transceiver = 1; + dst->transceiver = ynl_attr_get_u8(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_linkinfo_get_rsp * +ethtool_linkinfo_get(struct ynl_sock *ys, struct ethtool_linkinfo_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_linkinfo_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKINFO_GET, 1); + ys->req_policy = ðtool_linkinfo_nest; + yrs.yarg.rsp_policy = ðtool_linkinfo_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_LINKINFO_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_linkinfo_get_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_LINKINFO_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_linkinfo_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_LINKINFO_GET - dump */ +void +ethtool_linkinfo_get_req_dump_free(struct ethtool_linkinfo_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_linkinfo_get_list_free(struct ethtool_linkinfo_get_list *rsp) +{ + struct ethtool_linkinfo_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_linkinfo_get_list * +ethtool_linkinfo_get_dump(struct ynl_sock *ys, + struct ethtool_linkinfo_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_linkinfo_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_linkinfo_get_list); + yds.cb = ethtool_linkinfo_get_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_LINKINFO_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_LINKINFO_GET, 1); + ys->req_policy = ðtool_linkinfo_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_LINKINFO_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_linkinfo_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_LINKINFO_GET - notify */ +void ethtool_linkinfo_get_ntf_free(struct ethtool_linkinfo_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + free(rsp); +} + +/* ============== ETHTOOL_MSG_LINKINFO_SET ============== */ +/* ETHTOOL_MSG_LINKINFO_SET - do */ +void ethtool_linkinfo_set_req_free(struct ethtool_linkinfo_set_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_linkinfo_set(struct ynl_sock *ys, + struct ethtool_linkinfo_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKINFO_SET, 1); + ys->req_policy = ðtool_linkinfo_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_LINKINFO_HEADER, &req->header); + if (req->_present.port) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_PORT, req->port); + if (req->_present.phyaddr) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_PHYADDR, req->phyaddr); + if (req->_present.tp_mdix) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_TP_MDIX, req->tp_mdix); + if (req->_present.tp_mdix_ctrl) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_TP_MDIX_CTRL, req->tp_mdix_ctrl); + if (req->_present.transceiver) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKINFO_TRANSCEIVER, req->transceiver); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_LINKMODES_GET ============== */ +/* ETHTOOL_MSG_LINKMODES_GET - do */ +void ethtool_linkmodes_get_req_free(struct ethtool_linkmodes_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_linkmodes_get_rsp_free(struct ethtool_linkmodes_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_bitset_free(&rsp->ours); + ethtool_bitset_free(&rsp->peer); + free(rsp); +} + +int ethtool_linkmodes_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_linkmodes_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_LINKMODES_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_LINKMODES_AUTONEG) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.autoneg = 1; + dst->autoneg = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKMODES_OURS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ours = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->ours; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_LINKMODES_PEER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.peer = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->peer; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_LINKMODES_SPEED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.speed = 1; + dst->speed = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_LINKMODES_DUPLEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.duplex = 1; + dst->duplex = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.master_slave_cfg = 1; + dst->master_slave_cfg = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.master_slave_state = 1; + dst->master_slave_state = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKMODES_LANES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.lanes = 1; + dst->lanes = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_LINKMODES_RATE_MATCHING) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rate_matching = 1; + dst->rate_matching = ynl_attr_get_u8(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_linkmodes_get_rsp * +ethtool_linkmodes_get(struct ynl_sock *ys, + struct ethtool_linkmodes_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_linkmodes_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKMODES_GET, 1); + ys->req_policy = ðtool_linkmodes_nest; + yrs.yarg.rsp_policy = ðtool_linkmodes_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_LINKMODES_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_linkmodes_get_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_LINKMODES_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_linkmodes_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_LINKMODES_GET - dump */ +void +ethtool_linkmodes_get_req_dump_free(struct ethtool_linkmodes_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_linkmodes_get_list_free(struct ethtool_linkmodes_get_list *rsp) +{ + struct ethtool_linkmodes_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.ours); + ethtool_bitset_free(&rsp->obj.peer); + free(rsp); + } +} + +struct ethtool_linkmodes_get_list * +ethtool_linkmodes_get_dump(struct ynl_sock *ys, + struct ethtool_linkmodes_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_linkmodes_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_linkmodes_get_list); + yds.cb = ethtool_linkmodes_get_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_LINKMODES_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_LINKMODES_GET, 1); + ys->req_policy = ðtool_linkmodes_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_LINKMODES_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_linkmodes_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_LINKMODES_GET - notify */ +void ethtool_linkmodes_get_ntf_free(struct ethtool_linkmodes_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.ours); + ethtool_bitset_free(&rsp->obj.peer); + free(rsp); +} + +/* ============== ETHTOOL_MSG_LINKMODES_SET ============== */ +/* ETHTOOL_MSG_LINKMODES_SET - do */ +void ethtool_linkmodes_set_req_free(struct ethtool_linkmodes_set_req *req) +{ + ethtool_header_free(&req->header); + ethtool_bitset_free(&req->ours); + ethtool_bitset_free(&req->peer); + free(req); +} + +int ethtool_linkmodes_set(struct ynl_sock *ys, + struct ethtool_linkmodes_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKMODES_SET, 1); + ys->req_policy = ðtool_linkmodes_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_LINKMODES_HEADER, &req->header); + if (req->_present.autoneg) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_AUTONEG, req->autoneg); + if (req->_present.ours) + ethtool_bitset_put(nlh, ETHTOOL_A_LINKMODES_OURS, &req->ours); + if (req->_present.peer) + ethtool_bitset_put(nlh, ETHTOOL_A_LINKMODES_PEER, &req->peer); + if (req->_present.speed) + ynl_attr_put_u32(nlh, ETHTOOL_A_LINKMODES_SPEED, req->speed); + if (req->_present.duplex) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_DUPLEX, req->duplex); + if (req->_present.master_slave_cfg) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, req->master_slave_cfg); + if (req->_present.master_slave_state) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, req->master_slave_state); + if (req->_present.lanes) + ynl_attr_put_u32(nlh, ETHTOOL_A_LINKMODES_LANES, req->lanes); + if (req->_present.rate_matching) + ynl_attr_put_u8(nlh, ETHTOOL_A_LINKMODES_RATE_MATCHING, req->rate_matching); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_LINKSTATE_GET ============== */ +/* ETHTOOL_MSG_LINKSTATE_GET - do */ +void ethtool_linkstate_get_req_free(struct ethtool_linkstate_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_linkstate_get_rsp_free(struct ethtool_linkstate_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_linkstate_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_linkstate_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_LINKSTATE_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_LINKSTATE_LINK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.link = 1; + dst->link = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKSTATE_SQI) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sqi = 1; + dst->sqi = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_LINKSTATE_SQI_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sqi_max = 1; + dst->sqi_max = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_LINKSTATE_EXT_STATE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ext_state = 1; + dst->ext_state = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKSTATE_EXT_SUBSTATE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ext_substate = 1; + dst->ext_substate = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ext_down_cnt = 1; + dst->ext_down_cnt = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_linkstate_get_rsp * +ethtool_linkstate_get(struct ynl_sock *ys, + struct ethtool_linkstate_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_linkstate_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_LINKSTATE_GET, 1); + ys->req_policy = ðtool_linkstate_nest; + yrs.yarg.rsp_policy = ðtool_linkstate_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_LINKSTATE_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_linkstate_get_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_LINKSTATE_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_linkstate_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_LINKSTATE_GET - dump */ +void +ethtool_linkstate_get_req_dump_free(struct ethtool_linkstate_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_linkstate_get_list_free(struct ethtool_linkstate_get_list *rsp) +{ + struct ethtool_linkstate_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_linkstate_get_list * +ethtool_linkstate_get_dump(struct ynl_sock *ys, + struct ethtool_linkstate_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_linkstate_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_linkstate_get_list); + yds.cb = ethtool_linkstate_get_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_LINKSTATE_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_LINKSTATE_GET, 1); + ys->req_policy = ðtool_linkstate_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_LINKSTATE_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_linkstate_get_list_free(yds.first); + return NULL; +} + +/* ============== ETHTOOL_MSG_DEBUG_GET ============== */ +/* ETHTOOL_MSG_DEBUG_GET - do */ +void ethtool_debug_get_req_free(struct ethtool_debug_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_debug_get_rsp_free(struct ethtool_debug_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_bitset_free(&rsp->msgmask); + free(rsp); +} + +int ethtool_debug_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_debug_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_DEBUG_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_DEBUG_MSGMASK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.msgmask = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->msgmask; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_debug_get_rsp * +ethtool_debug_get(struct ynl_sock *ys, struct ethtool_debug_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_debug_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_DEBUG_GET, 1); + ys->req_policy = ðtool_debug_nest; + yrs.yarg.rsp_policy = ðtool_debug_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_DEBUG_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_debug_get_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_DEBUG_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_debug_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_DEBUG_GET - dump */ +void ethtool_debug_get_req_dump_free(struct ethtool_debug_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_debug_get_list_free(struct ethtool_debug_get_list *rsp) +{ + struct ethtool_debug_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.msgmask); + free(rsp); + } +} + +struct ethtool_debug_get_list * +ethtool_debug_get_dump(struct ynl_sock *ys, + struct ethtool_debug_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_debug_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_debug_get_list); + yds.cb = ethtool_debug_get_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_DEBUG_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_DEBUG_GET, 1); + ys->req_policy = ðtool_debug_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_DEBUG_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_debug_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_DEBUG_GET - notify */ +void ethtool_debug_get_ntf_free(struct ethtool_debug_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.msgmask); + free(rsp); +} + +/* ============== ETHTOOL_MSG_DEBUG_SET ============== */ +/* ETHTOOL_MSG_DEBUG_SET - do */ +void ethtool_debug_set_req_free(struct ethtool_debug_set_req *req) +{ + ethtool_header_free(&req->header); + ethtool_bitset_free(&req->msgmask); + free(req); +} + +int ethtool_debug_set(struct ynl_sock *ys, struct ethtool_debug_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_DEBUG_SET, 1); + ys->req_policy = ðtool_debug_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_DEBUG_HEADER, &req->header); + if (req->_present.msgmask) + ethtool_bitset_put(nlh, ETHTOOL_A_DEBUG_MSGMASK, &req->msgmask); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_WOL_GET ============== */ +/* ETHTOOL_MSG_WOL_GET - do */ +void ethtool_wol_get_req_free(struct ethtool_wol_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_wol_get_rsp_free(struct ethtool_wol_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_bitset_free(&rsp->modes); + free(rsp->sopass); + free(rsp); +} + +int ethtool_wol_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_wol_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_WOL_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_WOL_MODES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.modes = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->modes; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_WOL_SOPASS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.sopass_len = len; + dst->sopass = malloc(len); + memcpy(dst->sopass, ynl_attr_data(attr), len); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_wol_get_rsp * +ethtool_wol_get(struct ynl_sock *ys, struct ethtool_wol_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_wol_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_WOL_GET, 1); + ys->req_policy = ðtool_wol_nest; + yrs.yarg.rsp_policy = ðtool_wol_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_WOL_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_wol_get_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_WOL_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_wol_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_WOL_GET - dump */ +void ethtool_wol_get_req_dump_free(struct ethtool_wol_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_wol_get_list_free(struct ethtool_wol_get_list *rsp) +{ + struct ethtool_wol_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.modes); + free(rsp->obj.sopass); + free(rsp); + } +} + +struct ethtool_wol_get_list * +ethtool_wol_get_dump(struct ynl_sock *ys, struct ethtool_wol_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_wol_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_wol_get_list); + yds.cb = ethtool_wol_get_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_WOL_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_WOL_GET, 1); + ys->req_policy = ðtool_wol_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_WOL_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_wol_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_WOL_GET - notify */ +void ethtool_wol_get_ntf_free(struct ethtool_wol_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.modes); + free(rsp->obj.sopass); + free(rsp); +} + +/* ============== ETHTOOL_MSG_WOL_SET ============== */ +/* ETHTOOL_MSG_WOL_SET - do */ +void ethtool_wol_set_req_free(struct ethtool_wol_set_req *req) +{ + ethtool_header_free(&req->header); + ethtool_bitset_free(&req->modes); + free(req->sopass); + free(req); +} + +int ethtool_wol_set(struct ynl_sock *ys, struct ethtool_wol_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_WOL_SET, 1); + ys->req_policy = ðtool_wol_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_WOL_HEADER, &req->header); + if (req->_present.modes) + ethtool_bitset_put(nlh, ETHTOOL_A_WOL_MODES, &req->modes); + if (req->_present.sopass_len) + ynl_attr_put(nlh, ETHTOOL_A_WOL_SOPASS, req->sopass, req->_present.sopass_len); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_FEATURES_GET ============== */ +/* ETHTOOL_MSG_FEATURES_GET - do */ +void ethtool_features_get_req_free(struct ethtool_features_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_features_get_rsp_free(struct ethtool_features_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_bitset_free(&rsp->hw); + ethtool_bitset_free(&rsp->wanted); + ethtool_bitset_free(&rsp->active); + ethtool_bitset_free(&rsp->nochange); + free(rsp); +} + +int ethtool_features_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_features_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_FEATURES_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEATURES_HW) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.hw = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->hw; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEATURES_WANTED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.wanted = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->wanted; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEATURES_ACTIVE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.active = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->active; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEATURES_NOCHANGE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.nochange = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->nochange; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_features_get_rsp * +ethtool_features_get(struct ynl_sock *ys, struct ethtool_features_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_features_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_FEATURES_GET, 1); + ys->req_policy = ðtool_features_nest; + yrs.yarg.rsp_policy = ðtool_features_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_FEATURES_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_features_get_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_FEATURES_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_features_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_FEATURES_GET - dump */ +void +ethtool_features_get_req_dump_free(struct ethtool_features_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_features_get_list_free(struct ethtool_features_get_list *rsp) +{ + struct ethtool_features_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.hw); + ethtool_bitset_free(&rsp->obj.wanted); + ethtool_bitset_free(&rsp->obj.active); + ethtool_bitset_free(&rsp->obj.nochange); + free(rsp); + } +} + +struct ethtool_features_get_list * +ethtool_features_get_dump(struct ynl_sock *ys, + struct ethtool_features_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_features_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_features_get_list); + yds.cb = ethtool_features_get_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_FEATURES_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_FEATURES_GET, 1); + ys->req_policy = ðtool_features_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_FEATURES_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_features_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_FEATURES_GET - notify */ +void ethtool_features_get_ntf_free(struct ethtool_features_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.hw); + ethtool_bitset_free(&rsp->obj.wanted); + ethtool_bitset_free(&rsp->obj.active); + ethtool_bitset_free(&rsp->obj.nochange); + free(rsp); +} + +/* ============== ETHTOOL_MSG_FEATURES_SET ============== */ +/* ETHTOOL_MSG_FEATURES_SET - do */ +void ethtool_features_set_req_free(struct ethtool_features_set_req *req) +{ + ethtool_header_free(&req->header); + ethtool_bitset_free(&req->hw); + ethtool_bitset_free(&req->wanted); + ethtool_bitset_free(&req->active); + ethtool_bitset_free(&req->nochange); + free(req); +} + +void ethtool_features_set_rsp_free(struct ethtool_features_set_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_bitset_free(&rsp->hw); + ethtool_bitset_free(&rsp->wanted); + ethtool_bitset_free(&rsp->active); + ethtool_bitset_free(&rsp->nochange); + free(rsp); +} + +int ethtool_features_set_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_features_set_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_FEATURES_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEATURES_HW) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.hw = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->hw; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEATURES_WANTED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.wanted = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->wanted; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEATURES_ACTIVE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.active = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->active; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEATURES_NOCHANGE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.nochange = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->nochange; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_features_set_rsp * +ethtool_features_set(struct ynl_sock *ys, struct ethtool_features_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_features_set_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_FEATURES_SET, 1); + ys->req_policy = ðtool_features_nest; + yrs.yarg.rsp_policy = ðtool_features_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_FEATURES_HEADER, &req->header); + if (req->_present.hw) + ethtool_bitset_put(nlh, ETHTOOL_A_FEATURES_HW, &req->hw); + if (req->_present.wanted) + ethtool_bitset_put(nlh, ETHTOOL_A_FEATURES_WANTED, &req->wanted); + if (req->_present.active) + ethtool_bitset_put(nlh, ETHTOOL_A_FEATURES_ACTIVE, &req->active); + if (req->_present.nochange) + ethtool_bitset_put(nlh, ETHTOOL_A_FEATURES_NOCHANGE, &req->nochange); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_features_set_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_FEATURES_SET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_features_set_rsp_free(rsp); + return NULL; +} + +/* ============== ETHTOOL_MSG_PRIVFLAGS_GET ============== */ +/* ETHTOOL_MSG_PRIVFLAGS_GET - do */ +void ethtool_privflags_get_req_free(struct ethtool_privflags_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_privflags_get_rsp_free(struct ethtool_privflags_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_bitset_free(&rsp->flags); + free(rsp); +} + +int ethtool_privflags_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_privflags_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_PRIVFLAGS_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_PRIVFLAGS_FLAGS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.flags = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->flags; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_privflags_get_rsp * +ethtool_privflags_get(struct ynl_sock *ys, + struct ethtool_privflags_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_privflags_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PRIVFLAGS_GET, 1); + ys->req_policy = ðtool_privflags_nest; + yrs.yarg.rsp_policy = ðtool_privflags_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PRIVFLAGS_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_privflags_get_rsp_parse; + yrs.rsp_cmd = 14; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_privflags_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_PRIVFLAGS_GET - dump */ +void +ethtool_privflags_get_req_dump_free(struct ethtool_privflags_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_privflags_get_list_free(struct ethtool_privflags_get_list *rsp) +{ + struct ethtool_privflags_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.flags); + free(rsp); + } +} + +struct ethtool_privflags_get_list * +ethtool_privflags_get_dump(struct ynl_sock *ys, + struct ethtool_privflags_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_privflags_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_privflags_get_list); + yds.cb = ethtool_privflags_get_rsp_parse; + yds.rsp_cmd = 14; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PRIVFLAGS_GET, 1); + ys->req_policy = ðtool_privflags_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PRIVFLAGS_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_privflags_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_PRIVFLAGS_GET - notify */ +void ethtool_privflags_get_ntf_free(struct ethtool_privflags_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.flags); + free(rsp); +} + +/* ============== ETHTOOL_MSG_PRIVFLAGS_SET ============== */ +/* ETHTOOL_MSG_PRIVFLAGS_SET - do */ +void ethtool_privflags_set_req_free(struct ethtool_privflags_set_req *req) +{ + ethtool_header_free(&req->header); + ethtool_bitset_free(&req->flags); + free(req); +} + +int ethtool_privflags_set(struct ynl_sock *ys, + struct ethtool_privflags_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PRIVFLAGS_SET, 1); + ys->req_policy = ðtool_privflags_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PRIVFLAGS_HEADER, &req->header); + if (req->_present.flags) + ethtool_bitset_put(nlh, ETHTOOL_A_PRIVFLAGS_FLAGS, &req->flags); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_RINGS_GET ============== */ +/* ETHTOOL_MSG_RINGS_GET - do */ +void ethtool_rings_get_req_free(struct ethtool_rings_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_rings_get_rsp_free(struct ethtool_rings_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_rings_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_rings_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_RINGS_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_RINGS_RX_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_max = 1; + dst->rx_max = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_RX_MINI_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_mini_max = 1; + dst->rx_mini_max = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_RX_JUMBO_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_jumbo_max = 1; + dst->rx_jumbo_max = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_TX_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_max = 1; + dst->tx_max = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_RX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx = 1; + dst->rx = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_RX_MINI) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_mini = 1; + dst->rx_mini = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_RX_JUMBO) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_jumbo = 1; + dst->rx_jumbo = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_TX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx = 1; + dst->tx = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_RX_BUF_LEN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_buf_len = 1; + dst->rx_buf_len = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_TCP_DATA_SPLIT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tcp_data_split = 1; + dst->tcp_data_split = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_RINGS_CQE_SIZE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.cqe_size = 1; + dst->cqe_size = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_TX_PUSH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_push = 1; + dst->tx_push = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_RINGS_RX_PUSH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_push = 1; + dst->rx_push = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_push_buf_len = 1; + dst->tx_push_buf_len = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_push_buf_len_max = 1; + dst->tx_push_buf_len_max = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_rings_get_rsp * +ethtool_rings_get(struct ynl_sock *ys, struct ethtool_rings_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_rings_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_RINGS_GET, 1); + ys->req_policy = ðtool_rings_nest; + yrs.yarg.rsp_policy = ðtool_rings_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_RINGS_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_rings_get_rsp_parse; + yrs.rsp_cmd = 16; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_rings_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_RINGS_GET - dump */ +void ethtool_rings_get_req_dump_free(struct ethtool_rings_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_rings_get_list_free(struct ethtool_rings_get_list *rsp) +{ + struct ethtool_rings_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_rings_get_list * +ethtool_rings_get_dump(struct ynl_sock *ys, + struct ethtool_rings_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_rings_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_rings_get_list); + yds.cb = ethtool_rings_get_rsp_parse; + yds.rsp_cmd = 16; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_RINGS_GET, 1); + ys->req_policy = ðtool_rings_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_RINGS_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_rings_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_RINGS_GET - notify */ +void ethtool_rings_get_ntf_free(struct ethtool_rings_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + free(rsp); +} + +/* ============== ETHTOOL_MSG_RINGS_SET ============== */ +/* ETHTOOL_MSG_RINGS_SET - do */ +void ethtool_rings_set_req_free(struct ethtool_rings_set_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_rings_set(struct ynl_sock *ys, struct ethtool_rings_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_RINGS_SET, 1); + ys->req_policy = ðtool_rings_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_RINGS_HEADER, &req->header); + if (req->_present.rx_max) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_MAX, req->rx_max); + if (req->_present.rx_mini_max) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_MINI_MAX, req->rx_mini_max); + if (req->_present.rx_jumbo_max) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_JUMBO_MAX, req->rx_jumbo_max); + if (req->_present.tx_max) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_TX_MAX, req->tx_max); + if (req->_present.rx) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX, req->rx); + if (req->_present.rx_mini) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_MINI, req->rx_mini); + if (req->_present.rx_jumbo) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_JUMBO, req->rx_jumbo); + if (req->_present.tx) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_TX, req->tx); + if (req->_present.rx_buf_len) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_RX_BUF_LEN, req->rx_buf_len); + if (req->_present.tcp_data_split) + ynl_attr_put_u8(nlh, ETHTOOL_A_RINGS_TCP_DATA_SPLIT, req->tcp_data_split); + if (req->_present.cqe_size) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_CQE_SIZE, req->cqe_size); + if (req->_present.tx_push) + ynl_attr_put_u8(nlh, ETHTOOL_A_RINGS_TX_PUSH, req->tx_push); + if (req->_present.rx_push) + ynl_attr_put_u8(nlh, ETHTOOL_A_RINGS_RX_PUSH, req->rx_push); + if (req->_present.tx_push_buf_len) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN, req->tx_push_buf_len); + if (req->_present.tx_push_buf_len_max) + ynl_attr_put_u32(nlh, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX, req->tx_push_buf_len_max); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_CHANNELS_GET ============== */ +/* ETHTOOL_MSG_CHANNELS_GET - do */ +void ethtool_channels_get_req_free(struct ethtool_channels_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_channels_get_rsp_free(struct ethtool_channels_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_channels_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_channels_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_CHANNELS_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_CHANNELS_RX_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_max = 1; + dst->rx_max = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_CHANNELS_TX_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_max = 1; + dst->tx_max = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_CHANNELS_OTHER_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.other_max = 1; + dst->other_max = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_CHANNELS_COMBINED_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.combined_max = 1; + dst->combined_max = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_CHANNELS_RX_COUNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_count = 1; + dst->rx_count = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_CHANNELS_TX_COUNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_count = 1; + dst->tx_count = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_CHANNELS_OTHER_COUNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.other_count = 1; + dst->other_count = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_CHANNELS_COMBINED_COUNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.combined_count = 1; + dst->combined_count = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_channels_get_rsp * +ethtool_channels_get(struct ynl_sock *ys, struct ethtool_channels_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_channels_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_CHANNELS_GET, 1); + ys->req_policy = ðtool_channels_nest; + yrs.yarg.rsp_policy = ðtool_channels_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_CHANNELS_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_channels_get_rsp_parse; + yrs.rsp_cmd = 18; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_channels_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_CHANNELS_GET - dump */ +void +ethtool_channels_get_req_dump_free(struct ethtool_channels_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_channels_get_list_free(struct ethtool_channels_get_list *rsp) +{ + struct ethtool_channels_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_channels_get_list * +ethtool_channels_get_dump(struct ynl_sock *ys, + struct ethtool_channels_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_channels_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_channels_get_list); + yds.cb = ethtool_channels_get_rsp_parse; + yds.rsp_cmd = 18; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_CHANNELS_GET, 1); + ys->req_policy = ðtool_channels_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_CHANNELS_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_channels_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_CHANNELS_GET - notify */ +void ethtool_channels_get_ntf_free(struct ethtool_channels_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + free(rsp); +} + +/* ============== ETHTOOL_MSG_CHANNELS_SET ============== */ +/* ETHTOOL_MSG_CHANNELS_SET - do */ +void ethtool_channels_set_req_free(struct ethtool_channels_set_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_channels_set(struct ynl_sock *ys, + struct ethtool_channels_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_CHANNELS_SET, 1); + ys->req_policy = ðtool_channels_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_CHANNELS_HEADER, &req->header); + if (req->_present.rx_max) + ynl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_RX_MAX, req->rx_max); + if (req->_present.tx_max) + ynl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_TX_MAX, req->tx_max); + if (req->_present.other_max) + ynl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_OTHER_MAX, req->other_max); + if (req->_present.combined_max) + ynl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_COMBINED_MAX, req->combined_max); + if (req->_present.rx_count) + ynl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_RX_COUNT, req->rx_count); + if (req->_present.tx_count) + ynl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_TX_COUNT, req->tx_count); + if (req->_present.other_count) + ynl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_OTHER_COUNT, req->other_count); + if (req->_present.combined_count) + ynl_attr_put_u32(nlh, ETHTOOL_A_CHANNELS_COMBINED_COUNT, req->combined_count); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_COALESCE_GET ============== */ +/* ETHTOOL_MSG_COALESCE_GET - do */ +void ethtool_coalesce_get_req_free(struct ethtool_coalesce_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_coalesce_get_rsp_free(struct ethtool_coalesce_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_coalesce_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_coalesce_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_COALESCE_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_COALESCE_RX_USECS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_usecs = 1; + dst->rx_usecs = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_RX_MAX_FRAMES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_max_frames = 1; + dst->rx_max_frames = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_RX_USECS_IRQ) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_usecs_irq = 1; + dst->rx_usecs_irq = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_max_frames_irq = 1; + dst->rx_max_frames_irq = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_USECS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_usecs = 1; + dst->tx_usecs = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_MAX_FRAMES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_max_frames = 1; + dst->tx_max_frames = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_USECS_IRQ) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_usecs_irq = 1; + dst->tx_usecs_irq = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_max_frames_irq = 1; + dst->tx_max_frames_irq = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_STATS_BLOCK_USECS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.stats_block_usecs = 1; + dst->stats_block_usecs = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.use_adaptive_rx = 1; + dst->use_adaptive_rx = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.use_adaptive_tx = 1; + dst->use_adaptive_tx = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_COALESCE_PKT_RATE_LOW) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pkt_rate_low = 1; + dst->pkt_rate_low = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_RX_USECS_LOW) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_usecs_low = 1; + dst->rx_usecs_low = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_max_frames_low = 1; + dst->rx_max_frames_low = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_USECS_LOW) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_usecs_low = 1; + dst->tx_usecs_low = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_max_frames_low = 1; + dst->tx_max_frames_low = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_PKT_RATE_HIGH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pkt_rate_high = 1; + dst->pkt_rate_high = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_RX_USECS_HIGH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_usecs_high = 1; + dst->rx_usecs_high = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_max_frames_high = 1; + dst->rx_max_frames_high = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_USECS_HIGH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_usecs_high = 1; + dst->tx_usecs_high = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_max_frames_high = 1; + dst->tx_max_frames_high = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rate_sample_interval = 1; + dst->rate_sample_interval = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_USE_CQE_MODE_TX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.use_cqe_mode_tx = 1; + dst->use_cqe_mode_tx = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_COALESCE_USE_CQE_MODE_RX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.use_cqe_mode_rx = 1; + dst->use_cqe_mode_rx = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_aggr_max_bytes = 1; + dst->tx_aggr_max_bytes = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_aggr_max_frames = 1; + dst->tx_aggr_max_frames = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_aggr_time_usecs = 1; + dst->tx_aggr_time_usecs = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_coalesce_get_rsp * +ethtool_coalesce_get(struct ynl_sock *ys, struct ethtool_coalesce_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_coalesce_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_COALESCE_GET, 1); + ys->req_policy = ðtool_coalesce_nest; + yrs.yarg.rsp_policy = ðtool_coalesce_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_COALESCE_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_coalesce_get_rsp_parse; + yrs.rsp_cmd = 20; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_coalesce_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_COALESCE_GET - dump */ +void +ethtool_coalesce_get_req_dump_free(struct ethtool_coalesce_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_coalesce_get_list_free(struct ethtool_coalesce_get_list *rsp) +{ + struct ethtool_coalesce_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_coalesce_get_list * +ethtool_coalesce_get_dump(struct ynl_sock *ys, + struct ethtool_coalesce_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_coalesce_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_coalesce_get_list); + yds.cb = ethtool_coalesce_get_rsp_parse; + yds.rsp_cmd = 20; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_COALESCE_GET, 1); + ys->req_policy = ðtool_coalesce_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_COALESCE_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_coalesce_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_COALESCE_GET - notify */ +void ethtool_coalesce_get_ntf_free(struct ethtool_coalesce_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + free(rsp); +} + +/* ============== ETHTOOL_MSG_COALESCE_SET ============== */ +/* ETHTOOL_MSG_COALESCE_SET - do */ +void ethtool_coalesce_set_req_free(struct ethtool_coalesce_set_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_coalesce_set(struct ynl_sock *ys, + struct ethtool_coalesce_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_COALESCE_SET, 1); + ys->req_policy = ðtool_coalesce_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_COALESCE_HEADER, &req->header); + if (req->_present.rx_usecs) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_USECS, req->rx_usecs); + if (req->_present.rx_max_frames) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_MAX_FRAMES, req->rx_max_frames); + if (req->_present.rx_usecs_irq) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_USECS_IRQ, req->rx_usecs_irq); + if (req->_present.rx_max_frames_irq) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ, req->rx_max_frames_irq); + if (req->_present.tx_usecs) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_USECS, req->tx_usecs); + if (req->_present.tx_max_frames) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_MAX_FRAMES, req->tx_max_frames); + if (req->_present.tx_usecs_irq) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_USECS_IRQ, req->tx_usecs_irq); + if (req->_present.tx_max_frames_irq) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ, req->tx_max_frames_irq); + if (req->_present.stats_block_usecs) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_STATS_BLOCK_USECS, req->stats_block_usecs); + if (req->_present.use_adaptive_rx) + ynl_attr_put_u8(nlh, ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX, req->use_adaptive_rx); + if (req->_present.use_adaptive_tx) + ynl_attr_put_u8(nlh, ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX, req->use_adaptive_tx); + if (req->_present.pkt_rate_low) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_PKT_RATE_LOW, req->pkt_rate_low); + if (req->_present.rx_usecs_low) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_USECS_LOW, req->rx_usecs_low); + if (req->_present.rx_max_frames_low) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW, req->rx_max_frames_low); + if (req->_present.tx_usecs_low) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_USECS_LOW, req->tx_usecs_low); + if (req->_present.tx_max_frames_low) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW, req->tx_max_frames_low); + if (req->_present.pkt_rate_high) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_PKT_RATE_HIGH, req->pkt_rate_high); + if (req->_present.rx_usecs_high) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_USECS_HIGH, req->rx_usecs_high); + if (req->_present.rx_max_frames_high) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH, req->rx_max_frames_high); + if (req->_present.tx_usecs_high) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_USECS_HIGH, req->tx_usecs_high); + if (req->_present.tx_max_frames_high) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH, req->tx_max_frames_high); + if (req->_present.rate_sample_interval) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL, req->rate_sample_interval); + if (req->_present.use_cqe_mode_tx) + ynl_attr_put_u8(nlh, ETHTOOL_A_COALESCE_USE_CQE_MODE_TX, req->use_cqe_mode_tx); + if (req->_present.use_cqe_mode_rx) + ynl_attr_put_u8(nlh, ETHTOOL_A_COALESCE_USE_CQE_MODE_RX, req->use_cqe_mode_rx); + if (req->_present.tx_aggr_max_bytes) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES, req->tx_aggr_max_bytes); + if (req->_present.tx_aggr_max_frames) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES, req->tx_aggr_max_frames); + if (req->_present.tx_aggr_time_usecs) + ynl_attr_put_u32(nlh, ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS, req->tx_aggr_time_usecs); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_PAUSE_GET ============== */ +/* ETHTOOL_MSG_PAUSE_GET - do */ +void ethtool_pause_get_req_free(struct ethtool_pause_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_pause_get_rsp_free(struct ethtool_pause_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_pause_stat_free(&rsp->stats); + free(rsp); +} + +int ethtool_pause_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_pause_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_PAUSE_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_PAUSE_AUTONEG) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.autoneg = 1; + dst->autoneg = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_PAUSE_RX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx = 1; + dst->rx = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_PAUSE_TX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx = 1; + dst->tx = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_PAUSE_STATS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.stats = 1; + + parg.rsp_policy = ðtool_pause_stat_nest; + parg.data = &dst->stats; + if (ethtool_pause_stat_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_PAUSE_STATS_SRC) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.stats_src = 1; + dst->stats_src = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_pause_get_rsp * +ethtool_pause_get(struct ynl_sock *ys, struct ethtool_pause_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_pause_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PAUSE_GET, 1); + ys->req_policy = ðtool_pause_nest; + yrs.yarg.rsp_policy = ðtool_pause_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PAUSE_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_pause_get_rsp_parse; + yrs.rsp_cmd = 22; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_pause_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_PAUSE_GET - dump */ +void ethtool_pause_get_req_dump_free(struct ethtool_pause_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_pause_get_list_free(struct ethtool_pause_get_list *rsp) +{ + struct ethtool_pause_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_pause_stat_free(&rsp->obj.stats); + free(rsp); + } +} + +struct ethtool_pause_get_list * +ethtool_pause_get_dump(struct ynl_sock *ys, + struct ethtool_pause_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_pause_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_pause_get_list); + yds.cb = ethtool_pause_get_rsp_parse; + yds.rsp_cmd = 22; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PAUSE_GET, 1); + ys->req_policy = ðtool_pause_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PAUSE_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_pause_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_PAUSE_GET - notify */ +void ethtool_pause_get_ntf_free(struct ethtool_pause_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_pause_stat_free(&rsp->obj.stats); + free(rsp); +} + +/* ============== ETHTOOL_MSG_PAUSE_SET ============== */ +/* ETHTOOL_MSG_PAUSE_SET - do */ +void ethtool_pause_set_req_free(struct ethtool_pause_set_req *req) +{ + ethtool_header_free(&req->header); + ethtool_pause_stat_free(&req->stats); + free(req); +} + +int ethtool_pause_set(struct ynl_sock *ys, struct ethtool_pause_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PAUSE_SET, 1); + ys->req_policy = ðtool_pause_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PAUSE_HEADER, &req->header); + if (req->_present.autoneg) + ynl_attr_put_u8(nlh, ETHTOOL_A_PAUSE_AUTONEG, req->autoneg); + if (req->_present.rx) + ynl_attr_put_u8(nlh, ETHTOOL_A_PAUSE_RX, req->rx); + if (req->_present.tx) + ynl_attr_put_u8(nlh, ETHTOOL_A_PAUSE_TX, req->tx); + if (req->_present.stats) + ethtool_pause_stat_put(nlh, ETHTOOL_A_PAUSE_STATS, &req->stats); + if (req->_present.stats_src) + ynl_attr_put_u32(nlh, ETHTOOL_A_PAUSE_STATS_SRC, req->stats_src); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_EEE_GET ============== */ +/* ETHTOOL_MSG_EEE_GET - do */ +void ethtool_eee_get_req_free(struct ethtool_eee_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_eee_get_rsp_free(struct ethtool_eee_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_bitset_free(&rsp->modes_ours); + ethtool_bitset_free(&rsp->modes_peer); + free(rsp); +} + +int ethtool_eee_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_eee_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_EEE_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_EEE_MODES_OURS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.modes_ours = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->modes_ours; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_EEE_MODES_PEER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.modes_peer = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->modes_peer; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_EEE_ACTIVE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.active = 1; + dst->active = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_EEE_ENABLED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.enabled = 1; + dst->enabled = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_EEE_TX_LPI_ENABLED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_lpi_enabled = 1; + dst->tx_lpi_enabled = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_EEE_TX_LPI_TIMER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_lpi_timer = 1; + dst->tx_lpi_timer = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_eee_get_rsp * +ethtool_eee_get(struct ynl_sock *ys, struct ethtool_eee_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_eee_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_EEE_GET, 1); + ys->req_policy = ðtool_eee_nest; + yrs.yarg.rsp_policy = ðtool_eee_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_EEE_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_eee_get_rsp_parse; + yrs.rsp_cmd = 24; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_eee_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_EEE_GET - dump */ +void ethtool_eee_get_req_dump_free(struct ethtool_eee_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_eee_get_list_free(struct ethtool_eee_get_list *rsp) +{ + struct ethtool_eee_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.modes_ours); + ethtool_bitset_free(&rsp->obj.modes_peer); + free(rsp); + } +} + +struct ethtool_eee_get_list * +ethtool_eee_get_dump(struct ynl_sock *ys, struct ethtool_eee_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_eee_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_eee_get_list); + yds.cb = ethtool_eee_get_rsp_parse; + yds.rsp_cmd = 24; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_EEE_GET, 1); + ys->req_policy = ðtool_eee_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_EEE_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_eee_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_EEE_GET - notify */ +void ethtool_eee_get_ntf_free(struct ethtool_eee_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.modes_ours); + ethtool_bitset_free(&rsp->obj.modes_peer); + free(rsp); +} + +/* ============== ETHTOOL_MSG_EEE_SET ============== */ +/* ETHTOOL_MSG_EEE_SET - do */ +void ethtool_eee_set_req_free(struct ethtool_eee_set_req *req) +{ + ethtool_header_free(&req->header); + ethtool_bitset_free(&req->modes_ours); + ethtool_bitset_free(&req->modes_peer); + free(req); +} + +int ethtool_eee_set(struct ynl_sock *ys, struct ethtool_eee_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_EEE_SET, 1); + ys->req_policy = ðtool_eee_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_EEE_HEADER, &req->header); + if (req->_present.modes_ours) + ethtool_bitset_put(nlh, ETHTOOL_A_EEE_MODES_OURS, &req->modes_ours); + if (req->_present.modes_peer) + ethtool_bitset_put(nlh, ETHTOOL_A_EEE_MODES_PEER, &req->modes_peer); + if (req->_present.active) + ynl_attr_put_u8(nlh, ETHTOOL_A_EEE_ACTIVE, req->active); + if (req->_present.enabled) + ynl_attr_put_u8(nlh, ETHTOOL_A_EEE_ENABLED, req->enabled); + if (req->_present.tx_lpi_enabled) + ynl_attr_put_u8(nlh, ETHTOOL_A_EEE_TX_LPI_ENABLED, req->tx_lpi_enabled); + if (req->_present.tx_lpi_timer) + ynl_attr_put_u32(nlh, ETHTOOL_A_EEE_TX_LPI_TIMER, req->tx_lpi_timer); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_TSINFO_GET ============== */ +/* ETHTOOL_MSG_TSINFO_GET - do */ +void ethtool_tsinfo_get_req_free(struct ethtool_tsinfo_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_tsinfo_get_rsp_free(struct ethtool_tsinfo_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_bitset_free(&rsp->timestamping); + ethtool_bitset_free(&rsp->tx_types); + ethtool_bitset_free(&rsp->rx_filters); + free(rsp); +} + +int ethtool_tsinfo_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_tsinfo_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_TSINFO_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_TSINFO_TIMESTAMPING) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.timestamping = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->timestamping; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_TSINFO_TX_TYPES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_types = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->tx_types; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_TSINFO_RX_FILTERS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_filters = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->rx_filters; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_TSINFO_PHC_INDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.phc_index = 1; + dst->phc_index = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_tsinfo_get_rsp * +ethtool_tsinfo_get(struct ynl_sock *ys, struct ethtool_tsinfo_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_tsinfo_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_TSINFO_GET, 1); + ys->req_policy = ðtool_tsinfo_nest; + yrs.yarg.rsp_policy = ðtool_tsinfo_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_TSINFO_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_tsinfo_get_rsp_parse; + yrs.rsp_cmd = 26; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_tsinfo_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_TSINFO_GET - dump */ +void ethtool_tsinfo_get_req_dump_free(struct ethtool_tsinfo_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_tsinfo_get_list_free(struct ethtool_tsinfo_get_list *rsp) +{ + struct ethtool_tsinfo_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.timestamping); + ethtool_bitset_free(&rsp->obj.tx_types); + ethtool_bitset_free(&rsp->obj.rx_filters); + free(rsp); + } +} + +struct ethtool_tsinfo_get_list * +ethtool_tsinfo_get_dump(struct ynl_sock *ys, + struct ethtool_tsinfo_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_tsinfo_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_tsinfo_get_list); + yds.cb = ethtool_tsinfo_get_rsp_parse; + yds.rsp_cmd = 26; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_TSINFO_GET, 1); + ys->req_policy = ðtool_tsinfo_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_TSINFO_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_tsinfo_get_list_free(yds.first); + return NULL; +} + +/* ============== ETHTOOL_MSG_CABLE_TEST_ACT ============== */ +/* ETHTOOL_MSG_CABLE_TEST_ACT - do */ +void ethtool_cable_test_act_req_free(struct ethtool_cable_test_act_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_cable_test_act(struct ynl_sock *ys, + struct ethtool_cable_test_act_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_CABLE_TEST_ACT, 1); + ys->req_policy = ðtool_cable_test_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_CABLE_TEST_HEADER, &req->header); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_CABLE_TEST_TDR_ACT ============== */ +/* ETHTOOL_MSG_CABLE_TEST_TDR_ACT - do */ +void +ethtool_cable_test_tdr_act_req_free(struct ethtool_cable_test_tdr_act_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_cable_test_tdr_act(struct ynl_sock *ys, + struct ethtool_cable_test_tdr_act_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_CABLE_TEST_TDR_ACT, 1); + ys->req_policy = ðtool_cable_test_tdr_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_CABLE_TEST_TDR_HEADER, &req->header); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_TUNNEL_INFO_GET ============== */ +/* ETHTOOL_MSG_TUNNEL_INFO_GET - do */ +void ethtool_tunnel_info_get_req_free(struct ethtool_tunnel_info_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_tunnel_info_get_rsp_free(struct ethtool_tunnel_info_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_tunnel_udp_free(&rsp->udp_ports); + free(rsp); +} + +int ethtool_tunnel_info_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_tunnel_info_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_TUNNEL_INFO_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_TUNNEL_INFO_UDP_PORTS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.udp_ports = 1; + + parg.rsp_policy = ðtool_tunnel_udp_nest; + parg.data = &dst->udp_ports; + if (ethtool_tunnel_udp_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_tunnel_info_get_rsp * +ethtool_tunnel_info_get(struct ynl_sock *ys, + struct ethtool_tunnel_info_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_tunnel_info_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_TUNNEL_INFO_GET, 1); + ys->req_policy = ðtool_tunnel_info_nest; + yrs.yarg.rsp_policy = ðtool_tunnel_info_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_TUNNEL_INFO_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_tunnel_info_get_rsp_parse; + yrs.rsp_cmd = 29; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_tunnel_info_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_TUNNEL_INFO_GET - dump */ +void +ethtool_tunnel_info_get_req_dump_free(struct ethtool_tunnel_info_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void +ethtool_tunnel_info_get_list_free(struct ethtool_tunnel_info_get_list *rsp) +{ + struct ethtool_tunnel_info_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_tunnel_udp_free(&rsp->obj.udp_ports); + free(rsp); + } +} + +struct ethtool_tunnel_info_get_list * +ethtool_tunnel_info_get_dump(struct ynl_sock *ys, + struct ethtool_tunnel_info_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_tunnel_info_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_tunnel_info_get_list); + yds.cb = ethtool_tunnel_info_get_rsp_parse; + yds.rsp_cmd = 29; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_TUNNEL_INFO_GET, 1); + ys->req_policy = ðtool_tunnel_info_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_TUNNEL_INFO_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_tunnel_info_get_list_free(yds.first); + return NULL; +} + +/* ============== ETHTOOL_MSG_FEC_GET ============== */ +/* ETHTOOL_MSG_FEC_GET - do */ +void ethtool_fec_get_req_free(struct ethtool_fec_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_fec_get_rsp_free(struct ethtool_fec_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_bitset_free(&rsp->modes); + ethtool_fec_stat_free(&rsp->stats); + free(rsp); +} + +int ethtool_fec_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_fec_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_FEC_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEC_MODES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.modes = 1; + + parg.rsp_policy = ðtool_bitset_nest; + parg.data = &dst->modes; + if (ethtool_bitset_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_FEC_AUTO) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.auto_ = 1; + dst->auto_ = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_FEC_ACTIVE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.active = 1; + dst->active = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_FEC_STATS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.stats = 1; + + parg.rsp_policy = ðtool_fec_stat_nest; + parg.data = &dst->stats; + if (ethtool_fec_stat_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_fec_get_rsp * +ethtool_fec_get(struct ynl_sock *ys, struct ethtool_fec_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_fec_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_FEC_GET, 1); + ys->req_policy = ðtool_fec_nest; + yrs.yarg.rsp_policy = ðtool_fec_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_FEC_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_fec_get_rsp_parse; + yrs.rsp_cmd = 30; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_fec_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_FEC_GET - dump */ +void ethtool_fec_get_req_dump_free(struct ethtool_fec_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_fec_get_list_free(struct ethtool_fec_get_list *rsp) +{ + struct ethtool_fec_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.modes); + ethtool_fec_stat_free(&rsp->obj.stats); + free(rsp); + } +} + +struct ethtool_fec_get_list * +ethtool_fec_get_dump(struct ynl_sock *ys, struct ethtool_fec_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_fec_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_fec_get_list); + yds.cb = ethtool_fec_get_rsp_parse; + yds.rsp_cmd = 30; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_FEC_GET, 1); + ys->req_policy = ðtool_fec_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_FEC_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_fec_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_FEC_GET - notify */ +void ethtool_fec_get_ntf_free(struct ethtool_fec_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_bitset_free(&rsp->obj.modes); + ethtool_fec_stat_free(&rsp->obj.stats); + free(rsp); +} + +/* ============== ETHTOOL_MSG_FEC_SET ============== */ +/* ETHTOOL_MSG_FEC_SET - do */ +void ethtool_fec_set_req_free(struct ethtool_fec_set_req *req) +{ + ethtool_header_free(&req->header); + ethtool_bitset_free(&req->modes); + ethtool_fec_stat_free(&req->stats); + free(req); +} + +int ethtool_fec_set(struct ynl_sock *ys, struct ethtool_fec_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_FEC_SET, 1); + ys->req_policy = ðtool_fec_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_FEC_HEADER, &req->header); + if (req->_present.modes) + ethtool_bitset_put(nlh, ETHTOOL_A_FEC_MODES, &req->modes); + if (req->_present.auto_) + ynl_attr_put_u8(nlh, ETHTOOL_A_FEC_AUTO, req->auto_); + if (req->_present.active) + ynl_attr_put_u32(nlh, ETHTOOL_A_FEC_ACTIVE, req->active); + if (req->_present.stats) + ethtool_fec_stat_put(nlh, ETHTOOL_A_FEC_STATS, &req->stats); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_MODULE_EEPROM_GET ============== */ +/* ETHTOOL_MSG_MODULE_EEPROM_GET - do */ +void +ethtool_module_eeprom_get_req_free(struct ethtool_module_eeprom_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void +ethtool_module_eeprom_get_rsp_free(struct ethtool_module_eeprom_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp->data); + free(rsp); +} + +int ethtool_module_eeprom_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_module_eeprom_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_MODULE_EEPROM_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_MODULE_EEPROM_OFFSET) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.offset = 1; + dst->offset = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_MODULE_EEPROM_LENGTH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.length = 1; + dst->length = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_MODULE_EEPROM_PAGE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.page = 1; + dst->page = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_MODULE_EEPROM_BANK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.bank = 1; + dst->bank = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.i2c_address = 1; + dst->i2c_address = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_MODULE_EEPROM_DATA) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.data_len = len; + dst->data = malloc(len); + memcpy(dst->data, ynl_attr_data(attr), len); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_module_eeprom_get_rsp * +ethtool_module_eeprom_get(struct ynl_sock *ys, + struct ethtool_module_eeprom_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_module_eeprom_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MODULE_EEPROM_GET, 1); + ys->req_policy = ðtool_module_eeprom_nest; + yrs.yarg.rsp_policy = ðtool_module_eeprom_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_MODULE_EEPROM_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_module_eeprom_get_rsp_parse; + yrs.rsp_cmd = 32; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_module_eeprom_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_MODULE_EEPROM_GET - dump */ +void +ethtool_module_eeprom_get_req_dump_free(struct ethtool_module_eeprom_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void +ethtool_module_eeprom_get_list_free(struct ethtool_module_eeprom_get_list *rsp) +{ + struct ethtool_module_eeprom_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp->obj.data); + free(rsp); + } +} + +struct ethtool_module_eeprom_get_list * +ethtool_module_eeprom_get_dump(struct ynl_sock *ys, + struct ethtool_module_eeprom_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_module_eeprom_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_module_eeprom_get_list); + yds.cb = ethtool_module_eeprom_get_rsp_parse; + yds.rsp_cmd = 32; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_MODULE_EEPROM_GET, 1); + ys->req_policy = ðtool_module_eeprom_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_MODULE_EEPROM_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_module_eeprom_get_list_free(yds.first); + return NULL; +} + +/* ============== ETHTOOL_MSG_PHC_VCLOCKS_GET ============== */ +/* ETHTOOL_MSG_PHC_VCLOCKS_GET - do */ +void ethtool_phc_vclocks_get_req_free(struct ethtool_phc_vclocks_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_phc_vclocks_get_rsp_free(struct ethtool_phc_vclocks_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_phc_vclocks_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_phc_vclocks_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_PHC_VCLOCKS_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_PHC_VCLOCKS_NUM) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.num = 1; + dst->num = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_phc_vclocks_get_rsp * +ethtool_phc_vclocks_get(struct ynl_sock *ys, + struct ethtool_phc_vclocks_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_phc_vclocks_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PHC_VCLOCKS_GET, 1); + ys->req_policy = ðtool_phc_vclocks_nest; + yrs.yarg.rsp_policy = ðtool_phc_vclocks_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PHC_VCLOCKS_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_phc_vclocks_get_rsp_parse; + yrs.rsp_cmd = 34; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_phc_vclocks_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_PHC_VCLOCKS_GET - dump */ +void +ethtool_phc_vclocks_get_req_dump_free(struct ethtool_phc_vclocks_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void +ethtool_phc_vclocks_get_list_free(struct ethtool_phc_vclocks_get_list *rsp) +{ + struct ethtool_phc_vclocks_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_phc_vclocks_get_list * +ethtool_phc_vclocks_get_dump(struct ynl_sock *ys, + struct ethtool_phc_vclocks_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_phc_vclocks_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_phc_vclocks_get_list); + yds.cb = ethtool_phc_vclocks_get_rsp_parse; + yds.rsp_cmd = 34; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PHC_VCLOCKS_GET, 1); + ys->req_policy = ðtool_phc_vclocks_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PHC_VCLOCKS_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_phc_vclocks_get_list_free(yds.first); + return NULL; +} + +/* ============== ETHTOOL_MSG_MODULE_GET ============== */ +/* ETHTOOL_MSG_MODULE_GET - do */ +void ethtool_module_get_req_free(struct ethtool_module_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_module_get_rsp_free(struct ethtool_module_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_module_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_module_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_MODULE_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_MODULE_POWER_MODE_POLICY) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.power_mode_policy = 1; + dst->power_mode_policy = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_MODULE_POWER_MODE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.power_mode = 1; + dst->power_mode = ynl_attr_get_u8(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_module_get_rsp * +ethtool_module_get(struct ynl_sock *ys, struct ethtool_module_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_module_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MODULE_GET, 1); + ys->req_policy = ðtool_module_nest; + yrs.yarg.rsp_policy = ðtool_module_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_MODULE_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_module_get_rsp_parse; + yrs.rsp_cmd = 35; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_module_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_MODULE_GET - dump */ +void ethtool_module_get_req_dump_free(struct ethtool_module_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_module_get_list_free(struct ethtool_module_get_list *rsp) +{ + struct ethtool_module_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_module_get_list * +ethtool_module_get_dump(struct ynl_sock *ys, + struct ethtool_module_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_module_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_module_get_list); + yds.cb = ethtool_module_get_rsp_parse; + yds.rsp_cmd = 35; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_MODULE_GET, 1); + ys->req_policy = ðtool_module_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_MODULE_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_module_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_MODULE_GET - notify */ +void ethtool_module_get_ntf_free(struct ethtool_module_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + free(rsp); +} + +/* ============== ETHTOOL_MSG_MODULE_SET ============== */ +/* ETHTOOL_MSG_MODULE_SET - do */ +void ethtool_module_set_req_free(struct ethtool_module_set_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_module_set(struct ynl_sock *ys, struct ethtool_module_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MODULE_SET, 1); + ys->req_policy = ðtool_module_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_MODULE_HEADER, &req->header); + if (req->_present.power_mode_policy) + ynl_attr_put_u8(nlh, ETHTOOL_A_MODULE_POWER_MODE_POLICY, req->power_mode_policy); + if (req->_present.power_mode) + ynl_attr_put_u8(nlh, ETHTOOL_A_MODULE_POWER_MODE, req->power_mode); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_PSE_GET ============== */ +/* ETHTOOL_MSG_PSE_GET - do */ +void ethtool_pse_get_req_free(struct ethtool_pse_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_pse_get_rsp_free(struct ethtool_pse_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_pse_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_pse_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_PSE_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_PODL_PSE_ADMIN_STATE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.admin_state = 1; + dst->admin_state = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PODL_PSE_ADMIN_CONTROL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.admin_control = 1; + dst->admin_control = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PODL_PSE_PW_D_STATUS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pw_d_status = 1; + dst->pw_d_status = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_pse_get_rsp * +ethtool_pse_get(struct ynl_sock *ys, struct ethtool_pse_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_pse_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PSE_GET, 1); + ys->req_policy = ðtool_pse_nest; + yrs.yarg.rsp_policy = ðtool_pse_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PSE_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_pse_get_rsp_parse; + yrs.rsp_cmd = 37; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_pse_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_PSE_GET - dump */ +void ethtool_pse_get_req_dump_free(struct ethtool_pse_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_pse_get_list_free(struct ethtool_pse_get_list *rsp) +{ + struct ethtool_pse_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_pse_get_list * +ethtool_pse_get_dump(struct ynl_sock *ys, struct ethtool_pse_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_pse_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_pse_get_list); + yds.cb = ethtool_pse_get_rsp_parse; + yds.rsp_cmd = 37; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PSE_GET, 1); + ys->req_policy = ðtool_pse_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PSE_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_pse_get_list_free(yds.first); + return NULL; +} + +/* ============== ETHTOOL_MSG_PSE_SET ============== */ +/* ETHTOOL_MSG_PSE_SET - do */ +void ethtool_pse_set_req_free(struct ethtool_pse_set_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_pse_set(struct ynl_sock *ys, struct ethtool_pse_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PSE_SET, 1); + ys->req_policy = ðtool_pse_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PSE_HEADER, &req->header); + if (req->_present.admin_state) + ynl_attr_put_u32(nlh, ETHTOOL_A_PODL_PSE_ADMIN_STATE, req->admin_state); + if (req->_present.admin_control) + ynl_attr_put_u32(nlh, ETHTOOL_A_PODL_PSE_ADMIN_CONTROL, req->admin_control); + if (req->_present.pw_d_status) + ynl_attr_put_u32(nlh, ETHTOOL_A_PODL_PSE_PW_D_STATUS, req->pw_d_status); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_RSS_GET ============== */ +/* ETHTOOL_MSG_RSS_GET - do */ +void ethtool_rss_get_req_free(struct ethtool_rss_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_rss_get_rsp_free(struct ethtool_rss_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp->indir); + free(rsp->hkey); + free(rsp); +} + +int ethtool_rss_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_rss_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_RSS_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_RSS_CONTEXT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.context = 1; + dst->context = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RSS_HFUNC) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.hfunc = 1; + dst->hfunc = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_RSS_INDIR) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.indir_len = len; + dst->indir = malloc(len); + memcpy(dst->indir, ynl_attr_data(attr), len); + } else if (type == ETHTOOL_A_RSS_HKEY) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.hkey_len = len; + dst->hkey = malloc(len); + memcpy(dst->hkey, ynl_attr_data(attr), len); + } else if (type == ETHTOOL_A_RSS_INPUT_XFRM) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.input_xfrm = 1; + dst->input_xfrm = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_rss_get_rsp * +ethtool_rss_get(struct ynl_sock *ys, struct ethtool_rss_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_rss_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_RSS_GET, 1); + ys->req_policy = ðtool_rss_nest; + yrs.yarg.rsp_policy = ðtool_rss_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_RSS_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_rss_get_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_RSS_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_rss_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_RSS_GET - dump */ +void ethtool_rss_get_req_dump_free(struct ethtool_rss_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_rss_get_list_free(struct ethtool_rss_get_list *rsp) +{ + struct ethtool_rss_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp->obj.indir); + free(rsp->obj.hkey); + free(rsp); + } +} + +struct ethtool_rss_get_list * +ethtool_rss_get_dump(struct ynl_sock *ys, struct ethtool_rss_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_rss_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_rss_get_list); + yds.cb = ethtool_rss_get_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_RSS_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_RSS_GET, 1); + ys->req_policy = ðtool_rss_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_RSS_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_rss_get_list_free(yds.first); + return NULL; +} + +/* ============== ETHTOOL_MSG_PLCA_GET_CFG ============== */ +/* ETHTOOL_MSG_PLCA_GET_CFG - do */ +void ethtool_plca_get_cfg_req_free(struct ethtool_plca_get_cfg_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_plca_get_cfg_rsp_free(struct ethtool_plca_get_cfg_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_plca_get_cfg_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_plca_get_cfg_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_PLCA_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_PLCA_VERSION) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.version = 1; + dst->version = ynl_attr_get_u16(attr); + } else if (type == ETHTOOL_A_PLCA_ENABLED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.enabled = 1; + dst->enabled = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_PLCA_STATUS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.status = 1; + dst->status = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_PLCA_NODE_CNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.node_cnt = 1; + dst->node_cnt = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PLCA_NODE_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.node_id = 1; + dst->node_id = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PLCA_TO_TMR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.to_tmr = 1; + dst->to_tmr = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PLCA_BURST_CNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.burst_cnt = 1; + dst->burst_cnt = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PLCA_BURST_TMR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.burst_tmr = 1; + dst->burst_tmr = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_plca_get_cfg_rsp * +ethtool_plca_get_cfg(struct ynl_sock *ys, struct ethtool_plca_get_cfg_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_plca_get_cfg_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PLCA_GET_CFG, 1); + ys->req_policy = ðtool_plca_nest; + yrs.yarg.rsp_policy = ðtool_plca_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_plca_get_cfg_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_PLCA_GET_CFG; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_plca_get_cfg_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_PLCA_GET_CFG - dump */ +void +ethtool_plca_get_cfg_req_dump_free(struct ethtool_plca_get_cfg_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_plca_get_cfg_list_free(struct ethtool_plca_get_cfg_list *rsp) +{ + struct ethtool_plca_get_cfg_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_plca_get_cfg_list * +ethtool_plca_get_cfg_dump(struct ynl_sock *ys, + struct ethtool_plca_get_cfg_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_plca_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_plca_get_cfg_list); + yds.cb = ethtool_plca_get_cfg_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_PLCA_GET_CFG; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PLCA_GET_CFG, 1); + ys->req_policy = ðtool_plca_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_plca_get_cfg_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_PLCA_GET_CFG - notify */ +void ethtool_plca_get_cfg_ntf_free(struct ethtool_plca_get_cfg_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + free(rsp); +} + +/* ============== ETHTOOL_MSG_PLCA_SET_CFG ============== */ +/* ETHTOOL_MSG_PLCA_SET_CFG - do */ +void ethtool_plca_set_cfg_req_free(struct ethtool_plca_set_cfg_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_plca_set_cfg(struct ynl_sock *ys, + struct ethtool_plca_set_cfg_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PLCA_SET_CFG, 1); + ys->req_policy = ðtool_plca_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header); + if (req->_present.version) + ynl_attr_put_u16(nlh, ETHTOOL_A_PLCA_VERSION, req->version); + if (req->_present.enabled) + ynl_attr_put_u8(nlh, ETHTOOL_A_PLCA_ENABLED, req->enabled); + if (req->_present.status) + ynl_attr_put_u8(nlh, ETHTOOL_A_PLCA_STATUS, req->status); + if (req->_present.node_cnt) + ynl_attr_put_u32(nlh, ETHTOOL_A_PLCA_NODE_CNT, req->node_cnt); + if (req->_present.node_id) + ynl_attr_put_u32(nlh, ETHTOOL_A_PLCA_NODE_ID, req->node_id); + if (req->_present.to_tmr) + ynl_attr_put_u32(nlh, ETHTOOL_A_PLCA_TO_TMR, req->to_tmr); + if (req->_present.burst_cnt) + ynl_attr_put_u32(nlh, ETHTOOL_A_PLCA_BURST_CNT, req->burst_cnt); + if (req->_present.burst_tmr) + ynl_attr_put_u32(nlh, ETHTOOL_A_PLCA_BURST_TMR, req->burst_tmr); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== ETHTOOL_MSG_PLCA_GET_STATUS ============== */ +/* ETHTOOL_MSG_PLCA_GET_STATUS - do */ +void ethtool_plca_get_status_req_free(struct ethtool_plca_get_status_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_plca_get_status_rsp_free(struct ethtool_plca_get_status_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + free(rsp); +} + +int ethtool_plca_get_status_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_plca_get_status_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_PLCA_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_PLCA_VERSION) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.version = 1; + dst->version = ynl_attr_get_u16(attr); + } else if (type == ETHTOOL_A_PLCA_ENABLED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.enabled = 1; + dst->enabled = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_PLCA_STATUS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.status = 1; + dst->status = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_PLCA_NODE_CNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.node_cnt = 1; + dst->node_cnt = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PLCA_NODE_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.node_id = 1; + dst->node_id = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PLCA_TO_TMR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.to_tmr = 1; + dst->to_tmr = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PLCA_BURST_CNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.burst_cnt = 1; + dst->burst_cnt = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_PLCA_BURST_TMR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.burst_tmr = 1; + dst->burst_tmr = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_plca_get_status_rsp * +ethtool_plca_get_status(struct ynl_sock *ys, + struct ethtool_plca_get_status_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_plca_get_status_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_PLCA_GET_STATUS, 1); + ys->req_policy = ðtool_plca_nest; + yrs.yarg.rsp_policy = ðtool_plca_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_plca_get_status_rsp_parse; + yrs.rsp_cmd = 40; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_plca_get_status_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_PLCA_GET_STATUS - dump */ +void +ethtool_plca_get_status_req_dump_free(struct ethtool_plca_get_status_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void +ethtool_plca_get_status_list_free(struct ethtool_plca_get_status_list *rsp) +{ + struct ethtool_plca_get_status_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + free(rsp); + } +} + +struct ethtool_plca_get_status_list * +ethtool_plca_get_status_dump(struct ynl_sock *ys, + struct ethtool_plca_get_status_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_plca_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_plca_get_status_list); + yds.cb = ethtool_plca_get_status_rsp_parse; + yds.rsp_cmd = 40; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_PLCA_GET_STATUS, 1); + ys->req_policy = ðtool_plca_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_PLCA_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_plca_get_status_list_free(yds.first); + return NULL; +} + +/* ============== ETHTOOL_MSG_MM_GET ============== */ +/* ETHTOOL_MSG_MM_GET - do */ +void ethtool_mm_get_req_free(struct ethtool_mm_get_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_mm_get_rsp_free(struct ethtool_mm_get_rsp *rsp) +{ + ethtool_header_free(&rsp->header); + ethtool_mm_stat_free(&rsp->stats); + free(rsp); +} + +int ethtool_mm_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_mm_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_MM_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_MM_PMAC_ENABLED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pmac_enabled = 1; + dst->pmac_enabled = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_MM_TX_ENABLED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_enabled = 1; + dst->tx_enabled = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_MM_TX_ACTIVE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_active = 1; + dst->tx_active = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_MM_TX_MIN_FRAG_SIZE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_min_frag_size = 1; + dst->tx_min_frag_size = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_MM_RX_MIN_FRAG_SIZE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_min_frag_size = 1; + dst->rx_min_frag_size = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_MM_VERIFY_ENABLED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.verify_enabled = 1; + dst->verify_enabled = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_MM_VERIFY_TIME) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.verify_time = 1; + dst->verify_time = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_MM_MAX_VERIFY_TIME) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.max_verify_time = 1; + dst->max_verify_time = ynl_attr_get_u32(attr); + } else if (type == ETHTOOL_A_MM_STATS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.stats = 1; + + parg.rsp_policy = ðtool_mm_stat_nest; + parg.data = &dst->stats; + if (ethtool_mm_stat_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ethtool_mm_get_rsp * +ethtool_mm_get(struct ynl_sock *ys, struct ethtool_mm_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ethtool_mm_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MM_GET, 1); + ys->req_policy = ðtool_mm_nest; + yrs.yarg.rsp_policy = ðtool_mm_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_MM_HEADER, &req->header); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ethtool_mm_get_rsp_parse; + yrs.rsp_cmd = ETHTOOL_MSG_MM_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ethtool_mm_get_rsp_free(rsp); + return NULL; +} + +/* ETHTOOL_MSG_MM_GET - dump */ +void ethtool_mm_get_req_dump_free(struct ethtool_mm_get_req_dump *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +void ethtool_mm_get_list_free(struct ethtool_mm_get_list *rsp) +{ + struct ethtool_mm_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ethtool_header_free(&rsp->obj.header); + ethtool_mm_stat_free(&rsp->obj.stats); + free(rsp); + } +} + +struct ethtool_mm_get_list * +ethtool_mm_get_dump(struct ynl_sock *ys, struct ethtool_mm_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = ðtool_mm_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ethtool_mm_get_list); + yds.cb = ethtool_mm_get_rsp_parse; + yds.rsp_cmd = ETHTOOL_MSG_MM_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, ETHTOOL_MSG_MM_GET, 1); + ys->req_policy = ðtool_mm_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_MM_HEADER, &req->header); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ethtool_mm_get_list_free(yds.first); + return NULL; +} + +/* ETHTOOL_MSG_MM_GET - notify */ +void ethtool_mm_get_ntf_free(struct ethtool_mm_get_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_mm_stat_free(&rsp->obj.stats); + free(rsp); +} + +/* ============== ETHTOOL_MSG_MM_SET ============== */ +/* ETHTOOL_MSG_MM_SET - do */ +void ethtool_mm_set_req_free(struct ethtool_mm_set_req *req) +{ + ethtool_header_free(&req->header); + free(req); +} + +int ethtool_mm_set(struct ynl_sock *ys, struct ethtool_mm_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, ETHTOOL_MSG_MM_SET, 1); + ys->req_policy = ðtool_mm_nest; + + if (req->_present.header) + ethtool_header_put(nlh, ETHTOOL_A_MM_HEADER, &req->header); + if (req->_present.verify_enabled) + ynl_attr_put_u8(nlh, ETHTOOL_A_MM_VERIFY_ENABLED, req->verify_enabled); + if (req->_present.verify_time) + ynl_attr_put_u32(nlh, ETHTOOL_A_MM_VERIFY_TIME, req->verify_time); + if (req->_present.tx_enabled) + ynl_attr_put_u8(nlh, ETHTOOL_A_MM_TX_ENABLED, req->tx_enabled); + if (req->_present.pmac_enabled) + ynl_attr_put_u8(nlh, ETHTOOL_A_MM_PMAC_ENABLED, req->pmac_enabled); + if (req->_present.tx_min_frag_size) + ynl_attr_put_u32(nlh, ETHTOOL_A_MM_TX_MIN_FRAG_SIZE, req->tx_min_frag_size); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ETHTOOL_MSG_CABLE_TEST_NTF - event */ +int ethtool_cable_test_ntf_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_cable_test_ntf_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_CABLE_TEST_NTF_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_CABLE_TEST_NTF_STATUS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.status = 1; + dst->status = ynl_attr_get_u8(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +void ethtool_cable_test_ntf_free(struct ethtool_cable_test_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + free(rsp); +} + +/* ETHTOOL_MSG_CABLE_TEST_TDR_NTF - event */ +int ethtool_cable_test_tdr_ntf_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ethtool_cable_test_tdr_ntf_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.header = 1; + + parg.rsp_policy = ðtool_header_nest; + parg.data = &dst->header; + if (ethtool_header_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.status = 1; + dst->status = ynl_attr_get_u8(attr); + } else if (type == ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.nest = 1; + + parg.rsp_policy = ðtool_cable_nest_nest; + parg.data = &dst->nest; + if (ethtool_cable_nest_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +void ethtool_cable_test_tdr_ntf_free(struct ethtool_cable_test_tdr_ntf *rsp) +{ + ethtool_header_free(&rsp->obj.header); + ethtool_cable_nest_free(&rsp->obj.nest); + free(rsp); +} + +static const struct ynl_ntf_info ethtool_ntf_info[] = { + [ETHTOOL_MSG_LINKINFO_NTF] = { + .alloc_sz = sizeof(struct ethtool_linkinfo_get_ntf), + .cb = ethtool_linkinfo_get_rsp_parse, + .policy = ðtool_linkinfo_nest, + .free = (void *)ethtool_linkinfo_get_ntf_free, + }, + [ETHTOOL_MSG_LINKMODES_NTF] = { + .alloc_sz = sizeof(struct ethtool_linkmodes_get_ntf), + .cb = ethtool_linkmodes_get_rsp_parse, + .policy = ðtool_linkmodes_nest, + .free = (void *)ethtool_linkmodes_get_ntf_free, + }, + [ETHTOOL_MSG_DEBUG_NTF] = { + .alloc_sz = sizeof(struct ethtool_debug_get_ntf), + .cb = ethtool_debug_get_rsp_parse, + .policy = ðtool_debug_nest, + .free = (void *)ethtool_debug_get_ntf_free, + }, + [ETHTOOL_MSG_WOL_NTF] = { + .alloc_sz = sizeof(struct ethtool_wol_get_ntf), + .cb = ethtool_wol_get_rsp_parse, + .policy = ðtool_wol_nest, + .free = (void *)ethtool_wol_get_ntf_free, + }, + [ETHTOOL_MSG_FEATURES_NTF] = { + .alloc_sz = sizeof(struct ethtool_features_get_ntf), + .cb = ethtool_features_get_rsp_parse, + .policy = ðtool_features_nest, + .free = (void *)ethtool_features_get_ntf_free, + }, + [ETHTOOL_MSG_PRIVFLAGS_NTF] = { + .alloc_sz = sizeof(struct ethtool_privflags_get_ntf), + .cb = ethtool_privflags_get_rsp_parse, + .policy = ðtool_privflags_nest, + .free = (void *)ethtool_privflags_get_ntf_free, + }, + [ETHTOOL_MSG_RINGS_NTF] = { + .alloc_sz = sizeof(struct ethtool_rings_get_ntf), + .cb = ethtool_rings_get_rsp_parse, + .policy = ðtool_rings_nest, + .free = (void *)ethtool_rings_get_ntf_free, + }, + [ETHTOOL_MSG_CHANNELS_NTF] = { + .alloc_sz = sizeof(struct ethtool_channels_get_ntf), + .cb = ethtool_channels_get_rsp_parse, + .policy = ðtool_channels_nest, + .free = (void *)ethtool_channels_get_ntf_free, + }, + [ETHTOOL_MSG_COALESCE_NTF] = { + .alloc_sz = sizeof(struct ethtool_coalesce_get_ntf), + .cb = ethtool_coalesce_get_rsp_parse, + .policy = ðtool_coalesce_nest, + .free = (void *)ethtool_coalesce_get_ntf_free, + }, + [ETHTOOL_MSG_PAUSE_NTF] = { + .alloc_sz = sizeof(struct ethtool_pause_get_ntf), + .cb = ethtool_pause_get_rsp_parse, + .policy = ðtool_pause_nest, + .free = (void *)ethtool_pause_get_ntf_free, + }, + [ETHTOOL_MSG_EEE_NTF] = { + .alloc_sz = sizeof(struct ethtool_eee_get_ntf), + .cb = ethtool_eee_get_rsp_parse, + .policy = ðtool_eee_nest, + .free = (void *)ethtool_eee_get_ntf_free, + }, + [ETHTOOL_MSG_CABLE_TEST_NTF] = { + .alloc_sz = sizeof(struct ethtool_cable_test_ntf), + .cb = ethtool_cable_test_ntf_rsp_parse, + .policy = ðtool_cable_test_ntf_nest, + .free = (void *)ethtool_cable_test_ntf_free, + }, + [ETHTOOL_MSG_CABLE_TEST_TDR_NTF] = { + .alloc_sz = sizeof(struct ethtool_cable_test_tdr_ntf), + .cb = ethtool_cable_test_tdr_ntf_rsp_parse, + .policy = ðtool_cable_test_tdr_ntf_nest, + .free = (void *)ethtool_cable_test_tdr_ntf_free, + }, + [ETHTOOL_MSG_FEC_NTF] = { + .alloc_sz = sizeof(struct ethtool_fec_get_ntf), + .cb = ethtool_fec_get_rsp_parse, + .policy = ðtool_fec_nest, + .free = (void *)ethtool_fec_get_ntf_free, + }, + [ETHTOOL_MSG_MODULE_NTF] = { + .alloc_sz = sizeof(struct ethtool_module_get_ntf), + .cb = ethtool_module_get_rsp_parse, + .policy = ðtool_module_nest, + .free = (void *)ethtool_module_get_ntf_free, + }, + [ETHTOOL_MSG_PLCA_NTF] = { + .alloc_sz = sizeof(struct ethtool_plca_get_cfg_ntf), + .cb = ethtool_plca_get_cfg_rsp_parse, + .policy = ðtool_plca_nest, + .free = (void *)ethtool_plca_get_cfg_ntf_free, + }, + [ETHTOOL_MSG_MM_NTF] = { + .alloc_sz = sizeof(struct ethtool_mm_get_ntf), + .cb = ethtool_mm_get_rsp_parse, + .policy = ðtool_mm_nest, + .free = (void *)ethtool_mm_get_ntf_free, + }, +}; + +const struct ynl_family ynl_ethtool_family = { + .name = "ethtool", + .hdr_len = sizeof(struct genlmsghdr), + .ntf_info = ethtool_ntf_info, + .ntf_info_size = YNL_ARRAY_SIZE(ethtool_ntf_info), +}; diff --git a/generated/ethtool-user.h b/generated/ethtool-user.h new file mode 100644 index 0000000..ebaf14f --- /dev/null +++ b/generated/ethtool-user.h @@ -0,0 +1,5537 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/ethtool.yaml */ +/* YNL-GEN user header */ +/* YNL-ARG --user-header linux/ethtool_netlink.h --exclude-op stats-get */ + +#ifndef _LINUX_ETHTOOL_GEN_H +#define _LINUX_ETHTOOL_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_ethtool_family; + +/* Enums */ +const char *ethtool_op_str(int op); +const char *ethtool_udp_tunnel_type_str(int value); +const char *ethtool_stringset_str(enum ethtool_stringset value); + +/* Common nested types */ +struct ethtool_header { + struct { + __u32 dev_index:1; + __u32 dev_name_len; + __u32 flags:1; + } _present; + + __u32 dev_index; + char *dev_name; + __u32 flags; +}; + +struct ethtool_pause_stat { + struct { + __u32 tx_frames:1; + __u32 rx_frames:1; + } _present; + + __u64 tx_frames; + __u64 rx_frames; +}; + +struct ethtool_cable_test_tdr_cfg { + struct { + __u32 first:1; + __u32 last:1; + __u32 step:1; + __u32 pair:1; + } _present; + + __u32 first; + __u32 last; + __u32 step; + __u8 pair; +}; + +struct ethtool_fec_stat { + struct { + __u32 corrected_len; + __u32 uncorr_len; + __u32 corr_bits_len; + } _present; + + void *corrected; + void *uncorr; + void *corr_bits; +}; + +struct ethtool_mm_stat { + struct { + __u32 reassembly_errors:1; + __u32 smd_errors:1; + __u32 reassembly_ok:1; + __u32 rx_frag_count:1; + __u32 tx_frag_count:1; + __u32 hold_count:1; + } _present; + + __u64 reassembly_errors; + __u64 smd_errors; + __u64 reassembly_ok; + __u64 rx_frag_count; + __u64 tx_frag_count; + __u64 hold_count; +}; + +struct ethtool_cable_result { + struct { + __u32 pair:1; + __u32 code:1; + } _present; + + __u8 pair; + __u8 code; +}; + +struct ethtool_cable_fault_length { + struct { + __u32 pair:1; + __u32 cm:1; + } _present; + + __u8 pair; + __u32 cm; +}; + +struct ethtool_bitset_bit { + struct { + __u32 index:1; + __u32 name_len; + __u32 value:1; + } _present; + + __u32 index; + char *name; +}; + +struct ethtool_tunnel_udp_entry { + struct { + __u32 port:1; + __u32 type:1; + } _present; + + __u16 port /* big-endian */; + int type; +}; + +struct ethtool_string { + struct { + __u32 index:1; + __u32 value_len; + } _present; + + __u32 index; + char *value; +}; + +struct ethtool_cable_nest { + struct { + __u32 result:1; + __u32 fault_length:1; + } _present; + + struct ethtool_cable_result result; + struct ethtool_cable_fault_length fault_length; +}; + +struct ethtool_bitset_bits { + unsigned int n_bit; + struct ethtool_bitset_bit *bit; +}; + +struct ethtool_strings { + unsigned int n_string; + struct ethtool_string *string; +}; + +struct ethtool_bitset { + struct { + __u32 nomask:1; + __u32 size:1; + __u32 bits:1; + } _present; + + __u32 size; + struct ethtool_bitset_bits bits; +}; + +struct ethtool_stringset_ { + struct { + __u32 id:1; + __u32 count:1; + } _present; + + __u32 id; + __u32 count; + unsigned int n_strings; + struct ethtool_strings *strings; +}; + +struct ethtool_tunnel_udp_table { + struct { + __u32 size:1; + __u32 types:1; + } _present; + + __u32 size; + struct ethtool_bitset types; + unsigned int n_entry; + struct ethtool_tunnel_udp_entry *entry; +}; + +struct ethtool_stringsets { + unsigned int n_stringset; + struct ethtool_stringset_ *stringset; +}; + +struct ethtool_tunnel_udp { + struct { + __u32 table:1; + } _present; + + struct ethtool_tunnel_udp_table table; +}; + +/* ============== ETHTOOL_MSG_STRSET_GET ============== */ +/* ETHTOOL_MSG_STRSET_GET - do */ +struct ethtool_strset_get_req { + struct { + __u32 header:1; + __u32 stringsets:1; + __u32 counts_only:1; + } _present; + + struct ethtool_header header; + struct ethtool_stringsets stringsets; +}; + +static inline struct ethtool_strset_get_req *ethtool_strset_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_strset_get_req)); +} +void ethtool_strset_get_req_free(struct ethtool_strset_get_req *req); + +static inline void +ethtool_strset_get_req_set_header_dev_index(struct ethtool_strset_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_strset_get_req_set_header_dev_name(struct ethtool_strset_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_strset_get_req_set_header_flags(struct ethtool_strset_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +__ethtool_strset_get_req_set_stringsets_stringset(struct ethtool_strset_get_req *req, + struct ethtool_stringset_ *stringset, + unsigned int n_stringset) +{ + free(req->stringsets.stringset); + req->stringsets.stringset = stringset; + req->stringsets.n_stringset = n_stringset; +} +static inline void +ethtool_strset_get_req_set_counts_only(struct ethtool_strset_get_req *req) +{ + req->_present.counts_only = 1; +} + +struct ethtool_strset_get_rsp { + struct { + __u32 header:1; + __u32 stringsets:1; + } _present; + + struct ethtool_header header; + struct ethtool_stringsets stringsets; +}; + +void ethtool_strset_get_rsp_free(struct ethtool_strset_get_rsp *rsp); + +/* + * Get string set from the kernel. + */ +struct ethtool_strset_get_rsp * +ethtool_strset_get(struct ynl_sock *ys, struct ethtool_strset_get_req *req); + +/* ETHTOOL_MSG_STRSET_GET - dump */ +struct ethtool_strset_get_req_dump { + struct { + __u32 header:1; + __u32 stringsets:1; + __u32 counts_only:1; + } _present; + + struct ethtool_header header; + struct ethtool_stringsets stringsets; +}; + +static inline struct ethtool_strset_get_req_dump * +ethtool_strset_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_strset_get_req_dump)); +} +void ethtool_strset_get_req_dump_free(struct ethtool_strset_get_req_dump *req); + +static inline void +ethtool_strset_get_req_dump_set_header_dev_index(struct ethtool_strset_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_strset_get_req_dump_set_header_dev_name(struct ethtool_strset_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_strset_get_req_dump_set_header_flags(struct ethtool_strset_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +__ethtool_strset_get_req_dump_set_stringsets_stringset(struct ethtool_strset_get_req_dump *req, + struct ethtool_stringset_ *stringset, + unsigned int n_stringset) +{ + free(req->stringsets.stringset); + req->stringsets.stringset = stringset; + req->stringsets.n_stringset = n_stringset; +} +static inline void +ethtool_strset_get_req_dump_set_counts_only(struct ethtool_strset_get_req_dump *req) +{ + req->_present.counts_only = 1; +} + +struct ethtool_strset_get_list { + struct ethtool_strset_get_list *next; + struct ethtool_strset_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_strset_get_list_free(struct ethtool_strset_get_list *rsp); + +struct ethtool_strset_get_list * +ethtool_strset_get_dump(struct ynl_sock *ys, + struct ethtool_strset_get_req_dump *req); + +/* ============== ETHTOOL_MSG_LINKINFO_GET ============== */ +/* ETHTOOL_MSG_LINKINFO_GET - do */ +struct ethtool_linkinfo_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_linkinfo_get_req * +ethtool_linkinfo_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_linkinfo_get_req)); +} +void ethtool_linkinfo_get_req_free(struct ethtool_linkinfo_get_req *req); + +static inline void +ethtool_linkinfo_get_req_set_header_dev_index(struct ethtool_linkinfo_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_linkinfo_get_req_set_header_dev_name(struct ethtool_linkinfo_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_linkinfo_get_req_set_header_flags(struct ethtool_linkinfo_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_linkinfo_get_rsp { + struct { + __u32 header:1; + __u32 port:1; + __u32 phyaddr:1; + __u32 tp_mdix:1; + __u32 tp_mdix_ctrl:1; + __u32 transceiver:1; + } _present; + + struct ethtool_header header; + __u8 port; + __u8 phyaddr; + __u8 tp_mdix; + __u8 tp_mdix_ctrl; + __u8 transceiver; +}; + +void ethtool_linkinfo_get_rsp_free(struct ethtool_linkinfo_get_rsp *rsp); + +/* + * Get link info. + */ +struct ethtool_linkinfo_get_rsp * +ethtool_linkinfo_get(struct ynl_sock *ys, struct ethtool_linkinfo_get_req *req); + +/* ETHTOOL_MSG_LINKINFO_GET - dump */ +struct ethtool_linkinfo_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_linkinfo_get_req_dump * +ethtool_linkinfo_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_linkinfo_get_req_dump)); +} +void +ethtool_linkinfo_get_req_dump_free(struct ethtool_linkinfo_get_req_dump *req); + +static inline void +ethtool_linkinfo_get_req_dump_set_header_dev_index(struct ethtool_linkinfo_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_linkinfo_get_req_dump_set_header_dev_name(struct ethtool_linkinfo_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_linkinfo_get_req_dump_set_header_flags(struct ethtool_linkinfo_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_linkinfo_get_list { + struct ethtool_linkinfo_get_list *next; + struct ethtool_linkinfo_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_linkinfo_get_list_free(struct ethtool_linkinfo_get_list *rsp); + +struct ethtool_linkinfo_get_list * +ethtool_linkinfo_get_dump(struct ynl_sock *ys, + struct ethtool_linkinfo_get_req_dump *req); + +/* ETHTOOL_MSG_LINKINFO_GET - notify */ +struct ethtool_linkinfo_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_linkinfo_get_ntf *ntf); + struct ethtool_linkinfo_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_linkinfo_get_ntf_free(struct ethtool_linkinfo_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_LINKINFO_SET ============== */ +/* ETHTOOL_MSG_LINKINFO_SET - do */ +struct ethtool_linkinfo_set_req { + struct { + __u32 header:1; + __u32 port:1; + __u32 phyaddr:1; + __u32 tp_mdix:1; + __u32 tp_mdix_ctrl:1; + __u32 transceiver:1; + } _present; + + struct ethtool_header header; + __u8 port; + __u8 phyaddr; + __u8 tp_mdix; + __u8 tp_mdix_ctrl; + __u8 transceiver; +}; + +static inline struct ethtool_linkinfo_set_req * +ethtool_linkinfo_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_linkinfo_set_req)); +} +void ethtool_linkinfo_set_req_free(struct ethtool_linkinfo_set_req *req); + +static inline void +ethtool_linkinfo_set_req_set_header_dev_index(struct ethtool_linkinfo_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_linkinfo_set_req_set_header_dev_name(struct ethtool_linkinfo_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_linkinfo_set_req_set_header_flags(struct ethtool_linkinfo_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_linkinfo_set_req_set_port(struct ethtool_linkinfo_set_req *req, + __u8 port) +{ + req->_present.port = 1; + req->port = port; +} +static inline void +ethtool_linkinfo_set_req_set_phyaddr(struct ethtool_linkinfo_set_req *req, + __u8 phyaddr) +{ + req->_present.phyaddr = 1; + req->phyaddr = phyaddr; +} +static inline void +ethtool_linkinfo_set_req_set_tp_mdix(struct ethtool_linkinfo_set_req *req, + __u8 tp_mdix) +{ + req->_present.tp_mdix = 1; + req->tp_mdix = tp_mdix; +} +static inline void +ethtool_linkinfo_set_req_set_tp_mdix_ctrl(struct ethtool_linkinfo_set_req *req, + __u8 tp_mdix_ctrl) +{ + req->_present.tp_mdix_ctrl = 1; + req->tp_mdix_ctrl = tp_mdix_ctrl; +} +static inline void +ethtool_linkinfo_set_req_set_transceiver(struct ethtool_linkinfo_set_req *req, + __u8 transceiver) +{ + req->_present.transceiver = 1; + req->transceiver = transceiver; +} + +/* + * Set link info. + */ +int ethtool_linkinfo_set(struct ynl_sock *ys, + struct ethtool_linkinfo_set_req *req); + +/* ============== ETHTOOL_MSG_LINKMODES_GET ============== */ +/* ETHTOOL_MSG_LINKMODES_GET - do */ +struct ethtool_linkmodes_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_linkmodes_get_req * +ethtool_linkmodes_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_linkmodes_get_req)); +} +void ethtool_linkmodes_get_req_free(struct ethtool_linkmodes_get_req *req); + +static inline void +ethtool_linkmodes_get_req_set_header_dev_index(struct ethtool_linkmodes_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_linkmodes_get_req_set_header_dev_name(struct ethtool_linkmodes_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_linkmodes_get_req_set_header_flags(struct ethtool_linkmodes_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_linkmodes_get_rsp { + struct { + __u32 header:1; + __u32 autoneg:1; + __u32 ours:1; + __u32 peer:1; + __u32 speed:1; + __u32 duplex:1; + __u32 master_slave_cfg:1; + __u32 master_slave_state:1; + __u32 lanes:1; + __u32 rate_matching:1; + } _present; + + struct ethtool_header header; + __u8 autoneg; + struct ethtool_bitset ours; + struct ethtool_bitset peer; + __u32 speed; + __u8 duplex; + __u8 master_slave_cfg; + __u8 master_slave_state; + __u32 lanes; + __u8 rate_matching; +}; + +void ethtool_linkmodes_get_rsp_free(struct ethtool_linkmodes_get_rsp *rsp); + +/* + * Get link modes. + */ +struct ethtool_linkmodes_get_rsp * +ethtool_linkmodes_get(struct ynl_sock *ys, + struct ethtool_linkmodes_get_req *req); + +/* ETHTOOL_MSG_LINKMODES_GET - dump */ +struct ethtool_linkmodes_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_linkmodes_get_req_dump * +ethtool_linkmodes_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_linkmodes_get_req_dump)); +} +void +ethtool_linkmodes_get_req_dump_free(struct ethtool_linkmodes_get_req_dump *req); + +static inline void +ethtool_linkmodes_get_req_dump_set_header_dev_index(struct ethtool_linkmodes_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_linkmodes_get_req_dump_set_header_dev_name(struct ethtool_linkmodes_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_linkmodes_get_req_dump_set_header_flags(struct ethtool_linkmodes_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_linkmodes_get_list { + struct ethtool_linkmodes_get_list *next; + struct ethtool_linkmodes_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_linkmodes_get_list_free(struct ethtool_linkmodes_get_list *rsp); + +struct ethtool_linkmodes_get_list * +ethtool_linkmodes_get_dump(struct ynl_sock *ys, + struct ethtool_linkmodes_get_req_dump *req); + +/* ETHTOOL_MSG_LINKMODES_GET - notify */ +struct ethtool_linkmodes_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_linkmodes_get_ntf *ntf); + struct ethtool_linkmodes_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_linkmodes_get_ntf_free(struct ethtool_linkmodes_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_LINKMODES_SET ============== */ +/* ETHTOOL_MSG_LINKMODES_SET - do */ +struct ethtool_linkmodes_set_req { + struct { + __u32 header:1; + __u32 autoneg:1; + __u32 ours:1; + __u32 peer:1; + __u32 speed:1; + __u32 duplex:1; + __u32 master_slave_cfg:1; + __u32 master_slave_state:1; + __u32 lanes:1; + __u32 rate_matching:1; + } _present; + + struct ethtool_header header; + __u8 autoneg; + struct ethtool_bitset ours; + struct ethtool_bitset peer; + __u32 speed; + __u8 duplex; + __u8 master_slave_cfg; + __u8 master_slave_state; + __u32 lanes; + __u8 rate_matching; +}; + +static inline struct ethtool_linkmodes_set_req * +ethtool_linkmodes_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_linkmodes_set_req)); +} +void ethtool_linkmodes_set_req_free(struct ethtool_linkmodes_set_req *req); + +static inline void +ethtool_linkmodes_set_req_set_header_dev_index(struct ethtool_linkmodes_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_linkmodes_set_req_set_header_dev_name(struct ethtool_linkmodes_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_linkmodes_set_req_set_header_flags(struct ethtool_linkmodes_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_linkmodes_set_req_set_autoneg(struct ethtool_linkmodes_set_req *req, + __u8 autoneg) +{ + req->_present.autoneg = 1; + req->autoneg = autoneg; +} +static inline void +ethtool_linkmodes_set_req_set_ours_nomask(struct ethtool_linkmodes_set_req *req) +{ + req->_present.ours = 1; + req->ours._present.nomask = 1; +} +static inline void +ethtool_linkmodes_set_req_set_ours_size(struct ethtool_linkmodes_set_req *req, + __u32 size) +{ + req->_present.ours = 1; + req->ours._present.size = 1; + req->ours.size = size; +} +static inline void +__ethtool_linkmodes_set_req_set_ours_bits_bit(struct ethtool_linkmodes_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->ours.bits.bit); + req->ours.bits.bit = bit; + req->ours.bits.n_bit = n_bit; +} +static inline void +ethtool_linkmodes_set_req_set_peer_nomask(struct ethtool_linkmodes_set_req *req) +{ + req->_present.peer = 1; + req->peer._present.nomask = 1; +} +static inline void +ethtool_linkmodes_set_req_set_peer_size(struct ethtool_linkmodes_set_req *req, + __u32 size) +{ + req->_present.peer = 1; + req->peer._present.size = 1; + req->peer.size = size; +} +static inline void +__ethtool_linkmodes_set_req_set_peer_bits_bit(struct ethtool_linkmodes_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->peer.bits.bit); + req->peer.bits.bit = bit; + req->peer.bits.n_bit = n_bit; +} +static inline void +ethtool_linkmodes_set_req_set_speed(struct ethtool_linkmodes_set_req *req, + __u32 speed) +{ + req->_present.speed = 1; + req->speed = speed; +} +static inline void +ethtool_linkmodes_set_req_set_duplex(struct ethtool_linkmodes_set_req *req, + __u8 duplex) +{ + req->_present.duplex = 1; + req->duplex = duplex; +} +static inline void +ethtool_linkmodes_set_req_set_master_slave_cfg(struct ethtool_linkmodes_set_req *req, + __u8 master_slave_cfg) +{ + req->_present.master_slave_cfg = 1; + req->master_slave_cfg = master_slave_cfg; +} +static inline void +ethtool_linkmodes_set_req_set_master_slave_state(struct ethtool_linkmodes_set_req *req, + __u8 master_slave_state) +{ + req->_present.master_slave_state = 1; + req->master_slave_state = master_slave_state; +} +static inline void +ethtool_linkmodes_set_req_set_lanes(struct ethtool_linkmodes_set_req *req, + __u32 lanes) +{ + req->_present.lanes = 1; + req->lanes = lanes; +} +static inline void +ethtool_linkmodes_set_req_set_rate_matching(struct ethtool_linkmodes_set_req *req, + __u8 rate_matching) +{ + req->_present.rate_matching = 1; + req->rate_matching = rate_matching; +} + +/* + * Set link modes. + */ +int ethtool_linkmodes_set(struct ynl_sock *ys, + struct ethtool_linkmodes_set_req *req); + +/* ============== ETHTOOL_MSG_LINKSTATE_GET ============== */ +/* ETHTOOL_MSG_LINKSTATE_GET - do */ +struct ethtool_linkstate_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_linkstate_get_req * +ethtool_linkstate_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_linkstate_get_req)); +} +void ethtool_linkstate_get_req_free(struct ethtool_linkstate_get_req *req); + +static inline void +ethtool_linkstate_get_req_set_header_dev_index(struct ethtool_linkstate_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_linkstate_get_req_set_header_dev_name(struct ethtool_linkstate_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_linkstate_get_req_set_header_flags(struct ethtool_linkstate_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_linkstate_get_rsp { + struct { + __u32 header:1; + __u32 link:1; + __u32 sqi:1; + __u32 sqi_max:1; + __u32 ext_state:1; + __u32 ext_substate:1; + __u32 ext_down_cnt:1; + } _present; + + struct ethtool_header header; + __u8 link; + __u32 sqi; + __u32 sqi_max; + __u8 ext_state; + __u8 ext_substate; + __u32 ext_down_cnt; +}; + +void ethtool_linkstate_get_rsp_free(struct ethtool_linkstate_get_rsp *rsp); + +/* + * Get link state. + */ +struct ethtool_linkstate_get_rsp * +ethtool_linkstate_get(struct ynl_sock *ys, + struct ethtool_linkstate_get_req *req); + +/* ETHTOOL_MSG_LINKSTATE_GET - dump */ +struct ethtool_linkstate_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_linkstate_get_req_dump * +ethtool_linkstate_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_linkstate_get_req_dump)); +} +void +ethtool_linkstate_get_req_dump_free(struct ethtool_linkstate_get_req_dump *req); + +static inline void +ethtool_linkstate_get_req_dump_set_header_dev_index(struct ethtool_linkstate_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_linkstate_get_req_dump_set_header_dev_name(struct ethtool_linkstate_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_linkstate_get_req_dump_set_header_flags(struct ethtool_linkstate_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_linkstate_get_list { + struct ethtool_linkstate_get_list *next; + struct ethtool_linkstate_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_linkstate_get_list_free(struct ethtool_linkstate_get_list *rsp); + +struct ethtool_linkstate_get_list * +ethtool_linkstate_get_dump(struct ynl_sock *ys, + struct ethtool_linkstate_get_req_dump *req); + +/* ============== ETHTOOL_MSG_DEBUG_GET ============== */ +/* ETHTOOL_MSG_DEBUG_GET - do */ +struct ethtool_debug_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_debug_get_req *ethtool_debug_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_debug_get_req)); +} +void ethtool_debug_get_req_free(struct ethtool_debug_get_req *req); + +static inline void +ethtool_debug_get_req_set_header_dev_index(struct ethtool_debug_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_debug_get_req_set_header_dev_name(struct ethtool_debug_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_debug_get_req_set_header_flags(struct ethtool_debug_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_debug_get_rsp { + struct { + __u32 header:1; + __u32 msgmask:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset msgmask; +}; + +void ethtool_debug_get_rsp_free(struct ethtool_debug_get_rsp *rsp); + +/* + * Get debug message mask. + */ +struct ethtool_debug_get_rsp * +ethtool_debug_get(struct ynl_sock *ys, struct ethtool_debug_get_req *req); + +/* ETHTOOL_MSG_DEBUG_GET - dump */ +struct ethtool_debug_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_debug_get_req_dump * +ethtool_debug_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_debug_get_req_dump)); +} +void ethtool_debug_get_req_dump_free(struct ethtool_debug_get_req_dump *req); + +static inline void +ethtool_debug_get_req_dump_set_header_dev_index(struct ethtool_debug_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_debug_get_req_dump_set_header_dev_name(struct ethtool_debug_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_debug_get_req_dump_set_header_flags(struct ethtool_debug_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_debug_get_list { + struct ethtool_debug_get_list *next; + struct ethtool_debug_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_debug_get_list_free(struct ethtool_debug_get_list *rsp); + +struct ethtool_debug_get_list * +ethtool_debug_get_dump(struct ynl_sock *ys, + struct ethtool_debug_get_req_dump *req); + +/* ETHTOOL_MSG_DEBUG_GET - notify */ +struct ethtool_debug_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_debug_get_ntf *ntf); + struct ethtool_debug_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_debug_get_ntf_free(struct ethtool_debug_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_DEBUG_SET ============== */ +/* ETHTOOL_MSG_DEBUG_SET - do */ +struct ethtool_debug_set_req { + struct { + __u32 header:1; + __u32 msgmask:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset msgmask; +}; + +static inline struct ethtool_debug_set_req *ethtool_debug_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_debug_set_req)); +} +void ethtool_debug_set_req_free(struct ethtool_debug_set_req *req); + +static inline void +ethtool_debug_set_req_set_header_dev_index(struct ethtool_debug_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_debug_set_req_set_header_dev_name(struct ethtool_debug_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_debug_set_req_set_header_flags(struct ethtool_debug_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_debug_set_req_set_msgmask_nomask(struct ethtool_debug_set_req *req) +{ + req->_present.msgmask = 1; + req->msgmask._present.nomask = 1; +} +static inline void +ethtool_debug_set_req_set_msgmask_size(struct ethtool_debug_set_req *req, + __u32 size) +{ + req->_present.msgmask = 1; + req->msgmask._present.size = 1; + req->msgmask.size = size; +} +static inline void +__ethtool_debug_set_req_set_msgmask_bits_bit(struct ethtool_debug_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->msgmask.bits.bit); + req->msgmask.bits.bit = bit; + req->msgmask.bits.n_bit = n_bit; +} + +/* + * Set debug message mask. + */ +int ethtool_debug_set(struct ynl_sock *ys, struct ethtool_debug_set_req *req); + +/* ============== ETHTOOL_MSG_WOL_GET ============== */ +/* ETHTOOL_MSG_WOL_GET - do */ +struct ethtool_wol_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_wol_get_req *ethtool_wol_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_wol_get_req)); +} +void ethtool_wol_get_req_free(struct ethtool_wol_get_req *req); + +static inline void +ethtool_wol_get_req_set_header_dev_index(struct ethtool_wol_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_wol_get_req_set_header_dev_name(struct ethtool_wol_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_wol_get_req_set_header_flags(struct ethtool_wol_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_wol_get_rsp { + struct { + __u32 header:1; + __u32 modes:1; + __u32 sopass_len; + } _present; + + struct ethtool_header header; + struct ethtool_bitset modes; + void *sopass; +}; + +void ethtool_wol_get_rsp_free(struct ethtool_wol_get_rsp *rsp); + +/* + * Get WOL params. + */ +struct ethtool_wol_get_rsp * +ethtool_wol_get(struct ynl_sock *ys, struct ethtool_wol_get_req *req); + +/* ETHTOOL_MSG_WOL_GET - dump */ +struct ethtool_wol_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_wol_get_req_dump * +ethtool_wol_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_wol_get_req_dump)); +} +void ethtool_wol_get_req_dump_free(struct ethtool_wol_get_req_dump *req); + +static inline void +ethtool_wol_get_req_dump_set_header_dev_index(struct ethtool_wol_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_wol_get_req_dump_set_header_dev_name(struct ethtool_wol_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_wol_get_req_dump_set_header_flags(struct ethtool_wol_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_wol_get_list { + struct ethtool_wol_get_list *next; + struct ethtool_wol_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_wol_get_list_free(struct ethtool_wol_get_list *rsp); + +struct ethtool_wol_get_list * +ethtool_wol_get_dump(struct ynl_sock *ys, struct ethtool_wol_get_req_dump *req); + +/* ETHTOOL_MSG_WOL_GET - notify */ +struct ethtool_wol_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_wol_get_ntf *ntf); + struct ethtool_wol_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_wol_get_ntf_free(struct ethtool_wol_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_WOL_SET ============== */ +/* ETHTOOL_MSG_WOL_SET - do */ +struct ethtool_wol_set_req { + struct { + __u32 header:1; + __u32 modes:1; + __u32 sopass_len; + } _present; + + struct ethtool_header header; + struct ethtool_bitset modes; + void *sopass; +}; + +static inline struct ethtool_wol_set_req *ethtool_wol_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_wol_set_req)); +} +void ethtool_wol_set_req_free(struct ethtool_wol_set_req *req); + +static inline void +ethtool_wol_set_req_set_header_dev_index(struct ethtool_wol_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_wol_set_req_set_header_dev_name(struct ethtool_wol_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_wol_set_req_set_header_flags(struct ethtool_wol_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_wol_set_req_set_modes_nomask(struct ethtool_wol_set_req *req) +{ + req->_present.modes = 1; + req->modes._present.nomask = 1; +} +static inline void +ethtool_wol_set_req_set_modes_size(struct ethtool_wol_set_req *req, __u32 size) +{ + req->_present.modes = 1; + req->modes._present.size = 1; + req->modes.size = size; +} +static inline void +__ethtool_wol_set_req_set_modes_bits_bit(struct ethtool_wol_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->modes.bits.bit); + req->modes.bits.bit = bit; + req->modes.bits.n_bit = n_bit; +} +static inline void +ethtool_wol_set_req_set_sopass(struct ethtool_wol_set_req *req, + const void *sopass, size_t len) +{ + free(req->sopass); + req->_present.sopass_len = len; + req->sopass = malloc(req->_present.sopass_len); + memcpy(req->sopass, sopass, req->_present.sopass_len); +} + +/* + * Set WOL params. + */ +int ethtool_wol_set(struct ynl_sock *ys, struct ethtool_wol_set_req *req); + +/* ============== ETHTOOL_MSG_FEATURES_GET ============== */ +/* ETHTOOL_MSG_FEATURES_GET - do */ +struct ethtool_features_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_features_get_req * +ethtool_features_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_features_get_req)); +} +void ethtool_features_get_req_free(struct ethtool_features_get_req *req); + +static inline void +ethtool_features_get_req_set_header_dev_index(struct ethtool_features_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_features_get_req_set_header_dev_name(struct ethtool_features_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_features_get_req_set_header_flags(struct ethtool_features_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_features_get_rsp { + struct { + __u32 header:1; + __u32 hw:1; + __u32 wanted:1; + __u32 active:1; + __u32 nochange:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset hw; + struct ethtool_bitset wanted; + struct ethtool_bitset active; + struct ethtool_bitset nochange; +}; + +void ethtool_features_get_rsp_free(struct ethtool_features_get_rsp *rsp); + +/* + * Get features. + */ +struct ethtool_features_get_rsp * +ethtool_features_get(struct ynl_sock *ys, struct ethtool_features_get_req *req); + +/* ETHTOOL_MSG_FEATURES_GET - dump */ +struct ethtool_features_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_features_get_req_dump * +ethtool_features_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_features_get_req_dump)); +} +void +ethtool_features_get_req_dump_free(struct ethtool_features_get_req_dump *req); + +static inline void +ethtool_features_get_req_dump_set_header_dev_index(struct ethtool_features_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_features_get_req_dump_set_header_dev_name(struct ethtool_features_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_features_get_req_dump_set_header_flags(struct ethtool_features_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_features_get_list { + struct ethtool_features_get_list *next; + struct ethtool_features_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_features_get_list_free(struct ethtool_features_get_list *rsp); + +struct ethtool_features_get_list * +ethtool_features_get_dump(struct ynl_sock *ys, + struct ethtool_features_get_req_dump *req); + +/* ETHTOOL_MSG_FEATURES_GET - notify */ +struct ethtool_features_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_features_get_ntf *ntf); + struct ethtool_features_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_features_get_ntf_free(struct ethtool_features_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_FEATURES_SET ============== */ +/* ETHTOOL_MSG_FEATURES_SET - do */ +struct ethtool_features_set_req { + struct { + __u32 header:1; + __u32 hw:1; + __u32 wanted:1; + __u32 active:1; + __u32 nochange:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset hw; + struct ethtool_bitset wanted; + struct ethtool_bitset active; + struct ethtool_bitset nochange; +}; + +static inline struct ethtool_features_set_req * +ethtool_features_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_features_set_req)); +} +void ethtool_features_set_req_free(struct ethtool_features_set_req *req); + +static inline void +ethtool_features_set_req_set_header_dev_index(struct ethtool_features_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_features_set_req_set_header_dev_name(struct ethtool_features_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_features_set_req_set_header_flags(struct ethtool_features_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_features_set_req_set_hw_nomask(struct ethtool_features_set_req *req) +{ + req->_present.hw = 1; + req->hw._present.nomask = 1; +} +static inline void +ethtool_features_set_req_set_hw_size(struct ethtool_features_set_req *req, + __u32 size) +{ + req->_present.hw = 1; + req->hw._present.size = 1; + req->hw.size = size; +} +static inline void +__ethtool_features_set_req_set_hw_bits_bit(struct ethtool_features_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->hw.bits.bit); + req->hw.bits.bit = bit; + req->hw.bits.n_bit = n_bit; +} +static inline void +ethtool_features_set_req_set_wanted_nomask(struct ethtool_features_set_req *req) +{ + req->_present.wanted = 1; + req->wanted._present.nomask = 1; +} +static inline void +ethtool_features_set_req_set_wanted_size(struct ethtool_features_set_req *req, + __u32 size) +{ + req->_present.wanted = 1; + req->wanted._present.size = 1; + req->wanted.size = size; +} +static inline void +__ethtool_features_set_req_set_wanted_bits_bit(struct ethtool_features_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->wanted.bits.bit); + req->wanted.bits.bit = bit; + req->wanted.bits.n_bit = n_bit; +} +static inline void +ethtool_features_set_req_set_active_nomask(struct ethtool_features_set_req *req) +{ + req->_present.active = 1; + req->active._present.nomask = 1; +} +static inline void +ethtool_features_set_req_set_active_size(struct ethtool_features_set_req *req, + __u32 size) +{ + req->_present.active = 1; + req->active._present.size = 1; + req->active.size = size; +} +static inline void +__ethtool_features_set_req_set_active_bits_bit(struct ethtool_features_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->active.bits.bit); + req->active.bits.bit = bit; + req->active.bits.n_bit = n_bit; +} +static inline void +ethtool_features_set_req_set_nochange_nomask(struct ethtool_features_set_req *req) +{ + req->_present.nochange = 1; + req->nochange._present.nomask = 1; +} +static inline void +ethtool_features_set_req_set_nochange_size(struct ethtool_features_set_req *req, + __u32 size) +{ + req->_present.nochange = 1; + req->nochange._present.size = 1; + req->nochange.size = size; +} +static inline void +__ethtool_features_set_req_set_nochange_bits_bit(struct ethtool_features_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->nochange.bits.bit); + req->nochange.bits.bit = bit; + req->nochange.bits.n_bit = n_bit; +} + +struct ethtool_features_set_rsp { + struct { + __u32 header:1; + __u32 hw:1; + __u32 wanted:1; + __u32 active:1; + __u32 nochange:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset hw; + struct ethtool_bitset wanted; + struct ethtool_bitset active; + struct ethtool_bitset nochange; +}; + +void ethtool_features_set_rsp_free(struct ethtool_features_set_rsp *rsp); + +/* + * Set features. + */ +struct ethtool_features_set_rsp * +ethtool_features_set(struct ynl_sock *ys, struct ethtool_features_set_req *req); + +/* ============== ETHTOOL_MSG_PRIVFLAGS_GET ============== */ +/* ETHTOOL_MSG_PRIVFLAGS_GET - do */ +struct ethtool_privflags_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_privflags_get_req * +ethtool_privflags_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_privflags_get_req)); +} +void ethtool_privflags_get_req_free(struct ethtool_privflags_get_req *req); + +static inline void +ethtool_privflags_get_req_set_header_dev_index(struct ethtool_privflags_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_privflags_get_req_set_header_dev_name(struct ethtool_privflags_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_privflags_get_req_set_header_flags(struct ethtool_privflags_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_privflags_get_rsp { + struct { + __u32 header:1; + __u32 flags:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset flags; +}; + +void ethtool_privflags_get_rsp_free(struct ethtool_privflags_get_rsp *rsp); + +/* + * Get device private flags. + */ +struct ethtool_privflags_get_rsp * +ethtool_privflags_get(struct ynl_sock *ys, + struct ethtool_privflags_get_req *req); + +/* ETHTOOL_MSG_PRIVFLAGS_GET - dump */ +struct ethtool_privflags_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_privflags_get_req_dump * +ethtool_privflags_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_privflags_get_req_dump)); +} +void +ethtool_privflags_get_req_dump_free(struct ethtool_privflags_get_req_dump *req); + +static inline void +ethtool_privflags_get_req_dump_set_header_dev_index(struct ethtool_privflags_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_privflags_get_req_dump_set_header_dev_name(struct ethtool_privflags_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_privflags_get_req_dump_set_header_flags(struct ethtool_privflags_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_privflags_get_list { + struct ethtool_privflags_get_list *next; + struct ethtool_privflags_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_privflags_get_list_free(struct ethtool_privflags_get_list *rsp); + +struct ethtool_privflags_get_list * +ethtool_privflags_get_dump(struct ynl_sock *ys, + struct ethtool_privflags_get_req_dump *req); + +/* ETHTOOL_MSG_PRIVFLAGS_GET - notify */ +struct ethtool_privflags_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_privflags_get_ntf *ntf); + struct ethtool_privflags_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_privflags_get_ntf_free(struct ethtool_privflags_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_PRIVFLAGS_SET ============== */ +/* ETHTOOL_MSG_PRIVFLAGS_SET - do */ +struct ethtool_privflags_set_req { + struct { + __u32 header:1; + __u32 flags:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset flags; +}; + +static inline struct ethtool_privflags_set_req * +ethtool_privflags_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_privflags_set_req)); +} +void ethtool_privflags_set_req_free(struct ethtool_privflags_set_req *req); + +static inline void +ethtool_privflags_set_req_set_header_dev_index(struct ethtool_privflags_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_privflags_set_req_set_header_dev_name(struct ethtool_privflags_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_privflags_set_req_set_header_flags(struct ethtool_privflags_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_privflags_set_req_set_flags_nomask(struct ethtool_privflags_set_req *req) +{ + req->_present.flags = 1; + req->flags._present.nomask = 1; +} +static inline void +ethtool_privflags_set_req_set_flags_size(struct ethtool_privflags_set_req *req, + __u32 size) +{ + req->_present.flags = 1; + req->flags._present.size = 1; + req->flags.size = size; +} +static inline void +__ethtool_privflags_set_req_set_flags_bits_bit(struct ethtool_privflags_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->flags.bits.bit); + req->flags.bits.bit = bit; + req->flags.bits.n_bit = n_bit; +} + +/* + * Set device private flags. + */ +int ethtool_privflags_set(struct ynl_sock *ys, + struct ethtool_privflags_set_req *req); + +/* ============== ETHTOOL_MSG_RINGS_GET ============== */ +/* ETHTOOL_MSG_RINGS_GET - do */ +struct ethtool_rings_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_rings_get_req *ethtool_rings_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_rings_get_req)); +} +void ethtool_rings_get_req_free(struct ethtool_rings_get_req *req); + +static inline void +ethtool_rings_get_req_set_header_dev_index(struct ethtool_rings_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_rings_get_req_set_header_dev_name(struct ethtool_rings_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_rings_get_req_set_header_flags(struct ethtool_rings_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_rings_get_rsp { + struct { + __u32 header:1; + __u32 rx_max:1; + __u32 rx_mini_max:1; + __u32 rx_jumbo_max:1; + __u32 tx_max:1; + __u32 rx:1; + __u32 rx_mini:1; + __u32 rx_jumbo:1; + __u32 tx:1; + __u32 rx_buf_len:1; + __u32 tcp_data_split:1; + __u32 cqe_size:1; + __u32 tx_push:1; + __u32 rx_push:1; + __u32 tx_push_buf_len:1; + __u32 tx_push_buf_len_max:1; + } _present; + + struct ethtool_header header; + __u32 rx_max; + __u32 rx_mini_max; + __u32 rx_jumbo_max; + __u32 tx_max; + __u32 rx; + __u32 rx_mini; + __u32 rx_jumbo; + __u32 tx; + __u32 rx_buf_len; + __u8 tcp_data_split; + __u32 cqe_size; + __u8 tx_push; + __u8 rx_push; + __u32 tx_push_buf_len; + __u32 tx_push_buf_len_max; +}; + +void ethtool_rings_get_rsp_free(struct ethtool_rings_get_rsp *rsp); + +/* + * Get ring params. + */ +struct ethtool_rings_get_rsp * +ethtool_rings_get(struct ynl_sock *ys, struct ethtool_rings_get_req *req); + +/* ETHTOOL_MSG_RINGS_GET - dump */ +struct ethtool_rings_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_rings_get_req_dump * +ethtool_rings_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_rings_get_req_dump)); +} +void ethtool_rings_get_req_dump_free(struct ethtool_rings_get_req_dump *req); + +static inline void +ethtool_rings_get_req_dump_set_header_dev_index(struct ethtool_rings_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_rings_get_req_dump_set_header_dev_name(struct ethtool_rings_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_rings_get_req_dump_set_header_flags(struct ethtool_rings_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_rings_get_list { + struct ethtool_rings_get_list *next; + struct ethtool_rings_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_rings_get_list_free(struct ethtool_rings_get_list *rsp); + +struct ethtool_rings_get_list * +ethtool_rings_get_dump(struct ynl_sock *ys, + struct ethtool_rings_get_req_dump *req); + +/* ETHTOOL_MSG_RINGS_GET - notify */ +struct ethtool_rings_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_rings_get_ntf *ntf); + struct ethtool_rings_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_rings_get_ntf_free(struct ethtool_rings_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_RINGS_SET ============== */ +/* ETHTOOL_MSG_RINGS_SET - do */ +struct ethtool_rings_set_req { + struct { + __u32 header:1; + __u32 rx_max:1; + __u32 rx_mini_max:1; + __u32 rx_jumbo_max:1; + __u32 tx_max:1; + __u32 rx:1; + __u32 rx_mini:1; + __u32 rx_jumbo:1; + __u32 tx:1; + __u32 rx_buf_len:1; + __u32 tcp_data_split:1; + __u32 cqe_size:1; + __u32 tx_push:1; + __u32 rx_push:1; + __u32 tx_push_buf_len:1; + __u32 tx_push_buf_len_max:1; + } _present; + + struct ethtool_header header; + __u32 rx_max; + __u32 rx_mini_max; + __u32 rx_jumbo_max; + __u32 tx_max; + __u32 rx; + __u32 rx_mini; + __u32 rx_jumbo; + __u32 tx; + __u32 rx_buf_len; + __u8 tcp_data_split; + __u32 cqe_size; + __u8 tx_push; + __u8 rx_push; + __u32 tx_push_buf_len; + __u32 tx_push_buf_len_max; +}; + +static inline struct ethtool_rings_set_req *ethtool_rings_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_rings_set_req)); +} +void ethtool_rings_set_req_free(struct ethtool_rings_set_req *req); + +static inline void +ethtool_rings_set_req_set_header_dev_index(struct ethtool_rings_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_rings_set_req_set_header_dev_name(struct ethtool_rings_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_rings_set_req_set_header_flags(struct ethtool_rings_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_rings_set_req_set_rx_max(struct ethtool_rings_set_req *req, + __u32 rx_max) +{ + req->_present.rx_max = 1; + req->rx_max = rx_max; +} +static inline void +ethtool_rings_set_req_set_rx_mini_max(struct ethtool_rings_set_req *req, + __u32 rx_mini_max) +{ + req->_present.rx_mini_max = 1; + req->rx_mini_max = rx_mini_max; +} +static inline void +ethtool_rings_set_req_set_rx_jumbo_max(struct ethtool_rings_set_req *req, + __u32 rx_jumbo_max) +{ + req->_present.rx_jumbo_max = 1; + req->rx_jumbo_max = rx_jumbo_max; +} +static inline void +ethtool_rings_set_req_set_tx_max(struct ethtool_rings_set_req *req, + __u32 tx_max) +{ + req->_present.tx_max = 1; + req->tx_max = tx_max; +} +static inline void +ethtool_rings_set_req_set_rx(struct ethtool_rings_set_req *req, __u32 rx) +{ + req->_present.rx = 1; + req->rx = rx; +} +static inline void +ethtool_rings_set_req_set_rx_mini(struct ethtool_rings_set_req *req, + __u32 rx_mini) +{ + req->_present.rx_mini = 1; + req->rx_mini = rx_mini; +} +static inline void +ethtool_rings_set_req_set_rx_jumbo(struct ethtool_rings_set_req *req, + __u32 rx_jumbo) +{ + req->_present.rx_jumbo = 1; + req->rx_jumbo = rx_jumbo; +} +static inline void +ethtool_rings_set_req_set_tx(struct ethtool_rings_set_req *req, __u32 tx) +{ + req->_present.tx = 1; + req->tx = tx; +} +static inline void +ethtool_rings_set_req_set_rx_buf_len(struct ethtool_rings_set_req *req, + __u32 rx_buf_len) +{ + req->_present.rx_buf_len = 1; + req->rx_buf_len = rx_buf_len; +} +static inline void +ethtool_rings_set_req_set_tcp_data_split(struct ethtool_rings_set_req *req, + __u8 tcp_data_split) +{ + req->_present.tcp_data_split = 1; + req->tcp_data_split = tcp_data_split; +} +static inline void +ethtool_rings_set_req_set_cqe_size(struct ethtool_rings_set_req *req, + __u32 cqe_size) +{ + req->_present.cqe_size = 1; + req->cqe_size = cqe_size; +} +static inline void +ethtool_rings_set_req_set_tx_push(struct ethtool_rings_set_req *req, + __u8 tx_push) +{ + req->_present.tx_push = 1; + req->tx_push = tx_push; +} +static inline void +ethtool_rings_set_req_set_rx_push(struct ethtool_rings_set_req *req, + __u8 rx_push) +{ + req->_present.rx_push = 1; + req->rx_push = rx_push; +} +static inline void +ethtool_rings_set_req_set_tx_push_buf_len(struct ethtool_rings_set_req *req, + __u32 tx_push_buf_len) +{ + req->_present.tx_push_buf_len = 1; + req->tx_push_buf_len = tx_push_buf_len; +} +static inline void +ethtool_rings_set_req_set_tx_push_buf_len_max(struct ethtool_rings_set_req *req, + __u32 tx_push_buf_len_max) +{ + req->_present.tx_push_buf_len_max = 1; + req->tx_push_buf_len_max = tx_push_buf_len_max; +} + +/* + * Set ring params. + */ +int ethtool_rings_set(struct ynl_sock *ys, struct ethtool_rings_set_req *req); + +/* ============== ETHTOOL_MSG_CHANNELS_GET ============== */ +/* ETHTOOL_MSG_CHANNELS_GET - do */ +struct ethtool_channels_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_channels_get_req * +ethtool_channels_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_channels_get_req)); +} +void ethtool_channels_get_req_free(struct ethtool_channels_get_req *req); + +static inline void +ethtool_channels_get_req_set_header_dev_index(struct ethtool_channels_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_channels_get_req_set_header_dev_name(struct ethtool_channels_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_channels_get_req_set_header_flags(struct ethtool_channels_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_channels_get_rsp { + struct { + __u32 header:1; + __u32 rx_max:1; + __u32 tx_max:1; + __u32 other_max:1; + __u32 combined_max:1; + __u32 rx_count:1; + __u32 tx_count:1; + __u32 other_count:1; + __u32 combined_count:1; + } _present; + + struct ethtool_header header; + __u32 rx_max; + __u32 tx_max; + __u32 other_max; + __u32 combined_max; + __u32 rx_count; + __u32 tx_count; + __u32 other_count; + __u32 combined_count; +}; + +void ethtool_channels_get_rsp_free(struct ethtool_channels_get_rsp *rsp); + +/* + * Get channel params. + */ +struct ethtool_channels_get_rsp * +ethtool_channels_get(struct ynl_sock *ys, struct ethtool_channels_get_req *req); + +/* ETHTOOL_MSG_CHANNELS_GET - dump */ +struct ethtool_channels_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_channels_get_req_dump * +ethtool_channels_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_channels_get_req_dump)); +} +void +ethtool_channels_get_req_dump_free(struct ethtool_channels_get_req_dump *req); + +static inline void +ethtool_channels_get_req_dump_set_header_dev_index(struct ethtool_channels_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_channels_get_req_dump_set_header_dev_name(struct ethtool_channels_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_channels_get_req_dump_set_header_flags(struct ethtool_channels_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_channels_get_list { + struct ethtool_channels_get_list *next; + struct ethtool_channels_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_channels_get_list_free(struct ethtool_channels_get_list *rsp); + +struct ethtool_channels_get_list * +ethtool_channels_get_dump(struct ynl_sock *ys, + struct ethtool_channels_get_req_dump *req); + +/* ETHTOOL_MSG_CHANNELS_GET - notify */ +struct ethtool_channels_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_channels_get_ntf *ntf); + struct ethtool_channels_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_channels_get_ntf_free(struct ethtool_channels_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_CHANNELS_SET ============== */ +/* ETHTOOL_MSG_CHANNELS_SET - do */ +struct ethtool_channels_set_req { + struct { + __u32 header:1; + __u32 rx_max:1; + __u32 tx_max:1; + __u32 other_max:1; + __u32 combined_max:1; + __u32 rx_count:1; + __u32 tx_count:1; + __u32 other_count:1; + __u32 combined_count:1; + } _present; + + struct ethtool_header header; + __u32 rx_max; + __u32 tx_max; + __u32 other_max; + __u32 combined_max; + __u32 rx_count; + __u32 tx_count; + __u32 other_count; + __u32 combined_count; +}; + +static inline struct ethtool_channels_set_req * +ethtool_channels_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_channels_set_req)); +} +void ethtool_channels_set_req_free(struct ethtool_channels_set_req *req); + +static inline void +ethtool_channels_set_req_set_header_dev_index(struct ethtool_channels_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_channels_set_req_set_header_dev_name(struct ethtool_channels_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_channels_set_req_set_header_flags(struct ethtool_channels_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_channels_set_req_set_rx_max(struct ethtool_channels_set_req *req, + __u32 rx_max) +{ + req->_present.rx_max = 1; + req->rx_max = rx_max; +} +static inline void +ethtool_channels_set_req_set_tx_max(struct ethtool_channels_set_req *req, + __u32 tx_max) +{ + req->_present.tx_max = 1; + req->tx_max = tx_max; +} +static inline void +ethtool_channels_set_req_set_other_max(struct ethtool_channels_set_req *req, + __u32 other_max) +{ + req->_present.other_max = 1; + req->other_max = other_max; +} +static inline void +ethtool_channels_set_req_set_combined_max(struct ethtool_channels_set_req *req, + __u32 combined_max) +{ + req->_present.combined_max = 1; + req->combined_max = combined_max; +} +static inline void +ethtool_channels_set_req_set_rx_count(struct ethtool_channels_set_req *req, + __u32 rx_count) +{ + req->_present.rx_count = 1; + req->rx_count = rx_count; +} +static inline void +ethtool_channels_set_req_set_tx_count(struct ethtool_channels_set_req *req, + __u32 tx_count) +{ + req->_present.tx_count = 1; + req->tx_count = tx_count; +} +static inline void +ethtool_channels_set_req_set_other_count(struct ethtool_channels_set_req *req, + __u32 other_count) +{ + req->_present.other_count = 1; + req->other_count = other_count; +} +static inline void +ethtool_channels_set_req_set_combined_count(struct ethtool_channels_set_req *req, + __u32 combined_count) +{ + req->_present.combined_count = 1; + req->combined_count = combined_count; +} + +/* + * Set channel params. + */ +int ethtool_channels_set(struct ynl_sock *ys, + struct ethtool_channels_set_req *req); + +/* ============== ETHTOOL_MSG_COALESCE_GET ============== */ +/* ETHTOOL_MSG_COALESCE_GET - do */ +struct ethtool_coalesce_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_coalesce_get_req * +ethtool_coalesce_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_coalesce_get_req)); +} +void ethtool_coalesce_get_req_free(struct ethtool_coalesce_get_req *req); + +static inline void +ethtool_coalesce_get_req_set_header_dev_index(struct ethtool_coalesce_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_coalesce_get_req_set_header_dev_name(struct ethtool_coalesce_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_coalesce_get_req_set_header_flags(struct ethtool_coalesce_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_coalesce_get_rsp { + struct { + __u32 header:1; + __u32 rx_usecs:1; + __u32 rx_max_frames:1; + __u32 rx_usecs_irq:1; + __u32 rx_max_frames_irq:1; + __u32 tx_usecs:1; + __u32 tx_max_frames:1; + __u32 tx_usecs_irq:1; + __u32 tx_max_frames_irq:1; + __u32 stats_block_usecs:1; + __u32 use_adaptive_rx:1; + __u32 use_adaptive_tx:1; + __u32 pkt_rate_low:1; + __u32 rx_usecs_low:1; + __u32 rx_max_frames_low:1; + __u32 tx_usecs_low:1; + __u32 tx_max_frames_low:1; + __u32 pkt_rate_high:1; + __u32 rx_usecs_high:1; + __u32 rx_max_frames_high:1; + __u32 tx_usecs_high:1; + __u32 tx_max_frames_high:1; + __u32 rate_sample_interval:1; + __u32 use_cqe_mode_tx:1; + __u32 use_cqe_mode_rx:1; + __u32 tx_aggr_max_bytes:1; + __u32 tx_aggr_max_frames:1; + __u32 tx_aggr_time_usecs:1; + } _present; + + struct ethtool_header header; + __u32 rx_usecs; + __u32 rx_max_frames; + __u32 rx_usecs_irq; + __u32 rx_max_frames_irq; + __u32 tx_usecs; + __u32 tx_max_frames; + __u32 tx_usecs_irq; + __u32 tx_max_frames_irq; + __u32 stats_block_usecs; + __u8 use_adaptive_rx; + __u8 use_adaptive_tx; + __u32 pkt_rate_low; + __u32 rx_usecs_low; + __u32 rx_max_frames_low; + __u32 tx_usecs_low; + __u32 tx_max_frames_low; + __u32 pkt_rate_high; + __u32 rx_usecs_high; + __u32 rx_max_frames_high; + __u32 tx_usecs_high; + __u32 tx_max_frames_high; + __u32 rate_sample_interval; + __u8 use_cqe_mode_tx; + __u8 use_cqe_mode_rx; + __u32 tx_aggr_max_bytes; + __u32 tx_aggr_max_frames; + __u32 tx_aggr_time_usecs; +}; + +void ethtool_coalesce_get_rsp_free(struct ethtool_coalesce_get_rsp *rsp); + +/* + * Get coalesce params. + */ +struct ethtool_coalesce_get_rsp * +ethtool_coalesce_get(struct ynl_sock *ys, struct ethtool_coalesce_get_req *req); + +/* ETHTOOL_MSG_COALESCE_GET - dump */ +struct ethtool_coalesce_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_coalesce_get_req_dump * +ethtool_coalesce_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_coalesce_get_req_dump)); +} +void +ethtool_coalesce_get_req_dump_free(struct ethtool_coalesce_get_req_dump *req); + +static inline void +ethtool_coalesce_get_req_dump_set_header_dev_index(struct ethtool_coalesce_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_coalesce_get_req_dump_set_header_dev_name(struct ethtool_coalesce_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_coalesce_get_req_dump_set_header_flags(struct ethtool_coalesce_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_coalesce_get_list { + struct ethtool_coalesce_get_list *next; + struct ethtool_coalesce_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_coalesce_get_list_free(struct ethtool_coalesce_get_list *rsp); + +struct ethtool_coalesce_get_list * +ethtool_coalesce_get_dump(struct ynl_sock *ys, + struct ethtool_coalesce_get_req_dump *req); + +/* ETHTOOL_MSG_COALESCE_GET - notify */ +struct ethtool_coalesce_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_coalesce_get_ntf *ntf); + struct ethtool_coalesce_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_coalesce_get_ntf_free(struct ethtool_coalesce_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_COALESCE_SET ============== */ +/* ETHTOOL_MSG_COALESCE_SET - do */ +struct ethtool_coalesce_set_req { + struct { + __u32 header:1; + __u32 rx_usecs:1; + __u32 rx_max_frames:1; + __u32 rx_usecs_irq:1; + __u32 rx_max_frames_irq:1; + __u32 tx_usecs:1; + __u32 tx_max_frames:1; + __u32 tx_usecs_irq:1; + __u32 tx_max_frames_irq:1; + __u32 stats_block_usecs:1; + __u32 use_adaptive_rx:1; + __u32 use_adaptive_tx:1; + __u32 pkt_rate_low:1; + __u32 rx_usecs_low:1; + __u32 rx_max_frames_low:1; + __u32 tx_usecs_low:1; + __u32 tx_max_frames_low:1; + __u32 pkt_rate_high:1; + __u32 rx_usecs_high:1; + __u32 rx_max_frames_high:1; + __u32 tx_usecs_high:1; + __u32 tx_max_frames_high:1; + __u32 rate_sample_interval:1; + __u32 use_cqe_mode_tx:1; + __u32 use_cqe_mode_rx:1; + __u32 tx_aggr_max_bytes:1; + __u32 tx_aggr_max_frames:1; + __u32 tx_aggr_time_usecs:1; + } _present; + + struct ethtool_header header; + __u32 rx_usecs; + __u32 rx_max_frames; + __u32 rx_usecs_irq; + __u32 rx_max_frames_irq; + __u32 tx_usecs; + __u32 tx_max_frames; + __u32 tx_usecs_irq; + __u32 tx_max_frames_irq; + __u32 stats_block_usecs; + __u8 use_adaptive_rx; + __u8 use_adaptive_tx; + __u32 pkt_rate_low; + __u32 rx_usecs_low; + __u32 rx_max_frames_low; + __u32 tx_usecs_low; + __u32 tx_max_frames_low; + __u32 pkt_rate_high; + __u32 rx_usecs_high; + __u32 rx_max_frames_high; + __u32 tx_usecs_high; + __u32 tx_max_frames_high; + __u32 rate_sample_interval; + __u8 use_cqe_mode_tx; + __u8 use_cqe_mode_rx; + __u32 tx_aggr_max_bytes; + __u32 tx_aggr_max_frames; + __u32 tx_aggr_time_usecs; +}; + +static inline struct ethtool_coalesce_set_req * +ethtool_coalesce_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_coalesce_set_req)); +} +void ethtool_coalesce_set_req_free(struct ethtool_coalesce_set_req *req); + +static inline void +ethtool_coalesce_set_req_set_header_dev_index(struct ethtool_coalesce_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_coalesce_set_req_set_header_dev_name(struct ethtool_coalesce_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_coalesce_set_req_set_header_flags(struct ethtool_coalesce_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_coalesce_set_req_set_rx_usecs(struct ethtool_coalesce_set_req *req, + __u32 rx_usecs) +{ + req->_present.rx_usecs = 1; + req->rx_usecs = rx_usecs; +} +static inline void +ethtool_coalesce_set_req_set_rx_max_frames(struct ethtool_coalesce_set_req *req, + __u32 rx_max_frames) +{ + req->_present.rx_max_frames = 1; + req->rx_max_frames = rx_max_frames; +} +static inline void +ethtool_coalesce_set_req_set_rx_usecs_irq(struct ethtool_coalesce_set_req *req, + __u32 rx_usecs_irq) +{ + req->_present.rx_usecs_irq = 1; + req->rx_usecs_irq = rx_usecs_irq; +} +static inline void +ethtool_coalesce_set_req_set_rx_max_frames_irq(struct ethtool_coalesce_set_req *req, + __u32 rx_max_frames_irq) +{ + req->_present.rx_max_frames_irq = 1; + req->rx_max_frames_irq = rx_max_frames_irq; +} +static inline void +ethtool_coalesce_set_req_set_tx_usecs(struct ethtool_coalesce_set_req *req, + __u32 tx_usecs) +{ + req->_present.tx_usecs = 1; + req->tx_usecs = tx_usecs; +} +static inline void +ethtool_coalesce_set_req_set_tx_max_frames(struct ethtool_coalesce_set_req *req, + __u32 tx_max_frames) +{ + req->_present.tx_max_frames = 1; + req->tx_max_frames = tx_max_frames; +} +static inline void +ethtool_coalesce_set_req_set_tx_usecs_irq(struct ethtool_coalesce_set_req *req, + __u32 tx_usecs_irq) +{ + req->_present.tx_usecs_irq = 1; + req->tx_usecs_irq = tx_usecs_irq; +} +static inline void +ethtool_coalesce_set_req_set_tx_max_frames_irq(struct ethtool_coalesce_set_req *req, + __u32 tx_max_frames_irq) +{ + req->_present.tx_max_frames_irq = 1; + req->tx_max_frames_irq = tx_max_frames_irq; +} +static inline void +ethtool_coalesce_set_req_set_stats_block_usecs(struct ethtool_coalesce_set_req *req, + __u32 stats_block_usecs) +{ + req->_present.stats_block_usecs = 1; + req->stats_block_usecs = stats_block_usecs; +} +static inline void +ethtool_coalesce_set_req_set_use_adaptive_rx(struct ethtool_coalesce_set_req *req, + __u8 use_adaptive_rx) +{ + req->_present.use_adaptive_rx = 1; + req->use_adaptive_rx = use_adaptive_rx; +} +static inline void +ethtool_coalesce_set_req_set_use_adaptive_tx(struct ethtool_coalesce_set_req *req, + __u8 use_adaptive_tx) +{ + req->_present.use_adaptive_tx = 1; + req->use_adaptive_tx = use_adaptive_tx; +} +static inline void +ethtool_coalesce_set_req_set_pkt_rate_low(struct ethtool_coalesce_set_req *req, + __u32 pkt_rate_low) +{ + req->_present.pkt_rate_low = 1; + req->pkt_rate_low = pkt_rate_low; +} +static inline void +ethtool_coalesce_set_req_set_rx_usecs_low(struct ethtool_coalesce_set_req *req, + __u32 rx_usecs_low) +{ + req->_present.rx_usecs_low = 1; + req->rx_usecs_low = rx_usecs_low; +} +static inline void +ethtool_coalesce_set_req_set_rx_max_frames_low(struct ethtool_coalesce_set_req *req, + __u32 rx_max_frames_low) +{ + req->_present.rx_max_frames_low = 1; + req->rx_max_frames_low = rx_max_frames_low; +} +static inline void +ethtool_coalesce_set_req_set_tx_usecs_low(struct ethtool_coalesce_set_req *req, + __u32 tx_usecs_low) +{ + req->_present.tx_usecs_low = 1; + req->tx_usecs_low = tx_usecs_low; +} +static inline void +ethtool_coalesce_set_req_set_tx_max_frames_low(struct ethtool_coalesce_set_req *req, + __u32 tx_max_frames_low) +{ + req->_present.tx_max_frames_low = 1; + req->tx_max_frames_low = tx_max_frames_low; +} +static inline void +ethtool_coalesce_set_req_set_pkt_rate_high(struct ethtool_coalesce_set_req *req, + __u32 pkt_rate_high) +{ + req->_present.pkt_rate_high = 1; + req->pkt_rate_high = pkt_rate_high; +} +static inline void +ethtool_coalesce_set_req_set_rx_usecs_high(struct ethtool_coalesce_set_req *req, + __u32 rx_usecs_high) +{ + req->_present.rx_usecs_high = 1; + req->rx_usecs_high = rx_usecs_high; +} +static inline void +ethtool_coalesce_set_req_set_rx_max_frames_high(struct ethtool_coalesce_set_req *req, + __u32 rx_max_frames_high) +{ + req->_present.rx_max_frames_high = 1; + req->rx_max_frames_high = rx_max_frames_high; +} +static inline void +ethtool_coalesce_set_req_set_tx_usecs_high(struct ethtool_coalesce_set_req *req, + __u32 tx_usecs_high) +{ + req->_present.tx_usecs_high = 1; + req->tx_usecs_high = tx_usecs_high; +} +static inline void +ethtool_coalesce_set_req_set_tx_max_frames_high(struct ethtool_coalesce_set_req *req, + __u32 tx_max_frames_high) +{ + req->_present.tx_max_frames_high = 1; + req->tx_max_frames_high = tx_max_frames_high; +} +static inline void +ethtool_coalesce_set_req_set_rate_sample_interval(struct ethtool_coalesce_set_req *req, + __u32 rate_sample_interval) +{ + req->_present.rate_sample_interval = 1; + req->rate_sample_interval = rate_sample_interval; +} +static inline void +ethtool_coalesce_set_req_set_use_cqe_mode_tx(struct ethtool_coalesce_set_req *req, + __u8 use_cqe_mode_tx) +{ + req->_present.use_cqe_mode_tx = 1; + req->use_cqe_mode_tx = use_cqe_mode_tx; +} +static inline void +ethtool_coalesce_set_req_set_use_cqe_mode_rx(struct ethtool_coalesce_set_req *req, + __u8 use_cqe_mode_rx) +{ + req->_present.use_cqe_mode_rx = 1; + req->use_cqe_mode_rx = use_cqe_mode_rx; +} +static inline void +ethtool_coalesce_set_req_set_tx_aggr_max_bytes(struct ethtool_coalesce_set_req *req, + __u32 tx_aggr_max_bytes) +{ + req->_present.tx_aggr_max_bytes = 1; + req->tx_aggr_max_bytes = tx_aggr_max_bytes; +} +static inline void +ethtool_coalesce_set_req_set_tx_aggr_max_frames(struct ethtool_coalesce_set_req *req, + __u32 tx_aggr_max_frames) +{ + req->_present.tx_aggr_max_frames = 1; + req->tx_aggr_max_frames = tx_aggr_max_frames; +} +static inline void +ethtool_coalesce_set_req_set_tx_aggr_time_usecs(struct ethtool_coalesce_set_req *req, + __u32 tx_aggr_time_usecs) +{ + req->_present.tx_aggr_time_usecs = 1; + req->tx_aggr_time_usecs = tx_aggr_time_usecs; +} + +/* + * Set coalesce params. + */ +int ethtool_coalesce_set(struct ynl_sock *ys, + struct ethtool_coalesce_set_req *req); + +/* ============== ETHTOOL_MSG_PAUSE_GET ============== */ +/* ETHTOOL_MSG_PAUSE_GET - do */ +struct ethtool_pause_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_pause_get_req *ethtool_pause_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_pause_get_req)); +} +void ethtool_pause_get_req_free(struct ethtool_pause_get_req *req); + +static inline void +ethtool_pause_get_req_set_header_dev_index(struct ethtool_pause_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_pause_get_req_set_header_dev_name(struct ethtool_pause_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_pause_get_req_set_header_flags(struct ethtool_pause_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_pause_get_rsp { + struct { + __u32 header:1; + __u32 autoneg:1; + __u32 rx:1; + __u32 tx:1; + __u32 stats:1; + __u32 stats_src:1; + } _present; + + struct ethtool_header header; + __u8 autoneg; + __u8 rx; + __u8 tx; + struct ethtool_pause_stat stats; + __u32 stats_src; +}; + +void ethtool_pause_get_rsp_free(struct ethtool_pause_get_rsp *rsp); + +/* + * Get pause params. + */ +struct ethtool_pause_get_rsp * +ethtool_pause_get(struct ynl_sock *ys, struct ethtool_pause_get_req *req); + +/* ETHTOOL_MSG_PAUSE_GET - dump */ +struct ethtool_pause_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_pause_get_req_dump * +ethtool_pause_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_pause_get_req_dump)); +} +void ethtool_pause_get_req_dump_free(struct ethtool_pause_get_req_dump *req); + +static inline void +ethtool_pause_get_req_dump_set_header_dev_index(struct ethtool_pause_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_pause_get_req_dump_set_header_dev_name(struct ethtool_pause_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_pause_get_req_dump_set_header_flags(struct ethtool_pause_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_pause_get_list { + struct ethtool_pause_get_list *next; + struct ethtool_pause_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_pause_get_list_free(struct ethtool_pause_get_list *rsp); + +struct ethtool_pause_get_list * +ethtool_pause_get_dump(struct ynl_sock *ys, + struct ethtool_pause_get_req_dump *req); + +/* ETHTOOL_MSG_PAUSE_GET - notify */ +struct ethtool_pause_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_pause_get_ntf *ntf); + struct ethtool_pause_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_pause_get_ntf_free(struct ethtool_pause_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_PAUSE_SET ============== */ +/* ETHTOOL_MSG_PAUSE_SET - do */ +struct ethtool_pause_set_req { + struct { + __u32 header:1; + __u32 autoneg:1; + __u32 rx:1; + __u32 tx:1; + __u32 stats:1; + __u32 stats_src:1; + } _present; + + struct ethtool_header header; + __u8 autoneg; + __u8 rx; + __u8 tx; + struct ethtool_pause_stat stats; + __u32 stats_src; +}; + +static inline struct ethtool_pause_set_req *ethtool_pause_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_pause_set_req)); +} +void ethtool_pause_set_req_free(struct ethtool_pause_set_req *req); + +static inline void +ethtool_pause_set_req_set_header_dev_index(struct ethtool_pause_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_pause_set_req_set_header_dev_name(struct ethtool_pause_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_pause_set_req_set_header_flags(struct ethtool_pause_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_pause_set_req_set_autoneg(struct ethtool_pause_set_req *req, + __u8 autoneg) +{ + req->_present.autoneg = 1; + req->autoneg = autoneg; +} +static inline void +ethtool_pause_set_req_set_rx(struct ethtool_pause_set_req *req, __u8 rx) +{ + req->_present.rx = 1; + req->rx = rx; +} +static inline void +ethtool_pause_set_req_set_tx(struct ethtool_pause_set_req *req, __u8 tx) +{ + req->_present.tx = 1; + req->tx = tx; +} +static inline void +ethtool_pause_set_req_set_stats_tx_frames(struct ethtool_pause_set_req *req, + __u64 tx_frames) +{ + req->_present.stats = 1; + req->stats._present.tx_frames = 1; + req->stats.tx_frames = tx_frames; +} +static inline void +ethtool_pause_set_req_set_stats_rx_frames(struct ethtool_pause_set_req *req, + __u64 rx_frames) +{ + req->_present.stats = 1; + req->stats._present.rx_frames = 1; + req->stats.rx_frames = rx_frames; +} +static inline void +ethtool_pause_set_req_set_stats_src(struct ethtool_pause_set_req *req, + __u32 stats_src) +{ + req->_present.stats_src = 1; + req->stats_src = stats_src; +} + +/* + * Set pause params. + */ +int ethtool_pause_set(struct ynl_sock *ys, struct ethtool_pause_set_req *req); + +/* ============== ETHTOOL_MSG_EEE_GET ============== */ +/* ETHTOOL_MSG_EEE_GET - do */ +struct ethtool_eee_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_eee_get_req *ethtool_eee_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_eee_get_req)); +} +void ethtool_eee_get_req_free(struct ethtool_eee_get_req *req); + +static inline void +ethtool_eee_get_req_set_header_dev_index(struct ethtool_eee_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_eee_get_req_set_header_dev_name(struct ethtool_eee_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_eee_get_req_set_header_flags(struct ethtool_eee_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_eee_get_rsp { + struct { + __u32 header:1; + __u32 modes_ours:1; + __u32 modes_peer:1; + __u32 active:1; + __u32 enabled:1; + __u32 tx_lpi_enabled:1; + __u32 tx_lpi_timer:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset modes_ours; + struct ethtool_bitset modes_peer; + __u8 active; + __u8 enabled; + __u8 tx_lpi_enabled; + __u32 tx_lpi_timer; +}; + +void ethtool_eee_get_rsp_free(struct ethtool_eee_get_rsp *rsp); + +/* + * Get eee params. + */ +struct ethtool_eee_get_rsp * +ethtool_eee_get(struct ynl_sock *ys, struct ethtool_eee_get_req *req); + +/* ETHTOOL_MSG_EEE_GET - dump */ +struct ethtool_eee_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_eee_get_req_dump * +ethtool_eee_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_eee_get_req_dump)); +} +void ethtool_eee_get_req_dump_free(struct ethtool_eee_get_req_dump *req); + +static inline void +ethtool_eee_get_req_dump_set_header_dev_index(struct ethtool_eee_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_eee_get_req_dump_set_header_dev_name(struct ethtool_eee_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_eee_get_req_dump_set_header_flags(struct ethtool_eee_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_eee_get_list { + struct ethtool_eee_get_list *next; + struct ethtool_eee_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_eee_get_list_free(struct ethtool_eee_get_list *rsp); + +struct ethtool_eee_get_list * +ethtool_eee_get_dump(struct ynl_sock *ys, struct ethtool_eee_get_req_dump *req); + +/* ETHTOOL_MSG_EEE_GET - notify */ +struct ethtool_eee_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_eee_get_ntf *ntf); + struct ethtool_eee_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_eee_get_ntf_free(struct ethtool_eee_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_EEE_SET ============== */ +/* ETHTOOL_MSG_EEE_SET - do */ +struct ethtool_eee_set_req { + struct { + __u32 header:1; + __u32 modes_ours:1; + __u32 modes_peer:1; + __u32 active:1; + __u32 enabled:1; + __u32 tx_lpi_enabled:1; + __u32 tx_lpi_timer:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset modes_ours; + struct ethtool_bitset modes_peer; + __u8 active; + __u8 enabled; + __u8 tx_lpi_enabled; + __u32 tx_lpi_timer; +}; + +static inline struct ethtool_eee_set_req *ethtool_eee_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_eee_set_req)); +} +void ethtool_eee_set_req_free(struct ethtool_eee_set_req *req); + +static inline void +ethtool_eee_set_req_set_header_dev_index(struct ethtool_eee_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_eee_set_req_set_header_dev_name(struct ethtool_eee_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_eee_set_req_set_header_flags(struct ethtool_eee_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_eee_set_req_set_modes_ours_nomask(struct ethtool_eee_set_req *req) +{ + req->_present.modes_ours = 1; + req->modes_ours._present.nomask = 1; +} +static inline void +ethtool_eee_set_req_set_modes_ours_size(struct ethtool_eee_set_req *req, + __u32 size) +{ + req->_present.modes_ours = 1; + req->modes_ours._present.size = 1; + req->modes_ours.size = size; +} +static inline void +__ethtool_eee_set_req_set_modes_ours_bits_bit(struct ethtool_eee_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->modes_ours.bits.bit); + req->modes_ours.bits.bit = bit; + req->modes_ours.bits.n_bit = n_bit; +} +static inline void +ethtool_eee_set_req_set_modes_peer_nomask(struct ethtool_eee_set_req *req) +{ + req->_present.modes_peer = 1; + req->modes_peer._present.nomask = 1; +} +static inline void +ethtool_eee_set_req_set_modes_peer_size(struct ethtool_eee_set_req *req, + __u32 size) +{ + req->_present.modes_peer = 1; + req->modes_peer._present.size = 1; + req->modes_peer.size = size; +} +static inline void +__ethtool_eee_set_req_set_modes_peer_bits_bit(struct ethtool_eee_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->modes_peer.bits.bit); + req->modes_peer.bits.bit = bit; + req->modes_peer.bits.n_bit = n_bit; +} +static inline void +ethtool_eee_set_req_set_active(struct ethtool_eee_set_req *req, __u8 active) +{ + req->_present.active = 1; + req->active = active; +} +static inline void +ethtool_eee_set_req_set_enabled(struct ethtool_eee_set_req *req, __u8 enabled) +{ + req->_present.enabled = 1; + req->enabled = enabled; +} +static inline void +ethtool_eee_set_req_set_tx_lpi_enabled(struct ethtool_eee_set_req *req, + __u8 tx_lpi_enabled) +{ + req->_present.tx_lpi_enabled = 1; + req->tx_lpi_enabled = tx_lpi_enabled; +} +static inline void +ethtool_eee_set_req_set_tx_lpi_timer(struct ethtool_eee_set_req *req, + __u32 tx_lpi_timer) +{ + req->_present.tx_lpi_timer = 1; + req->tx_lpi_timer = tx_lpi_timer; +} + +/* + * Set eee params. + */ +int ethtool_eee_set(struct ynl_sock *ys, struct ethtool_eee_set_req *req); + +/* ============== ETHTOOL_MSG_TSINFO_GET ============== */ +/* ETHTOOL_MSG_TSINFO_GET - do */ +struct ethtool_tsinfo_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_tsinfo_get_req *ethtool_tsinfo_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_tsinfo_get_req)); +} +void ethtool_tsinfo_get_req_free(struct ethtool_tsinfo_get_req *req); + +static inline void +ethtool_tsinfo_get_req_set_header_dev_index(struct ethtool_tsinfo_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_tsinfo_get_req_set_header_dev_name(struct ethtool_tsinfo_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_tsinfo_get_req_set_header_flags(struct ethtool_tsinfo_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_tsinfo_get_rsp { + struct { + __u32 header:1; + __u32 timestamping:1; + __u32 tx_types:1; + __u32 rx_filters:1; + __u32 phc_index:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset timestamping; + struct ethtool_bitset tx_types; + struct ethtool_bitset rx_filters; + __u32 phc_index; +}; + +void ethtool_tsinfo_get_rsp_free(struct ethtool_tsinfo_get_rsp *rsp); + +/* + * Get tsinfo params. + */ +struct ethtool_tsinfo_get_rsp * +ethtool_tsinfo_get(struct ynl_sock *ys, struct ethtool_tsinfo_get_req *req); + +/* ETHTOOL_MSG_TSINFO_GET - dump */ +struct ethtool_tsinfo_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_tsinfo_get_req_dump * +ethtool_tsinfo_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_tsinfo_get_req_dump)); +} +void ethtool_tsinfo_get_req_dump_free(struct ethtool_tsinfo_get_req_dump *req); + +static inline void +ethtool_tsinfo_get_req_dump_set_header_dev_index(struct ethtool_tsinfo_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_tsinfo_get_req_dump_set_header_dev_name(struct ethtool_tsinfo_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_tsinfo_get_req_dump_set_header_flags(struct ethtool_tsinfo_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_tsinfo_get_list { + struct ethtool_tsinfo_get_list *next; + struct ethtool_tsinfo_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_tsinfo_get_list_free(struct ethtool_tsinfo_get_list *rsp); + +struct ethtool_tsinfo_get_list * +ethtool_tsinfo_get_dump(struct ynl_sock *ys, + struct ethtool_tsinfo_get_req_dump *req); + +/* ============== ETHTOOL_MSG_CABLE_TEST_ACT ============== */ +/* ETHTOOL_MSG_CABLE_TEST_ACT - do */ +struct ethtool_cable_test_act_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_cable_test_act_req * +ethtool_cable_test_act_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_cable_test_act_req)); +} +void ethtool_cable_test_act_req_free(struct ethtool_cable_test_act_req *req); + +static inline void +ethtool_cable_test_act_req_set_header_dev_index(struct ethtool_cable_test_act_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_cable_test_act_req_set_header_dev_name(struct ethtool_cable_test_act_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_cable_test_act_req_set_header_flags(struct ethtool_cable_test_act_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +/* + * Cable test. + */ +int ethtool_cable_test_act(struct ynl_sock *ys, + struct ethtool_cable_test_act_req *req); + +/* ============== ETHTOOL_MSG_CABLE_TEST_TDR_ACT ============== */ +/* ETHTOOL_MSG_CABLE_TEST_TDR_ACT - do */ +struct ethtool_cable_test_tdr_act_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_cable_test_tdr_act_req * +ethtool_cable_test_tdr_act_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_cable_test_tdr_act_req)); +} +void +ethtool_cable_test_tdr_act_req_free(struct ethtool_cable_test_tdr_act_req *req); + +static inline void +ethtool_cable_test_tdr_act_req_set_header_dev_index(struct ethtool_cable_test_tdr_act_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_cable_test_tdr_act_req_set_header_dev_name(struct ethtool_cable_test_tdr_act_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_cable_test_tdr_act_req_set_header_flags(struct ethtool_cable_test_tdr_act_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +/* + * Cable test TDR. + */ +int ethtool_cable_test_tdr_act(struct ynl_sock *ys, + struct ethtool_cable_test_tdr_act_req *req); + +/* ============== ETHTOOL_MSG_TUNNEL_INFO_GET ============== */ +/* ETHTOOL_MSG_TUNNEL_INFO_GET - do */ +struct ethtool_tunnel_info_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_tunnel_info_get_req * +ethtool_tunnel_info_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_tunnel_info_get_req)); +} +void ethtool_tunnel_info_get_req_free(struct ethtool_tunnel_info_get_req *req); + +static inline void +ethtool_tunnel_info_get_req_set_header_dev_index(struct ethtool_tunnel_info_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_tunnel_info_get_req_set_header_dev_name(struct ethtool_tunnel_info_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_tunnel_info_get_req_set_header_flags(struct ethtool_tunnel_info_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_tunnel_info_get_rsp { + struct { + __u32 header:1; + __u32 udp_ports:1; + } _present; + + struct ethtool_header header; + struct ethtool_tunnel_udp udp_ports; +}; + +void ethtool_tunnel_info_get_rsp_free(struct ethtool_tunnel_info_get_rsp *rsp); + +/* + * Get tsinfo params. + */ +struct ethtool_tunnel_info_get_rsp * +ethtool_tunnel_info_get(struct ynl_sock *ys, + struct ethtool_tunnel_info_get_req *req); + +/* ETHTOOL_MSG_TUNNEL_INFO_GET - dump */ +struct ethtool_tunnel_info_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_tunnel_info_get_req_dump * +ethtool_tunnel_info_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_tunnel_info_get_req_dump)); +} +void +ethtool_tunnel_info_get_req_dump_free(struct ethtool_tunnel_info_get_req_dump *req); + +static inline void +ethtool_tunnel_info_get_req_dump_set_header_dev_index(struct ethtool_tunnel_info_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_tunnel_info_get_req_dump_set_header_dev_name(struct ethtool_tunnel_info_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_tunnel_info_get_req_dump_set_header_flags(struct ethtool_tunnel_info_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_tunnel_info_get_list { + struct ethtool_tunnel_info_get_list *next; + struct ethtool_tunnel_info_get_rsp obj __attribute__((aligned(8))); +}; + +void +ethtool_tunnel_info_get_list_free(struct ethtool_tunnel_info_get_list *rsp); + +struct ethtool_tunnel_info_get_list * +ethtool_tunnel_info_get_dump(struct ynl_sock *ys, + struct ethtool_tunnel_info_get_req_dump *req); + +/* ============== ETHTOOL_MSG_FEC_GET ============== */ +/* ETHTOOL_MSG_FEC_GET - do */ +struct ethtool_fec_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_fec_get_req *ethtool_fec_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_fec_get_req)); +} +void ethtool_fec_get_req_free(struct ethtool_fec_get_req *req); + +static inline void +ethtool_fec_get_req_set_header_dev_index(struct ethtool_fec_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_fec_get_req_set_header_dev_name(struct ethtool_fec_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_fec_get_req_set_header_flags(struct ethtool_fec_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_fec_get_rsp { + struct { + __u32 header:1; + __u32 modes:1; + __u32 auto_:1; + __u32 active:1; + __u32 stats:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset modes; + __u8 auto_; + __u32 active; + struct ethtool_fec_stat stats; +}; + +void ethtool_fec_get_rsp_free(struct ethtool_fec_get_rsp *rsp); + +/* + * Get FEC params. + */ +struct ethtool_fec_get_rsp * +ethtool_fec_get(struct ynl_sock *ys, struct ethtool_fec_get_req *req); + +/* ETHTOOL_MSG_FEC_GET - dump */ +struct ethtool_fec_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_fec_get_req_dump * +ethtool_fec_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_fec_get_req_dump)); +} +void ethtool_fec_get_req_dump_free(struct ethtool_fec_get_req_dump *req); + +static inline void +ethtool_fec_get_req_dump_set_header_dev_index(struct ethtool_fec_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_fec_get_req_dump_set_header_dev_name(struct ethtool_fec_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_fec_get_req_dump_set_header_flags(struct ethtool_fec_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_fec_get_list { + struct ethtool_fec_get_list *next; + struct ethtool_fec_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_fec_get_list_free(struct ethtool_fec_get_list *rsp); + +struct ethtool_fec_get_list * +ethtool_fec_get_dump(struct ynl_sock *ys, struct ethtool_fec_get_req_dump *req); + +/* ETHTOOL_MSG_FEC_GET - notify */ +struct ethtool_fec_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_fec_get_ntf *ntf); + struct ethtool_fec_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_fec_get_ntf_free(struct ethtool_fec_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_FEC_SET ============== */ +/* ETHTOOL_MSG_FEC_SET - do */ +struct ethtool_fec_set_req { + struct { + __u32 header:1; + __u32 modes:1; + __u32 auto_:1; + __u32 active:1; + __u32 stats:1; + } _present; + + struct ethtool_header header; + struct ethtool_bitset modes; + __u8 auto_; + __u32 active; + struct ethtool_fec_stat stats; +}; + +static inline struct ethtool_fec_set_req *ethtool_fec_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_fec_set_req)); +} +void ethtool_fec_set_req_free(struct ethtool_fec_set_req *req); + +static inline void +ethtool_fec_set_req_set_header_dev_index(struct ethtool_fec_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_fec_set_req_set_header_dev_name(struct ethtool_fec_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_fec_set_req_set_header_flags(struct ethtool_fec_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_fec_set_req_set_modes_nomask(struct ethtool_fec_set_req *req) +{ + req->_present.modes = 1; + req->modes._present.nomask = 1; +} +static inline void +ethtool_fec_set_req_set_modes_size(struct ethtool_fec_set_req *req, __u32 size) +{ + req->_present.modes = 1; + req->modes._present.size = 1; + req->modes.size = size; +} +static inline void +__ethtool_fec_set_req_set_modes_bits_bit(struct ethtool_fec_set_req *req, + struct ethtool_bitset_bit *bit, + unsigned int n_bit) +{ + free(req->modes.bits.bit); + req->modes.bits.bit = bit; + req->modes.bits.n_bit = n_bit; +} +static inline void +ethtool_fec_set_req_set_auto_(struct ethtool_fec_set_req *req, __u8 auto_) +{ + req->_present.auto_ = 1; + req->auto_ = auto_; +} +static inline void +ethtool_fec_set_req_set_active(struct ethtool_fec_set_req *req, __u32 active) +{ + req->_present.active = 1; + req->active = active; +} +static inline void +ethtool_fec_set_req_set_stats_corrected(struct ethtool_fec_set_req *req, + const void *corrected, size_t len) +{ + free(req->stats.corrected); + req->stats._present.corrected_len = len; + req->stats.corrected = malloc(req->stats._present.corrected_len); + memcpy(req->stats.corrected, corrected, req->stats._present.corrected_len); +} +static inline void +ethtool_fec_set_req_set_stats_uncorr(struct ethtool_fec_set_req *req, + const void *uncorr, size_t len) +{ + free(req->stats.uncorr); + req->stats._present.uncorr_len = len; + req->stats.uncorr = malloc(req->stats._present.uncorr_len); + memcpy(req->stats.uncorr, uncorr, req->stats._present.uncorr_len); +} +static inline void +ethtool_fec_set_req_set_stats_corr_bits(struct ethtool_fec_set_req *req, + const void *corr_bits, size_t len) +{ + free(req->stats.corr_bits); + req->stats._present.corr_bits_len = len; + req->stats.corr_bits = malloc(req->stats._present.corr_bits_len); + memcpy(req->stats.corr_bits, corr_bits, req->stats._present.corr_bits_len); +} + +/* + * Set FEC params. + */ +int ethtool_fec_set(struct ynl_sock *ys, struct ethtool_fec_set_req *req); + +/* ============== ETHTOOL_MSG_MODULE_EEPROM_GET ============== */ +/* ETHTOOL_MSG_MODULE_EEPROM_GET - do */ +struct ethtool_module_eeprom_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_module_eeprom_get_req * +ethtool_module_eeprom_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_module_eeprom_get_req)); +} +void +ethtool_module_eeprom_get_req_free(struct ethtool_module_eeprom_get_req *req); + +static inline void +ethtool_module_eeprom_get_req_set_header_dev_index(struct ethtool_module_eeprom_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_module_eeprom_get_req_set_header_dev_name(struct ethtool_module_eeprom_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_module_eeprom_get_req_set_header_flags(struct ethtool_module_eeprom_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_module_eeprom_get_rsp { + struct { + __u32 header:1; + __u32 offset:1; + __u32 length:1; + __u32 page:1; + __u32 bank:1; + __u32 i2c_address:1; + __u32 data_len; + } _present; + + struct ethtool_header header; + __u32 offset; + __u32 length; + __u8 page; + __u8 bank; + __u8 i2c_address; + void *data; +}; + +void +ethtool_module_eeprom_get_rsp_free(struct ethtool_module_eeprom_get_rsp *rsp); + +/* + * Get module EEPROM params. + */ +struct ethtool_module_eeprom_get_rsp * +ethtool_module_eeprom_get(struct ynl_sock *ys, + struct ethtool_module_eeprom_get_req *req); + +/* ETHTOOL_MSG_MODULE_EEPROM_GET - dump */ +struct ethtool_module_eeprom_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_module_eeprom_get_req_dump * +ethtool_module_eeprom_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_module_eeprom_get_req_dump)); +} +void +ethtool_module_eeprom_get_req_dump_free(struct ethtool_module_eeprom_get_req_dump *req); + +static inline void +ethtool_module_eeprom_get_req_dump_set_header_dev_index(struct ethtool_module_eeprom_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_module_eeprom_get_req_dump_set_header_dev_name(struct ethtool_module_eeprom_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_module_eeprom_get_req_dump_set_header_flags(struct ethtool_module_eeprom_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_module_eeprom_get_list { + struct ethtool_module_eeprom_get_list *next; + struct ethtool_module_eeprom_get_rsp obj __attribute__((aligned(8))); +}; + +void +ethtool_module_eeprom_get_list_free(struct ethtool_module_eeprom_get_list *rsp); + +struct ethtool_module_eeprom_get_list * +ethtool_module_eeprom_get_dump(struct ynl_sock *ys, + struct ethtool_module_eeprom_get_req_dump *req); + +/* ============== ETHTOOL_MSG_PHC_VCLOCKS_GET ============== */ +/* ETHTOOL_MSG_PHC_VCLOCKS_GET - do */ +struct ethtool_phc_vclocks_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_phc_vclocks_get_req * +ethtool_phc_vclocks_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_phc_vclocks_get_req)); +} +void ethtool_phc_vclocks_get_req_free(struct ethtool_phc_vclocks_get_req *req); + +static inline void +ethtool_phc_vclocks_get_req_set_header_dev_index(struct ethtool_phc_vclocks_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_phc_vclocks_get_req_set_header_dev_name(struct ethtool_phc_vclocks_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_phc_vclocks_get_req_set_header_flags(struct ethtool_phc_vclocks_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_phc_vclocks_get_rsp { + struct { + __u32 header:1; + __u32 num:1; + } _present; + + struct ethtool_header header; + __u32 num; +}; + +void ethtool_phc_vclocks_get_rsp_free(struct ethtool_phc_vclocks_get_rsp *rsp); + +/* + * Get PHC VCLOCKs. + */ +struct ethtool_phc_vclocks_get_rsp * +ethtool_phc_vclocks_get(struct ynl_sock *ys, + struct ethtool_phc_vclocks_get_req *req); + +/* ETHTOOL_MSG_PHC_VCLOCKS_GET - dump */ +struct ethtool_phc_vclocks_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_phc_vclocks_get_req_dump * +ethtool_phc_vclocks_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_phc_vclocks_get_req_dump)); +} +void +ethtool_phc_vclocks_get_req_dump_free(struct ethtool_phc_vclocks_get_req_dump *req); + +static inline void +ethtool_phc_vclocks_get_req_dump_set_header_dev_index(struct ethtool_phc_vclocks_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_phc_vclocks_get_req_dump_set_header_dev_name(struct ethtool_phc_vclocks_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_phc_vclocks_get_req_dump_set_header_flags(struct ethtool_phc_vclocks_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_phc_vclocks_get_list { + struct ethtool_phc_vclocks_get_list *next; + struct ethtool_phc_vclocks_get_rsp obj __attribute__((aligned(8))); +}; + +void +ethtool_phc_vclocks_get_list_free(struct ethtool_phc_vclocks_get_list *rsp); + +struct ethtool_phc_vclocks_get_list * +ethtool_phc_vclocks_get_dump(struct ynl_sock *ys, + struct ethtool_phc_vclocks_get_req_dump *req); + +/* ============== ETHTOOL_MSG_MODULE_GET ============== */ +/* ETHTOOL_MSG_MODULE_GET - do */ +struct ethtool_module_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_module_get_req *ethtool_module_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_module_get_req)); +} +void ethtool_module_get_req_free(struct ethtool_module_get_req *req); + +static inline void +ethtool_module_get_req_set_header_dev_index(struct ethtool_module_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_module_get_req_set_header_dev_name(struct ethtool_module_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_module_get_req_set_header_flags(struct ethtool_module_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_module_get_rsp { + struct { + __u32 header:1; + __u32 power_mode_policy:1; + __u32 power_mode:1; + } _present; + + struct ethtool_header header; + __u8 power_mode_policy; + __u8 power_mode; +}; + +void ethtool_module_get_rsp_free(struct ethtool_module_get_rsp *rsp); + +/* + * Get module params. + */ +struct ethtool_module_get_rsp * +ethtool_module_get(struct ynl_sock *ys, struct ethtool_module_get_req *req); + +/* ETHTOOL_MSG_MODULE_GET - dump */ +struct ethtool_module_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_module_get_req_dump * +ethtool_module_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_module_get_req_dump)); +} +void ethtool_module_get_req_dump_free(struct ethtool_module_get_req_dump *req); + +static inline void +ethtool_module_get_req_dump_set_header_dev_index(struct ethtool_module_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_module_get_req_dump_set_header_dev_name(struct ethtool_module_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_module_get_req_dump_set_header_flags(struct ethtool_module_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_module_get_list { + struct ethtool_module_get_list *next; + struct ethtool_module_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_module_get_list_free(struct ethtool_module_get_list *rsp); + +struct ethtool_module_get_list * +ethtool_module_get_dump(struct ynl_sock *ys, + struct ethtool_module_get_req_dump *req); + +/* ETHTOOL_MSG_MODULE_GET - notify */ +struct ethtool_module_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_module_get_ntf *ntf); + struct ethtool_module_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_module_get_ntf_free(struct ethtool_module_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_MODULE_SET ============== */ +/* ETHTOOL_MSG_MODULE_SET - do */ +struct ethtool_module_set_req { + struct { + __u32 header:1; + __u32 power_mode_policy:1; + __u32 power_mode:1; + } _present; + + struct ethtool_header header; + __u8 power_mode_policy; + __u8 power_mode; +}; + +static inline struct ethtool_module_set_req *ethtool_module_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_module_set_req)); +} +void ethtool_module_set_req_free(struct ethtool_module_set_req *req); + +static inline void +ethtool_module_set_req_set_header_dev_index(struct ethtool_module_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_module_set_req_set_header_dev_name(struct ethtool_module_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_module_set_req_set_header_flags(struct ethtool_module_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_module_set_req_set_power_mode_policy(struct ethtool_module_set_req *req, + __u8 power_mode_policy) +{ + req->_present.power_mode_policy = 1; + req->power_mode_policy = power_mode_policy; +} +static inline void +ethtool_module_set_req_set_power_mode(struct ethtool_module_set_req *req, + __u8 power_mode) +{ + req->_present.power_mode = 1; + req->power_mode = power_mode; +} + +/* + * Set module params. + */ +int ethtool_module_set(struct ynl_sock *ys, struct ethtool_module_set_req *req); + +/* ============== ETHTOOL_MSG_PSE_GET ============== */ +/* ETHTOOL_MSG_PSE_GET - do */ +struct ethtool_pse_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_pse_get_req *ethtool_pse_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_pse_get_req)); +} +void ethtool_pse_get_req_free(struct ethtool_pse_get_req *req); + +static inline void +ethtool_pse_get_req_set_header_dev_index(struct ethtool_pse_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_pse_get_req_set_header_dev_name(struct ethtool_pse_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_pse_get_req_set_header_flags(struct ethtool_pse_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_pse_get_rsp { + struct { + __u32 header:1; + __u32 admin_state:1; + __u32 admin_control:1; + __u32 pw_d_status:1; + } _present; + + struct ethtool_header header; + __u32 admin_state; + __u32 admin_control; + __u32 pw_d_status; +}; + +void ethtool_pse_get_rsp_free(struct ethtool_pse_get_rsp *rsp); + +/* + * Get Power Sourcing Equipment params. + */ +struct ethtool_pse_get_rsp * +ethtool_pse_get(struct ynl_sock *ys, struct ethtool_pse_get_req *req); + +/* ETHTOOL_MSG_PSE_GET - dump */ +struct ethtool_pse_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_pse_get_req_dump * +ethtool_pse_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_pse_get_req_dump)); +} +void ethtool_pse_get_req_dump_free(struct ethtool_pse_get_req_dump *req); + +static inline void +ethtool_pse_get_req_dump_set_header_dev_index(struct ethtool_pse_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_pse_get_req_dump_set_header_dev_name(struct ethtool_pse_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_pse_get_req_dump_set_header_flags(struct ethtool_pse_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_pse_get_list { + struct ethtool_pse_get_list *next; + struct ethtool_pse_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_pse_get_list_free(struct ethtool_pse_get_list *rsp); + +struct ethtool_pse_get_list * +ethtool_pse_get_dump(struct ynl_sock *ys, struct ethtool_pse_get_req_dump *req); + +/* ============== ETHTOOL_MSG_PSE_SET ============== */ +/* ETHTOOL_MSG_PSE_SET - do */ +struct ethtool_pse_set_req { + struct { + __u32 header:1; + __u32 admin_state:1; + __u32 admin_control:1; + __u32 pw_d_status:1; + } _present; + + struct ethtool_header header; + __u32 admin_state; + __u32 admin_control; + __u32 pw_d_status; +}; + +static inline struct ethtool_pse_set_req *ethtool_pse_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_pse_set_req)); +} +void ethtool_pse_set_req_free(struct ethtool_pse_set_req *req); + +static inline void +ethtool_pse_set_req_set_header_dev_index(struct ethtool_pse_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_pse_set_req_set_header_dev_name(struct ethtool_pse_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_pse_set_req_set_header_flags(struct ethtool_pse_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_pse_set_req_set_admin_state(struct ethtool_pse_set_req *req, + __u32 admin_state) +{ + req->_present.admin_state = 1; + req->admin_state = admin_state; +} +static inline void +ethtool_pse_set_req_set_admin_control(struct ethtool_pse_set_req *req, + __u32 admin_control) +{ + req->_present.admin_control = 1; + req->admin_control = admin_control; +} +static inline void +ethtool_pse_set_req_set_pw_d_status(struct ethtool_pse_set_req *req, + __u32 pw_d_status) +{ + req->_present.pw_d_status = 1; + req->pw_d_status = pw_d_status; +} + +/* + * Set Power Sourcing Equipment params. + */ +int ethtool_pse_set(struct ynl_sock *ys, struct ethtool_pse_set_req *req); + +/* ============== ETHTOOL_MSG_RSS_GET ============== */ +/* ETHTOOL_MSG_RSS_GET - do */ +struct ethtool_rss_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_rss_get_req *ethtool_rss_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_rss_get_req)); +} +void ethtool_rss_get_req_free(struct ethtool_rss_get_req *req); + +static inline void +ethtool_rss_get_req_set_header_dev_index(struct ethtool_rss_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_rss_get_req_set_header_dev_name(struct ethtool_rss_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_rss_get_req_set_header_flags(struct ethtool_rss_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_rss_get_rsp { + struct { + __u32 header:1; + __u32 context:1; + __u32 hfunc:1; + __u32 indir_len; + __u32 hkey_len; + __u32 input_xfrm:1; + } _present; + + struct ethtool_header header; + __u32 context; + __u32 hfunc; + void *indir; + void *hkey; + __u32 input_xfrm; +}; + +void ethtool_rss_get_rsp_free(struct ethtool_rss_get_rsp *rsp); + +/* + * Get RSS params. + */ +struct ethtool_rss_get_rsp * +ethtool_rss_get(struct ynl_sock *ys, struct ethtool_rss_get_req *req); + +/* ETHTOOL_MSG_RSS_GET - dump */ +struct ethtool_rss_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_rss_get_req_dump * +ethtool_rss_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_rss_get_req_dump)); +} +void ethtool_rss_get_req_dump_free(struct ethtool_rss_get_req_dump *req); + +static inline void +ethtool_rss_get_req_dump_set_header_dev_index(struct ethtool_rss_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_rss_get_req_dump_set_header_dev_name(struct ethtool_rss_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_rss_get_req_dump_set_header_flags(struct ethtool_rss_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_rss_get_list { + struct ethtool_rss_get_list *next; + struct ethtool_rss_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_rss_get_list_free(struct ethtool_rss_get_list *rsp); + +struct ethtool_rss_get_list * +ethtool_rss_get_dump(struct ynl_sock *ys, struct ethtool_rss_get_req_dump *req); + +/* ============== ETHTOOL_MSG_PLCA_GET_CFG ============== */ +/* ETHTOOL_MSG_PLCA_GET_CFG - do */ +struct ethtool_plca_get_cfg_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_plca_get_cfg_req * +ethtool_plca_get_cfg_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_plca_get_cfg_req)); +} +void ethtool_plca_get_cfg_req_free(struct ethtool_plca_get_cfg_req *req); + +static inline void +ethtool_plca_get_cfg_req_set_header_dev_index(struct ethtool_plca_get_cfg_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_plca_get_cfg_req_set_header_dev_name(struct ethtool_plca_get_cfg_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_plca_get_cfg_req_set_header_flags(struct ethtool_plca_get_cfg_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_plca_get_cfg_rsp { + struct { + __u32 header:1; + __u32 version:1; + __u32 enabled:1; + __u32 status:1; + __u32 node_cnt:1; + __u32 node_id:1; + __u32 to_tmr:1; + __u32 burst_cnt:1; + __u32 burst_tmr:1; + } _present; + + struct ethtool_header header; + __u16 version; + __u8 enabled; + __u8 status; + __u32 node_cnt; + __u32 node_id; + __u32 to_tmr; + __u32 burst_cnt; + __u32 burst_tmr; +}; + +void ethtool_plca_get_cfg_rsp_free(struct ethtool_plca_get_cfg_rsp *rsp); + +/* + * Get PLCA params. + */ +struct ethtool_plca_get_cfg_rsp * +ethtool_plca_get_cfg(struct ynl_sock *ys, struct ethtool_plca_get_cfg_req *req); + +/* ETHTOOL_MSG_PLCA_GET_CFG - dump */ +struct ethtool_plca_get_cfg_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_plca_get_cfg_req_dump * +ethtool_plca_get_cfg_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_plca_get_cfg_req_dump)); +} +void +ethtool_plca_get_cfg_req_dump_free(struct ethtool_plca_get_cfg_req_dump *req); + +static inline void +ethtool_plca_get_cfg_req_dump_set_header_dev_index(struct ethtool_plca_get_cfg_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_plca_get_cfg_req_dump_set_header_dev_name(struct ethtool_plca_get_cfg_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_plca_get_cfg_req_dump_set_header_flags(struct ethtool_plca_get_cfg_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_plca_get_cfg_list { + struct ethtool_plca_get_cfg_list *next; + struct ethtool_plca_get_cfg_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_plca_get_cfg_list_free(struct ethtool_plca_get_cfg_list *rsp); + +struct ethtool_plca_get_cfg_list * +ethtool_plca_get_cfg_dump(struct ynl_sock *ys, + struct ethtool_plca_get_cfg_req_dump *req); + +/* ETHTOOL_MSG_PLCA_GET_CFG - notify */ +struct ethtool_plca_get_cfg_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_plca_get_cfg_ntf *ntf); + struct ethtool_plca_get_cfg_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_plca_get_cfg_ntf_free(struct ethtool_plca_get_cfg_ntf *rsp); + +/* ============== ETHTOOL_MSG_PLCA_SET_CFG ============== */ +/* ETHTOOL_MSG_PLCA_SET_CFG - do */ +struct ethtool_plca_set_cfg_req { + struct { + __u32 header:1; + __u32 version:1; + __u32 enabled:1; + __u32 status:1; + __u32 node_cnt:1; + __u32 node_id:1; + __u32 to_tmr:1; + __u32 burst_cnt:1; + __u32 burst_tmr:1; + } _present; + + struct ethtool_header header; + __u16 version; + __u8 enabled; + __u8 status; + __u32 node_cnt; + __u32 node_id; + __u32 to_tmr; + __u32 burst_cnt; + __u32 burst_tmr; +}; + +static inline struct ethtool_plca_set_cfg_req * +ethtool_plca_set_cfg_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_plca_set_cfg_req)); +} +void ethtool_plca_set_cfg_req_free(struct ethtool_plca_set_cfg_req *req); + +static inline void +ethtool_plca_set_cfg_req_set_header_dev_index(struct ethtool_plca_set_cfg_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_plca_set_cfg_req_set_header_dev_name(struct ethtool_plca_set_cfg_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_plca_set_cfg_req_set_header_flags(struct ethtool_plca_set_cfg_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_plca_set_cfg_req_set_version(struct ethtool_plca_set_cfg_req *req, + __u16 version) +{ + req->_present.version = 1; + req->version = version; +} +static inline void +ethtool_plca_set_cfg_req_set_enabled(struct ethtool_plca_set_cfg_req *req, + __u8 enabled) +{ + req->_present.enabled = 1; + req->enabled = enabled; +} +static inline void +ethtool_plca_set_cfg_req_set_status(struct ethtool_plca_set_cfg_req *req, + __u8 status) +{ + req->_present.status = 1; + req->status = status; +} +static inline void +ethtool_plca_set_cfg_req_set_node_cnt(struct ethtool_plca_set_cfg_req *req, + __u32 node_cnt) +{ + req->_present.node_cnt = 1; + req->node_cnt = node_cnt; +} +static inline void +ethtool_plca_set_cfg_req_set_node_id(struct ethtool_plca_set_cfg_req *req, + __u32 node_id) +{ + req->_present.node_id = 1; + req->node_id = node_id; +} +static inline void +ethtool_plca_set_cfg_req_set_to_tmr(struct ethtool_plca_set_cfg_req *req, + __u32 to_tmr) +{ + req->_present.to_tmr = 1; + req->to_tmr = to_tmr; +} +static inline void +ethtool_plca_set_cfg_req_set_burst_cnt(struct ethtool_plca_set_cfg_req *req, + __u32 burst_cnt) +{ + req->_present.burst_cnt = 1; + req->burst_cnt = burst_cnt; +} +static inline void +ethtool_plca_set_cfg_req_set_burst_tmr(struct ethtool_plca_set_cfg_req *req, + __u32 burst_tmr) +{ + req->_present.burst_tmr = 1; + req->burst_tmr = burst_tmr; +} + +/* + * Set PLCA params. + */ +int ethtool_plca_set_cfg(struct ynl_sock *ys, + struct ethtool_plca_set_cfg_req *req); + +/* ============== ETHTOOL_MSG_PLCA_GET_STATUS ============== */ +/* ETHTOOL_MSG_PLCA_GET_STATUS - do */ +struct ethtool_plca_get_status_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_plca_get_status_req * +ethtool_plca_get_status_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_plca_get_status_req)); +} +void ethtool_plca_get_status_req_free(struct ethtool_plca_get_status_req *req); + +static inline void +ethtool_plca_get_status_req_set_header_dev_index(struct ethtool_plca_get_status_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_plca_get_status_req_set_header_dev_name(struct ethtool_plca_get_status_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_plca_get_status_req_set_header_flags(struct ethtool_plca_get_status_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_plca_get_status_rsp { + struct { + __u32 header:1; + __u32 version:1; + __u32 enabled:1; + __u32 status:1; + __u32 node_cnt:1; + __u32 node_id:1; + __u32 to_tmr:1; + __u32 burst_cnt:1; + __u32 burst_tmr:1; + } _present; + + struct ethtool_header header; + __u16 version; + __u8 enabled; + __u8 status; + __u32 node_cnt; + __u32 node_id; + __u32 to_tmr; + __u32 burst_cnt; + __u32 burst_tmr; +}; + +void ethtool_plca_get_status_rsp_free(struct ethtool_plca_get_status_rsp *rsp); + +/* + * Get PLCA status params. + */ +struct ethtool_plca_get_status_rsp * +ethtool_plca_get_status(struct ynl_sock *ys, + struct ethtool_plca_get_status_req *req); + +/* ETHTOOL_MSG_PLCA_GET_STATUS - dump */ +struct ethtool_plca_get_status_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_plca_get_status_req_dump * +ethtool_plca_get_status_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_plca_get_status_req_dump)); +} +void +ethtool_plca_get_status_req_dump_free(struct ethtool_plca_get_status_req_dump *req); + +static inline void +ethtool_plca_get_status_req_dump_set_header_dev_index(struct ethtool_plca_get_status_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_plca_get_status_req_dump_set_header_dev_name(struct ethtool_plca_get_status_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_plca_get_status_req_dump_set_header_flags(struct ethtool_plca_get_status_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_plca_get_status_list { + struct ethtool_plca_get_status_list *next; + struct ethtool_plca_get_status_rsp obj __attribute__((aligned(8))); +}; + +void +ethtool_plca_get_status_list_free(struct ethtool_plca_get_status_list *rsp); + +struct ethtool_plca_get_status_list * +ethtool_plca_get_status_dump(struct ynl_sock *ys, + struct ethtool_plca_get_status_req_dump *req); + +/* ============== ETHTOOL_MSG_MM_GET ============== */ +/* ETHTOOL_MSG_MM_GET - do */ +struct ethtool_mm_get_req { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_mm_get_req *ethtool_mm_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_mm_get_req)); +} +void ethtool_mm_get_req_free(struct ethtool_mm_get_req *req); + +static inline void +ethtool_mm_get_req_set_header_dev_index(struct ethtool_mm_get_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_mm_get_req_set_header_dev_name(struct ethtool_mm_get_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_mm_get_req_set_header_flags(struct ethtool_mm_get_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_mm_get_rsp { + struct { + __u32 header:1; + __u32 pmac_enabled:1; + __u32 tx_enabled:1; + __u32 tx_active:1; + __u32 tx_min_frag_size:1; + __u32 rx_min_frag_size:1; + __u32 verify_enabled:1; + __u32 verify_time:1; + __u32 max_verify_time:1; + __u32 stats:1; + } _present; + + struct ethtool_header header; + __u8 pmac_enabled; + __u8 tx_enabled; + __u8 tx_active; + __u32 tx_min_frag_size; + __u32 rx_min_frag_size; + __u8 verify_enabled; + __u32 verify_time; + __u32 max_verify_time; + struct ethtool_mm_stat stats; +}; + +void ethtool_mm_get_rsp_free(struct ethtool_mm_get_rsp *rsp); + +/* + * Get MAC Merge configuration and state + */ +struct ethtool_mm_get_rsp * +ethtool_mm_get(struct ynl_sock *ys, struct ethtool_mm_get_req *req); + +/* ETHTOOL_MSG_MM_GET - dump */ +struct ethtool_mm_get_req_dump { + struct { + __u32 header:1; + } _present; + + struct ethtool_header header; +}; + +static inline struct ethtool_mm_get_req_dump * +ethtool_mm_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_mm_get_req_dump)); +} +void ethtool_mm_get_req_dump_free(struct ethtool_mm_get_req_dump *req); + +static inline void +ethtool_mm_get_req_dump_set_header_dev_index(struct ethtool_mm_get_req_dump *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_mm_get_req_dump_set_header_dev_name(struct ethtool_mm_get_req_dump *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_mm_get_req_dump_set_header_flags(struct ethtool_mm_get_req_dump *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} + +struct ethtool_mm_get_list { + struct ethtool_mm_get_list *next; + struct ethtool_mm_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_mm_get_list_free(struct ethtool_mm_get_list *rsp); + +struct ethtool_mm_get_list * +ethtool_mm_get_dump(struct ynl_sock *ys, struct ethtool_mm_get_req_dump *req); + +/* ETHTOOL_MSG_MM_GET - notify */ +struct ethtool_mm_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_mm_get_ntf *ntf); + struct ethtool_mm_get_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_mm_get_ntf_free(struct ethtool_mm_get_ntf *rsp); + +/* ============== ETHTOOL_MSG_MM_SET ============== */ +/* ETHTOOL_MSG_MM_SET - do */ +struct ethtool_mm_set_req { + struct { + __u32 header:1; + __u32 verify_enabled:1; + __u32 verify_time:1; + __u32 tx_enabled:1; + __u32 pmac_enabled:1; + __u32 tx_min_frag_size:1; + } _present; + + struct ethtool_header header; + __u8 verify_enabled; + __u32 verify_time; + __u8 tx_enabled; + __u8 pmac_enabled; + __u32 tx_min_frag_size; +}; + +static inline struct ethtool_mm_set_req *ethtool_mm_set_req_alloc(void) +{ + return calloc(1, sizeof(struct ethtool_mm_set_req)); +} +void ethtool_mm_set_req_free(struct ethtool_mm_set_req *req); + +static inline void +ethtool_mm_set_req_set_header_dev_index(struct ethtool_mm_set_req *req, + __u32 dev_index) +{ + req->_present.header = 1; + req->header._present.dev_index = 1; + req->header.dev_index = dev_index; +} +static inline void +ethtool_mm_set_req_set_header_dev_name(struct ethtool_mm_set_req *req, + const char *dev_name) +{ + free(req->header.dev_name); + req->header._present.dev_name_len = strlen(dev_name); + req->header.dev_name = malloc(req->header._present.dev_name_len + 1); + memcpy(req->header.dev_name, dev_name, req->header._present.dev_name_len); + req->header.dev_name[req->header._present.dev_name_len] = 0; +} +static inline void +ethtool_mm_set_req_set_header_flags(struct ethtool_mm_set_req *req, + __u32 flags) +{ + req->_present.header = 1; + req->header._present.flags = 1; + req->header.flags = flags; +} +static inline void +ethtool_mm_set_req_set_verify_enabled(struct ethtool_mm_set_req *req, + __u8 verify_enabled) +{ + req->_present.verify_enabled = 1; + req->verify_enabled = verify_enabled; +} +static inline void +ethtool_mm_set_req_set_verify_time(struct ethtool_mm_set_req *req, + __u32 verify_time) +{ + req->_present.verify_time = 1; + req->verify_time = verify_time; +} +static inline void +ethtool_mm_set_req_set_tx_enabled(struct ethtool_mm_set_req *req, + __u8 tx_enabled) +{ + req->_present.tx_enabled = 1; + req->tx_enabled = tx_enabled; +} +static inline void +ethtool_mm_set_req_set_pmac_enabled(struct ethtool_mm_set_req *req, + __u8 pmac_enabled) +{ + req->_present.pmac_enabled = 1; + req->pmac_enabled = pmac_enabled; +} +static inline void +ethtool_mm_set_req_set_tx_min_frag_size(struct ethtool_mm_set_req *req, + __u32 tx_min_frag_size) +{ + req->_present.tx_min_frag_size = 1; + req->tx_min_frag_size = tx_min_frag_size; +} + +/* + * Set MAC Merge configuration + */ +int ethtool_mm_set(struct ynl_sock *ys, struct ethtool_mm_set_req *req); + +/* ETHTOOL_MSG_CABLE_TEST_NTF - event */ +struct ethtool_cable_test_ntf_rsp { + struct { + __u32 header:1; + __u32 status:1; + } _present; + + struct ethtool_header header; + __u8 status; +}; + +struct ethtool_cable_test_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_cable_test_ntf *ntf); + struct ethtool_cable_test_ntf_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_cable_test_ntf_free(struct ethtool_cable_test_ntf *rsp); + +/* ETHTOOL_MSG_CABLE_TEST_TDR_NTF - event */ +struct ethtool_cable_test_tdr_ntf_rsp { + struct { + __u32 header:1; + __u32 status:1; + __u32 nest:1; + } _present; + + struct ethtool_header header; + __u8 status; + struct ethtool_cable_nest nest; +}; + +struct ethtool_cable_test_tdr_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ethtool_cable_test_tdr_ntf *ntf); + struct ethtool_cable_test_tdr_ntf_rsp obj __attribute__((aligned(8))); +}; + +void ethtool_cable_test_tdr_ntf_free(struct ethtool_cable_test_tdr_ntf *rsp); + +#endif /* _LINUX_ETHTOOL_GEN_H */ diff --git a/generated/fou-user.c b/generated/fou-user.c new file mode 100644 index 0000000..469f1ba --- /dev/null +++ b/generated/fou-user.c @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/fou.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "fou-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const fou_op_strmap[] = { + [FOU_CMD_ADD] = "add", + [FOU_CMD_DEL] = "del", + [FOU_CMD_GET] = "get", +}; + +const char *fou_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(fou_op_strmap)) + return NULL; + return fou_op_strmap[op]; +} + +static const char * const fou_encap_type_strmap[] = { + [0] = "unspec", + [1] = "direct", + [2] = "gue", +}; + +const char *fou_encap_type_str(int value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(fou_encap_type_strmap)) + return NULL; + return fou_encap_type_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr fou_policy[FOU_ATTR_MAX + 1] = { + [FOU_ATTR_UNSPEC] = { .name = "unspec", .type = YNL_PT_REJECT, }, + [FOU_ATTR_PORT] = { .name = "port", .type = YNL_PT_U16, }, + [FOU_ATTR_AF] = { .name = "af", .type = YNL_PT_U8, }, + [FOU_ATTR_IPPROTO] = { .name = "ipproto", .type = YNL_PT_U8, }, + [FOU_ATTR_TYPE] = { .name = "type", .type = YNL_PT_U8, }, + [FOU_ATTR_REMCSUM_NOPARTIAL] = { .name = "remcsum_nopartial", .type = YNL_PT_FLAG, }, + [FOU_ATTR_LOCAL_V4] = { .name = "local_v4", .type = YNL_PT_U32, }, + [FOU_ATTR_LOCAL_V6] = { .name = "local_v6", .type = YNL_PT_BINARY,}, + [FOU_ATTR_PEER_V4] = { .name = "peer_v4", .type = YNL_PT_U32, }, + [FOU_ATTR_PEER_V6] = { .name = "peer_v6", .type = YNL_PT_BINARY,}, + [FOU_ATTR_PEER_PORT] = { .name = "peer_port", .type = YNL_PT_U16, }, + [FOU_ATTR_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest fou_nest = { + .max_attr = FOU_ATTR_MAX, + .table = fou_policy, +}; + +/* Common nested types */ +/* ============== FOU_CMD_ADD ============== */ +/* FOU_CMD_ADD - do */ +void fou_add_req_free(struct fou_add_req *req) +{ + free(req->local_v6); + free(req->peer_v6); + free(req); +} + +int fou_add(struct ynl_sock *ys, struct fou_add_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, FOU_CMD_ADD, 1); + ys->req_policy = &fou_nest; + + if (req->_present.port) + ynl_attr_put_u16(nlh, FOU_ATTR_PORT, req->port); + if (req->_present.ipproto) + ynl_attr_put_u8(nlh, FOU_ATTR_IPPROTO, req->ipproto); + if (req->_present.type) + ynl_attr_put_u8(nlh, FOU_ATTR_TYPE, req->type); + if (req->_present.remcsum_nopartial) + ynl_attr_put(nlh, FOU_ATTR_REMCSUM_NOPARTIAL, NULL, 0); + if (req->_present.local_v4) + ynl_attr_put_u32(nlh, FOU_ATTR_LOCAL_V4, req->local_v4); + if (req->_present.peer_v4) + ynl_attr_put_u32(nlh, FOU_ATTR_PEER_V4, req->peer_v4); + if (req->_present.local_v6_len) + ynl_attr_put(nlh, FOU_ATTR_LOCAL_V6, req->local_v6, req->_present.local_v6_len); + if (req->_present.peer_v6_len) + ynl_attr_put(nlh, FOU_ATTR_PEER_V6, req->peer_v6, req->_present.peer_v6_len); + if (req->_present.peer_port) + ynl_attr_put_u16(nlh, FOU_ATTR_PEER_PORT, req->peer_port); + if (req->_present.ifindex) + ynl_attr_put_s32(nlh, FOU_ATTR_IFINDEX, req->ifindex); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== FOU_CMD_DEL ============== */ +/* FOU_CMD_DEL - do */ +void fou_del_req_free(struct fou_del_req *req) +{ + free(req->local_v6); + free(req->peer_v6); + free(req); +} + +int fou_del(struct ynl_sock *ys, struct fou_del_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, FOU_CMD_DEL, 1); + ys->req_policy = &fou_nest; + + if (req->_present.af) + ynl_attr_put_u8(nlh, FOU_ATTR_AF, req->af); + if (req->_present.ifindex) + ynl_attr_put_s32(nlh, FOU_ATTR_IFINDEX, req->ifindex); + if (req->_present.port) + ynl_attr_put_u16(nlh, FOU_ATTR_PORT, req->port); + if (req->_present.peer_port) + ynl_attr_put_u16(nlh, FOU_ATTR_PEER_PORT, req->peer_port); + if (req->_present.local_v4) + ynl_attr_put_u32(nlh, FOU_ATTR_LOCAL_V4, req->local_v4); + if (req->_present.peer_v4) + ynl_attr_put_u32(nlh, FOU_ATTR_PEER_V4, req->peer_v4); + if (req->_present.local_v6_len) + ynl_attr_put(nlh, FOU_ATTR_LOCAL_V6, req->local_v6, req->_present.local_v6_len); + if (req->_present.peer_v6_len) + ynl_attr_put(nlh, FOU_ATTR_PEER_V6, req->peer_v6, req->_present.peer_v6_len); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== FOU_CMD_GET ============== */ +/* FOU_CMD_GET - do */ +void fou_get_req_free(struct fou_get_req *req) +{ + free(req->local_v6); + free(req->peer_v6); + free(req); +} + +void fou_get_rsp_free(struct fou_get_rsp *rsp) +{ + free(rsp->local_v6); + free(rsp->peer_v6); + free(rsp); +} + +int fou_get_rsp_parse(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg) +{ + const struct nlattr *attr; + struct fou_get_rsp *dst; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == FOU_ATTR_PORT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port = 1; + dst->port = ynl_attr_get_u16(attr); + } else if (type == FOU_ATTR_IPPROTO) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ipproto = 1; + dst->ipproto = ynl_attr_get_u8(attr); + } else if (type == FOU_ATTR_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.type = 1; + dst->type = ynl_attr_get_u8(attr); + } else if (type == FOU_ATTR_REMCSUM_NOPARTIAL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.remcsum_nopartial = 1; + } else if (type == FOU_ATTR_LOCAL_V4) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.local_v4 = 1; + dst->local_v4 = ynl_attr_get_u32(attr); + } else if (type == FOU_ATTR_PEER_V4) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.peer_v4 = 1; + dst->peer_v4 = ynl_attr_get_u32(attr); + } else if (type == FOU_ATTR_LOCAL_V6) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.local_v6_len = len; + dst->local_v6 = malloc(len); + memcpy(dst->local_v6, ynl_attr_data(attr), len); + } else if (type == FOU_ATTR_PEER_V6) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.peer_v6_len = len; + dst->peer_v6 = malloc(len); + memcpy(dst->peer_v6, ynl_attr_data(attr), len); + } else if (type == FOU_ATTR_PEER_PORT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.peer_port = 1; + dst->peer_port = ynl_attr_get_u16(attr); + } else if (type == FOU_ATTR_IFINDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ifindex = 1; + dst->ifindex = ynl_attr_get_s32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct fou_get_rsp *fou_get(struct ynl_sock *ys, struct fou_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct fou_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, FOU_CMD_GET, 1); + ys->req_policy = &fou_nest; + yrs.yarg.rsp_policy = &fou_nest; + + if (req->_present.af) + ynl_attr_put_u8(nlh, FOU_ATTR_AF, req->af); + if (req->_present.ifindex) + ynl_attr_put_s32(nlh, FOU_ATTR_IFINDEX, req->ifindex); + if (req->_present.port) + ynl_attr_put_u16(nlh, FOU_ATTR_PORT, req->port); + if (req->_present.peer_port) + ynl_attr_put_u16(nlh, FOU_ATTR_PEER_PORT, req->peer_port); + if (req->_present.local_v4) + ynl_attr_put_u32(nlh, FOU_ATTR_LOCAL_V4, req->local_v4); + if (req->_present.peer_v4) + ynl_attr_put_u32(nlh, FOU_ATTR_PEER_V4, req->peer_v4); + if (req->_present.local_v6_len) + ynl_attr_put(nlh, FOU_ATTR_LOCAL_V6, req->local_v6, req->_present.local_v6_len); + if (req->_present.peer_v6_len) + ynl_attr_put(nlh, FOU_ATTR_PEER_V6, req->peer_v6, req->_present.peer_v6_len); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = fou_get_rsp_parse; + yrs.rsp_cmd = FOU_CMD_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + fou_get_rsp_free(rsp); + return NULL; +} + +/* FOU_CMD_GET - dump */ +void fou_get_list_free(struct fou_get_list *rsp) +{ + struct fou_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.local_v6); + free(rsp->obj.peer_v6); + free(rsp); + } +} + +struct fou_get_list *fou_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &fou_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct fou_get_list); + yds.cb = fou_get_rsp_parse; + yds.rsp_cmd = FOU_CMD_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, FOU_CMD_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + fou_get_list_free(yds.first); + return NULL; +} + +const struct ynl_family ynl_fou_family = { + .name = "fou", + .hdr_len = sizeof(struct genlmsghdr), +}; diff --git a/generated/fou-user.h b/generated/fou-user.h new file mode 100644 index 0000000..fd56671 --- /dev/null +++ b/generated/fou-user.h @@ -0,0 +1,343 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/fou.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_FOU_GEN_H +#define _LINUX_FOU_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_fou_family; + +/* Enums */ +const char *fou_op_str(int op); +const char *fou_encap_type_str(int value); + +/* Common nested types */ +/* ============== FOU_CMD_ADD ============== */ +/* FOU_CMD_ADD - do */ +struct fou_add_req { + struct { + __u32 port:1; + __u32 ipproto:1; + __u32 type:1; + __u32 remcsum_nopartial:1; + __u32 local_v4:1; + __u32 peer_v4:1; + __u32 local_v6_len; + __u32 peer_v6_len; + __u32 peer_port:1; + __u32 ifindex:1; + } _present; + + __u16 port /* big-endian */; + __u8 ipproto; + __u8 type; + __u32 local_v4; + __u32 peer_v4; + void *local_v6; + void *peer_v6; + __u16 peer_port /* big-endian */; + __s32 ifindex; +}; + +static inline struct fou_add_req *fou_add_req_alloc(void) +{ + return calloc(1, sizeof(struct fou_add_req)); +} +void fou_add_req_free(struct fou_add_req *req); + +static inline void +fou_add_req_set_port(struct fou_add_req *req, __u16 port /* big-endian */) +{ + req->_present.port = 1; + req->port = port; +} +static inline void +fou_add_req_set_ipproto(struct fou_add_req *req, __u8 ipproto) +{ + req->_present.ipproto = 1; + req->ipproto = ipproto; +} +static inline void fou_add_req_set_type(struct fou_add_req *req, __u8 type) +{ + req->_present.type = 1; + req->type = type; +} +static inline void fou_add_req_set_remcsum_nopartial(struct fou_add_req *req) +{ + req->_present.remcsum_nopartial = 1; +} +static inline void +fou_add_req_set_local_v4(struct fou_add_req *req, __u32 local_v4) +{ + req->_present.local_v4 = 1; + req->local_v4 = local_v4; +} +static inline void +fou_add_req_set_peer_v4(struct fou_add_req *req, __u32 peer_v4) +{ + req->_present.peer_v4 = 1; + req->peer_v4 = peer_v4; +} +static inline void +fou_add_req_set_local_v6(struct fou_add_req *req, const void *local_v6, + size_t len) +{ + free(req->local_v6); + req->_present.local_v6_len = len; + req->local_v6 = malloc(req->_present.local_v6_len); + memcpy(req->local_v6, local_v6, req->_present.local_v6_len); +} +static inline void +fou_add_req_set_peer_v6(struct fou_add_req *req, const void *peer_v6, + size_t len) +{ + free(req->peer_v6); + req->_present.peer_v6_len = len; + req->peer_v6 = malloc(req->_present.peer_v6_len); + memcpy(req->peer_v6, peer_v6, req->_present.peer_v6_len); +} +static inline void +fou_add_req_set_peer_port(struct fou_add_req *req, + __u16 peer_port /* big-endian */) +{ + req->_present.peer_port = 1; + req->peer_port = peer_port; +} +static inline void +fou_add_req_set_ifindex(struct fou_add_req *req, __s32 ifindex) +{ + req->_present.ifindex = 1; + req->ifindex = ifindex; +} + +/* + * Add port. + */ +int fou_add(struct ynl_sock *ys, struct fou_add_req *req); + +/* ============== FOU_CMD_DEL ============== */ +/* FOU_CMD_DEL - do */ +struct fou_del_req { + struct { + __u32 af:1; + __u32 ifindex:1; + __u32 port:1; + __u32 peer_port:1; + __u32 local_v4:1; + __u32 peer_v4:1; + __u32 local_v6_len; + __u32 peer_v6_len; + } _present; + + __u8 af; + __s32 ifindex; + __u16 port /* big-endian */; + __u16 peer_port /* big-endian */; + __u32 local_v4; + __u32 peer_v4; + void *local_v6; + void *peer_v6; +}; + +static inline struct fou_del_req *fou_del_req_alloc(void) +{ + return calloc(1, sizeof(struct fou_del_req)); +} +void fou_del_req_free(struct fou_del_req *req); + +static inline void fou_del_req_set_af(struct fou_del_req *req, __u8 af) +{ + req->_present.af = 1; + req->af = af; +} +static inline void +fou_del_req_set_ifindex(struct fou_del_req *req, __s32 ifindex) +{ + req->_present.ifindex = 1; + req->ifindex = ifindex; +} +static inline void +fou_del_req_set_port(struct fou_del_req *req, __u16 port /* big-endian */) +{ + req->_present.port = 1; + req->port = port; +} +static inline void +fou_del_req_set_peer_port(struct fou_del_req *req, + __u16 peer_port /* big-endian */) +{ + req->_present.peer_port = 1; + req->peer_port = peer_port; +} +static inline void +fou_del_req_set_local_v4(struct fou_del_req *req, __u32 local_v4) +{ + req->_present.local_v4 = 1; + req->local_v4 = local_v4; +} +static inline void +fou_del_req_set_peer_v4(struct fou_del_req *req, __u32 peer_v4) +{ + req->_present.peer_v4 = 1; + req->peer_v4 = peer_v4; +} +static inline void +fou_del_req_set_local_v6(struct fou_del_req *req, const void *local_v6, + size_t len) +{ + free(req->local_v6); + req->_present.local_v6_len = len; + req->local_v6 = malloc(req->_present.local_v6_len); + memcpy(req->local_v6, local_v6, req->_present.local_v6_len); +} +static inline void +fou_del_req_set_peer_v6(struct fou_del_req *req, const void *peer_v6, + size_t len) +{ + free(req->peer_v6); + req->_present.peer_v6_len = len; + req->peer_v6 = malloc(req->_present.peer_v6_len); + memcpy(req->peer_v6, peer_v6, req->_present.peer_v6_len); +} + +/* + * Delete port. + */ +int fou_del(struct ynl_sock *ys, struct fou_del_req *req); + +/* ============== FOU_CMD_GET ============== */ +/* FOU_CMD_GET - do */ +struct fou_get_req { + struct { + __u32 af:1; + __u32 ifindex:1; + __u32 port:1; + __u32 peer_port:1; + __u32 local_v4:1; + __u32 peer_v4:1; + __u32 local_v6_len; + __u32 peer_v6_len; + } _present; + + __u8 af; + __s32 ifindex; + __u16 port /* big-endian */; + __u16 peer_port /* big-endian */; + __u32 local_v4; + __u32 peer_v4; + void *local_v6; + void *peer_v6; +}; + +static inline struct fou_get_req *fou_get_req_alloc(void) +{ + return calloc(1, sizeof(struct fou_get_req)); +} +void fou_get_req_free(struct fou_get_req *req); + +static inline void fou_get_req_set_af(struct fou_get_req *req, __u8 af) +{ + req->_present.af = 1; + req->af = af; +} +static inline void +fou_get_req_set_ifindex(struct fou_get_req *req, __s32 ifindex) +{ + req->_present.ifindex = 1; + req->ifindex = ifindex; +} +static inline void +fou_get_req_set_port(struct fou_get_req *req, __u16 port /* big-endian */) +{ + req->_present.port = 1; + req->port = port; +} +static inline void +fou_get_req_set_peer_port(struct fou_get_req *req, + __u16 peer_port /* big-endian */) +{ + req->_present.peer_port = 1; + req->peer_port = peer_port; +} +static inline void +fou_get_req_set_local_v4(struct fou_get_req *req, __u32 local_v4) +{ + req->_present.local_v4 = 1; + req->local_v4 = local_v4; +} +static inline void +fou_get_req_set_peer_v4(struct fou_get_req *req, __u32 peer_v4) +{ + req->_present.peer_v4 = 1; + req->peer_v4 = peer_v4; +} +static inline void +fou_get_req_set_local_v6(struct fou_get_req *req, const void *local_v6, + size_t len) +{ + free(req->local_v6); + req->_present.local_v6_len = len; + req->local_v6 = malloc(req->_present.local_v6_len); + memcpy(req->local_v6, local_v6, req->_present.local_v6_len); +} +static inline void +fou_get_req_set_peer_v6(struct fou_get_req *req, const void *peer_v6, + size_t len) +{ + free(req->peer_v6); + req->_present.peer_v6_len = len; + req->peer_v6 = malloc(req->_present.peer_v6_len); + memcpy(req->peer_v6, peer_v6, req->_present.peer_v6_len); +} + +struct fou_get_rsp { + struct { + __u32 port:1; + __u32 ipproto:1; + __u32 type:1; + __u32 remcsum_nopartial:1; + __u32 local_v4:1; + __u32 peer_v4:1; + __u32 local_v6_len; + __u32 peer_v6_len; + __u32 peer_port:1; + __u32 ifindex:1; + } _present; + + __u16 port /* big-endian */; + __u8 ipproto; + __u8 type; + __u32 local_v4; + __u32 peer_v4; + void *local_v6; + void *peer_v6; + __u16 peer_port /* big-endian */; + __s32 ifindex; +}; + +void fou_get_rsp_free(struct fou_get_rsp *rsp); + +/* + * Get tunnel info. + */ +struct fou_get_rsp *fou_get(struct ynl_sock *ys, struct fou_get_req *req); + +/* FOU_CMD_GET - dump */ +struct fou_get_list { + struct fou_get_list *next; + struct fou_get_rsp obj __attribute__((aligned(8))); +}; + +void fou_get_list_free(struct fou_get_list *rsp); + +struct fou_get_list *fou_get_dump(struct ynl_sock *ys); + +#endif /* _LINUX_FOU_GEN_H */ diff --git a/generated/handshake-user.c b/generated/handshake-user.c new file mode 100644 index 0000000..6ea4b21 --- /dev/null +++ b/generated/handshake-user.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/handshake.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "handshake-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const handshake_op_strmap[] = { + [HANDSHAKE_CMD_READY] = "ready", + [HANDSHAKE_CMD_ACCEPT] = "accept", + [HANDSHAKE_CMD_DONE] = "done", +}; + +const char *handshake_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(handshake_op_strmap)) + return NULL; + return handshake_op_strmap[op]; +} + +static const char * const handshake_handler_class_strmap[] = { + [0] = "none", + [1] = "tlshd", + [2] = "max", +}; + +const char *handshake_handler_class_str(enum handshake_handler_class value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(handshake_handler_class_strmap)) + return NULL; + return handshake_handler_class_strmap[value]; +} + +static const char * const handshake_msg_type_strmap[] = { + [0] = "unspec", + [1] = "clienthello", + [2] = "serverhello", +}; + +const char *handshake_msg_type_str(enum handshake_msg_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(handshake_msg_type_strmap)) + return NULL; + return handshake_msg_type_strmap[value]; +} + +static const char * const handshake_auth_strmap[] = { + [0] = "unspec", + [1] = "unauth", + [2] = "psk", + [3] = "x509", +}; + +const char *handshake_auth_str(enum handshake_auth value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(handshake_auth_strmap)) + return NULL; + return handshake_auth_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr handshake_x509_policy[HANDSHAKE_A_X509_MAX + 1] = { + [HANDSHAKE_A_X509_CERT] = { .name = "cert", .type = YNL_PT_U32, }, + [HANDSHAKE_A_X509_PRIVKEY] = { .name = "privkey", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest handshake_x509_nest = { + .max_attr = HANDSHAKE_A_X509_MAX, + .table = handshake_x509_policy, +}; + +struct ynl_policy_attr handshake_accept_policy[HANDSHAKE_A_ACCEPT_MAX + 1] = { + [HANDSHAKE_A_ACCEPT_SOCKFD] = { .name = "sockfd", .type = YNL_PT_U32, }, + [HANDSHAKE_A_ACCEPT_HANDLER_CLASS] = { .name = "handler-class", .type = YNL_PT_U32, }, + [HANDSHAKE_A_ACCEPT_MESSAGE_TYPE] = { .name = "message-type", .type = YNL_PT_U32, }, + [HANDSHAKE_A_ACCEPT_TIMEOUT] = { .name = "timeout", .type = YNL_PT_U32, }, + [HANDSHAKE_A_ACCEPT_AUTH_MODE] = { .name = "auth-mode", .type = YNL_PT_U32, }, + [HANDSHAKE_A_ACCEPT_PEER_IDENTITY] = { .name = "peer-identity", .type = YNL_PT_U32, }, + [HANDSHAKE_A_ACCEPT_CERTIFICATE] = { .name = "certificate", .type = YNL_PT_NEST, .nest = &handshake_x509_nest, }, + [HANDSHAKE_A_ACCEPT_PEERNAME] = { .name = "peername", .type = YNL_PT_NUL_STR, }, +}; + +struct ynl_policy_nest handshake_accept_nest = { + .max_attr = HANDSHAKE_A_ACCEPT_MAX, + .table = handshake_accept_policy, +}; + +struct ynl_policy_attr handshake_done_policy[HANDSHAKE_A_DONE_MAX + 1] = { + [HANDSHAKE_A_DONE_STATUS] = { .name = "status", .type = YNL_PT_U32, }, + [HANDSHAKE_A_DONE_SOCKFD] = { .name = "sockfd", .type = YNL_PT_U32, }, + [HANDSHAKE_A_DONE_REMOTE_AUTH] = { .name = "remote-auth", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest handshake_done_nest = { + .max_attr = HANDSHAKE_A_DONE_MAX, + .table = handshake_done_policy, +}; + +/* Common nested types */ +void handshake_x509_free(struct handshake_x509 *obj) +{ +} + +int handshake_x509_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct handshake_x509 *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == HANDSHAKE_A_X509_CERT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.cert = 1; + dst->cert = ynl_attr_get_s32(attr); + } else if (type == HANDSHAKE_A_X509_PRIVKEY) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.privkey = 1; + dst->privkey = ynl_attr_get_s32(attr); + } + } + + return 0; +} + +/* ============== HANDSHAKE_CMD_ACCEPT ============== */ +/* HANDSHAKE_CMD_ACCEPT - do */ +void handshake_accept_req_free(struct handshake_accept_req *req) +{ + free(req); +} + +void handshake_accept_rsp_free(struct handshake_accept_rsp *rsp) +{ + unsigned int i; + + free(rsp->peer_identity); + for (i = 0; i < rsp->n_certificate; i++) + handshake_x509_free(&rsp->certificate[i]); + free(rsp->certificate); + free(rsp->peername); + free(rsp); +} + +int handshake_accept_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct handshake_accept_rsp *dst; + unsigned int n_peer_identity = 0; + unsigned int n_certificate = 0; + const struct nlattr *attr; + struct ynl_parse_arg parg; + int i; + + dst = yarg->data; + parg.ys = yarg->ys; + + if (dst->certificate) + return ynl_error_parse(yarg, "attribute already present (accept.certificate)"); + if (dst->peer_identity) + return ynl_error_parse(yarg, "attribute already present (accept.peer-identity)"); + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == HANDSHAKE_A_ACCEPT_SOCKFD) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sockfd = 1; + dst->sockfd = ynl_attr_get_s32(attr); + } else if (type == HANDSHAKE_A_ACCEPT_MESSAGE_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.message_type = 1; + dst->message_type = ynl_attr_get_u32(attr); + } else if (type == HANDSHAKE_A_ACCEPT_TIMEOUT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.timeout = 1; + dst->timeout = ynl_attr_get_u32(attr); + } else if (type == HANDSHAKE_A_ACCEPT_AUTH_MODE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.auth_mode = 1; + dst->auth_mode = ynl_attr_get_u32(attr); + } else if (type == HANDSHAKE_A_ACCEPT_PEER_IDENTITY) { + n_peer_identity++; + } else if (type == HANDSHAKE_A_ACCEPT_CERTIFICATE) { + n_certificate++; + } else if (type == HANDSHAKE_A_ACCEPT_PEERNAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.peername_len = len; + dst->peername = malloc(len + 1); + memcpy(dst->peername, ynl_attr_get_str(attr), len); + dst->peername[len] = 0; + } + } + + if (n_certificate) { + dst->certificate = calloc(n_certificate, sizeof(*dst->certificate)); + dst->n_certificate = n_certificate; + i = 0; + parg.rsp_policy = &handshake_x509_nest; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == HANDSHAKE_A_ACCEPT_CERTIFICATE) { + parg.data = &dst->certificate[i]; + if (handshake_x509_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + i++; + } + } + } + if (n_peer_identity) { + dst->peer_identity = calloc(n_peer_identity, sizeof(*dst->peer_identity)); + dst->n_peer_identity = n_peer_identity; + i = 0; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == HANDSHAKE_A_ACCEPT_PEER_IDENTITY) { + dst->peer_identity[i] = ynl_attr_get_u32(attr); + i++; + } + } + } + + return YNL_PARSE_CB_OK; +} + +struct handshake_accept_rsp * +handshake_accept(struct ynl_sock *ys, struct handshake_accept_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct handshake_accept_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, HANDSHAKE_CMD_ACCEPT, 1); + ys->req_policy = &handshake_accept_nest; + yrs.yarg.rsp_policy = &handshake_accept_nest; + + if (req->_present.handler_class) + ynl_attr_put_u32(nlh, HANDSHAKE_A_ACCEPT_HANDLER_CLASS, req->handler_class); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = handshake_accept_rsp_parse; + yrs.rsp_cmd = HANDSHAKE_CMD_ACCEPT; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + handshake_accept_rsp_free(rsp); + return NULL; +} + +/* HANDSHAKE_CMD_ACCEPT - notify */ +void handshake_accept_ntf_free(struct handshake_accept_ntf *rsp) +{ + unsigned int i; + + free(rsp->obj.peer_identity); + for (i = 0; i < rsp->obj.n_certificate; i++) + handshake_x509_free(&rsp->obj.certificate[i]); + free(rsp->obj.certificate); + free(rsp->obj.peername); + free(rsp); +} + +/* ============== HANDSHAKE_CMD_DONE ============== */ +/* HANDSHAKE_CMD_DONE - do */ +void handshake_done_req_free(struct handshake_done_req *req) +{ + free(req->remote_auth); + free(req); +} + +int handshake_done(struct ynl_sock *ys, struct handshake_done_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, HANDSHAKE_CMD_DONE, 1); + ys->req_policy = &handshake_done_nest; + + if (req->_present.status) + ynl_attr_put_u32(nlh, HANDSHAKE_A_DONE_STATUS, req->status); + if (req->_present.sockfd) + ynl_attr_put_s32(nlh, HANDSHAKE_A_DONE_SOCKFD, req->sockfd); + for (unsigned int i = 0; i < req->n_remote_auth; i++) + ynl_attr_put_u32(nlh, HANDSHAKE_A_DONE_REMOTE_AUTH, req->remote_auth[i]); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +static const struct ynl_ntf_info handshake_ntf_info[] = { + [HANDSHAKE_CMD_READY] = { + .alloc_sz = sizeof(struct handshake_accept_ntf), + .cb = handshake_accept_rsp_parse, + .policy = &handshake_accept_nest, + .free = (void *)handshake_accept_ntf_free, + }, +}; + +const struct ynl_family ynl_handshake_family = { + .name = "handshake", + .hdr_len = sizeof(struct genlmsghdr), + .ntf_info = handshake_ntf_info, + .ntf_info_size = YNL_ARRAY_SIZE(handshake_ntf_info), +}; diff --git a/generated/handshake-user.h b/generated/handshake-user.h new file mode 100644 index 0000000..bce537d --- /dev/null +++ b/generated/handshake-user.h @@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/handshake.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_HANDSHAKE_GEN_H +#define _LINUX_HANDSHAKE_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_handshake_family; + +/* Enums */ +const char *handshake_op_str(int op); +const char *handshake_handler_class_str(enum handshake_handler_class value); +const char *handshake_msg_type_str(enum handshake_msg_type value); +const char *handshake_auth_str(enum handshake_auth value); + +/* Common nested types */ +struct handshake_x509 { + struct { + __u32 cert:1; + __u32 privkey:1; + } _present; + + __s32 cert; + __s32 privkey; +}; + +/* ============== HANDSHAKE_CMD_ACCEPT ============== */ +/* HANDSHAKE_CMD_ACCEPT - do */ +struct handshake_accept_req { + struct { + __u32 handler_class:1; + } _present; + + enum handshake_handler_class handler_class; +}; + +static inline struct handshake_accept_req *handshake_accept_req_alloc(void) +{ + return calloc(1, sizeof(struct handshake_accept_req)); +} +void handshake_accept_req_free(struct handshake_accept_req *req); + +static inline void +handshake_accept_req_set_handler_class(struct handshake_accept_req *req, + enum handshake_handler_class handler_class) +{ + req->_present.handler_class = 1; + req->handler_class = handler_class; +} + +struct handshake_accept_rsp { + struct { + __u32 sockfd:1; + __u32 message_type:1; + __u32 timeout:1; + __u32 auth_mode:1; + __u32 peername_len; + } _present; + + __s32 sockfd; + enum handshake_msg_type message_type; + __u32 timeout; + enum handshake_auth auth_mode; + unsigned int n_peer_identity; + __u32 *peer_identity; + unsigned int n_certificate; + struct handshake_x509 *certificate; + char *peername; +}; + +void handshake_accept_rsp_free(struct handshake_accept_rsp *rsp); + +/* + * Handler retrieves next queued handshake request + */ +struct handshake_accept_rsp * +handshake_accept(struct ynl_sock *ys, struct handshake_accept_req *req); + +/* HANDSHAKE_CMD_ACCEPT - notify */ +struct handshake_accept_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct handshake_accept_ntf *ntf); + struct handshake_accept_rsp obj __attribute__((aligned(8))); +}; + +void handshake_accept_ntf_free(struct handshake_accept_ntf *rsp); + +/* ============== HANDSHAKE_CMD_DONE ============== */ +/* HANDSHAKE_CMD_DONE - do */ +struct handshake_done_req { + struct { + __u32 status:1; + __u32 sockfd:1; + } _present; + + __u32 status; + __s32 sockfd; + unsigned int n_remote_auth; + __u32 *remote_auth; +}; + +static inline struct handshake_done_req *handshake_done_req_alloc(void) +{ + return calloc(1, sizeof(struct handshake_done_req)); +} +void handshake_done_req_free(struct handshake_done_req *req); + +static inline void +handshake_done_req_set_status(struct handshake_done_req *req, __u32 status) +{ + req->_present.status = 1; + req->status = status; +} +static inline void +handshake_done_req_set_sockfd(struct handshake_done_req *req, __s32 sockfd) +{ + req->_present.sockfd = 1; + req->sockfd = sockfd; +} +static inline void +__handshake_done_req_set_remote_auth(struct handshake_done_req *req, + __u32 *remote_auth, + unsigned int n_remote_auth) +{ + free(req->remote_auth); + req->remote_auth = remote_auth; + req->n_remote_auth = n_remote_auth; +} + +/* + * Handler reports handshake completion + */ +int handshake_done(struct ynl_sock *ys, struct handshake_done_req *req); + +#endif /* _LINUX_HANDSHAKE_GEN_H */ diff --git a/generated/mptcp_pm-user.c b/generated/mptcp_pm-user.c new file mode 100644 index 0000000..deb15fa --- /dev/null +++ b/generated/mptcp_pm-user.c @@ -0,0 +1,641 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/mptcp_pm.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "mptcp_pm-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const mptcp_pm_op_strmap[] = { + [MPTCP_PM_CMD_ADD_ADDR] = "add-addr", + [MPTCP_PM_CMD_DEL_ADDR] = "del-addr", + [MPTCP_PM_CMD_GET_ADDR] = "get-addr", + [MPTCP_PM_CMD_FLUSH_ADDRS] = "flush-addrs", + [MPTCP_PM_CMD_SET_LIMITS] = "set-limits", + [MPTCP_PM_CMD_GET_LIMITS] = "get-limits", + [MPTCP_PM_CMD_SET_FLAGS] = "set-flags", + [MPTCP_PM_CMD_ANNOUNCE] = "announce", + [MPTCP_PM_CMD_REMOVE] = "remove", + [MPTCP_PM_CMD_SUBFLOW_CREATE] = "subflow-create", + [MPTCP_PM_CMD_SUBFLOW_DESTROY] = "subflow-destroy", +}; + +const char *mptcp_pm_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(mptcp_pm_op_strmap)) + return NULL; + return mptcp_pm_op_strmap[op]; +} + +static const char * const mptcp_pm_event_type_strmap[] = { + [0] = "unspec", + [1] = "created", + [2] = "established", + [3] = "closed", + [6] = "announced", + [7] = "removed", + [10] = "sub-established", + [11] = "sub-closed", + [13] = "sub-priority", + [15] = "listener-created", + [16] = "listener-closed", +}; + +const char *mptcp_pm_event_type_str(enum mptcp_event_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(mptcp_pm_event_type_strmap)) + return NULL; + return mptcp_pm_event_type_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr mptcp_pm_address_policy[MPTCP_PM_ADDR_ATTR_MAX + 1] = { + [MPTCP_PM_ADDR_ATTR_UNSPEC] = { .name = "unspec", .type = YNL_PT_REJECT, }, + [MPTCP_PM_ADDR_ATTR_FAMILY] = { .name = "family", .type = YNL_PT_U16, }, + [MPTCP_PM_ADDR_ATTR_ID] = { .name = "id", .type = YNL_PT_U8, }, + [MPTCP_PM_ADDR_ATTR_ADDR4] = { .name = "addr4", .type = YNL_PT_U32, }, + [MPTCP_PM_ADDR_ATTR_ADDR6] = { .name = "addr6", .type = YNL_PT_BINARY,}, + [MPTCP_PM_ADDR_ATTR_PORT] = { .name = "port", .type = YNL_PT_U16, }, + [MPTCP_PM_ADDR_ATTR_FLAGS] = { .name = "flags", .type = YNL_PT_U32, }, + [MPTCP_PM_ADDR_ATTR_IF_IDX] = { .name = "if-idx", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest mptcp_pm_address_nest = { + .max_attr = MPTCP_PM_ADDR_ATTR_MAX, + .table = mptcp_pm_address_policy, +}; + +struct ynl_policy_attr mptcp_pm_endpoint_policy[MPTCP_PM_ENDPOINT_MAX + 1] = { + [MPTCP_PM_ENDPOINT_ADDR] = { .name = "addr", .type = YNL_PT_NEST, .nest = &mptcp_pm_address_nest, }, +}; + +struct ynl_policy_nest mptcp_pm_endpoint_nest = { + .max_attr = MPTCP_PM_ENDPOINT_MAX, + .table = mptcp_pm_endpoint_policy, +}; + +struct ynl_policy_attr mptcp_pm_attr_policy[MPTCP_PM_ATTR_MAX + 1] = { + [MPTCP_PM_ATTR_UNSPEC] = { .name = "unspec", .type = YNL_PT_REJECT, }, + [MPTCP_PM_ATTR_ADDR] = { .name = "addr", .type = YNL_PT_NEST, .nest = &mptcp_pm_address_nest, }, + [MPTCP_PM_ATTR_RCV_ADD_ADDRS] = { .name = "rcv-add-addrs", .type = YNL_PT_U32, }, + [MPTCP_PM_ATTR_SUBFLOWS] = { .name = "subflows", .type = YNL_PT_U32, }, + [MPTCP_PM_ATTR_TOKEN] = { .name = "token", .type = YNL_PT_U32, }, + [MPTCP_PM_ATTR_LOC_ID] = { .name = "loc-id", .type = YNL_PT_U8, }, + [MPTCP_PM_ATTR_ADDR_REMOTE] = { .name = "addr-remote", .type = YNL_PT_NEST, .nest = &mptcp_pm_address_nest, }, +}; + +struct ynl_policy_nest mptcp_pm_attr_nest = { + .max_attr = MPTCP_PM_ATTR_MAX, + .table = mptcp_pm_attr_policy, +}; + +/* Common nested types */ +void mptcp_pm_address_free(struct mptcp_pm_address *obj) +{ + free(obj->addr6); +} + +int mptcp_pm_address_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct mptcp_pm_address *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.family) + ynl_attr_put_u16(nlh, MPTCP_PM_ADDR_ATTR_FAMILY, obj->family); + if (obj->_present.id) + ynl_attr_put_u8(nlh, MPTCP_PM_ADDR_ATTR_ID, obj->id); + if (obj->_present.addr4) + ynl_attr_put_u32(nlh, MPTCP_PM_ADDR_ATTR_ADDR4, obj->addr4); + if (obj->_present.addr6_len) + ynl_attr_put(nlh, MPTCP_PM_ADDR_ATTR_ADDR6, obj->addr6, obj->_present.addr6_len); + if (obj->_present.port) + ynl_attr_put_u16(nlh, MPTCP_PM_ADDR_ATTR_PORT, obj->port); + if (obj->_present.flags) + ynl_attr_put_u32(nlh, MPTCP_PM_ADDR_ATTR_FLAGS, obj->flags); + if (obj->_present.if_idx) + ynl_attr_put_s32(nlh, MPTCP_PM_ADDR_ATTR_IF_IDX, obj->if_idx); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int mptcp_pm_address_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct mptcp_pm_address *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == MPTCP_PM_ADDR_ATTR_FAMILY) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.family = 1; + dst->family = ynl_attr_get_u16(attr); + } else if (type == MPTCP_PM_ADDR_ATTR_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u8(attr); + } else if (type == MPTCP_PM_ADDR_ATTR_ADDR4) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.addr4 = 1; + dst->addr4 = ynl_attr_get_u32(attr); + } else if (type == MPTCP_PM_ADDR_ATTR_ADDR6) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.addr6_len = len; + dst->addr6 = malloc(len); + memcpy(dst->addr6, ynl_attr_data(attr), len); + } else if (type == MPTCP_PM_ADDR_ATTR_PORT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port = 1; + dst->port = ynl_attr_get_u16(attr); + } else if (type == MPTCP_PM_ADDR_ATTR_FLAGS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.flags = 1; + dst->flags = ynl_attr_get_u32(attr); + } else if (type == MPTCP_PM_ADDR_ATTR_IF_IDX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.if_idx = 1; + dst->if_idx = ynl_attr_get_s32(attr); + } + } + + return 0; +} + +/* ============== MPTCP_PM_CMD_ADD_ADDR ============== */ +/* MPTCP_PM_CMD_ADD_ADDR - do */ +void mptcp_pm_add_addr_req_free(struct mptcp_pm_add_addr_req *req) +{ + mptcp_pm_address_free(&req->addr); + free(req); +} + +int mptcp_pm_add_addr(struct ynl_sock *ys, struct mptcp_pm_add_addr_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_ADD_ADDR, 1); + ys->req_policy = &mptcp_pm_endpoint_nest; + + if (req->_present.addr) + mptcp_pm_address_put(nlh, MPTCP_PM_ENDPOINT_ADDR, &req->addr); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== MPTCP_PM_CMD_DEL_ADDR ============== */ +/* MPTCP_PM_CMD_DEL_ADDR - do */ +void mptcp_pm_del_addr_req_free(struct mptcp_pm_del_addr_req *req) +{ + mptcp_pm_address_free(&req->addr); + free(req); +} + +int mptcp_pm_del_addr(struct ynl_sock *ys, struct mptcp_pm_del_addr_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_DEL_ADDR, 1); + ys->req_policy = &mptcp_pm_endpoint_nest; + + if (req->_present.addr) + mptcp_pm_address_put(nlh, MPTCP_PM_ENDPOINT_ADDR, &req->addr); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== MPTCP_PM_CMD_GET_ADDR ============== */ +/* MPTCP_PM_CMD_GET_ADDR - do */ +void mptcp_pm_get_addr_req_free(struct mptcp_pm_get_addr_req *req) +{ + mptcp_pm_address_free(&req->addr); + free(req); +} + +void mptcp_pm_get_addr_rsp_free(struct mptcp_pm_get_addr_rsp *rsp) +{ + mptcp_pm_address_free(&rsp->addr); + free(rsp); +} + +int mptcp_pm_get_addr_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct mptcp_pm_get_addr_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == MPTCP_PM_ATTR_ADDR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.addr = 1; + + parg.rsp_policy = &mptcp_pm_address_nest; + parg.data = &dst->addr; + if (mptcp_pm_address_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct mptcp_pm_get_addr_rsp * +mptcp_pm_get_addr(struct ynl_sock *ys, struct mptcp_pm_get_addr_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct mptcp_pm_get_addr_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_GET_ADDR, 1); + ys->req_policy = &mptcp_pm_attr_nest; + yrs.yarg.rsp_policy = &mptcp_pm_attr_nest; + + if (req->_present.addr) + mptcp_pm_address_put(nlh, MPTCP_PM_ATTR_ADDR, &req->addr); + if (req->_present.token) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_TOKEN, req->token); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = mptcp_pm_get_addr_rsp_parse; + yrs.rsp_cmd = MPTCP_PM_CMD_GET_ADDR; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + mptcp_pm_get_addr_rsp_free(rsp); + return NULL; +} + +/* MPTCP_PM_CMD_GET_ADDR - dump */ +void mptcp_pm_get_addr_list_free(struct mptcp_pm_get_addr_list *rsp) +{ + struct mptcp_pm_get_addr_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + mptcp_pm_address_free(&rsp->obj.addr); + free(rsp); + } +} + +struct mptcp_pm_get_addr_list *mptcp_pm_get_addr_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &mptcp_pm_attr_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct mptcp_pm_get_addr_list); + yds.cb = mptcp_pm_get_addr_rsp_parse; + yds.rsp_cmd = MPTCP_PM_CMD_GET_ADDR; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, MPTCP_PM_CMD_GET_ADDR, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + mptcp_pm_get_addr_list_free(yds.first); + return NULL; +} + +/* ============== MPTCP_PM_CMD_FLUSH_ADDRS ============== */ +/* MPTCP_PM_CMD_FLUSH_ADDRS - do */ +void mptcp_pm_flush_addrs_req_free(struct mptcp_pm_flush_addrs_req *req) +{ + mptcp_pm_address_free(&req->addr); + free(req); +} + +int mptcp_pm_flush_addrs(struct ynl_sock *ys, + struct mptcp_pm_flush_addrs_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_FLUSH_ADDRS, 1); + ys->req_policy = &mptcp_pm_endpoint_nest; + + if (req->_present.addr) + mptcp_pm_address_put(nlh, MPTCP_PM_ENDPOINT_ADDR, &req->addr); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== MPTCP_PM_CMD_SET_LIMITS ============== */ +/* MPTCP_PM_CMD_SET_LIMITS - do */ +void mptcp_pm_set_limits_req_free(struct mptcp_pm_set_limits_req *req) +{ + free(req); +} + +int mptcp_pm_set_limits(struct ynl_sock *ys, + struct mptcp_pm_set_limits_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_SET_LIMITS, 1); + ys->req_policy = &mptcp_pm_attr_nest; + + if (req->_present.rcv_add_addrs) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_RCV_ADD_ADDRS, req->rcv_add_addrs); + if (req->_present.subflows) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_SUBFLOWS, req->subflows); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== MPTCP_PM_CMD_GET_LIMITS ============== */ +/* MPTCP_PM_CMD_GET_LIMITS - do */ +void mptcp_pm_get_limits_req_free(struct mptcp_pm_get_limits_req *req) +{ + free(req); +} + +void mptcp_pm_get_limits_rsp_free(struct mptcp_pm_get_limits_rsp *rsp) +{ + free(rsp); +} + +int mptcp_pm_get_limits_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct mptcp_pm_get_limits_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == MPTCP_PM_ATTR_RCV_ADD_ADDRS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rcv_add_addrs = 1; + dst->rcv_add_addrs = ynl_attr_get_u32(attr); + } else if (type == MPTCP_PM_ATTR_SUBFLOWS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.subflows = 1; + dst->subflows = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct mptcp_pm_get_limits_rsp * +mptcp_pm_get_limits(struct ynl_sock *ys, struct mptcp_pm_get_limits_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct mptcp_pm_get_limits_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_GET_LIMITS, 1); + ys->req_policy = &mptcp_pm_attr_nest; + yrs.yarg.rsp_policy = &mptcp_pm_attr_nest; + + if (req->_present.rcv_add_addrs) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_RCV_ADD_ADDRS, req->rcv_add_addrs); + if (req->_present.subflows) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_SUBFLOWS, req->subflows); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = mptcp_pm_get_limits_rsp_parse; + yrs.rsp_cmd = MPTCP_PM_CMD_GET_LIMITS; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + mptcp_pm_get_limits_rsp_free(rsp); + return NULL; +} + +/* ============== MPTCP_PM_CMD_SET_FLAGS ============== */ +/* MPTCP_PM_CMD_SET_FLAGS - do */ +void mptcp_pm_set_flags_req_free(struct mptcp_pm_set_flags_req *req) +{ + mptcp_pm_address_free(&req->addr); + mptcp_pm_address_free(&req->addr_remote); + free(req); +} + +int mptcp_pm_set_flags(struct ynl_sock *ys, struct mptcp_pm_set_flags_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_SET_FLAGS, 1); + ys->req_policy = &mptcp_pm_attr_nest; + + if (req->_present.addr) + mptcp_pm_address_put(nlh, MPTCP_PM_ATTR_ADDR, &req->addr); + if (req->_present.token) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_TOKEN, req->token); + if (req->_present.addr_remote) + mptcp_pm_address_put(nlh, MPTCP_PM_ATTR_ADDR_REMOTE, &req->addr_remote); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== MPTCP_PM_CMD_ANNOUNCE ============== */ +/* MPTCP_PM_CMD_ANNOUNCE - do */ +void mptcp_pm_announce_req_free(struct mptcp_pm_announce_req *req) +{ + mptcp_pm_address_free(&req->addr); + free(req); +} + +int mptcp_pm_announce(struct ynl_sock *ys, struct mptcp_pm_announce_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_ANNOUNCE, 1); + ys->req_policy = &mptcp_pm_attr_nest; + + if (req->_present.addr) + mptcp_pm_address_put(nlh, MPTCP_PM_ATTR_ADDR, &req->addr); + if (req->_present.token) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_TOKEN, req->token); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== MPTCP_PM_CMD_REMOVE ============== */ +/* MPTCP_PM_CMD_REMOVE - do */ +void mptcp_pm_remove_req_free(struct mptcp_pm_remove_req *req) +{ + free(req); +} + +int mptcp_pm_remove(struct ynl_sock *ys, struct mptcp_pm_remove_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_REMOVE, 1); + ys->req_policy = &mptcp_pm_attr_nest; + + if (req->_present.token) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_TOKEN, req->token); + if (req->_present.loc_id) + ynl_attr_put_u8(nlh, MPTCP_PM_ATTR_LOC_ID, req->loc_id); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== MPTCP_PM_CMD_SUBFLOW_CREATE ============== */ +/* MPTCP_PM_CMD_SUBFLOW_CREATE - do */ +void mptcp_pm_subflow_create_req_free(struct mptcp_pm_subflow_create_req *req) +{ + mptcp_pm_address_free(&req->addr); + mptcp_pm_address_free(&req->addr_remote); + free(req); +} + +int mptcp_pm_subflow_create(struct ynl_sock *ys, + struct mptcp_pm_subflow_create_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_SUBFLOW_CREATE, 1); + ys->req_policy = &mptcp_pm_attr_nest; + + if (req->_present.addr) + mptcp_pm_address_put(nlh, MPTCP_PM_ATTR_ADDR, &req->addr); + if (req->_present.token) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_TOKEN, req->token); + if (req->_present.addr_remote) + mptcp_pm_address_put(nlh, MPTCP_PM_ATTR_ADDR_REMOTE, &req->addr_remote); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== MPTCP_PM_CMD_SUBFLOW_DESTROY ============== */ +/* MPTCP_PM_CMD_SUBFLOW_DESTROY - do */ +void +mptcp_pm_subflow_destroy_req_free(struct mptcp_pm_subflow_destroy_req *req) +{ + mptcp_pm_address_free(&req->addr); + mptcp_pm_address_free(&req->addr_remote); + free(req); +} + +int mptcp_pm_subflow_destroy(struct ynl_sock *ys, + struct mptcp_pm_subflow_destroy_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, MPTCP_PM_CMD_SUBFLOW_DESTROY, 1); + ys->req_policy = &mptcp_pm_attr_nest; + + if (req->_present.addr) + mptcp_pm_address_put(nlh, MPTCP_PM_ATTR_ADDR, &req->addr); + if (req->_present.token) + ynl_attr_put_u32(nlh, MPTCP_PM_ATTR_TOKEN, req->token); + if (req->_present.addr_remote) + mptcp_pm_address_put(nlh, MPTCP_PM_ATTR_ADDR_REMOTE, &req->addr_remote); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +const struct ynl_family ynl_mptcp_pm_family = { + .name = "mptcp_pm", + .hdr_len = sizeof(struct genlmsghdr), +}; diff --git a/generated/mptcp_pm-user.h b/generated/mptcp_pm-user.h new file mode 100644 index 0000000..a7b27e6 --- /dev/null +++ b/generated/mptcp_pm-user.h @@ -0,0 +1,1048 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/mptcp_pm.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_MPTCP_PM_GEN_H +#define _LINUX_MPTCP_PM_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_mptcp_pm_family; + +/* Enums */ +const char *mptcp_pm_op_str(int op); +const char *mptcp_pm_event_type_str(enum mptcp_event_type value); + +/* Common nested types */ +struct mptcp_pm_address { + struct { + __u32 family:1; + __u32 id:1; + __u32 addr4:1; + __u32 addr6_len; + __u32 port:1; + __u32 flags:1; + __u32 if_idx:1; + } _present; + + __u16 family; + __u8 id; + __u32 addr4 /* big-endian */; + void *addr6; + __u16 port /* big-endian */; + __u32 flags; + __s32 if_idx; +}; + +/* ============== MPTCP_PM_CMD_ADD_ADDR ============== */ +/* MPTCP_PM_CMD_ADD_ADDR - do */ +struct mptcp_pm_add_addr_req { + struct { + __u32 addr:1; + } _present; + + struct mptcp_pm_address addr; +}; + +static inline struct mptcp_pm_add_addr_req *mptcp_pm_add_addr_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_add_addr_req)); +} +void mptcp_pm_add_addr_req_free(struct mptcp_pm_add_addr_req *req); + +static inline void +mptcp_pm_add_addr_req_set_addr_family(struct mptcp_pm_add_addr_req *req, + __u16 family) +{ + req->_present.addr = 1; + req->addr._present.family = 1; + req->addr.family = family; +} +static inline void +mptcp_pm_add_addr_req_set_addr_id(struct mptcp_pm_add_addr_req *req, __u8 id) +{ + req->_present.addr = 1; + req->addr._present.id = 1; + req->addr.id = id; +} +static inline void +mptcp_pm_add_addr_req_set_addr_addr4(struct mptcp_pm_add_addr_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.addr4 = 1; + req->addr.addr4 = addr4; +} +static inline void +mptcp_pm_add_addr_req_set_addr_addr6(struct mptcp_pm_add_addr_req *req, + const void *addr6, size_t len) +{ + free(req->addr.addr6); + req->addr._present.addr6_len = len; + req->addr.addr6 = malloc(req->addr._present.addr6_len); + memcpy(req->addr.addr6, addr6, req->addr._present.addr6_len); +} +static inline void +mptcp_pm_add_addr_req_set_addr_port(struct mptcp_pm_add_addr_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.port = 1; + req->addr.port = port; +} +static inline void +mptcp_pm_add_addr_req_set_addr_flags(struct mptcp_pm_add_addr_req *req, + __u32 flags) +{ + req->_present.addr = 1; + req->addr._present.flags = 1; + req->addr.flags = flags; +} +static inline void +mptcp_pm_add_addr_req_set_addr_if_idx(struct mptcp_pm_add_addr_req *req, + __s32 if_idx) +{ + req->_present.addr = 1; + req->addr._present.if_idx = 1; + req->addr.if_idx = if_idx; +} + +/* + * Add endpoint + */ +int mptcp_pm_add_addr(struct ynl_sock *ys, struct mptcp_pm_add_addr_req *req); + +/* ============== MPTCP_PM_CMD_DEL_ADDR ============== */ +/* MPTCP_PM_CMD_DEL_ADDR - do */ +struct mptcp_pm_del_addr_req { + struct { + __u32 addr:1; + } _present; + + struct mptcp_pm_address addr; +}; + +static inline struct mptcp_pm_del_addr_req *mptcp_pm_del_addr_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_del_addr_req)); +} +void mptcp_pm_del_addr_req_free(struct mptcp_pm_del_addr_req *req); + +static inline void +mptcp_pm_del_addr_req_set_addr_family(struct mptcp_pm_del_addr_req *req, + __u16 family) +{ + req->_present.addr = 1; + req->addr._present.family = 1; + req->addr.family = family; +} +static inline void +mptcp_pm_del_addr_req_set_addr_id(struct mptcp_pm_del_addr_req *req, __u8 id) +{ + req->_present.addr = 1; + req->addr._present.id = 1; + req->addr.id = id; +} +static inline void +mptcp_pm_del_addr_req_set_addr_addr4(struct mptcp_pm_del_addr_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.addr4 = 1; + req->addr.addr4 = addr4; +} +static inline void +mptcp_pm_del_addr_req_set_addr_addr6(struct mptcp_pm_del_addr_req *req, + const void *addr6, size_t len) +{ + free(req->addr.addr6); + req->addr._present.addr6_len = len; + req->addr.addr6 = malloc(req->addr._present.addr6_len); + memcpy(req->addr.addr6, addr6, req->addr._present.addr6_len); +} +static inline void +mptcp_pm_del_addr_req_set_addr_port(struct mptcp_pm_del_addr_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.port = 1; + req->addr.port = port; +} +static inline void +mptcp_pm_del_addr_req_set_addr_flags(struct mptcp_pm_del_addr_req *req, + __u32 flags) +{ + req->_present.addr = 1; + req->addr._present.flags = 1; + req->addr.flags = flags; +} +static inline void +mptcp_pm_del_addr_req_set_addr_if_idx(struct mptcp_pm_del_addr_req *req, + __s32 if_idx) +{ + req->_present.addr = 1; + req->addr._present.if_idx = 1; + req->addr.if_idx = if_idx; +} + +/* + * Delete endpoint + */ +int mptcp_pm_del_addr(struct ynl_sock *ys, struct mptcp_pm_del_addr_req *req); + +/* ============== MPTCP_PM_CMD_GET_ADDR ============== */ +/* MPTCP_PM_CMD_GET_ADDR - do */ +struct mptcp_pm_get_addr_req { + struct { + __u32 addr:1; + __u32 token:1; + } _present; + + struct mptcp_pm_address addr; + __u32 token; +}; + +static inline struct mptcp_pm_get_addr_req *mptcp_pm_get_addr_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_get_addr_req)); +} +void mptcp_pm_get_addr_req_free(struct mptcp_pm_get_addr_req *req); + +static inline void +mptcp_pm_get_addr_req_set_addr_family(struct mptcp_pm_get_addr_req *req, + __u16 family) +{ + req->_present.addr = 1; + req->addr._present.family = 1; + req->addr.family = family; +} +static inline void +mptcp_pm_get_addr_req_set_addr_id(struct mptcp_pm_get_addr_req *req, __u8 id) +{ + req->_present.addr = 1; + req->addr._present.id = 1; + req->addr.id = id; +} +static inline void +mptcp_pm_get_addr_req_set_addr_addr4(struct mptcp_pm_get_addr_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.addr4 = 1; + req->addr.addr4 = addr4; +} +static inline void +mptcp_pm_get_addr_req_set_addr_addr6(struct mptcp_pm_get_addr_req *req, + const void *addr6, size_t len) +{ + free(req->addr.addr6); + req->addr._present.addr6_len = len; + req->addr.addr6 = malloc(req->addr._present.addr6_len); + memcpy(req->addr.addr6, addr6, req->addr._present.addr6_len); +} +static inline void +mptcp_pm_get_addr_req_set_addr_port(struct mptcp_pm_get_addr_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.port = 1; + req->addr.port = port; +} +static inline void +mptcp_pm_get_addr_req_set_addr_flags(struct mptcp_pm_get_addr_req *req, + __u32 flags) +{ + req->_present.addr = 1; + req->addr._present.flags = 1; + req->addr.flags = flags; +} +static inline void +mptcp_pm_get_addr_req_set_addr_if_idx(struct mptcp_pm_get_addr_req *req, + __s32 if_idx) +{ + req->_present.addr = 1; + req->addr._present.if_idx = 1; + req->addr.if_idx = if_idx; +} +static inline void +mptcp_pm_get_addr_req_set_token(struct mptcp_pm_get_addr_req *req, __u32 token) +{ + req->_present.token = 1; + req->token = token; +} + +struct mptcp_pm_get_addr_rsp { + struct { + __u32 addr:1; + } _present; + + struct mptcp_pm_address addr; +}; + +void mptcp_pm_get_addr_rsp_free(struct mptcp_pm_get_addr_rsp *rsp); + +/* + * Get endpoint information + */ +struct mptcp_pm_get_addr_rsp * +mptcp_pm_get_addr(struct ynl_sock *ys, struct mptcp_pm_get_addr_req *req); + +/* MPTCP_PM_CMD_GET_ADDR - dump */ +struct mptcp_pm_get_addr_list { + struct mptcp_pm_get_addr_list *next; + struct mptcp_pm_get_addr_rsp obj __attribute__((aligned(8))); +}; + +void mptcp_pm_get_addr_list_free(struct mptcp_pm_get_addr_list *rsp); + +struct mptcp_pm_get_addr_list *mptcp_pm_get_addr_dump(struct ynl_sock *ys); + +/* ============== MPTCP_PM_CMD_FLUSH_ADDRS ============== */ +/* MPTCP_PM_CMD_FLUSH_ADDRS - do */ +struct mptcp_pm_flush_addrs_req { + struct { + __u32 addr:1; + } _present; + + struct mptcp_pm_address addr; +}; + +static inline struct mptcp_pm_flush_addrs_req * +mptcp_pm_flush_addrs_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_flush_addrs_req)); +} +void mptcp_pm_flush_addrs_req_free(struct mptcp_pm_flush_addrs_req *req); + +static inline void +mptcp_pm_flush_addrs_req_set_addr_family(struct mptcp_pm_flush_addrs_req *req, + __u16 family) +{ + req->_present.addr = 1; + req->addr._present.family = 1; + req->addr.family = family; +} +static inline void +mptcp_pm_flush_addrs_req_set_addr_id(struct mptcp_pm_flush_addrs_req *req, + __u8 id) +{ + req->_present.addr = 1; + req->addr._present.id = 1; + req->addr.id = id; +} +static inline void +mptcp_pm_flush_addrs_req_set_addr_addr4(struct mptcp_pm_flush_addrs_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.addr4 = 1; + req->addr.addr4 = addr4; +} +static inline void +mptcp_pm_flush_addrs_req_set_addr_addr6(struct mptcp_pm_flush_addrs_req *req, + const void *addr6, size_t len) +{ + free(req->addr.addr6); + req->addr._present.addr6_len = len; + req->addr.addr6 = malloc(req->addr._present.addr6_len); + memcpy(req->addr.addr6, addr6, req->addr._present.addr6_len); +} +static inline void +mptcp_pm_flush_addrs_req_set_addr_port(struct mptcp_pm_flush_addrs_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.port = 1; + req->addr.port = port; +} +static inline void +mptcp_pm_flush_addrs_req_set_addr_flags(struct mptcp_pm_flush_addrs_req *req, + __u32 flags) +{ + req->_present.addr = 1; + req->addr._present.flags = 1; + req->addr.flags = flags; +} +static inline void +mptcp_pm_flush_addrs_req_set_addr_if_idx(struct mptcp_pm_flush_addrs_req *req, + __s32 if_idx) +{ + req->_present.addr = 1; + req->addr._present.if_idx = 1; + req->addr.if_idx = if_idx; +} + +/* + * flush addresses + */ +int mptcp_pm_flush_addrs(struct ynl_sock *ys, + struct mptcp_pm_flush_addrs_req *req); + +/* ============== MPTCP_PM_CMD_SET_LIMITS ============== */ +/* MPTCP_PM_CMD_SET_LIMITS - do */ +struct mptcp_pm_set_limits_req { + struct { + __u32 rcv_add_addrs:1; + __u32 subflows:1; + } _present; + + __u32 rcv_add_addrs; + __u32 subflows; +}; + +static inline struct mptcp_pm_set_limits_req * +mptcp_pm_set_limits_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_set_limits_req)); +} +void mptcp_pm_set_limits_req_free(struct mptcp_pm_set_limits_req *req); + +static inline void +mptcp_pm_set_limits_req_set_rcv_add_addrs(struct mptcp_pm_set_limits_req *req, + __u32 rcv_add_addrs) +{ + req->_present.rcv_add_addrs = 1; + req->rcv_add_addrs = rcv_add_addrs; +} +static inline void +mptcp_pm_set_limits_req_set_subflows(struct mptcp_pm_set_limits_req *req, + __u32 subflows) +{ + req->_present.subflows = 1; + req->subflows = subflows; +} + +/* + * Set protocol limits + */ +int mptcp_pm_set_limits(struct ynl_sock *ys, + struct mptcp_pm_set_limits_req *req); + +/* ============== MPTCP_PM_CMD_GET_LIMITS ============== */ +/* MPTCP_PM_CMD_GET_LIMITS - do */ +struct mptcp_pm_get_limits_req { + struct { + __u32 rcv_add_addrs:1; + __u32 subflows:1; + } _present; + + __u32 rcv_add_addrs; + __u32 subflows; +}; + +static inline struct mptcp_pm_get_limits_req * +mptcp_pm_get_limits_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_get_limits_req)); +} +void mptcp_pm_get_limits_req_free(struct mptcp_pm_get_limits_req *req); + +static inline void +mptcp_pm_get_limits_req_set_rcv_add_addrs(struct mptcp_pm_get_limits_req *req, + __u32 rcv_add_addrs) +{ + req->_present.rcv_add_addrs = 1; + req->rcv_add_addrs = rcv_add_addrs; +} +static inline void +mptcp_pm_get_limits_req_set_subflows(struct mptcp_pm_get_limits_req *req, + __u32 subflows) +{ + req->_present.subflows = 1; + req->subflows = subflows; +} + +struct mptcp_pm_get_limits_rsp { + struct { + __u32 rcv_add_addrs:1; + __u32 subflows:1; + } _present; + + __u32 rcv_add_addrs; + __u32 subflows; +}; + +void mptcp_pm_get_limits_rsp_free(struct mptcp_pm_get_limits_rsp *rsp); + +/* + * Get protocol limits + */ +struct mptcp_pm_get_limits_rsp * +mptcp_pm_get_limits(struct ynl_sock *ys, struct mptcp_pm_get_limits_req *req); + +/* ============== MPTCP_PM_CMD_SET_FLAGS ============== */ +/* MPTCP_PM_CMD_SET_FLAGS - do */ +struct mptcp_pm_set_flags_req { + struct { + __u32 addr:1; + __u32 token:1; + __u32 addr_remote:1; + } _present; + + struct mptcp_pm_address addr; + __u32 token; + struct mptcp_pm_address addr_remote; +}; + +static inline struct mptcp_pm_set_flags_req *mptcp_pm_set_flags_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_set_flags_req)); +} +void mptcp_pm_set_flags_req_free(struct mptcp_pm_set_flags_req *req); + +static inline void +mptcp_pm_set_flags_req_set_addr_family(struct mptcp_pm_set_flags_req *req, + __u16 family) +{ + req->_present.addr = 1; + req->addr._present.family = 1; + req->addr.family = family; +} +static inline void +mptcp_pm_set_flags_req_set_addr_id(struct mptcp_pm_set_flags_req *req, __u8 id) +{ + req->_present.addr = 1; + req->addr._present.id = 1; + req->addr.id = id; +} +static inline void +mptcp_pm_set_flags_req_set_addr_addr4(struct mptcp_pm_set_flags_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.addr4 = 1; + req->addr.addr4 = addr4; +} +static inline void +mptcp_pm_set_flags_req_set_addr_addr6(struct mptcp_pm_set_flags_req *req, + const void *addr6, size_t len) +{ + free(req->addr.addr6); + req->addr._present.addr6_len = len; + req->addr.addr6 = malloc(req->addr._present.addr6_len); + memcpy(req->addr.addr6, addr6, req->addr._present.addr6_len); +} +static inline void +mptcp_pm_set_flags_req_set_addr_port(struct mptcp_pm_set_flags_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.port = 1; + req->addr.port = port; +} +static inline void +mptcp_pm_set_flags_req_set_addr_flags(struct mptcp_pm_set_flags_req *req, + __u32 flags) +{ + req->_present.addr = 1; + req->addr._present.flags = 1; + req->addr.flags = flags; +} +static inline void +mptcp_pm_set_flags_req_set_addr_if_idx(struct mptcp_pm_set_flags_req *req, + __s32 if_idx) +{ + req->_present.addr = 1; + req->addr._present.if_idx = 1; + req->addr.if_idx = if_idx; +} +static inline void +mptcp_pm_set_flags_req_set_token(struct mptcp_pm_set_flags_req *req, + __u32 token) +{ + req->_present.token = 1; + req->token = token; +} +static inline void +mptcp_pm_set_flags_req_set_addr_remote_family(struct mptcp_pm_set_flags_req *req, + __u16 family) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.family = 1; + req->addr_remote.family = family; +} +static inline void +mptcp_pm_set_flags_req_set_addr_remote_id(struct mptcp_pm_set_flags_req *req, + __u8 id) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.id = 1; + req->addr_remote.id = id; +} +static inline void +mptcp_pm_set_flags_req_set_addr_remote_addr4(struct mptcp_pm_set_flags_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.addr4 = 1; + req->addr_remote.addr4 = addr4; +} +static inline void +mptcp_pm_set_flags_req_set_addr_remote_addr6(struct mptcp_pm_set_flags_req *req, + const void *addr6, size_t len) +{ + free(req->addr_remote.addr6); + req->addr_remote._present.addr6_len = len; + req->addr_remote.addr6 = malloc(req->addr_remote._present.addr6_len); + memcpy(req->addr_remote.addr6, addr6, req->addr_remote._present.addr6_len); +} +static inline void +mptcp_pm_set_flags_req_set_addr_remote_port(struct mptcp_pm_set_flags_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.port = 1; + req->addr_remote.port = port; +} +static inline void +mptcp_pm_set_flags_req_set_addr_remote_flags(struct mptcp_pm_set_flags_req *req, + __u32 flags) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.flags = 1; + req->addr_remote.flags = flags; +} +static inline void +mptcp_pm_set_flags_req_set_addr_remote_if_idx(struct mptcp_pm_set_flags_req *req, + __s32 if_idx) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.if_idx = 1; + req->addr_remote.if_idx = if_idx; +} + +/* + * Change endpoint flags + */ +int mptcp_pm_set_flags(struct ynl_sock *ys, struct mptcp_pm_set_flags_req *req); + +/* ============== MPTCP_PM_CMD_ANNOUNCE ============== */ +/* MPTCP_PM_CMD_ANNOUNCE - do */ +struct mptcp_pm_announce_req { + struct { + __u32 addr:1; + __u32 token:1; + } _present; + + struct mptcp_pm_address addr; + __u32 token; +}; + +static inline struct mptcp_pm_announce_req *mptcp_pm_announce_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_announce_req)); +} +void mptcp_pm_announce_req_free(struct mptcp_pm_announce_req *req); + +static inline void +mptcp_pm_announce_req_set_addr_family(struct mptcp_pm_announce_req *req, + __u16 family) +{ + req->_present.addr = 1; + req->addr._present.family = 1; + req->addr.family = family; +} +static inline void +mptcp_pm_announce_req_set_addr_id(struct mptcp_pm_announce_req *req, __u8 id) +{ + req->_present.addr = 1; + req->addr._present.id = 1; + req->addr.id = id; +} +static inline void +mptcp_pm_announce_req_set_addr_addr4(struct mptcp_pm_announce_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.addr4 = 1; + req->addr.addr4 = addr4; +} +static inline void +mptcp_pm_announce_req_set_addr_addr6(struct mptcp_pm_announce_req *req, + const void *addr6, size_t len) +{ + free(req->addr.addr6); + req->addr._present.addr6_len = len; + req->addr.addr6 = malloc(req->addr._present.addr6_len); + memcpy(req->addr.addr6, addr6, req->addr._present.addr6_len); +} +static inline void +mptcp_pm_announce_req_set_addr_port(struct mptcp_pm_announce_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.port = 1; + req->addr.port = port; +} +static inline void +mptcp_pm_announce_req_set_addr_flags(struct mptcp_pm_announce_req *req, + __u32 flags) +{ + req->_present.addr = 1; + req->addr._present.flags = 1; + req->addr.flags = flags; +} +static inline void +mptcp_pm_announce_req_set_addr_if_idx(struct mptcp_pm_announce_req *req, + __s32 if_idx) +{ + req->_present.addr = 1; + req->addr._present.if_idx = 1; + req->addr.if_idx = if_idx; +} +static inline void +mptcp_pm_announce_req_set_token(struct mptcp_pm_announce_req *req, __u32 token) +{ + req->_present.token = 1; + req->token = token; +} + +/* + * announce new sf + */ +int mptcp_pm_announce(struct ynl_sock *ys, struct mptcp_pm_announce_req *req); + +/* ============== MPTCP_PM_CMD_REMOVE ============== */ +/* MPTCP_PM_CMD_REMOVE - do */ +struct mptcp_pm_remove_req { + struct { + __u32 token:1; + __u32 loc_id:1; + } _present; + + __u32 token; + __u8 loc_id; +}; + +static inline struct mptcp_pm_remove_req *mptcp_pm_remove_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_remove_req)); +} +void mptcp_pm_remove_req_free(struct mptcp_pm_remove_req *req); + +static inline void +mptcp_pm_remove_req_set_token(struct mptcp_pm_remove_req *req, __u32 token) +{ + req->_present.token = 1; + req->token = token; +} +static inline void +mptcp_pm_remove_req_set_loc_id(struct mptcp_pm_remove_req *req, __u8 loc_id) +{ + req->_present.loc_id = 1; + req->loc_id = loc_id; +} + +/* + * announce removal + */ +int mptcp_pm_remove(struct ynl_sock *ys, struct mptcp_pm_remove_req *req); + +/* ============== MPTCP_PM_CMD_SUBFLOW_CREATE ============== */ +/* MPTCP_PM_CMD_SUBFLOW_CREATE - do */ +struct mptcp_pm_subflow_create_req { + struct { + __u32 addr:1; + __u32 token:1; + __u32 addr_remote:1; + } _present; + + struct mptcp_pm_address addr; + __u32 token; + struct mptcp_pm_address addr_remote; +}; + +static inline struct mptcp_pm_subflow_create_req * +mptcp_pm_subflow_create_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_subflow_create_req)); +} +void mptcp_pm_subflow_create_req_free(struct mptcp_pm_subflow_create_req *req); + +static inline void +mptcp_pm_subflow_create_req_set_addr_family(struct mptcp_pm_subflow_create_req *req, + __u16 family) +{ + req->_present.addr = 1; + req->addr._present.family = 1; + req->addr.family = family; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_id(struct mptcp_pm_subflow_create_req *req, + __u8 id) +{ + req->_present.addr = 1; + req->addr._present.id = 1; + req->addr.id = id; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_addr4(struct mptcp_pm_subflow_create_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.addr4 = 1; + req->addr.addr4 = addr4; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_addr6(struct mptcp_pm_subflow_create_req *req, + const void *addr6, size_t len) +{ + free(req->addr.addr6); + req->addr._present.addr6_len = len; + req->addr.addr6 = malloc(req->addr._present.addr6_len); + memcpy(req->addr.addr6, addr6, req->addr._present.addr6_len); +} +static inline void +mptcp_pm_subflow_create_req_set_addr_port(struct mptcp_pm_subflow_create_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.port = 1; + req->addr.port = port; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_flags(struct mptcp_pm_subflow_create_req *req, + __u32 flags) +{ + req->_present.addr = 1; + req->addr._present.flags = 1; + req->addr.flags = flags; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_if_idx(struct mptcp_pm_subflow_create_req *req, + __s32 if_idx) +{ + req->_present.addr = 1; + req->addr._present.if_idx = 1; + req->addr.if_idx = if_idx; +} +static inline void +mptcp_pm_subflow_create_req_set_token(struct mptcp_pm_subflow_create_req *req, + __u32 token) +{ + req->_present.token = 1; + req->token = token; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_remote_family(struct mptcp_pm_subflow_create_req *req, + __u16 family) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.family = 1; + req->addr_remote.family = family; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_remote_id(struct mptcp_pm_subflow_create_req *req, + __u8 id) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.id = 1; + req->addr_remote.id = id; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_remote_addr4(struct mptcp_pm_subflow_create_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.addr4 = 1; + req->addr_remote.addr4 = addr4; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_remote_addr6(struct mptcp_pm_subflow_create_req *req, + const void *addr6, + size_t len) +{ + free(req->addr_remote.addr6); + req->addr_remote._present.addr6_len = len; + req->addr_remote.addr6 = malloc(req->addr_remote._present.addr6_len); + memcpy(req->addr_remote.addr6, addr6, req->addr_remote._present.addr6_len); +} +static inline void +mptcp_pm_subflow_create_req_set_addr_remote_port(struct mptcp_pm_subflow_create_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.port = 1; + req->addr_remote.port = port; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_remote_flags(struct mptcp_pm_subflow_create_req *req, + __u32 flags) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.flags = 1; + req->addr_remote.flags = flags; +} +static inline void +mptcp_pm_subflow_create_req_set_addr_remote_if_idx(struct mptcp_pm_subflow_create_req *req, + __s32 if_idx) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.if_idx = 1; + req->addr_remote.if_idx = if_idx; +} + +/* + * todo + */ +int mptcp_pm_subflow_create(struct ynl_sock *ys, + struct mptcp_pm_subflow_create_req *req); + +/* ============== MPTCP_PM_CMD_SUBFLOW_DESTROY ============== */ +/* MPTCP_PM_CMD_SUBFLOW_DESTROY - do */ +struct mptcp_pm_subflow_destroy_req { + struct { + __u32 addr:1; + __u32 token:1; + __u32 addr_remote:1; + } _present; + + struct mptcp_pm_address addr; + __u32 token; + struct mptcp_pm_address addr_remote; +}; + +static inline struct mptcp_pm_subflow_destroy_req * +mptcp_pm_subflow_destroy_req_alloc(void) +{ + return calloc(1, sizeof(struct mptcp_pm_subflow_destroy_req)); +} +void +mptcp_pm_subflow_destroy_req_free(struct mptcp_pm_subflow_destroy_req *req); + +static inline void +mptcp_pm_subflow_destroy_req_set_addr_family(struct mptcp_pm_subflow_destroy_req *req, + __u16 family) +{ + req->_present.addr = 1; + req->addr._present.family = 1; + req->addr.family = family; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_id(struct mptcp_pm_subflow_destroy_req *req, + __u8 id) +{ + req->_present.addr = 1; + req->addr._present.id = 1; + req->addr.id = id; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_addr4(struct mptcp_pm_subflow_destroy_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.addr4 = 1; + req->addr.addr4 = addr4; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_addr6(struct mptcp_pm_subflow_destroy_req *req, + const void *addr6, size_t len) +{ + free(req->addr.addr6); + req->addr._present.addr6_len = len; + req->addr.addr6 = malloc(req->addr._present.addr6_len); + memcpy(req->addr.addr6, addr6, req->addr._present.addr6_len); +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_port(struct mptcp_pm_subflow_destroy_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr = 1; + req->addr._present.port = 1; + req->addr.port = port; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_flags(struct mptcp_pm_subflow_destroy_req *req, + __u32 flags) +{ + req->_present.addr = 1; + req->addr._present.flags = 1; + req->addr.flags = flags; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_if_idx(struct mptcp_pm_subflow_destroy_req *req, + __s32 if_idx) +{ + req->_present.addr = 1; + req->addr._present.if_idx = 1; + req->addr.if_idx = if_idx; +} +static inline void +mptcp_pm_subflow_destroy_req_set_token(struct mptcp_pm_subflow_destroy_req *req, + __u32 token) +{ + req->_present.token = 1; + req->token = token; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_remote_family(struct mptcp_pm_subflow_destroy_req *req, + __u16 family) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.family = 1; + req->addr_remote.family = family; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_remote_id(struct mptcp_pm_subflow_destroy_req *req, + __u8 id) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.id = 1; + req->addr_remote.id = id; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_remote_addr4(struct mptcp_pm_subflow_destroy_req *req, + __u32 addr4 /* big-endian */) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.addr4 = 1; + req->addr_remote.addr4 = addr4; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_remote_addr6(struct mptcp_pm_subflow_destroy_req *req, + const void *addr6, + size_t len) +{ + free(req->addr_remote.addr6); + req->addr_remote._present.addr6_len = len; + req->addr_remote.addr6 = malloc(req->addr_remote._present.addr6_len); + memcpy(req->addr_remote.addr6, addr6, req->addr_remote._present.addr6_len); +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_remote_port(struct mptcp_pm_subflow_destroy_req *req, + __u16 port /* big-endian */) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.port = 1; + req->addr_remote.port = port; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_remote_flags(struct mptcp_pm_subflow_destroy_req *req, + __u32 flags) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.flags = 1; + req->addr_remote.flags = flags; +} +static inline void +mptcp_pm_subflow_destroy_req_set_addr_remote_if_idx(struct mptcp_pm_subflow_destroy_req *req, + __s32 if_idx) +{ + req->_present.addr_remote = 1; + req->addr_remote._present.if_idx = 1; + req->addr_remote.if_idx = if_idx; +} + +/* + * todo + */ +int mptcp_pm_subflow_destroy(struct ynl_sock *ys, + struct mptcp_pm_subflow_destroy_req *req); + +#endif /* _LINUX_MPTCP_PM_GEN_H */ diff --git a/generated/netdev-user.c b/generated/netdev-user.c new file mode 100644 index 0000000..40acba3 --- /dev/null +++ b/generated/netdev-user.c @@ -0,0 +1,1100 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/netdev.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "netdev-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const netdev_op_strmap[] = { + [NETDEV_CMD_DEV_GET] = "dev-get", + [NETDEV_CMD_DEV_ADD_NTF] = "dev-add-ntf", + [NETDEV_CMD_DEV_DEL_NTF] = "dev-del-ntf", + [NETDEV_CMD_DEV_CHANGE_NTF] = "dev-change-ntf", + [NETDEV_CMD_PAGE_POOL_GET] = "page-pool-get", + [NETDEV_CMD_PAGE_POOL_ADD_NTF] = "page-pool-add-ntf", + [NETDEV_CMD_PAGE_POOL_DEL_NTF] = "page-pool-del-ntf", + [NETDEV_CMD_PAGE_POOL_CHANGE_NTF] = "page-pool-change-ntf", + [NETDEV_CMD_PAGE_POOL_STATS_GET] = "page-pool-stats-get", + [NETDEV_CMD_QUEUE_GET] = "queue-get", + [NETDEV_CMD_NAPI_GET] = "napi-get", + [NETDEV_CMD_QSTATS_GET] = "qstats-get", +}; + +const char *netdev_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(netdev_op_strmap)) + return NULL; + return netdev_op_strmap[op]; +} + +static const char * const netdev_xdp_act_strmap[] = { + [0] = "basic", + [1] = "redirect", + [2] = "ndo-xmit", + [3] = "xsk-zerocopy", + [4] = "hw-offload", + [5] = "rx-sg", + [6] = "ndo-xmit-sg", +}; + +const char *netdev_xdp_act_str(enum netdev_xdp_act value) +{ + value = ffs(value) - 1; + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(netdev_xdp_act_strmap)) + return NULL; + return netdev_xdp_act_strmap[value]; +} + +static const char * const netdev_xdp_rx_metadata_strmap[] = { + [0] = "timestamp", + [1] = "hash", + [2] = "vlan-tag", +}; + +const char *netdev_xdp_rx_metadata_str(enum netdev_xdp_rx_metadata value) +{ + value = ffs(value) - 1; + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(netdev_xdp_rx_metadata_strmap)) + return NULL; + return netdev_xdp_rx_metadata_strmap[value]; +} + +static const char * const netdev_xsk_flags_strmap[] = { + [0] = "tx-timestamp", + [1] = "tx-checksum", +}; + +const char *netdev_xsk_flags_str(enum netdev_xsk_flags value) +{ + value = ffs(value) - 1; + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(netdev_xsk_flags_strmap)) + return NULL; + return netdev_xsk_flags_strmap[value]; +} + +static const char * const netdev_queue_type_strmap[] = { + [0] = "rx", + [1] = "tx", +}; + +const char *netdev_queue_type_str(enum netdev_queue_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(netdev_queue_type_strmap)) + return NULL; + return netdev_queue_type_strmap[value]; +} + +static const char * const netdev_qstats_scope_strmap[] = { + [0] = "queue", +}; + +const char *netdev_qstats_scope_str(enum netdev_qstats_scope value) +{ + value = ffs(value) - 1; + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(netdev_qstats_scope_strmap)) + return NULL; + return netdev_qstats_scope_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr netdev_page_pool_info_policy[NETDEV_A_PAGE_POOL_MAX + 1] = { + [NETDEV_A_PAGE_POOL_ID] = { .name = "id", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest netdev_page_pool_info_nest = { + .max_attr = NETDEV_A_PAGE_POOL_MAX, + .table = netdev_page_pool_info_policy, +}; + +struct ynl_policy_attr netdev_dev_policy[NETDEV_A_DEV_MAX + 1] = { + [NETDEV_A_DEV_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, + [NETDEV_A_DEV_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [NETDEV_A_DEV_XDP_FEATURES] = { .name = "xdp-features", .type = YNL_PT_U64, }, + [NETDEV_A_DEV_XDP_ZC_MAX_SEGS] = { .name = "xdp-zc-max-segs", .type = YNL_PT_U32, }, + [NETDEV_A_DEV_XDP_RX_METADATA_FEATURES] = { .name = "xdp-rx-metadata-features", .type = YNL_PT_U64, }, + [NETDEV_A_DEV_XSK_FEATURES] = { .name = "xsk-features", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest netdev_dev_nest = { + .max_attr = NETDEV_A_DEV_MAX, + .table = netdev_dev_policy, +}; + +struct ynl_policy_attr netdev_page_pool_policy[NETDEV_A_PAGE_POOL_MAX + 1] = { + [NETDEV_A_PAGE_POOL_ID] = { .name = "id", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, + [NETDEV_A_PAGE_POOL_NAPI_ID] = { .name = "napi-id", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_INFLIGHT] = { .name = "inflight", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_INFLIGHT_MEM] = { .name = "inflight-mem", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_DETACH_TIME] = { .name = "detach-time", .type = YNL_PT_UINT, }, +}; + +struct ynl_policy_nest netdev_page_pool_nest = { + .max_attr = NETDEV_A_PAGE_POOL_MAX, + .table = netdev_page_pool_policy, +}; + +struct ynl_policy_attr netdev_page_pool_stats_policy[NETDEV_A_PAGE_POOL_STATS_MAX + 1] = { + [NETDEV_A_PAGE_POOL_STATS_INFO] = { .name = "info", .type = YNL_PT_NEST, .nest = &netdev_page_pool_info_nest, }, + [NETDEV_A_PAGE_POOL_STATS_ALLOC_FAST] = { .name = "alloc-fast", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_ALLOC_SLOW] = { .name = "alloc-slow", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_ALLOC_SLOW_HIGH_ORDER] = { .name = "alloc-slow-high-order", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_ALLOC_EMPTY] = { .name = "alloc-empty", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_ALLOC_REFILL] = { .name = "alloc-refill", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_ALLOC_WAIVE] = { .name = "alloc-waive", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_RECYCLE_CACHED] = { .name = "recycle-cached", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_RECYCLE_CACHE_FULL] = { .name = "recycle-cache-full", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_RECYCLE_RING] = { .name = "recycle-ring", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_RECYCLE_RING_FULL] = { .name = "recycle-ring-full", .type = YNL_PT_UINT, }, + [NETDEV_A_PAGE_POOL_STATS_RECYCLE_RELEASED_REFCNT] = { .name = "recycle-released-refcnt", .type = YNL_PT_UINT, }, +}; + +struct ynl_policy_nest netdev_page_pool_stats_nest = { + .max_attr = NETDEV_A_PAGE_POOL_STATS_MAX, + .table = netdev_page_pool_stats_policy, +}; + +struct ynl_policy_attr netdev_queue_policy[NETDEV_A_QUEUE_MAX + 1] = { + [NETDEV_A_QUEUE_ID] = { .name = "id", .type = YNL_PT_U32, }, + [NETDEV_A_QUEUE_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, + [NETDEV_A_QUEUE_TYPE] = { .name = "type", .type = YNL_PT_U32, }, + [NETDEV_A_QUEUE_NAPI_ID] = { .name = "napi-id", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest netdev_queue_nest = { + .max_attr = NETDEV_A_QUEUE_MAX, + .table = netdev_queue_policy, +}; + +struct ynl_policy_attr netdev_napi_policy[NETDEV_A_NAPI_MAX + 1] = { + [NETDEV_A_NAPI_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, + [NETDEV_A_NAPI_ID] = { .name = "id", .type = YNL_PT_U32, }, + [NETDEV_A_NAPI_IRQ] = { .name = "irq", .type = YNL_PT_U32, }, + [NETDEV_A_NAPI_PID] = { .name = "pid", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest netdev_napi_nest = { + .max_attr = NETDEV_A_NAPI_MAX, + .table = netdev_napi_policy, +}; + +struct ynl_policy_attr netdev_qstats_policy[NETDEV_A_QSTATS_MAX + 1] = { + [NETDEV_A_QSTATS_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, + [NETDEV_A_QSTATS_QUEUE_TYPE] = { .name = "queue-type", .type = YNL_PT_U32, }, + [NETDEV_A_QSTATS_QUEUE_ID] = { .name = "queue-id", .type = YNL_PT_U32, }, + [NETDEV_A_QSTATS_SCOPE] = { .name = "scope", .type = YNL_PT_UINT, }, + [NETDEV_A_QSTATS_RX_PACKETS] = { .name = "rx-packets", .type = YNL_PT_UINT, }, + [NETDEV_A_QSTATS_RX_BYTES] = { .name = "rx-bytes", .type = YNL_PT_UINT, }, + [NETDEV_A_QSTATS_TX_PACKETS] = { .name = "tx-packets", .type = YNL_PT_UINT, }, + [NETDEV_A_QSTATS_TX_BYTES] = { .name = "tx-bytes", .type = YNL_PT_UINT, }, + [NETDEV_A_QSTATS_RX_ALLOC_FAIL] = { .name = "rx-alloc-fail", .type = YNL_PT_UINT, }, +}; + +struct ynl_policy_nest netdev_qstats_nest = { + .max_attr = NETDEV_A_QSTATS_MAX, + .table = netdev_qstats_policy, +}; + +/* Common nested types */ +void netdev_page_pool_info_free(struct netdev_page_pool_info *obj) +{ +} + +int netdev_page_pool_info_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct netdev_page_pool_info *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.id) + ynl_attr_put_uint(nlh, NETDEV_A_PAGE_POOL_ID, obj->id); + if (obj->_present.ifindex) + ynl_attr_put_u32(nlh, NETDEV_A_PAGE_POOL_IFINDEX, obj->ifindex); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int netdev_page_pool_info_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct netdev_page_pool_info *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == NETDEV_A_PAGE_POOL_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_IFINDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ifindex = 1; + dst->ifindex = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +/* ============== NETDEV_CMD_DEV_GET ============== */ +/* NETDEV_CMD_DEV_GET - do */ +void netdev_dev_get_req_free(struct netdev_dev_get_req *req) +{ + free(req); +} + +void netdev_dev_get_rsp_free(struct netdev_dev_get_rsp *rsp) +{ + free(rsp); +} + +int netdev_dev_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct netdev_dev_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == NETDEV_A_DEV_IFINDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ifindex = 1; + dst->ifindex = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_DEV_XDP_FEATURES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.xdp_features = 1; + dst->xdp_features = ynl_attr_get_u64(attr); + } else if (type == NETDEV_A_DEV_XDP_ZC_MAX_SEGS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.xdp_zc_max_segs = 1; + dst->xdp_zc_max_segs = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_DEV_XDP_RX_METADATA_FEATURES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.xdp_rx_metadata_features = 1; + dst->xdp_rx_metadata_features = ynl_attr_get_u64(attr); + } else if (type == NETDEV_A_DEV_XSK_FEATURES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.xsk_features = 1; + dst->xsk_features = ynl_attr_get_u64(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct netdev_dev_get_rsp * +netdev_dev_get(struct ynl_sock *ys, struct netdev_dev_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct netdev_dev_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_DEV_GET, 1); + ys->req_policy = &netdev_dev_nest; + yrs.yarg.rsp_policy = &netdev_dev_nest; + + if (req->_present.ifindex) + ynl_attr_put_u32(nlh, NETDEV_A_DEV_IFINDEX, req->ifindex); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = netdev_dev_get_rsp_parse; + yrs.rsp_cmd = NETDEV_CMD_DEV_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + netdev_dev_get_rsp_free(rsp); + return NULL; +} + +/* NETDEV_CMD_DEV_GET - dump */ +void netdev_dev_get_list_free(struct netdev_dev_get_list *rsp) +{ + struct netdev_dev_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp); + } +} + +struct netdev_dev_get_list *netdev_dev_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &netdev_dev_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct netdev_dev_get_list); + yds.cb = netdev_dev_get_rsp_parse; + yds.rsp_cmd = NETDEV_CMD_DEV_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_DEV_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + netdev_dev_get_list_free(yds.first); + return NULL; +} + +/* NETDEV_CMD_DEV_GET - notify */ +void netdev_dev_get_ntf_free(struct netdev_dev_get_ntf *rsp) +{ + free(rsp); +} + +/* ============== NETDEV_CMD_PAGE_POOL_GET ============== */ +/* NETDEV_CMD_PAGE_POOL_GET - do */ +void netdev_page_pool_get_req_free(struct netdev_page_pool_get_req *req) +{ + free(req); +} + +void netdev_page_pool_get_rsp_free(struct netdev_page_pool_get_rsp *rsp) +{ + free(rsp); +} + +int netdev_page_pool_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct netdev_page_pool_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == NETDEV_A_PAGE_POOL_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_IFINDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ifindex = 1; + dst->ifindex = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_PAGE_POOL_NAPI_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.napi_id = 1; + dst->napi_id = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_INFLIGHT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.inflight = 1; + dst->inflight = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_INFLIGHT_MEM) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.inflight_mem = 1; + dst->inflight_mem = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_DETACH_TIME) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.detach_time = 1; + dst->detach_time = ynl_attr_get_uint(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct netdev_page_pool_get_rsp * +netdev_page_pool_get(struct ynl_sock *ys, struct netdev_page_pool_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct netdev_page_pool_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_PAGE_POOL_GET, 1); + ys->req_policy = &netdev_page_pool_nest; + yrs.yarg.rsp_policy = &netdev_page_pool_nest; + + if (req->_present.id) + ynl_attr_put_uint(nlh, NETDEV_A_PAGE_POOL_ID, req->id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = netdev_page_pool_get_rsp_parse; + yrs.rsp_cmd = NETDEV_CMD_PAGE_POOL_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + netdev_page_pool_get_rsp_free(rsp); + return NULL; +} + +/* NETDEV_CMD_PAGE_POOL_GET - dump */ +void netdev_page_pool_get_list_free(struct netdev_page_pool_get_list *rsp) +{ + struct netdev_page_pool_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp); + } +} + +struct netdev_page_pool_get_list * +netdev_page_pool_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &netdev_page_pool_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct netdev_page_pool_get_list); + yds.cb = netdev_page_pool_get_rsp_parse; + yds.rsp_cmd = NETDEV_CMD_PAGE_POOL_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_PAGE_POOL_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + netdev_page_pool_get_list_free(yds.first); + return NULL; +} + +/* NETDEV_CMD_PAGE_POOL_GET - notify */ +void netdev_page_pool_get_ntf_free(struct netdev_page_pool_get_ntf *rsp) +{ + free(rsp); +} + +/* ============== NETDEV_CMD_PAGE_POOL_STATS_GET ============== */ +/* NETDEV_CMD_PAGE_POOL_STATS_GET - do */ +void +netdev_page_pool_stats_get_req_free(struct netdev_page_pool_stats_get_req *req) +{ + netdev_page_pool_info_free(&req->info); + free(req); +} + +void +netdev_page_pool_stats_get_rsp_free(struct netdev_page_pool_stats_get_rsp *rsp) +{ + netdev_page_pool_info_free(&rsp->info); + free(rsp); +} + +int netdev_page_pool_stats_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct netdev_page_pool_stats_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == NETDEV_A_PAGE_POOL_STATS_INFO) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.info = 1; + + parg.rsp_policy = &netdev_page_pool_info_nest; + parg.data = &dst->info; + if (netdev_page_pool_info_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == NETDEV_A_PAGE_POOL_STATS_ALLOC_FAST) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.alloc_fast = 1; + dst->alloc_fast = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_ALLOC_SLOW) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.alloc_slow = 1; + dst->alloc_slow = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_ALLOC_SLOW_HIGH_ORDER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.alloc_slow_high_order = 1; + dst->alloc_slow_high_order = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_ALLOC_EMPTY) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.alloc_empty = 1; + dst->alloc_empty = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_ALLOC_REFILL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.alloc_refill = 1; + dst->alloc_refill = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_ALLOC_WAIVE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.alloc_waive = 1; + dst->alloc_waive = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_RECYCLE_CACHED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.recycle_cached = 1; + dst->recycle_cached = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_RECYCLE_CACHE_FULL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.recycle_cache_full = 1; + dst->recycle_cache_full = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_RECYCLE_RING) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.recycle_ring = 1; + dst->recycle_ring = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_RECYCLE_RING_FULL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.recycle_ring_full = 1; + dst->recycle_ring_full = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_PAGE_POOL_STATS_RECYCLE_RELEASED_REFCNT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.recycle_released_refcnt = 1; + dst->recycle_released_refcnt = ynl_attr_get_uint(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct netdev_page_pool_stats_get_rsp * +netdev_page_pool_stats_get(struct ynl_sock *ys, + struct netdev_page_pool_stats_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct netdev_page_pool_stats_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_PAGE_POOL_STATS_GET, 1); + ys->req_policy = &netdev_page_pool_stats_nest; + yrs.yarg.rsp_policy = &netdev_page_pool_stats_nest; + + if (req->_present.info) + netdev_page_pool_info_put(nlh, NETDEV_A_PAGE_POOL_STATS_INFO, &req->info); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = netdev_page_pool_stats_get_rsp_parse; + yrs.rsp_cmd = NETDEV_CMD_PAGE_POOL_STATS_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + netdev_page_pool_stats_get_rsp_free(rsp); + return NULL; +} + +/* NETDEV_CMD_PAGE_POOL_STATS_GET - dump */ +void +netdev_page_pool_stats_get_list_free(struct netdev_page_pool_stats_get_list *rsp) +{ + struct netdev_page_pool_stats_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + netdev_page_pool_info_free(&rsp->obj.info); + free(rsp); + } +} + +struct netdev_page_pool_stats_get_list * +netdev_page_pool_stats_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &netdev_page_pool_stats_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct netdev_page_pool_stats_get_list); + yds.cb = netdev_page_pool_stats_get_rsp_parse; + yds.rsp_cmd = NETDEV_CMD_PAGE_POOL_STATS_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_PAGE_POOL_STATS_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + netdev_page_pool_stats_get_list_free(yds.first); + return NULL; +} + +/* ============== NETDEV_CMD_QUEUE_GET ============== */ +/* NETDEV_CMD_QUEUE_GET - do */ +void netdev_queue_get_req_free(struct netdev_queue_get_req *req) +{ + free(req); +} + +void netdev_queue_get_rsp_free(struct netdev_queue_get_rsp *rsp) +{ + free(rsp); +} + +int netdev_queue_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct netdev_queue_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == NETDEV_A_QUEUE_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_QUEUE_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.type = 1; + dst->type = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_QUEUE_NAPI_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.napi_id = 1; + dst->napi_id = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_QUEUE_IFINDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ifindex = 1; + dst->ifindex = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct netdev_queue_get_rsp * +netdev_queue_get(struct ynl_sock *ys, struct netdev_queue_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct netdev_queue_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_QUEUE_GET, 1); + ys->req_policy = &netdev_queue_nest; + yrs.yarg.rsp_policy = &netdev_queue_nest; + + if (req->_present.ifindex) + ynl_attr_put_u32(nlh, NETDEV_A_QUEUE_IFINDEX, req->ifindex); + if (req->_present.type) + ynl_attr_put_u32(nlh, NETDEV_A_QUEUE_TYPE, req->type); + if (req->_present.id) + ynl_attr_put_u32(nlh, NETDEV_A_QUEUE_ID, req->id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = netdev_queue_get_rsp_parse; + yrs.rsp_cmd = NETDEV_CMD_QUEUE_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + netdev_queue_get_rsp_free(rsp); + return NULL; +} + +/* NETDEV_CMD_QUEUE_GET - dump */ +void netdev_queue_get_req_dump_free(struct netdev_queue_get_req_dump *req) +{ + free(req); +} + +void netdev_queue_get_list_free(struct netdev_queue_get_list *rsp) +{ + struct netdev_queue_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp); + } +} + +struct netdev_queue_get_list * +netdev_queue_get_dump(struct ynl_sock *ys, + struct netdev_queue_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &netdev_queue_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct netdev_queue_get_list); + yds.cb = netdev_queue_get_rsp_parse; + yds.rsp_cmd = NETDEV_CMD_QUEUE_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_QUEUE_GET, 1); + ys->req_policy = &netdev_queue_nest; + + if (req->_present.ifindex) + ynl_attr_put_u32(nlh, NETDEV_A_QUEUE_IFINDEX, req->ifindex); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + netdev_queue_get_list_free(yds.first); + return NULL; +} + +/* ============== NETDEV_CMD_NAPI_GET ============== */ +/* NETDEV_CMD_NAPI_GET - do */ +void netdev_napi_get_req_free(struct netdev_napi_get_req *req) +{ + free(req); +} + +void netdev_napi_get_rsp_free(struct netdev_napi_get_rsp *rsp) +{ + free(rsp); +} + +int netdev_napi_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct netdev_napi_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == NETDEV_A_NAPI_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_NAPI_IFINDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ifindex = 1; + dst->ifindex = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_NAPI_IRQ) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.irq = 1; + dst->irq = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_NAPI_PID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pid = 1; + dst->pid = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct netdev_napi_get_rsp * +netdev_napi_get(struct ynl_sock *ys, struct netdev_napi_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct netdev_napi_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_NAPI_GET, 1); + ys->req_policy = &netdev_napi_nest; + yrs.yarg.rsp_policy = &netdev_napi_nest; + + if (req->_present.id) + ynl_attr_put_u32(nlh, NETDEV_A_NAPI_ID, req->id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = netdev_napi_get_rsp_parse; + yrs.rsp_cmd = NETDEV_CMD_NAPI_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + netdev_napi_get_rsp_free(rsp); + return NULL; +} + +/* NETDEV_CMD_NAPI_GET - dump */ +void netdev_napi_get_req_dump_free(struct netdev_napi_get_req_dump *req) +{ + free(req); +} + +void netdev_napi_get_list_free(struct netdev_napi_get_list *rsp) +{ + struct netdev_napi_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp); + } +} + +struct netdev_napi_get_list * +netdev_napi_get_dump(struct ynl_sock *ys, struct netdev_napi_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &netdev_napi_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct netdev_napi_get_list); + yds.cb = netdev_napi_get_rsp_parse; + yds.rsp_cmd = NETDEV_CMD_NAPI_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_NAPI_GET, 1); + ys->req_policy = &netdev_napi_nest; + + if (req->_present.ifindex) + ynl_attr_put_u32(nlh, NETDEV_A_NAPI_IFINDEX, req->ifindex); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + netdev_napi_get_list_free(yds.first); + return NULL; +} + +/* ============== NETDEV_CMD_QSTATS_GET ============== */ +/* NETDEV_CMD_QSTATS_GET - dump */ +int netdev_qstats_get_rsp_dump_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct netdev_qstats_get_rsp_dump *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == NETDEV_A_QSTATS_IFINDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ifindex = 1; + dst->ifindex = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_QSTATS_QUEUE_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.queue_type = 1; + dst->queue_type = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_QSTATS_QUEUE_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.queue_id = 1; + dst->queue_id = ynl_attr_get_u32(attr); + } else if (type == NETDEV_A_QSTATS_RX_PACKETS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_packets = 1; + dst->rx_packets = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_QSTATS_RX_BYTES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_bytes = 1; + dst->rx_bytes = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_QSTATS_TX_PACKETS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_packets = 1; + dst->tx_packets = ynl_attr_get_uint(attr); + } else if (type == NETDEV_A_QSTATS_TX_BYTES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tx_bytes = 1; + dst->tx_bytes = ynl_attr_get_uint(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +void netdev_qstats_get_req_dump_free(struct netdev_qstats_get_req_dump *req) +{ + free(req); +} + +void netdev_qstats_get_rsp_list_free(struct netdev_qstats_get_rsp_list *rsp) +{ + struct netdev_qstats_get_rsp_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp); + } +} + +struct netdev_qstats_get_rsp_list * +netdev_qstats_get_dump(struct ynl_sock *ys, + struct netdev_qstats_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &netdev_qstats_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct netdev_qstats_get_rsp_list); + yds.cb = netdev_qstats_get_rsp_dump_parse; + yds.rsp_cmd = NETDEV_CMD_QSTATS_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_QSTATS_GET, 1); + ys->req_policy = &netdev_qstats_nest; + + if (req->_present.scope) + ynl_attr_put_uint(nlh, NETDEV_A_QSTATS_SCOPE, req->scope); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + netdev_qstats_get_rsp_list_free(yds.first); + return NULL; +} + +static const struct ynl_ntf_info netdev_ntf_info[] = { + [NETDEV_CMD_DEV_ADD_NTF] = { + .alloc_sz = sizeof(struct netdev_dev_get_ntf), + .cb = netdev_dev_get_rsp_parse, + .policy = &netdev_dev_nest, + .free = (void *)netdev_dev_get_ntf_free, + }, + [NETDEV_CMD_DEV_DEL_NTF] = { + .alloc_sz = sizeof(struct netdev_dev_get_ntf), + .cb = netdev_dev_get_rsp_parse, + .policy = &netdev_dev_nest, + .free = (void *)netdev_dev_get_ntf_free, + }, + [NETDEV_CMD_DEV_CHANGE_NTF] = { + .alloc_sz = sizeof(struct netdev_dev_get_ntf), + .cb = netdev_dev_get_rsp_parse, + .policy = &netdev_dev_nest, + .free = (void *)netdev_dev_get_ntf_free, + }, + [NETDEV_CMD_PAGE_POOL_ADD_NTF] = { + .alloc_sz = sizeof(struct netdev_page_pool_get_ntf), + .cb = netdev_page_pool_get_rsp_parse, + .policy = &netdev_page_pool_nest, + .free = (void *)netdev_page_pool_get_ntf_free, + }, + [NETDEV_CMD_PAGE_POOL_DEL_NTF] = { + .alloc_sz = sizeof(struct netdev_page_pool_get_ntf), + .cb = netdev_page_pool_get_rsp_parse, + .policy = &netdev_page_pool_nest, + .free = (void *)netdev_page_pool_get_ntf_free, + }, + [NETDEV_CMD_PAGE_POOL_CHANGE_NTF] = { + .alloc_sz = sizeof(struct netdev_page_pool_get_ntf), + .cb = netdev_page_pool_get_rsp_parse, + .policy = &netdev_page_pool_nest, + .free = (void *)netdev_page_pool_get_ntf_free, + }, +}; + +const struct ynl_family ynl_netdev_family = { + .name = "netdev", + .hdr_len = sizeof(struct genlmsghdr), + .ntf_info = netdev_ntf_info, + .ntf_info_size = YNL_ARRAY_SIZE(netdev_ntf_info), +}; diff --git a/generated/netdev-user.h b/generated/netdev-user.h new file mode 100644 index 0000000..7b0fdd7 --- /dev/null +++ b/generated/netdev-user.h @@ -0,0 +1,499 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/netdev.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_NETDEV_GEN_H +#define _LINUX_NETDEV_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_netdev_family; + +/* Enums */ +const char *netdev_op_str(int op); +const char *netdev_xdp_act_str(enum netdev_xdp_act value); +const char *netdev_xdp_rx_metadata_str(enum netdev_xdp_rx_metadata value); +const char *netdev_xsk_flags_str(enum netdev_xsk_flags value); +const char *netdev_queue_type_str(enum netdev_queue_type value); +const char *netdev_qstats_scope_str(enum netdev_qstats_scope value); + +/* Common nested types */ +struct netdev_page_pool_info { + struct { + __u32 id:1; + __u32 ifindex:1; + } _present; + + __u64 id; + __u32 ifindex; +}; + +/* ============== NETDEV_CMD_DEV_GET ============== */ +/* NETDEV_CMD_DEV_GET - do */ +struct netdev_dev_get_req { + struct { + __u32 ifindex:1; + } _present; + + __u32 ifindex; +}; + +static inline struct netdev_dev_get_req *netdev_dev_get_req_alloc(void) +{ + return calloc(1, sizeof(struct netdev_dev_get_req)); +} +void netdev_dev_get_req_free(struct netdev_dev_get_req *req); + +static inline void +netdev_dev_get_req_set_ifindex(struct netdev_dev_get_req *req, __u32 ifindex) +{ + req->_present.ifindex = 1; + req->ifindex = ifindex; +} + +struct netdev_dev_get_rsp { + struct { + __u32 ifindex:1; + __u32 xdp_features:1; + __u32 xdp_zc_max_segs:1; + __u32 xdp_rx_metadata_features:1; + __u32 xsk_features:1; + } _present; + + __u32 ifindex; + __u64 xdp_features; + __u32 xdp_zc_max_segs; + __u64 xdp_rx_metadata_features; + __u64 xsk_features; +}; + +void netdev_dev_get_rsp_free(struct netdev_dev_get_rsp *rsp); + +/* + * Get / dump information about a netdev. + */ +struct netdev_dev_get_rsp * +netdev_dev_get(struct ynl_sock *ys, struct netdev_dev_get_req *req); + +/* NETDEV_CMD_DEV_GET - dump */ +struct netdev_dev_get_list { + struct netdev_dev_get_list *next; + struct netdev_dev_get_rsp obj __attribute__((aligned(8))); +}; + +void netdev_dev_get_list_free(struct netdev_dev_get_list *rsp); + +struct netdev_dev_get_list *netdev_dev_get_dump(struct ynl_sock *ys); + +/* NETDEV_CMD_DEV_GET - notify */ +struct netdev_dev_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct netdev_dev_get_ntf *ntf); + struct netdev_dev_get_rsp obj __attribute__((aligned(8))); +}; + +void netdev_dev_get_ntf_free(struct netdev_dev_get_ntf *rsp); + +/* ============== NETDEV_CMD_PAGE_POOL_GET ============== */ +/* NETDEV_CMD_PAGE_POOL_GET - do */ +struct netdev_page_pool_get_req { + struct { + __u32 id:1; + } _present; + + __u64 id; +}; + +static inline struct netdev_page_pool_get_req * +netdev_page_pool_get_req_alloc(void) +{ + return calloc(1, sizeof(struct netdev_page_pool_get_req)); +} +void netdev_page_pool_get_req_free(struct netdev_page_pool_get_req *req); + +static inline void +netdev_page_pool_get_req_set_id(struct netdev_page_pool_get_req *req, __u64 id) +{ + req->_present.id = 1; + req->id = id; +} + +struct netdev_page_pool_get_rsp { + struct { + __u32 id:1; + __u32 ifindex:1; + __u32 napi_id:1; + __u32 inflight:1; + __u32 inflight_mem:1; + __u32 detach_time:1; + } _present; + + __u64 id; + __u32 ifindex; + __u64 napi_id; + __u64 inflight; + __u64 inflight_mem; + __u64 detach_time; +}; + +void netdev_page_pool_get_rsp_free(struct netdev_page_pool_get_rsp *rsp); + +/* + * Get / dump information about Page Pools. +(Only Page Pools associated with a net_device can be listed.) + + */ +struct netdev_page_pool_get_rsp * +netdev_page_pool_get(struct ynl_sock *ys, struct netdev_page_pool_get_req *req); + +/* NETDEV_CMD_PAGE_POOL_GET - dump */ +struct netdev_page_pool_get_list { + struct netdev_page_pool_get_list *next; + struct netdev_page_pool_get_rsp obj __attribute__((aligned(8))); +}; + +void netdev_page_pool_get_list_free(struct netdev_page_pool_get_list *rsp); + +struct netdev_page_pool_get_list * +netdev_page_pool_get_dump(struct ynl_sock *ys); + +/* NETDEV_CMD_PAGE_POOL_GET - notify */ +struct netdev_page_pool_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct netdev_page_pool_get_ntf *ntf); + struct netdev_page_pool_get_rsp obj __attribute__((aligned(8))); +}; + +void netdev_page_pool_get_ntf_free(struct netdev_page_pool_get_ntf *rsp); + +/* ============== NETDEV_CMD_PAGE_POOL_STATS_GET ============== */ +/* NETDEV_CMD_PAGE_POOL_STATS_GET - do */ +struct netdev_page_pool_stats_get_req { + struct { + __u32 info:1; + } _present; + + struct netdev_page_pool_info info; +}; + +static inline struct netdev_page_pool_stats_get_req * +netdev_page_pool_stats_get_req_alloc(void) +{ + return calloc(1, sizeof(struct netdev_page_pool_stats_get_req)); +} +void +netdev_page_pool_stats_get_req_free(struct netdev_page_pool_stats_get_req *req); + +static inline void +netdev_page_pool_stats_get_req_set_info_id(struct netdev_page_pool_stats_get_req *req, + __u64 id) +{ + req->_present.info = 1; + req->info._present.id = 1; + req->info.id = id; +} +static inline void +netdev_page_pool_stats_get_req_set_info_ifindex(struct netdev_page_pool_stats_get_req *req, + __u32 ifindex) +{ + req->_present.info = 1; + req->info._present.ifindex = 1; + req->info.ifindex = ifindex; +} + +struct netdev_page_pool_stats_get_rsp { + struct { + __u32 info:1; + __u32 alloc_fast:1; + __u32 alloc_slow:1; + __u32 alloc_slow_high_order:1; + __u32 alloc_empty:1; + __u32 alloc_refill:1; + __u32 alloc_waive:1; + __u32 recycle_cached:1; + __u32 recycle_cache_full:1; + __u32 recycle_ring:1; + __u32 recycle_ring_full:1; + __u32 recycle_released_refcnt:1; + } _present; + + struct netdev_page_pool_info info; + __u64 alloc_fast; + __u64 alloc_slow; + __u64 alloc_slow_high_order; + __u64 alloc_empty; + __u64 alloc_refill; + __u64 alloc_waive; + __u64 recycle_cached; + __u64 recycle_cache_full; + __u64 recycle_ring; + __u64 recycle_ring_full; + __u64 recycle_released_refcnt; +}; + +void +netdev_page_pool_stats_get_rsp_free(struct netdev_page_pool_stats_get_rsp *rsp); + +/* + * Get page pool statistics. + */ +struct netdev_page_pool_stats_get_rsp * +netdev_page_pool_stats_get(struct ynl_sock *ys, + struct netdev_page_pool_stats_get_req *req); + +/* NETDEV_CMD_PAGE_POOL_STATS_GET - dump */ +struct netdev_page_pool_stats_get_list { + struct netdev_page_pool_stats_get_list *next; + struct netdev_page_pool_stats_get_rsp obj __attribute__((aligned(8))); +}; + +void +netdev_page_pool_stats_get_list_free(struct netdev_page_pool_stats_get_list *rsp); + +struct netdev_page_pool_stats_get_list * +netdev_page_pool_stats_get_dump(struct ynl_sock *ys); + +/* ============== NETDEV_CMD_QUEUE_GET ============== */ +/* NETDEV_CMD_QUEUE_GET - do */ +struct netdev_queue_get_req { + struct { + __u32 ifindex:1; + __u32 type:1; + __u32 id:1; + } _present; + + __u32 ifindex; + enum netdev_queue_type type; + __u32 id; +}; + +static inline struct netdev_queue_get_req *netdev_queue_get_req_alloc(void) +{ + return calloc(1, sizeof(struct netdev_queue_get_req)); +} +void netdev_queue_get_req_free(struct netdev_queue_get_req *req); + +static inline void +netdev_queue_get_req_set_ifindex(struct netdev_queue_get_req *req, + __u32 ifindex) +{ + req->_present.ifindex = 1; + req->ifindex = ifindex; +} +static inline void +netdev_queue_get_req_set_type(struct netdev_queue_get_req *req, + enum netdev_queue_type type) +{ + req->_present.type = 1; + req->type = type; +} +static inline void +netdev_queue_get_req_set_id(struct netdev_queue_get_req *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} + +struct netdev_queue_get_rsp { + struct { + __u32 id:1; + __u32 type:1; + __u32 napi_id:1; + __u32 ifindex:1; + } _present; + + __u32 id; + enum netdev_queue_type type; + __u32 napi_id; + __u32 ifindex; +}; + +void netdev_queue_get_rsp_free(struct netdev_queue_get_rsp *rsp); + +/* + * Get queue information from the kernel. Only configured queues will be reported (as opposed to all available hardware queues). + */ +struct netdev_queue_get_rsp * +netdev_queue_get(struct ynl_sock *ys, struct netdev_queue_get_req *req); + +/* NETDEV_CMD_QUEUE_GET - dump */ +struct netdev_queue_get_req_dump { + struct { + __u32 ifindex:1; + } _present; + + __u32 ifindex; +}; + +static inline struct netdev_queue_get_req_dump * +netdev_queue_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct netdev_queue_get_req_dump)); +} +void netdev_queue_get_req_dump_free(struct netdev_queue_get_req_dump *req); + +static inline void +netdev_queue_get_req_dump_set_ifindex(struct netdev_queue_get_req_dump *req, + __u32 ifindex) +{ + req->_present.ifindex = 1; + req->ifindex = ifindex; +} + +struct netdev_queue_get_list { + struct netdev_queue_get_list *next; + struct netdev_queue_get_rsp obj __attribute__((aligned(8))); +}; + +void netdev_queue_get_list_free(struct netdev_queue_get_list *rsp); + +struct netdev_queue_get_list * +netdev_queue_get_dump(struct ynl_sock *ys, + struct netdev_queue_get_req_dump *req); + +/* ============== NETDEV_CMD_NAPI_GET ============== */ +/* NETDEV_CMD_NAPI_GET - do */ +struct netdev_napi_get_req { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +static inline struct netdev_napi_get_req *netdev_napi_get_req_alloc(void) +{ + return calloc(1, sizeof(struct netdev_napi_get_req)); +} +void netdev_napi_get_req_free(struct netdev_napi_get_req *req); + +static inline void +netdev_napi_get_req_set_id(struct netdev_napi_get_req *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} + +struct netdev_napi_get_rsp { + struct { + __u32 id:1; + __u32 ifindex:1; + __u32 irq:1; + __u32 pid:1; + } _present; + + __u32 id; + __u32 ifindex; + __u32 irq; + __u32 pid; +}; + +void netdev_napi_get_rsp_free(struct netdev_napi_get_rsp *rsp); + +/* + * Get information about NAPI instances configured on the system. + */ +struct netdev_napi_get_rsp * +netdev_napi_get(struct ynl_sock *ys, struct netdev_napi_get_req *req); + +/* NETDEV_CMD_NAPI_GET - dump */ +struct netdev_napi_get_req_dump { + struct { + __u32 ifindex:1; + } _present; + + __u32 ifindex; +}; + +static inline struct netdev_napi_get_req_dump * +netdev_napi_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct netdev_napi_get_req_dump)); +} +void netdev_napi_get_req_dump_free(struct netdev_napi_get_req_dump *req); + +static inline void +netdev_napi_get_req_dump_set_ifindex(struct netdev_napi_get_req_dump *req, + __u32 ifindex) +{ + req->_present.ifindex = 1; + req->ifindex = ifindex; +} + +struct netdev_napi_get_list { + struct netdev_napi_get_list *next; + struct netdev_napi_get_rsp obj __attribute__((aligned(8))); +}; + +void netdev_napi_get_list_free(struct netdev_napi_get_list *rsp); + +struct netdev_napi_get_list * +netdev_napi_get_dump(struct ynl_sock *ys, struct netdev_napi_get_req_dump *req); + +/* ============== NETDEV_CMD_QSTATS_GET ============== */ +/* NETDEV_CMD_QSTATS_GET - dump */ +struct netdev_qstats_get_req_dump { + struct { + __u32 scope:1; + } _present; + + __u64 scope; +}; + +static inline struct netdev_qstats_get_req_dump * +netdev_qstats_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct netdev_qstats_get_req_dump)); +} +void netdev_qstats_get_req_dump_free(struct netdev_qstats_get_req_dump *req); + +static inline void +netdev_qstats_get_req_dump_set_scope(struct netdev_qstats_get_req_dump *req, + __u64 scope) +{ + req->_present.scope = 1; + req->scope = scope; +} + +struct netdev_qstats_get_rsp_dump { + struct { + __u32 ifindex:1; + __u32 queue_type:1; + __u32 queue_id:1; + __u32 rx_packets:1; + __u32 rx_bytes:1; + __u32 tx_packets:1; + __u32 tx_bytes:1; + } _present; + + __u32 ifindex; + enum netdev_queue_type queue_type; + __u32 queue_id; + __u64 rx_packets; + __u64 rx_bytes; + __u64 tx_packets; + __u64 tx_bytes; +}; + +struct netdev_qstats_get_rsp_list { + struct netdev_qstats_get_rsp_list *next; + struct netdev_qstats_get_rsp_dump obj __attribute__((aligned(8))); +}; + +void netdev_qstats_get_rsp_list_free(struct netdev_qstats_get_rsp_list *rsp); + +struct netdev_qstats_get_rsp_list * +netdev_qstats_get_dump(struct ynl_sock *ys, + struct netdev_qstats_get_req_dump *req); + +#endif /* _LINUX_NETDEV_GEN_H */ diff --git a/generated/nfsd-user.c b/generated/nfsd-user.c new file mode 100644 index 0000000..9d05eb1 --- /dev/null +++ b/generated/nfsd-user.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/nfsd.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "nfsd-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const nfsd_op_strmap[] = { + [NFSD_CMD_RPC_STATUS_GET] = "rpc-status-get", +}; + +const char *nfsd_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(nfsd_op_strmap)) + return NULL; + return nfsd_op_strmap[op]; +} + +/* Policies */ +struct ynl_policy_attr nfsd_rpc_status_policy[NFSD_A_RPC_STATUS_MAX + 1] = { + [NFSD_A_RPC_STATUS_XID] = { .name = "xid", .type = YNL_PT_U32, }, + [NFSD_A_RPC_STATUS_FLAGS] = { .name = "flags", .type = YNL_PT_U32, }, + [NFSD_A_RPC_STATUS_PROG] = { .name = "prog", .type = YNL_PT_U32, }, + [NFSD_A_RPC_STATUS_VERSION] = { .name = "version", .type = YNL_PT_U8, }, + [NFSD_A_RPC_STATUS_PROC] = { .name = "proc", .type = YNL_PT_U32, }, + [NFSD_A_RPC_STATUS_SERVICE_TIME] = { .name = "service_time", .type = YNL_PT_U64, }, + [NFSD_A_RPC_STATUS_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [NFSD_A_RPC_STATUS_SADDR4] = { .name = "saddr4", .type = YNL_PT_U32, }, + [NFSD_A_RPC_STATUS_DADDR4] = { .name = "daddr4", .type = YNL_PT_U32, }, + [NFSD_A_RPC_STATUS_SADDR6] = { .name = "saddr6", .type = YNL_PT_BINARY,}, + [NFSD_A_RPC_STATUS_DADDR6] = { .name = "daddr6", .type = YNL_PT_BINARY,}, + [NFSD_A_RPC_STATUS_SPORT] = { .name = "sport", .type = YNL_PT_U16, }, + [NFSD_A_RPC_STATUS_DPORT] = { .name = "dport", .type = YNL_PT_U16, }, + [NFSD_A_RPC_STATUS_COMPOUND_OPS] = { .name = "compound-ops", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest nfsd_rpc_status_nest = { + .max_attr = NFSD_A_RPC_STATUS_MAX, + .table = nfsd_rpc_status_policy, +}; + +/* Common nested types */ +/* ============== NFSD_CMD_RPC_STATUS_GET ============== */ +/* NFSD_CMD_RPC_STATUS_GET - dump */ +int nfsd_rpc_status_get_rsp_dump_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct nfsd_rpc_status_get_rsp_dump *dst; + unsigned int n_compound_ops = 0; + const struct nlattr *attr; + int i; + + dst = yarg->data; + + if (dst->compound_ops) + return ynl_error_parse(yarg, "attribute already present (rpc-status.compound-ops)"); + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == NFSD_A_RPC_STATUS_XID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.xid = 1; + dst->xid = ynl_attr_get_u32(attr); + } else if (type == NFSD_A_RPC_STATUS_FLAGS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.flags = 1; + dst->flags = ynl_attr_get_u32(attr); + } else if (type == NFSD_A_RPC_STATUS_PROG) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.prog = 1; + dst->prog = ynl_attr_get_u32(attr); + } else if (type == NFSD_A_RPC_STATUS_VERSION) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.version = 1; + dst->version = ynl_attr_get_u8(attr); + } else if (type == NFSD_A_RPC_STATUS_PROC) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.proc = 1; + dst->proc = ynl_attr_get_u32(attr); + } else if (type == NFSD_A_RPC_STATUS_SERVICE_TIME) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.service_time = 1; + dst->service_time = ynl_attr_get_s64(attr); + } else if (type == NFSD_A_RPC_STATUS_SADDR4) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.saddr4 = 1; + dst->saddr4 = ynl_attr_get_u32(attr); + } else if (type == NFSD_A_RPC_STATUS_DADDR4) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.daddr4 = 1; + dst->daddr4 = ynl_attr_get_u32(attr); + } else if (type == NFSD_A_RPC_STATUS_SADDR6) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.saddr6_len = len; + dst->saddr6 = malloc(len); + memcpy(dst->saddr6, ynl_attr_data(attr), len); + } else if (type == NFSD_A_RPC_STATUS_DADDR6) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.daddr6_len = len; + dst->daddr6 = malloc(len); + memcpy(dst->daddr6, ynl_attr_data(attr), len); + } else if (type == NFSD_A_RPC_STATUS_SPORT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sport = 1; + dst->sport = ynl_attr_get_u16(attr); + } else if (type == NFSD_A_RPC_STATUS_DPORT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dport = 1; + dst->dport = ynl_attr_get_u16(attr); + } else if (type == NFSD_A_RPC_STATUS_COMPOUND_OPS) { + n_compound_ops++; + } + } + + if (n_compound_ops) { + dst->compound_ops = calloc(n_compound_ops, sizeof(*dst->compound_ops)); + dst->n_compound_ops = n_compound_ops; + i = 0; + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + if (ynl_attr_type(attr) == NFSD_A_RPC_STATUS_COMPOUND_OPS) { + dst->compound_ops[i] = ynl_attr_get_u32(attr); + i++; + } + } + } + + return YNL_PARSE_CB_OK; +} + +void +nfsd_rpc_status_get_rsp_list_free(struct nfsd_rpc_status_get_rsp_list *rsp) +{ + struct nfsd_rpc_status_get_rsp_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.saddr6); + free(rsp->obj.daddr6); + free(rsp->obj.compound_ops); + free(rsp); + } +} + +struct nfsd_rpc_status_get_rsp_list * +nfsd_rpc_status_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &nfsd_rpc_status_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct nfsd_rpc_status_get_rsp_list); + yds.cb = nfsd_rpc_status_get_rsp_dump_parse; + yds.rsp_cmd = NFSD_CMD_RPC_STATUS_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, NFSD_CMD_RPC_STATUS_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + nfsd_rpc_status_get_rsp_list_free(yds.first); + return NULL; +} + +const struct ynl_family ynl_nfsd_family = { + .name = "nfsd", + .hdr_len = sizeof(struct genlmsghdr), +}; diff --git a/generated/nfsd-user.h b/generated/nfsd-user.h new file mode 100644 index 0000000..989c6e2 --- /dev/null +++ b/generated/nfsd-user.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/nfsd.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_NFSD_GEN_H +#define _LINUX_NFSD_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_nfsd_family; + +/* Enums */ +const char *nfsd_op_str(int op); + +/* Common nested types */ +/* ============== NFSD_CMD_RPC_STATUS_GET ============== */ +/* NFSD_CMD_RPC_STATUS_GET - dump */ +struct nfsd_rpc_status_get_rsp_dump { + struct { + __u32 xid:1; + __u32 flags:1; + __u32 prog:1; + __u32 version:1; + __u32 proc:1; + __u32 service_time:1; + __u32 saddr4:1; + __u32 daddr4:1; + __u32 saddr6_len; + __u32 daddr6_len; + __u32 sport:1; + __u32 dport:1; + } _present; + + __u32 xid /* big-endian */; + __u32 flags; + __u32 prog; + __u8 version; + __u32 proc; + __s64 service_time; + __u32 saddr4 /* big-endian */; + __u32 daddr4 /* big-endian */; + void *saddr6; + void *daddr6; + __u16 sport /* big-endian */; + __u16 dport /* big-endian */; + unsigned int n_compound_ops; + __u32 *compound_ops; +}; + +struct nfsd_rpc_status_get_rsp_list { + struct nfsd_rpc_status_get_rsp_list *next; + struct nfsd_rpc_status_get_rsp_dump obj __attribute__((aligned(8))); +}; + +void +nfsd_rpc_status_get_rsp_list_free(struct nfsd_rpc_status_get_rsp_list *rsp); + +struct nfsd_rpc_status_get_rsp_list * +nfsd_rpc_status_get_dump(struct ynl_sock *ys); + +#endif /* _LINUX_NFSD_GEN_H */ diff --git a/generated/nlctrl-user.c b/generated/nlctrl-user.c new file mode 100644 index 0000000..c847873 --- /dev/null +++ b/generated/nlctrl-user.c @@ -0,0 +1,616 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/nlctrl.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "nlctrl-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const nlctrl_op_strmap[] = { + [1] = "getfamily", + [CTRL_CMD_GETPOLICY] = "getpolicy", +}; + +const char *nlctrl_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(nlctrl_op_strmap)) + return NULL; + return nlctrl_op_strmap[op]; +} + +static const char * const nlctrl_op_flags_strmap[] = { + [0] = "admin-perm", + [1] = "cmd-cap-do", + [2] = "cmd-cap-dump", + [3] = "cmd-cap-haspol", + [4] = "uns-admin-perm", +}; + +const char *nlctrl_op_flags_str(int value) +{ + value = ffs(value) - 1; + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(nlctrl_op_flags_strmap)) + return NULL; + return nlctrl_op_flags_strmap[value]; +} + +static const char * const nlctrl_attr_type_strmap[] = { + [0] = "invalid", + [1] = "flag", + [2] = "u8", + [3] = "u16", + [4] = "u32", + [5] = "u64", + [6] = "s8", + [7] = "s16", + [8] = "s32", + [9] = "s64", + [10] = "binary", + [11] = "string", + [12] = "nul-string", + [13] = "nested", + [14] = "nested-array", + [15] = "bitfield32", + [16] = "sint", + [17] = "uint", +}; + +const char *nlctrl_attr_type_str(enum netlink_attribute_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(nlctrl_attr_type_strmap)) + return NULL; + return nlctrl_attr_type_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr nlctrl_op_attrs_policy[CTRL_ATTR_OP_MAX + 1] = { + [CTRL_ATTR_OP_ID] = { .name = "id", .type = YNL_PT_U32, }, + [CTRL_ATTR_OP_FLAGS] = { .name = "flags", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest nlctrl_op_attrs_nest = { + .max_attr = CTRL_ATTR_OP_MAX, + .table = nlctrl_op_attrs_policy, +}; + +struct ynl_policy_attr nlctrl_mcast_group_attrs_policy[CTRL_ATTR_MCAST_GRP_MAX + 1] = { + [CTRL_ATTR_MCAST_GRP_NAME] = { .name = "name", .type = YNL_PT_NUL_STR, }, + [CTRL_ATTR_MCAST_GRP_ID] = { .name = "id", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest nlctrl_mcast_group_attrs_nest = { + .max_attr = CTRL_ATTR_MCAST_GRP_MAX, + .table = nlctrl_mcast_group_attrs_policy, +}; + +struct ynl_policy_attr nlctrl_policy_attrs_policy[NL_POLICY_TYPE_ATTR_MAX + 1] = { + [NL_POLICY_TYPE_ATTR_TYPE] = { .name = "type", .type = YNL_PT_U32, }, + [NL_POLICY_TYPE_ATTR_MIN_VALUE_S] = { .name = "min-value-s", .type = YNL_PT_U64, }, + [NL_POLICY_TYPE_ATTR_MAX_VALUE_S] = { .name = "max-value-s", .type = YNL_PT_U64, }, + [NL_POLICY_TYPE_ATTR_MIN_VALUE_U] = { .name = "min-value-u", .type = YNL_PT_U64, }, + [NL_POLICY_TYPE_ATTR_MAX_VALUE_U] = { .name = "max-value-u", .type = YNL_PT_U64, }, + [NL_POLICY_TYPE_ATTR_MIN_LENGTH] = { .name = "min-length", .type = YNL_PT_U32, }, + [NL_POLICY_TYPE_ATTR_MAX_LENGTH] = { .name = "max-length", .type = YNL_PT_U32, }, + [NL_POLICY_TYPE_ATTR_POLICY_IDX] = { .name = "policy-idx", .type = YNL_PT_U32, }, + [NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE] = { .name = "policy-maxtype", .type = YNL_PT_U32, }, + [NL_POLICY_TYPE_ATTR_BITFIELD32_MASK] = { .name = "bitfield32-mask", .type = YNL_PT_U32, }, + [NL_POLICY_TYPE_ATTR_MASK] = { .name = "mask", .type = YNL_PT_U64, }, + [NL_POLICY_TYPE_ATTR_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, +}; + +struct ynl_policy_nest nlctrl_policy_attrs_nest = { + .max_attr = NL_POLICY_TYPE_ATTR_MAX, + .table = nlctrl_policy_attrs_policy, +}; + +struct ynl_policy_attr nlctrl_op_policy_attrs_policy[CTRL_ATTR_POLICY_MAX + 1] = { + [CTRL_ATTR_POLICY_DO] = { .name = "do", .type = YNL_PT_U32, }, + [CTRL_ATTR_POLICY_DUMP] = { .name = "dump", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest nlctrl_op_policy_attrs_nest = { + .max_attr = CTRL_ATTR_POLICY_MAX, + .table = nlctrl_op_policy_attrs_policy, +}; + +struct ynl_policy_attr nlctrl_ctrl_attrs_policy[CTRL_ATTR_MAX + 1] = { + [CTRL_ATTR_FAMILY_ID] = { .name = "family-id", .type = YNL_PT_U16, }, + [CTRL_ATTR_FAMILY_NAME] = { .name = "family-name", .type = YNL_PT_NUL_STR, }, + [CTRL_ATTR_VERSION] = { .name = "version", .type = YNL_PT_U32, }, + [CTRL_ATTR_HDRSIZE] = { .name = "hdrsize", .type = YNL_PT_U32, }, + [CTRL_ATTR_MAXATTR] = { .name = "maxattr", .type = YNL_PT_U32, }, + [CTRL_ATTR_OPS] = { .name = "ops", .type = YNL_PT_NEST, .nest = &nlctrl_op_attrs_nest, }, + [CTRL_ATTR_MCAST_GROUPS] = { .name = "mcast-groups", .type = YNL_PT_NEST, .nest = &nlctrl_mcast_group_attrs_nest, }, + [CTRL_ATTR_POLICY] = { .name = "policy", .type = YNL_PT_NEST, .nest = &nlctrl_policy_attrs_nest, }, + [CTRL_ATTR_OP_POLICY] = { .name = "op-policy", .type = YNL_PT_NEST, .nest = &nlctrl_op_policy_attrs_nest, }, + [CTRL_ATTR_OP] = { .name = "op", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest nlctrl_ctrl_attrs_nest = { + .max_attr = CTRL_ATTR_MAX, + .table = nlctrl_ctrl_attrs_policy, +}; + +/* Common nested types */ +void nlctrl_op_attrs_free(struct nlctrl_op_attrs *obj) +{ +} + +int nlctrl_op_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested, __u32 idx) +{ + struct nlctrl_op_attrs *dst = yarg->data; + const struct nlattr *attr; + + dst->idx = idx; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == CTRL_ATTR_OP_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } else if (type == CTRL_ATTR_OP_FLAGS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.flags = 1; + dst->flags = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void nlctrl_mcast_group_attrs_free(struct nlctrl_mcast_group_attrs *obj) +{ + free(obj->name); +} + +int nlctrl_mcast_group_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested, __u32 idx) +{ + struct nlctrl_mcast_group_attrs *dst = yarg->data; + const struct nlattr *attr; + + dst->idx = idx; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == CTRL_ATTR_MCAST_GRP_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.name_len = len; + dst->name = malloc(len + 1); + memcpy(dst->name, ynl_attr_get_str(attr), len); + dst->name[len] = 0; + } else if (type == CTRL_ATTR_MCAST_GRP_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void nlctrl_policy_attrs_free(struct nlctrl_policy_attrs *obj) +{ +} + +int nlctrl_policy_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested, __u32 attr_id, + __u32 policy_id) +{ + struct nlctrl_policy_attrs *dst = yarg->data; + const struct nlattr *attr; + + dst->attr_id = attr_id; + dst->policy_id = policy_id; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == NL_POLICY_TYPE_ATTR_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.type = 1; + dst->type = ynl_attr_get_u32(attr); + } else if (type == NL_POLICY_TYPE_ATTR_MIN_VALUE_S) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.min_value_s = 1; + dst->min_value_s = ynl_attr_get_s64(attr); + } else if (type == NL_POLICY_TYPE_ATTR_MAX_VALUE_S) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.max_value_s = 1; + dst->max_value_s = ynl_attr_get_s64(attr); + } else if (type == NL_POLICY_TYPE_ATTR_MIN_VALUE_U) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.min_value_u = 1; + dst->min_value_u = ynl_attr_get_u64(attr); + } else if (type == NL_POLICY_TYPE_ATTR_MAX_VALUE_U) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.max_value_u = 1; + dst->max_value_u = ynl_attr_get_u64(attr); + } else if (type == NL_POLICY_TYPE_ATTR_MIN_LENGTH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.min_length = 1; + dst->min_length = ynl_attr_get_u32(attr); + } else if (type == NL_POLICY_TYPE_ATTR_MAX_LENGTH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.max_length = 1; + dst->max_length = ynl_attr_get_u32(attr); + } else if (type == NL_POLICY_TYPE_ATTR_POLICY_IDX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.policy_idx = 1; + dst->policy_idx = ynl_attr_get_u32(attr); + } else if (type == NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.policy_maxtype = 1; + dst->policy_maxtype = ynl_attr_get_u32(attr); + } else if (type == NL_POLICY_TYPE_ATTR_BITFIELD32_MASK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.bitfield32_mask = 1; + dst->bitfield32_mask = ynl_attr_get_u32(attr); + } else if (type == NL_POLICY_TYPE_ATTR_MASK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.mask = 1; + dst->mask = ynl_attr_get_u64(attr); + } + } + + return 0; +} + +void nlctrl_op_policy_attrs_free(struct nlctrl_op_policy_attrs *obj) +{ +} + +int nlctrl_op_policy_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested, __u32 op_id) +{ + struct nlctrl_op_policy_attrs *dst = yarg->data; + const struct nlattr *attr; + + dst->op_id = op_id; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == CTRL_ATTR_POLICY_DO) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.do_ = 1; + dst->do_ = ynl_attr_get_u32(attr); + } else if (type == CTRL_ATTR_POLICY_DUMP) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dump = 1; + dst->dump = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +/* ============== CTRL_CMD_GETFAMILY ============== */ +/* CTRL_CMD_GETFAMILY - do */ +void nlctrl_getfamily_req_free(struct nlctrl_getfamily_req *req) +{ + free(req->family_name); + free(req); +} + +void nlctrl_getfamily_rsp_free(struct nlctrl_getfamily_rsp *rsp) +{ + free(rsp->family_name); + free(rsp->mcast_groups); + free(rsp->ops); + free(rsp); +} + +int nlctrl_getfamily_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + const struct nlattr *attr_mcast_groups; + struct nlctrl_getfamily_rsp *dst; + unsigned int n_mcast_groups = 0; + const struct nlattr *attr_ops; + const struct nlattr *attr; + struct ynl_parse_arg parg; + unsigned int n_ops = 0; + int i; + + dst = yarg->data; + parg.ys = yarg->ys; + + if (dst->mcast_groups) + return ynl_error_parse(yarg, "attribute already present (ctrl-attrs.mcast-groups)"); + if (dst->ops) + return ynl_error_parse(yarg, "attribute already present (ctrl-attrs.ops)"); + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == CTRL_ATTR_FAMILY_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.family_id = 1; + dst->family_id = ynl_attr_get_u16(attr); + } else if (type == CTRL_ATTR_FAMILY_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.family_name_len = len; + dst->family_name = malloc(len + 1); + memcpy(dst->family_name, ynl_attr_get_str(attr), len); + dst->family_name[len] = 0; + } else if (type == CTRL_ATTR_HDRSIZE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.hdrsize = 1; + dst->hdrsize = ynl_attr_get_u32(attr); + } else if (type == CTRL_ATTR_MAXATTR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.maxattr = 1; + dst->maxattr = ynl_attr_get_u32(attr); + } else if (type == CTRL_ATTR_MCAST_GROUPS) { + const struct nlattr *attr2; + + attr_mcast_groups = attr; + ynl_attr_for_each_nested(attr2, attr) + dst->n_mcast_groups++; + } else if (type == CTRL_ATTR_OPS) { + const struct nlattr *attr2; + + attr_ops = attr; + ynl_attr_for_each_nested(attr2, attr) + dst->n_ops++; + } else if (type == CTRL_ATTR_VERSION) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.version = 1; + dst->version = ynl_attr_get_u32(attr); + } + } + + if (n_mcast_groups) { + dst->mcast_groups = calloc(n_mcast_groups, sizeof(*dst->mcast_groups)); + dst->n_mcast_groups = n_mcast_groups; + i = 0; + parg.rsp_policy = &nlctrl_mcast_group_attrs_nest; + ynl_attr_for_each_nested(attr, attr_mcast_groups) { + parg.data = &dst->mcast_groups[i]; + if (nlctrl_mcast_group_attrs_parse(&parg, attr, ynl_attr_type(attr))) + return YNL_PARSE_CB_ERROR; + i++; + } + } + if (n_ops) { + dst->ops = calloc(n_ops, sizeof(*dst->ops)); + dst->n_ops = n_ops; + i = 0; + parg.rsp_policy = &nlctrl_op_attrs_nest; + ynl_attr_for_each_nested(attr, attr_ops) { + parg.data = &dst->ops[i]; + if (nlctrl_op_attrs_parse(&parg, attr, ynl_attr_type(attr))) + return YNL_PARSE_CB_ERROR; + i++; + } + } + + return YNL_PARSE_CB_OK; +} + +struct nlctrl_getfamily_rsp * +nlctrl_getfamily(struct ynl_sock *ys, struct nlctrl_getfamily_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlctrl_getfamily_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, CTRL_CMD_GETFAMILY, 1); + ys->req_policy = &nlctrl_ctrl_attrs_nest; + yrs.yarg.rsp_policy = &nlctrl_ctrl_attrs_nest; + + if (req->_present.family_name_len) + ynl_attr_put_str(nlh, CTRL_ATTR_FAMILY_NAME, req->family_name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = nlctrl_getfamily_rsp_parse; + yrs.rsp_cmd = 1; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + nlctrl_getfamily_rsp_free(rsp); + return NULL; +} + +/* CTRL_CMD_GETFAMILY - dump */ +void nlctrl_getfamily_list_free(struct nlctrl_getfamily_list *rsp) +{ + struct nlctrl_getfamily_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.family_name); + free(rsp->obj.mcast_groups); + free(rsp->obj.ops); + free(rsp); + } +} + +struct nlctrl_getfamily_list *nlctrl_getfamily_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &nlctrl_ctrl_attrs_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct nlctrl_getfamily_list); + yds.cb = nlctrl_getfamily_rsp_parse; + yds.rsp_cmd = 1; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, CTRL_CMD_GETFAMILY, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + nlctrl_getfamily_list_free(yds.first); + return NULL; +} + +/* ============== CTRL_CMD_GETPOLICY ============== */ +/* CTRL_CMD_GETPOLICY - dump */ +int nlctrl_getpolicy_rsp_dump_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct nlctrl_getpolicy_rsp_dump *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == CTRL_ATTR_FAMILY_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.family_id = 1; + dst->family_id = ynl_attr_get_u16(attr); + } else if (type == CTRL_ATTR_OP_POLICY) { + const struct nlattr *attr_op_id; + __u32 op_id; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.op_policy = 1; + + parg.rsp_policy = &nlctrl_op_policy_attrs_nest; + parg.data = &dst->op_policy; + attr_op_id = ynl_attr_data(attr); + op_id = ynl_attr_type(attr_op_id); + nlctrl_op_policy_attrs_parse(&parg, attr_op_id, op_id); + } else if (type == CTRL_ATTR_POLICY) { + const struct nlattr *attr_policy_id, *attr_attr_id; + __u32 policy_id, attr_id; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.policy = 1; + + parg.rsp_policy = &nlctrl_policy_attrs_nest; + parg.data = &dst->policy; + attr_policy_id = ynl_attr_data(attr); + policy_id = ynl_attr_type(attr_policy_id); + attr_attr_id = ynl_attr_data(attr_policy_id); + attr_id = ynl_attr_type(attr_attr_id); + nlctrl_policy_attrs_parse(&parg, attr_attr_id, policy_id, attr_id); + } + } + + return YNL_PARSE_CB_OK; +} + +void nlctrl_getpolicy_req_dump_free(struct nlctrl_getpolicy_req_dump *req) +{ + free(req->family_name); + free(req); +} + +void nlctrl_getpolicy_rsp_list_free(struct nlctrl_getpolicy_rsp_list *rsp) +{ + struct nlctrl_getpolicy_rsp_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp); + } +} + +struct nlctrl_getpolicy_rsp_list * +nlctrl_getpolicy_dump(struct ynl_sock *ys, + struct nlctrl_getpolicy_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &nlctrl_ctrl_attrs_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct nlctrl_getpolicy_rsp_list); + yds.cb = nlctrl_getpolicy_rsp_dump_parse; + yds.rsp_cmd = CTRL_CMD_GETPOLICY; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, CTRL_CMD_GETPOLICY, 1); + ys->req_policy = &nlctrl_ctrl_attrs_nest; + + if (req->_present.family_name_len) + ynl_attr_put_str(nlh, CTRL_ATTR_FAMILY_NAME, req->family_name); + if (req->_present.family_id) + ynl_attr_put_u16(nlh, CTRL_ATTR_FAMILY_ID, req->family_id); + if (req->_present.op) + ynl_attr_put_u32(nlh, CTRL_ATTR_OP, req->op); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + nlctrl_getpolicy_rsp_list_free(yds.first); + return NULL; +} + +const struct ynl_family ynl_nlctrl_family = { + .name = "nlctrl", + .hdr_len = sizeof(struct genlmsghdr), +}; diff --git a/generated/nlctrl-user.h b/generated/nlctrl-user.h new file mode 100644 index 0000000..e2f7275 --- /dev/null +++ b/generated/nlctrl-user.h @@ -0,0 +1,221 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/nlctrl.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_NLCTRL_GEN_H +#define _LINUX_NLCTRL_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_nlctrl_family; + +/* Enums */ +const char *nlctrl_op_str(int op); +const char *nlctrl_op_flags_str(int value); +const char *nlctrl_attr_type_str(enum netlink_attribute_type value); + +/* Common nested types */ +struct nlctrl_op_attrs { + struct { + __u32 id:1; + __u32 flags:1; + } _present; + + __u32 idx; + __u32 id; + __u32 flags; +}; + +struct nlctrl_mcast_group_attrs { + struct { + __u32 name_len; + __u32 id:1; + } _present; + + __u32 idx; + char *name; + __u32 id; +}; + +struct nlctrl_policy_attrs { + struct { + __u32 type:1; + __u32 min_value_s:1; + __u32 max_value_s:1; + __u32 min_value_u:1; + __u32 max_value_u:1; + __u32 min_length:1; + __u32 max_length:1; + __u32 policy_idx:1; + __u32 policy_maxtype:1; + __u32 bitfield32_mask:1; + __u32 mask:1; + } _present; + + __u32 attr_id; + __u32 policy_id; + enum netlink_attribute_type type; + __s64 min_value_s; + __s64 max_value_s; + __u64 min_value_u; + __u64 max_value_u; + __u32 min_length; + __u32 max_length; + __u32 policy_idx; + __u32 policy_maxtype; + __u32 bitfield32_mask; + __u64 mask; +}; + +struct nlctrl_op_policy_attrs { + struct { + __u32 do_:1; + __u32 dump:1; + } _present; + + __u32 op_id; + __u32 do_; + __u32 dump; +}; + +/* ============== CTRL_CMD_GETFAMILY ============== */ +/* CTRL_CMD_GETFAMILY - do */ +struct nlctrl_getfamily_req { + struct { + __u32 family_name_len; + } _present; + + char *family_name; +}; + +static inline struct nlctrl_getfamily_req *nlctrl_getfamily_req_alloc(void) +{ + return calloc(1, sizeof(struct nlctrl_getfamily_req)); +} +void nlctrl_getfamily_req_free(struct nlctrl_getfamily_req *req); + +static inline void +nlctrl_getfamily_req_set_family_name(struct nlctrl_getfamily_req *req, + const char *family_name) +{ + free(req->family_name); + req->_present.family_name_len = strlen(family_name); + req->family_name = malloc(req->_present.family_name_len + 1); + memcpy(req->family_name, family_name, req->_present.family_name_len); + req->family_name[req->_present.family_name_len] = 0; +} + +struct nlctrl_getfamily_rsp { + struct { + __u32 family_id:1; + __u32 family_name_len; + __u32 hdrsize:1; + __u32 maxattr:1; + __u32 version:1; + } _present; + + __u16 family_id; + char *family_name; + __u32 hdrsize; + __u32 maxattr; + unsigned int n_mcast_groups; + struct nlctrl_mcast_group_attrs *mcast_groups; + unsigned int n_ops; + struct nlctrl_op_attrs *ops; + __u32 version; +}; + +void nlctrl_getfamily_rsp_free(struct nlctrl_getfamily_rsp *rsp); + +/* + * Get / dump genetlink families + */ +struct nlctrl_getfamily_rsp * +nlctrl_getfamily(struct ynl_sock *ys, struct nlctrl_getfamily_req *req); + +/* CTRL_CMD_GETFAMILY - dump */ +struct nlctrl_getfamily_list { + struct nlctrl_getfamily_list *next; + struct nlctrl_getfamily_rsp obj __attribute__((aligned(8))); +}; + +void nlctrl_getfamily_list_free(struct nlctrl_getfamily_list *rsp); + +struct nlctrl_getfamily_list *nlctrl_getfamily_dump(struct ynl_sock *ys); + +/* ============== CTRL_CMD_GETPOLICY ============== */ +/* CTRL_CMD_GETPOLICY - dump */ +struct nlctrl_getpolicy_req_dump { + struct { + __u32 family_name_len; + __u32 family_id:1; + __u32 op:1; + } _present; + + char *family_name; + __u16 family_id; + __u32 op; +}; + +static inline struct nlctrl_getpolicy_req_dump * +nlctrl_getpolicy_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct nlctrl_getpolicy_req_dump)); +} +void nlctrl_getpolicy_req_dump_free(struct nlctrl_getpolicy_req_dump *req); + +static inline void +nlctrl_getpolicy_req_dump_set_family_name(struct nlctrl_getpolicy_req_dump *req, + const char *family_name) +{ + free(req->family_name); + req->_present.family_name_len = strlen(family_name); + req->family_name = malloc(req->_present.family_name_len + 1); + memcpy(req->family_name, family_name, req->_present.family_name_len); + req->family_name[req->_present.family_name_len] = 0; +} +static inline void +nlctrl_getpolicy_req_dump_set_family_id(struct nlctrl_getpolicy_req_dump *req, + __u16 family_id) +{ + req->_present.family_id = 1; + req->family_id = family_id; +} +static inline void +nlctrl_getpolicy_req_dump_set_op(struct nlctrl_getpolicy_req_dump *req, + __u32 op) +{ + req->_present.op = 1; + req->op = op; +} + +struct nlctrl_getpolicy_rsp_dump { + struct { + __u32 family_id:1; + __u32 op_policy:1; + __u32 policy:1; + } _present; + + __u16 family_id; + struct nlctrl_op_policy_attrs op_policy; + struct nlctrl_policy_attrs policy; +}; + +struct nlctrl_getpolicy_rsp_list { + struct nlctrl_getpolicy_rsp_list *next; + struct nlctrl_getpolicy_rsp_dump obj __attribute__((aligned(8))); +}; + +void nlctrl_getpolicy_rsp_list_free(struct nlctrl_getpolicy_rsp_list *rsp); + +struct nlctrl_getpolicy_rsp_list * +nlctrl_getpolicy_dump(struct ynl_sock *ys, + struct nlctrl_getpolicy_req_dump *req); + +#endif /* _LINUX_NLCTRL_GEN_H */ diff --git a/generated/ovs_datapath-user.c b/generated/ovs_datapath-user.c new file mode 100644 index 0000000..f270fa2 --- /dev/null +++ b/generated/ovs_datapath-user.c @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/ovs_datapath.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "ovs_datapath-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const ovs_datapath_op_strmap[] = { + [OVS_DP_CMD_GET] = "get", + [OVS_DP_CMD_NEW] = "new", + [OVS_DP_CMD_DEL] = "del", +}; + +const char *ovs_datapath_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(ovs_datapath_op_strmap)) + return NULL; + return ovs_datapath_op_strmap[op]; +} + +static const char * const ovs_datapath_user_features_strmap[] = { + [0] = "unaligned", + [1] = "vport-pids", + [2] = "tc-recirc-sharing", + [3] = "dispatch-upcall-per-cpu", +}; + +const char *ovs_datapath_user_features_str(int value) +{ + value = ffs(value) - 1; + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(ovs_datapath_user_features_strmap)) + return NULL; + return ovs_datapath_user_features_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr ovs_datapath_datapath_policy[OVS_DP_ATTR_MAX + 1] = { + [OVS_DP_ATTR_NAME] = { .name = "name", .type = YNL_PT_NUL_STR, }, + [OVS_DP_ATTR_UPCALL_PID] = { .name = "upcall-pid", .type = YNL_PT_U32, }, + [OVS_DP_ATTR_STATS] = { .name = "stats", .type = YNL_PT_BINARY,}, + [OVS_DP_ATTR_MEGAFLOW_STATS] = { .name = "megaflow-stats", .type = YNL_PT_BINARY,}, + [OVS_DP_ATTR_USER_FEATURES] = { .name = "user-features", .type = YNL_PT_U32, }, + [OVS_DP_ATTR_PAD] = { .name = "pad", .type = YNL_PT_REJECT, }, + [OVS_DP_ATTR_MASKS_CACHE_SIZE] = { .name = "masks-cache-size", .type = YNL_PT_U32, }, + [OVS_DP_ATTR_PER_CPU_PIDS] = { .name = "per-cpu-pids", .type = YNL_PT_BINARY,}, + [OVS_DP_ATTR_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ovs_datapath_datapath_nest = { + .max_attr = OVS_DP_ATTR_MAX, + .table = ovs_datapath_datapath_policy, +}; + +/* Common nested types */ +/* ============== OVS_DP_CMD_GET ============== */ +/* OVS_DP_CMD_GET - do */ +void ovs_datapath_get_req_free(struct ovs_datapath_get_req *req) +{ + free(req->name); + free(req); +} + +void ovs_datapath_get_rsp_free(struct ovs_datapath_get_rsp *rsp) +{ + free(rsp->name); + free(rsp->stats); + free(rsp->megaflow_stats); + free(rsp->per_cpu_pids); + free(rsp); +} + +int ovs_datapath_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ovs_datapath_get_rsp *dst; + const struct nlattr *attr; + void *hdr; + + dst = yarg->data; + + hdr = ynl_nlmsg_data_offset(nlh, sizeof(struct genlmsghdr)); + memcpy(&dst->_hdr, hdr, sizeof(struct ovs_header)); + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_DP_ATTR_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.name_len = len; + dst->name = malloc(len + 1); + memcpy(dst->name, ynl_attr_get_str(attr), len); + dst->name[len] = 0; + } else if (type == OVS_DP_ATTR_UPCALL_PID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.upcall_pid = 1; + dst->upcall_pid = ynl_attr_get_u32(attr); + } else if (type == OVS_DP_ATTR_STATS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.stats_len = len; + dst->stats = malloc(len); + memcpy(dst->stats, ynl_attr_data(attr), len); + } else if (type == OVS_DP_ATTR_MEGAFLOW_STATS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.megaflow_stats_len = len; + dst->megaflow_stats = malloc(len); + memcpy(dst->megaflow_stats, ynl_attr_data(attr), len); + } else if (type == OVS_DP_ATTR_USER_FEATURES) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.user_features = 1; + dst->user_features = ynl_attr_get_u32(attr); + } else if (type == OVS_DP_ATTR_MASKS_CACHE_SIZE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.masks_cache_size = 1; + dst->masks_cache_size = ynl_attr_get_u32(attr); + } else if (type == OVS_DP_ATTR_PER_CPU_PIDS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.per_cpu_pids_len = len; + dst->per_cpu_pids = malloc(len); + memcpy(dst->per_cpu_pids, ynl_attr_data(attr), len); + } + } + + return YNL_PARSE_CB_OK; +} + +struct ovs_datapath_get_rsp * +ovs_datapath_get(struct ynl_sock *ys, struct ovs_datapath_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ovs_datapath_get_rsp *rsp; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, OVS_DP_CMD_GET, 1); + ys->req_policy = &ovs_datapath_datapath_nest; + yrs.yarg.rsp_policy = &ovs_datapath_datapath_nest; + + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + if (req->_present.name_len) + ynl_attr_put_str(nlh, OVS_DP_ATTR_NAME, req->name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ovs_datapath_get_rsp_parse; + yrs.rsp_cmd = OVS_DP_CMD_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ovs_datapath_get_rsp_free(rsp); + return NULL; +} + +/* OVS_DP_CMD_GET - dump */ +void ovs_datapath_get_req_dump_free(struct ovs_datapath_get_req_dump *req) +{ + free(req->name); + free(req); +} + +void ovs_datapath_get_list_free(struct ovs_datapath_get_list *rsp) +{ + struct ovs_datapath_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.name); + free(rsp->obj.stats); + free(rsp->obj.megaflow_stats); + free(rsp->obj.per_cpu_pids); + free(rsp); + } +} + +struct ovs_datapath_get_list * +ovs_datapath_get_dump(struct ynl_sock *ys, + struct ovs_datapath_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &ovs_datapath_datapath_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ovs_datapath_get_list); + yds.cb = ovs_datapath_get_rsp_parse; + yds.rsp_cmd = OVS_DP_CMD_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, OVS_DP_CMD_GET, 1); + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + ys->req_policy = &ovs_datapath_datapath_nest; + + if (req->_present.name_len) + ynl_attr_put_str(nlh, OVS_DP_ATTR_NAME, req->name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ovs_datapath_get_list_free(yds.first); + return NULL; +} + +/* ============== OVS_DP_CMD_NEW ============== */ +/* OVS_DP_CMD_NEW - do */ +void ovs_datapath_new_req_free(struct ovs_datapath_new_req *req) +{ + free(req->name); + free(req); +} + +int ovs_datapath_new(struct ynl_sock *ys, struct ovs_datapath_new_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, OVS_DP_CMD_NEW, 1); + ys->req_policy = &ovs_datapath_datapath_nest; + + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + if (req->_present.name_len) + ynl_attr_put_str(nlh, OVS_DP_ATTR_NAME, req->name); + if (req->_present.upcall_pid) + ynl_attr_put_u32(nlh, OVS_DP_ATTR_UPCALL_PID, req->upcall_pid); + if (req->_present.user_features) + ynl_attr_put_u32(nlh, OVS_DP_ATTR_USER_FEATURES, req->user_features); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== OVS_DP_CMD_DEL ============== */ +/* OVS_DP_CMD_DEL - do */ +void ovs_datapath_del_req_free(struct ovs_datapath_del_req *req) +{ + free(req->name); + free(req); +} + +int ovs_datapath_del(struct ynl_sock *ys, struct ovs_datapath_del_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, OVS_DP_CMD_DEL, 1); + ys->req_policy = &ovs_datapath_datapath_nest; + + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + if (req->_present.name_len) + ynl_attr_put_str(nlh, OVS_DP_ATTR_NAME, req->name); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +const struct ynl_family ynl_ovs_datapath_family = { + .name = "ovs_datapath", + .hdr_len = sizeof(struct genlmsghdr) + sizeof(struct ovs_header), +}; diff --git a/generated/ovs_datapath-user.h b/generated/ovs_datapath-user.h new file mode 100644 index 0000000..fcd5b46 --- /dev/null +++ b/generated/ovs_datapath-user.h @@ -0,0 +1,208 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/ovs_datapath.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_OVS_DATAPATH_GEN_H +#define _LINUX_OVS_DATAPATH_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_ovs_datapath_family; + +/* Enums */ +const char *ovs_datapath_op_str(int op); +const char *ovs_datapath_user_features_str(int value); + +/* Common nested types */ +/* ============== OVS_DP_CMD_GET ============== */ +/* OVS_DP_CMD_GET - do */ +struct ovs_datapath_get_req { + struct ovs_header _hdr; + + struct { + __u32 name_len; + } _present; + + char *name; +}; + +static inline struct ovs_datapath_get_req *ovs_datapath_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ovs_datapath_get_req)); +} +void ovs_datapath_get_req_free(struct ovs_datapath_get_req *req); + +static inline void +ovs_datapath_get_req_set_name(struct ovs_datapath_get_req *req, + const char *name) +{ + free(req->name); + req->_present.name_len = strlen(name); + req->name = malloc(req->_present.name_len + 1); + memcpy(req->name, name, req->_present.name_len); + req->name[req->_present.name_len] = 0; +} + +struct ovs_datapath_get_rsp { + struct ovs_header _hdr; + + struct { + __u32 name_len; + __u32 upcall_pid:1; + __u32 stats_len; + __u32 megaflow_stats_len; + __u32 user_features:1; + __u32 masks_cache_size:1; + __u32 per_cpu_pids_len; + } _present; + + char *name; + __u32 upcall_pid; + void *stats; + void *megaflow_stats; + __u32 user_features; + __u32 masks_cache_size; + void *per_cpu_pids; +}; + +void ovs_datapath_get_rsp_free(struct ovs_datapath_get_rsp *rsp); + +/* + * Get / dump OVS data path configuration and state + */ +struct ovs_datapath_get_rsp * +ovs_datapath_get(struct ynl_sock *ys, struct ovs_datapath_get_req *req); + +/* OVS_DP_CMD_GET - dump */ +struct ovs_datapath_get_req_dump { + struct ovs_header _hdr; + + struct { + __u32 name_len; + } _present; + + char *name; +}; + +static inline struct ovs_datapath_get_req_dump * +ovs_datapath_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ovs_datapath_get_req_dump)); +} +void ovs_datapath_get_req_dump_free(struct ovs_datapath_get_req_dump *req); + +static inline void +ovs_datapath_get_req_dump_set_name(struct ovs_datapath_get_req_dump *req, + const char *name) +{ + free(req->name); + req->_present.name_len = strlen(name); + req->name = malloc(req->_present.name_len + 1); + memcpy(req->name, name, req->_present.name_len); + req->name[req->_present.name_len] = 0; +} + +struct ovs_datapath_get_list { + struct ovs_datapath_get_list *next; + struct ovs_datapath_get_rsp obj __attribute__((aligned(8))); +}; + +void ovs_datapath_get_list_free(struct ovs_datapath_get_list *rsp); + +struct ovs_datapath_get_list * +ovs_datapath_get_dump(struct ynl_sock *ys, + struct ovs_datapath_get_req_dump *req); + +/* ============== OVS_DP_CMD_NEW ============== */ +/* OVS_DP_CMD_NEW - do */ +struct ovs_datapath_new_req { + struct ovs_header _hdr; + + struct { + __u32 name_len; + __u32 upcall_pid:1; + __u32 user_features:1; + } _present; + + char *name; + __u32 upcall_pid; + __u32 user_features; +}; + +static inline struct ovs_datapath_new_req *ovs_datapath_new_req_alloc(void) +{ + return calloc(1, sizeof(struct ovs_datapath_new_req)); +} +void ovs_datapath_new_req_free(struct ovs_datapath_new_req *req); + +static inline void +ovs_datapath_new_req_set_name(struct ovs_datapath_new_req *req, + const char *name) +{ + free(req->name); + req->_present.name_len = strlen(name); + req->name = malloc(req->_present.name_len + 1); + memcpy(req->name, name, req->_present.name_len); + req->name[req->_present.name_len] = 0; +} +static inline void +ovs_datapath_new_req_set_upcall_pid(struct ovs_datapath_new_req *req, + __u32 upcall_pid) +{ + req->_present.upcall_pid = 1; + req->upcall_pid = upcall_pid; +} +static inline void +ovs_datapath_new_req_set_user_features(struct ovs_datapath_new_req *req, + __u32 user_features) +{ + req->_present.user_features = 1; + req->user_features = user_features; +} + +/* + * Create new OVS data path + */ +int ovs_datapath_new(struct ynl_sock *ys, struct ovs_datapath_new_req *req); + +/* ============== OVS_DP_CMD_DEL ============== */ +/* OVS_DP_CMD_DEL - do */ +struct ovs_datapath_del_req { + struct ovs_header _hdr; + + struct { + __u32 name_len; + } _present; + + char *name; +}; + +static inline struct ovs_datapath_del_req *ovs_datapath_del_req_alloc(void) +{ + return calloc(1, sizeof(struct ovs_datapath_del_req)); +} +void ovs_datapath_del_req_free(struct ovs_datapath_del_req *req); + +static inline void +ovs_datapath_del_req_set_name(struct ovs_datapath_del_req *req, + const char *name) +{ + free(req->name); + req->_present.name_len = strlen(name); + req->name = malloc(req->_present.name_len + 1); + memcpy(req->name, name, req->_present.name_len); + req->name[req->_present.name_len] = 0; +} + +/* + * Delete existing OVS data path + */ +int ovs_datapath_del(struct ynl_sock *ys, struct ovs_datapath_del_req *req); + +#endif /* _LINUX_OVS_DATAPATH_GEN_H */ diff --git a/generated/ovs_flow-user.c b/generated/ovs_flow-user.c new file mode 100644 index 0000000..e92cb3d --- /dev/null +++ b/generated/ovs_flow-user.c @@ -0,0 +1,1989 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/ovs_flow.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "ovs_flow-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const ovs_flow_op_strmap[] = { + [OVS_FLOW_CMD_GET] = "get", + [OVS_FLOW_CMD_NEW] = "new", +}; + +const char *ovs_flow_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(ovs_flow_op_strmap)) + return NULL; + return ovs_flow_op_strmap[op]; +} + +static const char * const ovs_flow_ovs_frag_type_strmap[] = { + [0] = "none", + [1] = "first", + [2] = "later", + [255] = "any", +}; + +const char *ovs_flow_ovs_frag_type_str(enum ovs_frag_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(ovs_flow_ovs_frag_type_strmap)) + return NULL; + return ovs_flow_ovs_frag_type_strmap[value]; +} + +static const char * const ovs_flow_ovs_ufid_flags_strmap[] = { + [0] = "omit-key", + [1] = "omit-mask", + [2] = "omit-actions", +}; + +const char *ovs_flow_ovs_ufid_flags_str(int value) +{ + value = ffs(value) - 1; + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(ovs_flow_ovs_ufid_flags_strmap)) + return NULL; + return ovs_flow_ovs_ufid_flags_strmap[value]; +} + +static const char * const ovs_flow_ovs_hash_alg_strmap[] = { + [0] = "ovs-hash-alg-l4", +}; + +const char *ovs_flow_ovs_hash_alg_str(enum ovs_hash_alg value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(ovs_flow_ovs_hash_alg_strmap)) + return NULL; + return ovs_flow_ovs_hash_alg_strmap[value]; +} + +static const char * const ovs_flow_ct_state_flags_strmap[] = { + [0] = "new", + [1] = "established", + [2] = "related", + [3] = "reply-dir", + [4] = "invalid", + [5] = "tracked", + [6] = "src-nat", + [7] = "dst-nat", +}; + +const char *ovs_flow_ct_state_flags_str(int value) +{ + value = ffs(value) - 1; + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(ovs_flow_ct_state_flags_strmap)) + return NULL; + return ovs_flow_ct_state_flags_strmap[value]; +} + +/* Policies */ +extern struct ynl_policy_nest ovs_flow_key_attrs_nest; +extern struct ynl_policy_nest ovs_flow_action_attrs_nest; + +struct ynl_policy_attr ovs_flow_ovs_nsh_key_attrs_policy[OVS_NSH_KEY_ATTR_MAX + 1] = { + [OVS_NSH_KEY_ATTR_BASE] = { .name = "base", .type = YNL_PT_BINARY,}, + [OVS_NSH_KEY_ATTR_MD1] = { .name = "md1", .type = YNL_PT_BINARY,}, + [OVS_NSH_KEY_ATTR_MD2] = { .name = "md2", .type = YNL_PT_BINARY,}, +}; + +struct ynl_policy_nest ovs_flow_ovs_nsh_key_attrs_nest = { + .max_attr = OVS_NSH_KEY_ATTR_MAX, + .table = ovs_flow_ovs_nsh_key_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_userspace_attrs_policy[OVS_USERSPACE_ATTR_MAX + 1] = { + [OVS_USERSPACE_ATTR_PID] = { .name = "pid", .type = YNL_PT_U32, }, + [OVS_USERSPACE_ATTR_USERDATA] = { .name = "userdata", .type = YNL_PT_BINARY,}, + [OVS_USERSPACE_ATTR_EGRESS_TUN_PORT] = { .name = "egress-tun-port", .type = YNL_PT_U32, }, + [OVS_USERSPACE_ATTR_ACTIONS] = { .name = "actions", .type = YNL_PT_FLAG, }, +}; + +struct ynl_policy_nest ovs_flow_userspace_attrs_nest = { + .max_attr = OVS_USERSPACE_ATTR_MAX, + .table = ovs_flow_userspace_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_vxlan_ext_attrs_policy[OVS_VXLAN_EXT_MAX + 1] = { + [OVS_VXLAN_EXT_GBP] = { .name = "gbp", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ovs_flow_vxlan_ext_attrs_nest = { + .max_attr = OVS_VXLAN_EXT_MAX, + .table = ovs_flow_vxlan_ext_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_nat_attrs_policy[OVS_NAT_ATTR_MAX + 1] = { + [OVS_NAT_ATTR_SRC] = { .name = "src", .type = YNL_PT_FLAG, }, + [OVS_NAT_ATTR_DST] = { .name = "dst", .type = YNL_PT_FLAG, }, + [OVS_NAT_ATTR_IP_MIN] = { .name = "ip-min", .type = YNL_PT_BINARY,}, + [OVS_NAT_ATTR_IP_MAX] = { .name = "ip-max", .type = YNL_PT_BINARY,}, + [OVS_NAT_ATTR_PROTO_MIN] = { .name = "proto-min", .type = YNL_PT_U16, }, + [OVS_NAT_ATTR_PROTO_MAX] = { .name = "proto-max", .type = YNL_PT_U16, }, + [OVS_NAT_ATTR_PERSISTENT] = { .name = "persistent", .type = YNL_PT_FLAG, }, + [OVS_NAT_ATTR_PROTO_HASH] = { .name = "proto-hash", .type = YNL_PT_FLAG, }, + [OVS_NAT_ATTR_PROTO_RANDOM] = { .name = "proto-random", .type = YNL_PT_FLAG, }, +}; + +struct ynl_policy_nest ovs_flow_nat_attrs_nest = { + .max_attr = OVS_NAT_ATTR_MAX, + .table = ovs_flow_nat_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_tunnel_key_attrs_policy[OVS_TUNNEL_KEY_ATTR_MAX + 1] = { + [OVS_TUNNEL_KEY_ATTR_ID] = { .name = "id", .type = YNL_PT_U64, }, + [OVS_TUNNEL_KEY_ATTR_IPV4_SRC] = { .name = "ipv4-src", .type = YNL_PT_U32, }, + [OVS_TUNNEL_KEY_ATTR_IPV4_DST] = { .name = "ipv4-dst", .type = YNL_PT_U32, }, + [OVS_TUNNEL_KEY_ATTR_TOS] = { .name = "tos", .type = YNL_PT_U8, }, + [OVS_TUNNEL_KEY_ATTR_TTL] = { .name = "ttl", .type = YNL_PT_U8, }, + [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = { .name = "dont-fragment", .type = YNL_PT_FLAG, }, + [OVS_TUNNEL_KEY_ATTR_CSUM] = { .name = "csum", .type = YNL_PT_FLAG, }, + [OVS_TUNNEL_KEY_ATTR_OAM] = { .name = "oam", .type = YNL_PT_FLAG, }, + [OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS] = { .name = "geneve-opts", .type = YNL_PT_BINARY,}, + [OVS_TUNNEL_KEY_ATTR_TP_SRC] = { .name = "tp-src", .type = YNL_PT_U16, }, + [OVS_TUNNEL_KEY_ATTR_TP_DST] = { .name = "tp-dst", .type = YNL_PT_U16, }, + [OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS] = { .name = "vxlan-opts", .type = YNL_PT_NEST, .nest = &ovs_flow_vxlan_ext_attrs_nest, }, + [OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .name = "ipv6-src", .type = YNL_PT_BINARY,}, + [OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .name = "ipv6-dst", .type = YNL_PT_BINARY,}, + [OVS_TUNNEL_KEY_ATTR_PAD] = { .name = "pad", .type = YNL_PT_BINARY,}, + [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .name = "erspan-opts", .type = YNL_PT_BINARY,}, + [OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE] = { .name = "ipv4-info-bridge", .type = YNL_PT_FLAG, }, +}; + +struct ynl_policy_nest ovs_flow_tunnel_key_attrs_nest = { + .max_attr = OVS_TUNNEL_KEY_ATTR_MAX, + .table = ovs_flow_tunnel_key_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_ct_attrs_policy[OVS_CT_ATTR_MAX + 1] = { + [OVS_CT_ATTR_COMMIT] = { .name = "commit", .type = YNL_PT_FLAG, }, + [OVS_CT_ATTR_ZONE] = { .name = "zone", .type = YNL_PT_U16, }, + [OVS_CT_ATTR_MARK] = { .name = "mark", .type = YNL_PT_BINARY,}, + [OVS_CT_ATTR_LABELS] = { .name = "labels", .type = YNL_PT_BINARY,}, + [OVS_CT_ATTR_HELPER] = { .name = "helper", .type = YNL_PT_NUL_STR, }, + [OVS_CT_ATTR_NAT] = { .name = "nat", .type = YNL_PT_NEST, .nest = &ovs_flow_nat_attrs_nest, }, + [OVS_CT_ATTR_FORCE_COMMIT] = { .name = "force-commit", .type = YNL_PT_FLAG, }, + [OVS_CT_ATTR_EVENTMASK] = { .name = "eventmask", .type = YNL_PT_U32, }, + [OVS_CT_ATTR_TIMEOUT] = { .name = "timeout", .type = YNL_PT_NUL_STR, }, +}; + +struct ynl_policy_nest ovs_flow_ct_attrs_nest = { + .max_attr = OVS_CT_ATTR_MAX, + .table = ovs_flow_ct_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_check_pkt_len_attrs_policy[OVS_CHECK_PKT_LEN_ATTR_MAX + 1] = { + [OVS_CHECK_PKT_LEN_ATTR_PKT_LEN] = { .name = "pkt-len", .type = YNL_PT_U16, }, + [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER] = { .name = "actions-if-greater", .type = YNL_PT_NEST, .nest = &ovs_flow_action_attrs_nest, }, + [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL] = { .name = "actions-if-less-equal", .type = YNL_PT_NEST, .nest = &ovs_flow_action_attrs_nest, }, +}; + +struct ynl_policy_nest ovs_flow_check_pkt_len_attrs_nest = { + .max_attr = OVS_CHECK_PKT_LEN_ATTR_MAX, + .table = ovs_flow_check_pkt_len_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_dec_ttl_attrs_policy[OVS_DEC_TTL_ATTR_MAX + 1] = { + [OVS_DEC_TTL_ATTR_ACTION] = { .name = "action", .type = YNL_PT_NEST, .nest = &ovs_flow_action_attrs_nest, }, +}; + +struct ynl_policy_nest ovs_flow_dec_ttl_attrs_nest = { + .max_attr = OVS_DEC_TTL_ATTR_MAX, + .table = ovs_flow_dec_ttl_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_key_attrs_policy[OVS_KEY_ATTR_MAX + 1] = { + [OVS_KEY_ATTR_ENCAP] = { .name = "encap", .type = YNL_PT_NEST, .nest = &ovs_flow_key_attrs_nest, }, + [OVS_KEY_ATTR_PRIORITY] = { .name = "priority", .type = YNL_PT_U32, }, + [OVS_KEY_ATTR_IN_PORT] = { .name = "in-port", .type = YNL_PT_U32, }, + [OVS_KEY_ATTR_ETHERNET] = { .name = "ethernet", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_VLAN] = { .name = "vlan", .type = YNL_PT_U16, }, + [OVS_KEY_ATTR_ETHERTYPE] = { .name = "ethertype", .type = YNL_PT_U16, }, + [OVS_KEY_ATTR_IPV4] = { .name = "ipv4", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_IPV6] = { .name = "ipv6", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_TCP] = { .name = "tcp", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_UDP] = { .name = "udp", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_ICMP] = { .name = "icmp", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_ICMPV6] = { .name = "icmpv6", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_ARP] = { .name = "arp", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_ND] = { .name = "nd", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_SKB_MARK] = { .name = "skb-mark", .type = YNL_PT_U32, }, + [OVS_KEY_ATTR_TUNNEL] = { .name = "tunnel", .type = YNL_PT_NEST, .nest = &ovs_flow_tunnel_key_attrs_nest, }, + [OVS_KEY_ATTR_SCTP] = { .name = "sctp", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_TCP_FLAGS] = { .name = "tcp-flags", .type = YNL_PT_U16, }, + [OVS_KEY_ATTR_DP_HASH] = { .name = "dp-hash", .type = YNL_PT_U32, }, + [OVS_KEY_ATTR_RECIRC_ID] = { .name = "recirc-id", .type = YNL_PT_U32, }, + [OVS_KEY_ATTR_MPLS] = { .name = "mpls", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_CT_STATE] = { .name = "ct-state", .type = YNL_PT_U32, }, + [OVS_KEY_ATTR_CT_ZONE] = { .name = "ct-zone", .type = YNL_PT_U16, }, + [OVS_KEY_ATTR_CT_MARK] = { .name = "ct-mark", .type = YNL_PT_U32, }, + [OVS_KEY_ATTR_CT_LABELS] = { .name = "ct-labels", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4] = { .name = "ct-orig-tuple-ipv4", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6] = { .name = "ct-orig-tuple-ipv6", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_NSH] = { .name = "nsh", .type = YNL_PT_NEST, .nest = &ovs_flow_ovs_nsh_key_attrs_nest, }, + [OVS_KEY_ATTR_PACKET_TYPE] = { .name = "packet-type", .type = YNL_PT_U32, }, + [OVS_KEY_ATTR_ND_EXTENSIONS] = { .name = "nd-extensions", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_TUNNEL_INFO] = { .name = "tunnel-info", .type = YNL_PT_BINARY,}, + [OVS_KEY_ATTR_IPV6_EXTHDRS] = { .name = "ipv6-exthdrs", .type = YNL_PT_BINARY,}, +}; + +struct ynl_policy_nest ovs_flow_key_attrs_nest = { + .max_attr = OVS_KEY_ATTR_MAX, + .table = ovs_flow_key_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_sample_attrs_policy[OVS_SAMPLE_ATTR_MAX + 1] = { + [OVS_SAMPLE_ATTR_PROBABILITY] = { .name = "probability", .type = YNL_PT_U32, }, + [OVS_SAMPLE_ATTR_ACTIONS] = { .name = "actions", .type = YNL_PT_NEST, .nest = &ovs_flow_action_attrs_nest, }, +}; + +struct ynl_policy_nest ovs_flow_sample_attrs_nest = { + .max_attr = OVS_SAMPLE_ATTR_MAX, + .table = ovs_flow_sample_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_action_attrs_policy[OVS_ACTION_ATTR_MAX + 1] = { + [OVS_ACTION_ATTR_OUTPUT] = { .name = "output", .type = YNL_PT_U32, }, + [OVS_ACTION_ATTR_USERSPACE] = { .name = "userspace", .type = YNL_PT_NEST, .nest = &ovs_flow_userspace_attrs_nest, }, + [OVS_ACTION_ATTR_SET] = { .name = "set", .type = YNL_PT_NEST, .nest = &ovs_flow_key_attrs_nest, }, + [OVS_ACTION_ATTR_PUSH_VLAN] = { .name = "push-vlan", .type = YNL_PT_BINARY,}, + [OVS_ACTION_ATTR_POP_VLAN] = { .name = "pop-vlan", .type = YNL_PT_FLAG, }, + [OVS_ACTION_ATTR_SAMPLE] = { .name = "sample", .type = YNL_PT_NEST, .nest = &ovs_flow_sample_attrs_nest, }, + [OVS_ACTION_ATTR_RECIRC] = { .name = "recirc", .type = YNL_PT_U32, }, + [OVS_ACTION_ATTR_HASH] = { .name = "hash", .type = YNL_PT_BINARY,}, + [OVS_ACTION_ATTR_PUSH_MPLS] = { .name = "push-mpls", .type = YNL_PT_BINARY,}, + [OVS_ACTION_ATTR_POP_MPLS] = { .name = "pop-mpls", .type = YNL_PT_U16, }, + [OVS_ACTION_ATTR_SET_MASKED] = { .name = "set-masked", .type = YNL_PT_NEST, .nest = &ovs_flow_key_attrs_nest, }, + [OVS_ACTION_ATTR_CT] = { .name = "ct", .type = YNL_PT_NEST, .nest = &ovs_flow_ct_attrs_nest, }, + [OVS_ACTION_ATTR_TRUNC] = { .name = "trunc", .type = YNL_PT_U32, }, + [OVS_ACTION_ATTR_PUSH_ETH] = { .name = "push-eth", .type = YNL_PT_BINARY,}, + [OVS_ACTION_ATTR_POP_ETH] = { .name = "pop-eth", .type = YNL_PT_FLAG, }, + [OVS_ACTION_ATTR_CT_CLEAR] = { .name = "ct-clear", .type = YNL_PT_FLAG, }, + [OVS_ACTION_ATTR_PUSH_NSH] = { .name = "push-nsh", .type = YNL_PT_NEST, .nest = &ovs_flow_ovs_nsh_key_attrs_nest, }, + [OVS_ACTION_ATTR_POP_NSH] = { .name = "pop-nsh", .type = YNL_PT_FLAG, }, + [OVS_ACTION_ATTR_METER] = { .name = "meter", .type = YNL_PT_U32, }, + [OVS_ACTION_ATTR_CLONE] = { .name = "clone", .type = YNL_PT_NEST, .nest = &ovs_flow_action_attrs_nest, }, + [OVS_ACTION_ATTR_CHECK_PKT_LEN] = { .name = "check-pkt-len", .type = YNL_PT_NEST, .nest = &ovs_flow_check_pkt_len_attrs_nest, }, + [OVS_ACTION_ATTR_ADD_MPLS] = { .name = "add-mpls", .type = YNL_PT_BINARY,}, + [OVS_ACTION_ATTR_DEC_TTL] = { .name = "dec-ttl", .type = YNL_PT_NEST, .nest = &ovs_flow_dec_ttl_attrs_nest, }, +}; + +struct ynl_policy_nest ovs_flow_action_attrs_nest = { + .max_attr = OVS_ACTION_ATTR_MAX, + .table = ovs_flow_action_attrs_policy, +}; + +struct ynl_policy_attr ovs_flow_flow_attrs_policy[OVS_FLOW_ATTR_MAX + 1] = { + [OVS_FLOW_ATTR_KEY] = { .name = "key", .type = YNL_PT_NEST, .nest = &ovs_flow_key_attrs_nest, }, + [OVS_FLOW_ATTR_ACTIONS] = { .name = "actions", .type = YNL_PT_NEST, .nest = &ovs_flow_action_attrs_nest, }, + [OVS_FLOW_ATTR_STATS] = { .name = "stats", .type = YNL_PT_BINARY,}, + [OVS_FLOW_ATTR_TCP_FLAGS] = { .name = "tcp-flags", .type = YNL_PT_U8, }, + [OVS_FLOW_ATTR_USED] = { .name = "used", .type = YNL_PT_U64, }, + [OVS_FLOW_ATTR_CLEAR] = { .name = "clear", .type = YNL_PT_FLAG, }, + [OVS_FLOW_ATTR_MASK] = { .name = "mask", .type = YNL_PT_NEST, .nest = &ovs_flow_key_attrs_nest, }, + [OVS_FLOW_ATTR_PROBE] = { .name = "probe", .type = YNL_PT_BINARY,}, + [OVS_FLOW_ATTR_UFID] = { .name = "ufid", .type = YNL_PT_BINARY,}, + [OVS_FLOW_ATTR_UFID_FLAGS] = { .name = "ufid-flags", .type = YNL_PT_U32, }, + [OVS_FLOW_ATTR_PAD] = { .name = "pad", .type = YNL_PT_BINARY,}, +}; + +struct ynl_policy_nest ovs_flow_flow_attrs_nest = { + .max_attr = OVS_FLOW_ATTR_MAX, + .table = ovs_flow_flow_attrs_policy, +}; + +/* Common nested types */ +void ovs_flow_ovs_nsh_key_attrs_free(struct ovs_flow_ovs_nsh_key_attrs *obj); +int ovs_flow_ovs_nsh_key_attrs_put(struct nlmsghdr *nlh, + unsigned int attr_type, + struct ovs_flow_ovs_nsh_key_attrs *obj); +int ovs_flow_ovs_nsh_key_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void ovs_flow_userspace_attrs_free(struct ovs_flow_userspace_attrs *obj); +int ovs_flow_userspace_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_userspace_attrs *obj); +int ovs_flow_userspace_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void ovs_flow_vxlan_ext_attrs_free(struct ovs_flow_vxlan_ext_attrs *obj); +int ovs_flow_vxlan_ext_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_vxlan_ext_attrs *obj); +int ovs_flow_vxlan_ext_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void ovs_flow_nat_attrs_free(struct ovs_flow_nat_attrs *obj); +int ovs_flow_nat_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_nat_attrs *obj); +int ovs_flow_nat_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void ovs_flow_tunnel_key_attrs_free(struct ovs_flow_tunnel_key_attrs *obj); +int ovs_flow_tunnel_key_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_tunnel_key_attrs *obj); +int ovs_flow_tunnel_key_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void ovs_flow_ct_attrs_free(struct ovs_flow_ct_attrs *obj); +int ovs_flow_ct_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_ct_attrs *obj); +int ovs_flow_ct_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void +ovs_flow_check_pkt_len_attrs_free(struct ovs_flow_check_pkt_len_attrs *obj); +int ovs_flow_check_pkt_len_attrs_put(struct nlmsghdr *nlh, + unsigned int attr_type, + struct ovs_flow_check_pkt_len_attrs *obj); +int ovs_flow_check_pkt_len_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void ovs_flow_dec_ttl_attrs_free(struct ovs_flow_dec_ttl_attrs *obj); +int ovs_flow_dec_ttl_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_dec_ttl_attrs *obj); +int ovs_flow_dec_ttl_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void ovs_flow_key_attrs_free(struct ovs_flow_key_attrs *obj); +int ovs_flow_key_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_key_attrs *obj); +int ovs_flow_key_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void ovs_flow_sample_attrs_free(struct ovs_flow_sample_attrs *obj); +int ovs_flow_sample_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_sample_attrs *obj); +int ovs_flow_sample_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); +void ovs_flow_action_attrs_free(struct ovs_flow_action_attrs *obj); +int ovs_flow_action_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_action_attrs *obj); +int ovs_flow_action_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested); + +void ovs_flow_ovs_nsh_key_attrs_free(struct ovs_flow_ovs_nsh_key_attrs *obj) +{ + free(obj->base); + free(obj->md1); + free(obj->md2); +} + +int ovs_flow_ovs_nsh_key_attrs_put(struct nlmsghdr *nlh, + unsigned int attr_type, + struct ovs_flow_ovs_nsh_key_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.base_len) + ynl_attr_put(nlh, OVS_NSH_KEY_ATTR_BASE, obj->base, obj->_present.base_len); + if (obj->_present.md1_len) + ynl_attr_put(nlh, OVS_NSH_KEY_ATTR_MD1, obj->md1, obj->_present.md1_len); + if (obj->_present.md2_len) + ynl_attr_put(nlh, OVS_NSH_KEY_ATTR_MD2, obj->md2, obj->_present.md2_len); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_ovs_nsh_key_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_ovs_nsh_key_attrs *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_NSH_KEY_ATTR_BASE) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.base_len = len; + dst->base = malloc(len); + memcpy(dst->base, ynl_attr_data(attr), len); + } else if (type == OVS_NSH_KEY_ATTR_MD1) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.md1_len = len; + dst->md1 = malloc(len); + memcpy(dst->md1, ynl_attr_data(attr), len); + } else if (type == OVS_NSH_KEY_ATTR_MD2) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.md2_len = len; + dst->md2 = malloc(len); + memcpy(dst->md2, ynl_attr_data(attr), len); + } + } + + return 0; +} + +void ovs_flow_userspace_attrs_free(struct ovs_flow_userspace_attrs *obj) +{ + free(obj->userdata); +} + +int ovs_flow_userspace_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_userspace_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.pid) + ynl_attr_put_u32(nlh, OVS_USERSPACE_ATTR_PID, obj->pid); + if (obj->_present.userdata_len) + ynl_attr_put(nlh, OVS_USERSPACE_ATTR_USERDATA, obj->userdata, obj->_present.userdata_len); + if (obj->_present.egress_tun_port) + ynl_attr_put_u32(nlh, OVS_USERSPACE_ATTR_EGRESS_TUN_PORT, obj->egress_tun_port); + if (obj->_present.actions) + ynl_attr_put(nlh, OVS_USERSPACE_ATTR_ACTIONS, NULL, 0); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_userspace_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_userspace_attrs *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_USERSPACE_ATTR_PID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pid = 1; + dst->pid = ynl_attr_get_u32(attr); + } else if (type == OVS_USERSPACE_ATTR_USERDATA) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.userdata_len = len; + dst->userdata = malloc(len); + memcpy(dst->userdata, ynl_attr_data(attr), len); + } else if (type == OVS_USERSPACE_ATTR_EGRESS_TUN_PORT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.egress_tun_port = 1; + dst->egress_tun_port = ynl_attr_get_u32(attr); + } else if (type == OVS_USERSPACE_ATTR_ACTIONS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.actions = 1; + } + } + + return 0; +} + +void ovs_flow_vxlan_ext_attrs_free(struct ovs_flow_vxlan_ext_attrs *obj) +{ +} + +int ovs_flow_vxlan_ext_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_vxlan_ext_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.gbp) + ynl_attr_put_u32(nlh, OVS_VXLAN_EXT_GBP, obj->gbp); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_vxlan_ext_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_vxlan_ext_attrs *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_VXLAN_EXT_GBP) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.gbp = 1; + dst->gbp = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +void ovs_flow_nat_attrs_free(struct ovs_flow_nat_attrs *obj) +{ + free(obj->ip_min); + free(obj->ip_max); +} + +int ovs_flow_nat_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_nat_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.src) + ynl_attr_put(nlh, OVS_NAT_ATTR_SRC, NULL, 0); + if (obj->_present.dst) + ynl_attr_put(nlh, OVS_NAT_ATTR_DST, NULL, 0); + if (obj->_present.ip_min_len) + ynl_attr_put(nlh, OVS_NAT_ATTR_IP_MIN, obj->ip_min, obj->_present.ip_min_len); + if (obj->_present.ip_max_len) + ynl_attr_put(nlh, OVS_NAT_ATTR_IP_MAX, obj->ip_max, obj->_present.ip_max_len); + if (obj->_present.proto_min) + ynl_attr_put_u16(nlh, OVS_NAT_ATTR_PROTO_MIN, obj->proto_min); + if (obj->_present.proto_max) + ynl_attr_put_u16(nlh, OVS_NAT_ATTR_PROTO_MAX, obj->proto_max); + if (obj->_present.persistent) + ynl_attr_put(nlh, OVS_NAT_ATTR_PERSISTENT, NULL, 0); + if (obj->_present.proto_hash) + ynl_attr_put(nlh, OVS_NAT_ATTR_PROTO_HASH, NULL, 0); + if (obj->_present.proto_random) + ynl_attr_put(nlh, OVS_NAT_ATTR_PROTO_RANDOM, NULL, 0); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_nat_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_nat_attrs *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_NAT_ATTR_SRC) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.src = 1; + } else if (type == OVS_NAT_ATTR_DST) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dst = 1; + } else if (type == OVS_NAT_ATTR_IP_MIN) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ip_min_len = len; + dst->ip_min = malloc(len); + memcpy(dst->ip_min, ynl_attr_data(attr), len); + } else if (type == OVS_NAT_ATTR_IP_MAX) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ip_max_len = len; + dst->ip_max = malloc(len); + memcpy(dst->ip_max, ynl_attr_data(attr), len); + } else if (type == OVS_NAT_ATTR_PROTO_MIN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.proto_min = 1; + dst->proto_min = ynl_attr_get_u16(attr); + } else if (type == OVS_NAT_ATTR_PROTO_MAX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.proto_max = 1; + dst->proto_max = ynl_attr_get_u16(attr); + } else if (type == OVS_NAT_ATTR_PERSISTENT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.persistent = 1; + } else if (type == OVS_NAT_ATTR_PROTO_HASH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.proto_hash = 1; + } else if (type == OVS_NAT_ATTR_PROTO_RANDOM) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.proto_random = 1; + } + } + + return 0; +} + +void ovs_flow_tunnel_key_attrs_free(struct ovs_flow_tunnel_key_attrs *obj) +{ + free(obj->geneve_opts); + ovs_flow_vxlan_ext_attrs_free(&obj->vxlan_opts); + free(obj->ipv6_src); + free(obj->ipv6_dst); + free(obj->pad); + free(obj->erspan_opts); +} + +int ovs_flow_tunnel_key_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_tunnel_key_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.id) + ynl_attr_put_u64(nlh, OVS_TUNNEL_KEY_ATTR_ID, obj->id); + if (obj->_present.ipv4_src) + ynl_attr_put_u32(nlh, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, obj->ipv4_src); + if (obj->_present.ipv4_dst) + ynl_attr_put_u32(nlh, OVS_TUNNEL_KEY_ATTR_IPV4_DST, obj->ipv4_dst); + if (obj->_present.tos) + ynl_attr_put_u8(nlh, OVS_TUNNEL_KEY_ATTR_TOS, obj->tos); + if (obj->_present.ttl) + ynl_attr_put_u8(nlh, OVS_TUNNEL_KEY_ATTR_TTL, obj->ttl); + if (obj->_present.dont_fragment) + ynl_attr_put(nlh, OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT, NULL, 0); + if (obj->_present.csum) + ynl_attr_put(nlh, OVS_TUNNEL_KEY_ATTR_CSUM, NULL, 0); + if (obj->_present.oam) + ynl_attr_put(nlh, OVS_TUNNEL_KEY_ATTR_OAM, NULL, 0); + if (obj->_present.geneve_opts_len) + ynl_attr_put(nlh, OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS, obj->geneve_opts, obj->_present.geneve_opts_len); + if (obj->_present.tp_src) + ynl_attr_put_u16(nlh, OVS_TUNNEL_KEY_ATTR_TP_SRC, obj->tp_src); + if (obj->_present.tp_dst) + ynl_attr_put_u16(nlh, OVS_TUNNEL_KEY_ATTR_TP_DST, obj->tp_dst); + if (obj->_present.vxlan_opts) + ovs_flow_vxlan_ext_attrs_put(nlh, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS, &obj->vxlan_opts); + if (obj->_present.ipv6_src_len) + ynl_attr_put(nlh, OVS_TUNNEL_KEY_ATTR_IPV6_SRC, obj->ipv6_src, obj->_present.ipv6_src_len); + if (obj->_present.ipv6_dst_len) + ynl_attr_put(nlh, OVS_TUNNEL_KEY_ATTR_IPV6_DST, obj->ipv6_dst, obj->_present.ipv6_dst_len); + if (obj->_present.pad_len) + ynl_attr_put(nlh, OVS_TUNNEL_KEY_ATTR_PAD, obj->pad, obj->_present.pad_len); + if (obj->_present.erspan_opts_len) + ynl_attr_put(nlh, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS, obj->erspan_opts, obj->_present.erspan_opts_len); + if (obj->_present.ipv4_info_bridge) + ynl_attr_put(nlh, OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE, NULL, 0); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_tunnel_key_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_tunnel_key_attrs *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_TUNNEL_KEY_ATTR_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u64(attr); + } else if (type == OVS_TUNNEL_KEY_ATTR_IPV4_SRC) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ipv4_src = 1; + dst->ipv4_src = ynl_attr_get_u32(attr); + } else if (type == OVS_TUNNEL_KEY_ATTR_IPV4_DST) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ipv4_dst = 1; + dst->ipv4_dst = ynl_attr_get_u32(attr); + } else if (type == OVS_TUNNEL_KEY_ATTR_TOS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tos = 1; + dst->tos = ynl_attr_get_u8(attr); + } else if (type == OVS_TUNNEL_KEY_ATTR_TTL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ttl = 1; + dst->ttl = ynl_attr_get_u8(attr); + } else if (type == OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dont_fragment = 1; + } else if (type == OVS_TUNNEL_KEY_ATTR_CSUM) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.csum = 1; + } else if (type == OVS_TUNNEL_KEY_ATTR_OAM) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.oam = 1; + } else if (type == OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.geneve_opts_len = len; + dst->geneve_opts = malloc(len); + memcpy(dst->geneve_opts, ynl_attr_data(attr), len); + } else if (type == OVS_TUNNEL_KEY_ATTR_TP_SRC) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tp_src = 1; + dst->tp_src = ynl_attr_get_u16(attr); + } else if (type == OVS_TUNNEL_KEY_ATTR_TP_DST) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tp_dst = 1; + dst->tp_dst = ynl_attr_get_u16(attr); + } else if (type == OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.vxlan_opts = 1; + + parg.rsp_policy = &ovs_flow_vxlan_ext_attrs_nest; + parg.data = &dst->vxlan_opts; + if (ovs_flow_vxlan_ext_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_TUNNEL_KEY_ATTR_IPV6_SRC) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ipv6_src_len = len; + dst->ipv6_src = malloc(len); + memcpy(dst->ipv6_src, ynl_attr_data(attr), len); + } else if (type == OVS_TUNNEL_KEY_ATTR_IPV6_DST) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ipv6_dst_len = len; + dst->ipv6_dst = malloc(len); + memcpy(dst->ipv6_dst, ynl_attr_data(attr), len); + } else if (type == OVS_TUNNEL_KEY_ATTR_PAD) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.pad_len = len; + dst->pad = malloc(len); + memcpy(dst->pad, ynl_attr_data(attr), len); + } else if (type == OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.erspan_opts_len = len; + dst->erspan_opts = malloc(len); + memcpy(dst->erspan_opts, ynl_attr_data(attr), len); + } else if (type == OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ipv4_info_bridge = 1; + } + } + + return 0; +} + +void ovs_flow_ct_attrs_free(struct ovs_flow_ct_attrs *obj) +{ + free(obj->mark); + free(obj->labels); + free(obj->helper); + ovs_flow_nat_attrs_free(&obj->nat); + free(obj->timeout); +} + +int ovs_flow_ct_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_ct_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.commit) + ynl_attr_put(nlh, OVS_CT_ATTR_COMMIT, NULL, 0); + if (obj->_present.zone) + ynl_attr_put_u16(nlh, OVS_CT_ATTR_ZONE, obj->zone); + if (obj->_present.mark_len) + ynl_attr_put(nlh, OVS_CT_ATTR_MARK, obj->mark, obj->_present.mark_len); + if (obj->_present.labels_len) + ynl_attr_put(nlh, OVS_CT_ATTR_LABELS, obj->labels, obj->_present.labels_len); + if (obj->_present.helper_len) + ynl_attr_put_str(nlh, OVS_CT_ATTR_HELPER, obj->helper); + if (obj->_present.nat) + ovs_flow_nat_attrs_put(nlh, OVS_CT_ATTR_NAT, &obj->nat); + if (obj->_present.force_commit) + ynl_attr_put(nlh, OVS_CT_ATTR_FORCE_COMMIT, NULL, 0); + if (obj->_present.eventmask) + ynl_attr_put_u32(nlh, OVS_CT_ATTR_EVENTMASK, obj->eventmask); + if (obj->_present.timeout_len) + ynl_attr_put_str(nlh, OVS_CT_ATTR_TIMEOUT, obj->timeout); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_ct_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_ct_attrs *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_CT_ATTR_COMMIT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.commit = 1; + } else if (type == OVS_CT_ATTR_ZONE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.zone = 1; + dst->zone = ynl_attr_get_u16(attr); + } else if (type == OVS_CT_ATTR_MARK) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.mark_len = len; + dst->mark = malloc(len); + memcpy(dst->mark, ynl_attr_data(attr), len); + } else if (type == OVS_CT_ATTR_LABELS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.labels_len = len; + dst->labels = malloc(len); + memcpy(dst->labels, ynl_attr_data(attr), len); + } else if (type == OVS_CT_ATTR_HELPER) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.helper_len = len; + dst->helper = malloc(len + 1); + memcpy(dst->helper, ynl_attr_get_str(attr), len); + dst->helper[len] = 0; + } else if (type == OVS_CT_ATTR_NAT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.nat = 1; + + parg.rsp_policy = &ovs_flow_nat_attrs_nest; + parg.data = &dst->nat; + if (ovs_flow_nat_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_CT_ATTR_FORCE_COMMIT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.force_commit = 1; + } else if (type == OVS_CT_ATTR_EVENTMASK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.eventmask = 1; + dst->eventmask = ynl_attr_get_u32(attr); + } else if (type == OVS_CT_ATTR_TIMEOUT) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.timeout_len = len; + dst->timeout = malloc(len + 1); + memcpy(dst->timeout, ynl_attr_get_str(attr), len); + dst->timeout[len] = 0; + } + } + + return 0; +} + +void +ovs_flow_check_pkt_len_attrs_free(struct ovs_flow_check_pkt_len_attrs *obj) +{ + if (obj->actions_if_greater) + ovs_flow_action_attrs_free(obj->actions_if_greater); + if (obj->actions_if_less_equal) + ovs_flow_action_attrs_free(obj->actions_if_less_equal); +} + +int ovs_flow_check_pkt_len_attrs_put(struct nlmsghdr *nlh, + unsigned int attr_type, + struct ovs_flow_check_pkt_len_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.pkt_len) + ynl_attr_put_u16(nlh, OVS_CHECK_PKT_LEN_ATTR_PKT_LEN, obj->pkt_len); + if (obj->_present.actions_if_greater) + ovs_flow_action_attrs_put(nlh, OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER, obj->actions_if_greater); + if (obj->_present.actions_if_less_equal) + ovs_flow_action_attrs_put(nlh, OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL, obj->actions_if_less_equal); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_check_pkt_len_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_check_pkt_len_attrs *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_CHECK_PKT_LEN_ATTR_PKT_LEN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pkt_len = 1; + dst->pkt_len = ynl_attr_get_u16(attr); + } else if (type == OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.actions_if_greater = 1; + + parg.rsp_policy = &ovs_flow_action_attrs_nest; + parg.data = &dst->actions_if_greater; + if (ovs_flow_action_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.actions_if_less_equal = 1; + + parg.rsp_policy = &ovs_flow_action_attrs_nest; + parg.data = &dst->actions_if_less_equal; + if (ovs_flow_action_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return 0; +} + +void ovs_flow_dec_ttl_attrs_free(struct ovs_flow_dec_ttl_attrs *obj) +{ + if (obj->action) + ovs_flow_action_attrs_free(obj->action); +} + +int ovs_flow_dec_ttl_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_dec_ttl_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.action) + ovs_flow_action_attrs_put(nlh, OVS_DEC_TTL_ATTR_ACTION, obj->action); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_dec_ttl_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_dec_ttl_attrs *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_DEC_TTL_ATTR_ACTION) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.action = 1; + + parg.rsp_policy = &ovs_flow_action_attrs_nest; + parg.data = &dst->action; + if (ovs_flow_action_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return 0; +} + +void ovs_flow_key_attrs_free(struct ovs_flow_key_attrs *obj) +{ + if (obj->encap) + ovs_flow_key_attrs_free(obj->encap); + free(obj->ethernet); + free(obj->ipv4); + free(obj->ipv6); + free(obj->tcp); + free(obj->udp); + free(obj->icmp); + free(obj->icmpv6); + free(obj->arp); + free(obj->nd); + ovs_flow_tunnel_key_attrs_free(&obj->tunnel); + free(obj->sctp); + free(obj->mpls); + free(obj->ct_labels); + free(obj->ct_orig_tuple_ipv4); + free(obj->ct_orig_tuple_ipv6); + ovs_flow_ovs_nsh_key_attrs_free(&obj->nsh); + free(obj->nd_extensions); + free(obj->tunnel_info); + free(obj->ipv6_exthdrs); +} + +int ovs_flow_key_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_key_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.encap) + ovs_flow_key_attrs_put(nlh, OVS_KEY_ATTR_ENCAP, obj->encap); + if (obj->_present.priority) + ynl_attr_put_u32(nlh, OVS_KEY_ATTR_PRIORITY, obj->priority); + if (obj->_present.in_port) + ynl_attr_put_u32(nlh, OVS_KEY_ATTR_IN_PORT, obj->in_port); + if (obj->_present.ethernet_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_ETHERNET, obj->ethernet, obj->_present.ethernet_len); + if (obj->_present.vlan) + ynl_attr_put_u16(nlh, OVS_KEY_ATTR_VLAN, obj->vlan); + if (obj->_present.ethertype) + ynl_attr_put_u16(nlh, OVS_KEY_ATTR_ETHERTYPE, obj->ethertype); + if (obj->_present.ipv4_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_IPV4, obj->ipv4, obj->_present.ipv4_len); + if (obj->_present.ipv6_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_IPV6, obj->ipv6, obj->_present.ipv6_len); + if (obj->_present.tcp_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_TCP, obj->tcp, obj->_present.tcp_len); + if (obj->_present.udp_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_UDP, obj->udp, obj->_present.udp_len); + if (obj->_present.icmp_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_ICMP, obj->icmp, obj->_present.icmp_len); + if (obj->_present.icmpv6_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_ICMPV6, obj->icmpv6, obj->_present.icmpv6_len); + if (obj->_present.arp_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_ARP, obj->arp, obj->_present.arp_len); + if (obj->_present.nd_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_ND, obj->nd, obj->_present.nd_len); + if (obj->_present.skb_mark) + ynl_attr_put_u32(nlh, OVS_KEY_ATTR_SKB_MARK, obj->skb_mark); + if (obj->_present.tunnel) + ovs_flow_tunnel_key_attrs_put(nlh, OVS_KEY_ATTR_TUNNEL, &obj->tunnel); + if (obj->_present.sctp_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_SCTP, obj->sctp, obj->_present.sctp_len); + if (obj->_present.tcp_flags) + ynl_attr_put_u16(nlh, OVS_KEY_ATTR_TCP_FLAGS, obj->tcp_flags); + if (obj->_present.dp_hash) + ynl_attr_put_u32(nlh, OVS_KEY_ATTR_DP_HASH, obj->dp_hash); + if (obj->_present.recirc_id) + ynl_attr_put_u32(nlh, OVS_KEY_ATTR_RECIRC_ID, obj->recirc_id); + if (obj->_present.mpls_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_MPLS, obj->mpls, obj->_present.mpls_len); + if (obj->_present.ct_state) + ynl_attr_put_u32(nlh, OVS_KEY_ATTR_CT_STATE, obj->ct_state); + if (obj->_present.ct_zone) + ynl_attr_put_u16(nlh, OVS_KEY_ATTR_CT_ZONE, obj->ct_zone); + if (obj->_present.ct_mark) + ynl_attr_put_u32(nlh, OVS_KEY_ATTR_CT_MARK, obj->ct_mark); + if (obj->_present.ct_labels_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_CT_LABELS, obj->ct_labels, obj->_present.ct_labels_len); + if (obj->_present.ct_orig_tuple_ipv4_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4, obj->ct_orig_tuple_ipv4, obj->_present.ct_orig_tuple_ipv4_len); + if (obj->_present.ct_orig_tuple_ipv6_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6, obj->ct_orig_tuple_ipv6, obj->_present.ct_orig_tuple_ipv6_len); + if (obj->_present.nsh) + ovs_flow_ovs_nsh_key_attrs_put(nlh, OVS_KEY_ATTR_NSH, &obj->nsh); + if (obj->_present.packet_type) + ynl_attr_put_u32(nlh, OVS_KEY_ATTR_PACKET_TYPE, obj->packet_type); + if (obj->_present.nd_extensions_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_ND_EXTENSIONS, obj->nd_extensions, obj->_present.nd_extensions_len); + if (obj->_present.tunnel_info_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_TUNNEL_INFO, obj->tunnel_info, obj->_present.tunnel_info_len); + if (obj->_present.ipv6_exthdrs_len) + ynl_attr_put(nlh, OVS_KEY_ATTR_IPV6_EXTHDRS, obj->ipv6_exthdrs, obj->_present.ipv6_exthdrs_len); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_key_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_key_attrs *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_KEY_ATTR_ENCAP) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.encap = 1; + + parg.rsp_policy = &ovs_flow_key_attrs_nest; + parg.data = &dst->encap; + if (ovs_flow_key_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_KEY_ATTR_PRIORITY) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.priority = 1; + dst->priority = ynl_attr_get_u32(attr); + } else if (type == OVS_KEY_ATTR_IN_PORT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.in_port = 1; + dst->in_port = ynl_attr_get_u32(attr); + } else if (type == OVS_KEY_ATTR_ETHERNET) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ethernet_len = len; + dst->ethernet = malloc(len); + memcpy(dst->ethernet, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_VLAN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.vlan = 1; + dst->vlan = ynl_attr_get_u16(attr); + } else if (type == OVS_KEY_ATTR_ETHERTYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ethertype = 1; + dst->ethertype = ynl_attr_get_u16(attr); + } else if (type == OVS_KEY_ATTR_IPV4) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ipv4_len = len; + dst->ipv4 = malloc(len); + memcpy(dst->ipv4, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_IPV6) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ipv6_len = len; + dst->ipv6 = malloc(len); + memcpy(dst->ipv6, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_TCP) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.tcp_len = len; + dst->tcp = malloc(len); + memcpy(dst->tcp, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_UDP) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.udp_len = len; + dst->udp = malloc(len); + memcpy(dst->udp, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_ICMP) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.icmp_len = len; + dst->icmp = malloc(len); + memcpy(dst->icmp, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_ICMPV6) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.icmpv6_len = len; + dst->icmpv6 = malloc(len); + memcpy(dst->icmpv6, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_ARP) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.arp_len = len; + dst->arp = malloc(len); + memcpy(dst->arp, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_ND) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.nd_len = len; + dst->nd = malloc(len); + memcpy(dst->nd, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_SKB_MARK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.skb_mark = 1; + dst->skb_mark = ynl_attr_get_u32(attr); + } else if (type == OVS_KEY_ATTR_TUNNEL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tunnel = 1; + + parg.rsp_policy = &ovs_flow_tunnel_key_attrs_nest; + parg.data = &dst->tunnel; + if (ovs_flow_tunnel_key_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_KEY_ATTR_SCTP) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.sctp_len = len; + dst->sctp = malloc(len); + memcpy(dst->sctp, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_TCP_FLAGS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.tcp_flags = 1; + dst->tcp_flags = ynl_attr_get_u16(attr); + } else if (type == OVS_KEY_ATTR_DP_HASH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dp_hash = 1; + dst->dp_hash = ynl_attr_get_u32(attr); + } else if (type == OVS_KEY_ATTR_RECIRC_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.recirc_id = 1; + dst->recirc_id = ynl_attr_get_u32(attr); + } else if (type == OVS_KEY_ATTR_MPLS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.mpls_len = len; + dst->mpls = malloc(len); + memcpy(dst->mpls, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_CT_STATE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ct_state = 1; + dst->ct_state = ynl_attr_get_u32(attr); + } else if (type == OVS_KEY_ATTR_CT_ZONE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ct_zone = 1; + dst->ct_zone = ynl_attr_get_u16(attr); + } else if (type == OVS_KEY_ATTR_CT_MARK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ct_mark = 1; + dst->ct_mark = ynl_attr_get_u32(attr); + } else if (type == OVS_KEY_ATTR_CT_LABELS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ct_labels_len = len; + dst->ct_labels = malloc(len); + memcpy(dst->ct_labels, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ct_orig_tuple_ipv4_len = len; + dst->ct_orig_tuple_ipv4 = malloc(len); + memcpy(dst->ct_orig_tuple_ipv4, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ct_orig_tuple_ipv6_len = len; + dst->ct_orig_tuple_ipv6 = malloc(len); + memcpy(dst->ct_orig_tuple_ipv6, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_NSH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.nsh = 1; + + parg.rsp_policy = &ovs_flow_ovs_nsh_key_attrs_nest; + parg.data = &dst->nsh; + if (ovs_flow_ovs_nsh_key_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_KEY_ATTR_PACKET_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.packet_type = 1; + dst->packet_type = ynl_attr_get_u32(attr); + } else if (type == OVS_KEY_ATTR_ND_EXTENSIONS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.nd_extensions_len = len; + dst->nd_extensions = malloc(len); + memcpy(dst->nd_extensions, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_TUNNEL_INFO) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.tunnel_info_len = len; + dst->tunnel_info = malloc(len); + memcpy(dst->tunnel_info, ynl_attr_data(attr), len); + } else if (type == OVS_KEY_ATTR_IPV6_EXTHDRS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ipv6_exthdrs_len = len; + dst->ipv6_exthdrs = malloc(len); + memcpy(dst->ipv6_exthdrs, ynl_attr_data(attr), len); + } + } + + return 0; +} + +void ovs_flow_sample_attrs_free(struct ovs_flow_sample_attrs *obj) +{ + if (obj->actions) + ovs_flow_action_attrs_free(obj->actions); +} + +int ovs_flow_sample_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_sample_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.probability) + ynl_attr_put_u32(nlh, OVS_SAMPLE_ATTR_PROBABILITY, obj->probability); + if (obj->_present.actions) + ovs_flow_action_attrs_put(nlh, OVS_SAMPLE_ATTR_ACTIONS, obj->actions); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_sample_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_sample_attrs *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_SAMPLE_ATTR_PROBABILITY) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.probability = 1; + dst->probability = ynl_attr_get_u32(attr); + } else if (type == OVS_SAMPLE_ATTR_ACTIONS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.actions = 1; + + parg.rsp_policy = &ovs_flow_action_attrs_nest; + parg.data = &dst->actions; + if (ovs_flow_action_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return 0; +} + +void ovs_flow_action_attrs_free(struct ovs_flow_action_attrs *obj) +{ + ovs_flow_userspace_attrs_free(&obj->userspace); + if (obj->set) + ovs_flow_key_attrs_free(obj->set); + free(obj->push_vlan); + ovs_flow_sample_attrs_free(&obj->sample); + free(obj->hash); + free(obj->push_mpls); + if (obj->set_masked) + ovs_flow_key_attrs_free(obj->set_masked); + ovs_flow_ct_attrs_free(&obj->ct); + free(obj->push_eth); + ovs_flow_ovs_nsh_key_attrs_free(&obj->push_nsh); + if (obj->clone) + ovs_flow_action_attrs_free(obj->clone); + ovs_flow_check_pkt_len_attrs_free(&obj->check_pkt_len); + free(obj->add_mpls); + ovs_flow_dec_ttl_attrs_free(&obj->dec_ttl); +} + +int ovs_flow_action_attrs_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_flow_action_attrs *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.output) + ynl_attr_put_u32(nlh, OVS_ACTION_ATTR_OUTPUT, obj->output); + if (obj->_present.userspace) + ovs_flow_userspace_attrs_put(nlh, OVS_ACTION_ATTR_USERSPACE, &obj->userspace); + if (obj->_present.set) + ovs_flow_key_attrs_put(nlh, OVS_ACTION_ATTR_SET, obj->set); + if (obj->_present.push_vlan_len) + ynl_attr_put(nlh, OVS_ACTION_ATTR_PUSH_VLAN, obj->push_vlan, obj->_present.push_vlan_len); + if (obj->_present.pop_vlan) + ynl_attr_put(nlh, OVS_ACTION_ATTR_POP_VLAN, NULL, 0); + if (obj->_present.sample) + ovs_flow_sample_attrs_put(nlh, OVS_ACTION_ATTR_SAMPLE, &obj->sample); + if (obj->_present.recirc) + ynl_attr_put_u32(nlh, OVS_ACTION_ATTR_RECIRC, obj->recirc); + if (obj->_present.hash_len) + ynl_attr_put(nlh, OVS_ACTION_ATTR_HASH, obj->hash, obj->_present.hash_len); + if (obj->_present.push_mpls_len) + ynl_attr_put(nlh, OVS_ACTION_ATTR_PUSH_MPLS, obj->push_mpls, obj->_present.push_mpls_len); + if (obj->_present.pop_mpls) + ynl_attr_put_u16(nlh, OVS_ACTION_ATTR_POP_MPLS, obj->pop_mpls); + if (obj->_present.set_masked) + ovs_flow_key_attrs_put(nlh, OVS_ACTION_ATTR_SET_MASKED, obj->set_masked); + if (obj->_present.ct) + ovs_flow_ct_attrs_put(nlh, OVS_ACTION_ATTR_CT, &obj->ct); + if (obj->_present.trunc) + ynl_attr_put_u32(nlh, OVS_ACTION_ATTR_TRUNC, obj->trunc); + if (obj->_present.push_eth_len) + ynl_attr_put(nlh, OVS_ACTION_ATTR_PUSH_ETH, obj->push_eth, obj->_present.push_eth_len); + if (obj->_present.pop_eth) + ynl_attr_put(nlh, OVS_ACTION_ATTR_POP_ETH, NULL, 0); + if (obj->_present.ct_clear) + ynl_attr_put(nlh, OVS_ACTION_ATTR_CT_CLEAR, NULL, 0); + if (obj->_present.push_nsh) + ovs_flow_ovs_nsh_key_attrs_put(nlh, OVS_ACTION_ATTR_PUSH_NSH, &obj->push_nsh); + if (obj->_present.pop_nsh) + ynl_attr_put(nlh, OVS_ACTION_ATTR_POP_NSH, NULL, 0); + if (obj->_present.meter) + ynl_attr_put_u32(nlh, OVS_ACTION_ATTR_METER, obj->meter); + if (obj->_present.clone) + ovs_flow_action_attrs_put(nlh, OVS_ACTION_ATTR_CLONE, obj->clone); + if (obj->_present.check_pkt_len) + ovs_flow_check_pkt_len_attrs_put(nlh, OVS_ACTION_ATTR_CHECK_PKT_LEN, &obj->check_pkt_len); + if (obj->_present.add_mpls_len) + ynl_attr_put(nlh, OVS_ACTION_ATTR_ADD_MPLS, obj->add_mpls, obj->_present.add_mpls_len); + if (obj->_present.dec_ttl) + ovs_flow_dec_ttl_attrs_put(nlh, OVS_ACTION_ATTR_DEC_TTL, &obj->dec_ttl); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int ovs_flow_action_attrs_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_flow_action_attrs *dst = yarg->data; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + parg.ys = yarg->ys; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_ACTION_ATTR_OUTPUT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.output = 1; + dst->output = ynl_attr_get_u32(attr); + } else if (type == OVS_ACTION_ATTR_USERSPACE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.userspace = 1; + + parg.rsp_policy = &ovs_flow_userspace_attrs_nest; + parg.data = &dst->userspace; + if (ovs_flow_userspace_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_ACTION_ATTR_SET) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.set = 1; + + parg.rsp_policy = &ovs_flow_key_attrs_nest; + parg.data = &dst->set; + if (ovs_flow_key_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_ACTION_ATTR_PUSH_VLAN) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.push_vlan_len = len; + dst->push_vlan = malloc(len); + memcpy(dst->push_vlan, ynl_attr_data(attr), len); + } else if (type == OVS_ACTION_ATTR_POP_VLAN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pop_vlan = 1; + } else if (type == OVS_ACTION_ATTR_SAMPLE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.sample = 1; + + parg.rsp_policy = &ovs_flow_sample_attrs_nest; + parg.data = &dst->sample; + if (ovs_flow_sample_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_ACTION_ATTR_RECIRC) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.recirc = 1; + dst->recirc = ynl_attr_get_u32(attr); + } else if (type == OVS_ACTION_ATTR_HASH) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.hash_len = len; + dst->hash = malloc(len); + memcpy(dst->hash, ynl_attr_data(attr), len); + } else if (type == OVS_ACTION_ATTR_PUSH_MPLS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.push_mpls_len = len; + dst->push_mpls = malloc(len); + memcpy(dst->push_mpls, ynl_attr_data(attr), len); + } else if (type == OVS_ACTION_ATTR_POP_MPLS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pop_mpls = 1; + dst->pop_mpls = ynl_attr_get_u16(attr); + } else if (type == OVS_ACTION_ATTR_SET_MASKED) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.set_masked = 1; + + parg.rsp_policy = &ovs_flow_key_attrs_nest; + parg.data = &dst->set_masked; + if (ovs_flow_key_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_ACTION_ATTR_CT) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ct = 1; + + parg.rsp_policy = &ovs_flow_ct_attrs_nest; + parg.data = &dst->ct; + if (ovs_flow_ct_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_ACTION_ATTR_TRUNC) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.trunc = 1; + dst->trunc = ynl_attr_get_u32(attr); + } else if (type == OVS_ACTION_ATTR_PUSH_ETH) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.push_eth_len = len; + dst->push_eth = malloc(len); + memcpy(dst->push_eth, ynl_attr_data(attr), len); + } else if (type == OVS_ACTION_ATTR_POP_ETH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pop_eth = 1; + } else if (type == OVS_ACTION_ATTR_CT_CLEAR) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ct_clear = 1; + } else if (type == OVS_ACTION_ATTR_PUSH_NSH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.push_nsh = 1; + + parg.rsp_policy = &ovs_flow_ovs_nsh_key_attrs_nest; + parg.data = &dst->push_nsh; + if (ovs_flow_ovs_nsh_key_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_ACTION_ATTR_POP_NSH) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.pop_nsh = 1; + } else if (type == OVS_ACTION_ATTR_METER) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.meter = 1; + dst->meter = ynl_attr_get_u32(attr); + } else if (type == OVS_ACTION_ATTR_CLONE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.clone = 1; + + parg.rsp_policy = &ovs_flow_action_attrs_nest; + parg.data = &dst->clone; + if (ovs_flow_action_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_ACTION_ATTR_CHECK_PKT_LEN) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.check_pkt_len = 1; + + parg.rsp_policy = &ovs_flow_check_pkt_len_attrs_nest; + parg.data = &dst->check_pkt_len; + if (ovs_flow_check_pkt_len_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_ACTION_ATTR_ADD_MPLS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.add_mpls_len = len; + dst->add_mpls = malloc(len); + memcpy(dst->add_mpls, ynl_attr_data(attr), len); + } else if (type == OVS_ACTION_ATTR_DEC_TTL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dec_ttl = 1; + + parg.rsp_policy = &ovs_flow_dec_ttl_attrs_nest; + parg.data = &dst->dec_ttl; + if (ovs_flow_dec_ttl_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return 0; +} + +/* ============== OVS_FLOW_CMD_GET ============== */ +/* OVS_FLOW_CMD_GET - do */ +void ovs_flow_get_req_free(struct ovs_flow_get_req *req) +{ + ovs_flow_key_attrs_free(&req->key); + free(req->ufid); + free(req); +} + +void ovs_flow_get_rsp_free(struct ovs_flow_get_rsp *rsp) +{ + ovs_flow_key_attrs_free(&rsp->key); + free(rsp->ufid); + ovs_flow_key_attrs_free(&rsp->mask); + free(rsp->stats); + ovs_flow_action_attrs_free(&rsp->actions); + free(rsp); +} + +int ovs_flow_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ovs_flow_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + void *hdr; + + dst = yarg->data; + parg.ys = yarg->ys; + + hdr = ynl_nlmsg_data_offset(nlh, sizeof(struct genlmsghdr)); + memcpy(&dst->_hdr, hdr, sizeof(struct ovs_header)); + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_FLOW_ATTR_KEY) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.key = 1; + + parg.rsp_policy = &ovs_flow_key_attrs_nest; + parg.data = &dst->key; + if (ovs_flow_key_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_FLOW_ATTR_UFID) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.ufid_len = len; + dst->ufid = malloc(len); + memcpy(dst->ufid, ynl_attr_data(attr), len); + } else if (type == OVS_FLOW_ATTR_MASK) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.mask = 1; + + parg.rsp_policy = &ovs_flow_key_attrs_nest; + parg.data = &dst->mask; + if (ovs_flow_key_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } else if (type == OVS_FLOW_ATTR_STATS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.stats_len = len; + dst->stats = malloc(len); + memcpy(dst->stats, ynl_attr_data(attr), len); + } else if (type == OVS_FLOW_ATTR_ACTIONS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.actions = 1; + + parg.rsp_policy = &ovs_flow_action_attrs_nest; + parg.data = &dst->actions; + if (ovs_flow_action_attrs_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ovs_flow_get_rsp * +ovs_flow_get(struct ynl_sock *ys, struct ovs_flow_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ovs_flow_get_rsp *rsp; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, OVS_FLOW_CMD_GET, 1); + ys->req_policy = &ovs_flow_flow_attrs_nest; + yrs.yarg.rsp_policy = &ovs_flow_flow_attrs_nest; + + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + if (req->_present.key) + ovs_flow_key_attrs_put(nlh, OVS_FLOW_ATTR_KEY, &req->key); + if (req->_present.ufid_len) + ynl_attr_put(nlh, OVS_FLOW_ATTR_UFID, req->ufid, req->_present.ufid_len); + if (req->_present.ufid_flags) + ynl_attr_put_u32(nlh, OVS_FLOW_ATTR_UFID_FLAGS, req->ufid_flags); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ovs_flow_get_rsp_parse; + yrs.rsp_cmd = OVS_FLOW_CMD_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ovs_flow_get_rsp_free(rsp); + return NULL; +} + +/* OVS_FLOW_CMD_GET - dump */ +void ovs_flow_get_req_dump_free(struct ovs_flow_get_req_dump *req) +{ + ovs_flow_key_attrs_free(&req->key); + free(req->ufid); + free(req); +} + +void ovs_flow_get_list_free(struct ovs_flow_get_list *rsp) +{ + struct ovs_flow_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + ovs_flow_key_attrs_free(&rsp->obj.key); + free(rsp->obj.ufid); + ovs_flow_key_attrs_free(&rsp->obj.mask); + free(rsp->obj.stats); + ovs_flow_action_attrs_free(&rsp->obj.actions); + free(rsp); + } +} + +struct ovs_flow_get_list * +ovs_flow_get_dump(struct ynl_sock *ys, struct ovs_flow_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &ovs_flow_flow_attrs_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ovs_flow_get_list); + yds.cb = ovs_flow_get_rsp_parse; + yds.rsp_cmd = OVS_FLOW_CMD_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, OVS_FLOW_CMD_GET, 1); + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + ys->req_policy = &ovs_flow_flow_attrs_nest; + + if (req->_present.key) + ovs_flow_key_attrs_put(nlh, OVS_FLOW_ATTR_KEY, &req->key); + if (req->_present.ufid_len) + ynl_attr_put(nlh, OVS_FLOW_ATTR_UFID, req->ufid, req->_present.ufid_len); + if (req->_present.ufid_flags) + ynl_attr_put_u32(nlh, OVS_FLOW_ATTR_UFID_FLAGS, req->ufid_flags); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ovs_flow_get_list_free(yds.first); + return NULL; +} + +/* ============== OVS_FLOW_CMD_NEW ============== */ +/* OVS_FLOW_CMD_NEW - do */ +void ovs_flow_new_req_free(struct ovs_flow_new_req *req) +{ + ovs_flow_key_attrs_free(&req->key); + free(req->ufid); + ovs_flow_key_attrs_free(&req->mask); + ovs_flow_action_attrs_free(&req->actions); + free(req); +} + +int ovs_flow_new(struct ynl_sock *ys, struct ovs_flow_new_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, OVS_FLOW_CMD_NEW, 1); + ys->req_policy = &ovs_flow_flow_attrs_nest; + + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + if (req->_present.key) + ovs_flow_key_attrs_put(nlh, OVS_FLOW_ATTR_KEY, &req->key); + if (req->_present.ufid_len) + ynl_attr_put(nlh, OVS_FLOW_ATTR_UFID, req->ufid, req->_present.ufid_len); + if (req->_present.mask) + ovs_flow_key_attrs_put(nlh, OVS_FLOW_ATTR_MASK, &req->mask); + if (req->_present.actions) + ovs_flow_action_attrs_put(nlh, OVS_FLOW_ATTR_ACTIONS, &req->actions); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +const struct ynl_family ynl_ovs_flow_family = { + .name = "ovs_flow", + .hdr_len = sizeof(struct genlmsghdr) + sizeof(struct ovs_header), +}; diff --git a/generated/ovs_flow-user.h b/generated/ovs_flow-user.h new file mode 100644 index 0000000..c5f5c08 --- /dev/null +++ b/generated/ovs_flow-user.h @@ -0,0 +1,2449 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/ovs_flow.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_OVS_FLOW_GEN_H +#define _LINUX_OVS_FLOW_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_ovs_flow_family; + +/* Enums */ +const char *ovs_flow_op_str(int op); +const char *ovs_flow_ovs_frag_type_str(enum ovs_frag_type value); +const char *ovs_flow_ovs_ufid_flags_str(int value); +const char *ovs_flow_ovs_hash_alg_str(enum ovs_hash_alg value); +const char *ovs_flow_ct_state_flags_str(int value); + +/* Common nested types */ +struct ovs_flow_ovs_nsh_key_attrs { + struct { + __u32 base_len; + __u32 md1_len; + __u32 md2_len; + } _present; + + void *base; + void *md1; + void *md2; +}; + +struct ovs_flow_userspace_attrs { + struct { + __u32 pid:1; + __u32 userdata_len; + __u32 egress_tun_port:1; + __u32 actions:1; + } _present; + + __u32 pid; + void *userdata; + __u32 egress_tun_port; +}; + +struct ovs_flow_vxlan_ext_attrs { + struct { + __u32 gbp:1; + } _present; + + __u32 gbp; +}; + +struct ovs_flow_nat_attrs { + struct { + __u32 src:1; + __u32 dst:1; + __u32 ip_min_len; + __u32 ip_max_len; + __u32 proto_min:1; + __u32 proto_max:1; + __u32 persistent:1; + __u32 proto_hash:1; + __u32 proto_random:1; + } _present; + + void *ip_min; + void *ip_max; + __u16 proto_min; + __u16 proto_max; +}; + +struct ovs_flow_tunnel_key_attrs { + struct { + __u32 id:1; + __u32 ipv4_src:1; + __u32 ipv4_dst:1; + __u32 tos:1; + __u32 ttl:1; + __u32 dont_fragment:1; + __u32 csum:1; + __u32 oam:1; + __u32 geneve_opts_len; + __u32 tp_src:1; + __u32 tp_dst:1; + __u32 vxlan_opts:1; + __u32 ipv6_src_len; + __u32 ipv6_dst_len; + __u32 pad_len; + __u32 erspan_opts_len; + __u32 ipv4_info_bridge:1; + } _present; + + __u64 id /* big-endian */; + __u32 ipv4_src /* big-endian */; + __u32 ipv4_dst /* big-endian */; + __u8 tos; + __u8 ttl; + void *geneve_opts; + __u16 tp_src /* big-endian */; + __u16 tp_dst /* big-endian */; + struct ovs_flow_vxlan_ext_attrs vxlan_opts; + void *ipv6_src; + void *ipv6_dst; + void *pad; + void *erspan_opts; +}; + +struct ovs_flow_ct_attrs { + struct { + __u32 commit:1; + __u32 zone:1; + __u32 mark_len; + __u32 labels_len; + __u32 helper_len; + __u32 nat:1; + __u32 force_commit:1; + __u32 eventmask:1; + __u32 timeout_len; + } _present; + + __u16 zone; + void *mark; + void *labels; + char *helper; + struct ovs_flow_nat_attrs nat; + __u32 eventmask; + char *timeout; +}; + +struct ovs_flow_check_pkt_len_attrs { + struct { + __u32 pkt_len:1; + __u32 actions_if_greater:1; + __u32 actions_if_less_equal:1; + } _present; + + __u16 pkt_len; + struct ovs_flow_action_attrs *actions_if_greater; + struct ovs_flow_action_attrs *actions_if_less_equal; +}; + +struct ovs_flow_dec_ttl_attrs { + struct { + __u32 action:1; + } _present; + + struct ovs_flow_action_attrs *action; +}; + +struct ovs_flow_key_attrs { + struct { + __u32 encap:1; + __u32 priority:1; + __u32 in_port:1; + __u32 ethernet_len; + __u32 vlan:1; + __u32 ethertype:1; + __u32 ipv4_len; + __u32 ipv6_len; + __u32 tcp_len; + __u32 udp_len; + __u32 icmp_len; + __u32 icmpv6_len; + __u32 arp_len; + __u32 nd_len; + __u32 skb_mark:1; + __u32 tunnel:1; + __u32 sctp_len; + __u32 tcp_flags:1; + __u32 dp_hash:1; + __u32 recirc_id:1; + __u32 mpls_len; + __u32 ct_state:1; + __u32 ct_zone:1; + __u32 ct_mark:1; + __u32 ct_labels_len; + __u32 ct_orig_tuple_ipv4_len; + __u32 ct_orig_tuple_ipv6_len; + __u32 nsh:1; + __u32 packet_type:1; + __u32 nd_extensions_len; + __u32 tunnel_info_len; + __u32 ipv6_exthdrs_len; + } _present; + + struct ovs_flow_key_attrs *encap; + __u32 priority; + __u32 in_port; + void *ethernet; + __u16 vlan /* big-endian */; + __u16 ethertype /* big-endian */; + void *ipv4; + void *ipv6; + void *tcp; + void *udp; + void *icmp; + void *icmpv6; + void *arp; + void *nd; + __u32 skb_mark; + struct ovs_flow_tunnel_key_attrs tunnel; + void *sctp; + __u16 tcp_flags /* big-endian */; + __u32 dp_hash; + __u32 recirc_id; + void *mpls; + __u32 ct_state; + __u16 ct_zone; + __u32 ct_mark; + void *ct_labels; + void *ct_orig_tuple_ipv4; + void *ct_orig_tuple_ipv6; + struct ovs_flow_ovs_nsh_key_attrs nsh; + __u32 packet_type /* big-endian */; + void *nd_extensions; + void *tunnel_info; + void *ipv6_exthdrs; +}; + +struct ovs_flow_sample_attrs { + struct { + __u32 probability:1; + __u32 actions:1; + } _present; + + __u32 probability; + struct ovs_flow_action_attrs *actions; +}; + +struct ovs_flow_action_attrs { + struct { + __u32 output:1; + __u32 userspace:1; + __u32 set:1; + __u32 push_vlan_len; + __u32 pop_vlan:1; + __u32 sample:1; + __u32 recirc:1; + __u32 hash_len; + __u32 push_mpls_len; + __u32 pop_mpls:1; + __u32 set_masked:1; + __u32 ct:1; + __u32 trunc:1; + __u32 push_eth_len; + __u32 pop_eth:1; + __u32 ct_clear:1; + __u32 push_nsh:1; + __u32 pop_nsh:1; + __u32 meter:1; + __u32 clone:1; + __u32 check_pkt_len:1; + __u32 add_mpls_len; + __u32 dec_ttl:1; + } _present; + + __u32 output; + struct ovs_flow_userspace_attrs userspace; + struct ovs_flow_key_attrs *set; + void *push_vlan; + struct ovs_flow_sample_attrs sample; + __u32 recirc; + void *hash; + void *push_mpls; + __u16 pop_mpls /* big-endian */; + struct ovs_flow_key_attrs *set_masked; + struct ovs_flow_ct_attrs ct; + __u32 trunc; + void *push_eth; + struct ovs_flow_ovs_nsh_key_attrs push_nsh; + __u32 meter; + struct ovs_flow_action_attrs *clone; + struct ovs_flow_check_pkt_len_attrs check_pkt_len; + void *add_mpls; + struct ovs_flow_dec_ttl_attrs dec_ttl; +}; + +/* ============== OVS_FLOW_CMD_GET ============== */ +/* OVS_FLOW_CMD_GET - do */ +struct ovs_flow_get_req { + struct ovs_header _hdr; + + struct { + __u32 key:1; + __u32 ufid_len; + __u32 ufid_flags:1; + } _present; + + struct ovs_flow_key_attrs key; + void *ufid; + __u32 ufid_flags; +}; + +static inline struct ovs_flow_get_req *ovs_flow_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ovs_flow_get_req)); +} +void ovs_flow_get_req_free(struct ovs_flow_get_req *req); + +static inline void +ovs_flow_get_req_set_key_priority(struct ovs_flow_get_req *req, __u32 priority) +{ + req->_present.key = 1; + req->key._present.priority = 1; + req->key.priority = priority; +} +static inline void +ovs_flow_get_req_set_key_in_port(struct ovs_flow_get_req *req, __u32 in_port) +{ + req->_present.key = 1; + req->key._present.in_port = 1; + req->key.in_port = in_port; +} +static inline void +ovs_flow_get_req_set_key_ethernet(struct ovs_flow_get_req *req, + const void *ethernet, size_t len) +{ + free(req->key.ethernet); + req->key._present.ethernet_len = len; + req->key.ethernet = malloc(req->key._present.ethernet_len); + memcpy(req->key.ethernet, ethernet, req->key._present.ethernet_len); +} +static inline void +ovs_flow_get_req_set_key_vlan(struct ovs_flow_get_req *req, + __u16 vlan /* big-endian */) +{ + req->_present.key = 1; + req->key._present.vlan = 1; + req->key.vlan = vlan; +} +static inline void +ovs_flow_get_req_set_key_ethertype(struct ovs_flow_get_req *req, + __u16 ethertype /* big-endian */) +{ + req->_present.key = 1; + req->key._present.ethertype = 1; + req->key.ethertype = ethertype; +} +static inline void +ovs_flow_get_req_set_key_ipv4(struct ovs_flow_get_req *req, const void *ipv4, + size_t len) +{ + free(req->key.ipv4); + req->key._present.ipv4_len = len; + req->key.ipv4 = malloc(req->key._present.ipv4_len); + memcpy(req->key.ipv4, ipv4, req->key._present.ipv4_len); +} +static inline void +ovs_flow_get_req_set_key_ipv6(struct ovs_flow_get_req *req, const void *ipv6, + size_t len) +{ + free(req->key.ipv6); + req->key._present.ipv6_len = len; + req->key.ipv6 = malloc(req->key._present.ipv6_len); + memcpy(req->key.ipv6, ipv6, req->key._present.ipv6_len); +} +static inline void +ovs_flow_get_req_set_key_tcp(struct ovs_flow_get_req *req, const void *tcp, + size_t len) +{ + free(req->key.tcp); + req->key._present.tcp_len = len; + req->key.tcp = malloc(req->key._present.tcp_len); + memcpy(req->key.tcp, tcp, req->key._present.tcp_len); +} +static inline void +ovs_flow_get_req_set_key_udp(struct ovs_flow_get_req *req, const void *udp, + size_t len) +{ + free(req->key.udp); + req->key._present.udp_len = len; + req->key.udp = malloc(req->key._present.udp_len); + memcpy(req->key.udp, udp, req->key._present.udp_len); +} +static inline void +ovs_flow_get_req_set_key_icmp(struct ovs_flow_get_req *req, const void *icmp, + size_t len) +{ + free(req->key.icmp); + req->key._present.icmp_len = len; + req->key.icmp = malloc(req->key._present.icmp_len); + memcpy(req->key.icmp, icmp, req->key._present.icmp_len); +} +static inline void +ovs_flow_get_req_set_key_icmpv6(struct ovs_flow_get_req *req, + const void *icmpv6, size_t len) +{ + free(req->key.icmpv6); + req->key._present.icmpv6_len = len; + req->key.icmpv6 = malloc(req->key._present.icmpv6_len); + memcpy(req->key.icmpv6, icmpv6, req->key._present.icmpv6_len); +} +static inline void +ovs_flow_get_req_set_key_arp(struct ovs_flow_get_req *req, const void *arp, + size_t len) +{ + free(req->key.arp); + req->key._present.arp_len = len; + req->key.arp = malloc(req->key._present.arp_len); + memcpy(req->key.arp, arp, req->key._present.arp_len); +} +static inline void +ovs_flow_get_req_set_key_nd(struct ovs_flow_get_req *req, const void *nd, + size_t len) +{ + free(req->key.nd); + req->key._present.nd_len = len; + req->key.nd = malloc(req->key._present.nd_len); + memcpy(req->key.nd, nd, req->key._present.nd_len); +} +static inline void +ovs_flow_get_req_set_key_skb_mark(struct ovs_flow_get_req *req, __u32 skb_mark) +{ + req->_present.key = 1; + req->key._present.skb_mark = 1; + req->key.skb_mark = skb_mark; +} +static inline void +ovs_flow_get_req_set_key_tunnel_id(struct ovs_flow_get_req *req, + __u64 id /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.id = 1; + req->key.tunnel.id = id; +} +static inline void +ovs_flow_get_req_set_key_tunnel_ipv4_src(struct ovs_flow_get_req *req, + __u32 ipv4_src /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ipv4_src = 1; + req->key.tunnel.ipv4_src = ipv4_src; +} +static inline void +ovs_flow_get_req_set_key_tunnel_ipv4_dst(struct ovs_flow_get_req *req, + __u32 ipv4_dst /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ipv4_dst = 1; + req->key.tunnel.ipv4_dst = ipv4_dst; +} +static inline void +ovs_flow_get_req_set_key_tunnel_tos(struct ovs_flow_get_req *req, __u8 tos) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.tos = 1; + req->key.tunnel.tos = tos; +} +static inline void +ovs_flow_get_req_set_key_tunnel_ttl(struct ovs_flow_get_req *req, __u8 ttl) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ttl = 1; + req->key.tunnel.ttl = ttl; +} +static inline void +ovs_flow_get_req_set_key_tunnel_dont_fragment(struct ovs_flow_get_req *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.dont_fragment = 1; +} +static inline void +ovs_flow_get_req_set_key_tunnel_csum(struct ovs_flow_get_req *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.csum = 1; +} +static inline void +ovs_flow_get_req_set_key_tunnel_oam(struct ovs_flow_get_req *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.oam = 1; +} +static inline void +ovs_flow_get_req_set_key_tunnel_geneve_opts(struct ovs_flow_get_req *req, + const void *geneve_opts, + size_t len) +{ + free(req->key.tunnel.geneve_opts); + req->key.tunnel._present.geneve_opts_len = len; + req->key.tunnel.geneve_opts = malloc(req->key.tunnel._present.geneve_opts_len); + memcpy(req->key.tunnel.geneve_opts, geneve_opts, req->key.tunnel._present.geneve_opts_len); +} +static inline void +ovs_flow_get_req_set_key_tunnel_tp_src(struct ovs_flow_get_req *req, + __u16 tp_src /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.tp_src = 1; + req->key.tunnel.tp_src = tp_src; +} +static inline void +ovs_flow_get_req_set_key_tunnel_tp_dst(struct ovs_flow_get_req *req, + __u16 tp_dst /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.tp_dst = 1; + req->key.tunnel.tp_dst = tp_dst; +} +static inline void +ovs_flow_get_req_set_key_tunnel_vxlan_opts_gbp(struct ovs_flow_get_req *req, + __u32 gbp) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.vxlan_opts = 1; + req->key.tunnel.vxlan_opts._present.gbp = 1; + req->key.tunnel.vxlan_opts.gbp = gbp; +} +static inline void +ovs_flow_get_req_set_key_tunnel_ipv6_src(struct ovs_flow_get_req *req, + const void *ipv6_src, size_t len) +{ + free(req->key.tunnel.ipv6_src); + req->key.tunnel._present.ipv6_src_len = len; + req->key.tunnel.ipv6_src = malloc(req->key.tunnel._present.ipv6_src_len); + memcpy(req->key.tunnel.ipv6_src, ipv6_src, req->key.tunnel._present.ipv6_src_len); +} +static inline void +ovs_flow_get_req_set_key_tunnel_ipv6_dst(struct ovs_flow_get_req *req, + const void *ipv6_dst, size_t len) +{ + free(req->key.tunnel.ipv6_dst); + req->key.tunnel._present.ipv6_dst_len = len; + req->key.tunnel.ipv6_dst = malloc(req->key.tunnel._present.ipv6_dst_len); + memcpy(req->key.tunnel.ipv6_dst, ipv6_dst, req->key.tunnel._present.ipv6_dst_len); +} +static inline void +ovs_flow_get_req_set_key_tunnel_pad(struct ovs_flow_get_req *req, + const void *pad, size_t len) +{ + free(req->key.tunnel.pad); + req->key.tunnel._present.pad_len = len; + req->key.tunnel.pad = malloc(req->key.tunnel._present.pad_len); + memcpy(req->key.tunnel.pad, pad, req->key.tunnel._present.pad_len); +} +static inline void +ovs_flow_get_req_set_key_tunnel_erspan_opts(struct ovs_flow_get_req *req, + const void *erspan_opts, + size_t len) +{ + free(req->key.tunnel.erspan_opts); + req->key.tunnel._present.erspan_opts_len = len; + req->key.tunnel.erspan_opts = malloc(req->key.tunnel._present.erspan_opts_len); + memcpy(req->key.tunnel.erspan_opts, erspan_opts, req->key.tunnel._present.erspan_opts_len); +} +static inline void +ovs_flow_get_req_set_key_tunnel_ipv4_info_bridge(struct ovs_flow_get_req *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ipv4_info_bridge = 1; +} +static inline void +ovs_flow_get_req_set_key_sctp(struct ovs_flow_get_req *req, const void *sctp, + size_t len) +{ + free(req->key.sctp); + req->key._present.sctp_len = len; + req->key.sctp = malloc(req->key._present.sctp_len); + memcpy(req->key.sctp, sctp, req->key._present.sctp_len); +} +static inline void +ovs_flow_get_req_set_key_tcp_flags(struct ovs_flow_get_req *req, + __u16 tcp_flags /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tcp_flags = 1; + req->key.tcp_flags = tcp_flags; +} +static inline void +ovs_flow_get_req_set_key_dp_hash(struct ovs_flow_get_req *req, __u32 dp_hash) +{ + req->_present.key = 1; + req->key._present.dp_hash = 1; + req->key.dp_hash = dp_hash; +} +static inline void +ovs_flow_get_req_set_key_recirc_id(struct ovs_flow_get_req *req, + __u32 recirc_id) +{ + req->_present.key = 1; + req->key._present.recirc_id = 1; + req->key.recirc_id = recirc_id; +} +static inline void +ovs_flow_get_req_set_key_mpls(struct ovs_flow_get_req *req, const void *mpls, + size_t len) +{ + free(req->key.mpls); + req->key._present.mpls_len = len; + req->key.mpls = malloc(req->key._present.mpls_len); + memcpy(req->key.mpls, mpls, req->key._present.mpls_len); +} +static inline void +ovs_flow_get_req_set_key_ct_state(struct ovs_flow_get_req *req, __u32 ct_state) +{ + req->_present.key = 1; + req->key._present.ct_state = 1; + req->key.ct_state = ct_state; +} +static inline void +ovs_flow_get_req_set_key_ct_zone(struct ovs_flow_get_req *req, __u16 ct_zone) +{ + req->_present.key = 1; + req->key._present.ct_zone = 1; + req->key.ct_zone = ct_zone; +} +static inline void +ovs_flow_get_req_set_key_ct_mark(struct ovs_flow_get_req *req, __u32 ct_mark) +{ + req->_present.key = 1; + req->key._present.ct_mark = 1; + req->key.ct_mark = ct_mark; +} +static inline void +ovs_flow_get_req_set_key_ct_labels(struct ovs_flow_get_req *req, + const void *ct_labels, size_t len) +{ + free(req->key.ct_labels); + req->key._present.ct_labels_len = len; + req->key.ct_labels = malloc(req->key._present.ct_labels_len); + memcpy(req->key.ct_labels, ct_labels, req->key._present.ct_labels_len); +} +static inline void +ovs_flow_get_req_set_key_ct_orig_tuple_ipv4(struct ovs_flow_get_req *req, + const void *ct_orig_tuple_ipv4, + size_t len) +{ + free(req->key.ct_orig_tuple_ipv4); + req->key._present.ct_orig_tuple_ipv4_len = len; + req->key.ct_orig_tuple_ipv4 = malloc(req->key._present.ct_orig_tuple_ipv4_len); + memcpy(req->key.ct_orig_tuple_ipv4, ct_orig_tuple_ipv4, req->key._present.ct_orig_tuple_ipv4_len); +} +static inline void +ovs_flow_get_req_set_key_ct_orig_tuple_ipv6(struct ovs_flow_get_req *req, + const void *ct_orig_tuple_ipv6, + size_t len) +{ + free(req->key.ct_orig_tuple_ipv6); + req->key._present.ct_orig_tuple_ipv6_len = len; + req->key.ct_orig_tuple_ipv6 = malloc(req->key._present.ct_orig_tuple_ipv6_len); + memcpy(req->key.ct_orig_tuple_ipv6, ct_orig_tuple_ipv6, req->key._present.ct_orig_tuple_ipv6_len); +} +static inline void +ovs_flow_get_req_set_key_nsh_base(struct ovs_flow_get_req *req, + const void *base, size_t len) +{ + free(req->key.nsh.base); + req->key.nsh._present.base_len = len; + req->key.nsh.base = malloc(req->key.nsh._present.base_len); + memcpy(req->key.nsh.base, base, req->key.nsh._present.base_len); +} +static inline void +ovs_flow_get_req_set_key_nsh_md1(struct ovs_flow_get_req *req, const void *md1, + size_t len) +{ + free(req->key.nsh.md1); + req->key.nsh._present.md1_len = len; + req->key.nsh.md1 = malloc(req->key.nsh._present.md1_len); + memcpy(req->key.nsh.md1, md1, req->key.nsh._present.md1_len); +} +static inline void +ovs_flow_get_req_set_key_nsh_md2(struct ovs_flow_get_req *req, const void *md2, + size_t len) +{ + free(req->key.nsh.md2); + req->key.nsh._present.md2_len = len; + req->key.nsh.md2 = malloc(req->key.nsh._present.md2_len); + memcpy(req->key.nsh.md2, md2, req->key.nsh._present.md2_len); +} +static inline void +ovs_flow_get_req_set_key_packet_type(struct ovs_flow_get_req *req, + __u32 packet_type /* big-endian */) +{ + req->_present.key = 1; + req->key._present.packet_type = 1; + req->key.packet_type = packet_type; +} +static inline void +ovs_flow_get_req_set_key_nd_extensions(struct ovs_flow_get_req *req, + const void *nd_extensions, size_t len) +{ + free(req->key.nd_extensions); + req->key._present.nd_extensions_len = len; + req->key.nd_extensions = malloc(req->key._present.nd_extensions_len); + memcpy(req->key.nd_extensions, nd_extensions, req->key._present.nd_extensions_len); +} +static inline void +ovs_flow_get_req_set_key_tunnel_info(struct ovs_flow_get_req *req, + const void *tunnel_info, size_t len) +{ + free(req->key.tunnel_info); + req->key._present.tunnel_info_len = len; + req->key.tunnel_info = malloc(req->key._present.tunnel_info_len); + memcpy(req->key.tunnel_info, tunnel_info, req->key._present.tunnel_info_len); +} +static inline void +ovs_flow_get_req_set_key_ipv6_exthdrs(struct ovs_flow_get_req *req, + const void *ipv6_exthdrs, size_t len) +{ + free(req->key.ipv6_exthdrs); + req->key._present.ipv6_exthdrs_len = len; + req->key.ipv6_exthdrs = malloc(req->key._present.ipv6_exthdrs_len); + memcpy(req->key.ipv6_exthdrs, ipv6_exthdrs, req->key._present.ipv6_exthdrs_len); +} +static inline void +ovs_flow_get_req_set_ufid(struct ovs_flow_get_req *req, const void *ufid, + size_t len) +{ + free(req->ufid); + req->_present.ufid_len = len; + req->ufid = malloc(req->_present.ufid_len); + memcpy(req->ufid, ufid, req->_present.ufid_len); +} +static inline void +ovs_flow_get_req_set_ufid_flags(struct ovs_flow_get_req *req, __u32 ufid_flags) +{ + req->_present.ufid_flags = 1; + req->ufid_flags = ufid_flags; +} + +struct ovs_flow_get_rsp { + struct ovs_header _hdr; + + struct { + __u32 key:1; + __u32 ufid_len; + __u32 mask:1; + __u32 stats_len; + __u32 actions:1; + } _present; + + struct ovs_flow_key_attrs key; + void *ufid; + struct ovs_flow_key_attrs mask; + void *stats; + struct ovs_flow_action_attrs actions; +}; + +void ovs_flow_get_rsp_free(struct ovs_flow_get_rsp *rsp); + +/* + * Get / dump OVS flow configuration and state + */ +struct ovs_flow_get_rsp * +ovs_flow_get(struct ynl_sock *ys, struct ovs_flow_get_req *req); + +/* OVS_FLOW_CMD_GET - dump */ +struct ovs_flow_get_req_dump { + struct ovs_header _hdr; + + struct { + __u32 key:1; + __u32 ufid_len; + __u32 ufid_flags:1; + } _present; + + struct ovs_flow_key_attrs key; + void *ufid; + __u32 ufid_flags; +}; + +static inline struct ovs_flow_get_req_dump *ovs_flow_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ovs_flow_get_req_dump)); +} +void ovs_flow_get_req_dump_free(struct ovs_flow_get_req_dump *req); + +static inline void +ovs_flow_get_req_dump_set_key_priority(struct ovs_flow_get_req_dump *req, + __u32 priority) +{ + req->_present.key = 1; + req->key._present.priority = 1; + req->key.priority = priority; +} +static inline void +ovs_flow_get_req_dump_set_key_in_port(struct ovs_flow_get_req_dump *req, + __u32 in_port) +{ + req->_present.key = 1; + req->key._present.in_port = 1; + req->key.in_port = in_port; +} +static inline void +ovs_flow_get_req_dump_set_key_ethernet(struct ovs_flow_get_req_dump *req, + const void *ethernet, size_t len) +{ + free(req->key.ethernet); + req->key._present.ethernet_len = len; + req->key.ethernet = malloc(req->key._present.ethernet_len); + memcpy(req->key.ethernet, ethernet, req->key._present.ethernet_len); +} +static inline void +ovs_flow_get_req_dump_set_key_vlan(struct ovs_flow_get_req_dump *req, + __u16 vlan /* big-endian */) +{ + req->_present.key = 1; + req->key._present.vlan = 1; + req->key.vlan = vlan; +} +static inline void +ovs_flow_get_req_dump_set_key_ethertype(struct ovs_flow_get_req_dump *req, + __u16 ethertype /* big-endian */) +{ + req->_present.key = 1; + req->key._present.ethertype = 1; + req->key.ethertype = ethertype; +} +static inline void +ovs_flow_get_req_dump_set_key_ipv4(struct ovs_flow_get_req_dump *req, + const void *ipv4, size_t len) +{ + free(req->key.ipv4); + req->key._present.ipv4_len = len; + req->key.ipv4 = malloc(req->key._present.ipv4_len); + memcpy(req->key.ipv4, ipv4, req->key._present.ipv4_len); +} +static inline void +ovs_flow_get_req_dump_set_key_ipv6(struct ovs_flow_get_req_dump *req, + const void *ipv6, size_t len) +{ + free(req->key.ipv6); + req->key._present.ipv6_len = len; + req->key.ipv6 = malloc(req->key._present.ipv6_len); + memcpy(req->key.ipv6, ipv6, req->key._present.ipv6_len); +} +static inline void +ovs_flow_get_req_dump_set_key_tcp(struct ovs_flow_get_req_dump *req, + const void *tcp, size_t len) +{ + free(req->key.tcp); + req->key._present.tcp_len = len; + req->key.tcp = malloc(req->key._present.tcp_len); + memcpy(req->key.tcp, tcp, req->key._present.tcp_len); +} +static inline void +ovs_flow_get_req_dump_set_key_udp(struct ovs_flow_get_req_dump *req, + const void *udp, size_t len) +{ + free(req->key.udp); + req->key._present.udp_len = len; + req->key.udp = malloc(req->key._present.udp_len); + memcpy(req->key.udp, udp, req->key._present.udp_len); +} +static inline void +ovs_flow_get_req_dump_set_key_icmp(struct ovs_flow_get_req_dump *req, + const void *icmp, size_t len) +{ + free(req->key.icmp); + req->key._present.icmp_len = len; + req->key.icmp = malloc(req->key._present.icmp_len); + memcpy(req->key.icmp, icmp, req->key._present.icmp_len); +} +static inline void +ovs_flow_get_req_dump_set_key_icmpv6(struct ovs_flow_get_req_dump *req, + const void *icmpv6, size_t len) +{ + free(req->key.icmpv6); + req->key._present.icmpv6_len = len; + req->key.icmpv6 = malloc(req->key._present.icmpv6_len); + memcpy(req->key.icmpv6, icmpv6, req->key._present.icmpv6_len); +} +static inline void +ovs_flow_get_req_dump_set_key_arp(struct ovs_flow_get_req_dump *req, + const void *arp, size_t len) +{ + free(req->key.arp); + req->key._present.arp_len = len; + req->key.arp = malloc(req->key._present.arp_len); + memcpy(req->key.arp, arp, req->key._present.arp_len); +} +static inline void +ovs_flow_get_req_dump_set_key_nd(struct ovs_flow_get_req_dump *req, + const void *nd, size_t len) +{ + free(req->key.nd); + req->key._present.nd_len = len; + req->key.nd = malloc(req->key._present.nd_len); + memcpy(req->key.nd, nd, req->key._present.nd_len); +} +static inline void +ovs_flow_get_req_dump_set_key_skb_mark(struct ovs_flow_get_req_dump *req, + __u32 skb_mark) +{ + req->_present.key = 1; + req->key._present.skb_mark = 1; + req->key.skb_mark = skb_mark; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_id(struct ovs_flow_get_req_dump *req, + __u64 id /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.id = 1; + req->key.tunnel.id = id; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_ipv4_src(struct ovs_flow_get_req_dump *req, + __u32 ipv4_src /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ipv4_src = 1; + req->key.tunnel.ipv4_src = ipv4_src; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_ipv4_dst(struct ovs_flow_get_req_dump *req, + __u32 ipv4_dst /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ipv4_dst = 1; + req->key.tunnel.ipv4_dst = ipv4_dst; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_tos(struct ovs_flow_get_req_dump *req, + __u8 tos) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.tos = 1; + req->key.tunnel.tos = tos; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_ttl(struct ovs_flow_get_req_dump *req, + __u8 ttl) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ttl = 1; + req->key.tunnel.ttl = ttl; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_dont_fragment(struct ovs_flow_get_req_dump *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.dont_fragment = 1; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_csum(struct ovs_flow_get_req_dump *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.csum = 1; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_oam(struct ovs_flow_get_req_dump *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.oam = 1; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_geneve_opts(struct ovs_flow_get_req_dump *req, + const void *geneve_opts, + size_t len) +{ + free(req->key.tunnel.geneve_opts); + req->key.tunnel._present.geneve_opts_len = len; + req->key.tunnel.geneve_opts = malloc(req->key.tunnel._present.geneve_opts_len); + memcpy(req->key.tunnel.geneve_opts, geneve_opts, req->key.tunnel._present.geneve_opts_len); +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_tp_src(struct ovs_flow_get_req_dump *req, + __u16 tp_src /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.tp_src = 1; + req->key.tunnel.tp_src = tp_src; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_tp_dst(struct ovs_flow_get_req_dump *req, + __u16 tp_dst /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.tp_dst = 1; + req->key.tunnel.tp_dst = tp_dst; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_vxlan_opts_gbp(struct ovs_flow_get_req_dump *req, + __u32 gbp) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.vxlan_opts = 1; + req->key.tunnel.vxlan_opts._present.gbp = 1; + req->key.tunnel.vxlan_opts.gbp = gbp; +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_ipv6_src(struct ovs_flow_get_req_dump *req, + const void *ipv6_src, size_t len) +{ + free(req->key.tunnel.ipv6_src); + req->key.tunnel._present.ipv6_src_len = len; + req->key.tunnel.ipv6_src = malloc(req->key.tunnel._present.ipv6_src_len); + memcpy(req->key.tunnel.ipv6_src, ipv6_src, req->key.tunnel._present.ipv6_src_len); +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_ipv6_dst(struct ovs_flow_get_req_dump *req, + const void *ipv6_dst, size_t len) +{ + free(req->key.tunnel.ipv6_dst); + req->key.tunnel._present.ipv6_dst_len = len; + req->key.tunnel.ipv6_dst = malloc(req->key.tunnel._present.ipv6_dst_len); + memcpy(req->key.tunnel.ipv6_dst, ipv6_dst, req->key.tunnel._present.ipv6_dst_len); +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_pad(struct ovs_flow_get_req_dump *req, + const void *pad, size_t len) +{ + free(req->key.tunnel.pad); + req->key.tunnel._present.pad_len = len; + req->key.tunnel.pad = malloc(req->key.tunnel._present.pad_len); + memcpy(req->key.tunnel.pad, pad, req->key.tunnel._present.pad_len); +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_erspan_opts(struct ovs_flow_get_req_dump *req, + const void *erspan_opts, + size_t len) +{ + free(req->key.tunnel.erspan_opts); + req->key.tunnel._present.erspan_opts_len = len; + req->key.tunnel.erspan_opts = malloc(req->key.tunnel._present.erspan_opts_len); + memcpy(req->key.tunnel.erspan_opts, erspan_opts, req->key.tunnel._present.erspan_opts_len); +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_ipv4_info_bridge(struct ovs_flow_get_req_dump *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ipv4_info_bridge = 1; +} +static inline void +ovs_flow_get_req_dump_set_key_sctp(struct ovs_flow_get_req_dump *req, + const void *sctp, size_t len) +{ + free(req->key.sctp); + req->key._present.sctp_len = len; + req->key.sctp = malloc(req->key._present.sctp_len); + memcpy(req->key.sctp, sctp, req->key._present.sctp_len); +} +static inline void +ovs_flow_get_req_dump_set_key_tcp_flags(struct ovs_flow_get_req_dump *req, + __u16 tcp_flags /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tcp_flags = 1; + req->key.tcp_flags = tcp_flags; +} +static inline void +ovs_flow_get_req_dump_set_key_dp_hash(struct ovs_flow_get_req_dump *req, + __u32 dp_hash) +{ + req->_present.key = 1; + req->key._present.dp_hash = 1; + req->key.dp_hash = dp_hash; +} +static inline void +ovs_flow_get_req_dump_set_key_recirc_id(struct ovs_flow_get_req_dump *req, + __u32 recirc_id) +{ + req->_present.key = 1; + req->key._present.recirc_id = 1; + req->key.recirc_id = recirc_id; +} +static inline void +ovs_flow_get_req_dump_set_key_mpls(struct ovs_flow_get_req_dump *req, + const void *mpls, size_t len) +{ + free(req->key.mpls); + req->key._present.mpls_len = len; + req->key.mpls = malloc(req->key._present.mpls_len); + memcpy(req->key.mpls, mpls, req->key._present.mpls_len); +} +static inline void +ovs_flow_get_req_dump_set_key_ct_state(struct ovs_flow_get_req_dump *req, + __u32 ct_state) +{ + req->_present.key = 1; + req->key._present.ct_state = 1; + req->key.ct_state = ct_state; +} +static inline void +ovs_flow_get_req_dump_set_key_ct_zone(struct ovs_flow_get_req_dump *req, + __u16 ct_zone) +{ + req->_present.key = 1; + req->key._present.ct_zone = 1; + req->key.ct_zone = ct_zone; +} +static inline void +ovs_flow_get_req_dump_set_key_ct_mark(struct ovs_flow_get_req_dump *req, + __u32 ct_mark) +{ + req->_present.key = 1; + req->key._present.ct_mark = 1; + req->key.ct_mark = ct_mark; +} +static inline void +ovs_flow_get_req_dump_set_key_ct_labels(struct ovs_flow_get_req_dump *req, + const void *ct_labels, size_t len) +{ + free(req->key.ct_labels); + req->key._present.ct_labels_len = len; + req->key.ct_labels = malloc(req->key._present.ct_labels_len); + memcpy(req->key.ct_labels, ct_labels, req->key._present.ct_labels_len); +} +static inline void +ovs_flow_get_req_dump_set_key_ct_orig_tuple_ipv4(struct ovs_flow_get_req_dump *req, + const void *ct_orig_tuple_ipv4, + size_t len) +{ + free(req->key.ct_orig_tuple_ipv4); + req->key._present.ct_orig_tuple_ipv4_len = len; + req->key.ct_orig_tuple_ipv4 = malloc(req->key._present.ct_orig_tuple_ipv4_len); + memcpy(req->key.ct_orig_tuple_ipv4, ct_orig_tuple_ipv4, req->key._present.ct_orig_tuple_ipv4_len); +} +static inline void +ovs_flow_get_req_dump_set_key_ct_orig_tuple_ipv6(struct ovs_flow_get_req_dump *req, + const void *ct_orig_tuple_ipv6, + size_t len) +{ + free(req->key.ct_orig_tuple_ipv6); + req->key._present.ct_orig_tuple_ipv6_len = len; + req->key.ct_orig_tuple_ipv6 = malloc(req->key._present.ct_orig_tuple_ipv6_len); + memcpy(req->key.ct_orig_tuple_ipv6, ct_orig_tuple_ipv6, req->key._present.ct_orig_tuple_ipv6_len); +} +static inline void +ovs_flow_get_req_dump_set_key_nsh_base(struct ovs_flow_get_req_dump *req, + const void *base, size_t len) +{ + free(req->key.nsh.base); + req->key.nsh._present.base_len = len; + req->key.nsh.base = malloc(req->key.nsh._present.base_len); + memcpy(req->key.nsh.base, base, req->key.nsh._present.base_len); +} +static inline void +ovs_flow_get_req_dump_set_key_nsh_md1(struct ovs_flow_get_req_dump *req, + const void *md1, size_t len) +{ + free(req->key.nsh.md1); + req->key.nsh._present.md1_len = len; + req->key.nsh.md1 = malloc(req->key.nsh._present.md1_len); + memcpy(req->key.nsh.md1, md1, req->key.nsh._present.md1_len); +} +static inline void +ovs_flow_get_req_dump_set_key_nsh_md2(struct ovs_flow_get_req_dump *req, + const void *md2, size_t len) +{ + free(req->key.nsh.md2); + req->key.nsh._present.md2_len = len; + req->key.nsh.md2 = malloc(req->key.nsh._present.md2_len); + memcpy(req->key.nsh.md2, md2, req->key.nsh._present.md2_len); +} +static inline void +ovs_flow_get_req_dump_set_key_packet_type(struct ovs_flow_get_req_dump *req, + __u32 packet_type /* big-endian */) +{ + req->_present.key = 1; + req->key._present.packet_type = 1; + req->key.packet_type = packet_type; +} +static inline void +ovs_flow_get_req_dump_set_key_nd_extensions(struct ovs_flow_get_req_dump *req, + const void *nd_extensions, + size_t len) +{ + free(req->key.nd_extensions); + req->key._present.nd_extensions_len = len; + req->key.nd_extensions = malloc(req->key._present.nd_extensions_len); + memcpy(req->key.nd_extensions, nd_extensions, req->key._present.nd_extensions_len); +} +static inline void +ovs_flow_get_req_dump_set_key_tunnel_info(struct ovs_flow_get_req_dump *req, + const void *tunnel_info, size_t len) +{ + free(req->key.tunnel_info); + req->key._present.tunnel_info_len = len; + req->key.tunnel_info = malloc(req->key._present.tunnel_info_len); + memcpy(req->key.tunnel_info, tunnel_info, req->key._present.tunnel_info_len); +} +static inline void +ovs_flow_get_req_dump_set_key_ipv6_exthdrs(struct ovs_flow_get_req_dump *req, + const void *ipv6_exthdrs, + size_t len) +{ + free(req->key.ipv6_exthdrs); + req->key._present.ipv6_exthdrs_len = len; + req->key.ipv6_exthdrs = malloc(req->key._present.ipv6_exthdrs_len); + memcpy(req->key.ipv6_exthdrs, ipv6_exthdrs, req->key._present.ipv6_exthdrs_len); +} +static inline void +ovs_flow_get_req_dump_set_ufid(struct ovs_flow_get_req_dump *req, + const void *ufid, size_t len) +{ + free(req->ufid); + req->_present.ufid_len = len; + req->ufid = malloc(req->_present.ufid_len); + memcpy(req->ufid, ufid, req->_present.ufid_len); +} +static inline void +ovs_flow_get_req_dump_set_ufid_flags(struct ovs_flow_get_req_dump *req, + __u32 ufid_flags) +{ + req->_present.ufid_flags = 1; + req->ufid_flags = ufid_flags; +} + +struct ovs_flow_get_list { + struct ovs_flow_get_list *next; + struct ovs_flow_get_rsp obj __attribute__((aligned(8))); +}; + +void ovs_flow_get_list_free(struct ovs_flow_get_list *rsp); + +struct ovs_flow_get_list * +ovs_flow_get_dump(struct ynl_sock *ys, struct ovs_flow_get_req_dump *req); + +/* ============== OVS_FLOW_CMD_NEW ============== */ +/* OVS_FLOW_CMD_NEW - do */ +struct ovs_flow_new_req { + struct ovs_header _hdr; + + struct { + __u32 key:1; + __u32 ufid_len; + __u32 mask:1; + __u32 actions:1; + } _present; + + struct ovs_flow_key_attrs key; + void *ufid; + struct ovs_flow_key_attrs mask; + struct ovs_flow_action_attrs actions; +}; + +static inline struct ovs_flow_new_req *ovs_flow_new_req_alloc(void) +{ + return calloc(1, sizeof(struct ovs_flow_new_req)); +} +void ovs_flow_new_req_free(struct ovs_flow_new_req *req); + +static inline void +ovs_flow_new_req_set_key_priority(struct ovs_flow_new_req *req, __u32 priority) +{ + req->_present.key = 1; + req->key._present.priority = 1; + req->key.priority = priority; +} +static inline void +ovs_flow_new_req_set_key_in_port(struct ovs_flow_new_req *req, __u32 in_port) +{ + req->_present.key = 1; + req->key._present.in_port = 1; + req->key.in_port = in_port; +} +static inline void +ovs_flow_new_req_set_key_ethernet(struct ovs_flow_new_req *req, + const void *ethernet, size_t len) +{ + free(req->key.ethernet); + req->key._present.ethernet_len = len; + req->key.ethernet = malloc(req->key._present.ethernet_len); + memcpy(req->key.ethernet, ethernet, req->key._present.ethernet_len); +} +static inline void +ovs_flow_new_req_set_key_vlan(struct ovs_flow_new_req *req, + __u16 vlan /* big-endian */) +{ + req->_present.key = 1; + req->key._present.vlan = 1; + req->key.vlan = vlan; +} +static inline void +ovs_flow_new_req_set_key_ethertype(struct ovs_flow_new_req *req, + __u16 ethertype /* big-endian */) +{ + req->_present.key = 1; + req->key._present.ethertype = 1; + req->key.ethertype = ethertype; +} +static inline void +ovs_flow_new_req_set_key_ipv4(struct ovs_flow_new_req *req, const void *ipv4, + size_t len) +{ + free(req->key.ipv4); + req->key._present.ipv4_len = len; + req->key.ipv4 = malloc(req->key._present.ipv4_len); + memcpy(req->key.ipv4, ipv4, req->key._present.ipv4_len); +} +static inline void +ovs_flow_new_req_set_key_ipv6(struct ovs_flow_new_req *req, const void *ipv6, + size_t len) +{ + free(req->key.ipv6); + req->key._present.ipv6_len = len; + req->key.ipv6 = malloc(req->key._present.ipv6_len); + memcpy(req->key.ipv6, ipv6, req->key._present.ipv6_len); +} +static inline void +ovs_flow_new_req_set_key_tcp(struct ovs_flow_new_req *req, const void *tcp, + size_t len) +{ + free(req->key.tcp); + req->key._present.tcp_len = len; + req->key.tcp = malloc(req->key._present.tcp_len); + memcpy(req->key.tcp, tcp, req->key._present.tcp_len); +} +static inline void +ovs_flow_new_req_set_key_udp(struct ovs_flow_new_req *req, const void *udp, + size_t len) +{ + free(req->key.udp); + req->key._present.udp_len = len; + req->key.udp = malloc(req->key._present.udp_len); + memcpy(req->key.udp, udp, req->key._present.udp_len); +} +static inline void +ovs_flow_new_req_set_key_icmp(struct ovs_flow_new_req *req, const void *icmp, + size_t len) +{ + free(req->key.icmp); + req->key._present.icmp_len = len; + req->key.icmp = malloc(req->key._present.icmp_len); + memcpy(req->key.icmp, icmp, req->key._present.icmp_len); +} +static inline void +ovs_flow_new_req_set_key_icmpv6(struct ovs_flow_new_req *req, + const void *icmpv6, size_t len) +{ + free(req->key.icmpv6); + req->key._present.icmpv6_len = len; + req->key.icmpv6 = malloc(req->key._present.icmpv6_len); + memcpy(req->key.icmpv6, icmpv6, req->key._present.icmpv6_len); +} +static inline void +ovs_flow_new_req_set_key_arp(struct ovs_flow_new_req *req, const void *arp, + size_t len) +{ + free(req->key.arp); + req->key._present.arp_len = len; + req->key.arp = malloc(req->key._present.arp_len); + memcpy(req->key.arp, arp, req->key._present.arp_len); +} +static inline void +ovs_flow_new_req_set_key_nd(struct ovs_flow_new_req *req, const void *nd, + size_t len) +{ + free(req->key.nd); + req->key._present.nd_len = len; + req->key.nd = malloc(req->key._present.nd_len); + memcpy(req->key.nd, nd, req->key._present.nd_len); +} +static inline void +ovs_flow_new_req_set_key_skb_mark(struct ovs_flow_new_req *req, __u32 skb_mark) +{ + req->_present.key = 1; + req->key._present.skb_mark = 1; + req->key.skb_mark = skb_mark; +} +static inline void +ovs_flow_new_req_set_key_tunnel_id(struct ovs_flow_new_req *req, + __u64 id /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.id = 1; + req->key.tunnel.id = id; +} +static inline void +ovs_flow_new_req_set_key_tunnel_ipv4_src(struct ovs_flow_new_req *req, + __u32 ipv4_src /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ipv4_src = 1; + req->key.tunnel.ipv4_src = ipv4_src; +} +static inline void +ovs_flow_new_req_set_key_tunnel_ipv4_dst(struct ovs_flow_new_req *req, + __u32 ipv4_dst /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ipv4_dst = 1; + req->key.tunnel.ipv4_dst = ipv4_dst; +} +static inline void +ovs_flow_new_req_set_key_tunnel_tos(struct ovs_flow_new_req *req, __u8 tos) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.tos = 1; + req->key.tunnel.tos = tos; +} +static inline void +ovs_flow_new_req_set_key_tunnel_ttl(struct ovs_flow_new_req *req, __u8 ttl) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ttl = 1; + req->key.tunnel.ttl = ttl; +} +static inline void +ovs_flow_new_req_set_key_tunnel_dont_fragment(struct ovs_flow_new_req *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.dont_fragment = 1; +} +static inline void +ovs_flow_new_req_set_key_tunnel_csum(struct ovs_flow_new_req *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.csum = 1; +} +static inline void +ovs_flow_new_req_set_key_tunnel_oam(struct ovs_flow_new_req *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.oam = 1; +} +static inline void +ovs_flow_new_req_set_key_tunnel_geneve_opts(struct ovs_flow_new_req *req, + const void *geneve_opts, + size_t len) +{ + free(req->key.tunnel.geneve_opts); + req->key.tunnel._present.geneve_opts_len = len; + req->key.tunnel.geneve_opts = malloc(req->key.tunnel._present.geneve_opts_len); + memcpy(req->key.tunnel.geneve_opts, geneve_opts, req->key.tunnel._present.geneve_opts_len); +} +static inline void +ovs_flow_new_req_set_key_tunnel_tp_src(struct ovs_flow_new_req *req, + __u16 tp_src /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.tp_src = 1; + req->key.tunnel.tp_src = tp_src; +} +static inline void +ovs_flow_new_req_set_key_tunnel_tp_dst(struct ovs_flow_new_req *req, + __u16 tp_dst /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.tp_dst = 1; + req->key.tunnel.tp_dst = tp_dst; +} +static inline void +ovs_flow_new_req_set_key_tunnel_vxlan_opts_gbp(struct ovs_flow_new_req *req, + __u32 gbp) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.vxlan_opts = 1; + req->key.tunnel.vxlan_opts._present.gbp = 1; + req->key.tunnel.vxlan_opts.gbp = gbp; +} +static inline void +ovs_flow_new_req_set_key_tunnel_ipv6_src(struct ovs_flow_new_req *req, + const void *ipv6_src, size_t len) +{ + free(req->key.tunnel.ipv6_src); + req->key.tunnel._present.ipv6_src_len = len; + req->key.tunnel.ipv6_src = malloc(req->key.tunnel._present.ipv6_src_len); + memcpy(req->key.tunnel.ipv6_src, ipv6_src, req->key.tunnel._present.ipv6_src_len); +} +static inline void +ovs_flow_new_req_set_key_tunnel_ipv6_dst(struct ovs_flow_new_req *req, + const void *ipv6_dst, size_t len) +{ + free(req->key.tunnel.ipv6_dst); + req->key.tunnel._present.ipv6_dst_len = len; + req->key.tunnel.ipv6_dst = malloc(req->key.tunnel._present.ipv6_dst_len); + memcpy(req->key.tunnel.ipv6_dst, ipv6_dst, req->key.tunnel._present.ipv6_dst_len); +} +static inline void +ovs_flow_new_req_set_key_tunnel_pad(struct ovs_flow_new_req *req, + const void *pad, size_t len) +{ + free(req->key.tunnel.pad); + req->key.tunnel._present.pad_len = len; + req->key.tunnel.pad = malloc(req->key.tunnel._present.pad_len); + memcpy(req->key.tunnel.pad, pad, req->key.tunnel._present.pad_len); +} +static inline void +ovs_flow_new_req_set_key_tunnel_erspan_opts(struct ovs_flow_new_req *req, + const void *erspan_opts, + size_t len) +{ + free(req->key.tunnel.erspan_opts); + req->key.tunnel._present.erspan_opts_len = len; + req->key.tunnel.erspan_opts = malloc(req->key.tunnel._present.erspan_opts_len); + memcpy(req->key.tunnel.erspan_opts, erspan_opts, req->key.tunnel._present.erspan_opts_len); +} +static inline void +ovs_flow_new_req_set_key_tunnel_ipv4_info_bridge(struct ovs_flow_new_req *req) +{ + req->_present.key = 1; + req->key._present.tunnel = 1; + req->key.tunnel._present.ipv4_info_bridge = 1; +} +static inline void +ovs_flow_new_req_set_key_sctp(struct ovs_flow_new_req *req, const void *sctp, + size_t len) +{ + free(req->key.sctp); + req->key._present.sctp_len = len; + req->key.sctp = malloc(req->key._present.sctp_len); + memcpy(req->key.sctp, sctp, req->key._present.sctp_len); +} +static inline void +ovs_flow_new_req_set_key_tcp_flags(struct ovs_flow_new_req *req, + __u16 tcp_flags /* big-endian */) +{ + req->_present.key = 1; + req->key._present.tcp_flags = 1; + req->key.tcp_flags = tcp_flags; +} +static inline void +ovs_flow_new_req_set_key_dp_hash(struct ovs_flow_new_req *req, __u32 dp_hash) +{ + req->_present.key = 1; + req->key._present.dp_hash = 1; + req->key.dp_hash = dp_hash; +} +static inline void +ovs_flow_new_req_set_key_recirc_id(struct ovs_flow_new_req *req, + __u32 recirc_id) +{ + req->_present.key = 1; + req->key._present.recirc_id = 1; + req->key.recirc_id = recirc_id; +} +static inline void +ovs_flow_new_req_set_key_mpls(struct ovs_flow_new_req *req, const void *mpls, + size_t len) +{ + free(req->key.mpls); + req->key._present.mpls_len = len; + req->key.mpls = malloc(req->key._present.mpls_len); + memcpy(req->key.mpls, mpls, req->key._present.mpls_len); +} +static inline void +ovs_flow_new_req_set_key_ct_state(struct ovs_flow_new_req *req, __u32 ct_state) +{ + req->_present.key = 1; + req->key._present.ct_state = 1; + req->key.ct_state = ct_state; +} +static inline void +ovs_flow_new_req_set_key_ct_zone(struct ovs_flow_new_req *req, __u16 ct_zone) +{ + req->_present.key = 1; + req->key._present.ct_zone = 1; + req->key.ct_zone = ct_zone; +} +static inline void +ovs_flow_new_req_set_key_ct_mark(struct ovs_flow_new_req *req, __u32 ct_mark) +{ + req->_present.key = 1; + req->key._present.ct_mark = 1; + req->key.ct_mark = ct_mark; +} +static inline void +ovs_flow_new_req_set_key_ct_labels(struct ovs_flow_new_req *req, + const void *ct_labels, size_t len) +{ + free(req->key.ct_labels); + req->key._present.ct_labels_len = len; + req->key.ct_labels = malloc(req->key._present.ct_labels_len); + memcpy(req->key.ct_labels, ct_labels, req->key._present.ct_labels_len); +} +static inline void +ovs_flow_new_req_set_key_ct_orig_tuple_ipv4(struct ovs_flow_new_req *req, + const void *ct_orig_tuple_ipv4, + size_t len) +{ + free(req->key.ct_orig_tuple_ipv4); + req->key._present.ct_orig_tuple_ipv4_len = len; + req->key.ct_orig_tuple_ipv4 = malloc(req->key._present.ct_orig_tuple_ipv4_len); + memcpy(req->key.ct_orig_tuple_ipv4, ct_orig_tuple_ipv4, req->key._present.ct_orig_tuple_ipv4_len); +} +static inline void +ovs_flow_new_req_set_key_ct_orig_tuple_ipv6(struct ovs_flow_new_req *req, + const void *ct_orig_tuple_ipv6, + size_t len) +{ + free(req->key.ct_orig_tuple_ipv6); + req->key._present.ct_orig_tuple_ipv6_len = len; + req->key.ct_orig_tuple_ipv6 = malloc(req->key._present.ct_orig_tuple_ipv6_len); + memcpy(req->key.ct_orig_tuple_ipv6, ct_orig_tuple_ipv6, req->key._present.ct_orig_tuple_ipv6_len); +} +static inline void +ovs_flow_new_req_set_key_nsh_base(struct ovs_flow_new_req *req, + const void *base, size_t len) +{ + free(req->key.nsh.base); + req->key.nsh._present.base_len = len; + req->key.nsh.base = malloc(req->key.nsh._present.base_len); + memcpy(req->key.nsh.base, base, req->key.nsh._present.base_len); +} +static inline void +ovs_flow_new_req_set_key_nsh_md1(struct ovs_flow_new_req *req, const void *md1, + size_t len) +{ + free(req->key.nsh.md1); + req->key.nsh._present.md1_len = len; + req->key.nsh.md1 = malloc(req->key.nsh._present.md1_len); + memcpy(req->key.nsh.md1, md1, req->key.nsh._present.md1_len); +} +static inline void +ovs_flow_new_req_set_key_nsh_md2(struct ovs_flow_new_req *req, const void *md2, + size_t len) +{ + free(req->key.nsh.md2); + req->key.nsh._present.md2_len = len; + req->key.nsh.md2 = malloc(req->key.nsh._present.md2_len); + memcpy(req->key.nsh.md2, md2, req->key.nsh._present.md2_len); +} +static inline void +ovs_flow_new_req_set_key_packet_type(struct ovs_flow_new_req *req, + __u32 packet_type /* big-endian */) +{ + req->_present.key = 1; + req->key._present.packet_type = 1; + req->key.packet_type = packet_type; +} +static inline void +ovs_flow_new_req_set_key_nd_extensions(struct ovs_flow_new_req *req, + const void *nd_extensions, size_t len) +{ + free(req->key.nd_extensions); + req->key._present.nd_extensions_len = len; + req->key.nd_extensions = malloc(req->key._present.nd_extensions_len); + memcpy(req->key.nd_extensions, nd_extensions, req->key._present.nd_extensions_len); +} +static inline void +ovs_flow_new_req_set_key_tunnel_info(struct ovs_flow_new_req *req, + const void *tunnel_info, size_t len) +{ + free(req->key.tunnel_info); + req->key._present.tunnel_info_len = len; + req->key.tunnel_info = malloc(req->key._present.tunnel_info_len); + memcpy(req->key.tunnel_info, tunnel_info, req->key._present.tunnel_info_len); +} +static inline void +ovs_flow_new_req_set_key_ipv6_exthdrs(struct ovs_flow_new_req *req, + const void *ipv6_exthdrs, size_t len) +{ + free(req->key.ipv6_exthdrs); + req->key._present.ipv6_exthdrs_len = len; + req->key.ipv6_exthdrs = malloc(req->key._present.ipv6_exthdrs_len); + memcpy(req->key.ipv6_exthdrs, ipv6_exthdrs, req->key._present.ipv6_exthdrs_len); +} +static inline void +ovs_flow_new_req_set_ufid(struct ovs_flow_new_req *req, const void *ufid, + size_t len) +{ + free(req->ufid); + req->_present.ufid_len = len; + req->ufid = malloc(req->_present.ufid_len); + memcpy(req->ufid, ufid, req->_present.ufid_len); +} +static inline void +ovs_flow_new_req_set_mask_priority(struct ovs_flow_new_req *req, + __u32 priority) +{ + req->_present.mask = 1; + req->mask._present.priority = 1; + req->mask.priority = priority; +} +static inline void +ovs_flow_new_req_set_mask_in_port(struct ovs_flow_new_req *req, __u32 in_port) +{ + req->_present.mask = 1; + req->mask._present.in_port = 1; + req->mask.in_port = in_port; +} +static inline void +ovs_flow_new_req_set_mask_ethernet(struct ovs_flow_new_req *req, + const void *ethernet, size_t len) +{ + free(req->mask.ethernet); + req->mask._present.ethernet_len = len; + req->mask.ethernet = malloc(req->mask._present.ethernet_len); + memcpy(req->mask.ethernet, ethernet, req->mask._present.ethernet_len); +} +static inline void +ovs_flow_new_req_set_mask_vlan(struct ovs_flow_new_req *req, + __u16 vlan /* big-endian */) +{ + req->_present.mask = 1; + req->mask._present.vlan = 1; + req->mask.vlan = vlan; +} +static inline void +ovs_flow_new_req_set_mask_ethertype(struct ovs_flow_new_req *req, + __u16 ethertype /* big-endian */) +{ + req->_present.mask = 1; + req->mask._present.ethertype = 1; + req->mask.ethertype = ethertype; +} +static inline void +ovs_flow_new_req_set_mask_ipv4(struct ovs_flow_new_req *req, const void *ipv4, + size_t len) +{ + free(req->mask.ipv4); + req->mask._present.ipv4_len = len; + req->mask.ipv4 = malloc(req->mask._present.ipv4_len); + memcpy(req->mask.ipv4, ipv4, req->mask._present.ipv4_len); +} +static inline void +ovs_flow_new_req_set_mask_ipv6(struct ovs_flow_new_req *req, const void *ipv6, + size_t len) +{ + free(req->mask.ipv6); + req->mask._present.ipv6_len = len; + req->mask.ipv6 = malloc(req->mask._present.ipv6_len); + memcpy(req->mask.ipv6, ipv6, req->mask._present.ipv6_len); +} +static inline void +ovs_flow_new_req_set_mask_tcp(struct ovs_flow_new_req *req, const void *tcp, + size_t len) +{ + free(req->mask.tcp); + req->mask._present.tcp_len = len; + req->mask.tcp = malloc(req->mask._present.tcp_len); + memcpy(req->mask.tcp, tcp, req->mask._present.tcp_len); +} +static inline void +ovs_flow_new_req_set_mask_udp(struct ovs_flow_new_req *req, const void *udp, + size_t len) +{ + free(req->mask.udp); + req->mask._present.udp_len = len; + req->mask.udp = malloc(req->mask._present.udp_len); + memcpy(req->mask.udp, udp, req->mask._present.udp_len); +} +static inline void +ovs_flow_new_req_set_mask_icmp(struct ovs_flow_new_req *req, const void *icmp, + size_t len) +{ + free(req->mask.icmp); + req->mask._present.icmp_len = len; + req->mask.icmp = malloc(req->mask._present.icmp_len); + memcpy(req->mask.icmp, icmp, req->mask._present.icmp_len); +} +static inline void +ovs_flow_new_req_set_mask_icmpv6(struct ovs_flow_new_req *req, + const void *icmpv6, size_t len) +{ + free(req->mask.icmpv6); + req->mask._present.icmpv6_len = len; + req->mask.icmpv6 = malloc(req->mask._present.icmpv6_len); + memcpy(req->mask.icmpv6, icmpv6, req->mask._present.icmpv6_len); +} +static inline void +ovs_flow_new_req_set_mask_arp(struct ovs_flow_new_req *req, const void *arp, + size_t len) +{ + free(req->mask.arp); + req->mask._present.arp_len = len; + req->mask.arp = malloc(req->mask._present.arp_len); + memcpy(req->mask.arp, arp, req->mask._present.arp_len); +} +static inline void +ovs_flow_new_req_set_mask_nd(struct ovs_flow_new_req *req, const void *nd, + size_t len) +{ + free(req->mask.nd); + req->mask._present.nd_len = len; + req->mask.nd = malloc(req->mask._present.nd_len); + memcpy(req->mask.nd, nd, req->mask._present.nd_len); +} +static inline void +ovs_flow_new_req_set_mask_skb_mark(struct ovs_flow_new_req *req, + __u32 skb_mark) +{ + req->_present.mask = 1; + req->mask._present.skb_mark = 1; + req->mask.skb_mark = skb_mark; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_id(struct ovs_flow_new_req *req, + __u64 id /* big-endian */) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.id = 1; + req->mask.tunnel.id = id; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_ipv4_src(struct ovs_flow_new_req *req, + __u32 ipv4_src /* big-endian */) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.ipv4_src = 1; + req->mask.tunnel.ipv4_src = ipv4_src; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_ipv4_dst(struct ovs_flow_new_req *req, + __u32 ipv4_dst /* big-endian */) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.ipv4_dst = 1; + req->mask.tunnel.ipv4_dst = ipv4_dst; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_tos(struct ovs_flow_new_req *req, __u8 tos) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.tos = 1; + req->mask.tunnel.tos = tos; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_ttl(struct ovs_flow_new_req *req, __u8 ttl) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.ttl = 1; + req->mask.tunnel.ttl = ttl; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_dont_fragment(struct ovs_flow_new_req *req) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.dont_fragment = 1; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_csum(struct ovs_flow_new_req *req) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.csum = 1; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_oam(struct ovs_flow_new_req *req) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.oam = 1; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_geneve_opts(struct ovs_flow_new_req *req, + const void *geneve_opts, + size_t len) +{ + free(req->mask.tunnel.geneve_opts); + req->mask.tunnel._present.geneve_opts_len = len; + req->mask.tunnel.geneve_opts = malloc(req->mask.tunnel._present.geneve_opts_len); + memcpy(req->mask.tunnel.geneve_opts, geneve_opts, req->mask.tunnel._present.geneve_opts_len); +} +static inline void +ovs_flow_new_req_set_mask_tunnel_tp_src(struct ovs_flow_new_req *req, + __u16 tp_src /* big-endian */) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.tp_src = 1; + req->mask.tunnel.tp_src = tp_src; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_tp_dst(struct ovs_flow_new_req *req, + __u16 tp_dst /* big-endian */) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.tp_dst = 1; + req->mask.tunnel.tp_dst = tp_dst; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_vxlan_opts_gbp(struct ovs_flow_new_req *req, + __u32 gbp) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.vxlan_opts = 1; + req->mask.tunnel.vxlan_opts._present.gbp = 1; + req->mask.tunnel.vxlan_opts.gbp = gbp; +} +static inline void +ovs_flow_new_req_set_mask_tunnel_ipv6_src(struct ovs_flow_new_req *req, + const void *ipv6_src, size_t len) +{ + free(req->mask.tunnel.ipv6_src); + req->mask.tunnel._present.ipv6_src_len = len; + req->mask.tunnel.ipv6_src = malloc(req->mask.tunnel._present.ipv6_src_len); + memcpy(req->mask.tunnel.ipv6_src, ipv6_src, req->mask.tunnel._present.ipv6_src_len); +} +static inline void +ovs_flow_new_req_set_mask_tunnel_ipv6_dst(struct ovs_flow_new_req *req, + const void *ipv6_dst, size_t len) +{ + free(req->mask.tunnel.ipv6_dst); + req->mask.tunnel._present.ipv6_dst_len = len; + req->mask.tunnel.ipv6_dst = malloc(req->mask.tunnel._present.ipv6_dst_len); + memcpy(req->mask.tunnel.ipv6_dst, ipv6_dst, req->mask.tunnel._present.ipv6_dst_len); +} +static inline void +ovs_flow_new_req_set_mask_tunnel_pad(struct ovs_flow_new_req *req, + const void *pad, size_t len) +{ + free(req->mask.tunnel.pad); + req->mask.tunnel._present.pad_len = len; + req->mask.tunnel.pad = malloc(req->mask.tunnel._present.pad_len); + memcpy(req->mask.tunnel.pad, pad, req->mask.tunnel._present.pad_len); +} +static inline void +ovs_flow_new_req_set_mask_tunnel_erspan_opts(struct ovs_flow_new_req *req, + const void *erspan_opts, + size_t len) +{ + free(req->mask.tunnel.erspan_opts); + req->mask.tunnel._present.erspan_opts_len = len; + req->mask.tunnel.erspan_opts = malloc(req->mask.tunnel._present.erspan_opts_len); + memcpy(req->mask.tunnel.erspan_opts, erspan_opts, req->mask.tunnel._present.erspan_opts_len); +} +static inline void +ovs_flow_new_req_set_mask_tunnel_ipv4_info_bridge(struct ovs_flow_new_req *req) +{ + req->_present.mask = 1; + req->mask._present.tunnel = 1; + req->mask.tunnel._present.ipv4_info_bridge = 1; +} +static inline void +ovs_flow_new_req_set_mask_sctp(struct ovs_flow_new_req *req, const void *sctp, + size_t len) +{ + free(req->mask.sctp); + req->mask._present.sctp_len = len; + req->mask.sctp = malloc(req->mask._present.sctp_len); + memcpy(req->mask.sctp, sctp, req->mask._present.sctp_len); +} +static inline void +ovs_flow_new_req_set_mask_tcp_flags(struct ovs_flow_new_req *req, + __u16 tcp_flags /* big-endian */) +{ + req->_present.mask = 1; + req->mask._present.tcp_flags = 1; + req->mask.tcp_flags = tcp_flags; +} +static inline void +ovs_flow_new_req_set_mask_dp_hash(struct ovs_flow_new_req *req, __u32 dp_hash) +{ + req->_present.mask = 1; + req->mask._present.dp_hash = 1; + req->mask.dp_hash = dp_hash; +} +static inline void +ovs_flow_new_req_set_mask_recirc_id(struct ovs_flow_new_req *req, + __u32 recirc_id) +{ + req->_present.mask = 1; + req->mask._present.recirc_id = 1; + req->mask.recirc_id = recirc_id; +} +static inline void +ovs_flow_new_req_set_mask_mpls(struct ovs_flow_new_req *req, const void *mpls, + size_t len) +{ + free(req->mask.mpls); + req->mask._present.mpls_len = len; + req->mask.mpls = malloc(req->mask._present.mpls_len); + memcpy(req->mask.mpls, mpls, req->mask._present.mpls_len); +} +static inline void +ovs_flow_new_req_set_mask_ct_state(struct ovs_flow_new_req *req, + __u32 ct_state) +{ + req->_present.mask = 1; + req->mask._present.ct_state = 1; + req->mask.ct_state = ct_state; +} +static inline void +ovs_flow_new_req_set_mask_ct_zone(struct ovs_flow_new_req *req, __u16 ct_zone) +{ + req->_present.mask = 1; + req->mask._present.ct_zone = 1; + req->mask.ct_zone = ct_zone; +} +static inline void +ovs_flow_new_req_set_mask_ct_mark(struct ovs_flow_new_req *req, __u32 ct_mark) +{ + req->_present.mask = 1; + req->mask._present.ct_mark = 1; + req->mask.ct_mark = ct_mark; +} +static inline void +ovs_flow_new_req_set_mask_ct_labels(struct ovs_flow_new_req *req, + const void *ct_labels, size_t len) +{ + free(req->mask.ct_labels); + req->mask._present.ct_labels_len = len; + req->mask.ct_labels = malloc(req->mask._present.ct_labels_len); + memcpy(req->mask.ct_labels, ct_labels, req->mask._present.ct_labels_len); +} +static inline void +ovs_flow_new_req_set_mask_ct_orig_tuple_ipv4(struct ovs_flow_new_req *req, + const void *ct_orig_tuple_ipv4, + size_t len) +{ + free(req->mask.ct_orig_tuple_ipv4); + req->mask._present.ct_orig_tuple_ipv4_len = len; + req->mask.ct_orig_tuple_ipv4 = malloc(req->mask._present.ct_orig_tuple_ipv4_len); + memcpy(req->mask.ct_orig_tuple_ipv4, ct_orig_tuple_ipv4, req->mask._present.ct_orig_tuple_ipv4_len); +} +static inline void +ovs_flow_new_req_set_mask_ct_orig_tuple_ipv6(struct ovs_flow_new_req *req, + const void *ct_orig_tuple_ipv6, + size_t len) +{ + free(req->mask.ct_orig_tuple_ipv6); + req->mask._present.ct_orig_tuple_ipv6_len = len; + req->mask.ct_orig_tuple_ipv6 = malloc(req->mask._present.ct_orig_tuple_ipv6_len); + memcpy(req->mask.ct_orig_tuple_ipv6, ct_orig_tuple_ipv6, req->mask._present.ct_orig_tuple_ipv6_len); +} +static inline void +ovs_flow_new_req_set_mask_nsh_base(struct ovs_flow_new_req *req, + const void *base, size_t len) +{ + free(req->mask.nsh.base); + req->mask.nsh._present.base_len = len; + req->mask.nsh.base = malloc(req->mask.nsh._present.base_len); + memcpy(req->mask.nsh.base, base, req->mask.nsh._present.base_len); +} +static inline void +ovs_flow_new_req_set_mask_nsh_md1(struct ovs_flow_new_req *req, + const void *md1, size_t len) +{ + free(req->mask.nsh.md1); + req->mask.nsh._present.md1_len = len; + req->mask.nsh.md1 = malloc(req->mask.nsh._present.md1_len); + memcpy(req->mask.nsh.md1, md1, req->mask.nsh._present.md1_len); +} +static inline void +ovs_flow_new_req_set_mask_nsh_md2(struct ovs_flow_new_req *req, + const void *md2, size_t len) +{ + free(req->mask.nsh.md2); + req->mask.nsh._present.md2_len = len; + req->mask.nsh.md2 = malloc(req->mask.nsh._present.md2_len); + memcpy(req->mask.nsh.md2, md2, req->mask.nsh._present.md2_len); +} +static inline void +ovs_flow_new_req_set_mask_packet_type(struct ovs_flow_new_req *req, + __u32 packet_type /* big-endian */) +{ + req->_present.mask = 1; + req->mask._present.packet_type = 1; + req->mask.packet_type = packet_type; +} +static inline void +ovs_flow_new_req_set_mask_nd_extensions(struct ovs_flow_new_req *req, + const void *nd_extensions, size_t len) +{ + free(req->mask.nd_extensions); + req->mask._present.nd_extensions_len = len; + req->mask.nd_extensions = malloc(req->mask._present.nd_extensions_len); + memcpy(req->mask.nd_extensions, nd_extensions, req->mask._present.nd_extensions_len); +} +static inline void +ovs_flow_new_req_set_mask_tunnel_info(struct ovs_flow_new_req *req, + const void *tunnel_info, size_t len) +{ + free(req->mask.tunnel_info); + req->mask._present.tunnel_info_len = len; + req->mask.tunnel_info = malloc(req->mask._present.tunnel_info_len); + memcpy(req->mask.tunnel_info, tunnel_info, req->mask._present.tunnel_info_len); +} +static inline void +ovs_flow_new_req_set_mask_ipv6_exthdrs(struct ovs_flow_new_req *req, + const void *ipv6_exthdrs, size_t len) +{ + free(req->mask.ipv6_exthdrs); + req->mask._present.ipv6_exthdrs_len = len; + req->mask.ipv6_exthdrs = malloc(req->mask._present.ipv6_exthdrs_len); + memcpy(req->mask.ipv6_exthdrs, ipv6_exthdrs, req->mask._present.ipv6_exthdrs_len); +} +static inline void +ovs_flow_new_req_set_actions_output(struct ovs_flow_new_req *req, __u32 output) +{ + req->_present.actions = 1; + req->actions._present.output = 1; + req->actions.output = output; +} +static inline void +ovs_flow_new_req_set_actions_userspace_pid(struct ovs_flow_new_req *req, + __u32 pid) +{ + req->_present.actions = 1; + req->actions._present.userspace = 1; + req->actions.userspace._present.pid = 1; + req->actions.userspace.pid = pid; +} +static inline void +ovs_flow_new_req_set_actions_userspace_userdata(struct ovs_flow_new_req *req, + const void *userdata, + size_t len) +{ + free(req->actions.userspace.userdata); + req->actions.userspace._present.userdata_len = len; + req->actions.userspace.userdata = malloc(req->actions.userspace._present.userdata_len); + memcpy(req->actions.userspace.userdata, userdata, req->actions.userspace._present.userdata_len); +} +static inline void +ovs_flow_new_req_set_actions_userspace_egress_tun_port(struct ovs_flow_new_req *req, + __u32 egress_tun_port) +{ + req->_present.actions = 1; + req->actions._present.userspace = 1; + req->actions.userspace._present.egress_tun_port = 1; + req->actions.userspace.egress_tun_port = egress_tun_port; +} +static inline void +ovs_flow_new_req_set_actions_userspace_actions(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.userspace = 1; + req->actions.userspace._present.actions = 1; +} +static inline void +ovs_flow_new_req_set_actions_push_vlan(struct ovs_flow_new_req *req, + const void *push_vlan, size_t len) +{ + free(req->actions.push_vlan); + req->actions._present.push_vlan_len = len; + req->actions.push_vlan = malloc(req->actions._present.push_vlan_len); + memcpy(req->actions.push_vlan, push_vlan, req->actions._present.push_vlan_len); +} +static inline void +ovs_flow_new_req_set_actions_pop_vlan(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.pop_vlan = 1; +} +static inline void +ovs_flow_new_req_set_actions_sample_probability(struct ovs_flow_new_req *req, + __u32 probability) +{ + req->_present.actions = 1; + req->actions._present.sample = 1; + req->actions.sample._present.probability = 1; + req->actions.sample.probability = probability; +} +static inline void +ovs_flow_new_req_set_actions_recirc(struct ovs_flow_new_req *req, __u32 recirc) +{ + req->_present.actions = 1; + req->actions._present.recirc = 1; + req->actions.recirc = recirc; +} +static inline void +ovs_flow_new_req_set_actions_hash(struct ovs_flow_new_req *req, + const void *hash, size_t len) +{ + free(req->actions.hash); + req->actions._present.hash_len = len; + req->actions.hash = malloc(req->actions._present.hash_len); + memcpy(req->actions.hash, hash, req->actions._present.hash_len); +} +static inline void +ovs_flow_new_req_set_actions_push_mpls(struct ovs_flow_new_req *req, + const void *push_mpls, size_t len) +{ + free(req->actions.push_mpls); + req->actions._present.push_mpls_len = len; + req->actions.push_mpls = malloc(req->actions._present.push_mpls_len); + memcpy(req->actions.push_mpls, push_mpls, req->actions._present.push_mpls_len); +} +static inline void +ovs_flow_new_req_set_actions_pop_mpls(struct ovs_flow_new_req *req, + __u16 pop_mpls /* big-endian */) +{ + req->_present.actions = 1; + req->actions._present.pop_mpls = 1; + req->actions.pop_mpls = pop_mpls; +} +static inline void +ovs_flow_new_req_set_actions_ct_commit(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.commit = 1; +} +static inline void +ovs_flow_new_req_set_actions_ct_zone(struct ovs_flow_new_req *req, __u16 zone) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.zone = 1; + req->actions.ct.zone = zone; +} +static inline void +ovs_flow_new_req_set_actions_ct_mark(struct ovs_flow_new_req *req, + const void *mark, size_t len) +{ + free(req->actions.ct.mark); + req->actions.ct._present.mark_len = len; + req->actions.ct.mark = malloc(req->actions.ct._present.mark_len); + memcpy(req->actions.ct.mark, mark, req->actions.ct._present.mark_len); +} +static inline void +ovs_flow_new_req_set_actions_ct_labels(struct ovs_flow_new_req *req, + const void *labels, size_t len) +{ + free(req->actions.ct.labels); + req->actions.ct._present.labels_len = len; + req->actions.ct.labels = malloc(req->actions.ct._present.labels_len); + memcpy(req->actions.ct.labels, labels, req->actions.ct._present.labels_len); +} +static inline void +ovs_flow_new_req_set_actions_ct_helper(struct ovs_flow_new_req *req, + const char *helper) +{ + free(req->actions.ct.helper); + req->actions.ct._present.helper_len = strlen(helper); + req->actions.ct.helper = malloc(req->actions.ct._present.helper_len + 1); + memcpy(req->actions.ct.helper, helper, req->actions.ct._present.helper_len); + req->actions.ct.helper[req->actions.ct._present.helper_len] = 0; +} +static inline void +ovs_flow_new_req_set_actions_ct_nat_src(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.nat = 1; + req->actions.ct.nat._present.src = 1; +} +static inline void +ovs_flow_new_req_set_actions_ct_nat_dst(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.nat = 1; + req->actions.ct.nat._present.dst = 1; +} +static inline void +ovs_flow_new_req_set_actions_ct_nat_ip_min(struct ovs_flow_new_req *req, + const void *ip_min, size_t len) +{ + free(req->actions.ct.nat.ip_min); + req->actions.ct.nat._present.ip_min_len = len; + req->actions.ct.nat.ip_min = malloc(req->actions.ct.nat._present.ip_min_len); + memcpy(req->actions.ct.nat.ip_min, ip_min, req->actions.ct.nat._present.ip_min_len); +} +static inline void +ovs_flow_new_req_set_actions_ct_nat_ip_max(struct ovs_flow_new_req *req, + const void *ip_max, size_t len) +{ + free(req->actions.ct.nat.ip_max); + req->actions.ct.nat._present.ip_max_len = len; + req->actions.ct.nat.ip_max = malloc(req->actions.ct.nat._present.ip_max_len); + memcpy(req->actions.ct.nat.ip_max, ip_max, req->actions.ct.nat._present.ip_max_len); +} +static inline void +ovs_flow_new_req_set_actions_ct_nat_proto_min(struct ovs_flow_new_req *req, + __u16 proto_min) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.nat = 1; + req->actions.ct.nat._present.proto_min = 1; + req->actions.ct.nat.proto_min = proto_min; +} +static inline void +ovs_flow_new_req_set_actions_ct_nat_proto_max(struct ovs_flow_new_req *req, + __u16 proto_max) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.nat = 1; + req->actions.ct.nat._present.proto_max = 1; + req->actions.ct.nat.proto_max = proto_max; +} +static inline void +ovs_flow_new_req_set_actions_ct_nat_persistent(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.nat = 1; + req->actions.ct.nat._present.persistent = 1; +} +static inline void +ovs_flow_new_req_set_actions_ct_nat_proto_hash(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.nat = 1; + req->actions.ct.nat._present.proto_hash = 1; +} +static inline void +ovs_flow_new_req_set_actions_ct_nat_proto_random(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.nat = 1; + req->actions.ct.nat._present.proto_random = 1; +} +static inline void +ovs_flow_new_req_set_actions_ct_force_commit(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.force_commit = 1; +} +static inline void +ovs_flow_new_req_set_actions_ct_eventmask(struct ovs_flow_new_req *req, + __u32 eventmask) +{ + req->_present.actions = 1; + req->actions._present.ct = 1; + req->actions.ct._present.eventmask = 1; + req->actions.ct.eventmask = eventmask; +} +static inline void +ovs_flow_new_req_set_actions_ct_timeout(struct ovs_flow_new_req *req, + const char *timeout) +{ + free(req->actions.ct.timeout); + req->actions.ct._present.timeout_len = strlen(timeout); + req->actions.ct.timeout = malloc(req->actions.ct._present.timeout_len + 1); + memcpy(req->actions.ct.timeout, timeout, req->actions.ct._present.timeout_len); + req->actions.ct.timeout[req->actions.ct._present.timeout_len] = 0; +} +static inline void +ovs_flow_new_req_set_actions_trunc(struct ovs_flow_new_req *req, __u32 trunc) +{ + req->_present.actions = 1; + req->actions._present.trunc = 1; + req->actions.trunc = trunc; +} +static inline void +ovs_flow_new_req_set_actions_push_eth(struct ovs_flow_new_req *req, + const void *push_eth, size_t len) +{ + free(req->actions.push_eth); + req->actions._present.push_eth_len = len; + req->actions.push_eth = malloc(req->actions._present.push_eth_len); + memcpy(req->actions.push_eth, push_eth, req->actions._present.push_eth_len); +} +static inline void +ovs_flow_new_req_set_actions_pop_eth(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.pop_eth = 1; +} +static inline void +ovs_flow_new_req_set_actions_ct_clear(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.ct_clear = 1; +} +static inline void +ovs_flow_new_req_set_actions_push_nsh_base(struct ovs_flow_new_req *req, + const void *base, size_t len) +{ + free(req->actions.push_nsh.base); + req->actions.push_nsh._present.base_len = len; + req->actions.push_nsh.base = malloc(req->actions.push_nsh._present.base_len); + memcpy(req->actions.push_nsh.base, base, req->actions.push_nsh._present.base_len); +} +static inline void +ovs_flow_new_req_set_actions_push_nsh_md1(struct ovs_flow_new_req *req, + const void *md1, size_t len) +{ + free(req->actions.push_nsh.md1); + req->actions.push_nsh._present.md1_len = len; + req->actions.push_nsh.md1 = malloc(req->actions.push_nsh._present.md1_len); + memcpy(req->actions.push_nsh.md1, md1, req->actions.push_nsh._present.md1_len); +} +static inline void +ovs_flow_new_req_set_actions_push_nsh_md2(struct ovs_flow_new_req *req, + const void *md2, size_t len) +{ + free(req->actions.push_nsh.md2); + req->actions.push_nsh._present.md2_len = len; + req->actions.push_nsh.md2 = malloc(req->actions.push_nsh._present.md2_len); + memcpy(req->actions.push_nsh.md2, md2, req->actions.push_nsh._present.md2_len); +} +static inline void +ovs_flow_new_req_set_actions_pop_nsh(struct ovs_flow_new_req *req) +{ + req->_present.actions = 1; + req->actions._present.pop_nsh = 1; +} +static inline void +ovs_flow_new_req_set_actions_meter(struct ovs_flow_new_req *req, __u32 meter) +{ + req->_present.actions = 1; + req->actions._present.meter = 1; + req->actions.meter = meter; +} +static inline void +ovs_flow_new_req_set_actions_check_pkt_len_pkt_len(struct ovs_flow_new_req *req, + __u16 pkt_len) +{ + req->_present.actions = 1; + req->actions._present.check_pkt_len = 1; + req->actions.check_pkt_len._present.pkt_len = 1; + req->actions.check_pkt_len.pkt_len = pkt_len; +} +static inline void +ovs_flow_new_req_set_actions_add_mpls(struct ovs_flow_new_req *req, + const void *add_mpls, size_t len) +{ + free(req->actions.add_mpls); + req->actions._present.add_mpls_len = len; + req->actions.add_mpls = malloc(req->actions._present.add_mpls_len); + memcpy(req->actions.add_mpls, add_mpls, req->actions._present.add_mpls_len); +} + +/* + * Create OVS flow configuration in a data path + */ +int ovs_flow_new(struct ynl_sock *ys, struct ovs_flow_new_req *req); + +#endif /* _LINUX_OVS_FLOW_GEN_H */ diff --git a/generated/ovs_vport-user.c b/generated/ovs_vport-user.c new file mode 100644 index 0000000..8899dfe --- /dev/null +++ b/generated/ovs_vport-user.c @@ -0,0 +1,413 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/ovs_vport.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "ovs_vport-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const ovs_vport_op_strmap[] = { + [OVS_VPORT_CMD_NEW] = "new", + [OVS_VPORT_CMD_DEL] = "del", + [OVS_VPORT_CMD_GET] = "get", +}; + +const char *ovs_vport_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(ovs_vport_op_strmap)) + return NULL; + return ovs_vport_op_strmap[op]; +} + +static const char * const ovs_vport_vport_type_strmap[] = { + [0] = "unspec", + [1] = "netdev", + [2] = "internal", + [3] = "gre", + [4] = "vxlan", + [5] = "geneve", +}; + +const char *ovs_vport_vport_type_str(enum ovs_vport_type value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(ovs_vport_vport_type_strmap)) + return NULL; + return ovs_vport_vport_type_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr ovs_vport_vport_options_policy[OVS_TUNNEL_ATTR_MAX + 1] = { + [OVS_TUNNEL_ATTR_DST_PORT] = { .name = "dst-port", .type = YNL_PT_U32, }, + [OVS_TUNNEL_ATTR_EXTENSION] = { .name = "extension", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest ovs_vport_vport_options_nest = { + .max_attr = OVS_TUNNEL_ATTR_MAX, + .table = ovs_vport_vport_options_policy, +}; + +struct ynl_policy_attr ovs_vport_upcall_stats_policy[OVS_VPORT_UPCALL_ATTR_MAX + 1] = { + [OVS_VPORT_UPCALL_ATTR_SUCCESS] = { .name = "success", .type = YNL_PT_U64, }, + [OVS_VPORT_UPCALL_ATTR_FAIL] = { .name = "fail", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest ovs_vport_upcall_stats_nest = { + .max_attr = OVS_VPORT_UPCALL_ATTR_MAX, + .table = ovs_vport_upcall_stats_policy, +}; + +struct ynl_policy_attr ovs_vport_vport_policy[OVS_VPORT_ATTR_MAX + 1] = { + [OVS_VPORT_ATTR_UNSPEC] = { .name = "unspec", .type = YNL_PT_REJECT, }, + [OVS_VPORT_ATTR_PORT_NO] = { .name = "port-no", .type = YNL_PT_U32, }, + [OVS_VPORT_ATTR_TYPE] = { .name = "type", .type = YNL_PT_U32, }, + [OVS_VPORT_ATTR_NAME] = { .name = "name", .type = YNL_PT_NUL_STR, }, + [OVS_VPORT_ATTR_OPTIONS] = { .name = "options", .type = YNL_PT_NEST, .nest = &ovs_vport_vport_options_nest, }, + [OVS_VPORT_ATTR_UPCALL_PID] = { .name = "upcall-pid", .type = YNL_PT_BINARY,}, + [OVS_VPORT_ATTR_STATS] = { .name = "stats", .type = YNL_PT_BINARY,}, + [OVS_VPORT_ATTR_PAD] = { .name = "pad", .type = YNL_PT_REJECT, }, + [OVS_VPORT_ATTR_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, + [OVS_VPORT_ATTR_NETNSID] = { .name = "netnsid", .type = YNL_PT_U32, }, + [OVS_VPORT_ATTR_UPCALL_STATS] = { .name = "upcall-stats", .type = YNL_PT_NEST, .nest = &ovs_vport_upcall_stats_nest, }, +}; + +struct ynl_policy_nest ovs_vport_vport_nest = { + .max_attr = OVS_VPORT_ATTR_MAX, + .table = ovs_vport_vport_policy, +}; + +/* Common nested types */ +void ovs_vport_vport_options_free(struct ovs_vport_vport_options *obj) +{ +} + +int ovs_vport_vport_options_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct ovs_vport_vport_options *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.dst_port) + ynl_attr_put_u32(nlh, OVS_TUNNEL_ATTR_DST_PORT, obj->dst_port); + if (obj->_present.extension) + ynl_attr_put_u32(nlh, OVS_TUNNEL_ATTR_EXTENSION, obj->extension); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +void ovs_vport_upcall_stats_free(struct ovs_vport_upcall_stats *obj) +{ +} + +int ovs_vport_upcall_stats_parse(struct ynl_parse_arg *yarg, + const struct nlattr *nested) +{ + struct ovs_vport_upcall_stats *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_VPORT_UPCALL_ATTR_SUCCESS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.success = 1; + dst->success = ynl_attr_get_u64(attr); + } else if (type == OVS_VPORT_UPCALL_ATTR_FAIL) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.fail = 1; + dst->fail = ynl_attr_get_u64(attr); + } + } + + return 0; +} + +/* ============== OVS_VPORT_CMD_NEW ============== */ +/* OVS_VPORT_CMD_NEW - do */ +void ovs_vport_new_req_free(struct ovs_vport_new_req *req) +{ + free(req->name); + free(req->upcall_pid); + ovs_vport_vport_options_free(&req->options); + free(req); +} + +int ovs_vport_new(struct ynl_sock *ys, struct ovs_vport_new_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, OVS_VPORT_CMD_NEW, 1); + ys->req_policy = &ovs_vport_vport_nest; + + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + if (req->_present.name_len) + ynl_attr_put_str(nlh, OVS_VPORT_ATTR_NAME, req->name); + if (req->_present.type) + ynl_attr_put_u32(nlh, OVS_VPORT_ATTR_TYPE, req->type); + if (req->_present.upcall_pid_len) + ynl_attr_put(nlh, OVS_VPORT_ATTR_UPCALL_PID, req->upcall_pid, req->_present.upcall_pid_len); + if (req->_present.ifindex) + ynl_attr_put_u32(nlh, OVS_VPORT_ATTR_IFINDEX, req->ifindex); + if (req->_present.options) + ovs_vport_vport_options_put(nlh, OVS_VPORT_ATTR_OPTIONS, &req->options); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== OVS_VPORT_CMD_DEL ============== */ +/* OVS_VPORT_CMD_DEL - do */ +void ovs_vport_del_req_free(struct ovs_vport_del_req *req) +{ + free(req->name); + free(req); +} + +int ovs_vport_del(struct ynl_sock *ys, struct ovs_vport_del_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, OVS_VPORT_CMD_DEL, 1); + ys->req_policy = &ovs_vport_vport_nest; + + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + if (req->_present.port_no) + ynl_attr_put_u32(nlh, OVS_VPORT_ATTR_PORT_NO, req->port_no); + if (req->_present.type) + ynl_attr_put_u32(nlh, OVS_VPORT_ATTR_TYPE, req->type); + if (req->_present.name_len) + ynl_attr_put_str(nlh, OVS_VPORT_ATTR_NAME, req->name); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== OVS_VPORT_CMD_GET ============== */ +/* OVS_VPORT_CMD_GET - do */ +void ovs_vport_get_req_free(struct ovs_vport_get_req *req) +{ + free(req->name); + free(req); +} + +void ovs_vport_get_rsp_free(struct ovs_vport_get_rsp *rsp) +{ + free(rsp->name); + free(rsp->upcall_pid); + free(rsp->stats); + ovs_vport_upcall_stats_free(&rsp->upcall_stats); + free(rsp); +} + +int ovs_vport_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct ovs_vport_get_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + void *hdr; + + dst = yarg->data; + parg.ys = yarg->ys; + + hdr = ynl_nlmsg_data_offset(nlh, sizeof(struct genlmsghdr)); + memcpy(&dst->_hdr, hdr, sizeof(struct ovs_header)); + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == OVS_VPORT_ATTR_PORT_NO) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.port_no = 1; + dst->port_no = ynl_attr_get_u32(attr); + } else if (type == OVS_VPORT_ATTR_TYPE) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.type = 1; + dst->type = ynl_attr_get_u32(attr); + } else if (type == OVS_VPORT_ATTR_NAME) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = strnlen(ynl_attr_get_str(attr), ynl_attr_data_len(attr)); + dst->_present.name_len = len; + dst->name = malloc(len + 1); + memcpy(dst->name, ynl_attr_get_str(attr), len); + dst->name[len] = 0; + } else if (type == OVS_VPORT_ATTR_UPCALL_PID) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.upcall_pid_len = len; + dst->upcall_pid = malloc(len); + memcpy(dst->upcall_pid, ynl_attr_data(attr), len); + } else if (type == OVS_VPORT_ATTR_STATS) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.stats_len = len; + dst->stats = malloc(len); + memcpy(dst->stats, ynl_attr_data(attr), len); + } else if (type == OVS_VPORT_ATTR_IFINDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ifindex = 1; + dst->ifindex = ynl_attr_get_u32(attr); + } else if (type == OVS_VPORT_ATTR_NETNSID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.netnsid = 1; + dst->netnsid = ynl_attr_get_u32(attr); + } else if (type == OVS_VPORT_ATTR_UPCALL_STATS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.upcall_stats = 1; + + parg.rsp_policy = &ovs_vport_upcall_stats_nest; + parg.data = &dst->upcall_stats; + if (ovs_vport_upcall_stats_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct ovs_vport_get_rsp * +ovs_vport_get(struct ynl_sock *ys, struct ovs_vport_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct ovs_vport_get_rsp *rsp; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, OVS_VPORT_CMD_GET, 1); + ys->req_policy = &ovs_vport_vport_nest; + yrs.yarg.rsp_policy = &ovs_vport_vport_nest; + + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + if (req->_present.name_len) + ynl_attr_put_str(nlh, OVS_VPORT_ATTR_NAME, req->name); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = ovs_vport_get_rsp_parse; + yrs.rsp_cmd = OVS_VPORT_CMD_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + ovs_vport_get_rsp_free(rsp); + return NULL; +} + +/* OVS_VPORT_CMD_GET - dump */ +void ovs_vport_get_req_dump_free(struct ovs_vport_get_req_dump *req) +{ + free(req->name); + free(req); +} + +void ovs_vport_get_list_free(struct ovs_vport_get_list *rsp) +{ + struct ovs_vport_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp->obj.name); + free(rsp->obj.upcall_pid); + free(rsp->obj.stats); + ovs_vport_upcall_stats_free(&rsp->obj.upcall_stats); + free(rsp); + } +} + +struct ovs_vport_get_list * +ovs_vport_get_dump(struct ynl_sock *ys, struct ovs_vport_get_req_dump *req) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + size_t hdr_len; + void *hdr; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &ovs_vport_vport_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct ovs_vport_get_list); + yds.cb = ovs_vport_get_rsp_parse; + yds.rsp_cmd = OVS_VPORT_CMD_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, OVS_VPORT_CMD_GET, 1); + hdr_len = sizeof(req->_hdr); + hdr = ynl_nlmsg_put_extra_header(nlh, hdr_len); + memcpy(hdr, &req->_hdr, hdr_len); + + ys->req_policy = &ovs_vport_vport_nest; + + if (req->_present.name_len) + ynl_attr_put_str(nlh, OVS_VPORT_ATTR_NAME, req->name); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + ovs_vport_get_list_free(yds.first); + return NULL; +} + +const struct ynl_family ynl_ovs_vport_family = { + .name = "ovs_vport", + .hdr_len = sizeof(struct genlmsghdr), +}; diff --git a/generated/ovs_vport-user.h b/generated/ovs_vport-user.h new file mode 100644 index 0000000..493a638 --- /dev/null +++ b/generated/ovs_vport-user.h @@ -0,0 +1,270 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/ovs_vport.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_OVS_VPORT_GEN_H +#define _LINUX_OVS_VPORT_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_ovs_vport_family; + +/* Enums */ +const char *ovs_vport_op_str(int op); +const char *ovs_vport_vport_type_str(enum ovs_vport_type value); + +/* Common nested types */ +struct ovs_vport_vport_options { + struct { + __u32 dst_port:1; + __u32 extension:1; + } _present; + + __u32 dst_port; + __u32 extension; +}; + +struct ovs_vport_upcall_stats { + struct { + __u32 success:1; + __u32 fail:1; + } _present; + + __u64 success; + __u64 fail; +}; + +/* ============== OVS_VPORT_CMD_NEW ============== */ +/* OVS_VPORT_CMD_NEW - do */ +struct ovs_vport_new_req { + struct ovs_header _hdr; + + struct { + __u32 name_len; + __u32 type:1; + __u32 upcall_pid_len; + __u32 ifindex:1; + __u32 options:1; + } _present; + + char *name; + enum ovs_vport_type type; + void *upcall_pid; + __u32 ifindex; + struct ovs_vport_vport_options options; +}; + +static inline struct ovs_vport_new_req *ovs_vport_new_req_alloc(void) +{ + return calloc(1, sizeof(struct ovs_vport_new_req)); +} +void ovs_vport_new_req_free(struct ovs_vport_new_req *req); + +static inline void +ovs_vport_new_req_set_name(struct ovs_vport_new_req *req, const char *name) +{ + free(req->name); + req->_present.name_len = strlen(name); + req->name = malloc(req->_present.name_len + 1); + memcpy(req->name, name, req->_present.name_len); + req->name[req->_present.name_len] = 0; +} +static inline void +ovs_vport_new_req_set_type(struct ovs_vport_new_req *req, + enum ovs_vport_type type) +{ + req->_present.type = 1; + req->type = type; +} +static inline void +ovs_vport_new_req_set_upcall_pid(struct ovs_vport_new_req *req, + const void *upcall_pid, size_t len) +{ + free(req->upcall_pid); + req->_present.upcall_pid_len = len; + req->upcall_pid = malloc(req->_present.upcall_pid_len); + memcpy(req->upcall_pid, upcall_pid, req->_present.upcall_pid_len); +} +static inline void +ovs_vport_new_req_set_ifindex(struct ovs_vport_new_req *req, __u32 ifindex) +{ + req->_present.ifindex = 1; + req->ifindex = ifindex; +} +static inline void +ovs_vport_new_req_set_options_dst_port(struct ovs_vport_new_req *req, + __u32 dst_port) +{ + req->_present.options = 1; + req->options._present.dst_port = 1; + req->options.dst_port = dst_port; +} +static inline void +ovs_vport_new_req_set_options_extension(struct ovs_vport_new_req *req, + __u32 extension) +{ + req->_present.options = 1; + req->options._present.extension = 1; + req->options.extension = extension; +} + +/* + * Create a new OVS vport + */ +int ovs_vport_new(struct ynl_sock *ys, struct ovs_vport_new_req *req); + +/* ============== OVS_VPORT_CMD_DEL ============== */ +/* OVS_VPORT_CMD_DEL - do */ +struct ovs_vport_del_req { + struct ovs_header _hdr; + + struct { + __u32 port_no:1; + __u32 type:1; + __u32 name_len; + } _present; + + __u32 port_no; + enum ovs_vport_type type; + char *name; +}; + +static inline struct ovs_vport_del_req *ovs_vport_del_req_alloc(void) +{ + return calloc(1, sizeof(struct ovs_vport_del_req)); +} +void ovs_vport_del_req_free(struct ovs_vport_del_req *req); + +static inline void +ovs_vport_del_req_set_port_no(struct ovs_vport_del_req *req, __u32 port_no) +{ + req->_present.port_no = 1; + req->port_no = port_no; +} +static inline void +ovs_vport_del_req_set_type(struct ovs_vport_del_req *req, + enum ovs_vport_type type) +{ + req->_present.type = 1; + req->type = type; +} +static inline void +ovs_vport_del_req_set_name(struct ovs_vport_del_req *req, const char *name) +{ + free(req->name); + req->_present.name_len = strlen(name); + req->name = malloc(req->_present.name_len + 1); + memcpy(req->name, name, req->_present.name_len); + req->name[req->_present.name_len] = 0; +} + +/* + * Delete existing OVS vport from a data path + */ +int ovs_vport_del(struct ynl_sock *ys, struct ovs_vport_del_req *req); + +/* ============== OVS_VPORT_CMD_GET ============== */ +/* OVS_VPORT_CMD_GET - do */ +struct ovs_vport_get_req { + struct ovs_header _hdr; + + struct { + __u32 name_len; + } _present; + + char *name; +}; + +static inline struct ovs_vport_get_req *ovs_vport_get_req_alloc(void) +{ + return calloc(1, sizeof(struct ovs_vport_get_req)); +} +void ovs_vport_get_req_free(struct ovs_vport_get_req *req); + +static inline void +ovs_vport_get_req_set_name(struct ovs_vport_get_req *req, const char *name) +{ + free(req->name); + req->_present.name_len = strlen(name); + req->name = malloc(req->_present.name_len + 1); + memcpy(req->name, name, req->_present.name_len); + req->name[req->_present.name_len] = 0; +} + +struct ovs_vport_get_rsp { + struct ovs_header _hdr; + + struct { + __u32 port_no:1; + __u32 type:1; + __u32 name_len; + __u32 upcall_pid_len; + __u32 stats_len; + __u32 ifindex:1; + __u32 netnsid:1; + __u32 upcall_stats:1; + } _present; + + __u32 port_no; + enum ovs_vport_type type; + char *name; + void *upcall_pid; + void *stats; + __u32 ifindex; + __u32 netnsid; + struct ovs_vport_upcall_stats upcall_stats; +}; + +void ovs_vport_get_rsp_free(struct ovs_vport_get_rsp *rsp); + +/* + * Get / dump OVS vport configuration and state + */ +struct ovs_vport_get_rsp * +ovs_vport_get(struct ynl_sock *ys, struct ovs_vport_get_req *req); + +/* OVS_VPORT_CMD_GET - dump */ +struct ovs_vport_get_req_dump { + struct ovs_header _hdr; + + struct { + __u32 name_len; + } _present; + + char *name; +}; + +static inline struct ovs_vport_get_req_dump *ovs_vport_get_req_dump_alloc(void) +{ + return calloc(1, sizeof(struct ovs_vport_get_req_dump)); +} +void ovs_vport_get_req_dump_free(struct ovs_vport_get_req_dump *req); + +static inline void +ovs_vport_get_req_dump_set_name(struct ovs_vport_get_req_dump *req, + const char *name) +{ + free(req->name); + req->_present.name_len = strlen(name); + req->name = malloc(req->_present.name_len + 1); + memcpy(req->name, name, req->_present.name_len); + req->name[req->_present.name_len] = 0; +} + +struct ovs_vport_get_list { + struct ovs_vport_get_list *next; + struct ovs_vport_get_rsp obj __attribute__((aligned(8))); +}; + +void ovs_vport_get_list_free(struct ovs_vport_get_list *rsp); + +struct ovs_vport_get_list * +ovs_vport_get_dump(struct ynl_sock *ys, struct ovs_vport_get_req_dump *req); + +#endif /* _LINUX_OVS_VPORT_GEN_H */ diff --git a/generated/psp-user.c b/generated/psp-user.c new file mode 100644 index 0000000..efd0f39 --- /dev/null +++ b/generated/psp-user.c @@ -0,0 +1,668 @@ +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/psp.yaml */ +/* YNL-GEN user source */ + +#include +#include +#include "psp-user.h" +#include "ynl.h" +#include + +#include + +/* Enums */ +static const char * const psp_op_strmap[] = { + [PSP_CMD_DEV_GET] = "dev-get", + [PSP_CMD_DEV_ADD_NTF] = "dev-add-ntf", + [PSP_CMD_DEV_DEL_NTF] = "dev-del-ntf", + [PSP_CMD_DEV_SET] = "dev-set", + [PSP_CMD_DEV_CHANGE_NTF] = "dev-change-ntf", + [PSP_CMD_KEY_ROTATE] = "key-rotate", + [PSP_CMD_KEY_ROTATE_NTF] = "key-rotate-ntf", + [PSP_CMD_RX_ASSOC] = "rx-assoc", + [PSP_CMD_TX_ASSOC] = "tx-assoc", + [PSP_CMD_GET_STATS] = "get-stats", +}; + +const char *psp_op_str(int op) +{ + if (op < 0 || op >= (int)YNL_ARRAY_SIZE(psp_op_strmap)) + return NULL; + return psp_op_strmap[op]; +} + +static const char * const psp_version_strmap[] = { + [0] = "hdr0-aes-gcm-128", + [1] = "hdr0-aes-gcm-256", + [2] = "hdr0-aes-gmac-128", + [3] = "hdr0-aes-gmac-256", +}; + +const char *psp_version_str(enum psp_version value) +{ + if (value < 0 || value >= (int)YNL_ARRAY_SIZE(psp_version_strmap)) + return NULL; + return psp_version_strmap[value]; +} + +/* Policies */ +struct ynl_policy_attr psp_keys_policy[PSP_A_KEYS_MAX + 1] = { + [PSP_A_KEYS_KEY] = { .name = "key", .type = YNL_PT_BINARY,}, + [PSP_A_KEYS_SPI] = { .name = "spi", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest psp_keys_nest = { + .max_attr = PSP_A_KEYS_MAX, + .table = psp_keys_policy, +}; + +struct ynl_policy_attr psp_dev_policy[PSP_A_DEV_MAX + 1] = { + [PSP_A_DEV_ID] = { .name = "id", .type = YNL_PT_U32, }, + [PSP_A_DEV_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, }, + [PSP_A_DEV_PSP_VERSIONS_CAP] = { .name = "psp-versions-cap", .type = YNL_PT_U32, }, + [PSP_A_DEV_PSP_VERSIONS_ENA] = { .name = "psp-versions-ena", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest psp_dev_nest = { + .max_attr = PSP_A_DEV_MAX, + .table = psp_dev_policy, +}; + +struct ynl_policy_attr psp_assoc_policy[PSP_A_ASSOC_MAX + 1] = { + [PSP_A_ASSOC_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [PSP_A_ASSOC_DEV_ID] = { .name = "dev-id", .type = YNL_PT_U32, }, + [PSP_A_ASSOC_VERSION] = { .name = "version", .type = YNL_PT_U32, }, + [PSP_A_ASSOC_RX_KEY] = { .name = "rx-key", .type = YNL_PT_NEST, .nest = &psp_keys_nest, }, + [PSP_A_ASSOC_TX_KEY] = { .name = "tx-key", .type = YNL_PT_NEST, .nest = &psp_keys_nest, }, + [PSP_A_ASSOC_SOCK_FD] = { .name = "sock-fd", .type = YNL_PT_U32, }, +}; + +struct ynl_policy_nest psp_assoc_nest = { + .max_attr = PSP_A_ASSOC_MAX, + .table = psp_assoc_policy, +}; + +struct ynl_policy_attr psp_stats_policy[PSP_A_STATS_MAX + 1] = { + [PSP_A_STATS_DEV_ID] = { .name = "dev-id", .type = YNL_PT_U32, }, + [PSP_A_STATS_PAD] = { .name = "pad", .type = YNL_PT_IGNORE, }, + [PSP_A_STATS_KEY_ROTATIONS] = { .name = "key-rotations", .type = YNL_PT_U64, }, + [PSP_A_STATS_STALE_EVENTS] = { .name = "stale-events", .type = YNL_PT_U64, }, + [PSP_A_STATS_RX_PACKETS] = { .name = "rx-packets", .type = YNL_PT_U64, }, + [PSP_A_STATS_RX_BYTES] = { .name = "rx-bytes", .type = YNL_PT_U64, }, + [PSP_A_STATS_RX_AUTH_FAIL] = { .name = "rx-auth-fail", .type = YNL_PT_U64, }, + [PSP_A_STATS_RX_ERROR] = { .name = "rx-error", .type = YNL_PT_U64, }, + [PSP_A_STATS_RX_BAD] = { .name = "rx-bad", .type = YNL_PT_U64, }, + [PSP_A_STATS_TX_PACKETS] = { .name = "tx-packets", .type = YNL_PT_U64, }, + [PSP_A_STATS_TX_BYTES] = { .name = "tx-bytes", .type = YNL_PT_U64, }, + [PSP_A_STATS_TX_ERROR] = { .name = "tx-error", .type = YNL_PT_U64, }, +}; + +struct ynl_policy_nest psp_stats_nest = { + .max_attr = PSP_A_STATS_MAX, + .table = psp_stats_policy, +}; + +/* Common nested types */ +void psp_keys_free(struct psp_keys *obj) +{ + free(obj->key); +} + +int psp_keys_put(struct nlmsghdr *nlh, unsigned int attr_type, + struct psp_keys *obj) +{ + struct nlattr *nest; + + nest = ynl_attr_nest_start(nlh, attr_type); + if (obj->_present.key_len) + ynl_attr_put(nlh, PSP_A_KEYS_KEY, obj->key, obj->_present.key_len); + if (obj->_present.spi) + ynl_attr_put_u32(nlh, PSP_A_KEYS_SPI, obj->spi); + ynl_attr_nest_end(nlh, nest); + + return 0; +} + +int psp_keys_parse(struct ynl_parse_arg *yarg, const struct nlattr *nested) +{ + struct psp_keys *dst = yarg->data; + const struct nlattr *attr; + + ynl_attr_for_each_nested(attr, nested) { + unsigned int type = ynl_attr_type(attr); + + if (type == PSP_A_KEYS_KEY) { + unsigned int len; + + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + + len = ynl_attr_data_len(attr); + dst->_present.key_len = len; + dst->key = malloc(len); + memcpy(dst->key, ynl_attr_data(attr), len); + } else if (type == PSP_A_KEYS_SPI) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.spi = 1; + dst->spi = ynl_attr_get_u32(attr); + } + } + + return 0; +} + +/* ============== PSP_CMD_DEV_GET ============== */ +/* PSP_CMD_DEV_GET - do */ +void psp_dev_get_req_free(struct psp_dev_get_req *req) +{ + free(req); +} + +void psp_dev_get_rsp_free(struct psp_dev_get_rsp *rsp) +{ + free(rsp); +} + +int psp_dev_get_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct psp_dev_get_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == PSP_A_DEV_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } else if (type == PSP_A_DEV_IFINDEX) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.ifindex = 1; + dst->ifindex = ynl_attr_get_u32(attr); + } else if (type == PSP_A_DEV_PSP_VERSIONS_CAP) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.psp_versions_cap = 1; + dst->psp_versions_cap = ynl_attr_get_u32(attr); + } else if (type == PSP_A_DEV_PSP_VERSIONS_ENA) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.psp_versions_ena = 1; + dst->psp_versions_ena = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct psp_dev_get_rsp * +psp_dev_get(struct ynl_sock *ys, struct psp_dev_get_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct psp_dev_get_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, PSP_CMD_DEV_GET, 1); + ys->req_policy = &psp_dev_nest; + yrs.yarg.rsp_policy = &psp_dev_nest; + + if (req->_present.id) + ynl_attr_put_u32(nlh, PSP_A_DEV_ID, req->id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = psp_dev_get_rsp_parse; + yrs.rsp_cmd = PSP_CMD_DEV_GET; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + psp_dev_get_rsp_free(rsp); + return NULL; +} + +/* PSP_CMD_DEV_GET - dump */ +void psp_dev_get_list_free(struct psp_dev_get_list *rsp) +{ + struct psp_dev_get_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp); + } +} + +struct psp_dev_get_list *psp_dev_get_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &psp_dev_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct psp_dev_get_list); + yds.cb = psp_dev_get_rsp_parse; + yds.rsp_cmd = PSP_CMD_DEV_GET; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, PSP_CMD_DEV_GET, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + psp_dev_get_list_free(yds.first); + return NULL; +} + +/* PSP_CMD_DEV_GET - notify */ +void psp_dev_get_ntf_free(struct psp_dev_get_ntf *rsp) +{ + free(rsp); +} + +/* ============== PSP_CMD_DEV_SET ============== */ +/* PSP_CMD_DEV_SET - do */ +void psp_dev_set_req_free(struct psp_dev_set_req *req) +{ + free(req); +} + +int psp_dev_set(struct ynl_sock *ys, struct psp_dev_set_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, PSP_CMD_DEV_SET, 1); + ys->req_policy = &psp_dev_nest; + + if (req->_present.id) + ynl_attr_put_u32(nlh, PSP_A_DEV_ID, req->id); + if (req->_present.psp_versions_ena) + ynl_attr_put_u32(nlh, PSP_A_DEV_PSP_VERSIONS_ENA, req->psp_versions_ena); + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + return -1; + + return 0; +} + +/* ============== PSP_CMD_KEY_ROTATE ============== */ +/* PSP_CMD_KEY_ROTATE - do */ +void psp_key_rotate_req_free(struct psp_key_rotate_req *req) +{ + free(req); +} + +void psp_key_rotate_rsp_free(struct psp_key_rotate_rsp *rsp) +{ + free(rsp); +} + +int psp_key_rotate_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct psp_key_rotate_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == PSP_A_DEV_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.id = 1; + dst->id = ynl_attr_get_u32(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct psp_key_rotate_rsp * +psp_key_rotate(struct ynl_sock *ys, struct psp_key_rotate_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct psp_key_rotate_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, PSP_CMD_KEY_ROTATE, 1); + ys->req_policy = &psp_dev_nest; + yrs.yarg.rsp_policy = &psp_dev_nest; + + if (req->_present.id) + ynl_attr_put_u32(nlh, PSP_A_DEV_ID, req->id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = psp_key_rotate_rsp_parse; + yrs.rsp_cmd = PSP_CMD_KEY_ROTATE; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + psp_key_rotate_rsp_free(rsp); + return NULL; +} + +/* PSP_CMD_KEY_ROTATE - notify */ +void psp_key_rotate_ntf_free(struct psp_key_rotate_ntf *rsp) +{ + free(rsp); +} + +/* ============== PSP_CMD_RX_ASSOC ============== */ +/* PSP_CMD_RX_ASSOC - do */ +void psp_rx_assoc_req_free(struct psp_rx_assoc_req *req) +{ + free(req); +} + +void psp_rx_assoc_rsp_free(struct psp_rx_assoc_rsp *rsp) +{ + psp_keys_free(&rsp->rx_key); + free(rsp); +} + +int psp_rx_assoc_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct psp_rx_assoc_rsp *dst; + const struct nlattr *attr; + struct ynl_parse_arg parg; + + dst = yarg->data; + parg.ys = yarg->ys; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == PSP_A_ASSOC_DEV_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dev_id = 1; + dst->dev_id = ynl_attr_get_u32(attr); + } else if (type == PSP_A_ASSOC_VERSION) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.version = 1; + dst->version = ynl_attr_get_u32(attr); + } else if (type == PSP_A_ASSOC_RX_KEY) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.rx_key = 1; + + parg.rsp_policy = &psp_keys_nest; + parg.data = &dst->rx_key; + if (psp_keys_parse(&parg, attr)) + return YNL_PARSE_CB_ERROR; + } + } + + return YNL_PARSE_CB_OK; +} + +struct psp_rx_assoc_rsp * +psp_rx_assoc(struct ynl_sock *ys, struct psp_rx_assoc_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct psp_rx_assoc_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, PSP_CMD_RX_ASSOC, 1); + ys->req_policy = &psp_assoc_nest; + yrs.yarg.rsp_policy = &psp_assoc_nest; + + if (req->_present.dev_id) + ynl_attr_put_u32(nlh, PSP_A_ASSOC_DEV_ID, req->dev_id); + if (req->_present.version) + ynl_attr_put_u32(nlh, PSP_A_ASSOC_VERSION, req->version); + if (req->_present.sock_fd) + ynl_attr_put_u32(nlh, PSP_A_ASSOC_SOCK_FD, req->sock_fd); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = psp_rx_assoc_rsp_parse; + yrs.rsp_cmd = PSP_CMD_RX_ASSOC; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + psp_rx_assoc_rsp_free(rsp); + return NULL; +} + +/* ============== PSP_CMD_TX_ASSOC ============== */ +/* PSP_CMD_TX_ASSOC - do */ +void psp_tx_assoc_req_free(struct psp_tx_assoc_req *req) +{ + psp_keys_free(&req->tx_key); + free(req); +} + +void psp_tx_assoc_rsp_free(struct psp_tx_assoc_rsp *rsp) +{ + free(rsp); +} + +int psp_tx_assoc_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + return YNL_PARSE_CB_OK; +} + +struct psp_tx_assoc_rsp * +psp_tx_assoc(struct ynl_sock *ys, struct psp_tx_assoc_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct psp_tx_assoc_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, PSP_CMD_TX_ASSOC, 1); + ys->req_policy = &psp_assoc_nest; + yrs.yarg.rsp_policy = &psp_assoc_nest; + + if (req->_present.dev_id) + ynl_attr_put_u32(nlh, PSP_A_ASSOC_DEV_ID, req->dev_id); + if (req->_present.version) + ynl_attr_put_u32(nlh, PSP_A_ASSOC_VERSION, req->version); + if (req->_present.tx_key) + psp_keys_put(nlh, PSP_A_ASSOC_TX_KEY, &req->tx_key); + if (req->_present.sock_fd) + ynl_attr_put_u32(nlh, PSP_A_ASSOC_SOCK_FD, req->sock_fd); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = psp_tx_assoc_rsp_parse; + yrs.rsp_cmd = PSP_CMD_TX_ASSOC; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + psp_tx_assoc_rsp_free(rsp); + return NULL; +} + +/* ============== PSP_CMD_GET_STATS ============== */ +/* PSP_CMD_GET_STATS - do */ +void psp_get_stats_req_free(struct psp_get_stats_req *req) +{ + free(req); +} + +void psp_get_stats_rsp_free(struct psp_get_stats_rsp *rsp) +{ + free(rsp); +} + +int psp_get_stats_rsp_parse(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg) +{ + struct psp_get_stats_rsp *dst; + const struct nlattr *attr; + + dst = yarg->data; + + ynl_attr_for_each(attr, nlh, yarg->ys->family->hdr_len) { + unsigned int type = ynl_attr_type(attr); + + if (type == PSP_A_STATS_DEV_ID) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.dev_id = 1; + dst->dev_id = ynl_attr_get_u32(attr); + } else if (type == PSP_A_STATS_KEY_ROTATIONS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.key_rotations = 1; + dst->key_rotations = ynl_attr_get_u64(attr); + } else if (type == PSP_A_STATS_STALE_EVENTS) { + if (ynl_attr_validate(yarg, attr)) + return YNL_PARSE_CB_ERROR; + dst->_present.stale_events = 1; + dst->stale_events = ynl_attr_get_u64(attr); + } + } + + return YNL_PARSE_CB_OK; +} + +struct psp_get_stats_rsp * +psp_get_stats(struct ynl_sock *ys, struct psp_get_stats_req *req) +{ + struct ynl_req_state yrs = { .yarg = { .ys = ys, }, }; + struct psp_get_stats_rsp *rsp; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, ys->family_id, PSP_CMD_GET_STATS, 1); + ys->req_policy = &psp_stats_nest; + yrs.yarg.rsp_policy = &psp_stats_nest; + + if (req->_present.dev_id) + ynl_attr_put_u32(nlh, PSP_A_STATS_DEV_ID, req->dev_id); + + rsp = calloc(1, sizeof(*rsp)); + yrs.yarg.data = rsp; + yrs.cb = psp_get_stats_rsp_parse; + yrs.rsp_cmd = PSP_CMD_GET_STATS; + + err = ynl_exec(ys, nlh, &yrs); + if (err < 0) + goto err_free; + + return rsp; + +err_free: + psp_get_stats_rsp_free(rsp); + return NULL; +} + +/* PSP_CMD_GET_STATS - dump */ +void psp_get_stats_list_free(struct psp_get_stats_list *rsp) +{ + struct psp_get_stats_list *next = rsp; + + while ((void *)next != YNL_LIST_END) { + rsp = next; + next = rsp->next; + + free(rsp); + } +} + +struct psp_get_stats_list *psp_get_stats_dump(struct ynl_sock *ys) +{ + struct ynl_dump_state yds = {}; + struct nlmsghdr *nlh; + int err; + + yds.yarg.ys = ys; + yds.yarg.rsp_policy = &psp_stats_nest; + yds.yarg.data = NULL; + yds.alloc_sz = sizeof(struct psp_get_stats_list); + yds.cb = psp_get_stats_rsp_parse; + yds.rsp_cmd = PSP_CMD_GET_STATS; + + nlh = ynl_gemsg_start_dump(ys, ys->family_id, PSP_CMD_GET_STATS, 1); + + err = ynl_exec_dump(ys, nlh, &yds); + if (err < 0) + goto free_list; + + return yds.first; + +free_list: + psp_get_stats_list_free(yds.first); + return NULL; +} + +static const struct ynl_ntf_info psp_ntf_info[] = { + [PSP_CMD_DEV_ADD_NTF] = { + .alloc_sz = sizeof(struct psp_dev_get_ntf), + .cb = psp_dev_get_rsp_parse, + .policy = &psp_dev_nest, + .free = (void *)psp_dev_get_ntf_free, + }, + [PSP_CMD_DEV_DEL_NTF] = { + .alloc_sz = sizeof(struct psp_dev_get_ntf), + .cb = psp_dev_get_rsp_parse, + .policy = &psp_dev_nest, + .free = (void *)psp_dev_get_ntf_free, + }, + [PSP_CMD_DEV_CHANGE_NTF] = { + .alloc_sz = sizeof(struct psp_dev_get_ntf), + .cb = psp_dev_get_rsp_parse, + .policy = &psp_dev_nest, + .free = (void *)psp_dev_get_ntf_free, + }, + [PSP_CMD_KEY_ROTATE_NTF] = { + .alloc_sz = sizeof(struct psp_key_rotate_ntf), + .cb = psp_key_rotate_rsp_parse, + .policy = &psp_dev_nest, + .free = (void *)psp_key_rotate_ntf_free, + }, +}; + +const struct ynl_family ynl_psp_family = { + .name = "psp", + .hdr_len = sizeof(struct genlmsghdr), + .ntf_info = psp_ntf_info, + .ntf_info_size = YNL_ARRAY_SIZE(psp_ntf_info), +}; diff --git a/generated/psp-user.h b/generated/psp-user.h new file mode 100644 index 0000000..e9b4c1a --- /dev/null +++ b/generated/psp-user.h @@ -0,0 +1,368 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/psp.yaml */ +/* YNL-GEN user header */ + +#ifndef _LINUX_PSP_GEN_H +#define _LINUX_PSP_GEN_H + +#include +#include +#include +#include + +struct ynl_sock; + +extern const struct ynl_family ynl_psp_family; + +/* Enums */ +const char *psp_op_str(int op); +const char *psp_version_str(enum psp_version value); + +/* Common nested types */ +struct psp_keys { + struct { + __u32 key_len; + __u32 spi:1; + } _present; + + void *key; + __u32 spi; +}; + +/* ============== PSP_CMD_DEV_GET ============== */ +/* PSP_CMD_DEV_GET - do */ +struct psp_dev_get_req { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +static inline struct psp_dev_get_req *psp_dev_get_req_alloc(void) +{ + return calloc(1, sizeof(struct psp_dev_get_req)); +} +void psp_dev_get_req_free(struct psp_dev_get_req *req); + +static inline void +psp_dev_get_req_set_id(struct psp_dev_get_req *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} + +struct psp_dev_get_rsp { + struct { + __u32 id:1; + __u32 ifindex:1; + __u32 psp_versions_cap:1; + __u32 psp_versions_ena:1; + } _present; + + __u32 id; + __u32 ifindex; + __u32 psp_versions_cap; + __u32 psp_versions_ena; +}; + +void psp_dev_get_rsp_free(struct psp_dev_get_rsp *rsp); + +/* + * Get / dump information about PSP capable devices on the system. + */ +struct psp_dev_get_rsp * +psp_dev_get(struct ynl_sock *ys, struct psp_dev_get_req *req); + +/* PSP_CMD_DEV_GET - dump */ +struct psp_dev_get_list { + struct psp_dev_get_list *next; + struct psp_dev_get_rsp obj __attribute__((aligned(8))); +}; + +void psp_dev_get_list_free(struct psp_dev_get_list *rsp); + +struct psp_dev_get_list *psp_dev_get_dump(struct ynl_sock *ys); + +/* PSP_CMD_DEV_GET - notify */ +struct psp_dev_get_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct psp_dev_get_ntf *ntf); + struct psp_dev_get_rsp obj __attribute__((aligned(8))); +}; + +void psp_dev_get_ntf_free(struct psp_dev_get_ntf *rsp); + +/* ============== PSP_CMD_DEV_SET ============== */ +/* PSP_CMD_DEV_SET - do */ +struct psp_dev_set_req { + struct { + __u32 id:1; + __u32 psp_versions_ena:1; + } _present; + + __u32 id; + __u32 psp_versions_ena; +}; + +static inline struct psp_dev_set_req *psp_dev_set_req_alloc(void) +{ + return calloc(1, sizeof(struct psp_dev_set_req)); +} +void psp_dev_set_req_free(struct psp_dev_set_req *req); + +static inline void +psp_dev_set_req_set_id(struct psp_dev_set_req *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} +static inline void +psp_dev_set_req_set_psp_versions_ena(struct psp_dev_set_req *req, + __u32 psp_versions_ena) +{ + req->_present.psp_versions_ena = 1; + req->psp_versions_ena = psp_versions_ena; +} + +/* + * Set the configuration of a PSP device. + */ +int psp_dev_set(struct ynl_sock *ys, struct psp_dev_set_req *req); + +/* ============== PSP_CMD_KEY_ROTATE ============== */ +/* PSP_CMD_KEY_ROTATE - do */ +struct psp_key_rotate_req { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +static inline struct psp_key_rotate_req *psp_key_rotate_req_alloc(void) +{ + return calloc(1, sizeof(struct psp_key_rotate_req)); +} +void psp_key_rotate_req_free(struct psp_key_rotate_req *req); + +static inline void +psp_key_rotate_req_set_id(struct psp_key_rotate_req *req, __u32 id) +{ + req->_present.id = 1; + req->id = id; +} + +struct psp_key_rotate_rsp { + struct { + __u32 id:1; + } _present; + + __u32 id; +}; + +void psp_key_rotate_rsp_free(struct psp_key_rotate_rsp *rsp); + +/* + * Rotate the main key. + */ +struct psp_key_rotate_rsp * +psp_key_rotate(struct ynl_sock *ys, struct psp_key_rotate_req *req); + +/* PSP_CMD_KEY_ROTATE - notify */ +struct psp_key_rotate_ntf { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct psp_key_rotate_ntf *ntf); + struct psp_key_rotate_rsp obj __attribute__((aligned(8))); +}; + +void psp_key_rotate_ntf_free(struct psp_key_rotate_ntf *rsp); + +/* ============== PSP_CMD_RX_ASSOC ============== */ +/* PSP_CMD_RX_ASSOC - do */ +struct psp_rx_assoc_req { + struct { + __u32 dev_id:1; + __u32 version:1; + __u32 sock_fd:1; + } _present; + + __u32 dev_id; + enum psp_version version; + __u32 sock_fd; +}; + +static inline struct psp_rx_assoc_req *psp_rx_assoc_req_alloc(void) +{ + return calloc(1, sizeof(struct psp_rx_assoc_req)); +} +void psp_rx_assoc_req_free(struct psp_rx_assoc_req *req); + +static inline void +psp_rx_assoc_req_set_dev_id(struct psp_rx_assoc_req *req, __u32 dev_id) +{ + req->_present.dev_id = 1; + req->dev_id = dev_id; +} +static inline void +psp_rx_assoc_req_set_version(struct psp_rx_assoc_req *req, + enum psp_version version) +{ + req->_present.version = 1; + req->version = version; +} +static inline void +psp_rx_assoc_req_set_sock_fd(struct psp_rx_assoc_req *req, __u32 sock_fd) +{ + req->_present.sock_fd = 1; + req->sock_fd = sock_fd; +} + +struct psp_rx_assoc_rsp { + struct { + __u32 dev_id:1; + __u32 version:1; + __u32 rx_key:1; + } _present; + + __u32 dev_id; + enum psp_version version; + struct psp_keys rx_key; +}; + +void psp_rx_assoc_rsp_free(struct psp_rx_assoc_rsp *rsp); + +/* + * Allocate a new Rx key + SPI pair, associate it with a socket. + */ +struct psp_rx_assoc_rsp * +psp_rx_assoc(struct ynl_sock *ys, struct psp_rx_assoc_req *req); + +/* ============== PSP_CMD_TX_ASSOC ============== */ +/* PSP_CMD_TX_ASSOC - do */ +struct psp_tx_assoc_req { + struct { + __u32 dev_id:1; + __u32 version:1; + __u32 tx_key:1; + __u32 sock_fd:1; + } _present; + + __u32 dev_id; + enum psp_version version; + struct psp_keys tx_key; + __u32 sock_fd; +}; + +static inline struct psp_tx_assoc_req *psp_tx_assoc_req_alloc(void) +{ + return calloc(1, sizeof(struct psp_tx_assoc_req)); +} +void psp_tx_assoc_req_free(struct psp_tx_assoc_req *req); + +static inline void +psp_tx_assoc_req_set_dev_id(struct psp_tx_assoc_req *req, __u32 dev_id) +{ + req->_present.dev_id = 1; + req->dev_id = dev_id; +} +static inline void +psp_tx_assoc_req_set_version(struct psp_tx_assoc_req *req, + enum psp_version version) +{ + req->_present.version = 1; + req->version = version; +} +static inline void +psp_tx_assoc_req_set_tx_key_key(struct psp_tx_assoc_req *req, const void *key, + size_t len) +{ + free(req->tx_key.key); + req->tx_key._present.key_len = len; + req->tx_key.key = malloc(req->tx_key._present.key_len); + memcpy(req->tx_key.key, key, req->tx_key._present.key_len); +} +static inline void +psp_tx_assoc_req_set_tx_key_spi(struct psp_tx_assoc_req *req, __u32 spi) +{ + req->_present.tx_key = 1; + req->tx_key._present.spi = 1; + req->tx_key.spi = spi; +} +static inline void +psp_tx_assoc_req_set_sock_fd(struct psp_tx_assoc_req *req, __u32 sock_fd) +{ + req->_present.sock_fd = 1; + req->sock_fd = sock_fd; +} + +struct psp_tx_assoc_rsp { +}; + +void psp_tx_assoc_rsp_free(struct psp_tx_assoc_rsp *rsp); + +/* + * Add a PSP Tx association. + */ +struct psp_tx_assoc_rsp * +psp_tx_assoc(struct ynl_sock *ys, struct psp_tx_assoc_req *req); + +/* ============== PSP_CMD_GET_STATS ============== */ +/* PSP_CMD_GET_STATS - do */ +struct psp_get_stats_req { + struct { + __u32 dev_id:1; + } _present; + + __u32 dev_id; +}; + +static inline struct psp_get_stats_req *psp_get_stats_req_alloc(void) +{ + return calloc(1, sizeof(struct psp_get_stats_req)); +} +void psp_get_stats_req_free(struct psp_get_stats_req *req); + +static inline void +psp_get_stats_req_set_dev_id(struct psp_get_stats_req *req, __u32 dev_id) +{ + req->_present.dev_id = 1; + req->dev_id = dev_id; +} + +struct psp_get_stats_rsp { + struct { + __u32 dev_id:1; + __u32 key_rotations:1; + __u32 stale_events:1; + } _present; + + __u32 dev_id; + __u64 key_rotations; + __u64 stale_events; +}; + +void psp_get_stats_rsp_free(struct psp_get_stats_rsp *rsp); + +/* + * Get device statistics. + */ +struct psp_get_stats_rsp * +psp_get_stats(struct ynl_sock *ys, struct psp_get_stats_req *req); + +/* PSP_CMD_GET_STATS - dump */ +struct psp_get_stats_list { + struct psp_get_stats_list *next; + struct psp_get_stats_rsp obj __attribute__((aligned(8))); +}; + +void psp_get_stats_list_free(struct psp_get_stats_list *rsp); + +struct psp_get_stats_list *psp_get_stats_dump(struct ynl_sock *ys); + +#endif /* _LINUX_PSP_GEN_H */ diff --git a/uapi/linux/devlink.h b/uapi/linux/devlink.h new file mode 100644 index 0000000..2da0c7e --- /dev/null +++ b/uapi/linux/devlink.h @@ -0,0 +1,712 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * include/uapi/linux/devlink.h - Network physical device Netlink interface + * Copyright (c) 2016 Mellanox Technologies. All rights reserved. + * Copyright (c) 2016 Jiri Pirko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef _UAPI_LINUX_DEVLINK_H_ +#define _UAPI_LINUX_DEVLINK_H_ + +#include + +#define DEVLINK_GENL_NAME "devlink" +#define DEVLINK_GENL_VERSION 0x1 +#define DEVLINK_GENL_MCGRP_CONFIG_NAME "config" + +enum devlink_command { + /* don't change the order or add anything between, this is ABI! */ + DEVLINK_CMD_UNSPEC, + + DEVLINK_CMD_GET, /* can dump */ + DEVLINK_CMD_SET, + DEVLINK_CMD_NEW, + DEVLINK_CMD_DEL, + + DEVLINK_CMD_PORT_GET, /* can dump */ + DEVLINK_CMD_PORT_SET, + DEVLINK_CMD_PORT_NEW, + DEVLINK_CMD_PORT_DEL, + + DEVLINK_CMD_PORT_SPLIT, + DEVLINK_CMD_PORT_UNSPLIT, + + DEVLINK_CMD_SB_GET, /* can dump */ + DEVLINK_CMD_SB_SET, + DEVLINK_CMD_SB_NEW, + DEVLINK_CMD_SB_DEL, + + DEVLINK_CMD_SB_POOL_GET, /* can dump */ + DEVLINK_CMD_SB_POOL_SET, + DEVLINK_CMD_SB_POOL_NEW, + DEVLINK_CMD_SB_POOL_DEL, + + DEVLINK_CMD_SB_PORT_POOL_GET, /* can dump */ + DEVLINK_CMD_SB_PORT_POOL_SET, + DEVLINK_CMD_SB_PORT_POOL_NEW, + DEVLINK_CMD_SB_PORT_POOL_DEL, + + DEVLINK_CMD_SB_TC_POOL_BIND_GET, /* can dump */ + DEVLINK_CMD_SB_TC_POOL_BIND_SET, + DEVLINK_CMD_SB_TC_POOL_BIND_NEW, + DEVLINK_CMD_SB_TC_POOL_BIND_DEL, + + /* Shared buffer occupancy monitoring commands */ + DEVLINK_CMD_SB_OCC_SNAPSHOT, + DEVLINK_CMD_SB_OCC_MAX_CLEAR, + + DEVLINK_CMD_ESWITCH_GET, +#define DEVLINK_CMD_ESWITCH_MODE_GET /* obsolete, never use this! */ \ + DEVLINK_CMD_ESWITCH_GET + + DEVLINK_CMD_ESWITCH_SET, +#define DEVLINK_CMD_ESWITCH_MODE_SET /* obsolete, never use this! */ \ + DEVLINK_CMD_ESWITCH_SET + + DEVLINK_CMD_DPIPE_TABLE_GET, + DEVLINK_CMD_DPIPE_ENTRIES_GET, + DEVLINK_CMD_DPIPE_HEADERS_GET, + DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, + DEVLINK_CMD_RESOURCE_SET, + DEVLINK_CMD_RESOURCE_DUMP, + + /* Hot driver reload, makes configuration changes take place. The + * devlink instance is not released during the process. + */ + DEVLINK_CMD_RELOAD, + + DEVLINK_CMD_PARAM_GET, /* can dump */ + DEVLINK_CMD_PARAM_SET, + DEVLINK_CMD_PARAM_NEW, + DEVLINK_CMD_PARAM_DEL, + + DEVLINK_CMD_REGION_GET, + DEVLINK_CMD_REGION_SET, + DEVLINK_CMD_REGION_NEW, + DEVLINK_CMD_REGION_DEL, + DEVLINK_CMD_REGION_READ, + + DEVLINK_CMD_PORT_PARAM_GET, /* can dump */ + DEVLINK_CMD_PORT_PARAM_SET, + DEVLINK_CMD_PORT_PARAM_NEW, + DEVLINK_CMD_PORT_PARAM_DEL, + + DEVLINK_CMD_INFO_GET, /* can dump */ + + DEVLINK_CMD_HEALTH_REPORTER_GET, + DEVLINK_CMD_HEALTH_REPORTER_SET, + DEVLINK_CMD_HEALTH_REPORTER_RECOVER, + DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, + DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, + DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, + + DEVLINK_CMD_FLASH_UPDATE, + DEVLINK_CMD_FLASH_UPDATE_END, /* notification only */ + DEVLINK_CMD_FLASH_UPDATE_STATUS, /* notification only */ + + DEVLINK_CMD_TRAP_GET, /* can dump */ + DEVLINK_CMD_TRAP_SET, + DEVLINK_CMD_TRAP_NEW, + DEVLINK_CMD_TRAP_DEL, + + DEVLINK_CMD_TRAP_GROUP_GET, /* can dump */ + DEVLINK_CMD_TRAP_GROUP_SET, + DEVLINK_CMD_TRAP_GROUP_NEW, + DEVLINK_CMD_TRAP_GROUP_DEL, + + DEVLINK_CMD_TRAP_POLICER_GET, /* can dump */ + DEVLINK_CMD_TRAP_POLICER_SET, + DEVLINK_CMD_TRAP_POLICER_NEW, + DEVLINK_CMD_TRAP_POLICER_DEL, + + DEVLINK_CMD_HEALTH_REPORTER_TEST, + + DEVLINK_CMD_RATE_GET, /* can dump */ + DEVLINK_CMD_RATE_SET, + DEVLINK_CMD_RATE_NEW, + DEVLINK_CMD_RATE_DEL, + + DEVLINK_CMD_LINECARD_GET, /* can dump */ + DEVLINK_CMD_LINECARD_SET, + DEVLINK_CMD_LINECARD_NEW, + DEVLINK_CMD_LINECARD_DEL, + + DEVLINK_CMD_SELFTESTS_GET, /* can dump */ + DEVLINK_CMD_SELFTESTS_RUN, + + DEVLINK_CMD_NOTIFY_FILTER_SET, + + /* add new commands above here */ + __DEVLINK_CMD_MAX, + DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1 +}; + +enum devlink_port_type { + DEVLINK_PORT_TYPE_NOTSET, + DEVLINK_PORT_TYPE_AUTO, + DEVLINK_PORT_TYPE_ETH, + DEVLINK_PORT_TYPE_IB, +}; + +enum devlink_sb_pool_type { + DEVLINK_SB_POOL_TYPE_INGRESS, + DEVLINK_SB_POOL_TYPE_EGRESS, +}; + +/* static threshold - limiting the maximum number of bytes. + * dynamic threshold - limiting the maximum number of bytes + * based on the currently available free space in the shared buffer pool. + * In this mode, the maximum quota is calculated based + * on the following formula: + * max_quota = alpha / (1 + alpha) * Free_Buffer + * While Free_Buffer is the amount of none-occupied buffer associated to + * the relevant pool. + * The value range which can be passed is 0-20 and serves + * for computation of alpha by following formula: + * alpha = 2 ^ (passed_value - 10) + */ + +enum devlink_sb_threshold_type { + DEVLINK_SB_THRESHOLD_TYPE_STATIC, + DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC, +}; + +#define DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX 20 + +enum devlink_eswitch_mode { + DEVLINK_ESWITCH_MODE_LEGACY, + DEVLINK_ESWITCH_MODE_SWITCHDEV, +}; + +enum devlink_eswitch_inline_mode { + DEVLINK_ESWITCH_INLINE_MODE_NONE, + DEVLINK_ESWITCH_INLINE_MODE_LINK, + DEVLINK_ESWITCH_INLINE_MODE_NETWORK, + DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT, +}; + +enum devlink_eswitch_encap_mode { + DEVLINK_ESWITCH_ENCAP_MODE_NONE, + DEVLINK_ESWITCH_ENCAP_MODE_BASIC, +}; + +enum devlink_port_flavour { + DEVLINK_PORT_FLAVOUR_PHYSICAL, /* Any kind of a port physically + * facing the user. + */ + DEVLINK_PORT_FLAVOUR_CPU, /* CPU port */ + DEVLINK_PORT_FLAVOUR_DSA, /* Distributed switch architecture + * interconnect port. + */ + DEVLINK_PORT_FLAVOUR_PCI_PF, /* Represents eswitch port for + * the PCI PF. It is an internal + * port that faces the PCI PF. + */ + DEVLINK_PORT_FLAVOUR_PCI_VF, /* Represents eswitch port + * for the PCI VF. It is an internal + * port that faces the PCI VF. + */ + DEVLINK_PORT_FLAVOUR_VIRTUAL, /* Any virtual port facing the user. */ + DEVLINK_PORT_FLAVOUR_UNUSED, /* Port which exists in the switch, but + * is not used in any way. + */ + DEVLINK_PORT_FLAVOUR_PCI_SF, /* Represents eswitch port + * for the PCI SF. It is an internal + * port that faces the PCI SF. + */ +}; + +enum devlink_rate_type { + DEVLINK_RATE_TYPE_LEAF, + DEVLINK_RATE_TYPE_NODE, +}; + +enum devlink_param_cmode { + DEVLINK_PARAM_CMODE_RUNTIME, + DEVLINK_PARAM_CMODE_DRIVERINIT, + DEVLINK_PARAM_CMODE_PERMANENT, + + /* Add new configuration modes above */ + __DEVLINK_PARAM_CMODE_MAX, + DEVLINK_PARAM_CMODE_MAX = __DEVLINK_PARAM_CMODE_MAX - 1 +}; + +enum devlink_param_fw_load_policy_value { + DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DRIVER, + DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_FLASH, + DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_DISK, + DEVLINK_PARAM_FW_LOAD_POLICY_VALUE_UNKNOWN, +}; + +enum devlink_param_reset_dev_on_drv_probe_value { + DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_UNKNOWN, + DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_ALWAYS, + DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_NEVER, + DEVLINK_PARAM_RESET_DEV_ON_DRV_PROBE_VALUE_DISK, +}; + +enum { + DEVLINK_ATTR_STATS_RX_PACKETS, /* u64 */ + DEVLINK_ATTR_STATS_RX_BYTES, /* u64 */ + DEVLINK_ATTR_STATS_RX_DROPPED, /* u64 */ + + __DEVLINK_ATTR_STATS_MAX, + DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1 +}; + +/* Specify what sections of a flash component can be overwritten when + * performing an update. Overwriting of firmware binary sections is always + * implicitly assumed to be allowed. + * + * Each section must be documented in + * Documentation/networking/devlink/devlink-flash.rst + * + */ +enum devlink_flash_overwrite { + DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT, + DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT, + + __DEVLINK_FLASH_OVERWRITE_MAX_BIT, + DEVLINK_FLASH_OVERWRITE_MAX_BIT = __DEVLINK_FLASH_OVERWRITE_MAX_BIT - 1 +}; + +#define DEVLINK_FLASH_OVERWRITE_SETTINGS _BITUL(DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT) +#define DEVLINK_FLASH_OVERWRITE_IDENTIFIERS _BITUL(DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT) + +#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \ + (_BITUL(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1) + +enum devlink_attr_selftest_id { + DEVLINK_ATTR_SELFTEST_ID_UNSPEC, + DEVLINK_ATTR_SELFTEST_ID_FLASH, /* flag */ + + __DEVLINK_ATTR_SELFTEST_ID_MAX, + DEVLINK_ATTR_SELFTEST_ID_MAX = __DEVLINK_ATTR_SELFTEST_ID_MAX - 1 +}; + +enum devlink_selftest_status { + DEVLINK_SELFTEST_STATUS_SKIP, + DEVLINK_SELFTEST_STATUS_PASS, + DEVLINK_SELFTEST_STATUS_FAIL +}; + +enum devlink_attr_selftest_result { + DEVLINK_ATTR_SELFTEST_RESULT_UNSPEC, + DEVLINK_ATTR_SELFTEST_RESULT, /* nested */ + DEVLINK_ATTR_SELFTEST_RESULT_ID, /* u32, enum devlink_attr_selftest_id */ + DEVLINK_ATTR_SELFTEST_RESULT_STATUS, /* u8, enum devlink_selftest_status */ + + __DEVLINK_ATTR_SELFTEST_RESULT_MAX, + DEVLINK_ATTR_SELFTEST_RESULT_MAX = __DEVLINK_ATTR_SELFTEST_RESULT_MAX - 1 +}; + +/** + * enum devlink_trap_action - Packet trap action. + * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not + * sent to the CPU. + * @DEVLINK_TRAP_ACTION_TRAP: The sole copy of the packet is sent to the CPU. + * @DEVLINK_TRAP_ACTION_MIRROR: Packet is forwarded by the device and a copy is + * sent to the CPU. + */ +enum devlink_trap_action { + DEVLINK_TRAP_ACTION_DROP, + DEVLINK_TRAP_ACTION_TRAP, + DEVLINK_TRAP_ACTION_MIRROR, +}; + +/** + * enum devlink_trap_type - Packet trap type. + * @DEVLINK_TRAP_TYPE_DROP: Trap reason is a drop. Trapped packets are only + * processed by devlink and not injected to the + * kernel's Rx path. + * @DEVLINK_TRAP_TYPE_EXCEPTION: Trap reason is an exception. Packet was not + * forwarded as intended due to an exception + * (e.g., missing neighbour entry) and trapped to + * control plane for resolution. Trapped packets + * are processed by devlink and injected to + * the kernel's Rx path. + * @DEVLINK_TRAP_TYPE_CONTROL: Packet was trapped because it is required for + * the correct functioning of the control plane. + * For example, an ARP request packet. Trapped + * packets are injected to the kernel's Rx path, + * but not reported to drop monitor. + */ +enum devlink_trap_type { + DEVLINK_TRAP_TYPE_DROP, + DEVLINK_TRAP_TYPE_EXCEPTION, + DEVLINK_TRAP_TYPE_CONTROL, +}; + +enum { + /* Trap can report input port as metadata */ + DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT, + /* Trap can report flow action cookie as metadata */ + DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE, +}; + +enum devlink_reload_action { + DEVLINK_RELOAD_ACTION_UNSPEC, + DEVLINK_RELOAD_ACTION_DRIVER_REINIT, /* Driver entities re-instantiation */ + DEVLINK_RELOAD_ACTION_FW_ACTIVATE, /* FW activate */ + + /* Add new reload actions above */ + __DEVLINK_RELOAD_ACTION_MAX, + DEVLINK_RELOAD_ACTION_MAX = __DEVLINK_RELOAD_ACTION_MAX - 1 +}; + +enum devlink_reload_limit { + DEVLINK_RELOAD_LIMIT_UNSPEC, /* unspecified, no constraints */ + DEVLINK_RELOAD_LIMIT_NO_RESET, /* No reset allowed, no down time allowed, + * no link flap and no configuration is lost. + */ + + /* Add new reload limit above */ + __DEVLINK_RELOAD_LIMIT_MAX, + DEVLINK_RELOAD_LIMIT_MAX = __DEVLINK_RELOAD_LIMIT_MAX - 1 +}; + +#define DEVLINK_RELOAD_LIMITS_VALID_MASK (_BITUL(__DEVLINK_RELOAD_LIMIT_MAX) - 1) + +enum devlink_linecard_state { + DEVLINK_LINECARD_STATE_UNSPEC, + DEVLINK_LINECARD_STATE_UNPROVISIONED, + DEVLINK_LINECARD_STATE_UNPROVISIONING, + DEVLINK_LINECARD_STATE_PROVISIONING, + DEVLINK_LINECARD_STATE_PROVISIONING_FAILED, + DEVLINK_LINECARD_STATE_PROVISIONED, + DEVLINK_LINECARD_STATE_ACTIVE, + + __DEVLINK_LINECARD_STATE_MAX, + DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1 +}; + +enum devlink_attr { + /* don't change the order or add anything between, this is ABI! */ + DEVLINK_ATTR_UNSPEC, + + /* bus name + dev name together are a handle for devlink entity */ + DEVLINK_ATTR_BUS_NAME, /* string */ + DEVLINK_ATTR_DEV_NAME, /* string */ + + DEVLINK_ATTR_PORT_INDEX, /* u32 */ + DEVLINK_ATTR_PORT_TYPE, /* u16 */ + DEVLINK_ATTR_PORT_DESIRED_TYPE, /* u16 */ + DEVLINK_ATTR_PORT_NETDEV_IFINDEX, /* u32 */ + DEVLINK_ATTR_PORT_NETDEV_NAME, /* string */ + DEVLINK_ATTR_PORT_IBDEV_NAME, /* string */ + DEVLINK_ATTR_PORT_SPLIT_COUNT, /* u32 */ + DEVLINK_ATTR_PORT_SPLIT_GROUP, /* u32 */ + DEVLINK_ATTR_SB_INDEX, /* u32 */ + DEVLINK_ATTR_SB_SIZE, /* u32 */ + DEVLINK_ATTR_SB_INGRESS_POOL_COUNT, /* u16 */ + DEVLINK_ATTR_SB_EGRESS_POOL_COUNT, /* u16 */ + DEVLINK_ATTR_SB_INGRESS_TC_COUNT, /* u16 */ + DEVLINK_ATTR_SB_EGRESS_TC_COUNT, /* u16 */ + DEVLINK_ATTR_SB_POOL_INDEX, /* u16 */ + DEVLINK_ATTR_SB_POOL_TYPE, /* u8 */ + DEVLINK_ATTR_SB_POOL_SIZE, /* u32 */ + DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE, /* u8 */ + DEVLINK_ATTR_SB_THRESHOLD, /* u32 */ + DEVLINK_ATTR_SB_TC_INDEX, /* u16 */ + DEVLINK_ATTR_SB_OCC_CUR, /* u32 */ + DEVLINK_ATTR_SB_OCC_MAX, /* u32 */ + DEVLINK_ATTR_ESWITCH_MODE, /* u16 */ + DEVLINK_ATTR_ESWITCH_INLINE_MODE, /* u8 */ + + DEVLINK_ATTR_DPIPE_TABLES, /* nested */ + DEVLINK_ATTR_DPIPE_TABLE, /* nested */ + DEVLINK_ATTR_DPIPE_TABLE_NAME, /* string */ + DEVLINK_ATTR_DPIPE_TABLE_SIZE, /* u64 */ + DEVLINK_ATTR_DPIPE_TABLE_MATCHES, /* nested */ + DEVLINK_ATTR_DPIPE_TABLE_ACTIONS, /* nested */ + DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED, /* u8 */ + + DEVLINK_ATTR_DPIPE_ENTRIES, /* nested */ + DEVLINK_ATTR_DPIPE_ENTRY, /* nested */ + DEVLINK_ATTR_DPIPE_ENTRY_INDEX, /* u64 */ + DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES, /* nested */ + DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES, /* nested */ + DEVLINK_ATTR_DPIPE_ENTRY_COUNTER, /* u64 */ + + DEVLINK_ATTR_DPIPE_MATCH, /* nested */ + DEVLINK_ATTR_DPIPE_MATCH_VALUE, /* nested */ + DEVLINK_ATTR_DPIPE_MATCH_TYPE, /* u32 */ + + DEVLINK_ATTR_DPIPE_ACTION, /* nested */ + DEVLINK_ATTR_DPIPE_ACTION_VALUE, /* nested */ + DEVLINK_ATTR_DPIPE_ACTION_TYPE, /* u32 */ + + DEVLINK_ATTR_DPIPE_VALUE, + DEVLINK_ATTR_DPIPE_VALUE_MASK, + DEVLINK_ATTR_DPIPE_VALUE_MAPPING, /* u32 */ + + DEVLINK_ATTR_DPIPE_HEADERS, /* nested */ + DEVLINK_ATTR_DPIPE_HEADER, /* nested */ + DEVLINK_ATTR_DPIPE_HEADER_NAME, /* string */ + DEVLINK_ATTR_DPIPE_HEADER_ID, /* u32 */ + DEVLINK_ATTR_DPIPE_HEADER_FIELDS, /* nested */ + DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, /* u8 */ + DEVLINK_ATTR_DPIPE_HEADER_INDEX, /* u32 */ + + DEVLINK_ATTR_DPIPE_FIELD, /* nested */ + DEVLINK_ATTR_DPIPE_FIELD_NAME, /* string */ + DEVLINK_ATTR_DPIPE_FIELD_ID, /* u32 */ + DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, /* u32 */ + DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, /* u32 */ + + DEVLINK_ATTR_PAD, + + DEVLINK_ATTR_ESWITCH_ENCAP_MODE, /* u8 */ + DEVLINK_ATTR_RESOURCE_LIST, /* nested */ + DEVLINK_ATTR_RESOURCE, /* nested */ + DEVLINK_ATTR_RESOURCE_NAME, /* string */ + DEVLINK_ATTR_RESOURCE_ID, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE_NEW, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE_VALID, /* u8 */ + DEVLINK_ATTR_RESOURCE_SIZE_MIN, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE_MAX, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE_GRAN, /* u64 */ + DEVLINK_ATTR_RESOURCE_UNIT, /* u8 */ + DEVLINK_ATTR_RESOURCE_OCC, /* u64 */ + DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID, /* u64 */ + DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,/* u64 */ + + DEVLINK_ATTR_PORT_FLAVOUR, /* u16 */ + DEVLINK_ATTR_PORT_NUMBER, /* u32 */ + DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER, /* u32 */ + + DEVLINK_ATTR_PARAM, /* nested */ + DEVLINK_ATTR_PARAM_NAME, /* string */ + DEVLINK_ATTR_PARAM_GENERIC, /* flag */ + DEVLINK_ATTR_PARAM_TYPE, /* u8 */ + DEVLINK_ATTR_PARAM_VALUES_LIST, /* nested */ + DEVLINK_ATTR_PARAM_VALUE, /* nested */ + DEVLINK_ATTR_PARAM_VALUE_DATA, /* dynamic */ + DEVLINK_ATTR_PARAM_VALUE_CMODE, /* u8 */ + + DEVLINK_ATTR_REGION_NAME, /* string */ + DEVLINK_ATTR_REGION_SIZE, /* u64 */ + DEVLINK_ATTR_REGION_SNAPSHOTS, /* nested */ + DEVLINK_ATTR_REGION_SNAPSHOT, /* nested */ + DEVLINK_ATTR_REGION_SNAPSHOT_ID, /* u32 */ + + DEVLINK_ATTR_REGION_CHUNKS, /* nested */ + DEVLINK_ATTR_REGION_CHUNK, /* nested */ + DEVLINK_ATTR_REGION_CHUNK_DATA, /* binary */ + DEVLINK_ATTR_REGION_CHUNK_ADDR, /* u64 */ + DEVLINK_ATTR_REGION_CHUNK_LEN, /* u64 */ + + DEVLINK_ATTR_INFO_DRIVER_NAME, /* string */ + DEVLINK_ATTR_INFO_SERIAL_NUMBER, /* string */ + DEVLINK_ATTR_INFO_VERSION_FIXED, /* nested */ + DEVLINK_ATTR_INFO_VERSION_RUNNING, /* nested */ + DEVLINK_ATTR_INFO_VERSION_STORED, /* nested */ + DEVLINK_ATTR_INFO_VERSION_NAME, /* string */ + DEVLINK_ATTR_INFO_VERSION_VALUE, /* string */ + + DEVLINK_ATTR_SB_POOL_CELL_SIZE, /* u32 */ + + DEVLINK_ATTR_FMSG, /* nested */ + DEVLINK_ATTR_FMSG_OBJ_NEST_START, /* flag */ + DEVLINK_ATTR_FMSG_PAIR_NEST_START, /* flag */ + DEVLINK_ATTR_FMSG_ARR_NEST_START, /* flag */ + DEVLINK_ATTR_FMSG_NEST_END, /* flag */ + DEVLINK_ATTR_FMSG_OBJ_NAME, /* string */ + DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE, /* u8 */ + DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA, /* dynamic */ + + DEVLINK_ATTR_HEALTH_REPORTER, /* nested */ + DEVLINK_ATTR_HEALTH_REPORTER_NAME, /* string */ + DEVLINK_ATTR_HEALTH_REPORTER_STATE, /* u8 */ + DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT, /* u64 */ + DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT, /* u64 */ + DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS, /* u64 */ + DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD, /* u64 */ + DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER, /* u8 */ + + DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME, /* string */ + DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, /* string */ + DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG, /* string */ + DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE, /* u64 */ + DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL, /* u64 */ + + DEVLINK_ATTR_PORT_PCI_PF_NUMBER, /* u16 */ + DEVLINK_ATTR_PORT_PCI_VF_NUMBER, /* u16 */ + + DEVLINK_ATTR_STATS, /* nested */ + + DEVLINK_ATTR_TRAP_NAME, /* string */ + /* enum devlink_trap_action */ + DEVLINK_ATTR_TRAP_ACTION, /* u8 */ + /* enum devlink_trap_type */ + DEVLINK_ATTR_TRAP_TYPE, /* u8 */ + DEVLINK_ATTR_TRAP_GENERIC, /* flag */ + DEVLINK_ATTR_TRAP_METADATA, /* nested */ + DEVLINK_ATTR_TRAP_GROUP_NAME, /* string */ + + DEVLINK_ATTR_RELOAD_FAILED, /* u8 0 or 1 */ + + DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS, /* u64 */ + + DEVLINK_ATTR_NETNS_FD, /* u32 */ + DEVLINK_ATTR_NETNS_PID, /* u32 */ + DEVLINK_ATTR_NETNS_ID, /* u32 */ + + DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, /* u8 */ + + DEVLINK_ATTR_TRAP_POLICER_ID, /* u32 */ + DEVLINK_ATTR_TRAP_POLICER_RATE, /* u64 */ + DEVLINK_ATTR_TRAP_POLICER_BURST, /* u64 */ + + DEVLINK_ATTR_PORT_FUNCTION, /* nested */ + + DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER, /* string */ + + DEVLINK_ATTR_PORT_LANES, /* u32 */ + DEVLINK_ATTR_PORT_SPLITTABLE, /* u8 */ + + DEVLINK_ATTR_PORT_EXTERNAL, /* u8 */ + DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, /* u32 */ + + DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT, /* u64 */ + DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK, /* bitfield32 */ + + DEVLINK_ATTR_RELOAD_ACTION, /* u8 */ + DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, /* bitfield32 */ + DEVLINK_ATTR_RELOAD_LIMITS, /* bitfield32 */ + + DEVLINK_ATTR_DEV_STATS, /* nested */ + DEVLINK_ATTR_RELOAD_STATS, /* nested */ + DEVLINK_ATTR_RELOAD_STATS_ENTRY, /* nested */ + DEVLINK_ATTR_RELOAD_STATS_LIMIT, /* u8 */ + DEVLINK_ATTR_RELOAD_STATS_VALUE, /* u32 */ + DEVLINK_ATTR_REMOTE_RELOAD_STATS, /* nested */ + DEVLINK_ATTR_RELOAD_ACTION_INFO, /* nested */ + DEVLINK_ATTR_RELOAD_ACTION_STATS, /* nested */ + + DEVLINK_ATTR_PORT_PCI_SF_NUMBER, /* u32 */ + + DEVLINK_ATTR_RATE_TYPE, /* u16 */ + DEVLINK_ATTR_RATE_TX_SHARE, /* u64 */ + DEVLINK_ATTR_RATE_TX_MAX, /* u64 */ + DEVLINK_ATTR_RATE_NODE_NAME, /* string */ + DEVLINK_ATTR_RATE_PARENT_NODE_NAME, /* string */ + + DEVLINK_ATTR_REGION_MAX_SNAPSHOTS, /* u32 */ + + DEVLINK_ATTR_LINECARD_INDEX, /* u32 */ + DEVLINK_ATTR_LINECARD_STATE, /* u8 */ + DEVLINK_ATTR_LINECARD_TYPE, /* string */ + DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES, /* nested */ + + DEVLINK_ATTR_NESTED_DEVLINK, /* nested */ + + DEVLINK_ATTR_SELFTESTS, /* nested */ + + DEVLINK_ATTR_RATE_TX_PRIORITY, /* u32 */ + DEVLINK_ATTR_RATE_TX_WEIGHT, /* u32 */ + + DEVLINK_ATTR_REGION_DIRECT, /* flag */ + + /* Add new attributes above here, update the spec in + * Documentation/netlink/specs/devlink.yaml and re-generate + * net/devlink/netlink_gen.c. + */ + + __DEVLINK_ATTR_MAX, + DEVLINK_ATTR_MAX = __DEVLINK_ATTR_MAX - 1 +}; + +/* Mapping between internal resource described by the field and system + * structure + */ +enum devlink_dpipe_field_mapping_type { + DEVLINK_DPIPE_FIELD_MAPPING_TYPE_NONE, + DEVLINK_DPIPE_FIELD_MAPPING_TYPE_IFINDEX, +}; + +/* Match type - specify the type of the match */ +enum devlink_dpipe_match_type { + DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT, +}; + +/* Action type - specify the action type */ +enum devlink_dpipe_action_type { + DEVLINK_DPIPE_ACTION_TYPE_FIELD_MODIFY, +}; + +enum devlink_dpipe_field_ethernet_id { + DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC, +}; + +enum devlink_dpipe_field_ipv4_id { + DEVLINK_DPIPE_FIELD_IPV4_DST_IP, +}; + +enum devlink_dpipe_field_ipv6_id { + DEVLINK_DPIPE_FIELD_IPV6_DST_IP, +}; + +enum devlink_dpipe_header_id { + DEVLINK_DPIPE_HEADER_ETHERNET, + DEVLINK_DPIPE_HEADER_IPV4, + DEVLINK_DPIPE_HEADER_IPV6, +}; + +enum devlink_resource_unit { + DEVLINK_RESOURCE_UNIT_ENTRY, +}; + +enum devlink_port_fn_attr_cap { + DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT, + DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT, + DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT, + DEVLINK_PORT_FN_ATTR_CAP_IPSEC_PACKET_BIT, + + /* Add new caps above */ + __DEVLINK_PORT_FN_ATTR_CAPS_MAX, +}; + +#define DEVLINK_PORT_FN_CAP_ROCE _BITUL(DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT) +#define DEVLINK_PORT_FN_CAP_MIGRATABLE \ + _BITUL(DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT) +#define DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT) +#define DEVLINK_PORT_FN_CAP_IPSEC_PACKET _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_PACKET_BIT) + +enum devlink_port_function_attr { + DEVLINK_PORT_FUNCTION_ATTR_UNSPEC, + DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, /* binary */ + DEVLINK_PORT_FN_ATTR_STATE, /* u8 */ + DEVLINK_PORT_FN_ATTR_OPSTATE, /* u8 */ + DEVLINK_PORT_FN_ATTR_CAPS, /* bitfield32 */ + DEVLINK_PORT_FN_ATTR_DEVLINK, /* nested */ + + __DEVLINK_PORT_FUNCTION_ATTR_MAX, + DEVLINK_PORT_FUNCTION_ATTR_MAX = __DEVLINK_PORT_FUNCTION_ATTR_MAX - 1 +}; + +enum devlink_port_fn_state { + DEVLINK_PORT_FN_STATE_INACTIVE, + DEVLINK_PORT_FN_STATE_ACTIVE, +}; + +/** + * enum devlink_port_fn_opstate - indicates operational state of the function + * @DEVLINK_PORT_FN_OPSTATE_ATTACHED: Driver is attached to the function. + * For graceful tear down of the function, after inactivation of the + * function, user should wait for operational state to turn DETACHED. + * @DEVLINK_PORT_FN_OPSTATE_DETACHED: Driver is detached from the function. + * It is safe to delete the port. + */ +enum devlink_port_fn_opstate { + DEVLINK_PORT_FN_OPSTATE_DETACHED, + DEVLINK_PORT_FN_OPSTATE_ATTACHED, +}; + +#endif /* _UAPI_LINUX_DEVLINK_H_ */ diff --git a/uapi/linux/dpll.h b/uapi/linux/dpll.h new file mode 100644 index 0000000..0c13d7f --- /dev/null +++ b/uapi/linux/dpll.h @@ -0,0 +1,238 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/dpll.yaml */ +/* YNL-GEN uapi header */ + +#ifndef _UAPI_LINUX_DPLL_H +#define _UAPI_LINUX_DPLL_H + +#define DPLL_FAMILY_NAME "dpll" +#define DPLL_FAMILY_VERSION 1 + +/** + * enum dpll_mode - working modes a dpll can support, differentiates if and how + * dpll selects one of its inputs to syntonize with it, valid values for + * DPLL_A_MODE attribute + * @DPLL_MODE_MANUAL: input can be only selected by sending a request to dpll + * @DPLL_MODE_AUTOMATIC: highest prio input pin auto selected by dpll + */ +enum dpll_mode { + DPLL_MODE_MANUAL = 1, + DPLL_MODE_AUTOMATIC, + + /* private: */ + __DPLL_MODE_MAX, + DPLL_MODE_MAX = (__DPLL_MODE_MAX - 1) +}; + +/** + * enum dpll_lock_status - provides information of dpll device lock status, + * valid values for DPLL_A_LOCK_STATUS attribute + * @DPLL_LOCK_STATUS_UNLOCKED: dpll was not yet locked to any valid input (or + * forced by setting DPLL_A_MODE to DPLL_MODE_DETACHED) + * @DPLL_LOCK_STATUS_LOCKED: dpll is locked to a valid signal, but no holdover + * available + * @DPLL_LOCK_STATUS_LOCKED_HO_ACQ: dpll is locked and holdover acquired + * @DPLL_LOCK_STATUS_HOLDOVER: dpll is in holdover state - lost a valid lock or + * was forced by disconnecting all the pins (latter possible only when dpll + * lock-state was already DPLL_LOCK_STATUS_LOCKED_HO_ACQ, if dpll lock-state + * was not DPLL_LOCK_STATUS_LOCKED_HO_ACQ, the dpll's lock-state shall remain + * DPLL_LOCK_STATUS_UNLOCKED) + */ +enum dpll_lock_status { + DPLL_LOCK_STATUS_UNLOCKED = 1, + DPLL_LOCK_STATUS_LOCKED, + DPLL_LOCK_STATUS_LOCKED_HO_ACQ, + DPLL_LOCK_STATUS_HOLDOVER, + + /* private: */ + __DPLL_LOCK_STATUS_MAX, + DPLL_LOCK_STATUS_MAX = (__DPLL_LOCK_STATUS_MAX - 1) +}; + +/** + * enum dpll_lock_status_error - if previous status change was done due to a + * failure, this provides information of dpll device lock status error. Valid + * values for DPLL_A_LOCK_STATUS_ERROR attribute + * @DPLL_LOCK_STATUS_ERROR_NONE: dpll device lock status was changed without + * any error + * @DPLL_LOCK_STATUS_ERROR_UNDEFINED: dpll device lock status was changed due + * to undefined error. Driver fills this value up in case it is not able to + * obtain suitable exact error type. + * @DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN: dpll device lock status was changed + * because of associated media got down. This may happen for example if dpll + * device was previously locked on an input pin of type + * PIN_TYPE_SYNCE_ETH_PORT. + * @DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH: the FFO + * (Fractional Frequency Offset) between the RX and TX symbol rate on the + * media got too high. This may happen for example if dpll device was + * previously locked on an input pin of type PIN_TYPE_SYNCE_ETH_PORT. + */ +enum dpll_lock_status_error { + DPLL_LOCK_STATUS_ERROR_NONE = 1, + DPLL_LOCK_STATUS_ERROR_UNDEFINED, + DPLL_LOCK_STATUS_ERROR_MEDIA_DOWN, + DPLL_LOCK_STATUS_ERROR_FRACTIONAL_FREQUENCY_OFFSET_TOO_HIGH, + + /* private: */ + __DPLL_LOCK_STATUS_ERROR_MAX, + DPLL_LOCK_STATUS_ERROR_MAX = (__DPLL_LOCK_STATUS_ERROR_MAX - 1) +}; + +#define DPLL_TEMP_DIVIDER 1000 + +/** + * enum dpll_type - type of dpll, valid values for DPLL_A_TYPE attribute + * @DPLL_TYPE_PPS: dpll produces Pulse-Per-Second signal + * @DPLL_TYPE_EEC: dpll drives the Ethernet Equipment Clock + */ +enum dpll_type { + DPLL_TYPE_PPS = 1, + DPLL_TYPE_EEC, + + /* private: */ + __DPLL_TYPE_MAX, + DPLL_TYPE_MAX = (__DPLL_TYPE_MAX - 1) +}; + +/** + * enum dpll_pin_type - defines possible types of a pin, valid values for + * DPLL_A_PIN_TYPE attribute + * @DPLL_PIN_TYPE_MUX: aggregates another layer of selectable pins + * @DPLL_PIN_TYPE_EXT: external input + * @DPLL_PIN_TYPE_SYNCE_ETH_PORT: ethernet port PHY's recovered clock + * @DPLL_PIN_TYPE_INT_OSCILLATOR: device internal oscillator + * @DPLL_PIN_TYPE_GNSS: GNSS recovered clock + */ +enum dpll_pin_type { + DPLL_PIN_TYPE_MUX = 1, + DPLL_PIN_TYPE_EXT, + DPLL_PIN_TYPE_SYNCE_ETH_PORT, + DPLL_PIN_TYPE_INT_OSCILLATOR, + DPLL_PIN_TYPE_GNSS, + + /* private: */ + __DPLL_PIN_TYPE_MAX, + DPLL_PIN_TYPE_MAX = (__DPLL_PIN_TYPE_MAX - 1) +}; + +/** + * enum dpll_pin_direction - defines possible direction of a pin, valid values + * for DPLL_A_PIN_DIRECTION attribute + * @DPLL_PIN_DIRECTION_INPUT: pin used as a input of a signal + * @DPLL_PIN_DIRECTION_OUTPUT: pin used to output the signal + */ +enum dpll_pin_direction { + DPLL_PIN_DIRECTION_INPUT = 1, + DPLL_PIN_DIRECTION_OUTPUT, + + /* private: */ + __DPLL_PIN_DIRECTION_MAX, + DPLL_PIN_DIRECTION_MAX = (__DPLL_PIN_DIRECTION_MAX - 1) +}; + +#define DPLL_PIN_FREQUENCY_1_HZ 1 +#define DPLL_PIN_FREQUENCY_10_KHZ 10000 +#define DPLL_PIN_FREQUENCY_77_5_KHZ 77500 +#define DPLL_PIN_FREQUENCY_10_MHZ 10000000 + +/** + * enum dpll_pin_state - defines possible states of a pin, valid values for + * DPLL_A_PIN_STATE attribute + * @DPLL_PIN_STATE_CONNECTED: pin connected, active input of phase locked loop + * @DPLL_PIN_STATE_DISCONNECTED: pin disconnected, not considered as a valid + * input + * @DPLL_PIN_STATE_SELECTABLE: pin enabled for automatic input selection + */ +enum dpll_pin_state { + DPLL_PIN_STATE_CONNECTED = 1, + DPLL_PIN_STATE_DISCONNECTED, + DPLL_PIN_STATE_SELECTABLE, + + /* private: */ + __DPLL_PIN_STATE_MAX, + DPLL_PIN_STATE_MAX = (__DPLL_PIN_STATE_MAX - 1) +}; + +/** + * enum dpll_pin_capabilities - defines possible capabilities of a pin, valid + * flags on DPLL_A_PIN_CAPABILITIES attribute + * @DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE: pin direction can be changed + * @DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE: pin priority can be changed + * @DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE: pin state can be changed + */ +enum dpll_pin_capabilities { + DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE = 1, + DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE = 2, + DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE = 4, +}; + +#define DPLL_PHASE_OFFSET_DIVIDER 1000 + +enum dpll_a { + DPLL_A_ID = 1, + DPLL_A_MODULE_NAME, + DPLL_A_PAD, + DPLL_A_CLOCK_ID, + DPLL_A_MODE, + DPLL_A_MODE_SUPPORTED, + DPLL_A_LOCK_STATUS, + DPLL_A_TEMP, + DPLL_A_TYPE, + DPLL_A_LOCK_STATUS_ERROR, + + __DPLL_A_MAX, + DPLL_A_MAX = (__DPLL_A_MAX - 1) +}; + +enum dpll_a_pin { + DPLL_A_PIN_ID = 1, + DPLL_A_PIN_PARENT_ID, + DPLL_A_PIN_MODULE_NAME, + DPLL_A_PIN_PAD, + DPLL_A_PIN_CLOCK_ID, + DPLL_A_PIN_BOARD_LABEL, + DPLL_A_PIN_PANEL_LABEL, + DPLL_A_PIN_PACKAGE_LABEL, + DPLL_A_PIN_TYPE, + DPLL_A_PIN_DIRECTION, + DPLL_A_PIN_FREQUENCY, + DPLL_A_PIN_FREQUENCY_SUPPORTED, + DPLL_A_PIN_FREQUENCY_MIN, + DPLL_A_PIN_FREQUENCY_MAX, + DPLL_A_PIN_PRIO, + DPLL_A_PIN_STATE, + DPLL_A_PIN_CAPABILITIES, + DPLL_A_PIN_PARENT_DEVICE, + DPLL_A_PIN_PARENT_PIN, + DPLL_A_PIN_PHASE_ADJUST_MIN, + DPLL_A_PIN_PHASE_ADJUST_MAX, + DPLL_A_PIN_PHASE_ADJUST, + DPLL_A_PIN_PHASE_OFFSET, + DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET, + + __DPLL_A_PIN_MAX, + DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1) +}; + +enum dpll_cmd { + DPLL_CMD_DEVICE_ID_GET = 1, + DPLL_CMD_DEVICE_GET, + DPLL_CMD_DEVICE_SET, + DPLL_CMD_DEVICE_CREATE_NTF, + DPLL_CMD_DEVICE_DELETE_NTF, + DPLL_CMD_DEVICE_CHANGE_NTF, + DPLL_CMD_PIN_ID_GET, + DPLL_CMD_PIN_GET, + DPLL_CMD_PIN_SET, + DPLL_CMD_PIN_CREATE_NTF, + DPLL_CMD_PIN_DELETE_NTF, + DPLL_CMD_PIN_CHANGE_NTF, + + __DPLL_CMD_MAX, + DPLL_CMD_MAX = (__DPLL_CMD_MAX - 1) +}; + +#define DPLL_MCGRP_MONITOR "monitor" + +#endif /* _UAPI_LINUX_DPLL_H */ diff --git a/uapi/linux/ethtool_netlink.h b/uapi/linux/ethtool_netlink.h new file mode 100644 index 0000000..3f89074 --- /dev/null +++ b/uapi/linux/ethtool_netlink.h @@ -0,0 +1,985 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +/* + * include/uapi/linux/ethtool_netlink.h - netlink interface for ethtool + * + * See Documentation/networking/ethtool-netlink.rst in kernel source tree for + * doucumentation of the interface. + */ + +#ifndef _UAPI_LINUX_ETHTOOL_NETLINK_H_ +#define _UAPI_LINUX_ETHTOOL_NETLINK_H_ + +#include + +/* message types - userspace to kernel */ +enum { + ETHTOOL_MSG_USER_NONE, + ETHTOOL_MSG_STRSET_GET, + ETHTOOL_MSG_LINKINFO_GET, + ETHTOOL_MSG_LINKINFO_SET, + ETHTOOL_MSG_LINKMODES_GET, + ETHTOOL_MSG_LINKMODES_SET, + ETHTOOL_MSG_LINKSTATE_GET, + ETHTOOL_MSG_DEBUG_GET, + ETHTOOL_MSG_DEBUG_SET, + ETHTOOL_MSG_WOL_GET, + ETHTOOL_MSG_WOL_SET, + ETHTOOL_MSG_FEATURES_GET, + ETHTOOL_MSG_FEATURES_SET, + ETHTOOL_MSG_PRIVFLAGS_GET, + ETHTOOL_MSG_PRIVFLAGS_SET, + ETHTOOL_MSG_RINGS_GET, + ETHTOOL_MSG_RINGS_SET, + ETHTOOL_MSG_CHANNELS_GET, + ETHTOOL_MSG_CHANNELS_SET, + ETHTOOL_MSG_COALESCE_GET, + ETHTOOL_MSG_COALESCE_SET, + ETHTOOL_MSG_PAUSE_GET, + ETHTOOL_MSG_PAUSE_SET, + ETHTOOL_MSG_EEE_GET, + ETHTOOL_MSG_EEE_SET, + ETHTOOL_MSG_TSINFO_GET, + ETHTOOL_MSG_CABLE_TEST_ACT, + ETHTOOL_MSG_CABLE_TEST_TDR_ACT, + ETHTOOL_MSG_TUNNEL_INFO_GET, + ETHTOOL_MSG_FEC_GET, + ETHTOOL_MSG_FEC_SET, + ETHTOOL_MSG_MODULE_EEPROM_GET, + ETHTOOL_MSG_STATS_GET, + ETHTOOL_MSG_PHC_VCLOCKS_GET, + ETHTOOL_MSG_MODULE_GET, + ETHTOOL_MSG_MODULE_SET, + ETHTOOL_MSG_PSE_GET, + ETHTOOL_MSG_PSE_SET, + ETHTOOL_MSG_RSS_GET, + ETHTOOL_MSG_PLCA_GET_CFG, + ETHTOOL_MSG_PLCA_SET_CFG, + ETHTOOL_MSG_PLCA_GET_STATUS, + ETHTOOL_MSG_MM_GET, + ETHTOOL_MSG_MM_SET, + + /* add new constants above here */ + __ETHTOOL_MSG_USER_CNT, + ETHTOOL_MSG_USER_MAX = __ETHTOOL_MSG_USER_CNT - 1 +}; + +/* message types - kernel to userspace */ +enum { + ETHTOOL_MSG_KERNEL_NONE, + ETHTOOL_MSG_STRSET_GET_REPLY, + ETHTOOL_MSG_LINKINFO_GET_REPLY, + ETHTOOL_MSG_LINKINFO_NTF, + ETHTOOL_MSG_LINKMODES_GET_REPLY, + ETHTOOL_MSG_LINKMODES_NTF, + ETHTOOL_MSG_LINKSTATE_GET_REPLY, + ETHTOOL_MSG_DEBUG_GET_REPLY, + ETHTOOL_MSG_DEBUG_NTF, + ETHTOOL_MSG_WOL_GET_REPLY, + ETHTOOL_MSG_WOL_NTF, + ETHTOOL_MSG_FEATURES_GET_REPLY, + ETHTOOL_MSG_FEATURES_SET_REPLY, + ETHTOOL_MSG_FEATURES_NTF, + ETHTOOL_MSG_PRIVFLAGS_GET_REPLY, + ETHTOOL_MSG_PRIVFLAGS_NTF, + ETHTOOL_MSG_RINGS_GET_REPLY, + ETHTOOL_MSG_RINGS_NTF, + ETHTOOL_MSG_CHANNELS_GET_REPLY, + ETHTOOL_MSG_CHANNELS_NTF, + ETHTOOL_MSG_COALESCE_GET_REPLY, + ETHTOOL_MSG_COALESCE_NTF, + ETHTOOL_MSG_PAUSE_GET_REPLY, + ETHTOOL_MSG_PAUSE_NTF, + ETHTOOL_MSG_EEE_GET_REPLY, + ETHTOOL_MSG_EEE_NTF, + ETHTOOL_MSG_TSINFO_GET_REPLY, + ETHTOOL_MSG_CABLE_TEST_NTF, + ETHTOOL_MSG_CABLE_TEST_TDR_NTF, + ETHTOOL_MSG_TUNNEL_INFO_GET_REPLY, + ETHTOOL_MSG_FEC_GET_REPLY, + ETHTOOL_MSG_FEC_NTF, + ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY, + ETHTOOL_MSG_STATS_GET_REPLY, + ETHTOOL_MSG_PHC_VCLOCKS_GET_REPLY, + ETHTOOL_MSG_MODULE_GET_REPLY, + ETHTOOL_MSG_MODULE_NTF, + ETHTOOL_MSG_PSE_GET_REPLY, + ETHTOOL_MSG_RSS_GET_REPLY, + ETHTOOL_MSG_PLCA_GET_CFG_REPLY, + ETHTOOL_MSG_PLCA_GET_STATUS_REPLY, + ETHTOOL_MSG_PLCA_NTF, + ETHTOOL_MSG_MM_GET_REPLY, + ETHTOOL_MSG_MM_NTF, + + /* add new constants above here */ + __ETHTOOL_MSG_KERNEL_CNT, + ETHTOOL_MSG_KERNEL_MAX = __ETHTOOL_MSG_KERNEL_CNT - 1 +}; + +/* request header */ + +/* use compact bitsets in reply */ +#define ETHTOOL_FLAG_COMPACT_BITSETS (1 << 0) +/* provide optional reply for SET or ACT requests */ +#define ETHTOOL_FLAG_OMIT_REPLY (1 << 1) +/* request statistics, if supported by the driver */ +#define ETHTOOL_FLAG_STATS (1 << 2) + +#define ETHTOOL_FLAG_ALL (ETHTOOL_FLAG_COMPACT_BITSETS | \ + ETHTOOL_FLAG_OMIT_REPLY | \ + ETHTOOL_FLAG_STATS) + +enum { + ETHTOOL_A_HEADER_UNSPEC, + ETHTOOL_A_HEADER_DEV_INDEX, /* u32 */ + ETHTOOL_A_HEADER_DEV_NAME, /* string */ + ETHTOOL_A_HEADER_FLAGS, /* u32 - ETHTOOL_FLAG_* */ + + /* add new constants above here */ + __ETHTOOL_A_HEADER_CNT, + ETHTOOL_A_HEADER_MAX = __ETHTOOL_A_HEADER_CNT - 1 +}; + +/* bit sets */ + +enum { + ETHTOOL_A_BITSET_BIT_UNSPEC, + ETHTOOL_A_BITSET_BIT_INDEX, /* u32 */ + ETHTOOL_A_BITSET_BIT_NAME, /* string */ + ETHTOOL_A_BITSET_BIT_VALUE, /* flag */ + + /* add new constants above here */ + __ETHTOOL_A_BITSET_BIT_CNT, + ETHTOOL_A_BITSET_BIT_MAX = __ETHTOOL_A_BITSET_BIT_CNT - 1 +}; + +enum { + ETHTOOL_A_BITSET_BITS_UNSPEC, + ETHTOOL_A_BITSET_BITS_BIT, /* nest - _A_BITSET_BIT_* */ + + /* add new constants above here */ + __ETHTOOL_A_BITSET_BITS_CNT, + ETHTOOL_A_BITSET_BITS_MAX = __ETHTOOL_A_BITSET_BITS_CNT - 1 +}; + +enum { + ETHTOOL_A_BITSET_UNSPEC, + ETHTOOL_A_BITSET_NOMASK, /* flag */ + ETHTOOL_A_BITSET_SIZE, /* u32 */ + ETHTOOL_A_BITSET_BITS, /* nest - _A_BITSET_BITS_* */ + ETHTOOL_A_BITSET_VALUE, /* binary */ + ETHTOOL_A_BITSET_MASK, /* binary */ + + /* add new constants above here */ + __ETHTOOL_A_BITSET_CNT, + ETHTOOL_A_BITSET_MAX = __ETHTOOL_A_BITSET_CNT - 1 +}; + +/* string sets */ + +enum { + ETHTOOL_A_STRING_UNSPEC, + ETHTOOL_A_STRING_INDEX, /* u32 */ + ETHTOOL_A_STRING_VALUE, /* string */ + + /* add new constants above here */ + __ETHTOOL_A_STRING_CNT, + ETHTOOL_A_STRING_MAX = __ETHTOOL_A_STRING_CNT - 1 +}; + +enum { + ETHTOOL_A_STRINGS_UNSPEC, + ETHTOOL_A_STRINGS_STRING, /* nest - _A_STRINGS_* */ + + /* add new constants above here */ + __ETHTOOL_A_STRINGS_CNT, + ETHTOOL_A_STRINGS_MAX = __ETHTOOL_A_STRINGS_CNT - 1 +}; + +enum { + ETHTOOL_A_STRINGSET_UNSPEC, + ETHTOOL_A_STRINGSET_ID, /* u32 */ + ETHTOOL_A_STRINGSET_COUNT, /* u32 */ + ETHTOOL_A_STRINGSET_STRINGS, /* nest - _A_STRINGS_* */ + + /* add new constants above here */ + __ETHTOOL_A_STRINGSET_CNT, + ETHTOOL_A_STRINGSET_MAX = __ETHTOOL_A_STRINGSET_CNT - 1 +}; + +enum { + ETHTOOL_A_STRINGSETS_UNSPEC, + ETHTOOL_A_STRINGSETS_STRINGSET, /* nest - _A_STRINGSET_* */ + + /* add new constants above here */ + __ETHTOOL_A_STRINGSETS_CNT, + ETHTOOL_A_STRINGSETS_MAX = __ETHTOOL_A_STRINGSETS_CNT - 1 +}; + +/* STRSET */ + +enum { + ETHTOOL_A_STRSET_UNSPEC, + ETHTOOL_A_STRSET_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_STRSET_STRINGSETS, /* nest - _A_STRINGSETS_* */ + ETHTOOL_A_STRSET_COUNTS_ONLY, /* flag */ + + /* add new constants above here */ + __ETHTOOL_A_STRSET_CNT, + ETHTOOL_A_STRSET_MAX = __ETHTOOL_A_STRSET_CNT - 1 +}; + +/* LINKINFO */ + +enum { + ETHTOOL_A_LINKINFO_UNSPEC, + ETHTOOL_A_LINKINFO_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_LINKINFO_PORT, /* u8 */ + ETHTOOL_A_LINKINFO_PHYADDR, /* u8 */ + ETHTOOL_A_LINKINFO_TP_MDIX, /* u8 */ + ETHTOOL_A_LINKINFO_TP_MDIX_CTRL, /* u8 */ + ETHTOOL_A_LINKINFO_TRANSCEIVER, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_LINKINFO_CNT, + ETHTOOL_A_LINKINFO_MAX = __ETHTOOL_A_LINKINFO_CNT - 1 +}; + +/* LINKMODES */ + +enum { + ETHTOOL_A_LINKMODES_UNSPEC, + ETHTOOL_A_LINKMODES_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_LINKMODES_AUTONEG, /* u8 */ + ETHTOOL_A_LINKMODES_OURS, /* bitset */ + ETHTOOL_A_LINKMODES_PEER, /* bitset */ + ETHTOOL_A_LINKMODES_SPEED, /* u32 */ + ETHTOOL_A_LINKMODES_DUPLEX, /* u8 */ + ETHTOOL_A_LINKMODES_MASTER_SLAVE_CFG, /* u8 */ + ETHTOOL_A_LINKMODES_MASTER_SLAVE_STATE, /* u8 */ + ETHTOOL_A_LINKMODES_LANES, /* u32 */ + ETHTOOL_A_LINKMODES_RATE_MATCHING, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_LINKMODES_CNT, + ETHTOOL_A_LINKMODES_MAX = __ETHTOOL_A_LINKMODES_CNT - 1 +}; + +/* LINKSTATE */ + +enum { + ETHTOOL_A_LINKSTATE_UNSPEC, + ETHTOOL_A_LINKSTATE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_LINKSTATE_LINK, /* u8 */ + ETHTOOL_A_LINKSTATE_SQI, /* u32 */ + ETHTOOL_A_LINKSTATE_SQI_MAX, /* u32 */ + ETHTOOL_A_LINKSTATE_EXT_STATE, /* u8 */ + ETHTOOL_A_LINKSTATE_EXT_SUBSTATE, /* u8 */ + ETHTOOL_A_LINKSTATE_EXT_DOWN_CNT, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_LINKSTATE_CNT, + ETHTOOL_A_LINKSTATE_MAX = __ETHTOOL_A_LINKSTATE_CNT - 1 +}; + +/* DEBUG */ + +enum { + ETHTOOL_A_DEBUG_UNSPEC, + ETHTOOL_A_DEBUG_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_DEBUG_MSGMASK, /* bitset */ + + /* add new constants above here */ + __ETHTOOL_A_DEBUG_CNT, + ETHTOOL_A_DEBUG_MAX = __ETHTOOL_A_DEBUG_CNT - 1 +}; + +/* WOL */ + +enum { + ETHTOOL_A_WOL_UNSPEC, + ETHTOOL_A_WOL_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_WOL_MODES, /* bitset */ + ETHTOOL_A_WOL_SOPASS, /* binary */ + + /* add new constants above here */ + __ETHTOOL_A_WOL_CNT, + ETHTOOL_A_WOL_MAX = __ETHTOOL_A_WOL_CNT - 1 +}; + +/* FEATURES */ + +enum { + ETHTOOL_A_FEATURES_UNSPEC, + ETHTOOL_A_FEATURES_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_FEATURES_HW, /* bitset */ + ETHTOOL_A_FEATURES_WANTED, /* bitset */ + ETHTOOL_A_FEATURES_ACTIVE, /* bitset */ + ETHTOOL_A_FEATURES_NOCHANGE, /* bitset */ + + /* add new constants above here */ + __ETHTOOL_A_FEATURES_CNT, + ETHTOOL_A_FEATURES_MAX = __ETHTOOL_A_FEATURES_CNT - 1 +}; + +/* PRIVFLAGS */ + +enum { + ETHTOOL_A_PRIVFLAGS_UNSPEC, + ETHTOOL_A_PRIVFLAGS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PRIVFLAGS_FLAGS, /* bitset */ + + /* add new constants above here */ + __ETHTOOL_A_PRIVFLAGS_CNT, + ETHTOOL_A_PRIVFLAGS_MAX = __ETHTOOL_A_PRIVFLAGS_CNT - 1 +}; + +/* RINGS */ + +enum { + ETHTOOL_TCP_DATA_SPLIT_UNKNOWN = 0, + ETHTOOL_TCP_DATA_SPLIT_DISABLED, + ETHTOOL_TCP_DATA_SPLIT_ENABLED, +}; + +enum { + ETHTOOL_A_RINGS_UNSPEC, + ETHTOOL_A_RINGS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_RINGS_RX_MAX, /* u32 */ + ETHTOOL_A_RINGS_RX_MINI_MAX, /* u32 */ + ETHTOOL_A_RINGS_RX_JUMBO_MAX, /* u32 */ + ETHTOOL_A_RINGS_TX_MAX, /* u32 */ + ETHTOOL_A_RINGS_RX, /* u32 */ + ETHTOOL_A_RINGS_RX_MINI, /* u32 */ + ETHTOOL_A_RINGS_RX_JUMBO, /* u32 */ + ETHTOOL_A_RINGS_TX, /* u32 */ + ETHTOOL_A_RINGS_RX_BUF_LEN, /* u32 */ + ETHTOOL_A_RINGS_TCP_DATA_SPLIT, /* u8 */ + ETHTOOL_A_RINGS_CQE_SIZE, /* u32 */ + ETHTOOL_A_RINGS_TX_PUSH, /* u8 */ + ETHTOOL_A_RINGS_RX_PUSH, /* u8 */ + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN, /* u32 */ + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_RINGS_CNT, + ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1) +}; + +/* CHANNELS */ + +enum { + ETHTOOL_A_CHANNELS_UNSPEC, + ETHTOOL_A_CHANNELS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_CHANNELS_RX_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_TX_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_OTHER_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_COMBINED_MAX, /* u32 */ + ETHTOOL_A_CHANNELS_RX_COUNT, /* u32 */ + ETHTOOL_A_CHANNELS_TX_COUNT, /* u32 */ + ETHTOOL_A_CHANNELS_OTHER_COUNT, /* u32 */ + ETHTOOL_A_CHANNELS_COMBINED_COUNT, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_CHANNELS_CNT, + ETHTOOL_A_CHANNELS_MAX = (__ETHTOOL_A_CHANNELS_CNT - 1) +}; + +/* COALESCE */ + +enum { + ETHTOOL_A_COALESCE_UNSPEC, + ETHTOOL_A_COALESCE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_COALESCE_RX_USECS, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES, /* u32 */ + ETHTOOL_A_COALESCE_RX_USECS_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_IRQ, /* u32 */ + ETHTOOL_A_COALESCE_STATS_BLOCK_USECS, /* u32 */ + ETHTOOL_A_COALESCE_USE_ADAPTIVE_RX, /* u8 */ + ETHTOOL_A_COALESCE_USE_ADAPTIVE_TX, /* u8 */ + ETHTOOL_A_COALESCE_PKT_RATE_LOW, /* u32 */ + ETHTOOL_A_COALESCE_RX_USECS_LOW, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_LOW, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS_LOW, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_LOW, /* u32 */ + ETHTOOL_A_COALESCE_PKT_RATE_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_RX_USECS_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_RX_MAX_FRAMES_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_TX_USECS_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH, /* u32 */ + ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL, /* u32 */ + ETHTOOL_A_COALESCE_USE_CQE_MODE_TX, /* u8 */ + ETHTOOL_A_COALESCE_USE_CQE_MODE_RX, /* u8 */ + ETHTOOL_A_COALESCE_TX_AGGR_MAX_BYTES, /* u32 */ + ETHTOOL_A_COALESCE_TX_AGGR_MAX_FRAMES, /* u32 */ + ETHTOOL_A_COALESCE_TX_AGGR_TIME_USECS, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_COALESCE_CNT, + ETHTOOL_A_COALESCE_MAX = (__ETHTOOL_A_COALESCE_CNT - 1) +}; + +/* PAUSE */ + +enum { + ETHTOOL_A_PAUSE_UNSPEC, + ETHTOOL_A_PAUSE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PAUSE_AUTONEG, /* u8 */ + ETHTOOL_A_PAUSE_RX, /* u8 */ + ETHTOOL_A_PAUSE_TX, /* u8 */ + ETHTOOL_A_PAUSE_STATS, /* nest - _PAUSE_STAT_* */ + ETHTOOL_A_PAUSE_STATS_SRC, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_PAUSE_CNT, + ETHTOOL_A_PAUSE_MAX = (__ETHTOOL_A_PAUSE_CNT - 1) +}; + +enum { + ETHTOOL_A_PAUSE_STAT_UNSPEC, + ETHTOOL_A_PAUSE_STAT_PAD, + + ETHTOOL_A_PAUSE_STAT_TX_FRAMES, + ETHTOOL_A_PAUSE_STAT_RX_FRAMES, + + /* add new constants above here + * adjust ETHTOOL_PAUSE_STAT_CNT if adding non-stats! + */ + __ETHTOOL_A_PAUSE_STAT_CNT, + ETHTOOL_A_PAUSE_STAT_MAX = (__ETHTOOL_A_PAUSE_STAT_CNT - 1) +}; + +/* EEE */ + +enum { + ETHTOOL_A_EEE_UNSPEC, + ETHTOOL_A_EEE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_EEE_MODES_OURS, /* bitset */ + ETHTOOL_A_EEE_MODES_PEER, /* bitset */ + ETHTOOL_A_EEE_ACTIVE, /* u8 */ + ETHTOOL_A_EEE_ENABLED, /* u8 */ + ETHTOOL_A_EEE_TX_LPI_ENABLED, /* u8 */ + ETHTOOL_A_EEE_TX_LPI_TIMER, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_EEE_CNT, + ETHTOOL_A_EEE_MAX = (__ETHTOOL_A_EEE_CNT - 1) +}; + +/* TSINFO */ + +enum { + ETHTOOL_A_TSINFO_UNSPEC, + ETHTOOL_A_TSINFO_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_TSINFO_TIMESTAMPING, /* bitset */ + ETHTOOL_A_TSINFO_TX_TYPES, /* bitset */ + ETHTOOL_A_TSINFO_RX_FILTERS, /* bitset */ + ETHTOOL_A_TSINFO_PHC_INDEX, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_TSINFO_CNT, + ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1) +}; + +/* PHC VCLOCKS */ + +enum { + ETHTOOL_A_PHC_VCLOCKS_UNSPEC, + ETHTOOL_A_PHC_VCLOCKS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PHC_VCLOCKS_NUM, /* u32 */ + ETHTOOL_A_PHC_VCLOCKS_INDEX, /* array, s32 */ + + /* add new constants above here */ + __ETHTOOL_A_PHC_VCLOCKS_CNT, + ETHTOOL_A_PHC_VCLOCKS_MAX = (__ETHTOOL_A_PHC_VCLOCKS_CNT - 1) +}; + +/* CABLE TEST */ + +enum { + ETHTOOL_A_CABLE_TEST_UNSPEC, + ETHTOOL_A_CABLE_TEST_HEADER, /* nest - _A_HEADER_* */ + + /* add new constants above here */ + __ETHTOOL_A_CABLE_TEST_CNT, + ETHTOOL_A_CABLE_TEST_MAX = __ETHTOOL_A_CABLE_TEST_CNT - 1 +}; + +/* CABLE TEST NOTIFY */ +enum { + ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC, + ETHTOOL_A_CABLE_RESULT_CODE_OK, + ETHTOOL_A_CABLE_RESULT_CODE_OPEN, + ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT, + ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT, +}; + +enum { + ETHTOOL_A_CABLE_PAIR_A, + ETHTOOL_A_CABLE_PAIR_B, + ETHTOOL_A_CABLE_PAIR_C, + ETHTOOL_A_CABLE_PAIR_D, +}; + +enum { + ETHTOOL_A_CABLE_RESULT_UNSPEC, + ETHTOOL_A_CABLE_RESULT_PAIR, /* u8 ETHTOOL_A_CABLE_PAIR_ */ + ETHTOOL_A_CABLE_RESULT_CODE, /* u8 ETHTOOL_A_CABLE_RESULT_CODE_ */ + + __ETHTOOL_A_CABLE_RESULT_CNT, + ETHTOOL_A_CABLE_RESULT_MAX = (__ETHTOOL_A_CABLE_RESULT_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_FAULT_LENGTH_UNSPEC, + ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR, /* u8 ETHTOOL_A_CABLE_PAIR_ */ + ETHTOOL_A_CABLE_FAULT_LENGTH_CM, /* u32 */ + + __ETHTOOL_A_CABLE_FAULT_LENGTH_CNT, + ETHTOOL_A_CABLE_FAULT_LENGTH_MAX = (__ETHTOOL_A_CABLE_FAULT_LENGTH_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_NTF_STATUS_UNSPEC, + ETHTOOL_A_CABLE_TEST_NTF_STATUS_STARTED, + ETHTOOL_A_CABLE_TEST_NTF_STATUS_COMPLETED +}; + +enum { + ETHTOOL_A_CABLE_NEST_UNSPEC, + ETHTOOL_A_CABLE_NEST_RESULT, /* nest - ETHTOOL_A_CABLE_RESULT_ */ + ETHTOOL_A_CABLE_NEST_FAULT_LENGTH, /* nest - ETHTOOL_A_CABLE_FAULT_LENGTH_ */ + __ETHTOOL_A_CABLE_NEST_CNT, + ETHTOOL_A_CABLE_NEST_MAX = (__ETHTOOL_A_CABLE_NEST_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_NTF_UNSPEC, + ETHTOOL_A_CABLE_TEST_NTF_HEADER, /* nest - ETHTOOL_A_HEADER_* */ + ETHTOOL_A_CABLE_TEST_NTF_STATUS, /* u8 - _STARTED/_COMPLETE */ + ETHTOOL_A_CABLE_TEST_NTF_NEST, /* nest - of results: */ + + __ETHTOOL_A_CABLE_TEST_NTF_CNT, + ETHTOOL_A_CABLE_TEST_NTF_MAX = (__ETHTOOL_A_CABLE_TEST_NTF_CNT - 1) +}; + +/* CABLE TEST TDR */ + +enum { + ETHTOOL_A_CABLE_TEST_TDR_CFG_UNSPEC, + ETHTOOL_A_CABLE_TEST_TDR_CFG_FIRST, /* u32 */ + ETHTOOL_A_CABLE_TEST_TDR_CFG_LAST, /* u32 */ + ETHTOOL_A_CABLE_TEST_TDR_CFG_STEP, /* u32 */ + ETHTOOL_A_CABLE_TEST_TDR_CFG_PAIR, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_CABLE_TEST_TDR_CFG_CNT, + ETHTOOL_A_CABLE_TEST_TDR_CFG_MAX = __ETHTOOL_A_CABLE_TEST_TDR_CFG_CNT - 1 +}; + +enum { + ETHTOOL_A_CABLE_TEST_TDR_UNSPEC, + ETHTOOL_A_CABLE_TEST_TDR_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_CABLE_TEST_TDR_CFG, /* nest - *_TDR_CFG_* */ + + /* add new constants above here */ + __ETHTOOL_A_CABLE_TEST_TDR_CNT, + ETHTOOL_A_CABLE_TEST_TDR_MAX = __ETHTOOL_A_CABLE_TEST_TDR_CNT - 1 +}; + +/* CABLE TEST TDR NOTIFY */ + +enum { + ETHTOOL_A_CABLE_AMPLITUDE_UNSPEC, + ETHTOOL_A_CABLE_AMPLITUDE_PAIR, /* u8 */ + ETHTOOL_A_CABLE_AMPLITUDE_mV, /* s16 */ + + __ETHTOOL_A_CABLE_AMPLITUDE_CNT, + ETHTOOL_A_CABLE_AMPLITUDE_MAX = (__ETHTOOL_A_CABLE_AMPLITUDE_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_PULSE_UNSPEC, + ETHTOOL_A_CABLE_PULSE_mV, /* s16 */ + + __ETHTOOL_A_CABLE_PULSE_CNT, + ETHTOOL_A_CABLE_PULSE_MAX = (__ETHTOOL_A_CABLE_PULSE_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_STEP_UNSPEC, + ETHTOOL_A_CABLE_STEP_FIRST_DISTANCE, /* u32 */ + ETHTOOL_A_CABLE_STEP_LAST_DISTANCE, /* u32 */ + ETHTOOL_A_CABLE_STEP_STEP_DISTANCE, /* u32 */ + + __ETHTOOL_A_CABLE_STEP_CNT, + ETHTOOL_A_CABLE_STEP_MAX = (__ETHTOOL_A_CABLE_STEP_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TDR_NEST_UNSPEC, + ETHTOOL_A_CABLE_TDR_NEST_STEP, /* nest - ETHTTOOL_A_CABLE_STEP */ + ETHTOOL_A_CABLE_TDR_NEST_AMPLITUDE, /* nest - ETHTOOL_A_CABLE_AMPLITUDE */ + ETHTOOL_A_CABLE_TDR_NEST_PULSE, /* nest - ETHTOOL_A_CABLE_PULSE */ + + __ETHTOOL_A_CABLE_TDR_NEST_CNT, + ETHTOOL_A_CABLE_TDR_NEST_MAX = (__ETHTOOL_A_CABLE_TDR_NEST_CNT - 1) +}; + +enum { + ETHTOOL_A_CABLE_TEST_TDR_NTF_UNSPEC, + ETHTOOL_A_CABLE_TEST_TDR_NTF_HEADER, /* nest - ETHTOOL_A_HEADER_* */ + ETHTOOL_A_CABLE_TEST_TDR_NTF_STATUS, /* u8 - _STARTED/_COMPLETE */ + ETHTOOL_A_CABLE_TEST_TDR_NTF_NEST, /* nest - of results: */ + + /* add new constants above here */ + __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT, + ETHTOOL_A_CABLE_TEST_TDR_NTF_MAX = __ETHTOOL_A_CABLE_TEST_TDR_NTF_CNT - 1 +}; + +/* TUNNEL INFO */ + +enum { + ETHTOOL_UDP_TUNNEL_TYPE_VXLAN, + ETHTOOL_UDP_TUNNEL_TYPE_GENEVE, + ETHTOOL_UDP_TUNNEL_TYPE_VXLAN_GPE, + + __ETHTOOL_UDP_TUNNEL_TYPE_CNT +}; + +enum { + ETHTOOL_A_TUNNEL_UDP_ENTRY_UNSPEC, + + ETHTOOL_A_TUNNEL_UDP_ENTRY_PORT, /* be16 */ + ETHTOOL_A_TUNNEL_UDP_ENTRY_TYPE, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT, + ETHTOOL_A_TUNNEL_UDP_ENTRY_MAX = (__ETHTOOL_A_TUNNEL_UDP_ENTRY_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_UDP_TABLE_UNSPEC, + + ETHTOOL_A_TUNNEL_UDP_TABLE_SIZE, /* u32 */ + ETHTOOL_A_TUNNEL_UDP_TABLE_TYPES, /* bitset */ + ETHTOOL_A_TUNNEL_UDP_TABLE_ENTRY, /* nest - _UDP_ENTRY_* */ + + /* add new constants above here */ + __ETHTOOL_A_TUNNEL_UDP_TABLE_CNT, + ETHTOOL_A_TUNNEL_UDP_TABLE_MAX = (__ETHTOOL_A_TUNNEL_UDP_TABLE_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_UDP_UNSPEC, + + ETHTOOL_A_TUNNEL_UDP_TABLE, /* nest - _UDP_TABLE_* */ + + /* add new constants above here */ + __ETHTOOL_A_TUNNEL_UDP_CNT, + ETHTOOL_A_TUNNEL_UDP_MAX = (__ETHTOOL_A_TUNNEL_UDP_CNT - 1) +}; + +enum { + ETHTOOL_A_TUNNEL_INFO_UNSPEC, + ETHTOOL_A_TUNNEL_INFO_HEADER, /* nest - _A_HEADER_* */ + + ETHTOOL_A_TUNNEL_INFO_UDP_PORTS, /* nest - _UDP_TABLE */ + + /* add new constants above here */ + __ETHTOOL_A_TUNNEL_INFO_CNT, + ETHTOOL_A_TUNNEL_INFO_MAX = (__ETHTOOL_A_TUNNEL_INFO_CNT - 1) +}; + +/* FEC */ + +enum { + ETHTOOL_A_FEC_UNSPEC, + ETHTOOL_A_FEC_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_FEC_MODES, /* bitset */ + ETHTOOL_A_FEC_AUTO, /* u8 */ + ETHTOOL_A_FEC_ACTIVE, /* u32 */ + ETHTOOL_A_FEC_STATS, /* nest - _A_FEC_STAT */ + + __ETHTOOL_A_FEC_CNT, + ETHTOOL_A_FEC_MAX = (__ETHTOOL_A_FEC_CNT - 1) +}; + +enum { + ETHTOOL_A_FEC_STAT_UNSPEC, + ETHTOOL_A_FEC_STAT_PAD, + + ETHTOOL_A_FEC_STAT_CORRECTED, /* array, u64 */ + ETHTOOL_A_FEC_STAT_UNCORR, /* array, u64 */ + ETHTOOL_A_FEC_STAT_CORR_BITS, /* array, u64 */ + + /* add new constants above here */ + __ETHTOOL_A_FEC_STAT_CNT, + ETHTOOL_A_FEC_STAT_MAX = (__ETHTOOL_A_FEC_STAT_CNT - 1) +}; + +/* MODULE EEPROM */ + +enum { + ETHTOOL_A_MODULE_EEPROM_UNSPEC, + ETHTOOL_A_MODULE_EEPROM_HEADER, /* nest - _A_HEADER_* */ + + ETHTOOL_A_MODULE_EEPROM_OFFSET, /* u32 */ + ETHTOOL_A_MODULE_EEPROM_LENGTH, /* u32 */ + ETHTOOL_A_MODULE_EEPROM_PAGE, /* u8 */ + ETHTOOL_A_MODULE_EEPROM_BANK, /* u8 */ + ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS, /* u8 */ + ETHTOOL_A_MODULE_EEPROM_DATA, /* binary */ + + __ETHTOOL_A_MODULE_EEPROM_CNT, + ETHTOOL_A_MODULE_EEPROM_MAX = (__ETHTOOL_A_MODULE_EEPROM_CNT - 1) +}; + +/* STATS */ + +enum { + ETHTOOL_A_STATS_UNSPEC, + ETHTOOL_A_STATS_PAD, + ETHTOOL_A_STATS_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_STATS_GROUPS, /* bitset */ + + ETHTOOL_A_STATS_GRP, /* nest - _A_STATS_GRP_* */ + + ETHTOOL_A_STATS_SRC, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_STATS_CNT, + ETHTOOL_A_STATS_MAX = (__ETHTOOL_A_STATS_CNT - 1) +}; + +enum { + ETHTOOL_STATS_ETH_PHY, + ETHTOOL_STATS_ETH_MAC, + ETHTOOL_STATS_ETH_CTRL, + ETHTOOL_STATS_RMON, + + /* add new constants above here */ + __ETHTOOL_STATS_CNT +}; + +enum { + ETHTOOL_A_STATS_GRP_UNSPEC, + ETHTOOL_A_STATS_GRP_PAD, + + ETHTOOL_A_STATS_GRP_ID, /* u32 */ + ETHTOOL_A_STATS_GRP_SS_ID, /* u32 */ + + ETHTOOL_A_STATS_GRP_STAT, /* nest */ + + ETHTOOL_A_STATS_GRP_HIST_RX, /* nest */ + ETHTOOL_A_STATS_GRP_HIST_TX, /* nest */ + + ETHTOOL_A_STATS_GRP_HIST_BKT_LOW, /* u32 */ + ETHTOOL_A_STATS_GRP_HIST_BKT_HI, /* u32 */ + ETHTOOL_A_STATS_GRP_HIST_VAL, /* u64 */ + + /* add new constants above here */ + __ETHTOOL_A_STATS_GRP_CNT, + ETHTOOL_A_STATS_GRP_MAX = (__ETHTOOL_A_STATS_GRP_CNT - 1) +}; + +enum { + /* 30.3.2.1.5 aSymbolErrorDuringCarrier */ + ETHTOOL_A_STATS_ETH_PHY_5_SYM_ERR, + + /* add new constants above here */ + __ETHTOOL_A_STATS_ETH_PHY_CNT, + ETHTOOL_A_STATS_ETH_PHY_MAX = (__ETHTOOL_A_STATS_ETH_PHY_CNT - 1) +}; + +enum { + /* 30.3.1.1.2 aFramesTransmittedOK */ + ETHTOOL_A_STATS_ETH_MAC_2_TX_PKT, + /* 30.3.1.1.3 aSingleCollisionFrames */ + ETHTOOL_A_STATS_ETH_MAC_3_SINGLE_COL, + /* 30.3.1.1.4 aMultipleCollisionFrames */ + ETHTOOL_A_STATS_ETH_MAC_4_MULTI_COL, + /* 30.3.1.1.5 aFramesReceivedOK */ + ETHTOOL_A_STATS_ETH_MAC_5_RX_PKT, + /* 30.3.1.1.6 aFrameCheckSequenceErrors */ + ETHTOOL_A_STATS_ETH_MAC_6_FCS_ERR, + /* 30.3.1.1.7 aAlignmentErrors */ + ETHTOOL_A_STATS_ETH_MAC_7_ALIGN_ERR, + /* 30.3.1.1.8 aOctetsTransmittedOK */ + ETHTOOL_A_STATS_ETH_MAC_8_TX_BYTES, + /* 30.3.1.1.9 aFramesWithDeferredXmissions */ + ETHTOOL_A_STATS_ETH_MAC_9_TX_DEFER, + /* 30.3.1.1.10 aLateCollisions */ + ETHTOOL_A_STATS_ETH_MAC_10_LATE_COL, + /* 30.3.1.1.11 aFramesAbortedDueToXSColls */ + ETHTOOL_A_STATS_ETH_MAC_11_XS_COL, + /* 30.3.1.1.12 aFramesLostDueToIntMACXmitError */ + ETHTOOL_A_STATS_ETH_MAC_12_TX_INT_ERR, + /* 30.3.1.1.13 aCarrierSenseErrors */ + ETHTOOL_A_STATS_ETH_MAC_13_CS_ERR, + /* 30.3.1.1.14 aOctetsReceivedOK */ + ETHTOOL_A_STATS_ETH_MAC_14_RX_BYTES, + /* 30.3.1.1.15 aFramesLostDueToIntMACRcvError */ + ETHTOOL_A_STATS_ETH_MAC_15_RX_INT_ERR, + + /* 30.3.1.1.18 aMulticastFramesXmittedOK */ + ETHTOOL_A_STATS_ETH_MAC_18_TX_MCAST, + /* 30.3.1.1.19 aBroadcastFramesXmittedOK */ + ETHTOOL_A_STATS_ETH_MAC_19_TX_BCAST, + /* 30.3.1.1.20 aFramesWithExcessiveDeferral */ + ETHTOOL_A_STATS_ETH_MAC_20_XS_DEFER, + /* 30.3.1.1.21 aMulticastFramesReceivedOK */ + ETHTOOL_A_STATS_ETH_MAC_21_RX_MCAST, + /* 30.3.1.1.22 aBroadcastFramesReceivedOK */ + ETHTOOL_A_STATS_ETH_MAC_22_RX_BCAST, + /* 30.3.1.1.23 aInRangeLengthErrors */ + ETHTOOL_A_STATS_ETH_MAC_23_IR_LEN_ERR, + /* 30.3.1.1.24 aOutOfRangeLengthField */ + ETHTOOL_A_STATS_ETH_MAC_24_OOR_LEN, + /* 30.3.1.1.25 aFrameTooLongErrors */ + ETHTOOL_A_STATS_ETH_MAC_25_TOO_LONG_ERR, + + /* add new constants above here */ + __ETHTOOL_A_STATS_ETH_MAC_CNT, + ETHTOOL_A_STATS_ETH_MAC_MAX = (__ETHTOOL_A_STATS_ETH_MAC_CNT - 1) +}; + +enum { + /* 30.3.3.3 aMACControlFramesTransmitted */ + ETHTOOL_A_STATS_ETH_CTRL_3_TX, + /* 30.3.3.4 aMACControlFramesReceived */ + ETHTOOL_A_STATS_ETH_CTRL_4_RX, + /* 30.3.3.5 aUnsupportedOpcodesReceived */ + ETHTOOL_A_STATS_ETH_CTRL_5_RX_UNSUP, + + /* add new constants above here */ + __ETHTOOL_A_STATS_ETH_CTRL_CNT, + ETHTOOL_A_STATS_ETH_CTRL_MAX = (__ETHTOOL_A_STATS_ETH_CTRL_CNT - 1) +}; + +enum { + /* etherStatsUndersizePkts */ + ETHTOOL_A_STATS_RMON_UNDERSIZE, + /* etherStatsOversizePkts */ + ETHTOOL_A_STATS_RMON_OVERSIZE, + /* etherStatsFragments */ + ETHTOOL_A_STATS_RMON_FRAG, + /* etherStatsJabbers */ + ETHTOOL_A_STATS_RMON_JABBER, + + /* add new constants above here */ + __ETHTOOL_A_STATS_RMON_CNT, + ETHTOOL_A_STATS_RMON_MAX = (__ETHTOOL_A_STATS_RMON_CNT - 1) +}; + +/* MODULE */ + +enum { + ETHTOOL_A_MODULE_UNSPEC, + ETHTOOL_A_MODULE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_MODULE_POWER_MODE_POLICY, /* u8 */ + ETHTOOL_A_MODULE_POWER_MODE, /* u8 */ + + /* add new constants above here */ + __ETHTOOL_A_MODULE_CNT, + ETHTOOL_A_MODULE_MAX = (__ETHTOOL_A_MODULE_CNT - 1) +}; + +/* Power Sourcing Equipment */ +enum { + ETHTOOL_A_PSE_UNSPEC, + ETHTOOL_A_PSE_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PODL_PSE_ADMIN_STATE, /* u32 */ + ETHTOOL_A_PODL_PSE_ADMIN_CONTROL, /* u32 */ + ETHTOOL_A_PODL_PSE_PW_D_STATUS, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_PSE_CNT, + ETHTOOL_A_PSE_MAX = (__ETHTOOL_A_PSE_CNT - 1) +}; + +enum { + ETHTOOL_A_RSS_UNSPEC, + ETHTOOL_A_RSS_HEADER, + ETHTOOL_A_RSS_CONTEXT, /* u32 */ + ETHTOOL_A_RSS_HFUNC, /* u32 */ + ETHTOOL_A_RSS_INDIR, /* binary */ + ETHTOOL_A_RSS_HKEY, /* binary */ + ETHTOOL_A_RSS_INPUT_XFRM, /* u32 */ + + __ETHTOOL_A_RSS_CNT, + ETHTOOL_A_RSS_MAX = (__ETHTOOL_A_RSS_CNT - 1), +}; + +/* PLCA */ + +enum { + ETHTOOL_A_PLCA_UNSPEC, + ETHTOOL_A_PLCA_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_PLCA_VERSION, /* u16 */ + ETHTOOL_A_PLCA_ENABLED, /* u8 */ + ETHTOOL_A_PLCA_STATUS, /* u8 */ + ETHTOOL_A_PLCA_NODE_CNT, /* u32 */ + ETHTOOL_A_PLCA_NODE_ID, /* u32 */ + ETHTOOL_A_PLCA_TO_TMR, /* u32 */ + ETHTOOL_A_PLCA_BURST_CNT, /* u32 */ + ETHTOOL_A_PLCA_BURST_TMR, /* u32 */ + + /* add new constants above here */ + __ETHTOOL_A_PLCA_CNT, + ETHTOOL_A_PLCA_MAX = (__ETHTOOL_A_PLCA_CNT - 1) +}; + +/* MAC Merge (802.3) */ + +enum { + ETHTOOL_A_MM_STAT_UNSPEC, + ETHTOOL_A_MM_STAT_PAD, + + /* aMACMergeFrameAssErrorCount */ + ETHTOOL_A_MM_STAT_REASSEMBLY_ERRORS, /* u64 */ + /* aMACMergeFrameSmdErrorCount */ + ETHTOOL_A_MM_STAT_SMD_ERRORS, /* u64 */ + /* aMACMergeFrameAssOkCount */ + ETHTOOL_A_MM_STAT_REASSEMBLY_OK, /* u64 */ + /* aMACMergeFragCountRx */ + ETHTOOL_A_MM_STAT_RX_FRAG_COUNT, /* u64 */ + /* aMACMergeFragCountTx */ + ETHTOOL_A_MM_STAT_TX_FRAG_COUNT, /* u64 */ + /* aMACMergeHoldCount */ + ETHTOOL_A_MM_STAT_HOLD_COUNT, /* u64 */ + + /* add new constants above here */ + __ETHTOOL_A_MM_STAT_CNT, + ETHTOOL_A_MM_STAT_MAX = (__ETHTOOL_A_MM_STAT_CNT - 1) +}; + +enum { + ETHTOOL_A_MM_UNSPEC, + ETHTOOL_A_MM_HEADER, /* nest - _A_HEADER_* */ + ETHTOOL_A_MM_PMAC_ENABLED, /* u8 */ + ETHTOOL_A_MM_TX_ENABLED, /* u8 */ + ETHTOOL_A_MM_TX_ACTIVE, /* u8 */ + ETHTOOL_A_MM_TX_MIN_FRAG_SIZE, /* u32 */ + ETHTOOL_A_MM_RX_MIN_FRAG_SIZE, /* u32 */ + ETHTOOL_A_MM_VERIFY_ENABLED, /* u8 */ + ETHTOOL_A_MM_VERIFY_STATUS, /* u8 */ + ETHTOOL_A_MM_VERIFY_TIME, /* u32 */ + ETHTOOL_A_MM_MAX_VERIFY_TIME, /* u32 */ + ETHTOOL_A_MM_STATS, /* nest - _A_MM_STAT_* */ + + /* add new constants above here */ + __ETHTOOL_A_MM_CNT, + ETHTOOL_A_MM_MAX = (__ETHTOOL_A_MM_CNT - 1) +}; + +/* generic netlink info */ +#define ETHTOOL_GENL_NAME "ethtool" +#define ETHTOOL_GENL_VERSION 1 + +#define ETHTOOL_MCGRP_MONITOR_NAME "monitor" + +#endif /* _UAPI_LINUX_ETHTOOL_NETLINK_H_ */ diff --git a/uapi/linux/handshake.h b/uapi/linux/handshake.h new file mode 100644 index 0000000..3d7ea58 --- /dev/null +++ b/uapi/linux/handshake.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/handshake.yaml */ +/* YNL-GEN uapi header */ + +#ifndef _UAPI_LINUX_HANDSHAKE_H +#define _UAPI_LINUX_HANDSHAKE_H + +#define HANDSHAKE_FAMILY_NAME "handshake" +#define HANDSHAKE_FAMILY_VERSION 1 + +enum handshake_handler_class { + HANDSHAKE_HANDLER_CLASS_NONE, + HANDSHAKE_HANDLER_CLASS_TLSHD, + HANDSHAKE_HANDLER_CLASS_MAX, +}; + +enum handshake_msg_type { + HANDSHAKE_MSG_TYPE_UNSPEC, + HANDSHAKE_MSG_TYPE_CLIENTHELLO, + HANDSHAKE_MSG_TYPE_SERVERHELLO, +}; + +enum handshake_auth { + HANDSHAKE_AUTH_UNSPEC, + HANDSHAKE_AUTH_UNAUTH, + HANDSHAKE_AUTH_PSK, + HANDSHAKE_AUTH_X509, +}; + +enum { + HANDSHAKE_A_X509_CERT = 1, + HANDSHAKE_A_X509_PRIVKEY, + + __HANDSHAKE_A_X509_MAX, + HANDSHAKE_A_X509_MAX = (__HANDSHAKE_A_X509_MAX - 1) +}; + +enum { + HANDSHAKE_A_ACCEPT_SOCKFD = 1, + HANDSHAKE_A_ACCEPT_HANDLER_CLASS, + HANDSHAKE_A_ACCEPT_MESSAGE_TYPE, + HANDSHAKE_A_ACCEPT_TIMEOUT, + HANDSHAKE_A_ACCEPT_AUTH_MODE, + HANDSHAKE_A_ACCEPT_PEER_IDENTITY, + HANDSHAKE_A_ACCEPT_CERTIFICATE, + HANDSHAKE_A_ACCEPT_PEERNAME, + + __HANDSHAKE_A_ACCEPT_MAX, + HANDSHAKE_A_ACCEPT_MAX = (__HANDSHAKE_A_ACCEPT_MAX - 1) +}; + +enum { + HANDSHAKE_A_DONE_STATUS = 1, + HANDSHAKE_A_DONE_SOCKFD, + HANDSHAKE_A_DONE_REMOTE_AUTH, + + __HANDSHAKE_A_DONE_MAX, + HANDSHAKE_A_DONE_MAX = (__HANDSHAKE_A_DONE_MAX - 1) +}; + +enum { + HANDSHAKE_CMD_READY = 1, + HANDSHAKE_CMD_ACCEPT, + HANDSHAKE_CMD_DONE, + + __HANDSHAKE_CMD_MAX, + HANDSHAKE_CMD_MAX = (__HANDSHAKE_CMD_MAX - 1) +}; + +#define HANDSHAKE_MCGRP_NONE "none" +#define HANDSHAKE_MCGRP_TLSHD "tlshd" + +#endif /* _UAPI_LINUX_HANDSHAKE_H */ diff --git a/uapi/linux/mptcp_pm.h b/uapi/linux/mptcp_pm.h new file mode 100644 index 0000000..50589e5 --- /dev/null +++ b/uapi/linux/mptcp_pm.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/mptcp_pm.yaml */ +/* YNL-GEN uapi header */ + +#ifndef _UAPI_LINUX_MPTCP_PM_H +#define _UAPI_LINUX_MPTCP_PM_H + +#define MPTCP_PM_NAME "mptcp_pm" +#define MPTCP_PM_VER 1 + +/** + * enum mptcp_event_type + * @MPTCP_EVENT_UNSPEC: unused event + * @MPTCP_EVENT_CREATED: token, family, saddr4 | saddr6, daddr4 | daddr6, + * sport, dport A new MPTCP connection has been created. It is the good time + * to allocate memory and send ADD_ADDR if needed. Depending on the + * traffic-patterns it can take a long time until the MPTCP_EVENT_ESTABLISHED + * is sent. + * @MPTCP_EVENT_ESTABLISHED: token, family, saddr4 | saddr6, daddr4 | daddr6, + * sport, dport A MPTCP connection is established (can start new subflows). + * @MPTCP_EVENT_CLOSED: token A MPTCP connection has stopped. + * @MPTCP_EVENT_ANNOUNCED: token, rem_id, family, daddr4 | daddr6 [, dport] A + * new address has been announced by the peer. + * @MPTCP_EVENT_REMOVED: token, rem_id An address has been lost by the peer. + * @MPTCP_EVENT_SUB_ESTABLISHED: token, family, loc_id, rem_id, saddr4 | + * saddr6, daddr4 | daddr6, sport, dport, backup, if_idx [, error] A new + * subflow has been established. 'error' should not be set. + * @MPTCP_EVENT_SUB_CLOSED: token, family, loc_id, rem_id, saddr4 | saddr6, + * daddr4 | daddr6, sport, dport, backup, if_idx [, error] A subflow has been + * closed. An error (copy of sk_err) could be set if an error has been + * detected for this subflow. + * @MPTCP_EVENT_SUB_PRIORITY: token, family, loc_id, rem_id, saddr4 | saddr6, + * daddr4 | daddr6, sport, dport, backup, if_idx [, error] The priority of a + * subflow has changed. 'error' should not be set. + * @MPTCP_EVENT_LISTENER_CREATED: family, sport, saddr4 | saddr6 A new PM + * listener is created. + * @MPTCP_EVENT_LISTENER_CLOSED: family, sport, saddr4 | saddr6 A PM listener + * is closed. + */ +enum mptcp_event_type { + MPTCP_EVENT_UNSPEC, + MPTCP_EVENT_CREATED, + MPTCP_EVENT_ESTABLISHED, + MPTCP_EVENT_CLOSED, + MPTCP_EVENT_ANNOUNCED = 6, + MPTCP_EVENT_REMOVED, + MPTCP_EVENT_SUB_ESTABLISHED = 10, + MPTCP_EVENT_SUB_CLOSED, + MPTCP_EVENT_SUB_PRIORITY = 13, + MPTCP_EVENT_LISTENER_CREATED = 15, + MPTCP_EVENT_LISTENER_CLOSED, +}; + +enum { + MPTCP_PM_ADDR_ATTR_UNSPEC, + MPTCP_PM_ADDR_ATTR_FAMILY, + MPTCP_PM_ADDR_ATTR_ID, + MPTCP_PM_ADDR_ATTR_ADDR4, + MPTCP_PM_ADDR_ATTR_ADDR6, + MPTCP_PM_ADDR_ATTR_PORT, + MPTCP_PM_ADDR_ATTR_FLAGS, + MPTCP_PM_ADDR_ATTR_IF_IDX, + + __MPTCP_PM_ADDR_ATTR_MAX +}; +#define MPTCP_PM_ADDR_ATTR_MAX (__MPTCP_PM_ADDR_ATTR_MAX - 1) + +enum { + MPTCP_SUBFLOW_ATTR_UNSPEC, + MPTCP_SUBFLOW_ATTR_TOKEN_REM, + MPTCP_SUBFLOW_ATTR_TOKEN_LOC, + MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ, + MPTCP_SUBFLOW_ATTR_MAP_SEQ, + MPTCP_SUBFLOW_ATTR_MAP_SFSEQ, + MPTCP_SUBFLOW_ATTR_SSN_OFFSET, + MPTCP_SUBFLOW_ATTR_MAP_DATALEN, + MPTCP_SUBFLOW_ATTR_FLAGS, + MPTCP_SUBFLOW_ATTR_ID_REM, + MPTCP_SUBFLOW_ATTR_ID_LOC, + MPTCP_SUBFLOW_ATTR_PAD, + + __MPTCP_SUBFLOW_ATTR_MAX +}; +#define MPTCP_SUBFLOW_ATTR_MAX (__MPTCP_SUBFLOW_ATTR_MAX - 1) + +enum { + MPTCP_PM_ENDPOINT_ADDR = 1, + + __MPTCP_PM_ENDPOINT_MAX +}; +#define MPTCP_PM_ENDPOINT_MAX (__MPTCP_PM_ENDPOINT_MAX - 1) + +enum { + MPTCP_PM_ATTR_UNSPEC, + MPTCP_PM_ATTR_ADDR, + MPTCP_PM_ATTR_RCV_ADD_ADDRS, + MPTCP_PM_ATTR_SUBFLOWS, + MPTCP_PM_ATTR_TOKEN, + MPTCP_PM_ATTR_LOC_ID, + MPTCP_PM_ATTR_ADDR_REMOTE, + + __MPTCP_ATTR_AFTER_LAST +}; +#define MPTCP_PM_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1) + +enum mptcp_event_attr { + MPTCP_ATTR_UNSPEC, + MPTCP_ATTR_TOKEN, + MPTCP_ATTR_FAMILY, + MPTCP_ATTR_LOC_ID, + MPTCP_ATTR_REM_ID, + MPTCP_ATTR_SADDR4, + MPTCP_ATTR_SADDR6, + MPTCP_ATTR_DADDR4, + MPTCP_ATTR_DADDR6, + MPTCP_ATTR_SPORT, + MPTCP_ATTR_DPORT, + MPTCP_ATTR_BACKUP, + MPTCP_ATTR_ERROR, + MPTCP_ATTR_FLAGS, + MPTCP_ATTR_TIMEOUT, + MPTCP_ATTR_IF_IDX, + MPTCP_ATTR_RESET_REASON, + MPTCP_ATTR_RESET_FLAGS, + MPTCP_ATTR_SERVER_SIDE, + + __MPTCP_ATTR_MAX +}; +#define MPTCP_ATTR_MAX (__MPTCP_ATTR_MAX - 1) + +enum { + MPTCP_PM_CMD_UNSPEC, + MPTCP_PM_CMD_ADD_ADDR, + MPTCP_PM_CMD_DEL_ADDR, + MPTCP_PM_CMD_GET_ADDR, + MPTCP_PM_CMD_FLUSH_ADDRS, + MPTCP_PM_CMD_SET_LIMITS, + MPTCP_PM_CMD_GET_LIMITS, + MPTCP_PM_CMD_SET_FLAGS, + MPTCP_PM_CMD_ANNOUNCE, + MPTCP_PM_CMD_REMOVE, + MPTCP_PM_CMD_SUBFLOW_CREATE, + MPTCP_PM_CMD_SUBFLOW_DESTROY, + + __MPTCP_PM_CMD_AFTER_LAST +}; +#define MPTCP_PM_CMD_MAX (__MPTCP_PM_CMD_AFTER_LAST - 1) + +#endif /* _UAPI_LINUX_MPTCP_PM_H */ diff --git a/uapi/linux/netdev.h b/uapi/linux/netdev.h new file mode 100644 index 0000000..bb65ee8 --- /dev/null +++ b/uapi/linux/netdev.h @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/netdev.yaml */ +/* YNL-GEN uapi header */ + +#ifndef _UAPI_LINUX_NETDEV_H +#define _UAPI_LINUX_NETDEV_H + +#define NETDEV_FAMILY_NAME "netdev" +#define NETDEV_FAMILY_VERSION 1 + +/** + * enum netdev_xdp_act + * @NETDEV_XDP_ACT_BASIC: XDP features set supported by all drivers + * (XDP_ABORTED, XDP_DROP, XDP_PASS, XDP_TX) + * @NETDEV_XDP_ACT_REDIRECT: The netdev supports XDP_REDIRECT + * @NETDEV_XDP_ACT_NDO_XMIT: This feature informs if netdev implements + * ndo_xdp_xmit callback. + * @NETDEV_XDP_ACT_XSK_ZEROCOPY: This feature informs if netdev supports AF_XDP + * in zero copy mode. + * @NETDEV_XDP_ACT_HW_OFFLOAD: This feature informs if netdev supports XDP hw + * offloading. + * @NETDEV_XDP_ACT_RX_SG: This feature informs if netdev implements non-linear + * XDP buffer support in the driver napi callback. + * @NETDEV_XDP_ACT_NDO_XMIT_SG: This feature informs if netdev implements + * non-linear XDP buffer support in ndo_xdp_xmit callback. + */ +enum netdev_xdp_act { + NETDEV_XDP_ACT_BASIC = 1, + NETDEV_XDP_ACT_REDIRECT = 2, + NETDEV_XDP_ACT_NDO_XMIT = 4, + NETDEV_XDP_ACT_XSK_ZEROCOPY = 8, + NETDEV_XDP_ACT_HW_OFFLOAD = 16, + NETDEV_XDP_ACT_RX_SG = 32, + NETDEV_XDP_ACT_NDO_XMIT_SG = 64, + + /* private: */ + NETDEV_XDP_ACT_MASK = 127, +}; + +/** + * enum netdev_xdp_rx_metadata + * @NETDEV_XDP_RX_METADATA_TIMESTAMP: Device is capable of exposing receive HW + * timestamp via bpf_xdp_metadata_rx_timestamp(). + * @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet + * hash via bpf_xdp_metadata_rx_hash(). + * @NETDEV_XDP_RX_METADATA_VLAN_TAG: Device is capable of exposing receive + * packet VLAN tag via bpf_xdp_metadata_rx_vlan_tag(). + */ +enum netdev_xdp_rx_metadata { + NETDEV_XDP_RX_METADATA_TIMESTAMP = 1, + NETDEV_XDP_RX_METADATA_HASH = 2, + NETDEV_XDP_RX_METADATA_VLAN_TAG = 4, +}; + +/** + * enum netdev_xsk_flags + * @NETDEV_XSK_FLAGS_TX_TIMESTAMP: HW timestamping egress packets is supported + * by the driver. + * @NETDEV_XSK_FLAGS_TX_CHECKSUM: L3 checksum HW offload is supported by the + * driver. + */ +enum netdev_xsk_flags { + NETDEV_XSK_FLAGS_TX_TIMESTAMP = 1, + NETDEV_XSK_FLAGS_TX_CHECKSUM = 2, +}; + +enum netdev_queue_type { + NETDEV_QUEUE_TYPE_RX, + NETDEV_QUEUE_TYPE_TX, +}; + +enum netdev_qstats_scope { + NETDEV_QSTATS_SCOPE_QUEUE = 1, +}; + +enum { + NETDEV_A_DEV_IFINDEX = 1, + NETDEV_A_DEV_PAD, + NETDEV_A_DEV_XDP_FEATURES, + NETDEV_A_DEV_XDP_ZC_MAX_SEGS, + NETDEV_A_DEV_XDP_RX_METADATA_FEATURES, + NETDEV_A_DEV_XSK_FEATURES, + + __NETDEV_A_DEV_MAX, + NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1) +}; + +enum { + NETDEV_A_PAGE_POOL_ID = 1, + NETDEV_A_PAGE_POOL_IFINDEX, + NETDEV_A_PAGE_POOL_NAPI_ID, + NETDEV_A_PAGE_POOL_INFLIGHT, + NETDEV_A_PAGE_POOL_INFLIGHT_MEM, + NETDEV_A_PAGE_POOL_DETACH_TIME, + + __NETDEV_A_PAGE_POOL_MAX, + NETDEV_A_PAGE_POOL_MAX = (__NETDEV_A_PAGE_POOL_MAX - 1) +}; + +enum { + NETDEV_A_PAGE_POOL_STATS_INFO = 1, + NETDEV_A_PAGE_POOL_STATS_ALLOC_FAST = 8, + NETDEV_A_PAGE_POOL_STATS_ALLOC_SLOW, + NETDEV_A_PAGE_POOL_STATS_ALLOC_SLOW_HIGH_ORDER, + NETDEV_A_PAGE_POOL_STATS_ALLOC_EMPTY, + NETDEV_A_PAGE_POOL_STATS_ALLOC_REFILL, + NETDEV_A_PAGE_POOL_STATS_ALLOC_WAIVE, + NETDEV_A_PAGE_POOL_STATS_RECYCLE_CACHED, + NETDEV_A_PAGE_POOL_STATS_RECYCLE_CACHE_FULL, + NETDEV_A_PAGE_POOL_STATS_RECYCLE_RING, + NETDEV_A_PAGE_POOL_STATS_RECYCLE_RING_FULL, + NETDEV_A_PAGE_POOL_STATS_RECYCLE_RELEASED_REFCNT, + + __NETDEV_A_PAGE_POOL_STATS_MAX, + NETDEV_A_PAGE_POOL_STATS_MAX = (__NETDEV_A_PAGE_POOL_STATS_MAX - 1) +}; + +enum { + NETDEV_A_NAPI_IFINDEX = 1, + NETDEV_A_NAPI_ID, + NETDEV_A_NAPI_IRQ, + NETDEV_A_NAPI_PID, + + __NETDEV_A_NAPI_MAX, + NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1) +}; + +enum { + NETDEV_A_QUEUE_ID = 1, + NETDEV_A_QUEUE_IFINDEX, + NETDEV_A_QUEUE_TYPE, + NETDEV_A_QUEUE_NAPI_ID, + + __NETDEV_A_QUEUE_MAX, + NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1) +}; + +enum { + NETDEV_A_QSTATS_IFINDEX = 1, + NETDEV_A_QSTATS_QUEUE_TYPE, + NETDEV_A_QSTATS_QUEUE_ID, + NETDEV_A_QSTATS_SCOPE, + NETDEV_A_QSTATS_RX_PACKETS = 8, + NETDEV_A_QSTATS_RX_BYTES, + NETDEV_A_QSTATS_TX_PACKETS, + NETDEV_A_QSTATS_TX_BYTES, + NETDEV_A_QSTATS_RX_ALLOC_FAIL, + + __NETDEV_A_QSTATS_MAX, + NETDEV_A_QSTATS_MAX = (__NETDEV_A_QSTATS_MAX - 1) +}; + +enum { + NETDEV_CMD_DEV_GET = 1, + NETDEV_CMD_DEV_ADD_NTF, + NETDEV_CMD_DEV_DEL_NTF, + NETDEV_CMD_DEV_CHANGE_NTF, + NETDEV_CMD_PAGE_POOL_GET, + NETDEV_CMD_PAGE_POOL_ADD_NTF, + NETDEV_CMD_PAGE_POOL_DEL_NTF, + NETDEV_CMD_PAGE_POOL_CHANGE_NTF, + NETDEV_CMD_PAGE_POOL_STATS_GET, + NETDEV_CMD_QUEUE_GET, + NETDEV_CMD_NAPI_GET, + NETDEV_CMD_QSTATS_GET, + + __NETDEV_CMD_MAX, + NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1) +}; + +#define NETDEV_MCGRP_MGMT "mgmt" +#define NETDEV_MCGRP_PAGE_POOL "page-pool" + +#endif /* _UAPI_LINUX_NETDEV_H */ diff --git a/uapi/linux/nfsd_netlink.h b/uapi/linux/nfsd_netlink.h new file mode 100644 index 0000000..3cd044e --- /dev/null +++ b/uapi/linux/nfsd_netlink.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/nfsd.yaml */ +/* YNL-GEN uapi header */ + +#ifndef _UAPI_LINUX_NFSD_NETLINK_H +#define _UAPI_LINUX_NFSD_NETLINK_H + +#define NFSD_FAMILY_NAME "nfsd" +#define NFSD_FAMILY_VERSION 1 + +enum { + NFSD_A_RPC_STATUS_XID = 1, + NFSD_A_RPC_STATUS_FLAGS, + NFSD_A_RPC_STATUS_PROG, + NFSD_A_RPC_STATUS_VERSION, + NFSD_A_RPC_STATUS_PROC, + NFSD_A_RPC_STATUS_SERVICE_TIME, + NFSD_A_RPC_STATUS_PAD, + NFSD_A_RPC_STATUS_SADDR4, + NFSD_A_RPC_STATUS_DADDR4, + NFSD_A_RPC_STATUS_SADDR6, + NFSD_A_RPC_STATUS_DADDR6, + NFSD_A_RPC_STATUS_SPORT, + NFSD_A_RPC_STATUS_DPORT, + NFSD_A_RPC_STATUS_COMPOUND_OPS, + + __NFSD_A_RPC_STATUS_MAX, + NFSD_A_RPC_STATUS_MAX = (__NFSD_A_RPC_STATUS_MAX - 1) +}; + +enum { + NFSD_CMD_RPC_STATUS_GET = 1, + + __NFSD_CMD_MAX, + NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1) +}; + +#endif /* _UAPI_LINUX_NFSD_NETLINK_H */ diff --git a/uapi/linux/openvswitch.h b/uapi/linux/openvswitch.h new file mode 100644 index 0000000..efc82c3 --- /dev/null +++ b/uapi/linux/openvswitch.h @@ -0,0 +1,1107 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ + +/* + * Copyright (c) 2007-2017 Nicira, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + */ + +#ifndef _UAPI__LINUX_OPENVSWITCH_H +#define _UAPI__LINUX_OPENVSWITCH_H 1 + +#include +#include + +/** + * struct ovs_header - header for OVS Generic Netlink messages. + * @dp_ifindex: ifindex of local port for datapath (0 to make a request not + * specific to a datapath). + * + * Attributes following the header are specific to a particular OVS Generic + * Netlink family, but all of the OVS families use this header. + */ + +struct ovs_header { + int dp_ifindex; +}; + +/* Datapaths. */ + +#define OVS_DATAPATH_FAMILY "ovs_datapath" +#define OVS_DATAPATH_MCGROUP "ovs_datapath" + +/* V2: + * - API users are expected to provide OVS_DP_ATTR_USER_FEATURES + * when creating the datapath. + */ +#define OVS_DATAPATH_VERSION 2 + +/* First OVS datapath version to support features */ +#define OVS_DP_VER_FEATURES 2 + +enum ovs_datapath_cmd { + OVS_DP_CMD_UNSPEC, + OVS_DP_CMD_NEW, + OVS_DP_CMD_DEL, + OVS_DP_CMD_GET, + OVS_DP_CMD_SET +}; + +/** + * enum ovs_datapath_attr - attributes for %OVS_DP_* commands. + * @OVS_DP_ATTR_NAME: Name of the network device that serves as the "local + * port". This is the name of the network device whose dp_ifindex is given in + * the &struct ovs_header. Always present in notifications. Required in + * %OVS_DP_NEW requests. May be used as an alternative to specifying + * dp_ifindex in other requests (with a dp_ifindex of 0). + * @OVS_DP_ATTR_UPCALL_PID: The Netlink socket in userspace that is initially + * set on the datapath port (for OVS_ACTION_ATTR_MISS). Only valid on + * %OVS_DP_CMD_NEW requests. A value of zero indicates that upcalls should + * not be sent. + * @OVS_DP_ATTR_PER_CPU_PIDS: Per-cpu array of PIDs for upcalls when + * OVS_DP_F_DISPATCH_UPCALL_PER_CPU feature is set. + * @OVS_DP_ATTR_STATS: Statistics about packets that have passed through the + * datapath. Always present in notifications. + * @OVS_DP_ATTR_MEGAFLOW_STATS: Statistics about mega flow masks usage for the + * datapath. Always present in notifications. + * @OVS_DP_ATTR_IFINDEX: Interface index for a new datapath netdev. Only + * valid for %OVS_DP_CMD_NEW requests. + * + * These attributes follow the &struct ovs_header within the Generic Netlink + * payload for %OVS_DP_* commands. + */ +enum ovs_datapath_attr { + OVS_DP_ATTR_UNSPEC, + OVS_DP_ATTR_NAME, /* name of dp_ifindex netdev */ + OVS_DP_ATTR_UPCALL_PID, /* Netlink PID to receive upcalls */ + OVS_DP_ATTR_STATS, /* struct ovs_dp_stats */ + OVS_DP_ATTR_MEGAFLOW_STATS, /* struct ovs_dp_megaflow_stats */ + OVS_DP_ATTR_USER_FEATURES, /* OVS_DP_F_* */ + OVS_DP_ATTR_PAD, + OVS_DP_ATTR_MASKS_CACHE_SIZE, + OVS_DP_ATTR_PER_CPU_PIDS, /* Netlink PIDS to receive upcalls in + * per-cpu dispatch mode + */ + OVS_DP_ATTR_IFINDEX, + __OVS_DP_ATTR_MAX +}; + +#define OVS_DP_ATTR_MAX (__OVS_DP_ATTR_MAX - 1) + +struct ovs_dp_stats { + __u64 n_hit; /* Number of flow table matches. */ + __u64 n_missed; /* Number of flow table misses. */ + __u64 n_lost; /* Number of misses not sent to userspace. */ + __u64 n_flows; /* Number of flows present */ +}; + +struct ovs_dp_megaflow_stats { + __u64 n_mask_hit; /* Number of masks used for flow lookups. */ + __u32 n_masks; /* Number of masks for the datapath. */ + __u32 pad0; /* Pad for future expension. */ + __u64 n_cache_hit; /* Number of cache matches for flow lookups. */ + __u64 pad1; /* Pad for future expension. */ +}; + +struct ovs_vport_stats { + __u64 rx_packets; /* total packets received */ + __u64 tx_packets; /* total packets transmitted */ + __u64 rx_bytes; /* total bytes received */ + __u64 tx_bytes; /* total bytes transmitted */ + __u64 rx_errors; /* bad packets received */ + __u64 tx_errors; /* packet transmit problems */ + __u64 rx_dropped; /* no space in linux buffers */ + __u64 tx_dropped; /* no space available in linux */ +}; + +/* Allow last Netlink attribute to be unaligned */ +#define OVS_DP_F_UNALIGNED (1 << 0) + +/* Allow datapath to associate multiple Netlink PIDs to each vport */ +#define OVS_DP_F_VPORT_PIDS (1 << 1) + +/* Allow tc offload recirc sharing */ +#define OVS_DP_F_TC_RECIRC_SHARING (1 << 2) + +/* Allow per-cpu dispatch of upcalls */ +#define OVS_DP_F_DISPATCH_UPCALL_PER_CPU (1 << 3) + +/* Fixed logical ports. */ +#define OVSP_LOCAL ((__u32)0) + +/* Packet transfer. */ + +#define OVS_PACKET_FAMILY "ovs_packet" +#define OVS_PACKET_VERSION 0x1 + +enum ovs_packet_cmd { + OVS_PACKET_CMD_UNSPEC, + + /* Kernel-to-user notifications. */ + OVS_PACKET_CMD_MISS, /* Flow table miss. */ + OVS_PACKET_CMD_ACTION, /* OVS_ACTION_ATTR_USERSPACE action. */ + + /* Userspace commands. */ + OVS_PACKET_CMD_EXECUTE /* Apply actions to a packet. */ +}; + +/** + * enum ovs_packet_attr - attributes for %OVS_PACKET_* commands. + * @OVS_PACKET_ATTR_PACKET: Present for all notifications. Contains the entire + * packet as received, from the start of the Ethernet header onward. For + * %OVS_PACKET_CMD_ACTION, %OVS_PACKET_ATTR_PACKET reflects changes made by + * actions preceding %OVS_ACTION_ATTR_USERSPACE, but %OVS_PACKET_ATTR_KEY is + * the flow key extracted from the packet as originally received. + * @OVS_PACKET_ATTR_KEY: Present for all notifications. Contains the flow key + * extracted from the packet as nested %OVS_KEY_ATTR_* attributes. This allows + * userspace to adapt its flow setup strategy by comparing its notion of the + * flow key against the kernel's. + * @OVS_PACKET_ATTR_ACTIONS: Contains actions for the packet. Used + * for %OVS_PACKET_CMD_EXECUTE. It has nested %OVS_ACTION_ATTR_* attributes. + * Also used in upcall when %OVS_ACTION_ATTR_USERSPACE has optional + * %OVS_USERSPACE_ATTR_ACTIONS attribute. + * @OVS_PACKET_ATTR_USERDATA: Present for an %OVS_PACKET_CMD_ACTION + * notification if the %OVS_ACTION_ATTR_USERSPACE action specified an + * %OVS_USERSPACE_ATTR_USERDATA attribute, with the same length and content + * specified there. + * @OVS_PACKET_ATTR_EGRESS_TUN_KEY: Present for an %OVS_PACKET_CMD_ACTION + * notification if the %OVS_ACTION_ATTR_USERSPACE action specified an + * %OVS_USERSPACE_ATTR_EGRESS_TUN_PORT attribute, which is sent only if the + * output port is actually a tunnel port. Contains the output tunnel key + * extracted from the packet as nested %OVS_TUNNEL_KEY_ATTR_* attributes. + * @OVS_PACKET_ATTR_MRU: Present for an %OVS_PACKET_CMD_ACTION and + * @OVS_PACKET_ATTR_LEN: Packet size before truncation. + * %OVS_PACKET_ATTR_USERSPACE action specify the Maximum received fragment + * size. + * @OVS_PACKET_ATTR_HASH: Packet hash info (e.g. hash, sw_hash and l4_hash in skb). + * + * These attributes follow the &struct ovs_header within the Generic Netlink + * payload for %OVS_PACKET_* commands. + */ +enum ovs_packet_attr { + OVS_PACKET_ATTR_UNSPEC, + OVS_PACKET_ATTR_PACKET, /* Packet data. */ + OVS_PACKET_ATTR_KEY, /* Nested OVS_KEY_ATTR_* attributes. */ + OVS_PACKET_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ + OVS_PACKET_ATTR_USERDATA, /* OVS_ACTION_ATTR_USERSPACE arg. */ + OVS_PACKET_ATTR_EGRESS_TUN_KEY, /* Nested OVS_TUNNEL_KEY_ATTR_* + attributes. */ + OVS_PACKET_ATTR_UNUSED1, + OVS_PACKET_ATTR_UNUSED2, + OVS_PACKET_ATTR_PROBE, /* Packet operation is a feature probe, + error logging should be suppressed. */ + OVS_PACKET_ATTR_MRU, /* Maximum received IP fragment size. */ + OVS_PACKET_ATTR_LEN, /* Packet size before truncation. */ + OVS_PACKET_ATTR_HASH, /* Packet hash. */ + __OVS_PACKET_ATTR_MAX +}; + +#define OVS_PACKET_ATTR_MAX (__OVS_PACKET_ATTR_MAX - 1) + +/* Virtual ports. */ + +#define OVS_VPORT_FAMILY "ovs_vport" +#define OVS_VPORT_MCGROUP "ovs_vport" +#define OVS_VPORT_VERSION 0x1 + +enum ovs_vport_cmd { + OVS_VPORT_CMD_UNSPEC, + OVS_VPORT_CMD_NEW, + OVS_VPORT_CMD_DEL, + OVS_VPORT_CMD_GET, + OVS_VPORT_CMD_SET +}; + +enum ovs_vport_type { + OVS_VPORT_TYPE_UNSPEC, + OVS_VPORT_TYPE_NETDEV, /* network device */ + OVS_VPORT_TYPE_INTERNAL, /* network device implemented by datapath */ + OVS_VPORT_TYPE_GRE, /* GRE tunnel. */ + OVS_VPORT_TYPE_VXLAN, /* VXLAN tunnel. */ + OVS_VPORT_TYPE_GENEVE, /* Geneve tunnel. */ + __OVS_VPORT_TYPE_MAX +}; + +#define OVS_VPORT_TYPE_MAX (__OVS_VPORT_TYPE_MAX - 1) + +/** + * enum ovs_vport_attr - attributes for %OVS_VPORT_* commands. + * @OVS_VPORT_ATTR_PORT_NO: 32-bit port number within datapath. + * @OVS_VPORT_ATTR_TYPE: 32-bit %OVS_VPORT_TYPE_* constant describing the type + * of vport. + * @OVS_VPORT_ATTR_NAME: Name of vport. For a vport based on a network device + * this is the name of the network device. Maximum length %IFNAMSIZ-1 bytes + * plus a null terminator. + * @OVS_VPORT_ATTR_OPTIONS: Vport-specific configuration information. + * @OVS_VPORT_ATTR_UPCALL_PID: The array of Netlink socket pids in userspace + * among which OVS_PACKET_CMD_MISS upcalls will be distributed for packets + * received on this port. If this is a single-element array of value 0, + * upcalls should not be sent. + * @OVS_VPORT_ATTR_STATS: A &struct ovs_vport_stats giving statistics for + * packets sent or received through the vport. + * + * These attributes follow the &struct ovs_header within the Generic Netlink + * payload for %OVS_VPORT_* commands. + * + * For %OVS_VPORT_CMD_NEW requests, the %OVS_VPORT_ATTR_TYPE and + * %OVS_VPORT_ATTR_NAME attributes are required. %OVS_VPORT_ATTR_PORT_NO is + * optional; if not specified a free port number is automatically selected. + * Whether %OVS_VPORT_ATTR_OPTIONS is required or optional depends on the type + * of vport. + * + * For other requests, if %OVS_VPORT_ATTR_NAME is specified then it is used to + * look up the vport to operate on; otherwise dp_idx from the &struct + * ovs_header plus %OVS_VPORT_ATTR_PORT_NO determine the vport. + */ +enum ovs_vport_attr { + OVS_VPORT_ATTR_UNSPEC, + OVS_VPORT_ATTR_PORT_NO, /* u32 port number within datapath */ + OVS_VPORT_ATTR_TYPE, /* u32 OVS_VPORT_TYPE_* constant. */ + OVS_VPORT_ATTR_NAME, /* string name, up to IFNAMSIZ bytes long */ + OVS_VPORT_ATTR_OPTIONS, /* nested attributes, varies by vport type */ + OVS_VPORT_ATTR_UPCALL_PID, /* array of u32 Netlink socket PIDs for */ + /* receiving upcalls */ + OVS_VPORT_ATTR_STATS, /* struct ovs_vport_stats */ + OVS_VPORT_ATTR_PAD, + OVS_VPORT_ATTR_IFINDEX, + OVS_VPORT_ATTR_NETNSID, + OVS_VPORT_ATTR_UPCALL_STATS, + __OVS_VPORT_ATTR_MAX +}; + +#define OVS_VPORT_ATTR_MAX (__OVS_VPORT_ATTR_MAX - 1) + +/** + * enum ovs_vport_upcall_attr - attributes for %OVS_VPORT_UPCALL* commands + * @OVS_VPORT_UPCALL_SUCCESS: 64-bit upcall success packets. + * @OVS_VPORT_UPCALL_FAIL: 64-bit upcall fail packets. + */ +enum ovs_vport_upcall_attr { + OVS_VPORT_UPCALL_ATTR_SUCCESS, + OVS_VPORT_UPCALL_ATTR_FAIL, + __OVS_VPORT_UPCALL_ATTR_MAX +}; + +#define OVS_VPORT_UPCALL_ATTR_MAX (__OVS_VPORT_UPCALL_ATTR_MAX - 1) + +enum { + OVS_VXLAN_EXT_UNSPEC, + OVS_VXLAN_EXT_GBP, /* Flag or __u32 */ + __OVS_VXLAN_EXT_MAX, +}; + +#define OVS_VXLAN_EXT_MAX (__OVS_VXLAN_EXT_MAX - 1) + + +/* OVS_VPORT_ATTR_OPTIONS attributes for tunnels. + */ +enum { + OVS_TUNNEL_ATTR_UNSPEC, + OVS_TUNNEL_ATTR_DST_PORT, /* 16-bit UDP port, used by L4 tunnels. */ + OVS_TUNNEL_ATTR_EXTENSION, + __OVS_TUNNEL_ATTR_MAX +}; + +#define OVS_TUNNEL_ATTR_MAX (__OVS_TUNNEL_ATTR_MAX - 1) + +/* Flows. */ + +#define OVS_FLOW_FAMILY "ovs_flow" +#define OVS_FLOW_MCGROUP "ovs_flow" +#define OVS_FLOW_VERSION 0x1 + +enum ovs_flow_cmd { + OVS_FLOW_CMD_UNSPEC, + OVS_FLOW_CMD_NEW, + OVS_FLOW_CMD_DEL, + OVS_FLOW_CMD_GET, + OVS_FLOW_CMD_SET +}; + +struct ovs_flow_stats { + __u64 n_packets; /* Number of matched packets. */ + __u64 n_bytes; /* Number of matched bytes. */ +}; + +enum ovs_key_attr { + OVS_KEY_ATTR_UNSPEC, + OVS_KEY_ATTR_ENCAP, /* Nested set of encapsulated attributes. */ + OVS_KEY_ATTR_PRIORITY, /* u32 skb->priority */ + OVS_KEY_ATTR_IN_PORT, /* u32 OVS dp port number */ + OVS_KEY_ATTR_ETHERNET, /* struct ovs_key_ethernet */ + OVS_KEY_ATTR_VLAN, /* be16 VLAN TCI */ + OVS_KEY_ATTR_ETHERTYPE, /* be16 Ethernet type */ + OVS_KEY_ATTR_IPV4, /* struct ovs_key_ipv4 */ + OVS_KEY_ATTR_IPV6, /* struct ovs_key_ipv6 */ + OVS_KEY_ATTR_TCP, /* struct ovs_key_tcp */ + OVS_KEY_ATTR_UDP, /* struct ovs_key_udp */ + OVS_KEY_ATTR_ICMP, /* struct ovs_key_icmp */ + OVS_KEY_ATTR_ICMPV6, /* struct ovs_key_icmpv6 */ + OVS_KEY_ATTR_ARP, /* struct ovs_key_arp */ + OVS_KEY_ATTR_ND, /* struct ovs_key_nd */ + OVS_KEY_ATTR_SKB_MARK, /* u32 skb mark */ + OVS_KEY_ATTR_TUNNEL, /* Nested set of ovs_tunnel attributes */ + OVS_KEY_ATTR_SCTP, /* struct ovs_key_sctp */ + OVS_KEY_ATTR_TCP_FLAGS, /* be16 TCP flags. */ + OVS_KEY_ATTR_DP_HASH, /* u32 hash value. Value 0 indicates the hash + is not computed by the datapath. */ + OVS_KEY_ATTR_RECIRC_ID, /* u32 recirc id */ + OVS_KEY_ATTR_MPLS, /* array of struct ovs_key_mpls. + * The implementation may restrict + * the accepted length of the array. */ + OVS_KEY_ATTR_CT_STATE, /* u32 bitmask of OVS_CS_F_* */ + OVS_KEY_ATTR_CT_ZONE, /* u16 connection tracking zone. */ + OVS_KEY_ATTR_CT_MARK, /* u32 connection tracking mark */ + OVS_KEY_ATTR_CT_LABELS, /* 16-octet connection tracking label */ + OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4, /* struct ovs_key_ct_tuple_ipv4 */ + OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6, /* struct ovs_key_ct_tuple_ipv6 */ + OVS_KEY_ATTR_NSH, /* Nested set of ovs_nsh_key_* */ + + /* User space decided to squat on types 29 and 30. They are defined + * below, but should not be sent to the kernel. + * + * WARNING: No new types should be added unless they are defined + * for both kernel and user space (no 'ifdef's). It's hard + * to keep compatibility otherwise. + */ + OVS_KEY_ATTR_PACKET_TYPE, /* be32 packet type */ + OVS_KEY_ATTR_ND_EXTENSIONS, /* IPv6 Neighbor Discovery extensions */ + + OVS_KEY_ATTR_TUNNEL_INFO, /* struct ip_tunnel_info. + * For in-kernel use only. + */ + OVS_KEY_ATTR_IPV6_EXTHDRS, /* struct ovs_key_ipv6_exthdr */ + __OVS_KEY_ATTR_MAX +}; + +#define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1) + +enum ovs_tunnel_key_attr { + /* OVS_TUNNEL_KEY_ATTR_NONE, standard nl API requires this attribute! */ + OVS_TUNNEL_KEY_ATTR_ID, /* be64 Tunnel ID */ + OVS_TUNNEL_KEY_ATTR_IPV4_SRC, /* be32 src IP address. */ + OVS_TUNNEL_KEY_ATTR_IPV4_DST, /* be32 dst IP address. */ + OVS_TUNNEL_KEY_ATTR_TOS, /* u8 Tunnel IP ToS. */ + OVS_TUNNEL_KEY_ATTR_TTL, /* u8 Tunnel IP TTL. */ + OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT, /* No argument, set DF. */ + OVS_TUNNEL_KEY_ATTR_CSUM, /* No argument. CSUM packet. */ + OVS_TUNNEL_KEY_ATTR_OAM, /* No argument. OAM frame. */ + OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS, /* Array of Geneve options. */ + OVS_TUNNEL_KEY_ATTR_TP_SRC, /* be16 src Transport Port. */ + OVS_TUNNEL_KEY_ATTR_TP_DST, /* be16 dst Transport Port. */ + OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS, /* Nested OVS_VXLAN_EXT_* */ + OVS_TUNNEL_KEY_ATTR_IPV6_SRC, /* struct in6_addr src IPv6 address. */ + OVS_TUNNEL_KEY_ATTR_IPV6_DST, /* struct in6_addr dst IPv6 address. */ + OVS_TUNNEL_KEY_ATTR_PAD, + OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS, /* struct erspan_metadata */ + OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE, /* No argument. IPV4_INFO_BRIDGE mode.*/ + __OVS_TUNNEL_KEY_ATTR_MAX +}; + +#define OVS_TUNNEL_KEY_ATTR_MAX (__OVS_TUNNEL_KEY_ATTR_MAX - 1) + +/** + * enum ovs_frag_type - IPv4 and IPv6 fragment type + * @OVS_FRAG_TYPE_NONE: Packet is not a fragment. + * @OVS_FRAG_TYPE_FIRST: Packet is a fragment with offset 0. + * @OVS_FRAG_TYPE_LATER: Packet is a fragment with nonzero offset. + * + * Used as the @ipv4_frag in &struct ovs_key_ipv4 and as @ipv6_frag &struct + * ovs_key_ipv6. + */ +enum ovs_frag_type { + OVS_FRAG_TYPE_NONE, + OVS_FRAG_TYPE_FIRST, + OVS_FRAG_TYPE_LATER, + __OVS_FRAG_TYPE_MAX +}; + +#define OVS_FRAG_TYPE_MAX (__OVS_FRAG_TYPE_MAX - 1) + +struct ovs_key_ethernet { + __u8 eth_src[ETH_ALEN]; + __u8 eth_dst[ETH_ALEN]; +}; + +struct ovs_key_mpls { + __be32 mpls_lse; +}; + +struct ovs_key_ipv4 { + __be32 ipv4_src; + __be32 ipv4_dst; + __u8 ipv4_proto; + __u8 ipv4_tos; + __u8 ipv4_ttl; + __u8 ipv4_frag; /* One of OVS_FRAG_TYPE_*. */ +}; + +struct ovs_key_ipv6 { + __be32 ipv6_src[4]; + __be32 ipv6_dst[4]; + __be32 ipv6_label; /* 20-bits in least-significant bits. */ + __u8 ipv6_proto; + __u8 ipv6_tclass; + __u8 ipv6_hlimit; + __u8 ipv6_frag; /* One of OVS_FRAG_TYPE_*. */ +}; + +/* separate structure to support backward compatibility with older user space */ +struct ovs_key_ipv6_exthdrs { + __u16 hdrs; +}; + +struct ovs_key_tcp { + __be16 tcp_src; + __be16 tcp_dst; +}; + +struct ovs_key_udp { + __be16 udp_src; + __be16 udp_dst; +}; + +struct ovs_key_sctp { + __be16 sctp_src; + __be16 sctp_dst; +}; + +struct ovs_key_icmp { + __u8 icmp_type; + __u8 icmp_code; +}; + +struct ovs_key_icmpv6 { + __u8 icmpv6_type; + __u8 icmpv6_code; +}; + +struct ovs_key_arp { + __be32 arp_sip; + __be32 arp_tip; + __be16 arp_op; + __u8 arp_sha[ETH_ALEN]; + __u8 arp_tha[ETH_ALEN]; +}; + +struct ovs_key_nd { + __be32 nd_target[4]; + __u8 nd_sll[ETH_ALEN]; + __u8 nd_tll[ETH_ALEN]; +}; + +#define OVS_CT_LABELS_LEN_32 4 +#define OVS_CT_LABELS_LEN (OVS_CT_LABELS_LEN_32 * sizeof(__u32)) +struct ovs_key_ct_labels { + union { + __u8 ct_labels[OVS_CT_LABELS_LEN]; + __u32 ct_labels_32[OVS_CT_LABELS_LEN_32]; + }; +}; + +/* OVS_KEY_ATTR_CT_STATE flags */ +#define OVS_CS_F_NEW 0x01 /* Beginning of a new connection. */ +#define OVS_CS_F_ESTABLISHED 0x02 /* Part of an existing connection. */ +#define OVS_CS_F_RELATED 0x04 /* Related to an established + * connection. */ +#define OVS_CS_F_REPLY_DIR 0x08 /* Flow is in the reply direction. */ +#define OVS_CS_F_INVALID 0x10 /* Could not track connection. */ +#define OVS_CS_F_TRACKED 0x20 /* Conntrack has occurred. */ +#define OVS_CS_F_SRC_NAT 0x40 /* Packet's source address/port was + * mangled by NAT. + */ +#define OVS_CS_F_DST_NAT 0x80 /* Packet's destination address/port + * was mangled by NAT. + */ + +#define OVS_CS_F_NAT_MASK (OVS_CS_F_SRC_NAT | OVS_CS_F_DST_NAT) + +struct ovs_key_ct_tuple_ipv4 { + __be32 ipv4_src; + __be32 ipv4_dst; + __be16 src_port; + __be16 dst_port; + __u8 ipv4_proto; +}; + +struct ovs_key_ct_tuple_ipv6 { + __be32 ipv6_src[4]; + __be32 ipv6_dst[4]; + __be16 src_port; + __be16 dst_port; + __u8 ipv6_proto; +}; + +enum ovs_nsh_key_attr { + OVS_NSH_KEY_ATTR_UNSPEC, + OVS_NSH_KEY_ATTR_BASE, /* struct ovs_nsh_key_base. */ + OVS_NSH_KEY_ATTR_MD1, /* struct ovs_nsh_key_md1. */ + OVS_NSH_KEY_ATTR_MD2, /* variable-length octets for MD type 2. */ + __OVS_NSH_KEY_ATTR_MAX +}; + +#define OVS_NSH_KEY_ATTR_MAX (__OVS_NSH_KEY_ATTR_MAX - 1) + +struct ovs_nsh_key_base { + __u8 flags; + __u8 ttl; + __u8 mdtype; + __u8 np; + __be32 path_hdr; +}; + +#define NSH_MD1_CONTEXT_SIZE 4 + +struct ovs_nsh_key_md1 { + __be32 context[NSH_MD1_CONTEXT_SIZE]; +}; + +/** + * enum ovs_flow_attr - attributes for %OVS_FLOW_* commands. + * @OVS_FLOW_ATTR_KEY: Nested %OVS_KEY_ATTR_* attributes specifying the flow + * key. Always present in notifications. Required for all requests (except + * dumps). + * @OVS_FLOW_ATTR_ACTIONS: Nested %OVS_ACTION_ATTR_* attributes specifying + * the actions to take for packets that match the key. Always present in + * notifications. Required for %OVS_FLOW_CMD_NEW requests, optional for + * %OVS_FLOW_CMD_SET requests. An %OVS_FLOW_CMD_SET without + * %OVS_FLOW_ATTR_ACTIONS will not modify the actions. To clear the actions, + * an %OVS_FLOW_ATTR_ACTIONS without any nested attributes must be given. + * @OVS_FLOW_ATTR_STATS: &struct ovs_flow_stats giving statistics for this + * flow. Present in notifications if the stats would be nonzero. Ignored in + * requests. + * @OVS_FLOW_ATTR_TCP_FLAGS: An 8-bit value giving the OR'd value of all of the + * TCP flags seen on packets in this flow. Only present in notifications for + * TCP flows, and only if it would be nonzero. Ignored in requests. + * @OVS_FLOW_ATTR_USED: A 64-bit integer giving the time, in milliseconds on + * the system monotonic clock, at which a packet was last processed for this + * flow. Only present in notifications if a packet has been processed for this + * flow. Ignored in requests. + * @OVS_FLOW_ATTR_CLEAR: If present in a %OVS_FLOW_CMD_SET request, clears the + * last-used time, accumulated TCP flags, and statistics for this flow. + * Otherwise ignored in requests. Never present in notifications. + * @OVS_FLOW_ATTR_MASK: Nested %OVS_KEY_ATTR_* attributes specifying the + * mask bits for wildcarded flow match. Mask bit value '1' specifies exact + * match with corresponding flow key bit, while mask bit value '0' specifies + * a wildcarded match. Omitting attribute is treated as wildcarding all + * corresponding fields. Optional for all requests. If not present, + * all flow key bits are exact match bits. + * @OVS_FLOW_ATTR_UFID: A value between 1-16 octets specifying a unique + * identifier for the flow. Causes the flow to be indexed by this value rather + * than the value of the %OVS_FLOW_ATTR_KEY attribute. Optional for all + * requests. Present in notifications if the flow was created with this + * attribute. + * @OVS_FLOW_ATTR_UFID_FLAGS: A 32-bit value of OR'd %OVS_UFID_F_* + * flags that provide alternative semantics for flow installation and + * retrieval. Optional for all requests. + * + * These attributes follow the &struct ovs_header within the Generic Netlink + * payload for %OVS_FLOW_* commands. + */ +enum ovs_flow_attr { + OVS_FLOW_ATTR_UNSPEC, + OVS_FLOW_ATTR_KEY, /* Sequence of OVS_KEY_ATTR_* attributes. */ + OVS_FLOW_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ + OVS_FLOW_ATTR_STATS, /* struct ovs_flow_stats. */ + OVS_FLOW_ATTR_TCP_FLAGS, /* 8-bit OR'd TCP flags. */ + OVS_FLOW_ATTR_USED, /* u64 msecs last used in monotonic time. */ + OVS_FLOW_ATTR_CLEAR, /* Flag to clear stats, tcp_flags, used. */ + OVS_FLOW_ATTR_MASK, /* Sequence of OVS_KEY_ATTR_* attributes. */ + OVS_FLOW_ATTR_PROBE, /* Flow operation is a feature probe, error + * logging should be suppressed. */ + OVS_FLOW_ATTR_UFID, /* Variable length unique flow identifier. */ + OVS_FLOW_ATTR_UFID_FLAGS,/* u32 of OVS_UFID_F_*. */ + OVS_FLOW_ATTR_PAD, + __OVS_FLOW_ATTR_MAX +}; + +#define OVS_FLOW_ATTR_MAX (__OVS_FLOW_ATTR_MAX - 1) + +/** + * Omit attributes for notifications. + * + * If a datapath request contains an %OVS_UFID_F_OMIT_* flag, then the datapath + * may omit the corresponding %OVS_FLOW_ATTR_* from the response. + */ +#define OVS_UFID_F_OMIT_KEY (1 << 0) +#define OVS_UFID_F_OMIT_MASK (1 << 1) +#define OVS_UFID_F_OMIT_ACTIONS (1 << 2) + +/** + * enum ovs_sample_attr - Attributes for %OVS_ACTION_ATTR_SAMPLE action. + * @OVS_SAMPLE_ATTR_PROBABILITY: 32-bit fraction of packets to sample with + * @OVS_ACTION_ATTR_SAMPLE. A value of 0 samples no packets, a value of + * %UINT32_MAX samples all packets and intermediate values sample intermediate + * fractions of packets. + * @OVS_SAMPLE_ATTR_ACTIONS: Set of actions to execute in sampling event. + * Actions are passed as nested attributes. + * + * Executes the specified actions with the given probability on a per-packet + * basis. + */ +enum ovs_sample_attr { + OVS_SAMPLE_ATTR_UNSPEC, + OVS_SAMPLE_ATTR_PROBABILITY, /* u32 number */ + OVS_SAMPLE_ATTR_ACTIONS, /* Nested OVS_ACTION_ATTR_* attributes. */ + __OVS_SAMPLE_ATTR_MAX, + +#ifdef __KERNEL__ + OVS_SAMPLE_ATTR_ARG /* struct sample_arg */ +#endif +}; + +#define OVS_SAMPLE_ATTR_MAX (__OVS_SAMPLE_ATTR_MAX - 1) + +#ifdef __KERNEL__ +struct sample_arg { + bool exec; /* When true, actions in sample will not + * change flow keys. False otherwise. + */ + u32 probability; /* Same value as + * 'OVS_SAMPLE_ATTR_PROBABILITY'. + */ +}; +#endif + +/** + * enum ovs_userspace_attr - Attributes for %OVS_ACTION_ATTR_USERSPACE action. + * @OVS_USERSPACE_ATTR_PID: u32 Netlink PID to which the %OVS_PACKET_CMD_ACTION + * message should be sent. Required. + * @OVS_USERSPACE_ATTR_USERDATA: If present, its variable-length argument is + * copied to the %OVS_PACKET_CMD_ACTION message as %OVS_PACKET_ATTR_USERDATA. + * @OVS_USERSPACE_ATTR_EGRESS_TUN_PORT: If present, u32 output port to get + * tunnel info. + * @OVS_USERSPACE_ATTR_ACTIONS: If present, send actions with upcall. + */ +enum ovs_userspace_attr { + OVS_USERSPACE_ATTR_UNSPEC, + OVS_USERSPACE_ATTR_PID, /* u32 Netlink PID to receive upcalls. */ + OVS_USERSPACE_ATTR_USERDATA, /* Optional user-specified cookie. */ + OVS_USERSPACE_ATTR_EGRESS_TUN_PORT, /* Optional, u32 output port + * to get tunnel info. */ + OVS_USERSPACE_ATTR_ACTIONS, /* Optional flag to get actions. */ + __OVS_USERSPACE_ATTR_MAX +}; + +#define OVS_USERSPACE_ATTR_MAX (__OVS_USERSPACE_ATTR_MAX - 1) + +struct ovs_action_trunc { + __u32 max_len; /* Max packet size in bytes. */ +}; + +/** + * struct ovs_action_push_mpls - %OVS_ACTION_ATTR_PUSH_MPLS action argument. + * @mpls_lse: MPLS label stack entry to push. + * @mpls_ethertype: Ethertype to set in the encapsulating ethernet frame. + * + * The only values @mpls_ethertype should ever be given are %ETH_P_MPLS_UC and + * %ETH_P_MPLS_MC, indicating MPLS unicast or multicast. Other are rejected. + */ +struct ovs_action_push_mpls { + __be32 mpls_lse; + __be16 mpls_ethertype; /* Either %ETH_P_MPLS_UC or %ETH_P_MPLS_MC */ +}; + +/** + * struct ovs_action_add_mpls - %OVS_ACTION_ATTR_ADD_MPLS action + * argument. + * @mpls_lse: MPLS label stack entry to push. + * @mpls_ethertype: Ethertype to set in the encapsulating ethernet frame. + * @tun_flags: MPLS tunnel attributes. + * + * The only values @mpls_ethertype should ever be given are %ETH_P_MPLS_UC and + * %ETH_P_MPLS_MC, indicating MPLS unicast or multicast. Other are rejected. + */ +struct ovs_action_add_mpls { + __be32 mpls_lse; + __be16 mpls_ethertype; /* Either %ETH_P_MPLS_UC or %ETH_P_MPLS_MC */ + __u16 tun_flags; +}; + +#define OVS_MPLS_L3_TUNNEL_FLAG_MASK (1 << 0) /* Flag to specify the place of + * insertion of MPLS header. + * When false, the MPLS header + * will be inserted at the start + * of the packet. + * When true, the MPLS header + * will be inserted at the start + * of the l3 header. + */ + +/** + * struct ovs_action_push_vlan - %OVS_ACTION_ATTR_PUSH_VLAN action argument. + * @vlan_tpid: Tag protocol identifier (TPID) to push. + * @vlan_tci: Tag control identifier (TCI) to push. The CFI bit must be set + * (but it will not be set in the 802.1Q header that is pushed). + * + * The @vlan_tpid value is typically %ETH_P_8021Q or %ETH_P_8021AD. + * The only acceptable TPID values are those that the kernel module also parses + * as 802.1Q or 802.1AD headers, to prevent %OVS_ACTION_ATTR_PUSH_VLAN followed + * by %OVS_ACTION_ATTR_POP_VLAN from having surprising results. + */ +struct ovs_action_push_vlan { + __be16 vlan_tpid; /* 802.1Q or 802.1ad TPID. */ + __be16 vlan_tci; /* 802.1Q TCI (VLAN ID and priority). */ +}; + +/* Data path hash algorithm for computing Datapath hash. + * + * The algorithm type only specifies the fields in a flow + * will be used as part of the hash. Each datapath is free + * to use its own hash algorithm. The hash value will be + * opaque to the user space daemon. + */ +enum ovs_hash_alg { + OVS_HASH_ALG_L4, + OVS_HASH_ALG_SYM_L4, +}; + +/* + * struct ovs_action_hash - %OVS_ACTION_ATTR_HASH action argument. + * @hash_alg: Algorithm used to compute hash prior to recirculation. + * @hash_basis: basis used for computing hash. + */ +struct ovs_action_hash { + __u32 hash_alg; /* One of ovs_hash_alg. */ + __u32 hash_basis; +}; + +/** + * enum ovs_ct_attr - Attributes for %OVS_ACTION_ATTR_CT action. + * @OVS_CT_ATTR_COMMIT: If present, commits the connection to the conntrack + * table. This allows future packets for the same connection to be identified + * as 'established' or 'related'. The flow key for the current packet will + * retain the pre-commit connection state. + * @OVS_CT_ATTR_ZONE: u16 connection tracking zone. + * @OVS_CT_ATTR_MARK: u32 value followed by u32 mask. For each bit set in the + * mask, the corresponding bit in the value is copied to the connection + * tracking mark field in the connection. + * @OVS_CT_ATTR_LABELS: %OVS_CT_LABELS_LEN value followed by %OVS_CT_LABELS_LEN + * mask. For each bit set in the mask, the corresponding bit in the value is + * copied to the connection tracking label field in the connection. + * @OVS_CT_ATTR_HELPER: variable length string defining conntrack ALG. + * @OVS_CT_ATTR_NAT: Nested OVS_NAT_ATTR_* for performing L3 network address + * translation (NAT) on the packet. + * @OVS_CT_ATTR_FORCE_COMMIT: Like %OVS_CT_ATTR_COMMIT, but instead of doing + * nothing if the connection is already committed will check that the current + * packet is in conntrack entry's original direction. If directionality does + * not match, will delete the existing conntrack entry and commit a new one. + * @OVS_CT_ATTR_EVENTMASK: Mask of bits indicating which conntrack event types + * (enum ip_conntrack_events IPCT_*) should be reported. For any bit set to + * zero, the corresponding event type is not generated. Default behavior + * depends on system configuration, but typically all event types are + * generated, hence listening on NFNLGRP_CONNTRACK_UPDATE events may get a lot + * of events. Explicitly passing this attribute allows limiting the updates + * received to the events of interest. The bit 1 << IPCT_NEW, 1 << + * IPCT_RELATED, and 1 << IPCT_DESTROY must be set to ones for those events to + * be received on NFNLGRP_CONNTRACK_NEW and NFNLGRP_CONNTRACK_DESTROY groups, + * respectively. Remaining bits control the changes for which an event is + * delivered on the NFNLGRP_CONNTRACK_UPDATE group. + * @OVS_CT_ATTR_TIMEOUT: Variable length string defining conntrack timeout. + */ +enum ovs_ct_attr { + OVS_CT_ATTR_UNSPEC, + OVS_CT_ATTR_COMMIT, /* No argument, commits connection. */ + OVS_CT_ATTR_ZONE, /* u16 zone id. */ + OVS_CT_ATTR_MARK, /* mark to associate with this connection. */ + OVS_CT_ATTR_LABELS, /* labels to associate with this connection. */ + OVS_CT_ATTR_HELPER, /* netlink helper to assist detection of + related connections. */ + OVS_CT_ATTR_NAT, /* Nested OVS_NAT_ATTR_* */ + OVS_CT_ATTR_FORCE_COMMIT, /* No argument */ + OVS_CT_ATTR_EVENTMASK, /* u32 mask of IPCT_* events. */ + OVS_CT_ATTR_TIMEOUT, /* Associate timeout with this connection for + * fine-grain timeout tuning. */ + __OVS_CT_ATTR_MAX +}; + +#define OVS_CT_ATTR_MAX (__OVS_CT_ATTR_MAX - 1) + +/** + * enum ovs_nat_attr - Attributes for %OVS_CT_ATTR_NAT. + * + * @OVS_NAT_ATTR_SRC: Flag for Source NAT (mangle source address/port). + * @OVS_NAT_ATTR_DST: Flag for Destination NAT (mangle destination + * address/port). Only one of (@OVS_NAT_ATTR_SRC, @OVS_NAT_ATTR_DST) may be + * specified. Effective only for packets for ct_state NEW connections. + * Packets of committed connections are mangled by the NAT action according to + * the committed NAT type regardless of the flags specified. As a corollary, a + * NAT action without a NAT type flag will only mangle packets of committed + * connections. The following NAT attributes only apply for NEW + * (non-committed) connections, and they may be included only when the CT + * action has the @OVS_CT_ATTR_COMMIT flag and either @OVS_NAT_ATTR_SRC or + * @OVS_NAT_ATTR_DST is also included. + * @OVS_NAT_ATTR_IP_MIN: struct in_addr or struct in6_addr + * @OVS_NAT_ATTR_IP_MAX: struct in_addr or struct in6_addr + * @OVS_NAT_ATTR_PROTO_MIN: u16 L4 protocol specific lower boundary (port) + * @OVS_NAT_ATTR_PROTO_MAX: u16 L4 protocol specific upper boundary (port) + * @OVS_NAT_ATTR_PERSISTENT: Flag for persistent IP mapping across reboots + * @OVS_NAT_ATTR_PROTO_HASH: Flag for pseudo random L4 port mapping (MD5) + * @OVS_NAT_ATTR_PROTO_RANDOM: Flag for fully randomized L4 port mapping + */ +enum ovs_nat_attr { + OVS_NAT_ATTR_UNSPEC, + OVS_NAT_ATTR_SRC, + OVS_NAT_ATTR_DST, + OVS_NAT_ATTR_IP_MIN, + OVS_NAT_ATTR_IP_MAX, + OVS_NAT_ATTR_PROTO_MIN, + OVS_NAT_ATTR_PROTO_MAX, + OVS_NAT_ATTR_PERSISTENT, + OVS_NAT_ATTR_PROTO_HASH, + OVS_NAT_ATTR_PROTO_RANDOM, + __OVS_NAT_ATTR_MAX, +}; + +#define OVS_NAT_ATTR_MAX (__OVS_NAT_ATTR_MAX - 1) + +/* + * struct ovs_action_push_eth - %OVS_ACTION_ATTR_PUSH_ETH action argument. + * @addresses: Source and destination MAC addresses. + * @eth_type: Ethernet type + */ +struct ovs_action_push_eth { + struct ovs_key_ethernet addresses; +}; + +/* + * enum ovs_check_pkt_len_attr - Attributes for %OVS_ACTION_ATTR_CHECK_PKT_LEN. + * + * @OVS_CHECK_PKT_LEN_ATTR_PKT_LEN: u16 Packet length to check for. + * @OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER: Nested OVS_ACTION_ATTR_* + * actions to apply if the packer length is greater than the specified + * length in the attr - OVS_CHECK_PKT_LEN_ATTR_PKT_LEN. + * @OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL - Nested OVS_ACTION_ATTR_* + * actions to apply if the packer length is lesser or equal to the specified + * length in the attr - OVS_CHECK_PKT_LEN_ATTR_PKT_LEN. + */ +enum ovs_check_pkt_len_attr { + OVS_CHECK_PKT_LEN_ATTR_UNSPEC, + OVS_CHECK_PKT_LEN_ATTR_PKT_LEN, + OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER, + OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL, + __OVS_CHECK_PKT_LEN_ATTR_MAX, + +#ifdef __KERNEL__ + OVS_CHECK_PKT_LEN_ATTR_ARG /* struct check_pkt_len_arg */ +#endif +}; + +#define OVS_CHECK_PKT_LEN_ATTR_MAX (__OVS_CHECK_PKT_LEN_ATTR_MAX - 1) + +#ifdef __KERNEL__ +struct check_pkt_len_arg { + u16 pkt_len; /* Same value as OVS_CHECK_PKT_LEN_ATTR_PKT_LEN'. */ + bool exec_for_greater; /* When true, actions in IF_GREATER will + * not change flow keys. False otherwise. + */ + bool exec_for_lesser_equal; /* When true, actions in IF_LESS_EQUAL + * will not change flow keys. False + * otherwise. + */ +}; +#endif + +/** + * enum ovs_action_attr - Action types. + * + * @OVS_ACTION_ATTR_OUTPUT: Output packet to port. + * @OVS_ACTION_ATTR_TRUNC: Output packet to port with truncated packet size. + * @OVS_ACTION_ATTR_USERSPACE: Send packet to userspace according to nested + * %OVS_USERSPACE_ATTR_* attributes. + * @OVS_ACTION_ATTR_SET: Replaces the contents of an existing header. The + * single nested %OVS_KEY_ATTR_* attribute specifies a header to modify and its + * value. + * @OVS_ACTION_ATTR_SET_MASKED: Replaces the contents of an existing header. A + * nested %OVS_KEY_ATTR_* attribute specifies a header to modify, its value, + * and a mask. For every bit set in the mask, the corresponding bit value + * is copied from the value to the packet header field, rest of the bits are + * left unchanged. The non-masked value bits must be passed in as zeroes. + * Masking is not supported for the %OVS_KEY_ATTR_TUNNEL attribute. + * @OVS_ACTION_ATTR_PUSH_VLAN: Push a new outermost 802.1Q or 802.1ad header + * onto the packet. + * @OVS_ACTION_ATTR_POP_VLAN: Pop the outermost 802.1Q or 802.1ad header + * from the packet. + * @OVS_ACTION_ATTR_SAMPLE: Probabilitically executes actions, as specified in + * the nested %OVS_SAMPLE_ATTR_* attributes. + * @OVS_ACTION_ATTR_PUSH_MPLS: Push a new MPLS label stack entry onto the + * top of the packets MPLS label stack. Set the ethertype of the + * encapsulating frame to either %ETH_P_MPLS_UC or %ETH_P_MPLS_MC to + * indicate the new packet contents. + * @OVS_ACTION_ATTR_POP_MPLS: Pop an MPLS label stack entry off of the + * packet's MPLS label stack. Set the encapsulating frame's ethertype to + * indicate the new packet contents. This could potentially still be + * %ETH_P_MPLS if the resulting MPLS label stack is not empty. If there + * is no MPLS label stack, as determined by ethertype, no action is taken. + * @OVS_ACTION_ATTR_CT: Track the connection. Populate the conntrack-related + * entries in the flow key. + * @OVS_ACTION_ATTR_PUSH_ETH: Push a new outermost Ethernet header onto the + * packet. + * @OVS_ACTION_ATTR_POP_ETH: Pop the outermost Ethernet header off the + * packet. + * @OVS_ACTION_ATTR_CT_CLEAR: Clear conntrack state from the packet. + * @OVS_ACTION_ATTR_PUSH_NSH: push NSH header to the packet. + * @OVS_ACTION_ATTR_POP_NSH: pop the outermost NSH header off the packet. + * @OVS_ACTION_ATTR_METER: Run packet through a meter, which may drop the + * packet, or modify the packet (e.g., change the DSCP field). + * @OVS_ACTION_ATTR_CLONE: make a copy of the packet and execute a list of + * actions without affecting the original packet and key. + * @OVS_ACTION_ATTR_CHECK_PKT_LEN: Check the packet length and execute a set + * of actions if greater than the specified packet length, else execute + * another set of actions. + * @OVS_ACTION_ATTR_ADD_MPLS: Push a new MPLS label stack entry at the + * start of the packet or at the start of the l3 header depending on the value + * of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS + * argument. + * @OVS_ACTION_ATTR_DROP: Explicit drop action. + * + * Only a single header can be set with a single %OVS_ACTION_ATTR_SET. Not all + * fields within a header are modifiable, e.g. the IPv4 protocol and fragment + * type may not be changed. + * + * @OVS_ACTION_ATTR_SET_TO_MASKED: Kernel internal masked set action translated + * from the @OVS_ACTION_ATTR_SET. + */ + +enum ovs_action_attr { + OVS_ACTION_ATTR_UNSPEC, + OVS_ACTION_ATTR_OUTPUT, /* u32 port number. */ + OVS_ACTION_ATTR_USERSPACE, /* Nested OVS_USERSPACE_ATTR_*. */ + OVS_ACTION_ATTR_SET, /* One nested OVS_KEY_ATTR_*. */ + OVS_ACTION_ATTR_PUSH_VLAN, /* struct ovs_action_push_vlan. */ + OVS_ACTION_ATTR_POP_VLAN, /* No argument. */ + OVS_ACTION_ATTR_SAMPLE, /* Nested OVS_SAMPLE_ATTR_*. */ + OVS_ACTION_ATTR_RECIRC, /* u32 recirc_id. */ + OVS_ACTION_ATTR_HASH, /* struct ovs_action_hash. */ + OVS_ACTION_ATTR_PUSH_MPLS, /* struct ovs_action_push_mpls. */ + OVS_ACTION_ATTR_POP_MPLS, /* __be16 ethertype. */ + OVS_ACTION_ATTR_SET_MASKED, /* One nested OVS_KEY_ATTR_* including + * data immediately followed by a mask. + * The data must be zero for the unmasked + * bits. */ + OVS_ACTION_ATTR_CT, /* Nested OVS_CT_ATTR_* . */ + OVS_ACTION_ATTR_TRUNC, /* u32 struct ovs_action_trunc. */ + OVS_ACTION_ATTR_PUSH_ETH, /* struct ovs_action_push_eth. */ + OVS_ACTION_ATTR_POP_ETH, /* No argument. */ + OVS_ACTION_ATTR_CT_CLEAR, /* No argument. */ + OVS_ACTION_ATTR_PUSH_NSH, /* Nested OVS_NSH_KEY_ATTR_*. */ + OVS_ACTION_ATTR_POP_NSH, /* No argument. */ + OVS_ACTION_ATTR_METER, /* u32 meter ID. */ + OVS_ACTION_ATTR_CLONE, /* Nested OVS_CLONE_ATTR_*. */ + OVS_ACTION_ATTR_CHECK_PKT_LEN, /* Nested OVS_CHECK_PKT_LEN_ATTR_*. */ + OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */ + OVS_ACTION_ATTR_DEC_TTL, /* Nested OVS_DEC_TTL_ATTR_*. */ + OVS_ACTION_ATTR_DROP, /* u32 error code. */ + + __OVS_ACTION_ATTR_MAX, /* Nothing past this will be accepted + * from userspace. */ + +#ifdef __KERNEL__ + OVS_ACTION_ATTR_SET_TO_MASKED, /* Kernel module internal masked + * set action converted from + * OVS_ACTION_ATTR_SET. */ +#endif +}; + +#define OVS_ACTION_ATTR_MAX (__OVS_ACTION_ATTR_MAX - 1) + +/* Meters. */ +#define OVS_METER_FAMILY "ovs_meter" +#define OVS_METER_MCGROUP "ovs_meter" +#define OVS_METER_VERSION 0x1 + +enum ovs_meter_cmd { + OVS_METER_CMD_UNSPEC, + OVS_METER_CMD_FEATURES, /* Get features supported by the datapath. */ + OVS_METER_CMD_SET, /* Add or modify a meter. */ + OVS_METER_CMD_DEL, /* Delete a meter. */ + OVS_METER_CMD_GET /* Get meter stats. */ +}; + +enum ovs_meter_attr { + OVS_METER_ATTR_UNSPEC, + OVS_METER_ATTR_ID, /* u32 meter ID within datapath. */ + OVS_METER_ATTR_KBPS, /* No argument. If set, units in kilobits + * per second. Otherwise, units in + * packets per second. + */ + OVS_METER_ATTR_STATS, /* struct ovs_flow_stats for the meter. */ + OVS_METER_ATTR_BANDS, /* Nested attributes for meter bands. */ + OVS_METER_ATTR_USED, /* u64 msecs last used in monotonic time. */ + OVS_METER_ATTR_CLEAR, /* Flag to clear stats, used. */ + OVS_METER_ATTR_MAX_METERS, /* u32 number of meters supported. */ + OVS_METER_ATTR_MAX_BANDS, /* u32 max number of bands per meter. */ + OVS_METER_ATTR_PAD, + __OVS_METER_ATTR_MAX +}; + +#define OVS_METER_ATTR_MAX (__OVS_METER_ATTR_MAX - 1) + +enum ovs_band_attr { + OVS_BAND_ATTR_UNSPEC, + OVS_BAND_ATTR_TYPE, /* u32 OVS_METER_BAND_TYPE_* constant. */ + OVS_BAND_ATTR_RATE, /* u32 band rate in meter units (see above). */ + OVS_BAND_ATTR_BURST, /* u32 burst size in meter units. */ + OVS_BAND_ATTR_STATS, /* struct ovs_flow_stats for the band. */ + __OVS_BAND_ATTR_MAX +}; + +#define OVS_BAND_ATTR_MAX (__OVS_BAND_ATTR_MAX - 1) + +enum ovs_meter_band_type { + OVS_METER_BAND_TYPE_UNSPEC, + OVS_METER_BAND_TYPE_DROP, /* Drop exceeding packets. */ + __OVS_METER_BAND_TYPE_MAX +}; + +#define OVS_METER_BAND_TYPE_MAX (__OVS_METER_BAND_TYPE_MAX - 1) + +/* Conntrack limit */ +#define OVS_CT_LIMIT_FAMILY "ovs_ct_limit" +#define OVS_CT_LIMIT_MCGROUP "ovs_ct_limit" +#define OVS_CT_LIMIT_VERSION 0x1 + +enum ovs_ct_limit_cmd { + OVS_CT_LIMIT_CMD_UNSPEC, + OVS_CT_LIMIT_CMD_SET, /* Add or modify ct limit. */ + OVS_CT_LIMIT_CMD_DEL, /* Delete ct limit. */ + OVS_CT_LIMIT_CMD_GET /* Get ct limit. */ +}; + +enum ovs_ct_limit_attr { + OVS_CT_LIMIT_ATTR_UNSPEC, + OVS_CT_LIMIT_ATTR_ZONE_LIMIT, /* Nested struct ovs_zone_limit. */ + __OVS_CT_LIMIT_ATTR_MAX +}; + +#define OVS_CT_LIMIT_ATTR_MAX (__OVS_CT_LIMIT_ATTR_MAX - 1) + +#define OVS_ZONE_LIMIT_DEFAULT_ZONE -1 + +struct ovs_zone_limit { + int zone_id; + __u32 limit; + __u32 count; +}; + +enum ovs_dec_ttl_attr { + OVS_DEC_TTL_ATTR_UNSPEC, + OVS_DEC_TTL_ATTR_ACTION, /* Nested struct nlattr */ + __OVS_DEC_TTL_ATTR_MAX +}; + +#define OVS_DEC_TTL_ATTR_MAX (__OVS_DEC_TTL_ATTR_MAX - 1) + +#endif /* _LINUX_OPENVSWITCH_H */ diff --git a/uapi/linux/psp.h b/uapi/linux/psp.h new file mode 100644 index 0000000..194041d --- /dev/null +++ b/uapi/linux/psp.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ +/* Do not edit directly, auto-generated from: */ +/* Documentation/netlink/specs/psp.yaml */ +/* YNL-GEN uapi header */ + +#ifndef _UAPI_LINUX_PSP_H +#define _UAPI_LINUX_PSP_H + +#define PSP_FAMILY_NAME "psp" +#define PSP_FAMILY_VERSION 1 + +enum psp_version { + PSP_VERSION_HDR0_AES_GCM_128, + PSP_VERSION_HDR0_AES_GCM_256, + PSP_VERSION_HDR0_AES_GMAC_128, + PSP_VERSION_HDR0_AES_GMAC_256, +}; + +enum { + PSP_A_DEV_ID = 1, + PSP_A_DEV_IFINDEX, + PSP_A_DEV_PSP_VERSIONS_CAP, + PSP_A_DEV_PSP_VERSIONS_ENA, + + __PSP_A_DEV_MAX, + PSP_A_DEV_MAX = (__PSP_A_DEV_MAX - 1) +}; + +enum { + PSP_A_ASSOC_PAD = 1, + PSP_A_ASSOC_DEV_ID, + PSP_A_ASSOC_VERSION, + PSP_A_ASSOC_RX_KEY, + PSP_A_ASSOC_TX_KEY, + PSP_A_ASSOC_SOCK_FD, + + __PSP_A_ASSOC_MAX, + PSP_A_ASSOC_MAX = (__PSP_A_ASSOC_MAX - 1) +}; + +enum { + PSP_A_KEYS_KEY = 1, + PSP_A_KEYS_SPI, + + __PSP_A_KEYS_MAX, + PSP_A_KEYS_MAX = (__PSP_A_KEYS_MAX - 1) +}; + +enum { + PSP_A_STATS_DEV_ID = 1, + PSP_A_STATS_PAD, + PSP_A_STATS_KEY_ROTATIONS, + PSP_A_STATS_STALE_EVENTS, + PSP_A_STATS_RX_PACKETS, + PSP_A_STATS_RX_BYTES, + PSP_A_STATS_RX_AUTH_FAIL, + PSP_A_STATS_RX_ERROR, + PSP_A_STATS_RX_BAD, + PSP_A_STATS_TX_PACKETS, + PSP_A_STATS_TX_BYTES, + PSP_A_STATS_TX_ERROR, + + __PSP_A_STATS_MAX, + PSP_A_STATS_MAX = (__PSP_A_STATS_MAX - 1) +}; + +enum { + PSP_CMD_DEV_GET = 1, + PSP_CMD_DEV_ADD_NTF, + PSP_CMD_DEV_DEL_NTF, + PSP_CMD_DEV_SET, + PSP_CMD_DEV_CHANGE_NTF, + PSP_CMD_KEY_ROTATE, + PSP_CMD_KEY_ROTATE_NTF, + PSP_CMD_RX_ASSOC, + PSP_CMD_TX_ASSOC, + PSP_CMD_GET_STATS, + + __PSP_CMD_MAX, + PSP_CMD_MAX = (__PSP_CMD_MAX - 1) +}; + +#define PSP_MCGRP_MGMT "mgmt" +#define PSP_MCGRP_USE "use" + +#endif /* _UAPI_LINUX_PSP_H */ diff --git a/update-from-kernel.sh b/update-from-kernel.sh new file mode 100755 index 0000000..d043bb2 --- /dev/null +++ b/update-from-kernel.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +if [ $# -ne 1 ]; then + echo "Usage: $0 PATH_TO_KERNEL" + exit 1 +fi +if [ $(dirname $0) != "." ]; then + echo "Script must be run directly in the ynl-c directory" + exit 1 +fi + +KSRC=$1 + +make -C ${KSRC}/tools/net/ynl -j $(nproc) || exit 1 + +cp -v ${KSRC}/tools/net/ynl/Makefile.deps ./ +sed -i 's@^UAPI_PATH:=.*@UAPI_PATH:=../uapi/@' Makefile.deps + +mkdir -p uapi/linux/ +for hdr in $(cat Makefile.deps | sed -n 's/.*,\([^,]*\.h\))/\1/p'); do + cp -v ${KSRC}/include/uapi/linux/$hdr ./uapi/linux/ +done + +mkdir -p lib +cp -v ${KSRC}/tools/net/ynl/lib/*.{c,h} ./ + +mkdir -p generated +cp -v ${KSRC}/tools/net/ynl/generated/*.{c,h} ./generated/ diff --git a/ynl-priv.h b/ynl-priv.h new file mode 100644 index 0000000..6cf8900 --- /dev/null +++ b/ynl-priv.h @@ -0,0 +1,457 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +#ifndef __YNL_C_PRIV_H +#define __YNL_C_PRIV_H 1 + +#include +#include +#include + +struct ynl_parse_arg; + +/* + * YNL internals / low level stuff + */ + +enum ynl_policy_type { + YNL_PT_REJECT = 1, + YNL_PT_IGNORE, + YNL_PT_NEST, + YNL_PT_FLAG, + YNL_PT_BINARY, + YNL_PT_U8, + YNL_PT_U16, + YNL_PT_U32, + YNL_PT_U64, + YNL_PT_UINT, + YNL_PT_NUL_STR, + YNL_PT_BITFIELD32, +}; + +enum ynl_parse_result { + YNL_PARSE_CB_ERROR = -1, + YNL_PARSE_CB_STOP = 0, + YNL_PARSE_CB_OK = 1, +}; + +#define YNL_SOCKET_BUFFER_SIZE (1 << 17) + +#define YNL_ARRAY_SIZE(array) (sizeof(array) ? \ + sizeof(array) / sizeof(array[0]) : 0) + +typedef int (*ynl_parse_cb_t)(const struct nlmsghdr *nlh, + struct ynl_parse_arg *yarg); + +struct ynl_policy_attr { + enum ynl_policy_type type; + unsigned int len; + const char *name; + struct ynl_policy_nest *nest; +}; + +struct ynl_policy_nest { + unsigned int max_attr; + struct ynl_policy_attr *table; +}; + +struct ynl_parse_arg { + struct ynl_sock *ys; + struct ynl_policy_nest *rsp_policy; + void *data; +}; + +struct ynl_dump_list_type { + struct ynl_dump_list_type *next; + unsigned char data[] __attribute__((aligned(8))); +}; +extern struct ynl_dump_list_type *YNL_LIST_END; + +static inline bool ynl_dump_obj_is_last(void *obj) +{ + unsigned long uptr = (unsigned long)obj; + + uptr -= offsetof(struct ynl_dump_list_type, data); + return uptr == (unsigned long)YNL_LIST_END; +} + +static inline void *ynl_dump_obj_next(void *obj) +{ + unsigned long uptr = (unsigned long)obj; + struct ynl_dump_list_type *list; + + uptr -= offsetof(struct ynl_dump_list_type, data); + list = (void *)uptr; + uptr = (unsigned long)list->next; + uptr += offsetof(struct ynl_dump_list_type, data); + + return (void *)uptr; +} + +struct ynl_ntf_base_type { + __u16 family; + __u8 cmd; + struct ynl_ntf_base_type *next; + void (*free)(struct ynl_ntf_base_type *ntf); + unsigned char data[] __attribute__((aligned(8))); +}; + +struct nlmsghdr * +ynl_gemsg_start_req(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version); +struct nlmsghdr * +ynl_gemsg_start_dump(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version); + +int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr); + +/* YNL specific helpers used by the auto-generated code */ + +struct ynl_req_state { + struct ynl_parse_arg yarg; + ynl_parse_cb_t cb; + __u32 rsp_cmd; +}; + +struct ynl_dump_state { + struct ynl_parse_arg yarg; + void *first; + struct ynl_dump_list_type *last; + size_t alloc_sz; + ynl_parse_cb_t cb; + __u32 rsp_cmd; +}; + +struct ynl_ntf_info { + struct ynl_policy_nest *policy; + ynl_parse_cb_t cb; + size_t alloc_sz; + void (*free)(struct ynl_ntf_base_type *ntf); +}; + +int ynl_exec(struct ynl_sock *ys, struct nlmsghdr *req_nlh, + struct ynl_req_state *yrs); +int ynl_exec_dump(struct ynl_sock *ys, struct nlmsghdr *req_nlh, + struct ynl_dump_state *yds); + +void ynl_error_unknown_notification(struct ynl_sock *ys, __u8 cmd); +int ynl_error_parse(struct ynl_parse_arg *yarg, const char *msg); + +/* Netlink message handling helpers */ + +#define YNL_MSG_OVERFLOW 1 + +static inline struct nlmsghdr *ynl_nlmsg_put_header(void *buf) +{ + struct nlmsghdr *nlh = buf; + + memset(nlh, 0, sizeof(*nlh)); + nlh->nlmsg_len = NLMSG_HDRLEN; + + return nlh; +} + +static inline unsigned int ynl_nlmsg_data_len(const struct nlmsghdr *nlh) +{ + return nlh->nlmsg_len - NLMSG_HDRLEN; +} + +static inline void *ynl_nlmsg_data(const struct nlmsghdr *nlh) +{ + return (unsigned char *)nlh + NLMSG_HDRLEN; +} + +static inline void * +ynl_nlmsg_data_offset(const struct nlmsghdr *nlh, unsigned int offset) +{ + return (unsigned char *)nlh + NLMSG_HDRLEN + offset; +} + +static inline void *ynl_nlmsg_end_addr(const struct nlmsghdr *nlh) +{ + return (char *)nlh + nlh->nlmsg_len; +} + +static inline void * +ynl_nlmsg_put_extra_header(struct nlmsghdr *nlh, unsigned int size) +{ + void *tail = ynl_nlmsg_end_addr(nlh); + + nlh->nlmsg_len += NLMSG_ALIGN(size); + return tail; +} + +/* Netlink attribute helpers */ + +static inline unsigned int ynl_attr_type(const struct nlattr *attr) +{ + return attr->nla_type & NLA_TYPE_MASK; +} + +static inline unsigned int ynl_attr_data_len(const struct nlattr *attr) +{ + return attr->nla_len - NLA_HDRLEN; +} + +static inline void *ynl_attr_data(const struct nlattr *attr) +{ + return (unsigned char *)attr + NLA_HDRLEN; +} + +static inline void *ynl_attr_data_end(const struct nlattr *attr) +{ + return ynl_attr_data(attr) + ynl_attr_data_len(attr); +} + +#define ynl_attr_for_each(attr, nlh, fixed_hdr_sz) \ + for ((attr) = ynl_attr_first(nlh, (nlh)->nlmsg_len, \ + NLMSG_HDRLEN + fixed_hdr_sz); attr; \ + (attr) = ynl_attr_next(ynl_nlmsg_end_addr(nlh), attr)) + +#define ynl_attr_for_each_nested(attr, outer) \ + for ((attr) = ynl_attr_first(outer, outer->nla_len, \ + sizeof(struct nlattr)); attr; \ + (attr) = ynl_attr_next(ynl_attr_data_end(outer), attr)) + +#define ynl_attr_for_each_payload(start, len, attr) \ + for ((attr) = ynl_attr_first(start, len, 0); attr; \ + (attr) = ynl_attr_next(start + len, attr)) + +static inline struct nlattr * +ynl_attr_if_good(const void *end, struct nlattr *attr) +{ + if (attr + 1 > (const struct nlattr *)end) + return NULL; + if (ynl_attr_data_end(attr) > end) + return NULL; + return attr; +} + +static inline struct nlattr * +ynl_attr_next(const void *end, const struct nlattr *prev) +{ + struct nlattr *attr; + + attr = (void *)((char *)prev + NLA_ALIGN(prev->nla_len)); + return ynl_attr_if_good(end, attr); +} + +static inline struct nlattr * +ynl_attr_first(const void *start, size_t len, size_t skip) +{ + struct nlattr *attr; + + attr = (void *)((char *)start + NLMSG_ALIGN(skip)); + return ynl_attr_if_good(start + len, attr); +} + +static inline bool +__ynl_attr_put_overflow(struct nlmsghdr *nlh, size_t size) +{ + bool o; + + /* ynl_msg_start() stashed buffer length in nlmsg_pid. */ + o = nlh->nlmsg_len + NLA_HDRLEN + NLMSG_ALIGN(size) > nlh->nlmsg_pid; + if (o) + /* YNL_MSG_OVERFLOW is < NLMSG_HDRLEN, all subsequent checks + * are guaranteed to fail. + */ + nlh->nlmsg_pid = YNL_MSG_OVERFLOW; + return o; +} + +static inline struct nlattr * +ynl_attr_nest_start(struct nlmsghdr *nlh, unsigned int attr_type) +{ + struct nlattr *attr; + + if (__ynl_attr_put_overflow(nlh, 0)) + return ynl_nlmsg_end_addr(nlh) - NLA_HDRLEN; + + attr = ynl_nlmsg_end_addr(nlh); + attr->nla_type = attr_type | NLA_F_NESTED; + nlh->nlmsg_len += NLA_HDRLEN; + + return attr; +} + +static inline void +ynl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *attr) +{ + attr->nla_len = (char *)ynl_nlmsg_end_addr(nlh) - (char *)attr; +} + +static inline void +ynl_attr_put(struct nlmsghdr *nlh, unsigned int attr_type, + const void *value, size_t size) +{ + struct nlattr *attr; + + if (__ynl_attr_put_overflow(nlh, size)) + return; + + attr = ynl_nlmsg_end_addr(nlh); + attr->nla_type = attr_type; + attr->nla_len = NLA_HDRLEN + size; + + memcpy(ynl_attr_data(attr), value, size); + + nlh->nlmsg_len += NLMSG_ALIGN(attr->nla_len); +} + +static inline void +ynl_attr_put_str(struct nlmsghdr *nlh, unsigned int attr_type, const char *str) +{ + struct nlattr *attr; + size_t len; + + len = strlen(str); + if (__ynl_attr_put_overflow(nlh, len)) + return; + + attr = ynl_nlmsg_end_addr(nlh); + attr->nla_type = attr_type; + + strcpy(ynl_attr_data(attr), str); + attr->nla_len = NLA_HDRLEN + NLA_ALIGN(len); + + nlh->nlmsg_len += NLMSG_ALIGN(attr->nla_len); +} + +static inline const char *ynl_attr_get_str(const struct nlattr *attr) +{ + return (const char *)ynl_attr_data(attr); +} + +static inline __s8 ynl_attr_get_s8(const struct nlattr *attr) +{ + return *(__s8 *)ynl_attr_data(attr); +} + +static inline __s16 ynl_attr_get_s16(const struct nlattr *attr) +{ + return *(__s16 *)ynl_attr_data(attr); +} + +static inline __s32 ynl_attr_get_s32(const struct nlattr *attr) +{ + return *(__s32 *)ynl_attr_data(attr); +} + +static inline __s64 ynl_attr_get_s64(const struct nlattr *attr) +{ + __s64 tmp; + + memcpy(&tmp, (unsigned char *)(attr + 1), sizeof(tmp)); + return tmp; +} + +static inline __u8 ynl_attr_get_u8(const struct nlattr *attr) +{ + return *(__u8 *)ynl_attr_data(attr); +} + +static inline __u16 ynl_attr_get_u16(const struct nlattr *attr) +{ + return *(__u16 *)ynl_attr_data(attr); +} + +static inline __u32 ynl_attr_get_u32(const struct nlattr *attr) +{ + return *(__u32 *)ynl_attr_data(attr); +} + +static inline __u64 ynl_attr_get_u64(const struct nlattr *attr) +{ + __u64 tmp; + + memcpy(&tmp, (unsigned char *)(attr + 1), sizeof(tmp)); + return tmp; +} + +static inline void +ynl_attr_put_s8(struct nlmsghdr *nlh, unsigned int attr_type, __s8 value) +{ + ynl_attr_put(nlh, attr_type, &value, sizeof(value)); +} + +static inline void +ynl_attr_put_s16(struct nlmsghdr *nlh, unsigned int attr_type, __s16 value) +{ + ynl_attr_put(nlh, attr_type, &value, sizeof(value)); +} + +static inline void +ynl_attr_put_s32(struct nlmsghdr *nlh, unsigned int attr_type, __s32 value) +{ + ynl_attr_put(nlh, attr_type, &value, sizeof(value)); +} + +static inline void +ynl_attr_put_s64(struct nlmsghdr *nlh, unsigned int attr_type, __s64 value) +{ + ynl_attr_put(nlh, attr_type, &value, sizeof(value)); +} + +static inline void +ynl_attr_put_u8(struct nlmsghdr *nlh, unsigned int attr_type, __u8 value) +{ + ynl_attr_put(nlh, attr_type, &value, sizeof(value)); +} + +static inline void +ynl_attr_put_u16(struct nlmsghdr *nlh, unsigned int attr_type, __u16 value) +{ + ynl_attr_put(nlh, attr_type, &value, sizeof(value)); +} + +static inline void +ynl_attr_put_u32(struct nlmsghdr *nlh, unsigned int attr_type, __u32 value) +{ + ynl_attr_put(nlh, attr_type, &value, sizeof(value)); +} + +static inline void +ynl_attr_put_u64(struct nlmsghdr *nlh, unsigned int attr_type, __u64 value) +{ + ynl_attr_put(nlh, attr_type, &value, sizeof(value)); +} + +static inline __u64 ynl_attr_get_uint(const struct nlattr *attr) +{ + switch (ynl_attr_data_len(attr)) { + case 4: + return ynl_attr_get_u32(attr); + case 8: + return ynl_attr_get_u64(attr); + default: + return 0; + } +} + +static inline __s64 ynl_attr_get_sint(const struct nlattr *attr) +{ + switch (ynl_attr_data_len(attr)) { + case 4: + return ynl_attr_get_s32(attr); + case 8: + return ynl_attr_get_s64(attr); + default: + return 0; + } +} + +static inline void +ynl_attr_put_uint(struct nlmsghdr *nlh, __u16 type, __u64 data) +{ + if ((__u32)data == (__u64)data) + ynl_attr_put_u32(nlh, type, data); + else + ynl_attr_put_u64(nlh, type, data); +} + +static inline void +ynl_attr_put_sint(struct nlmsghdr *nlh, __u16 type, __s64 data) +{ + if ((__s32)data == (__s64)data) + ynl_attr_put_s32(nlh, type, data); + else + ynl_attr_put_s64(nlh, type, data); +} +#endif diff --git a/ynl.c b/ynl.c new file mode 100644 index 0000000..4b9c091 --- /dev/null +++ b/ynl.c @@ -0,0 +1,976 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ynl.h" + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*arr)) + +#define __yerr_msg(yse, _msg...) \ + ({ \ + struct ynl_error *_yse = (yse); \ + \ + if (_yse) { \ + snprintf(_yse->msg, sizeof(_yse->msg) - 1, _msg); \ + _yse->msg[sizeof(_yse->msg) - 1] = 0; \ + } \ + }) + +#define __yerr_code(yse, _code...) \ + ({ \ + struct ynl_error *_yse = (yse); \ + \ + if (_yse) { \ + _yse->code = _code; \ + } \ + }) + +#define __yerr(yse, _code, _msg...) \ + ({ \ + __yerr_msg(yse, _msg); \ + __yerr_code(yse, _code); \ + }) + +#define __perr(yse, _msg) __yerr(yse, errno, _msg) + +#define yerr_msg(_ys, _msg...) __yerr_msg(&(_ys)->err, _msg) +#define yerr(_ys, _code, _msg...) __yerr(&(_ys)->err, _code, _msg) +#define perr(_ys, _msg) __yerr(&(_ys)->err, errno, _msg) + +/* -- Netlink boiler plate */ +static int +ynl_err_walk_report_one(struct ynl_policy_nest *policy, unsigned int type, + char *str, int str_sz, int *n) +{ + if (!policy) { + if (*n < str_sz) + *n += snprintf(str, str_sz, "!policy"); + return 1; + } + + if (type > policy->max_attr) { + if (*n < str_sz) + *n += snprintf(str, str_sz, "!oob"); + return 1; + } + + if (!policy->table[type].name) { + if (*n < str_sz) + *n += snprintf(str, str_sz, "!name"); + return 1; + } + + if (*n < str_sz) + *n += snprintf(str, str_sz - *n, + ".%s", policy->table[type].name); + return 0; +} + +static int +ynl_err_walk(struct ynl_sock *ys, void *start, void *end, unsigned int off, + struct ynl_policy_nest *policy, char *str, int str_sz, + struct ynl_policy_nest **nest_pol) +{ + unsigned int astart_off, aend_off; + const struct nlattr *attr; + unsigned int data_len; + unsigned int type; + bool found = false; + int n = 0; + + if (!policy) { + if (n < str_sz) + n += snprintf(str, str_sz, "!policy"); + return n; + } + + data_len = end - start; + + ynl_attr_for_each_payload(start, data_len, attr) { + astart_off = (char *)attr - (char *)start; + aend_off = astart_off + ynl_attr_data_len(attr); + if (aend_off <= off) + continue; + + found = true; + break; + } + if (!found) + return 0; + + off -= astart_off; + + type = ynl_attr_type(attr); + + if (ynl_err_walk_report_one(policy, type, str, str_sz, &n)) + return n; + + if (!off) { + if (nest_pol) + *nest_pol = policy->table[type].nest; + return n; + } + + if (!policy->table[type].nest) { + if (n < str_sz) + n += snprintf(str, str_sz, "!nest"); + return n; + } + + off -= sizeof(struct nlattr); + start = ynl_attr_data(attr); + end = start + ynl_attr_data_len(attr); + + return n + ynl_err_walk(ys, start, end, off, policy->table[type].nest, + &str[n], str_sz - n, nest_pol); +} + +#define NLMSGERR_ATTR_MISS_TYPE (NLMSGERR_ATTR_POLICY + 1) +#define NLMSGERR_ATTR_MISS_NEST (NLMSGERR_ATTR_POLICY + 2) +#define NLMSGERR_ATTR_MAX (NLMSGERR_ATTR_MAX + 2) + +static int +ynl_ext_ack_check(struct ynl_sock *ys, const struct nlmsghdr *nlh, + unsigned int hlen) +{ + const struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {}; + char miss_attr[sizeof(ys->err.msg)]; + char bad_attr[sizeof(ys->err.msg)]; + const struct nlattr *attr; + const char *str = NULL; + + if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS)) { + yerr_msg(ys, "%s", strerror(ys->err.code)); + return YNL_PARSE_CB_OK; + } + + ynl_attr_for_each(attr, nlh, hlen) { + unsigned int len, type; + + len = ynl_attr_data_len(attr); + type = ynl_attr_type(attr); + + if (type > NLMSGERR_ATTR_MAX) + continue; + + tb[type] = attr; + + switch (type) { + case NLMSGERR_ATTR_OFFS: + case NLMSGERR_ATTR_MISS_TYPE: + case NLMSGERR_ATTR_MISS_NEST: + if (len != sizeof(__u32)) + return YNL_PARSE_CB_ERROR; + break; + case NLMSGERR_ATTR_MSG: + str = ynl_attr_get_str(attr); + if (str[len - 1]) + return YNL_PARSE_CB_ERROR; + break; + default: + break; + } + } + + bad_attr[0] = '\0'; + miss_attr[0] = '\0'; + + if (tb[NLMSGERR_ATTR_OFFS]) { + unsigned int n, off; + void *start, *end; + + ys->err.attr_offs = ynl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]); + + n = snprintf(bad_attr, sizeof(bad_attr), "%sbad attribute: ", + str ? " (" : ""); + + start = ynl_nlmsg_data_offset(ys->nlh, ys->family->hdr_len); + end = ynl_nlmsg_end_addr(ys->nlh); + + off = ys->err.attr_offs; + off -= sizeof(struct nlmsghdr); + off -= ys->family->hdr_len; + + n += ynl_err_walk(ys, start, end, off, ys->req_policy, + &bad_attr[n], sizeof(bad_attr) - n, NULL); + + if (n >= sizeof(bad_attr)) + n = sizeof(bad_attr) - 1; + bad_attr[n] = '\0'; + } + if (tb[NLMSGERR_ATTR_MISS_TYPE]) { + struct ynl_policy_nest *nest_pol = NULL; + unsigned int n, off, type; + void *start, *end; + int n2; + + type = ynl_attr_get_u32(tb[NLMSGERR_ATTR_MISS_TYPE]); + + n = snprintf(miss_attr, sizeof(miss_attr), "%smissing attribute: ", + bad_attr[0] ? ", " : (str ? " (" : "")); + + start = ynl_nlmsg_data_offset(ys->nlh, ys->family->hdr_len); + end = ynl_nlmsg_end_addr(ys->nlh); + + nest_pol = ys->req_policy; + if (tb[NLMSGERR_ATTR_MISS_NEST]) { + off = ynl_attr_get_u32(tb[NLMSGERR_ATTR_MISS_NEST]); + off -= sizeof(struct nlmsghdr); + off -= ys->family->hdr_len; + + n += ynl_err_walk(ys, start, end, off, ys->req_policy, + &miss_attr[n], sizeof(miss_attr) - n, + &nest_pol); + } + + n2 = 0; + ynl_err_walk_report_one(nest_pol, type, &miss_attr[n], + sizeof(miss_attr) - n, &n2); + n += n2; + + if (n >= sizeof(miss_attr)) + n = sizeof(miss_attr) - 1; + miss_attr[n] = '\0'; + } + + /* Implicitly depend on ys->err.code already set */ + if (str) + yerr_msg(ys, "Kernel %s: '%s'%s%s%s", + ys->err.code ? "error" : "warning", + str, bad_attr, miss_attr, + bad_attr[0] || miss_attr[0] ? ")" : ""); + else if (bad_attr[0] || miss_attr[0]) + yerr_msg(ys, "Kernel %s: %s%s", + ys->err.code ? "error" : "warning", + bad_attr, miss_attr); + else + yerr_msg(ys, "%s", strerror(ys->err.code)); + + return YNL_PARSE_CB_OK; +} + +static int +ynl_cb_error(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg) +{ + const struct nlmsgerr *err = ynl_nlmsg_data(nlh); + unsigned int hlen; + int code; + + code = err->error >= 0 ? err->error : -err->error; + yarg->ys->err.code = code; + errno = code; + + hlen = sizeof(*err); + if (!(nlh->nlmsg_flags & NLM_F_CAPPED)) + hlen += ynl_nlmsg_data_len(&err->msg); + + ynl_ext_ack_check(yarg->ys, nlh, hlen); + + return code ? YNL_PARSE_CB_ERROR : YNL_PARSE_CB_STOP; +} + +static int ynl_cb_done(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg) +{ + int err; + + err = *(int *)NLMSG_DATA(nlh); + if (err < 0) { + yarg->ys->err.code = -err; + errno = -err; + + ynl_ext_ack_check(yarg->ys, nlh, sizeof(int)); + + return YNL_PARSE_CB_ERROR; + } + return YNL_PARSE_CB_STOP; +} + +/* Attribute validation */ + +int ynl_attr_validate(struct ynl_parse_arg *yarg, const struct nlattr *attr) +{ + struct ynl_policy_attr *policy; + unsigned int type, len; + unsigned char *data; + + data = ynl_attr_data(attr); + len = ynl_attr_data_len(attr); + type = ynl_attr_type(attr); + if (type > yarg->rsp_policy->max_attr) { + yerr(yarg->ys, YNL_ERROR_INTERNAL, + "Internal error, validating unknown attribute"); + return -1; + } + + policy = &yarg->rsp_policy->table[type]; + + switch (policy->type) { + case YNL_PT_REJECT: + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Rejected attribute (%s)", policy->name); + return -1; + case YNL_PT_IGNORE: + break; + case YNL_PT_U8: + if (len == sizeof(__u8)) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (u8 %s)", policy->name); + return -1; + case YNL_PT_U16: + if (len == sizeof(__u16)) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (u16 %s)", policy->name); + return -1; + case YNL_PT_U32: + if (len == sizeof(__u32)) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (u32 %s)", policy->name); + return -1; + case YNL_PT_U64: + if (len == sizeof(__u64)) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (u64 %s)", policy->name); + return -1; + case YNL_PT_UINT: + if (len == sizeof(__u32) || len == sizeof(__u64)) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (uint %s)", policy->name); + return -1; + case YNL_PT_FLAG: + /* Let flags grow into real attrs, why not.. */ + break; + case YNL_PT_NEST: + if (!len || len >= sizeof(*attr)) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (nest %s)", policy->name); + return -1; + case YNL_PT_BINARY: + if (!policy->len || len == policy->len) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (binary %s)", policy->name); + return -1; + case YNL_PT_NUL_STR: + if ((!policy->len || len <= policy->len) && !data[len - 1]) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (string %s)", policy->name); + return -1; + case YNL_PT_BITFIELD32: + if (len == sizeof(struct nla_bitfield32)) + break; + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (bitfield32 %s)", policy->name); + return -1; + default: + yerr(yarg->ys, YNL_ERROR_ATTR_INVALID, + "Invalid attribute (unknown %s)", policy->name); + return -1; + } + + return 0; +} + +/* Generic code */ + +static void ynl_err_reset(struct ynl_sock *ys) +{ + ys->err.code = 0; + ys->err.attr_offs = 0; + ys->err.msg[0] = 0; +} + +struct nlmsghdr *ynl_msg_start(struct ynl_sock *ys, __u32 id, __u16 flags) +{ + struct nlmsghdr *nlh; + + ynl_err_reset(ys); + + nlh = ys->nlh = ynl_nlmsg_put_header(ys->tx_buf); + nlh->nlmsg_type = id; + nlh->nlmsg_flags = flags; + nlh->nlmsg_seq = ++ys->seq; + + /* This is a local YNL hack for length checking, we put the buffer + * length in nlmsg_pid, since messages sent to the kernel always use + * PID 0. Message needs to be terminated with ynl_msg_end(). + */ + nlh->nlmsg_pid = YNL_SOCKET_BUFFER_SIZE; + + return nlh; +} + +static int ynl_msg_end(struct ynl_sock *ys, struct nlmsghdr *nlh) +{ + /* We stash buffer length in nlmsg_pid. */ + if (nlh->nlmsg_pid == 0) { + yerr(ys, YNL_ERROR_INPUT_INVALID, + "Unknown input buffer length"); + return -EINVAL; + } + if (nlh->nlmsg_pid == YNL_MSG_OVERFLOW) { + yerr(ys, YNL_ERROR_INPUT_TOO_BIG, + "Constructed message longer than internal buffer"); + return -EMSGSIZE; + } + + nlh->nlmsg_pid = 0; + return 0; +} + +struct nlmsghdr * +ynl_gemsg_start(struct ynl_sock *ys, __u32 id, __u16 flags, + __u8 cmd, __u8 version) +{ + struct genlmsghdr gehdr; + struct nlmsghdr *nlh; + void *data; + + nlh = ynl_msg_start(ys, id, flags); + + memset(&gehdr, 0, sizeof(gehdr)); + gehdr.cmd = cmd; + gehdr.version = version; + + data = ynl_nlmsg_put_extra_header(nlh, sizeof(gehdr)); + memcpy(data, &gehdr, sizeof(gehdr)); + + return nlh; +} + +void ynl_msg_start_req(struct ynl_sock *ys, __u32 id) +{ + ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK); +} + +void ynl_msg_start_dump(struct ynl_sock *ys, __u32 id) +{ + ynl_msg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP); +} + +struct nlmsghdr * +ynl_gemsg_start_req(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version) +{ + return ynl_gemsg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK, cmd, version); +} + +struct nlmsghdr * +ynl_gemsg_start_dump(struct ynl_sock *ys, __u32 id, __u8 cmd, __u8 version) +{ + return ynl_gemsg_start(ys, id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, + cmd, version); +} + +static int ynl_cb_null(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg) +{ + yerr(yarg->ys, YNL_ERROR_UNEXPECT_MSG, + "Received a message when none were expected"); + + return YNL_PARSE_CB_ERROR; +} + +static int +__ynl_sock_read_msgs(struct ynl_parse_arg *yarg, ynl_parse_cb_t cb, int flags) +{ + struct ynl_sock *ys = yarg->ys; + const struct nlmsghdr *nlh; + ssize_t len, rem; + int ret; + + len = recv(ys->socket, ys->rx_buf, YNL_SOCKET_BUFFER_SIZE, flags); + if (len < 0) { + if (flags & MSG_DONTWAIT && errno == EAGAIN) + return YNL_PARSE_CB_STOP; + return len; + } + + ret = YNL_PARSE_CB_STOP; + for (rem = len; rem > 0; NLMSG_NEXT(nlh, rem)) { + nlh = (struct nlmsghdr *)&ys->rx_buf[len - rem]; + if (!NLMSG_OK(nlh, rem)) { + yerr(yarg->ys, YNL_ERROR_INV_RESP, + "Invalid message or trailing data in the response."); + return YNL_PARSE_CB_ERROR; + } + + if (nlh->nlmsg_flags & NLM_F_DUMP_INTR) { + /* TODO: handle this better */ + yerr(yarg->ys, YNL_ERROR_DUMP_INTER, + "Dump interrupted / inconsistent, please retry."); + return YNL_PARSE_CB_ERROR; + } + + switch (nlh->nlmsg_type) { + case 0: + yerr(yarg->ys, YNL_ERROR_INV_RESP, + "Invalid message type in the response."); + return YNL_PARSE_CB_ERROR; + case NLMSG_NOOP: + case NLMSG_OVERRUN ... NLMSG_MIN_TYPE - 1: + ret = YNL_PARSE_CB_OK; + break; + case NLMSG_ERROR: + ret = ynl_cb_error(nlh, yarg); + break; + case NLMSG_DONE: + ret = ynl_cb_done(nlh, yarg); + break; + default: + ret = cb(nlh, yarg); + break; + } + } + + return ret; +} + +static int ynl_sock_read_msgs(struct ynl_parse_arg *yarg, ynl_parse_cb_t cb) +{ + return __ynl_sock_read_msgs(yarg, cb, 0); +} + +static int ynl_recv_ack(struct ynl_sock *ys, int ret) +{ + struct ynl_parse_arg yarg = { .ys = ys, }; + + if (!ret) { + yerr(ys, YNL_ERROR_EXPECT_ACK, + "Expecting an ACK but nothing received"); + return -1; + } + + return ynl_sock_read_msgs(&yarg, ynl_cb_null); +} + +/* Init/fini and genetlink boiler plate */ +static int +ynl_get_family_info_mcast(struct ynl_sock *ys, const struct nlattr *mcasts) +{ + const struct nlattr *entry, *attr; + unsigned int i; + + ynl_attr_for_each_nested(attr, mcasts) + ys->n_mcast_groups++; + + if (!ys->n_mcast_groups) + return 0; + + ys->mcast_groups = calloc(ys->n_mcast_groups, + sizeof(*ys->mcast_groups)); + if (!ys->mcast_groups) + return YNL_PARSE_CB_ERROR; + + i = 0; + ynl_attr_for_each_nested(entry, mcasts) { + ynl_attr_for_each_nested(attr, entry) { + if (ynl_attr_type(attr) == CTRL_ATTR_MCAST_GRP_ID) + ys->mcast_groups[i].id = ynl_attr_get_u32(attr); + if (ynl_attr_type(attr) == CTRL_ATTR_MCAST_GRP_NAME) { + strncpy(ys->mcast_groups[i].name, + ynl_attr_get_str(attr), + GENL_NAMSIZ - 1); + ys->mcast_groups[i].name[GENL_NAMSIZ - 1] = 0; + } + } + i++; + } + + return 0; +} + +static int +ynl_get_family_info_cb(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg) +{ + struct ynl_sock *ys = yarg->ys; + const struct nlattr *attr; + bool found_id = true; + + ynl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) { + if (ynl_attr_type(attr) == CTRL_ATTR_MCAST_GROUPS) + if (ynl_get_family_info_mcast(ys, attr)) + return YNL_PARSE_CB_ERROR; + + if (ynl_attr_type(attr) != CTRL_ATTR_FAMILY_ID) + continue; + + if (ynl_attr_data_len(attr) != sizeof(__u16)) { + yerr(ys, YNL_ERROR_ATTR_INVALID, "Invalid family ID"); + return YNL_PARSE_CB_ERROR; + } + + ys->family_id = ynl_attr_get_u16(attr); + found_id = true; + } + + if (!found_id) { + yerr(ys, YNL_ERROR_ATTR_MISSING, "Family ID missing"); + return YNL_PARSE_CB_ERROR; + } + return YNL_PARSE_CB_OK; +} + +static int ynl_sock_read_family(struct ynl_sock *ys, const char *family_name) +{ + struct ynl_parse_arg yarg = { .ys = ys, }; + struct nlmsghdr *nlh; + int err; + + nlh = ynl_gemsg_start_req(ys, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, 1); + ynl_attr_put_str(nlh, CTRL_ATTR_FAMILY_NAME, family_name); + + err = ynl_msg_end(ys, nlh); + if (err < 0) + return err; + + err = send(ys->socket, nlh, nlh->nlmsg_len, 0); + if (err < 0) { + perr(ys, "failed to request socket family info"); + return err; + } + + err = ynl_sock_read_msgs(&yarg, ynl_get_family_info_cb); + if (err < 0) { + free(ys->mcast_groups); + perr(ys, "failed to receive the socket family info - no such family?"); + return err; + } + + err = ynl_recv_ack(ys, err); + if (err < 0) { + free(ys->mcast_groups); + return err; + } + + return 0; +} + +struct ynl_sock * +ynl_sock_create(const struct ynl_family *yf, struct ynl_error *yse) +{ + struct sockaddr_nl addr; + struct ynl_sock *ys; + socklen_t addrlen; + int one = 1; + + ys = malloc(sizeof(*ys) + 2 * YNL_SOCKET_BUFFER_SIZE); + if (!ys) + return NULL; + memset(ys, 0, sizeof(*ys)); + + ys->family = yf; + ys->tx_buf = &ys->raw_buf[0]; + ys->rx_buf = &ys->raw_buf[YNL_SOCKET_BUFFER_SIZE]; + ys->ntf_last_next = &ys->ntf_first; + + ys->socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); + if (ys->socket < 0) { + __perr(yse, "failed to create a netlink socket"); + goto err_free_sock; + } + + if (setsockopt(ys->socket, SOL_NETLINK, NETLINK_CAP_ACK, + &one, sizeof(one))) { + __perr(yse, "failed to enable netlink ACK"); + goto err_close_sock; + } + if (setsockopt(ys->socket, SOL_NETLINK, NETLINK_EXT_ACK, + &one, sizeof(one))) { + __perr(yse, "failed to enable netlink ext ACK"); + goto err_close_sock; + } + + memset(&addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + if (bind(ys->socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + __perr(yse, "unable to bind to a socket address"); + goto err_close_sock;; + } + + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + if (getsockname(ys->socket, (struct sockaddr *)&addr, &addrlen) < 0) { + __perr(yse, "unable to read socket address"); + goto err_close_sock;; + } + ys->portid = addr.nl_pid; + ys->seq = random(); + + + if (ynl_sock_read_family(ys, yf->name)) { + if (yse) + memcpy(yse, &ys->err, sizeof(*yse)); + goto err_close_sock; + } + + return ys; + +err_close_sock: + close(ys->socket); +err_free_sock: + free(ys); + return NULL; +} + +void ynl_sock_destroy(struct ynl_sock *ys) +{ + struct ynl_ntf_base_type *ntf; + + close(ys->socket); + while ((ntf = ynl_ntf_dequeue(ys))) + ynl_ntf_free(ntf); + free(ys->mcast_groups); + free(ys); +} + +/* YNL multicast handling */ + +void ynl_ntf_free(struct ynl_ntf_base_type *ntf) +{ + ntf->free(ntf); +} + +int ynl_subscribe(struct ynl_sock *ys, const char *grp_name) +{ + unsigned int i; + int err; + + for (i = 0; i < ys->n_mcast_groups; i++) + if (!strcmp(ys->mcast_groups[i].name, grp_name)) + break; + if (i == ys->n_mcast_groups) { + yerr(ys, ENOENT, "Multicast group '%s' not found", grp_name); + return -1; + } + + err = setsockopt(ys->socket, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, + &ys->mcast_groups[i].id, + sizeof(ys->mcast_groups[i].id)); + if (err < 0) { + perr(ys, "Subscribing to multicast group failed"); + return -1; + } + + return 0; +} + +int ynl_socket_get_fd(struct ynl_sock *ys) +{ + return ys->socket; +} + +struct ynl_ntf_base_type *ynl_ntf_dequeue(struct ynl_sock *ys) +{ + struct ynl_ntf_base_type *ntf; + + if (!ynl_has_ntf(ys)) + return NULL; + + ntf = ys->ntf_first; + ys->ntf_first = ntf->next; + if (ys->ntf_last_next == &ntf->next) + ys->ntf_last_next = &ys->ntf_first; + + return ntf; +} + +static int ynl_ntf_parse(struct ynl_sock *ys, const struct nlmsghdr *nlh) +{ + struct ynl_parse_arg yarg = { .ys = ys, }; + const struct ynl_ntf_info *info; + struct ynl_ntf_base_type *rsp; + struct genlmsghdr *gehdr; + int ret; + + gehdr = ynl_nlmsg_data(nlh); + if (gehdr->cmd >= ys->family->ntf_info_size) + return YNL_PARSE_CB_ERROR; + info = &ys->family->ntf_info[gehdr->cmd]; + if (!info->cb) + return YNL_PARSE_CB_ERROR; + + rsp = calloc(1, info->alloc_sz); + rsp->free = info->free; + yarg.data = rsp->data; + yarg.rsp_policy = info->policy; + + ret = info->cb(nlh, &yarg); + if (ret <= YNL_PARSE_CB_STOP) + goto err_free; + + rsp->family = nlh->nlmsg_type; + rsp->cmd = gehdr->cmd; + + *ys->ntf_last_next = rsp; + ys->ntf_last_next = &rsp->next; + + return YNL_PARSE_CB_OK; + +err_free: + info->free(rsp); + return YNL_PARSE_CB_ERROR; +} + +static int +ynl_ntf_trampoline(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg) +{ + return ynl_ntf_parse(yarg->ys, nlh); +} + +int ynl_ntf_check(struct ynl_sock *ys) +{ + struct ynl_parse_arg yarg = { .ys = ys, }; + int err; + + do { + err = __ynl_sock_read_msgs(&yarg, ynl_ntf_trampoline, + MSG_DONTWAIT); + if (err < 0) + return err; + } while (err > 0); + + return 0; +} + +/* YNL specific helpers used by the auto-generated code */ + +struct ynl_dump_list_type *YNL_LIST_END = (void *)(0xb4d123); + +void ynl_error_unknown_notification(struct ynl_sock *ys, __u8 cmd) +{ + yerr(ys, YNL_ERROR_UNKNOWN_NTF, + "Unknown notification message type '%d'", cmd); +} + +int ynl_error_parse(struct ynl_parse_arg *yarg, const char *msg) +{ + yerr(yarg->ys, YNL_ERROR_INV_RESP, "Error parsing response: %s", msg); + return YNL_PARSE_CB_ERROR; +} + +static int +ynl_check_alien(struct ynl_sock *ys, const struct nlmsghdr *nlh, __u32 rsp_cmd) +{ + struct genlmsghdr *gehdr; + + if (ynl_nlmsg_data_len(nlh) < sizeof(*gehdr)) { + yerr(ys, YNL_ERROR_INV_RESP, + "Kernel responded with truncated message"); + return -1; + } + + gehdr = ynl_nlmsg_data(nlh); + if (gehdr->cmd != rsp_cmd) + return ynl_ntf_parse(ys, nlh); + + return 0; +} + +static +int ynl_req_trampoline(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg) +{ + struct ynl_req_state *yrs = (void *)yarg; + int ret; + + ret = ynl_check_alien(yrs->yarg.ys, nlh, yrs->rsp_cmd); + if (ret) + return ret < 0 ? YNL_PARSE_CB_ERROR : YNL_PARSE_CB_OK; + + return yrs->cb(nlh, &yrs->yarg); +} + +int ynl_exec(struct ynl_sock *ys, struct nlmsghdr *req_nlh, + struct ynl_req_state *yrs) +{ + int err; + + err = ynl_msg_end(ys, req_nlh); + if (err < 0) + return err; + + err = send(ys->socket, req_nlh, req_nlh->nlmsg_len, 0); + if (err < 0) + return err; + + do { + err = ynl_sock_read_msgs(&yrs->yarg, ynl_req_trampoline); + } while (err > 0); + + return err; +} + +static int +ynl_dump_trampoline(const struct nlmsghdr *nlh, struct ynl_parse_arg *data) +{ + struct ynl_dump_state *ds = (void *)data; + struct ynl_dump_list_type *obj; + struct ynl_parse_arg yarg = {}; + int ret; + + ret = ynl_check_alien(ds->yarg.ys, nlh, ds->rsp_cmd); + if (ret) + return ret < 0 ? YNL_PARSE_CB_ERROR : YNL_PARSE_CB_OK; + + obj = calloc(1, ds->alloc_sz); + if (!obj) + return YNL_PARSE_CB_ERROR; + + if (!ds->first) + ds->first = obj; + if (ds->last) + ds->last->next = obj; + ds->last = obj; + + yarg = ds->yarg; + yarg.data = &obj->data; + + return ds->cb(nlh, &yarg); +} + +static void *ynl_dump_end(struct ynl_dump_state *ds) +{ + if (!ds->first) + return YNL_LIST_END; + + ds->last->next = YNL_LIST_END; + return ds->first; +} + +int ynl_exec_dump(struct ynl_sock *ys, struct nlmsghdr *req_nlh, + struct ynl_dump_state *yds) +{ + int err; + + err = ynl_msg_end(ys, req_nlh); + if (err < 0) + return err; + + err = send(ys->socket, req_nlh, req_nlh->nlmsg_len, 0); + if (err < 0) + return err; + + do { + err = ynl_sock_read_msgs(&yds->yarg, ynl_dump_trampoline); + if (err < 0) + goto err_close_list; + } while (err > 0); + + yds->first = ynl_dump_end(yds); + return 0; + +err_close_list: + yds->first = ynl_dump_end(yds); + return -1; +} diff --git a/ynl.h b/ynl.h new file mode 100644 index 0000000..eef7c63 --- /dev/null +++ b/ynl.h @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +#ifndef __YNL_C_H +#define __YNL_C_H 1 + +#include +#include +#include + +#include "ynl-priv.h" + +enum ynl_error_code { + YNL_ERROR_NONE = 0, + __YNL_ERRNO_END = 4096, + YNL_ERROR_INTERNAL, + YNL_ERROR_DUMP_INTER, + YNL_ERROR_EXPECT_ACK, + YNL_ERROR_EXPECT_MSG, + YNL_ERROR_UNEXPECT_MSG, + YNL_ERROR_ATTR_MISSING, + YNL_ERROR_ATTR_INVALID, + YNL_ERROR_UNKNOWN_NTF, + YNL_ERROR_INV_RESP, + YNL_ERROR_INPUT_INVALID, + YNL_ERROR_INPUT_TOO_BIG, +}; + +/** + * struct ynl_error - error encountered by YNL + * @code: errno (low values) or YNL error code (enum ynl_error_code) + * @attr_offs: offset of bad attribute (for very advanced users) + * @msg: error message + * + * Error information for when YNL operations fail. + * Users should interact with the err member of struct ynl_sock directly. + * The main exception to that rule is ynl_sock_create(). + */ +struct ynl_error { + enum ynl_error_code code; + unsigned int attr_offs; + char msg[512]; +}; + +/** + * struct ynl_family - YNL family info + * Family description generated by codegen. Pass to ynl_sock_create(). + */ +struct ynl_family { +/* private: */ + const char *name; + size_t hdr_len; + const struct ynl_ntf_info *ntf_info; + unsigned int ntf_info_size; +}; + +/** + * struct ynl_sock - YNL wrapped netlink socket + * @err: YNL error descriptor, cleared on every request. + */ +struct ynl_sock { + struct ynl_error err; + +/* private: */ + const struct ynl_family *family; + int socket; + __u32 seq; + __u32 portid; + __u16 family_id; + + unsigned int n_mcast_groups; + struct { + unsigned int id; + char name[GENL_NAMSIZ]; + } *mcast_groups; + + struct ynl_ntf_base_type *ntf_first; + struct ynl_ntf_base_type **ntf_last_next; + + struct nlmsghdr *nlh; + struct ynl_policy_nest *req_policy; + unsigned char *tx_buf; + unsigned char *rx_buf; + unsigned char raw_buf[]; +}; + +struct ynl_sock * +ynl_sock_create(const struct ynl_family *yf, struct ynl_error *e); +void ynl_sock_destroy(struct ynl_sock *ys); + +#define ynl_dump_foreach(dump, iter) \ + for (typeof(dump->obj) *iter = &dump->obj; \ + !ynl_dump_obj_is_last(iter); \ + iter = ynl_dump_obj_next(iter)) + +/** + * ynl_dump_empty() - does the dump have no entries + * @dump: pointer to the dump list, as returned by a dump call + * + * Check if the dump is empty, i.e. contains no objects. + * Dump calls return NULL on error, and terminator element if empty. + */ +static inline bool ynl_dump_empty(void *dump) +{ + return dump == (void *)YNL_LIST_END; +} + +int ynl_subscribe(struct ynl_sock *ys, const char *grp_name); +int ynl_socket_get_fd(struct ynl_sock *ys); +int ynl_ntf_check(struct ynl_sock *ys); + +/** + * ynl_has_ntf() - check if socket has *parsed* notifications + * @ys: active YNL socket + * + * Note that this does not take into account notifications sitting + * in netlink socket, just the notifications which have already been + * read and parsed (e.g. during a ynl_ntf_check() call). + */ +static inline bool ynl_has_ntf(struct ynl_sock *ys) +{ + return ys->ntf_last_next != &ys->ntf_first; +} +struct ynl_ntf_base_type *ynl_ntf_dequeue(struct ynl_sock *ys); + +void ynl_ntf_free(struct ynl_ntf_base_type *ntf); +#endif