};
struct netfront_dev {
+ int refcount;
+
domid_t dom;
unsigned short tx_freelist[NET_TX_RING_SIZE + 1];
void (*netif_rx)(unsigned char* data, int len, void* arg);
void *netif_rx_arg;
- struct netfront_dev_list *ldev;
-};
-
-struct netfront_dev_list {
- struct netfront_dev *dev;
unsigned char rawmac[6];
char *ip;
char *mask;
char *gw;
- int refcount;
-
- struct netfront_dev_list *next;
+ struct netfront_dev *next;
};
-static struct netfront_dev_list *dev_list = NULL;
+static struct netfront_dev *dev_list = NULL;
void init_rx_buffers(struct netfront_dev *dev);
-static struct netfront_dev *_init_netfront(struct netfront_dev *dev,
- unsigned char rawmac[6], char **ip, char **mask, char **gw);
-static void _shutdown_netfront(struct netfront_dev *dev);
+static struct netfront_dev *_init_netfront(struct netfront_dev *dev);
+static int _shutdown_netfront(struct netfront_dev *dev);
void netfront_set_rx_handler(struct netfront_dev *dev,
void (*thenetif_rx)(unsigned char *data, int len,
void *arg),
mask_evtchn(dev->evtchn);
free(dev->mac);
+ free(dev->ip);
free(dev->backend);
gnttab_end_access(dev->rx_ring_ref);
{
char nodename[256];
struct netfront_dev *dev;
- struct netfront_dev_list *ldev = NULL;
- struct netfront_dev_list *list = NULL;
+ struct netfront_dev *list;
static int netfrontends = 0;
if (!_nodename)
}
/* Check if the device is already initialized */
- for (list = dev_list; list != NULL; list = list->next) {
- if (strcmp(nodename, list->dev->nodename) == 0) {
- list->refcount++;
- dev = list->dev;
+ for (dev = dev_list; dev != NULL; dev = dev->next) {
+ if (strcmp(nodename, dev->nodename) == 0) {
+ dev->refcount++;
if (thenetif_rx)
netfront_set_rx_handler(dev, thenetif_rx, NULL);
goto out;
dev->netif_rx = thenetif_rx;
dev->netif_rx_arg = NULL;
- ldev = malloc(sizeof(struct netfront_dev_list));
- memset(ldev, 0, sizeof(struct netfront_dev_list));
-
- if (_init_netfront(dev, ldev->rawmac, &(ldev->ip), &(ldev->mask), &(ldev->gw))) {
- dev->ldev = ldev;
- ldev->dev = dev;
- ldev->refcount = 1;
- ldev->next = NULL;
+ if (_init_netfront(dev)) {
+ dev->refcount = 1;
+ dev->next = NULL;
if (!dev_list) {
- dev_list = ldev;
+ dev_list = dev;
} else {
for (list = dev_list; list->next != NULL; list = list->next)
;
- list->next = ldev;
- }
+ list->next = dev;
+ }
netfrontends++;
} else {
- free(ldev);
dev = NULL;
goto err;
}
out:
if (rawmac) {
- rawmac[0] = ldev->rawmac[0];
- rawmac[1] = ldev->rawmac[1];
- rawmac[2] = ldev->rawmac[2];
- rawmac[3] = ldev->rawmac[3];
- rawmac[4] = ldev->rawmac[4];
- rawmac[5] = ldev->rawmac[5];
+ rawmac[0] = dev->rawmac[0];
+ rawmac[1] = dev->rawmac[1];
+ rawmac[2] = dev->rawmac[2];
+ rawmac[3] = dev->rawmac[3];
+ rawmac[4] = dev->rawmac[4];
+ rawmac[5] = dev->rawmac[5];
}
if (ip)
- *ip = strdup(ldev->ip);
+ *ip = strdup(dev->ip);
err:
return dev;
char *netfront_get_netmask(struct netfront_dev *dev)
{
- return dev->ldev->mask ? strdup(dev->ldev->mask) : NULL;
+ return dev->mask ? strdup(dev->mask) : NULL;
}
char *netfront_get_gateway(struct netfront_dev *dev)
{
- return dev->ldev->gw ? strdup(dev->ldev->gw) : NULL;
+ return dev->gw ? strdup(dev->gw) : NULL;
}
-static struct netfront_dev *_init_netfront(struct netfront_dev *dev,
- unsigned char rawmac[6],
- char **ip, char **mask, char **gw)
+static struct netfront_dev *_init_netfront(struct netfront_dev *dev)
{
xenbus_transaction_t xbt;
char* err = NULL;
{
XenbusState state;
char path[strlen(dev->backend) + strlen("/state") + 1];
+ char *p;
+
snprintf(path, sizeof(path), "%s/state", dev->backend);
xenbus_watch_path_token(XBT_NIL, path, path, &dev->events);
goto error;
}
- if (ip) {
- char *p;
-
- snprintf(path, sizeof(path), "%s/ip", dev->backend);
- xenbus_read(XBT_NIL, path, ip);
-
- if (mask) {
- p = strchr(*ip, ' ');
- if (p) {
- *p++ = '\0';
- *mask = p;
-
- if (gw) {
- p = strchr(p, ' ');
- if (p) {
- *p++ = '\0';
- *gw = p;
- }
- }
- }
+ snprintf(path, sizeof(path), "%s/ip", dev->backend);
+ xenbus_read(XBT_NIL, path, &dev->ip);
+
+ p = strchr(dev->ip, ' ');
+ if (p) {
+ *p++ = '\0';
+ dev->mask = p;
+
+ p = strchr(p, ' ');
+ if (p) {
+ *p++ = '\0';
+ dev->gw = p;
}
}
}
/* Special conversion specifier 'hh' needed for __ia64__. Without
* this mini-os panics with 'Unaligned reference'.
*/
- if (rawmac)
- sscanf(dev->mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
- &rawmac[0],
- &rawmac[1],
- &rawmac[2],
- &rawmac[3],
- &rawmac[4],
- &rawmac[5]);
+ sscanf(dev->mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+ &dev->rawmac[0],
+ &dev->rawmac[1],
+ &dev->rawmac[2],
+ &dev->rawmac[3],
+ &dev->rawmac[4],
+ &dev->rawmac[5]);
return dev;
void shutdown_netfront(struct netfront_dev *dev)
{
- struct netfront_dev_list *list = NULL;
- struct netfront_dev_list *to_del = NULL;
+ struct netfront_dev *list;
/* Check this is a valid device */
- for (list = dev_list; list != NULL; list = list->next) {
- if (list->dev == dev)
- break;
- }
+ for (list = dev_list; list != NULL && list != dev; list = list->next);
if (!list) {
printk("Trying to shutdown an invalid netfront device (%p)\n", dev);
return;
}
- list->refcount--;
- if (list->refcount == 0) {
- _shutdown_netfront(dev);
+ dev->refcount--;
+ if (dev->refcount == 0) {
+ if (_shutdown_netfront(dev))
+ return;
- to_del = list;
- if (to_del == dev_list) {
- free(to_del);
- dev_list = NULL;
+ if (dev == dev_list) {
+ dev_list = NULL;
} else {
- for (list = dev_list; list->next != to_del; list = list->next)
+ for (list = dev_list; list->next != dev; list = list->next)
;
- list->next = to_del->next;
- free(to_del);
+ list->next = dev->next;
}
+ free_netfront(dev);
}
}
-static void _shutdown_netfront(struct netfront_dev *dev)
+static int _shutdown_netfront(struct netfront_dev *dev)
{
char* err = NULL, *err2;
XenbusState state;
err2 = xenbus_rm(XBT_NIL, nodename);
free(err2);
- if (!err)
- free_netfront(dev);
+ return err ? -EBUSY : 0;
}
void suspend_netfront(void)
{
- struct netfront_dev_list *list;
+ struct netfront_dev *dev;
- for (list = dev_list; list != NULL; list = list->next)
- _shutdown_netfront(list->dev);
+ for (dev = dev_list; dev != NULL; dev = dev->next)
+ _shutdown_netfront(dev);
}
void resume_netfront(void)
{
- struct netfront_dev_list *list;
+ struct netfront_dev *dev;
- for (list = dev_list; list != NULL; list = list->next)
- _init_netfront(list->dev, NULL, NULL, NULL, NULL);
+ for (dev = dev_list; dev != NULL; dev = dev->next)
+ _init_netfront(dev);
}
void init_rx_buffers(struct netfront_dev *dev)