Browse code

dco_linux: factor out netlink notification code

ovpn_handle_msg() is soon becoming the main entry point for parsing
*all* incoming netlink messages. For this reason it is essential
that this function is kept simple and slim.

Move all code parsing netlink multicast notifications to their own
helpers and then invoke them.

This patch does not introduce any functional change.
It is intended in preparation for extending ovpn_handle_msg() to
become a genering netlink message parser.

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

Antonio Quartulli authored on 2025/07/24 00:32:19
Showing 1 changed files
... ...
@@ -956,6 +956,164 @@ dco_parse_peer(struct nl_msg *msg, void *arg)
956 956
     return NL_OK;
957 957
 }
958 958
 
959
+static bool
960
+ovpn_iface_check(dco_context_t *dco, struct nlattr *attrs[])
961
+{
962
+    /* we must know which interface this message is referring to in order to
963
+     * avoid mixing messages for other instances
964
+     */
965
+    if (!attrs[OVPN_A_IFINDEX])
966
+    {
967
+        msg(D_DCO, "ovpn-dco: Received message without ifindex");
968
+        return false;
969
+    }
970
+
971
+    uint32_t ifindex = nla_get_u32(attrs[OVPN_A_IFINDEX]);
972
+    if (ifindex != dco->ifindex)
973
+    {
974
+        msg(D_DCO_DEBUG,
975
+            "ovpn-dco: ignoring message for foreign ifindex %d", ifindex);
976
+        return false;
977
+    }
978
+
979
+    return true;
980
+}
981
+
982
+static int
983
+ovpn_handle_peer_del_ntf(dco_context_t *dco, struct nlattr *attrs[])
984
+{
985
+    if (!ovpn_iface_check(dco, attrs))
986
+    {
987
+        return NL_STOP;
988
+    }
989
+
990
+    if (!attrs[OVPN_A_PEER])
991
+    {
992
+        msg(D_DCO, "ovpn-dco: no peer in PEER_DEL_NTF message");
993
+        return NL_STOP;
994
+    }
995
+
996
+    struct nlattr *dp_attrs[OVPN_A_PEER_MAX + 1];
997
+    if (nla_parse_nested(dp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER],
998
+                         NULL))
999
+    {
1000
+        msg(D_DCO, "ovpn-dco: can't parse peer in PEER_DEL_NTF messsage");
1001
+        return NL_STOP;
1002
+    }
1003
+
1004
+    if (!dp_attrs[OVPN_A_PEER_DEL_REASON])
1005
+    {
1006
+        msg(D_DCO, "ovpn-dco: no reason in PEER_DEL_NTF message");
1007
+        return NL_STOP;
1008
+    }
1009
+    if (!dp_attrs[OVPN_A_PEER_ID])
1010
+    {
1011
+        msg(D_DCO, "ovpn-dco: no peer-id in PEER_DEL_NTF message");
1012
+        return NL_STOP;
1013
+    }
1014
+
1015
+    int reason = nla_get_u32(dp_attrs[OVPN_A_PEER_DEL_REASON]);
1016
+    unsigned int peerid = nla_get_u32(dp_attrs[OVPN_A_PEER_ID]);
1017
+
1018
+    msg(D_DCO_DEBUG, "ovpn-dco: received CMD_PEER_DEL_NTF, ifindex: %d, peer-id %u, reason: %d",
1019
+        dco->ifindex, peerid, reason);
1020
+    dco->dco_message_peer_id = peerid;
1021
+    dco->dco_del_peer_reason = reason;
1022
+    dco->dco_message_type = OVPN_CMD_PEER_DEL_NTF;
1023
+
1024
+    return NL_OK;
1025
+}
1026
+
1027
+static int
1028
+ovpn_handle_peer_float_ntf(dco_context_t *dco, struct nlattr *attrs[])
1029
+{
1030
+    if (!ovpn_iface_check(dco, attrs))
1031
+    {
1032
+        return NL_STOP;
1033
+    }
1034
+
1035
+    if (!attrs[OVPN_A_PEER])
1036
+    {
1037
+        msg(D_DCO, "ovpn-dco: no peer in PEER_FLOAT_NTF message");
1038
+        return NL_STOP;
1039
+    }
1040
+
1041
+    struct nlattr *fp_attrs[OVPN_A_PEER_MAX + 1];
1042
+    if (nla_parse_nested(fp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER],
1043
+                         NULL))
1044
+    {
1045
+        msg(D_DCO, "ovpn-dco: can't parse peer in PEER_FLOAT_NTF messsage");
1046
+        return NL_STOP;
1047
+    }
1048
+
1049
+    if (!fp_attrs[OVPN_A_PEER_ID])
1050
+    {
1051
+        msg(D_DCO, "ovpn-dco: no peer-id in PEER_FLOAT_NTF message");
1052
+        return NL_STOP;
1053
+    }
1054
+    uint32_t peerid = nla_get_u32(fp_attrs[OVPN_A_PEER_ID]);
1055
+
1056
+    if (!ovpn_parse_float_addr(fp_attrs, (struct sockaddr *)&dco->dco_float_peer_ss))
1057
+    {
1058
+        return NL_STOP;
1059
+    }
1060
+
1061
+    struct gc_arena gc = gc_new();
1062
+    msg(D_DCO_DEBUG,
1063
+        "ovpn-dco: received CMD_PEER_FLOAT_NTF, ifindex: %u, peer-id %u, address: %s",
1064
+        dco->ifindex, peerid, print_sockaddr((struct sockaddr *)&dco->dco_float_peer_ss, &gc));
1065
+    dco->dco_message_peer_id = (int)peerid;
1066
+    dco->dco_message_type = OVPN_CMD_PEER_FLOAT_NTF;
1067
+
1068
+    gc_free(&gc);
1069
+
1070
+    return NL_OK;
1071
+}
1072
+
1073
+static int
1074
+ovpn_handle_key_swap_ntf(dco_context_t *dco, struct nlattr *attrs[])
1075
+{
1076
+    if (!ovpn_iface_check(dco, attrs))
1077
+    {
1078
+        return NL_STOP;
1079
+    }
1080
+
1081
+    if (!attrs[OVPN_A_KEYCONF])
1082
+    {
1083
+        msg(D_DCO, "ovpn-dco: no keyconf in KEY_SWAP_NTF message");
1084
+        return NL_STOP;
1085
+    }
1086
+
1087
+    struct nlattr *dp_attrs[OVPN_A_KEYCONF_MAX + 1];
1088
+    if (nla_parse_nested(dp_attrs, OVPN_A_KEYCONF_MAX,
1089
+                         attrs[OVPN_A_KEYCONF], NULL))
1090
+    {
1091
+        msg(D_DCO, "ovpn-dco: can't parse keyconf in KEY_SWAP_NTF message");
1092
+        return NL_STOP;
1093
+    }
1094
+    if (!dp_attrs[OVPN_A_KEYCONF_PEER_ID])
1095
+    {
1096
+        msg(D_DCO, "ovpn-dco: no peer-id in KEY_SWAP_NTF message");
1097
+        return NL_STOP;
1098
+    }
1099
+    if (!dp_attrs[OVPN_A_KEYCONF_KEY_ID])
1100
+    {
1101
+        msg(D_DCO, "ovpn-dco: no key-id in KEY_SWAP_NTF message");
1102
+        return NL_STOP;
1103
+    }
1104
+
1105
+    int key_id = nla_get_u16(dp_attrs[OVPN_A_KEYCONF_KEY_ID]);
1106
+    unsigned int peer_id = nla_get_u32(dp_attrs[OVPN_A_KEYCONF_PEER_ID]);
1107
+
1108
+    msg(D_DCO_DEBUG, "ovpn-dco: received CMD_KEY_SWAP_NTF, ifindex: %d, peer-id %u, key-id: %d",
1109
+        dco->ifindex, peer_id, key_id);
1110
+    dco->dco_message_peer_id = peer_id;
1111
+    dco->dco_message_key_id = key_id;
1112
+    dco->dco_message_type = OVPN_CMD_KEY_SWAP_NTF;
1113
+
1114
+    return NL_OK;
1115
+}
1116
+
959 1117
 /* This function parses any netlink message sent by ovpn-dco to userspace */
