static void backend_create_netif(struct backend_info *be) { int err; long handle; struct xenbus_device *dev = be->dev; if (be->netif != NULL) return; err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle); if (err != 1) { xenbus_dev_fatal(dev, err, "reading handle"); return; } be->netif = netif_alloc(&dev->dev, dev->otherend_id, handle); if (IS_ERR(be->netif)) { err = PTR_ERR(be->netif); be->netif = NULL; xenbus_dev_fatal(dev, err, "creating interface"); return; } kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE); }
// ARP请求 void arp_request(u32 req_ip) { arp_frm *arp_rep; eth_frm *eth_arp; eth_arp = netif_alloc(ETH_HDRLEN + ARP_FRMLEN); if(eth_arp != NULL) { arp_rep = (arp_frm *)(eth_arp->data); arp_rep->hardware_type = htons(ARP_HWTYPE_ETH); arp_rep->protocol_type = htons(ARP_PTTYPE_IP); arp_rep->hw_addr_len = MAC_ADDR_LEN; arp_rep->pt_addr_len = IP_ADDR_LEN; arp_rep->operation = htons(ARP_TYPE_REQ); mem_copy(arp_rep->src_mac, local.mac, MAC_ADDR_LEN); arp_rep->src_ip.inw = local.ip.inw; mem_setbytes(arp_rep->dst_mac, 0x00, MAC_ADDR_LEN); arp_rep->dst_ip.inw = req_ip; mem_setbytes(eth_arp->dst, 0xFF, MAC_ADDR_LEN); mem_copy(eth_arp->src, local.mac, MAC_ADDR_LEN); eth_arp->type = htons(ETH_TYPE_ARP); netif_push(eth_arp, ETH_HDRLEN + ARP_FRMLEN, &local); } }
/** * Callback received when the hotplug scripts have placed the handle node. * Read it, and create a netif structure. If the frontend is ready, connect. */ static void backend_changed(struct xenbus_watch *watch, const char **vec, unsigned int len) { int err; long handle; struct backend_info *be = container_of(watch, struct backend_info, backend_watch); struct xenbus_device *dev = be->dev; DPRINTK(""); err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%li", &handle); if (XENBUS_EXIST_ERR(err)) { /* Since this watch will fire once immediately after it is registered, we expect this. Ignore it, and wait for the hotplug scripts. */ return; } if (err != 1) { xenbus_dev_fatal(dev, err, "reading handle"); return; } if (be->netif == NULL) { u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; be->netif = netif_alloc(dev->otherend_id, handle, be_mac); if (IS_ERR(be->netif)) { err = PTR_ERR(be->netif); be->netif = NULL; xenbus_dev_fatal(dev, err, "creating interface"); return; } kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE); maybe_connect(be); } }