#include #include #include #include #include void timespec_diff(struct timespec *a, const struct timespec *b) { a->tv_sec -= b->tv_sec; if (a->tv_nsec < b->tv_nsec) { a->tv_nsec += 1e9 - b->tv_nsec; a->tv_sec--; } else { a->tv_nsec -= b->tv_nsec; } } static const char *create = "add table inet slew {" " flags owner;" " map tunmap-pre { typeof ip daddr . @ih,32,32 : verdict; };" " map tunmap-post { typeof meta mark : verdict; };" " chain pre { type filter hook prerouting priority -300; policy accept;" " udp dport 2152 ip daddr . @ih,32,32 vmap @tunmap-pre;" " };" " chain post { type filter hook postrouting priority 400; policy accept;" " meta mark vmap @tunmap-post;" " };" "}" ; static struct nft_ctx *nft_ctx; int main(void) { nft_ctx = nft_ctx_new(NFT_CTX_DEFAULT); if (!nft_ctx) { printf("cannot create nft_ctx\n"); return 1; } if (nft_run_cmd_from_buffer(nft_ctx, create)) { printf("cannot init table\n"); return 1; } char cmd[1024]; const unsigned int n = 5000; struct timespec last_start; struct timespec last_diff; struct timespec start; struct timespec now; clock_gettime(CLOCK_MONOTONIC, &last_start); int count_since_last = 0; for (unsigned int i = 1; i <= n; i++) { snprintf(cmd, sizeof(cmd), "add chain inet slew tunmap-pre-%u;\n" "add rule inet slew tunmap-pre-%u" " ip daddr set 127.0.1.1" " meta mark set %u counter accept;\n" "add chain inet slew tunmap-post-%u;\n" "add rule inet slew tunmap-post-%u" " ip saddr set 127.0.2.1" " udp sport set 2152" " @ih,32,32 set 0x%x" " counter accept;\n" "add element inet slew tunmap-pre { " "127.0.1.1 . 0x%x : jump tunmap-pre-%u };\n" "add element inet slew tunmap-post { %u : jump tunmap-post-%u };\n", i, i, i, i, i, UINT_MAX - i, i, i, i, i); bool show_time = ((i & 0x7f) == 0) || (i == 1) || (i == n) || (i == n - 1); if (show_time) clock_gettime(CLOCK_MONOTONIC, &start); if (nft_run_cmd_from_buffer(nft_ctx, cmd)) { printf("failed on %u\n", i); return 1; } count_since_last++; if (show_time) { clock_gettime(CLOCK_MONOTONIC, &now); last_diff = now; timespec_diff(&last_diff, &last_start); last_start = now; timespec_diff(&now, &start); printf("created idx %4d in %8u ns (%d in %u ms)\n", i, now.tv_nsec, count_since_last, last_diff.tv_nsec / 1000000 + last_diff.tv_sec * 1000); fflush(stdout); count_since_last = 0; clock_gettime(CLOCK_MONOTONIC, &last_start); } } for (unsigned int i = 1; i <= n; i++) { snprintf(cmd, sizeof(cmd), "delete element inet slew tunmap-pre { 127.0.1.1 . 0x%x };\n" "delete element inet slew tunmap-post { %u };\n" "delete chain inet slew tunmap-pre-%u;\n" "delete chain inet slew tunmap-post-%u;\n", i, i, i, i); bool show_time = ((i & 0x7f) == 0) || (i == 1) || (i == n) || (i == n - 1); if (show_time) clock_gettime(CLOCK_MONOTONIC, &start); if (nft_run_cmd_from_buffer(nft_ctx, cmd)) { printf("failed on deleting %u\n", i); return 1; } count_since_last++; if (show_time) { clock_gettime(CLOCK_MONOTONIC, &now); last_diff = now; timespec_diff(&last_diff, &last_start); last_start = now; timespec_diff(&now, &start); printf("deleted idx %4d in %8u ns (%d in %u ms)\n", i, now.tv_nsec, count_since_last, last_diff.tv_nsec / 1000000 + last_diff.tv_sec * 1000); fflush(stdout); count_since_last = 0; clock_gettime(CLOCK_MONOTONIC, &last_start); } } nft_ctx_free(nft_ctx); return 0; }