960 1118
 static int
961 1119
 ovpn_handle_msg(struct nl_msg *msg, void *arg)
... ...
@@ -979,24 +1137,6 @@ ovpn_handle_msg(struct nl_msg *msg, void *arg)
979 979
         return NL_STOP;
980 980
     }
981 981
 
982
-    /* we must know which interface this message is referring to in order to
983
-     * avoid mixing messages for other instances
984
-     */
985
-    if (!attrs[OVPN_A_IFINDEX])
986
-    {
987
-        msg(D_DCO, "ovpn-dco: Received message without ifindex");
988
-        return NL_STOP;
989
-    }
990
-
991
-    uint32_t ifindex = nla_get_u32(attrs[OVPN_A_IFINDEX]);
992
-    if (ifindex != dco->ifindex)
993
-    {
994
-        msg(D_DCO_DEBUG,
995
-            "ovpn-dco: ignoring message (type=%d) for foreign ifindex %d",
996
-            gnlh->cmd, ifindex);
997
-        return NL_STOP;
998
-    }
999
-
1000 982
     /* based on the message type, we parse the subobject contained in the
1001 983
      * message, that stores the type-specific attributes.
1002 984
      *
... ...
@@ -1008,116 +1148,17 @@ ovpn_handle_msg(struct nl_msg *msg, void *arg)
1008 1008
     {
1009 1009
         case OVPN_CMD_PEER_DEL_NTF:
1010 1010
         {
1011
-            if (!attrs[OVPN_A_PEER])
1012
-            {
1013
-                msg(D_DCO, "ovpn-dco: no peer in PEER_DEL_NTF message");
1014
-                return NL_STOP;
1015
-            }
1016
-
1017
-            struct nlattr *dp_attrs[OVPN_A_PEER_MAX + 1];
1018
-            if (nla_parse_nested(dp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER],
1019
-                                 NULL))
1020
-            {
1021
-                msg(D_DCO, "ovpn-dco: can't parse peer in PEER_DEL_NTF messsage");
1022
-                return NL_STOP;
1023
-            }
1024
-
1025
-            if (!dp_attrs[OVPN_A_PEER_DEL_REASON])
1026
-            {
1027
-                msg(D_DCO, "ovpn-dco: no reason in PEER_DEL_NTF message");
1028
-                return NL_STOP;
1029
-            }
1030
-            if (!dp_attrs[OVPN_A_PEER_ID])
1031
-            {
1032
-                msg(D_DCO, "ovpn-dco: no peer-id in PEER_DEL_NTF message");
1033
-                return NL_STOP;
1034
-            }
1035
-
1036
-            int reason = nla_get_u32(dp_attrs[OVPN_A_PEER_DEL_REASON]);
1037
-            unsigned int peerid = nla_get_u32(dp_attrs[OVPN_A_PEER_ID]);
1038
-
1039
-            msg(D_DCO_DEBUG, "ovpn-dco: received CMD_PEER_DEL_NTF, ifindex: %d, peer-id %u, reason: %d",
1040
-                ifindex, peerid, reason);
1041
-            dco->dco_message_peer_id = peerid;
1042
-            dco->dco_del_peer_reason = reason;
1043
-            dco->dco_message_type = OVPN_CMD_PEER_DEL_NTF;
1044
-            break;
1011
+            return ovpn_handle_peer_del_ntf(dco, attrs);
1045 1012
         }
1046 1013
 
1047 1014
         case OVPN_CMD_PEER_FLOAT_NTF:
1048 1015
         {
1049
-            if (!attrs[OVPN_A_PEER])
1050
-            {
1051
-                msg(D_DCO, "ovpn-dco: no peer in PEER_FLOAT_NTF message");
1052
-                return NL_STOP;
1053
-            }
1054
-
1055
-            struct nlattr *fp_attrs[OVPN_A_PEER_MAX + 1];
1056
-            if (nla_parse_nested(fp_attrs, OVPN_A_PEER_MAX, attrs[OVPN_A_PEER],
1057
-                                 NULL))
1058
-            {
1059
-                msg(D_DCO, "ovpn-dco: can't parse peer in PEER_FLOAT_NTF messsage");
1060
-                return NL_STOP;
1061
-            }
1062
-
1063
-            if (!fp_attrs[OVPN_A_PEER_ID])
1064
-            {
1065
-                msg(D_DCO, "ovpn-dco: no peer-id in PEER_FLOAT_NTF message");
1066
-                return NL_STOP;
1067
-            }
1068
-            uint32_t peerid = nla_get_u32(fp_attrs[OVPN_A_PEER_ID]);
1069
-
1070
-            if (!ovpn_parse_float_addr(fp_attrs, (struct sockaddr *)&dco->dco_float_peer_ss))
1071
-            {
1072
-                return NL_STOP;
1073
-            }
1074
-
1075
-            struct gc_arena gc = gc_new();
1076
-            msg(D_DCO_DEBUG,
1077
-                "ovpn-dco: received CMD_PEER_FLOAT_NTF, ifindex: %u, peer-id %u, address: %s",
1078
-                ifindex, peerid, print_sockaddr((struct sockaddr *)&dco->dco_float_peer_ss, &gc));
1079
-            dco->dco_message_peer_id = (int)peerid;
1080
-            dco->dco_message_type = OVPN_CMD_PEER_FLOAT_NTF;
1081
-
1082
-            gc_free(&gc);
1083
-            break;
1016
+            return ovpn_handle_peer_float_ntf(dco, attrs);
1084 1017
         }
1085 1018
 
1086 1019
         case OVPN_CMD_KEY_SWAP_NTF:
1087 1020
         {
1088
-            if (!attrs[OVPN_A_KEYCONF])
1089
-            {
1090
-                msg(D_DCO, "ovpn-dco: no keyconf in KEY_SWAP_NTF message");
1091
-                return NL_STOP;
1092
-            }
1093
-
1094
-            struct nlattr *dp_attrs[OVPN_A_KEYCONF_MAX + 1];
1095
-            if (nla_parse_nested(dp_attrs, OVPN_A_KEYCONF_MAX,
1096
-                                 attrs[OVPN_A_KEYCONF], NULL))
1097
-            {
1098
-                msg(D_DCO, "ovpn-dco: can't parse keyconf in KEY_SWAP_NTF message");
1099
-                return NL_STOP;
1100
-            }
1101
-            if (!dp_attrs[OVPN_A_KEYCONF_PEER_ID])
1102
-            {
1103
-                msg(D_DCO, "ovpn-dco: no peer-id in KEY_SWAP_NTF message");
1104
-                return NL_STOP;
1105
-            }
1106
-            if (!dp_attrs[OVPN_A_KEYCONF_KEY_ID])
1107
-            {
1108
-                msg(D_DCO, "ovpn-dco: no key-id in KEY_SWAP_NTF message");
1109
-                return NL_STOP;
1110
-            }
1111
-
1112
-            int key_id = nla_get_u16(dp_attrs[OVPN_A_KEYCONF_KEY_ID]);
1113
-            unsigned int peer_id = nla_get_u32(dp_attrs[OVPN_A_KEYCONF_PEER_ID]);
1114
-
1115
-            msg(D_DCO_DEBUG, "ovpn-dco: received CMD_KEY_SWAP_NTF, ifindex: %d, peer-id %u, key-id: %d",
1116
-                ifindex, peer_id, key_id);
1117
-            dco->dco_message_peer_id = peer_id;
1118
-            dco->dco_message_key_id = key_id;
1119
-            dco->dco_message_type = OVPN_CMD_KEY_SWAP_NTF;
1120
-            break;
1021
+            return ovpn_handle_key_swap_ntf(dco, attrs);
1121 1022
         }
1122 1023
 
1123 1024
         default: