Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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");
			}
		}