NAK. When running with --disable-dco:
Program received signal SIGUSR2, User defined signal 2. 0x00007ffff7aee967 in __GI___poll (fds=0x555555668ca0, nfds=2, timeout=10000) at ../sysdeps/unix/sysv/linux/poll.c:29 29 ../sysdeps/unix/sysv/linux/poll.c: No such file or directory. (gdb) c Continuing. 2023-03-21 11:52:25 us=550135 event_wait : Interrupted system call (fd=-1,code=4) Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7be46a0 in nl_cb_set () from /lib/x86_64-linux-gnu/libnl-3.so.200 (gdb) bt #0 0x00007ffff7be46a0 in nl_cb_set () from /lib/x86_64-linux-gnu/libnl-3.so.200 #1 0x000055555557047a in ovpn_nl_msg_send (dco=dco@entry=0x555555656348, nl_msg=0x55555566d1b0, cb=cb@entry=0x55555556fde0 <dco_parse_peer_multi>, cb_arg=cb_arg@entry=0x7fffffffc100, prefix=prefix@entry=0x5555555f4050 <__func__.33438> "dco_get_peer_stats_multi") at dco_linux.c:182 #2 0x00005555555715ec in dco_get_peer_stats_multi (dco=dco@entry=0x555555656348, m=m@entry=0x7fffffffc100) at dco_linux.c:939 #3 0x0000555555597c63 in multi_print_status (m=m@entry=0x7fffffffc100, so=so@entry=0x55555564dc90, version=1) at multi.c:852 #4 0x000055555559c75e in multi_print_status (version=<optimized out>, so=0x55555564dc90, m=0x7fffffffc100) at multi.c:3848 #5 multi_process_signal (m=m@entry=0x7fffffffc100) at multi.c:3848 #6 0x000055555559537f in tunnel_server_udp (top=0x7fffffffd3d0) at mudp.c:506 #7 0x00005555555a1369 in openvpn_main (argc=4, argv=0x7fffffffe638) at openvpn.c:319 #8 0x00007ffff7a00083 in __libc_start_main (main=0x555555561730 <main>, argc=4, argv=0x7fffffffe638, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe628) at ../csu/libc-start.c:308 #9 0x000055555556176e in _start () ti 21. maalisk. 2023 klo 1.22 Antonio Quartulli (a...@unstable.cc) kirjoitti: > > With this API it is possible to retrieve the stats for a specific peer > or for all peers and then update the userspace counters with the value > reported by DCO. > > Change-Id: Ia3990b86b1be7ca844fb1674b39ce0d60528ccff > Signed-off-by: Antonio Quartulli <a...@unstable.cc> > --- > > Pleas, use the latest ovpn-dco master branch! > > src/openvpn/dco_linux.c | 194 ++++++++++++++++++++++++++++++++--- > src/openvpn/ovpn_dco_linux.h | 14 ++- > 2 files changed, 190 insertions(+), 18 deletions(-) > > diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c > index 47961849..1f18fa81 100644 > --- a/src/openvpn/dco_linux.c > +++ b/src/openvpn/dco_linux.c > @@ -41,6 +41,7 @@ > #include "tun.h" > #include "ssl.h" > #include "fdmisc.h" > +#include "multi.h" > #include "ssl_verify.h" > > #include "ovpn_dco_linux.h" > @@ -168,16 +169,17 @@ ovpn_nl_recvmsgs(dco_context_t *dco, const char *prefix) > * @param dco The dco context to use > * @param nl_msg the message to use > * @param cb An optional callback if the caller expects an answer > + * @param cb_arg An optional param to pass to the callback > * @param prefix A prefix to report in the error message to give the user > context > * @return status of sending the message > */ > static int > ovpn_nl_msg_send(dco_context_t *dco, struct nl_msg *nl_msg, ovpn_nl_cb cb, > - const char *prefix) > + void *cb_arg, const char *prefix) > { > dco->status = 1; > > - nl_cb_set(dco->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, cb, dco); > + nl_cb_set(dco->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, cb, cb_arg); > nl_send_auto(dco->nl_sock, nl_msg); > > while (dco->status == 1) > @@ -268,7 +270,7 @@ dco_new_peer(dco_context_t *dco, unsigned int peerid, int > sd, > } > nla_nest_end(nl_msg, attr); > > - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, __func__); > + ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); > > nla_put_failure: > nlmsg_free(nl_msg); > @@ -489,7 +491,7 @@ dco_swap_keys(dco_context_t *dco, unsigned int peerid) > NLA_PUT_U32(nl_msg, OVPN_SWAP_KEYS_ATTR_PEER_ID, peerid); > nla_nest_end(nl_msg, attr); > > - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, __func__); > + ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); > > nla_put_failure: > nlmsg_free(nl_msg); > @@ -513,7 +515,7 @@ dco_del_peer(dco_context_t *dco, unsigned int peerid) > NLA_PUT_U32(nl_msg, OVPN_DEL_PEER_ATTR_PEER_ID, peerid); > nla_nest_end(nl_msg, attr); > > - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, __func__); > + ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); > > nla_put_failure: > nlmsg_free(nl_msg); > @@ -539,7 +541,7 @@ dco_del_key(dco_context_t *dco, unsigned int peerid, > NLA_PUT_U8(nl_msg, OVPN_DEL_KEY_ATTR_KEY_SLOT, slot); > nla_nest_end(nl_msg, attr); > > - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, __func__); > + ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); > > nla_put_failure: > nlmsg_free(nl_msg); > @@ -596,7 +598,7 @@ dco_new_key(dco_context_t *dco, unsigned int peerid, int > keyid, > > nla_nest_end(nl_msg, attr); > > - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, __func__); > + ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); > > nla_put_failure: > nlmsg_free(nl_msg); > @@ -625,7 +627,7 @@ dco_set_peer(dco_context_t *dco, unsigned int peerid, > keepalive_timeout); > nla_nest_end(nl_msg, attr); > > - ret = ovpn_nl_msg_send(dco, nl_msg, NULL, __func__); > + ret = ovpn_nl_msg_send(dco, nl_msg, NULL, NULL, __func__); > > nla_put_failure: > nlmsg_free(nl_msg); > @@ -706,7 +708,7 @@ ovpn_get_mcast_id(dco_context_t *dco) > int ret = -EMSGSIZE; > NLA_PUT_STRING(nl_msg, CTRL_ATTR_FAMILY_NAME, OVPN_NL_NAME); > > - ret = ovpn_nl_msg_send(dco, nl_msg, mcast_family_handler, __func__); > + ret = ovpn_nl_msg_send(dco, nl_msg, mcast_family_handler, dco, __func__); > > nla_put_failure: > nlmsg_free(nl_msg); > @@ -819,18 +821,184 @@ dco_do_read(dco_context_t *dco) > return ovpn_nl_recvmsgs(dco, __func__); > } > > +static void > +dco_update_peer_stat(struct context_2 *c2, struct nlattr *tb[], uint32_t id) > +{ > + if (tb[OVPN_GET_PEER_RESP_ATTR_LINK_RX_BYTES]) > + { > + c2->dco_read_bytes = > nla_get_u64(tb[OVPN_GET_PEER_RESP_ATTR_LINK_RX_BYTES]); > + msg(D_DCO_DEBUG, "%s / dco_read_bytes: %lu", __func__, > + c2->dco_read_bytes); > + } > + else > + { > + msg(M_WARN, "%s: no link RX bytes provided in reply for peer %u", > + __func__, id); > + } > + > + if (tb[OVPN_GET_PEER_RESP_ATTR_LINK_TX_BYTES]) > + { > + c2->dco_write_bytes = > nla_get_u64(tb[OVPN_GET_PEER_RESP_ATTR_LINK_TX_BYTES]); > + msg(D_DCO_DEBUG, "%s / dco_write_bytes: %lu", __func__, > + c2->dco_write_bytes); > + } > + else > + { > + msg(M_WARN, "%s: no link TX bytes provided in reply for peer %u", > + __func__, id); > + } > + > + if (tb[OVPN_GET_PEER_RESP_ATTR_VPN_RX_BYTES]) > + { > + c2->tun_read_bytes = > nla_get_u64(tb[OVPN_GET_PEER_RESP_ATTR_VPN_RX_BYTES]); > + msg(D_DCO_DEBUG, "%s / tun_read_bytes: %lu", __func__, > + c2->tun_read_bytes); > + } > + else > + { > + msg(M_WARN, "%s: no VPN RX bytes provided in reply for peer %u", > + __func__, id); > + } > + > + if (tb[OVPN_GET_PEER_RESP_ATTR_VPN_TX_BYTES]) > + { > + c2->tun_write_bytes = > nla_get_u64(tb[OVPN_GET_PEER_RESP_ATTR_VPN_TX_BYTES]); > + msg(D_DCO_DEBUG, "%s / tun_write_bytes: %lu", __func__, > + c2->tun_write_bytes); > + } > + else > + { > + msg(M_WARN, "%s: no VPN TX bytes provided in reply for peer %u", > + __func__, id); > + } > +} > + > +int > +dco_parse_peer_multi(struct nl_msg *msg, void *arg) > +{ > + struct nlattr *tb[OVPN_ATTR_MAX + 1]; > + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); > + > + msg(D_DCO_DEBUG, "%s: parsing message...", __func__); > + > + nla_parse(tb, OVPN_ATTR_MAX, genlmsg_attrdata(gnlh, 0), > + genlmsg_attrlen(gnlh, 0), NULL); > + > + if (!tb[OVPN_ATTR_GET_PEER]) > + { > + return NL_SKIP; > + } > + > + struct nlattr *tb_peer[OVPN_GET_PEER_RESP_ATTR_MAX + 1]; > + > + nla_parse(tb_peer, OVPN_GET_PEER_RESP_ATTR_MAX, > + nla_data(tb[OVPN_ATTR_GET_PEER]), > + nla_len(tb[OVPN_ATTR_GET_PEER]), NULL); > + > + if (!tb_peer[OVPN_GET_PEER_RESP_ATTR_PEER_ID]) > + { > + msg(M_WARN, "%s: no peer-id provided in reply", __func__); > + return NL_SKIP; > + } > + > + uint32_t peer_id = nla_get_u32(tb_peer[OVPN_GET_PEER_RESP_ATTR_PEER_ID]); > + struct multi_context *m = arg; > + struct hash_iterator hi; > + hash_iterator_init(m->hash, &hi); > + > + struct hash_element *he; > + while ((he = hash_iterator_next(&hi))) > + { > + struct multi_instance *mi = (struct multi_instance *)he->value; > + > + if (mi->context.c2.tls_multi->peer_id != peer_id) > + { > + continue; > + } > + > + dco_update_peer_stat(&mi->context.c2, tb_peer, peer_id); > + > + return NL_OK; > + } > + > + msg(D_DCO_DEBUG, "%s: peer %d returned by kernel, but not found locally", > + __func__, peer_id); > + > + return NL_SKIP; > +} > + > int > dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m) > { > - /* Not implemented. */ > - return 0; > + msg(D_DCO_DEBUG, "%s", __func__); > + > + struct nl_msg *nl_msg = ovpn_dco_nlmsg_create(dco, OVPN_CMD_GET_PEER); > + > + nlmsg_hdr(nl_msg)->nlmsg_flags |= NLM_F_DUMP; > + > + return ovpn_nl_msg_send(dco, nl_msg, dco_parse_peer_multi, m, __func__); > +} > + > +static int > +dco_parse_peer(struct nl_msg *msg, void *arg) > +{ > + struct context *c = arg; > + struct nlattr *tb[OVPN_ATTR_MAX + 1]; > + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); > + > + msg(D_DCO_DEBUG, "%s: parsing message...", __func__); > + > + nla_parse(tb, OVPN_ATTR_MAX, genlmsg_attrdata(gnlh, 0), > + genlmsg_attrlen(gnlh, 0), NULL); > + > + if (!tb[OVPN_ATTR_GET_PEER]) > + { > + msg(D_DCO_DEBUG, "%s: malformed reply", __func__); > + return NL_SKIP; > + } > + > + struct nlattr *tb_peer[OVPN_GET_PEER_RESP_ATTR_MAX + 1]; > + > + nla_parse(tb_peer, OVPN_GET_PEER_RESP_ATTR_MAX, > + nla_data(tb[OVPN_ATTR_GET_PEER]), > + nla_len(tb[OVPN_ATTR_GET_PEER]), NULL); > + > + if (!tb_peer[OVPN_GET_PEER_RESP_ATTR_PEER_ID]) > + { > + msg(M_WARN, "%s: no peer-id provided in reply", __func__); > + return NL_SKIP; > + } > + > + uint32_t peer_id = nla_get_u32(tb_peer[OVPN_GET_PEER_RESP_ATTR_PEER_ID]); > + if (c->c2.tls_multi->dco_peer_id != peer_id) > + { > + return NL_SKIP; > + } > + > + dco_update_peer_stat(&c->c2, tb_peer, peer_id); > + > + return NL_OK; > } > > int > dco_get_peer_stats(struct context *c) > { > - /* Not implemented. */ > - return 0; > + uint32_t peer_id = c->c2.tls_multi->dco_peer_id; > + msg(D_DCO_DEBUG, "%s: peer-id %d", __func__, peer_id); > + > + dco_context_t *dco = &c->c1.tuntap->dco; > + struct nl_msg *nl_msg = ovpn_dco_nlmsg_create(dco, OVPN_CMD_GET_PEER); > + struct nlattr *attr = nla_nest_start(nl_msg, OVPN_ATTR_GET_PEER); > + int ret = -EMSGSIZE; > + > + NLA_PUT_U32(nl_msg, OVPN_GET_PEER_ATTR_PEER_ID, peer_id); > + nla_nest_end(nl_msg, attr); > + > + ret = ovpn_nl_msg_send(dco, nl_msg, dco_parse_peer, c, __func__); > + > +nla_put_failure: > + nlmsg_free(nl_msg); > + return ret; > } > > bool > diff --git a/src/openvpn/ovpn_dco_linux.h b/src/openvpn/ovpn_dco_linux.h > index d3fd9a89..73e19b59 100644 > --- a/src/openvpn/ovpn_dco_linux.h > +++ b/src/openvpn/ovpn_dco_linux.h > @@ -2,7 +2,7 @@ > /* > * OpenVPN data channel accelerator > * > - * Copyright (C) 2019-2022 OpenVPN, Inc. > + * Copyright (C) 2019-2023 OpenVPN, Inc. > * > * Author: James Yonan <ja...@openvpn.net> > * Antonio Quartulli <anto...@openvpn.net> > @@ -188,10 +188,14 @@ enum ovpn_netlink_get_peer_response_attrs { > OVPN_GET_PEER_RESP_ATTR_LOCAL_PORT, > OVPN_GET_PEER_RESP_ATTR_KEEPALIVE_INTERVAL, > OVPN_GET_PEER_RESP_ATTR_KEEPALIVE_TIMEOUT, > - OVPN_GET_PEER_RESP_ATTR_RX_BYTES, > - OVPN_GET_PEER_RESP_ATTR_TX_BYTES, > - OVPN_GET_PEER_RESP_ATTR_RX_PACKETS, > - OVPN_GET_PEER_RESP_ATTR_TX_PACKETS, > + OVPN_GET_PEER_RESP_ATTR_VPN_RX_BYTES, > + OVPN_GET_PEER_RESP_ATTR_VPN_TX_BYTES, > + OVPN_GET_PEER_RESP_ATTR_VPN_RX_PACKETS, > + OVPN_GET_PEER_RESP_ATTR_VPN_TX_PACKETS, > + OVPN_GET_PEER_RESP_ATTR_LINK_RX_BYTES, > + OVPN_GET_PEER_RESP_ATTR_LINK_TX_BYTES, > + OVPN_GET_PEER_RESP_ATTR_LINK_RX_PACKETS, > + OVPN_GET_PEER_RESP_ATTR_LINK_TX_PACKETS, > > __OVPN_GET_PEER_RESP_ATTR_AFTER_LAST, > OVPN_GET_PEER_RESP_ATTR_MAX = __OVPN_GET_PEER_RESP_ATTR_AFTER_LAST - > 1, > -- > 2.39.2 > > > > _______________________________________________ > Openvpn-devel mailing list > Openvpn-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/openvpn-devel -- -Lev _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel