Browse code

dco_linux: rearrange functions

In preparation for the implementation of a generic netlink
message parser, move all parsing functions above ovpn_handle_msg().

The latter is soon going to become a generic message parser which
will invoke specific handlers, thus they are required to be defined
earlier in the file.

No functional change is intended.

This patch is only meant to reduce entropy in the patch which will do
the real netlink parser change.

Better reviewed with: git show --color-moved

Change-Id: I94004579aef4a1ccccdbcf8edd7b722e5a611c72
Signed-off-by: Antonio Quartulli <antonio@mandelbit.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20250723060747.19524-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg32263.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Antonio Quartulli authored on 2025/07/23 15:07:41
Showing 1 changed files
... ...
@@ -806,6 +806,150 @@ ovpn_parse_float_addr(struct nlattr **attrs, struct sockaddr *out)
806 806
     return false;
807 807
 }
808 808
 
809
+/* libnl < 3.11.0 does not implement nla_get_uint() */
810
+static uint64_t
811
+ovpn_nla_get_uint(struct nlattr *attr)
812
+{
813
+    if (nla_len(attr) == sizeof(uint32_t))
814
+    {
815
+        return nla_get_u32(attr);
816
+    }
817
+    else
818
+    {
819
+        return nla_get_u64(attr);
820
+    }
821
+}
822
+
823
+static void
824
+dco_update_peer_stat(struct context_2 *c2, struct nlattr *tb[], uint32_t id)
825
+{
826
+    if (tb[OVPN_A_PEER_LINK_RX_BYTES])
827
+    {
828
+        c2->dco_read_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_LINK_RX_BYTES]);
829
+        msg(D_DCO_DEBUG, "%s / dco_read_bytes: " counter_format, __func__,
830
+            c2->dco_read_bytes);
831
+    }
832
+    else
833
+    {
834
+        msg(M_WARN, "%s: no link RX bytes provided in reply for peer %u",
835
+            __func__, id);
836
+    }
837
+
838
+    if (tb[OVPN_A_PEER_LINK_TX_BYTES])
839
+    {
840
+        c2->dco_write_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_LINK_TX_BYTES]);
841
+        msg(D_DCO_DEBUG, "%s / dco_write_bytes: " counter_format, __func__,
842
+            c2->dco_write_bytes);
843
+    }
844
+    else
845
+    {
846
+        msg(M_WARN, "%s: no link TX bytes provided in reply for peer %u",
847
+            __func__, id);
848
+    }
849
+
850
+    if (tb[OVPN_A_PEER_VPN_RX_BYTES])
851
+    {
852
+        c2->tun_read_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_VPN_RX_BYTES]);
853
+        msg(D_DCO_DEBUG, "%s / tun_read_bytes: " counter_format, __func__,
854
+            c2->tun_read_bytes);
855
+    }
856
+    else
857
+    {
858
+        msg(M_WARN, "%s: no VPN RX bytes provided in reply for peer %u",
859
+            __func__, id);
860
+    }
861
+
862
+    if (tb[OVPN_A_PEER_VPN_TX_BYTES])
863
+    {
864
+        c2->tun_write_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_VPN_TX_BYTES]);
865
+        msg(D_DCO_DEBUG, "%s / tun_write_bytes: " counter_format, __func__,
866
+            c2->tun_write_bytes);
867
+    }
868
+    else
869
+    {
870
+        msg(M_WARN, "%s: no VPN TX bytes provided in reply for peer %u",
871
+            __func__, id);
872
+    }
873
+}
874
+
875
+static int
876
+dco_parse_peer_multi(struct nl_msg *msg, void *arg)
877
+{
878
+    struct nlattr *tb[OVPN_A_MAX + 1];
879
+    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
880
+
881
+    msg(D_DCO_DEBUG, "%s: parsing message...", __func__);
882
+
883
+    nla_parse(tb, OVPN_A_MAX, genlmsg_attrdata(gnlh, 0),
884
+              genlmsg_attrlen(gnlh, 0), NULL);
885
+
886
+    if (!tb[OVPN_A_PEER])
887
+    {
888
+        return NL_SKIP;
889
+    }
890
+
891
+    struct nlattr *tb_peer[OVPN_A_PEER_MAX + 1];
892
+    nla_parse_nested(tb_peer, OVPN_A_PEER_MAX, tb[OVPN_A_PEER], NULL);
893
+
894
+    if (!tb_peer[OVPN_A_PEER_ID])
895
+    {
896
+        msg(M_WARN, "%s: no peer-id provided in reply", __func__);
897
+        return NL_SKIP;
898
+    }
899
+
900
+    struct multi_context *m = arg;
901
+    uint32_t peer_id = nla_get_u32(tb_peer[OVPN_A_PEER_ID]);
902
+
903
+    if (peer_id >= m->max_clients || !m->instances[peer_id])
904
+    {
905
+        msg(M_WARN, "%s: cannot store DCO stats for peer %u", __func__,
906
+            peer_id);
907
+        return NL_SKIP;
908
+    }
909
+
910
+    dco_update_peer_stat(&m->instances[peer_id]->context.c2, tb_peer, peer_id);
911
+
912
+    return NL_OK;
913
+}
914
+
915
+static int
916
+dco_parse_peer(struct nl_msg *msg, void *arg)
917
+{
918
+    struct context *c = arg;
919
+    struct nlattr *tb[OVPN_A_MAX + 1];
920
+    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
921
+
922
+    msg(D_DCO_DEBUG, "%s: parsing message...", __func__);
923
+
924
+    nla_parse(tb, OVPN_A_MAX, genlmsg_attrdata(gnlh, 0),
925
+              genlmsg_attrlen(gnlh, 0), NULL);
926
+
927
+    if (!tb[OVPN_A_PEER])
928
+    {
929
+        msg(D_DCO_DEBUG, "%s: malformed reply", __func__);
930
+        return NL_SKIP;
931
+    }
932
+
933
+    struct nlattr *tb_peer[OVPN_A_PEER_MAX + 1];
934
+    nla_parse_nested(tb_peer, OVPN_A_PEER_MAX, tb[OVPN_A_PEER], NULL);
935
+
936
+    if (!tb_peer[OVPN_A_PEER_ID])
937
+    {
938
+        msg(M_WARN, "%s: no peer-id provided in reply", __func__);
939
+        return NL_SKIP;
940
+    }
941
+
942
+    uint32_t peer_id = nla_get_u32(tb_peer[OVPN_A_PEER_ID]);
943
+    if (c->c2.tls_multi->dco_peer_id != peer_id)
944
+    {
945
+        return NL_SKIP;
946
+    }
947
+
948
+    dco_update_peer_stat(&c->c2, tb_peer, peer_id);
949
+
950
+    return NL_OK;
951
+}
952
+
809 953
 /* This function parses any netlink message sent by ovpn-dco to userspace */
