On 2012-02-16, Grant Edwards <grant.b.edwa...@gmail.com> wrote: > What's the simplest/best way to "disable" IPv6 at runtime?
Here's my first try at disabling ipv6 at runtime. It seems to work well enough, but it's not as clean as I had hoped. Could a patch using this approach be accepted? Of course I'd clean up the formatting, add a changelog entry and so on. I'd also be happy to make this something that has to be enabled via CDL -- though with the changes shown below, the stack behaves exactly as before by default. I'm not keen on the "add a globally visible flag" approach, but it seemed like the only simple solution. The three things I'm trying to disable are all called via init-table entries, and AFAICT there's no practical way to remove/skip a table entry at runtime. The declaration and definition of the globally visible cyg_ipv6_runtime_disable flag probably belong somewhere else, but I haven't figured out where. Index: net/bsd_tcpip/current/src/sys/kern/uipc_domain.c =================================================================== --- net/bsd_tcpip/current/src/sys/kern/uipc_domain.c (revision 6840) +++ net/bsd_tcpip/current/src/sys/kern/uipc_domain.c (working copy) @@ -106,32 +106,42 @@ (*pr->pr_init)(); } /* * update global informatio about maximums */ max_hdr = max_linkhdr + max_protohdr; max_datalen = MHLEN - max_hdr; splx(s); } +int cyg_ipv6_runtime_disable; + /* * Add a new protocol domain to the list of supported domains * Note: you cant unload it again because a socket may be using it. * XXX can't fail at this time. */ void net_add_domain(void *data) { int s; struct domain *dp; + extern struct domain inet6domain; dp = (struct domain *)data; + + if (cyg_ipv6_runtime_disable && dp == &inet6domain) + { + diag_printf("net_add_domain(&inet6domain) -- skipped\n"); + return; + } + s = splnet(); dp->dom_next = domains; domains = dp; splx(s); net_init_domain(dp); } /* ARGSUSED*/ static void domaininit(void *dummy) Index: net/bsd_tcpip/current/src/sys/netinet6/ip6_input.c =================================================================== --- net/bsd_tcpip/current/src/sys/netinet6/ip6_input.c (revision 6840) +++ net/bsd_tcpip/current/src/sys/netinet6/ip6_input.c (working copy) @@ -260,33 +260,41 @@ add_performance_log(val, addr) unsigned long long val; struct in6_addr *addr; { ip6_logentry = (ip6_logentry + 1) % ip6_logsize; ip6_performance_log[ip6_logentry] = val; ip6_performance_addrlog[ip6_logentry] = *addr; } #endif +extern int cyg_ipv6_runtime_disable; + /* * IP6 initialization: fill in IP6 protocol switch table. * All protocols not implemented in kernel go to raw IP6 protocol handler. */ void ip6_init() { struct ip6protosw *pr; int i; #ifndef __OpenBSD__ struct timeval tv; #endif + if (cyg_ipv6_runtime_disable) + { + diag_printf("ip6_init() -- skipping\n"); + return; + } + #ifdef RADIX_ART rt_tables[AF_INET6]->rnh_addrsize = sizeof(struct in6_addr); #endif #ifdef DIAGNOSTIC if (sizeof(struct protosw) != sizeof(struct ip6protosw)) panic("sizeof(protosw) != sizeof(ip6protosw)"); #endif pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); if (pr == 0) @@ -338,20 +346,26 @@ #endif } static void ip6_init2(dummy) void *dummy; { #if defined(__bsdi__) && _BSDI_VERSION < 199802 struct ifnet *loifp = &loif; #endif + + if (cyg_ipv6_runtime_disable) + { + diag_printf("ip6_init2() -- skipping\n"); + return; + } /* * to route local address of p2p link to loopback, * assign loopback address first. */ #ifdef __bsdi__ in6_ifattach(loifp, NULL); #elif defined(__OpenBSD__) in6_ifattach(lo0ifp, NULL); #else -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss