diff --git a/private/bpfloader.te b/private/bpfloader.te
index c0b4999824e428bc9c634bbb42c371fea499fbe8..e6902316d62a4dd020af14b0c492ecf1ae5b677f 100644
--- a/private/bpfloader.te
+++ b/private/bpfloader.te
@@ -21,7 +21,7 @@ allow bpfloader self:bpf { prog_load prog_run };
 
 # Neverallow rules
 neverallow { domain -bpfloader } *:bpf prog_load;
-neverallow { domain -bpfloader -netd } *:bpf prog_run;
+neverallow { domain -bpfloader -netd -netutils_wrapper} *:bpf prog_run;
 neverallow { domain -netd -bpfloader } bpfloader_exec:file { execute execute_no_trans };
 neverallow bpfloader domain:{ tcp_socket udp_socket rawip_socket } *;
 # only system_server, netd and bpfloader can read/write the bpf maps
diff --git a/private/netutils_wrapper.te b/private/netutils_wrapper.te
index 9a5697e36a3679e734818d5ec849312d9eb75a26..f56e8d8618f8cb267938a882f1d6925caee6af31 100644
--- a/private/netutils_wrapper.te
+++ b/private/netutils_wrapper.te
@@ -18,6 +18,13 @@ allow netutils_wrapper self:netlink_xfrm_socket ~ioctl;
 allow netutils_wrapper netd_socket:sock_file { open getattr read write append };
 allow netutils_wrapper netd:unix_stream_socket { read getattr connectto };
 
+# For vendor code that update the iptables rules at runtime. They need to reload
+# the whole chain including the xt_bpf rules. They need to access to the pinned
+# program when reloading the rule.
+allow netutils_wrapper fs_bpf:dir search;
+allow netutils_wrapper fs_bpf:file { read write };
+allow netutils_wrapper bpfloader:bpf prog_run;
+
 # For /data/misc/net access to ndc and ip
 r_dir_file(netutils_wrapper, net_data_file)