@@ -42,6 +42,12 @@ struct Socket {
4242 __u16 dst_port ;
4343};
4444
45+ struct PortKey {
46+ __u32 src_ip ;
47+ __u16 src_port ;
48+ __u16 pad ;
49+ };
50+
4551struct {
4652 __uint (type , BPF_MAP_TYPE_HASH );
4753 __uint (max_entries , 10 );
@@ -87,7 +93,7 @@ struct {
8793struct {
8894 int (* type )[BPF_MAP_TYPE_HASH ];
8995 int (* max_entries )[MAX_CONNECTIONS ];
90- __u16 * key ;
96+ struct PortKey * key ;
9197 __u64 * value ;
9298} map_ports SEC (".maps" );
9399
@@ -341,10 +347,13 @@ int cg_sock_ops(struct bpf_sock_ops *ctx) {
341347
342348 struct Socket * sock = bpf_map_lookup_elem (& map_socks , & cookie );
343349 if (sock ) {
344- __u16 src_port = ctx -> local_port ;
345- bpf_map_update_elem (& map_ports , & src_port , & cookie , 0 );
346- BPF_LOG_INFO ("sockops: map_ports set src_port=%u dst=%x:%u\n" ,
347- src_port , sock -> dst_addr , sock -> dst_port );
350+ struct PortKey pkey ;
351+ __builtin_memset (& pkey , 0 , sizeof (pkey ));
352+ pkey .src_ip = ctx -> local_ip4 ;
353+ pkey .src_port = ctx -> local_port ;
354+ bpf_map_update_elem (& map_ports , & pkey , & cookie , 0 );
355+ BPF_LOG_INFO ("sockops: map_ports set src=%x:%u dst=%x:%u\n" ,
356+ pkey .src_ip , pkey .src_port , sock -> dst_addr , sock -> dst_port );
348357 } else {
349358 BPF_LOG_INFO ("sockops: map_socks miss local_port=%u\n" , ctx -> local_port );
350359 }
@@ -353,7 +362,7 @@ int cg_sock_ops(struct bpf_sock_ops *ctx) {
353362}
354363
355364// This is triggered when the proxy queries the original destination information through getsockopt SO_ORIGINAL_DST.
356- // This program uses the source port of the client to retrieve the socket's cookie from map_ports,
365+ // This program uses the client source ip+ port to retrieve the socket's cookie from map_ports,
357366// and then from map_socks to get the original destination information,
358367// then establishes a connection with the original target and forwards the client's request.
359368SEC ("cgroup/getsockopt" )
@@ -390,19 +399,24 @@ int cg_sock_opt(struct bpf_sockopt *ctx) {
390399 return 1 ;
391400 }
392401
393- __u16 src_port = bpf_ntohs (ctx -> sk -> dst_port );
402+ struct PortKey pkey ;
403+ __builtin_memset (& pkey , 0 , sizeof (pkey ));
404+ pkey .src_ip = ctx -> sk -> dst_ip4 ;
405+ pkey .src_port = bpf_ntohs (ctx -> sk -> dst_port );
394406
395- // Retrieve the socket cookie using the clients' src_port
396- __u64 * cookie = bpf_map_lookup_elem (& map_ports , & src_port );
407+ // Retrieve socket cookie using clients' source ip+port
408+ __u64 * cookie = bpf_map_lookup_elem (& map_ports , & pkey );
397409 if (!cookie ) {
398- BPF_LOG_INFO ("getsockopt: map_ports miss src_port=%u\n" , src_port );
410+ BPF_LOG_INFO ("getsockopt: map_ports miss src=%x:%u\n" ,
411+ pkey .src_ip , pkey .src_port );
399412 return 1 ;
400413 }
401414
402415 // Using the cookie (socket identifier), retrieve the original socket (client connect to destination) from map_socks
403416 struct Socket * sock = bpf_map_lookup_elem (& map_socks , cookie );
404417 if (!sock ) {
405- BPF_LOG_INFO ("getsockopt: map_socks miss src_port=%u\n" , src_port );
418+ BPF_LOG_INFO ("getsockopt: map_socks miss src=%x:%u\n" ,
419+ pkey .src_ip , pkey .src_port );
406420 return 1 ;
407421 }
408422
@@ -418,8 +432,8 @@ int cg_sock_opt(struct bpf_sockopt *ctx) {
418432 sa -> sin_addr .s_addr = bpf_htonl (sock -> dst_addr );
419433 sa -> sin_port = bpf_htons (sock -> dst_port );
420434 ctx -> retval = 0 ;
421- BPF_LOG_INFO ("getsockopt: restore src_port= %u dst=%x:%u\n" ,
422- src_port , sock -> dst_addr , sock -> dst_port );
435+ BPF_LOG_INFO ("getsockopt: restore src=%x: %u dst=%x:%u\n" ,
436+ pkey . src_ip , pkey . src_port , sock -> dst_addr , sock -> dst_port );
423437 return 1 ;
424438}
425439
@@ -431,13 +445,16 @@ int tcp_set_state(struct pt_regs *ctx)
431445
432446 if (state == TCP_CLOSE )
433447 {
434- __u16 src_port = BPF_CORE_READ (sk , __sk_common .skc_num );
435- __u64 * cookie = bpf_map_lookup_elem (& map_ports , & src_port );
448+ struct PortKey pkey ;
449+ __builtin_memset (& pkey , 0 , sizeof (pkey ));
450+ pkey .src_ip = BPF_CORE_READ (sk , __sk_common .skc_rcv_saddr );
451+ pkey .src_port = BPF_CORE_READ (sk , __sk_common .skc_num );
452+ __u64 * cookie = bpf_map_lookup_elem (& map_ports , & pkey );
436453 if (cookie )
437454 {
438- BPF_LOG_INFO ("tcp_close: cleanup src_port=% u\n" , src_port );
439- bpf_map_delete_elem (& map_ports , & src_port );
440- bpf_map_delete_elem (& map_socks , & cookie );
455+ BPF_LOG_INFO ("tcp_close: cleanup src=%x:% u\n" , pkey . src_ip , pkey . src_port );
456+ bpf_map_delete_elem (& map_ports , & pkey );
457+ bpf_map_delete_elem (& map_socks , cookie );
441458 }
442459 }
443460
0 commit comments