Exemple #1
0
void start_networking(void)
{
    struct netfront_dev *dev;
    struct netif *_netif;
    struct netif *niret;
    struct netfrontif *nfi;
    struct ip_addr ip;
    struct ip_addr mask;
    struct ip_addr gw;
    char *ifip = NULL;

    ASSERT(netif == NULL);
    IP4_ADDR(&ip,   192, 168,   1, 128);
    IP4_ADDR(&mask, 255, 255, 255,   0);
    IP4_ADDR(&gw,     0,   0,   0,   0);

    tprintk("Starting networking\n");

    /* init netfront */
    dev = init_netfront(NULL, NULL, NULL, &ifip);
    if (!dev) {
        tprintk("Could not init netfront\n");
        goto err_out;
    }
    if (ifip) {
        tprintk("Got IP address %s\n", ifip);

        ip.addr = inet_addr(ifip);
	if (IN_CLASSA(ntohl(ip.addr))) {
	    tprintk("Use class A netmask (255.0.0.0)\n");
	    mask.addr = htonl(IN_CLASSA_NET);
	} else if (IN_CLASSB(ntohl(ip.addr))) {
	    mask.addr = htonl(IN_CLASSB_NET);
	    tprintk("Use class B netmask (255.255.0.0)\n");
	} else if (IN_CLASSC(ntohl(ip.addr))) {
	    mask.addr = htonl(IN_CLASSC_NET);
	    tprintk("Use class C netmask (255.255.255.0)\n");
	} else {
	    tprintk("Could not auto-detect IP class for %s,"
		    "use class C netmask (255.255.255.0)\n", ifip);
	}
    } else {
        tprintk("Set IP to 192.168.1.128, use class A netmask (255.0.0.0)\n");
    }

    /* allocate netif */
    _netif = mem_calloc(1, sizeof(*_netif));
    if (!_netif) {
        tprintk("Could not allocate netif\n");
        goto err_shutdown_netfront;
    }
    /* allocate netif state data */
    nfi = mem_calloc(1, sizeof(*nfi));
    if (!nfi) {
        tprintk("Could not allocate netfrontif\n");
        goto err_free_netif;
    }
    nfi->dev = dev;

    /* init lwIP */
#ifdef CONFIG_LWIP_NOTHREADS
    lwip_init();
    niret = netif_add(_netif, &ip, &mask, &gw, nfi,
                      netfrontif_init, ethernet_input);
#else
    tcpip_init(NULL, NULL);
    niret = netif_add(_netif, &ip, &mask, &gw, nfi,
                      netfrontif_init, tcpip_input);
#endif
    if (!niret) {
        tprintk("Could not initialize lwIP\n");
	goto err_free_nfi;
    }
    netif_set_default(_netif);
    netif_set_up(_netif);

    netif = _netif;
    tprintk("Networking started\n");
    return;

 err_free_nfi:
    mem_free(nfi);
 err_free_netif:
    mem_free(_netif);
 err_shutdown_netfront:
    shutdown_netfront(dev);
 err_out:
    return;
}
Exemple #2
0
/**
 * Initializes and sets up a netfront interface for lwIP.
 * This function should be passed as a parameter to netfrontif_add().
 *
 * @param netif
 *  the lwip network interface structure for this netfrontif
 * @return
 *  ERR_OK if the interface was successfully initialized;
 *  An err_t value otherwise
 */
err_t netfrontif_init(struct netif *netif)
{
    struct netfrontif *nfi;
    static uint8_t netfrontif_id = 0;

    LWIP_ASSERT("netif != NULL", (netif != NULL));

    if (!(netif->state)) {
	nfi = mem_calloc(1, sizeof(*nfi));
	if (!nfi) {
	    LWIP_DEBUGF(NETIF_DEBUG, ("netfrontif_init: "
				      "Could not allocate \n"));
	    goto err_out;
	}
	netif->state = nfi;
	nfi->_state_is_private = 1;
	nfi->_dev_is_private = 1;
	nfi->_hwaddr_is_private = 1;
    } else {
	nfi = netif->state;
	nfi->_state_is_private = 0;
	nfi->_dev_is_private = !(nfi->dev);
	nfi->_hwaddr_is_private = eth_addr_cmp(&nfi->hwaddr, &ethzero);
    }

    /* Netfront */
    if (nfi->_dev_is_private) {
	/* user did not provide an opened netfront, we need to do it here */
	if (!nfi->_state_is_private) {
	    /* use vif_id to open an specific NIC interface */
	    /* Note: netfront will duplicate the passed nodename */
	    char nodename[128];

	    snprintf(nodename, sizeof(nodename), "device/vif/%u", nfi->vif_id);
	    nfi->dev = init_netfront(nodename, NULL, NULL, NULL);
	} else {
	    /* open the next available net interface */
	    nfi->dev = init_netfront(NULL, NULL, NULL, NULL);
	}
	if (!nfi->dev) {
	    LWIP_DEBUGF(NETIF_DEBUG, ("netfrontif_init: "
				      "Could not init netfront\n"));
	    goto err_free_nfi;
	}
    }

    netfront_set_rx_pbuf_handler(nfi->dev, netfrontif_rx_handler, netif);

    /* Interface identifier */
    netif->name[0] = NETFRONTIF_NPREFIX;
    netif->name[1] = '0' + netfrontif_id;
    netfrontif_id++;

    /* We directly use etharp_output() here to save a function call.
     * Instead, there could be function declared that calls etharp_output()
     * only if there is a link is available... */
    netif->output = etharp_output;
    netif->linkoutput = netfrontif_transmit;
#if LWIP_NETIF_REMOVE_CALLBACK
    netif->remove_callback = netfrontif_exit;
#endif /* CONFIG_NETIF_REMOVE_CALLBACK */

    /* Hardware address */
    if (nfi->_hwaddr_is_private) {
	if (!netfront_get_hwaddr(nfi->dev, &nfi->hwaddr)) {
	    LWIP_DEBUGF(NETIF_DEBUG, ("netfrontif_init: %c%c: "
				      "Could not retrieve hardware address\n",
				      netif->name[0], netif->name[1]));
	    goto err_shutdown_netfront;
	}
    } else {
	LWIP_DEBUGF(NETIF_DEBUG, ("netfrontif_init: %c%c: "
				  "Overwriting hardware address\n",
				  netif->name[0], netif->name[1]));
    }
    SMEMCPY(&netif->hwaddr, &nfi->hwaddr, ETHARP_HWADDR_LEN);
    netif->hwaddr_len = ETHARP_HWADDR_LEN;
    LWIP_DEBUGF(NETIF_DEBUG, ("netfrontif_init: %c%c: hardware address: "
			      "%02x:%02x:%02x:%02x:%02x:%02x\n",
			      netif->name[0], netif->name[1],
			      netif->hwaddr[0],
			      netif->hwaddr[1],
			      netif->hwaddr[2],
			      netif->hwaddr[3],
			      netif->hwaddr[4],
			      netif->hwaddr[5]));

    /* Initialize the snmp variables and counters inside the struct netif.
     * The last argument is the link speed, in units of bits per second. */
    NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, NETFRONTIF_SPEED);
    LWIP_DEBUGF(NETIF_DEBUG, ("netfrontif_init: %c%c: Link speed: %llu bps\n",
			      netif->name[0], netif->name[1], NETFRONTIF_SPEED));

    /* Device capabilities */
    netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;

    /* Maximum transfer unit */
    netif->mtu = NETFRONTIF_MTU;
    LWIP_DEBUGF(NETIF_DEBUG, ("netfrontif_init: %c%c: MTU: %u\n",
			      netif->name[0], netif->name[1], netif->mtu));