810 954
 static int
811 955
 ovpn_handle_msg(struct nl_msg *msg, void *arg)
... ...
@@ -988,112 +1132,6 @@ dco_do_read(dco_context_t *dco)
988 988
     return ovpn_nl_recvmsgs(dco, __func__);
989 989
 }
990 990
 
991
-/* libnl < 3.11.0 does not implement nla_get_uint() */
992
-static uint64_t
993
-ovpn_nla_get_uint(struct nlattr *attr)
994
-{
995
-    if (nla_len(attr) == sizeof(uint32_t))
996
-    {
997
-        return nla_get_u32(attr);
998
-    }
999
-    else
1000
-    {
1001
-        return nla_get_u64(attr);
1002
-    }
1003
-}
1004
-
1005
-static void
1006
-dco_update_peer_stat(struct context_2 *c2, struct nlattr *tb[], uint32_t id)
1007
-{
1008
-    if (tb[OVPN_A_PEER_LINK_RX_BYTES])
1009
-    {
1010
-        c2->dco_read_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_LINK_RX_BYTES]);
1011
-        msg(D_DCO_DEBUG, "%s / dco_read_bytes: " counter_format, __func__,
1012
-            c2->dco_read_bytes);
1013
-    }
1014
-    else
1015
-    {
1016
-        msg(M_WARN, "%s: no link RX bytes provided in reply for peer %u",
1017
-            __func__, id);
1018
-    }
1019
-
1020
-    if (tb[OVPN_A_PEER_LINK_TX_BYTES])
1021
-    {
1022
-        c2->dco_write_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_LINK_TX_BYTES]);
1023
-        msg(D_DCO_DEBUG, "%s / dco_write_bytes: " counter_format, __func__,
1024
-            c2->dco_write_bytes);
1025
-    }
1026
-    else
1027
-    {
1028
-        msg(M_WARN, "%s: no link TX bytes provided in reply for peer %u",
1029
-            __func__, id);
1030
-    }
1031
-
1032
-    if (tb[OVPN_A_PEER_VPN_RX_BYTES])
1033
-    {
1034
-        c2->tun_read_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_VPN_RX_BYTES]);
1035
-        msg(D_DCO_DEBUG, "%s / tun_read_bytes: " counter_format, __func__,
1036
-            c2->tun_read_bytes);
1037
-    }
1038
-    else
1039
-    {
1040
-        msg(M_WARN, "%s: no VPN RX bytes provided in reply for peer %u",
1041
-            __func__, id);
1042
-    }
1043
-
1044
-    if (tb[OVPN_A_PEER_VPN_TX_BYTES])
1045
-    {
1046
-        c2->tun_write_bytes = ovpn_nla_get_uint(tb[OVPN_A_PEER_VPN_TX_BYTES]);
1047
-        msg(D_DCO_DEBUG, "%s / tun_write_bytes: " counter_format, __func__,
1048
-            c2->tun_write_bytes);
1049
-    }
1050
-    else
1051
-    {
1052
-        msg(M_WARN, "%s: no VPN TX bytes provided in reply for peer %u",
1053
-            __func__, id);
1054
-    }
1055
-}
1056
-
1057
-int
1058
-dco_parse_peer_multi(struct nl_msg *msg, void *arg)
1059
-{
1060
-    struct nlattr *tb[OVPN_A_MAX + 1];
1061
-    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1062
-
1063
-    msg(D_DCO_DEBUG, "%s: parsing message...", __func__);
1064
-
1065
-    nla_parse(tb, OVPN_A_MAX, genlmsg_attrdata(gnlh, 0),
1066
-              genlmsg_attrlen(gnlh, 0), NULL);
1067
-
1068
-    if (!tb[OVPN_A_PEER])
1069
-    {
1070
-        return NL_SKIP;
1071
-    }
1072
-
1073
-    struct nlattr *tb_peer[OVPN_A_PEER_MAX + 1];
1074
-    nla_parse_nested(tb_peer, OVPN_A_PEER_MAX, tb[OVPN_A_PEER], NULL);
1075
-
1076
-    if (!tb_peer[OVPN_A_PEER_ID])
1077
-    {
1078
-        msg(M_WARN, "%s: no peer-id provided in reply", __func__);
1079
-        return NL_SKIP;
1080
-    }
1081
-
1082
-    struct multi_context *m = arg;
1083
-    uint32_t peer_id = nla_get_u32(tb_peer[OVPN_A_PEER_ID]);
1084
-
1085
-    if (peer_id >= m->max_clients || !m->instances[peer_id])
1086
-    {
1087
-        msg(M_WARN, "%s: cannot store DCO stats for peer %u", __func__,
1088
-            peer_id);
1089
-        return NL_SKIP;
1090
-    }
1091
-
1092
-    dco_update_peer_stat(&m->instances[peer_id]->context.c2, tb_peer, peer_id);
1093
-
1094
-    return NL_OK;
1095
-}
1096
-
1097 991
 int
