fi
 }
 
+start_events()
+{
+       mptcp_lib_events "${ns1}" "${evts_ns1}" evts_ns1_pid
+       mptcp_lib_events "${ns2}" "${evts_ns2}" evts_ns2_pid
+}
+
 reset_with_events()
 {
        reset "${1}" || return 1
 
-       mptcp_lib_events "${ns1}" "${evts_ns1}" evts_ns1_pid
-       mptcp_lib_events "${ns2}" "${evts_ns2}" evts_ns2_pid
+       start_events
 }
 
 reset_with_tcp_filter()
        fi
 }
 
+# $1: ns ; $2: event type ; $3: count
+chk_evt_nr()
+{
+       local ns=${1}
+       local evt_name="${2}"
+       local exp="${3}"
+
+       local evts="${evts_ns1}"
+       local evt="${!evt_name}"
+       local count
+
+       evt_name="${evt_name:16}" # without MPTCP_LIB_EVENT_
+       [ "${ns}" == "ns2" ] && evts="${evts_ns2}"
+
+       print_check "event ${ns} ${evt_name} (${exp})"
+
+       if [[ "${evt_name}" = "LISTENER_"* ]] &&
+          ! mptcp_lib_kallsyms_has "mptcp_event_pm_listener$"; then
+               print_skip "event not supported"
+               return
+       fi
+
+       count=$(grep -cw "type:${evt}" "${evts}")
+       if [ "${count}" != "${exp}" ]; then
+               fail_test "got ${count} events, expected ${exp}"
+       else
+               print_ok
+       fi
+}
+
 userspace_tests()
 {
        # userspace pm type prevents add_addr
 
        if reset_with_tcp_filter "delete and re-add" ns2 10.0.3.2 REJECT OUTPUT &&
           mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
+               start_events
                pm_nl_set_limits $ns1 0 3
                pm_nl_set_limits $ns2 0 3
                pm_nl_add_endpoint $ns2 10.0.1.2 id 1 dev ns2eth1 flags subflow
 
                mptcp_lib_kill_wait $tests_pid
 
+               kill_events_pids
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_CREATED 1
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_ESTABLISHED 1
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_ANNOUNCED 0
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_REMOVED 4
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_ESTABLISHED 6
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_CLOSED 4
+
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_CREATED 1
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_ANNOUNCED 0
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_REMOVED 0
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_ESTABLISHED 6
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 5 # one has been closed before estab
+
                chk_join_nr 6 6 6
                chk_rm_nr 4 4
        fi
 
        # remove and re-add
-       if reset "delete re-add signal" &&
+       if reset_with_events "delete re-add signal" &&
           mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
                pm_nl_set_limits $ns1 0 3
                pm_nl_set_limits $ns2 3 3
                chk_mptcp_info subflows 3 subflows 3
                mptcp_lib_kill_wait $tests_pid
 
+               kill_events_pids
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_LISTENER_CREATED 1
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_CREATED 1
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_ESTABLISHED 1
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_ANNOUNCED 0
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_REMOVED 0
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_ESTABLISHED 4
+               chk_evt_nr ns1 MPTCP_LIB_EVENT_SUB_CLOSED 2
+
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_CREATED 1
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_ESTABLISHED 1
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_ANNOUNCED 5
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_REMOVED 3
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_ESTABLISHED 4
+               chk_evt_nr ns2 MPTCP_LIB_EVENT_SUB_CLOSED 2
+
                chk_join_nr 4 4 4
                chk_add_nr 5 5
                chk_rm_nr 3 2 invert
 
 readonly KSFT_TEST="${MPTCP_LIB_KSFT_TEST:-$(basename "${0}" .sh)}"
 
 # These variables are used in some selftests, read-only
+declare -rx MPTCP_LIB_EVENT_CREATED=1           # MPTCP_EVENT_CREATED
+declare -rx MPTCP_LIB_EVENT_ESTABLISHED=2       # MPTCP_EVENT_ESTABLISHED
+declare -rx MPTCP_LIB_EVENT_CLOSED=3            # MPTCP_EVENT_CLOSED
 declare -rx MPTCP_LIB_EVENT_ANNOUNCED=6         # MPTCP_EVENT_ANNOUNCED
 declare -rx MPTCP_LIB_EVENT_REMOVED=7           # MPTCP_EVENT_REMOVED
 declare -rx MPTCP_LIB_EVENT_SUB_ESTABLISHED=10  # MPTCP_EVENT_SUB_ESTABLISHED
 declare -rx MPTCP_LIB_EVENT_SUB_CLOSED=11       # MPTCP_EVENT_SUB_CLOSED
+declare -rx MPTCP_LIB_EVENT_SUB_PRIORITY=13     # MPTCP_EVENT_SUB_PRIORITY
 declare -rx MPTCP_LIB_EVENT_LISTENER_CREATED=15 # MPTCP_EVENT_LISTENER_CREATED
 declare -rx MPTCP_LIB_EVENT_LISTENER_CLOSED=16  # MPTCP_EVENT_LISTENER_CLOSED