diff --git a/luci-app-openmptcprouter/luasrc/view/openmptcprouter/wizard.htm b/luci-app-openmptcprouter/luasrc/view/openmptcprouter/wizard.htm
index c465ff932..48a7bbba9 100755
--- a/luci-app-openmptcprouter/luasrc/view/openmptcprouter/wizard.htm
+++ b/luci-app-openmptcprouter/luasrc/view/openmptcprouter/wizard.htm
@@ -241,7 +241,7 @@
- <%:Set the default Proxy used for TCP when ShadowSocks is enabled, for TCP and UDP when V2Ray VLESS or VMESS is enabled.%>
+ <%:Set the default Proxy used for TCP when ShadowSocks is enabled, for TCP and UDP when V2Ray VLESS, VMESS or Trojan is enabled.%>
<%:Only ShadowSocks is supported with server multiple IPs for now.%>
diff --git a/netifd/Makefile b/netifd/Makefile
new file mode 100755
index 000000000..808432756
--- /dev/null
+++ b/netifd/Makefile
@@ -0,0 +1,49 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=netifd
+PKG_RELEASE:=3
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git
+PKG_SOURCE_DATE:=2023-08-31
+PKG_SOURCE_VERSION:=1a07f1dff32b3af49e39533e33e8964b59535662
+PKG_MIRROR_HASH:=dc621dd04c3c9631002f929cf10a4620f57af8b0baf614c590bda17957fa6201
+PKG_MAINTAINER:=Felix Fietkau
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=
+
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/netifd
+ SECTION:=base
+ CATEGORY:=Base system
+ DEPENDS:=+libuci +libnl-tiny +libubus +ubus +ubusd +jshn +libubox
+ TITLE:=OpenWrt Network Interface Configuration Daemon
+endef
+
+define Package/netifd/conffiles
+/etc/udhcpc.user
+/etc/udhcpc.user.d/
+endef
+
+TARGET_CFLAGS += \
+ -I$(STAGING_DIR)/usr/include/libnl-tiny \
+ -I$(STAGING_DIR)/usr/include
+
+CMAKE_OPTIONS += \
+ -DLIBNL_LIBS=-lnl-tiny \
+ -DDEBUG=1
+
+define Package/netifd/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/netifd $(1)/sbin/
+ $(CP) ./files/* $(1)/
+ $(INSTALL_DIR) $(1)/etc/udhcpc.user.d/
+ $(CP) $(PKG_BUILD_DIR)/scripts/* $(1)/lib/netifd/
+endef
+
+$(eval $(call BuildPackage,netifd))
diff --git a/netifd/files/etc/init.d/packet_steering b/netifd/files/etc/init.d/packet_steering
new file mode 100755
index 000000000..9d8f791e2
--- /dev/null
+++ b/netifd/files/etc/init.d/packet_steering
@@ -0,0 +1,18 @@
+#!/bin/sh /etc/rc.common
+
+START=25
+USE_PROCD=1
+
+start_service() {
+ reload_service
+}
+
+service_triggers() {
+ procd_add_reload_trigger "network"
+ procd_add_reload_trigger "firewall"
+ procd_add_raw_trigger "interface.*" 1000 /etc/init.d/packet_steering reload
+}
+
+reload_service() {
+ /usr/libexec/network/packet-steering.sh
+}
diff --git a/netifd/files/lib/netifd/dhcp.script b/netifd/files/lib/netifd/dhcp.script
new file mode 100755
index 000000000..02a95dd76
--- /dev/null
+++ b/netifd/files/lib/netifd/dhcp.script
@@ -0,0 +1,121 @@
+#!/bin/sh
+[ -z "$1" ] && echo "Error: should be run by udhcpc" && exit 1
+
+. /lib/functions.sh
+. /lib/netifd/netifd-proto.sh
+
+set_classless_routes() {
+ local max=128
+ while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do
+ proto_add_ipv4_route "${1%%/*}" "${1##*/}" "$2" "$ip"
+ max=$(($max-1))
+ shift 2
+ done
+}
+
+setup_interface() {
+ proto_init_update "*" 1
+ proto_add_ipv4_address "$ip" "${subnet:-255.255.255.0}"
+ # TODO: apply $broadcast
+
+ local ip_net
+ eval "$(ipcalc.sh "$ip/$mask")";ip_net="$NETWORK"
+
+ local i
+ for i in $router; do
+ local gw_net
+ eval "$(ipcalc.sh "$i/$mask")";gw_net="$NETWORK"
+
+ [ "$ip_net" != "$gw_net" ] && proto_add_ipv4_route "$i" 32 "" "$ip"
+ #[ "$DEFAULTROUTE" = 0 ] || proto_add_ipv4_route 0.0.0.0 0 "$i" "$ip"
+ proto_add_ipv4_route 0.0.0.0 0 "$i" "$ip"
+
+ local r
+ for r in $CUSTOMROUTES; do
+ proto_add_ipv4_route "${r%%/*}" "${r##*/}" "$i" "$ip"
+ done
+ done
+
+ # CIDR STATIC ROUTES (rfc3442)
+ [ -n "$staticroutes" ] && set_classless_routes $staticroutes
+ [ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes
+
+ for i in $dns; do
+ proto_add_dns_server "$i"
+ done
+ for i in $domain; do
+ proto_add_dns_search "$i"
+ done
+
+ # TODO: Deprecate timesvr in favor of timesrv
+ if [ -n "$timesvr" -a -z "$timesrv" ]; then
+ timesrv="$timesvr"
+ echo "Environment variable 'timesvr' will be deprecated; use 'timesrv' instead."
+ fi
+
+ proto_add_data
+ [ -n "$ZONE" ] && json_add_string zone "$ZONE"
+ [ -n "$ntpsrv" ] && json_add_string ntpserver "$ntpsrv"
+ [ -n "$timesrv" ] && json_add_string timeserver "$timesrv"
+ [ -n "$hostname" ] && json_add_string hostname "$hostname"
+ [ -n "$message" ] && json_add_string message "$message"
+ [ -n "$timezone" ] && json_add_int timezone "$timezone"
+ [ -n "$lease" ] && json_add_int leasetime "$lease"
+ [ -n "$serverid" ] && json_add_string dhcpserver "$serverid"
+ proto_close_data
+
+ proto_send_update "$INTERFACE"
+
+
+ if [ "$IFACE6RD" != 0 -a -n "$ip6rd" ]; then
+ local v4mask="${ip6rd%% *}"
+ ip6rd="${ip6rd#* }"
+ local ip6rdprefixlen="${ip6rd%% *}"
+ ip6rd="${ip6rd#* }"
+ local ip6rdprefix="${ip6rd%% *}"
+ ip6rd="${ip6rd#* }"
+ local ip6rdbr="${ip6rd%% *}"
+
+ [ -n "$ZONE" ] || ZONE=$(fw3 -q network $INTERFACE 2>/dev/null)
+ [ -z "$IFACE6RD" -o "$IFACE6RD" = 1 ] && IFACE6RD=${INTERFACE}_6
+
+ json_init
+ json_add_string name "$IFACE6RD"
+ json_add_string ifname "@$INTERFACE"
+ json_add_string proto "6rd"
+ json_add_string peeraddr "$ip6rdbr"
+ json_add_int ip4prefixlen "$v4mask"
+ json_add_string ip6prefix "$ip6rdprefix"
+ json_add_int ip6prefixlen "$ip6rdprefixlen"
+ json_add_string tunlink "$INTERFACE"
+ [ -n "$IFACE6RD_DELEGATE" ] && json_add_boolean delegate "$IFACE6RD_DELEGATE"
+ [ -n "$ZONE6RD" ] || ZONE6RD=$ZONE
+ [ -n "$ZONE6RD" ] && json_add_string zone "$ZONE6RD"
+ [ -n "$MTU6RD" ] && json_add_string mtu "$MTU6RD"
+ json_close_object
+
+ ubus call network add_dynamic "$(json_dump)"
+ fi
+}
+
+deconfig_interface() {
+ proto_init_update "*" 0
+ proto_send_update "$INTERFACE"
+}
+
+case "$1" in
+ deconfig)
+ deconfig_interface
+ ;;
+ renew|bound)
+ setup_interface
+ ;;
+esac
+
+# user rules
+[ -f /etc/udhcpc.user ] && . /etc/udhcpc.user "$@"
+for f in /etc/udhcpc.user.d/*; do
+ [ -f "$f" ] && (. "$f" "$@")
+done
+
+exit 0
diff --git a/netifd/files/lib/netifd/proto/dhcp.sh b/netifd/files/lib/netifd/proto/dhcp.sh
new file mode 100755
index 000000000..0771d8a05
--- /dev/null
+++ b/netifd/files/lib/netifd/proto/dhcp.sh
@@ -0,0 +1,89 @@
+#!/bin/sh
+
+[ -x /sbin/udhcpc ] || exit 0
+
+. /lib/functions.sh
+. ../netifd-proto.sh
+init_proto "$@"
+
+proto_dhcp_init_config() {
+ renew_handler=1
+
+ proto_config_add_string 'ipaddr:ipaddr'
+ proto_config_add_string 'hostname:hostname'
+ proto_config_add_string clientid
+ proto_config_add_string vendorid
+ proto_config_add_boolean 'broadcast:bool'
+ proto_config_add_boolean 'norelease:bool'
+ proto_config_add_string 'reqopts:list(string)'
+ proto_config_add_boolean 'defaultreqopts:bool'
+ proto_config_add_string iface6rd
+ proto_config_add_array 'sendopts:list(string)'
+ proto_config_add_boolean delegate
+ proto_config_add_string zone6rd
+ proto_config_add_string zone
+ proto_config_add_string mtu6rd
+ proto_config_add_string customroutes
+ proto_config_add_boolean classlessroute
+}
+
+proto_dhcp_add_sendopts() {
+ [ -n "$1" ] && append "$3" "-x $1"
+}
+
+proto_dhcp_setup() {
+ local config="$1"
+ local iface="$2"
+
+ local ipaddr hostname clientid vendorid broadcast norelease reqopts defaultreqopts iface6rd sendopts delegate zone6rd zone mtu6rd customroutes classlessroute defaultroute
+ json_get_vars ipaddr hostname clientid vendorid broadcast norelease reqopts defaultreqopts iface6rd delegate zone6rd zone mtu6rd customroutes classlessroute defaultroute
+
+ local opt dhcpopts
+ for opt in $reqopts; do
+ append dhcpopts "-O $opt"
+ done
+
+ json_for_each_item proto_dhcp_add_sendopts sendopts dhcpopts
+
+ [ -z "$hostname" ] && hostname="$(cat /proc/sys/kernel/hostname)"
+ [ "$hostname" = "*" ] && hostname=
+
+ [ "$defaultreqopts" = 0 ] && defaultreqopts="-o" || defaultreqopts=
+ [ "$broadcast" = 1 ] && broadcast="-B" || broadcast=
+ [ "$norelease" = 1 ] && norelease="" || norelease="-R"
+ [ -n "$clientid" ] && clientid="-x 0x3d:${clientid//:/}" || clientid="-C"
+ [ -n "$iface6rd" ] && proto_export "IFACE6RD=$iface6rd"
+ [ "$iface6rd" != 0 -a -f /lib/netifd/proto/6rd.sh ] && append dhcpopts "-O 212"
+ [ -n "$zone6rd" ] && proto_export "ZONE6RD=$zone6rd"
+ [ -n "$zone" ] && proto_export "ZONE=$zone"
+ [ -n "$mtu6rd" ] && proto_export "MTU6RD=$mtu6rd"
+ [ -n "$customroutes" ] && proto_export "CUSTOMROUTES=$customroutes"
+ [ -n "$defaultroute" ] && proto_export "DEFAULTROUTE=$defaultroute"
+ [ "$delegate" = "0" ] && proto_export "IFACE6RD_DELEGATE=0"
+ # Request classless route option (see RFC 3442) by default
+ [ "$classlessroute" = "0" ] || append dhcpopts "-O 121"
+
+ proto_export "INTERFACE=$config"
+ proto_run_command "$config" udhcpc \
+ -p /var/run/udhcpc-$iface.pid \
+ -s /lib/netifd/dhcp.script \
+ -f -t 0 -i "$iface" \
+ ${ipaddr:+-r ${ipaddr/\/*/}} \
+ ${hostname:+-x "hostname:$hostname"} \
+ ${vendorid:+-V "$vendorid"} \
+ $clientid $defaultreqopts $broadcast $norelease $dhcpopts
+}
+
+proto_dhcp_renew() {
+ local interface="$1"
+ # SIGUSR1 forces udhcpc to renew its lease
+ local sigusr1="$(kill -l SIGUSR1)"
+ [ -n "$sigusr1" ] && proto_kill_command "$interface" $sigusr1
+}
+
+proto_dhcp_teardown() {
+ local interface="$1"
+ proto_kill_command "$interface"
+}
+
+add_protocol dhcp
diff --git a/netifd/files/usr/libexec/network/packet-steering.sh b/netifd/files/usr/libexec/network/packet-steering.sh
new file mode 100755
index 000000000..799c08080
--- /dev/null
+++ b/netifd/files/usr/libexec/network/packet-steering.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+NPROCS="$(grep -c "^processor.*:" /proc/cpuinfo)"
+[ "$NPROCS" -gt 1 ] || exit
+
+PROC_MASK="$(( (1 << $NPROCS) - 1 ))"
+
+find_irq_cpu() {
+ local dev="$1"
+ local match="$(grep -m 1 "$dev\$" /proc/interrupts)"
+ local cpu=0
+
+ [ -n "$match" ] && {
+ set -- $match
+ shift
+ for cur in $(seq 1 $NPROCS); do
+ [ "$1" -gt 0 ] && {
+ cpu=$(($cur - 1))
+ break
+ }
+ shift
+ done
+ }
+
+ echo "$cpu"
+}
+
+set_hex_val() {
+ local file="$1"
+ local val="$2"
+ val="$(printf %x "$val")"
+ [ -n "$DEBUG" ] && echo "$file = $val"
+ echo "$val" > "$file"
+}
+
+packet_steering="$(uci get "network.@globals[0].packet_steering")"
+[ "$packet_steering" != 1 ] && exit 0
+
+exec 512>/var/lock/smp_tune.lock
+flock 512 || exit 1
+
+[ -e "/usr/libexec/platform/packet-steering.sh" ] && {
+ /usr/libexec/platform/packet-steering.sh
+ exit 0
+}
+
+for dev in /sys/class/net/*; do
+ [ -d "$dev" ] || continue
+
+ # ignore virtual interfaces
+ [ -n "$(ls "${dev}/" | grep '^lower_')" ] && continue
+ [ -d "${dev}/device" ] || continue
+
+ device="$(readlink "${dev}/device")"
+ device="$(basename "$device")"
+ irq_cpu="$(find_irq_cpu "$device")"
+ irq_cpu_mask="$((1 << $irq_cpu))"
+
+ for q in ${dev}/queues/tx-*; do
+ set_hex_val "$q/xps_cpus" "$PROC_MASK"
+ done
+
+ # ignore dsa slave ports for RPS
+ subsys="$(readlink "${dev}/device/subsystem")"
+ subsys="$(basename "$subsys")"
+ [ "$subsys" = "mdio_bus" ] && continue
+
+ for q in ${dev}/queues/rx-*; do
+ set_hex_val "$q/rps_cpus" "$PROC_MASK"
+ done
+done
diff --git a/v2ray-core/files/etc/init.d/v2ray b/v2ray-core/files/etc/init.d/v2ray
index 1c122c897..7adbfa052 100755
--- a/v2ray-core/files/etc/init.d/v2ray
+++ b/v2ray-core/files/etc/init.d/v2ray
@@ -448,7 +448,7 @@ add_v2ray_redirect_rules() {
v2ray-rules -f
#logger -t "v2ray" "v2ray-rules -l ${port} -L ${port} -s $OUTBOUND_SERVERS_V4 --rule-name def --src-default forward --dst-default forward --local-default forward"
commandline="-l ${port} -s $OUTBOUND_SERVERS_V4 --rule-name def --src-default forward --dst-default forward --local-default forward"
- [ "$(uci -q get v2ray.main_transparent_proxy.redirect_udp)" = "1" ] && ([ "$(uci -q get v2ray.omrout.protocol)" = "vless" ] || [ "$(uci -q get v2ray.omrout.protocol)" = "vmess" ]) && commandline="$commandline -L ${port}"
+ [ "$(uci -q get v2ray.main_transparent_proxy.redirect_udp)" = "1" ] && [ "$(uci -q get v2ray.omrout.protocol)" != "socks" ] && commandline="$commandline -L ${port}"
v2ray-rules $commandline
[ "$(uci -q get v2ray.main.inbounds | grep omr6)" != "" ] && [ -n "$OUTBOUND_SERVERS_V6" ] && {
v2ray-rules6 -f
@@ -1885,7 +1885,7 @@ init_transparent_proxy() {
TRANSPARENT_PROXY_PORT="$redirect_port"
TRANSPARENT_PROXY_USE_TPROXY="$use_tproxy"
- if [ "x$redirect_udp" = "x1" ] && [ "$(uci -q get v2ray.omrout.protocol)" != "trojan" ] && [ "$(uci -q get v2ray.omrout.protocol)" != "socks" ]; then
+ if [ "x$redirect_udp" = "x1" ] && [ "$(uci -q get v2ray.omrout.protocol)" != "socks" ]; then
TRANSPARENT_PROXY_ADDITION="udp"
elif [ "x$redirect_dns" = "x1" ] ; then
TRANSPARENT_PROXY_ADDITION="dns"
diff --git a/v2ray-core/files/etc/uci-defaults/3010-omr-v2ray b/v2ray-core/files/etc/uci-defaults/3010-omr-v2ray
index e72351856..df545a5b6 100755
--- a/v2ray-core/files/etc/uci-defaults/3010-omr-v2ray
+++ b/v2ray-core/files/etc/uci-defaults/3010-omr-v2ray
@@ -6,7 +6,7 @@ if [ -z "$(uci -q get v2ray.main)" ]; then
set v2ray.main=v2ray
set v2ray.main.v2ray_file='/usr/bin/v2ray'
set v2ray.main.mem_percentage='0'
- set v2ray.main.loglevel='debug'
+ set v2ray.main.loglevel='error'
set v2ray.main.access_log='/dev/null'
set v2ray.main.error_log='/dev/null'
set v2ray.main.enabled='0'
@@ -30,7 +30,7 @@ if [ -z "$(uci -q get v2ray.main)" ]; then
set v2ray.main_transparent_proxy.proxy_mode='default'
set v2ray.main_transparent_proxy.apnic_delegated_mirror='apnic'
set v2ray.main_transparent_proxy.gfwlist_mirror='github'
- set v2ray.main_transparent_proxy.redirect_udp='1'
+ set v2ray.main_transparent_proxy.redirect_udp='0'
set v2ray.main_transparent_proxy.redirect_port='1897'
set v2ray.omrout=outbound
set v2ray.omrout.tag='omrout_tunnel'
@@ -197,5 +197,4 @@ if [ "$(uci -q get v2ray.omrout.s_socks_port)" = "" ]; then
EOF
fi
-fi
exit 0
\ No newline at end of file
diff --git a/v2ray-core/patches/add-mptcp-support.patch b/v2ray-core/patches/add-mptcp-support.patch
index 4878679da..85ba7a316 100644
--- a/v2ray-core/patches/add-mptcp-support.patch
+++ b/v2ray-core/patches/add-mptcp-support.patch
@@ -2444,7 +2444,7 @@ index 729899015..41f70be7b 100644
+ if x != nil {
+ return x.Mptcp
+ }
-+ return false
++ return true
+}
+
var File_transport_internet_config_proto protoreflect.FileDescriptor