Thanks for suggestion, unfortunately it is a little complicate to change to that API, because it would require to change some internals from openvpn.
I did give it a try and it worked with createTCPConnection, but I see in kernel the same problem for the socked created for NWTCPConnection.
Meaning when the socket is created for NWTCPConnection by the kernel, necp matches it on the "broken" rule, and it is bound to utun interface, but later when it is into the connected state it is bound to en0 interface. So what I think it happens, maybe I'm wrong, createTCPConnection creates the socket with the utun interface because necp, and then createTCPConnection internally bounds it to the en0 interface. Because the socket is created in NE app and cannot be bound to utun interface.
Bellow is the match policy (I'm connecting on a remote server on port 80):
error 15:32:36.187216+0100 kernel necp_socket_find_policy_match_with_info_locked: DATA-TRACE <SOCKET>: EXAMINING - policy id=16174 session_order=2002 policy_order=10806 result=IP_TUNNEL (cond_policy_id 0)
error 15:32:36.187220+0100 kernel necp_socket_check_policy: DATA-TRACE <SOCKET>: ------ matching <NECP_KERNEL_CONDITION_BOUND_INTERFACE> <value (22 / 0x16) (0 / 0x0) (0 / 0x0) input (22 / 0x16) (0 / 0x0) (0 / 0x0)>
error 15:32:36.187223+0100 kernel necp_socket_check_policy: DATA-TRACE <SOCKET>: ------ matching <NECP_KERNEL_CONDITION_APP_ID> <value (66373 / 0x10345) (0 / 0x0) (0 / 0x0) input (66373 / 0x10345) (0 / 0x0) (0 / 0x0)>
error 15:32:36.187227+0100 kernel necp_socket_check_policy: DATA-TRACE <SOCKET>: ------ matching <NECP_KERNEL_CONDITION_PID> <value (45946 / 0xB37A) (0 / 0x0) (0 / 0x0) input (45946 / 0xB37A) (0 / 0x0) (0 / 0x0)>
error 15:32:36.187231+0100 kernel necp_socket_find_policy_match_with_info_locked: DATA-TRACE <SOCKET 0>: MATCHED POLICY - proto 6 port <local 59836/59836 remote 80/80> <drop-all order 11001> <pid=45946 Application 66373 Real Application 0 BoundInterface 22> (policy id=16174 session_order=2002 policy_order=10806 result=IP_TUNNEL)
thanks again for the suggestion. I would have used it, but we have too many 3rd party libraries, not only openvpn, that work with sockets.