From nobody Sat Oct 4 15:57:29 2025 Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E74B21B9FE; Thu, 14 Aug 2025 16:44:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755189857; cv=none; b=Kl94SFi9f4W4wPsnE3GBtMShnB+AIgfYlau1S/oN9a01LV2nBuIJvtpa/qfq6UhnghRXXATzcXib+LVXUB+rCvpAvxBFNTCOCN9zdaseXEuBofA9Vi5X2CBVbsVAvy9YLxXoxH2mDblxRgxOW6PnxB0QjtYJTuhJGZR1t00FXIk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755189857; c=relaxed/simple; bh=Pi12NCjVNa0Ym+EGtm5xt0Js6GSAC2n7/7dVT3rMZoQ=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=gmBsSbftWrk35w+iu8cxrLZmNodInk2gJerEkUVbeKuDd9KZUAK8nKETmw/mvuLxdlzPGCHJ+E3meKo6Kg2mmsb7FX6kKjysDRMk4mBq+ac+utX8Us/CXaLX3OaN8N/j3CZ5FSJbeR9pteh4n+O2vtWd8FavcljUzwiqqKXPviU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fomichev.me; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.216.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=fomichev.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pj1-f47.google.com with SMTP id 98e67ed59e1d1-323266d2d9eso1019621a91.0; Thu, 14 Aug 2025 09:44:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755189854; x=1755794654; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=n6Ds2V8iI29lENVwGkMXUhsBybo0WpVnyyaXg0iPlVc=; b=W+t5I/xpTpXvvkstmhGzTCR0X6z/Je8rKE8JNDagkEvNmM6Et2ah5+8xrZP9SjEYIu 3pls2LlqArW5BDI0Y/9T98c9T5i2q1gl+V4ukafW5SKKLu+M1g1ljPv7dcnF2gQ/JDE8 zUQcMjyukRLewCRY7cPdT/JCIwvlBJUOOUORmtqrzAtMFe6SIsE6A7+HpqibPxTDqz2r 0GavYUHsk0N9tUYCfvjKhBjP/jNcVxacsH6NwIhoE6jh9Oj2NM2PG2d9S4/T9vg1O1RD icndY4XS2skykSZZQbY1rnOKnfPuiABzT4D3+PitEkK+e/28RAkKYVbFXA7H6gqWvOxt JJYA== X-Forwarded-Encrypted: i=1; AJvYcCVZP0IfP+Sej9NZNhQSuRKpeh7yUz3b/TLYzVOEmzyUUQUij+qexQ3qM3fyhoQbaY2YPPY7kxuTNrC9saQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yxds0PY0YcxCUog5HvinyvVD3m1bemsfzoRtLNmOWM2MfRl5TN0 o3c2E4cV2qJ8oizNh60/E2E9sTo+1z9XMXOCXR1NCSv3+71iSWZy5vnlu2Ih X-Gm-Gg: ASbGncsQMjlH3PhvpGY+JyeGIXE/dxDRT+Khww21yLiRj/qwu0w/XCoqyn54vKVl693 +VIbPfQ8FmY83xeEzHAvOLe0sfjXiKp1dFp55+Uc6+UY3UGD7HnkirxZEaV8CB3hx+TZgp5Kscc /8c0aBlncqH0h5SgvCn9jOY3f46VcsiN8J/PQWhSgL2qRK+hMXCV2DU5GFPFjcgv/SQXoywOJ+s 173SHeXb+82ZRs43Kq/QLxQi8X2FL221lRp6tZdUA6K0OYOtacT4rKvZKM+oah5JeulTM/NRqB9 6rUbzWiI1T4q53m1QT9MYqhZSj7SxxkXVhNP9YquBceyfJPc/wCRjZjuK4JMcSjpiSP6IHG/ms7 /8KdYtuNbuLpwdD7Rh03lOhkwJtqyNa2BBKbW5dYAu0RZ+9EpqffWwiBtw2k= X-Google-Smtp-Source: AGHT+IEfWn7TjnKHS0RiH5DoZStYJK0DFqD4OC/pvUjtCfhkz0jsuZUx0Us7RAkcm9ZX0vY7n2Ukwg== X-Received: by 2002:a17:90b:1f85:b0:31f:867:d6b4 with SMTP id 98e67ed59e1d1-323279c8531mr6918867a91.10.1755189854415; Thu, 14 Aug 2025 09:44:14 -0700 (PDT) Received: from localhost (c-73-158-218-242.hsd1.ca.comcast.net. [73.158.218.242]) by smtp.gmail.com with UTF8SMTPSA id 98e67ed59e1d1-3232ae14f6dsm1029231a91.6.2025.08.14.09.44.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Aug 2025 09:44:14 -0700 (PDT) From: Stanislav Fomichev To: netdev@vger.kernel.org Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, donald.hunter@gmail.com, horms@kernel.org, jstancek@redhat.com, sdf@fomichev.me, jacob.e.keller@intel.com, linux-kernel@vger.kernel.org Subject: [PATCH net-next] tools: ynl: make ynl.c more c++ friendly Date: Thu, 14 Aug 2025 09:44:13 -0700 Message-ID: <20250814164413.1258893-1-sdf@fomichev.me> X-Mailer: git-send-email 2.50.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Compiling ynl.c in a C++ code base requires invoking C compiler and using extern "C" for the headers. To make it easier, we can add small changes to the ynl.c file to make it palatable to the native C++ compiler. The changes are: - avoid using void* pointer arithmetic, use char* instead - avoid implicit void* type casts, add c-style explicit casts - avoid implicit int->enum type casts, add c-style explicit casts - avoid anonymous structs (for type casts) - namespacify cpp version, this should let us compile both ynl.c as c and ynl.c as cpp in the same binary (YNL_CPP can be used to enable/disable namespacing) Also add test_cpp rule to make sure ynl.c won't break C++ in the future. Signed-off-by: Stanislav Fomichev Reviewed-by: Jacob Keller --- tools/net/ynl/lib/Makefile | 5 +++- tools/net/ynl/lib/ynl-priv.h | 11 ++++++- tools/net/ynl/lib/ynl.c | 58 +++++++++++++++++++++--------------- tools/net/ynl/lib/ynl.h | 19 +++++++++--- 4 files changed, 63 insertions(+), 30 deletions(-) diff --git a/tools/net/ynl/lib/Makefile b/tools/net/ynl/lib/Makefile index 4b2b98704ff9..94f8dc4a31d1 100644 --- a/tools/net/ynl/lib/Makefile +++ b/tools/net/ynl/lib/Makefile @@ -11,7 +11,7 @@ OBJS=3D$(patsubst %.c,%.o,${SRCS}) =20 include $(wildcard *.d) =20 -all: ynl.a +all: ynl.a test_cpp =20 ynl.a: $(OBJS) @echo -e "\tAR $@" @@ -23,6 +23,9 @@ ynl.a: $(OBJS) distclean: clean rm -f *.a =20 +test_cpp: ynl.c + $(COMPILE.cpp) -DYNL_CPP -o ynl.cc.o $< + %.o: %.c $(COMPILE.c) -MMD -c -o $@ $< =20 diff --git a/tools/net/ynl/lib/ynl-priv.h b/tools/net/ynl/lib/ynl-priv.h index 824777d7e05e..1dbb14e760e6 100644 --- a/tools/net/ynl/lib/ynl-priv.h +++ b/tools/net/ynl/lib/ynl-priv.h @@ -6,6 +6,10 @@ #include #include =20 +#if defined(__cplusplus) && defined(YNL_CPP) +namespace ynl_cpp { +#endif + struct ynl_parse_arg; =20 /* @@ -224,7 +228,7 @@ static inline void *ynl_attr_data_end(const struct nlat= tr *attr) =20 #define ynl_attr_for_each_payload(start, len, attr) \ for ((attr) =3D ynl_attr_first(start, len, 0); attr; \ - (attr) =3D ynl_attr_next(start + len, attr)) + (attr) =3D ynl_attr_next((char *)start + len, attr)) =20 static inline struct nlattr * ynl_attr_if_good(const void *end, struct nlattr *attr) @@ -467,4 +471,9 @@ ynl_attr_put_sint(struct nlmsghdr *nlh, __u16 type, __s= 64 data) else ynl_attr_put_s64(nlh, type, data); } + +#if defined(__cplusplus) && defined(YNL_CPP) +} // namespace ynl_cpp +#endif + #endif diff --git a/tools/net/ynl/lib/ynl.c b/tools/net/ynl/lib/ynl.c index 2a169c3c0797..9155b4d5b9f9 100644 --- a/tools/net/ynl/lib/ynl.c +++ b/tools/net/ynl/lib/ynl.c @@ -11,6 +11,10 @@ =20 #include "ynl.h" =20 +#if defined(__cplusplus) && defined(YNL_CPP) +namespace ynl_cpp { +#endif + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*arr)) =20 #define __yerr_msg(yse, _msg...) \ @@ -23,13 +27,13 @@ } \ }) =20 -#define __yerr_code(yse, _code...) \ - ({ \ - struct ynl_error *_yse =3D (yse); \ - \ - if (_yse) { \ - _yse->code =3D _code; \ - } \ +#define __yerr_code(yse, _code...) \ + ({ \ + struct ynl_error *_yse =3D (yse); \ + \ + if (_yse) { \ + _yse->code =3D (enum ynl_error_code)_code; \ + } \ }) =20 #define __yerr(yse, _code, _msg...) \ @@ -149,7 +153,7 @@ ynl_err_walk(struct ynl_sock *ys, void *start, void *en= d, unsigned int off, return n; } =20 - data_len =3D end - start; + data_len =3D (char *)end - (char *)start; =20 ynl_attr_for_each_payload(start, data_len, attr) { astart_off =3D (char *)attr - (char *)start; @@ -192,7 +196,7 @@ ynl_err_walk(struct ynl_sock *ys, void *start, void *en= d, unsigned int off, =20 off -=3D sizeof(struct nlattr); start =3D ynl_attr_data(attr); - end =3D start + ynl_attr_data_len(attr); + end =3D (char *)start + ynl_attr_data_len(attr); =20 return n + ynl_err_walk(ys, start, end, off, next_pol, &str[n], str_sz - n, nest_pol); @@ -325,12 +329,12 @@ ynl_ext_ack_check(struct ynl_sock *ys, const struct n= lmsghdr *nlh, static int ynl_cb_error(const struct nlmsghdr *nlh, struct ynl_parse_arg *yarg) { - const struct nlmsgerr *err =3D ynl_nlmsg_data(nlh); + const struct nlmsgerr *err =3D (struct nlmsgerr *)ynl_nlmsg_data(nlh); unsigned int hlen; int code; =20 code =3D err->error >=3D 0 ? err->error : -err->error; - yarg->ys->err.code =3D code; + yarg->ys->err.code =3D (enum ynl_error_code)code; errno =3D code; =20 hlen =3D sizeof(*err); @@ -348,7 +352,7 @@ static int ynl_cb_done(const struct nlmsghdr *nlh, stru= ct ynl_parse_arg *yarg) =20 err =3D *(int *)NLMSG_DATA(nlh); if (err < 0) { - yarg->ys->err.code =3D -err; + yarg->ys->err.code =3D (enum ynl_error_code)-err; errno =3D -err; =20 ynl_ext_ack_check(yarg->ys, nlh, sizeof(int)); @@ -366,7 +370,7 @@ int ynl_attr_validate(struct ynl_parse_arg *yarg, const= struct nlattr *attr) unsigned int type, len; unsigned char *data; =20 - data =3D ynl_attr_data(attr); + data =3D (unsigned char *)ynl_attr_data(attr); len =3D ynl_attr_data_len(attr); type =3D ynl_attr_type(attr); if (type > yarg->rsp_policy->max_attr) { @@ -463,7 +467,7 @@ int ynl_submsg_failed(struct ynl_parse_arg *yarg, const= char *field_name, =20 static void ynl_err_reset(struct ynl_sock *ys) { - ys->err.code =3D 0; + ys->err.code =3D YNL_ERROR_NONE; ys->err.attr_offs =3D 0; ys->err.msg[0] =3D 0; } @@ -643,8 +647,8 @@ ynl_get_family_info_mcast(struct ynl_sock *ys, const st= ruct nlattr *mcasts) if (!ys->n_mcast_groups) return 0; =20 - ys->mcast_groups =3D calloc(ys->n_mcast_groups, - sizeof(*ys->mcast_groups)); + ys->mcast_groups =3D (struct ynl_sock_mcast *)calloc( + ys->n_mcast_groups, sizeof(*ys->mcast_groups)); if (!ys->mcast_groups) return YNL_PARSE_CB_ERROR; =20 @@ -741,7 +745,8 @@ ynl_sock_create(const struct ynl_family *yf, struct ynl= _error *yse) int sock_type; int one =3D 1; =20 - ys =3D malloc(sizeof(*ys) + 2 * YNL_SOCKET_BUFFER_SIZE); + ys =3D (struct ynl_sock *)malloc(sizeof(*ys) + + 2 * YNL_SOCKET_BUFFER_SIZE); if (!ys) return NULL; memset(ys, 0, sizeof(*ys)); @@ -878,7 +883,7 @@ static int ynl_ntf_parse(struct ynl_sock *ys, const str= uct nlmsghdr *nlh) } else { struct genlmsghdr *gehdr; =20 - gehdr =3D ynl_nlmsg_data(nlh); + gehdr =3D (struct genlmsghdr *)ynl_nlmsg_data(nlh); cmd =3D gehdr->cmd; } =20 @@ -888,7 +893,7 @@ static int ynl_ntf_parse(struct ynl_sock *ys, const str= uct nlmsghdr *nlh) if (!info->cb) return YNL_PARSE_CB_ERROR; =20 - rsp =3D calloc(1, info->alloc_sz); + rsp =3D (struct ynl_ntf_base_type *)calloc(1, info->alloc_sz); rsp->free =3D info->free; yarg.data =3D rsp->data; yarg.rsp_policy =3D info->policy; @@ -933,7 +938,8 @@ int ynl_ntf_check(struct ynl_sock *ys) =20 /* YNL specific helpers used by the auto-generated code */ =20 -struct ynl_dump_list_type *YNL_LIST_END =3D (void *)(0xb4d123); +struct ynl_dump_list_type *YNL_LIST_END =3D + (struct ynl_dump_list_type *)(void *)(0xb4d123); =20 void ynl_error_unknown_notification(struct ynl_sock *ys, __u8 cmd) { @@ -962,7 +968,7 @@ ynl_check_alien(struct ynl_sock *ys, const struct nlmsg= hdr *nlh, __u32 rsp_cmd) return -1; } =20 - gehdr =3D ynl_nlmsg_data(nlh); + gehdr =3D (struct genlmsghdr *)ynl_nlmsg_data(nlh); if (gehdr->cmd !=3D rsp_cmd) return ynl_ntf_parse(ys, nlh); } @@ -973,7 +979,7 @@ ynl_check_alien(struct ynl_sock *ys, const struct nlmsg= hdr *nlh, __u32 rsp_cmd) static int ynl_req_trampoline(const struct nlmsghdr *nlh, struct ynl_parse_arg *y= arg) { - struct ynl_req_state *yrs =3D (void *)yarg; + struct ynl_req_state *yrs =3D (struct ynl_req_state *)yarg; int ret; =20 ret =3D ynl_check_alien(yrs->yarg.ys, nlh, yrs->rsp_cmd); @@ -1006,7 +1012,7 @@ int ynl_exec(struct ynl_sock *ys, struct nlmsghdr *re= q_nlh, static int ynl_dump_trampoline(const struct nlmsghdr *nlh, struct ynl_parse_arg *data) { - struct ynl_dump_state *ds =3D (void *)data; + struct ynl_dump_state *ds =3D (struct ynl_dump_state *)data; struct ynl_dump_list_type *obj; struct ynl_parse_arg yarg =3D {}; int ret; @@ -1015,7 +1021,7 @@ ynl_dump_trampoline(const struct nlmsghdr *nlh, struc= t ynl_parse_arg *data) if (ret) return ret < 0 ? YNL_PARSE_CB_ERROR : YNL_PARSE_CB_OK; =20 - obj =3D calloc(1, ds->alloc_sz); + obj =3D (struct ynl_dump_list_type *)calloc(1, ds->alloc_sz); if (!obj) return YNL_PARSE_CB_ERROR; =20 @@ -1066,3 +1072,7 @@ int ynl_exec_dump(struct ynl_sock *ys, struct nlmsghd= r *req_nlh, yds->first =3D ynl_dump_end(yds); return -1; } + +#if defined(__cplusplus) && defined(YNL_CPP) +} // namespace ynl_cpp +#endif diff --git a/tools/net/ynl/lib/ynl.h b/tools/net/ynl/lib/ynl.h index db7c0591a63f..47a8652f056f 100644 --- a/tools/net/ynl/lib/ynl.h +++ b/tools/net/ynl/lib/ynl.h @@ -9,6 +9,10 @@ =20 #include "ynl-priv.h" =20 +#if defined(__cplusplus) && defined(YNL_CPP) +namespace ynl_cpp { +#endif + enum ynl_error_code { YNL_ERROR_NONE =3D 0, __YNL_ERRNO_END =3D 4096, @@ -56,6 +60,11 @@ struct ynl_family { unsigned int ntf_info_size; }; =20 +struct ynl_sock_mcast { + unsigned int id; + char name[GENL_NAMSIZ]; +}; + /** * struct ynl_sock - YNL wrapped netlink socket * @err: YNL error descriptor, cleared on every request. @@ -71,10 +80,7 @@ struct ynl_sock { __u16 family_id; =20 unsigned int n_mcast_groups; - struct { - unsigned int id; - char name[GENL_NAMSIZ]; - } *mcast_groups; + struct ynl_sock_mcast *mcast_groups; =20 struct ynl_ntf_base_type *ntf_first; struct ynl_ntf_base_type **ntf_last_next; @@ -140,4 +146,9 @@ static inline bool ynl_has_ntf(struct ynl_sock *ys) struct ynl_ntf_base_type *ynl_ntf_dequeue(struct ynl_sock *ys); =20 void ynl_ntf_free(struct ynl_ntf_base_type *ntf); + +#if defined(__cplusplus) && defined(YNL_CPP) +} // namespace ynl_cpp +#endif + #endif --=20 2.50.1