#if LWIP_NETIF_HOSTNAME
    /* Initialize interface hostname */
    if (!netif->hostname)
	netif->hostname = NULL;
#endif /* LWIP_NETIF_HOSTNAME */

#ifndef CONFIG_LWIP_NOTHREADS
  nfi->_thread_exit = 0;
  nfi->_thread_name[0] = netif->name[0];
  nfi->_thread_name[1] = netif->name[1];
  nfi->_thread_name[2] = '-';
  nfi->_thread_name[3] = 'r';
  nfi->_thread_name[4] = 'x';
  nfi->_thread_name[5] = '\0';
  create_thread(nfi->_thread_name, netfrontif_thread, netif);
#endif /* CONFIG_LWIP_NOTHREADS */

    return ERR_OK;

err_shutdown_netfront:
    if (nfi->_dev_is_private) {
        shutdown_netfront(nfi->dev);
        nfi->dev = NULL;
    }
err_free_nfi:
    if (nfi->_state_is_private) {
	mem_free(nfi);
	netif->state = NULL;
    }
err_out:
    return ERR_IF;
}
Exemple #3
0
int close(int fd)
{
    printk("close(%d)\n", fd);
    switch (files[fd].type) {
        default:
	    files[fd].type = FTYPE_NONE;
	    return 0;
#ifdef CONFIG_XENBUS
	case FTYPE_XENBUS:
            xs_daemon_close((void*)(intptr_t) fd);
            return 0;
#endif
#ifdef HAVE_LWIP
	case FTYPE_SOCKET: {
	    int res = lwip_close(files[fd].socket.fd);
	    files[fd].type = FTYPE_NONE;
	    return res;
	}
#endif
#ifdef CONFIG_XC
	case FTYPE_XC:
	    minios_interface_close_fd(fd);
	    return 0;
	case FTYPE_EVTCHN:
	    minios_evtchn_close_fd(fd);
            return 0;
	case FTYPE_GNTMAP:
	    minios_gnttab_close_fd(fd);
	    return 0;
#endif
#ifdef CONFIG_NETFRONT
	case FTYPE_TAP:
	    shutdown_netfront(files[fd].tap.dev);
	    files[fd].type = FTYPE_NONE;
	    return 0;
#endif
#ifdef CONFIG_BLKFRONT
	case FTYPE_BLK:
            shutdown_blkfront(files[fd].blk.dev);
	    files[fd].type = FTYPE_NONE;
	    return 0;
#endif
#ifdef CONFIG_TPMFRONT
	case FTYPE_TPMFRONT:
            shutdown_tpmfront(files[fd].tpmfront.dev);
	    files[fd].type = FTYPE_NONE;
	    return 0;
#endif
#ifdef CONFIG_TPM_TIS
	case FTYPE_TPM_TIS:
            shutdown_tpm_tis(files[fd].tpm_tis.dev);
	    files[fd].type = FTYPE_NONE;
	    return 0;
#endif
#ifdef CONFIG_KBDFRONT
	case FTYPE_KBD:
            shutdown_kbdfront(files[fd].kbd.dev);
            files[fd].type = FTYPE_NONE;
            return 0;
#endif
#ifdef CONFIG_FBFRONT
	case FTYPE_FB:
            shutdown_fbfront(files[fd].fb.dev);
            files[fd].type = FTYPE_NONE;
            return 0;
#endif
#ifdef CONFIG_CONSFRONT
        case FTYPE_SAVEFILE:
        case FTYPE_CONSOLE:
            fini_console(files[fd].cons.dev);
            files[fd].type = FTYPE_NONE;
            return 0;
#endif
	case FTYPE_NONE:
	    break;
    }
    printk("close(%d): Bad descriptor\n", fd);
    errno = EBADF;
    return -1;
}
Exemple #4
0
Fichier : kexec.c Projet : CPFL/xen
void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline, unsigned long flags)
{
    struct xc_dom_image *dom;
    int rc;
    domid_t domid = DOMID_SELF;
    xen_pfn_t pfn;
    xc_interface *xc_handle;
    unsigned long i;
    void *seg;
    xen_pfn_t boot_page_mfn = virt_to_mfn(&_boot_page);
    char features[] = "";
    struct mmu_update *m2p_updates;
    unsigned long nr_m2p_updates;

    DEBUG("booting with cmdline %s\n", cmdline);
    xc_handle = xc_interface_open(0,0,0);

    dom = xc_dom_allocate(xc_handle, cmdline, features);
    dom->allocate = kexec_allocate;

    /* We are using guest owned memory, therefore no limits. */
    xc_dom_kernel_max_size(dom, 0);
    xc_dom_ramdisk_max_size(dom, 0);

    dom->kernel_blob = kernel;
    dom->kernel_size = kernel_size;

    dom->ramdisk_blob = module;
    dom->ramdisk_size = module_size;

    dom->flags = flags;
    dom->console_evtchn = start_info.console.domU.evtchn;
    dom->xenstore_evtchn = start_info.store_evtchn;

    tpm_hash2pcr(dom, cmdline);

    if ( (rc = xc_dom_boot_xen_init(dom, xc_handle, domid)) != 0 ) {
        grub_printf("xc_dom_boot_xen_init returned %d\n", rc);
        errnum = ERR_BOOT_FAILURE;
        goto out;
    }
    if ( (rc = xc_dom_parse_image(dom)) != 0 ) {
        grub_printf("xc_dom_parse_image returned %d\n", rc);
        errnum = ERR_BOOT_FAILURE;
        goto out;
    }

#ifdef __i386__
    if (strcmp(dom->guest_type, "xen-3.0-x86_32p")) {
        grub_printf("can only boot x86 32 PAE kernels, not %s\n", dom->guest_type);
        errnum = ERR_EXEC_FORMAT;
        goto out;
    }
#endif
#ifdef __x86_64__
    if (strcmp(dom->guest_type, "xen-3.0-x86_64")) {
        grub_printf("can only boot x86 64 kernels, not %s\n", dom->guest_type);
        errnum = ERR_EXEC_FORMAT;
        goto out;
    }
#endif

    /* equivalent of xc_dom_mem_init */
    dom->arch_hooks = xc_dom_find_arch_hooks(xc_handle, dom->guest_type);
    dom->total_pages = start_info.nr_pages;

    /* equivalent of arch_setup_meminit */

    /* setup initial p2m */
    dom->p2m_host = malloc(sizeof(*dom->p2m_host) * dom->total_pages);

    /* Start with our current P2M */
    for (i = 0; i < dom->total_pages; i++)
        dom->p2m_host[i] = pfn_to_mfn(i);

    if ( (rc = xc_dom_build_image(dom)) != 0 ) {
        grub_printf("xc_dom_build_image returned %d\n", rc);
        errnum = ERR_BOOT_FAILURE;
        goto out;
    }

    /* copy hypercall page */
    /* TODO: domctl instead, but requires privileges */
    if (dom->parms.virt_hypercall != -1) {
        pfn = PHYS_PFN(dom->parms.virt_hypercall - dom->parms.virt_base);
        memcpy((void *) pages[pfn], hypercall_page, PAGE_SIZE);
    }

    /* Equivalent of xc_dom_boot_image */
    dom->shared_info_mfn = PHYS_PFN(start_info.shared_info);

    if (!xc_dom_compat_check(dom)) {
        grub_printf("xc_dom_compat_check failed\n");
        errnum = ERR_EXEC_FORMAT;
        goto out;
    }

    /* Move current console, xenstore and boot MFNs to the allocated place */
    do_exchange(dom, dom->console_pfn, start_info.console.domU.mfn);
    do_exchange(dom, dom->xenstore_pfn, start_info.store_mfn);
    DEBUG("virt base at %llx\n", dom->parms.virt_base);
    DEBUG("bootstack_pfn %lx\n", dom->bootstack_pfn);
    _boot_target = dom->parms.virt_base + PFN_PHYS(dom->bootstack_pfn);
    DEBUG("_boot_target %lx\n", _boot_target);
    do_exchange(dom, PHYS_PFN(_boot_target - dom->parms.virt_base),
            virt_to_mfn(&_boot_page));

    /* Make sure the bootstrap page table does not RW-map any of our current
     * page table frames */
    kexec_allocate(dom, dom->virt_pgtab_end);

    if ( (rc = xc_dom_update_guest_p2m(dom))) {
        grub_printf("xc_dom_update_guest_p2m returned %d\n", rc);
        errnum = ERR_BOOT_FAILURE;
        goto out;
    }

    if ( dom->arch_hooks->setup_pgtables )
        if ( (rc = dom->arch_hooks->setup_pgtables(dom))) {
            grub_printf("setup_pgtables returned %d\n", rc);
            errnum = ERR_BOOT_FAILURE;
            goto out;
        }

    /* start info page */
#undef start_info
    if ( dom->arch_hooks->start_info )
        dom->arch_hooks->start_info(dom);
#define start_info (start_info_union.start_info)

    xc_dom_log_memory_footprint(dom);

    /* Unmap libxc's projection of the boot page table */
    seg = xc_dom_seg_to_ptr(dom, &dom->pgtables_seg);
    munmap(seg, dom->pgtables_seg.vend - dom->pgtables_seg.vstart);

    /* Unmap day0 pages to avoid having a r/w mapping of the future page table */
    for (pfn = 0; pfn < allocated; pfn++)
        munmap((void*) pages[pfn], PAGE_SIZE);

    /* Pin the boot page table base */
    if ( (rc = pin_table(dom->xch,
#ifdef __i386__
                MMUEXT_PIN_L3_TABLE,
#endif
#ifdef __x86_64__
                MMUEXT_PIN_L4_TABLE,
#endif
                xc_dom_p2m_host(dom, dom->pgtables_seg.pfn),
                dom->guest_domid)) != 0 ) {
        grub_printf("pin_table(%lx) returned %d\n", xc_dom_p2m_host(dom,
                    dom->pgtables_seg.pfn), rc);
        errnum = ERR_BOOT_FAILURE;
        goto out_remap;
    }

    /* We populate the Mini-OS page table here so that boot.S can just call
     * update_va_mapping to project itself there.  */
    need_pgt(_boot_target);
    DEBUG("day0 pages %lx\n", allocated);
    DEBUG("boot target page %lx\n", _boot_target);
    DEBUG("boot page %p\n", &_boot_page);
    DEBUG("boot page mfn %lx\n", boot_page_mfn);
    _boot_page_entry = PFN_PHYS(boot_page_mfn) | L1_PROT;
    DEBUG("boot page entry %llx\n", _boot_page_entry);
    _boot_oldpdmfn = virt_to_mfn(start_info.pt_base);
    DEBUG("boot old pd mfn %lx\n", _boot_oldpdmfn);
    DEBUG("boot pd virt %lx\n", dom->pgtables_seg.vstart);
    _boot_pdmfn = dom->p2m_host[PHYS_PFN(dom->pgtables_seg.vstart - dom->parms.virt_base)];
    DEBUG("boot pd mfn %lx\n", _boot_pdmfn);
    _boot_stack = _boot_target + PAGE_SIZE;
    DEBUG("boot stack %lx\n", _boot_stack);
    _boot_start_info = dom->parms.virt_base + PFN_PHYS(dom->start_info_pfn);
    DEBUG("boot start info %lx\n", _boot_start_info);
    _boot_start = dom->parms.virt_entry;
    DEBUG("boot start %lx\n", _boot_start);

    /* Keep only useful entries */
    for (nr_m2p_updates = pfn = 0; pfn < start_info.nr_pages; pfn++)
        if (dom->p2m_host[pfn] != pfn_to_mfn(pfn))
            nr_m2p_updates++;

    m2p_updates = malloc(sizeof(*m2p_updates) * nr_m2p_updates);
    for (i = pfn = 0; pfn < start_info.nr_pages; pfn++)
        if (dom->p2m_host[pfn] != pfn_to_mfn(pfn)) {
            m2p_updates[i].ptr = PFN_PHYS(dom->p2m_host[pfn]) | MMU_MACHPHYS_UPDATE;
            m2p_updates[i].val = pfn;
            i++;
        }

    for (i = 0; i < blk_nb; i++)
        shutdown_blkfront(blk_dev[i]);
    if (net_dev)
        shutdown_netfront(net_dev);
    if (kbd_dev)
        shutdown_kbdfront(kbd_dev);
    stop_kernel();

    /* Update M2P */
    if ((rc = HYPERVISOR_mmu_update(m2p_updates, nr_m2p_updates, NULL, DOMID_SELF)) < 0) {
        xprintk("Could not update M2P\n");
        ASSERT(0);
    }

    xprintk("go!\n");

    /* Jump to trampoline boot page */
    _boot();

    ASSERT(0);

out_remap:
    for (pfn = 0; pfn < allocated; pfn++)
        do_map_frames(pages[pfn], &pages_mfns[pfn], 1, 0, 0, DOMID_SELF, 0, L1_PROT);
out:
    xc_dom_release(dom);
    for (pfn = 0; pfn < allocated; pfn++)
        free_page((void*)pages[pfn]);
    free(pages);
    free(pages_mfns);
    pages = NULL;
    pages_mfns = NULL;
    allocated = 0;
    xc_interface_close(xc_handle );
}
Exemple #5
0
int close(int fd)
{
    printk("close(%d)\n", fd);
    if (fd < 0 || fd > NOFILE) {
	errno = EBADF;
	return -1;
    }
    switch (files[fd].type) {
        default:
	    files[fd].type = FTYPE_NONE;
	    return 0;
	case FTYPE_XENBUS:
            xs_daemon_close((void*)(intptr_t) fd);
            return 0;
#ifdef HAVE_LWIP
	case FTYPE_SOCKET: {
	    int res = lwip_close(files[fd].socket.fd);
	    files[fd].type = FTYPE_NONE;
	    return res;
	}
#endif
	case FTYPE_XC:
	    minios_interface_close_fd(fd);
	    return 0;
	case FTYPE_EVTCHN:
	    minios_evtchn_close_fd(fd);
            return 0;
	case FTYPE_GNTMAP:
	    printk("close gntmap fd %d; gntmap %p, %d entries\n",
		   fd,
		   files[fd].gntmap.entries,
		   files[fd].gntmap.nentries);
	    minios_gnttab_close_fd(fd);
	    return 0;
	case FTYPE_TAP:
	    shutdown_netfront(files[fd].tap.dev);
	    files[fd].type = FTYPE_NONE;
	    return 0;
	case FTYPE_BLK:
            shutdown_blkfront(files[fd].blk.dev);
	    files[fd].type = FTYPE_NONE;
	    return 0;
	case FTYPE_KBD:
            shutdown_kbdfront(files[fd].kbd.dev);
            files[fd].type = FTYPE_NONE;
            return 0;
	case FTYPE_FB:
            shutdown_fbfront(files[fd].fb.dev);
            files[fd].type = FTYPE_NONE;
            return 0;
        case FTYPE_SAVEFILE:
        case FTYPE_CONSOLE:
            fini_console(files[fd].cons.dev);
            files[fd].type = FTYPE_NONE;
            return 0;
	case FTYPE_NONE:
	    break;
    }
    printk("close(%d): Bad descriptor\n", fd);
    errno = EBADF;
    return -1;
}
Exemple #6
0
/* Shut down the network */
void stop_networking(void)
{
  if (dev)
    shutdown_netfront(dev);
}