1098 992
 dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m,
1099 993
                          const bool raise_sigusr1_on_err)
... ...
@@ -1118,44 +1156,6 @@ dco_get_peer_stats_multi(dco_context_t *dco, struct multi_context *m,
1118 1118
     return ret;
1119 1119
 }
1120 1120
 
1121
-static int
1122
-dco_parse_peer(struct nl_msg *msg, void *arg)
1123
-{
1124
-    struct context *c = arg;
1125
-    struct nlattr *tb[OVPN_A_MAX + 1];
1126
-    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1127
-
1128
-    msg(D_DCO_DEBUG, "%s: parsing message...", __func__);
1129
-
1130
-    nla_parse(tb, OVPN_A_MAX, genlmsg_attrdata(gnlh, 0),
1131
-              genlmsg_attrlen(gnlh, 0), NULL);
1132
-
1133
-    if (!tb[OVPN_A_PEER])
1134
-    {
1135
-        msg(D_DCO_DEBUG, "%s: malformed reply", __func__);
1136
-        return NL_SKIP;
1137
-    }
1138
-
1139
-    struct nlattr *tb_peer[OVPN_A_PEER_MAX + 1];
1140
-    nla_parse_nested(tb_peer, OVPN_A_PEER_MAX, tb[OVPN_A_PEER], NULL);
1141
-
1142
-    if (!tb_peer[OVPN_A_PEER_ID])
1143
-    {
1144
-        msg(M_WARN, "%s: no peer-id provided in reply", __func__);
1145
-        return NL_SKIP;
1146
-    }
1147
-
1148
-    uint32_t peer_id = nla_get_u32(tb_peer[OVPN_A_PEER_ID]);
1149
-    if (c->c2.tls_multi->dco_peer_id != peer_id)
1150
-    {
1151
-        return NL_SKIP;
1152
-    }
1153
-
1154
-    dco_update_peer_stat(&c->c2, tb_peer, peer_id);
1155
-
1156
-    return NL_OK;
1157
-}
1158
-
1159 1121
 int
1160 1122
 dco_get_peer_stats(struct context *c, const bool raise_sigusr1_on_err)
1161 1123
 {