refactor/fix: match dscp instead of tos (#294)

Co-authored-by: dae-bot[bot] <136105375+dae-bot[bot]@users.noreply.github.com>
This commit is contained in:
mzz 2023-08-20 23:43:33 +08:00 committed by GitHub
parent 5c9e0cfa15
commit c6557ce207
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 150 additions and 128 deletions

View File

@ -52,7 +52,7 @@ const (
MatchType_IpVersion MatchType_IpVersion
MatchType_Mac MatchType_Mac
MatchType_ProcessName MatchType_ProcessName
MatchType_Tos MatchType_Dscp
MatchType_Fallback MatchType_Fallback
MatchType_MustRules MatchType_MustRules

View File

@ -22,7 +22,7 @@ const (
Function_IpVersion = "ipversion" Function_IpVersion = "ipversion"
Function_Mac = "mac" Function_Mac = "mac"
Function_ProcessName = "pname" Function_ProcessName = "pname"
Function_Tos = "tos" Function_Dscp = "dscp"
Function_QName = "qname" Function_QName = "qname"
Function_QType = "qtype" Function_QType = "qtype"

View File

@ -147,7 +147,7 @@ func UintParserFactory[T constraints.Unsigned](callback func(f *config_parser.Fu
return func(log *logrus.Logger, f *config_parser.Function, key string, paramValueGroup []string, overrideOutbound *Outbound) (err error) { return func(log *logrus.Logger, f *config_parser.Function, key string, paramValueGroup []string, overrideOutbound *Outbound) (err error) {
var values []T var values []T
for _, v := range paramValueGroup { for _, v := range paramValueGroup {
val, err := strconv.ParseUint(v, 10, 8*size) val, err := strconv.ParseUint(v, 0, 8*size)
if err != nil { if err != nil {
return fmt.Errorf("cannot parse %v: %w", v, err) return fmt.Errorf("cannot parse %v: %w", v, err)
} }

View File

@ -757,6 +757,7 @@ func (c *ControlPlane) Serve(readyChan chan<- bool, listener *Listener) (err err
Outbound: uint8(consts.OutboundControlPlaneRouting), Outbound: uint8(consts.OutboundControlPlaneRouting),
Pname: [16]uint8{}, Pname: [16]uint8{},
Pid: 0, Pid: 0,
Dscp: 0,
} }
realDst = pktDst realDst = pktDst
goto destRetrieved goto destRetrieved

View File

@ -729,7 +729,7 @@ func (c *DnsController) dialSend(invokingDepth int, req *udpRequest, data []byte
"_qname": qname, "_qname": qname,
"qtype": qtype, "qtype": qtype,
"pid": req.routingResult.Pid, "pid": req.routingResult.Pid,
"tos": req.routingResult.Tos, "dscp": req.routingResult.Dscp,
"pname": ProcessName2String(req.routingResult.Pname[:]), "pname": ProcessName2String(req.routingResult.Pname[:]),
"mac": Mac2String(req.routingResult.Mac[:]), "mac": Mac2String(req.routingResult.Mac[:]),
} }

View File

@ -140,7 +140,7 @@ struct routing_result {
__u8 outbound; __u8 outbound;
__u8 pname[TASK_COMM_LEN]; __u8 pname[TASK_COMM_LEN];
__u32 pid; __u32 pid;
__u8 tos; __u8 dscp;
}; };
struct dst_routing_result { struct dst_routing_result {
@ -150,13 +150,17 @@ struct dst_routing_result {
struct routing_result routing_result; struct routing_result routing_result;
}; };
struct tuples { struct tuples_key {
union ip6 sip; union ip6 sip;
union ip6 dip; union ip6 dip;
__u16 sport; __u16 sport;
__u16 dport; __u16 dport;
__u8 l4proto; __u8 l4proto;
__u8 tos; };
struct tuples {
struct tuples_key five;
__u8 dscp;
}; };
struct { struct {
@ -185,7 +189,7 @@ struct {
struct { struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH); __uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, struct tuples); __type(key, struct tuples_key);
__type(value, struct routing_result); // outbound __type(value, struct routing_result); // outbound
__uint(max_entries, MAX_DST_MAPPING_NUM); __uint(max_entries, MAX_DST_MAPPING_NUM);
/// NOTICE: It MUST be pinned. /// NOTICE: It MUST be pinned.
@ -284,7 +288,7 @@ enum __attribute__((packed)) MatchType {
MatchType_IpVersion, MatchType_IpVersion,
MatchType_Mac, MatchType_Mac,
MatchType_ProcessName, MatchType_ProcessName,
MatchType_Tos, MatchType_Dscp,
MatchType_Fallback, MatchType_Fallback,
}; };
enum L4ProtoType { enum L4ProtoType {
@ -320,7 +324,7 @@ struct match_set {
enum L4ProtoType l4proto_type; enum L4ProtoType l4proto_type;
enum IpVersionType ip_version; enum IpVersionType ip_version;
__u32 pname[TASK_COMM_LEN / 4]; __u32 pname[TASK_COMM_LEN / 4];
__u8 tos; __u8 dscp;
}; };
bool not ; // A subrule flag (this is not a match_set flag). bool not ; // A subrule flag (this is not a match_set flag).
enum MatchType type; enum MatchType type;
@ -370,34 +374,40 @@ struct {
// Functions: // Functions:
static __always_inline __u8 ipv4_get_dscp(const struct iphdr *iph) {
return (iph->tos & 0xfc) >> 2;
}
static __always_inline __u8 ipv6_get_dscp(const struct ipv6hdr *ipv6h) {
return (ipv6h->priority << 2) + (ipv6h->flow_lbl[0] >> 6);
}
static void __always_inline static void __always_inline
get_tuples(const struct __sk_buff *skb, struct tuples *tuples, get_tuples(const struct __sk_buff *skb, struct tuples *tuples,
const struct iphdr *iph, const struct ipv6hdr *ipv6h, const struct iphdr *iph, const struct ipv6hdr *ipv6h,
const struct tcphdr *tcph, const struct udphdr *udph, __u8 l4proto) { const struct tcphdr *tcph, const struct udphdr *udph, __u8 l4proto) {
__builtin_memset(tuples, 0, sizeof(*tuples)); __builtin_memset(tuples, 0, sizeof(*tuples));
tuples->l4proto = l4proto; tuples->five.l4proto = l4proto;
if (skb->protocol == bpf_htons(ETH_P_IP)) { if (skb->protocol == bpf_htons(ETH_P_IP)) {
tuples->sip.u6_addr32[2] = bpf_htonl(0x0000ffff); tuples->five.sip.u6_addr32[2] = bpf_htonl(0x0000ffff);
tuples->sip.u6_addr32[3] = iph->saddr; tuples->five.sip.u6_addr32[3] = iph->saddr;
tuples->dip.u6_addr32[2] = bpf_htonl(0x0000ffff); tuples->five.dip.u6_addr32[2] = bpf_htonl(0x0000ffff);
tuples->dip.u6_addr32[3] = iph->daddr; tuples->five.dip.u6_addr32[3] = iph->daddr;
tuples->tos = iph->tos; tuples->dscp = ipv4_get_dscp(iph);
} else { } else {
__builtin_memcpy(&tuples->dip, &ipv6h->daddr, IPV6_BYTE_LENGTH); __builtin_memcpy(&tuples->five.dip, &ipv6h->daddr, IPV6_BYTE_LENGTH);
__builtin_memcpy(&tuples->sip, &ipv6h->saddr, IPV6_BYTE_LENGTH); __builtin_memcpy(&tuples->five.sip, &ipv6h->saddr, IPV6_BYTE_LENGTH);
tuples->tos = ipv6h->priority; tuples->dscp = ipv6_get_dscp(ipv6h);
} }
if (l4proto == IPPROTO_TCP) { if (l4proto == IPPROTO_TCP) {
tuples->sport = tcph->source; tuples->five.sport = tcph->source;
tuples->dport = tcph->dest; tuples->five.dport = tcph->dest;
} else { } else {
tuples->sport = udph->source; tuples->five.sport = udph->source;
tuples->dport = udph->dest; tuples->five.dport = udph->dest;
} }
} }
@ -971,13 +981,13 @@ decap_after_udp_hdr(struct __sk_buff *skb, __u32 eth_h_len, __u8 ihl,
// Do not use __always_inline here because this function is too heavy. // Do not use __always_inline here because this function is too heavy.
// low -> high: outbound(8b) mark(32b) unused(23b) sign(1b) // low -> high: outbound(8b) mark(32b) unused(23b) sign(1b)
static __s64 __attribute__((noinline)) static __s64 __attribute__((noinline))
route(const __u32 flag[6], const void *l4hdr, const __be32 saddr[4], route(const __u32 flag[8], const void *l4hdr, const __be32 saddr[4],
const __be32 daddr[4], const __be32 mac[4]) { const __be32 daddr[4], const __be32 mac[4]) {
#define _l4proto_type flag[0] #define _l4proto_type flag[0]
#define _ipversion_type flag[1] #define _ipversion_type flag[1]
#define _pname &flag[2] #define _pname &flag[2]
#define _is_wan flag[2] #define _is_wan flag[2]
#define _tos flag[3] #define _dscp flag[6]
int ret; int ret;
struct lpm_key lpm_key_instance, *lpm_key; struct lpm_key lpm_key_instance, *lpm_key;
@ -1132,8 +1142,8 @@ route(const __u32 flag[6], const void *l4hdr, const __be32 saddr[4],
isdns_must_goodsubrule_badrule |= 0b10; isdns_must_goodsubrule_badrule |= 0b10;
} }
break; break;
case MatchType_Tos: case MatchType_Dscp:
if (_tos == match_set->tos) { if (_dscp == match_set->dscp) {
isdns_must_goodsubrule_badrule |= 0b10; isdns_must_goodsubrule_badrule |= 0b10;
} }
break; break;
@ -1214,7 +1224,7 @@ route(const __u32 flag[6], const void *l4hdr, const __be32 saddr[4],
#undef _ipversion_type #undef _ipversion_type
#undef _pname #undef _pname
#undef _is_wan #undef _is_wan
#undef _tos #undef _dscp
} }
static bool __always_inline is_not_to_lan(void *_ori_src) { static bool __always_inline is_not_to_lan(void *_ori_src) {
@ -1283,7 +1293,7 @@ int tproxy_lan_egress(struct __sk_buff *skb) {
} }
struct tuples tuples; struct tuples tuples;
get_tuples(skb, &tuples, &iph, &ipv6h, &tcph, &udph, l4proto); get_tuples(skb, &tuples, &iph, &ipv6h, &tcph, &udph, l4proto);
if (*tproxy_port != tuples.sport) { if (*tproxy_port != tuples.five.sport) {
return TC_ACT_PIPE; return TC_ACT_PIPE;
} }
@ -1297,17 +1307,17 @@ int tproxy_lan_egress(struct __sk_buff *skb) {
if (is_not_to_lan(&ori_src)) { if (is_not_to_lan(&ori_src)) {
return TC_ACT_PIPE; return TC_ACT_PIPE;
} }
if ((ret = rewrite_ip(skb, eth_h_len, l4proto, ihl, tuples.sip.u6_addr32, if ((ret = rewrite_ip(skb, eth_h_len, l4proto, ihl, tuples.five.sip.u6_addr32,
ori_src.ip, false, true))) { ori_src.ip, false, true))) {
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
if ((ret = rewrite_port(skb, eth_h_len, l4proto, ihl, tuples.sport, if ((ret = rewrite_port(skb, eth_h_len, l4proto, ihl, tuples.five.sport,
ori_src.port, false, true))) { ori_src.port, false, true))) {
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
disable_l4_checksum(skb, eth_h_len, l4proto, ihl); disable_l4_checksum(skb, eth_h_len, l4proto, ihl);
// bpf_printk("from %pI6 to %pI6", tuples.sip, ori_src.ip); // bpf_printk("from %pI6 to %pI6", tuples.five.sip, ori_src.ip);
// bpf_printk("from %u to %u", bpf_ntohs(tuples.sport), // bpf_printk("from %u to %u", bpf_ntohs(tuples.five.sport),
// bpf_ntohs(ori_src.port)); // bpf_ntohs(ori_src.port));
return TC_ACT_OK; return TC_ACT_OK;
} }
@ -1356,20 +1366,20 @@ int tproxy_lan_ingress(struct __sk_buff *skb) {
__u32 tuple_size; __u32 tuple_size;
struct bpf_sock *sk; struct bpf_sock *sk;
bool is_old_conn = false; bool is_old_conn = false;
__u32 flag[6]; __u32 flag[8];
void *l4hdr; void *l4hdr;
if (skb->protocol == bpf_htons(ETH_P_IP)) { if (skb->protocol == bpf_htons(ETH_P_IP)) {
tuple.ipv4.daddr = tuples.dip.u6_addr32[3]; tuple.ipv4.daddr = tuples.five.dip.u6_addr32[3];
tuple.ipv4.saddr = tuples.sip.u6_addr32[3]; tuple.ipv4.saddr = tuples.five.sip.u6_addr32[3];
tuple.ipv4.dport = tuples.dport; tuple.ipv4.dport = tuples.five.dport;
tuple.ipv4.sport = tuples.sport; tuple.ipv4.sport = tuples.five.sport;
tuple_size = sizeof(tuple.ipv4); tuple_size = sizeof(tuple.ipv4);
} else { } else {
__builtin_memcpy(tuple.ipv6.daddr, &tuples.dip, IPV6_BYTE_LENGTH); __builtin_memcpy(tuple.ipv6.daddr, &tuples.five.dip, IPV6_BYTE_LENGTH);
__builtin_memcpy(tuple.ipv6.saddr, &tuples.sip, IPV6_BYTE_LENGTH); __builtin_memcpy(tuple.ipv6.saddr, &tuples.five.sip, IPV6_BYTE_LENGTH);
tuple.ipv6.dport = tuples.dport; tuple.ipv6.dport = tuples.five.dport;
tuple.ipv6.sport = tuples.sport; tuple.ipv6.sport = tuples.five.sport;
tuple_size = sizeof(tuple.ipv6); tuple_size = sizeof(tuple.ipv6);
} }
@ -1409,7 +1419,7 @@ new_connection:
} else { } else {
flag[1] = IpVersionType_6; flag[1] = IpVersionType_6;
} }
flag[3] = tuples.tos; flag[6] = tuples.dscp;
__be32 mac[4] = { __be32 mac[4] = {
0, 0,
0, 0,
@ -1418,8 +1428,8 @@ new_connection:
(ethh.h_source[4] << 8) + (ethh.h_source[5])), (ethh.h_source[4] << 8) + (ethh.h_source[5])),
}; };
__s64 s64_ret; __s64 s64_ret;
if ((s64_ret = route(flag, l4hdr, tuples.sip.u6_addr32, tuples.dip.u6_addr32, if ((s64_ret = route(flag, l4hdr, tuples.five.sip.u6_addr32,
mac)) < 0) { tuples.five.dip.u6_addr32, mac)) < 0) {
bpf_printk("shot routing: %d", s64_ret); bpf_printk("shot routing: %d", s64_ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
@ -1427,7 +1437,7 @@ new_connection:
routing_result.outbound = s64_ret; routing_result.outbound = s64_ret;
routing_result.mark = s64_ret >> 8; routing_result.mark = s64_ret >> 8;
routing_result.must = (s64_ret >> 40) & 1; routing_result.must = (s64_ret >> 40) & 1;
routing_result.tos = tuples.tos; routing_result.dscp = tuples.dscp;
__builtin_memcpy(routing_result.mac, ethh.h_source, __builtin_memcpy(routing_result.mac, ethh.h_source,
sizeof(routing_result.mac)); sizeof(routing_result.mac));
/// NOTICE: No pid pname info for LAN packet. /// NOTICE: No pid pname info for LAN packet.
@ -1441,19 +1451,19 @@ new_connection:
// } // }
// Save routing result. // Save routing result.
if ((ret = bpf_map_update_elem(&routing_tuples_map, &tuples, &routing_result, if ((ret = bpf_map_update_elem(&routing_tuples_map, &tuples.five,
BPF_ANY))) { &routing_result, BPF_ANY))) {
bpf_printk("shot save routing result: %d", ret); bpf_printk("shot save routing result: %d", ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
#if defined(__DEBUG_ROUTING) || defined(__PRINT_ROUTING_RESULT) #if defined(__DEBUG_ROUTING) || defined(__PRINT_ROUTING_RESULT)
if (l4proto == IPPROTO_TCP) { if (l4proto == IPPROTO_TCP) {
bpf_printk("tcp(lan): outbound: %u, target: %pI6:%u", ret, bpf_printk("tcp(lan): outbound: %u, target: %pI6:%u", ret,
tuples.dip.u6_addr32, bpf_ntohs(tuples.dport)); tuples.five.dip.u6_addr32, bpf_ntohs(tuples.five.dport));
} else { } else {
bpf_printk("udp(lan): outbound: %u, target: %pI6:%u", bpf_printk("udp(lan): outbound: %u, target: %pI6:%u",
routing_result.outbound, tuples.dip.u6_addr32, routing_result.outbound, tuples.five.dip.u6_addr32,
bpf_ntohs(tuples.dport)); bpf_ntohs(tuples.five.dport));
} }
#endif #endif
if (routing_result.outbound == OUTBOUND_DIRECT) { if (routing_result.outbound == OUTBOUND_DIRECT) {
@ -1471,7 +1481,7 @@ new_connection:
__u32 *alive; __u32 *alive;
alive = bpf_map_lookup_elem(&outbound_connectivity_map, &q); alive = bpf_map_lookup_elem(&outbound_connectivity_map, &q);
if (alive && *alive == 0 && if (alive && *alive == 0 &&
!(l4proto == IPPROTO_UDP && tuples.dport == bpf_htons(53))) { !(l4proto == IPPROTO_UDP && tuples.five.dport == bpf_htons(53))) {
// Outbound is not alive. Dns is an exception. // Outbound is not alive. Dns is an exception.
goto block; goto block;
} }
@ -1623,7 +1633,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
if (!tproxy_port) { if (!tproxy_port) {
return TC_ACT_OK; return TC_ACT_OK;
} }
bool tproxy_response = *tproxy_port == tuples.sport; bool tproxy_response = *tproxy_port == tuples.five.sport;
// Double check to avoid conflicts when binding wan and lan to the same // Double check to avoid conflicts when binding wan and lan to the same
// interface. // interface.
if (tproxy_response && l4proto == IPPROTO_TCP) { if (tproxy_response && l4proto == IPPROTO_TCP) {
@ -1638,16 +1648,16 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
struct bpf_sock_tuple tuple = {0}; struct bpf_sock_tuple tuple = {0};
__u32 tuple_size; __u32 tuple_size;
if (skb->protocol == bpf_htons(ETH_P_IP)) { if (skb->protocol == bpf_htons(ETH_P_IP)) {
tuple.ipv4.daddr = tuples.dip.u6_addr32[3]; tuple.ipv4.daddr = tuples.five.dip.u6_addr32[3];
tuple.ipv4.saddr = tuples.sip.u6_addr32[3]; tuple.ipv4.saddr = tuples.five.sip.u6_addr32[3];
tuple.ipv4.dport = tuples.dport; tuple.ipv4.dport = tuples.five.dport;
tuple.ipv4.sport = tuples.sport; tuple.ipv4.sport = tuples.five.sport;
tuple_size = sizeof(tuple.ipv4); tuple_size = sizeof(tuple.ipv4);
} else { } else {
__builtin_memcpy(tuple.ipv6.daddr, &tuples.dip, IPV6_BYTE_LENGTH); __builtin_memcpy(tuple.ipv6.daddr, &tuples.five.dip, IPV6_BYTE_LENGTH);
__builtin_memcpy(tuple.ipv6.saddr, &tuples.sip, IPV6_BYTE_LENGTH); __builtin_memcpy(tuple.ipv6.saddr, &tuples.five.sip, IPV6_BYTE_LENGTH);
tuple.ipv6.dport = tuples.dport; tuple.ipv6.dport = tuples.five.dport;
tuple.ipv6.sport = tuples.sport; tuple.ipv6.sport = tuples.five.sport;
tuple_size = sizeof(tuple.ipv6); tuple_size = sizeof(tuple.ipv6);
} }
struct bpf_sock *sk = struct bpf_sock *sk =
@ -1664,8 +1674,8 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
// Packets from tproxy port. // Packets from tproxy port.
// We need to redirect it to original port. // We need to redirect it to original port.
// bpf_printk("tproxy_response: %pI6:%u", tuples.dip.u6_addr32, // bpf_printk("tproxy_response: %pI6:%u", tuples.five.dip.u6_addr32,
// bpf_ntohs(tuples.dport)); // bpf_ntohs(tuples.five.dport));
// Write mac. // Write mac.
if ((ret = bpf_skb_store_bytes(skb, offsetof(struct ethhdr, h_dest), if ((ret = bpf_skb_store_bytes(skb, offsetof(struct ethhdr, h_dest),
@ -1687,7 +1697,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
__builtin_memset(&key_src, 0, sizeof(key_src)); __builtin_memset(&key_src, 0, sizeof(key_src));
// Use daddr as key in WAN because tproxy (control plane) also lookups the // Use daddr as key in WAN because tproxy (control plane) also lookups the
// map element using income client ip (that is daddr). // map element using income client ip (that is daddr).
__builtin_memcpy(&key_src.ip, &tuples.dip, IPV6_BYTE_LENGTH); __builtin_memcpy(&key_src.ip, &tuples.five.dip, IPV6_BYTE_LENGTH);
key_src.port = tcph.source; key_src.port = tcph.source;
__u8 outbound; __u8 outbound;
bool must; bool must;
@ -1696,18 +1706,19 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
if (unlikely(tcp_state_syn)) { if (unlikely(tcp_state_syn)) {
// New TCP connection. // New TCP connection.
// bpf_printk("[%X]New Connection", bpf_ntohl(tcph.seq)); // bpf_printk("[%X]New Connection", bpf_ntohl(tcph.seq));
__u32 flag[6] = {L4ProtoType_TCP}; // TCP __u32 flag[8] = {L4ProtoType_TCP}; // TCP
if (skb->protocol == bpf_htons(ETH_P_IP)) { if (skb->protocol == bpf_htons(ETH_P_IP)) {
flag[1] = IpVersionType_4; flag[1] = IpVersionType_4;
} else { } else {
flag[1] = IpVersionType_6; flag[1] = IpVersionType_6;
} }
flag[3] = tuples.tos; flag[6] = tuples.dscp;
if (pid_is_control_plane(skb, &pid_pname)) { if (pid_is_control_plane(skb, &pid_pname)) {
// From control plane. Direct. // From control plane. Direct.
return TC_ACT_OK; return TC_ACT_OK;
} }
if (pid_pname) { if (pid_pname) {
// 2, 3, 4, 5
__builtin_memcpy(&flag[2], pid_pname->pname, TASK_COMM_LEN); __builtin_memcpy(&flag[2], pid_pname->pname, TASK_COMM_LEN);
} }
__be32 mac[4] = { __be32 mac[4] = {
@ -1718,8 +1729,8 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
(ethh.h_source[4] << 8) + (ethh.h_source[5])), (ethh.h_source[4] << 8) + (ethh.h_source[5])),
}; };
__s64 s64_ret; __s64 s64_ret;
if ((s64_ret = route(flag, &tcph, tuples.sip.u6_addr32, if ((s64_ret = route(flag, &tcph, tuples.five.sip.u6_addr32,
tuples.dip.u6_addr32, mac)) < 0) { tuples.five.dip.u6_addr32, mac)) < 0) {
bpf_printk("shot routing: %d", s64_ret); bpf_printk("shot routing: %d", s64_ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
@ -1731,10 +1742,10 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
#if defined(__DEBUG_ROUTING) || defined(__PRINT_ROUTING_RESULT) #if defined(__DEBUG_ROUTING) || defined(__PRINT_ROUTING_RESULT)
// Print only new connection. // Print only new connection.
__u32 pid = pid_pname ? pid_pname->pid : 0; __u32 pid = pid_pname ? pid_pname->pid : 0;
bpf_printk("tcp(wan): from %pI6:%u [PID %u]", tuples.sip.u6_addr32, bpf_printk("tcp(wan): from %pI6:%u [PID %u]", tuples.five.sip.u6_addr32,
bpf_ntohs(tuples.sport), pid); bpf_ntohs(tuples.five.sport), pid);
bpf_printk("tcp(wan): outbound: %u, %pI6:%u", outbound, bpf_printk("tcp(wan): outbound: %u, %pI6:%u", outbound,
tuples.dip.u6_addr32, bpf_ntohs(tuples.dport)); tuples.five.dip.u6_addr32, bpf_ntohs(tuples.five.dport));
#endif #endif
} else { } else {
// bpf_printk("[%X]Old Connection", bpf_ntohl(tcph.seq)); // bpf_printk("[%X]Old Connection", bpf_ntohl(tcph.seq));
@ -1768,7 +1779,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
__u32 *alive; __u32 *alive;
alive = bpf_map_lookup_elem(&outbound_connectivity_map, &q); alive = bpf_map_lookup_elem(&outbound_connectivity_map, &q);
if (alive && *alive == 0 && if (alive && *alive == 0 &&
!(l4proto == IPPROTO_UDP && tuples.dport == bpf_htons(53))) { !(l4proto == IPPROTO_UDP && tuples.five.dport == bpf_htons(53))) {
// Outbound is not alive. Dns is an exception. // Outbound is not alive. Dns is an exception.
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
@ -1776,12 +1787,12 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
if (unlikely(tcp_state_syn)) { if (unlikely(tcp_state_syn)) {
struct dst_routing_result routing_info; struct dst_routing_result routing_info;
__builtin_memset(&routing_info, 0, sizeof(routing_info)); __builtin_memset(&routing_info, 0, sizeof(routing_info));
__builtin_memcpy(routing_info.ip, &tuples.dip, IPV6_BYTE_LENGTH); __builtin_memcpy(routing_info.ip, &tuples.five.dip, IPV6_BYTE_LENGTH);
routing_info.port = tcph.dest; routing_info.port = tcph.dest;
routing_info.routing_result.outbound = outbound; routing_info.routing_result.outbound = outbound;
routing_info.routing_result.mark = mark; routing_info.routing_result.mark = mark;
routing_info.routing_result.must = must; routing_info.routing_result.must = must;
routing_info.routing_result.tos = tuples.tos; routing_info.routing_result.dscp = tuples.dscp;
__builtin_memcpy(routing_info.routing_result.mac, ethh.h_source, __builtin_memcpy(routing_info.routing_result.mac, ethh.h_source,
sizeof(ethh.h_source)); sizeof(ethh.h_source));
if (pid_pname) { if (pid_pname) {
@ -1809,19 +1820,20 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
} else if (l4proto == IPPROTO_UDP) { } else if (l4proto == IPPROTO_UDP) {
// Routing. It decides if we redirect traffic to control plane. // Routing. It decides if we redirect traffic to control plane.
__u32 flag[6] = {L4ProtoType_UDP}; __u32 flag[8] = {L4ProtoType_UDP};
if (skb->protocol == bpf_htons(ETH_P_IP)) { if (skb->protocol == bpf_htons(ETH_P_IP)) {
flag[1] = IpVersionType_4; flag[1] = IpVersionType_4;
} else { } else {
flag[1] = IpVersionType_6; flag[1] = IpVersionType_6;
} }
flag[3] = tuples.tos; flag[6] = tuples.dscp;
struct pid_pname *pid_pname; struct pid_pname *pid_pname;
if (pid_is_control_plane(skb, &pid_pname)) { if (pid_is_control_plane(skb, &pid_pname)) {
// From control plane. Direct. // From control plane. Direct.
return TC_ACT_OK; return TC_ACT_OK;
} }
if (pid_pname) { if (pid_pname) {
// 2, 3, 4, 5
__builtin_memcpy(&flag[2], pid_pname->pname, TASK_COMM_LEN); __builtin_memcpy(&flag[2], pid_pname->pname, TASK_COMM_LEN);
} }
__be32 mac[4] = { __be32 mac[4] = {
@ -1832,21 +1844,21 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
(ethh.h_source[4] << 8) + (ethh.h_source[5])), (ethh.h_source[4] << 8) + (ethh.h_source[5])),
}; };
__s64 s64_ret; __s64 s64_ret;
if ((s64_ret = route(flag, &udph, tuples.sip.u6_addr32, if ((s64_ret = route(flag, &udph, tuples.five.sip.u6_addr32,
tuples.dip.u6_addr32, mac)) < 0) { tuples.five.dip.u6_addr32, mac)) < 0) {
bpf_printk("shot routing: %d", s64_ret); bpf_printk("shot routing: %d", s64_ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
// Construct new hdr to encap. // Construct new hdr to encap.
struct dst_routing_result new_hdr; struct dst_routing_result new_hdr;
__builtin_memset(&new_hdr, 0, sizeof(new_hdr)); __builtin_memset(&new_hdr, 0, sizeof(new_hdr));
__builtin_memcpy(new_hdr.ip, &tuples.dip, IPV6_BYTE_LENGTH); __builtin_memcpy(new_hdr.ip, &tuples.five.dip, IPV6_BYTE_LENGTH);
new_hdr.port = udph.dest; new_hdr.port = udph.dest;
new_hdr.recognize = RECOGNIZE; new_hdr.recognize = RECOGNIZE;
new_hdr.routing_result.outbound = s64_ret; new_hdr.routing_result.outbound = s64_ret;
new_hdr.routing_result.mark = s64_ret >> 8; new_hdr.routing_result.mark = s64_ret >> 8;
new_hdr.routing_result.must = (s64_ret >> 40) & 1; new_hdr.routing_result.must = (s64_ret >> 40) & 1;
new_hdr.routing_result.tos = tuples.tos; new_hdr.routing_result.dscp = tuples.dscp;
__builtin_memcpy(new_hdr.routing_result.mac, ethh.h_source, __builtin_memcpy(new_hdr.routing_result.mac, ethh.h_source,
sizeof(ethh.h_source)); sizeof(ethh.h_source));
if (pid_pname) { if (pid_pname) {
@ -1856,11 +1868,11 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
} }
#if defined(__DEBUG_ROUTING) || defined(__PRINT_ROUTING_RESULT) #if defined(__DEBUG_ROUTING) || defined(__PRINT_ROUTING_RESULT)
__u32 pid = pid_pname ? pid_pname->pid : 0; __u32 pid = pid_pname ? pid_pname->pid : 0;
bpf_printk("udp(wan): from %pI6:%u [PID %u]", tuples.sip.u6_addr32, bpf_printk("udp(wan): from %pI6:%u [PID %u]", tuples.five.sip.u6_addr32,
bpf_ntohs(tuples.sport), pid); bpf_ntohs(tuples.five.sport), pid);
bpf_printk("udp(wan): outbound: %u, %pI6:%u", bpf_printk("udp(wan): outbound: %u, %pI6:%u",
new_hdr.routing_result.outbound, tuples.dip.u6_addr32, new_hdr.routing_result.outbound, tuples.five.dip.u6_addr32,
bpf_ntohs(tuples.dport)); bpf_ntohs(tuples.five.dport));
#endif #endif
if (new_hdr.routing_result.outbound == OUTBOUND_DIRECT && if (new_hdr.routing_result.outbound == OUTBOUND_DIRECT &&
@ -1883,7 +1895,7 @@ int tproxy_wan_egress(struct __sk_buff *skb) {
__u32 *alive; __u32 *alive;
alive = bpf_map_lookup_elem(&outbound_connectivity_map, &q); alive = bpf_map_lookup_elem(&outbound_connectivity_map, &q);
if (alive && *alive == 0 && if (alive && *alive == 0 &&
!(l4proto == IPPROTO_UDP && tuples.dport == bpf_htons(53))) { !(l4proto == IPPROTO_UDP && tuples.five.dport == bpf_htons(53))) {
// Outbound is not alive. Dns is an exception. // Outbound is not alive. Dns is an exception.
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
@ -1972,17 +1984,17 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
if (!tproxy_port) { if (!tproxy_port) {
goto accept; goto accept;
} }
if (unlikely(*tproxy_port == tuples.dport)) { if (unlikely(*tproxy_port == tuples.five.dport)) {
struct bpf_sock_tuple tuple = {0}; struct bpf_sock_tuple tuple = {0};
__u32 tuple_size; __u32 tuple_size;
if (skb->protocol == bpf_htons(ETH_P_IP)) { if (skb->protocol == bpf_htons(ETH_P_IP)) {
tuple.ipv4.daddr = tuples.dip.u6_addr32[3]; tuple.ipv4.daddr = tuples.five.dip.u6_addr32[3];
tuple.ipv4.dport = tuples.dport; tuple.ipv4.dport = tuples.five.dport;
tuple_size = sizeof(tuple.ipv4); tuple_size = sizeof(tuple.ipv4);
} else { } else {
__builtin_memcpy(tuple.ipv6.daddr, &tuples.dip, IPV6_BYTE_LENGTH); __builtin_memcpy(tuple.ipv6.daddr, &tuples.five.dip, IPV6_BYTE_LENGTH);
tuple.ipv6.dport = tuples.dport; tuple.ipv6.dport = tuples.five.dport;
tuple_size = sizeof(tuple.ipv6); tuple_size = sizeof(tuple.ipv6);
} }
@ -2027,7 +2039,7 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
__builtin_memset(&key_dst, 0, sizeof(key_dst)); __builtin_memset(&key_dst, 0, sizeof(key_dst));
// Use daddr as key in WAN because tproxy (control plane) also lookups the // Use daddr as key in WAN because tproxy (control plane) also lookups the
// map element using income client ip (that is daddr). // map element using income client ip (that is daddr).
__builtin_memcpy(&key_dst.ip, &tuples.dip, IPV6_BYTE_LENGTH); __builtin_memcpy(&key_dst.ip, &tuples.five.dip, IPV6_BYTE_LENGTH);
key_dst.port = tcph.dest; key_dst.port = tcph.dest;
struct dst_routing_result *original_dst = struct dst_routing_result *original_dst =
bpf_map_lookup_elem(&tcp_dst_map, &key_dst); bpf_map_lookup_elem(&tcp_dst_map, &key_dst);
@ -2039,12 +2051,13 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
// Rewrite sip and sport. // Rewrite sip and sport.
if ((ret = rewrite_ip(skb, eth_h_len, IPPROTO_TCP, ihl, if ((ret = rewrite_ip(skb, eth_h_len, IPPROTO_TCP, ihl,
tuples.sip.u6_addr32, original_dst->ip, false, tuples.five.sip.u6_addr32, original_dst->ip, false,
true))) { true))) {
bpf_printk("Shot IP: %d", ret); bpf_printk("Shot IP: %d", ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
if ((ret = rewrite_port(skb, eth_h_len, IPPROTO_TCP, ihl, tuples.sport, if ((ret =
rewrite_port(skb, eth_h_len, IPPROTO_TCP, ihl, tuples.five.sport,
original_dst->port, false, true))) { original_dst->port, false, true))) {
bpf_printk("Shot Port: %d", ret); bpf_printk("Shot Port: %d", ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
@ -2068,14 +2081,15 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
// Rewrite udp src ip // Rewrite udp src ip
if ((ret = rewrite_ip(skb, eth_h_len, IPPROTO_UDP, ihl, if ((ret = rewrite_ip(skb, eth_h_len, IPPROTO_UDP, ihl,
tuples.sip.u6_addr32, ori_src.ip, false, true))) { tuples.five.sip.u6_addr32, ori_src.ip, false,
true))) {
bpf_printk("Shot IP: %d", ret); bpf_printk("Shot IP: %d", ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
// Rewrite udp src port // Rewrite udp src port
if ((ret = rewrite_port(skb, eth_h_len, IPPROTO_UDP, ihl, tuples.sport, if ((ret = rewrite_port(skb, eth_h_len, IPPROTO_UDP, ihl,
ori_src.port, false, true))) { tuples.five.sport, ori_src.port, false, true))) {
bpf_printk("Shot Port: %d", ret); bpf_printk("Shot Port: %d", ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
@ -2091,8 +2105,9 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
// } // }
} }
// Rewrite dip to host ip. // Rewrite dip to host ip.
if ((ret = rewrite_ip(skb, eth_h_len, l4proto, ihl, tuples.dip.u6_addr32, if ((ret =
tuples.sip.u6_addr32, true, true))) { rewrite_ip(skb, eth_h_len, l4proto, ihl, tuples.five.dip.u6_addr32,
tuples.five.sip.u6_addr32, true, true))) {
bpf_printk("Shot IP: %d", ret); bpf_printk("Shot IP: %d", ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
@ -2101,7 +2116,7 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
// Get tproxy ip and port. // Get tproxy ip and port.
// saddr should be tproxy ip. // saddr should be tproxy ip.
__be32 *tproxy_ip = tuples.sip.u6_addr32; __be32 *tproxy_ip = tuples.five.sip.u6_addr32;
// __builtin_memcpy(tproxy_ip, saddr, sizeof(tproxy_ip)); // __builtin_memcpy(tproxy_ip, saddr, sizeof(tproxy_ip));
__be16 *tproxy_port = bpf_map_lookup_elem(&param_map, &tproxy_port_key); __be16 *tproxy_port = bpf_map_lookup_elem(&param_map, &tproxy_port_key);
if (!tproxy_port) { if (!tproxy_port) {
@ -2110,14 +2125,14 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
// bpf_printk("should send to: %pI6:%u", tproxy_ip, // bpf_printk("should send to: %pI6:%u", tproxy_ip,
// bpf_ntohs(*tproxy_port)); // bpf_ntohs(*tproxy_port));
if ((ret = rewrite_ip(skb, eth_h_len, l4proto, ihl, tuples.dip.u6_addr32, if ((ret = rewrite_ip(skb, eth_h_len, l4proto, ihl,
tproxy_ip, true, true))) { tuples.five.dip.u6_addr32, tproxy_ip, true, true))) {
bpf_printk("Shot IP: %d", ret); bpf_printk("Shot IP: %d", ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }
// Rewrite dst port. // Rewrite dst port.
if ((ret = rewrite_port(skb, eth_h_len, l4proto, ihl, tuples.dport, if ((ret = rewrite_port(skb, eth_h_len, l4proto, ihl, tuples.five.dport,
*tproxy_port, true, true))) { *tproxy_port, true, true))) {
bpf_printk("Shot Port: %d", ret); bpf_printk("Shot Port: %d", ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
@ -2125,8 +2140,9 @@ int tproxy_wan_ingress(struct __sk_buff *skb) {
// (1) Use daddr as saddr to pass NIC verification. Notice that we do not // (1) Use daddr as saddr to pass NIC verification. Notice that we do not
// modify the <sport> so tproxy will send packet to it. // modify the <sport> so tproxy will send packet to it.
if ((ret = rewrite_ip(skb, eth_h_len, l4proto, ihl, tuples.sip.u6_addr32, if ((ret =
tuples.dip.u6_addr32, false, true))) { rewrite_ip(skb, eth_h_len, l4proto, ihl, tuples.five.sip.u6_addr32,
tuples.five.dip.u6_addr32, false, true))) {
bpf_printk("Shot IP: %d", ret); bpf_printk("Shot IP: %d", ret);
return TC_ACT_SHOT; return TC_ACT_SHOT;
} }

View File

@ -44,7 +44,7 @@ func NewRoutingMatcherBuilder(log *logrus.Logger, rules []*config_parser.Routing
rulesBuilder.RegisterFunctionParser(consts.Function_L4Proto, routing.L4ProtoParserFactory(b.addL4Proto)) rulesBuilder.RegisterFunctionParser(consts.Function_L4Proto, routing.L4ProtoParserFactory(b.addL4Proto))
rulesBuilder.RegisterFunctionParser(consts.Function_Mac, routing.MacParserFactory(b.addSourceMac)) rulesBuilder.RegisterFunctionParser(consts.Function_Mac, routing.MacParserFactory(b.addSourceMac))
rulesBuilder.RegisterFunctionParser(consts.Function_ProcessName, routing.ProcessNameParserFactory(b.addProcessName)) rulesBuilder.RegisterFunctionParser(consts.Function_ProcessName, routing.ProcessNameParserFactory(b.addProcessName))
rulesBuilder.RegisterFunctionParser(consts.Function_Tos, routing.UintParserFactory(b.addTos)) rulesBuilder.RegisterFunctionParser(consts.Function_Dscp, routing.UintParserFactory(b.addDscp))
rulesBuilder.RegisterFunctionParser(consts.Function_IpVersion, routing.IpVersionParserFactory(b.addIpVersion)) rulesBuilder.RegisterFunctionParser(consts.Function_IpVersion, routing.IpVersionParserFactory(b.addIpVersion))
if err = rulesBuilder.Apply(rules); err != nil { if err = rulesBuilder.Apply(rules); err != nil {
return nil, err return nil, err
@ -276,7 +276,7 @@ func (b *RoutingMatcherBuilder) addProcessName(f *config_parser.Function, values
return nil return nil
} }
func (b *RoutingMatcherBuilder) addTos(f *config_parser.Function, values []uint8, outbound *routing.Outbound) (err error) { func (b *RoutingMatcherBuilder) addDscp(f *config_parser.Function, values []uint8, outbound *routing.Outbound) (err error) {
for i, value := range values { for i, value := range values {
outboundName := consts.OutboundLogicalOr.String() outboundName := consts.OutboundLogicalOr.String()
if i == len(values)-1 { if i == len(values)-1 {
@ -287,7 +287,7 @@ func (b *RoutingMatcherBuilder) addTos(f *config_parser.Function, values []uint8
return err return err
} }
matchSet := bpfMatchSet{ matchSet := bpfMatchSet{
Type: uint8(consts.MatchType_Tos), Type: uint8(consts.MatchType_Dscp),
Not: f.Not, Not: f.Not,
Outbound: outboundId, Outbound: outboundId,
Mark: outbound.Mark, Mark: outbound.Mark,

View File

@ -93,7 +93,7 @@ func (m *RoutingMatcher) Match(
if processName[0] != 0 && match.Value == processName { if processName[0] != 0 && match.Value == processName {
goodSubrule = true goodSubrule = true
} }
case consts.MatchType_Tos: case consts.MatchType_Dscp:
if tos == match.Value[0] { if tos == match.Value[0] {
goodSubrule = true goodSubrule = true
} }

View File

@ -83,6 +83,7 @@ destRetrieved:
Domain: domain, Domain: domain,
Mac: routingResult.Mac, Mac: routingResult.Mac,
ProcessName: routingResult.Pname, ProcessName: routingResult.Pname,
Dscp: routingResult.Dscp,
Src: src, Src: src,
Dest: dst, Dest: dst,
Mark: routingResult.Mark, Mark: routingResult.Mark,
@ -110,6 +111,7 @@ type RouteDialParam struct {
Outbound consts.OutboundIndex Outbound consts.OutboundIndex
Domain string Domain string
Mac [6]uint8 Mac [6]uint8
Dscp uint8
ProcessName [16]uint8 ProcessName [16]uint8
Src netip.AddrPort Src netip.AddrPort
Dest netip.AddrPort Dest netip.AddrPort
@ -119,9 +121,12 @@ type RouteDialParam struct {
func (c *ControlPlane) RouteDialTcp(p *RouteDialParam) (conn netproxy.Conn, err error) { func (c *ControlPlane) RouteDialTcp(p *RouteDialParam) (conn netproxy.Conn, err error) {
routingResult := &bpfRoutingResult{ routingResult := &bpfRoutingResult{
Mark: p.Mark, Mark: p.Mark,
Must: 0,
Mac: p.Mac, Mac: p.Mac,
Outbound: uint8(p.Outbound), Outbound: uint8(p.Outbound),
Pname: p.ProcessName, Pname: p.ProcessName,
Pid: 0,
Dscp: p.Dscp,
} }
outboundIndex := consts.OutboundIndex(routingResult.Outbound) outboundIndex := consts.OutboundIndex(routingResult.Outbound)
domain := p.Domain domain := p.Domain
@ -182,7 +187,7 @@ func (c *ControlPlane) RouteDialTcp(p *RouteDialParam) (conn netproxy.Conn, err
"sniffed": domain, "sniffed": domain,
"ip": RefineAddrPortToShow(dst), "ip": RefineAddrPortToShow(dst),
"pid": routingResult.Pid, "pid": routingResult.Pid,
"tos": routingResult.Tos, "dscp": routingResult.Dscp,
"pname": ProcessName2String(routingResult.Pname[:]), "pname": ProcessName2String(routingResult.Pname[:]),
"mac": Mac2String(routingResult.Mac[:]), "mac": Mac2String(routingResult.Mac[:]),
}).Infof("%v <-> %v", RefineSourceToShow(src, dst.Addr(), consts.LanWanFlag_NotApplicable), dialTarget) }).Infof("%v <-> %v", RefineSourceToShow(src, dst.Addr(), consts.LanWanFlag_NotApplicable), dialTarget)

View File

@ -274,7 +274,7 @@ getNew:
"to": realDst.String(), "to": realDst.String(),
"domain": domain, "domain": domain,
"pid": routingResult.Pid, "pid": routingResult.Pid,
"tos": routingResult.Tos, "dscp": routingResult.Dscp,
"pname": ProcessName2String(routingResult.Pname[:]), "pname": ProcessName2String(routingResult.Pname[:]),
"mac": Mac2String(routingResult.Mac[:]), "mac": Mac2String(routingResult.Mac[:]),
"from": realSrc.String(), "from": realSrc.String(),
@ -299,7 +299,7 @@ getNew:
"domain": domain, "domain": domain,
"ip": RefineAddrPortToShow(realDst), "ip": RefineAddrPortToShow(realDst),
"pid": routingResult.Pid, "pid": routingResult.Pid,
"tos": routingResult.Tos, "dscp": routingResult.Dscp,
"pname": ProcessName2String(routingResult.Pname[:]), "pname": ProcessName2String(routingResult.Pname[:]),
"mac": Mac2String(routingResult.Mac[:]), "mac": Mac2String(routingResult.Mac[:]),
} }

View File

@ -37,7 +37,7 @@ func (c *ControlPlane) Route(src, dst netip.AddrPort, domain string, l4proto con
l4proto, l4proto,
domain, domain,
routingResult.Pname, routingResult.Pname,
routingResult.Tos, routingResult.Dscp,
append([]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, routingResult.Mac[:]...), append([]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, routingResult.Mac[:]...),
); err != nil { ); err != nil {
return 0, 0, false, err return 0, 0, false, err
@ -50,7 +50,7 @@ func (c *controlPlaneCore) RetrieveRoutingResult(src, dst netip.AddrPort, l4prot
srcIp6 := src.Addr().As16() srcIp6 := src.Addr().As16()
dstIp6 := dst.Addr().As16() dstIp6 := dst.Addr().As16()
tuples := &bpfTuples{ tuples := &bpfTuplesKey{
Sip: struct{ U6Addr8 [16]uint8 }{U6Addr8: srcIp6}, Sip: struct{ U6Addr8 [16]uint8 }{U6Addr8: srcIp6},
Sport: common.Htons(src.Port()), Sport: common.Htons(src.Port()),
Dip: struct{ U6Addr8 [16]uint8 }{U6Addr8: dstIp6}, Dip: struct{ U6Addr8 [16]uint8 }{U6Addr8: dstIp6},

View File

@ -55,8 +55,8 @@ mac('02:42:ac:11:00:02') -> direct
### Process Name rule (only support localhost process when binding to WAN) ### Process Name rule (only support localhost process when binding to WAN)
pname(curl) -> direct pname(curl) -> direct
### ToS rule (match ToS/DSCP; is useful for BT bypass) ### DSCP rule (match DSCP; is useful for BT bypass). See https://github.com/daeuniverse/dae/discussions/295
tos(4) -> direct dscp(0x4) -> direct
### Multiple domains rule ### Multiple domains rule
domain(keyword: google, suffix: www.twitter.com, suffix: v2raya.org) -> my_group domain(keyword: google, suffix: www.twitter.com, suffix: v2raya.org) -> my_group

View File

@ -55,8 +55,8 @@ mac('02:42:ac:11:00:02') -> direct
### 进程名称规则绑定WAN时仅支持本机进程 ### 进程名称规则绑定WAN时仅支持本机进程
pname(curl) -> direct pname(curl) -> direct
### ToS规则匹配 ToS 和 DSCP可用于绕过 BT ### DSCP规则匹配 DSCP可用于绕过 BT见 https://github.com/daeuniverse/dae/discussions/295
tos(4) -> direct dscp(0x4) -> direct
### 多个域名规则 ### 多个域名规则
domain(keyword: google, suffix: www.twitter.com, suffix: v2raya.org) -> my_group domain(keyword: google, suffix: www.twitter.com, suffix: v2raya.org) -> my_group

6
go.mod
View File

@ -8,7 +8,7 @@ require (
github.com/bits-and-blooms/bloom/v3 v3.5.0 github.com/bits-and-blooms/bloom/v3 v3.5.0
github.com/cilium/ebpf v0.11.0 github.com/cilium/ebpf v0.11.0
github.com/daeuniverse/dae-config-dist/go/dae_config v0.0.0-20230604120805-1c27619b592d github.com/daeuniverse/dae-config-dist/go/dae_config v0.0.0-20230604120805-1c27619b592d
github.com/daeuniverse/softwind v0.0.0-20230809141237-cbe650b0e27c github.com/daeuniverse/softwind v0.0.0-20230820153831-295ddb4d7a68
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/miekg/dns v1.1.55 github.com/miekg/dns v1.1.55
@ -34,7 +34,7 @@ require (
github.com/golang/mock v1.6.0 // indirect github.com/golang/mock v1.6.0 // indirect
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
github.com/klauspost/compress v1.16.7 // indirect github.com/klauspost/compress v1.16.7 // indirect
github.com/mzz2017/quic-go v0.0.0-20230809140948-2ea096492e36 // indirect github.com/mzz2017/quic-go v0.0.0-20230820052354-b1f9b30e2593 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/quic-go/qtls-go1-20 v0.3.1 // indirect github.com/quic-go/qtls-go1-20 v0.3.1 // indirect
golang.org/x/mod v0.12.0 // indirect golang.org/x/mod v0.12.0 // indirect
@ -67,7 +67,7 @@ require (
gitlab.com/yawning/chacha20.git v0.0.0-20230427033715-7877545b1b37 // indirect gitlab.com/yawning/chacha20.git v0.0.0-20230427033715-7877545b1b37 // indirect
golang.org/x/term v0.10.0 // indirect golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect golang.org/x/text v0.11.0 // indirect
google.golang.org/grpc v1.56.2 // indirect google.golang.org/grpc v1.57.0 // indirect
) )
// replace github.com/daeuniverse/softwind => ../softwind // replace github.com/daeuniverse/softwind => ../softwind

12
go.sum
View File

@ -13,8 +13,8 @@ github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUg
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/daeuniverse/dae-config-dist/go/dae_config v0.0.0-20230604120805-1c27619b592d h1:hnC39MjR7xt5kZjrKlef7DXKFDkiX8MIcDXYC/6Jf9Q= github.com/daeuniverse/dae-config-dist/go/dae_config v0.0.0-20230604120805-1c27619b592d h1:hnC39MjR7xt5kZjrKlef7DXKFDkiX8MIcDXYC/6Jf9Q=
github.com/daeuniverse/dae-config-dist/go/dae_config v0.0.0-20230604120805-1c27619b592d/go.mod h1:VGWGgv7pCP5WGyHGUyb9+nq/gW0yBm+i/GfCNATOJ1M= github.com/daeuniverse/dae-config-dist/go/dae_config v0.0.0-20230604120805-1c27619b592d/go.mod h1:VGWGgv7pCP5WGyHGUyb9+nq/gW0yBm+i/GfCNATOJ1M=
github.com/daeuniverse/softwind v0.0.0-20230809141237-cbe650b0e27c h1:CWSa7Jnmuz8pWjMi31wxbSC+cPDzk9eZ5UClZMC2uIc= github.com/daeuniverse/softwind v0.0.0-20230820153831-295ddb4d7a68 h1:bEA1Y9Vzoppg3FEcE5YQwHY2mjX5hwK24n4oEM2dGD4=
github.com/daeuniverse/softwind v0.0.0-20230809141237-cbe650b0e27c/go.mod h1:fL1IT5Qi5oZsrZwq38b4HYQH5AFe8XofpuukHQByTbM= github.com/daeuniverse/softwind v0.0.0-20230820153831-295ddb4d7a68/go.mod h1:msDwqsQcevrfE1YNMfREU1It2LJCYptgvdwhuQ194UY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -91,8 +91,8 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mzz2017/disk-bloom v1.0.1 h1:rEF9MiXd9qMW3ibRpqcerLXULoTgRlM21yqqJl1B90M= github.com/mzz2017/disk-bloom v1.0.1 h1:rEF9MiXd9qMW3ibRpqcerLXULoTgRlM21yqqJl1B90M=
github.com/mzz2017/disk-bloom v1.0.1/go.mod h1:JLHETtUu44Z6iBmsqzkOtFlRvXSlKnxjwiBRDapizDI= github.com/mzz2017/disk-bloom v1.0.1/go.mod h1:JLHETtUu44Z6iBmsqzkOtFlRvXSlKnxjwiBRDapizDI=
github.com/mzz2017/quic-go v0.0.0-20230809140948-2ea096492e36 h1:ikWpUK6uyLmECHFDL/ZU3KA86l7eqIpDf3L46GA42jI= github.com/mzz2017/quic-go v0.0.0-20230820052354-b1f9b30e2593 h1:WfhfXZs6AIZo1DhVoeExDIxDmT35tZJ0OaGgUKzPIgU=
github.com/mzz2017/quic-go v0.0.0-20230809140948-2ea096492e36/go.mod h1:DBA25b2LoPhrfSzOPE8KcDOicysx00qvvnqe0BpA8DQ= github.com/mzz2017/quic-go v0.0.0-20230820052354-b1f9b30e2593/go.mod h1:DBA25b2LoPhrfSzOPE8KcDOicysx00qvvnqe0BpA8DQ=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
@ -210,8 +210,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 h1:2FZP5XuJY9zQyGM5N0rtovnoXjiMUEIUMvw0m9wlpLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130 h1:2FZP5XuJY9zQyGM5N0rtovnoXjiMUEIUMvw0m9wlpLc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o= google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o=
google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=