forked from xdp-project/xdp-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loongarch64 does not support bpf trampoline and freplace, so use tail call to call XDP program. Signed-off-by: Vincent Li <[email protected]>
- Loading branch information
1 parent
4ad6135
commit ad2a4e6
Showing
5 changed files
with
492 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | ||
|
||
XDP_TARGETS := xdp_tailcall.bpf | ||
BPF_SKEL_TARGETS := $(XDP_TARGETS) | ||
USER_TARGETS := xdp_sni xdp_sni_log | ||
|
||
LIB_DIR = ../lib | ||
|
||
include $(LIB_DIR)/common.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
* Copyright (c) 2024, BPFire. All rights reserved. | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <bpf/bpf.h> | ||
#include <bpf/libbpf.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <errno.h> | ||
#include <stdlib.h> | ||
|
||
#define MAX_DOMAIN_SIZE 63 | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
int map_fd; | ||
char server_name[MAX_DOMAIN_SIZE + 1] = {0}; | ||
__u8 value = 1; | ||
|
||
// Check for proper number of arguments | ||
if (argc != 4) { | ||
fprintf(stderr, "Usage: %s <map_path> <add|delete> <domain>\n", argv[0]); | ||
return 1; | ||
} | ||
|
||
// Reverse the input domain | ||
strncpy(server_name, argv[3], MAX_DOMAIN_SIZE); | ||
server_name[MAX_DOMAIN_SIZE] = '\0'; // Ensure null termination | ||
|
||
// Open the BPF map | ||
const char *map_path = argv[1]; | ||
map_fd = bpf_obj_get(map_path); | ||
if (map_fd < 0) { | ||
fprintf(stderr, "Failed to open map at %s: %s\n", map_path, strerror(errno)); | ||
return 1; | ||
} | ||
|
||
// Add or delete the domain based on the first argument | ||
if (strcmp(argv[2], "add") == 0) { | ||
// Update the map with the reversed domain name | ||
if (bpf_map_update_elem(map_fd, server_name, &value, BPF_ANY) != 0) { | ||
fprintf(stderr, "Failed to add domain to map: %s\n", | ||
strerror(errno)); | ||
return 1; | ||
} | ||
printf("Domain %s (reversed: %s) added to denylist\n", argv[3], | ||
server_name); | ||
} else if (strcmp(argv[2], "delete") == 0) { | ||
// Remove the reversed domain from the map | ||
if (bpf_map_delete_elem(map_fd, server_name) != 0) { | ||
fprintf(stderr, | ||
"Failed to remove domain from map: %s\n", | ||
strerror(errno)); | ||
return 1; | ||
} | ||
printf("Domain %s (reversed: %s) removed from denylist\n", | ||
argv[3], server_name); | ||
} else { | ||
fprintf(stderr, "Invalid command: %s. Use 'add' or 'delete'.\n", | ||
argv[2]); | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <arpa/inet.h> | ||
#include <bpf/libbpf.h> | ||
#include <bpf/bpf.h> | ||
#include <syslog.h> | ||
|
||
#define MAX_DOMAIN_SIZE 63 | ||
|
||
struct sni_event { | ||
__u8 len; | ||
__u32 src_ip; // IPv4 address | ||
char sni[MAX_DOMAIN_SIZE + 1]; | ||
}; | ||
|
||
// No need for DNS label to dot notation for SNI. | ||
// Instead, just copy the SNI directly for logging. | ||
void copy_sni(char *sni, char *output, size_t len) | ||
{ | ||
if (len > MAX_DOMAIN_SIZE) { | ||
len = MAX_DOMAIN_SIZE; // Ensure we don't overflow | ||
} | ||
// Directly copy the SNI string | ||
for (size_t i = 0; i < len; i++) { | ||
output[i] = sni[i]; | ||
} | ||
output[len] = '\0'; // Null-terminate | ||
} | ||
|
||
// Corrected handle_event function to match the signature expected by ring_buffer__new | ||
int handle_event(void *ctx __attribute__((unused)), void *data, | ||
size_t data_sz __attribute__((unused))) | ||
{ | ||
struct sni_event *event = (struct sni_event *)data; | ||
|
||
char src_ip_str[INET_ADDRSTRLEN]; | ||
inet_ntop(AF_INET, &event->src_ip, src_ip_str, sizeof(src_ip_str)); | ||
|
||
char domain_str[MAX_DOMAIN_SIZE + 1] = { 0 }; // Buffer for SNI | ||
copy_sni(event->sni, domain_str, event->len); | ||
|
||
syslog(LOG_INFO, "Received SNI: %s from source IP: %s", domain_str, | ||
src_ip_str); | ||
|
||
return 0; // Return 0 to indicate success | ||
} | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
if (argc != 2) { | ||
fprintf(stderr, "Usage: %s <path_to_ringbuf>\n", argv[0]); | ||
return 1; | ||
} | ||
|
||
const char *ringbuf_path = argv[1]; | ||
struct ring_buffer *rb; | ||
int ringbuf_fd; | ||
|
||
openlog("sni_logger", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); | ||
|
||
// Open the ring buffer | ||
ringbuf_fd = bpf_obj_get(ringbuf_path); | ||
if (ringbuf_fd < 0) { | ||
perror("Failed to open ring buffer"); | ||
return 1; | ||
} | ||
|
||
// Set up ring buffer polling with the corrected function signature | ||
rb = ring_buffer__new(ringbuf_fd, handle_event, NULL, NULL); | ||
if (!rb) { | ||
perror("Failed to create ring buffer"); | ||
return 1; | ||
} | ||
|
||
// Poll the ring buffer | ||
while (1) { | ||
ring_buffer__poll(rb, -1); // Block indefinitely | ||
} | ||
|
||
ring_buffer__free(rb); | ||
closelog(); | ||
return 0; | ||
} |
Oops, something went wrong.