void route(const char * gw) { int ret; struct uinet_socket * so; struct rt_msghdr * rtm; struct uinet_sockaddr * sa; struct uinet_sockaddr_in * sin; char buf[4096]; errno = 0; ret = uinet_socreate(uinet_instance_default(), UINET_PF_ROUTE, &so, UINET_SOCK_RAW, 0); if (ret) { errno = ret; pfatal("uinet_socreate"); } memset(buf, 0, sizeof(buf)); rtm = (struct rt_msghdr *)buf; rtm->rtm_version = RTM_VERSION; rtm->rtm_type = RTM_ADD; rtm->rtm_flags = RTF_GATEWAY; rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; rtm->rtm_pid = getpid(); rtm->rtm_seq = 1234; sa = (struct uinet_sockaddr *)(rtm + 1); sin = (struct uinet_sockaddr_in *)(sa); sin->sin_len = sizeof(struct uinet_sockaddr_in); sin->sin_family = AF_INET; sin->sin_addr.s_addr = inet_addr("0.0.0.0"); sa = (struct uinet_sockaddr *)((unsigned char *)(sa) + ROUNDUP(sa->sa_len)); sin = (struct uinet_sockaddr_in *)(sa); sin->sin_len = sizeof(struct uinet_sockaddr_in); sin->sin_family = AF_INET; sin->sin_addr.s_addr = inet_addr(gw); sa = (struct uinet_sockaddr *)((unsigned char *)(sa) + ROUNDUP(sa->sa_len)); sin = (struct uinet_sockaddr_in *)(sa); sin->sin_len = 0; sin->sin_family = AF_INET; sa = (struct uinet_sockaddr *)((unsigned char *)(sa) + ROUNDUP(sa->sa_len)); rtm->rtm_msglen = (char *)sa - buf; errno = socket_write(so, buf, rtm->rtm_msglen); if (errno) pfatal("socket_write"); /* probably should loop through reply messages and see whether the setting of the route succeeded; right now we just assume it worked. */ return; }
static void shutdown_helper(void *arg) { struct uhi_msg *msg = arg; uint8_t signo; int lock_attempts; int have_lock; VNET_ITERATOR_DECL(vnet_iter); struct uinet_instance *uinst; int shutdown_complete = 0; if (msg) { /* * Loop to respond to multiple messages, but only shutdown * once. This allows multiple, possibly concurrent, * executions of uinet_shutdown() to result in one shutdown * and none of the calls to uinet_shutdown() to block * indefinitely. This provides nice behavior when * uinet_shutdown() is called from a signal handler in a * multi-threaded application that is not carefully policing * signal masks in all the threads. */ for (;;) { if (uhi_msg_wait(msg, &signo) == 0) { if (!shutdown_complete) { printf("\nuinet shutting down"); if (signo) printf(" from signal handler (signal %u)", signo); printf("\n"); printf("Shutting down all uinet instances...\n"); /* * We may be shutting down as a * result of a signal occurring * while another thread is holding * the vnet list lock, so attempt to * acquire the lock in a way that * will avoid getting stuck. */ lock_attempts = 0; have_lock = 0; while ((lock_attempts < 5) && !(have_lock = VNET_LIST_TRY_RLOCK())) { printf("Waiting for vnet list lock...\n"); uhi_nanosleep(UHI_NSEC_PER_SEC); lock_attempts++; } if (lock_attempts > 0 && have_lock) printf("Acquired vnet list lock\n"); if (!have_lock) printf("Proceeding without vnet list lock\n"); #ifdef VIMAGE VNET_FOREACH(vnet_iter) { uinst = vnet_iter->vnet_uinet; uinet_instance_shutdown(uinst); } #else uinet_instance_shutdown(uinet_instance_default()); #endif if (have_lock) VNET_LIST_RUNLOCK(); printf("uinet shutdown complete\n"); shutdown_complete = 1; } uhi_msg_rsp_send(msg, NULL); } else { printf("Failed to receive shutdown message\n"); } }