update 2026-10-19 17:31:01

This commit is contained in:
action committed 2026-10-19 17:31:01 +08:00
1 parent 6604b3420d
commit 313fe55d56
38 files changed
+982 -1508

No files matched your search

@@ -589,6 +589,7 @@ set clashoo_china6 {
2401:8680:4020::/43,
2401:8680:4040::/42,
2401:8680:4080::/41,
2401:8680:4100::/48,
2401:8680:4103::/48,
2401:8680:4104::/46,
2401:8680:4108::/45,
@@ -775,6 +776,7 @@ set clashoo_china6 {
2401:f860:8a::/47,
2401:f860:8c::/46,
2401:f860:91::/48,
2401:f860:93::/48,
2401:f860:95::/48,
2401:f860:96::/48,
2401:f860:98::/45,
@@ -958,6 +960,8 @@ set clashoo_china6 {
2402:7820::/32,
2402:7d00::/32,
2402:7d80::/32,
2402:7da0::/32,
2402:7e20::/32,
2402:8180::/32,
2402:8300::/32,
2402:8380::/32,
@@ -1253,12 +1257,16 @@ set clashoo_china6 {
2403:6180::/32,
2403:6280::/32,
2403:62c0::/32,
2403:6380::/42,
2403:6380::/44,
2403:6380:20::/44,
2403:6380:33::/48,
2403:6380:34::/46,
2403:6380:38::/45,
2403:6380:41::/48,
2403:6380:44::/46,
2403:6380:48::/45,
2403:6380:50::/44,
2403:6380:70::/44,
2403:6380:60::/43,
2403:6380:80::/41,
2403:6380:100::/40,
2403:6380:200::/39,
@@ -1484,6 +1492,9 @@ set clashoo_china6 {
2404:1e80::/32,
2404:1f40::/32,
2404:21c0::/32,
2404:2280:1000::/36,
2404:2280:2000::/35,
2404:2280:4000::/36,
2404:30c0::/32,
2404:3140::/32,
2404:31c0::/32,
@@ -1765,7 +1776,7 @@ set clashoo_china6 {
2405:84c0:800c::/46,
2405:84c0:8010::/48,
2405:84c0:8019::/48,
2405:84c0:801c::/46,
2405:84c0:801e::/47,
2405:84c0:8020::/47,
2405:84c0:8036::/47,
2405:84c0:8038::/46,
@@ -2221,7 +2232,7 @@ set clashoo_china6 {
2406:840:9103::/48,
2406:840:9104::/46,
2406:840:9108::/45,
2406:840:9112::/47,
2406:840:9113::/48,
2406:840:9114::/46,
2406:840:9118::/45,
2406:840:9120::/43,
@@ -2265,6 +2276,10 @@ set clashoo_china6 {
2406:840:9968::/46,
2406:840:996d::/48,
2406:840:996e::/47,
2406:840:9970::/46,
2406:840:9974::/47,
2406:840:9976::/48,
2406:840:9978::/45,
2406:840:9981::/48,
2406:840:9982::/47,
2406:840:9984::/46,
@@ -2294,6 +2309,7 @@ set clashoo_china6 {
2406:840:e0cc::/47,
2406:840:e0ce::/48,
2406:840:e0d0::/44,
2406:840:e0e4::/48,
2406:840:e0e6::/47,
2406:840:e0e9::/48,
2406:840:e0ea::/47,
@@ -2384,7 +2400,7 @@ set clashoo_china6 {
2406:840:ea00::/40,
2406:840:eb06::/48,
2406:840:eb09::/48,
2406:840:eb0a::/48,
2406:840:eb0a::/47,
2406:840:eb0c::/47,
2406:840:eb0e::/48,
2406:840:eb10::/44,
@@ -2468,6 +2484,10 @@ set clashoo_china6 {
2406:840:f600::/42,
2406:840:f640::/43,
2406:840:f670::/44,
2406:840:f680::/47,
2406:840:f682::/48,
2406:840:f684::/46,
2406:840:f688::/45,
2406:840:f690::/44,
2406:840:f6a0::/43,
2406:840:f6c0::/42,
@@ -2628,6 +2648,7 @@ set clashoo_china6 {
2406:840:fee8::/46,
2406:840:feec::/48,
2406:840:feee::/47,
2406:840:feff::/48,
2406:840:ff00::/40,
2406:880::/32,
2406:8c0::/32,
@@ -2878,7 +2899,7 @@ set clashoo_china6 {
2406:e780::/32,
2406:e8c0::/32,
2406:ea40::/28,
2406:f280::/33,
2406:f280::/32,
2406:f300::/32,
2406:f4c0::/32,
2406:f7c0::/32,
@@ -3036,26 +3057,7 @@ set clashoo_china6 {
2407:fb80::/32,
2407:fc80::/32,
2407:fd80::/32,
2408:4000::/40,
2408:4000:100::/47,
2408:4000:103::/48,
2408:4000:104::/46,
2408:4000:108::/45,
2408:4000:110::/44,
2408:4000:120::/43,
2408:4000:140::/42,
2408:4000:180::/41,
2408:4000:200::/39,
2408:4000:400::/38,
2408:4000:800::/37,
2408:4000:1000::/36,
2408:4000:2000::/35,
2408:4000:4000::/34,
2408:4000:8000::/33,
2408:4001::/32,
2408:4002::/31,
2408:4004::/30,
2408:4008::/29,
2408:4000::/28,
2408:4010::/30,
2408:4014::/31,
2408:4016:1::/48,
@@ -3121,6 +3123,41 @@ set clashoo_china6 {
240a:a000::/20,
240a:c000::/20,
240b:2000::/22,
240b:4000::/31,
240b:4002::/36,
240b:4002:1000::/44,
240b:4002:1011::/48,
240b:4002:1012::/47,
240b:4002:1014::/46,
240b:4002:1018::/45,
240b:4002:1020::/43,
240b:4002:1040::/42,
240b:4002:1080::/41,
240b:4002:1100::/40,
240b:4002:1200::/39,
240b:4002:1400::/38,
240b:4002:1800::/37,
240b:4002:2000::/35,
240b:4002:4000::/34,
240b:4002:8000::/33,
240b:4004::/31,
240b:4006::/48,
240b:4006:1000::/43,
240b:4006:1020::/44,
240b:4006:1100::/45,
240b:4006:110c::/46,
240b:4006:1110::/45,
240b:4006:1118::/46,
240b:4007::/32,
240b:4009::/32,
240b:400b::/32,
240b:400c::/30,
240b:4010:fffe::/47,
240b:4011::/32,
240b:4012::/31,
240b:4014::/30,
240b:4018::/30,
240b:401f::/32,
240b:6000::/20,
240b:8000::/21,
240b:a000::/25,
@@ -3240,7 +3277,7 @@ set clashoo_china6 {
2a04:3e00:400::/38,
2a04:3e00:800::/37,
2a04:3e00:1001::/48,
2a04:3e00:1002::/48,
2a04:3e00:1002::/47,
2a04:3e00:1004::/46,
2a04:3e00:1008::/45,
2a04:3e00:1010::/44,
@@ -3264,12 +3301,10 @@ set clashoo_china6 {
2a04:f580:9010::/48,
2a04:f580:9012::/47,
2a04:f580:9020::/48,
2a04:f580:9030::/48,
2a04:f580:9040::/48,
2a04:f580:9050::/48,
2a04:f580:9060::/48,
2a04:f580:9070::/48,
2a04:f580:9080::/48,
2a04:f580:9210::/48,
2a04:f580:9212::/47,
2a04:f580:9220::/48,
@@ -3318,9 +3353,7 @@ set clashoo_china6 {
2a0a:d681:e200::/39,
2a0a:d681:e400::/38,
2a0a:d681:e800::/37,
2a0a:d681:f000::/37,
2a0a:d681:f800::/38,
2a0a:d681:fe00::/40,
2a0a:d681:f000::/36,
2a0a:d682::/33,
2a0a:d682:8000::/34,
2a0a:d682:c000::/36,
@@ -3340,6 +3373,7 @@ set clashoo_china6 {
2a0a:d685:1f0::/45,
2a0a:d685:1f8::/47,
2a0a:d685:1fa::/48,
2a0a:d685:200::/48,
2a0a:d685:202::/47,
2a0a:d685:204::/46,
2a0a:d685:208::/45,
@@ -3429,7 +3463,10 @@ set clashoo_china6 {
2a13:1802:2000::/35,
2a13:1802:4000::/34,
2a13:1802:8000::/34,
2a13:1802:c000::/44,
2a13:1802:c000::/48,
2a13:1802:c002::/47,
2a13:1802:c004::/46,
2a13:1802:c008::/45,
2a13:1802:c020::/43,
2a13:1802:c040::/42,
2a13:1802:c080::/41,
@@ -64,6 +64,7 @@ set clashoo_china {
5.10.138.0/23,
5.10.140.0/24,
5.10.143.0/24,
5.181.224.0/23,
8.128.4.0/22,
8.128.32.0/19,
8.128.64.0/19,
@@ -91,11 +92,92 @@ set clashoo_china {
8.168.0.0/15,
8.176.0.0/17,
8.176.128.0/19,
8.208.0.0/17,
8.208.128.0/21,
8.208.140.0/22,
8.208.144.0/20,
8.208.160.0/19,
8.208.192.0/18,
8.209.0.0/19,
8.209.36.0/22,
8.209.40.0/21,
8.209.48.0/20,
8.209.64.0/18,
8.209.128.0/18,
8.209.192.0/24,
8.209.194.0/23,
8.209.196.0/22,
8.209.200.0/21,
8.209.208.0/20,
8.209.224.0/19,
8.210.0.0/16,
8.211.0.0/17,
8.211.128.0/18,
8.211.192.0/19,
8.211.224.0/22,
8.211.232.0/21,
8.211.240.0/20,
8.212.0.0/18,
8.212.64.0/20,
8.212.80.0/21,
8.212.88.0/22,
8.212.92.0/24,
8.212.94.0/23,
8.212.96.0/22,
8.212.104.0/21,
8.212.112.0/20,
8.212.128.0/19,
8.212.160.0/20,
8.212.176.0/21,
8.212.188.0/22,
8.212.192.0/18,
8.213.0.0/16,
8.214.0.0/17,
8.214.128.0/19,
8.214.164.0/22,
8.214.168.0/21,
8.214.176.0/20,
8.214.192.0/18,
8.215.0.0/17,
8.215.128.0/19,
8.215.160.0/22,
8.215.168.0/21,
8.215.176.0/20,
8.215.192.0/18,
8.216.0.0/18,
8.216.64.0/21,
8.216.72.0/22,
8.216.80.0/20,
8.216.96.0/19,
8.216.128.0/17,
8.217.0.0/16,
8.218.0.0/15,
8.220.0.0/18,
8.220.64.0/19,
8.220.96.0/20,
8.220.112.0/21,
8.220.120.0/22,
8.220.128.0/19,
8.220.160.0/21,
8.220.172.0/22,
8.220.176.0/20,
8.220.192.0/19,
8.220.224.0/21,
8.220.232.0/22,
8.220.240.0/21,
8.221.0.0/17,
8.221.128.0/20,
8.221.144.0/21,
8.221.156.0/22,
8.221.160.0/19,
8.221.192.0/18,
8.222.0.0/15,
14.0.0.0/21,
14.0.12.0/22,
14.1.0.0/22,
14.1.24.0/22,
14.1.108.0/22,
14.1.112.0/22,
14.16.0.0/12,
14.102.128.0/22,
14.102.180.0/22,
@@ -308,6 +390,80 @@ set clashoo_china {
42.242.0.0/15,
42.244.0.0/14,
42.248.0.0/13,
43.90.0.0/16,
43.92.0.0/15,
43.94.0.0/18,
43.96.0.0/23,
43.96.2.130/32,
43.96.3.0/24,
43.96.4.0/22,
43.96.8.0/22,
43.96.16.130/32,
43.96.18.0/24,
43.96.20.0/22,
43.96.24.0/22,
43.96.32.0/22,
43.96.36.130/32,
43.96.40.0/24,
43.96.42.0/24,
43.96.44.0/23,
43.96.46.0/24,
43.96.48.0/21,
43.96.59.0/24,
43.96.60.0/24,
43.96.62.0/23,
43.96.64.0/21,
43.96.72.0/22,
43.96.77.131/32,
43.96.78.0/24,
43.96.80.0/23,
43.96.85.0/24,
43.96.86.0/24,
43.96.88.0/23,
43.96.90.0/24,
43.96.92.0/22,
43.96.96.0/23,
43.96.100.0/23,
43.96.103.0/24,
43.96.104.0/23,
43.96.107.0/24,
43.96.109.0/24,
43.96.110.0/23,
43.96.112.0/22,
43.96.116.0/24,
43.96.118.0/23,
43.96.120.0/24,
43.96.122.0/24,
43.96.124.0/23,
43.96.126.0/24,
43.97.0.0/17,
43.98.0.0/15,
43.100.0.0/15,
43.102.0.0/17,
43.102.192.0/18,
43.103.0.0/16,
43.104.0.0/14,
43.108.0.0/16,
43.110.0.0/15,
43.112.0.0/15,
43.114.0.0/16,
43.116.0.0/17,
43.116.160.0/24,
43.116.192.0/18,
43.117.0.0/16,
43.118.0.0/17,
43.118.128.0/18,
43.119.0.0/16,
43.120.0.0/15,
43.122.0.0/16,
43.123.0.0/17,
43.123.128.0/18,
43.124.0.0/16,
43.125.0.0/20,
43.125.24.0/21,
43.125.32.0/20,
43.125.48.0/21,
43.126.0.0/17,
43.136.0.0/13,
43.144.0.0/15,
43.148.0.0/14,
@@ -458,7 +614,8 @@ set clashoo_china {
43.242.160.0/21,
43.242.168.0/22,
43.242.180.0/22,
43.242.188.0/22,
43.242.189.0/24,
43.242.190.0/23,
43.242.192.0/21,
43.242.204.0/22,
43.242.216.0/21,
@@ -728,6 +885,7 @@ set clashoo_china {
45.127.128.0/22,
45.127.144.0/21,
45.127.156.0/22,
45.199.179.0/24,
45.248.8.0/22,
45.248.80.0/21,
45.248.96.0/20,
@@ -773,6 +931,7 @@ set clashoo_china {
45.251.160.0/19,
45.251.192.0/19,
45.251.224.0/22,
45.251.248.0/23,
45.252.0.0/21,
45.252.9.0/24,
45.252.10.0/23,
@@ -830,8 +989,166 @@ set clashoo_china {
45.255.224.0/20,
45.255.240.0/21,
45.255.248.0/22,
47.52.0.0/16,
47.56.0.0/16,
47.57.0.0/17,
47.57.128.0/18,
47.57.192.0/22,
47.57.196.0/24,
47.57.198.0/23,
47.57.200.0/21,
47.57.208.0/20,
47.57.224.0/19,
47.74.0.0/15,
47.76.0.0/16,
47.77.0.0/20,
47.77.16.0/21,
47.77.24.0/22,
47.77.32.0/19,
47.77.64.0/19,
47.77.96.0/20,
47.77.112.0/23,
47.77.128.0/17,
47.78.0.0/15,
47.80.0.0/14,
47.84.0.0/16,
47.85.0.0/17,
47.85.128.0/23,
47.85.131.0/24,
47.85.132.0/22,
47.85.136.0/21,
47.85.144.0/20,
47.85.160.0/19,
47.85.192.0/18,
47.86.0.0/16,
47.87.0.0/20,
47.87.16.0/21,
47.87.32.0/19,
47.87.64.0/21,
47.87.72.0/24,
47.87.80.0/20,
47.87.96.0/19,
47.87.128.0/20,
47.87.144.0/21,
47.87.156.0/22,
47.87.160.0/19,
47.87.192.0/18,
47.88.0.0/16,
47.89.0.0/18,
47.89.72.0/21,
47.89.80.0/22,
47.89.84.0/24,
47.89.88.0/23,
47.89.90.0/24,
47.89.92.0/22,
47.89.96.0/20,
47.89.122.0/23,
47.89.124.0/23,
47.89.128.0/17,
47.90.0.0/17,
47.90.128.0/19,
47.90.160.0/21,
47.90.168.0/22,
47.90.176.0/20,
47.90.192.0/18,
47.91.0.0/16,
47.92.0.0/14,
47.96.0.0/11,
47.235.0.0/21,
47.235.8.0/22,
47.235.12.0/23,
47.235.16.0/20,
47.236.0.0/17,
47.236.128.0/18,
47.236.192.0/20,
47.236.208.0/21,
47.236.220.0/22,
47.236.224.0/19,
47.237.0.0/17,
47.237.128.0/18,
47.237.192.0/19,
47.237.224.0/20,
47.237.240.0/21,
47.237.249.0/24,
47.237.250.0/23,
47.237.252.0/22,
47.238.0.0/20,
47.238.16.0/21,
47.238.28.0/22,
47.238.32.0/19,
47.238.64.0/18,
47.238.128.0/17,
47.239.0.0/16,
47.240.0.0/14,
47.244.0.0/16,
47.245.0.0/17,
47.245.128.0/20,
47.245.144.0/21,
47.245.152.0/22,
47.245.160.0/19,
47.245.192.0/20,
47.245.208.0/21,
47.245.216.0/22,
47.245.224.0/19,
47.246.32.0/22,
47.246.66.0/23,
47.246.68.0/23,
47.246.72.0/21,
47.246.82.0/23,
47.246.84.0/22,
47.246.88.0/23,
47.246.91.0/24,
47.246.92.0/23,
47.246.96.0/22,
47.246.101.0/24,
47.246.102.0/23,
47.246.104.0/21,
47.246.120.0/24,
47.246.122.0/23,
47.246.124.0/23,
47.246.128.0/23,
47.246.131.0/24,
47.246.132.0/23,
47.246.135.0/24,
47.246.136.0/21,
47.246.144.0/22,
47.246.150.0/23,
47.246.152.0/22,
47.246.157.0/24,
47.246.158.0/23,
47.246.160.0/23,
47.246.162.0/24,
47.246.164.0/22,
47.246.168.0/21,
47.246.176.0/20,
47.246.192.0/20,
47.246.208.0/23,
47.246.212.0/22,
47.250.0.0/18,
47.250.68.0/22,
47.250.72.0/21,
47.250.80.0/20,
47.250.96.0/21,
47.250.108.0/22,
47.250.112.0/20,
47.250.128.0/17,
47.251.0.0/17,
47.251.132.0/22,
47.251.136.0/21,
47.251.144.0/20,
47.251.160.0/19,
47.251.196.0/22,
47.251.200.0/21,
47.251.208.0/20,
47.251.224.0/19,
47.252.0.0/16,
47.253.0.0/18,
47.253.64.0/19,
47.253.96.0/20,
47.253.112.0/21,
47.253.120.0/22,
47.253.128.0/17,
47.254.0.0/16,
49.4.0.0/17,
49.4.128.0/22,
49.4.160.0/20,
@@ -916,9 +1233,7 @@ set clashoo_china {
59.153.136.0/22,
59.153.152.0/22,
59.153.164.0/22,
59.153.168.0/22,
59.153.173.0/24,
59.153.174.0/23,
59.153.168.0/21,
59.153.176.0/20,
59.153.192.0/22,
59.155.0.0/16,
@@ -971,6 +1286,7 @@ set clashoo_china {
61.232.0.0/14,
61.236.0.0/15,
61.240.0.0/14,
62.182.190.0/23,
62.234.0.0/16,
63.140.0.0/24,
63.140.3.0/24,
@@ -1147,8 +1463,7 @@ set clashoo_china {
103.5.56.0/22,
103.5.152.0/22,
103.5.168.0/22,
103.5.192.0/23,
103.5.194.0/24,
103.5.192.0/22,
103.5.252.0/22,
103.6.76.0/22,
103.6.220.0/22,
@@ -1163,7 +1478,8 @@ set clashoo_china {
103.8.108.0/22,
103.8.156.0/22,
103.8.200.0/21,
103.8.220.0/22,
103.8.221.0/24,
103.8.222.0/23,
103.9.8.0/22,
103.9.24.0/22,
103.9.108.0/22,
@@ -1674,6 +1990,7 @@ set clashoo_china {
103.74.48.0/22,
103.74.56.0/21,
103.74.80.0/22,
103.74.126.0/23,
103.74.148.0/22,
103.74.152.0/21,
103.74.204.0/22,
@@ -1733,7 +2050,7 @@ set clashoo_china {
103.81.120.0/22,
103.81.148.0/22,
103.81.164.0/22,
103.81.184.0/23,
103.81.184.0/22,
103.81.200.0/22,
103.81.232.0/22,
103.82.60.0/22,
@@ -1796,6 +2113,7 @@ set clashoo_china {
103.89.184.0/21,
103.89.192.0/19,
103.89.224.0/21,
103.90.51.0/24,
103.90.52.0/22,
103.90.56.0/23,
103.90.92.0/22,
@@ -3151,7 +3469,8 @@ set clashoo_china {
114.112.240.0/23,
114.112.245.0/24,
114.112.247.0/24,
114.112.248.0/22,
114.112.248.0/23,
114.112.251.0/24,
114.112.252.0/23,
114.113.0.0/17,
114.113.128.0/21,
@@ -3269,6 +3588,7 @@ set clashoo_china {
116.242.0.0/15,
116.244.0.0/14,
116.248.0.0/15,
116.251.64.0/18,
116.252.0.0/15,
116.254.104.0/21,
116.254.128.0/17,
@@ -3308,6 +3628,7 @@ set clashoo_china {
117.120.148.0/22,
117.120.164.0/22,
117.120.184.0/21,
117.120.196.0/22,
117.120.208.0/21,
117.120.216.0/22,
117.120.248.0/21,
@@ -3451,7 +3772,6 @@ set clashoo_china {
119.161.120.0/21,
119.161.128.0/21,
119.161.144.0/21,
119.161.152.0/23,
119.161.160.0/19,
119.161.192.0/18,
119.162.0.0/15,
@@ -3528,8 +3848,7 @@ set clashoo_china {
121.59.102.0/23,
121.59.104.0/23,
121.59.107.0/24,
121.59.108.0/24,
121.59.110.0/23,
121.59.108.0/22,
121.59.112.0/21,
121.59.121.0/24,
121.59.123.0/24,
@@ -3569,8 +3888,7 @@ set clashoo_china {
122.8.68.0/22,
122.8.76.0/22,
122.8.80.0/23,
122.8.112.0/21,
122.8.124.0/22,
122.8.116.0/22,
122.8.192.0/18,
122.9.0.0/16,
122.10.129.0/24,
@@ -3660,15 +3978,13 @@ set clashoo_china {
123.49.128.0/18,
123.49.192.0/23,
123.49.194.0/24,
123.49.197.0/24,
123.49.198.0/23,
123.49.196.0/22,
123.49.200.0/21,
123.49.208.0/20,
123.49.224.0/21,
123.49.232.0/22,
123.49.236.0/24,
123.49.224.0/20,
123.49.240.0/24,
123.49.242.0/23,
123.49.245.0/24,
123.49.248.0/21,
123.50.160.0/19,
123.52.0.0/14,
@@ -3849,6 +4165,15 @@ set clashoo_china {
139.5.212.0/22,
139.5.244.0/22,
139.9.0.0/16,
139.95.0.0/20,
139.95.16.0/22,
139.95.22.0/23,
139.95.24.0/21,
139.95.32.0/21,
139.95.40.0/23,
139.95.64.0/23,
139.95.96.0/22,
139.95.128.0/17,
139.129.0.0/16,
139.148.0.0/16,
139.155.0.0/16,
@@ -3918,7 +4243,8 @@ set clashoo_china {
140.249.0.0/16,
140.250.0.0/16,
140.255.0.0/16,
142.86.192.0/19,
142.86.200.0/21,
142.86.208.0/20,
142.86.224.0/20,
142.86.240.0/21,
142.86.248.0/22,
@@ -3965,9 +4291,23 @@ set clashoo_china {
146.222.94.0/24,
147.78.132.0/24,
147.78.134.0/24,
147.139.0.0/17,
147.139.128.0/18,
147.139.192.0/19,
147.139.224.0/20,
147.139.240.0/21,
147.139.248.0/22,
148.70.0.0/16,
149.41.64.0/18,
149.41.192.0/19,
149.129.0.0/20,
149.129.16.0/21,
149.129.32.0/19,
149.129.64.0/18,
149.129.128.0/19,
149.129.168.0/21,
149.129.176.0/20,
149.129.192.0/18,
150.0.0.0/16,
150.115.0.0/16,
150.121.0.0/16,
@@ -4025,6 +4365,10 @@ set clashoo_china {
156.107.170.0/24,
156.107.179.0/24,
156.107.181.0/24,
156.227.20.0/24,
156.236.12.0/24,
156.236.17.0/24,
156.245.1.0/24,
157.0.0.0/16,
157.10.34.0/23,
157.10.36.0/23,
@@ -4043,7 +4387,7 @@ set clashoo_china {
157.20.194.0/23,
157.20.246.0/23,
157.61.0.0/16,
157.66.42.0/23,
157.66.43.0/24,
157.66.70.0/23,
157.66.88.0/21,
157.66.164.0/23,
@@ -4119,6 +4463,7 @@ set clashoo_china {
160.250.170.0/23,
160.250.214.0/23,
160.250.252.0/23,
161.117.0.0/16,
161.163.0.0/21,
161.163.28.0/23,
161.189.0.0/16,
@@ -4178,7 +4523,6 @@ set clashoo_china {
163.223.32.0/23,
163.223.72.0/23,
163.223.124.0/23,
163.223.217.0/24,
163.223.222.0/23,
163.227.34.0/23,
163.227.40.0/23,
@@ -4206,6 +4550,29 @@ set clashoo_china {
167.189.0.0/16,
167.220.244.0/22,
168.160.0.0/16,
170.33.15.0/24,
170.33.20.0/22,
170.33.24.0/24,
170.33.29.0/24,
170.33.30.0/23,
170.33.32.0/22,
170.33.41.0/24,
170.33.64.0/23,
170.33.66.0/24,
170.33.68.0/23,
170.33.72.0/23,
170.33.76.0/22,
170.33.80.0/22,
170.33.84.0/24,
170.33.104.0/22,
170.33.112.0/23,
170.33.114.0/24,
170.33.129.0/24,
170.33.130.0/23,
170.33.136.0/23,
170.33.138.0/24,
170.33.168.0/23,
170.33.192.0/23,
170.179.0.0/16,
171.8.0.0/13,
171.34.0.0/15,
@@ -4340,7 +4707,6 @@ set clashoo_china {
183.91.52.0/22,
183.91.56.0/24,
183.91.61.0/24,
183.91.63.0/24,
183.91.128.0/22,
183.91.136.0/21,
183.91.144.0/20,
@@ -4384,6 +4750,12 @@ set clashoo_china {
193.119.0.0/19,
194.138.202.0/23,
194.138.245.0/24,
198.11.128.0/20,
198.11.145.0/24,
198.11.146.0/23,
198.11.148.0/22,
198.11.152.0/21,
198.11.160.0/19,
198.175.100.0/22,
198.208.17.0/24,
198.208.19.0/24,
@@ -4754,8 +5126,7 @@ set clashoo_china {
202.143.56.0/21,
202.143.100.0/22,
202.143.104.0/22,
202.144.196.0/23,
202.144.198.0/24,
202.144.196.0/22,
202.146.160.0/20,
202.146.184.0/23,
202.146.186.0/24,
@@ -4795,7 +5166,6 @@ set clashoo_china {
202.164.0.0/20,
202.164.96.0/19,
202.165.176.0/20,
202.165.208.0/21,
202.165.239.0/24,
202.165.240.0/23,
202.165.243.0/24,
@@ -5667,6 +6037,7 @@ set clashoo_china {
203.81.1.0/24,
203.81.2.0/24,
203.81.5.0/24,
203.81.7.0/24,
203.81.16.0/20,
203.81.244.0/22,
203.82.0.0/23,
@@ -5740,17 +6111,7 @@ set clashoo_china {
203.104.32.0/20,
203.105.96.0/19,
203.105.128.0/19,
203.107.0.0/23,
203.107.2.0/24,
203.107.4.0/22,
203.107.8.0/21,
203.107.16.0/20,
203.107.32.0/19,
203.107.69.0/24,
203.107.70.0/23,
203.107.72.0/21,
203.107.80.0/20,
203.107.96.0/19,
203.107.0.0/17,
203.110.160.0/19,
203.110.208.0/20,
203.110.232.0/23,
@@ -5775,8 +6136,7 @@ set clashoo_china {
203.123.58.0/24,
203.128.32.0/19,
203.128.96.0/19,
203.128.225.0/24,
203.128.226.0/23,
203.128.224.0/22,
203.128.228.0/24,
203.128.231.0/24,
203.129.8.0/24,
@@ -5889,6 +6249,7 @@ set clashoo_china {
203.223.16.0/24,
203.223.21.0/24,
203.223.22.0/23,
205.204.96.0/19,
206.109.70.0/23,
206.109.75.0/24,
210.2.0.0/19,
@@ -5944,6 +6305,8 @@ set clashoo_china {
211.144.0.0/14,
211.148.0.0/16,
211.149.0.0/19,
211.149.33.0/24,
211.149.34.0/23,
211.149.48.0/21,
211.149.64.0/21,
211.149.80.0/21,
Binary file not shown.
Binary file not shown.
+2 -2
View File
@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dns2socks-rust
PKG_VERSION:=0.2.6
PKG_VERSION:=0.2.7
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/tun2proxy/dns2socks/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=c90e9cf8da4d2b01618110ea8416ff6c53e17efd8319ee5ec12132fd14b35ec0
PKG_HASH:=34ecdeb98281d0873146a08f351e485e7fb9cfacb55ac748ccfe463987f6befd
PKG_BUILD_DIR:=$(BUILD_DIR)/dns2socks-$(PKG_VERSION)
PKG_MAINTAINER:=Zxlhhyccc <zxlhhyccc@gmail.com>
+2 -2
View File
@@ -1,12 +1,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=geoview
PKG_VERSION:=0.2.6
PKG_VERSION:=0.2.8
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/snowie2000/geoview/tar.gz/$(PKG_VERSION)?
PKG_HASH:=1b46d4255ab22ec433a14f804e9487885cc2693323579c1385d51919838db132
PKG_HASH:=e9e957568250157459b4ccc3398a995202678a0dbf1e932c4b0b6179d8b79e5f
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=LICENSE
+2 -2
View File
@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=honk
PKG_VERSION:=2026.10.18
PKG_VERSION:=2026.10.19
PKG_RELEASE:=1
# Pinned honk-core revision (Glassyiris/honk feat/native-api), cross-compiled by
# ci/build-core.sh. The per-architecture asset/hash are filled by that script;
# keep a committed fallback so the feed still evaluates without a staging run.
CORE_COMMIT:=0e61ed382c6746773d11e78a9f81a8092aa33c62
CORE_COMMIT:=423fef29c15d10f4f21e93d161dfc33f32e532ca
-include $(CURDIR)/generated-stage.mk
+1
Submodule luci-app-eqosplus added at c7ea61c971.
-47
View File
@@ -1,47 +0,0 @@
name: Build
on:
push:
tags:
- v*
jobs:
build:
name: Build ${{ matrix.arch }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arch:
- aarch64_generic
- i386_pentium-mmx
- loongarch64_generic
- mips_mips32
- mipsel_24kc
- mipsel_mips32
- x86_64
steps:
- uses: actions/checkout@main
with:
fetch-depth: 0
- name: Building packages
uses: sbwml/openwrt-gh-action-sdk@go1.24
env:
ARCH: ${{ matrix.arch }}-openwrt-24.10
FEEDNAME: packages_ci
PACKAGES: luci-app-eqosplus
NO_REFRESH_CHECK: true
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.arch }}
path: bin/packages/${{ matrix.arch }}/packages_ci/*.ipk
- name: Upload packages
uses: ncipollo/release-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
allowUpdates: true
replacesArtifacts: true
artifacts: "bin/packages/${{ matrix.arch }}/packages_ci/*.ipk"
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2025 sirpdboy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-39
View File
@@ -1,39 +0,0 @@
#
# Copyright (C) 2006-2017 OpenWrt.org#
# Copyright (C) 2022-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-eqosplus
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
THEME_NAME:=eqosplus
PKG_NAME:=luci-app-$(THEME_NAME)
PKG_LICENSE:=Apache-2.0
LUCI_TITLE:=LuCI support for eqosplus.
LUCI_DESCRIPTION:=LuCI support for Easy eqosplus(Support speed limit based on IP address).
LUCI_DEPENDS:=+ip-full +tc +nftables +bc +kmod-ifb
LUCI_PKGARCH:=all
PKG_VERSION:=1.3.0
PKG_RELEASE:=20251128
PKG_MAINTAINER:=sirpdboy <herboy2008@gmail.com>
define Build/Compile
endef
define Package/$(PKG_NAME)/postinst
#!/bin/sh
rm -f /tmp/luci-*
endef
define Package/$(PKG_NAME)/conffiles
/etc/config/eqosplus
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
-91
View File
@@ -1,91 +0,0 @@
![hello](https://views.whatilearened.today/views/github/sirpdboy/deplives.svg) [![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
<h1 align="center">
<br>luci-app-eqosplus<br>
</h1>
<p align="center">
<a href="https://openwrt.org"><img alt="OpenWrt" src="https://img.shields.io/badge/OpenWrt-%E2%89%A519.07-ff0000?logo=openwrt&logoColor=white"></a>
<a href="https://www.google.com/chrome/"><img alt="Chrome" src="https://img.shields.io/badge/Chrome-%E2%89%A5111-4285F3?logo=googlechrome&logoColor=white"></a>
<a href="https://www.apple.com/safari/"><img alt="Safari" src="https://img.shields.io/badge/Safari-%E2%89%A516.4-000000?logo=safari&logoColor=white"></a>
<a href="https://www.mozilla.org/firefox/"><img alt="Firefox" src="https://img.shields.io/badge/Firefox-%E2%89%A5128-FF7138?logo=firefoxbrowser&logoColor=white"></a>
<a target="_blank" href="https://github.com/sirpdboy/luci-app-eqosplus/releases"> <img alt="GitHub release" src="https://img.shields.io/github/v/release/sirpdboy/luci-app-eqosplus"></a>
<a href="https://github.com/sirpdboy/luci-app-eqosplus/releases"><img alt="Downloads" src="https://img.shields.io/github/downloads/sirpdboy/luci-app-eqosplus/total"></a>
</p>
[中文] | [English](README.md)
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明1.jpg)
Please read this page carefully, which includes precautions and instructions on how to use it.
## Enhanced version of EQOS with timed speed limit and added features such as timed limit.
### Method for downloading source code:
```Brach
# downloading
git clone https://github.com/sirpdboy/luci-app-eqosplus package/luci-app-eqosplus
make menuconfig
```
### Configuration Menu
```Brach
make menuconfig
# find LuCI -> Applications, select luci-app-eqosplus, save and exit
```
### compile
```Brach
# compile
make package/luci-app-eqosplus/compile V=s
```
## describe
- luci-app-eqosplus : https://github.com/sirpdboy/luci-app-eqosplus
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明2.jpg)
## interface
![screenshots](./doc/eqosplus0.png)
![screenshots](./doc/eqosplus1.png)
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/eqosplus.png)
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/eqosplus2.png)
# My other project
- Watch Dog : https://github.com/sirpdboy/luci-app-watchdog
- Net Speedtest : https://github.com/sirpdboy/luci-app-netspeedtest
- Task Plan : https://github.com/sirpdboy/luci-app-taskplan
- Power Off Device : https://github.com/sirpdboy/luci-app-poweroffdevice
- OpentoPD Theme : https://github.com/sirpdboy/luci-theme-opentopd
- KuCat Theme : https://github.com/sirpdboy/luci-theme-kucat
- KuCat Theme Config : https://github.com/sirpdboy/luci-app-kucat-config
- NFT Time Control : https://github.com/sirpdboy/luci-app-timecontrol
- Parent Control: https://github.com/sirpdboy/luci-theme-parentcontrol
- Eqos Plus: https://github.com/sirpdboy/luci-app-eqosplus
- Advanced : https://github.com/sirpdboy/luci-app-advanced
- ddns-go : https://github.com/sirpdboy/luci-app-ddns-go
- Advanced Plus): https://github.com/sirpdboy/luci-app-advancedplus
- Net Wizard: https://github.com/sirpdboy/luci-app-netwizard
- Part Exp: https://github.com/sirpdboy/luci-app-partexp
- Lukcy: https://github.com/sirpdboy/luci-app-lukcy
## HELP
| <img src="https://img.shields.io/badge/-Alipay-F5F5F5.svg" href="#赞助支持本项目-" height="25" alt="图飞了"/> | <img src="https://img.shields.io/badge/-WeChat-F5F5F5.svg" height="25" alt="图飞了" href="#赞助支持本项目-"/> |
| :-----------------: | :-------------: |
|![xm1](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/支付宝.png) | ![xm1](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/微信.png) |
<a href="#readme">
<img src="https://img.shields.io/badge/-TOP-orange.svg" alt="no" title="Return TOP" align="right"/>
</a>
![hello](https://visitor-badge-deno.deno.dev/sirpdboy.sirpdboy.svg) [![](https://img.shields.io/badge/TGGroup-ClickJoin-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
-109
View File
@@ -1,109 +0,0 @@
![hello](https://views.whatilearened.today/views/github/sirpdboy/deplives.svg) [![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
<h1 align="center">
<br>luci-app-eqosplus<br>
</h1>
<p align="center">
<a target="_blank" href="https://github.com/sirpdboy/luci-app-eqosplus/releases">
<img src="https://img.shields.io/github/release/sirpdboy/luci-app-eqosplus.svg?style=flat-square&label=luci-app-eqosplus&colorB=green">
</a>
</p>
[中文] | [English](README.md)
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明1.jpg)
请 **认真阅读完毕** 本页面,本页面包含注意事项和如何使用。
## 功能说明:
### 定时限速1.2.2版
#### 2023.7.19 定时限速1.2.2:增加更多日期:工作日和休息日,自定义日期1,2,3中间用逗号分隔;加入MAC地址限速,从此不用担心IPV6和IPV4的限速问题。
### 定时限速1.0版
#### 2022.12.24 定时限速在eqos的加强版,加入定时限制等功能。
## 编译使用方法 [![](https://img.shields.io/badge/-编译使用方法-F5F5F5.svg)](#编译使用方法-)
将luci-app-eqosplus添加至 LEDE/OpenWRT 源码的方法。
### 下载源码方法一:
编辑源码文件夹根目录feeds.conf.default并加入如下内容:
```Brach
# feeds获取源码:
src-git eqosplus https://github.com/sirpdboy/luci-app-eqosplus
```
```Brach
# 更新feeds,并安装主题:
scripts/feeds update eqosplus
scripts/feeds install luci-app-eqosplus
```
### 下载源码方法:
```Brach
# 下载源码
git clone https://github.com/sirpdboy/luci-app-eqosplus package/luci-app-eqosplus
make menuconfig
```
### 配置菜单
```Brach
make menuconfig
# 找到 LuCI -> Applications, 选择 luci-app-eqosplus, 保存后退出。
```
### 编译
```Brach
# 编译固件
make package/luci-app-eqosplus/compile V=s
```
## 说明 [![](https://img.shields.io/badge/-说明-F5F5F5.svg)](#说明-)
源码来源:https://github.com/sirpdboy/luci-app-eqosplus
- 你可以随意使用其中的源码,但请注明出处。
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明2.jpg)
## 界面
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/eqosplus.png)
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/eqosplus2.png)
# My other project
- 路由安全看门狗 :https://github.com/sirpdboy/luci-app-watchdog
- 网络速度测试 :https://github.com/sirpdboy/luci-app-netspeedtest
- 计划任务插件(原定时设置) : https://github.com/sirpdboy/luci-app-taskplan
- 关机功能插件 : https://github.com/sirpdboy/luci-app-poweroffdevice
- opentopd主题 : https://github.com/sirpdboy/luci-theme-opentopd
- kucat酷猫主题: https://github.com/sirpdboy/luci-theme-kucat
- kucat酷猫主题设置工具: https://github.com/sirpdboy/luci-app-kucat-config
- NFT版上网时间控制插件: https://github.com/sirpdboy/luci-app-timecontrol
- 家长控制: https://github.com/sirpdboy/luci-theme-parentcontrol
- 定时限速: https://github.com/sirpdboy/luci-app-eqosplus
- 系统高级设置 : https://github.com/sirpdboy/luci-app-advanced
- ddns-go动态域名: https://github.com/sirpdboy/luci-app-ddns-go
- 进阶设置(系统高级设置+主题设置kucat/agron/opentopd): https://github.com/sirpdboy/luci-app-advancedplus
- 网络设置向导: https://github.com/sirpdboy/luci-app-netwizard
- 一键分区扩容: https://github.com/sirpdboy/luci-app-partexp
- lukcy大吉: https://github.com/sirpdboy/luci-app-lukcy
## 捐助
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明3.jpg)
| <img src="https://img.shields.io/badge/-支付宝-F5F5F5.svg" href="#赞助支持本项目-" height="25" alt="图飞了"/> | <img src="https://img.shields.io/badge/-微信-F5F5F5.svg" height="25" alt="图飞了" href="#赞助支持本项目-"/> |
| :-----------------: | :-------------: |
|![xm1](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/支付宝.png) | ![xm1](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/微信.png) |
<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="图飞了" title="返回顶部" align="right"/>
</a>
![](https://visitor-badge-deno.deno.dev/sirpdboy.sirpdboy.svg) [![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 645 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 664 KiB

@@ -1,19 +0,0 @@
module("luci.controller.eqosplus", package.seeall)
-- Copyright 2022-2023 sirpdboy <herboy2008@gmail.com>
function index()
if not nixio.fs.access("/etc/config/eqosplus") then return end
entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false
local e = entry({"admin", "control", "eqosplus"}, cbi("eqosplus"), _("Eqosplus"), 10)
e.dependent=false
e.acl_depends = { "luci-app-eqosplus" }
entry({"admin", "control", "eqosplus", "status"}, call("act_status")).leaf = true
end
function act_status()
local sys = require "luci.sys"
local e = {}
e.status = sys.call(" busybox ps -w | grep eqosplus | grep -v grep >/dev/null ") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
@@ -1,190 +0,0 @@
-- Copyright 2022-2023 sirpdboy <herboy2008@gmail.com>
-- Licensed to the public under the Apache License 2.0.
local sys = require "luci.sys"
local ifaces = sys.net:devices()
local WADM = require "luci.tools.webadmin"
local ipc = require "luci.ip"
local a, t, e
a = Map("eqosplus", translate("Network speed limit"))
a.description = translate("Users can limit the network speed for uploading/downloading through MAC, IP, and IP segments (192.168.110.00-192.168.10.200). The speed unit is MB/second.")
a.template = "eqosplus/index"
t = a:section(TypedSection, "eqosplus")
t.anonymous = true
e = t:option(DummyValue, "eqosplus_status", translate("Status"))
e.template = "eqosplus/eqosplus"
e.value = translate("Collecting data...")
ipi = t:option(ListValue, "ifname", translate("Interface"), translate("Set the interface used for restriction, use pppoe-wan for dialing, use WAN hardware interface for DHCP mode (such as eth1), and use br-lan for bypass mode"))
ipi.default = "1"
ipi:value(1,translate("Automatic settings"))
ipi:value("br-lan", translate("br-lan (LAN Bridge)"))
local function get_wan_interfaces()
local result = {}
local ubus = require "ubus"
local conn = ubus.connect()
if not conn then
return result
end
local network_status = conn:call("network.interface", "dump", {})
for _, iface in ipairs(network_status.interface) do
if iface.interface:match("^wan") or iface.interface:match("^pppoe") or iface.proto == "pppoe" then
local dev = iface.l3_device or iface.device
if dev then
table.insert(result, {
name = dev,
proto = iface.proto,
logical_name = iface.interface
})
end
end
end
conn:close()
return result
end
local wan_ifaces = get_wan_interfaces()
for _, iface in ipairs(wan_ifaces) do
ipi:value(iface.name, translate(iface.name) .. (iface.proto == "pppoe" and " (PPPoE)" or " (WAN)"))
end
t = a:section(TypedSection, "device")
t.template = "cbi/tblsection"
t.anonymous = true
t.addremove = true
comment = t:option(Value, "comment", translate("Comment"))
comment.size = 8
e = t:option(Flag, "enable", translate("Enabled"))
e.rmempty = false
e.size = 4
ip = t:option(Value, "mac", translate("IP/MAC"))
ip.size = 8
local function get_devices()
local devices = {}
local seen_ips = {}
local ubus = require "ubus"
local conn = ubus.connect()
local function get_hostname(ip)
local f = io.popen("nslookup "..ip.." 2>/dev/null | grep 'name =' | cut -d'=' -f2 | sed 's/\\.$//'")
if f then
local name = f:read("*l")
f:close()
if name and name ~= "" then
return name:match("^%s*(.-)%s*$")
end
end
local leases_file = io.open("/tmp/dhcp.leases", "r")
if leases_file then
for line in leases_file:lines() do
local mac, ip_lease, _, hostname = line:match("^(%S+)%s+(%S+)%s+(%S+)%s+(%S+)")
if ip_lease == ip and hostname ~= "*" then
leases_file:close()
return hostname
end
end
leases_file:close()
end
return "unknown"
end
if conn then
local leases = conn:call("dhcp", "ipv4leases", {}) or {}
for _, lease in ipairs(leases) do
if lease.ipaddr and lease.mac then
local hostname = lease.hostname or get_hostname(lease.ipaddr)
devices[#devices+1] = {
ip = lease.ipaddr,
mac = lease.mac:upper(),
hostname = hostname,
display = string.format("%s (%s) - %s", lease.ipaddr, lease.mac:upper(), hostname)
}
seen_ips[lease.ipaddr] = true
end
end
conn:close()
end
local arp_cmd = io.popen("ip -4 neigh show dev br-lan 2>/dev/null")
if arp_cmd then
for line in arp_cmd:lines() do
local ip_addr, mac = line:match("^(%S+)%s+.+%s+(%S+)%s+")
if ip_addr and mac and mac ~= "00:00:00:00:00:00" and not seen_ips[ip_addr] then
mac = mac:upper()
local hostname = get_hostname(ip_addr)
devices[#devices+1] = {
ip = ip_addr,
mac = mac,
hostname = hostname,
display = string.format("%s (%s) - %s", ip_addr, mac, hostname)
}
seen_ips[ip_addr] = true
end
end
arp_cmd:close()
end
table.sort(devices, function(a, b) return a.ip < b.ip end)
return devices
end
local devices = get_devices()
for _, dev in ipairs(devices) do
ip:value(dev.ip, dev.display)
end
dl = t:option(Value, "download", translate("Downloads"))
dl.default = '0.1'
dl.size = 4
ul = t:option(Value, "upload", translate("Uploads"))
ul.default = '0.1'
ul.size = 4
function validate_time(self, value, section)
local hh, mm, ss
hh, mm, ss = string.match (value, "^(%d?%d):(%d%d)$")
hh = tonumber (hh)
mm = tonumber (mm)
if hh and mm and hh <= 23 and mm <= 59 then
return value
else
return nil, "Time HH:MM or space"
end
end
e = t:option(Value, "timestart", translate("Start control time"))
e.placeholder = '00:00'
e.default = '00:00'
e.validate = validate_time
e.rmempty = true
e.size = 4
e = t:option(Value, "timeend", translate("Stop control time"))
e.placeholder = '00:00'
e.default = '00:00'
e.validate = validate_time
e.rmempty = true
e.size = 4
week=t:option(Value,"week",translate("Week Day(1~7)"))
week.rmempty = true
week:value('0',translate("Everyday"))
week:value(1,translate("Monday"))
week:value(2,translate("Tuesday"))
week:value(3,translate("Wednesday"))
week:value(4,translate("Thursday"))
week:value(5,translate("Friday"))
week:value(6,translate("Saturday"))
week:value(7,translate("Sunday"))
week:value('1,2,3,4,5',translate("Workday"))
week:value('6,7',translate("Rest Day"))
week.default='0'
week.size = 6
return a
@@ -1,3 +0,0 @@
<%+cbi/valueheader%>
<font class="eqosplus_status"><%=pcdata(self:cfgvalue(section) or self.default or "")%></font>
<%+cbi/valuefooter%>
@@ -1,12 +0,0 @@
<% include("cbi/map") %>
<script type="text/javascript">//<![CDATA[
XHR.poll(2, '<%=luci.dispatcher.build_url("admin", "control", "eqosplus", "status" )%>', null,
function (x, result) {
var status = document.getElementsByClassName('eqosplus_status')[0];
status.setAttribute("style", "font-weight:bold;");
status.setAttribute("color", result.status ? "green" : "red");
status.innerHTML = result.status ? '<%=translate("RUNNING")%>' : '<%=translate("NOT RUNNING")%>';
}
)
//]]>
</script>
@@ -1,61 +0,0 @@
msgid "Eqosplus"
msgstr ""
msgid "Network speed limit"
msgstr ""
msgid "Running state"
msgstr ""
msgid "Not running"
msgstr ""
msgid "Running"
msgstr ""
msgid "Users can limit the network speed for uploading/downloading through MAC, IP, and IP segments (192.168.110.00-192.168.10.200). The speed unit is MB/second."
msgstr ""
msgid "MAC/IP"
msgstr ""
msgid "Downloads"
msgstr ""
msgid "Uploads"
msgstr ""
msgid "Comment"
msgstr ""
msgid "Upload bandwidth(Mbit/s)"
msgstr ""
msgid "Download bandwidth(Mbit/s)"
msgstr ""
msgid "Start control time"
msgstr ""
msgid "Stop control time"
msgstr ""
msgid "Week Day(1~7)"
msgstr ""
msgid "Suggested feedback:"
msgstr ""
msgid "Set the interface used for restriction, use pppoe-wan for dialing, use WAN hardware interface for DHCP mode (such as eth1), and use br-lan for bypass mode"
msgstr ""
msgid "Rest Day"
msgstr ""
msgid "Workday"
msgstr ""
msgid "Automatic settings"
msgstr ""
-61
View File
@@ -1,61 +0,0 @@
msgid "Eqosplus"
msgstr "定时限速"
msgid "Network speed limit"
msgstr "定时网速限制"
msgid "Running state"
msgstr "运行状态"
msgid "Not running"
msgstr "未运行"
msgid "Running"
msgstr "已运行"
msgid "Users can limit the network speed for uploading/downloading through MAC, IP.The speed unit is MB/second."
msgstr "可以通过MAC,IP限制用户上传/下载的网速。速度单位为<font color=\"red\"><b> MB/秒 </b></font>。"
msgid "MAC/IP"
msgstr "MAC/IP"
msgid "Downloads"
msgstr "下载速度"
msgid "Uploads"
msgstr "上传速度"
msgid "Comment"
msgstr "备注"
msgid "Upload bandwidth(Mbit/s)"
msgstr "上传总带宽(Mbit/s)"
msgid "Download bandwidth(Mbit/s)"
msgstr "下载总带宽(Mbit/s)"
msgid "Start control time"
msgstr "起控时间"
msgid "Stop control time"
msgstr "停控时间"
msgid "Week Day(1~7)"
msgstr "星期(1~7)"
msgid "Suggested feedback:"
msgstr "建议反馈:"
msgid "Set the interface used for restriction, use pppoe-wan for dialing, use WAN hardware interface for DHCP mode (such as eth1), and use br-lan for bypass mode"
msgstr "设定用来限制网络速度的接口,拨号使用pppoe-wan,DHCP模式使用WAN口的硬件接口(如:eth1),通用使用br-lan接口"
msgid "Rest Day"
msgstr "休息日"
msgid "Workday"
msgstr "工作日"
msgid "Automatic settings"
msgstr "自动设置"
-61
View File
@@ -1,61 +0,0 @@
msgid "Eqosplus"
msgstr "定时限速"
msgid "Network speed limit"
msgstr "定时网速限制"
msgid "Running state"
msgstr "运行状态"
msgid "Not running"
msgstr "未运行"
msgid "Running"
msgstr "已运行"
msgid "Users can limit the network speed for uploading/downloading through MAC, IP, and IP segments (192.168.110.00-192.168.10.200). The speed unit is MB/second."
msgstr "用户可以通过MAC、IP、IP段(192.168.10.100-192.168.10.200),限制上传/下载的网络速度。速度单位为MB/秒。。"
msgid "MAC/IP"
msgstr "MAC/IP"
msgid "Downloads"
msgstr "下载速度"
msgid "Uploads"
msgstr "上传速度"
msgid "Comment"
msgstr "备注"
msgid "Upload bandwidth(Mbit/s)"
msgstr "上传总带宽(Mbit/s)"
msgid "Download bandwidth(Mbit/s)"
msgstr "下载总带宽(Mbit/s)"
msgid "Start control time"
msgstr "起控时间"
msgid "Stop control time"
msgstr "停控时间"
msgid "Week Day(1~7)"
msgstr "星期(1~7)"
msgid "Suggested feedback:"
msgstr "建议反馈:"
msgid "Set the interface used for restriction, use pppoe-wan for dialing, use WAN hardware interface for DHCP mode (such as eth1), and use br-lan for bypass mode"
msgstr "设定用来限制网络速度的接口,拨号使用pppoe-wan,DHCP模式使用WAN口的硬件接口(如:eth1),通用使用br-lan接口"
msgid "Rest Day"
msgstr "休息日"
msgid "Workday"
msgstr "工作日"
msgid "Automatic settings"
msgstr "自动设置"
@@ -1,25 +0,0 @@
config eqosplus
option enabled '0'
option download '1000'
option upload '30'
option ifname '1'
config device
option timestart '00:00'
option week '0'
option download '1'
option timeend '23:55'
option upload '1'
option mac '192.168.10.10'
option enable '0'
config device
option mac '192.168.10.10-192.168.10.200'
option timestart '00:00'
option timeend '00:00'
option week '0'
option download '0.1'
option upload '0.1'
option enable '0'
@@ -1,5 +0,0 @@
#!/bin/sh
[ "$ACTION" = "ifup" ] && [ "$INTERFACE" = "wan" ] && {
sleep 5
/etc/init.d/eqosplus restart
}
@@ -1,54 +0,0 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-eqosplus
#
START=99
USE_PROCD=1
NAME=eqosplus
LOCK="/var/lock/$NAME.lock"
CR=/etc/crontabs/root
start_instance() {
procd_open_instance
procd_set_param command /usr/bin/eqosplusctrl
procd_set_param respawn
procd_set_param stderr 1
procd_close_instance
}
_eqosplus_start() {
if [ "$(grep -c 'option enable .1.' /etc/config/$NAME 2>/dev/null)" -gt "0" ]; then
if [ x$(uci -q get turboacc.config.sw_flow) = 'x1' ] || [ x$(uci -q get turboacc.config.sfe_flow) = 'x1' ] ;then
uci -q set turboacc.config.sw_flow='0'
uci -q set turboacc.config.sfe_flow='0'
uci -q set turboacc.config.hw_flow='0'
uci commit turboacc
/etc/init.d/turboacc restart
fi
touch $LOCK
eqosplus start
start_instance
(crontab -l ; echo "00 1 * * * /etc/init.d/eqosplus start") | sort - | uniq - | crontab -
fi
}
start_service(){
[ -f $LOCK ] && exit
stop_service
_eqosplus_start
rm -f $LOCK
}
service_triggers() {
procd_add_reload_trigger 'eqosplus'
}
stop_service(){
kill -9 $(busybox ps -w | grep 'eqosplusctrl' | grep -v 'grep' | awk '{print $1}') >/dev/null 2>&1
sed -i '/eqosplus/d' $CR >/dev/null 2>&1
rm -f $LOCK 2>/dev/null
eqosplus stop
}
@@ -1,13 +0,0 @@
#!/bin/sh
chmod +x /etc/init.d/eqosplus /usr/bin/eqosplus*
uci -q batch <<-EOF >/dev/null
delete ucitrack.@eqosplus[-1]
add ucitrack eqosplus
set ucitrack.@eqosplus[-1].init=eqosplus
commit ucitrack
EOF
[ -s /etc/config/eqosplus ] || echo "config eqosplus" > /etc/config/eqosplus
rm -f /tmp/luci-indexcache
exit 0
-379
View File
@@ -1,379 +0,0 @@
#!/bin/bash
# Copyright (C) 2006 OpenWrt.org
# Copyright 2022-2025 sirpdboy <herboy2008@gmail.com>
crrun=$1
crid=$2
NAME=eqosplus
IDLIST="/var/$NAME.idlist"
LOCK="/var/lock/$NAME.lock"
TMPID="/var/$NAME.tmpid"
LOG="/var/$NAME_log.log"
# idlist=`uci show $NAME | grep "enable='1'" | grep "device" | grep -oE '\[.*?\]' | grep -o '[0-9]' `
if [ x$(uci get $NAME.@$NAME[0].ifname 2>/dev/null) = 'x1' ]; then
ifname=$(uci -q get network.lan.ifname)
[ "x$ifname" = "x" ] && ifname="device" || ifname="ifname"
dev=$(uci -q get network.wan.$ifname)
[ ! "$dev" ] && dev=br-lan
else
dev=$(uci -q get $NAME.@$NAME[0].ifname 2>/dev/null)
[ ! "$dev" ] && dev=br-lan
fi
bin_nft=$(which nft)
bin_tc=$(which tc)
bin_ip=$(which ip)
DEBUG=1
nft_type() {
if command -v nft >/dev/null; then
nftables_ver="true"
fi
}
# Debug functions
dbg_nft() {
[ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: nft $*"
$bin_nft "$@"
}
dbg_tc() {
[ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: tc $*"
$bin_tc "$@"
}
dbg_ip() {
[ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: ip $*"
$bin_ip "$@"
}
is_macaddr() {
ret=1
if echo "$1" | grep -qE '^([0-9A-Fa-f]{2}[-:]){5}[0-9A-Fa-f]{2}$'; then
ret=0
fi
return $ret
}
# 数值比较函数
is_gt_zero() {
local value=$1
# 使用bc进行浮点数比较
echo "$value > 0" | bc -l 2>/dev/null | grep -q 1
}
# 转换为kbit
to_kbit() {
local mb=$1
# MB/s 转 kbit/s: 1 MB/s = 8192 kbit/s
echo "scale=0; $mb * 8192 / 1" | bc 2>/dev/null || echo "0"
}
# Default commands
tc="dbg_tc"
ip="dbg_ip"
nft="dbg_nft"
nft_type
stop_qos() {
for face in $(tc qdisc show 2>/dev/null | grep htb | awk '{print $5}'); do
$tc qdisc del dev $face root 2>/dev/null
done
$tc qdisc del dev ${dev} root 2>/dev/null
$tc qdisc del dev ${dev}_ifb root 2>/dev/null
$tc qdisc del dev ${dev} ingress 2>/dev/null
$ip link del dev ${dev}_ifb 2>/dev/null 2>&1
if [ -n "$nftables_ver" ]; then
$nft delete table inet ${NAME} 2>/dev/null
$nft delete table bridge ${NAME} 2>/dev/null
fi
echo "" > "$IDLIST" 2>/dev/null
}
init_qosplus() {
insmod sch_htb 2>/dev/null
insmod act_mirred 2>/dev/null
insmod ifb 2>/dev/null
$ip link del dev ${dev}_ifb 2>/dev/null
$ip link add dev ${dev}_ifb name ${dev}_ifb type ifb
$ip link set dev ${dev}_ifb up
$tc qdisc del dev ${dev} root 2>/dev/null
$tc qdisc add dev ${dev} root handle 1:0 htb default 1
$tc class add dev ${dev} parent 1:0 classid 1:1 htb rate 1000mbit ceil 1000mbit
$tc qdisc del dev ${dev}_ifb root 2>/dev/null
$tc qdisc add dev ${dev}_ifb root handle 1:0 htb default 1
$tc class add dev ${dev}_ifb parent 1:0 classid 1:1 htb rate 1000mbit ceil 1000mbit
lanipaddr=$(uci -q get network.lan.ipaddr 2>/dev/null | awk -F '.' '{print $1"."$2"."$3".0/24"}')
if [ -n "$lanipaddr" ]; then
$tc filter add dev $dev parent 1:0 protocol ip prio 1 u32 match ip src "$lanipaddr" match ip dst "$lanipaddr" flowid 1:1
$tc filter add dev ${dev}_ifb parent 1:0 protocol ip prio 1 u32 match ip src "$lanipaddr" match ip dst "$lanipaddr" flowid 1:1
fi
$tc qdisc del dev ${dev} ingress 2>/dev/null
$tc qdisc add dev ${dev} ingress
$tc filter add dev ${dev} parent ffff: protocol all prio 2 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ${dev}_ifb
if [ -n "$nftables_ver" ]; then
$nft delete table inet ${NAME} 2>/dev/null
$nft delete table bridge ${NAME} 2>/dev/null
$nft add table inet ${NAME}
$nft add chain inet ${NAME} mark_forward { type filter hook forward priority -200\; policy accept\; }
$nft add chain inet ${NAME} mark_output { type filter hook output priority -200\; policy accept\; }
$nft add chain inet ${NAME} mark_postrouting { type filter hook postrouting priority -200\; policy accept\; }
fi
return 0
}
del_id() {
local list_id=$1
id=$((list_id * 10 + 1000))
[ "${DEBUG:-0}" -eq 0 ] || echo "D: del_id $@ --$id --$mac"
$tc filter del dev ${dev} parent 1: handle 800::$(printf "%x" $id) 2>/dev/null
$tc class del dev ${dev} parent 1:1 classid 1:$id 2>/dev/null
$tc filter del dev ${dev}_ifb parent 1: handle 800::$(printf "%x" $id) 2>/dev/null
$tc class del dev ${dev}_ifb parent 1:1 classid 1:$id 2>/dev/null
mac=$(uci -q get $NAME.@device[$list_id].mac 2>/dev/null)
if [ -n "$nftables_ver" ] && [ -n "$mac" ]; then
if is_macaddr "$mac"; then
$nft delete rule inet ${NAME} mark_forward ether saddr $mac counter 2>/dev/null
$nft delete rule inet ${NAME} mark_output ether saddr $mac counter 2>/dev/null
$nft delete rule inet ${NAME} mark_postrouting ether saddr $mac counter 2>/dev/null
else
Z=$(echo $mac | awk -F '[/]' '{print $2}')
[ -n "$Z" ] && mac=$(echo $mac | awk -F '[/]' '{print $1}') || Z=32
$nft delete rule inet ${NAME} mark_forward ip saddr $mac/$Z counter 2>/dev/null
$nft delete rule inet ${NAME} mark_output ip saddr $mac/$Z counter 2>/dev/null
$nft delete rule inet ${NAME} mark_postrouting ip saddr $mac/$Z counter 2>/dev/null
fi
fi
}
add_mac() {
local list_id=$1
id=$((list_id * 10 + 1000))
M0=$(echo $mac | cut -d : -f 1)$(echo $mac | cut -d : -f 2)
M1=$(echo $mac | cut -d : -f 3)$(echo $mac | cut -d : -f 4)
M2=$(echo $mac | cut -d : -f 5)$(echo $mac | cut -d : -f 6)
[ "${DEBUG:-0}" -eq 0 ] || echo "D: add_mac $@ --id:$id --mac:$mac M012--$M0-$M1-$M2"
if is_gt_zero "$UL"; then
if [ -n "$nftables_ver" ]; then
$nft add rule inet ${NAME} mark_forward ether saddr $mac counter meta mark set $id
$nft add rule inet ${NAME} mark_output ether saddr $mac counter meta mark set $id
$nft add rule inet ${NAME} mark_postrouting ether saddr $mac counter meta mark set $id
fi
$tc class add dev ${dev}_ifb parent 1:1 classid 1:$id htb rate "${UL}kbit" ceil "${UL}kbit" prio $id burst 15k cburst 15k
$tc qdisc add dev ${dev}_ifb parent 1:$id handle ${id}: sfq perturb 10
$tc filter add dev ${dev}_ifb parent 1: protocol ip prio $id handle $id fw flowid 1:$id
$tc filter add dev ${dev}_ifb parent 1: protocol ip prio $((id + 100)) u32 \
match u16 0x0800 0xFFFF at -2 \
match u16 0x${M2} 0xFFFF at -4 \
match u32 0x${M0}${M1} 0xFFFFFFFF at -8 \
flowid 1:$id
fi
if is_gt_zero "$DL"; then
$tc class add dev ${dev} parent 1:1 classid 1:$id htb rate "${DL}kbit" ceil "${DL}kbit" prio $id burst 15k cburst 15k
$tc qdisc add dev ${dev} parent 1:$id handle ${id}: sfq perturb 10
$tc filter add dev ${dev} parent 1: protocol ip prio $id u32 \
match u16 0x0800 0xFFFF at -2 \
match u32 0x${M1}${M2} 0xFFFFFFFF at -12 \
match u16 0x${M0} 0xFFFF at -14 \
flowid 1:$id
fi
}
add_ip() {
local list_id=$1
id=$((list_id * 10 + 1000))
[ "${DEBUG:-0}" -eq 0 ] || echo "D: add_ip $@ --$id --$mac"
Z=$(echo $mac | awk -F '[/]' '{print $2}')
[ -n "$Z" ] && mac=$(echo $mac | awk -F '[/]' '{print $1}') || Z=32
if is_gt_zero "$UL"; then
if [ -n "$nftables_ver" ]; then
$nft add rule inet ${NAME} mark_forward ip saddr $mac/$Z counter meta mark set $id
$nft add rule inet ${NAME} mark_output ip saddr $mac/$Z counter meta mark set $id
$nft add rule inet ${NAME} mark_postrouting ip saddr $mac/$Z counter meta mark set $id
fi
$tc class add dev ${dev}_ifb parent 1:1 classid 1:$id htb rate "${UL}kbit" ceil "${UL}kbit" prio $id burst 15k cburst 15k
$tc qdisc add dev ${dev}_ifb parent 1:$id handle ${id}: sfq perturb 10
$tc filter add dev ${dev}_ifb parent 1: protocol ip prio $id handle $id fw flowid 1:$id
$tc filter add dev ${dev}_ifb parent 1:0 prio $((id + 100)) protocol ip u32 \
match ip src "$mac"/"$Z" \
flowid 1:$id
fi
if is_gt_zero "$DL"; then
$tc class add dev ${dev} parent 1:1 classid 1:$id htb rate "${DL}kbit" ceil "${DL}kbit" prio $id burst 15k cburst 15k
$tc qdisc add dev ${dev} parent 1:$id handle ${id}: sfq perturb 10
$tc filter add dev ${dev} parent 1:0 prio $id protocol ip u32 \
match ip dst "$mac"/"$Z" \
flowid 1:$id
fi
}
check_time() {
local start=$1
local end=$2
local current=$(date +%H%M)
local start_min=$((10#${start:0:2}*60 + 10#${start:3:2}))
local end_min=$((10#${end:0:2}*60 + 10#${end:3:2}))
local current_min=$((10#${current:0:2}*60 + 10#${current:2:2}))
if [[ $start_min -lt $end_min ]]; then
[[ $current_min -ge $start_min && $current_min -lt $end_min ]]
else
[[ $current_min -ge $start_min || $current_min -lt $end_min ]]
fi
}
check_list() {
local i=$1
local start_time=$(uci -q get $NAME.@device[$i].timestart 2>/dev/null)
local end_time=$(uci -q get $NAME.@device[$i].timeend 2>/dev/null)
local wweek=$(uci -q get $NAME.@device[$i].week 2>/dev/null)
local current_weekday=$(date +%u)
[ -z "$start_time" ] && [ -z "$end_time" ] && [ -z "$wweek" ] && return 0
if [ -n "$wweek" ] && [ "$wweek" != "0" ]; then
local day_match=0
for day in $(echo $wweek | tr ',' ' '); do
[ "$day" -eq "$current_weekday" ] && day_match=1 && break
done
[ "$day_match" -eq 0 ] && return 1
fi
if [ -n "$start_time" ] && [ -n "$end_time" ]; then
check_time "$start_time" "$end_time" || return 1
fi
return 0
}
case "$crrun" in
"stop")
stop_qos
;;
"start")
stop_qos > /dev/null 2>&1
sleep 2
init_qosplus
idlist=$(uci show $NAME 2>/dev/null | grep "enable='1'" | grep "device" | grep -oE '\[.*?\]' | grep -o '[0-9]' | sort -nu | sed -e 's/^/!/g' -e 's/$/!/g' > $IDLIST; cat $IDLIST 2>/dev/null | sed -e 's/!//g')
if [ ! -s "$IDLIST" ]; then
return 1
fi
device_count=0
for list in $(echo $idlist | sed -e 's/!//g'); do
if check_list $list; then
mac=$(uci -q get $NAME.@device[$list].mac 2>/dev/null)
download_mb=$(uci -q get $NAME.@device[$list].download 2>/dev/null)
upload_mb=$(uci -q get $NAME.@device[$list].upload 2>/dev/null)
comment=$(uci -q get $NAME.@device[$list].comment 2>/dev/null)
# 转换为kbit
DL=$(to_kbit "$download_mb")
UL=$(to_kbit "$upload_mb")
if [ -n "$mac" ]; then
if is_macaddr "$mac"; then
add_mac $list >>$LOG
echo "✅ MAC限速: $comment ($mac) - 下载:${download_mb}MB/s(${DL}kbit/s) 上传:${upload_mb}MB/s(${UL}kbit/s)" >>$LOG
else
add_ip $list >>$LOG
echo "✅ IP限速: $comment ($mac) - 下载:${download_mb}MB/s(${DL}kbit/s) 上传:${upload_mb}MB/s(${UL}kbit/s)" >>$LOG
fi
device_count=$((device_count + 1))
fi
else
[ -f "$IDLIST" ] && [ $(grep "!${list}!" "$IDLIST" 2>/dev/null | wc -l) -gt 0 ] && {
del_id $list >>$LOG
sed -i "/!$list!/d" "$IDLIST" >/dev/null 2>&1
comment=$(uci -q get $NAME.@device[$list].comment 2>/dev/null)
}
fi
done
echo "EQOSPLUS限速服务启动完成,共配置 $device_count 个设备" >>$LOG
echo ""
echo "当前限速状态:" >>$LOG
tc -s class show dev $dev | grep "rate" | head -5 >>$LOG
tc -s class show dev ${dev}_ifb | grep "rate" | head -5 >>$LOG
;;
"add")
echo "➕ 添加限速规则..."
for list in $(echo $crid | sed -e 's/!//g' | sed 's/,/ /g'); do
mac=$(uci -q get $NAME.@device[$list].mac 2>/dev/null)
download_mb=$(uci -q get $NAME.@device[$list].download 2>/dev/null)
upload_mb=$(uci -q get $NAME.@device[$list].upload 2>/dev/null)
comment=$(uci -q get $NAME.@device[$list].comment 2>/dev/null)
DL=$(to_kbit "$download_mb")
UL=$(to_kbit "$upload_mb")
if is_macaddr $mac; then
add_mac $list
echo "✅ 添加MAC限速: $comment ($mac)" >>$LOG
else
add_ip $list
echo "✅ 添加IP限速: $comment ($mac)" >>$LOG
fi
done
;;
"del")
for list in $(echo $crid | sed -e 's/!//g' | sed 's/,/ /g'); do
comment=$(uci -q get $NAME.@device[$list].comment 2>/dev/null)
mac=$(uci -q get $NAME.@device[$list].mac 2>/dev/null)
del_id $list
done
;;
"status")
echo "EQOSPLUS限速服务状态"
echo "### 网络接口: $dev ###"
echo "# 下载队列统计 #"
tc -s qdisc show dev $dev 2>/dev/null || echo "无下载队列"
echo "# 下载类统计 #"
tc -s class show dev $dev 2>/dev/null | grep -E "class htb|rate [0-9]" || echo "无下载类"
echo "# 下载过滤器 #"
tc -s filter show dev $dev parent 1: 2>/dev/null | head -10 || echo "无下载过滤器"
echo "### 虚拟接口: ${dev}_ifb ###"
echo "# 上传队列统计 #"
tc -s qdisc show dev ${dev}_ifb 2>/dev/null || echo "无上传队列"
echo "# 上传类统计 #"
tc -s class show dev ${dev}_ifb 2>/dev/null | grep -E "class htb|rate [0-9]" || echo "无上传类"
echo "# 上传过滤器 #"
tc -s filter show dev ${dev}_ifb parent 1: 2>/dev/null | head -10 || echo "无上传过滤器"
if [ -n "$nftables_ver" ]; then
echo "### NFTables规则 ###"
nft list table inet ${NAME} 2>/dev/null || echo "没有NFTables规则"
else
echo "NFTables不可用"
fi
# 显示流量统计
echo "### 流量统计 ###"
echo "下载流量:"
tc -s class show dev $dev 2>/dev/null | grep "Sent" | head -5
echo "上传流量:"
tc -s class show dev ${dev}_ifb 2>/dev/null | grep "Sent" | head -5
;;
esac
@@ -1,63 +0,0 @@
#!/bin/sh
# Copyright (C) 2006 OpenWrt.org
# Copyright 2022-2025 sirpdboy <herboy2008@gmail.com>
NAME=eqosplus
IDLIST="/var/$NAME.idlist"
TMPID="/var/$NAME.tmpid"
idlist=`uci show $NAME | grep "enable='1'" | grep "device" | grep -oE '\[.*?\]' | grep -o '[0-9]' `
check_list() {
i=$1
checki='0'
start_time=$(uci -q get $NAME.@device[$i].timestart 2>/dev/null)
end_time=$(uci -q get $NAME.@device[$i].timeend 2>/dev/null)
wweek=`uci -q get $NAME.@device[$i].week `
current_time=$(date +%H:%M)
current_weekday=$(date +%u)
for ww in `echo $wweek | sed 's/,/ /g' `; do
if [ $current_weekday = $ww ] || [ 'x0' = x$ww ] ;then
[ "$start_time" = "$end_time" ] && checki='1' || {
if [ "$start_time" \< "$end_time" ]; then
if [ "$current_time" \> "$start_time" ] && [ "$current_time" \< "$end_time" ] ; then
checki='1'
fi
else
if [ "$start_time" \> "$end_time" ] ; then
if [ "$current_time" \< "$start_time" ] && [ "$current_time" \> "$end_time" ] ; then
checki='1'
fi
fi
fi
}
fi
done
return
}
idlistusr(){
checki='0'
[ -s $IDLIST ] || touch $IDLIST
for list in $idlist ;do
check_list $list
if [ $checki == '1' ] ; then
[ `cat $IDLIST 2>/dev/null | grep "!${list}!" | wc -l ` -gt 0 ] || {
eqosplus add $list
echo "!${list}!" >> $IDLIST ; cat $IDLIST | sort | uniq > $TMPID ;cat $TMPID >$IDLIST ;rm -rf $TMPID
}
else
[ `cat $IDLIST 2>/dev/null | grep "!${list}!" | wc -l ` -gt 0 ] && {
eqosplus del $list
sed -i "/!$list!/d" $IDLIST >/dev/null 2>&1
}
fi
done
}
while :;do
sleep 30
idlistusr
sleep 30
done
@@ -1,11 +0,0 @@
{
"luci-app-eqosplus": {
"description": "Grant UCI access for luci-app-eqosplus",
"read": {
"uci": [ "eqosplus" ]
},
"write": {
"uci": [ "eqosplus" ]
}
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 585 KiB

+2 -2
View File
@@ -21,13 +21,13 @@ define Download/geoip
HASH:=4ff4b2ec242a9e87b296ba27ddb85f8311e8d3e071eaebac5be9231c60e408dd
endef
GEOSITE_VER:=20261018123756
GEOSITE_VER:=20261019032359
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
define Download/geosite
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
URL_FILE:=dlc.dat
FILE:=$(GEOSITE_FILE)
HASH:=0a38573dee9f6eb16c67e457c6d5d7f0755f12a8cdaa25ec26b358fdbcf9e79d
HASH:=1092fd1a58deccd964e92b5ff05ce01ecabaf67b8242ade8bdc6b6b35821d402
endef
GEOSITE_IRAN_VER:=202610120242
+246
View File
@@ -0,0 +1,246 @@
name: Build packages
on:
workflow_dispatch:
inputs:
openwrt_majors:
description: 'OpenWrt major versions (space-separated, e.g. 24 25)'
required: false
default: '24 25'
type: string
push:
branches:
- master
permissions:
contents: write
actions: write
env:
OPENWRT_MAJORS: '24 25'
jobs:
prepare:
name: Prepare version and matrix
runs-on: ubuntu-latest
outputs:
release_tag: ${{ steps.meta.outputs.release_tag }}
release_name: ${{ steps.meta.outputs.release_name }}
sdks: ${{ steps.matrix.outputs.sdks }}
steps:
- name: Checkout source
uses: actions/checkout@v6
- name: Generate version metadata
id: meta
shell: bash
run: |
pkg_release=$(grep '^PKG_RELEASE:=' Makefile | head -n 1 | cut -d= -f2 | tr -d '[:space:]')
date_tag=$(date +'%Y%m%d')
short_sha=$(git rev-parse --short HEAD)
release_tag="vmlinux-btf_r${pkg_release}_${date_tag}_${short_sha}"
release_name="vmlinux-btf r${pkg_release} (${date_tag})"
echo "release_tag=${release_tag}" >> "$GITHUB_OUTPUT"
echo "release_name=${release_name}" >> "$GITHUB_OUTPUT"
echo "Release tag: ${release_tag}"
echo "Release name: ${release_name}"
- name: Resolve latest SDK releases
id: matrix
shell: bash
run: |
set -euo pipefail
raw_majors="${{ inputs.openwrt_majors }}"
majors=$(echo "${raw_majors:-$OPENWRT_MAJORS}" | tr ',' ' ')
echo "Target major versions: ${majors}"
tags=""
for i in {1..3}; do
tags=$(git ls-remote --tags --refs https://github.com/openwrt/openwrt.git 2>/dev/null | awk -F'/' '{print $NF}' | sed 's/^v//' || true)
[ -n "$tags" ] && break
sleep 2
done
if [ -z "$tags" ]; then
echo "::error::Failed to fetch tags from https://github.com/openwrt/openwrt.git"
exit 1
fi
sdks=()
for major in $majors; do
latest=$(echo "$tags" | grep -E "^${major}\.[0-9.]+$" | sort -V | tail -n 1 || true)
[ -z "$latest" ] && latest=$(echo "$tags" | grep -E "^${major}\." | sort -V | tail -n 1 || true)
if [ -n "$latest" ]; then
echo "OpenWrt ${major} -> ${latest}"
sdks+=("$latest")
else
echo "::error::No OpenWrt release tag found for major: ${major}"
exit 1
fi
done
echo "sdks=$(jq -nc --args '$ARGS.positional' -- "${sdks[@]}")" >> "$GITHUB_OUTPUT"
build:
name: Build ${{ matrix.arch }}-openwrt-${{ matrix.sdk }}
runs-on: ubuntu-latest
needs: prepare
strategy:
fail-fast: false
matrix:
arch:
- aarch64_generic
- aarch64_cortex-a53
- aarch64_cortex-a72
- aarch64_cortex-a76
- x86_64
sdk: ${{ fromJson(needs.prepare.outputs.sdks) }}
steps:
- name: Checkout source
uses: actions/checkout@v6
- name: Build packages with OpenWrt SDK
shell: bash
run: |
set -euo pipefail
mkdir -p artifacts feed/vmlinux-btf
cp -a Makefile src feed/vmlinux-btf/
[ ! -f README.md ] || cp -a README.md feed/vmlinux-btf/
image="docker.io/openwrt/sdk:${{ matrix.arch }}-${{ matrix.sdk }}"
echo "Pulling SDK image ${image}..."
docker pull "${image}"
docker run --rm \
--user root \
-v "${{ github.workspace }}/feed:/feed:ro" \
-v "${{ github.workspace }}/artifacts:/artifacts" \
"${image}" \
bash -c '
set -e
# Install host dwarves/pahole (Bullseye has dwarves; Bookworm/Alpine have dwarves/pahole)
if command -v apt-get >/dev/null 2>&1; then
if [ -f /etc/debian_version ] && grep -q '^11' /etc/debian_version; then
printf "deb [check-valid-until=no trusted=yes] http://archive.debian.org/debian/ bullseye main\ndeb [check-valid-until=no trusted=yes] http://archive.debian.org/debian-security/ bullseye-security main\n" > /etc/apt/sources.list
rm -rf /etc/apt/sources.list.d/*
fi
apt-get update -o Acquire::Check-Valid-Until=false || apt-get update
apt-get install -y --no-install-recommends dwarves || apt-get install -y dwarves || apt-get install -y pahole
rm -rf /var/lib/apt/lists/*
elif command -v apk >/dev/null 2>&1; then
apk add --no-cache dwarves
fi
# Verify pahole binary exists and is executable
pahole_bin="$(command -v pahole || which pahole || true)"
if [ -z "$pahole_bin" ] || [ ! -x "$pahole_bin" ]; then
echo "::error::pahole binary not found after package installation"
exit 1
fi
echo "Using pahole binary: $pahole_bin ($("$pahole_bin" --version))"
# Ensure pahole is accessible within OpenWrt staging_dir host tools
mkdir -p /builder/staging_dir/host/bin
ln -sf "$pahole_bin" /builder/staging_dir/host/bin/pahole
# Fix permissions and compile as buildbot user
chown -R 1000:1000 /builder /artifacts
su -s /bin/bash buildbot -c '\''
set -e
[ ! -f setup.sh ] || bash setup.sh
echo "src-link packages_ci /feed" > feeds.conf
./scripts/feeds update packages_ci
./scripts/feeds install -p packages_ci vmlinux-btf
echo "CONFIG_PACKAGE_vmlinux-btf=m" >> .config
make defconfig
make package/vmlinux-btf/compile V=s
mkdir -p /artifacts/bin
cp -a bin/* /artifacts/bin/ 2>/dev/null || true
'\''
'
sudo chown -R "$USER:$USER" "${{ github.workspace }}/artifacts"
- name: Show built files
shell: bash
run: |
echo "=== Built package files ==="
find artifacts -type f | grep -E '\.(ipk|apk)$' || true
echo "==========================="
- name: Prepare renamed artifacts
shell: bash
run: |
set -euo pipefail
mkdir -p dist
found=0
while IFS= read -r f; do
[ -n "$f" ] || continue
found=1
base="$(basename "$f")"
ext="${base##*.}"
name="${base%.*}"
if [[ "$name" == *"${{ matrix.arch }}"* ]] || [[ "$name" == *"all"* ]]; then
new_name="${name}-openwrt-${{ matrix.sdk }}.${ext}"
else
new_name="${name}-${{ matrix.arch }}-openwrt-${{ matrix.sdk }}.${ext}"
fi
cp "$f" "dist/${new_name}"
done < <(find artifacts -type f \( -name "*.ipk" -o -name "*.apk" \) 2>/dev/null)
if [ "$found" -eq 0 ]; then
echo "::error::No package files found in artifacts"
exit 1
fi
ls -lah dist
- name: Upload build artifacts
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.arch }}-openwrt-${{ matrix.sdk }}
path: dist/*
if-no-files-found: error
compression-level: 0
retention-days: 3
release:
name: Publish release
runs-on: ubuntu-latest
needs:
- prepare
- build
steps:
- name: Download all build artifacts
uses: actions/download-artifact@v8
with:
path: release-dist
merge-multiple: true
- name: Create or update GitHub release
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ needs.prepare.outputs.release_tag }}
name: ${{ needs.prepare.outputs.release_name }}
files: release-dist/*
generate_release_notes: true
token: ${{ secrets.GITHUB_TOKEN }}
- name: Delete Old Releases
uses: ophub/delete-releases-workflows@main
with:
delete_releases: true
releases_keep_latest: 3
delete_tags: true
delete_workflows: true
workflows_keep_day: 3
gh_token: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
+60 -72
View File
@@ -4,17 +4,17 @@
# This is free software, licensed under the GNU General Public License v3.
#
VMLINUX_BTF_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=vmlinux-btf
PKG_VERSION:=$(LINUX_VERSION)
PKG_RELEASE:=6
PKG_RELEASE:=9
include $(INCLUDE_DIR)/package.mk
PKG_BUILD_PARALLEL:=1
define Package/vmlinux-btf
SECTION:=kernel
CATEGORY:=Kernel
@@ -22,100 +22,88 @@ define Package/vmlinux-btf
endef
define Package/vmlinux-btf/description
Supplies kernel BTF information to ensure CO-RE eBPF compatibility.
This package builds a shadow kernel tree using the OpenWrt kernel source,
applies the same patches/files, and generates detached BTF information
without modifying the main kernel build directory.
Generates detached kernel BTF from target kernel headers and config,
enabling CO-RE eBPF programs on OpenWrt without rebuilding the kernel.
endef
define Package/vmlinux-btf/postinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
ln -sf /usr/lib/debug/boot/vmlinux /usr/lib/debug/boot/vmlinux-$$(uname -r)
fi
[ -n "$${IPKG_INSTROOT}" ] || ln -sf vmlinux /usr/lib/debug/boot/vmlinux-$$(uname -r)
endef
define Package/vmlinux-btf/prerm
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
rm -f /usr/lib/debug/boot/vmlinux-$$(uname -r)
fi
[ -n "$${IPKG_INSTROOT}" ] || rm -f /usr/lib/debug/boot/vmlinux-$$(uname -r)
endef
# Toolchain and helpers
BTF_CC ?= $(if $(TARGET_CC_NOCACHE),$(TARGET_CC_NOCACHE),$(TARGET_CROSS)gcc)
BTF_PAHOLE ?= $(firstword \
$(wildcard $(STAGING_DIR_HOST)/bin/pahole /usr/bin/pahole /usr/local/bin/pahole) \
$(shell command -v pahole 2>/dev/null) \
pahole)
PAHOLE_JOBS := $(if $(filter -j%,$(PKG_JOBS)),$(patsubst -j%,%,$(filter -j%,$(PKG_JOBS))),1)
KERNEL_RELEASE := $(if $(wildcard $(LINUX_DIR)/include/config/kernel.release),$(shell cat $(LINUX_DIR)/include/config/kernel.release),$(LINUX_VERSION))
BTF_CFLAGS := \
-nostdinc \
-isystem $(shell $(BTF_CC) -print-file-name=include) \
-D__KERNEL__ \
-include $(LINUX_DIR)/include/linux/kconfig.h \
$(if $(wildcard $(LINUX_DIR)/include/linux/compiler-version.h),-include $(LINUX_DIR)/include/linux/compiler-version.h) \
$(if $(wildcard $(LINUX_DIR)/include/linux/compiler_types.h),-include $(LINUX_DIR)/include/linux/compiler_types.h) \
-I$(LINUX_DIR)/arch/$(LINUX_KARCH)/include \
-I$(LINUX_DIR)/arch/$(LINUX_KARCH)/include/generated \
-I$(LINUX_DIR)/include \
-I$(LINUX_DIR)/include/generated \
-I$(LINUX_DIR)/arch/$(LINUX_KARCH)/include/uapi \
-I$(LINUX_DIR)/arch/$(LINUX_KARCH)/include/generated/uapi \
-I$(LINUX_DIR)/include/uapi \
-I$(LINUX_DIR)/include/generated/uapi \
-I$(LINUX_DIR) \
$(filter -m% -march=% -mcpu=% -mtune=% -EB -EL,$(TARGET_CFLAGS)) \
-std=gnu11 -funsigned-char -fshort-wchar -fno-common -fno-PIE \
-O2 -g -gdwarf-4 -fno-eliminate-unused-debug-types \
-Wno-error -Wno-unused-function -Wno-unused-variable
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(TAR) -C $(PKG_BUILD_DIR) -xf $(DL_DIR)/$(LINUX_SOURCE)
mv $(PKG_BUILD_DIR)/linux-$(LINUX_VERSION) $(PKG_BUILD_DIR)/shadow-kernel
cp $(LINUX_DIR)/.config $(PKG_BUILD_DIR)/shadow-kernel/.config
$(CP) $(VMLINUX_BTF_DIR)/src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(PKG_BUILD_DIR)/shadow-kernel/scripts/config \
--file $(PKG_BUILD_DIR)/shadow-kernel/.config \
--disable WERROR \
--enable CGROUPS \
--enable CGROUP_BPF \
--enable SOCK_CGROUP_DATA \
--enable KALLSYMS \
--enable PERF_EVENTS \
--enable TRACEPOINTS \
--enable KPROBES \
--enable UPROBES \
--enable BPF \
--enable BPF_SYSCALL \
--enable BPF_JIT \
--enable BPF_JIT_DEFAULT_ON \
--enable INET \
--enable NET_INGRESS \
--enable NET_EGRESS \
--enable BPF_STREAM_PARSER \
--enable XDP_SOCKETS \
--enable NET_SCHED \
--enable NET_SCH_INGRESS \
--enable NET_CLS \
--enable NET_CLS_ACT \
--enable KPROBE_EVENTS \
--enable UPROBE_EVENTS \
--enable BPF_EVENTS \
--enable DEBUG_KERNEL \
--enable DEBUG_INFO \
--disable DEBUG_INFO_NONE \
--enable DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT \
--disable DEBUG_INFO_REDUCED \
--disable DEBUG_INFO_SPLIT \
--enable DEBUG_INFO_BTF \
--set-str EXTRA_FIRMWARE "" \
--set-str INITRAMFS_SOURCE ""
@if [ ! -f "$(LINUX_DIR)/include/generated/autoconf.h" ]; then \
echo "vmlinux-btf: kernel headers not found in $(LINUX_DIR)"; \
exit 1; \
fi
@if [ -z "$(BTF_PAHOLE)" ] || ! $(BTF_PAHOLE) --version >/dev/null 2>&1; then \
echo "vmlinux-btf: pahole not found or not working (install dwarves/pahole on host)"; \
exit 1; \
fi
$(MAKE) -C $(PKG_BUILD_DIR)/shadow-kernel \
$(KERNEL_MAKE_FLAGS) \
KBUILD_HOSTLDFLAGS="$(KBUILD_HOSTLDFLAGS) -lz" \
olddefconfig
# Compile BTF stub sources
$(BTF_CC) $(BTF_CFLAGS) -c $(PKG_BUILD_DIR)/shadow_btf_core.c -o $(PKG_BUILD_DIR)/shadow_btf_core.o
-$(BTF_CC) $(BTF_CFLAGS) -c $(PKG_BUILD_DIR)/shadow_btf_modules.c -o $(PKG_BUILD_DIR)/shadow_btf_modules.o 2>/dev/null
-$(BTF_CC) $(BTF_CFLAGS) -c $(PKG_BUILD_DIR)/shadow_btf_private.c -o $(PKG_BUILD_DIR)/shadow_btf_private.o 2>/dev/null
$(MAKE) -C $(PKG_BUILD_DIR)/shadow-kernel \
$(KERNEL_MAKE_FLAGS) \
$(PKG_JOBS) \
KBUILD_HOSTLDFLAGS="-L$(STAGING_DIR_HOST)/lib -lz" \
vmlinux
# Link compiled objects into a single relocatable object
objs="$(PKG_BUILD_DIR)/shadow_btf_core.o"; \
[ ! -f "$(PKG_BUILD_DIR)/shadow_btf_modules.o" ] || objs="$$objs $(PKG_BUILD_DIR)/shadow_btf_modules.o"; \
[ ! -f "$(PKG_BUILD_DIR)/shadow_btf_private.o" ] || objs="$$objs $(PKG_BUILD_DIR)/shadow_btf_private.o"; \
$(TARGET_CROSS)ld -r -o $(PKG_BUILD_DIR)/shadow_btf.o $$objs
pahole \
--jobs=$(PAHOLE_JOBS) \
# Extract detached BTF
$(BTF_PAHOLE) --jobs=$(PAHOLE_JOBS) \
--btf_encode_detached=$(PKG_BUILD_DIR)/vmlinux-btf \
$(PKG_BUILD_DIR)/shadow-kernel/vmlinux
endef
define Build/Clean
rm -rf $(PKG_BUILD_DIR)
$(PKG_BUILD_DIR)/shadow_btf.o
test -s $(PKG_BUILD_DIR)/vmlinux-btf
$(BTF_PAHOLE) -C sk_buff $(PKG_BUILD_DIR)/shadow_btf.o >/dev/null
endef
define Package/vmlinux-btf/install
$(INSTALL_DIR) $(1)/usr/lib/debug/boot
$(INSTALL_DATA) $(PKG_BUILD_DIR)/vmlinux-btf $(1)/usr/lib/debug/boot/vmlinux
$(LN) vmlinux $(1)/usr/lib/debug/boot/vmlinux-$(LINUX_VERSION)
$(LN) vmlinux $(1)/usr/lib/debug/boot/vmlinux-$(KERNEL_RELEASE)
endef
$(eval $(call BuildPackage,vmlinux-btf))
$(eval $(call BuildPackage,vmlinux-btf))
+17 -92
View File
@@ -1,117 +1,42 @@
# vmlinux-btf
An OpenWrt package that builds a BTF-enabled `vmlinux` in a shadow kernel tree and installs it as a standalone file, enabling CO-RE (Compile Once – Run Everywhere) eBPF programs to run on OpenWrt without tainting or modifying the main kernel build.
OpenWrt package that generates a detached BTF (`vmlinux`) file from kernel headers and `.config`, enabling CO-RE (Compile Once – Run Everywhere) eBPF programs on OpenWrt without rebuilding or replacing the running kernel.
---
## Overview
## How It Works
Official OpenWrt release kernels typically omit `CONFIG_DEBUG_INFO_BTF=y`. Without kernel BTF, modern eBPF tools that rely on CO-RE (such as `libbpf`-based loaders) cannot resolve kernel type layouts.
1. Downloads the upstream Linux kernel source that matches the current OpenWrt build environment.
2. Extracts it into an isolated `shadow-kernel` directory inside the build tree.
3. Applies the same generic and platform-specific patches that the main kernel receives, in the same order.
4. Copies the main kernel's `.config` as a baseline, then enables the full set of BTF and BPF-related options on top of it.
5. Compiles `vmlinux` with full DWARF debug info.
6. Uses `pahole` to extract a detached BTF blob from the resulting `vmlinux`.
7. Installs the blob to `/usr/lib/debug/boot/vmlinux` on the target device.
Rather than recompiling the entire kernel tree, this package compiles lightweight stub sources (`src/shadow_btf_*.c`) against the prepared target kernel headers (`$(LINUX_DIR)`) using the target configuration and toolchain. `pahole` then extracts the detached BTF blob from the linked object.
This approach keeps the main kernel tree completely untouched — BTF information is generated entirely in the shadow build.
## Requirements
---
## Host Build Dependencies
The following tools must be present on the **host machine** running the OpenWrt build system before compiling this package.
### Required by the OpenWrt build system itself
These are standard OpenWrt build prerequisites. If your environment already builds OpenWrt successfully, these should already be present.
| Tool | Purpose |
|------|---------|
| `gcc` / `binutils` | Cross-compilation toolchain |
| `make` | Build orchestration |
| `xz-utils` | Decompression of kernel source tarball (`xzcat`) |
| `tar` | Extraction of kernel source |
| `bc` | Kernel version arithmetic during `prepare` |
| `flex`, `bison` | Kernel parser generation |
| `libssl-dev` | Kernel certificate handling |
| `libelf-dev` | ELF binary manipulation, required by kernel build |
| `python3` | Kernel build scripts |
Install on Debian/Ubuntu:
```bash
sudo apt install build-essential libssl-dev libelf-dev \
bc flex bison python3 xz-utils tar
```
Install on Fedora/RHEL:
```bash
sudo dnf install gcc binutils openssl-devel elfutils-libelf-devel \
bc flex bison python3 xz tar
```
---
### Required specifically by this package
#### `dwarves` (provides `pahole`)
`pahole` is used to extract the detached BTF blob from the compiled `vmlinux`. This is the only tool required by this package that is **not** a standard OpenWrt build dependency.
Install on Debian/Ubuntu:
```bash
sudo apt install dwarves
```
Install on Fedora/RHEL:
```bash
sudo dnf install dwarves
```
> **Note:** A host `pahole` version of **1.16 or newer** is required for `--btf_encode_detached` support. The version bundled with the OpenWrt `dwarves/host` feed satisfies this requirement. If you install `pahole` manually from your system package manager, verify the version with `pahole --version`.
---
- OpenWrt buildroot or SDK environment.
- Host `pahole` >= 1.22 (from the `dwarves` package).
## Building
Add this package to your OpenWrt build configuration:
### In OpenWrt SDK
```bash
# From the OpenWrt build root
make menuconfig
# Navigate to: Kernel → vmlinux-btf
# Select with <M> or <*>
git clone https://github.com/QiuSimons/vmlinux-btf.git package/vmlinux-btf
make package/vmlinux-btf/compile V=s
```
Or build the IPK directly:
### In OpenWrt Buildroot
Select `vmlinux-btf` under `Kernel` in `make menuconfig`, then build:
```bash
make package/vmlinux-btf/{clean,compile} V=s
make package/vmlinux-btf/compile V=s
```
---
## Installed Files
| Path | Description |
|------|-------------|
| `/usr/lib/debug/boot/vmlinux` | Detached BTF blob |
| `/usr/lib/debug/boot/vmlinux-<kernel-version>` | Symlink created by `postinst` |
- `/usr/lib/debug/boot/vmlinux`: Detached BTF file.
- `/usr/lib/debug/boot/vmlinux-<release>`: Symlink targeting `vmlinux` (linked to `uname -r` on target installation).
The symlink is created at install time using the running kernel version (`uname -r`) and removed automatically on package removal.
---
## Notes
- **Build time is significant.** This package compiles a complete kernel from source. Expect 20–60 minutes depending on your hardware and target architecture.
- **Kernel version must match.** The shadow kernel is built from the same source version as the OpenWrt target kernel (`$(LINUX_VERSION)`). Installing this package on a device running a different kernel version will likely result in BTF type mismatches and broken CO-RE lookups.
- **Architecture-specific JIT support** (`HAVE_EBPF_JIT`) is set automatically by the kernel build system based on the target architecture and does not need to be configured manually.
---
Standard loaders such as `libbpf` look for BTF at `/usr/lib/debug/boot/vmlinux-$(uname -r)` and `/usr/lib/debug/boot/vmlinux` by default.
## License
GPL-3.0-or-later — see [https://www.gnu.org/licenses/gpl-3.0.html](https://www.gnu.org/licenses/gpl-3.0.html)
GPL-3.0-or-later
+76
View File
@@ -0,0 +1,76 @@
#include <linux/kconfig.h>
#ifndef KBUILD_MODNAME
#define KBUILD_MODNAME "shadow_btf_core"
#endif
#ifndef KBUILD_BASENAME
#define KBUILD_BASENAME "shadow_btf_core"
#endif
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/sched.h>
#include <linux/mm_types.h>
#include <linux/fs.h>
#include <linux/dcache.h>
#include <linux/cred.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/icmp.h>
#include <linux/bpf.h>
#include <linux/bpf_perf_event.h>
#include <net/sock.h>
#include <net/inet_sock.h>
#include <net/inet_connection_sock.h>
#include <net/net_namespace.h>
#include <net/dst.h>
#include <net/neighbour.h>
#include <net/xdp.h>
#include <net/ip.h>
#if __has_include(<net/netdev_rx_queue.h>)
#include <net/netdev_rx_queue.h>
#endif
#if __has_include(<linux/bpf_iter.h>)
#include <linux/bpf_iter.h>
#endif
#if IS_ENABLED(CONFIG_CGROUPS)
#include <linux/cgroup.h>
#endif
#define BTF_KEEP(name, type) \
static type * __attribute__((used, section(".discard.btf_keep"))) \
__btf_keep_##name
BTF_KEEP(pt_regs, struct pt_regs);
BTF_KEEP(task_struct, struct task_struct);
BTF_KEEP(mm_struct, struct mm_struct);
BTF_KEEP(file, struct file);
BTF_KEEP(dentry, struct dentry);
BTF_KEEP(inode, struct inode);
BTF_KEEP(cred, struct cred);
BTF_KEEP(module, struct module);
BTF_KEEP(sk_buff, struct sk_buff);
BTF_KEEP(net_device, struct net_device);
BTF_KEEP(netdev_queue, struct netdev_queue);
BTF_KEEP(netdev_rx_queue, struct netdev_rx_queue);
BTF_KEEP(sock, struct sock);
BTF_KEEP(inet_sock, struct inet_sock);
BTF_KEEP(inet_connection_sock, struct inet_connection_sock);
BTF_KEEP(tcp_sock, struct tcp_sock);
BTF_KEEP(udp_sock, struct udp_sock);
BTF_KEEP(net, struct net);
BTF_KEEP(dst_entry, struct dst_entry);
BTF_KEEP(neighbour, struct neighbour);
BTF_KEEP(xdp_buff, struct xdp_buff);
BTF_KEEP(bpf_perf_event_data, struct bpf_perf_event_data);
#if IS_ENABLED(CONFIG_CGROUPS)
BTF_KEEP(cgroup, struct cgroup);
#endif
+79
View File
@@ -0,0 +1,79 @@
#include <linux/kconfig.h>
#ifndef KBUILD_MODNAME
#define KBUILD_MODNAME "shadow_btf_modules"
#endif
#ifndef KBUILD_BASENAME
#define KBUILD_BASENAME "shadow_btf_modules"
#endif
#include <linux/types.h>
#define BTF_KEEP(name, type) \
static type * __attribute__((used, section(".discard.btf_keep"))) \
__btf_keep_##name
#if IS_ENABLED(CONFIG_INET)
#include <net/route.h>
#include <net/ip_fib.h>
BTF_KEEP(rtable, struct rtable);
#endif
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ipv6.h>
#include <net/if_inet6.h>
BTF_KEEP(ipv6_pinfo, struct ipv6_pinfo);
#endif
#if IS_ENABLED(CONFIG_NETFILTER)
#include <linux/netfilter.h>
BTF_KEEP(nf_hook_state, struct nf_hook_state);
#endif
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_tuple.h>
BTF_KEEP(nf_conn, struct nf_conn);
BTF_KEEP(nf_conntrack_tuple, struct nf_conntrack_tuple);
#endif
#if IS_ENABLED(CONFIG_NF_NAT) && __has_include(<net/netfilter/nf_nat.h>)
#include <net/netfilter/nf_nat.h>
BTF_KEEP(nf_conn_nat, struct nf_conn_nat);
#endif
#if IS_ENABLED(CONFIG_NF_TABLES) && __has_include(<net/netfilter/nf_tables.h>)
#include <net/netfilter/nf_tables.h>
BTF_KEEP(nft_pktinfo, struct nft_pktinfo);
#endif
#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) && __has_include(<net/netfilter/nf_flow_table.h>)
#include <net/netfilter/nf_flow_table.h>
BTF_KEEP(flow_offload, struct flow_offload);
#endif
#if IS_ENABLED(CONFIG_NETFILTER_XTABLES)
#include <linux/netfilter/x_tables.h>
BTF_KEEP(xt_table, struct xt_table);
BTF_KEEP(xt_action_param, struct xt_action_param);
#endif
#if IS_ENABLED(CONFIG_NET_SCHED)
#include <net/sch_generic.h>
#include <net/pkt_sched.h>
BTF_KEEP(qdisc, struct Qdisc);
#endif
#if IS_ENABLED(CONFIG_NET_CLS) && __has_include(<net/pkt_cls.h>)
#include <net/pkt_cls.h>
BTF_KEEP(tcf_result, struct tcf_result);
#endif
#if IS_ENABLED(CONFIG_NET_CLS_ACT) && __has_include(<net/act_api.h>)
#include <net/act_api.h>
#endif
#if IS_ENABLED(CONFIG_XDP_SOCKETS) && __has_include(<net/xdp_sock.h>)
#include <net/xdp_sock.h>
BTF_KEEP(xdp_sock, struct xdp_sock);
#endif
+23
View File
@@ -0,0 +1,23 @@
#include <linux/kconfig.h>
#ifndef KBUILD_MODNAME
#define KBUILD_MODNAME "shadow_btf_private"
#endif
#ifndef KBUILD_BASENAME
#define KBUILD_BASENAME "shadow_btf_private"
#endif
#define BTF_KEEP(name, type) \
static type * __attribute__((used, section(".discard.btf_keep"))) \
__btf_keep_##name
#if IS_ENABLED(CONFIG_BRIDGE) && __has_include("net/bridge/br_private.h")
#include "net/bridge/br_private.h"
BTF_KEEP(net_bridge, struct net_bridge);
BTF_KEEP(net_bridge_port, struct net_bridge_port);
#endif
#if __has_include("fs/mount.h")
#include "fs/mount.h"
BTF_KEEP(mount, struct mount);
#endif